diff --git a/.circleci/config.yml b/.circleci/config.yml index 34ebad5f8..30f026dcf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,200 +1,464 @@ -# CircleCI v2 Config -version: 2 +# CircleCI v2.1 Config +version: 2.1 -defaults_working_directory: &defaults_working_directory - working_directory: /home/circleci/project +## +# orbs +# +# Orbs used in this pipeline +## +orbs: + slack: circleci/slack@3.4.2 + pr-tools: mojaloop/pr-tools@0.1.8 -defaults_docker_node: &defaults_docker_node - docker: - - image: node:10.15-alpine -defaults_Dependencies: &defaults_Dependencies - name: Install default dependencies - command: | - apk --no-cache add git - apk --no-cache add ca-certificates - apk --no-cache add curl - apk --no-cache add openssh-client - apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake - npm config set unsafe-perm true - npm install -g gitbook-cli - -defaults_Environment: &defaults_environment - name: Set default environment - command: | - echo "Nothing to do here right now...move along!" - -defaults_slack_announcement: &defaults_slack_announcement - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{ - \"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\" - }" - -defaults_git_identity_setup: &defaults_git_identity_setup - name: Setup Git Identity - command: | - echo "Setting BASH_ENV..." - source $BASH_ENV +## +# defaults +# +# YAML defaults templates, in alphabetical order +## +defaults_Dependencies: &defaults_Dependencies | + apk --no-cache add git \ + ca-certificates \ + curl \ + openssh-client \ + make gcc g++ python3 libtool autoconf automake \ + python3 \ + py3-pip + pip3 install --upgrade pip + pip3 install awscli - git config --global user.email "$GIT_CI_USER" - git config --global user.password "$GIT_CI_PASSWORD" - git config --global user.name "$GIT_CI_EMAIL" - git remote add $GITHUB_PROJECT_USERNAME https://$GIT_CI_USER:$GITHUB_TOKEN@github.com/$GITHUB_PROJECT_USERNAME/$GITHUB_PROJECT_REPONAME.git -defaults_publish_to_gh_pages: &defaults_publish_to_gh_pages - name: Publish documentation +defaults_configure_nvm: &defaults_configure_nvm + name: Configure NVM command: | - echo "Setting BASH_ENV..." - source $BASH_ENV - - echo "Fetching info from remote $GITHUB_PROJECT_USERNAME" - git fetch -q $GITHUB_PROJECT_USERNAME &> git.log + touch $HOME/.profile + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + echo "Installing Node version: $(cat .nvmrc)" + nvm install $(cat .nvmrc) + nvm alias default $(cat .nvmrc) + nvm use $(cat .nvmrc) - echo "Checking out $GITBOOK_TARGET_BRANCH" - git checkout -b $GITBOOK_TARGET_BRANCH $GITHUB_PROJECT_USERNAME/$GITBOOK_TARGET_BRANCH &> git.log +## +# Executors +# +# CircleCI Executors +## +executors: + default-docker: + working_directory: &WORKING_DIR /home/circleci/project + resource_class: large + docker: + - image: node:16.15.0-alpine # Ref: https://hub.docker.com/_/node?tab=tags&page=1&name=alpine - echo "Pulling latest code from $GITBOOK_TARGET_BRANCH branch..." - git pull -q $GITHUB_PROJECT_USERNAME $GITBOOK_TARGET_BRANCH --rebase &> git.log - - echo "Copying contents of _book to root..." - cp -R _book/* . - - echo "Staging general changes..." - git add . - - echo "Staging generated UML..." - git add -f assets/images/uml/*.* - - echo "Commiting changes..." - git commit -a -m "Updating release to $GITHUB_TAG" - - echo "Publishing $GITHUB_TAG release to $GITBOOK_TARGET_BRANCH on github..." - git push -q $GITHUB_PROJECT_USERNAME $GITBOOK_TARGET_BRANCH &> git.log + legacy-docker: + working_directory: *WORKING_DIR + docker: + - image: node:10.15.2-alpine + default-machine: + working_directory: *WORKING_DIR + machine: + image: ubuntu-2004:current # Ref: https://circleci.com/developer/machine/image/ubuntu-2004 + +## +# Jobs +# +# A map of CircleCI jobs +## jobs: - setup: - <<: *defaults_working_directory - <<: *defaults_docker_node + build: + executor: default-docker steps: - checkout - run: - <<: *defaults_Dependencies + name: Install general dependencies + command: *defaults_Dependencies - run: - <<: *defaults_environment + <<: *defaults_configure_nvm - run: - name: Access npm folder as root - command: cd $(npm root -g)/npm + name: install node dependencies + command: npm ci - run: - name: Update NPM install - command: npm install + name: build + command: npm run build + + build-legacy: + executor: legacy-docker + steps: + - checkout + - run: + name: Install general dependencies + command: *defaults_Dependencies - run: - name: Delete build dependencies - command: apk del build-dependencies + name: install node dependencies + command: | + cd ./legacy + npm ci + - run: + name: build + command: cd ./legacy && npm run gitbook:build - save_cache: - key: dependency-cache-{{ .Revision }} + name: Save legacy build cache + key: build-legacy-cache-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} paths: - - node_modules + - /home/circleci/project/legacy/_book - build: - <<: *defaults_working_directory - <<: *defaults_docker_node + test-puml: + executor: default-machine steps: - checkout - run: - <<: *defaults_Dependencies + <<: *defaults_configure_nvm - run: - <<: *defaults_environment + no_output_timeout: 30m + name: Update NPM install + command: npm ci - run: - name: Installing build dependencies + name: Check if plantuml has been updated correctly command: | - echo 'Installing build dependencies via APK' - apk add --no-cache -t gitbook-build-dependencies openjdk8-jre graphviz ttf-droid ttf-droid-nonlatin + set +o pipefail + npm run build:plantuml:all + FILE_COUNT=$(git diff --cached --name-only | grep .svg | wc -l) + if [ ${FILE_COUNT} -ne "0" ]; then + echo 'Plantuml files are out of sync. Please run npm run build:plantuml:all and try again.'; + exit 1; + else + echo 'Plantuml files are up to date'; + fi - echo 'Setting env vars' - echo 'export PLANTUML_VERSION=$PLANTUML_VERSION' >> $BASH_ENV - echo 'export LANG=$PLANTUML_LANG' >> $BASH_ENV + infra: + executor: default-docker + steps: + - checkout + - run: + name: Install general dependencies + command: *defaults_Dependencies + - run: + name: Install terraform + command: | + cd /usr/local/bin + curl https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ + unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ + rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip + environment: + TERRAFORM_VERSION: 1.11.4 + - run: + name: Clear stale state lock (if present) + command: | + cd ./infra/src + terraform init \ + -backend-config="bucket=docs.mojaloop.io-state" \ + -backend-config="region=eu-west-2" \ + -backend-config="dynamodb_table=docs.mojaloop.io-lock" + terraform force-unlock -force 7232e661-3027-02c3-49da-f8cd72eefc89 || true + - run: + name: Update infrastructure + command: | + cd ./infra/src + terraform init \ + -backend-config="bucket=docs.mojaloop.io-state" \ + -backend-config="region=eu-west-2" \ + -backend-config="dynamodb_table=docs.mojaloop.io-lock" + terraform refresh + terraform apply --auto-approve - echo 'Downloading plantuml jar' - curl -L https://sourceforge.net/projects/plantuml/files/plantuml.${PLANTUML_VERSION}.jar/download -o plantuml.jar + s3_upload: + executor: default-docker + steps: + - checkout + - run: + name: Install general dependencies + command: *defaults_Dependencies - restore_cache: keys: - - dependency-cache-{{ .Revision }} + - build-legacy-cache-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} - run: - name: Build Gitbooks + name: test aws cli + permissions command: | - npm run gitbook:build - - save_cache: - key: build-cache-{{ .Revision }} - paths: - - _book + aws --version + aws s3 ls s3://docs.mojaloop.io-root + - run: + name: run build and deploy script + command: ./scripts/_deploy_preview_s3.sh + environment: + BUCKET_NAME: docs.mojaloop.io-root + DOMAIN: docs.mojaloop.io - deploy: - <<: *defaults_working_directory - <<: *defaults_docker_node + deploy_pr_preview: + executor: default-docker steps: - checkout - run: - <<: *defaults_Dependencies + name: Install general dependencies + command: *defaults_Dependencies + - restore_cache: + keys: + - build-legacy-cache-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Configure GitHub CLI + command: | + apk add --no-cache github-cli - run: - <<: *defaults_environment + name: Check PR Preview Limits + command: | + set -x # Enable debug output + echo "Starting PR Preview Limits check..." + + # Debug CIRCLE_PULL_REQUEST value + echo "CIRCLE_PULL_REQUEST value: $CIRCLE_PULL_REQUEST" + + # Extract PR number from CIRCLE_PULL_REQUEST using POSIX-compliant syntax + PR_NUMBER=$(echo "$CIRCLE_PULL_REQUEST" | sed -E 's/.*\/pull\/([0-9]+)$/\1/') + + # If extraction failed, try branch name + if [ -z "$PR_NUMBER" ]; then + PR_NUMBER=$(echo "$CIRCLE_BRANCH" | sed -E 's/^pull\/([0-9]+)$/\1/') + fi + + if [ -z "$PR_NUMBER" ]; then + echo "Error: Could not extract PR number from CIRCLE_PULL_REQUEST or branch name" + exit 1 + fi + + echo "Extracted PR Number: $PR_NUMBER" + + PREVIEW_LIMIT=${PREVIEW_LIMIT:-10} # Default to 10 if not set + echo "Preview Limit: $PREVIEW_LIMIT" + + # Check if this PR already has a preview + echo "Checking if PR #${PR_NUMBER} already has a preview..." + if aws s3 ls "s3://docs.mojaloop.io-root/pr/${PR_NUMBER}/" 2>/dev/null; then + echo "PR #${PR_NUMBER} already has a preview, allowing update" + exit 0 + fi + + # Get count of existing previews + echo "Counting existing previews..." + # Debug: Show what we're seeing in S3 + echo "S3 listing for pr/ directory:" + aws s3 ls s3://docs.mojaloop.io-root/pr/ 2>/dev/null || echo "No pr/ directory found" + + # Check if pr/ directory exists before counting + if aws s3 ls s3://docs.mojaloop.io-root/pr/ 2>/dev/null; then + # List all directories in the pr folder and count them + PREVIEW_COUNT=$(aws s3 ls s3://docs.mojaloop.io-root/pr/ 2>/dev/null | grep -c '^[[:space:]]*PRE [0-9]' 2>/dev/null || echo "0") + else + PREVIEW_COUNT="0" + fi + # Ensure PREVIEW_COUNT is a clean number (remove any whitespace/newlines) + PREVIEW_COUNT=$(echo "$PREVIEW_COUNT" | tr -d '\n\r ') + echo "Current preview count: $PREVIEW_COUNT" + + if [ "$PREVIEW_COUNT" -ge "$PREVIEW_LIMIT" ]; then + echo "Maximum number of previews ($PREVIEW_LIMIT) reached" + gh pr comment "$PR_NUMBER" --body "⚠️ Preview deployment skipped: Maximum number of previews ($PREVIEW_LIMIT) reached. Please wait for other PRs to be merged or closed." + exit 1 + fi + + echo "Preview count ($PREVIEW_COUNT) is under limit ($PREVIEW_LIMIT), proceeding with deployment" - run: - name: setup environment vars + name: Deploy PR Preview command: | - echo 'export GITBOOK_TARGET_BRANCH=$GITBOOK_TARGET_BRANCH' >> $BASH_ENV - echo 'export GITHUB_TOKEN=$GITHUB_TOKEN' >> $BASH_ENV - echo 'export GITHUB_PROJECT_USERNAME=$CIRCLE_PROJECT_USERNAME' >> $BASH_ENV - echo 'export GITHUB_PROJECT_REPONAME=$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV - echo 'export GITHUB_TAG=$CIRCLE_TAG' >> $BASH_ENV - echo 'export GIT_CI_USER=$GIT_CI_USER' >> $BASH_ENV - echo 'export GIT_CI_EMAIL=$GIT_CI_EMAIL' >> $BASH_ENV + # Extract PR number from CIRCLE_PULL_REQUEST + export PR_NUMBER=$(echo "$CIRCLE_PULL_REQUEST" | sed -E 's/.*\/pull\/([0-9]+)$/\1/') + if [ -z "$PR_NUMBER" ]; then + echo "Error: Could not extract PR number from CIRCLE_PULL_REQUEST" + exit 1 + fi + ./scripts/_deploy_preview_s3.sh + environment: + BUCKET_NAME: docs.mojaloop.io-root + DOMAIN: docs.mojaloop.io + IS_PR: "true" + - run: + name: Comment PR with Preview URL + command: | + PR_NUMBER=${CIRCLE_PULL_REQUEST##*/} + if [ -n "$PR_NUMBER" ]; then + gh pr comment "$PR_NUMBER" --body "Preview deployment is available at: https://docs.mojaloop.io/pr/${PR_NUMBER}/" + fi + + cleanup_pr_preview: + executor: default-docker + steps: + - checkout + - run: + name: Install general dependencies + command: *defaults_Dependencies + - run: + name: Configure GitHub CLI and jq + command: | + apk add --no-cache github-cli jq + - run: + name: Cleanup PR Previews + command: | + set -x # Enable debug output + echo "Starting PR preview cleanup..." + + # Get all open PRs (including draft) + echo "Fetching open PRs..." + OPEN_PRS=$(gh pr list --state open --json number) + if ! echo "$OPEN_PRS" | jq empty 2>/dev/null; then + echo "Error: Invalid JSON response from GitHub CLI for open PRs" + echo "Response was: $OPEN_PRS" + exit 1 + fi + + # Create a list of open PR numbers for exclusion + OPEN_PR_NUMBERS=$(echo "$OPEN_PRS" | jq -r '.[].number') + echo "Open PR numbers: $OPEN_PR_NUMBERS" + + # Get all PR preview directories from S3 + echo "Fetching PR preview directories from S3..." + + # Check if the pr/ directory exists in S3 + if ! aws s3 ls s3://docs.mojaloop.io-root/pr/ 2>/dev/null; then + echo "No pr/ directory found in S3, no cleanup needed" + exit 0 + fi + + S3_PREVIEWS=$(aws s3 ls s3://docs.mojaloop.io-root/pr/ 2>/dev/null | grep '^[[:space:]]*PRE [0-9]' | awk '{print $2}' | sed 's/\///') + + if [ -z "$S3_PREVIEWS" ]; then + echo "No PR previews found in S3" + exit 0 + fi + + echo "Found PR preview directories: $S3_PREVIEWS" + + # Clean up previews for PRs that are not in the open list + echo "$S3_PREVIEWS" | while IFS= read -r pr_number; do + # Skip if PR number is empty + if [ -z "$pr_number" ]; then + echo "Skipping empty PR number" + continue + fi + + # Check if this PR is still open + if echo "$OPEN_PR_NUMBERS" | grep -q "^${pr_number}$"; then + echo "PR #$pr_number is still open, skipping cleanup" + continue + fi + + echo "PR #$pr_number is not open, cleaning up preview..." + if aws s3 rm s3://docs.mojaloop.io-root/pr/${pr_number} --recursive; then + echo "Cleanup completed for PR #$pr_number" + else + echo "Warning: Failed to cleanup PR #$pr_number" + fi + done + + echo "PR preview cleanup completed" + + # When a new tag is pushed, create a new version of docs + # and push it to master to be uploaded + bump_version: + executor: default-docker + steps: + - checkout + - run: + name: Install general dependencies + command: *defaults_Dependencies + - run: + <<: *defaults_configure_nvm + - run: + name: Configure git + command: | + git config user.email ${GIT_CI_EMAIL} + git config user.name ${GIT_CI_USER} + git checkout master - restore_cache: keys: - - build-cache-{{ .Revision }} + - build-legacy-cache-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }} - run: - <<: *defaults_git_identity_setup + name: create a new version in website/versioned_docs + command: | + npm ci + ./node_modules/.bin/vuepress version docs $CIRCLE_TAG - run: - <<: *defaults_publish_to_gh_pages + name: Configure ssh + command: | + mkdir -p ~/.ssh + ssh-keyscan -p 443 ssh.github.com >> ~/.ssh/known_hosts + ssh-keyscan github.com >> ~/.ssh/known_hosts - run: - <<: *defaults_slack_announcement + name: Commit and push the release + command: | + git add . + git commit -anm "chore(ci): release $CIRCLE_TAG" + git push -u origin master +## +# Workflows +# +# CircleCI Workflow config +## workflows: version: 2 build_and_test: + when: + not: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: - - setup: + - build: context: org-global filters: tags: only: /.*/ - branches: - ignore: - - /feature.*/ - - /bugfix.*/ - - gh-pages - - build: + + - build-legacy: context: org-global - requires: - - setup filters: tags: only: /.*/ + + - test-puml: + context: org-global + filters: + tags: + only: /.*/ + + - infra: + context: org-global + requires: + - build + - build-legacy + - test-puml + + - s3_upload: + context: org-global + requires: + - infra + filters: branches: - ignore: - - /feature.*/ - - /bugfix.*/ - - gh-pages - - deploy: + only: + - master + + - bump_version: context: org-global requires: - build + - build-legacy filters: - tags: - only: /v[0-9]+(\.[0-9]+)*/ branches: ignore: - /.*/ + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + + - deploy_pr_preview: + context: org-global + requires: + - infra + filters: + branches: + ignore: /master|main/ + + scheduled_cleanup: + when: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + jobs: + - cleanup_pr_preview: + context: org-global diff --git a/.gitignore b/.gitignore index 5f1920278..5bca1818b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,23 @@ -# --------------- # -# IntelliJ # -# --------------- # -.idea/ -**/*.iml - -# VSCode directory -.vscode - -# Node +build +.terraform +pids +logs node_modules - -# Gitbook -_book - -# Gitbook UML -**/uml - -# MacOs +npm-debug.log +coverage/ +run +dist .DS_Store +.nyc_output +.basement +config.local.js +basement_dist -*.log +# https://devspace.sh/ +devspace* +.devspace/**.* -*.jar +# Add ignores +*IGNORE* +*ignore* +!.npmignore diff --git a/.husky/post-commit b/.husky/post-commit new file mode 100755 index 000000000..3c7606197 --- /dev/null +++ b/.husky/post-commit @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +# . "$(dirname -- "$0")/_/husky.sh" + +echo "Running post-commit hooks..." + +git update-index --again diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..26069c529 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,8 @@ +# #!/usr/bin/env sh +# . "$(dirname -- "$0")/_/husky.sh" + +echo "Running pre-commit hooks..." + +npm run dep:check + +npm run build:plantuml:diff diff --git a/.ncurc.yaml b/.ncurc.yaml new file mode 100644 index 000000000..3cbc122a5 --- /dev/null +++ b/.ncurc.yaml @@ -0,0 +1,3 @@ +## Add a TODO comment indicating the reason for each rejected dependency upgrade added to this list, and what should be done to resolve it (i.e. handle it through a story, etc). +reject: [ +] diff --git a/.nvmrc b/.nvmrc index 70324da03..dc5620acb 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v10.15.1 +22.15.0 \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS index a66aed9b9..b1e397e9c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,7 +6,7 @@ ## @global-owner1 and @global-owner2 will be requested for ## review when someone opens a pull request. #* @global-owner1 @global-owner2 -* @millerabel @mdebarros @kjw000 @elnyry @NicoDuvenage +* @bushjames @elnyry-sam-k @kjw000 @millerabel @PaulMakinMojaloop @simeonoriko @vijayg10 @shashi165 @JulieG19 ## Order is important; the last matching pattern takes the most ## precedence. When someone opens a pull request that only diff --git a/LICENSE.md b/LICENSE.md index 91650b194..432308c9a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,10 +1,10 @@ # LICENSE -Copyright © 2017 Bill & Melinda Gates Foundation +Copyright © 2021 Mojaloop Foundation -The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 -(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). You may obtain a copy of the License at +The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 +(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). -[http://www.apache.org/licenses/LICENSE-2.0]() +You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/README.md b/README.md index a7a7247cb..e9b5364fc 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,145 @@ -# Mojaloop Overview -[![Git Commit](https://img.shields.io/github/last-commit/mojaloop/documentation.svg?style=flat)](https://github.com/mojaloop/documentation/commits/master) -[![Git Releases](https://img.shields.io/github/release/mojaloop/documentation.svg?style=flat)](https://github.com/mojaloop/documentation/releases) -[![CircleCI](https://circleci.com/gh/mojaloop/documentation.svg?style=svg)](https://circleci.com/gh/mojaloop/documentation) +# Mojaloop Documentation -Mojaloop is open source software for creating digital payments platforms that connect all customers, merchants, banks, and other financial providers in a country's economy. Rather than a financial product or application in itself, Mojaloop establishes a blueprint for technology that bridges all the financial products and applications in any given market. +> This is the official documentation for the Mojaloop project. -The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers \(DFSPs\) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. +__Published at: [docs.mojaloop.io](https://docs.mojaloop.io)__ -![Mojaloop Solution](./mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg) -Our model addresses these issues in several key ways: +## Building and testing locally -* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. -* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. -* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. +```bash -The intention for the Mojaloop project is for financial institutions and commercial providers to use the open-source software to help build digital, interoperable payments platforms that drive financial inclusion on a national scale. Specifically, the platforms will enable seamless, low-cost transactions between individual users, merchants, banks, providers, and even government offices - helping connect poor customers with everyone else in the digital economy. +# install npm dependencies +npm ci + +# run the local server +npm run dev +``` + +## Building the project +Run `npm run build` to build the project to render the static vuepress site for a deployment. + + +## Rebuild all Puml -> svg + +For consistent rending of sequence diagrams, we build the .puml sources to .svgs using the following script. + +This script requires docker to be installed and running, since it uses a docker container to run the plantuml server. + +```bash +# render all plantuml sources to svg files deterministically +./scripts/_build_plantuml.sh + +# render just one file at a time, e.g. `figure1.plantuml` +PUML_MATCH="figure1.plantuml" +./scripts/_build_plantuml.sh +``` + +This also ensures that the sequence diagrams are easily readable inline in markdown documents. + +This script also runs as a git commit hook, so any changes added to puml sources are automatically +rendered to svg without you having to do anything! + +If you want to skip the commit hook, you can always run `git commit -n` +## Versioning + +We use `vuepress-plugin-versioning` to help us keep older versions of our docs for posterity. By default, when you browse +the docs, you see the _latest published version_. Pending changes in the main/master branch are viewable under the versioning +tab in the top navigation bar. + +See [https://titanium-docs-devkit.netlify.app/guide/versioning.html](https://titanium-docs-devkit.netlify.app/guide/versioning.html) for more information on the plugin. + +We are working to automate this process, but for now, you can make a new version of the docs with the following: + +```bash +./node_modules/.bin/vuepress version docs +``` + +> Known issue: sidebar not appearing in older versions +> Go to `./website/versioned_docs//sidebar.config.json` +> And remove the `/next` at the start of each entry + +### Deploying Manually + +You can also deploy them manually, by running: +```bash +./scripts/_deploy_preview_s3.sh +``` + +Note that you need to have the `aws` cli, AWS access, and `aws-mfa` set up on your machine for this to work. + +## PR Preview System + +The documentation site includes an automated PR preview system that creates a live preview of documentation changes for each pull request. Here's how it works: + +### Key Components + +1. **CircleCI Configuration** (`.circleci/config.yml`): + - `deploy_pr_preview` job: Handles PR preview deployment + - `cleanup_pr_preview` job: Cleans up old PR previews + - Enforces a limit on the number of concurrent previews + +2. **Deployment Script** (`scripts/_deploy_preview_s3.sh`): + - Builds the documentation site with PR preview environment variables + - Uploads to S3 under the `/pr/{PR_NUMBER}/` path + - Sets appropriate permissions and headers + +3. **CloudFront Configuration** (`infra/src/cloudfront.tf`): + - Serves PR previews from the S3 bucket + - Handles directory indexes via CloudFront function + - Manages caching and routing + +4. **CloudFront Function** (`infra/src/redirect/index.js`): + - Handles directory index requests (e.g., `/pr/123/` → `/pr/123/index.html`) + - Manages legacy URL redirects + +5. **Preview Banner** (`docs/.vuepress/theme/components/PreviewBanner.vue`): + - Displays a prominent banner at the top of PR preview pages + - Shows PR number and links to the GitHub PR + - Automatically adjusts navbar height to accommodate the banner + +### How to Use + +1. Create a pull request against the main branch +2. CircleCI will automatically: + - Build the documentation with PR preview mode enabled + - Deploy to a preview URL: `https://docs.mojaloop.io/pr/{PR_NUMBER}` + - Comment on the PR with the preview URL +3. Preview will be automatically cleaned up when the PR is closed + +### Preview Limits + +- Maximum of 10 concurrent previews +- Previews are automatically cleaned up after PR closure +- Existing previews are updated when new commits are pushed + +### Testing Locally + +To test the PR preview system locally: + +```bash +# Run with PR preview mode enabled +VUEPRESS_IS_PR=true VUEPRESS_PR_NUMBER=123 npm run dev +``` + +This will: +- Show the PR preview banner +- Adjust the navbar height automatically +- Display the PR number and link to GitHub + +### Troubleshooting + +If a preview isn't working: +1. Check the CircleCI build logs for deployment issues +2. Verify the PR number is correctly extracted +3. Ensure the CloudFront function is properly handling directory indexes +4. Check S3 for the presence of files at `/pr/{PR_NUMBER}/` +5. Verify environment variables are set correctly in the build process + +## Contributing to the project +Please refer to the [Contributing Guide](./contributing-guide.md) for details on how to contribute to Mojaloop Docs 2.0. + +## License + +Apache License. Version 2.0 +See [`./license`](./LICENSE.md) for more information. diff --git a/SUMMARY.md b/SUMMARY.md deleted file mode 100644 index 70f4ecb62..000000000 --- a/SUMMARY.md +++ /dev/null @@ -1,142 +0,0 @@ -# Table of contents - -* [Mojaloop Overview](README.md) -* [Mojaloop Background](mojaloop-background/README.md) - * [Core Scenarios](mojaloop-background/core-scenarios.md) - * [Level One Principles](mojaloop-background/level-one-principles.md) -* [Onboarding](onboarding.md) -* [Deployment Guide](deployment-guide/README.md) - * [Releases](deployment-guide/releases.md) - * [Local Setup Linux](deployment-guide/local-setup-linux.md) - * [Local Setup Mac](deployment-guide/local-setup-mac.md) - * [Local Setup Windows](deployment-guide/local-setup-windows.md) - * [Troubleshooting](deployment-guide/deployment-troubleshooting.md) -* [Contributors Guide](contributors-guide/README.md) - * [Standards](contributors-guide/standards/README.md) - * [Versioning](contributors-guide/standards/versioning.md) - * [Creating new Features](contributors-guide/standards/creating-new-features.md) - * [ML OSS Bug Triage](contributors-guide/standards/triaging-ml-oss-bugs.md) - * [Tools and Technologies](contributors-guide/tools-and-technologies/README.md) - * [Pragmatic REST](contributors-guide/tools-and-technologies/pragmatic-rest.md) - * [Code Quality Metrics](contributors-guide/tools-and-technologies/code-quality-metrics.md) - * [Automated Testing](contributors-guide/tools-and-technologies/automated-testing.md) - * [Documentation](contributors-guide/documentation/README.md) - * [API Documentation](contributors-guide/documentation/api-documentation.md) - * [Documentation Style Guide](contributors-guide/documentation/documentation-style-guide.md) -* [Mojaloop Technical Overview](mojaloop-technical-overview/README.md) - * [Mojaloop Hub](mojaloop-technical-overview/overview/README.md) - * [Current Architecture - PI8](mojaloop-technical-overview/overview/components-PI8.md) - * [Legacy Architecture - PI7](mojaloop-technical-overview/overview/components-PI7.md) - * [Legacy Architecture - PI6](mojaloop-technical-overview/overview/components-PI6.md) - * [Legacy Architecture - PI5](mojaloop-technical-overview/overview/components-PI5.md) - * [Legacy Architecture - PI3](mojaloop-technical-overview/overview/components-PI3.md) - * [Account-Lookup Service](mojaloop-technical-overview/account-lookup-service/README.md) - * [GET Participants](mojaloop-technical-overview/account-lookup-service/als-get-participants.md) - * [POST Participants](mojaloop-technical-overview/account-lookup-service/als-post-participants.md) - * [POST Participants (batch)](mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md) - * [DEL Participants](mojaloop-technical-overview/account-lookup-service/als-del-participants.md) - * [GET Parties](mojaloop-technical-overview/account-lookup-service/als-get-parties.md) - * [Quoting Service](mojaloop-technical-overview/quoting-service/README.md) - * [Central-Ledger Services](mojaloop-technical-overview/central-ledger/README.md) - * [Admin Operations](mojaloop-technical-overview/central-ledger/admin-operations/README.md) - * [POST Participant Limit](mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md) - * [GET Participant Limit Details](mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md) - * [GET All Participant Limits](mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md) - * [POST Participant limits](mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md) - * [GET Transfer Status](mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md) - * [POST Participant Callback](mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) - * [GET Participant Callback](mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md) - * [GET Participant Position](mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md) - * [GET All Participants Positions](mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md) - * [Transfer Operations](mojaloop-technical-overview/central-ledger/transfers/README.md) - * [Prepare Handler](mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md) - * [Prepare Handler Consume (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md) - * [Prepare Handler Consume (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md) - * [Prepare Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md) - * [Prepare Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md) - * [Position Handler Consume (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md) - * [Position Handler Consume (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md) - * [Fulfil Handler](mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md) - * [Fulfil Handler Consume](mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md) - * [Fulfil Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md) - * [Fulfil Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md) - * [Fulfil Reject Transfer](mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md) - * [Fulfil Reject Transfer (a)](mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md) - * [Fulfil Handler (Reject-Abort)](mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md) - * [Notifications]() - * [Notification to Participant (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md) - * [Notification to Participant (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md) - * [Reject/Abort]() - * [Abort Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md) - * [Timeout]() - * [Transfer Timeout](mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md) - * [Timeout Handler Consume](mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md) - * [Bulk Transfer Operations](mojaloop-technical-overview/central-bulk-transfers/README.md) - * [Bulk Prepare Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md) - * [Bulk Prepare Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md) - * [Prepare Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md) - * [Position Handler Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md) - * [Prepare Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md) - * [Fulfil Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md) - * [Fulfil Abort Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md) - * [Bulk Fulfil Handler Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md) - * [Bulk Fulfil Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md) - * [Fulfil Handler - Commit](mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md) - * [Fulfil Handler - Reject/Abort](mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md) - * [Bulk Processing Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md) - * [Notifications]() - * [Notification to Participant (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md) - * [Notification to Participant (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md) - * [Timeout Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md) - * [Timeout Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md) - * [Central-Settlements Service](mojaloop-technical-overview/central-settlements/README.md) - * [Settlement Process](mojaloop-technical-overview/central-settlements/settlement-process/README.md) - * [Settlement Windows By Params](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md) - * [Request Settlement Window](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md) - * [Close Settlement Window](mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md) - * [Create Settlement](mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md) - * [Request Settlement](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md) - * [Settlement Transfer Acknowledgement](mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md) - * [Settlement Abort](mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md) - * [Request Settlement By SPA](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md) - * [Request Settlements By Params](mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md) - * [Funds In/Out](mojaloop-technical-overview/central-settlements/funds-in-out/README.md) - * [Reconciliation Transfer Prepare](mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md) - * [Transfer State and Position Change](mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md) - * [Funds In](mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md) - * [Funds Out - Prepare & Reserve](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md) - * [Funds Out - Commit](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md) - * [Funds Out - Abort](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md) - * [OSS Settlement FSD](mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md) - * [Central-Event-Processor Services](mojaloop-technical-overview/central-event-processor/README.md) - * [Event Handler (Placeholder)](mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md) - * [Notification Handler For Rejections](mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md) - * [Signature Validation](mojaloop-technical-overview/central-event-processor/signature-validation.md) - * [Event Framework](mojaloop-technical-overview/event-framework/README.md) - * [Event Stream Processor](mojaloop-technical-overview/event-stream-processor/README.md) - * [Fraud Services](mojaloop-technical-overview/fraud-services/README.md) - * [Ecosystem Fraud Documentation](mojaloop-technical-overview/fraud-services/related-documents/documentation.md) - * [SDK Scheme Adapter](mojaloop-technical-overview/sdk-scheme-adapter/README.md) - * [Usage](mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md) - * [Scheme Adapter to Scheme Adapter](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md) - * [Scheme Adapter to Local ML Cluster](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md) - * [Scheme Adapter to WSO2 API Gateway](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md) -* [API Specifications](api/README.md) - * [Mojaloop](api/mojaloop-api-specification.md) - * [Central Ledger API](api/central-ledger-api-specification.md) - * [Central Settlements](api/central-settlements-api-specification.md) - * [ALS Oracle](api/als-oracle-api-specification.md) -* [Repo Details](repositories/README.md) - * [Helm](repositories/helm.md) - * [Project](repositories/project.md) -* [Mojaloop Roadmap](mojaloop-roadmap.md) -* [Mojaloop Publications](mojaloop-publications.md) -* [Discussion Documents](discussions/readme.md) - * [ISO integration Overivew](discussions/ISO_Integration.md) - * [Moajoop Decimal Type; Based on XML Schema Decimal Type](discussions/decimal.md) - * [Workbench Workstream](discussions/workbench.md) - * [Cross Border Meeting Notes Day 1](discussions/cross_border_day_1.md) - * [Cross Border Meeting Notes Day 2](discussions/cross_border_day_2.md) -* [Frequently Asked Questions](contributors-guide/frequently-asked-questions.md) -* [Glossary of Terms](glossary.md) - diff --git a/api/assets/interface-contracts/oracle-service-swagger-v1.yaml b/api/assets/interface-contracts/oracle-service-swagger-v1.yaml deleted file mode 100644 index ec3c98087..000000000 --- a/api/assets/interface-contracts/oracle-service-swagger-v1.yaml +++ /dev/null @@ -1,952 +0,0 @@ -swagger: '2.0' -info: - version: '1.2' - title: Interface for interaction between Mojaloop's Account Lookup Service(ALS) and an Oracle Registry Service - description: Based on Mojaloop [API Definition](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) updated on 2018-03-13 Version 1.0. More information can be found are [mojaloop.io](http://mojaloop.io/) - contact: {} -basePath: / -schemes: [] -consumes: - - application/json -produces: - - application/json -paths: - /participants/{Type}/{ID}: - get: - description: The HTTP request GET /participants/{Type}/{ID} is used to find out in which FSP the requested Party, defined by {Type} and {ID} is located (for example, GET /participants/MSISDN/123456789). This HTTP request should support a query string to filter FSP information regarding a specific currency only (This similarly applies to the SubId). To query a specific currency only, the HTTP request GET /participants/{Type}/{ID}?currency=XYZ should be used, where XYZ is the requested currency. Note - Both the currency and the SubId can be used mutually inclusive or exclusive - summary: Look up participant information - tags: - - participants - operationId: ParticipantsByTypeAndIDGet - deprecated: false - produces: - - application/json - parameters: - - name: accept - in: header - required: true - type: string - description: The Accept header field indicates the version of the API the client would like the server to use. - - name: Type - in: path - required: true - type: string - description: The type of lookup being requested, this can be MSISDN, bankAccount etc. - - name: ID - in: path - required: true - type: string - description: The ID related to the Type, if MSISDN then this is the mobile number being requested - - name: Currency - in: query - required: false - type: string - description: The Currency code applicable to the ID being requested - - name: SubId - in: query - required: false - type: string - description: The SubId related to the ID, or the Type - - name: content-type - in: header - required: true - type: string - description: The Content-Type header indicates the specific version of the API used to send the payload body. - - name: date - in: header - required: true - type: string - description: The Date header field indicates the date when the request was sent. - - name: fspiop-source - in: header - required: true - type: string - description: The FSPIOP-Source header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field FSPIOP-Signature). - - name: x-forwarded-for - in: header - required: false - type: string - description: The X-Forwarded-For header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple X-Forwarded-For values as in the example shown here should be expected and supported by implementers of the API. Note - An alternative to X-Forwarded-For is defined in RFC 7239. However, to this point RFC 7239 is less-used and supported than X-Forwarded-For. - - name: fspiop-destination - in: header - required: false - type: string - description: The FSPIOP-Destination header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field should be set by the original sender of the request (if known), so that any entities between the client and the server do not need to parse the payload for routing purposes. - - name: fspiop-encryption - in: header - required: false - type: string - description: The FSPIOP-Encryption header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. - - name: fspiop-signature - in: header - required: false - type: string - description: The FSPIOP-Signature header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. - - name: fspiop-uri - in: header - required: false - type: string - description: The FSPIOP-URI header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see API Signature document. - - name: fspiop-http-method - in: header - required: false - type: string - description: The FSPIOP-HTTP-Method header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature document. - responses: - 200: - description: OK - schema: - $ref: '#/definitions/ParticipantsTypeIDGetResponse' - headers: - Content-Length: - type: string - 400: - description: Bad Request - The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 401: - description: Unauthorized - The request requires authentication in order to be processed. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 403: - description: Forbidden - The request was denied and will be denied in the future. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 404: - description: Not Found - The resource specified in the URI was not found. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 405: - description: Method Not Allowed - An unsupported HTTP method for the request was used. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 406: - description: Not acceptable - The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 501: - description: Not Implemented - The server does not support the requested service. The client should not retry. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 503: - description: Service Unavailable - The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame. - schema: - $ref: '#/definitions/ErrorInformationResponse' - put: - description: The PUT /participants/{Type}/{ID} is used to update information in the server regarding the provided identity, defined by {Type} and {ID} (for example, PUT /participants/MSISDN/123456789). - summary: Return participant information - tags: - - participants - operationId: ParticipantsByTypeAndIDPut - deprecated: false - produces: - - application/json - parameters: - - name: Type - in: path - required: true - type: string - description: The type of lookup being requested, this can be MSISDN, bankAccount etc. - - name: ID - in: path - required: true - type: string - description: The ID related to the Type, if MSISDN then this is the mobile number being requested - - name: content-type - in: header - required: true - type: string - description: The Content-Type header indicates the specific version of the API used to send the payload body. - - name: date - in: header - required: true - type: string - description: The Date header field indicates the date when the request was sent. - - name: fspiop-source - in: header - required: true - type: string - description: The FSPIOP-Source header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field FSPIOP-Signature). - - name: body - in: body - required: true - description: '' - schema: - $ref: '#/definitions/ParticipantsTypeIDPutRequest' - - name: accept - in: header - required: false - type: string - description: The Accept header field indicates the version of the API the client would like the server to use. - - name: x-forwarded-for - in: header - required: false - type: string - description: The X-Forwarded-For header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple X-Forwarded-For values as in the example shown here should be expected and supported by implementers of the API. Note - An alternative to X-Forwarded-For is defined in RFC 7239. However, to this point RFC 7239 is less-used and supported than X-Forwarded-For. - - name: fspiop-destination - in: header - required: false - type: string - description: The FSPIOP-Destination header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field should be set by the original sender of the request (if known), so that any entities between the client and the server do not need to parse the payload for routing purposes. - - name: fspiop-encryption - in: header - required: false - type: string - description: The FSPIOP-Encryption header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. - - name: fspiop-signature - in: header - required: false - type: string - description: The FSPIOP-Signature header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. - - name: fspiop-uri - in: header - required: false - type: string - description: The FSPIOP-URI header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see API Signature document. - - name: fspiop-http-method - in: header - required: false - type: string - description: The FSPIOP-HTTP-Method header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature document. - - name: content-length - in: header - required: false - type: integer - format: int32 - exclusiveMaximum: false - exclusiveMinimum: false - description: The Content-Length header field indicates the anticipated size of the payload body. Only sent if there is a body. Note - The API supports a maximum size of 5242880 bytes (5 Megabytes) - responses: - 204: - description: No Content - headers: {} - 400: - description: Bad Request - The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 401: - description: Unauthorized - The request requires authentication in order to be processed. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 403: - description: Forbidden - The request was denied and will be denied in the future. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 404: - description: Not Found - The resource specified in the URI was not found. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 405: - description: Method Not Allowed - An unsupported HTTP method for the request was used. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 406: - description: Not acceptable - The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 501: - description: Not Implemented - The server does not support the requested service. The client should not retry. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 503: - description: Service Unavailable - The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame. - schema: - $ref: '#/definitions/ErrorInformationResponse' - post: - description: The HTTP request POST /participants/{Type}/{ID} is used to create information in the server regarding the provided identity, defined by {Type} and {ID} (for example, POST /participants/MSISDN/123456789). - summary: Create participant information - tags: - - participants - operationId: ParticipantsByTypeAndIDPost - deprecated: false - produces: - - application/json - parameters: - - name: accept - in: header - required: true - type: string - description: The Accept header field indicates the version of the API the client would like the server to use. - - name: Type - in: path - required: true - type: string - description: The type of lookup being requested, this can be MSISDN, bankAccount etc. - - name: ID - in: path - required: true - type: string - description: The ID related to the Type, if MSISDN then this is the mobile number being requested - - name: content-type - in: header - required: true - type: string - description: The Content-Type header indicates the specific version of the API used to send the payload body. - - name: date - in: header - required: true - type: string - description: The Date header field indicates the date when the request was sent. - - name: fspiop-source - in: header - required: true - type: string - description: The FSPIOP-Source header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field FSPIOP-Signature). - - name: body - in: body - required: true - description: '' - schema: - $ref: '#/definitions/ParticipantsTypeIDPutRequest' - - name: x-forwarded-for - in: header - required: false - type: string - description: The X-Forwarded-For header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple X-Forwarded-For values as in the example shown here should be expected and supported by implementers of the API. Note - An alternative to X-Forwarded-For is defined in RFC 7239. However, to this point RFC 7239 is less-used and supported than X-Forwarded-For. - - name: fspiop-destination - in: header - required: false - type: string - description: The FSPIOP-Destination header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field should be set by the original sender of the request (if known), so that any entities between the client and the server do not need to parse the payload for routing purposes. - - name: fspiop-encryption - in: header - required: false - type: string - description: The FSPIOP-Encryption header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. - - name: fspiop-signature - in: header - required: false - type: string - description: The FSPIOP-Signature header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. - - name: fspiop-uri - in: header - required: false - type: string - description: The FSPIOP-URI header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see API Signature document. - - name: fspiop-http-method - in: header - required: false - type: string - description: The FSPIOP-HTTP-Method header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature document. - - name: content-length - in: header - required: false - type: integer - format: int32 - exclusiveMaximum: false - exclusiveMinimum: false - description: The Content-Length header field indicates the anticipated size of the payload body. Only sent if there is a body. Note - The API supports a maximum size of 5242880 bytes (5 Megabytes) - responses: - 201: - description: Created - headers: {} - 400: - description: Bad Request - The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 401: - description: Unauthorized - The request requires authentication in order to be processed. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 403: - description: Forbidden - The request was denied and will be denied in the future. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 404: - description: Not Found - The resource specified in the URI was not found. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 405: - description: Method Not Allowed - An unsupported HTTP method for the request was used. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 406: - description: Not acceptable - The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 501: - description: Not Implemented - The server does not support the requested service. The client should not retry. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 503: - description: Service Unavailable - The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame. - schema: - $ref: '#/definitions/ErrorInformationResponse' - delete: - description: The HTTP request DELETE /participants/{Type}/{ID} is used to delete information in the server regarding the provided identity, defined by {Type} and {ID}) (for example, DELETE /participants/MSISDN/123456789). This HTTP request should support a query string to delete FSP information regarding a specific currency only (This similarly applies to the SubId). To delete a specific currency only, the HTTP request DELETE /participants/{Type}/{ID}?currency=XYZ should be used, where XYZ is the requested currency. Note - Both the currency and the SubId can be used mutually inclusive or exclusive - summary: Delete participant information - tags: - - participants - operationId: ParticipantsByTypeAndIDDelete - deprecated: false - produces: - - application/json - parameters: - - name: accept - in: header - required: true - type: string - description: The Accept header field indicates the version of the API the client would like the server to use. - - name: Type - in: path - required: true - type: string - description: The type of lookup being requested, this can be MSISDN, bankAccount etc. - - name: ID - in: path - required: true - type: string - description: The ID related to the Type, if MSISDN then this is the mobile number being requested - - name: Currency - in: query - required: false - type: string - description: The Currency code applicable to the ID being requested - - name: SubId - in: query - required: false - type: string - description: The SubId related to the ID, or the Type - - name: content-type - in: header - required: true - type: string - description: The Content-Type header indicates the specific version of the API used to send the payload body. - - name: date - in: header - required: true - type: string - description: The Date header field indicates the date when the request was sent. - - name: fspiop-source - in: header - required: true - type: string - description: The FSPIOP-Source header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field FSPIOP-Signature). - - name: x-forwarded-for - in: header - required: false - type: string - description: The X-Forwarded-For header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple X-Forwarded-For values as in the example shown here should be expected and supported by implementers of the API. Note - An alternative to X-Forwarded-For is defined in RFC 7239. However, to this point RFC 7239 is less-used and supported than X-Forwarded-For. - - name: fspiop-destination - in: header - required: false - type: string - description: The FSPIOP-Destination header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field should be set by the original sender of the request (if known), so that any entities between the client and the server do not need to parse the payload for routing purposes. - - name: fspiop-encryption - in: header - required: false - type: string - description: The FSPIOP-Encryption header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. - - name: fspiop-signature - in: header - required: false - type: string - description: The FSPIOP-Signature header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. - - name: fspiop-uri - in: header - required: false - type: string - description: The FSPIOP-URI header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see API Signature document. - - name: fspiop-http-method - in: header - required: false - type: string - description: The FSPIOP-HTTP-Method header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature document. - responses: - 204: - description: No Content - headers: {} - 400: - description: Bad Request - The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 401: - description: Unauthorized - The request requires authentication in order to be processed. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 403: - description: Forbidden - The request was denied and will be denied in the future. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 404: - description: Not Found - The resource specified in the URI was not found. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 405: - description: Method Not Allowed - An unsupported HTTP method for the request was used. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 406: - description: Not acceptable - The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 501: - description: Not Implemented - The server does not support the requested service. The client should not retry. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 503: - description: Service Unavailable - The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame. - schema: - $ref: '#/definitions/ErrorInformationResponse' - /participants: - post: - description: The HTTP request POST /participants is used to create information in the server regarding the provided list of identities. This request should be used for bulk creation of FSP information for more than one Party. The optional currency parameter should indicate that each provided Party supports the currency - summary: Batch create participant information #fail these as a batch or accept it as a batch - tags: - - participants - operationId: ParticipantsPost - deprecated: false - produces: - - application/json - parameters: - - name: accept - in: header - required: true - type: string - description: The Accept header field indicates the version of the API the client would like the server to use. - - name: content-type - in: header - required: true - type: string - description: The Content-Type header indicates the specific version of the API used to send the payload body. - - name: date - in: header - required: true - type: string - description: The Date header field indicates the date when the request was sent. - - name: fspiop-source - in: header - required: true - type: string - description: The FSPIOP-Source header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field FSPIOP-Signature). - - name: body - in: body - required: true - description: '' - schema: - $ref: '#/definitions/ParticipantsPostRequest' - - name: content-length - in: header - required: false - type: integer - format: int32 - exclusiveMaximum: false - exclusiveMinimum: false - description: The Content-Length header field indicates the anticipated size of the payload body. Only sent if there is a body. Note - The API supports a maximum size of 5242880 bytes (5 Megabytes) - - name: x-forwarded-for - in: header - required: false - type: string - description: The X-Forwarded-For header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple X-Forwarded-For values as in the example shown here should be expected and supported by implementers of the API. Note - An alternative to X-Forwarded-For is defined in RFC 7239. However, to this point RFC 7239 is less-used and supported than X-Forwarded-For. - - name: fspiop-destination - in: header - required: false - type: string - description: The FSPIOP-Destination header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field should be set by the original sender of the request (if known), so that any entities between the client and the server do not need to parse the payload for routing purposes. - - name: fspiop-encryption - in: header - required: false - type: string - description: The FSPIOP-Encryption header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. - - name: fspiop-signature - in: header - required: false - type: string - description: The FSPIOP-Signature header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. - - name: fspiop-uri - in: header - required: false - type: string - description: The FSPIOP-URI header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see API Signature document. - - name: fspiop-http-method - in: header - required: false - type: string - description: The FSPIOP-HTTP-Method header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature document. - responses: - 201: - description: Created - headers: {} - schema: - $ref: '#/definitions/ParticipantsIDPutResponse' - 400: - description: Bad Request - The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 401: - description: Unauthorized - The request requires authentication in order to be processed. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 403: - description: Forbidden - The request was denied and will be denied in the future. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 404: - description: Not Found - The resource specified in the URI was not found. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 405: - description: Method Not Allowed - An unsupported HTTP method for the request was used. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 406: - description: Not acceptable - The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 501: - description: Not Implemented - The server does not support the requested service. The client should not retry. - schema: - $ref: '#/definitions/ErrorInformationResponse' - 503: - description: Service Unavailable - The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame. - schema: - $ref: '#/definitions/ErrorInformationResponse' -definitions: - CurrencyEnum: - title: CurrencyEnum - description: The currency codes defined in ISO 4217 as three-letter alphabetic codes are used as the standard naming representation for currencies. - example: AED - type: string - enum: - - AED - - AFN - - ALL - - AMD - - ANG - - AOA - - ARS - - AUD - - AWG - - AZN - - BAM - - BBD - - BDT - - BGN - - BHD - - BIF - - BMD - - BND - - BOB - - BRL - - BSD - - BTN - - BWP - - BYN - - BZD - - CAD - - CDF - - CHF - - CLP - - CNY - - COP - - CRC - - CUC - - CUP - - CVE - - CZK - - DJF - - DKK - - DOP - - DZD - - EGP - - ERN - - ETB - - EUR - - FJD - - FKP - - GBP - - GEL - - GGP - - GHS - - GIP - - GMD - - GNF - - GTQ - - GYD - - HKD - - HNL - - HRK - - HTG - - HUF - - IDR - - ILS - - IMP - - INR - - IQD - - IRR - - ISK - - JEP - - JMD - - JOD - - JPY - - KES - - KGS - - KHR - - KMF - - KPW - - KRW - - KWD - - KYD - - KZT - - LAK - - LBP - - LKR - - LRD - - LSL - - LYD - - MAD - - MDL - - MGA - - MKD - - MMK - - MNT - - MOP - - MRO - - MUR - - MVR - - MWK - - MXN - - MYR - - MZN - - NAD - - NGN - - NIO - - NOK - - NPR - - NZD - - OMR - - PAB - - PEN - - PGK - - PHP - - PKR - - PLN - - PYG - - QAR - - RON - - RSD - - RUB - - RWF - - SAR - - SBD - - SCR - - SDG - - SEK - - SGD - - SHP - - SLL - - SOS - - SPL - - SRD - - STD - - SVC - - SYP - - SZL - - THB - - TJS - - TMT - - TND - - TOP - - TRY - - TTD - - TVD - - TWD - - TZS - - UAH - - UGX - - USD - - UYU - - UZS - - VEF - - VND - - VUV - - WST - - XAF - - XCD - - XDR - - XOF - - XPF - - YER - - ZAR - - ZMW - - ZWD - PartyIdTypeEnum: - title: PartyIdTypeEnum - description: Below are the allowed values for the enumeration - MSISDN An MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. - EMAIL An email is used as reference to a participant. The format of the email should be according to the informational RFC 3696. - PERSONAL_ID A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element. - BUSINESS A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. - DEVICE A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element. - ACCOUNT_ID A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. - IBAN A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. - ALIAS An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. - example: MSISDN - type: string - enum: - - MSISDN - - EMAIL - - PERSONAL_ID - - BUSINESS - - DEVICE - - ACCOUNT_ID - - IBAN - - ALIAS - ErrorInformation: - title: ErrorInformation - description: Data model for the complex type ErrorInformation. - type: object - properties: - errorCode: - description: Specific error number. - type: string - errorDescription: - description: Error description string. - type: string - extensionList: - $ref: '#/definitions/ExtensionList' - required: - - errorCode - - errorDescription - ErrorInformationResponse: - title: ErrorInformationResponse - description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. - type: object - properties: - errorInformation: - $ref: '#/definitions/ErrorInformation' - Extension: - title: Extension - description: Data model for the complex type Extension - type: object - properties: - key: - description: Extension key. - type: string - value: - description: Extension value. - type: string - required: - - key - - value - ExtensionList: - title: ExtensionList - description: Data model for the complex type ExtensionList - type: object - properties: - extension: - description: Number of Extension elements - type: array - items: - $ref: '#/definitions/Extension' - minItems: 1 - maxItems: 16 - required: - - extension - ParticipantsTypeIDGetResponse: - title: ParticipantsTypeIDGetResponse - description: OK - type: object - properties: - partyList: - description: List of PartyTypeIdInfo elements that were either created or failed to be created. - type: array - items: - $ref: '#/definitions/PartyTypeIdInfo' - minItems: 1 - maxItems: 10000 - ParticipantsTypeIDPutRequest: - title: ParticipantsTypeIDPutRequest - description: PUT /participants/{Type}/{ID} object - type: object - properties: - fspId: - description: FSP Identifier that the Party belongs to. - type: string - currency: - description: Indicate that the provided Currency was set to be supported by each successfully added PartyIdInfo. - type: string - partySubIdOrType: - description: A sub-identifier or sub-type for the Party. - type: string - required: - - fspId - - currency - ParticipantsPostRequest: - title: ParticipantsPostRequest - description: POST /participants object - type: object - properties: - requestId: - description: The ID of the request, decided by the client. Used for identification of the callback from the server. - type: string - partyList: - description: List of PartyIdInfo elements that the client would like to update or create FSP information about. - type: array - items: - $ref: '#/definitions/PartyIdInfo' - minItems: 1 - maxItems: 10000 - required: - - requestId - - partyList - PartyIdInfo: - title: PartyIdInfo - description: Data model for the complex type PartyIdInfo. - type: object - properties: - partyIdType: - description: Type of the identifier. - type: string - partyIdentifier: - description: An identifier for the Party. - type: string - partySubIdOrType: - description: A sub-identifier or sub-type for the Party. - type: string - fspId: - description: FSP ID - type: string - currency: - description: Indicate that the provided Currency was set to be supported by each successfully added PartyIdInfo. - type: string - required: - - partyIdType - - partyIdentifier - ParticipantsIDPutResponse: - title: ParticipantsIDPutResponse - type: object - description: PUT /participants/{ID} object - properties: - partyList: - type: array - items: - $ref: '#/definitions/PartyResult' - minItems: 1 - maxItems: 10000 - description: List of PartyResult elements that were either created or failed to be created. - required: - - partyList - PartyResult: - title: PartyResult - type: object - description: Data model for the complex type PartyResult. - properties: - partyId: - $ref: '#/definitions/PartyIdInfo' - errorInformation: - $ref: '#/definitions/ErrorInformation' - required: - - partyId - PartyTypeIdInfo: - title: PartyTypeIdInfo - description: Data model for the complex type PartyIdInfo. - type: object - properties: - fspId: - description: FSP ID - type: string - currency: - description: Indicate that the provided Currency was set to be supported by each successfully added PartyIdInfo. - type: string - partySubIdOrType: - description: A sub-identifier or sub-type for the Party. - type: string - required: - - fspId - - currency -tags: - - name: participants - description: '' \ No newline at end of file diff --git a/api/mojaloop-api-specification.md b/api/mojaloop-api-specification.md deleted file mode 100644 index 02bb0694d..000000000 --- a/api/mojaloop-api-specification.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -showToc: false ---- -https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/Supporting%20Files/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/contributing-guide.md b/contributing-guide.md new file mode 100644 index 000000000..6c739d397 --- /dev/null +++ b/contributing-guide.md @@ -0,0 +1,62 @@ +# Mojaloop Docs 2.0 Contributing Guide + +> This README contains guide on contributing to Mojaloop Docs 2.0 - a Vuepress-powered site for Mojaloop documentation. + + +## Getting started +The first step in contributing to the Mojaloop documentation repository is to go through the Contributors guide and the + + +## Setting up locally +Refer to the [README](./README.md#building-and-testing-locally) for guide on how to setup the documentation site locally. + + +## Adding Content +New content added to the documentation should follow the guidelines defined here in additi + +## Creating new pages +TBD + +## Migrating existing pages +While much of the migration is done manually for now, a script will soon be provided to allow you move content from an existing directory to the new documentation site. + + +## Handling Images +TBDD + + +## Documentation Conventions +These are some of the defined conventions that guide contributing to the + +### Folder and Directory Structure +- All top-level documentation pages should be created as folders in the `vuepress/docs` directory. e.g. a `Community` top-level page is created in `vuepress/docs/community/` +- All + +## Assets +- Assets including images for a specific pages should be added to the `/assets/` directory for that page/ +- The naming convention for images (new or existing) added to the `/assets` documentation name should be `-
- + +### Page/Section Headers +As much as is possible, the following should be adhered to when creating headers for pages and sections: + +- Page headers should use sentence case. +- Page headers and section headers should not contain numbers. The previous Mojaloop documentation used numbers as part of page and section headers which resulted in brittle links that were easily broken when content was changed. + + +## Creating a Pull Request +Once you have created content that you are ready, the following steps should be followed to create a new PR: +- Run the `./verify-links` script to ensure that there are no broken links on your page. See [Verifying Page Links](#verifying-page-links) section for more details. +- Check for any typographical errors +- Create a pull request using `master` as the base branch + + + +## Verifying Page Links +Before opening a PR, ensure that all the links on the new page are correct and accessible. While this process is manual for now, a `./verify-links` script will soon be added to the repository that can be run to verify all the links of the page. + + +## Versioning + +TBD + + diff --git a/contributors-guide/README.md b/contributors-guide/README.md deleted file mode 100644 index 8e0ef21cf..000000000 --- a/contributors-guide/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Contributors Guide - -## How do I contribute? - -* Review the [Mojaloop Deployment](../deployment-guide/) Guide and the [Onboarding Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) -* Browse through the [Repository Overview](../repositories/) to understand how the Mojaloop code is managed across multiple Github Repositories -* Get familiar with our [Standards](standards/) on contributing to this project -* Go through the [New Contributor Checklist](./new-contributor-checklist.md), and browse through the project board and work on your [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) -* Review the [Roadmap](../mojaloop-roadmap.md) and contribute to future opportunities - -## What work is needed? - -Work is tracked as issues in the [mojaloop/project](https://github.com/mojaloop/project) repository GitHub. You'll see issues there that are open and marked as bugs, stories, or epics. An epic is larger work that contains multiple stories. Start with any stories that are marked with "[good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)". In addition, anything that is in the backlog and not assigned to someone are things we could use help with. Stories that have owners are in someone's backlog already, though you can always ask about them in the issue or on Slack. - -There's a [roadmap](../mojaloop-roadmap.md) that shows larger work that people could do or are working on. It has some main initiatives and epics and the order, but lacks dates as this work is community driven. Work is broken down from there into issues in GitHub. - -In general, we are looking for example implementations and bug fixes, and project enhancements. - -### Where do I get help? - -Join the [Mojaloop Slack Discussions](https://mojaloop-slack.herokuapp.com/) to connect with other developers. - -Also checkout the [FAQ](https://github.com/mojaloop/documentation/blob/master/contributors-guide/frequently-asked-questions.md) - -### What is the current release? - -See the [Mojaloop Slack Announcements](https://mojaloop.slack.com/messages/CG3MAJZ5J) to find out information on the latest release. - -### What's here and what's not? - -This is free code provided under an [Apache 2.0 license](https://github.com/mojaloop/mojaloop/blob/master/LICENSE.md). - -The code is released with an Apache 2.0 license but the Specification documents under the 'mojaloop-specification' documents are published with CC BY-ND 4.0 License - -We don't provide production servers to run it on. That's up to you. You are free \(and encouraged!\) to clone these repositories, participate in the community of developers, and contribute back to the code. - -We are not trying to replace any mobile wallet or financial providers. We provide code to link together new and existing financial providers using a common scheme. There are central services for identifying a customer's provider, quoting, fulfillment, deferred net settlement, and shared fraud management. Each provider can take advantage of these services to send and receive money with others on the system and there's no cost to them to onboard new providers. We provide code for a simple example mobile money provider to show how integration can be done, but our example DFSP is not meant to be a production mobile money provider. - -## Where do I send bugs, questions, and feedback? - -For bugs, see [Reporting bugs](https://github.com/mojaloop/mojaloop/blob/master/contribute/Reporting-Bugs.md). - -### Related Projects - -The [Interledger Protocol Suite](https://interledger.org/) \(ILP\) is an open and secure standard that enables DFSPs to settle payments with minimal _counter-party risk_ \(the risk you incur when someone else is holding your money\). With ILP, you can transact across different systems with no chance that someone in the middle disappears with your money. Mojaloop uses the Interledger Protocol Suite for the clearing layer. - -## Types of Contributors - -There are three types of contributors that we are targeting for this phase of the Mojaloop project. - -### Developers or General Contributors - -These individuals are those that want to start contributing to the Mojaloop community. This could be a developer or quality assurance person that wants to write new code or fix a bug. This could also be a business, compliance or risk specialist that wants to help provide rules, write documentation or participate in requirements gathering. - -### Hub Operators - -Typically these or organizations or individuals or government agencies that are interested in setting up their own Mojaloop Switch to become part of the ecosystem. - -### Implementation Teams - -Implementation teams can assist banks, government offices, mobile operators or credit unions in deploying Mojaloop. - diff --git a/contributors-guide/new-contributor-checklist.md b/contributors-guide/new-contributor-checklist.md deleted file mode 100644 index a2ea91725..000000000 --- a/contributors-guide/new-contributor-checklist.md +++ /dev/null @@ -1,63 +0,0 @@ -# New Contributor Checklist - -This guide summarizes the steps needed to get up and running as a contributor to Mojaloop. They needn't be completed all in one sitting, but by the end of the checklist, you should have learned a good deal about Mojaloop, and be prepared to contribute to the community. - - -## 1. Tools & Documentation - -- Make sure you have a GitHub account already, or sign up for an account [here](https://github.com/join) - -- Join the slack community at the [self-invite link](https://mojaloop-slack.herokuapp.com/), and join the following channels: - - `#announcements` - Announcements for new Releases and QA Status - - `#design-authority` - Questions + Discussion around Mojaloop Design - - `#general` - General discussion about Mojaloop - - `#help-mojaloop` - Ask for help with installing or running Mojaloop - - `#ml-oss-bug-triage` - Discussion and triage for new bugs and issues - -- Say hi! Feel free to give a short introduction of yourself to the community on the `#general` channel. - -- Review the [Git workflow guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) and ensure you are familiar with git. - - Further reading: [Introduction to Github workflow](https://www.atlassian.com/git/tutorials/comparing-workflows) - -- Familiarize yourself with our standard coding style: https://standardjs.com/ - -- Browse through the [Mojaloop Documentation](https://mojaloop.io/documentation/) and get a basic understanding of how the technology works. - -- Go through the [Developer Tools Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) to get the necessary developer tools up and running on your local environment. - -- (Optional) Get the Central-Ledger up and running on local machines: - - https://github.com/mojaloop/central-ledger/blob/master/Onboarding.md - - https://github.com/mojaloop/ml-api-adapter/blob/master/Onboarding.md - -- (Optional:) Run an entire switch yourself with Kubernetes https://mojaloop.io/documentation/deployment-guide/ _(note: if running locally, your Kubernetes cluster will need 8gb or more of RAM)_ - -## 2. Finding an Issue - -- Review the [good-first-issue](https://github.com/mojaloop/project/labels/good%20first%20issue) list on [`mojaloop/project`](https://github.com/mojaloop/project), to find a good issue to start working on. Alternatively, reach out to the community on Slack at `#general` to ask for help to find an issue. - -- Leave a comment on the issue asking for it to be assigned to you -- this helps make sure we don't duplicate work. As always, reach out to us on Slack if you have any questions or concerns. - -- Fork the relevant repos for the issue, clone and create a new branch for the issue - - Refer to our [git user guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) if you get lost - - -## 3. Opening your First PR - -> _Complete this part of the guide once you have been added to the Mojaloop GitHub organization. If you don't have access, reach out to us on the `#general` or `#help-mojaloop` - -- Sign up for [Zenhub](https://www.zenhub.com/), and connect it to the Mojaloop Organisation, Search for the _'project'_ workspace -- Install the [Zenhub Browser extension](https://www.zenhub.com/extension) for Chrome or Firefox, and browse the (Mojaloop Project Kanban board](https://github.com/mojaloop/project#zenhub) - -- When your branch is ready for review, open a new pull request from your repository back into the mojaloop project. - >_Note: if the CI/CD pipelines don't run, this may be because your Github account isn't added to the Mojaloop repo_ -- Ensure the following: - - A good description of the feature/bugfix you implemented - - The PR is _assigned_ to yourself - - You have assigned two or more _reviewers_. GitHub often has suggested reviewers, but if you don't know who to assign, feel free to ask whoever created the issue. - -- (Optional) Post a link to your PR on the `#ml-oss-devs` channel in Slack so everyone can share in the fun - - -## FAQs: - -> None as of yet. If you have problems getting through this list, or need more help, reach out to us on Slack! \ No newline at end of file diff --git a/contributors-guide/standards/README.md b/contributors-guide/standards/README.md deleted file mode 100644 index a8e6059d2..000000000 --- a/contributors-guide/standards/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Standards - -## Standards - -### Standards for adopting an Open Source contribution into Mojaloop - -This document provides guidelines regarding the adoption of a contribution to the Mojaloop Open Source repositories. - -#### Prerequisites - -1. The contribution should be in-line with the LevelOne Principles -2. Basic guidelines regarding status of the contribution \(Code-base / Standards / Designs / Specifications\) -3. Basic documentation to get started - -#### Guidelines regarding adoption - -1. Create a private repo on the Mojaloop GitHub organization -2. Have a sub-team of the DA take a look to make sure its portable \(to OSS\) - aligns with L1P principles, etc, and ensure design is in line with standards -3. Check Licensing -4. Assess Performance impact -5. Create action items \(stories\) to update naming, remove/sanitize any items that are not generic -6. Configuration for 'modes of operation' -7. Enable CI/CD pipeline - -### Versioning - -Review the information on [versioning](versioning.md) for Mojaloop. - -### Creating new Features - -Process for creating new [features and branches](creating-new-features.md) in Mojaloop. - -### Pull Request Process - -It's a good idea to ask about major changes on [Slack](https://mojaloop.slack.com). Submit pull requests which include both the change and the reason for the change. Pull requests will be denied if they violate the [Level One Principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf) - -### Code of conduct - -We use a [standard developer code of conduct](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) - -### Licensing - -See [License](https://github.com/mojaloop/mojaloop/blob/master/contribute/License.md) policy diff --git a/contributors-guide/standards/creating-new-features.md b/contributors-guide/standards/creating-new-features.md deleted file mode 100644 index 21e009b0a..000000000 --- a/contributors-guide/standards/creating-new-features.md +++ /dev/null @@ -1,46 +0,0 @@ -# Creating new Features - -### Fork - -Fork the Mojaloop repository into your own personal space. Ensure that you keep the `master` branch in sync. - -Refer to the following documentation for more information: [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/) - -1. Clone repo using Git Fork button \(refer to the above documentation for more information\) -2. Clone your forked repo: `git clone https://github.com//.git` -3. Synchronise your forked repo with Mojaloop - - Add a new upstream repo for Mojaloop `$ git remote add mojaloop https://github.com/mojaloop/.git` - - You should now see that you have two remotes: - - ```bash - git remote -v - origin https://github.com//.git (fetch) - origin https://github.com//.git (push) - mojaloop https://github.com/mojaloop/.git (fetch) - mojaloop https://github.com/mojaloop/.git (push) - ``` - -4. To sync to your current branch: `git pull mojaloop ` This will merge any changes from Mojaloop's repo into your forked repo. -5. Push the changes back to your remote fork: `git push origin ` - -### Creating a Branch - -Create a new branch from the `master` branch with the following format: `/` where `issue#` can be attained from the Github issue, and the `issueDescription` is the issue description formatted in CamelCase. - -1. Create and checkout the branch: `git checkout -b /` -2. Push the branch to your remote: `git push origin /` - -Where `` can be one of the following: - -| branchType | Description | -| :--- | :--- | -| feature | Any new or maintenance features that are in active development. | -| hotfix | A hotfix branch is for any urgent fixes. | -| release | A release branch containing a snapshot of a release. | -| backup | A temporary backup branch. Used normally during repo maintenance. | - -### Merge into Mojaloop Repo - -Once the feature is completed create a PR from your Feature Branch into the `master` branch on the Mojaloop repository \(not your personal repo\) for approval, and check validations \(e.g. unit tests, code coverage, etc executed via CircieCI\). diff --git a/contributors-guide/standards/versioning.md b/contributors-guide/standards/versioning.md deleted file mode 100644 index 350f77758..000000000 --- a/contributors-guide/standards/versioning.md +++ /dev/null @@ -1,53 +0,0 @@ -# Versioning - -## Versioning of releases made for core Switch services - -This document provides guidelines regarding the versioning strategy used for the releases of Mojaloop Open Source repositories corresponding to the Switch services. - -### Versioning Strategy - -1. The current versioning system is inspired by the [Semantic Versioning](https://semver.org/) numbering system for releases. -2. However, this is customized to depict the timelines of the Mojaloop project, based on the Program Increment \(PI\) and Sprint numbers -3. For example, the release number v5.1.0 implies that this release was the first one made during a Sprint 5.1, where Sprint5.1 is the first Sprint in PI-5. So for a version vX.Y.Z, X.Y is the Sprint number where X is the PI number and Z represents the number of release for this specific repository. Example v4.4.4 implies that the current release is the fourth of four releases made in Sprint 4.4 \(of PI-4\) - -### Current Version - -The currrent version information for Mojaloop can be found [here](../../deployment-guide/releases.md). - -### Sprint schedule for PI9 - -Below is the Sprint schedule for Program Increment 9 which ends with the PI 10 on-site event at the of January 2020 in Tanzania. Please use this as guidance during the versioning and release processes. - -|Phase/Milestone|Start|End|Weeks|Notes| -|---|---|---|---|---| -|**Phase-3 PI6 On-site**|4/16/2019|4/18/2019|3 days| Johannesburg| -|**Phase-3 PI7 On-site**|6/25/2019|6/27/2019|3 days| Arusha| -|**Phase-3 PI8 On-site**|9/10/2019|9/12/2019|3 days| Abidjan| -|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| -|**Sprint 9.1**|2/3/2020|2/16/2020|2 weeks| | -|**Sprint 9.2**|2/17/2020|3/1/2020|2 weeks| | -|**Sprint 9.3**|3/2/2020|3/15/2020|2 weeks| | -|**Sprint 9.4**|3/16/2020|3/29/2020|2 weeks| | -|**Sprint 9.5**|3/30/2020|4/12/2020|2 weeks| | -|**Sprint 9.6**|3/13/2020|4/19/2020|1 week | | -|**Phase-4 PI 10 On-site**|4/21/2020|4/23/2020|3 days| Tanzania | - -### Previous Sprint Schedules: - -#### PI8 -|Phase/Milestone|Start|End|Weeks|Notes| -|---|---|---|---|---| -|**Sprint 8.1**|9/16/2019|9/29/2019|2 weeks| | -|**Sprint 8.2**|9/30/2019|10/13/2019|2 weeks| | -|**Sprint 8.3**|10/14/2019|10/27/2019|2 weeks| | -|**Sprint 8.4**|10/28/2019|11/10/2019|2 weeks| | -|**Sprint 8.5**|11/11/2019|11/24/2019|2 weeks| | -|**Sprint 8.6**|11/25/2019|12/8/2019|2 weeks| | -|**Sprint 8.7**|12/9/2019|1/5/2020|4 weeks| Christmas Break| -|**Sprint 8.8**|1/6/2020|1/26/2020|3 weeks| 1 week prep| -|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| - -### Notes - -1. A new release for **helm** repo is made whenver a configuration change is needed for any of the core Switch services based on the changes made \(features, bug-fixes\). -2. However, if there is no release made to helm necessitated by a configuration change, then a release is done every Sprint anyway, to bring it up to date with the latest releases on the core Switch services. diff --git a/contributors-guide/tools-and-technologies/automated-testing.md b/contributors-guide/tools-and-technologies/automated-testing.md deleted file mode 100644 index cc6c42ca9..000000000 --- a/contributors-guide/tools-and-technologies/automated-testing.md +++ /dev/null @@ -1,138 +0,0 @@ -# QA and Regression Testing in Mojaloop -An overview of the testing framework set up in Mojaloop - -Contents: -1. [Regression requirements](#regression-topics) -2. [Developer Testing](#developer-testing) -3. [Postman and Newman Testing](#postman-and-newman-testing) -4. [Executing regression test](#executing-regression-test) -5. [Process flow of a typical Scheduled Test](#process-flow-of-a-typical-scheduled-test) -6. [Newman Commands](#newman-commands) - -## Regression Topics - In order for a deployed system to be robust, one of the last checkpoints is to determine if the environment it is deployed in, is in a healthy state and all exposed functionality works exactly the way as intended. - - Prior to that though, there are quite a number of disciplines one must put in place to ensure maximum control. - - To illustrate how the Mojaloop project reaches this goal, we are going to show you the various checkpoints put in place. - -### Developer Testing - Looking at each component and module, inside the code base, you will find a folder named "*test*" which contain three types of tests. - + Firstly, the *coverage test* which alerts one if there are unreachable or redundant code - + Unit Tests, which determines if the intended functionality works as expected - + Integration Tests, which does not test end-to-end functionality, but the immediate neighbouring interaction - + Automated code-standard checks implemented by means of packages that form part of the code base - - These tests are executed by running the command line instructions, by the developer, during the coding process. Also, the tests are automatically executed every time a *check-in* is done and a Github Pull-Request issued for the code to be integrated into the project. - - The procedure described above, falls outside the realm of Quality Assurance (QA) and Regression testing, which this document addresses. - - Once a developer has written new functionality or extended existing functionality, by having to go through the above rigorous tests, one can assume the functionality in question is executing as intended. How does one then ensure that this new portion of code does not negatively affect the project or product as a whole? - - When the code has passed all of the above and is deployed as part of the CI/CD processes implemented by our workflow, the new component(s) are accepted onto the various hosts, cloud-based or on-premise implementations. These hosts ranges from development platforms through to production environments. - -### Postman and Newman Testing - Parallel to the deployment process is the upkeep and maintenance of the [Postman](https://github.com/mojaloop/postman.git "Postman") Collection testing Framework. When a new release is done, as part of the workflow, Release Notes are published listing all of the new and/or enhanced functionality implemented as part of the release. These notes are used by the QA team to extend and enhance the existing Postman Collections where tests are written behind the request/response scripts to test both positive as well as negative scenarios agains the intended behaviour. These tests are then run in the following manner: - + Manually to determine if the tests cover all aspects and angles of the functionality, positive to assert intended behaviour and negative tests to determine if the correct alternate flows work as intended when something unexpected goes wrong - + Scheduled - as part of the Regression regime, to do exactly the same as the manual intent, but fully automated (with the *Newman Package*) with reports and logs produced to highlight any unintended behaviour and to also warn where known behaviour changed from a previous run. - -In order to facilitate the automated and scheduled testing of a Postman Collection, there are various methods one can follow and the one implemented for Mojaloop use is explained further down in this document. - -There is a complete repository containing all of the scripts, setup procedures and anything required in order to set up an automated [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"). This framework allows one to target any Postman Collection, specifying your intended Environment to execute against, as well as a comma-separated list of intended email recipients to receive the generated report. This framework is in daily use by Mojaloop and exists on an EC2 instance on AWS, hosting the required components like Node, Docker, Email Server and Newman, as well as various Bash Scripts and Templates for use by the framework to automatically run the intended collections every day. Using this guide will allow anyone to set up their own Framework. - -#### Postman Collections - -There are a number of Postman collections in use throughout the different processes: -+ [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json) : This collection needs to be executed once after a new deployment, normally by the Release Manager, to seed the Database with the required enumerations and static data, as well as test FSPs with their accounts and position data in order to be able to execute any manual or automation tests by other collections. - + Notes: Ensure that there is a delay of `200ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. -+ [OSS-API-Tests](https://github.com/mojaloop/postman/blob/master/OSS-API-Tests.postman_collection.json) : This suite of tests will issue a request/response against each and every exposed API, testing APIs such as the Mojaloop core APIs, bulk quotes, admin-APIs, Settlement APIs, Metrics APIs, Fund-in and out APIs etc. These tests are done to test the message headers, body, responses received and not to test the end-to-end flow of a transfer for example - + Notes: Ensure that there is a delay of `1500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. -+ [OSS-Feature-Tests](https://github.com/mojaloop/postman/blob/master/OSS-Feature-Tests.postman_collection.json) : Scenario based testing are performed with this collection, such as Settlements processes, Block Transfers, Negative testing scenarios and so on - + Notes: Ensure that there is a delay of `1500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. -+ [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) : This test collection is the one used by the scheduled regression testing framework to test end-to-end scenarios, resembling real-world use-cases where the response from one API call is used to populate the request of a subsequent call. We make use of an intelligent simulator playing the role of an FSP on the recipient side of the scenario, responding to various request from a Payer FSP as an example - + Notes: Ensure that there is a delay of `1500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. - -#### Environment Configuration - -You will need to customize the following environment config file to match your deployment environment: -+ [Local Environment Config](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local.postman_environment.json) - -_Tips:_ -- _The host configurations will be the most likely changes required to match your environment. e.g. `HOST_CENTRAL_LEDGER: http://central-ledger.local`_ -- _Refer to the ingress hosts that have been configured in your `values.yaml` as part of your Helm deployment._ - -### Executing regression test -For the Mojaloop QA and Regression Testing Framework specifically, Postman regression test can be executed by going into the EC2 instance via SSH, for which you need the PEM file, and then by running a script(s). - -Following the requirements and instructions as set out in the detail in [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"), everyone will be able to create their own Framework and gain access to their instance to execute tests against any Postman Collection targeting any Environment they have control over. - -##### Steps to execute the script via Postman UI -+ Import the desired collection into your Postman UI. You can either download the collection from the repo or alternatively use the `RAW` link and import it directly via the **import link** option. -+ Import the environment config into your Postman UI via the Environmental Config setup. Note that you will need to download the environmental config to your machine and customize it to your environment. -+ Ensure that you have pre-loaded all prerequisite test data before executing transactions (party, quotes, transfers) as per the example collection [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json): - + Hub Accounts - + FSP onboarding - + Add any test data to Simulator (if applicable) - + Oracle onboarding -+ The `p2p_money_transfer` test cases from the [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) collection are a good place to start. - -##### Steps to execute the bash script to run the Newman / Postman test via CLI -+ To run a test via this method, you will have to be in posession of the PEM-file of the server on which the Mojaloop QA and Regression Framework was deployed on an EC2 instance on Amazon Cloud. - -+ SSH into the specific EC2 instance and when running the script, it will in turn run the commands via an instantiated Docker container. - -+ You will notice that by using this approach where both the URLs for the Postman-Collection and Environment File are required as input parameters (together with a comma-delimited email recipient list for the report) you have total freedom of executing any Postman Collection you choose. - -+ Also, by having an Environment File, the specific Mojaloop services targeted can be on any server. This means you can execute any Postman test against any Mojaloop installation on any server of your choice. - -+ The EC2 instance we execute these tests from are merely containing all the tools and processes in order to execute your required test and does not host any Mojaloop Services as such. - -``` -./testMojaloop.sh -``` - -## Process flow of a typical Scheduled Test - -{% uml src="contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml" %} -{% enduml %} - -## Newman Commands -The following section is a reference, obtained from the Newman Package site itself, highlighting the different commands that may be used in order to have access to the Postman environment by specifying some commands via the CLI. -``` -Example: -+ newman run -e -n 1 -- - -Usage: run [options] - - URL or path to a Postman Collection. - - Options: - - -e, --environment Specify a URL or Path to a Postman Environment. - -g, --globals Specify a URL or Path to a file containing Postman Globals. - --folder Specify folder to run from a collection. Can be specified multiple times to run multiple folders (default: ) - -r, --reporters [reporters] Specify the reporters to use for this run. (default: cli) - -n, --iteration-count Define the number of iterations to run. - -d, --iteration-data Specify a data file to use for iterations (either json or csv). - --export-environment Exports the environment to a file after completing the run. - --export-globals Specify an output file to dump Globals before exiting. - --export-collection Specify an output file to save the executed collection - --postman-api-key API Key used to load the resources from the Postman API. - --delay-request [n] Specify the extent of delay between requests (milliseconds) (default: 0) - --bail [modifiers] Specify whether or not to gracefully stop a collection run on encountering an errorand whether to end the run with an error based on the optional modifier. - -x , --suppress-exit-code Specify whether or not to override the default exit code for the current run. - --silent Prevents newman from showing output to CLI. - --disable-unicode Forces unicode compliant symbols to be replaced by their plain text equivalents - --global-var Allows the specification of global variables via the command line, in a key=value format (default: ) - --color Enable/Disable colored output. (auto|on|off) (default: auto) - --timeout [n] Specify a timeout for collection run (in milliseconds) (default: 0) - --timeout-request [n] Specify a timeout for requests (in milliseconds). (default: 0) - --timeout-script [n] Specify a timeout for script (in milliseconds). (default: 0) - --ignore-redirects If present, Newman will not follow HTTP Redirects. - -k, --insecure Disables SSL validations. - --ssl-client-cert Specify the path to the Client SSL certificate. Supports .cert and .pfx files. - --ssl-client-key Specify the path to the Client SSL key (not needed for .pfx files) - --ssl-client-passphrase Specify the Client SSL passphrase (optional, needed for passphrase protected keys). - -h, --help output usage information -``` - diff --git a/contributors-guide/tools-and-technologies/license-scanning.md b/contributors-guide/tools-and-technologies/license-scanning.md deleted file mode 100644 index 7cf041946..000000000 --- a/contributors-guide/tools-and-technologies/license-scanning.md +++ /dev/null @@ -1,21 +0,0 @@ -# License Scanning - -## Motivation - -As an open source project, Mojaloop must remain free of so called ['viral' licenses](https://en.wikipedia.org/wiki/Viral_license) in any dependencies which are incompatible with the license of the project. - -In order to scan the licenses across all mojaloop subprojects, we made a tool called [`license-scanner`](https://github.com/vessels-tech/license-scanner). Using this tool we can, en masse: - -- run `fossa-cli` across the entire codebase and upload the reports to the Fossa Website (requires a Fossa API Key) -- run `npm-license-checker` across the codebase and export a `.xlsx` file for manually verifying the licenses - - -## Using `license-scanner` - ->Note: `license-scanner` is currently in Vessel Tech's company github repo, but may be brought into the core mojaloop project in the future. - -You can find `license-scanner` [here](https://github.com/vessels-tech/license-scanner). Follow the instructions in the readme to get up and running. - -## CI/CD Pipeline - -We are currently in the process of integrating license scans into the CI/CD Pipeline \ No newline at end of file diff --git a/deployment-guide/README.md b/deployment-guide/README.md deleted file mode 100644 index 05e559973..000000000 --- a/deployment-guide/README.md +++ /dev/null @@ -1,257 +0,0 @@ -# Mojaloop Deployment - -The document is intended for an audience with a stable technical knowledge that would like to setup an environment for development, testing and contributing to the Mojaloop project. - -## Deployment and Setup - -- [Pre-requisites](#1-pre-requisites) -- [Kubernetes](#3-kubernetes) - - [Kubernetes Dashboard](#31-kubernetes-dashboard) -- [Helm](#4-helm) - - [Helm configuration](#41-helm-configuration) -- [Postman](#6-postman) - - [Installing Postman](#61-installing-postman) - - [Setup Postman](#62-setup-postman) - -### 1. Pre-requisites - -A list of the pre-requisite tool set required for the deployment of Mojaloop; -- **Kubernetes** An open-source system for automating deployment, scaling, and management of containerized applications. Find out more about [Kubernetes](https://kubernetes.io), - - kubectl - Kubernetes CLI for Kubernetes Management is required. Find out more about [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/), - - [Install-kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/), - - microk8s - MicroK8s installs a barebones upstream Kubernetes for a single node deployment generally used for local development. We recommend this installation on Linux (ubuntu) OS. Find out more about [microk8s](https://microk8s.io/) and [microk8s documents](https://microk8s.io/docs/), - - [Install-microk8s](https://microk8s.io/docs/), - - kubectx - Not required but useful. Find out more about [kubectx](https://github.com/ahmetb/kubectx), - - kubetail - Not required but useful. Bash script that enables you to aggregate (tail/follow) logs from multiple pods into one stream. Find out more about [kubetail](https://github.com/johanhaleby/kubetail), -- **Docker** Provides containerized environment to host the application. Find out more about [Docker](https://docker.com), -- **Helm** A package manager for Kubernetes. Find out more about [Helm](https://helm.sh), -- **Postman** Postman is a Google Chrome application for the interacting with HTTP API's. It presents you with a friendly GUI for the construction requests and reading responces. https://www.getpostman.com/apps. Find out more about [Postman](https://postman.com). - -For **local guides** on how to setup the pre-requisites on your laptop or desktop, refer to the appropriate link document below; -- [Local Setup for Mac](local-setup-mac.md) -- [Local Setup for Linux](local-setup-linux.md) -- [Local Setup for Windows](local-setup-windows.md) - -### 2. Deployment Recommendations - -This provides environment resource recommendations with a view of the infrastructure architecture. - -**Resources Requirements:** - -* Control Plane (i.e. Master Node) - - [https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components](https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components) - - * 3x Master Nodes for future node scaling and HA (High Availability) - -* ETCd Plane: - - [https://etcd.io/docs/v3.3.12/op-guide/hardware](https://etcd.io/docs/v3.3.12/op-guide/hardware) - - * 3x ETCd nodes for HA (High Availability) - -* Compute Plane (i.e. Worker Node): - - TBC once load testing has been concluded. However the current general recommended size: - - * 3x Worker nodes, each being: - * 4x vCPUs, 16GB of RAM, and 40gb storage - - **Note** that this would also depend on your underlying infrastructure, and it does NOT include requirements for persistent volumes/storage. - -![Mojaloop Deployment Recommendations - Infrastructure Architecture](./assets/diagrams/deployment/KubeInfrastructureArch.svg) - -### 3. Kubernetes - -This section will guide the reader through the deployment process to setup Kubernetes. - -If you are new to Kubernetes it is strongly recommended to familiarize yourself with Kubernetes. [Kubernetes Concepts](https://kubernetes.io/docs/concepts/overview/) is a good place to start and will provide an overview. - -The following are Kubernetes concepts used within the project. An understanding of these concepts is imperative before attempting the deployment; - -* Deployment -* Pod -* ReplicaSets -* Service -* Ingress -* StatefulSet -* DaemonSet -* Ingress Controller -* ConfigMap -* Secret - -Insure **kubectl** is installed. A complete set of installation instruction are available [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). - -#### 3.1. Kubernetes Dashboard: - -1. Kubernetes Dashboard roles, services & deployment. - - Install for Dashboard using Helm (not needed if **MicroK8s** is installed): [kubernetes-dashboard](https://github.com/helm/charts/tree/master/stable/kubernetes-dashboard) - - **IMPORTANT:** Always verify the current [kubernetes-dashboard](https://github.com/kubernetes/dashboard) yaml file is still correct as used in the below command. - ```bash - kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml - ``` - - If you have installed MicroK8s, **enable the MicroK8s** dashboard; - ```bash - microk8s.enable dashboard - ``` - **Remember** to prefix all **kubectl** commands with **microk8s** if you opted not to create an alias. - -2. Verify Kubernetes Dashboard. _Windows replace `grep` with `findstr`_; - ```bash - kubectl get pod --namespace=kube-system |grep dashboard - ``` - -3. Start proxy for local UI in new terminal; - ```bash - kubectl proxy ui - ``` - -4. Open URI in default browser: - - ``` - http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ - ``` - - Select **Token**. Generate a token to use there by: _Windows replace `grep` with `findstr`_ - - ```bash - kubectl -n kube-system get secrets | grep dashboard-token - ``` - - The token to use is shown on the last line of the output of that command; - - ```bash - kubectl -n kube-system describe secrets/kubernetes-dashboard-token-btbwf - ``` - - The **{kubernetes-dashboard-token-btbwf}** is retrieved from the output in the previous step. For more information on generating the token, follow the **Authentication** link in the window. - -![kubernetes-dashboard](./assets/diagrams/deployment/kubernetesDashboard.png) - -### 4. Helm - -Please review [Mojaloop Helm Chart](../repositories/helm.md) to understand the relationships between the deployed Mojaloop helm charts. - -#### 4.1. Helm configuration - -1. Config Helm CLI and install Helm Tiller on K8s cluster: - ```bash - helm init - ``` - _Note: if `helm init` fails with `connection refused error`, refer to [troubleshooting](./deployment-troubleshooting.md#helm_init_connection_refused)_ - -2. Validate Helm Tiller is up and running. _Windows replace `grep` with `findstr`_: - ```bash - kubectl -n kube-system get po | grep tiller - ``` - -3. Add mojaloop repo to your Helm config (optional). _Linux use with sudo_: - ```bash - helm repo add mojaloop http://mojaloop.io/helm/repo/ - ``` - If the repo already exists, substitute 'add' with 'apply' in the above command. - -4. Add the additional dependency Helm repositories. This is needed to resolve Helm Chart dependencies required by Mojaloop charts. Linux use with sudo; - ```bash - helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator - helm repo add kiwigrid https://kiwigrid.github.io - helm repo add elastic https://helm.elastic.co - ``` - -5. Update helm repositories. _Linux use with sudo_: - ```bash - helm repo update - ``` - -6. Install nginx-ingress for load balancing & external access. _Linux use with sudo_: - ```bash - helm --namespace kube-public install stable/nginx-ingress - ``` - -### 5. Mojaloop - -#### 5.1. Mojaloop Helm Deployment - -1. Install Mojaloop. _Linux use with sudo_: - - Default installation: - ```bash - helm --namespace demo --name moja install mojaloop/mojaloop - ``` - - Version specific installation: - ```bash - helm --namespace demo --name moja install mojaloop/mojaloop -version {version} - ``` - - List of available versions: - ```bash - helm search -l mojaloop/mojaloop - ``` - - Custom configured installation: - ```bash - helm --namespace demo --name moja install mojaloop/mojaloop -f {custom-values.yaml} - ``` - _Note: Download and customize the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml). Also ensure that you are using the value.yaml from the correct version which can be found via [Helm Releases](https://github.com/mojaloop/helm/releases)._ - -#### 5.2. Verifying Mojaloop Deployment - -1. Update your /ect/hosts for local deployment: - - _Note: This is only applicable for local deployments, and is not needed if custom DNS or ingress rules are configured in a customized [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml)_. - - ```bash - vi /etc/hosts - ``` - _Windows the file can be updated in notepad - need to open with Administrative privileges. File location `C:\Windows\System32\drivers\etc\hosts`_. - - Include the following lines (_or alternatively combine them_) to the host config. - - The below required config is applicable to Helm release >= versions 6.2.2 for Mojaloop API Services; - ```text - 127.0.0.1 central-ledger.local central-settlement.local ml-api-adapter.local account-lookup-service.local account-lookup-service-admin.local quoting-service.local moja-simulator.local central-ledger central-settlement ml-api-adapter account-lookup-service account-lookup-service-admin quoting-service simulator host.docker.internal - ``` - - The below optional config is applicable to Helm release >= versions 6.2.2 for Internal components, please include the following in the host configuration. - ```text - 127.0.0.1 forensic-logging-sidecar.local central-kms.local central-event-processor.local email-notifier.local - ``` - - For Helm legacy releases prior to versions 6.2.2, please include the following in the host configuration. - ```text - 127.0.0.1 interop-switch.local central-end-user-registry.local central-directory.local central-hub.local - ``` - -2. Test system health in your browser after installation. This will only work if you have an active helm chart deployment running. - - _Note: The examples below are only applicable to a local deployment. The entries should match the DNS values or ingress rules as configured in the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) or otherwise matching any custom ingress rules configured_. - - **ml-api-adapter** health test: - ``` - http://ml-api-adapter.local/health - ``` - - **central-ledger** health test: - ``` - http://central-ledger.local/health - ``` - -### 6. Postman - -Postman is used to send requests and receive responses. - -#### 6.1. Installing Postman - -Please, follow these instructions: [Get Postman](https://www.getpostman.com/postman) and install the Postman application. - -#### 6.2. Setup Postman - -Grab the latest collections & environment files from [Mojaloop Postman Github repo](https://github.com/mojaloop/postman): [https://github.com/mojaloop/postman](https://github.com/mojaloop/postman) - -After an initial setup or new deployment, the [OSS New Deployment FSP Setup section](../contributors-guide/tools-and-technologies/automated-testing.md) needs to be completed. This will seed the Database with the required enumerations and static data to enable the sucessful execution of any manual or automation tests by the other collections. - -Refer to the [QA and Regression Testing in Mojaloop](../contributors-guide/tools-and-technologies/automated-testing.md) documentation for more complete information to complement your testing requirements. diff --git a/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg b/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg deleted file mode 100644 index b6dc2bb11..000000000 --- a/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg +++ /dev/null @@ -1,2 +0,0 @@ - -
3x Master
Nodes

[Not supported by viewer]
3x ETCd
Nodes

[Not supported by viewer]
Alt: DSN Round Robin Fail-over
Alt: DSN Round Robin Fail-over
Layer 4 Load Balancer
<font style="font-size: 14px">Layer 4 Load Balancer</font>
Firewall
Firewall
DMZ
[Not supported by viewer]
External
Consumer

[Not supported by viewer]
3x Worker
Nodes

[Not supported by viewer]
KEY
[Not supported by viewer]
Ingress Controller deployed as a DaemonSet
[Not supported by viewer]
\ No newline at end of file diff --git a/deployment-guide/deployment-troubleshooting.md b/deployment-guide/deployment-troubleshooting.md deleted file mode 100644 index a84d11156..000000000 --- a/deployment-guide/deployment-troubleshooting.md +++ /dev/null @@ -1,182 +0,0 @@ -# Deployment Troubleshooting - -## Local deployment with MicroK8s - suggestions: - -- use **v1.15 of MicroK8s** (higher version not yet supported) (details in "Installation of mojaloop helm charts fail with validation failed" section) -- try `microk8s.inspect` for hints (for example connectivity problems when ip forwarding is not enabled, more about it in "MicroK8s - Connectivity Issues section") -- enable following microk8s add-ons (check with `sudo microk8s.status`): - - storage - - ingress - - dns - - istio - - dashboard - -## 1. Known issues - -### 1.1. Mojaloop Helm Charts does not support Kubernetes v1.16 or greater - -#### Description - -When installing mojaloop helm charts, the following error occurs: - - ``` - Error: validation failed: [unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta2", unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta2", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta1"] - ``` - -#### Reason - -In version 1.16 of Kubernetes breaking change has been introduced (more about it [in "Deprecations and Removals" of Kubernetes release notes](https://kubernetes.io/docs/setup/release/notes/#deprecations-and-removals). The Kubernetes API versions `apps/v1beta1` and `apps/v1beta2`are no longer supported and and have been replaced by `apps/v1`. - -Currently Mojaloop helm charts (as of v8.4.x) refer to deprecated ids, therefore it's not possible to install current Mojaloop charts on Kubernetes version above 1.15 without manually changing charts. - -Refer to the following issue for more info: [mojaloop/helm#219](https://github.com/mojaloop/helm/issues/219) - -#### Fixes - -Ensure that you are deploying the Mojaloop Helm charts on v1.15 of Kubernetes (or microk8s when working locally). - -#### Additional details for `microk8s` fix - -To check version of `microk8s`: - ```bash - snap info microk8s - ``` -_Note: Look at the end of the output for a row starting with "installed"_ - -To install most recent supported version: - ```bash - snap refresh microk8s --channel=1.15/stable --classic - ``` - - -## 2. Deployment issues - -### 2.1. MicroK8s - helm init connection refused - -#### Description - -The helm init: - - ```bash - helm init - ``` - -fails with error when installing locally on `microk8s`: - - ``` - Error: error installing: Post http://localhost:8080/apis/apps/v1/namespaces/kube-system/deployments: dial tcp 127.0.0.1:8080: connect: connection refused - ``` - -#### Reason - -This may be a missing `~/.kube/config` file, where helm looks for connection details. - -#### Fix - option #1 - -One of the solutions is to generate that file by issuing: - - ```bash - microk8s.kubectl config view --raw > $HOME/.kube/config - ``` - -#### Fix - option #2 - -Another option is to export the config to a new file: - - ```bash - microk8s.kubectl config view --raw > $HOME/.kube/local.config - ``` - -And then export the following env var: - - ```bash - export KUBECONFIG=$HOME/.kube/local.config - ``` - -### 2.2. `ERR_NAME_NOT_RESOLVED` Error - -#### Description - -The following error is displayed when attempting to access an end-point (e.g. central-ledger.local) via the Kubernetes Service directly in a browser: `ERR_NAME_NOT_RESOLVED` - -#### Fixes - - * Verify that that Mojaloop was deployed by checking that the helm chart(s) was installed by executing: - - ```bash - helm list - ``` - - If the helm charts are not listed, see the [Helm Chart Installation](README.md#4-helm) section to install a chart. - - * Ensure that all the Mojaloop Pods/Containers have started up correctly and are available through the Kubernetes dashboard. - - * Note that the Mojaloop deployment via Helm can take a few minutes to initially startup depending on the system's available resources and specification. It is recommended that you wait at least 10m for all Pods/Containers to self heal before troubleshooting. - -### 2.3. MicroK8s - Connectivity Issues - -#### Description - -My pods can’t reach the internet or each other (but my MicroK8s host machine can). - -An example of this is that the Central-Ledger logs indicate that there is an error with the Broker transport as per the following example: -``` -2019-11-05T12:28:10.470Z - info: Server running at: -2019-11-05T12:28:10.474Z - info: Handler Setup - Registering {"type":"prepare","enabled":true}! -2019-11-05T12:28:10.476Z - info: CreateHandler::connect - creating Consumer for topics: [topic-transfer-prepare] -2019-11-05T12:28:10.515Z - info: CreateHandler::connect - successfully connected to topics: [topic-transfer-prepare] -2019-11-05T12:30:20.960Z - error: Consumer::onError()[topics='topic-transfer-prepare'] - Error: Local: Broker transport failure) -``` - -#### Fixes - -Make sure packets to/from the pod network interface can be forwarded to/from the default interface on the host via the iptables tool. Such changes can be made persistent by installing the iptables-persistent package: - -```bash -sudo iptables -P FORWARD ACCEPT -sudo apt-get install iptables-persistent -``` - -or, if using ufw: - - -```bash -sudo ufw default allow routed -``` -The MicroK8s inspect command can be used to check the firewall configuration: - -```bash -microk8s.inspect -``` - - -## 3. Ingress issues - -### 3.1. Ingress rules are not resolving for Nginx Ingress v0.22 or later - -#### Description - -Ingress rules are unable to resolve to the correct path based on the annotations specified in the values.yaml configuration files when using Nginx Ingress controllers v0.22 or later. - -This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. - -#### Fixes - - * Make the following change to all Ingress annotations (from --> to) in each of the values.yaml files: - - `nginx.ingress.kubernetes.io/rewrite-target: '/'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/$1'` - - -### 3.2. Ingress rules are not resolving for Nginx Ingress earlier than v0.22 - -#### Description - -Ingress rules are unable to resolve to the correct path based on the annotations specified in the values.yaml configuration files when using Nginx Ingress controllers that are older than v0.22. - -This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. - -#### Fixes - - * Make the following change to all Ingress annotations (from --> to) in each of the values.yaml files: - - `nginx.ingress.kubernetes.io/rewrite-target: '/$1'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/'` diff --git a/deployment-guide/local-setup-linux.md b/deployment-guide/local-setup-linux.md deleted file mode 100644 index cc10fd4bf..000000000 --- a/deployment-guide/local-setup-linux.md +++ /dev/null @@ -1,111 +0,0 @@ -# Mojaloop Setup for Linux (Ubuntu) - -Local setup on a Laptop or Desktop to run the Mojaloop project. - -## Setup Introduction - -This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. - -At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. - -* [Environment recommendations](#1-environment-recommendations) - * [Kubernetes](#2-kubernetes) - * [MicroK8S](#21-microk8s) - * [Docker](#12-docker) -* [Useful Tips](#2-useful-tips) - -## 1. Environment recommendations - -This environment setup was validated on: - * 64-bit version of Ubuntu Bionic 18.04(LTS). - * This guide is based on Ubuntu 18.04.2 (bionic) on a x86_64 desktop with 8 CPU's and 16GB RAM. - -## 2. Kubernetes - -Kubernetes installation for a local environment. - -#### 2.1. MicroK8S - -We recommend install directly from the snap store. - -Don't have the snap command? [Install snapd first](https://snapcraft.io/docs/core/install). - -1. Installing MicroK8s from snap. - ```bash - snap install microk8s --classic - ``` - -2. Verify MicroK8s is installed and available. - ```bash - microk8s.status - ``` - -3. During installation you can use the --wait-ready flag to wait for the kubernetes services to initialise. - ```bash - microk8s.status --wait -ready - ``` - -4. To avoid colliding with a **kubectl** already installed and to avoid overwriting any existing Kubernetes configuration file, MicroK8s adds a **microk8s.kubectl** command, configured to exclusively access the new **MicroK8s** install. - ```bash - microk8s.kubectl get services - ``` - -5. This step is only necessary if you require **microk8s.kubectl** to function as a standard **kubectl** command. This **DOES NOT** mean that you can then use **kubectl** to access **OTHER** k8s clusters. - - An example of why you would use this: You have a bash script or 3rd party tool that expects **kubectl** to be available. E.g. If you want to use Helm, it will not work against **microk8s.kubectl**, thus one **MUST** setup the alias for Helm to function correctly. - ```bash - snap alias microk8s.kubectl kubectl - ``` - - Reverting it at any time; - ```bash - snap unalias kubectl - ``` - - We will stick with the standard command of prefixing with **microk8s.** for this guide. - -6. If you already have **kubectl** installed and would like to use it to access the **MicroK8s** deployment. - ```bash - microk8s.kubectl config view --raw > $HOME/.kube/config - ``` - -7. View the current context. - ```bash - microk8s.kubectl config get-contexts - ``` - -9. Make sure the current context is **microk8s**. If not, set it as the current context. - ```bash - microk8s.kubectl config use-context microk8s - ``` - -### 1.2. Docker - -Docker is deployed as part of the MicroK8s installation. The docker daemon used by MicroK8s is listening on unix:///var/snap/microk8s/current/docker.sock. You can access it with the **microk8s.docker** command. - -1. If you require **microk8s.docker** to function as a standard **docker** command, you set an alias. - ```bash - sudo snap alias microk8s.docker docker - ``` - - Undo the alias; - ```bash - sudo snap unalias docker - ``` - -2. We will apply the native microK8s commands by prefix commands **microk8s.** - ```bash - microk8s.docker ps - ``` - -3. Continue setup and configuration from the Kubernetes Dashboard section in the [Mojaloop's deployment guide](./README.md#31-kubernetes-dashboard) document. - -## 2. Useful Tips - -1. Resolve problems with VSCode and kafka on ubuntu 18.04. To make the code work with VSCode debugger, added the following into the launch.json - ```json - "env": { - "LD_LIBRARY_PATH": "${workspaceFolder}/node_modules/node-rdkafka/build/deps", - "WITH_SASL": 0 - } - ``` diff --git a/deployment-guide/local-setup-mac.md b/deployment-guide/local-setup-mac.md deleted file mode 100644 index 2db7f5cbc..000000000 --- a/deployment-guide/local-setup-mac.md +++ /dev/null @@ -1,89 +0,0 @@ -# Mojaloop local environment setup for Mac - -Local setup on a Laptop or Desktop to run the Mojaloop project. - -## Setup Introduction - -This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. - -At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. - -* [Local Deployment](local-setup-mac.md#local-deployment) - * [Kubernetes](local-setup-mac.md#1-kubernetes) - * [Kubernetes Installation with Docker](local-setup-mac.md#11-kubernetes-installation-with-docker) - * [Kubernetes environment setup](local-setup-mac.md#12-kubernetes-environment-setup) - - -## 1. Kubernetes - -This section will guide the reader through the deployment process to setup Kubernetes within Docker. - -If you are new to Kubernetes it is strongly recommended to familiarize yourself with Kubernetes. [Kubernetes Concepts](https://kubernetes.io/docs/concepts/overview/) is a good place to start and will provide an overview. - -The following are Kubernetes concepts used within the project. An understanding of these concepts is imperative before attempting the deployment; - -* Deployment -* Pod -* ReplicaSets -* Service -* Ingress -* StatefulSet -* DaemonSet -* Ingress Controller -* ConfigMap -* Secret - -### 1.1. Kubernetes Installation with Docker - -* **kubectl** Complete set of installation instruction are available [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/) - - ```bash - brew install kubernetes-cli - ``` - To verify if the installation was successful, check the version; - - ```bash - kubectl version - ``` - -To install Kubernetes with Docker, follow the steps below; - -* Click on the Docker icon on the status barr - * Select **Preferences** - * Go to **Advanced** - * Increase the CPU allocation to at least 4 - * Increase the Memory allocation to at least 8.0 GiB - -![Kubernetes Install with Docker 1](./assets/diagrams/deployment/KubernetesInstallWithDocker-1.png) - -* Go to **Kubernetes** - * Select **Enable Kubernetes** tick box - * Make sure **Kubernetes** is selected - * Click **Apply** - * Click **Install** on the confirmation tab. - * The option is available to wait for completion or run as a background task. - -![Kubernetes Install with Docker 2](./assets/diagrams/deployment/KubernetesInstallWithDocker-2.png) - -### 1.2. Kubernetes environment setup: - -1. List the current Kubernetes context; - ```bash - kubectl config get-contexts - ``` - - **or** - ```bash - kubectx - ``` -2. Change your Contexts; - ```bash - kubectl config use-context docker-for-desktop - ``` - - **or** - ```bash - kubectx docker-for-desktop - ``` - -3. Continue setup and configuration from the Kubernetes Dashboard section in the [Mojaloop's deployment guide](./README.md#31-kubernetes-dashboard) document. \ No newline at end of file diff --git a/deployment-guide/local-setup-windows.md b/deployment-guide/local-setup-windows.md deleted file mode 100644 index bd6be3736..000000000 --- a/deployment-guide/local-setup-windows.md +++ /dev/null @@ -1,122 +0,0 @@ -# Mojaloop local environment setup for Windows - -Local setup on a Laptop or Desktop to run the Mojaloop project. - -## Setup Introduction - -This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. - -At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. - -* [Kubernetes](#1-kubernetes) - * [Kubernetes Installation with Docker](#11-kubernetes-installation-with-docker) - * [Kubernetes environment setup](#12-kubernetes-environment-setup) - - -## 1. Kubernetes - -This section will guide the reader through the deployment process to setup Kubernetes within Docker. - -If you are new to Kubernetes it is strongly recommended to familiarize yourself with Kubernetes. [Kubernetes Concepts](https://kubernetes.io/docs/concepts/overview/) is a good place to start and will provide an overview. - -The following are Kubernetes concepts used within the project. An understanding of these concepts is imperative before attempting the deployment; - -* Deployment -* Pod -* ReplicaSets -* Service -* Ingress -* StatefulSet -* DaemonSet -* Ingress Controller -* ConfigMap -* Secret - -### 1.1 Kubernetes Installation with Docker - -* **kubectl** is part of the installation package when installing Docker Desktop for Windows. - - Please note the minimum system and operation requirements; - * Docker Desktop for Windows require Microsoft Hyper-V to run. Hyper-V will be enable as part of the installation process, - * Windows 10 64bit: Pro, Enterprise, Education (1607 Anneversary Update, Build 14393 or later), - * CPU SLAT-capable feature, - * At least 4GB of RAM. (At least 16GB will be required to run the Mojaloop project). - -1. Installing Docker for Windows: - - You will require Docker Desktop for Windows 18.02 Edge (win50) and higher, or 18.06 Stable (win 70) and higher. Kubernetes on Docker Desktop for Windows is available on these versions and higher. They are downloadable from: - ``` - https://docs.docker.com/docker-for-windows/install/ - ``` - - Once download is completed, the downloaded file can normally be found in your Download folder. Installation is as per normal installations for windows. A restart will be required after this step. - -2. Enable visualization: - - Docker Desktop for Windows requires Microsoft Hyper-V to run. The Docker Desktop installer enables Hyper-V for you. - - If Hyper-V is not enabled, A pop-up messages will request if you would like to turn this on. Read the messages and select 'Ok' if appropriate. - - You need to insure that **VT-X/AMD-v** is enabled from `cmd.exe`: - ```bash - systeminfo - ``` - - If not, from `cmd.exe` run as Administrator and execute: - ```bash - bcdedit /set hypervisorlaunchtype auto - ``` - - A reboot would be required again for the updates to take effect. - -3. Start Docker Desktop for Windows: - - Docker does not start automatically after installation. To start it, select **Docker Desktop** and click on it (or hit Enter). - - When the _whale_ in the status bar stays steady, **Docker Desktop** is up-and-running, and accessible from any terminal window. Note - if the _whale_ is not on the status bar, it will be in the **hidden icon** notifications area, click the up arrow on the taskbar to show it. - - ![Docker is Running](./assets/diagrams/deployment/DockerIsRunning.png) - -### 1.2 Kubernetes environment setup - -1. Setting up the Kubernetes runtime environment within Docker Desktop: - - * Open the Docker Desktop for Windows menu by right-clicking the Docker icon. - * Select **Settings** to open the settings dialog. - * Under the **General** tab you can configure when to start and update Docker. - - * Go to **Advanced** tab - * Increase the CPU allocation to at least 4 - * Increase the Memory allocation to at least 8.0 GiB - - (If your system resource allow, more can be allocated as indicated below.) - - ![Docker Advance Settings](./assets/diagrams/deployment/DockerAdvanceSettings.png) - - Kubernetes on Docker Desktop for Windows is available in 18.02 Edge (win50) and higher, and in 18.06 Stable (win 70) and higher. - - * go to **Kubernetes** tab - * Select **Enable Kubernetes** - * Select **Show system container (advanced)** - - ![Enable Kubernetes](./assets/diagrams/deployment/EnableKubernetes.png) - -2. Set the context to be used. - - As mentioned, the Kubernetes client command, `kubectl` is included and configured to connect to the local Kubernetes server. If you have `kubectl` already installed, be sure to change context to point to **docker-for-desktop**; - - Through `cmd.exe`: - ```bash - kubectl config get-contexts - kubectl config use-context docker-for-desktop - ``` - - Or through the Docker Desktop for Windows menu: - - * right-clicking the Docker icon - * Select **Kubernetes** - * Select **docker-for-desktop** - - ![Docker For Desktop](./assets/diagrams/deployment/DockerForDesktop.png) - -3. Continue setup and configuration from the Kubernetes Dashboard section in the [Mojaloop's deployment guide](./README.md#31-kubernetes-dashboard) document. diff --git a/deployment-guide/releases.md b/deployment-guide/releases.md deleted file mode 100644 index 76d7022e5..000000000 --- a/deployment-guide/releases.md +++ /dev/null @@ -1,39 +0,0 @@ -# Mojaloop Releases - -Below you will find more information on the current and historical releases for Mojaloop. - -Refer to [Versioning Documentation](../contributors-guide/standards/versioning.md) for more information on the release strategy and standards. - -## Current Releases -* Helm: [![Git Releases](https://img.shields.io/github/release/mojaloop/helm.svg?style=flat)](https://github.com/mojaloop/helm/releases) -* Central-Ledger: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-ledger.svg?style=flat)](https://github.com/mojaloop/central-ledger/releases) -* Ml-API-Adapter: [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-api-adapter.svg?style=flat)](https://github.com/mojaloop/ml-api-adapter/releases) -* Central-Settlement: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-settlement.svg?style=flat)](https://github.com/mojaloop/central-settlement/releases) -* Central-Event-Processor: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-event-processor.svg?style=flat)](https://github.com/mojaloop/central-event-processor/releases) -* Email-Notifier: [![Git Releases](https://img.shields.io/github/release/mojaloop/email-notifier.svg?style=flat)](https://github.com/mojaloop/email-notifier/releases) -* Account-Lookup-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/account-lookup-service.svg?style=flat)](https://github.com/mojaloop/account-lookup-service/releases) -* Quoting-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/quoting-service.svg?style=flat)](https://github.com/mojaloop/quoting-service/releases) - - -## Helm Charts Packaged Releases - -Refer to [Mojaloop Helm Repository](../repositories/helm.md) documentation to find out more information about Helm. Below are some of the Helm releases made and timelines. Please note that this is not an exhaustive list. For an exhaustive list, please visit the [Helm releases page](https://github.com/mojaloop/helm/releases). - -| Version | Release Date | Tested | Notes | -| --- | :---: | :---: | --- | -| [8.7.0](https://github.com/mojaloop/helm/releases/tag/v8.7.0) | 2019/12/12 | ✓ | Sprint release | -| [8.4.0](https://github.com/mojaloop/helm/releases/tag/v8.4.0) | 2019/11/12 | ✓ | Sprint release | -| [8.1.0](https://github.com/mojaloop/helm/releases/tag/v8.1.0) | 2019/10/08 | ✓ | Sprint release | -| [7.4.3](https://github.com/mojaloop/helm/releases/tag/v7.4.3) | 2019/08/30 | ✓ | Sprint release | -| [7.4.1](https://github.com/mojaloop/helm/releases/tag/v7.4.1) | 2019/08/23 | ✓ | Sprint release | -| [6.3.1](https://github.com/mojaloop/helm/releases/tag/v6.3.1) | 2019/05/31 | ✓ | Sprint release | -| [5.5.0](https://github.com/mojaloop/helm/releases/tag/v5.5.0) | 2019/04/02 | - | Sprint release | -| [5.4.2](https://github.com/mojaloop/helm/releases/tag/v5.4.2) | 2019/03/29 | ✓ | Sprint release | -| [5.4.1](https://github.com/mojaloop/helm/releases/tag/v5.4.1) | 2019/03/21 | ✓ | Sprint release | -| [5.4.0](https://github.com/mojaloop/helm/releases/tag/v5.4.0) | 2019/03/19 | ✓ | Sprint release | -| [5.2.0](https://github.com/mojaloop/helm/releases/tag/v5.2.0) | 2019/02/20 | ✓ | Sprint release | -| [5.1.3](https://github.com/mojaloop/helm/releases/tag/v5.1.3) | 2019/02/14 | ✓ | Sprint release | -| [5.1.2](https://github.com/mojaloop/helm/releases/tag/v5.1.2) | 2019/02/11 | ✓ | Sprint release | -| [5.1.1](https://github.com/mojaloop/helm/releases/tag/v5.1.1) | 2019/02/08 | ✓ | Sprint release | -| [5.1.0](https://github.com/mojaloop/helm/releases/tag/v5.1.0) | 2019/02/06 | ✓ | Sprint release | -| [4.4.1](https://github.com/mojaloop/helm/releases/tag/v4.4.1) | 2019/01/31 | ✓ | Released at PI4 Convening in Jan 2019 | diff --git a/discussions/Scope-for-Versioning-Proposal.md b/discussions/Scope-for-Versioning-Proposal.md deleted file mode 100644 index caf4a70a4..000000000 --- a/discussions/Scope-for-Versioning-Proposal.md +++ /dev/null @@ -1,91 +0,0 @@ -# Scope for Versioning, A Proposal - -## Overview: - -This is a versioning proposal for Mojaloop that intends to address the Scope of the discussion as part of an initial iteration and then build on it. - -The goal is to come up with a proposal that keeps the versioning Scheme simple to use and clear regarding compatibility issues. However, it also needs to include all the details needed for a Mojaloop Mojaloop eco-system. - - -#### Proposal -A Mojaloop Version _**x.y**_ can be defined that can encompass the versions of all the three APIs included (detailed below). - -In the version _**x.y**_, ‘x’ indicates the Major version and ‘y’ a minor version, similar to the Mojaloop FSPIOP API versioning standards. - -To keep things simple, there is a need to bundle all the components included in the Mojaloop eco-system indicating what all items are included there. - -In effect we may say Mojaloop version _**x.y**_ includes -1. Mojaloop FSPIOP API - -1.1 Maintained by CCB - -1.2 Uses x.y format - -1.3 Currently version v1.0, v1.1 and v2.0 are in the pipeline - -2. Settlement API - -2.1 Maintained by Settlements stream, core-team - -2.2 To use x.y format - -2.3 Currently version v1.1 and v2.0 is in the pipeline - -3. Admin / Operations API - -3.1 Maintained by the core-team - -3.2 To use x.y format - -3.3 Can use version v1.0 - -4. Helm - -4.1 Maintained by Core-team - -4.2 Uses x.y.z format - -4.3 PI, Sprint based versioning. - -4.4 Bundles compatible versions of individual services together - -5. Internal Schemas - -5.1 DB Schema x.y - -5.2 Internal messaging Schema (Kafka) x.y - -**For example**: -Mojaloop **1.0** includes -1. APIs - -1.1 FSPIOP API v1.0 - -1.2 Settlements API v1.1 - -1.3 Admin API v1.0 - -2. Internal schemas - -2.1 DB Schema v1.0 - -2.2 Internal messaging version v1.0 - -3. Helm v9.1.0 - -3.1 Individual services' versions - -3.2 Monitoring components versions - -#### Advantages: -1. The advantage of this strategy is primarily simplicity. A given version say - Mojaloop v1.0 can just be used in discussions which then refers to specific versions of the three APIs - FSPIOP, Settlements, Admin APIs, along with the Helm version that is a bundle of the individual services which are compatible with each other and can be deployed together. Along with these, the Schema versions for the DB and Internal messaging to communicate whether any changes have been made to these or not since the previously released version. - -2. The other advantage, obviously, is that it caters for everyone who may be interested in differing levels of details, whether high level or detailed. Because of the nature of how the major and minor versions, it should be easy for Users and adopters to understand compatibility issues as well. - -#### Compatibility: -As described in the section 3.3 of the API Definition v1.0 - https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning , whether or not a version is backwards compatible, is indicated by the Major version. All versions with the same major version must be compatible while those having different major versions, will most likely not be compatible. - -#### Helm version: -1. Uses x.y.z format -2. Consists of individual service versions -3. Abstracts individual services and makes it manageable diff --git a/discussions/readme.md b/discussions/readme.md deleted file mode 100644 index eac37f946..000000000 --- a/discussions/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -# Discussion Documents - -## PI 9 - -- [Versioning Draft Proposal](./versioning_draft_proposal.md) -- [Code Improvement Project](./code_improvement.md) - -## PI 8 - -- [Cross Border Meeting Notes Day 1](./cross_border_day_1.md) - -- [Cross Border Meeting Notes Day 2](./cross_border_day_2.md) - -- [ISO integration Overivew](./ISO_Integration.md) - -- [Mojaoop Decimal Type; Based on XML Schema Decimal Type](./decimal.md) - -## PI 7 - -- [Workbench Workstream](./workbench.md) - diff --git a/discussions/versioning_draft_proposal.md b/discussions/versioning_draft_proposal.md deleted file mode 100644 index b03436fff..000000000 --- a/discussions/versioning_draft_proposal.md +++ /dev/null @@ -1,190 +0,0 @@ -# Versioning Draft Proposal - ->_Note:_ This document is a living draft of a proposal for versioning within Mojaloop. Once the proposal is ready, it will be submitted to the CCB for approval. - -__Goal:__ -- Propose a standard a new 'Mojaloop Version', which embodies: - 1. API Versions: FSPIOP API, Hub Operations / Admin API, Settlement API - 2. Internal Schema Versions: Database Schema and Internal Messaging Versions - 3. Helm: Individual Service Versions, Monitoring Component Versions - -This is covered in more detail in [Versioning Proposal Scope](./Scope-for-Versioning-Proposal.md) - - -## Definitions: - -- _service_: Mojaloop follows a microservices oriented approach, where a large application is broken down into smaller _micro services_. In this instance, Service refers to a containerized application running as part of a Mojaloop deployment. At the moment, this takes the form of a Docker container running inside of a Kubernetes cluster. e.g. `mojaloop/central-ledger` is the _central-ledger_ service -- _service version_: The version of the given service. This currently doesn't follow semantic versioning, but may in the future e.g. `mojaloop/central-ledger:v10.0.1`. The current approach is described in more detail in the [standards/Versioning doc](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/versioning.md). -- _helm_: Helm is an application package manager that runs on top of Kubernetes. It may also be refered to as the "deployment". A single helm deployment runs many different services, and MAY run multiple versions of the same service simultaneously. We also refer to the deployment as it's repo, `mojaloop/helm` interchangably. -- _helm version_: A helm version is the version of the packaged helm charts, e.g.`mojaloop/helm:v1.1.0` -- _interface_: An interface is the protocol by which a Mojaloop switch interacts with the outside world. This includes interactions with Participants (DFSPs) who transfer funds through the switch, hub operators running a Mojaloop switch, and admins performing administrative functions. -- _api_: Application Programming Interface - in most cases referring to the `FSPIOP-API` a.k.a. Open API for FSP Interoperability defined [here](https://github.com/mojaloop/mojaloop-specification). -- _api version_: The Version of the `FSPIOP-API`, e.g. `FSPIOP-API v1`. For the purposes of this document, it refers to the contract between a Mojaloop Switch and Participants (DFSPs) who implement the FSPIOP-API - - -## 1. [1197](https://github.com/mojaloop/project/issues/1197) Versioning Best Practices: - -> As a switch implementer, I want to research the best practices for managing and implementing versioning, so that we have a clear understanding of well tried approaches. - -### General: - -- Most best practices follow semantic versioning for APIs, this will be covered more in [#1198](https://github.com/mojaloop/project/issues/1198) - -#### Backwards Compatibility: - -> Hub operators will likely need to support multiple versions of the API at the same time, in order to cater for different participants as they can't all be expected to upgrade at the same time. - -- "The Robustness principle, states that you should be “liberal in what you accept and conservative in what you send”. In terms of APIs this implies a certain tolerance in consuming services." [3] - -- Backwards Compatibility vs Backwards Incompatiblity [4]: - - Generally, additions are considered backwards compatible - - Removing or changing names is backwards incompatible - - It's more something to assess on a case-by-case basis, but [Google's API Design Doc](https://cloud.google.com/apis/design/compatibility) helps lay out the cases. - - -### Versioning our APIs - -The [Mojaloop Spec](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning) already outlines many of the decisions made around versioning APIs. - -In terms of common best practices, there are many approaches for requesting different versions, including adding in a version in the url, but let's not worry about this because the spec already lays this out for us, using the HTML vendor extension: [3.3.4.1 Http Accept Header](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3341-http-accept-header) - -As for version negotiation, the spec also states that in the event of an unsupported version being requested by a client, a HTTP status 406 can be returned, along with an error message which describes the supported versions. [3.3.4.3 Non-Acceptable Version Requested by Client](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3343-non-acceptable-version-requested-by-client) - -Another best practice around versioning is specifying to what level clients may request specific apis. - - In a development environment, many APIs will allow specificy up to the BUGFIX version, i.e. vX.X.X - - In production however, this is limited to Major versions only, e.g. v1, v2 - - e.g. The Google API Platform supports only major versions, not minor and patch versions - - Given the new features that may become available with v1.1 of the Mojaloop API, we might want to allow participants to specify MAJOR and MINOR versions, i.e. vX.X. This practice should be avoided however, since minor versions should be backwards compatible - -Participants talking on on the same MAJOR version of the API should be able to interact. Participants on different MAJOR versions are not able to interact. For example, a participant on API v1.1 can send transfers to another participant on v1.0, but not to a different participant on v2.0. - - -### Managing Switch Versions - -> This is a big open question at the moment. Once we have a better idea of the scope of this versioning proposal, from [#1198](https://github.com/mojaloop/project/issues/1198) - -_2 high level approaches:_ -1. __For any given API version, we run one version the service set at a time, which can support multiple versions of the api.__ - -e.g.: -- `mojaloop/helm` release v1.0.0 MAY run `mojaloop/central-ledger:v10.0.0`, which supports `FSPIOP-API v1` only -- A future release of the helm charts: `mojaloop/helm` release v1.1.0 runs `mojaloop/central-ledger:v10.1.0`, which supports `FSPIOP-API v1` and `FSPIOP-API v1.1` - -This approach: -- pushes the version negotiation to the application layer (instead of the transport layer, such as nginx routing based on the `Accept` header) -- may assume database migrations have been run in an intermediate helm relase, e.g. `mojaloop/helm:v1.0.1`, to prepare for the next minor release - - -2. __API versions are closely linked to service versions, such that to support _n_ versions of the API, _n_ service versions must also be running.__ - -e.g.: -- `mojaloop/helm:v1.0.0` runs only 1 version of the central-ledger: `mojaloop/central-ledger:v10.0.0`, and supports `FSPIOP-API v1` only. -- A new deployment of `mojaloop/helm:v1.1.0` is made to support a new MINOR api version. This helm version runs 2 versions of the central-ledger service: `mojaloop/central-ledger:v10.0.0` and `mojaloop/central-ledger:v10.1.0`, alongside one another. -- routing between the different APIs is done at the transport layer, e.g. with an nginx router sending an Accept header of: `application/vnd.interoperability.participants+json;version=1` to `mojaloop/central-ledger:v10.0.0`, and an Accept header of: `application/vnd.interoperability.participants+json;version=1.1` to `mojaloop/central-ledger:v10.1.0` accordingly - - -### Version Management Across Mojaloop Services - -This section deals with how Mojaloop services interact within a given deployment. Here, we attempt to propose questions such as "should an instance of central-ledger:v10.0.1 be able to talk to ml-api-adapter:v10.1.0? How about ml-api-adapter:v11.0.0?"? or "how do we make sure both central-ledger:v10.0.1 and central-ledger:v10.1.0 talk to the database at the same time?" - -There are two places where this happens: -1. Where services interact with saved state - MySQL Percona Databases -2. Where services interact with each other - Apache Kakfa and (some) internal APIs - -This implies we need to version: -- the database schema -- messages within Apache kafka - - need to make sure the right services can appropriately read the right messages. E.g. Can `mojaloop/ml-api-adapter:v10.1.0` publish messages to kafka that `mojaloop/central-ledger:v10.0.1` can understand? - - Q: If we decide to make breaking changes to the message format, how can we ensure that messages in the kafka streams don't get picked up by the wong services? - -### Versioning the Database - -[5] demonstrates zero-downtime deployment approaches with Kubernetes - -Key observations: -- in order to support rollbacks, the services must be both forward and backwards compatible. - - consecutive app versions must be schema compatible -- 'Never deploy any breaking schema changes', separate into multiple deployments instead - -For example, start with a `PERSON` table: -``` -PK ID - NAME - ADDRESS_LINE_1 - ADDRESS_LINE_2 - ZIPCODE - COUNTRY -``` - -And we want to break this down (normalize) into 2 tables, `PERSON` and `ADDRESS`: -``` -#person -PK ID - NAME - -#address -PK ID -FK PERSON_ID - ADDRESS_LINE_1 - ADDRESS_LINE_2 - ZIPCODE - COUNTRY -``` - -If this change were made in one migration, 2 different versions of our application won't be able compatible. Instead, the schema changes must be broken down: - -1. Create `ADDRESS` table - - App use the `PERSON` table data as previously - - Trigger a copy of data to the `ADDRESS` table -2. The `ADDRESS` now becomes the 'source of truth' - - App now uses the `ADDRESS` table data - - Trigger a copy of new added to address to the `PERSON` table -3. Stop copying data -4. Remove extra columns from `PERSON` table - - -This means for any one change of the database schema, multiple application versions will need to be created, and multiple deployments must be made in succession for this change to be made. - -- [5] also notes how simple Kubernetes makes deploying such a change - - rolling upgrade deployments - - Tip: make sure your health endpoint waits for the migrations to finish! - -- Q: so how do we make big changes that touch both the database schema and the API? - - this seems really hard, and would need a lot of coordination - - If we don't design it correctly, it could mean that a single schema change could require all DFSPs to be on board - - This is why I think the API version and Service version should be unrelated. We should be able to deploy a new version of a service (which runs a migration), and supports an old API version - -## Versioning in Kafka Messages - -Currently, we use the lime protocol for our kafka message formats: https://limeprotocol.org/ - -Also refer to the [mojaloop/central-services-stream readme](https://github.com/mojaloop/central-services-stream/blob/master/src/kafka/protocol/readme.md) for more information about the message format. - -The lime protocol provides for a `type`, field, which supports MIME type declarations. So we could potentially handle messages in a manner similar to the API above (e.g. `application/vnd.specific+json`). Versioning messages in this manner means that consumers reading these messages would need to be backwards and fowards compatible (consecutive message versions must be schema compatible). - - -- Q. does it make sense to put the `version` in the Kafka topic? - - One example, ml-api-adapter publishes messages to the `prepare` topic - - If we add versioning to this, `ml-api-adapter:v10.0.0` publishes messages to a `prepare_v10.0` topic, and a new instance of the `ml-api-adapter:v10.1.0` will publish to the `prepare_v10.1` topic. - - subscribers can subscribe to whichever prepare topic they want, or both, depending on their own tolerance to such messages - - This may have some serious performance side effects - - -- Another potential option would be to allow for a message _'adapter'_ in the deployment. Say the `ml-api-adapter:v10.1.0` is producing messages to a `prepare_v10.1` topic, and there is no corresponding `central-ledger` in the deployment to read such messages, we could have an _adapter_, which subcscribes to `prepare_v10.1`, reformats them to be backwards compatible, and publishes them to `prepare_v10.0` in the old format. - -Such an approach would allow for incremental schema changes to the messaging format as services are gradually upgraded. - -All in all, I didn't see too much about this subject, so we'll likely need to return later down the line. - -[6] suggests some approaches, such as using a schema registry for kafka messages, such as [Apache Arvo](https://docs.confluent.io/current/schema-registry/index.html) -- This adds a certain level of 'strictness' to the messages we produce, and will help enforce versioning -- Adds a separate 'schema registry' component, which ensures messages conform to a given schema. This doesn't really help enforce versioning, and leaves the work up to us still, but does give more guarantees about the message formats. - -## References - -- [1] LTS versioning within [nodejs](https://nodejs.org/en/about/releases/). This is a great example of an LTS strategy, and how to clearly communicate such a strategy. -- [2] [Semantic Versioning Reference](https://semver.org/) -- [3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ -- [4] https://cloud.google.com/apis/design/compatibility -- [5] [Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway](https://www.youtube.com/watch?v=RvCnrBZ0DPY) -- [6] [Stackoverflow - Kafka Topic Message Versioning](https://stackoverflow.com/questions/52387013/kafka-topic-message-versioning) \ No newline at end of file diff --git a/docs/.vuepress/components/Foo/Bar.vue b/docs/.vuepress/components/Foo/Bar.vue new file mode 100644 index 000000000..7ee8286a2 --- /dev/null +++ b/docs/.vuepress/components/Foo/Bar.vue @@ -0,0 +1,15 @@ + + + diff --git a/docs/.vuepress/components/demo-component.vue b/docs/.vuepress/components/demo-component.vue new file mode 100644 index 000000000..7d49de79d --- /dev/null +++ b/docs/.vuepress/components/demo-component.vue @@ -0,0 +1,15 @@ + + + diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js new file mode 100644 index 000000000..4c268ea6e --- /dev/null +++ b/docs/.vuepress/config.js @@ -0,0 +1,2261 @@ +const { description } = require('../../package') + +// Determine if we're in PR preview mode +const isPrPreview = process.env.VUEPRESS_IS_PR === 'true' + +// Set base URL for PR previews +const base = isPrPreview ? `/pr/${process.env.VUEPRESS_PR_NUMBER}/` : '/' + +module.exports = { + /** + * Ref:https://v1.vuepress.vuejs.org/config/#title + */ + title: 'Mojaloop Documentation', + /** + * Ref:https://v1.vuepress.vuejs.org/config/#description + */ + description: description, + + /** + * Base URL for the site + * + * ref:https://v1.vuepress.vuejs.org/config/#base + */ + base, + + /** + * Extra tags to be injected to the page HTML `` + * + * ref:https://v1.vuepress.vuejs.org/config/#head + */ + head: [ + ['meta', { name: 'theme-color', content: '#00a3ff' }], + ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }], + ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }] + ], + + theme: 'titanium', + + /** + * Theme configuration, here is the default theme configuration for VuePress. + * + * ref:https://v1.vuepress.vuejs.org/theme/default-theme-config.html + */ + themeConfig: { + repo: 'https://github.com/mojaloop/documentation/', + docsBranch: 'master', + editLinks: true, + docsDir: 'docs', + editLinkText: 'Edit this page on GitHub', + smoothScroll: true, + logo: '/mojaloop_logo_med.png', + sidebarDepth: 2, + lastUpdated: true, + footerCopyright: 'Apache 2.0 Licensed | Copyright © 2020 - 2024 Mojaloop Foundation', + isPrPreview: isPrPreview, + prNumber: process.env.VUEPRESS_PR_NUMBER || '', + locales: { + '/': { + selectText: 'Languages', + label: 'English', + editLinkText: 'Edit this page on GitHub', + lastUpdated: 'Last Updated', + nav: [ + { text: 'Adoption', link: '/adoption/' }, + { text: 'Community', link: '/community/' }, + { text: 'Technical', link: '/technical/' }, + { text: 'Product', link: '/product/' }, + { text: 'Training Program', link: 'https://mojaloop.io/mojaloop-training-program/' } + ], + }, + '/fr/': { + selectText: 'Langues', + label: 'Français', + editLinkText: 'Modifier cette page sur GitHub', + lastUpdated: 'Dernière mise à jour', + nav: [ + { text: 'Adoption', link: '/fr/adoption/' }, + { text: 'Communauté', link: '/fr/community/' }, + { text: 'Technique', link: '/fr/technical/' }, + { text: 'Produit', link: '/fr/product/' }, + { text: 'Programme de formation', link: 'https://mojaloop.io/mojaloop-training-program/' } + ], + }, + }, + nav: [ + { text: 'Adoption', link: '/adoption/' }, + { text: 'Community', link: '/community/' }, + { text: 'Technical', link: '/technical/' }, + { text: 'Product', link: '/product/' }, + { text: 'Training Program', link: 'https://mojaloop.io/mojaloop-training-program/' } + ], + // Ref: https://vuepress.vuejs.org/theme/default-theme-config.html#sidebar + sidebar: { + '/adoption/': [ + { + title: 'Scheme Guide', + collapsable: false, + sidebarDepth: 2, + children: [ + ['Scheme/platform-operating-guideline', 'Platform Operating Guideline Template'], + ['Scheme/scheme-business-rules', 'Scheme Business Rules Template'], + ['Scheme/scheme-key-choices', 'Scheme Key Choices'], + ['Scheme/scheme-participation-agreement', 'Scheme Participation Agreement Template'], + ['Scheme/scheme-uniform-glossary', 'Uniform Glossary Template'], + ] + }, + { + title: 'Hub Operations Guide', + // path: './HubOperations/TechOps/tech-ops-introduction', + collapsable: false, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'Technical Operations Guide', + collapsable: true, + // path: 'HubOperations/TechOps/tech-ops-introduction', + sidebarDepth: 2, + children: [ + 'HubOperations/TechOps/tech-ops-introduction', + 'HubOperations/TechOps/incident-management', + 'HubOperations/TechOps/problem-management', + 'HubOperations/TechOps/change-management', + 'HubOperations/TechOps/release-management', + 'HubOperations/TechOps/defect-triage', + 'HubOperations/TechOps/key-terms-kpis', + 'HubOperations/TechOps/incident-management-escalation-matrix', + 'HubOperations/TechOps/service-level-agreements' + ] + }, + { + title: 'Settlement Management Guide', + collapsable: true, + // path: './HubOperations/Settlement/settlement-management-introduction', + sidebarDepth: 2, + children: [ + 'HubOperations/Settlement/settlement-management-introduction', + 'HubOperations/Settlement/settlement-basic-concepts', + 'HubOperations/Settlement/ledgers-in-the-hub', + ] + }, + { + title: 'Guide to Finance Portal v2', + collapsable: true, + // path: './HubOperations/Onboarding/busops-portal-introduction', + sidebarDepth: 2, + children: [ + 'HubOperations/Portalv2/busops-portal-introduction', + 'HubOperations/Portalv2/settlement-business-process', + 'HubOperations/Portalv2/accessing-the-portal', + 'HubOperations/Portalv2/managing-windows', + 'HubOperations/Portalv2/settling', + 'HubOperations/Portalv2/checking-settlement-details', + 'HubOperations/Portalv2/monitoring-dfsp-financial-details', + 'HubOperations/Portalv2/enabling-disabling-transactions', + 'HubOperations/Portalv2/recording-funds-in-out', + 'HubOperations/Portalv2/updating-ndc', + 'HubOperations/Portalv2/searching-for-transfer-data' + ] + }, + { + title: 'Role-Based Access Control', + collapsable: true, + // path: './HubOperations/RBAC/Role-based-access-control', + sidebarDepth: 2, + children: [ + 'HubOperations/RBAC/Role-based-access-control' + ] + }, + { + title: 'Onboarding Guide for the Hub Operator', + collapsable: true, + // path: './HubOperations/Onboarding/onboarding-introduction', + sidebarDepth: 2, + children: [ + 'HubOperations/Onboarding/onboarding-introduction', + 'HubOperations/Onboarding/business-onboarding', + 'HubOperations/Onboarding/technical-onboarding', + ] + } + ] + } + ], + '/community/': [ + { + title: 'Community', + collapsable: false, + sidebarDepth: 2, + children: [ + ['contributing/contributors-guide', 'Welcome to the community'], + ['mojaloop-roadmap', 'Product Roadmap'], + ['mojaloop-publications', 'Mojaloop Publications'] + ] + }, + { + title: 'Contributing', + collapsable: false, + sidebarDepth: 2, + children: [ + ['contributing/contributors-guide', 'Contributors\' Guide'], + ['contributing/product-engineering-process', 'Product Engineering Process'], + ['contributing/design-review', 'Technical Design & Code Review'], + ['contributing/consequential-change-process', 'Consequential Change Process'], + ['contributing/critical-change-process', 'Critical Change Process'], + ['contributing/new-contributor-checklist', 'New Contributor Checklist'], + ['contributing/pr-guidance', 'Pull Request Guidance'], + ['contributing/code-of-conduct', 'Code of Conduct'], + ['contributing/signing-the-cla', 'Signing the CLA'], + ['contributing/cvd', 'Disclosing Security Vulnerabilities'], + ] + }, + { + title: 'Standards', + collapsable: false, + sidebarDepth: 2, + children: [ + ['standards/guide', 'Our Standards'], + ['standards/invariants', 'Mojaloop Invariants'], + ['standards/versioning', 'Versioning'], + ['standards/creating-new-features', 'Creating New Features'], + ['standards/triaging-bugs', 'Triaging Bugs'], + ['standards/ai_policy', "AI Policy"], + ] + }, + { + title: 'Tools and Technologies', + collapsable: false, + sidebarDepth: 2, + children: [ + ['tools/tools-and-technologies', 'Tools'], + ['tools/pragmatic-rest', 'Pragmatic Rest'], + ['tools/code-quality-metrics', 'Code Quality Metrics'], + ['tools/automated-testing', 'Automated Testing'], + ['tools/cybersecurity', 'Cybersecurity'], + ] + }, + { + title: 'Documentation', + collapsable: false, + children: [ + ['documentation/standards', 'Standards'], + ['documentation/api-documentation', 'API Documentation'], + ['documentation/style-guide', 'Style Guide'], + ] + }, + { + title: 'Archive', + collapsable: false, + sidebarDepth: 4, + children: [ + { + title: 'Notes Archive', + collapsable: true, + path: 'archive/notes/', + children: [ + ['archive/notes/ccb-notes', 'CCB Notes'], + ['archive/notes/da-notes', 'Meeting Notes'], + ['archive/notes/scrum-of-scrum-notes', 'Scrum Notes'] + ] + }, + { + title: 'Discussion Docs Archive', + collapsable: true, + path: 'archive/discussion-docs/', + children: [ + { + title: 'PI 10', + collapsable: true, + children: [ + ['archive/discussion-docs/performance-project', 'Performance Project'], + ['archive/discussion-docs/code-improvement', 'Code Improvement Project'], + ['archive/discussion-docs/cross-border', 'Cross Border Project'], + ['archive/discussion-docs/psip-project', 'PSIP Project'] + ] + }, + { + title: 'PI 9', + collapsable: true, + children: [ + ['archive/discussion-docs/versioning-draft-proposal', 'Versioning Draft Proposal'], + ] + }, + { + title: 'PI 8', + collapsable: true, + children: [ + ['archive/discussion-docs/cross-border-day-1', 'CB Day 1 Meeting Notes'], + ['archive/discussion-docs/cross-border-day-2', 'CB Day 2 Meeting Notes'], + ['archive/discussion-docs/iso-integration', 'ISO Integration Overview'], + ['archive/discussion-docs/mojaloop-decimal', 'Mojaloop Decimal Type'] + ] + }, + { + title: 'PI 7', + collapsable: true, + children: [ + ['archive/discussion-docs/workbench', 'Workbench Workstream'], + ] + } + ] + }, + ] + } + ], + '/technical/': [ + { + title: 'Mojaloop Technical Overview', + collapsable: false, + sidebarDepth: 1, + children: [ + { + title: "Deployment Guide", + // path: 'technical/deployment-guide/readme', + collapsible: true, + sidebarDepth: 2, + children: [ + ['technical/deployment-guide/', 'Deploying Mojaloop'], + 'technical/deployment-guide/deployment-troubleshooting', + 'technical/deployment-guide/upgrade-strategy-guide', + 'technical/deployment-guide/mojaloop-repository-update-guide' + ] + }, + { + title: "Mojaloop Hub", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/overview/', 'Mojaloop Component Overview'], + 'technical/overview/components-PI14', + 'technical/overview/components-PI12', + 'technical/overview/components-PI11', + 'technical/overview/components-PI8', + 'technical/overview/components-PI7', + 'technical/overview/components-PI6', + 'technical/overview/components-PI5', + 'technical/overview/components-PI3' + ] + }, + { + title: "Mojaloop Releases", + path: "technical/releases" + }, + { + title: "Account Lookup Service", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/account-lookup-service/', 'Overview'], + 'technical/account-lookup-service/als-get-participants', + 'technical/account-lookup-service/als-post-participants', + 'technical/account-lookup-service/als-post-participants-batch', + 'technical/account-lookup-service/als-del-participants', + 'technical/account-lookup-service/als-get-parties', + ] + }, + { + title: "Quoting Service", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/quoting-service/', 'Overview'], + 'technical/quoting-service/qs-get-quotes', + 'technical/quoting-service/qs-post-quotes', + 'technical/quoting-service/qs-get-bulk-quotes', + 'technical/quoting-service/qs-post-bulk-quotes' + ] + }, + { + title: "Central Ledger", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/central-ledger/" + }, + { + title: "Admin Operations", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/admin-operations/", + }, + { + title: "POST Participant Limit", + path: "technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit" + }, + { + title: "GET Participant Limit Details", + path: "technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details" + }, + { + title: "GET All Participant Limits", + path: "technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants" + }, + { + title: "POST Participant limits", + path: "technical/central-ledger/admin-operations/1.1.0-post-participant-limits" + }, + { + title: "GET Transfer Status", + path: "technical/central-ledger/admin-operations/1.1.5-get-transfer-status" + }, + { + title: "POST Participant Callback", + path: "technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details" + }, + { + title: "GET Participant Callback", + path: "technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details" + }, + { + title: "GET Participant Position", + path: "technical/central-ledger/admin-operations/4.1.0-get-participant-position-details" + }, + { + title: "GET All Participants Positions", + path: "technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants" + } + ] + }, + { + title: "Transfers Operations", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/" + }, + { + title: "Prepare Handler", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/1.1.0-prepare-transfer-request" + }, + { + title: "Prepare Handler Consume", + path: "technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume" + } + ] + }, + { + title: "Prepare Position Handler", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume" + }, + { + title: "Prepare Position Handler v1.1", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1" + }, + { + title: "Prepare Position Handler", + path: "technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume" + }, + { + title: "Position Handler Consume", + path: "technical/central-ledger/transfers/1.1.2.a-position-handler-consume" + } + ] + }, + { + title: "Fulfil Handler", + path: "technical/central-ledger/transfers/2.1.0-fulfil-transfer-request" + }, + { + title: "Fulfil Handler v1.1", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1" + }, + { + title: "Fulfil Handler Consume", + path: "technical/central-ledger/transfers/2.1.1-fulfil-handler-consume" + }, + { + title: "Fulfil Handler Consume v1.1", + path: "technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1" + } + ] + }, + { + title: "Fulfil Position Handler", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume" + }, + { + title: "Fulfil Position Handler", + path: "technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume" + }, + { + title: "Fulfil Position Handler v1.1", + path: "technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1" + } + ] + }, + { + title: "Fulfil Reject Transfer", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer" + }, + { + title: "Fulfil Reject Transfer (a)", + path: "technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer" + }, + { + title: "Fulfil Handler (Reject-Abort)", + path: "technical/central-ledger/transfers/2.2.1-fulfil-reject-handler" + } + ] + }, + { + title: "Fulfil Reject Transfer v1.1", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1" + }, + { + title: "Fulfil Reject Transfer (a) v1.1", + path: "technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1" + }, + { + title: "Fulfil Handler (Reject-Abort) v1.1", + path: "technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1" + } + ] + }, + { + title: "Notifications", + collapsable: true, + children: [ + { + title: "Notification to Participant (a)", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant" + }, + { + title: "Notification to Participant (a) - v1.1", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1" + }, + { + title: "Notification to Participant (b)", + path: "technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant" + } + ] + }, + { + title: "Reject/Abort", + collapsable: true, + children: [ + { + title: "Abort Position Handler", + path: "technical/central-ledger/transfers/1.3.3-abort-position-handler-consume" + } + ] + }, + { + title: "Timeout", + collapsable: true, + children: [ + { + title: "Transfer Timeout", + path: "technical/central-ledger/transfers/2.3.0-transfer-timeout" + }, + { + title: "Timeout Handler Consume", + path: "technical/central-ledger/transfers/2.3.1-timeout-handler-consume" + } + ] + }, + ] + }, + { + title: "FX Transfer Operations", + collapsable: true, + children: [ + { + title: "Overview", + path: "central-fx-transfers/transfers/" + }, + { + title: "FX Prepare Handler", + collapsable: true, + children: [ + { + title: "Overview", + path: "central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request" + }, + { + title: "FX Prepare Handler Consume", + path: "central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume" + } + ] + }, + { + title: "FX Position Handler", + path: "central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume" + }, + { + title: "FX Fulfil Handler", + path: "central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request" + }, + { + title: "Notifications process", + path: "central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0" + }, + { + title: "Reject/Abort", + path: "central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer" + } + ] + }, + { + title: "Bulk Transfers Operations", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-bulk-transfers/" + }, + { + title: "Bulk Prepare", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview" + }, + { + title: "Bulk Prepare Handler", + path: "technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume" + } + ] + }, + { + title: "Prepare Handler", + collapsable: true, + path: "technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk" + }, + { + title: "Position Handler", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview" + }, + { + title: "Prepare Position Handler Consume", + path: "technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume" + }, + { + title: "Fulfil Position Handler Consume", + path: "technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume" + }, + { + title: "Fulfil Abort Position Handler Consume", + path: "technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort" + } + ] + }, + { + title: "Bulk Fulfil Handler", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview" + }, + { + title: "Bulk Fulfil Handler Consume", + path: "technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume" + }, + { + title: "Fulfil Handler - Commit", + path: "technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk" + }, + { + title: "Fulfil Handler - Reject/Abort", + path: "technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk" + } + ] + }, + { + title: "Bulk Processing Handler", + path: "technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler" + }, + { + title: "Notifications", + collapsable: true, + children: [ + { + title: "Notification to Participant (a)", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant" + }, + { + title: "Notification to Participant (b)", + path: "technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant" + } + ] + }, + { + title: "Timeout", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk" + }, + { + title: "Timeout Handler Consume", + path: "technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume" + } + ] + }, + { + title: "Bulk Abort Overview", + path: "technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk" + }, + { + title: "Get Bulk Transfer Overview", + path: "technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk" + } + ] + } + ] + }, + { + // TODO: Placeholder and temporary link for this section until it can be migrated from legacy docs. + title: 'Central Settlement Services', + path: 'https://docs.mojaloop.io/legacy/mojaloop-technical-overview/central-settlements/' + }, + { + title: "Transaction Requests Service", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/transaction-requests-service/" + }, + { + title: "GET Transaction Requests", + path: "technical/transaction-requests-service/transaction-requests-get" + }, + { + title: "POST Transaction Requests", + path: "technical/transaction-requests-service/transaction-requests-post" + }, + { + title: "Authorizations", + path: "technical/transaction-requests-service/authorizations" + } + ] + }, + { + title: "Central Event Processor Service", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/central-event-processor/" + }, + { + title: "Event Handler (Placeholder)", + path: "technical/central-event-processor/event-handler-placeholder" + }, + { + title: "Notification Handler for Rejections", + path: "technical/central-event-processor/notification-handler-for-rejections" + }, + { + title: "Signature Validation", + path: "technical/central-event-processor/signature-validation" + } + ] + }, + { + title: "Event Framework", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/event-framework/" + }, + { + title: "Event Stream Processor", + path: "technical/event-stream-processor/" + } + ] + }, + { + title: "Security & vulnerability management", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Security Overview", + path: "technical/security/security-overview" + }, + { + title: "Dependency vulnerability management", + path: "technical/security/dependency-vulnerability-management" + } + ] + }, + { + title: "SDK Scheme Adapter", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/sdk-scheme-adapter/" + }, + { + title: "Integration Flow Patterns", + path: "technical/sdk-scheme-adapter/IntegrationFlowPatterns" + }, + { + title: "Request To Pay - support", + path: "technical/sdk-scheme-adapter/RequestToPay" + }, + { + title: "Bulk Integration Flow Patterns", + path: "technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns" + }, + { + title: "Usage tests", + path: "technical/sdk-scheme-adapter/usage/" + }, + { + title: "Support for Bulk Transfers", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Overview", + path: "technical/sdk-scheme-adapter/BulkEnhancements/" + }, + { + title: "API", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design" + }, { + title: "DDD & Event Sourcing Design", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design" + }, { + title: "Tests", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests" + } + ] + } + ] + }, + { + title: "ML Testing Toolkit", + collapsable: true, + children: [ + { + title: "Overview", + path: "technical/ml-testing-toolkit/" + } + ] + } + ] + }, + { + title: 'Reference architecture', + // path: './HubOperations/TechOps/tech-ops-introduction', + collapsable: true, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'Bounded Contexts', + // path: 'reference-architecture/boundedContexts/', // optional, link of the title, which should be an absolute path and must exist + //collapsable: false, + initialOpenGroupIndex: -1, + children: [ + { + title: 'Common Terms & Conventions', + path: 'reference-architecture/boundedContexts/commonTermsConventions/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Account Lookup & Discovery', + path: 'reference-architecture/boundedContexts/accountLookupAndDiscovery/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Accounts & Balances', + path: 'reference-architecture/boundedContexts/accountsAndBalances/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Quoting/Agreements', + path: 'reference-architecture/boundedContexts/quotingAgreement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Auditing', + path: 'reference-architecture/boundedContexts/auditing/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'FSP Interop API', + path: 'reference-architecture/boundedContexts/fspInteropApi/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Logging', + path: 'reference-architecture/boundedContexts/logging/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Notifications And Alerts', + path: 'reference-architecture/boundedContexts/notificationsAndAlerts/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Participant Lifecycle Management', + path: 'reference-architecture/boundedContexts/participantLifecycleManagement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + //{ + // title: 'Platform Monitoring', + // path: '/boundedContexts/platformMonitoring/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + //}, + { + title: 'Reporting', + path: 'reference-architecture/boundedContexts/reporting/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Scheduling', + path: 'reference-architecture/boundedContexts/scheduling/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Security', + path: 'reference-architecture/boundedContexts/security/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Settlements', + path: 'reference-architecture/boundedContexts/settlements/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Third Party API', + path: 'reference-architecture/boundedContexts/thirdPartyApi/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Transfers', + path: 'reference-architecture/boundedContexts/transfers/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + ], + }, + { + title: 'Common Interface List', + path: 'reference-architecture/boundedContexts/commonInterfaces/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + + + { + title: 'How to Implement', + path: 'reference-architecture/howToImplement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Glossary', + path: 'reference-architecture/glossary/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Further Reading', + path: 'reference-architecture/furtherReading/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + } + ] + }, + { + title: 'Mojaloop APIs', + collapsable: false, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'FSPIOP API', + collapsable: true, + sidebarDepth: 4, + children: [ + { + title: 'Overview', + path: 'api/fspiop/', + }, + { + title: 'API Definitions', + collapsable: false, + children: [ + { + title: 'v1.1 (Current)', + path: 'api/fspiop/v1.1/api-definition' + }, + { + title: 'Older versions', + children: [ + ['api/fspiop/v1.0/api-definition', 'v1.0'], + ] + } + ] + }, + { + title: 'Logical Data Model', + path: 'api/fspiop/logical-data-model', + collapsable: true + }, + { + title: 'Generic Transaction Patterns', + path: 'api/fspiop/generic-transaction-patterns', + collapsable: true + }, + { + title: 'Use Cases', + path: 'api/fspiop/use-cases' + }, + { + title: 'JSON Binding Rules', + path: 'api/fspiop/json-binding-rules' + }, + { + title: 'Scheme Rules', + path: 'api/fspiop/scheme-rules', + }, + { + title: 'PKI Best Practices', + path: 'api/fspiop/pki-best-practices', + }, + { + title: 'Signature (v1.1)', + path: 'api/fspiop/v1.1/signature', + }, + { + title: 'Encryption (v1.1)', + path: 'api/fspiop/v1.1/encryption', + }, + { + title: 'Glossary', + path: 'api/fspiop/glossary', + }, + ] + }, + { + title: 'Administration API', + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: 'Overview', + path: 'api/administration/' + }, + { + title: 'Central Ledger API', + path: 'api/administration/central-ledger-api', + }, + ] + }, + { + title: 'Settlement API', + collapsable: true, + sidebarDepth: 2, + children: [ + ['api/settlement/', 'Overview'], + ] + }, + { + title: 'Thirdparty API', + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: 'Overview', + path: 'api/thirdparty/', + }, + { + title: 'Transaction Patterns', + collapsable: true, + children: [ + { + title: 'Transaction Patterns Linking', + path: 'api/thirdparty/transaction-patterns-linking' + }, + { + title: 'Transaction Patterns Transfer', + path: 'api/thirdparty/transaction-patterns-transfer' + } + ] + }, + { + title: 'Data Models', + path: 'api/thirdparty/data-models', + collapsable: true + }, + ] + }, + { + title: 'Misc', + collapsable: true, + children: [ + ['api/fspiop/glossary', 'Glossary'], + ['api/license', 'License'], + ], + } + ] + }, + { + title: 'Mojaloop Hub Operations', + collapsable: true, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'Bounded Contexts', + // path: 'reference-architecture/boundedContexts/', // optional, link of the title, which should be an absolute path and must exist + //collapsable: false, + initialOpenGroupIndex: -1, + children: [ + '', + 'business-operations-framework/SecurityBC', + 'business-operations-framework/Microfrontend-JAMStack', + 'business-operations-framework/ReportingBC', + 'business-operations-framework/ReportDeveloperGuide', + { + title: "Settlement Ops Implementation", + path: 'business-operations-framework/SettlementBC' + } + ] + } + ] + } + ], + '/product/': [ + { + title: 'Mojaloop Features', + collapsable: false, + sidebarDepth: 2, + children: [ + ['features/ml-feature-list', 'About Mojaloop'], + ['features/use-cases', 'Use Cases'], + ['features/transaction', 'Transactions'], + ['features/risk', 'Risk Management'], + ['features/connectivity', 'Onboarding DFSPs'], + ['features/product', 'Portals and Operational Features'], + ['features/tariffs', 'Fees and Tariffs'], + ['features/performance', 'Performance'], + ['features/deployment', 'Deploying Mojaloop'], + ['features/security', 'Mojaloop Security'], + ['features/engineering', 'Engineering Principles'], + ['features/invariants', 'Invariants'], + ['features/development', 'Continuous Development']] + } + ], + '/fr/adoption/': [ + { + title: 'Guide du Schéma', + collapsable: false, + sidebarDepth: 2, + children: [ + ['Scheme/platform-operating-guideline', 'Modèle de Directive Opérationnelle de la Plateforme'], + ['Scheme/scheme-business-rules', 'Modèle de Règles Commerciales du Schéma'], + ['Scheme/scheme-key-choices', 'Choix Clés du Schéma'], + ['Scheme/scheme-participation-agreement', 'Modèle d\'Accord de Participation au Schéma'], + ['Scheme/scheme-uniform-glossary', 'Modèle de Glossaire Uniforme'], + ] + }, + { + title: 'Guide des Opérations du Hub', + collapsable: false, + sidebarDepth: 1, + children: [ + { + title: 'Guide des Opérations Techniques', + collapsable: true, + sidebarDepth: 2, + children: [ + 'HubOperations/TechOps/tech-ops-introduction', + 'HubOperations/TechOps/incident-management', + 'HubOperations/TechOps/problem-management', + 'HubOperations/TechOps/change-management', + 'HubOperations/TechOps/release-management', + 'HubOperations/TechOps/defect-triage', + 'HubOperations/TechOps/key-terms-kpis', + 'HubOperations/TechOps/incident-management-escalation-matrix', + 'HubOperations/TechOps/service-level-agreements' + ] + }, + { + title: 'Guide de Gestion des Règlements', + collapsable: true, + sidebarDepth: 2, + children: [ + 'HubOperations/Settlement/settlement-management-introduction', + 'HubOperations/Settlement/settlement-basic-concepts', + 'HubOperations/Settlement/ledgers-in-the-hub', + ] + }, + { + title: 'Guide du Portail Finance v2', + collapsable: true, + sidebarDepth: 2, + children: [ + 'HubOperations/Portalv2/busops-portal-introduction', + 'HubOperations/Portalv2/settlement-business-process', + 'HubOperations/Portalv2/accessing-the-portal', + 'HubOperations/Portalv2/managing-windows', + 'HubOperations/Portalv2/settling', + 'HubOperations/Portalv2/checking-settlement-details', + 'HubOperations/Portalv2/monitoring-dfsp-financial-details', + 'HubOperations/Portalv2/enabling-disabling-transactions', + 'HubOperations/Portalv2/recording-funds-in-out', + 'HubOperations/Portalv2/updating-ndc', + 'HubOperations/Portalv2/searching-for-transfer-data' + ] + }, + { + title: 'Contrôle d\'Accès Basé sur les Rôles', + collapsable: true, + sidebarDepth: 2, + children: [ + 'HubOperations/RBAC/Role-based-access-control' + ] + }, + { + title: 'Guide d\'Intégration pour l\'Opérateur du Hub', + collapsable: true, + sidebarDepth: 2, + children: [ + 'HubOperations/Onboarding/onboarding-introduction', + 'HubOperations/Onboarding/business-onboarding', + 'HubOperations/Onboarding/technical-onboarding', + ] + } + ] + } + ], + '/fr/technical/': [ + { + title: 'Aperçu technique de Mojaloop', + collapsable: false, + sidebarDepth: 1, + children: [ + { + title: "Guide de déploiement", + // path: 'technical/deployment-guide/readme', + collapsible: true, + sidebarDepth: 2, + children: [ + ['technical/deployment-guide/', 'Déploiement de Mojaloop'], + 'technical/deployment-guide/deployment-troubleshooting', + 'technical/deployment-guide/upgrade-strategy-guide', + 'technical/deployment-guide/mojaloop-repository-update-guide' + ] + }, + { + title: "Mojaloop Hub", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/overview/', 'Aperçu des composants Mojaloop'], + 'technical/overview/components-PI14', + 'technical/overview/components-PI12', + 'technical/overview/components-PI11', + 'technical/overview/components-PI8', + 'technical/overview/components-PI7', + 'technical/overview/components-PI6', + 'technical/overview/components-PI5', + ['technical/overview/components-PI3', 'Vue d\'ensemble PI3'] + ] + }, + { + title: "Versions Mojaloop", + path: "technical/releases" + }, + { + title: "Service de recherche de comptes", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/account-lookup-service/', 'Aperçu'], + ['technical/account-lookup-service/als-get-participants', 'GET — Participants'], + 'technical/account-lookup-service/als-post-participants', + 'technical/account-lookup-service/als-post-participants-batch', + 'technical/account-lookup-service/als-del-participants', + ['technical/account-lookup-service/als-get-parties', 'GET — Parties'], + ] + }, + { + title: "Service de devis", + collapsable: true, + sidebarDepth: 2, + children: [ + ['technical/quoting-service/', 'Service de devis'], + 'technical/quoting-service/qs-get-quotes', + 'technical/quoting-service/qs-post-quotes', + 'technical/quoting-service/qs-get-bulk-quotes', + 'technical/quoting-service/qs-post-bulk-quotes' + ] + }, + { + title: "Grand livre central", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/" + }, + { + title: "Opérations d'administration", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/admin-operations/", + }, + { + title: "POST Limite de participant", + path: "technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit" + }, + { + title: "GET Détails de la limite de participant", + path: "technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details" + }, + { + title: "GET Limites de tous les participants", + path: "technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants" + }, + { + title: "POST Limites de participant", + path: "technical/central-ledger/admin-operations/1.1.0-post-participant-limits" + }, + { + title: "GET Statut du transfert", + path: "technical/central-ledger/admin-operations/1.1.5-get-transfer-status" + }, + { + title: "POST Callback du participant", + path: "technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details" + }, + { + title: "GET Callback du participant", + path: "technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details" + }, + { + title: "GET Position du participant", + path: "technical/central-ledger/admin-operations/4.1.0-get-participant-position-details" + }, + { + title: "GET Positions de tous les participants", + path: "technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants" + } + ] + }, + { + title: "Opérations de transferts", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/" + }, + { + title: "Gestionnaire de préparation", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/1.1.0-prepare-transfer-request" + }, + { + title: "Consommation du gestionnaire de préparation", + path: "technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume" + } + ] + }, + { + title: "Gestionnaire de position de préparation", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume" + }, + { + title: "Gestionnaire de position de préparation v1.1", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1" + }, + { + title: "Gestionnaire de position de préparation", + path: "technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume" + }, + { + title: "Consommation du gestionnaire de position", + path: "technical/central-ledger/transfers/1.1.2.a-position-handler-consume" + } + ] + }, + { + title: "Gestionnaire de clôture", + path: "technical/central-ledger/transfers/2.1.0-fulfil-transfer-request" + }, + { + title: "Gestionnaire de clôture v1.1", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1" + }, + { + title: "Consommation du gestionnaire de clôture", + path: "technical/central-ledger/transfers/2.1.1-fulfil-handler-consume" + }, + { + title: "Consommation du gestionnaire de clôture v1.1", + path: "technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1" + } + ] + }, + { + title: "Gestionnaire de position de clôture", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/1.3.0-position-handler-consume" + }, + { + title: "Gestionnaire de position de clôture", + path: "technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume" + }, + { + title: "Gestionnaire de position de clôture v1.1", + path: "technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1" + } + ] + }, + { + title: "Transfert rejeté lors de la clôture", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer" + }, + { + title: "Transfert rejeté (a)", + path: "technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer" + }, + { + title: "Gestionnaire de clôture (Rejet-Abandon)", + path: "technical/central-ledger/transfers/2.2.1-fulfil-reject-handler" + } + ] + }, + { + title: "Transfert rejeté lors de la clôture v1.1", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1" + }, + { + title: "Transfert rejeté (a) v1.1", + path: "technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1" + }, + { + title: "Gestionnaire de clôture (Rejet-Abandon) v1.1", + path: "technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1" + } + ] + }, + { + title: "Notifications", + collapsable: true, + children: [ + { + title: "Notification au participant (a)", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant" + }, + { + title: "Notification au participant (a) - v1.1", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1" + }, + { + title: "Notification au participant (b)", + path: "technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant" + } + ] + }, + { + title: "Rejet/Abandon", + collapsable: true, + children: [ + { + title: "Gestionnaire d'abandon de position", + path: "technical/central-ledger/transfers/1.3.3-abort-position-handler-consume" + } + ] + }, + { + title: "Expiration", + collapsable: true, + children: [ + { + title: "Expiration du transfert", + path: "technical/central-ledger/transfers/2.3.0-transfer-timeout" + }, + { + title: "Consommation du gestionnaire d'expiration", + path: "technical/central-ledger/transfers/2.3.1-timeout-handler-consume" + } + ] + }, + ] + }, + { + title: "Opérations de transfert FX", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "central-fx-transfers/transfers/" + }, + { + title: "Gestionnaire de préparation FX", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request" + }, + { + title: "Consommation du gestionnaire de préparation FX", + path: "central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume" + } + ] + }, + { + title: "Gestionnaire de position FX", + path: "central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume" + }, + { + title: "Gestionnaire de clôture FX", + path: "central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request" + }, + { + title: "Processus de notifications", + path: "central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0" + }, + { + title: "Rejet/Abandon", + path: "central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer" + } + ] + }, + { + title: "Opérations de transferts groupés", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-bulk-transfers/" + }, + { + title: "Préparation groupée", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview" + }, + { + title: "Gestionnaire de préparation groupée", + path: "technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume" + } + ] + }, + { + title: "Gestionnaire de préparation", + collapsable: true, + path: "technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk" + }, + { + title: "Gestionnaire de position", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview" + }, + { + title: "Consommation du gestionnaire de position de préparation", + path: "technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume" + }, + { + title: "Consommation du gestionnaire de position de clôture", + path: "technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume" + }, + { + title: "Consommation du gestionnaire d'abandon de position de clôture", + path: "technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort" + } + ] + }, + { + title: "Gestionnaire de clôture groupée", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview" + }, + { + title: "Consommation du gestionnaire de clôture groupée", + path: "technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume" + }, + { + title: "Gestionnaire de clôture - Confirmation", + path: "technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk" + }, + { + title: "Gestionnaire de clôture - Rejet/Abandon", + path: "technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk" + } + ] + }, + { + title: "Gestionnaire de traitement groupé", + path: "technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler" + }, + { + title: "Notifications", + collapsable: true, + children: [ + { + title: "Notification au participant (a)", + path: "technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant" + }, + { + title: "Notification au participant (b)", + path: "technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant" + } + ] + }, + { + title: "Expiration", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk" + }, + { + title: "Consommation du gestionnaire d'expiration", + path: "technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume" + } + ] + }, + { + title: "Aperçu sur l'abandon groupé", + path: "technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk" + }, + { + title: "Aperçu sur la récupération du transfert groupé", + path: "technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk" + } + ] + } + ] + }, + { + // TODO: Placeholder and temporary link for this section until it can be migrated from legacy docs. + title: 'Services de règlement central', + path: 'https://docs.mojaloop.io/legacy/mojaloop-technical-overview/central-settlements/' + }, + { + title: "Service des demandes de transaction", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/transaction-requests-service/" + }, + { + title: "GET Demandes de transaction", + path: "technical/transaction-requests-service/transaction-requests-get" + }, + { + title: "POST Demandes de transaction", + path: "technical/transaction-requests-service/transaction-requests-post" + }, + { + title: "Autorisations", + path: "technical/transaction-requests-service/authorizations" + } + ] + }, + { + title: "Service de traitement des événements centraux", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/central-event-processor/" + }, + { + title: "Gestionnaire d'événements (Placeholder)", + path: "technical/central-event-processor/event-handler-placeholder" + }, + { + title: "Gestionnaire de notification pour les rejets", + path: "technical/central-event-processor/notification-handler-for-rejections" + }, + { + title: "Validation de signature", + path: "technical/central-event-processor/signature-validation" + } + ] + }, + { + title: "Cadre d'événements", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/event-framework/" + }, + { + title: "Processeur de flux d'événements", + path: "technical/event-stream-processor/" + } + ] + }, + { + title: "Gestion de la sécurité & des vulnérabilités", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu de la sécurité", + path: "technical/security/security-overview" + }, + { + title: "Gestion des vulnérabilités des dépendances", + path: "technical/security/dependency-vulnerability-management" + } + ] + }, + { + title: "Adaptateur SDK Scheme", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/sdk-scheme-adapter/" + }, + { + title: "Modèles de flux d'intégration", + path: "technical/sdk-scheme-adapter/IntegrationFlowPatterns" + }, + { + title: "Request To Pay - support", + path: "technical/sdk-scheme-adapter/RequestToPay" + }, + { + title: "Modèles de flux d'intégration groupée", + path: "technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns" + }, + { + title: "Tests d'utilisation", + path: "technical/sdk-scheme-adapter/usage/" + }, + { + title: "Support pour les transferts groupés", + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: "Aperçu", + path: "technical/sdk-scheme-adapter/BulkEnhancements/" + }, + { + title: "API", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design" + }, { + title: "Conception DDD & Event Sourcing", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design" + }, { + title: "Tests", + path: "technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests" + } + ] + } + ] + }, + { + title: "ML Testing Toolkit", + collapsable: true, + children: [ + { + title: "Aperçu", + path: "technical/ml-testing-toolkit/" + } + ] + } + ] + }, + { + title: 'Architecture de référence', + // path: './HubOperations/TechOps/tech-ops-introduction', + collapsable: true, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'Contextes délimités', + // path: 'reference-architecture/boundedContexts/', // optional, link of the title, which should be an absolute path and must exist + //collapsable: false, + initialOpenGroupIndex: -1, + children: [ + { + title: 'Termes communs & conventions', + path: 'reference-architecture/boundedContexts/commonTermsConventions/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Recherche & découverte de compte', + path: 'reference-architecture/boundedContexts/accountLookupAndDiscovery/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Comptes & soldes', + path: 'reference-architecture/boundedContexts/accountsAndBalances/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Cotation/Accords', + path: 'reference-architecture/boundedContexts/quotingAgreement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Audit', + path: 'reference-architecture/boundedContexts/auditing/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'API FSP Interop', + path: 'reference-architecture/boundedContexts/fspInteropApi/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Journalisation', + path: 'reference-architecture/boundedContexts/logging/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Notifications et alertes', + path: 'reference-architecture/boundedContexts/notificationsAndAlerts/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Participant Lifecycle Management', + path: 'reference-architecture/boundedContexts/participantLifecycleManagement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + //{ + // title: 'Supervision de la plateforme', + // path: '/boundedContexts/platformMonitoring/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + //}, + { + title: 'BC Reporting', + path: 'reference-architecture/boundedContexts/reporting/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Scheduling BC', + path: 'reference-architecture/boundedContexts/scheduling/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'BC Security', + path: 'reference-architecture/boundedContexts/security/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Settlements BC', + path: 'reference-architecture/boundedContexts/settlements/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'BC Third Party API', + path: 'reference-architecture/boundedContexts/thirdPartyApi/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'BC Transferts', + path: 'reference-architecture/boundedContexts/transfers/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + ], + }, + { + title: 'Liste des Interfaces Communes', + path: 'reference-architecture/boundedContexts/commonInterfaces/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + + + { + title: 'Comment implémenter', + path: 'reference-architecture/howToImplement/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Glossaire', + path: 'reference-architecture/glossary/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + }, + { + title: 'Pour aller plus loin', + path: 'reference-architecture/furtherReading/', // optional, link of the title, which should be an absolute path and must exist + // children: [ /* ... */ ], + } + ] + }, + { + title: 'APIs Mojaloop', + collapsable: false, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'API FSPIOP', + collapsable: true, + sidebarDepth: 4, + children: [ + { + title: 'Aperçu', + path: 'api/fspiop/', + }, + { + title: 'Définitions API', + collapsable: false, + children: [ + { + title: 'v1.1 (Actuel)', + path: 'api/fspiop/v1.1/api-definition' + }, + { + title: 'Versions précédentes', + children: [ + ['api/fspiop/v1.0/api-definition', 'v1.0'], + ] + } + ] + }, + { + title: 'Modèle de données logique', + path: 'api/fspiop/logical-data-model', + collapsable: true + }, + { + title: 'Modèles de transactions génériques', + path: 'api/fspiop/generic-transaction-patterns', + collapsable: true + }, + { + title: 'Cas d\'utilisation', + path: 'api/fspiop/use-cases' + }, + { + title: 'Règles de liaison JSON', + path: 'api/fspiop/json-binding-rules' + }, + { + title: 'Règles du schéma', + path: 'api/fspiop/scheme-rules', + }, + { + title: 'Bonnes pratiques PKI', + path: 'api/fspiop/pki-best-practices', + }, + { + title: 'Signature (v1.1)', + path: 'api/fspiop/v1.1/signature', + }, + { + title: 'Chiffrement (v1.1)', + path: 'api/fspiop/v1.1/encryption', + }, + { + title: 'Glossaire', + path: 'api/fspiop/glossary', + }, + ] + }, + { + title: 'API d\'administration', + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: 'Aperçu', + path: 'api/administration/' + }, + { + title: 'API du grand livre central', + path: 'api/administration/central-ledger-api', + }, + ] + }, + { + title: 'API de règlement', + collapsable: true, + sidebarDepth: 2, + children: [ + ['api/settlement/', 'Aperçu'], + ] + }, + { + title: 'API tierce partie', + collapsable: true, + sidebarDepth: 2, + children: [ + { + title: 'Aperçu', + path: 'api/thirdparty/', + }, + { + title: 'Modèles de transactions', + collapsable: true, + children: [ + { + title: 'Modèle de transaction Linking', + path: 'api/thirdparty/transaction-patterns-linking' + }, + { + title: 'Modèle de transaction Transfert', + path: 'api/thirdparty/transaction-patterns-transfer' + } + ] + }, + { + title: 'Modèles de données', + path: 'api/thirdparty/data-models', + collapsable: true + }, + ] + }, + { + title: 'Divers', + collapsable: true, + children: [ + ['api/fspiop/glossary', 'Glossaire'], + ['api/license', 'Licence'], + ], + } + ] + }, + { + title: 'Opérations du Hub Mojaloop', + collapsable: true, // optional, defaults to true + sidebarDepth: 1, // optional, defaults to 1 + children: [ + { + title: 'Contextes délimités', + // path: 'reference-architecture/boundedContexts/', // optional, link of the title, which should be an absolute path and must exist + //collapsable: false, + initialOpenGroupIndex: -1, + children: [ + '', + 'business-operations-framework/SecurityBC', + 'business-operations-framework/Microfrontend-JAMStack', + 'business-operations-framework/ReportingBC', + 'business-operations-framework/ReportDeveloperGuide', + { + title: "Implémentation des opérations de règlement", + path: 'business-operations-framework/SettlementBC' + } + ] + } + ] + } + ], + '/fr/community/': [ + { + title: 'Communauté', + collapsable: false, + sidebarDepth: 2, + children: [ + ['contributing/contributors-guide', 'Bienvenue dans la communauté'], + ['mojaloop-roadmap', 'Feuille de route du produit'], + ['mojaloop-publications', 'Publications Mojaloop'] + ] + }, + { + title: 'Contribution', + collapsable: false, + sidebarDepth: 2, + children: [ + ['contributing/contributors-guide', 'Guide du contributeur'], + ['contributing/product-engineering-process', 'Processus d’ingénierie produit'], + ['contributing/design-review', 'Revue technique et de code'], + ['contributing/consequential-change-process', 'Processus de changement conséquent'], + ['contributing/critical-change-process', 'Processus de changement critique'], + ['contributing/new-contributor-checklist', 'Liste de contrôle du nouveau contributeur'], + ['contributing/pr-guidance', 'Directives pour les pull requests'], + ['contributing/code-of-conduct', 'Code de conduite'], + ['contributing/signing-the-cla', 'Signature de la CLA'], + ['contributing/cvd', 'Divulgation des vulnérabilités de sécurité'], + ] + }, + { + title: 'Standards', + collapsable: false, + sidebarDepth: 2, + children: [ + ['standards/guide', 'Nos standards'], + ['standards/invariants', 'Invariants Mojaloop'], + ['standards/versioning', 'Gestion des versions'], + ['standards/creating-new-features', 'Création de nouvelles fonctionnalités'], + ['standards/triaging-bugs', 'Tri des bogues'], + ['standards/ai_policy', 'Politique sur l’usage responsable de l’IA'], + ] + }, + { + title: 'Outils et technologies', + collapsable: false, + sidebarDepth: 2, + children: [ + ['tools/tools-and-technologies', 'Outils'], + ['tools/pragmatic-rest', 'REST pragmatique'], + ['tools/code-quality-metrics', 'Métriques de qualité du code'], + ['tools/automated-testing', 'Tests automatisés'], + ['tools/cybersecurity', 'Cybersécurité'], + ] + }, + { + title: 'Documentation', + collapsable: false, + children: [ + ['documentation/standards', 'Standards'], + ['documentation/api-documentation', 'Documentation API'], + ['documentation/style-guide', 'Guide de style'], + ] + }, + { + title: 'Archive', + collapsable: false, + sidebarDepth: 4, + children: [ + { + title: 'Archive des notes', + collapsable: true, + path: 'archive/notes/', + children: [ + ['archive/notes/ccb-notes', 'Notes du CCB'], + ['archive/notes/da-notes', 'Notes de réunion'], + ['archive/notes/scrum-of-scrum-notes', 'Notes du Scrum'], + ] + }, + { + title: 'Archive des docs de discussion', + collapsable: true, + path: 'archive/discussion-docs/', + children: [ + { + title: 'PI 10', + collapsable: true, + children: [ + ['archive/discussion-docs/performance-project', 'Projet performance'], + ['archive/discussion-docs/code-improvement', 'Projet amélioration du code'], + ['archive/discussion-docs/cross-border', 'Projet transfrontalier'], + ['archive/discussion-docs/psip-project', 'Projet PSIP'], + ] + }, + { + title: 'PI 9', + collapsable: true, + children: [ + ['archive/discussion-docs/versioning-draft-proposal', 'Proposition de versionnement (brouillon)'], + ] + }, + { + title: 'PI 8', + collapsable: true, + children: [ + ['archive/discussion-docs/cross-border-day-1', 'Notes réunion transfrontalier — jour 1'], + ['archive/discussion-docs/cross-border-day-2', 'Notes réunion transfrontalier — jour 2'], + ['archive/discussion-docs/iso-integration', 'Aperçu intégration ISO'], + ['archive/discussion-docs/mojaloop-decimal', 'Type décimal Mojaloop'], + ] + }, + { + title: 'PI 7', + collapsable: true, + children: [ + ['archive/discussion-docs/workbench', 'Fil de travail Lab / établi'], + ] + } + ] + }, + ] + } + ], + } + }, + + /** + * Apply plugins,ref:https://v1.vuepress.vuejs.org/zh/plugin/ + */ + plugins: [ + '@vuepress/plugin-back-to-top', + '@vuepress/plugin-medium-zoom', + 'versioning' + ], + + locales: { + '/': { + lang: 'en-US', + title: 'Mojaloop Documentation', + description: '', + }, + '/fr/': { + lang: 'fr-FR', + title: 'Documentation Mojaloop', + description: 'Documentation officielle du projet Mojaloop', + }, + }, +}; diff --git a/docs/.vuepress/enhanceApp.js b/docs/.vuepress/enhanceApp.js new file mode 100644 index 000000000..be9e13dfe --- /dev/null +++ b/docs/.vuepress/enhanceApp.js @@ -0,0 +1,37 @@ +/** + * Client app enhancement file. + * + * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements + */ + +const LOCALE_STORAGE_KEY = 'mojaloop-docs-locale-redirected' + +function getBrowserLang () { + if (typeof navigator === 'undefined') return 'en' + const lang = navigator.language || navigator.userLanguage || '' + return lang.toLowerCase().split('-')[0] +} + +export default ({ + Vue, + options, + router, + siteData, + isServer +}) => { + if (isServer) return + + router.afterEach((to) => { + const alreadyRedirected = sessionStorage.getItem(LOCALE_STORAGE_KEY) + if (alreadyRedirected) return + + sessionStorage.setItem(LOCALE_STORAGE_KEY, '1') + + const browserLang = getBrowserLang() + const isOnFrenchPage = to.path.startsWith('/fr/') + + if (browserLang === 'fr' && !isOnFrenchPage) { + return router.replace('/fr' + to.path) + } + }) +} diff --git a/docs/.vuepress/public/BizOps-Framework-BizOps-Framework.png b/docs/.vuepress/public/BizOps-Framework-BizOps-Framework.png new file mode 100644 index 000000000..a3a0a1290 Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-BizOps-Framework.png differ diff --git a/docs/.vuepress/public/BizOps-Framework-IaC-3.xx-&-Mojaloop-13.xx.png b/docs/.vuepress/public/BizOps-Framework-IaC-3.xx-&-Mojaloop-13.xx.png new file mode 100644 index 000000000..dd0df8f1e Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-IaC-3.xx-&-Mojaloop-13.xx.png differ diff --git a/docs/.vuepress/public/BizOps-Framework-IaC-4.xx-&-Mojaloop-13.xx.png b/docs/.vuepress/public/BizOps-Framework-IaC-4.xx-&-Mojaloop-13.xx.png new file mode 100644 index 000000000..31b84b3bd Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-IaC-4.xx-&-Mojaloop-13.xx.png differ diff --git a/docs/.vuepress/public/BizOps-Framework-Micro-frontend-deploy.png b/docs/.vuepress/public/BizOps-Framework-Micro-frontend-deploy.png new file mode 100644 index 000000000..5e1436e18 Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-Micro-frontend-deploy.png differ diff --git a/docs/.vuepress/public/BizOps-Framework-Security-BC.png b/docs/.vuepress/public/BizOps-Framework-Security-BC.png new file mode 100644 index 000000000..e1795ba89 Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-Security-BC.png differ diff --git a/docs/.vuepress/public/BizOps-Framework-Settlements.png b/docs/.vuepress/public/BizOps-Framework-Settlements.png new file mode 100644 index 000000000..460eb6637 Binary files /dev/null and b/docs/.vuepress/public/BizOps-Framework-Settlements.png differ diff --git a/docs/.vuepress/public/BusinessFlowView.png b/docs/.vuepress/public/BusinessFlowView.png new file mode 100644 index 000000000..95f1af385 Binary files /dev/null and b/docs/.vuepress/public/BusinessFlowView.png differ diff --git a/docs/.vuepress/public/PM4ML_system_architecture.png b/docs/.vuepress/public/PM4ML_system_architecture.png new file mode 100644 index 000000000..340db13a2 Binary files /dev/null and b/docs/.vuepress/public/PM4ML_system_architecture.png differ diff --git a/docs/.vuepress/public/Reporting-&-Auditing-Overview.png b/docs/.vuepress/public/Reporting-&-Auditing-Overview.png new file mode 100644 index 000000000..d55f8e71b Binary files /dev/null and b/docs/.vuepress/public/Reporting-&-Auditing-Overview.png differ diff --git a/docs/.vuepress/public/RestReportingArchitecture.drawio.png b/docs/.vuepress/public/RestReportingArchitecture.drawio.png new file mode 100644 index 000000000..4c3766373 Binary files /dev/null and b/docs/.vuepress/public/RestReportingArchitecture.drawio.png differ diff --git a/docs/.vuepress/public/TLS_connection.svg b/docs/.vuepress/public/TLS_connection.svg new file mode 100644 index 000000000..d4afa9830 --- /dev/null +++ b/docs/.vuepress/public/TLS_connection.svg @@ -0,0 +1,47 @@ +ClientClientServerServerTLS session initServer certificate exchange1Request server certificate2Server certificateServer certificatesigned by server's CA3Validate certificateClient certificate exchange4Request client certificate5Client certificateClient certificate issued by clientand signed by server's CA6Validate certificateTLS session initiated \ No newline at end of file diff --git a/docs/.vuepress/public/action_add_withdraw.png b/docs/.vuepress/public/action_add_withdraw.png new file mode 100644 index 000000000..fbe9126c6 Binary files /dev/null and b/docs/.vuepress/public/action_add_withdraw.png differ diff --git a/docs/.vuepress/public/action_change_net_debit_cap.png b/docs/.vuepress/public/action_change_net_debit_cap.png new file mode 100644 index 000000000..37478eebe Binary files /dev/null and b/docs/.vuepress/public/action_change_net_debit_cap.png differ diff --git a/docs/.vuepress/public/action_update_ndc.png b/docs/.vuepress/public/action_update_ndc.png new file mode 100644 index 000000000..55c3feea6 Binary files /dev/null and b/docs/.vuepress/public/action_update_ndc.png differ diff --git a/docs/.vuepress/public/add_withdraw_funds.png b/docs/.vuepress/public/add_withdraw_funds.png new file mode 100644 index 000000000..62f0dfebc Binary files /dev/null and b/docs/.vuepress/public/add_withdraw_funds.png differ diff --git a/docs/.vuepress/public/change_mgmt_flow.png b/docs/.vuepress/public/change_mgmt_flow.png new file mode 100644 index 000000000..4a6883c13 Binary files /dev/null and b/docs/.vuepress/public/change_mgmt_flow.png differ diff --git a/docs/.vuepress/public/check_settlement_details.png b/docs/.vuepress/public/check_settlement_details.png new file mode 100644 index 000000000..6917cd179 Binary files /dev/null and b/docs/.vuepress/public/check_settlement_details.png differ diff --git a/docs/.vuepress/public/client.png b/docs/.vuepress/public/client.png new file mode 100644 index 000000000..b296c0350 Binary files /dev/null and b/docs/.vuepress/public/client.png differ diff --git a/docs/.vuepress/public/clientgraphql.png b/docs/.vuepress/public/clientgraphql.png new file mode 100644 index 000000000..84a201287 Binary files /dev/null and b/docs/.vuepress/public/clientgraphql.png differ diff --git a/docs/.vuepress/public/close.png b/docs/.vuepress/public/close.png new file mode 100644 index 000000000..c87338a2d Binary files /dev/null and b/docs/.vuepress/public/close.png differ diff --git a/docs/.vuepress/public/confirm_action_add_withdraw_funds.png b/docs/.vuepress/public/confirm_action_add_withdraw_funds.png new file mode 100644 index 000000000..3140e66bb Binary files /dev/null and b/docs/.vuepress/public/confirm_action_add_withdraw_funds.png differ diff --git a/docs/.vuepress/public/confirm_action_update_ndc.png b/docs/.vuepress/public/confirm_action_update_ndc.png new file mode 100644 index 000000000..983a5330b Binary files /dev/null and b/docs/.vuepress/public/confirm_action_update_ndc.png differ diff --git a/docs/.vuepress/public/defect_triage.png b/docs/.vuepress/public/defect_triage.png new file mode 100644 index 000000000..5940d6be2 Binary files /dev/null and b/docs/.vuepress/public/defect_triage.png differ diff --git a/docs/.vuepress/public/dfsp_financial_positions_2.png b/docs/.vuepress/public/dfsp_financial_positions_2.png new file mode 100644 index 000000000..b549907fa Binary files /dev/null and b/docs/.vuepress/public/dfsp_financial_positions_2.png differ diff --git a/docs/.vuepress/public/disable_dfsp_position_ledger.png b/docs/.vuepress/public/disable_dfsp_position_ledger.png new file mode 100644 index 000000000..5ae883f7c Binary files /dev/null and b/docs/.vuepress/public/disable_dfsp_position_ledger.png differ diff --git a/docs/.vuepress/public/enable_dfsp_position_ledger.png b/docs/.vuepress/public/enable_dfsp_position_ledger.png new file mode 100644 index 000000000..ef732094e Binary files /dev/null and b/docs/.vuepress/public/enable_dfsp_position_ledger.png differ diff --git a/docs/.vuepress/public/finalise_settlement.png b/docs/.vuepress/public/finalise_settlement.png new file mode 100644 index 000000000..8121bcdf4 Binary files /dev/null and b/docs/.vuepress/public/finalise_settlement.png differ diff --git a/docs/.vuepress/public/finalising_settlement_popup.png b/docs/.vuepress/public/finalising_settlement_popup.png new file mode 100644 index 000000000..694410bb0 Binary files /dev/null and b/docs/.vuepress/public/finalising_settlement_popup.png differ diff --git a/docs/.vuepress/public/find_transfers.png b/docs/.vuepress/public/find_transfers.png new file mode 100644 index 000000000..4eea7f394 Binary files /dev/null and b/docs/.vuepress/public/find_transfers.png differ diff --git a/docs/.vuepress/public/frontend.png b/docs/.vuepress/public/frontend.png new file mode 100644 index 000000000..cbd35d0ff Binary files /dev/null and b/docs/.vuepress/public/frontend.png differ diff --git a/docs/.vuepress/public/implement.png b/docs/.vuepress/public/implement.png new file mode 100644 index 000000000..adb409a8e Binary files /dev/null and b/docs/.vuepress/public/implement.png differ diff --git a/docs/.vuepress/public/incident_mgmt_single_image.jpeg b/docs/.vuepress/public/incident_mgmt_single_image.jpeg new file mode 100644 index 000000000..f6c38c40a Binary files /dev/null and b/docs/.vuepress/public/incident_mgmt_single_image.jpeg differ diff --git a/docs/.vuepress/public/incident_mgmt_single_image.png b/docs/.vuepress/public/incident_mgmt_single_image.png new file mode 100644 index 000000000..5474a21b2 Binary files /dev/null and b/docs/.vuepress/public/incident_mgmt_single_image.png differ diff --git a/docs/.vuepress/public/mes_portal.png b/docs/.vuepress/public/mes_portal.png new file mode 100644 index 000000000..e157b8431 Binary files /dev/null and b/docs/.vuepress/public/mes_portal.png differ diff --git a/docs/.vuepress/public/mes_portal_request_types.png b/docs/.vuepress/public/mes_portal_request_types.png new file mode 100644 index 000000000..9381dd075 Binary files /dev/null and b/docs/.vuepress/public/mes_portal_request_types.png differ diff --git a/docs/.vuepress/public/mes_report_bug.png b/docs/.vuepress/public/mes_report_bug.png new file mode 100644 index 000000000..8a3fdfca9 Binary files /dev/null and b/docs/.vuepress/public/mes_report_bug.png differ diff --git a/docs/.vuepress/public/mes_technical_support.png b/docs/.vuepress/public/mes_technical_support.png new file mode 100644 index 000000000..5e60a1cd3 Binary files /dev/null and b/docs/.vuepress/public/mes_technical_support.png differ diff --git a/docs/.vuepress/public/microfrontendloading.png b/docs/.vuepress/public/microfrontendloading.png new file mode 100644 index 000000000..b25f49aad Binary files /dev/null and b/docs/.vuepress/public/microfrontendloading.png differ diff --git a/docs/.vuepress/public/mlns_position_popup.png b/docs/.vuepress/public/mlns_position_popup.png new file mode 100644 index 000000000..d174a653a Binary files /dev/null and b/docs/.vuepress/public/mlns_position_popup.png differ diff --git a/docs/.vuepress/public/mojaloop-sdk.png b/docs/.vuepress/public/mojaloop-sdk.png new file mode 100644 index 000000000..20990db3f Binary files /dev/null and b/docs/.vuepress/public/mojaloop-sdk.png differ diff --git a/docs/.vuepress/public/mojaloop_logo_med copy 2.png b/docs/.vuepress/public/mojaloop_logo_med copy 2.png new file mode 100644 index 000000000..74331d2b8 Binary files /dev/null and b/docs/.vuepress/public/mojaloop_logo_med copy 2.png differ diff --git a/docs/.vuepress/public/mojaloop_logo_med copy.png b/docs/.vuepress/public/mojaloop_logo_med copy.png new file mode 100644 index 000000000..74331d2b8 Binary files /dev/null and b/docs/.vuepress/public/mojaloop_logo_med copy.png differ diff --git a/docs/.vuepress/public/mojaloop_logo_med.png b/docs/.vuepress/public/mojaloop_logo_med.png new file mode 100644 index 000000000..74331d2b8 Binary files /dev/null and b/docs/.vuepress/public/mojaloop_logo_med.png differ diff --git a/docs/.vuepress/public/mttr.png b/docs/.vuepress/public/mttr.png new file mode 100644 index 000000000..6672547c2 Binary files /dev/null and b/docs/.vuepress/public/mttr.png differ diff --git a/docs/.vuepress/public/plan_approve.png b/docs/.vuepress/public/plan_approve.png new file mode 100644 index 000000000..bffa3366b Binary files /dev/null and b/docs/.vuepress/public/plan_approve.png differ diff --git a/docs/.vuepress/public/portal_login.png b/docs/.vuepress/public/portal_login.png new file mode 100644 index 000000000..b00b20f28 Binary files /dev/null and b/docs/.vuepress/public/portal_login.png differ diff --git a/docs/.vuepress/public/problem_mgmt.png b/docs/.vuepress/public/problem_mgmt.png new file mode 100644 index 000000000..4cd94d7d0 Binary files /dev/null and b/docs/.vuepress/public/problem_mgmt.png differ diff --git a/docs/.vuepress/public/raise_rfc.png b/docs/.vuepress/public/raise_rfc.png new file mode 100644 index 000000000..ae894b359 Binary files /dev/null and b/docs/.vuepress/public/raise_rfc.png differ diff --git a/docs/.vuepress/public/release_mgmt.png b/docs/.vuepress/public/release_mgmt.png new file mode 100644 index 000000000..a31843cec Binary files /dev/null and b/docs/.vuepress/public/release_mgmt.png differ diff --git a/docs/.vuepress/public/release_process.png b/docs/.vuepress/public/release_process.png new file mode 100644 index 000000000..a3f3b269a Binary files /dev/null and b/docs/.vuepress/public/release_process.png differ diff --git a/docs/.vuepress/public/release_service_components.png b/docs/.vuepress/public/release_service_components.png new file mode 100644 index 000000000..c9f2dcb6d Binary files /dev/null and b/docs/.vuepress/public/release_service_components.png differ diff --git a/docs/.vuepress/public/review_authorize.png b/docs/.vuepress/public/review_authorize.png new file mode 100644 index 000000000..7d71c8ed3 Binary files /dev/null and b/docs/.vuepress/public/review_authorize.png differ diff --git a/docs/.vuepress/public/rolepermissions.png b/docs/.vuepress/public/rolepermissions.png new file mode 100644 index 000000000..373ea01d0 Binary files /dev/null and b/docs/.vuepress/public/rolepermissions.png differ diff --git a/docs/.vuepress/public/security_incident_process.jpeg b/docs/.vuepress/public/security_incident_process.jpeg new file mode 100644 index 000000000..e27e16b3b Binary files /dev/null and b/docs/.vuepress/public/security_incident_process.jpeg differ diff --git a/docs/.vuepress/public/security_incident_process.png b/docs/.vuepress/public/security_incident_process.png new file mode 100644 index 000000000..4e60e123d Binary files /dev/null and b/docs/.vuepress/public/security_incident_process.png differ diff --git a/docs/.vuepress/public/security_overview.png b/docs/.vuepress/public/security_overview.png new file mode 100644 index 000000000..77aff024c Binary files /dev/null and b/docs/.vuepress/public/security_overview.png differ diff --git a/docs/.vuepress/public/settlementProcessAPI.svg b/docs/.vuepress/public/settlementProcessAPI.svg new file mode 100644 index 000000000..ac87eecfd --- /dev/null +++ b/docs/.vuepress/public/settlementProcessAPI.svg @@ -0,0 +1,505 @@ +Settlement ProcessBusiness Hub Operator UserBusiness Hub Operator UserSettlement BankSettlement BankMicro-frontendMicro-frontendExperience LayerExperience LayerProcess LayerProcess LayerReport APIReport APIMojaloopMojaloopClose a settlement window1User clicks close Settlement Window2Close Settlement Windowwindows Id3Add user informationPOST: /settlementWindows{SettlementWindowId}4Confirm that the settlement window is closed and wait retry with timeout if not.GET central-settlements/settlementWindows/{id}5Update UIInitiate Settlement6Initiate Settlement for these windows & CurrencyList of Settlement windows Ids[Optional] Currency or Settlement Model7POST: /settlements:initiate{"settlementWindows": [{"id": 0}], #settlement window id's (integer)"settlementModel":"defered net", # (string)"currency", :"XXX" # (currencyEnum)}8POST: /settlements:initiate{"settlementWindows": [{"id": 0}], #settlement window id's (integer)"settlementModel":"defered net", # (string)"currency", :"XXX" # (currencyEnum)"user": "hub operators name" # (string)}determine settlement Model/s9Load currencies for windows using GET central-settlements/settlementWindows/{id}10Load settlement models using GET central-ledger/settlementModels11Determine minimum list of settlement modelsloop[for settlement models]12Create settlementPOST: central-settlements/settlements{settlementModel, settlementWindowIds[]}13Advance settlement participant accountstate to PS_TRANSFERS_RECORDEDPUT: central-settlements/settlements/{id}Net creditparticipantposition ledgers are adjusted14Return reponse, success HTTP:200{["SettlementModel":"defered-net" #(string)"id":null, # optional (integer)"state": "state" # optional (string)"errorInformation": { # optional"errorCode": 0,"errorDescription": "string","extensionList": {"extension": [{"key": "string","value": "string" } ] } }]}15Update UI with settlement statusGenerate Settlement Matrix Report16Settlement Initiation Report Download17Add User18Settlement Initiation Report Download19report is downloaded20report is downloaded21Report is sent tosettlement bankto beginthe settlement transfersbetween participantsFinalise Settlement22TheSettlement Bankhas completed makingtransfers between participants.Thefinalisation reportthat is recieved fromthe Settlement Bank, includes the settlement accountbalances after all the transfers have been processed.It is possible that these account balances are notas expected. This would indicate that anadditionalfunds in / funds outhas occured in the settlementaccounts that has not yet been captured in theMojaloop Settlement ledgers.23Validate finalisation file24POST: /settlements:finalize25Fatal: Validate file formatLoad file into JSON object{"finalisationReference":"SettlementFinalisationFilename.xlsx" # (string),"settlementId" : 10 , # settlement batch id (integer)"participants" : [{"name": "payerfsp",# mojaloop participant name (string)"id": 1, # mojaloop database id (integer)"settlementAccountId": 1, # settlement account id for participant (integer)"externalBalance": 10000, # external balance of settlement account (number)"netSettlementAmount": {"amount": 0, # number"currency": "XXX" # currency string (CurrencyEnum)}} ] # all participants that are involved in the settlement}26Validate finalisationPOST: /settlements:finalizeload settlement data27Get settlement informationGET central-settlements/settlements/{id}28Get all participantsGET central-ledger/participants29Get all participants limitsGET central-ledger/participants/limits30For each participant get account balanceGET central-ledger/participants/{name}/accountsProcess validation31Fatal: Validate Participants and theiraccounts ids are valid, match,and are the correct type, and correct currency32Fatal: Validate Settlement Id non-matching33Fatal: Validate Participant Settlement datatransfer sum is zero34Fatal: Validate Participant Settlement datamatches net settlement amountCalculate Adjustments and Warnings35Non fatal: Validate Participant Settlementbalance is expectedReturn warnings if there are discrepencies36Non fatal: Validate Participant Settlementbalance is zero or positive37Return finalisation validation results{"finalisationId": "GUIDv4", # Guid version 4 (string)"valid":true, # (boolean) true if none failure error"errors": [{"type": "string", "message": "description", "errorInformation": {...}}],"warnings": [{"type": "string", "message": "description", "errorInformation": {...}}]}38Show validation results to user3940User confirms proceeding with finalisation41Confirm FinalisationPOST: /settlements:confirmFinalize{finalisationId:"GUIDv4", (string)"settlementId" : 10 , # settlement batch id (integer)balanceSettlementOption: true # (boolean)}42Confirm FinalisationPOST: /settlements:confirmFinalize{"finalisationId":"GUIDv4", (string)"settlementId" : 10 , # settlement batch id (integer)"balanceSettlementOption":true, # (boolean)"user":"userName" # (string)}loop[for each settlement debit participant]alt[if balanceSettlementOption is true]43Adjust settlment account according to settlement (funds Out)POST central-ledger/participants/{name}/accounts/{id}Confirm PUT /participants/{name}/accounts/{id}/transfers/{transferId}44Advance state to SettledPUT central-settlements/settlements/{sid}/participants/{pid}/accounts/{aid}PUT /settlements/{sid}/participants/{pid}Net debitparticipantposition ledgers are adjustedloop[for each settlement credit participant]alt[if balanceSettlementOption is true]45Adjust settlment account according to settlement (funds In)POST /participants/{name}/accounts/{id}reason: "Settlement Finanisation"extension list:[ { 'key'='user', 'value'='username'},{ 'key'='reference', 'value'='finalisatonReference'} ]46Advance state to SettledPUT central-settlements/settlements/{sid}/participants/{pid}/accounts/{aid}PUT /settlements/{sid}/participants/{pid}alt[if balanceSettlementOption is true]loop[For each participant rebalance Settlement account]47Get latest balanceGET central-ledger/participants/{name}/accounts48if < actual balance thenincrease balance (funds In)POST central-ledger/participants/{name}/accounts/{id}49if > actual balance thendecrease balance (funds Out)POST central-ledger/participants/{name}/accounts/{id}Confirm PUT /participants/{name}/accounts/{id}/transfers/{transferId}reason: "Settlement Rebalance"extension list:[ { 'key'='user', 'value'='username'},{ 'key'='reference', 'value'='finalisatonReference'} ]50Confirm correct balanceGET central-ledger/participants/{name}/accounts51Response{"state": "string","participants" : [{"name": "payerfsp",# mojaloop participant name (string)"id": 1, # mojaloop database id (integer)"settlementAccountId": 1, # settlement account id for participant (integer)"errors": [{"type": "string", "message": "description", "errorInformation": {...}}] # errorInformation std fspiop error information object}]}52SettlementProcessCompleted (Update settlement Status or display errors) \ No newline at end of file diff --git a/docs/.vuepress/public/settlementProcessFinaliseErrors.svg b/docs/.vuepress/public/settlementProcessFinaliseErrors.svg new file mode 100644 index 000000000..a6ca950ff --- /dev/null +++ b/docs/.vuepress/public/settlementProcessFinaliseErrors.svg @@ -0,0 +1,439 @@ +Settlement ProcessBusiness Hub Operator UserBusiness Hub Operator UserSettlement BankSettlement BankMicro-frontendMicro-frontendExperience LayerExperience LayerProcess LayerProcess LayerReport APIReport APIMojaloopMojaloopFinalise Settlement1 TheSettlement Bankhas completed makingtransfers between participants.Thefinalisation reportthat is recieved fromthe Settlement Bank, includes the settlement accountbalances after all the transfers have been processed. It is possible that these account balances are notas expected. This would indicate that anadditional funds in / funds outhas occured in the settlementaccounts that has not yet been captured in theMojaloop Settlement ledgers.2Validate finalisation file3POST: /settlements:finalize4Fatal: Validate file formatLoad file into JSON object{"finalisationReference":"SettlementFinalisationFilename.xlsx" # (string),"settlementId" : 10 , # settlement batch id (integer)"participants" : [{"name": "payerfsp",# mojaloop participant name (string)"id": 1, # mojaloop database id (integer)"settlementAccountId": 1, # settlement account id for participant (integer)"externalBalance": 10000, # external balance of settlement account (number)"netSettlementAmount": {"amount": 0, # number"currency": "XXX" # currency string (CurrencyEnum)}} ] # all participants that are involved in the settlement}5Validate finalisationPOST: /settlements:finalizeload settlement data6Get settlement informationGET central-settlements/settlements/{id}7Get all participants GET central-ledger/participants8Get all participants limits GET central-ledger/participants/limits9For each participant get account balance GET central-ledger/participants/{name}/accountsProcess validation10Fatal: Validate Participants and theiraccounts ids are valid, match,and are the correct type, and correct currency11Fatal: Validate Settlement Id non-matching12Fatal: Validate Participant Settlement datatransfer sum is zero13Fatal: Validate Participant Settlement datamatches net settlement amountalt[Success/Warnings]Calculate Adjustments and Warnings14Non fatal: Validate Participant Settlementbalance is expectedReturn warnings if there are discrepencies15Non fatal: Validate Participant Settlementbalance is zero or positive16Return finalisation validation results{"finalisationId": "GUIDv4", # Guid version 4 (string)"valid":true # (boolean) true if none failure error"warnings": [{"type": "string", "message": "description", "errorInformation": {...}}]}[Error]17Return Error, HTTP: code Ref: Finalize Settlement Validation Error Codes{"finalisationId": "GUIDv4", # Guid version 4 (string)"valid":false, # (boolean) false if failures"errors": [{"type": "string", "message": "description", "errorInformation": {...}}]}18Show validation results to user19 20User confirms proceeding with finalisation21Confirm FinalisationPOST: /settlements:confirmFinalize{finalisationId:"GUIDv4", (string)"settlementId" : 10 , # settlement batch id (integer)balanceSettlementOption: true # (boolean)}22Confirm FinalisationPOST: /settlements:confirmFinalize{"finalisationId":"GUIDv4", (string)"settlementId" : 10 , # settlement batch id (integer)"balanceSettlementOption":true, # (boolean)"user":"userName" # (string)}23validate finalisationId and settlementId against stored statealt[Validation Success]loop[for each settlement debit participant]alt[if balanceSettlementOption is true]24Adjust settlment account according to settlement (funds Out) POST central-ledger/participants/{name}/accounts/{id}25Confirm adjustment PUT central-ledger/participants/{name}/accounts/{id}/transfers/{transferId}26Advance settlement participant accountstate to PS_TRANSFERS_COMMITED PUT: central-settlements/settlements/{sid}/participants/{pid}27Advance settlement participant accountstate to SETTLED PUT: central-settlements/settlements/{sid}/participants/{pid}Net debitparticipantposition ledgers are adjustedloop[for each settlement credit participant]alt[if balanceSettlementOption is true]28Adjust settlment account according to settlement (funds In) POST /participants/{name}/accounts/{id}reason: "Settlement Finanisation"extension list:[ { 'key'='user', 'value'='username'},{ 'key'='reference', 'value'='finalisatonReference'} ]29Advance settlement participant accountstate to PS_TRANSFERS_COMMITED PUT: central-settlements/settlements/{sid}/participants/{pid}30Advance settlement participant accountstate to SETTLED PUT: central-settlements/settlements/{sid}/participants/{pid}alt[if balanceSettlementOption is true]loop[For each participant rebalance Settlement account]31Get latest balance GET central-ledger/participants/{name}/accountsalt[if latest balance < actual balance]32Increase balance (funds In) POST central-ledger/participants/{name}/accounts/{id}[if latest balance > actual balance]33Decrease balance (funds Out) POST central-ledger/participants/{name}/accounts/{id}34Confirm adjustment PUT /participants/{name}/accounts/{id}/transfers/{transferId}[if latest balance == actual balance]35do nothingreason: "Settlement Rebalance"extension list:[ { 'key'='user', 'value'='username'},{ 'key'='reference', 'value'='finalisatonReference'} ]36Confirm correct balance GET central-ledger/participants/{name}/accountsalt[Processing Success]37Response success, HTTP: 200{"settlement": {... map settlement object from settlements api }}[Processing Error]38Return Error, HTTP: code Ref:Finalize Settlement Confirmation Error Codes{"settlement": {... map settlement object from settlements api },"participantErrors" : [{"id": 1, # mojaloop database id (integer)"error": {"type": "string", "message": "description", "errorInformation": {...}} # errorInformation std fspiop error information object}]}[Validation failure]39Return Error, HTTP: code Ref:Finalize Settlement Confirmation Error Codes{"errorInformation": {"errorCode": 0,"errorDescription": "string","extensionList": {"extension": [{"key": "string","value": "string"}]}}} # errorInformation std fspiop error information object40SettlementProcessCompleted (Update settlement Status or display errors) \ No newline at end of file diff --git a/docs/.vuepress/public/settlementProcessInitiationErrors.svg b/docs/.vuepress/public/settlementProcessInitiationErrors.svg new file mode 100644 index 000000000..9452b5bf5 --- /dev/null +++ b/docs/.vuepress/public/settlementProcessInitiationErrors.svg @@ -0,0 +1,123 @@ +Settlement ProcessBusiness Hub Operator UserBusiness Hub Operator UserSettlement BankSettlement BankMicro-frontendMicro-frontendExperience LayerExperience LayerProcess LayerProcess LayerReport APIReport APIMojaloopMojaloopInitiate Settlement1Initiate Settlement for these windows & CurrencyList of Settlement windows Ids[Optional] Currency or Settlement Model2POST: /settlements:initiate{"settlementWindows": [{"id": 0}], #settlement window id's (integer)"settlementModel":"defered net", # (string)"currency", :"XXX" # (currencyEnum)}3POST: /settlements:initiate{"settlementWindows": [{"id": 0}], #settlement window id's (integer)"settlementModel":"defered net", # (string)"currency", :"XXX" # (currencyEnum)"user": "hub operators name" # (string)}determine settlement Model/s4Load currencies for windows using GET central-settlements/settlementWindows/{id}5Load settlementModels using GET central-ledger/settlementModels6Determine minimum list of settlementModels, return a map for each settlementModel containing a list of applicable settlementWindows7Validatealt[Validation Error]8Return Error HTTP: code Ref: Initiate Settlement Error Codes{"errorInformation": {"errorCode": 0,"errorDescription": "string","extensionList": {"extension": [{"key": "string","value": "string"}]}}} [Validation Success]loop[for settlement models]9Create settlement POST: central-settlements/settlements {settlementModel, settlementWindowIds[]}10Advance settlement participant accountstate to PS_TRANSFERS_RECORDED PUT: central-settlements/settlements/{id}11Advance settlement participant accountstate to PS_TRANSFERS_RESERVED PUT: central-settlements/settlements/{id}Net creditparticipantposition ledgers are adjusted12Return response, success/warnings HTTP:200[{"settlementModel":"defered-net" #(string)"settlement": {... map settlement object from settlements api }, #optional"errorInformation": { # optional"errorCode": 0,"errorDescription": "string","extensionList": {"extension": [{"key": "string","value": "string"}]}}}]13Update UI with settlement status \ No newline at end of file diff --git a/docs/.vuepress/public/settlement_details_popup.png b/docs/.vuepress/public/settlement_details_popup.png new file mode 100644 index 000000000..b9b709218 Binary files /dev/null and b/docs/.vuepress/public/settlement_details_popup.png differ diff --git a/docs/.vuepress/public/settlement_processing.jpg b/docs/.vuepress/public/settlement_processing.jpg new file mode 100644 index 000000000..cb01cf0c6 Binary files /dev/null and b/docs/.vuepress/public/settlement_processing.jpg differ diff --git a/docs/.vuepress/public/settlement_window_mgmt.png b/docs/.vuepress/public/settlement_window_mgmt.png new file mode 100644 index 000000000..fc2739647 Binary files /dev/null and b/docs/.vuepress/public/settlement_window_mgmt.png differ diff --git a/docs/.vuepress/public/settlement_window_mgmt_close.png b/docs/.vuepress/public/settlement_window_mgmt_close.png new file mode 100644 index 000000000..b2870a420 Binary files /dev/null and b/docs/.vuepress/public/settlement_window_mgmt_close.png differ diff --git a/docs/.vuepress/public/settlement_window_mgmt_selector.png b/docs/.vuepress/public/settlement_window_mgmt_selector.png new file mode 100644 index 000000000..063b7a7b9 Binary files /dev/null and b/docs/.vuepress/public/settlement_window_mgmt_selector.png differ diff --git a/docs/.vuepress/public/settlement_window_mgmt_settle_button.png b/docs/.vuepress/public/settlement_window_mgmt_settle_button.png new file mode 100644 index 000000000..f9632c41b Binary files /dev/null and b/docs/.vuepress/public/settlement_window_mgmt_settle_button.png differ diff --git a/docs/.vuepress/public/settlement_window_settlement_submitted.png b/docs/.vuepress/public/settlement_window_settlement_submitted.png new file mode 100644 index 000000000..fcb119519 Binary files /dev/null and b/docs/.vuepress/public/settlement_window_settlement_submitted.png differ diff --git a/docs/.vuepress/public/transfer_details_quote_parties.png b/docs/.vuepress/public/transfer_details_quote_parties.png new file mode 100644 index 000000000..7cc85b262 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_quote_parties.png differ diff --git a/docs/.vuepress/public/transfer_details_quote_request.png b/docs/.vuepress/public/transfer_details_quote_request.png new file mode 100644 index 000000000..4d78fd830 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_quote_request.png differ diff --git a/docs/.vuepress/public/transfer_details_quote_responses.png b/docs/.vuepress/public/transfer_details_quote_responses.png new file mode 100644 index 000000000..5d0af6352 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_quote_responses.png differ diff --git a/docs/.vuepress/public/transfer_details_transfer_fulfilments.png b/docs/.vuepress/public/transfer_details_transfer_fulfilments.png new file mode 100644 index 000000000..831ec63ba Binary files /dev/null and b/docs/.vuepress/public/transfer_details_transfer_fulfilments.png differ diff --git a/docs/.vuepress/public/transfer_details_transfer_participants.png b/docs/.vuepress/public/transfer_details_transfer_participants.png new file mode 100644 index 000000000..1c7c25888 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_transfer_participants.png differ diff --git a/docs/.vuepress/public/transfer_details_transfer_prepares.png b/docs/.vuepress/public/transfer_details_transfer_prepares.png new file mode 100644 index 000000000..982253b85 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_transfer_prepares.png differ diff --git a/docs/.vuepress/public/transfer_details_transfer_state_changes.png b/docs/.vuepress/public/transfer_details_transfer_state_changes.png new file mode 100644 index 000000000..1e22ba9b5 Binary files /dev/null and b/docs/.vuepress/public/transfer_details_transfer_state_changes.png differ diff --git a/docs/.vuepress/public/update_participant.png b/docs/.vuepress/public/update_participant.png new file mode 100644 index 000000000..b6a1b720e Binary files /dev/null and b/docs/.vuepress/public/update_participant.png differ diff --git a/docs/.vuepress/public/userroles.png b/docs/.vuepress/public/userroles.png new file mode 100644 index 000000000..3cdc58318 Binary files /dev/null and b/docs/.vuepress/public/userroles.png differ diff --git a/docs/.vuepress/styles/index.styl b/docs/.vuepress/styles/index.styl new file mode 100644 index 000000000..61bf8beba --- /dev/null +++ b/docs/.vuepress/styles/index.styl @@ -0,0 +1,42 @@ +/** + * Custom Styles here. + * + * ref:https://v1.vuepress.vuejs.org/config/#index-styl + */ + +@import url('https://fonts.googleapis.com/css?family=Varela+Round') +@import url('https://fonts.googleapis.com/css?family=Open+Sans') + +h1, h2, h3 + font-family: 'Varela Round' + +h5 + font-size: 1.05rem + +p + font-family: 'Open Sans' + +// .home +// margin-top: 56px + +.home .hero img + max-width 450px!important + +.home .feature + max-width: 33% !important + +.home .hero .description + color: #000000 !important + max-width: 720px !important + +.navbar .site-name + display: none + +// .navbar +// top: 55px !important + +.home .hero #main-title + display: none + +// .main-content-wrapper +// margin-top: 75px diff --git a/docs/.vuepress/styles/palette.styl b/docs/.vuepress/styles/palette.styl new file mode 100644 index 000000000..78335ca83 --- /dev/null +++ b/docs/.vuepress/styles/palette.styl @@ -0,0 +1,14 @@ +/** + * Custom palette here. + * + * ref:https://v1.vuepress.vuejs.org/zh/config/#palette-styl + */ + +$accentColor = #00a3ff +$textColor = #000000 +$borderColor = #eaecef +$codeBgColor = #282c34 +// Set this to 7 when we want a custom banner above the navbar +$navbarHeight = 3.5rem +// set this to 3.5 when we want a custom banner above the navbar +$navbarBannerHeight = 0rem diff --git a/docs/.vuepress/theme/CHANGELOG.md b/docs/.vuepress/theme/CHANGELOG.md new file mode 100644 index 000000000..88e9ba443 --- /dev/null +++ b/docs/.vuepress/theme/CHANGELOG.md @@ -0,0 +1,188 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [4.9.0](https://github.com/appcelerator/docs-devkit/compare/v4.8.3...v4.9.0) (2020-11-10) + + +### Bug Fixes + +* fix color shades, sidebar sub groups and type meta padding ([ffc5817](https://github.com/appcelerator/docs-devkit/commit/ffc581761be5331d94bd6d222c24b044925b11a8)) + + +### Features + +* **theme:** custom color theme for prism.js ([#83](https://github.com/appcelerator/docs-devkit/issues/83)) ([c826dc0](https://github.com/appcelerator/docs-devkit/commit/c826dc0d34e6f2c149109490800a752b0d39aef0)) + + + + + +## [4.8.3](https://github.com/appcelerator/docs-devkit/compare/v4.8.2...v4.8.3) (2020-10-21) + + +### Bug Fixes + +* use axway theme gray-dk in place of hard-coded #aaa ([7723256](https://github.com/appcelerator/docs-devkit/commit/7723256)) +* use named axway colors in place of hard-coded hex values ([961cbb1](https://github.com/appcelerator/docs-devkit/commit/961cbb1)) + + + + + +## [4.8.2](https://github.com/appcelerator/docs-devkit/compare/v4.8.1...v4.8.2) (2020-10-19) + + +### Bug Fixes + +* scroll behavior and css adjustments ([c8cb639](https://github.com/appcelerator/docs-devkit/commit/c8cb639)) +* **theme:** add axway color variables ([df8c5b3](https://github.com/appcelerator/docs-devkit/commit/df8c5b3)) +* **theme:** try to use axway typography values for headers ([7fd1115](https://github.com/appcelerator/docs-devkit/commit/7fd1115)) +* **theme:** use axway blue colors for inline code tags ([16bb3e5](https://github.com/appcelerator/docs-devkit/commit/16bb3e5)) +* **theme:** use axway danger/success/warn colors for badges ([a543d9c](https://github.com/appcelerator/docs-devkit/commit/a543d9c)) +* **theme:** use axway danger/success/warn colors for custom blocks ([4a9cfe1](https://github.com/appcelerator/docs-devkit/commit/4a9cfe1)) +* **theme:** use page relativePath to generate edit link ([#70](https://github.com/appcelerator/docs-devkit/issues/70)) ([ca0e1c2](https://github.com/appcelerator/docs-devkit/commit/ca0e1c2)), closes [#48](https://github.com/appcelerator/docs-devkit/issues/48) + + + + + +# [4.8.0](https://github.com/appcelerator/docs-devkit/compare/v4.7.0...v4.8.0) (2020-10-08) + + +### Features + +* **theme-titanium:** allow frontmatter to contain editUrl for edit this page link ([dd6a1e2](https://github.com/appcelerator/docs-devkit/commit/dd6a1e2)) + + + + + +## [4.5.1](https://github.com/appcelerator/docs-devkit/compare/v4.5.0...v4.5.1) (2020-06-19) + + +### Performance Improvements + +* cache page lookup ([4c27c0f](https://github.com/appcelerator/docs-devkit/commit/4c27c0f)) + + + + + +# [4.5.0](https://github.com/appcelerator/docs-devkit/compare/v4.4.1...v4.5.0) (2020-06-18) + + +### Bug Fixes + +* mark all nested sidebar items active ([fcc5312](https://github.com/appcelerator/docs-devkit/commit/fcc5312)) +* nested sidebars without path ([62bacb1](https://github.com/appcelerator/docs-devkit/commit/62bacb1)) +* pass reactive data to ensure child component updates ([1776df0](https://github.com/appcelerator/docs-devkit/commit/1776df0)) +* sidebar css fixes ([396ac84](https://github.com/appcelerator/docs-devkit/commit/396ac84)) + + +### Features + +* support nested sidebars ([1e28793](https://github.com/appcelerator/docs-devkit/commit/1e28793)) + + + + + +## [4.0.1](https://github.com/appcelerator/docs-devkit/compare/v4.0.0...v4.0.1) (2019-12-11) + +**Note:** Version bump only for package vuepress-theme-titanium + + + + + +# 4.0.0 (2019-12-02) [YANKED] + +# 3.0.0 (2019-12-02) [YANKED] + +# 2.0.0 (2019-12-02) [YANKED] + +# 1.0.0 (2019-12-02) + + +### Bug Fixes + +* **theme:** show footer only if configured ([9d9f4d2](https://github.com/appcelerator/docs-devkit/commit/9d9f4d2)) +* add default theme color palette ([31d20e6](https://github.com/appcelerator/docs-devkit/commit/31d20e6)) +* **theme:** add bottom padding to home page ([6b2d0be](https://github.com/appcelerator/docs-devkit/commit/6b2d0be)) +* **theme:** add default content class ([d516092](https://github.com/appcelerator/docs-devkit/commit/d516092)) +* **theme:** apply latest theme-default ([7b15292](https://github.com/appcelerator/docs-devkit/commit/7b15292)) +* **theme:** guard against undefined paths ([ed03520](https://github.com/appcelerator/docs-devkit/commit/ed03520)) +* **theme:** height wrapper to avoid glitches ([7923ded](https://github.com/appcelerator/docs-devkit/commit/7923ded)) +* **theme:** mark versions dropdown as can-hide ([eecb704](https://github.com/appcelerator/docs-devkit/commit/eecb704)) +* **theme:** only show api sidebar button if page has api docs ([06513cb](https://github.com/appcelerator/docs-devkit/commit/06513cb)) +* **theme:** show version dropdown on versioned pages only ([ab18f4d](https://github.com/appcelerator/docs-devkit/commit/ab18f4d)) +* **theme:** test for available headers before accessing ([91bb50d](https://github.com/appcelerator/docs-devkit/commit/91bb50d)) +* respect locale in version dropdown ([3e80fe9](https://github.com/appcelerator/docs-devkit/commit/3e80fe9)) +* use versioned links in navbar ([9a45f85](https://github.com/appcelerator/docs-devkit/commit/9a45f85)) +* **theme:** use correct edit link for pages ([953b39e](https://github.com/appcelerator/docs-devkit/commit/953b39e)) +* **versioning:** more safeguards in case no versions were created yet ([0615344](https://github.com/appcelerator/docs-devkit/commit/0615344)) +* **versioning:** properly generate versioned edit links ([1be0e45](https://github.com/appcelerator/docs-devkit/commit/1be0e45)) + + +### Features + +* custom next version label ([85d0746](https://github.com/appcelerator/docs-devkit/commit/85d0746)) +* make footer configurable ([27e4e14](https://github.com/appcelerator/docs-devkit/commit/27e4e14)) +* update to VuePress 1.0.2 ([74d7ca8](https://github.com/appcelerator/docs-devkit/commit/74d7ca8)) +* **theme:** update code color ([15f81f8](https://github.com/appcelerator/docs-devkit/commit/15f81f8)) +* **versioning:** search through current version only ([ce69184](https://github.com/appcelerator/docs-devkit/commit/ce69184)) + + + + + +# [0.2.0](https://github.com/appcelerator/docs-devkit/compare/v0.1.5...v0.2.0) (2019-09-09) + +**Note:** Version bump only for package vuepress-theme-titanium + + + + + +## [0.1.2](https://github.com/appcelerator/docs-devkit/compare/v0.1.1...v0.1.2) (2019-07-27) + + +### Bug Fixes + +* **theme:** test for available headers before accessing ([91bb50d](https://github.com/appcelerator/docs-devkit/commit/91bb50d)) + + + + + +# 0.1.0 (2019-07-27) + + +### Bug Fixes + +* **theme:** show footer only if configured ([9d9f4d2](https://github.com/appcelerator/docs-devkit/commit/9d9f4d2)) +* add default theme color palette ([31d20e6](https://github.com/appcelerator/docs-devkit/commit/31d20e6)) +* **theme:** add bottom padding to home page ([6b2d0be](https://github.com/appcelerator/docs-devkit/commit/6b2d0be)) +* **theme:** add default content class ([d516092](https://github.com/appcelerator/docs-devkit/commit/d516092)) +* **theme:** apply latest theme-default ([7b15292](https://github.com/appcelerator/docs-devkit/commit/7b15292)) +* **theme:** guard against undefined paths ([ed03520](https://github.com/appcelerator/docs-devkit/commit/ed03520)) +* **theme:** height wrapper to avoid glitches ([7923ded](https://github.com/appcelerator/docs-devkit/commit/7923ded)) +* **theme:** mark versions dropdown as can-hide ([eecb704](https://github.com/appcelerator/docs-devkit/commit/eecb704)) +* **theme:** only show api sidebar button if page has api docs ([06513cb](https://github.com/appcelerator/docs-devkit/commit/06513cb)) +* **theme:** show version dropdown on versioned pages only ([ab18f4d](https://github.com/appcelerator/docs-devkit/commit/ab18f4d)) +* respect locale in version dropdown ([3e80fe9](https://github.com/appcelerator/docs-devkit/commit/3e80fe9)) +* use versioned links in navbar ([9a45f85](https://github.com/appcelerator/docs-devkit/commit/9a45f85)) +* **theme:** use correct edit link for pages ([953b39e](https://github.com/appcelerator/docs-devkit/commit/953b39e)) +* **versioning:** more safeguards in case no versions were created yet ([0615344](https://github.com/appcelerator/docs-devkit/commit/0615344)) +* **versioning:** properly generate versioned edit links ([1be0e45](https://github.com/appcelerator/docs-devkit/commit/1be0e45)) + + +### Features + +* custom next version label ([85d0746](https://github.com/appcelerator/docs-devkit/commit/85d0746)) +* make footer configurable ([27e4e14](https://github.com/appcelerator/docs-devkit/commit/27e4e14)) +* update to VuePress 1.0.2 ([74d7ca8](https://github.com/appcelerator/docs-devkit/commit/74d7ca8)) +* **theme:** update code color ([15f81f8](https://github.com/appcelerator/docs-devkit/commit/15f81f8)) +* **versioning:** search through current version only ([ce69184](https://github.com/appcelerator/docs-devkit/commit/ce69184)) diff --git a/docs/.vuepress/theme/LICENSE b/docs/.vuepress/theme/LICENSE new file mode 100644 index 000000000..8b53a7231 --- /dev/null +++ b/docs/.vuepress/theme/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019-Present Axway Appcelerator + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/.vuepress/theme/README.md b/docs/.vuepress/theme/README.md new file mode 100644 index 000000000..81afc9b46 --- /dev/null +++ b/docs/.vuepress/theme/README.md @@ -0,0 +1,5 @@ +# vuepres-theme-titanium + +> Supercharged version of the default theme for VuePress + +📖 View the [Documentation](https://titanium-docs-devkit.netlify.com/theme/). diff --git a/docs/.vuepress/theme/components/AlgoliaSearchBox.vue b/docs/.vuepress/theme/components/AlgoliaSearchBox.vue new file mode 100644 index 000000000..7b2a5807c --- /dev/null +++ b/docs/.vuepress/theme/components/AlgoliaSearchBox.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/docs/.vuepress/theme/components/ContentSidebar.vue b/docs/.vuepress/theme/components/ContentSidebar.vue new file mode 100644 index 000000000..2f59f3e77 --- /dev/null +++ b/docs/.vuepress/theme/components/ContentSidebar.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/docs/.vuepress/theme/components/ContentSidebarButton.vue b/docs/.vuepress/theme/components/ContentSidebarButton.vue new file mode 100644 index 000000000..befabe149 --- /dev/null +++ b/docs/.vuepress/theme/components/ContentSidebarButton.vue @@ -0,0 +1,28 @@ + + + diff --git a/docs/.vuepress/theme/components/ContentSidebarLink.vue b/docs/.vuepress/theme/components/ContentSidebarLink.vue new file mode 100644 index 000000000..ae94e2513 --- /dev/null +++ b/docs/.vuepress/theme/components/ContentSidebarLink.vue @@ -0,0 +1,89 @@ + + + diff --git a/docs/.vuepress/theme/components/DropdownLink.vue b/docs/.vuepress/theme/components/DropdownLink.vue new file mode 100644 index 000000000..22b716883 --- /dev/null +++ b/docs/.vuepress/theme/components/DropdownLink.vue @@ -0,0 +1,230 @@ + + + + + diff --git a/docs/.vuepress/theme/components/DropdownTransition.vue b/docs/.vuepress/theme/components/DropdownTransition.vue new file mode 100644 index 000000000..eeaf12b5c --- /dev/null +++ b/docs/.vuepress/theme/components/DropdownTransition.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/docs/.vuepress/theme/components/Footer.vue b/docs/.vuepress/theme/components/Footer.vue new file mode 100644 index 000000000..d7c7e21fc --- /dev/null +++ b/docs/.vuepress/theme/components/Footer.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/docs/.vuepress/theme/components/Home.vue b/docs/.vuepress/theme/components/Home.vue new file mode 100644 index 000000000..6e999e265 --- /dev/null +++ b/docs/.vuepress/theme/components/Home.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/docs/.vuepress/theme/components/NavLink.vue b/docs/.vuepress/theme/components/NavLink.vue new file mode 100644 index 000000000..5d801edce --- /dev/null +++ b/docs/.vuepress/theme/components/NavLink.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/docs/.vuepress/theme/components/NavLinks.vue b/docs/.vuepress/theme/components/NavLinks.vue new file mode 100644 index 000000000..5a6d5e0fd --- /dev/null +++ b/docs/.vuepress/theme/components/NavLinks.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/docs/.vuepress/theme/components/Navbar.vue b/docs/.vuepress/theme/components/Navbar.vue new file mode 100644 index 000000000..f15018387 --- /dev/null +++ b/docs/.vuepress/theme/components/Navbar.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/docs/.vuepress/theme/components/Page.vue b/docs/.vuepress/theme/components/Page.vue new file mode 100644 index 000000000..9571d5ab0 --- /dev/null +++ b/docs/.vuepress/theme/components/Page.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/docs/.vuepress/theme/components/PageEdit.vue b/docs/.vuepress/theme/components/PageEdit.vue new file mode 100644 index 000000000..50b015c26 --- /dev/null +++ b/docs/.vuepress/theme/components/PageEdit.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/docs/.vuepress/theme/components/PageNav.vue b/docs/.vuepress/theme/components/PageNav.vue new file mode 100644 index 000000000..4c19aae5f --- /dev/null +++ b/docs/.vuepress/theme/components/PageNav.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/docs/.vuepress/theme/components/PreviewBanner.vue b/docs/.vuepress/theme/components/PreviewBanner.vue new file mode 100644 index 000000000..e1096cc5d --- /dev/null +++ b/docs/.vuepress/theme/components/PreviewBanner.vue @@ -0,0 +1,48 @@ + + + + + + + \ No newline at end of file diff --git a/docs/.vuepress/theme/components/SearchBoxWrapper.vue b/docs/.vuepress/theme/components/SearchBoxWrapper.vue new file mode 100644 index 000000000..1b3dd2ab1 --- /dev/null +++ b/docs/.vuepress/theme/components/SearchBoxWrapper.vue @@ -0,0 +1,20 @@ + + + diff --git a/docs/.vuepress/theme/components/Sidebar.vue b/docs/.vuepress/theme/components/Sidebar.vue new file mode 100644 index 000000000..3a5b32c75 --- /dev/null +++ b/docs/.vuepress/theme/components/Sidebar.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/docs/.vuepress/theme/components/SidebarArrow.vue b/docs/.vuepress/theme/components/SidebarArrow.vue new file mode 100644 index 000000000..8b3aadf3d --- /dev/null +++ b/docs/.vuepress/theme/components/SidebarArrow.vue @@ -0,0 +1,26 @@ + + + diff --git a/docs/.vuepress/theme/components/SidebarButton.vue b/docs/.vuepress/theme/components/SidebarButton.vue new file mode 100644 index 000000000..3f54afd55 --- /dev/null +++ b/docs/.vuepress/theme/components/SidebarButton.vue @@ -0,0 +1,40 @@ + + + diff --git a/docs/.vuepress/theme/components/SidebarGroup.vue b/docs/.vuepress/theme/components/SidebarGroup.vue new file mode 100644 index 000000000..56b1f421c --- /dev/null +++ b/docs/.vuepress/theme/components/SidebarGroup.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/docs/.vuepress/theme/components/SidebarLink.vue b/docs/.vuepress/theme/components/SidebarLink.vue new file mode 100644 index 000000000..baf5bb107 --- /dev/null +++ b/docs/.vuepress/theme/components/SidebarLink.vue @@ -0,0 +1,124 @@ + + + diff --git a/docs/.vuepress/theme/components/SidebarLinks.vue b/docs/.vuepress/theme/components/SidebarLinks.vue new file mode 100644 index 000000000..4a3de2a3b --- /dev/null +++ b/docs/.vuepress/theme/components/SidebarLinks.vue @@ -0,0 +1,73 @@ + + + diff --git a/docs/.vuepress/theme/global-components/AppHeading.vue b/docs/.vuepress/theme/global-components/AppHeading.vue new file mode 100644 index 000000000..a3f63cf83 --- /dev/null +++ b/docs/.vuepress/theme/global-components/AppHeading.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/docs/.vuepress/theme/global-components/Badge.vue b/docs/.vuepress/theme/global-components/Badge.vue new file mode 100644 index 000000000..f2da7cd29 --- /dev/null +++ b/docs/.vuepress/theme/global-components/Badge.vue @@ -0,0 +1,54 @@ + + + diff --git a/docs/.vuepress/theme/index.js b/docs/.vuepress/theme/index.js new file mode 100644 index 000000000..4000e6b45 --- /dev/null +++ b/docs/.vuepress/theme/index.js @@ -0,0 +1,28 @@ +const path = require('path') + +// Theme API. +module.exports = (options, ctx) => ({ + globalLayout: './layouts/GlobalLayout.vue', + alias () { + const { themeConfig, siteConfig } = ctx + // resolve algolia + const isAlgoliaSearch = ( + themeConfig.algolia || + Object.keys(siteConfig.locales && themeConfig.locales || {}) + .some(base => themeConfig.locales[base].algolia) + ) + return { + '@AlgoliaSearchBox': isAlgoliaSearch + ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue') + : path.resolve(__dirname, 'noopModule.js') + } + }, + plugins: [ + ['@vuepress/search', { searchMaxSuggestions: 10 }], + '@vuepress/nprogress', + ['container', { type: 'tip' }], + ['container', { type: 'warning' }], + ['container', { type: 'danger' }], + require('./plugins/smoothScroll') + ] +}) diff --git a/docs/.vuepress/theme/layouts/404.vue b/docs/.vuepress/theme/layouts/404.vue new file mode 100644 index 000000000..b35efaa09 --- /dev/null +++ b/docs/.vuepress/theme/layouts/404.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/docs/.vuepress/theme/layouts/GlobalLayout.vue b/docs/.vuepress/theme/layouts/GlobalLayout.vue new file mode 100644 index 000000000..5900262b8 --- /dev/null +++ b/docs/.vuepress/theme/layouts/GlobalLayout.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/docs/.vuepress/theme/layouts/Layout.vue b/docs/.vuepress/theme/layouts/Layout.vue new file mode 100644 index 000000000..0cbece3e4 --- /dev/null +++ b/docs/.vuepress/theme/layouts/Layout.vue @@ -0,0 +1,216 @@ + + + + + + diff --git a/docs/.vuepress/theme/noopModule.js b/docs/.vuepress/theme/noopModule.js new file mode 100644 index 000000000..b1c6ea436 --- /dev/null +++ b/docs/.vuepress/theme/noopModule.js @@ -0,0 +1 @@ +export default {} diff --git a/docs/.vuepress/theme/package.json b/docs/.vuepress/theme/package.json new file mode 100644 index 000000000..418a6ad64 --- /dev/null +++ b/docs/.vuepress/theme/package.json @@ -0,0 +1,26 @@ +{ + "name": "vuepress-theme-titanium", + "version": "4.9.0", + "description": "VuePress theme for Titanium projects", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Axway Appcelerator", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/appcelerator/docs-devkit.git", + "directory": "packages/vuepress/vuepress-theme-titanium" + }, + "dependencies": { + "@vuepress/plugin-nprogress": "^1.7.1", + "@vuepress/plugin-search": "^1.7.1", + "docsearch.js": "^2.6.3", + "lodash": "^4.17.15", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "vuepress-plugin-container": "^2.1.5" + }, + "gitHead": "2c02c2ac571b8c02ffea735f2db16211ea21ae6c" +} diff --git a/docs/.vuepress/theme/plugins/smoothScroll/appHeading.js b/docs/.vuepress/theme/plugins/smoothScroll/appHeading.js new file mode 100644 index 000000000..d5b9b8e06 --- /dev/null +++ b/docs/.vuepress/theme/plugins/smoothScroll/appHeading.js @@ -0,0 +1,40 @@ +module.exports = function appHeading (md, options) { + md.core.ruler.push('app-heading', state => { + const slugs = {} + const tokens = state.tokens + tokens + .filter(token => token.type === 'heading_open' || token.type === 'heading_close') + .forEach(token => { + token.tag = 'app-heading' + if (token.type === 'heading_open') { + const title = tokens[tokens.indexOf(token) + 1] + .children + .filter(token => token.type === 'text' || token.type === 'code_inline') + .reduce((acc, t) => acc + t.content, '') + let slug = token.attrGet('id') + if (slug == null) { + slug = uniqueSlug(slugify(title), slugs, false) + } else { + slug = uniqueSlug(slug, slugs, true) + } + token.attrSet('id', slug) + token.attrSet('level', token.markup.split('').length) + token.attrSet('href', `#${slug}`) + } + }) + }) +} + +const slugify = (s) => encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-')) +const hasProp = Object.prototype.hasOwnProperty +const uniqueSlug = (slug, slugs, failOnNonUnique) => { + let uniq = slug + let i = 1 + if (failOnNonUnique && hasProp.call(slugs, uniq)) { + throw Error(`User defined id attribute '${slug}' is NOT unique. Please fix it in your markdown to continue.`) + } else { + while (hasProp.call(slugs, uniq)) uniq = `${slug}-${i++}` + } + slugs[uniq] = true + return uniq +} diff --git a/docs/.vuepress/theme/plugins/smoothScroll/enhanceApp.js b/docs/.vuepress/theme/plugins/smoothScroll/enhanceApp.js new file mode 100644 index 000000000..053a509df --- /dev/null +++ b/docs/.vuepress/theme/plugins/smoothScroll/enhanceApp.js @@ -0,0 +1,44 @@ +const SCROLL_OFFSET = 75 + +// fork from vue-router@3.0.2 +// src/util/scroll.js +function getElementPosition (el) { + const docEl = document.documentElement + const docRect = docEl.getBoundingClientRect() + const elRect = el.getBoundingClientRect() + return { + x: elRect.left - docRect.left, + y: elRect.top - docRect.top + } +} + +module.exports = ({ Vue, options, router }) => { + router.options.scrollBehavior = (to, from, savedPosition) => { + if (savedPosition) { + return window.scrollTo({ + top: savedPosition.y - SCROLL_OFFSET, + behavior: 'smooth' + }) + } else if (from.path === to.path && to.hash) { + if (Vue.$vuepress.$get('disableScrollBehavior')) { + return + } + const targetAnchor = to.hash + const targetName = targetAnchor.slice(1) + const targetElement = + document.getElementById(targetName) || + document.querySelector(`[name=${targetName}]`) + if (targetElement) { + return window.scrollTo({ + top: getElementPosition(targetElement).y - SCROLL_OFFSET, + behavior: 'smooth' + }) + } + } else { + const html = document.querySelector('html') + html.style.scrollBehavior = 'auto' + window.scrollTo({ top: 0 }) + html.style.scrollBehavior = '' + } + } +} diff --git a/docs/.vuepress/theme/plugins/smoothScroll/index.js b/docs/.vuepress/theme/plugins/smoothScroll/index.js new file mode 100644 index 000000000..33abfaac4 --- /dev/null +++ b/docs/.vuepress/theme/plugins/smoothScroll/index.js @@ -0,0 +1,16 @@ +const path = require('path') +// const appHeading = require('./appHeading') + +module.exports = (context, options) => ({ + name: 'smooth-scroll', + enhanceAppFiles: path.resolve(__dirname, 'enhanceApp.js') + /** + * https://github.com/vuejs/vuepress/pull/2669 + * + chainMarkdown (config) { + config.plugins.delete('anchor') + config.plugin('app-heading') + .use(appHeading, []) + } + */ +}) diff --git a/docs/.vuepress/theme/styles/arrow.styl b/docs/.vuepress/theme/styles/arrow.styl new file mode 100644 index 000000000..20bffc0dc --- /dev/null +++ b/docs/.vuepress/theme/styles/arrow.styl @@ -0,0 +1,22 @@ +@require './config' + +.arrow + display inline-block + width 0 + height 0 + &.up + border-left 4px solid transparent + border-right 4px solid transparent + border-bottom 6px solid $arrowBgColor + &.down + border-left 4px solid transparent + border-right 4px solid transparent + border-top 6px solid $arrowBgColor + &.right + border-top 4px solid transparent + border-bottom 4px solid transparent + border-left 6px solid $arrowBgColor + &.left + border-top 4px solid transparent + border-bottom 4px solid transparent + border-right 6px solid $arrowBgColor diff --git a/docs/.vuepress/theme/styles/code.styl b/docs/.vuepress/theme/styles/code.styl new file mode 100644 index 000000000..ce99536f9 --- /dev/null +++ b/docs/.vuepress/theme/styles/code.styl @@ -0,0 +1,198 @@ +.content + code + font-size .875rem + font-weight 400 + -webkit-font-smoothing auto + line-height 1.5 + color $codeColor + display inline-block + padding 0 0.25rem + background-color $inlineCodeBgColor + border-radius .125rem + .token + &.deleted + color $danger + &.inserted + color $success + +.content + pre, pre[class*="language-"] + font-size 0.875rem + font-weight 400 + line-height 1.5 + padding 1rem + margin 0.85rem 0 + background-color $codeBgColor + border-radius 6px + overflow auto + code + color $primary-ltr + padding 0 + background-color transparent + border-radius 0 + +div[class*="language-"] + position relative + background-color $codeBgColor + border-radius 6px + .highlight-lines + user-select none + padding-top 1.3rem + position absolute + top 0 + left 0 + width 100% + line-height 1.4 + .highlighted + background-color rgba(0, 0, 0, 66%) + pre, pre[class*="language-"] + background transparent + position relative + z-index 1 + &::before + position absolute + z-index 3 + top 0.8em + right 1em + font-size 0.75rem + color rgba(255, 255, 255, 0.4) + &:not(.line-numbers-mode) + .line-numbers-wrapper + display none + &.line-numbers-mode + .highlight-lines .highlighted + position relative + &:before + content ' ' + position absolute + z-index 3 + left 0 + top 0 + display block + width $lineNumbersWrapperWidth + height 100% + background-color rgba(0, 0, 0, 66%) + pre + padding-left $lineNumbersWrapperWidth + 1 rem + vertical-align middle + .line-numbers-wrapper + position absolute + top 0 + width $lineNumbersWrapperWidth + text-align center + color rgba(255, 255, 255, 0.3) + padding 1.25rem 0 + line-height 1.4 + br + user-select none + .line-number + position relative + z-index 4 + user-select none + font-size 0.85em + &::after + content '' + position absolute + z-index 2 + top 0 + left 0 + width $lineNumbersWrapperWidth + height 100% + border-radius 6px 0 0 6px + border-right 1px solid rgba(0, 0, 0, 66%) + background-color $codeBgColor + + +for lang in $codeLang + div{'[class~="language-' + lang + '"]'} + &:before + content ('' + lang) + +div[class~="language-javascript"] + &:before + content "js" + +div[class~="language-typescript"] + &:before + content "ts" + +div[class~="language-markup"] + &:before + content "html" + +div[class~="language-markdown"] + &:before + content "md" + +div[class~="language-json"]:before + content "json" + +div[class~="language-ruby"]:before + content "rb" + +div[class~="language-python"]:before + content "py" + +div[class~="language-bash"]:before + content "sh" + +div[class~="language-php"]:before + content "php" + +// Custom Prism.js theme based on the Palenight High Contrast theme for VSCode, +// enhanced with the colors from our theme. + +.token + &.attr-name, + &.property + &.selector + color $warning-lt + &.attr-value, + &.char, + &.regex, + &.string, + &.variable + color $success-lt + &.boolean, + &.number + color $warning + &.comment + color $gray-dk + &.constant, + &.tag + color $danger-lt + &.atrule + &.function + color #82AAFF + &.keyword + color $danger-lt + &.operator, + &.punctuation + color #89DDFF + +.language-md + .token + &.title + color $warning-lt + &.important + font-weight 400 + &.content + padding 0 + +.content + pre + &.language-yml + code + color $success-lt +.language-yml + .token + &.atrule + color $danger-lt + +.language-css, +.language-sass, +.language-scss, +.language-stylus, + .token + &.property + color #B2CCD6 diff --git a/docs/.vuepress/theme/styles/colors.styl b/docs/.vuepress/theme/styles/colors.styl new file mode 100644 index 000000000..9089647fe --- /dev/null +++ b/docs/.vuepress/theme/styles/colors.styl @@ -0,0 +1,3 @@ +/** Overrides of colors used for inline code blocks **/ +$codeColor = $primary +$inlineCodeBgColor = $primary-ltr diff --git a/docs/.vuepress/theme/styles/custom-blocks.styl b/docs/.vuepress/theme/styles/custom-blocks.styl new file mode 100644 index 000000000..f9e2cafe8 --- /dev/null +++ b/docs/.vuepress/theme/styles/custom-blocks.styl @@ -0,0 +1,45 @@ +.custom-block + .custom-block-title + font-weight 600 + margin-bottom -0.4rem + &.tip, &.warning, &.danger + padding .1rem 1.5rem + border-left-width .5rem + border-left-style solid + margin 1rem 0 + &.tip + background-color $success-ltr + border-color $succcess + &.warning + background-color $warning-ltr + border-color $warning + .custom-block-title + color $warning + a + color $warning-dk + &.danger + background-color $danger-ltr + border-color $danger + .custom-block-title + color $danger + a + color $danger-dk + +pre.vue-container + border-left-width: .5rem; + border-left-style: solid; + border-color: $success; + border-radius: 0px; + & > code + font-size: 14px !important; + & > p + margin: -5px 0 -20px 0; + code + background-color: $success !important; + padding: 3px 5px; + border-radius: 3px; + color $black + em + color $gray-dk + font-weight light + diff --git a/docs/.vuepress/theme/styles/mobile.styl b/docs/.vuepress/theme/styles/mobile.styl new file mode 100644 index 000000000..4769f90fa --- /dev/null +++ b/docs/.vuepress/theme/styles/mobile.styl @@ -0,0 +1,53 @@ +@require './config' + +$mobileSidebarWidth = $sidebarWidth * 0.82 +$mobileContentSidebarWidth = $contentSidebarWidth * 0.82 + +// narrow desktop / iPad +@media (max-width: $MQNarrow) + .sidebar + font-size 15px + width $mobileSidebarWidth + .content-sidebar-wrapper + width $mobileContentSidebarWidth + +// wide mobile +@media (max-width: $MQMobile) + .sidebar + position fixed + top $navbarHeight + bottom 0 + height auto + z-index 10 + transform translateX(-100%) + transition transform .2s ease + .content-sidebar-wrapper + width $contentSidebarWidth * 1.2 + position fixed + top $navbarHeight + right 0 + bottom 0 + height auto + z-index: 10; + transform translateX(100%) + transition transform .2s ease + .theme-container + display block + &.sidebar-open + .sidebar + transform translateX(0) + &.content-sidebar-open + .content-sidebar-wrapper + transform translateX(0) + &.no-navbar + .sidebar + padding-top: 0 + +// narrow mobile +@media (max-width: $MQMobileNarrow) + h1 + font-size 1.9rem + .content + div[class*="language-"] + margin 0.85rem -1.5rem + border-radius 0 diff --git a/docs/.vuepress/theme/styles/nprogress.styl b/docs/.vuepress/theme/styles/nprogress.styl new file mode 100644 index 000000000..f186a67ec --- /dev/null +++ b/docs/.vuepress/theme/styles/nprogress.styl @@ -0,0 +1,48 @@ +#nprogress + pointer-events none + .bar + background $accentColor + position fixed + z-index 1031 + top 0 + left 0 + width 100% + height 2px + .peg + display block + position absolute + right 0px + width 100px + height 100% + box-shadow 0 0 10px $accentColor, 0 0 5px $accentColor + opacity 1.0 + transform rotate(3deg) translate(0px, -4px) + .spinner + display block + position fixed + z-index 1031 + top 15px + right 15px + .spinner-icon + width 18px + height 18px + box-sizing border-box + border solid 2px transparent + border-top-color $accentColor + border-left-color $accentColor + border-radius 50% + animation nprogress-spinner 400ms linear infinite + +.nprogress-custom-parent + overflow hidden + position relative + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar + position absolute + +@keyframes nprogress-spinner + 0% + transform rotate(0deg) + 100% + transform rotate(360deg) diff --git a/docs/.vuepress/theme/styles/palette.styl b/docs/.vuepress/theme/styles/palette.styl new file mode 100644 index 000000000..0bf0bf285 --- /dev/null +++ b/docs/.vuepress/theme/styles/palette.styl @@ -0,0 +1,40 @@ +/**** Axway Colors ****/ +$black = #001e26 +$black-lt = #d0d0d0 +$black-ltr = #efefef +$danger = #d22630 +$danger-dk = #800008 +$danger-lt = #ff605a +$danger-ltr = #ffebee +$gray = #c8c9c7 +$gray-dk = #979896 +$gray-lt = #f4f5f4 +$gray-ltr = #fbfcfa +$primary = #006580 +$primary-dk = #003b53 +$primary-lt = #99c1cc +$primary-ltr = #eef3f4 +$secondary = #4a4f54 +$secondary-dk = #22272b +$secondary-lt = #707070 +$secondary-ltr = #f8f8f8 +$succcess = #228665 +$success-dk = #006448 +$success-lt = #7de3b9 +$success-ltr = #ecf7f3 +$tertiary = #9d4b70 +$tertiary-dk = #6c1d45 +$tertiary-lt = #c3a4b4 +$tertiary-ltr = #efe7eb +$warning = #ff9e18 +$warning-dk = #b95e04 +$warning-lt = #ffcf51 +$warning-ltr = #fff5e7 +$white = white + +/** Override of main colors used in Vuepress **/ +$accentColor = $danger +$textColor = $black +$lightTextColor = $gray-dk +$borderColor = $black-ltr +$codeBgColor = $secondary-dk diff --git a/docs/.vuepress/theme/styles/table.styl b/docs/.vuepress/theme/styles/table.styl new file mode 100644 index 000000000..b3a454ff3 --- /dev/null +++ b/docs/.vuepress/theme/styles/table.styl @@ -0,0 +1,15 @@ +table + width 100% + margin-bottom 1rem + + border-collapse: collapse; + border-spacing: 0; + tr + border-bottom: 1px solid $black-ltr + tbody tr:last-child + border-bottom 0 + td, th + padding .75rem + vertical-align top + text-align left + line-height 1.5rem \ No newline at end of file diff --git a/docs/.vuepress/theme/styles/theme.styl b/docs/.vuepress/theme/styles/theme.styl new file mode 100644 index 000000000..5e4de46b9 --- /dev/null +++ b/docs/.vuepress/theme/styles/theme.styl @@ -0,0 +1,266 @@ +@require './config' +@require './colors' +@require './nprogress' +@require './code' +@require './custom-blocks' +@require './arrow' +@require './wrapper' +@require './toc' +@require './table' + +// Custom vars +$contentSidebarWidth = 12rem + +html + scroll-behavior smooth + +html, body + padding 0 + margin 0 + background-color $white + +body + font-family -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif; + -webkit-font-smoothing antialiased + -moz-osx-font-smoothing grayscale + font-size 1rem + line-height 1.5rem + color $textColor + min-height 100vh + text-rendering: optimizeLegibility + +.theme-container + display flex + flex-flow row nowrap + min-height 100vh + +.page + flex 1 1 auto + min-width 0 + +.navbar + position: fixed + z-index: 20 + top: 0 + left: 0 + right: 0 + height: var(--navbar-total-height) + background-color: $white + box-sizing: border-box + border-bottom: 1px solid $borderColor + display: flex + flex-direction: column + padding-top: 0 + padding-bottom: 0 + padding-left: $navbar-horizontal-padding + padding-right: $navbar-horizontal-padding + +.banner-content { + height: var(--navbar-banner-height) + min-height: var(--navbar-banner-height) + width: 100% + display: block + box-sizing: border-box + padding: 0 + position: static +} + +.navbar-content { + height: var(--navbar-height) + min-height: var(--navbar-height) + padding: 0 $navbar-horizontal-padding + display: flex + align-items: center + justify-content: space-between + width: 100% + box-sizing: border-box +} + +.sidebar-mask + position fixed + z-index 9 + top 0 + left 0 + width 100vw + height 100vh + display none + +.sidebar + font-size 15px + background-color $white + position sticky + top: var(--navbar-total-height) + height: calc(100vh - var(--navbar-total-height)) + flex 0 0 auto + width $sidebarWidth + box-sizing border-box + border-right 1px solid $borderColor + overflow-y auto + overflow-x hidden + +.content-sidebar-wrapper + background-color $white + position sticky + top: var(--navbar-total-height) + height: calc(100vh - var(--navbar-total-height)) + width $contentSidebarWidth + align-self: flex-start; + flex 0 0 auto + padding 2rem 1rem 2rem 0 + box-sizing border-box + +.content:not(.custom) + @extend $wrapper + padding-top: var(--navbar-total-height) + + @media (min-width: $MQMobile) + padding-top: var(--navbar-total-height) + + > *:first-child + margin-top 0 + + a:hover + text-decoration underline + + p.demo + padding 1rem 1.5rem + border 1px solid $gray + border-radius 4px + img + max-width 100% + +.content.custom + padding 0 + margin 0 + + img + max-width 100% + +a + font-weight 500 + color $accentColor + text-decoration none + +kbd + background $gray-lt + border solid 0.15rem $gray + border-bottom solid 0.25rem $gray + border-radius 0.15rem + padding 0 0.15em + +blockquote + font-size .9rem + color $gray-dk + border-left .5rem solid $gray-ltr + margin 0.5rem 0 + padding .25rem 0 .25rem 1rem + + & > p + margin 0 + +ul, ol + padding-left 1.2em + +strong + font-weight 600 + +h1, h2, h3, h4, h5, h6 + > .header-anchor + font-size 0.85em + float left + margin-left -0.87em + padding-right 0.23em + margin-top 0.125em + opacity 0 + + &:hover + text-decoration none + + &:not(:hover):not(:focus) + opacity: 0 + + .content:not(.custom) > & + &:hover .header-anchor + opacity: 1 + +h1, h2, h3, h4, strong + color $black + font-weight 700 + +h1, h2 + letter-spacing -.025rem + +h1 + font-size 2.625rem + line-height 3.125rem + +h2 + font-size 2rem + line-height 2.5rem + padding-bottom .3rem + border-bottom 1px solid $borderColor + margin 1.5rem 0 + +h3 + font-size 1.5rem + line-height 2rem + margin-top 1.5rem + +h4 + font-size 1.25rem + line-height 1.625rem + margin-bottom 0 + +code, kbd, .line-number + font-family Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace + +p, ul, ol + line-height 1.7 + +hr + border 0 + border-top 1px solid $borderColor + +caption + padding-top .75rem + padding-bottom .75rem + line-height 1rem + font-size .75rem + color $lightTextColor + text-align left + caption-side bottom + +.theme-container + &.sidebar-open,&.content-sidebar-open + .sidebar-mask + display: block + + &.no-navbar + .content:not(.custom) > h1, h2, h3, h4, h5, h6 + margin-top 1.5rem + padding-top 0 + + .sidebar + top 0 + + +@media (min-width: ($MQMobile + 1px)) + .theme-container.no-sidebar + .sidebar + display none + +@require 'mobile.styl' + +// Adjust sidebar and content top offset for banner + navbar +:root { + --navbar-banner-height: 2.5rem; + --navbar-height: 4rem; + --navbar-total-height: calc(var(--navbar-banner-height) + var(--navbar-height)); +} + +.content:not(.custom) { + padding-top: var(--navbar-total-height); + @media (min-width: $MQMobile) { + padding-top: calc(7rem + var(--navbar-banner-height)); + } +} diff --git a/docs/.vuepress/theme/styles/toc.styl b/docs/.vuepress/theme/styles/toc.styl new file mode 100644 index 000000000..d3e71069b --- /dev/null +++ b/docs/.vuepress/theme/styles/toc.styl @@ -0,0 +1,3 @@ +.table-of-contents + .badge + vertical-align middle diff --git a/docs/.vuepress/theme/styles/wrapper.styl b/docs/.vuepress/theme/styles/wrapper.styl new file mode 100644 index 000000000..5bc7ee354 --- /dev/null +++ b/docs/.vuepress/theme/styles/wrapper.styl @@ -0,0 +1,8 @@ +$wrapper + margin 0 auto + padding 2rem 2.5rem + @media (max-width: $MQNarrow) + padding 2rem + @media (max-width: $MQMobileNarrow) + padding 1.5rem + diff --git a/docs/.vuepress/theme/templates/ssr.html b/docs/.vuepress/theme/templates/ssr.html new file mode 100644 index 000000000..35a5a247b --- /dev/null +++ b/docs/.vuepress/theme/templates/ssr.html @@ -0,0 +1,18 @@ + + + + + + {{ title }} + + {{{ userHeadTags }}} + {{{ pageMeta }}} + {{{ renderResourceHints() }}} + {{{ renderStyles() }}} + + + + {{{ renderState() }}} + {{{ renderScripts() }}} + + diff --git a/docs/.vuepress/theme/util/index.js b/docs/.vuepress/theme/util/index.js new file mode 100644 index 000000000..06370d7ca --- /dev/null +++ b/docs/.vuepress/theme/util/index.js @@ -0,0 +1,384 @@ +export const hashRE = /#.*$/ +export const extRE = /\.(md|html)$/ +export const endingSlashRE = /\/$/ +export const outboundRE = /^(https?:|mailto:|tel:)/ + +const normalizedMap = new Map() + +export function normalize(path) { + if (normalizedMap.has(path)) { + return normalizedMap.get(path) + } + const result = decodeURI(path) + .replace(hashRE, '') + .replace(extRE, '') + normalizedMap.set(path, result) + return result +} + +export function getHash(path) { + const match = path.match(hashRE) + if (match) { + return match[0] + } +} + +export function isExternal(path) { + return outboundRE.test(path) +} + +export function isMailto(path) { + return /^mailto:/.test(path) +} + +export function isTel(path) { + return /^tel:/.test(path) +} + +export function ensureExt(path) { + if (isExternal(path)) { + return path + } + const hashMatch = path.match(hashRE) + const hash = hashMatch ? hashMatch[0] : '' + const normalized = normalize(path) + + if (endingSlashRE.test(normalized)) { + return path + } + return normalized + '.html' + hash +} + +export function isActive(route, path) { + const routeHash = route.hash + const linkHash = getHash(path) + if (linkHash && routeHash !== linkHash) { + return false + } + const routePath = normalize(route.path) + const pagePath = normalize(path) + return routePath === pagePath +} + +export function resolvePage(pages, rawPath, base) { + if (!resolvePage.cache) { + resolvePage.cache = new Map() + pages.forEach((page, i) => { + resolvePage.cache.set(normalize(page.regularPath), i) + }) + } + if (isExternal(rawPath)) { + return { + type: 'external', + path: rawPath + } + } + if (base) { + rawPath = resolvePath(rawPath, base) + } + const path = normalize(rawPath) + const cache = resolvePage.cache + if (cache.has(path)) { + const page = pages[cache.get(path)] + return Object.assign({}, page, { + type: 'page', + path: ensureExt(page.path) + }) + } + console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) + return {} +} + +function resolvePath(relative, base, append) { + const firstChar = relative.charAt(0) + if (firstChar === '/') { + return relative + } + + if (firstChar === '?' || firstChar === '#') { + return base + relative + } + + const stack = base.split('/') + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop() + } + + // resolve relative path + const segments = relative.replace(/^\//, '').split('/') + for (let i = 0; i < segments.length; i++) { + const segment = segments[i] + if (segment === '..') { + stack.pop() + } else if (segment !== '.') { + stack.push(segment) + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift('') + } + + return stack.join('/') +} + +/** + * @param { Page } page + * @param { string } regularPath + * @param { SiteData } site + * @param { string } localePath + * @returns { SidebarGroup } + */ +export function resolveSidebarItems(page, regularPath, site, localePath, versions) { + const { pages } = site + let themeConfig = site.themeConfig + + let localeConfig = localePath && themeConfig.locales + ? themeConfig.locales[localePath] || themeConfig + : themeConfig + if (page.version && page.version !== 'latest') { + const versionedConfig = site.themeConfig.versionedSidebar && site.themeConfig.versionedSidebar[page.version] + localeConfig = localePath && versionedConfig.locales + ? versionedConfig.locales[localePath] || versionedConfig + : versionedConfig + themeConfig = versionedConfig + } + + const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar + if (pageSidebarConfig === 'auto') { + return resolveHeaders(page) + } + + const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar + if (!sidebarConfig) { + return [] + } else { + const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig) + if (config === 'auto') { + return resolveHeaders(page) + } + return config + ? config.map(item => resolveItem(item, pages, base)) + : [] + } +} + +/** + * @param { Page } page + * @returns { SidebarGroup } + */ +function resolveHeaders(page) { + const headers = groupHeaders(page.headers || []) + return [{ + type: 'group', + collapsable: false, + title: page.title, + path: null, + children: headers.map(h => ({ + type: 'auto', + title: h.title, + basePath: page.path, + path: page.path + '#' + h.slug, + children: h.children || [] + })) + }] +} + +export function groupHeaders(headers) { + // group h3s under h2 + headers = headers.map(h => Object.assign({}, h)) + let lastH2 + headers.forEach(h => { + if (h.level === 2) { + lastH2 = h + } else if (lastH2) { + (lastH2.children || (lastH2.children = [])).push(h) + } + }) + return headers.filter(h => h.level === 2) +} + +export function resolveNavLinkItem(linkItem) { + return Object.assign(linkItem, { + type: linkItem.items && linkItem.items.length ? 'links' : 'link' + }) +} + +export function versionifyUserNav(navConfig, currentPage, currentVersion, localePath, routes) { + return navConfig.map(item => { + // assign item to new object so we don't override the original values + item = Object.assign({}, item) + if (item.items) { + item.items = versionifyUserNav(item.items, currentPage, currentVersion, localePath, routes) + } else { + let link = item.link + if (currentPage.version !== currentVersion) { + const cleanPath = item.link.replace(new RegExp(`^${localePath}`), '') + link = `${localePath}${currentPage.version}/${cleanPath}` + if (!routes.some(route => route.path === link)) { + // Fallback to the un-altered default link + link = item.link + } + } + item.link = link + } + + return Object.assign({}, item) + }) +} + +/** Doc paths under these prefixes reuse the default-locale sidebar keys; base is rewritten for resolvePath. */ +// const SIDEBAR_LOCALE_PREFIXES = ['/fr'] +const LOCALES = ['fr', 'en'] + +/** + * @param { Route } route + * @param { Array | Array | [link: string]: SidebarConfig } config + * @returns { base: string, config: SidebarConfig } + */ +export function resolveMatchingConfig(regularPath, config) { + if (Array.isArray(config)) { + return { + base: '/', + config: config + } + } + for (const base in config) { + if (ensureEndingSlash(regularPath).indexOf(base) === 0) { + return { + base, + config: config[base] + } + } + } + const localePrefix = LOCALES.find( + (l) => + regularPath === `/${l}` || + regularPath === `/${l}/` || + regularPath.startsWith(`/${l}/`) + ) + + if (!localePrefix) { + return {} + } + + const rest = regularPath.slice(localePrefix.length + 1) + + const pathWithoutLocale = + !rest || rest === '/' ? '/' : rest.startsWith('/') ? rest : `/${rest}` + + for (const base in config) { + if (ensureEndingSlash(pathWithoutLocale).indexOf(base) === 0) { + return { + base: `/${localePrefix}${base}`, + config: config[base] + } + } + } + return {} +} + +function ensureEndingSlash(path) { + return /(\.html|\/)$/.test(path) + ? path + : path + '/' +} + +function isSidebarLocaleBase(base) { + if (!base) { + return false + } + return LOCALES.some( + locale => base === `/${locale}/` || base.startsWith(`/${locale}/`) + ) +} + +/** + * For localized doc trees (e.g. /fr/...), prefer each page's title or frontmatter.sidebarTitle + * over the English label from themeConfig. + */ +function sidebarTitleForResolvedPage(resolved, base, fallbackTitle) { + if (resolved.type !== 'page') { + return fallbackTitle + } + const frontmatter = resolved.frontmatter || {} + + if (frontmatter.sidebarTitle) { + return frontmatter.sidebarTitle + } + + if (isSidebarLocaleBase(base)) { + return resolved.title || fallbackTitle + } + + return fallbackTitle || resolved.title +} + +function resolveItem(item, pages, base, groupDepth = 1) { + if (typeof item === 'string') { + return resolvePage(pages, item, base) + } else if (Array.isArray(item)) { + const resolved = resolvePage(pages, item[0], base) + return Object.assign(resolved, { + title: sidebarTitleForResolvedPage(resolved, base, item[1]) + }) + } else { + const children = item.children || [] + if (children.length === 0 && item.path) { + const resolved = resolvePage(pages, item.path, base) + return Object.assign(resolved, { + title: sidebarTitleForResolvedPage(resolved, base, item.title) + }) + } + return { + type: 'group', + path: item.path, + title: item.title, + sidebarDepth: item.sidebarDepth, + children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)), + collapsable: item.collapsable !== false + } + } +} + +export function calculateCurrentAnchor(sidebarLinks) { + const anchors = [].slice + .call(document.querySelectorAll('.header-anchor')) + .filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash)) + .map(el => { + return { + el, + hash: decodeURIComponent(el.hash), + top: el.getBoundingClientRect().top - 120 + } + }) + if (anchors.length === 0) { + return null + } + const l = anchors.length + if (anchors[0].top > 0 && anchors[0].top < 10) { + return anchors[0] + } + + if (anchors[l - 1].top < 0) { + return anchors[l - 1] + } + + for (let i = 0; i < l; i++) { + const anchor = anchors[i] + const nextAnchor = anchors[i + 1] + if (anchor.top < 0 && nextAnchor.top > 0) { + if (nextAnchor.top < 10) { + return nextAnchor + } + return anchor + } + } + + return anchors[0] +} diff --git a/docs/.vuepress/versions.json b/docs/.vuepress/versions.json new file mode 100644 index 000000000..9da960f67 --- /dev/null +++ b/docs/.vuepress/versions.json @@ -0,0 +1,3 @@ +[ + "v1.0.1" +] \ No newline at end of file diff --git a/docs/adoption/HubOperations/Onboarding/business-onboarding.md b/docs/adoption/HubOperations/Onboarding/business-onboarding.md new file mode 100644 index 000000000..a6fda7dcc --- /dev/null +++ b/docs/adoption/HubOperations/Onboarding/business-onboarding.md @@ -0,0 +1,20 @@ +# Business onboarding of DFSPs + +The onboarding journey for DFSPs comprises steps that happen outside the Mojaloop Hub. They are related to the business side of onboarding, and are useful for the Hub Operator to be aware of. + +::: tip NOTE +The steps of the DFSP application process and the business onboarding journey are defined by the Scheme, in conformance with local financial regulatory requirements. +::: + +Key milestones of the business onboarding journey are: + +1. The DFSP discovers the service offered by the Scheme, and indicates their intention and business reason to join the Scheme. +1. The DFSP signs an application agreement. +1. Documentation is shared with the DFSP, which allows the DFSP to assess the technical effort to integrate, as well as their business compatibility with the Scheme Rules. +1. The Scheme Operator performs due diligence for the candidate's eligibility. +1. The DFSP understands and signs a participation agreement (contract). +1. The DFSP completes a KYC procedure with the settlement bank. This is part of the process of opening a settlement bank account (also called liquidity account). +1. The DFSP develops new UI functionality/updates existing UI functionality to expose the Scheme-supported use case(s) to end users. +1. The DFSP opens and pre-funds their liquidity account at the settlement bank. + +In parallel with the business steps, after signing the participation agreement, the DFSP can start their [technical onboarding journey](technical-onboarding.md). \ No newline at end of file diff --git a/docs/adoption/HubOperations/Onboarding/onboarding-introduction.md b/docs/adoption/HubOperations/Onboarding/onboarding-introduction.md new file mode 100644 index 000000000..77e70bb4e --- /dev/null +++ b/docs/adoption/HubOperations/Onboarding/onboarding-introduction.md @@ -0,0 +1,6 @@ +# Introduction – Onboarding Guide for the Hub Operator + +This guide is aimed at the Operator of a Mojaloop Hub and provides information about the DFSP onboarding process. It provides a high-level overview of the onboarding journey that DFSPs take, acting as a checklist of onboarding activities. The aim is to help Hub employees have an understanding of the steps to complete when connecting DFSPs to the various Hub environments. + + + diff --git a/docs/adoption/HubOperations/Onboarding/technical-onboarding.md b/docs/adoption/HubOperations/Onboarding/technical-onboarding.md new file mode 100644 index 000000000..062d8fb21 --- /dev/null +++ b/docs/adoption/HubOperations/Onboarding/technical-onboarding.md @@ -0,0 +1,247 @@ +# Technical onboarding of DFSPs + +At a high level, onboarding to a Mojaloop Hub requires a DFSP to focus their efforts around the following major milestones: + +* [Integration](#api-integration) of their core backend with the Mojaloop Hub on the API level (this involves both coding and testing). +* [Connecting](#connecting-to-mojaloop-environments) to pre-production and production environments following rigorous Mojaloop security requirements. + +In addition to the steps that require DFSP involvement, the Hub Operator must also perform some onboarding activities in their [backend](#onboarding-in-the-hub-backend) independent from DFSPs. + +This section provides a high-level overview of all of these milestones. + +## API integration + +Within the context of the Mojaloop Financial Service Provider Interoperability (FSPIOP) API, a transfer happens in three main steps: + +1. Identifying the Payee (party lookup or discovery phase) +1. Agreeing the transfer (quote or agreement phase) +1. Executing the transfer (transfer phase) + +For further details on each of these phases, see **Module 2 - Static demo: An end-to-end example** of [Mojaloop training course](https://learn.mojaloop.io/) **MOJA-102**. + +These three phases correspond to the key resources of the Mojaloop FSPIOP API: + +* **Party lookup service**: Identifying the DFSP serving the Payee and the Payee itself (= the recipient of funds in a transaction) based on a Payee identifier (typically a MSISDN, that is, a mobile number). +* **Quotes service**: Requesting a quote and exchanging cryptographic proof to prepare and secure the transfer. A quote is a contract between a Payer DFSP and Payee DFSP for a particular financial transaction before the transaction is performed. It guarantees the agreement set by the Payer and Payee DFSPs about the Payer, the Payee, and transfer amount, and is valid during the lifetime of a quote and transfer of a specified financial transaction. +* **Transfers service**: Executing the transaction as per the agreed details and cryptographic proof. + +DFSPs can choose to: + +* connect directly to the Mojaloop Hub and implement the asynchronous Mojaloop version of these API services, or +* leverage an open-source integration component (the [Mojaloop-SDK](#mojaloop-sdk) or [Payment Manager OSS](#payment-manager-oss)) and implement a simplified, synchronous version of Mojaloop FSPIOP API services + +DFSPs with an in-house development team and experience with RESTful APIs will likely be able to manage the process internally and develop a direct connection to Mojaloop. However, it is recommended that DFSPs use one of the open-source integration components, as a direct connection requires additional code development and maintenance. Using the Mojaloop-SDK or Payment Manager OSS reduces the time it takes to integrate with the Mojaloop Hub and makes troubleshooting easier for the Hub Operator, thus reducing the overall cost of the system. + +While the DFSP is carrying out offline development work, the Hub Operator's role consists in answering ad-hoc questions around the specifics of the API, or - depending on the open-source tool chosen and the agreed deployment model - can even extend to doing some of the development too. + +### Open-source tools to facilitate API integration + +#### Mojaloop-SDK + +The [Mojaloop-SDK](https://github.com/mojaloop/sdk-scheme-adapter) presents a simplified, synchronous version of the Mojaloop FSPIOP API to a DFSP's backend system, allowing DFSPs to implement a simple API internally to interface with the Mojaloop Hub, while still being compliant with the Mojaloop FSPIOP API specification for interoperable external communications. + +The asynchronous pattern of the Mojaloop FSPIOP API (while it has many advantages) may not be suitable for client applications that operate in a synchronous request-response mode. The Mojaloop-SDK helps bridge this gap by offering a simplified request-response API, abstracting away the complexities of multiple request composition and asynchronous API details from end clients. + +![Mojaloop-SDK](../../../.vuepress/public/mojaloop-sdk.png) + +The Mojaloop-SDK must be downloaded from [GitHub](https://github.com/mojaloop/sdk-scheme-adapter) to the DFSP environment and integrated to the DFSP backend. It is provided as a Docker container image, and may be hosted on the same infrastructure as the core banking application or a virtual machine provisioned specifically for it. Ongoing maintenance may require some specialized support from a System Integrator trained in the software. + +Other than a simplified API, the Mojaloop-SDK also provides the security protocols required by Mojaloop "out of the box", by giving a simplified configuration interface to its users. This feature of the Mojaloop-SDK helps with the [connection step](#connecting-to-mojaloop-environments) of onboarding. + +#### Payment Manager OSS + +[Payment Manager OSS](https://pm4ml.github.io/documents/payment_manager_oss/latest/core_connector_rest/introduction.html) presents a use-case oriented, simplified, synchronous version of the Mojaloop FSPIOP API to a DFSP's backend system. The key integration component of Payment Manager is called Core Connector, it acts as a translator between a DFSP's core backend (CBS) and a component of Payment Manager (called Mojaloop Connector, which leverages the Mojaloop-SDK) that talks directly to the Mojaloop Hub. + +![Payment Manager OSS](../../../.vuepress/public/PM4ML_system_architecture.png) + +Core Connector is built in Apache Camel, a declarative Java-based language for integration engineers that does not require writing code from scratch. There is a ready-made Core Connector template available to simplify the development effort. The template provides a placeholder codebase for the API endpoints that need to be developed, and it must be customized to be aligned with the appropriate CBS technology. The flexibility provided by the template allows for Core Connector to be made to fit a DFSP's backend, rather than the other way around. + +The effort to customize a Core Connector template will differ depending on the chosen deployment option. When deploying Payment Manager, two options are available: + +* **Managed and hosted by System Integrator**: A System Integrator deploys Payment Manager in the cloud, and syncs up the Core Connector template with the DFSP's core backend implementation. +* **Self-hosted by DFSP**: The DFSP deploys Payment Manager on premise or in the cloud, and the customization of the Core Connector template can be done by a number of actors (depending on the outcome of an initial assessment of DFSP capabilities): + * the System Integrator + * the System Integrator and the vendor of the DFSP's core backend solution + * the DFSP and the vendor of the DFSP's core backend solution + +Payment Manager is provided as a set of Linux container images (Docker) and may be hosted on-premise using commodity server infrastructure or in appropriate cloud infrastructure where available. + +If the Hub Operator so chooses, it can assume a System Integrator role. + +Given that Payment Manager incorporates Mojaloop-SDK functionality, it also implements the security layer required by Mojaloop. This feature of Payment Manager helps with the [connection step](#connecting-to-mojaloop-environments) of onboarding. + +## Connecting to Mojaloop environments + +Once the DFSP has completed coding, they test their integration against a lab instance in a test environment provided by the Hub. This is where the connection phase of the technical onboarding journey begins, with a new set of responsibilities for the Hub Operator. + +The requirements around connecting are dictated by the multiple security protocols that any Mojaloop Hub and participating DFSPs must implement: + +* Two-way TLS with mutual X.509 authentication +* OAuth 2.0 authentication for sessions over the Hub API gateway +* IP-address-based whitelisting in firewall rules and API gateways +* JSON Web Signature (JWS) signing of messages +* Interledger Protocol (ILP) packet signing and validation + +If you are interested in more details, see [Security in Mojaloop](#security-in-mojaloop). + +Putting the above security measures into practice requires extensive information sharing and technical configuration from different teams at both the DFSP and the Mojaloop Hub. There are open-source tools available for the community to facilitate this process, both for DFSPs and the Hub Operator. + +### Open-source tools to facilitate connecting to Mojaloop environments + +#### Mojaloop-SDK + +The Mojaloop-SDK implements standard components that establish a uniform way of connecting DFSP systems to a Mojaloop Hub. It implements the following Mojaloop-compliant security functionality: + +* Two-way TLS with mutual X.509 authentication +* JSON Web Signature (JWS) signing of messages +* Generation of the Interledger Protocol (ILP) packet with signing and validation + +The Mojaloop-SDK can be downloaded from [GitHub](https://github.com/mojaloop/sdk-standard-components) hosted on the same infrastructure as the DFSP's core banking application or a virtual machine provisioned specifically for it. Following the generation, signing, and exchange of TLS and JWS certificates, DFSPs are required to configure TLS- and JWS-related environment variables in the Mojaloop-SDK. Finally, installing the certificates in the DFSP's firewalls and API gateway completes the certificate configuration part of the process. + +Obtaining the Hub API gateway credentials required for collecting OAuth 2.0 tokens and configuring them in the Mojaloop-SDK via environment variables must be done manually. + +Exchanging endpoint details with the Hub and configuring them in the Mojaloop-SDK via environment variables, as well as in firewall/gateway whitelists are manual steps too. + +#### Payment Manager OSS + +Payment Manager OSS provides all the security features that the Mojaloop-SDK provides, and more. Payment Manager comes with a Mojaloop Connection Manager (MCM) Client, which simplifies and automates certificate creation, signing and exchange, as well as the configuration of the connections required to different environments. How much of these processes is automated will differ depending on the chosen deployment option. Two options are available: + +* **Managed and hosted by System Integrator**: A System Integrator deploys Payment Manager in the cloud. +* **Self-hosted by DFSP**: The DFSP deploys Payment Manager on premise or in the cloud. + +When a DFSP opts for the **managed-hosted option**, the System Integrator (this role can be filled by the Hub Operator) can employ Infrastructure-as-Code and onboarding scripts to handle the following elements of the process in an automated way: + +* generation, signing, configuration, and installation of TLS certificates +* IP address whitelisting in firewalls and API gateways +* generation and configuration of client secret/key required to obtain OAuth 2.0 tokens + +Steps related to JWS certificates are carried out via the [Connection Wizard portal](https://pm4ml.github.io/documents/payment_manager_oss/latest/connection_wizard/index.html), an easy-to-use portal that Payment Manager provides for managing certificate and endpoint related processes in a guided way. DFSPs and the Hub Operator are required to generate JWS certificates using any tool of their preference and then share their public keys via the Connection Wizard portal. Configuring JWS certificates in Payment Manager is done via the Connection Wizard portal, while installing them in gateways is a manual step. + +When a DFSP opts for the **self-hosted option**, they use the [Connection Wizard portal](https://pm4ml.github.io/documents/payment_manager_oss/latest/connection_wizard/index.html) to manage certificate and endpoint related steps in a semi-automated way: + +* DFSPs enter their endpoint details and obtain the Hub's endpoints from the portal. They then configure this information in Payment Manager via environment variables as well as in firewall/gateway whitelists manually. +* DFSPs generate, sign, and configure TLS certificates at the click of a button via the Connection Wizard portal. +* DFSPs generate JWS certificates using a tool of their choice and share and configure them in Payment Manager at the click of a button in the Connection Wizard portal. + +Obtaining the Hub API gateway credentials required for collecting OAuth 2.0 tokens and configuring them in Payment Manager via environment variables must be done manually. + +#### MCM + +The Mojaloop Connection Manager (MCM) product is instrumental in simplifying and automating much of the information sharing and configuration around endpoints and certificates. MCM has an MCM Client and an MCM Server component, which talk to each other when exchanging endpoint details and certificates, and when signing Certificate Signing Requests. + +The MCM Client is incorporated into Payment Manager, whereas the MCM Server is within the boundaries of the Hub. MCM provides a portal for the Hub Operator to submit Hub endpoint information and Hub certificates, and to retrieve DFSP endpoint and certificate details submitted by the DFSP via Payment Manager. + +### Security in Mojaloop + +To understand what connecting a DFSP to a Mojaloop environment entails in detail, it is important to take a closer look at the security requirements of Mojaloop. + +Mojaloop requires the following security measures to be implemented in order to protect the data exchanged between DFSPs: + +* **Transport Layer Security** is a secure mechanism for exchanging a shared symmetric key over a network between two anonymous peers, with identity verification (that is, trusted certificates). It provides confidentiality (no one has read the content) and integrity (no one has changed the content). Mojaloop requires two-way TLS mutual authentication using X.509 certificates for securing bi-directional connections. DFSPs and the Mojaloop Hub authenticate each other to ensure that both parties involved in the communication are trusted. Both parties share their public certificates with each other and then verification/validation is performed based on that. +* Another security measure that is offered for authentication is the **OAuth tokens** that DFSPs are required to use when making an API call request. OAuth 2 is used to provide role-based access to Mojaloop Hub endpoints (API authorization). +* **IP address whitelisting** reduces the attack surface of the Mojaloop Hub. +* To protect the application level, Mojaloop implements **JSON Web Signature (JWS)** as defined in [RFC 7515 (JSON Web Signature (JWS))](https://tools.ietf.org/html/rfc7515), the standard for integrity and non-repudiation. Signing messages ensures the Payer DFSP and the Payee DFSP can trust that messages shared between each other have not been modified by a third party. +* The Mojaloop FSPIOP API implements support for the **Interledger Protocol (ILP)**. ILP is built on the concept of conditional transfers, in which ledgers involved in a financial transaction from the Payer to the Payee can first reserve funds out of a Payer account and later commit them to the Payee account. The transfer from the Payer to the Payee account is conditional on the presentation of a fulfilment that satisfies the condition attached to the original transfer request. + +![Security overview](../../../.vuepress/public/security_overview.png) + +The next sections provide background information about the steps involved in connecting to a Mojaloop environment. The information provided is written in a way so that DFSPs and the Hub can rely on PKI best practices and any proprietary tools and technologies that they prefer or have access to. + +::: tip +As mentioned above, using Payment Manager OSS, Mojaloop Connection Manager (MCM), and the Infrastructre-as-Code (IaC) that deploys the components making up the Mojaloop ecosystem, many of the steps in the processes described below can be done in an automated way. +::: + +#### Creating and sharing certificates + +##### TLS certificates + +Two-way or mutual TLS authentication (mTLS) relies on both parties (client and server) sharing their public certificates with each other and performing verification/validation based on that. + +The following high-level steps describe how connection is established and data is transferred between a client and server in the case of mTLS: + +1. The client requests a protected resource over the HTTPS protocol and the SSL/TLS handshake process begins. +1. The server returns its public certificate to the client along with a server hello. +1. The client validates/verifies the received certificate. The client verifies the certificate through the Certificate Authority (CA) for CA-signed certificates. +1. If the server certificate was validated successfully, the server requests the client certificate. +1. The client provides its public certificate to the server. +1. The server validates/verifies the received certificate. The server verifies the certificate through the Certificate Authority for CA-signed certificates. + +After completion of the handshake process, the client and server communicate and transfer data with each other, encrypted with the secret keys shared between the two during the handshake. + + + +The above process requires that before connecting to any environment (pre-production or production), the DFSP and the Mojaloop Hub each complete the following steps. + +1. Create a server certificate signed by your CA. +1. Share your server certificate and CA chain with the other party. +1. Install the other party's CA chain in your outbound firewall (validation/verification will happen against these installed certificates). +1. Generate a Certificate Signing Request (CSR) for your TLS client certificate and share with the other party. +1. Sign the other party's CSR using your CA. +1. Share the signed client certificate as well as your CA's root certificate with the other party. +1. Install your own client certificate signed by the other party's CA in your outbound API gateway. +1. Install the root certificate of the other party's CA in your outbound API gateway. + +##### JWS certificates + +Whenever an API client sends an API message to a counterparty, the API client should sign the message using its JWS private key. After the counterparty receives the API message, it must validate the signature with the sending party's public JWS key. JWS is used by the receiving party to validate that the message came from the expected sender, and that it has not been modified in transit. + +The above process requires that all DFSPs and the Mojaloop Hub itself have a JWS certificate and that before connecting to any environment (pre-production or production), the DFSP and the Mojaloop Hub each complete the following steps. + +1. Create a keystore (to hold your certificate and private key), an asymmetric key pair (a public key and a private key), and an associated certificate that identifies you. +1. Share your JWS public key. +1. Install the other parties' (the Hub and all other DFSPs) JWS public key in your inbound gateway. +1. Install your JWS private key in your outbound gateway. + +#### Sharing endpoint information + +The Mojaloop Hub and the DFSPs share endpoint information to: + +* whitelist the other party's public IP addresses in firewall rules in order to allow traffic +* configure the other party's callback URLs in API gateways + +Typically, access to any incoming and outgoing traffic for a DFSP will be controlled by the relevant Security team. The DFSP's firewall needs to be appropriately configured: + +* to access the Mojaloop Hub in any environment where the DFSP and the Hub interact, and +* for the Mojaloop Hub to make callbacks to the DFSP + +Apart from access to and from the Hub deployed in an environment, all other public access should be blocked to prevent any unauthorized/unwarranted access. + +Accordingly, access to the Mojaloop Hub is also regulated. DFSPs have to share their IP/IP range from which calls will be made to the Hub so that the firewall on the Hub can be configured appropriately. The Security team within the DFSP should be able to provide that information. + +#### Obtaining an OAuth token + +The Mojaloop Hub employs WSO2 technologies for integration between the Hub and DFSPs, and to provide a gateway to DFSPs. To connect to the various Hub environments, DFSPs must obtain access to WSO2. WSO2 offers an API Store portal where DFSPs can create API gateway accounts for application-level access, subscribe to APIs, and obtain OAuth tokens for use when interacting with the Mojaloop Hub. + +## Onboarding in the Hub backend + +Onboarding comprises certain steps that do not require any actions from DFSPs and are the sole responsibility of the Hub Operator. These steps are as follows: + +1. Configure the Hub API gateways that handle incoming and outgoing data flows from/to DFSPs. Mojaloop employs WSO2 technologies for gateway access, as well as DFSP authorization and authentication for message pass-through via the gateways. The WSO2 product stack can be deployed from code using a continuous integration and deployment (CI/CD) solution, provisioning can be done through automation scripts. +1. Create users and accounts, configure role-based access control. +1. Set up the Hub for managing the use cases supported by the Scheme: + - Configure Hub ledgers. + - Configure Hub notification emails. + - Configure settlement model. + - Onboard oracles. \ + Mojaloop provides a [provisioning script](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning/MojaloopHub_Setup) to perform all of the above steps in an automated way using the [Mojaloop Testing Toolkit (TTK)](https://github.com/mojaloop/ml-testing-toolkit). +1. Set up simulator DFSPs for initial validation activities. \ + Mojaloop provides [provisioning scripts](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning/MojaloopSims_Onboarding) to perform this step in an automated way using the Mojaloop Testing Toolkit (TTK). +1. Set up DFSPs in the Hub backend. For each DFSP: + - Add DFSP and create a currency for it. + - Add callback URLs for all API services. + - Add a Net Debit Cap and set initial Position to 0. + - Configure DFSP notification emails. \ + Similar to previous steps, the configuration of DFSP details can also be done via a provisioning script. + +## Testing and validation + +As DFSPs moves forward in their onboarding journey, they are required to perform tests in each environment. Business validation and technical requirements both need to be met when testing. Details of business validation are defined in the Scheme Rules. + +Here are some examples of the testing activities that DFSPs are expected to perform in the various pre-production environments: + +* end-to-end integration and application layer validation against simulators +* end-to-end integration and application layer validation against real, friendly DFSPs +* settlement process validation +* security setup validation +* validation of response time Service Level Agreements (SLAs) +* performance testing diff --git a/docs/adoption/HubOperations/Portalv2/accessing-the-portal.md b/docs/adoption/HubOperations/Portalv2/accessing-the-portal.md new file mode 100644 index 000000000..b47b21c7b --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/accessing-the-portal.md @@ -0,0 +1,92 @@ +# Accessing the portal + +On accessing the portal, you are prompted to log in. Enter your credentials on the login page. + + + +The portal implements role-based access control, meaning that the role you have determines the range of portal functionalities available to you. Currently, the following roles exist: + +* `portaladmin`: has full access to all portal functionalities +* `portaluser`: has limited access to portal functionalities + +The following table lists all available functionalities, the navigation paths where you can access them, and the relevant roles permissions. + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Portal functionalities and navigation paths
FunctionalityNavigation pathportaladminportaluser

View settlement window details

Settlement > Settlement Windows

Close settlement windows

Settlement > Settlement Windows

Settle settlement windows

Settlement > Settlement Windows

Finalize settlement

Settlement > Settlement Windows

View settlement details

Settlement > Settlements

View DFSP financial details

Participants > DFSP Financial Positions

Disable and re-enable transactions for a DFSP

Participants > DFSP Financial Positions

Record deposits to or withdrawals from DFSPs' liquidity accounts

Participants > DFSP Financial Positions

Update a DFSP’s Net Debit Cap

Participants > DFSP Financial Positions

x

Search for transfer data

Transfers > Find Transfers

\ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/busops-portal-introduction.md b/docs/adoption/HubOperations/Portalv2/busops-portal-introduction.md new file mode 100644 index 000000000..01159a2a0 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/busops-portal-introduction.md @@ -0,0 +1,23 @@ +# Introduction – Guide to Finance Portal v2 + +This guide is aimed at the Operator of a Mojaloop Hub and provides information about the Finance Portal, which facilitates the management of settlement-related processes on a daily basis. + +::: tip NOTE +The Finance Portal is labelled as "Business Operations Portal" on the portal user interface itself. +::: + +The portal provides functionality to: + +* [search for settlement windows and check settlement window details](managing-windows.md) +* [close and settle settlement windows](settling.md) +* [settle settlements](settling.md) +* [search for settlements and check settlement details](checking-settlement-details.md) +* [monitor DFSP financial details such as Balance, current Position, Net Debit Cap, percentage of NDC used](monitoring-dfsp-financial-details.md) +* [disable and re-enable transactions for a DFSP](enabling-disabling-transactions.md) +* [update a DFSP's Net Debit Cap](updating-ndc.md) +* [record deposits to or withdrawals from a DFSP's liquidity account](recording-funds-in-out.md) +* [search for transfer data](searching-for-transfer-data.md) + +::: tip NOTE +The Finance Portal currently only supports settlement processes that rely on the Deferred Net Settlement model. +::: \ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/checking-settlement-details.md b/docs/adoption/HubOperations/Portalv2/checking-settlement-details.md new file mode 100644 index 000000000..39dc18f94 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/checking-settlement-details.md @@ -0,0 +1,52 @@ +# Checking settlement details + +The **Settlement > Settlements** page allows you to view certain details of settlements, such as: + +* settlement identifier +* state of the settlement +* the total value of transactions +* the identifiers of the DFSPs involved in the transactions, as well as the associated Multilateral Net Settlement Position in the chosen period + +![Checking settlement details](../../../.vuepress/public/check_settlement_details.png) + +The **Settlements** page provides a list of settlements that you can filter using various search criteria: + +* **Date**: Provides a drop-down list of time ranges. The default value is **Today**. \ +\ +The **Clear** option allows you to remove any date filters already applied. +* **From** and **To**: Displays the start time and end time of the time range selected in the **Date** field. When **Date** is set to **Custom Range**, you have to set the date and time yourself in the **From** and **To** fields. +* **State**: Provides a drop-down list of settlement states. + * **Pending Settlement**: A new settlement consisting of one or more settlement windows has been created. The Multilateral Net Settlement Position due to/from each participant has been calculated. + * **Ps Transfers Recorded**: The Hub has marked the affected transfers as `RECEIVED_PREPARE` in its internal records. + * **Ps Transfers Reserved**: The Hub has marked the affected transfers as `RESERVED` in its internal records. + * **Ps Transfers Committed**: The Hub has marked the affected transfers as `COMMITTED` in its internal records. + * **Settling**: Settlement is ongoing. + * **Settled**: Settlement has completed. + * **Aborted**: The settlement could not be completed and should be rolled back. +* **Clear Filters** button: Allows you to remove all filters you applied. + +As you apply search criteria, the list of results (settlements) is continuously updated. + +The following details are shown: + +* **Settlement ID**: The unique identifier of the settlement. +* **State**: The status of the settlement. +* **Total Value**: The total value of transactions within the settlement batch. +* **Open Date**: The date and time when the settlement was created in the Hub. +* **Last Action Date**: The date and time when the last action was taken on the settlement in the Hub (for example, funds have been reserved, funds have been committed). +* **Action**: **Finalize** button. Allows you to finalize a settlement. This button is only displayed for Pending Settlements. For details about finalizing a settlement, see [Settling](settling.md#finalizing-a-settlement). + +To view details for a particular settlement, click the settlement in the results list. The **Settlement Details** pop-up window is displayed. + +![Settlement details pop-up window](../../../.vuepress/public/settlement_details_popup.png) + +The following additional details are shown: + +* **DFSP**: The unique identifier of the DFSP. +* **Window ID**: The unique identifier of the settlement window being settled. +* **Debit**: Aggregated debit amount resulting from the transfers that the DFSP engaged in. +* **Credit**: Aggregated credit amount resulting from the transfers that the DFSP engaged in. + +::: tip NOTE +At the time of writing, the information that clicking the **View Net Positions** button should display is not available. It will be added in a future version of the portal. +::: \ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md b/docs/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md new file mode 100644 index 000000000..73bd59d63 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md @@ -0,0 +1,28 @@ +# Disabling and re-enabling transactions for a DFSP + +In certain cases, it may be necessary to make a DFSP inactive temporarily or permanently. An example scenario is when you observe highly suspicious behavior and the actual cause needs investigation, the risk of money loss being too high. + +The **Participants** > **DFSP Financial Positions** page provides an option to stop the sending and receiving of transfers for a particular DFSP by disabling its Position Ledger at the click of a button. + +(The Hub maintains a Position Ledger for each DFSP. The Position Ledger tracks how much a DFSP owes or is owed. Every time a transfer is processed, the Position in the Hub is adjusted in real time.) + +To disable transactions for a particular DFSP, complete the following steps: + +::: warning +Disabling a DFSP will stop all incoming and outgoing transactions for that DFSP, so ensure you apply this option with care. Once the risk has been cleared, remember to resume services for the DFSP. +::: + +1. Go to the **Participants** > **DFSP Financial Positions** page. +1. Find the entry of the DFSP you want to disable. +1. Click the **Disable** button. + + + +To resume services for the DFSP that you have disabled previously, complete the following steps: + +1. Go to the **Participants** > **DFSP Financial Positions** page. +1. Find the entry of the DFSP you want to enable. +1. Click the **Enable** button. + + + diff --git a/docs/adoption/HubOperations/Portalv2/managing-windows.md b/docs/adoption/HubOperations/Portalv2/managing-windows.md new file mode 100644 index 000000000..fede50285 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/managing-windows.md @@ -0,0 +1,50 @@ +# Checking settlement window details + +The **Settlement Windows** page allows you to: + +* search for settlement windows based on multiple search criteria +* close an open settlement window +* settle a single window or settle multiple windows at once + +::: tip NOTE +Remember that settling must follow this procedure: + +* Close the settlement window that you want to settle. +* Settle closed window(s) of your choice. This creates a new settlement. +* Send settlement reports to DFSPs and the settlement bank, and obtain a confirmation from the bank that it has moved money in accordance with the report. +* Finalize the new settlement created in Step 2. + +Given that closing a window and initiating settlement by settling select windows are integral part of the settlement process, they are described in a section dedicated to [settling](settling.md). +::: + +A settlement window is a time period between two successive settlements. It has a start time and an end time, and any transfers that go through (and reach a `"COMMITTED"` state) during the time that the settlement window is open will be settled in bulk after the settlement window has closed. + +Transfers that take place in the same settlement window are settled in batch after the end of the settlement window. + +To access the **Settlement Windows** page, go to **Settlement** > **Settlement Windows**. + +![Managing settlement windows](../../../.vuepress/public/settlement_window_mgmt.png) + +The **Settlement Windows** page provides a list of settlement windows that you can filter using various search criteria: + +* **Date**: Provides a drop-down list of time ranges. The default value is **Today**. \ +\ +The **Clear** option allows you to remove any date filters already applied. +* **From** and **To**: Displays the start time and end time of the time range selected in the **Date** field. When **Date** is set to **Custom Range**, you have to set the date and time yourself in the **From** and **To** fields. +* **State**: Provides a drop-down list of settlement window states: + * **Open**: The settlement window is open, transfers are being accepted into the current open window. + * **Closed**: The settlement window is closed. It is not accepting any additional transfers and all new transfers are being allocated to a new, open settlement window. + * **Pending**: The settlement window is closed, but the settlement window still needs to be settled. A window can only be settled once the settlement bank has confirmed that all the participant DFSPs that engaged in transfers in the settlement window have settled their payments. + * **Settled**: The settlement bank has confirmed that all the affected DFSPs have settled their obligations towards one another. Following confirmation, the Hub Operator has settled the settlement window. + * **Aborted**: The settlement window was part of a settlement that got aborted. It is possible to add the aborted window to a new settlement. + * **Clear**: Allows you to remove any window state filters already applied. +* **Clear Filters** button: Allows you to remove all filters you applied. + +As you apply search criteria, the list of results (settlement windows) is continuously updated. The search results list displays the following details: + +* Window selector: Only displayed for **Pending** settlement windows. Clicking the window selector activates the **Settle Selected Windows** button. For details about settling a settlement window, see [Settling](settling.md#settling-a-closed-settlement-window). +* **Window ID**: The unique identifier of the settlement window. +* **State**: The state of the settlement window. +* **Opened Date**: The date and time when the settlement window was opened. +* **Closed Date**: The date and time when the settlement window was closed. +* **Action**: **Close Window** button. Allows you to close a settlement window. This button is only displayed for **Open** settlement windows as only open windows can be closed. For details about closing a settlement window, see [Settling](settling.md#closing-a-settlement-window). \ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md b/docs/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md new file mode 100644 index 000000000..0838ce654 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md @@ -0,0 +1,24 @@ +# Monitoring DFSP financial details + +The **DFSP Financial Positions** page allows you to monitor DFSPs' financial details such as Balance, current [Position](settlement-basic-concepts#position), [Net Debit Cap](settlement-basic-concepts#liquidity-management-net-debit-cap), percentage of NDC used. + +To access the **DFSP Financial Positions** page, go to **Participants** > **DFSP Financial Positions**. + +![Monitoring DFSP financial details](../../../.vuepress/public/dfsp_financial_positions_2.png) + +The following details are displayed for each DFSP: + +* **Balance**: Reflects the balance of the DFSP's liquidity account at the settlement bank. +* **Current Position**: The current Position of the DFSP. \ +\ +The Position of a DFSP reflects – at a given point in time – the sum total of the transfer amounts sent and received by the DFSP. The Position is the sum of all outgoing transactions minus incoming transactions since the beginning of the settlement window, as well as any provisional transfers that have not yet been settled. \ +\ +Each attempted outgoing transfer results in the Position being recalculated by the Mojaloop Hub in real time, which, in turn, is compared to the Net Debit Cap. \ +\ +Once the settlement window is closed, then Positions are adjusted based on the settlement – the Position changes to the net amount of the transfers that were not initiated or not yet fulfilled when the settlement window was closed. +* **NDC**: The Net Debit Cap set for the DFSP. \ +\ +When pre-funding their liquidity account, DFSPs define the maximum amount that they can "owe" to other DFSPs, this is called the Net Debit Cap (NDC). The NDC acts as a limit or a cap placed on a DFSP’s funds available for transacting, and it can never exceed the balance of the liquidity account. This is required to ensure that a DFSP's liabilities can be met with funds immediately available to the settlement bank. \ +\ +The Position is continuously checked against the Net Debit Cap ((TransferAmount + Position) < = NDC) and if a transfer would cause the Position amount to exceed the NDC amount, the transfer is blocked. +* **% NDC Used**: A Position/NDC indicator to show the percentage of NDC used. diff --git a/docs/adoption/HubOperations/Portalv2/recording-funds-in-out.md b/docs/adoption/HubOperations/Portalv2/recording-funds-in-out.md new file mode 100644 index 000000000..c30c25e6d --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/recording-funds-in-out.md @@ -0,0 +1,31 @@ +# Recording funds in or funds out for a DFSP + +The **DFSP Financial Positions** page allows you to record funds in or funds out in the Hub's ledgers in the case of movement of funds initiated by the DFSP: a DFSP deposits funds in their liquidity account or withdraws funds from their liquidity account. + +To access the **DFSP Financial Positions** page, go to **Participants** > **DFSP Financial Positions**. + + + +To record funds in or funds out for a DFSP, complete the following steps: + +1. Click the **Update** button next to the DFSP for which you want to record funds in/out. \ +![](../../../.vuepress/public/add_withdraw_funds.png) \ +The **Update Participant** window pops up. +1. Select **Add / Withdraw Funds** from the **Action** drop-down menu. \ + +1. Select the **Add Funds** or **Withdraw Funds** option depending on the action you want to take. \ +To record a deposit, use **Add Funds**. \ +To record a withdrawal, use **Withdraw Funds**. \ + +1. Enter the amount added or withdrawn by the DFSP in the **Amount** field. \ +Do not specify a plus or a minus sign when entering the amount. Instead, ensure you have selected the right action in the previous step. +1. Click **Submit**. +1. On clicking **Submit**, a confirmation window pops up asking you to confirm the action, or confirm and also update the Net Debit Cap of the DFSP. \ + + +1. Click **Confirm Only** or **Confirm and Update NDC**. \ +\ +On clicking **Confirm Only**, the **Balance** value on the **DFSP Financial Positions** page gets updated and the Hub adjusts the ledgers. \ +\ +On clicking **Confirm and Update NDC**, the **Update Participant** window changes and allows you to update the Net Debit Cap (NDC). \ + diff --git a/docs/adoption/HubOperations/Portalv2/searching-for-transfer-data.md b/docs/adoption/HubOperations/Portalv2/searching-for-transfer-data.md new file mode 100644 index 000000000..bdd6cb294 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/searching-for-transfer-data.md @@ -0,0 +1,189 @@ +# Searching for transfer data + +The Finance Portal provides a transfer search page, which allows you to find transfer data based on DFSP identifiers, end user identifiers, or transfer identifiers. This is useful when resolving issues. + +::: tip NOTE +The values displayed on the **Find Transfers** page are pulled from the Hub's central-ledger database. +::: + +## Finding transfers + +To find transfers, complete the following steps: + +1. Go to **Transfers** > **Find Transfers**. The **Find Transfers** page is displayed. \ + +1. Use the search filters to specify what you are looking for. You can fill in any number of search fields, in any combination. + * **Transfer ID**: Enter a full `transferId` or a fragment of a `transferId`. + * **Payer FSP ID**: Enter the full `fspId` or a fragment of the `fspId` of the Payer DFSP. + * **Payer ID Type**: Using the drop-down list, select the type of identifier used to identify the Payer (for example, **MSISDN** or **ACCOUNT_ID**). + * **Payer ID Value**: Enter the full identifier or a fragment of the identifier used to identify the Payer (for example, a phone number or a bank account number). + * **Payee FSPID**: Enter the full `fspId` or a fragment of the `fspId` of the Payee DFSP. + * **Payee ID Type**: Using the drop-down list, select the type of identifier used to identify the Payee. + * **Payee ID Value**: Enter the full identifier or a fragment of the identifier used to identify the Payee. + * **From** and **To**: Enter the start time and end time of the time range when the transfer(s) you are looking for happened. +1. Once you have set your search filters, click **Find Transfers**. The list of search results that meet the search criteria are displayed. + +Use the page navigation buttons at the bottom of the screen to navigate between pages of search results. + +You can remove all the filters you applied and start your search from scratch by clicking **Clear Filters**. + +Search results are displayed in columns. All columns are sortable: + +* Click a column header to change the sort order of the values displayed in the column. +* Click the magnifying-glass icon in the column header and enter a value that you are looking for. + +::: tip +The total number of transfers that get returned are limited to a thousand (1000) (this is to keep the load off the backend). If you are not able to find the transfer that you are looking for within the first thousand results, then start narrowing your search, using the search filters. \ + \ +If your search returns more than five hundred (500) results, the page will display an information message so you know that you do not necessarily see all results that meet your original search criteria and you should drill down more. +::: + +The following details are displayed for a transfer: + +::: tip NOTE +Transfers without quotes (that is "add/withdraw funds" transfers and settlement transfers) will display details for the following fields only: **Transfer ID**, **Timestamp**, **Amount**, **Currency**, **Status**. +::: + +* **Transfer ID**: The unique identifier of the transfer (corresponds to `transferId`). +* **Type**: The type of the transfer (corresponds to `transactionType` in Payment Manager and `transactionScenario` in the Mojaloop FSPIOP API). +* **Timestamp**: The date and time when the transfer request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **Payer FSPID**: The `fspId` of the Payer DFSP. +* **Payee FSPID**: The `fspId` of the Payee DFSP. +* **Amount**: The transfer amount. +* **Currency**: The currency of the transfer. +* **Status**: The state of the transfer (corresponds to `transferState` in Payment Manager and the Mojaloop FSPIOP API). +* **Payer Acct ID**: The identifier type and identifier value of the Payer's account. +* **Payee Acct ID**: The identifier type and identifier value of the Payee's account. + +## Transfer details + +To find out more details about a particular search result, click its entry in the search result list. A **Transfer Details** window pops up. This section provides information about the details that are displayed for a transfer. + +### Quote Requests + +The **Quote Requests** tab displays the `quoteId` and further information on sub-tabs. + +#### Quote Request sub-tab + + + +The **Quote Request** sub-tab displays the following details about the quote request: + +* **quoteId**: The unique identifier of the quote, decided by the Payer DFSP. +* **transactionReferenceId**: Corresponds to the `transactionId` specified in the quote request. +* **transactionRequestId**: Optional. Common ID between the DFSPs for the transaction request object, decided by the Payee DFSP. +* **note**: An optional memo attached to the transfer. +* **expirationDate**: An optional quote request expiration date, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **amount**: The amount that the quote is being requested for. +* **createdDate**: The date and time when the quote request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **transactionInitiator**: Specifies if the initiator of the transfer is the **PAYER** or the **PAYEE**. +* **transactionInitiatorType**: Specifies the type of the initiator: + * **CONSUMER**: Consumer is the initiator of the transaction. For example: peer-to-peer transfer or loan repayment from wallet. + * **AGENT**: Agent is the initiator of the transaction. For example: loan repayment via an agent. + * **BUSINESS**: Business is the initiator of the transaction. For example: loan disbursement. + * **DEVICE**: Device is the initiator of the transaction. For example: merchant-initiated merchant payment authorized on POS. +* **transactionScenario**: Specifies the transaction scenario (corresponds to `transactionType` in Payment Manager). +* **transactionSubScenario**: Specifies the transaction sub-scenario defined by the scheme. +* **balanceOfPaymentsType**: The BoP code as defined in [the IMF's Balance of Payments Coding System](https://www.imf.org/external/np/sta/bopcode/). +* **amountType**: **SEND** for send amount, **RECEIVE** for receive amount. +* **currency**: The currency of the amount that the quote is being requested for. A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). + +#### Quote Parties sub-tab + + + +The **Quote Parties** sub-tab displays the following details about the Payer DFSP and Payee DFSP: + +* **quoteId**: The unique identifier of the quote, decided by the Payer DFSP. +* **partyIdentifierType**: The type of identifier used to identify the party (for example, **MSISDN** or **ACCOUNT_ID**). +* **partyIdentifierValue**: The value of the identifier used to identify the party (for example, a phone number or a bank account number). +* **fspId**: The unique identifier of the DFSP registered in the Hub (corresponds to `fspId`) - as provided in the quote. +* **merchantClassificationCode**: Used when the Payee is a merchant accepting merchant payments. +* **partyName**: The display name of the party. +* **transferParticipantRoleType**: The role that the DFSP is playing in the transfer. +* **ledgerEntryType**: The type of financial entry this party is presenting — principal value (that is, the amount of money that the Payer wants the Payee to receive) or interchange fee. +* **amount**: The amount that the quote is being requested for. +* **currency**: The currency of the amount that the quote is being requested for. A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **createdDate**: The date and time when the quote request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **partySubIdOrTypeId**: A sub-identifier or sub-type for the party. +* **participant**: Reference to the resolved `fspId` (if supplied/known). + +#### Quote Errors sub-tab + +The **Quote Errors** sub-tab only displays information if there was an error in the quotes stage. + +### Quote Responses + + + +The **Quote Responses** tab displays details about the quote response: + +* **quoteId**: The unique identifier of the quote, decided by the Payer DFSP. +* **transactionReferenceId**: Corresponds to the `transactionId` specified in the quote request. +* **quoteResponseId**: The unique identifier of the quote response. +* **transferAmountCurrencyId**: The currency of the transfer amount. A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **transferAmount**: The amount that the Payer DFSP should transfer to the Payee DFSP. +* **payeeReceiveAmountCurrencyId**: The currency of the amount that the Payee should receive in the end-to-end transaction. +* **payeeReceiveAmount**: The amount that the Payee should receive in the end-to-end transaction. +* **payeeFspFeeCurrencyId**: The currency of the Payee DFSP's part of the transaction fee (if any). A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **payeeFspFeeAmount**: The Payee DFSP's part of the transaction fee (if any). +* **payeeFspCommissionCurrencyId**: The currency of the transaction commission from the Payee DFSP (if any). A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **payeeFspCommissionAmount**: The transaction commission from the Payee DFSP (if any). +* **ilpCondition**: The ILP condition that must be attached to the transfer by the Payer side. +* **responseExpirationDate**: The quote's expiration date as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **isValid**: An indicator whether or not the quote response has passed request validation and duplicate checks. +* **createdDate**: The date and time when the quote request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **ilpPacket**: The ILP packet returned from Payee side in response to the quote request. + +### Transfer Prepares + + + +The **Transfer Prepares** tab displays details about the transfer request: + +* **transferId**: The unique identifier of the transfer. +* **amount**: The amount that the Payer DFSP should transfer to the Payee DFSP. +* **currencyId**: The currency of the transfer amount. A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **ilpCondition**: The ILP condition that must be fulfilled to commit the transfer. +* **expirationDate**: The transfer's expiration date as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **createdDate**: The date and time when the transfer request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. + +### Transfer Participants + + + +The **Transfer Participants** tab displays the following details about the participants of the transfer: + +* **transferParticipantId**: The internal identifier of the scheme participant (DFSP) for whom the report is requested, corresponds to `participantId` as recorded in the Hub. +* **transferId**: The unique identifier of the transfer. +* **participantCurrencyId**: The currency that the participant (DFSP) transacts in. A three-letter alphabetic code conforming to [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **transferParticipantRoleType**: The role that the DFSP is playing in the transfer. +* **ledgerEntryType**: The type of financial entry this party is presenting — principal value (that is, the amount of money that the Payer wants the Payee to receive) or interchange fee. +* **amount**: The transfer amount. +* **createdDate**: The date and time when the transfer request was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. + +### Transfer Fulfilments + + + +The **Transfer Fulfilments** tab displays the following details about the transfer response: + +* **transferId**: The unique identifier of the transfer. +* **ilpFulfilment**: The fulfilment of the ILP condition specified within the transfer request. +* **completedDate**: The date and time when the transfer was completed, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. +* **isValid**: An indicator whether or not the transfer fulfilment is valid. +* **settlementWindowId**: The identifier of the settlement window to which this transfer has been assigned. +* **createdDate**: The date and time when the transfer response was created, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. + +### Transfer State Changes + + + +The **Transfer State Changes** tab displays the following details about the states that a transfer goes through: + +* **transferStateChangeId**: The unique identifier of the transfer state. +* **transferId**: The unique identifier of the transfer. +* **enumeration**: The state of the transfer (corresponds to `transferState` in Payment Manager and the Mojaloop FSPIOP API). +* **description**: The description of what the state means. +* **reason**: The reason why the transfer moved into a particular state. +* **createdDate**: The date and time when the transfer reached a particular state, as an [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted timestamp. \ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/settlement-business-process.md b/docs/adoption/HubOperations/Portalv2/settlement-business-process.md new file mode 100644 index 000000000..31103b46e --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/settlement-business-process.md @@ -0,0 +1,68 @@ +# Settlement process + +It is important to define a business process around settlement management. The following high-level process serves as an example that you can customize to the specifics of your organization's needs. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Settlement business process
StepDetails

1

The Hub Operator closes the settlement window and initiates settlement for select windows using the Finance Portal.

2

The Hub Operator retrieves a DFSP Settlement Report for each DFSP that was active in the settlement window.

3

The Hub Operator emails the DFSP Settlement Report to each DFSP's nominated contact points.

4

DFSPs review their report and reconcile transactions against their own records in a timely manner.

+

The report provides information about the DFSP's bilateral settlement position with each DFSP they transacted with (either as a Payer DFSP or Payee DFSP) in the settlement window(s) being settled. It also provides the sum total of the transfer amounts sent and received by the DFSP in the settlement window(s).

5

The Hub Operator retrieves the Settlement Bank Report.

6

The Hub Operator notifies settlement bank contact points that settlement can be enacted, sharing the Settlement Bank Report.

The report acts as payment instructions to the bank, and provides the bilateral settlement position of each DFSP against every other DFSP that transacted in the settlement window(s) being settled. It also provides the sum total of the transfer amounts sent and received by each DFSP.

7

The settlement bank moves money between the settlement account and DFSPs' liquidity accounts, in accordance with the aggregated net Positions indicated in the Settlement Bank Report.

8

The settlement bank confirms that money moved, and (since the Hub Operator has no visibility of the balance of accounts held at the settlement bank) shares the balance of each DFSP’s liquidity account.

9

The Hub Operator finalizes the settlement using the Finance Portal.

10

The Hub Operator verifies DFSP liquidity account balances against the balances shown in the portal, and updates them if necessary, using the "add/withdraw funds" functionality of the portal. Note that this may cause the DFSP’s NDC to be recalculated, potentially causing the DFSP’s outbound transactions to be declined by the Hub.

11

The Hub Operator retrieves a DFSP Settlement Result Report for each DFSP.

12

The Hub Operator notifies each DFSP of the settlement result and their liquidity account balance by sending the DFSP Settlement Result Report to each DFSP.

\ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/settling.md b/docs/adoption/HubOperations/Portalv2/settling.md new file mode 100644 index 000000000..aa4e41b91 --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/settling.md @@ -0,0 +1,67 @@ +# Settling + +1. [Close the settlement window](#closing-a-settlement-window) that you want to settle. +1. [Settle closed window(s) of your choice](#settling-a-closed-settlement-window). This creates a new settlement. +1. Send settlement reports to DFSPs and the settlement bank, and obtain a confirmation from the bank that it has moved money in accordance with the report. +1. [Finalize the new settlement](#finalizing-a-settlement) created in Step 2. + +This section describes those steps of the process (Steps 1, 2, and 4) that you perform via the portal. + +## Closing a settlement window + +To close an open settlement window, complete the following steps: + +1. Go to **Settlement** > **Settlement Windows**. The **Settlement Windows** page displays. +1. Find the settlement window that you are looking for, [using the search filters](managing-windows.md). +1. The open window will have a **Close Window** button displayed next to it in the **Action** column. Click the **Close Window** button. + +![Closing a settlement window](../../../.vuepress/public/settlement_window_mgmt_close.png) + +Closing a window will automatically open a new window with the state of **Open**. + +## Settling a closed settlement window + +To settle one or more settlement windows, complete the following steps: + +1. Go to **Settlement** > **Settlement Windows**. The **Settlement Windows** page displays. +1. Find the settlement window that you are looking for, [using the search filters](managing-windows.md). The settlement window must be in the **Closed** state. +1. Click the window selector next to the settlement window(s) that you wish to settle. \ +\ + \ +\ +This activates the **Settle Selected Windows** button. Click the **Settle Selected Windows** button. \ +\ + +1. A **Settlement Submitted** window pops up, where you have the following options: + +* View submitted settlements +* Continue viewing windows \ +\ + \ +\ +If you wish to view the new settlement you have just created, click the **View Submitted Settlements** button. This takes you to the **Settlements** page, where you can search for the new settlement, [using the search filters](checking-settlement-details.md). The settlement will be in the **Pending Settlement** state. + +## Finalizing a settlement + +To finalize the settlement, complete the following steps: + +**Prerequisites:** + +* The settlement bank has confirmed that all the DFSPs' MLNS Positions have been settled. + +**Steps:** + +1. Go to **Settlement** > **Settlements**. The **Settlements** page displays. +1. Find the settlement that you are looking for, using the [search filters](checking-settlement-details.md). The settlement must be in the **Pending Settlement** state. \ +\ + +1. Click the **Finalize** button next to the settlement. A status window pops up that displays the states of the settlement with checkmarks being added as the settlement process progresses. \ +\ +When the settlement is finalized, you will see all states displayed with checkmarks next to them. The last state will say **State: SETTLED.** In addition, the **Close** button will be activated enabling you to return to the **Settlements** page. \ +\ + +1. Back on the **Settlements** page, when looking for the settlement, you should see the state of the settlement now display as **Settled**. + +::: tip +In case the settlement state is something other than **Settled**, then it means that the settlement has not finished for some reason. Click **Finalize** again to complete the unfinished settlement process. +::: \ No newline at end of file diff --git a/docs/adoption/HubOperations/Portalv2/updating-ndc.md b/docs/adoption/HubOperations/Portalv2/updating-ndc.md new file mode 100644 index 000000000..d8a8056ab --- /dev/null +++ b/docs/adoption/HubOperations/Portalv2/updating-ndc.md @@ -0,0 +1,22 @@ +# Updating the Net Debit Cap of a DFSP + +The **DFSP Financial Positions** page allows you to update the Net Debit Cap (NDC) of a DFSP. + +To access the **DFSP Financial Positions** page, go to **Participants** > **DFSP Financial Positions**. + +![Updating the NDC of a DFSP]("../../../.vuepress/public/dfsp_financial_positions_2.png") + +To update the Net Debit Cap of a DFSP, complete the following steps: + +1. Click the **Update** button next to the DFSP for which you want to update the NDC. \ + +The **Update Participant** window pops up. +1. Select **Change Net Debit Cap** from the **Action** drop-down menu. \ + +1. Enter the new NDC amount in the **Amount** field. \ + +1. Click **Submit**. +1. On clicking **Submit**, a confirmation window pops up asking you to confirm the action. \ + +1. Click **Confirm**. \ +On clicking **Confirm**, the **NDC** value on the **DFSP Financial Positions** page gets updated and displays the new NDC amount. \ No newline at end of file diff --git a/docs/adoption/HubOperations/RBAC/Role-based-access-control.md b/docs/adoption/HubOperations/RBAC/Role-based-access-control.md new file mode 100644 index 000000000..1e5bbd5eb --- /dev/null +++ b/docs/adoption/HubOperations/RBAC/Role-based-access-control.md @@ -0,0 +1,312 @@ +# RBAC Context +The Mojaloop Hub uses a Role-Based Access Control (RBAC) method for mitigating risk. + +## What is RBAC and how to design for it? + +Role-based access control (RBAC) is a method of restricting network access based on the roles of individual users within an enterprise. RBAC lets employees have access rights only to the information they need to do their jobs and prevents them from accessing information that doesn't pertain to them. + +The RBAC design for a hub operator, outlines the security control points that should be considered or extended in order to mitigate risk within a typical Mojaloop hub operations organisation. Some control points are business processes and organisational structure related, some control points are technical relating to the identification, authentication and authorisation layers, and some control points require monitoring. All three should be considered to create accountability and mitigate risk. + +This document covers: +1. RBAC Overview.
+Where we discuss RBAC principles and organsational structures. +2. Technical implementation of the RBAC controls.
+Specificaly what is important for a Mojaloop Implementation and how to inforce this technically. +3. Role recommendations +4. Monitoring requirements and approach. + +## RBAC Overview + +### Principle of least privilege + +RBAC uses the security principle of least privilege. Least privilege means that a user has precisely the amount of privilege that is necessary to perform a job. The aim of this is to minimize the likelihood of issuing a user with excess permissions to complete actions in Mojaloop ecosystem. + +### Zero Trust Mojaloop Implementation + +A zero trust network is one in which no person, device, or network enjoys inherent trust. All trust, which allows access to information, must be earned, and the first step of that is demonstrating valid identity. A system needs to know who you are, confidently, before it can determine what you should have access to. + +Mojaloop's inherent design will implement a Zero Trust approach in its architecture and deployment requiring all entities that interact to first authenticate themselves, then seek authorization to access and process data depending on the role they belong to. + +### Segregation of Duties + +Segregation of Duties focuses on mitigating the risk of internal fraud by setting boundaries between roles assigned to an employee, and between the conflict of interest that may result from an employee's responsibilities, ensuring no single user can have end to end functional control of a business process and its data. It requires more than one individual to create, process and complete an action. + +### Audit + +Audit would need to work collaboratively with the business and the IT teams to Segregate these duties wherever possible and assign an appropriate mitigation control in cases wherein it is not feasible to do so. In addition, these controls would need to be monitored on a quarterly basis and the results need to be reported to senior management. + +Some contextual definitions include: +1. **Action** : a distinct event triggered by a user that results in: + - Creation of a data asset + - Reading or accessing of a data asset + - Update or effecting changes to the state of a data asset + - Delete or the removal of a data asset from an application or database. +2. **Permission** : authority to perform a specific action in the context of an application or service +3. **Role** : applications, actions and data access required to perform the tasks related to a single role +4. **User - role relationship** : The role (roles) assigned to each user that defines the permissions they have + +## Technical RBAC implementation + +An individual who needs to access the various Mojaloop Hub management portals can be registered and an “account” generated, which can be used to access various aspects of an operational instance of a Mojaloop Hub and to provide a basis for auditing that access by tying activities to the original registration. For the purposes of this document, an “account” is a digital identity, a means of authenticating (linking) the person asserting that identity to the original registration, and a set of attributes, which will include - among other things - a set of access rights, or rights that are enabled through the possession of those attributes. + +The registration process involves identity verification, background checking, and so on. The individual is then issued with credentials - a login account ID/digital identity and at least one authentication method, which may include a password and two-factor authentication (2FA). + +::: tip NOTE +The scope of this document is not limited to Mojaloop Hub operators. It also addresses aspects of DFSP operator access to the Payment Manager portals. +::: + +### 2FA considerations + +It should be noted that 2FA via a mobile phone may be inappropriate for some roles, since highly sensitive roles may require that mobile phones are locked away while the individual is “on shift”. This will necessitate other 2FA methods, such as key fobs. + +### Users, actions and roles in a Mojaloop context + +Mojaloop will have 2 Broad categories of users: + +1. **Human**
+These are hub and DFSP users who through various interfaces will interact with Mojaloop. DFSP users will interact with Mojaloop through the Payment Manager and portals that will be made available during the onboarding process. +2. **Non-human**
+These will automate the business processes and automate tasks that would otherwise be done by a human. These will communicate via API calls that will affect actions to fulfil business requirements. + +The context of this document will focus on Human users only. + +### User Lifecycle Management + +The "User Account Lifecycle" defines the collective management processes for every user account. These processes can be broken down into Creation, Review/Update, and Deactivation—or "CRUD". If any organization utilizes IT resources of any kind, they rely on user accounts to access them. + +### Onboarding + +The Onboarding process will have some activities involving user creation both at DFSP end and at the Hub. These will be as follows: + +1. Hub: The following users will be created + - Hub Operators + - Hub Administrators +2. DFSP + - DFSP Operators + - DFSP administrators (only applicable to Payment manager). + + +### Process of Segregation Of Duties determination + +1. Define user management workflows and processes. These are all business processes that make up Mojaloop business actions in Mojaloop. Examples include Onboarding. +1. Rationalise all User security access requirements for Applications of Mojaloop as outlined in the table below: + - Define business and application functions for users and APIs + - Define role profiles + - Define function & competence profiles + - Gather a list of applicable SOD conflicts by defining segregation of duties roles + - Role profile matrix table (with example data): + +| **Roles and Permissions** **Matrix** | Hub Users | Administrator | Standard Maker User | Standard Checker User | Standard Read Only | DFSP Users | Administrator | Standard Maker User | Standard Checker User | Standard Read Only | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| Onboarding Roles | X | | | | | | | | | | +| Create User Account | X | | | | | | | | | | +| Create DFSP Profile | X | | | | | | | | | | +| Create DFSP User | X | | | | | | | | | | +| +| **Finance Portal** | +| View Reports | | | X | X | X | | | X | X | X | +| Platform Configuration | | | | | | | | | | | +| + +3. Reconfigure any conflicting roles + - Business approvals + - Maker checker user creation +4. Periodic System Access & User Authorisation reporting +5. Separation of IT-security and Operational IT security that will support user management activities + +### Best Practices for RBAC and Mojaloop Identity Management + +1. All user ids should be unique and have a unique format that can be correlated in the hub but not meaningful to outsiders. +2. DFSP Users will not have access to any administrative role Hub +3. All non-human users must be restricted from logging on to the application front ends. +4. DFSP users will be trained on the roles and best practices +5. Enforce automated user provisioning and life cycle management. +6. Classify actions performed in Mojaloop to identify business risky actions that require additional controls. +7. Additional controls to mitigate RBAC risks can include: + - Multifactor authentication (MFA) + - Audit logging with alerts + - Auto user profile deactivation / disabling +8. Mojaloop will monitor user inactivity and disable inactive users over a specified period +9. Enforce centralised policy enforcement across identities e.g. Password policy, login policies, MFA, risk based authentication etc. +10. Identify and closely monitor privileged identities that have permissions to perform sensitive actions. +The following apply to privileged users: + - Advanced privileges must be requested for and approved on a case-by-case basis; + - Administrators should have their privileged permissions for the minimum time possible; + - Administrators should only have the permissions required to complete a specific task; + - Membership in administrative groups must be reviewed regularly; + - Enforce multi-factor authentication for administrative users; + - Keep access logs, audits, and set-up real-time notifications when access is activated. +11. Mojaloop will configure audit logs and alerts for all user actions in Mojaloop. Where possible explore identity analytics via applicable open source tools. + +### Automated Identity Management and RBAC Control + +The tools preferred for user and identity management in a Mojaloop deployment are: + +1. **KeyCloak Identity Management engine** – Store and process API authentication controls as well as act as API gateway. +2. **WSO2 Identity management engine** – Store and process user role profiles and broker self onboarding of DFSP users. + +## Designing Roles within your organisaion + +A user with an account that allows access to the Hub will have roles associated with that account, which define what they can do once they are authenticated themselves and are logged in. + +Many roles apply to multiple portals, however, some roles may be specific to individual portals. + +Care should be taken when assigning multiple roles to an account, or multiple accounts to an individual natural person. This is due to the potential that arises for the circumvention of controls. Part of the purpose of RBAC is to ensure that more than one person must be in the authorization chain for important actions, thereby reducing the vulnerabilities around bad actors. + +### Mojaloop ecosystem portals + +The Mojaloop ecosystem offers a number of portals, which support varying degrees of access control and RBAC. These are split into two groups: + +- Hub portals, which are related to the operation of the Hub itself +- Payment Manager portals, which relate to the management of a specific DFSP’s connection to the Hub + +### RBAC in Mojaloop Hub + +In the Mojaloop Hub environment, RBAC is implemented through a combination of tools - Ory Oathkeeper for identity management, and Keycloak for access control (including roles and maker/checker). + +The Hub itself has the following portals: + +- **Hub Operator onboarding:**
+Currently there is no bundled Identity and Access Management (IAM) solution for Hub operators, though the function is partly filled through the use of WSO2. Development work is underway to develop a comprehensive IAM solution based around Ory and Keycloak. This will see an admin operator created alongside the deployment of the Hub, which acts as a first foundational step in this area. +- **Finance Portal:**
+It has two principal functions: the management of settlement operations, and the management of the liquidity position of individual DFSPs (and related to this, their Net Debit Cap (NDC) value). +Access to the Finance Portal is currently limited to a simple username/password access control function. +- **Participant lifecycle:**
+Controlling and configuring access to the Hub by DFSPs. +From a technical perspective, this is currently achieved through use of the Mojaloop Connection Manager (MCM). However, it is envisaged that MCM itself will be developed to present an API, which can be used to develop a UI that would be available to Hub Operators and to DFSPs. +- **Hub operations:**
+These include transaction searches, status and performance monitoring, dashboarding and overall tech ops. +Currently these are achieved through the use of Prometheus/Grafana and a range of other tools, with standard access control embedded in these tools themselves. It is envisaged that this will be migrated into the Ory/Keycloak solution, as this develops. + +Other Hub operations, such as Fraud Management and Case/Dispute Management, are add-on modules that implement their own access control to manage access to their sensitive functions. These are not addressed in this document. + +In addition to the above access control measures, it should be noted that access to all of these functions is only possible via a VPN, with individual credentials controlling access. + +As well as these portals, there are two other primary means of accessing the Hub, neither of which is subject to RBAC: + +- The first of these is transactions, which are strictly controlled according to their own multi-layered cybersecurity measures. +- And secondly, bulk payments (government-to-person - G2P), which are supported by means of an API that is subject to the same controls as other, single transactions. It is envisaged that bulk payments will be a service that is provided to DFSPs (and their customers) by means of a secure API, with the DFSP operating a bulk payment portal for use by their customers. It is possible that the operator of an instance of the Mojaloop Hub might make available a white label bulk payment portal, which interfaces with the Hub bulk payment API, for customization by any DFSP that wishes to offer the service to their customers. (Note that this is not a unique approach: a similar approach has been proposed, for example, for merchant payments, with a white label app for QR code transactions being made available for DFSPs to incorporate into their mobile wallets.) + +The access controls around either single or bulk payments are not therefore discussed further in this document. + +### Payment Manager for integration + +Payment Manager is currently one of the primary mechanisms for integrating DFSPs to a Mojaloop Hub. Whereas the Hub is singular in a scheme, there is a separate instance of Payment Manager for each DFSP. The portals offered by Payment Manager must therefore be secured by means of RBAC to limit access to authorized representatives of the DFSP. + +In the Payment Manager environment, RBAC is implemented solely through Keycloak. + +The following portals are available: + +- **User/Operator onboarding:** +Payment Manager includes Keycloak for IAM. On deployment, a single admin user is created, which can be used to create further user accounts. +- **Hub connection management:** +This includes the ability to configure the Hub connection from the Payment Manager side, and by implication to disable it. It is therefore a controlled function, with different controls for viewing versus modification. +- **Transaction investigation:** +It is possible to investigate transaction queries using the Payment Manager portal. This is potentially an issue if Personally Identifiable Information (PII) is available through the portal. + +### Foundational accounts + +At the time that a Hub is first stood up, Ory/Keycloak will be used to create a foundational user account with administrator privileges. A system administrator will be assigned this account. Note that the system administrator will not be assigned any operational roles beyond those of a system administrator. + +All functions carried out using Ory/Keycloak are subject to system-level logging for audit purposes. + +The system administrator will then use Ory/Keycloak to create further user accounts, subject to standard identity and background checks for each individual (defined under the Scheme Rules associated with a particular Mojaloop deployment) before their accounts are created. + +These new user accounts will be assigned one of these roles: + +- OPERATOR +- MANAGER + +A user account may not have both OPERATOR and MANAGER roles. + +### Further accounts + +In addition to the system administrator, the foundational accounts will have the ability to use Ory/Keycloak to add further accounts. However, for these users, this activity will be subject to maker/checker controls. A user with role OPERATOR will be able to set up a user account (with processes in place to ensure that due diligence around identity verification and background checks have taken place). However, this account will not be activated until a person with role MANAGER approves it. + +A role will be assigned to each of these accounts, as they are created. As well as the roles associated with the foundational accounts, the following roles may be assigned to new user accounts: + +- ADMINISTRATOR +- FINANCE_MANAGER + +A user account cannot have more than one of OPERATOR, MANAGER, ADMINISTRATOR or FINANCE_MANAGER, in order to ensure separation of: + +- Financial management from other Hub operations tasks +- Operator and managerial roles in maker/checker functions + +::: tip NOTE +Assigning the ADMINISTRATOR or FINANCE_MANAGER roles is subject to a higher degree of identity verification and background checks than any other roles, due to the sensitive nature of the associated functions. These additional checks are set out in the Scheme Rules. +::: + +### Finance Portal / Business Operational Framework + +Many functions (such as the viewing of DFSP positions, the status of settlement windows, and so on) of the Finance Portal are available to all logged-in users, regardless of their role. However, the following functions may only be carried out by users with specific roles: + +- Settlement processing + - Close settlement window + - Initiate settlement +- DFSP liquidity management + - Add/withdraw funds + - Change NDC + +All of these are subject to maker/checker controls, so that a user with role ADMINISTRATOR can initiate the action, but it must be approved by a user with role FINANCE_MANAGER. + +### Participant lifecycle + +This portal provides a single interface for a Hub Operator to add and maintain DFSPs on the Hub ecosystems. + +There are some standardised functions that are subject to RBAC: + +- Create DFSP +- Create DFSP Accounts +- Suspend DFSP + +Each of these is subject to maker/checker controls, so that a user with role OPERATOR can set up the changes, and they must be approved by a user with role MANAGER. + +In addition, there is a significant workload in technical onboarding a DFSP, in particular around the establishment of the technical operating environment (certificates and so on). This is not subject to RBAC. This is not considered a significant risk, since there is no value without being able to create a DFSP and the associated accounts on the Hub itself - activities that are subject to RBAC. + +### Hub operations + +Access to the reporting functions of Prometheus/Grafana is not subject to RBAC controls - any signed-in/authenticated user, with any RBAC role assigned, may view the reports and dashboards. + +Creating a new report/dashboard is a restricted function, and is only available to users with the MANAGER role. + +As noted earlier, the operations and reporting portals will be migrated into the Ory/Keycloak environment in order to facilitate these controls. + +### Payment Manager + +The Payment Manager operator functionality is subject to RBAC controls, but maker/checker is not required. + +#### User/Operator onboarding + +On deployment of Payment Manager, a single admin user account is created using Keycloak. Note that the admin user will not be assigned any operational roles beyond those of a system administrator. + +All functions carried out using Keycloak are subject to system-level logging for audit purposes. + +The admin user will use Keycloak to create further user accounts, subject to standard identity and background checks for each individual (defined under the Scheme Rules associated with a particular Mojaloop deployment) before their accounts are created. + +These new user accounts will be assigned one of the following roles: + +- OPERATOR +- MANAGER + +A user account may not have both OPERATOR and MANAGER roles. + +### Dashboards + +The Payment Manager dashboards are available to any logged-in/authenticated user with role OPERATOR or MANAGER. + +### Hub connection management + +Viewing the settings for the Payment Manager/Hub connection is available to any logged-in/authenticated user with role OPERATOR or MANAGER. However, modifying the settings is a controlled function. Only a user with role MANAGER may modify the settings. + +### Transaction investigation + +Carrying out transaction investigations using the facilities of the Payment Manager portal is a controlled activity, due to the potential for revealing PII data. It is therefore only available to logged-in/authenticated users with role MANAGER. + +## Monitoring +Monitoring is the fourth pillar of mitigating the RBAC risk. Designing and configurating this is very dependent on the maturity of the Scheme, the scheme rules, the use cases being used, and the participants classes. +As a starting point for designing your monitoring, consider these categories: +1. External Security threat monitoring +1. Internal Security treat monitoring e.g. Auditing +1. Scheme rule enforcement monitoring + diff --git a/docs/adoption/HubOperations/Settlement/ledgers-in-the-hub.md b/docs/adoption/HubOperations/Settlement/ledgers-in-the-hub.md new file mode 100644 index 000000000..2e574a4c4 --- /dev/null +++ b/docs/adoption/HubOperations/Settlement/ledgers-in-the-hub.md @@ -0,0 +1,367 @@ +# Ledgers in the Hub + +## Managing risk + +Elements of the settlement process sit outside the control of the Hub, so it is important that there are a number of controls in place to prevent funds disappearing and to ensure there is always liquidity to support operation of the Hub. Other than the [Net Debit Cap](settlement-basic-concepts.md#liquidity-management-net-debit-cap), the Hub employs a number of internal ledgers to manage risk and ensure liquidity. These ledgers are as follows: + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LedgerDefinitionType of transfer recorded in ledger

DFSP Position Ledger

Tracks how much a DFSP owes or is owed. Every time a transfer is processed, the Position in the Hub is adjusted in real time.

P2P transfer: A person-to-person transaction between DFSP end users.
+
+Settlement transfer: The flow of funds between DFSPs aimed at reconciling the ledgers and updating Positions for a given settlement window.

DFSP Settlement Ledger

The DFSP’s liquidity account held at the settlement bank mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.

Funds transfer (in and out): The movement of funds initiated by the DFSP or the confirmation by the settlement bank that settlement has completed.

Hub Multilateral Net Settlement (HMLNS) Ledger

Used to capture the balancing journal entry for the net settlement amongst DFSPs. After a settlement window has been closed and settled amongst all the DFSPs, its balance will return to zero.

Settlement transfer: The flow of funds between DFSPs aimed at reconciling the ledgers and updating Positions for a given settlement window.

Hub Reconciliation Ledger

Ensures that movements in and out of the liquidity accounts and recorded in the Settlement Ledgers are balanced. The balance is the amount that the Hub Operator is administering in all the participant DFSPs' Settlement Ledgers.
+
+Acts as a control account, and tracks the movement of funds across all DFSP Settlement Ledgers (which mirror the movement of real funds).

Funds transfer (in and out): The movement of funds initiated by the DFSP or the confirmation by the settlement bank that settlement has completed.

+ +## Understanding accounting principles + +In accounting, a positive net position (more debits) is treated as an asset, while a negative net position (more credits) is treated as a liability. The Mojaloop Hub applies these same principles but from the Hub's perspective. What does that mean? + +A transfer is recorded by the Hub as a debit (DR) on the Payer DFSP side because the transfer reduces the amount that is owed back to that DFSP (reduced liability from the Hub's perspective). So while the Payer DFSP itself will treat the transfer as an increase in their liability in their own system, the Hub treats the transfer as an increase in their asset. + +The same transfer is recorded by the Hub as a credit (CR) on the Payee DFSP side because the transfer increases the amount owed to that DFSP (increased liability from the Hub's perspective). + +Recording a transaction in two accounts as opposing debit and credit entries (of equal amounts) is what we call "double entry" in accounting. + +Applying the above accounting principles to a deposit by a DFSP in the DFSP's liquidity account, the amount creates a liability from the Hub's perspective (the money needs to be paid back). The amount that is entered in the Hub is therefore negative. This way at any point, the amount the Hub owes to any DFSP can be quickly calculated by adding the DFSP's Position to their liquidity account balance. The double entry for the DFSP Settlement Ledger is added to the Hub Reconciliation Ledger. + +## Settlement: an example + +This section demonstrates how a transaction is logged in the various ledgers, using a simple example. + +Let’s take the following example: DFSP1 sends 50 USD to DFSP2. Here is how this example transaction is recorded in the Hub ledgers. + +### Step 1a: Reserving the transfer amount for the sender in the Position Ledger + +The DFSP Position Ledger is used for keeping track of changes in the Position of a DFSP. Once a settlement window is closed and the settlement process is started, the transfer amount is reserved in the Hub’s Position Ledgers maintained for the DFSPs as well as in the Hub Multilateral Net Settlement Ledger. Reserving the transfer amount for the Payer DFSP (DFSP1) guarantees that the funds cannot be used for another transfer. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 1b: Reserving the transfer amount for the recipient in the Position Ledger + +Similarly, the Position of the Payee DFSP is also tracked through the DFSP's Position Ledger. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 2a: Committing the transfer amount for the sender in the Position Ledger + +Following the reservation of the transfer amount, the next step is to commit the amount in the same ledgers as before. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 2b: Committing the transfer amount for the recipient in the Position Ledger + +Committing the transfer amount for the Payee DFSP (DFSP2) allows the DFSP to send funds to other DFSPs if desired. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 3: Reserving the transfer amount for the sender in the Settlement Ledger + +Once Positions are in a controlled state and corresponding debit and credit entries have been recorded in the Hub Multilateral Net Settlement Ledger, the transaction must be recorded and reserved in the DFSP Settlement Ledgers and the Hub Reconciliation Ledger as well to ensure that funds are not released inadvertently for another Funds-Out operation. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 4a: Committing the transfer amount for the recipient in the Settlement Ledger + +Once real money has moved on DFSPs' liquidity accounts, transfer amounts can be committed in the DFSP Settlement Ledgers and the Hub Reconciliation Ledger. Money movement is recorded for the Payee DFSP first. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Step 4b: Committing the transfer amount for the sender in the Settlement Ledger + +Finally, the transfer amount is committed on the sender side too. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +## Adding/withdrawing funds: an example + +### Adding funds + +As the funds of the liquidity accounts will fluctuate, the DFSPs will either add funds to fund their net sends, or look to make withdrawals. Deposits can happen whenever desired, but the Hub Reconciliation Ledger does need to be updated regularly, to avoid reconciliation issues. Whenever a change is made to the external account (that is, the DFSP's liquidity account), the Net Debit Cap must also be assessed. + +In the following example, DFSP1 adds 100,000 USD to their liquidity account. This is how the deposit amount is recorded in the Hub's ledgers. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

100,000 USD

100,000 USD

+ +### Withdrawing funds + +As a withdrawal could lead to an impact on the Net Debit Cap and the ability to transact, the NDC must be re-calculated in light of the DFSP's new balance (the balance must never be lower than the NDC). + +In the following example, DFSP2 withdraws 100,000 USD from their liquidity account. This is how the withdrawal amount is recorded in the Hub's ledgers. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

100,000 USD

100,000 USD

\ No newline at end of file diff --git a/docs/adoption/HubOperations/Settlement/settlement-basic-concepts.md b/docs/adoption/HubOperations/Settlement/settlement-basic-concepts.md new file mode 100644 index 000000000..5f28f7fe3 --- /dev/null +++ b/docs/adoption/HubOperations/Settlement/settlement-basic-concepts.md @@ -0,0 +1,129 @@ +# Basic concepts + +This section collects key concepts and elements of the settlement management process. + +## Liquidity cover + +As described in the [Introduction](settlement-management-introduction.md), one of the characteristics of a real-time payments system is that creditor DFSPs are required to disburse funds to their customers before they are reimbursed by the debtor DFSP. To mitigate the risk that a creditor DFSP will not receive the funds that it is due, Mojaloop requires that debtor DFSPs should provide credible evidence that they have sufficient good funds to meet the obligations they incur as a consequence of transacting in the system. + +This credible evidence is called *liquidity cover*. The Mojaloop system does not stipulate what forms it should take; and, for any given DFSP, it may take multiple forms. It might be: + +- funds deposited in an account over which the Mojaloop Hub has some control +- a line of credit from another financial institution +- collateral of some other kind + +However, any liquidity cover used in a Mojaloop scheme must have the following characteristics: + +- It must be capable of being converted into settlement payments *immediately* on demand from the Mojaloop scheme. +- It must be attested to by reliable evidence in the Mojaloop scheme's possession. +- It must not be convertible by the DFSP into other forms (for example, by withdrawing funds from a bank account, or drawing down funds from a line of credit) without the prior knowledge and approval of the Mojaloop scheme. + +The liquidity cover attributed to a given DFSP is liquidity cover for a given settlement model and currency, and is attributable to the scheme as a whole. That is to say that Mojaloop does not allow participants to maintain liquidity cover that is applicable only to their transfers with a specific DFSP or DFSPs. + +When a DFSP asks the Mojaloop Hub to make a transfer, the Mojaloop Hub checks that the debtor DFSP has sufficient liquidity cover to guarantee that the transfer can be settled if it completes successfully. It does this by comparing the DFSP's total good funds against the sum of the following items: + +1. The sum of transfers which have been completed but not yet settled, and to which the DFSP is *either* the creditor *or* the debtor party. +1. The sum of transfers which have been started but which have not yet completed, and to which the DFSP is the debtor party. +1. The amount of the proposed transfer. + +If the total of these three items is greater than the amount of good funds available to the debtor DFSP, then the transfer will be rejected by the Mojaloop Hub. Note that, in this arrangement, a DFSP's liquidity is credited with the effect of transfers where it is the beneficiary as soon as the transfer is completed, without needing to wait for the funds to be settled. Mojaloop does this to keep to a minimum the amount of liquidity that participants are required to maintain. + +## Settlement model + +Different schemes will want to settle funds between their participants in different ways. These will depend on who is operating the scheme, how much traffic there is through the scheme, and many other variables. + +Mojaloop is designed to support the industry standard ways of settling between participants. These are as follows: + +- Multilateral deferred net settlement +- Bilateral deferred net settlement +- Immediate gross settlement + +The meaning of the component terms of these settlement types is as follows. + +Settlements are *deferred net* if a number of transfers are settled together. Net settements (in which a number of transfers are settled together) are by definition deferred (since it takes time to construct a batch.) + +Settlements are *gross* if each transfer is settled separately. Gross settlements may be immediate or deferred. They are *deferred* if approval for settlement from outside the Hub is required, and *immediate* if the Hub can proceed to settlement of a transfer without requiring any external approval. At present, Mojaloop only supports immediate gross settlements. + +Settlements are *bilateral* if each pair of participants settles with each other for the net of all transfers between them. Settlements are *multilateral* if each participant settles with the Hub for the net of all transfers to which it has been a party, no matter who the other party was. + +A settlement model specifies a way in which a Mojaloop Hub will settle a set of transfers. In the simple case, there is only one settlement model and it settles all the transfers that are processed by the Hub. However, Mojaloop supports more than one settlement model for a single scheme. This allows, for instance, a scheme to define different settlement models for different currencies, or for different ledger account types. + +If a scheme defines more than one settlement model, it is the responsibility of the scheme to ensure that a given transfer can only belong to a single settlement model. For example, suppose that a scheme defines a settlement model for all transfers that require currency conversion (defined as: all transfers where the source currency and the target currency are different from each other), and also a settlement model for all transfers where the source currency is Kenyan shillings (KES). In this case, a transfer which converted from Kenyan shillings to South African rand could potentially belong to both models. + +## Settlement window + +Every transfer that is completed in the Hub is assigned to the currently open settlement window. The settlement window is a way of grouping transfers together. Assigning transfers to a settlement window happens independently of the settlement models that are used to settle the transfers. This means that if a scheme has defined more than one settlement model, transfers that belong to the different settlement models will share a settlement window. + +There is no deterministic way of assigning transfers to a particular settlement window. When a scheme administrator creates a new settlement window, there is no way to tell in advance which transfers will be assigned to the new settlement window and which transfers will be assigned to the old settlement window. + +A settlement window can have the following states: + +* `OPEN`: The settlement window is open, transfers are being accepted into the current open window. +* `CLOSED`: The settlement window is closed. It is not accepting any additional transfers and all new transfers are being allocated to a new, open settlement window. +* `PENDING_SETTLEMENT`: The settlement window is closed, the [Multilateral Net Settlement Positions](#multilateral-net-settlement-position) have been calcluated for each DFSP but settlement with the partner settlement bank has not happened yet. +* `SETTLED`: The settlement bank has confirmed that all the participant DFSPs that engaged in transfers in the settlement window have settled their payments, and the Hub Operator has settled the window. + +Closing a settlement window automatically opens the next one. + +### Settlements and settlement windows + +A Hub Administrator may request settlements for a given settlement model and for one or more settlement windows. + +If a scheme only has a single settlement model, then settling transfers for that model in a given settlement window will settle all the transfers in that window. If, on the other hand, a scheme has defined more than one settlement model, then settling transfers belonging to a particular settlement model for a given settlement window will mean that some of the transfers in that window have been settled, while others have not. + +It is particularly important to understand the implications of this where an Immediate Gross settlement model has been defined. In this case, individual transfers will be settled as soon as they have been completed. If the scheme only has an Immediate Gross settlement model, then all transfers will be settled as they are completed, and the settlement window will become irrelevant. If, on the other hand, the scheme mixes Gross and Net settlement models, or if the scheme has defined more than one Net settlement model, then it is possible for a given settlement window to contain some transfers which have been settled and some which have not been settled; and, in the case of transfers which are settled by a Gross settlement model, for transfers which have been settled to appear even in a currently open settlement window. This creates potential complications in defining the overall status of a settlement window. + +Mojaloop deals with this situation by always assigning the settlement window a state which is the minimum state of the transfers within it. *Minimum state* is defined by the sequence of settlement window states given above. So, for instance, if a settlement window contains transfers which have already been settled (because they are settled Gross) and other transfers whose settlement process has not yet started, then the settlement window's state will be `OPEN`. If a settlement window has been closed, and it contains transfers which belong to two different settlement models, one of which is being settled (and whose state is therefore `PENDING_SETTLEMENT`) and the other is not (and whose state is therefore `CLOSED`,) the overall state of the settlement window will be `CLOSED`. + +## Liquidity management (Net Debit Cap) + +As described above, Mojaloop requires participants to pre-fund transfers where they are the debit party by providing credible evidence to the Mojaloop Hub that they can meet all their current settlement demands. There may, however, be circumstances in which a participant does not want all of its liquidity cover to be used as cover for transfers. For instance, a participant might be a recipient in a remittance channel and therefore an overall net creditor; or a participant might deposit extra funds to cover periods when their accounts are not open to receive funds. + +To cover these possibilities, Mojaloop allows either participants or Hub Administrators to reserve part of their available liquidity cover, so that only part of it can be used to provide liqidity cover for transfers. This is called the Net Debit Cap (NDC). The NDC acts as a limit or a cap placed on a DFSP's funds available for transacting, and it can never exceed the balance of the liquidity account. This is required to ensure that a DFSP's liabilities can be met with funds immediately available to the settlement bank. + +When calculating whether or not a transfer is covered by available liquidity, the Hub will take into account any restriction on the amount of available funds specified by the Net Debit Cap. + +## Position + +The Position of a DFSP reflects the total unsettled obligations of a DFSP for a given settlement model at a given point in time: that is to say, the amount of funds that a DFSP will eventually be required to settle with the scheme. A DFSP's Position for a given settlement model is the net of the following elements: + +1. All completed but unsettled transfers that belong to the settlement model and where the DFSP is the debtor party. +2. All completed but unsettled transfers that belong to the settlement model and where the DFSP is the creditor party. +3. All transfers that have been requested but have not yet completed which belong to the settlement model and where the DFSP is the debtor party. + +For the Payer DFSP, this sum total includes transfer amounts that are pending and have not yet been completed. Note that if an abort or timeout happens, the affected transfers will not complete and the reservation for that transfer will be removed. + +The Position is the total position across all settlement windows that have not yet been settled. The amount of a participant's position only changes when some of the transfers which make up its position are settled. + +## Net Settlement Positions + +As described above, a deferred net settlement can be either multilateral or bilateral. When a Hub Administrator requests a settlement, the Hub will calculate how much each participant owes, or is owed, as a consequence of the transactions that are to be settled. The transactions to be settled are defined as all transactions which: + +- Belong to the settlement window(s) that are to be settled. +- Belong to the settlement model that is being settled. + +If the settlement is *multilateral*, then a DFSP will receive only one figure as the amount it owes, or is owed, as a consequence of the settlement. This figure is the net of all the transactions to be settled. + +If the settlement is *bilateral*, then a DFSP may receive multiple figures as the amount it owes, or is owed, as a consequence of the settlement. Each figure represents the net of the DFSP's transactions with a particular DFSP. The net of all these values will be equal to the overall figure which it would owe, or be owed, in a multilateral net settlement. + +## Settlement reports + +To facilitate DFSP reconciliation and settlement at the settlement bank, the Hub provides various settlement reports. A Scheme can choose to have several different reports for different purposes. Below are some examples: + +* DFSP Settlement Report: A report issued to a DFSP when settlement has been initiated. It provides the DFSP's bilateral settlement position with each DFSP they transacted with (either as a Payer DFSP or Payee DFSP) in the settlement window(s) being settled. It also provides the Multilateral Net Settlement Position of the DFSP (the sum total of the transfer amounts sent and received by the DFSP in the settlement window(s)). +* Settlement Bank Report: A report issued to the settlement bank when settlement has been initiated. It provides the bilateral settlement position of each DFSP against every other DFSP that transacted in the settlement window(s) being settled. It also provides the Multilateral Net Settlement Position of each DFSP (the sum total of the transfer amounts sent and received by the DFSP). +* DFSP Settlement Result Report: A report issued to a DFSP when settlement has been finalised. It provides details about the balance of the DFSP's liquidity account, and the money movements arising from the closure of the settlement window. + +## Finance Portal + +The [Finance Portal](busops-portal-introduction.md) (commonly referred to as "Finance Portal v2") is a web portal used by the Hub Operator to manage settlement-related processes on a daily basis. The portal provides functionality to: + +* monitor details such as the balance, [Position](#position), [Net Debit Cap](#liquidity-management-net-debit-cap) of DFSPs +* update a DFSP's [Net Debit Cap](#liquidity-management-net-debit-cap) +* manage settlement windows + +* record deposits to or withdrawals from DFSPs' liquidity accounts + +::: tip NOTE +The Finance Portal currently only supports settlement processes that rely on the Deferred Net Settlement model. +::: \ No newline at end of file diff --git a/docs/adoption/HubOperations/Settlement/settlement-management-introduction.md b/docs/adoption/HubOperations/Settlement/settlement-management-introduction.md new file mode 100644 index 000000000..b3b724d23 --- /dev/null +++ b/docs/adoption/HubOperations/Settlement/settlement-management-introduction.md @@ -0,0 +1,7 @@ +# Introduction – Settlement Management Guide + +When a payment is made in a real-time payments system like Mojaloop, the DFSP who is the custodian of the beneficiary's account (the creditor DFSP) agrees to credit the beneficiary with the funds immediately. But the creditor DFSP has not yet received the funds from the DFSP who is the custodian of the debtor's account: all that has happened so far is that the debtor DFSP has incurred an obligation to reimburse the creditor DFSP, and that obligation has been recorded in the Mojaloop Hub. + +The process of settlement is the process by which a debtor DFSP reimburses a creditor DFSP for the obligations that the debtor DFSP has incurred as a consequence of transfers. + +This guide describes how settlements are managed by the Mojaloop Hub and the partner settlement bank(s), and introduces the main building blocks of settlement processing. \ No newline at end of file diff --git a/docs/adoption/HubOperations/TechOps/change-management.md b/docs/adoption/HubOperations/TechOps/change-management.md new file mode 100644 index 000000000..205adaee8 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/change-management.md @@ -0,0 +1,388 @@ +# Change management + +The purpose of the change management process is to control the lifecycle of all changes, enabling changes to be made with minimum disruption to IT services. + +::: tip NOTE +The processes described in this section represent best practices and act as recommendations for organizations fulfilling a Hub Operator role. +::: + +## Objectives + +The objectives of change management are to: + +* Respond to changing business requirements while maximizing value and reducing incidents and re-work +* Respond to Requests for Change (RFCs) that will align services with business needs +* Ensure that changes are recorded and evaluated, and that authorized changes are managed in a controlled manner +* Optimize overall business risk + +## Scope + +The scope of change management should include changes to all architectures, processes, tools, metrics and documentation, as well as changes to all configuration items (CIs) across the whole service lifecycle. + +All changes must be recorded and managed in a controlled environment across all CIs. These can be physical assets such as servers or networks, virtual assets such as virtual servers or storage, or other types of assets such as agreements or contracts. + +Change management is not responsible for coordinating all of the service management processes to ensure the smooth implementation of projects. + +## Roles and responsibilities + +The roles listed below indicate some of the crucial stakeholders needed to make the change management process effective. + +### Change Manager + +The Change Manager acts as the lead, responsible for the overall change management process. + +The primary responsibilities of the Change Manager are: + +* Driving the efficiency and effectiveness of the change management process +* Producing management information +* Monitoring the effectiveness of change management and making recommendations for improvement +* Adherence to the change management process +* Planning and managing support for change management tools and processes +* Verifying that RFCs are correctly completed and allocated to change authorities (if applicable) +* Communicating decisions of change authorities to affected parties +* Monitoring and reviewing activities +* Publishing the change schedule and projected service outage +* Conducting post-implementation reviews to validate the results of change requests +* Determining business satisfaction with change requests + +### Change Coordinator + +Change Coordinators are Support staff members who handle the details of a change request. + +The responsibilities of a Change Coordinator include: + +* Gathering appropriate information based on the type of change being investigated +* Associating related configuration items, incidents, and services to the change request +* Providing status updates to requesters +* Reviewing change plans and schedules. Planning activities include scheduling the change request, assessing risk and impact, creating plans, defining and sequencing the tasks needed to accomplish the change request, and scheduling people and resources for each task. +* Reviewing all completed tasks. In the [Implement](#step-4-implement) stage, at least one task related to the change request is in progress. +* Conducting post-implementation reviews to validate the results of the change request +* Determining requester satisfaction with the change request + +### Change Initiator + +A Change Initiator is a person who initiates or requests a change, from a business or a technical role. Various people can initiate a change, this role is not exclusive to a single person. The change initiator/requester is required to provide all necessary information and justification for the change. + +Other responsibilities of a Change Initiator include: + +* Completing and submitting a change proposal (if required) +* Completing and submitting a Request for Change (RFC) +* Attending Change Advisory Board (CAB) meetings to provide further information +* Reviewing changes when requested by Change Management + +### Change Implementer + +This is the individual deemed as the owner of the change request throughout the request lifecycle. Implementing a change requires maker/checker approval, that is, all changes require one person to perform the change and another to validate the change. + +Responsibilities of a Change Implementer include: + +* Liaising with the change requester for business and technical queries and issues, if any +* Creating an RFC and updating its status whenever required +* Checking and deciding an implementation date, ensuring that it does not conflict with other activities, for example, lead times, change windows, and so on +* Assessing and managing the risk involved during the change request lifecycle +* Testing and implementing the change +* Coordinating and communicating with any other impacted team prior to submitting the change (in the absence of the Change Coodinator) +* Once the change is approved, creating a remedial case for the scheduled change +* Executing the change as on the scheduled date and time +* Providing closure status after successful completion +* Documenting the change procedure after its implementation + +### Change Approver + +This is an individual who provides first-level approval to a Request for Change before it goes to Change Advisory Board review. Change Approvers are scoped for different Hub changes, meaning that this role may be occupied by different individuals at various hierarchal levels of the change management framework, each with their own area where they act as an approver. + +Responsibilities of a Change Approver include: + +* Reviewing all RFCs submitted by the change initiators/requesters +* Ensuring that the change request has reached the necessary standard of readiness to warrant a decision by the Change Manager and the CAB +* Reviewing and commenting on the content within the Change Record, namely: Change Plan, Implementation, Test and Remediation Plan, and Schedule +* Granting approval once satisfied that all relevant criteria have been met and concerns addressed OR rejecting approval by giving clear concerns and reservations about the content of the Change Record +* The outcome of failed changes where negative outcome is a result of an undetermined approval + +### Technical SME + +The Technical Subject Matter Expert (SME) is an individual who is an authority in a particular technical area or topic. In relation to change manangement, the SME is responsible for: + +* Providing the detailed Implementation, Testing and Remediation Plans +* Attendance at CAB meeting to answer questions and concerns about the change to approvers and Change Management (if invited) +* The implementation of change tasks and updating the relevant records in the change management tool with respect to implementation status +* Reviewing and re-working a change as requested, and contributing to the review of a change post-implementation + +### CAB Member + +The Change Advisory Board (CAB) involves members from different domains, including information security, operations, development, networking, Service Desk, and business relations, among others. A member of the CAB has the following responsibilities: + +* Circulating RFCs within their area of responsibility and coordinating feedback +* Reviewing RFCs and recommending whether they should be authorized +* Reviewing successful, failed, and unauthorized changes +* Reviewing the change schedule and projected service outage + +### CAB Chair + +The CAB Chair is responsible for: + +* Convening and chairing CAB meetings +* Overseeing the overall change management process +* Ensuring that the CAB fulfils the charter on policies and procedures related to changes + +## Change types + +The change management process handles the following change types. + +### Standard changes + +A standard change is a change to a service or other configuration item that has been pre-authorized and so does not need to go through the approval process. In order to be considered a candidate for becoming a standard change, at least three successful minor changes must have been implemented. A request for a standard change must then be submitted to the Change Advisory Board for approval. + +The risk for a standard change must be low and well-understood, the tasks must be well-known, documented and proven, and there must be a defined trigger to initiate it, such as an event or service request. + +Examples of standard changes include: operating system (OS) upgrade, patch deployment, and so on. + +### Minor changes + +A minor change is a non-trivial change that has low impact and low risk. These are non-trivial changes that do not occur frequently but they still undergo every stage of the change lifecycle, including CAB approval. It is important to document relevant information for future reference. Over time, a minor change can be converted into a standard change. + +Examples of minor changes include: website changes, performance improvements. + +For a change to be classified as a minor change, it must have a lead time of less than 3 days. + +### Major changes + +A major change is a high-risk and high-impact change that could interrupt production live environments if not planned properly. Change evaluation is crucial to determine the schedule and approval workflow. A major change requires management approval along with CAB approval. The Request for Change (RFC) of a major change must contain a detailed proposal on cost-benefit, risk-impact analysis and financial implications, if any. + +Effectively, all changes that imply downtime, specifically downtime that affects DFSP onboarding and testing activities on lower environments should be classified as major changes and should be reviewed by the CAB. These changes should be implemented in coordination with the Technical Project Manager. + +For a change to be classified as a major change, it must have a lead time of 5 days or more. + +### Emergency changes + +An emergency change is a change that must be completed as soon as possible. An emergency change will only be accepted if it is linked to a Severity 1 Incident, which has a corresponding S1 ticket in the Service Desk tool. The Service Manager will instigate the opening of an emergency change and will instruct the Technical SME to raise it. + +### Summary of lead times and approval matrix + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Change typeLead time to implementReview and approval

Standard change

3 working days

Pre-approved

Minor change

3 working days

    +
  1. CAB

  2. +
  3. Business Approvers (where applicable)

  4. +

Major change

5 working days

    +
  1. CAB

  2. +
  3. Business Approvers (where applicable)

  4. +

Emergency change

ASAP

Emergency CAB or Business Owner

+ +## Change Advisory Board + +The Change Advisory Board (CAB) supports change management in assessing, prioritizing, and scheduling changes. The CAB must have full visibility of all changes that could have moderate or higher risk to services and configuration items. It is important that within the CAB, there are members who can provide expertise that is adequate to assess all changes from both a business and a technical point of view. + +There are permanent CAB members who are invited to all meetings but to ensure that there is a clear understanding across all stakeholder needs, other people will be asked to participate due to their expertise for a change that is to be discussed. If applicable, the external supplier may also be invited. + +### CAB meeting + +The CAB meeting can be held face-to-face or electronically. It may be more convenient to hold electronic meetings, however it may be more difficult to deal with questions this way. This will be the responsibility of the CAB Chair to decide depending on the situation. It is expected that CAB meetings will be electronic due to the limitations of timescales. + +A CAB meeting is a formal meeting with a designated structure. Prior to any CAB meeting, the changes to be discussed must be circulated to all members. The CAB Chair is responsible for ensuring this is completed but may delegate the task to the CAB Co-Chair or any CAB Member. + +All change representatives must attend or send a delegate. If there is no attendance, then the change will not be discussed and therefore not approved. All CAB attendees must come to the meeting prepared to discuss the changes they represent and to express views and opinions based on their particular area they represent. + +The CAB meeting is the forum to discuss previous changes both successful and failed, and review lessons learned. + +An agenda for the CAB meeting must be circulated prior to the meeting. The CAB Chair is responsible for ensuring that the structure is followed, minutes are taken, and action items are gathered to be distributed after the meeting. + +## Change management process + +This section provides a summary of the key activities of the change management process. Specific instructions on how to perform process activities within the context of a Service or Function may be provided by local operating procedures within a procedure manual. + +All changes must be raised in the Service Desk tool. + +The following figure provides a high-level summary of the change management process with the key activities: + +![High-level summary of change management process activities](../../../.vuepress/public/change_mgmt_flow.png) + +### Step 1: Raise Request for Change (RFC) + +#### Objective + +The objective of this activity is to ensure that the types of change requests are adhered to so that the process can respond to and manage the environment while protecting the business. + +The following figure provides a summary of the fist step of the change management process. + +![Change management process – Initiating a change by raising an RFC](../../../.vuepress/public/raise_rfc.png) + +#### Prerequisites + +Prerequisites for changes should be in line with the requirements for releases as described in the [release management process](release-management.md). The following should be clearly captured in the Service Desk tool while preparing the Change Record: + +* Handover from relevant team to Operations team, including full review of the following: + * Change Ticket or Change Record: Reason for the change including impact, risks, limitations. The categorization matrix for the change can be the same as for incidents. For details on the incident categorization matrix, see [Incident categorization matrix](incident-management.md#incident-categorization-matrix). + * Change runbook: Steps required to make the change and roll back the change if needed + * Test results from lower environment: Evidence that the change was tested successfully and causes no regression + * Test plan for higher environment: What specific tests need to be run to validate the change + * All related documentation including architecture, flowcharts, setup/configuration information, and so on have been updated +* Pre-change testing: Verify environment stability by reviewing the last Golden Path (GP) test results +* Post-change testing: Execution of the agreed tests to validate the change, and execution of the full GP tests to confirm no regression on the environment + +#### Inputs + +Inputs to the RFC are: + +* Service Requests +* Requests from [Incident Management](incident-management.md) to apply workarounds/fixes +* Requests from [Incident Management](incident-management.md) to make emergency changes to resolve Severity 1 incidents +* New functionality requests from Project Management Office +* Maintenance requests for change + +#### Outputs + +Change Records containing details of RFCs for review. + +### Step 2: Review and authorize + +#### Objective + +Changes are reviewed, and a technical approval stage determines if the required mandatory minimum information is captured to allow for an effective planning and scheduling phase. + +The following figure provides a summary of the "review and authorize" step of the change management process. + +![Change management process – Review and authorise](../../../.vuepress/public/review_authorize.png) + +#### Inputs + +Change Record for review. + +#### Outputs + +Change Record with technical approval. + +### Step 3: Plan and approve + +#### Objective + +Qualified Change Records that have passed an initial assessment in the previous process steps are planned and approved. The risk level of the change will direct the approval path. + +The following figure provides a summary of the "plan and approve" step of the change management process. + +![Change management process – Plan and approve](../../../.vuepress/public/plan_approve.png) + +#### Inputs + +Initially authorized Change Record. + +#### Outputs + +Fully planned and approved Change Record. + +### Step 4: Implement + +#### Objective + +The relevant Technical SMEs carry out the planned activities, recording any deviations, and undertaking remedial activities where applicable in accordance with the change plans to implement the requested changes. + +The following figure provides a summary of the "implement" step of the change mangement process. + +![Change management process – Implement](../../../.vuepress/public/implement.png) + +#### Inputs + +Approved Change Record. + +#### Outputs + +Implemented change, failed change, backed out change, remediated failed change. + +### Step 5: Close + +The final activity of the process ensures that changes that are subject to a post-implementation review receive the necessary attention and that remedial activities are understood and executed. + +The following figure provides a summary of the "close" step of the change mangement process. + +![Change management process – Close](../../../.vuepress/public/close.png) + +#### Inputs + +Successful changes, failed changes, failed changes with remediation. + +#### Outputs + +Closed changes. + +## Governance + +**Meeting name:** Change Advisory Board meeting + +**Meeting frequency:** Weekly + +**Meeting purpose:** + +* Review and approve/reject proposed changes in a business and technical context +* Prioritize proposed changes according to business needs +* Perform post-implementation review of completed changes and determine/document lessons learned +* Review previously approved changes but not implemented in the previous change window and recommend follow-up action + +**Meeting chair (process role):** CAB Chair + +**Recommended attendees (process roles):** + +* Standing CAB Members +* Business representatives +* Change Initiator/Implementer + +**Inputs:** + +* Change Schedule +* Change Record + +**Outputs:** + +* Approval/rejection +* Updated Change Records +* Action items + +### Governance for change communication + +The following guidelines apply to change communication: + +* Standard changes will be communicated to the internal stakeholders. +* Major, minor, and emergency changes shall be communicated to all the relevant business and technical stakeholders. +* Changes will be communicated after CAB approvals. +* At the start of the approved change window, an email update and a Slack notification (or similar) should be sent to the relevant stakeholders. +* At the end of the approved change window, an email update and a Slack notification (or similar) should be sent to the relevant stakeholders. +* External communication to customers (DFSPs) and partners of the Hub will be performed by the Service Manager. + +The notification must include the following details: + +* Title and description of change +* Impact to business +* Change window +* Contacts/Change Coordinator \ No newline at end of file diff --git a/docs/adoption/HubOperations/TechOps/defect-triage.md b/docs/adoption/HubOperations/TechOps/defect-triage.md new file mode 100644 index 000000000..4ee0332a0 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/defect-triage.md @@ -0,0 +1,93 @@ +# Defect triage + +The purpose of the defect triage process is to ensure that all the bugs identified in the Hub Operator's Production environment are captured, evaluated, and submitted to a Mojaloop Support team, a team dedicated to running Support services for the technical operations of a Mojaloop Hub. This team can be insourced or outsourced (or even part insourced and part outsourced), depending on the level of expertise or capacity within the scheme's hosting organization. If it is decided to outsource this function, there are organizations within the Mojaloop community that do provide different levels of support as a service. (For more information and referrals, contact the Mojaloop Foundation.) + +::: tip NOTE +The processes described in this section represent best practices and act as recommendations for organizations fulfilling a Hub Operator role. +::: + +::: tip NOTE +The process proposed here applies to bugs identified in the Hub Operator's Production environment, and new features or enhancements are outside its scope. However, to facilitate business conversations, Hub Operators can submit requests for new features or enhancements and those will be passed on to the Product teams in the community. +::: + +There needs to be a specific team that is responsible for the evaluation and resolution planning of each bug raised in the various environments (Production, Staging, QA, Dev, and so on). It can be a Support team or a QA/Development team. Within the remainder of this section, this team is referred to as the "Mojaloop Support Triage team". + +The Triage team has the following members: + +* Mojaloop Product Manager (core Mojaloop) +* Product Manager of extensions or other components implemented in the Hub - Payment Manager, PortX, and so on +* Hub Technical Subject Matter Expert (Product Delivery, that is Development and QA) +* Operations representative (Technical Operations and Infrastructure) + +## Bugs identified in a Hub Operator Production environment + +*Hub Operator steps:* + +1. An incident ticket is raised in the Hub Operator's [Service Desk](key-terms-kpis.md#key-terms) tool by a Hub L1 Support Engineer, as per the [incident management process](incident-management.md). +1. The ticket is escalated to the Hub L2/L3 team for in-depth investigation and analysis, as required. +1. The Hub L2/L3 team evaluates if the behavior is a new bug or a known issue, and whether a bug ticket/record already exists. If it is a known bug and a Mojaloop Support ticket already exists, then the L1 engineer must update the existing ticket with new details and information, and the priority and impact/severity (level of impact on the Hub or to its users) may be adjusted accordingly. The L1 engineer must communicate this back to the reporter/client DFSP (as referred to, in point 6). New bugs will follow the rest of the process below. +1. The Hub L2/L3 team confirms that the Production issue can be reproduced in lower environments running the same version as the Production (PRD) environment. That is, the bug is not a user error or an environmental issue. +1. The Hub L3 team may escalate to the Hub Technical Operations Manager, and report the bug via the Mojaloop Support Service Desk tool, adding all details of their analysis (including clear steps to reproduce the bug, the expected behavior, the actual behavior and any log files and details from the L2/L3 investigations), in addition to the identifier of the incident ticket created in Step 1 for easy tracking. +1. Response/acknowledgement/communication is sent back to the client DFSP within the agreed timelines. + +*Mojaloop Support team steps:* + +1. The Mojaloop Support team reviews, allocates a team member as owner, and acknowledges receipt of the bug. +1. Following an initial review of the issue raised, the Mojaloop Support team member forwards the issue to the Triage team for further evaluation. \ +The review of the ticket is conducted to a) establish good understanding of the issue raised, including the severity level and priority set by the Hub Operator; b) confirm completeness of the information provided, including log files, clear description, steps to reproduce, screenshots, and so on. +1. The Triage team evaluates the bug: enhancements/new feature requests are passed on to the community Product teams. Operational impact, severity, and priority are reviewed and the bug resolution is assigned to the relevant Product Manager. For details on prioritization, see [Prioritization of bugs](#prioritization-of-bugs). +1. The Product Manager clones the bug into their Product Delivery team's product backlog, which links both issues for reference and progress tracking. The Product Manager also reviews and sets priority against other items in their product backlog. +1. The Mojaloop Support Engineer assigned to the Mojaloop Support bug ticket monitors the cloned ticket and handles all communication between the Product Manager and the Hub Operator on the progress of the bugs, including sharing any remediation steps (for example, workarounds or alternative ways of using the affected functionality). Each subsequent update from the Product Delivery team should also be shared in the Product Manager bug ticket for visibility to the Hub Operator. The Product Manager assignee must remain the owner of the Product Manager bug ticket until the bug is resolved. +1. The Product Manager communicates the resolution plan and timelines back to the Support team via the original Product Manager bug ticket. The resolution plan is then communicated to the Hub Operator. \ +\ +For details on what happens if the Hub Operator does not agree with the proposed prioritization and resolution plan, see [Escalation process](#escalation-process). +1. The bug is resolved following the standard development process of the allocated Product Delivery team and is included in a release, which will be made available to the Hub Operator or can be offered as an ad-hoc (patch) release, if required. +1. The Mojaloop Support ticket is closed once the bug fix release is deployed and validated in the Hub Operator's environment. + +## Bugs identified during deployment/change window in Hub environment + +Deployments into Hub environments are the responsibility of the Hub Operator's team, and bugs identified during the deployment should be raised via the standard process (that is, a ticket is raised as per the Hub’s incident management process and then escalated to the Mojaloop Support team if required). In addition: + +* The Hub team will evaluate if the behavior is a known issue or a new defect. For known issues, the release should proceed and be completed as planned with the known bug reported as part of the post-deployment report. +* For new defects identified, the release/change can be rolled back depending on severity. This can be decided by the deployment team. In the case of a roll-back, regression tests must be executed to confirm that the previous working version is stable on the environment and the bug reported as part of the post-deployment report. +* The bug is captured via the Mojaloop Support Service Desk tool and will be handled via the process described above. + +## Escalation process + +If there is any discrepancy between the priority assigned or the client's (Hub Operator's) expectations and the resolution plan provided by the Mojaloop Support team, the [incident management escalation matrix](incident-management-escalation-matrix.md) governs what happens next. Accordingly, the incident will be set as priority P1 or any other lower priority type and stakeholders will be informed. + +The Mojaloop Support Team Lead and the Hub Operator Program Manager must be informed immediately. The Hub Operator Program Manager is a manager at the Hub organization who is responsible for translating the Scheme's business needs into technical operations directives. + +## Ownership and responsibility + +The creator of the Service Desk ticket (the Hub Operator's Support Engineer) remains the owner until the ticket is resolved. + +Priority and severity must be aligned, discussed, and negotiated between the Mojaloop Support Triage team and the Hub Operator's Operations team. + +Information from triage discussions and from the Product Delivery team must be shared in the Service Desk ticket by the Mojaloop Support Engineer. + +The Product Manager who is assigned the bug, must ensure that cross-referencing and tracking is in place to ensure the flow of information required or produced by the Product Delivery team's evaluation. + +The Product Manager who is assigned the bug, must determine and communicate the resolution plan back to the Mojaloop Support team/engineer, via the ticket only. + +### Prioritization of bugs + +The prioritization of bugs is the responsibility of Subject Matter Experts (SMEs) in the Mojaloop Support Triage team. + +All bugs are evaluated based on the expected behavior of the system and the actual behavior observed (and reproduced). The operational impact and the urgency of the bug must be captured by the Hub Operator's Operations team in order for this to be considered by the Triage team in the prioritization. + +Every bug is evaluated against the Product roadmap and backlog. + +New features or enhancement requests are channelled to the Product team and not handled by this process. This is communicated back to the requester via the Operations team. + +::: tip +Priority is the order in which the bug will be fixed. The higher the priority, the sooner the bug will be resolved. \ +\ +Severity is the level of impact on the Hub or to its users. \ +\ +These two factors work hand in hand. For example, a cosmetic bug like a typo on a webpage will likely be ranked as low severity but could be a quick and easy fix and ranked high priority. Hence, it is important to set these values with due consideration. +::: + +## Process flowchart + + diff --git a/docs/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md b/docs/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md new file mode 100644 index 000000000..2c600508e --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md @@ -0,0 +1,51 @@ +# Appendix A: Incident management escalation matrix + +This section provides information about key roles to contact when an incident occurs. + +::: tip NOTE +The incident management escalation matrix provided below acts as an example only. The actual names of roles may be different in your organization. +::: + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Support chain for incidents
Name of teamManager NEscalation N+1Escalation N+2

Level 1 Customer Support

L1/L2 Operations Support Team Leader

Service Manager

Technical Operations Manager

Level 2 Customer Support

Service Manager

Technical Operations Manager

Product Owner of the Hub / Program Manager

Level 3 Customer Support

Service Manager

Technical Operations Manager

Product Owner of the Hub / Program Manager

Level 4 Customer Support

Service Manager

Technical Operations Manager

Product Owner of the Hub / Program Manager

\ No newline at end of file diff --git a/docs/adoption/HubOperations/TechOps/incident-management.md b/docs/adoption/HubOperations/TechOps/incident-management.md new file mode 100644 index 000000000..be5e7bb50 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/incident-management.md @@ -0,0 +1,695 @@ +# Incident management + +The main objective of incident management is to restore normal service operation as quickly as possible and to minimize the impact on business operations, thus ensuring that the best possible levels of service quality and availability are maintained. "Normal service operation" is defined here as service operation within [service level agreements (SLAs)](service-level-agreements.md). + +This is achieved through a robust, well-aligned incident management process and guided by a Service Desk system that helps capture all issues, and track turnaround time (TAT) from the time an issue is reported to time of resolution and closure. + +The process of incident management involves detecting an incident, recording it with all the appropriate information, analyzing the issue, correcting the defects, and restoring the service in accordance with the stipulated TAT. + +This section collects the main processes, concepts, and principles around incident management. + +::: tip NOTE +The processes described in this section represent best practices and act as recommendations for organizations fulfilling a Hub Operator role. +::: + +::: tip NOTE +Throughout this section, the terms "client", "customer", "end user", and "user" all designate a DFSP employee. When these words are used in any other sense, the meaning of the word is called out and explained in detail. +::: + +## Incident management in a single image + +The following figure defines the process flow and key concepts of incident management in a single image. + + + + + +## Process boundaries + +The incident management process starts when: + +* an incident is triggered by a phone call/email/Service Desk interaction from users or customers +* an incident is found by way of an internal process or tool, for example, there is an event alert from one of the alert tools or monitoring systems +* Support staff at all levels (L1, L2, L3 Support Engineers) or the Service Manager directly raise an incident + +The incident management process ends: + +* for the customer: when ticket status in the Service Desk tool is changed to "Closed" +* for the Service Desk team: when the incident is solved and validation for closure is sent to the customer + +The boundaries of incident management stipulate that the process takes into account the following prerequisites: + +* A Service Level Agreement (SLA) between the Community (for example, Mojaloop), holding companies (for example, the Hub), and Digital Financial Service Providers (DFSPs) is in place. +* An SLA between the Implementing Partner (the Hub) and third-party Software Vendors (for example, Microsoft, Oracle, and so on) is in place. +* There is an existing operational level agreement (OLA). This agreement describes the responsibilities of each internal Support group towards other Support groups, including the process and time frame for delivery of their services. + +## Incident management step-by-step + +This section provides a detailed description of the incident management process. All incidents raised go through the following main steps. + +### Step 1: Report and log incident, change request, or question + +Issues, change requests, or questions can be reported and logged via the Service Desk tool as soon as they occur. The Service Desk tool is the primary channel for receiving incident-related queries. Emails, phone calls, and instant messaging can be used as secondary channels. + +The status of tickets as captured in the Service Desk system can take the following values: + +* **In Progress**: An incident that has been received via the Service Desk and assigned to a Support Engineer. Resolution efforts have commenced. +* **Escalated**: An incident that has been escalated to any party outside the Operations team, including the Product Delivery team or external L4 service providers. +* **Pending**: An incident that has been temporarily put on hold or awaiting feedback from the user or from another ticket that must be resolved before this ticket can be resolved. \ +\ +Bearing in mind that using the "Pending" status stops the SLA clock, the only reason that justifies the usage of "Pending" is when client action is required. This has to be an action that is the responsibility of the client/customer or their vendor and is a prerequisite to the continuation of the process; for example, requesting essential information or approval to solve the request. Tickets with Severity 1 and 2 must not be set to status "Pending". Restoring a service or a function of a service seldom depends on customer action. The only exception is when the customer stops the investigation or implementation of a solution or denies a necessary approval. In any case, the customer’s decision has to be documented. +* **Cancelled**: An incident that has been cancelled. An incident can only be cancelled when the customer initiates it. +* **Resolved**: An incident that was worked on by a Support Engineer and was fixed, and an alert has been triggered to the user to reopen if not satisfied. +* **Closed**: An incident that was closed once the resolution was acknowledged by the end user. + +All relevant information relating to incidents must be logged so that a full historical record is maintained. By maintaining accurate and complete incident records, future assigned Support group personnel are better able to resolve recorded incidents. + +### Step 2: Categorize and prioritize + +The end user/requester is assigned a ticket number for reference and ease of access when the issue is acknowledged and actioned by the Support Team. The ticket should be visible by the requester (the DFSP employee who raised the issue) at all Support levels. + +The requester will be automatically notified by email of any changes, status updates, requests for more information, readiness for testing, or final resolution with regards to the ticket. + +We generally classify support requests into: + +* Incident +* Service Request +* Change Request or Request for Change (RFC, such as features, enhancements) + +Incidents are categorized and sub-categorized based on the IT service or business area that the incident is causing a disruption to. + +These are some of the sample service categories: + +* Infrastructure +* Mojaloop +* Security +* Settlements +* Onboarding + +The severity of an incident can be determined using a [categorization matrix](#incident-categorization-matrix). Based on their severity, incidents can be categorized as: + +* Critical = S1 +* Severe = S2 +* Average = S3 +* Minor = S4 + +Once the incident is categorized, it gets automatically routed to an L1 Support Engineer with the relevant expertise. + +### Step 3: Investigate and resolve + +The assigned Support resource will be in charge of investigating the issue, as well as preparing the incident record, and communicating with the client on how to resolve the issue. + +Incident investigation may include any of the following actions: + +* Information gathering and analysis +* Research, including reproducing the issue +* Acquiring additional information from other sources + +Incident resolution may include any of the following actions: + +* Providing a resolution or steps towards a resolution +* Configuration changes + +Based on the complexity of the incident, it may have to be broken down into sub-tasks or tasks. Tasks are typically created when an incident resolution requires the contribution of multiple technicians from various departments. + +While the incident is being processed, the Support Engineer needs to ensure the Service Level Agreement is not breached. An SLA is the acceptable time within which an incident needs a response (response SLA) or resolution (resolution SLA). SLAs can be assigned to incidents based on their parameters like service category, requester, impact, urgency, and so on. In cases where an SLA is about to be breached or has already been breached, the incident can be escalated functionally or hierarchically to ensure that it is resolved at the earliest. + +An incident is considered resolved when the L1/L2/L3 Support Team has come up with a temporary workaround or a permanent solution for the issue. Workarounds may be: + +* instructions provided to the customer on how to complete their work using an alternative method +* temporary fixes that assist a system to work as expected but which do not resolve the issue permanently + +Workarounds need to be documented and communicated to the Service Desk so they can be added to the Knowledge Base. (It is good practice to maintain a repository of Knowledge Base articles, which describe the workaround or resolution steps of incidents that occurred in the past.) This will ensure that workarounds are accessible to the Service Desk to facilitate resolution during future recurrences of the incident. + +### Step 4: Escalate + +Incident escalation is recognition that there is the possibility of an incident exceeding the agreed resolution timeliness at each Support level. Clear escalation management allows the Support Team to identify, track, monitor, and manage situations that require increased awareness and swift action. + +There are two types of escalation: + +* **Functional escalation**: This type of escalation comes to play when a Support level team (for example, L1) is unable to resolve the issue or stay within the agreed timeline (meaning that the targeted time for resolution is exceeded). Therefore, the case is proactively assigned to the next service level (for example, L2). +* **Hierarchical escalation**: This type of escalation acts as a means to inform all the parties involved, in a proactive manner, of a potential SLA breach. This helps in bringing order, structure, responsibility, ownership, focused management, and resource mobilization for the purpose of delivering effective and efficient services. + +### Step 5: Close incident + +An incident can be closed once the issue is resolved and the user acknowledges the resolution and is satisfied with it. + +## Incident categorization matrix + +One of the most important stages in incident management is incident categorization. This not only helps sort incoming tickets but also ensures that the tickets are routed to the Support Engineers most qualified to work on the issue. Incident categorization also helps the Service Desk system apply the most appropriate SLAs to incidents and communicate those priorities to end users. Once an incident is categorized, Support Engineers can diagnose the incident and provide the end user with a resolution. + +The following table provides guidance as to how to classify the severity of an incident. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Incident categorization matrix
Severity codeCriteria

Severity 1

    +
  • Extensive impact to the business, Production system outage, normal operation is not possible.

  • +
  • Any incident that resulted in a major outage of the Hub, including connectivity of multiple partners/DFSPs.

  • +
  • Any incident that presents major financial risks and has contractual implications.

  • +
  • A security incident with a major impact on the privacy or availability of the Hub, partners/DFSPs, or customer data.

  • +

Severity 2

    +
  • Partial outage of the Hub.

  • +
  • Key functionality is impaired with no workaround available.

  • +

Severity 3

    +
  • Minor/moderate functional impact to a single user or small group of users. A workaround exists.

  • +

Severity 4

    +
  • A minor incident with (almost) no impact or detriment to the system functionality but nevertheless still a valid bug.

  • +
+ +Key: + +* Severity 1 = Critical +* Severity 2 = Severe +* Severity 3 = Average +* Severity 4 = Minor + +The severity code assigned to an incident will determine the solution time and will be used by the Service Desk to assign resources to the request. + +In addition to severity, in some cases the priority of an incident may also have to be considered. Priority is assigned by the Hub Operator (rather than the client) and is the order in which the incident will be fixed. The higher the priority, the sooner the incident will be resolved. Consider the following example: a cosmetic bug like a typo on a webpage will likely be ranked as low severity but could be a quick and easy fix and ranked high priority. Hence, it is important to give severity and priority due consideration. + +The following table provides guidance as to how to assign priority to an incident. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Priority matrix
Priority codeCriteria

Priority 1

A severe issue has occurred affecting multiple users within a service recipient (>50% of service recipient users) to the extent that they are unable to perform their assigned work functions, OR the service recipient or areas outside of the service recipient are affected.

Priority 2

An issue has occurred affecting either several users (affects >10 but no more than 50% of all service recipient users) OR a named power user of the service to the extent that they are unable to perform their assigned work functions and a business unit is affected.

Priority 3

An issue has occurred affecting a single user OR (affects <10 users OR no more than 25% of all users) to the extent that they are unable to perform their assigned work functions.

Priority 4

An issue has occurred affecting a single user, causing decreased functionality to a single application. There is a workaround for the user to perform their assigned work functions, but the outage causes a decrease in their productivity.
+ +## Security incidents + +This section describes the procedure that a Hub Operator is recommended to implement for handling security events/incidents. Security incidents may be classified as Severity 1, Severity 2, Severity 3, or Severity 4 incidents. Regardless of its categorization, follow the steps outlined in the table below if an incident is security-related. + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Security incident management
StepAdditional action or informationRole

Step 1: A suspected security event/incident is received through the Service Desk via a ticket assigned to the security team (L1) for initial review and triage.

Step 2: Invoke the triage process.

Step 2a:

+
    +
  • Identify artifacts of the incident.

  • +
  • Identify affected devices, systems, or users.

  • +
    +
  • Gather the key indicators of a threat.

  • +
  • Retrieve logs.

  • +
  • Look up artifacts (IP addresses, usernames, URLs, hostnames, and so on).

  • +
  • Review logs to find out if there is any law/regulation that is being violated by the incident (if it is a severe incident, it might damage the reputation of the organization).

  • +

L1 Information Security Officer (ISO)

Step 2b:

+
    +
  • Evaluate situation: impact assessment.

  • +
  • Estimate the potential effect of the event or incident.

  • +
    +
  • Review available indicators of compromise.

  • +
  • Assess impact based on the criticality of the affected system.

  • +
  • Review audit logs.

  • +
  • Draw a timeline of events.

  • +

L1 ISO

Step 2c:

+

Collect evidence.

    +
  • Collect and collate all available information to allow for categorization.

  • +

L1 ISO

Step 2d:

+

Determine categorization.

    +
  • Based on collected information, assign a category to the ticket.

  • +
  • L1 security will update categorizations as appropriate.

  • +
+

Example categories are:

+
    +
  • Denial of Service (DOS)

  • +
  • Malicious code

  • +
  • Unauthorized access

  • +
  • Data leak/loss

  • +
  • Data breach (breach of regulation related to data protection)

  • +
  • Inappropriate usage

  • +

L1 ISO

Step 2e:

+

Take basic steps to mitigate the effect on the environment.

Basic steps may include tasks such as: +
    +
  • Locking down an endpoint.

  • +
  • Deploying anti-malware where required.

  • +
  • Review security Standard Operating Procedures (SOPs) (if applicable) for any additional steps that may be required.

  • +
+

If mitigation steps taken are successful in resolving the reported issue, L1 Security will update the ticket and proceed to Step 8 (Close Issue).

L1/L2 ISO

Step 3: Make an assessment whether the reported issue is an event or an incident.

The assessment decision is taken by the L1 Security team in collaboration with L2 Security.

L1/L2 ISO

Step 4.1: If reported issue is categorized as an "event", follow these steps:

Step 4.1a:

+

Perform event follow-up.

Event follow-up examples include: +
    +
  • Verify and install anti-malware on all hosts.

  • +
  • Trigger tickets requesting patching of systems and/or review of event by Operations team.

  • +

L1/L2 ISO

Step 4.1b:

+

Go to Step 8.

L1 ISO

Step 4.2: If reported issue is categorized as an "incident", follow these steps:

Step 4.2a:

+

L1 ISO to escalate to L2 ISO for further investigation by re-assigning the ticket to the L2 Security group for follow-up.

L1 ISO

Step 4.2b:

+

L2 ISO to acknowledge receipt of the ticket from L1 and proceed to open Security Incident Report.

L2 ISO

Step 4.2c:

+

L2 ISO to review and verify incident severity and categorization.

L2 ISO

Step 5.1: If reported incident is categorized as an "S1" incident, follow these steps:

Step 5.1a:

+

Update Security Incident Report.

L2 ISO

Step 5.1b:

+

Inform stakeholders via secure email.

Stakeholders are documented in Appendix A: Incident management escalation matrix.

L2 ISO

Step 5.1c:

+

Proceed to Step 6.

L2 ISO

Step 5.2: If reported incident is categorized as an "S4" incident, follow these steps:

Step 5.2a:

+

Proceed to Step 6.

L2 ISO

Step 6: Contain and eradicate.

Step 6a:

+

Review and update mitigation actions to reduce impact.

Example mitigation actions include:

+
    +
  • Change passwords.

  • +
  • Lock down access.

  • +

L2 ISO

Step 6b:

+

Collect evidence.

L2 ISO

Step 6c:

+

Perform root cause analysis and identify/implement a fix.

L2 ISO

Step 6d:

+

Update incident Standard Operating Procedures (SOP) as necessary.

SOP updates are reviewed by L3 before adoption.

L2 ISO

Step 6.1: If Step 6 is successful, follow these steps:

Step 6.1a:

+

Update Security Incident Report and ticket.

Ensure ticket does not contain sensitive security information.

L2 ISO

Step 6.1b:

+

Communicate with stakeholders via secure email.

Stakeholders are documented in Appendix A: Incident management escalation matrix.

L2 ISO

Step 6.1c:

+

End system or service lockdown.

L2 ISO

Step 6.1d:

+

Proceed to Step 8.

L2 ISO

Step 6.2: If Step 6 is unsuccessful, follow these steps:

Step 6.2a:

+

Escalate to the L3 Security team.

L2 ISO

Step 6.2b:

+

Inform the business team.

L2 ISO

Step 6.2c:

+

L3 to proceed with Step 7.

L3 ISO

Step 7: L3 to review and resolve issue.

Step 7a:

+

Review activities and incident history documented by L1 and L2.

L3 ISO

Step 7b:

+

Provide guidance for further containment action.

L3 ISO

Step 7c:

+

If L3 resolves the issue, go to Step 8.

L3 ISO

Step 7d:

+

If L3 cannot resolve the issue, they may escalate to the system/software OEM or procure specialist services (subject to approval) for support.

If L3 cannot resolve the issue, they may escalate to the system/software OEM or procure specialist services (subject to approval) for support. A decision may be required on triggering the disaster recovery plan, including formation of a "war room".

A disaster recovery plan (DRP) is a bespoke arrangement, based on the Hub Operator's technical capabilities, as well as risk appetite. It is part of a Hub Operator's IT Security policies. It is necessary to assess details of the Hub Operator's DRP policy and expectations, and fine-tune the rollout to fit their needs. Details need to be worked out during implementation (preferably during the design phase) as the various options available may have cost implications.

L3 ISO

Step 8: Close the issue.

Step 8a:

+

Restore affected systems.

L1 / L2 / L3 ISO

Step 8b:

+

Update Security Incident Report.

L2 / L3 ISO

Step 8c:

+

Identify and communicate lessons learned.

L2 / L3 ISO

Step 8d:

+

Incident response team to review relevant recommendations for possible adoption.

This review session may include Tech Operations and Service Management teams, depending on severity.

L1 / L2 / L3 ISO

Step 8e:

+

Update stakeholders.

L2 / L3 ISO

Step 8f:

+

Close issue.

L1 / L2 / L3 ISO

Step 9: L3 ISO to modify and revise breach policies and procedures.

L3 ISO

+ +The following figure shows a summary of the process described above. + +![Security incident management](../../../.vuepress/public/security_incident_process.png) + +### Security Incident Report template + +When writing a Security Incident Report, it is good practice to use a template created for this purpose. + +## Roles and responsibilities + +This section provides generic guidelines on the proposed roles and responsibilities within the incident management process. + +::: tip NOTE +It is convenient to describe the running support for the technical operations of the Mojaloop Hub as levels. This document describes four levels. Levels are convenient because each level of support requires a different degree of knowledge of and access to the system. In other words, levels refer to different roles/Support teams within your organization. + +Some of these teams can optionally be outsourced, depending on the level of expertise or capacity within your organization. If you decide to outsource Support functions, there are organizations within the Mojaloop community that do provide different levels of Support as a service. (For more information and referrals, contact the Mojaloop Foundation.) +::: + +### End user/user/requester/L0 + +*Role* + +This is the stakeholder who experiences a disruption in service and raises an incident ticket to initiate the process of incident management. + +*Responsibilities* + +* Contact the Service Desk to raise a new incident request. +* Follow up on an existing request. +* Monitor the communication channel for any feedback from Support Engineers. +* Clearly communicate all the required or requested information to Support Engineers. +* Acknowledge the restoration of service and completion of the ticket. +* Respond to follow-up surveys after ticket resolution completing the feedback loop. + +### Level 1 Team/Service Desk + +*Role* + +This is the first point of contact (Support Level 1) for requesters or end users when they want to raise a request or incident. This role is responsible for basic Service Desk resolution, initial diagnostics, and the investigation of Service Desk tickets. + +*Responsibilities* + +* Log all incoming incident requests with appropriate parameters, such as severity and priority (if the latter is applicable). +* Assign tickets to Support Engineers based on the parameters above (severity and priority). +* Analyze and resolve incident to restore service. +* Escalate unresolved incidents to the Level 2 Team. +* Gather all required information from the requesters and send them regular updates on the status of their request. +* Act as a point of contact for requesters, and, if needed, coordinate between the Level 2 Team and end users. +* Verify the resolution with the end user and collect feedback while updating the tickets. +* Monitor feedback and surveys related to the actions that L1 took to resolve the issue for the purpose of analyzing the quality of service offered. + +### Level 2 Team (Application, Infrastructure, Security and Business Operations Support L2) (Customer Support Team) + +*Roles* + +This support function is made up of engineers or Business Operations Subject Matter Experts (SMEs) with advanced knowledge of the Hub. The L2 Team is expected to provide in-depth troubleshooting, technical analysis, transaction analysis, and support to resolve incidents reported. They usually receive more complex requests from end users; they also receive requests in the form of escalations from the L1 Team. + +*Responsibilities* + +* Carry out incident diagnosis. +* Document the steps followed to resolve the incident and submit Knowledge Base articles. (For every incident, the Support Team updates the Knowledge Base. The purpose of Knowledge Base articles is to enable end users and Support personnel to resolve issues on their own.) +* Handle intermediate incidents, for example, incidents related to Applications, Infrastructure, Log Analysis, Transactions Analysis, and so on. +* If the incident is resolved, confirm the resolution with the end user. +* Support DFSP onboarding. + +### Level 3 Team (Application, Infrastructure, and Security Support L3) (Technical Support Team) + +*Roles* + +This level is usually comprised of Specialist Engineers who have advanced knowledge of particular domains of the Hub – for example, knowledge of infrastructure components or system applications, or expertise in security engineering. + +*Responsibilities* + +* Perform deep analysis and/or reproduce the issue in a test environment in order to diagnose the issue properly and to test the solution. +* Interpret and analyze the code and data using information triaged from L1 and L2. +* If unresolved, escalate the incident to "L4" support partners to identify the underlying issue or to external vendors, DFSPs or Settlement Bank (transactions queries or transfer reports) as applicable. +* Provide subject matter expertise. +* Document the incident and update the Knowledge Base. (For every incident, the Support Team updates the Knowledge Base. The purpose of Knowledge Base articles is to enable end users and Support personnel to resolve issues on their own.) + +### Incident Manager/Service Manager + +*Role* + +The Service Manager monitors the effectiveness of the process. The Service Manager manages the process to restore normal service operation as quickly as possible and to minimize the impact on business operations. + +*Responsibilities* + +* Serve as the point of contact for all S1 incidents reported. +* Plan and facilitate all the activities involved in the incident management process. +* Ensure that the correct process is followed for all tickets, and correct any deviations. +* Coordinate and communicate with the Process Owner. +* Align customer expectations with the SLAs by being the interface between customers and the Operations team. +* Identify incidents that need to be reviewed and carry out the review. + +### Process Owner: Technical Operations Manager + +*Role* + +This is the owner of the process followed for managing incidents. This role also acts as a coordinator between teams and organizations. The Technical Operations Manager analyzes, modifies, and improves the process to ensure it best serves the interests of the organization. + +*Responsibilities* + +* Accountable for the overall quality of the process. Oversees the management of and compliance with the procedures, data models, policies, and technologies associated with the process. +* Owns the process and supporting documentation for the process from a strategic and tactical perspective. +* Ensures the incident management process aligns with other organization policies, for example, HR Policy, Security Policy, Level One Guiding Principles, and so on. +* Defines [key performance indicators (KPIs)](key-terms-kpis.md) and aligns them with critical success factors (CSFs), and ensures that these objectives are realized. +* Designs, documents, reviews, and improves processes. +* Establishes continuous service improvement (CSI) and ensures the procedures, policies, roles, technology, and other aspects of the incident management process are reviewed and improved upon. +* Stays informed about industry best practices and incorporates them into the incident management process. + +## Outputs of the incident management process + +The incident management process produces the following outputs. Note that the only mandatory output for Security or S1 incidents is the Root Cause Analysis (RCA), and all other outputs listed below might feed into the RCA. + +* Resolved or closed incidents. This is the most desired outcome of the incident management process. The closed incident record contains accurate details of the incident attributes and the steps taken for resolution or workaround. +* Requests for Change (RFC). +* Resolution metrics (Mean Time Between Failures, Mean Time To Repair, Mean Time To Acknowledge, and Mean Time To Failure). For details on KPIs, see the [Glossary](key-terms-kpis.md). +* Successfully implemented change through the change management process. +* RCA document complying to the RCA template. +* Restored service. +* Updated Knowledge Base database. +* Notification through various channels (Service Desk, email, call, and so on) on the initiation, resolution, and closure of an S1 incident to various stakeholders. +* Updated Daily Operation Report and management report to ascertain the decisions made with regards to service improvements, resource allocation/reallocation. +* Accurately recorded service and/or component outage details (for example, start, end, duration, outage classification, and so on). + +## Impact on other processes + +The incident management process interfaces with a number of other processes, feeding into and impacting each other: + +* **Change Management process**: The objective of the change management process is to ensure that standardized methods and procedures are used for efficient and prompt handling of all changes, in order to minimize the impact of change-related incidents upon service availability or quality, and consequently improve the day-to-day operations of the organization. +* **Release Management process**: Release and deployment management is defined as the process of managing, planning, and scheduling the rollout of IT services, updates, and releases to the production environment. The primary goal of this process is to ensure that the integrity of the live environment is protected and that the correct components and validated features are released for customer use. +* **Incident Communication process**: Incident communication is the process of alerting users that a service is experiencing some type of outage or degraded performance. This is especially important for services where 24/7 availability is expected. Incident communication is important for all partners, customers, and their customers. diff --git a/docs/adoption/HubOperations/TechOps/key-terms-kpis.md b/docs/adoption/HubOperations/TechOps/key-terms-kpis.md new file mode 100644 index 000000000..7fc61af60 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/key-terms-kpis.md @@ -0,0 +1,80 @@ +# Glossary + +This section acts as a glossary of Technical Operations terms and provides definitions of: + +* key terms guided by Information Technology Infrastructure Library (ITIL) best practices +* Key Performance Indicators (KPIs), that is, metrics that help determine whether specific incident management goals are met + +## Key terms + +**Change management:** Change management is the process of recording, approving, executing, closing, and reviewing all changes. The change can be either contractual (such as initial signature of contract, SLA upgrade, new resources needed, and so on), or operational arising from a change request. + +**Escalation:** The acknowledgement of the fact that an incident requires additional resources in order to meet service level targets or user expectations, taking into account the criticality, impact, and urgency of the incident. + +**Helpdesk/Service Desk:** The Single Point of Contact between the service provider and users. A typical Service Desk manages incidents and service requests, and also handles communication with the users. + +**Incident:** An unplanned interruption to an IT service, or reduction in the quality of an IT service. The failure of a configuration item that has not yet impacted service is also an incident; for example, the failure of one disk from a mirror set. + +**Incident management process (IMP):** The process of managing the lifecycle of all incidents. The primary purpose of incident management is to restore normal IT service operation as quickly as possible with the support of a whole organization in place. + +**Incident record/ticket:** A record containing the details of an incident. Each incident record (also known as a ticket) documents the lifecycle of a single incident. + +**Priority:** A category used to identify the relative importance of an incident or change. Priority is used to identify required times for actions to be taken. + +**Release management:** Release management is the process of managing, planning, scheduling, implementing, and controlling a software build through different stages and environments, with the goal of delivering features to customers or end users. + +**Request for Change (RFC):** The Request for Change (or simply Change Request) is a formal request for the implementation of a change. The RFC is a precursor to the "Change Record" and contains all information required to approve and execute a change. + +**Role:** A set of responsibilities, activities, and authorities granted to a person or team. Roles are used to assign owners to the various incident management processes, and to define responsibilities for the activities in the detailed process definitions. + +**Root cause analysis (RCA):** RCA is a collective term that describes a wide range of approaches, tools, and techniques used to uncover causes of incidents. It is called at each urgent incident, and every time an incident occurs more than once. + +**Service Level Agreement (SLA):** An agreement between an IT service provider and a customer. The SLA describes the IT service, documents service level targets, and specifies the responsibilities of the IT service provider and the customer. + +**Severity:** A measure of the effect of an incident on business processes. + +**TAT (Turnaround Time):** This is the time taken from when the incident is reported to the time it is resolved and closed. It includes Guaranteed Intervention Time (GIT) and Guaranteed Resolution Time (GRT). + +## Key Performance Indicators (KPIs) + +**Availability rate (Service availability rate):** The whole technical solution’s availability to provide the service per DFSP. + +**Average Incident Closure Duration:** Average amount of time between the registration of incidents and their closure. + +**Average Incident Response Time:** The average amount of time (for example, in minutes) between the detection of an incident and the first action taken to repair the incident. + +**Average Number of Incidents Solved By Service Desk:** Average number of incidents solved by Service Desk relative to all open incidents. + +**Guaranteed Intervention Time (GIT):** The time elapsed between the time an incident is reported (for example, an email is sent to the Service Desk tool) and the time that an acknowledgement response is returned to the reporter of the issue. + +**Guaranteed Resolution Time (GRT):** Sum of total time spent on resolving an issue from all parties. (The issue status must be “In Progress” or “Escalated” to count towards the sum total. Issue status “Pending” or “Closed” are not taken into account when calculating the sum total.) + +**Incidents Completed Without Escalation:** The percentage (%) of incidents completed within the SLA without any escalation. + +**Incident Queue Rate:** The number of incidents closed, relative to the number of incidents opened in a given time period. + +**Mean Time Between Failures (MTBF):** The average time between repairable failures of a technology product. The metric is used to track both the availability and reliability of an IT service or any other configuration item, to assess if they can perform their agreed function without interruption. The higher the time between failures, the more reliable the system. + +**Mean Time To Acknowledge (MTTA):** The average time it takes from when an alert is triggered to when work begins on the issue. This measures how long it takes an organization to respond to complaints, outages, or incidents across all departments on average. This metric is useful for tracking a team's responsiveness and an alert system's effectiveness. + +**Mean Time To Detect (MTTD) – "Proactive actions":** The difference between the onset of any event that is deemed revenue impacting and its actual detection by the technician who then initiates some specific action to recover the event back to its original state. This is not the same as starting the Mean Time To Repair (MTTR) clock (that is, once the technician receives a ticket). The onset of any revenue impacting event is almost always recorded at some specific time by some specific equipment. The key element is to bring the detection tool into the technician's environment, and then measure the difference between the event's timestamp and the technician's first action indicating recognition of the event (MTTD). + +**Mean Time To Failure (MTTF):** The average time between non-repairable failures of a technology product (mostly hardware). + +**Mean Time To Repair (MTTR):** Refers to the average amount of time required to repair a system and restore it to full functionality. \ +\ +The MTTR clock starts ticking when the repairs start and it goes on until operations are restored. This includes repair time, testing period, and return to the normal operating condition. + +**Mean Time To Recovery:** Mean Time To Recovery is a measure of the time between the point at which the failure is first discovered until the point at which the service returns to operation. So, in addition to repair time, testing period, and return to normal operating condition, it captures failure notification time and diagnosis. + +**Old Incident Backlog:** Number of open incidents older than 28 days (or any other given time frame) relative to all open incidents. + +**Percentage Of Incidents Solved Within Deadline/Target:** Number of incidents closed within the allowed duration time frame, relative to the number of all incidents closed in a given time period. A duration time frame is applied to each incident when it is received, and sets a limit on the amount of time available to resolve the incident. The applied duration time frame is derived from the agreements made with the customer about resolving incidents. + +**Percentage Of Incidents Solved Within SLA Time:** Total number of incidents resolved within SLA time, divided by the total number of incidents. + +**Percentage Of Outage Due To Incidents:** Percentage of outage (unavailability) due to incidents, relative to the service hours. + +**Percentage Of Overdue Incidents:** Number of overdue incidents (not closed and not solved within the established time frame) relative to the number of open (not closed) incidents. + +**Percentage Of Repeated Incidents:** Percentage of incidents that can be classified as a repeat incident, relative to all reported incidents within the measurement period. A repeat incident is an incident that has already occurred (multiple times) in the measurement period. diff --git a/docs/adoption/HubOperations/TechOps/problem-management.md b/docs/adoption/HubOperations/TechOps/problem-management.md new file mode 100644 index 000000000..a5c10e250 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/problem-management.md @@ -0,0 +1,131 @@ +# Problem management + +The overall objective of problem management is getting to the root cause of incidents (Severity 1 incidents or incidents that occurred more than once) or the potential causes of incidents, and then instigating actions to improve or correct the situation at once. + +The problem management procedure ensures that: + +* problems are properly logged +* problems are properly routed +* problem status is accurately reported +* queue of unresolved problems is visible and reported +* problems are properly prioritized and handled in the appropriate sequence +* resolution provided meets the requirements of the agreed upon service level agreement (SLA) +* resolution of root cause issues or problems is done + + +## Identifying problems + +A problem is declared by the relevant service management stakeholder in the following situations: + +* when there is an incident whose cause the incident owner cannot establish within set service level agreement +* when there are repeat occurrences of an incident with considerable impact to business +* when there is a service degradation or deviation from expected behavior that is likely to affect business in future if not mitigated, and whose mitigation is not well established + +In any of the scenarios above, or any other scenario that the Problem Manager may deem applicable, a problem record will be opened and the problem management process kicked off. + +If a problem turns out to be caused by a defect in the product, a bug is raised in accordance with the [defect triage process](defect-triage.md). + +## Categorizing and prioritizing problems + +In order to determine if SLAs are met, it is necessary to categorize and prioritize problems quickly and correctly. + +The goal of proper categorization is to: + +* identify the service impacted +* associate problems with related incidents +* indicate which Support groups need to be involved +* provide meaningful metrics on system reliability + +For each problem, the specific service will be identified. + +The priority assigned to a problem will determine how quickly it is scheduled for resolution. Priority is set based on a combination of the related incidents’ severity and impact. + +The table below provides guidance as to how to classify a problem. For guidance on how to read this table, see the following examples: + +* A problem with High severity and Low impact will be classified as a Medium-priority problem (check the cell at the junction of High severity and Low impact). +* A problem with Medium severity and High impact will be classified as a High-priority problem (check the cell at the junction of Medium severity and High impact). + + + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Problem priority matrix
SEVERITY

Low
+
+The problem prevents the user from performing a portion of their duties.

Medium
+
+The problem prevents the user from performing critical time-sensitive functions.

High
+
+A service or a major portion of a service is unavailable.

IMPACT

Low
+
+The problem affects one or two members of personnel.

+

Degraded service levels but still processing within SLAs.

Low

Low

Medium

Medium
+
+Degraded service levels but not processing within SLA constraints or able to perform only minimum level of service.

+

The cause of the problem seems to affect multiple functional areas.

Medium

Medium

High

High
+
+All users of a specific service are affected.

+

A customer-facing service is unavailable.

High

High

High

+ +## Documenting workarounds + +A workaround defines a temporary way of overcoming the adverse effects of a problem. Workarounds may be: + +* instructions provided to the customer on how to complete their work using an alternative method +* temporary fixes that assist a system to work as expected but which do not resolve the issue permanently + +Workarounds need to be documented and communicated to the Service Desk so they can be added to the Knowledge Base. This will ensure that workarounds are accessible to the Service Desk to facilitate resolution during future recurrences of the incident. + +In cases when a workaround is found, it is important to document all details of the workaround within the Problem Record and that the Problem Record remains open. + +## Documenting known errors + +When a diagnosis is made to identify a problem and its symptoms, a Known Error Record must be raised and placed in the Known Error documentation. If repeat incidents or problems arise, they can be identified and service restored more quickly. Any workarounds or solutions should also be documented in the particular problem's Known Error Record. + +In some cases it may be advantageous to raise a Known Error Record even earlier in the overall process – just for information purposes, for example – even though the diagnosis may not be complete or a workaround may not have yet been found. + +The Known Error Record must contain all known symptoms so that when a new incident occurs, a search of known errors can be performed and the appropriate match found. + +## Process + +The following figure shows a summary of the process described above. + +![Problem management](../../../.vuepress/public/problem_mgmt.png) diff --git a/docs/adoption/HubOperations/TechOps/release-management.md b/docs/adoption/HubOperations/TechOps/release-management.md new file mode 100644 index 000000000..380fed1f2 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/release-management.md @@ -0,0 +1,108 @@ +# Release management + +Release management handles the processes around managing, planning, scheduling, and controlling a software change through deployment and testing across various environments. + +::: tip NOTE +The processes described in this section represent best practices and act as recommendations for organizations fulfilling a Hub Operator role. +::: + +::: tip NOTE +This section references a "Mojaloop Support team": a team dedicated to running Support services for the technical operations of a Mojaloop Hub. Note that this team can be either an insourced or an outsourced unit, depending on the level of expertise or capacity within your organization. If you decide to outsource Support functions, there are organizations within the Mojaloop community that provide different levels of Support as a service. (For more information and referrals, contact the Mojaloop Foundation.) +::: + +## Release components and environments + +When accepting new releases from Mojaloop Open Source for Switch services and other components that are needed, the releases are taken through a series of testing activities in progressively higher environments, starting with development/QA environments and ending with production-level testing. + +The recommended environment setup comprises of multiple environments all serving different purposes, as depicted in the diagram below. + + + +A Hub-specific implementation of Mojaloop is built on a number of service components (Mojaloop OSS, extensions or other components, potential customizations), and releases will include new features, enhancements, or bug fixes of all of these components. + + + +## Development and testing (Definition of Done) + +Standard development and QA practices – followed by the Mojaloop Development/Product Delivery team – include the following as part of the Definition of Done. The recommendation is for the Hub Operator to adopt a similar strategy. + +* Unit tests developed for every piece of code written. +* Code, unit tests, and documentation have been peer reviewed. +* Integration tests have been developed and executed. +* Full regression tests have been executed successfully on commit (merge to master branch). +* Release notes have been created with the following details: + * Description of changes + * List of changed components/services + * List of user stories and bugs in the release + * Highlight of any fundamental (breaking) changes impacting any functionality, API solution, or system architecture +* Deployment runbook created, with deployment and rollback instructions including environment variables, database update scripts, and deployment prerequisites. +* Maintenance of regression test definitions, baseline test results from Mojaloop OSS, and Scheme-specific validation criteria (tests) added on top of them. +* Maintenance of a knowledge base of any new or significant changes to functionality, products, architecture, and so on, regarding Mojaloop OSS and other components, as well as customizations done for the Scheme. The knowledge base acts as the basis of knowledge handover to the Operations team. This handover includes full review of the deployment runbook and other release artifacts, such as release packages and database scripts, which will help the Operations team greatly in day-to-day operations, validation, debugging of issues, and maintenance. + +## Mojaloop releases + +The standard practice for Mojaloop releases is as follows: + +* All new versions of the individual applications, components, and microservices that make up Mojaloop, are available via Helm charts in the public repositories here: +* Unit tests and some functional integration tests are produced with each component version. +* The Mojaloop release also includes automated end-to-end regression tests. Test suites are versioned, with the version number corresponding to the version number of the Mojaloop release. +* A release package is produced, once every Program Increment (PI), for new versions of Mojaloop. This includes upgrades to individual applications, components, and microservices within Mojaloop. \ +\ +A Program Increment is a timeboxed interval during which an Agile team delivers incremental value. +* All Mojaloop maintenance updates, new features, and bug fixes are made available to users of Mojaloop as part of the release cycles, once in each PI period. + +## Product releases of extensions/additional components + +It is recommended that the standard practice for the product releases of extensions/additional components is in line with the Mojaloop release process [above](release-management.md#mojaloop-releases): + +* All new product versions are made available via release packages and described within the release notes. +* A release package includes automated end-to-end tests for each product release. Test suites are versioned, with the version number corresponding to the version number of the product release. +* Product releases are in line with the Mojaloop release cadence, once in each PI period. +* All product maintenance updates, new features, and bug fixes are made available to client DFSPs of extensions/additional products as part of the release cycle, once in each PI period. + +## Bugs and hotfixes + +Bugs and hotfixes are handled in the following way: + +* All bug fixes (both Mojaloop and other products) are included in the release packages. +* Likewise, hotfixes are also provided via a release. It is not recommended to deploy hotfixes directly from the specific application package releases, as deploying only a single component of a release (as opposed to deploying the release that includes the updated component) can result in the Hub being out of sync with the application package release. +* Bugs are tracked, managed, and prioritized as defined in the [defect triage process](defect-triage.md): + * The Service Desk tool is used for managing all bugs. + * A Mojaloop Support Triage team with representatives from both Mojaloop and other Product Delivery and Product Management teams are involved in analyzing urgency and impact to determine prioritization of bugs, including resolution planning/scheduling and communication back to the Hub Operator. + +## Environments and QA strategy + +In order to validate a deployment of a newly released Mojaloop version against the latest other products (extensions/additional components), an environment is to be set up by the Scheme with all the components needed along with the specific configuration that the Scheme uses. This allows the QA/validation and/or Mojaloop Support teams (a team dedicated to running Support services for the technical operations of a Mojaloop Hub) to carry out the deployment and testing of Mojaloop releases against the latest versions of other products. + +::: tip NOTE +The environment set up by the Mojaloop Support team for validation should follow a standard infrastructure, replicating or simulating a corresponding production setup as much as possible, so that any issues, bugs can be identified early in the process. A production setup typically includes API gateways, DMZs, cluster setup based on security zones, along with all the required components and customizations (including Scheme Rules) done by the Scheme. The Hub Operator must ensure that their production infrastructure is fully in sync with the Mojaloop Support team's infrastructure standards. +::: + +Following the successful deployment and validation of a release on the standard infrastructure and architecture, and after successfully running the latest version of Mojaloop and other products, the release is approved and can be shared/made available (via the Support Team's client server/repo). The Hub team can then schedule the deployment into the Hub Operator's (potentially bespoke) environment. + +The QA strategy employed by the Mojaloop and the extension products' Product Delivery teams ensures that new code of each and every service component has undergone comprehensive testing before it gets released. The QA strategy of the Mojaloop Support team, on the other hand, should focus on validating the deployability of the integrated service components and the interoperability of the products, guaranteeing that there is a working Mojaloop Switch, which then can be deployed in a Hub Operator's environment. + +## Release process + +The recommendation for Hub implementations is to stay in line with the Mojaloop release cadence of one release every PI period and avoid deploying individual changes directly from the master branch of specific applications, components, or services within Mojaloop. This recommendation ensures that the integrity of the applications remains cleaner and in line with the source repositories. + +For every release, the Mojaloop Support team is recommended to take the following steps: + +::: tip NOTE +Hub Operators must be informed of the target release date well ahead of time. +::: + +1. The Mojaloop Support team review all release artifacts including release notes and associated documentation, and create or enhance the deployment runbook as soon as the release is made available. +1. The Mojaloop Support team conduct deployment and validation of the planned Mojaloop and other product releases in a temporary Mojaloop Support environment (using the standard Mojaloop Support infrastructure but matching the client's – that is, the Hub Operator's – application versions). +1. Following the successful deployment and validation of a release on the standard Mojaloop Support infrastructure and architecture, and after successfully testing the latest version of Mojaloop and other products, the release is approved and made available to the Hub Operator. +1. The Hub Operator team confirm readiness (and optionally, target deployment window) for the deployment into the Hub Operator's Development environment. \ +\ +It is the Hub Operator's responsibility to carry out deployment into the Development environment and subsequent validation. Alternatively, they can request Mojaloop Support to perform these activities on their behalf. + +### Deployments by the Mojaloop Support team + +If the Hub Operator requests the Mojaloop Support team to perform deployment into the Hub Operator's Development environment, then the Mojaloop Support team sends out an email (or any other form of communication depending on the Hub Operator’s preferences) with information on the target release date, the range of features included in the release, and the deployment window. Following deployment, further communication is sent out to confirm that the deployment has been carried out, validated, and the deployment window has closed. + +## Process flowchart + + \ No newline at end of file diff --git a/docs/adoption/HubOperations/TechOps/service-level-agreements.md b/docs/adoption/HubOperations/TechOps/service-level-agreements.md new file mode 100644 index 000000000..c07bd71d1 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/service-level-agreements.md @@ -0,0 +1,35 @@ +# Appendix B: Service Level Agreements + +The timelines indicated in the following table are example target response times for handling incidents. They can act as a starting point for the Hub Operator to work out their own timelines. + +::: tip NOTE +The response cannot be an automated response. +::: + + + ++++ + + + + + + + + + + + + + + + + + + + + +
Example incident response timelines and SLA
Incident severityTarget response time

Severity 1

Within 2 hours

Severity 2

Within 4 business hours

Severity 3-4

Within 8 business hours

\ No newline at end of file diff --git a/docs/adoption/HubOperations/TechOps/tech-ops-introduction.md b/docs/adoption/HubOperations/TechOps/tech-ops-introduction.md new file mode 100644 index 000000000..e2a9f3323 --- /dev/null +++ b/docs/adoption/HubOperations/TechOps/tech-ops-introduction.md @@ -0,0 +1,31 @@ +# Introduction – Technical Operations Guide + +The Mojaloop Hub operates a number of environments that need managing and maintaining on a daily basis. The standard procedures described in this document outline the operations processes that enable the Hub Operator to handle all aspects of managing a live service. + +The following procedures need to be in place: + +- [**Incident management**](./incident-management.md): Managing incidents that have been reported to the Technical Operations team or that reached the team via alerts or monitoring activities. + +- [**Problem management**](./problem-management.md): Getting to the root cause of incidents or the potential causes of incidents, and instigating actions to improve or correct the situation at once. + +- [**Change management**](./change-management.md): Controlling the lifecycle of all changes, enabling changes to be made with minimum disruption to IT services. + +- [**Release management**](./release-management.md): Managing, planning, scheduling, and controlling a software change through deployment and testing across various environments. + +- [**Defect triage**](./defect-triage.md): Ensuring that all the bugs identified in the client’s Production environment are captured, evaluated, prioritized, and submitted to the Service Desk. + +A quick overview of the environments managed by the Hub Operator is provided below: + +- **Development**: Non-production software development environment where Mojaloop OSS code is merged with customizations. Gives developers fast test feedback on new code submissions. Digital Financial Service Providers (DFSPs) do not interact with this environment. Developer and QA access only. + +- **User Acceptance Testing (UAT)**: Testing environment for user acceptance and regression testing to validate new releases. + +- **Sandbox (SBX)**: Testing environment to validate DFSP connectivity on both API and security requirements. + +- **Staging (STG)**: Pre-production environment that mirrors production as closely as possible. Validation of new releases and DFSP integration. + +- **Production (PRD)**: Production environment compatible with production release. + +::: tip +A [Glossary](./key-terms-kpis.md) is provided to help clarify common Technical Operations terms used throughout this document. If you encounter a term that needs explaining, it is worth checking the glossary to see if a definition has been provided. +::: \ No newline at end of file diff --git a/docs/adoption/Scheme/platform-operating-guideline.md b/docs/adoption/Scheme/platform-operating-guideline.md new file mode 100644 index 000000000..8a174d79e --- /dev/null +++ b/docs/adoption/Scheme/platform-operating-guideline.md @@ -0,0 +1,555 @@ +# Platform Operating Guideline Template + +- Version: 2.0 + - Author: Carol Coye Benson (Glenbrook), Michael Richards (ModusBox) + - Date: October 2019 + - Description: + +--- + +## **About the Mojaloop Community Business Document Project** + +This document is part of the Mojaloop Community Business Document Project. The project is intended to support entities (countries, regions, associations of providers or commercial enterprises) implementing new payments systems using Mojaloop code. These entities will also need write Business Rules that participants in the system will follow. + +The Mojaloop Community Business Document Project provides templates for Business Rules and related documents. There are many choices involved in implementing a new payment system: the templates show some of the choices and, where appropriate, commentary is provided on how the particular choice is related to the goals of a Level One aligned system. + +The following documents are part of the project: + +- Scheme Key Choices + +- Scheme Participation Agreement Template + +- Scheme Business Rules Template + +- Platform Operating Guideline Template + +- Exception Management Operating Guideline Template + +- Uniform Glossary + +## **Introduction** + +A Scheme implementing a Level One aligned system, including those using Mojaloop reference code in the platform, will need to write Business Rules for the Scheme. A template for those Business Rules is included in this project. The Business Rules introduce the concept of Associated Documents, which are part of the Business Rules and have the same force — DFSPs signing the Business Rules are also bound to follow provisions in Associated Documents. + +The Platform Operating Guideline is an important Associated Document that describes how the Scheme Platform will operate, and specifies the obligations and responsibilities of the Scheme, the Platform Operator, and the DFSPs. + +This document is a template for such a Platform Operating Guideline. Many provisions in it, however, will vary depending on what choices the Scheme has made: some of these choices are described in the "Scheme Key Choices" document which is a part of this project. + +The Business Rules template that is part of this project can be used independent of a scheme's choice of platform. This Platform Operating Guideline is more specific to the use of Mojaloop as a platform. + +## **Table of Contents — Platform Operating Guideline Template** + +[1 - About This Document](#_1-about-this-document) + +[1.1 - Scheme Services](#_1-1-scheme-services) + +[1.2 - Open API Specification](#_1-2-open-api-specification) + +[1.3 - Scheme Use Cases](#_1-3-scheme-use-cases) + +[1.4 - Scheme Supported Identifiers](#_1-4-scheme-supported-identifiers) + +[2 - The Account Lookup Service](#_2-the-account-lookup-service) + +[2.1 - Description of the Account Lookup Service](#_2-1-description-of-the-account-lookup-service) + +[2.2 - Party Request](#_2-2-party-request) + +[2.3 - Parties Query](#_2-3-parties-query) + +[2.4 - Parties Query Response](#_2-4-parties-query-response) + +[3 - The Quote Service](#_3-the-quote-service) + +[3.1 - Description of the Quote Service](#_3-1-description-of-the-quote-service) + +[3.2 - Quote Request](#_3-2-quote-request) + +[3.3 - Quote Response](#_3-3-quote-response) + +[4 - The Transfer Service](#_4-the-transfer-service) + +[4.1 - Description of the Transfer Service](#_4-1-description-of-the-transfer-service) + +[4.2 - Transfer Request](#_4-2-transfer-request) + +[4.3 - Request to Pay](#_4-3-request-to-pay) + +[5 - The Settlement Service](#_5-the-settlement-service) + +[5.1 - Transfer Settlement](#_5-1-transfer-settlement) + +[5.2 - Fee Settlement: Processing Fees](#_5-2-fee-settlement-processing-fees) + +[5.3 - Fee Settlement: Interchange Fees](#_5-3-fee-settlement-interchange-fees) + +[6 - The Scheme Management Service](#_6-the-scheme-management-service) + +[6.1 - Description of the Scheme Management Service](#_6-1-description-of-the-scheme-management-service) + +[6.2 - The Registration Process](#_6-2-the-registration-process) + +[6.3 - DFSP Customer Service](#_6-3-dfsp-customer-service) + +[6.4 - Scheme System Management](#_6-4-scheme-system-management) + +[7 - The Fraud Management Service](#_7-the-fraud-management-service) + +[8 - Appendix: Scheme Supported Use Cases and System Parameters](#_8-appendix-scheme-supported-use-cases-and-system-parameters) + +[9 - Appendix: Merchant Category Codes](#_9-appendix-merchant-category-codes) + +## 1. About This Document + +These Platform Operating Guidelines specify operational and technical requirements for DFSPs and for the Scheme. From time to time the Scheme will issue additional Operational Bulletins, which will describe additional operational features of the Scheme and specify additional requirements of DFSPs. + +### 1.1 Scheme Services + +- Scheme Services are used by DFSPs to exchange interoperable transactions, and to manage their involvement with the Scheme. + +- The Scheme Account Lookup Service enables DFSPs in the system to identify the DFSP who manages the Transaction Account for an intended Payee or other counterparty to a Transfer. + +- The Scheme Transfer Service enables a Payer DFSP to send a Transfer to a Payee DFSP, thereby effecting a transfer of funds from a Payer to a Payee. + +- The Scheme Settlement Service enables DFSPs to settle their financial obligations to the Scheme with respect to Transfers. + +- The Scheme Management Service enables the Scheme to grant and revoke access to Scheme by DFSPs, manages the ongoing interactions of DFSPs with Scheme, monitors the effective operation of Scheme, and provides tools for DFSPs to manage their involvement with Scheme. + +- The Scheme Fraud Management Service enables DFSPs to collaborate on certain elements of fraud management in order to reduce costs and improve results. + +- DFSPs are required to follow the procedures detailed below for using Scheme. + +### 1.2 Open API Specification + +Scheme protocols are based on the operational and data models defined in the specifications document "Open API for FSP Interoperability Specification" version 1.0 dated \[xx\]. Where the Scheme departs from this specification, such departures are documented here and will supersede the relevant sections of that document. The Scheme may update the version used by issuing an Operational Bulletin. + +### 1.3 Scheme Use Cases + +Some rules and operational specifications vary by Use Cases and Secondary Use Cases supported by Scheme. Scheme recognizes Use Cases and Secondary Use Cases by a combination of required data components and system inference. This is detailed in an Appendix to this document. + +### 1.4 Scheme Supported Identifiers + +The Scheme supports certain Identifiers, or payment addresses, for use in making Transfers. The Identifier identifies the Payee whose Transaction Account is credited for the Transfer. Supported Scheme Identifiers are listed in an Appendix to the Business Rules. + +For each scheme supported identifier, this document should specify what the identifier is and how it is resolved (how it is determined which Payee DFSP is responsible for the transaction account associated with that identifier. + +#### 1.4.1 Example: The MSISDN Identifier + +Each scheme will have its own guidelines for each identifier; the provisions below could vary significantly depending on choices made. + +- MSISDN's are mobile numbers which are globally unique. MSISDN's are the Transaction Account Identifier for DFPSs who are Mobile Network Operators and who are providing Transaction Accounts to their customers. + +- Use of the MSISDN as a Payee Identifier is limited to Transaction Accounts provided by DFSPs who are the Mobile Network Operator responsible for that MSISDN. + +::: tip NOTE +If MSISDN's are used for other Transaction Accounts, they are aliases, and a separate protocol for resolving them must be specified. +::: + +- A Party Request for an MSISDN is resolved by a MSISDN directory service determined by the Scheme. The Scheme may specify directory service maintenance obligations for Mobile Network Operator DFSPs from time to time. + +#### 1.4.2 Example: The Bank Account Number Identifier + +Each scheme will have its own guidelines for each identifier; the provisions below could vary significantly depending on choices made. + +- Bank Account numbers are assigned to customers by Bank DFSPs who are providing Transaction Accounts to their customers. + +- The Bank Account Number, together with a Bank Code, form the Scheme Bank Account Number Identifier. Payer DFSPs are responsible for correctly formatting the Bank Account Number Identifier according to formats that will be specified by the Scheme. + +- Use of the Bank Account Number Identifier is limited to Transaction Accounts which are provided by DFSPs who are Banks. + +- A Party Request for a Bank Account Identifier is sent by the Payer DFSP to Scheme. Scheme checks that the Bank Code in the Bank Account Identifier is associated with a Bank active in Scheme. + +#### 1.4.3 Example: The Scheme Merchant Identifier + +Each scheme will have its own guidelines for each identifier; the provisions below could vary significantly depending on choices made. + +- The Merchant ID is a Scheme-defined identifier used for person-to-business payments. + +- Use of the Merchant ID is limited to DFSPs who are providing Transaction Accounts to merchants, billers, government agencies or other enterprise entities who are receiving payments from their customers over Scheme. It may be used for both in-person and remote payments. The term "merchant" used in this section includes all of these types of receivers of payments. + +- Use of the Merchant ID is limited to Transfers of the P2B or P2G Use Cases + +- A merchant may request multiple merchant IDs from their DFSP; these may be used by the merchant for different outlets, tills, or stores. There is no limit to the number of merchant IDs that can be linked to a single Transaction Account. A given merchant ID, however, may only be linked to a single Transaction Account. + +- The Merchant ID is issued by Scheme to the DFSP who is providing the merchant with the Transaction Account into which payments will be made. + +- The Merchant ID is issued as a number, which may be displayed by a merchant physically or digitally. + +- Merchant ID's may be rendered as QR codes by DFSPs or their merchant customers. QR codes must be rendered under format and brand guidelines that will be issued by the Scheme. DFSPs are prohibited from using other QR code data formats or brands to receive payments through Scheme. + +- DFSPs are required to display Scheme branding. Scheme brand requirements will be specified by the Scheme. Scheme branding must be visible to the customer in the merchant store, or on the device the paying customer is using to purchase remotely. + +- Registration Requirements. DFSPs will request a Merchant ID for a customer using a Scheme API specific to this purpose. DFSPs will be required to provide: + + - DFSP ID + + - The Transaction Account number which will receive the funds paid to the merchant. This may be either an MSISDN or a bank account number. + + - The \[business registration or tax ID\] of the merchant. Any number of merchant IDs may be associated with the same business registration or tax ID. + + - The Merchant Name + +- DFSPs requesting a Merchant ID from Scheme warrant that they have completed the required KYC information for the merchant account at the time of the request. + +- DFSPs are required to provide adequate training information to their customers. + +- Disabling Merchant IDs. DFSPs may request that a Merchant ID be disabled. Scheme will immediately disable this Merchant ID, but will retain it in the Scheme system for reporting purposes. Quote Requests or Transfer Requests made to this Merchant ID will be refused by Scheme and returned the Payer DFSP. + +The Scheme may wish to provide some mechanism for porting a Merchant ID from one DFSP to another. + +#### 1.4.4 The Scheme ID Identifier + +This ID would be similar to the Merchant ID above but would be meant for consumers as well as businesses, and could be expressed in phrases rather than as a number. Note each scheme will have its own guidelines for each identifier; the provisions below could vary significantly depending on choices made. + +- The Scheme ID is a Scheme-defined identifier. + +- DFSPs are required to offer their customers the option of requesting a Scheme ID. + +- Scheme IDs can be in any form, subject only to restrictions of length which Scheme will specify from time to time. Scheme reserves the right to refuse the use of any specific requested Scheme ID. + +Schemes may wish to enable Scheme ID's + +- Customers may request any number of Scheme IDs, subject to limits imposed by their DFSP. Multiple Scheme IDs can be associated with a single Transaction Account. Each Scheme ID, however, can be associated with only a single Transaction Account. + +- Registration Requirements. DFSPs will request a Scheme ID for a customer using a Scheme API specific to this purpose. DFSPs will be required to provide in this API: + + - DFSP ID + + - The requested Scheme ID + + - The Transaction Account number which will receive the funds paid to the customer. This may be either an MSISDN or a bank account number. + + - If the Transaction Account Holder is a merchant or business, the \[business registration or tax ID\] of the Account Holder. Any number of Scheme IDs may be associated with the same business registration or tax ID. + +- DFSPs requesting a Scheme ID from Scheme warrant that they have completed the required KYC information for the customer account at the time of the request. + +- Disabling Scheme Identifiers. DFSPs may request that a Scheme ID be disabled. Scheme will immediately disable this Scheme ID, but will retain it in the Scheme system for reporting purposes. Quote Requests or Transfer Requests made to this Scheme ID will be refused by Scheme and returned to the Payer DFSP. + +The Scheme may wish to provide some mechanism for porting a Scheme ID from one DFSP to another. + +The following sections describe each service and the obligations and responsibilities of stakeholders. Each service consists of processes: most of the processes are linked to specific API calls specified in the [Open API Specification](#_1-2-open-api-specification) section of this document. + +## 2. The Account Lookup Service + +### 2.1 Description of the Account Lookup Service + +- The Account Lookup Service allows DFSPs to map specific Identifiers for individual customers to the DFSP that provides a Transaction Account for that customer. Identifiers are used to identify individuals, merchants, billers, government agencies or other enterprises. Any Identifier Type supported by Scheme has a defined Identifier Service, the parameters of which are shown in the section "Scheme Supported Identifiers" of this document. + +- All Identifier Services ensure that Identifiers used for Scheme Transactions are unique within Scheme and are associated with a single DFSP who provides the relevant Transaction Account for that customer. Any Identifier must be associated with a single Transaction Account. + +- DFSPs must complete the Account Lookup process immediately before initiating a Quote process unless otherwise permitted in these Guidelines. + +### 2.2 Party Request + +- A Party Request is sent by a Payer DFSP to the Platform. The Party Request must contain the following key data elements: + + - The Identifier for the intended Payee + + - The Payer DFSP identifier + +The scheme may define additional key data elements which will be required in the Parties Request. + +- The request is forwarded from the Platform to the Account Lookup Service for that Identifier type. + +- The Identifier Service returns to the Account Lookup Service the identification of the DFSP associated with that Identifier, if a reference is found. If it is not, a negative response is returned and this is communicated by the Platform to the Payer DFSP. If a reference is found, the Account Lookup Service then associates the identified DFSP with the correct Scheme DFSP ID. + +### 2.3 Parties Query + +- If the Party Request succeeds in identifying a Payee DFSP, the Platform then executes a Parties Query to the identified DFSP to determine if the DFSP is willing to accept a Quote Request directed to that Identifier. + +### 2.4 Parties Query Response + +- The identified DFSP responds either with a positive Parties Query Response or with an error response. If positive, the Parties Query Response must contain the following key data elements: + + - The full Name of the Payee + + - The Payer DFSP Identifier + + - The Transaction Account Type, which specifies whether the Account is a bank account or a wallet + + - The Transaction Account Holder Type, which specifies whether the Transaction Account Holder is a consumer, a merchant (including other enterprise types) or a government agency. + + - If the Payee is a Merchant, the Merchant Category Code. These codes are found in an appendix to this document. + +The scheme may define additional data elements required in the Parties Query Response. + +- The Platform responds to the Payer DFSP with the result of the Parties Query Response + +## 3. The Quote Service + +#### 3.1 Description of the Quote Service + +- The Quote Process precedes the Transfer Process, and allows the Payer and Payee DFSP to exchange certain information prior to the Transfer. + +- The Quote Process must be completed before a Payer DFSP initiates the Transfer Process. This is true for all Use Cases and Secondary Use Cases. + +- The steps in the Quote Process are shown below. + +#### 3.2 Quote Request + +- A Quote Request is sent by a Payer DFSP to the Payee DFSP; the Quote Request is recorded by the Platform. The Quote Request must contain the following key data elements: + + - The Transfer Amount + + - The Amount Type set as a Send Amount. + + - The complete set of Party Information that was returned from the Parties Request Response. + + - The Full Name of the Payer (the Transaction Account Holder at the Payer DFSP) + + - Transaction Type data required for the Use Case and Secondary Use Case of the Transaction, as specified in the Use Case Appendix to this document. + + - An expiry time, the allowable parameters of which will be specified by the scheme from time to time. + +The scheme may define additional key data elements which will be required in the Parties Query Response. + +- A Quote Request for an amount above the Scheme Transaction Value Limit will be rejected by the Platform and returned to the Payer DFSP. + +### 3.3 Quote Response + +- A Quote Response is sent by the Payee DFSP to the Payer DFSP; the Quote Response is recorded by the Platform. The Payee DFSP is required to respond to a Quote Request. + +- The Quote Response must contain the following key data elements: + + - The Transfer Amount + + - An expiry time, the allowable parameters of which will be specified by the Scheme from time to time. + + - The signed Transaction Object which contains the parameters of the transfer. The Transaction Object is the authoritative description of the transaction for the purposes of Scheme reporting, fraud management and dispute resolution. + +The scheme may define additional key data elements which will be required in the Parties Query Response. + +- The Quote Response is signed by the Payee DFSP and defines the parameters of the Transaction; the Payer DFSP cannot change these parameters in the Transfer Process. + +## 4. The Transfer Service + +### 4.1 Description of the Transfer Service + +- The Transfer Service is the means by which the actual transfer of funds is accomplished between Payer DFSP and Payee DFSP. The Transfer Request is the key process within the service. A Transfer Request must be preceded by a Quote process. + +### 4.2 Transfer Request + +- A Transfer Request is sent by a Payer DFSP to the Payee DFSP via the Transfer Service at Scheme. The Platform records the Transfer Request. The Transfer Request must contain the following key data elements: + + - The Payer and Payee DFSP Identifiers + + - The Transaction Amount + + - An ILP packet representing the Transaction Object + + - An expiry time, the allowable parameters of which will be specified by the Scheme from time to time. + +The scheme may define additional key data elements which will be required in the Transfer Request. + +- The Transfer Request is signed by the Payer DFSP + +- The Platform performs a Transfer Approval process to determine if the proposed Transfer can be settled. The Transfer Approval process is further defined in the Settlement Service section of this document. + +- If the Transfer Request fails the Transfer Approval process, the Transfer Request is returned to the Payer DFSP. + +- If the Transfer Request passes the Transfer Approval process, the Platform reserves the funds specified in the Transfer Request in the Payer DFSP's Position Ledger. This is further defined in the Settlement Service section of this document. + +- The Payee DFSP determines if they will accept the Transfer. + +- If not accepted, an error response is returned to the Platform. The Platform releases the reservation of funds in the Payer DFSP's Position Ledger and returns an error condition to the Payer DFSP. + +- If accepted, the Payee DFSP returns a signed Transfer Response indicating that the Transfer has been Fulfilled. The Platform replaces the provisional debit with a debit in the Payer DFSP's Position Ledger and credits the Payee's DFSP's Position Ledger with a credit in the amount of the Transfer. + +- The Platform then sends a confirmation of the fulfilled Transfer to the Payer DFSP and to the Payee DFSP. + +- If the Platform does not receive a signed Transfer Response within the expiry period in the Transfer Request, the transfer will be cancelled and Scheme will notify the Payee and Payer DFSPs of this. + +- Payer and Payee DFSPs are required: + + - To notify their customers of the status of a transfer on a timely basis + + - To immediately debit and credit the Transaction Accounts of their customers upon fulfillment of the Transfer + + - To release any reserved funds immediately if a Transfer has been refused or cancelled + +### 4.3 Request to Pay + +_This section has not yet been written._ + +## 5. The Settlement Service + +This document presents a template for the settlement processes both for transfers and for scheme fees. There are multiple possible approaches to settlement, which are discussed in the "Key Choices" document that is part of this project. The template below covers two models: net settlement and continuous gross settlement. Mojaloop reference code supports a number of different settlement models, including these. + +### 5.1 Transfer Settlement + +#### 5.1.1 Description of the Transfer Settlement Service + +- Transfer Settlement is the means by which DFSPs settle their financial obligations to each other. There are five processes to Transfer Settlement: the Ledger Process, the Net Debit Cap Process, the Transfer Approval Process, the Settlement Posting Process and +the Settlement Account Management Process. + +- \[_Net settlement option_\] DFSPs are required to open a Settlement Bank account with the Scheme Settlement Bank. \[_Continuous gross settlement option_\] DFSPs are required to become joint owners of the Scheme Pooled Settlement bank account at the Scheme Settlement Bank, and to use or open such other individual bank accounts at the Scheme Settlement Bank as necessary to transfer funds into and out of the Scheme Pooled Settlement bank account. + +#### 5.1.2 The Platform Ledger + +- The Platform is responsible for maintaining a DFSP Position Ledger for each DFSP. This operation runs on a continual basis. \[_Continuous gross settlement option_\] The DFSP Position Ledger of each DFSP, less any provisional entries, represents the ownership share of that DFSP in the Scheme Pooled Settlement Bank Account. + +- The Position Ledger records: + + - All Fulfilled Transfer as debits to the Payer DFSP's ledger and credits to the Payee DFSP's ledger + + - All Transfer Requests as provisional debits to the Payer DFSP's ledger. These provisional debits are removed when the Transfer is Fulfilled, refused by the Payee DFSP, or expires. + + - \[_Net settlement option only_\] Settlement Entries delivered to and accepted by the Scheme Settlement Bank for that DFSP. + + - \[_Continuous gross settlement option only_\] Transfers into and out of the Scheme Pooled Settlement Bank account made by DFSPs. + +- The DFSP Ledger Position is the sum of all of the items listed above. This is used in the Transfer Approval Process. + +#### 5.1.3 Net Debit Cap Process + +- The Net Debit Cap for a DFSP is a value that the Platform uses during the Transfer Approval Process. The Net Debit for a DFSP is the sum of: + + - \[_Net Settlement Option only_\] A value set by the scheme that is intended to represent the funds the DFSP has available in its Settlement Bank Account + +Note the scheme may be able to automate the calculation of value described above, or it may choose to manually input this into the Platform Operator section of the Scheme Portal. + +- The Scheme Margin for that DFSP. This is a value, determined by the Scheme, that is specific to a given DFSP. This value may be a percentage of the DFSP Ledger Position or it may be an absolute value. The Scheme may change the Scheme Margin for any DFSP at its discretion. It may have the effect of either increasing or decreasing a DFSP's ability to execute transactions. + +- The DFSP Discretionary Margin. This is a value, determined by an individual DFSP, which lowers the absolute value of the Net Debit Cap. The DFSP Discretionary Margin is set within allowable parameters defined by the Scheme. This has the effect of decreasing the DFSP's ability to execute transactions. + +#### 5.1.4 Transfer Approval Process + +- Transfer Approval. When the Platform receives a Transfer Request from a Payer DFSP, the Platform will approve or reject the request based on a comparison of the amount of the requested transfer to the Payer DFSP's Current Ledger Position less the Payer DFSP's Net Debit Cap. + +- If the requested transfer is less this sum, the Platform will forward the request to the Payee DFSP. If it is more than the value of the Net Debit Cap, the Platform will reject the request and return it to the Payer DFSP. + +#### 5.1.5 Settlement Posting Process + +- \[_Net settlement option only_\] The scheme will define the parameters of the Settlement Windows used for the scheme; this will include the frequency of windows or other parameters (value limits, etc.) chosen for defining settlement windows. + +- \[_Net settlement option only_\] At the end of each defined settlement window, the Platform will calculate the net settlement position of every DFSP: this position is the balance in the DFSP Position Ledger. These balances become the Settlement Entries for that window. + +- \[_Net settlement option only_\] The Platform will send Settlement Entries for each DFSP to the scheme-chosen Settlement Bank + +- \[_Net settlement option only_\] The Settlement Bank will post Settlement Entries to the Settlement Bank Account of each DFSP, and send confirmation to the Platform of the completion of this process. + +Scheme rules will need to account for provisions and procedures in the event of a failure of the process described above. + +#### 5.1.6 Settlement Account Management Process + +- \[_Net settlement option_\] DFSPs may add funds to their Scheme Settlement Bank Account at their discretion. The Scheme will provide instructions on how to do this. \[_Continuous Gross settlement option_\] DFSPs may transfer funds into the Scheme Pooled Settlement Bank Account at their discretion. The Scheme will provide instruction on how to do this. + +- \[_Continuous Gross Settlement option only_\] The Scheme will provide and end-of-day report to DFSPs showing their share of ownership in the Scheme Pooled Settlement Bank Account. + +- DFSPs may request withdrawal of funds from their \[_Net settlement option_\] Settlement Bank Account through the Scheme Portal \[_Continuous gross settlement option_\] DFSPs may request withdrawal of funds from the Scheme Pooled Settlement Bank Account through the Scheme Portal. The scheme will review the requested withdrawal, and, if approved, execute the transfer on behalf of the DFSP. The purpose of this review is to ensure that a DFSP's share of the Settlement Bank Account is sufficient to support Transfers in process: this approval will not be unreasonably denied. + +#### 5.1.7 Scheme Settlement Reporting + +- The scheme will provide, through the Scheme DFSP Portal, information for DFSPs which includes for each DFSP: + + - The current Net Debit Cap and its components + + - The current Ledger Position and its components, including Fulfilled Transfers for all DFPSs and Provisional Transfers for Payer DFSPs + + - Alerts at certain levels of the Current Ledger Position: these levels to be determined by the DFSPS and/or the Scheme from time to time + +- Tools to enable DFSPs to forecast their anticipated transfer volume based on historical data + +### 5.2 Fee Settlement: Processing Fees + +This section is not yet written. + +### 5.3 Fee Settlement: Interchange Fees + +This section is not yet written. + +## 6. The Scheme Management Service + +::: tip NOTE +There is a parallel Platform Operator Service that is necessary for the operation of the platform which is not described in this document. +::: + +### 6.1 Description of the Scheme Management Service + +- The Scheme Management Service is provided by the Scheme to assist DFSPs in their use of Scheme Services. Many of these functions are provided through the Scheme Portal, which is made available to Scheme DFSPs. + +- The following processes are part of the Scheme Management Service: + +### 6.2 The Registration Process + +- The Registration Process enables DFSP application for participation and for operational and technical on-boarding. It covers the following areas: + + - Forms and processes for DFSP application for Participation in Scheme. + + - Forms and processes for obtaining digital certificates and digital signatures for use with the Platform. + + - Processes for downloading Scheme-provided software artifacts including SDKs and APIs. + + - Processes for testing technical readiness to access the Platform and Services. + + - Processes for receiving Scheme approval and certification for accessing the Platform and Services. + +### 6.3 DFSP Customer Service + +- The scheme will provide both an online and a telephone help desk for DFSPs. + +- The Scheme Portal will provide means by which DFSPs can designate Portal administrators and users, and update DFSP Profile information. + +### 6.4 Scheme System Management + +- The scheme will provide, through the Scheme Portal, means by which DFSPs can see their current Position Ledger, their Net Debit Cap, and their recent and historical activity with Scheme. + +- The scheme will provide, through the Scheme Portal, means by which DFSPs can use historical data, including their Positions and Net Debit Cap histories, to forecast upcoming volumes and required settlement funding levels. + +- The scheme will provide means by which DFSPs can obtain updates to software artifacts that they have previously downloaded. + +- The scheme will provide, through the Scheme Portal, means by which DFSPs can request a withdrawal from their share of the Scheme Settlement Bank Account. + +- The scheme will provide, through the Scheme Portal, means by which DFSPs can view their share of the balance in the Scheme Settlement Bank Account. + +## 7. The Fraud Management Service + +_This section has not yet been written, but is expected to include the +following sections:_ + +1. _Description of the Fraud Management Utility — Purpose and Scope_ + +2. _The Shared Transaction Database_ + +3. _Fraud Categorization Scheme_ + +4. _Reporting of Known Bad Actors or Transactions_ + +5. _Anomaly and Fraud Detection Algorithms and Processes_ + +6. _DFSP Reporting_ + +7. _Real-time Transaction Interception Options_ + +## 8. Appendix: Scheme Supported Use Cases and System Parameters + +_This is the same table as appears in the Business Rules document, but it has added the systemic codes necessary for the Platform to recognize a transaction as belonging to a given use case or secondary use case. A scheme would only define Secondary Use Cases if it wanted to write rules and/or specify fees that are unique to that Secondary Use Case._ + +_This table is an example of a table of Use Cases and Secondary Use Cases that a scheme might support._ + +| Use Case Code | Use Case | Secondary User Case | Required Data Elements | Other Methods of Use Case Determination | +| :--- | :----- | :--------- | :-------------------------- | :------------------------------------------- | +| 1.0 | P2P | Person to Person | API Setting
Scenario=Transfer

Initiator = Payer

Initiator Type = Consumer

Recipient Type = Consumer
| | +| 1.1 | P2P | Wallet to wallet | Transaction Account Type for Payer DFSP is Wallet and for Payee DFSP is Wallet | +| 1.2 | P2P | Bank to bank | Transaction Account Type for Payer DFSP is Bank and for Payee DFSP is Wallet | +| 1.3 | P2P | Wallet to bank | Transaction Account Type for Payer DFSP is Wallet and for Payee DFSP is Bank | +| 1.4 | P2P | Bank to Wallet | Transaction Account Type for Payer DFSP is Bank and for Payee DFSP is Wallet. | +| 2.0 | Bulk Payment | | API Settings
Scenario=Transfer

Initiator = Payer

Recipient Type = Consumer
| +| 2.1 | B2P | Bank to bank | Initiator Type = Business | +| 2.2 | G2P | Government to Person | Initiator Type = Government | +| 3.0 | P2B | Person to Business | API Settings
Scenario=Transfer

Initiator = Payer

Initiator Type = Consumer

Recipient Type = Business
| +| 3.1 | P2B | Till Number Purchase | Initiator Type = Device | | +| 3.2 | P2B | QR code Purchase | tbd | | +| 3.3 | P2B | Online Purchase | Merchant ID Code = tbd | | +| 3.4 | P2B | Bill Payment | | tbd: a data element in the Quote Request will include the Payer’s account number at the biller | +| 3.5 | P2B | Person to Business - Other | | | +| 4.0 | P2G | | API Settings
Scenario=Transfer

Initiator = Payer

Recipient Type = Government
| +| 4.1 | P2G | Person to Government | | | +| 4.1 | P2G | Till Number Purchase | Initiator Type = Device | | +| 4.2 | P2G | QR code Purchase | tbd | | +| 4.3 | P2G | Online Purchase | Merchant ID Code = tbd | | +| 4.4 | P2G | Bill Payment | | tbd: a data element in the Quote Request will include the Payer’s account number at the biller | + +## 9. Appendix: Merchant Category Codes + +_The scheme will want to specify codes to recognize the type of merchant being paid. The term "merchant" here is used broadly to include all types of non-consumer payments acceptors. A merchant category code scheme might want to recognize industries, domains (in-person stores vs remote or online) and/or merchant size._ diff --git a/docs/adoption/Scheme/scheme-business-rules.md b/docs/adoption/Scheme/scheme-business-rules.md new file mode 100644 index 000000000..cd76ddded --- /dev/null +++ b/docs/adoption/Scheme/scheme-business-rules.md @@ -0,0 +1,543 @@ +# Scheme Business Rules Template + +- Version: 4.0 + - Author: Carol Coye Benson (Glenbrook) + - Date: October 2019 + - Description: + +--- + +## **About the Mojaloop Community Business Document Project** + +This document is part of the Mojaloop Community Business Document Project. The project is intended to support entities (countries, regions, associations of providers or commercial enterprises) implementing new payments systems using Mojaloop code. These entities will also need write Business Rules that participants in the system will follow. + +The Mojaloop Community Business Document Project provides templates for Business Rules and related documents. There are many choices involved in implementing a new payment system: the templates show some of the choices and, where appropriate, commentary is provided on how the particular choice is related to the goals of a Level One aligned system. + +The following documents are part of the project: + +- Scheme Key Choices + +- Scheme Participation Agreement Template + +- Scheme Business Rules Template + +- Platform Operating Guideline Template + +- Exception Management Operating Guideline Template + +- Uniform Glossary + +## **Introduction** + +Payments Schemes around the world are in the process of implementation, or considering implementation, of Mojaloop-based payments systems. Mojaloop is open-source software for financial services companies, government regulators, and others taking on the challenges of interoperability and financial inclusion. The Bill & Melinda Gates Foundation has provided funding and support for Mojaloop through The Level One Project, a vision for digital financial markets based on principles of interoperability, collaboration, and inclusion. + +Schemes implementing Mojaloop will need to write Business Rules which govern the rights and responsibilities of participants in the system. This document provides a template for those Business Rules. The template is structured as a detailed outline: the actual wording of rules will be determined by implementing Schemes and the jurisdictions within which they operate. In many parts of the document, we simply suggest a topic which a Scheme might want to consider writing a rule about: again, the specifics of the rule will vary by Scheme. + +Before Business Rules are written, Schemes need to make major business decisions about how the system and its ecosystem partners will work. These decisions are described in a separate document within the Mojaloop Community Business Document Project, "Scheme Key Choices". People are encouraged to read that document first. + +Scheme Business Rules Template + +## **Table of Contents** + +[1 - About These Scheme Business Rules](#_1-about-these-scheme-business-rules) + +[2 - Scheme Goals](#_2-scheme-goals) + +[3 - Participation in Scheme](#_3-participation-in-scheme) + +[4 - Scheme Business Rules](#_4-scheme-business-rules) + +[5 - Responsibilities and Obligations of the Scheme](#_5-responsibilities-and-obligations-of-the-scheme) + +[6 - Participant Responsibilities and Obligations of Participants](#_6-participant-responsibilities-and-obligations-of-participants) + +[7 - Liability - Allocation of Responsibilities](#_7-liability-allocation-of-responsibilities) + +[8 - Security, Risk Management, and Data Confidentiality](#_8-security-risk-management-and-data-confidentiality) + +[9 - Scheme Platform and Services](#_9-scheme-platform-and-services) + +[10 - Exception Management](#_10-exception-management) + +[11 - Appendix: Associated Documents](#_11-appendix-associated-documents) + +[12 - Appendix: Onboarding and Exit Processes](#_12-appendix-onboarding-and-exit-processes) + +[13 - Appendix: Scheme Services](#_13-appendix-scheme-services) + +[14 - Appendix: Scheme Supported Use Cases](#_14-appendix-scheme-supported-use-cases) + +[15 - Appendix: Scheme Fee Schedule](#_15-appendix-scheme-fee-schedule) + +[16 - Appendix: Risk Management, Security, Privacy, and Service Standards](#_16-appendix-risk-management-security-privacy-and-service-standards) + +## **A Guide to This Document** + +Section Headings and bulleted entries underneath section headings are actual proposed wording, or suggested sections for a rules document. Text in italics are comments which can be used when a scheme drafts the actual language of a rules document. + +## 1. About These Scheme Business Rules + +### 1.1 These are the Scheme Business Rules + +::: tip NOTE +The Mojaloop software can be used for bilateral exchanges among DFSPs, as well as within a Scheme structure that uses a switch. This document assumes the latter; that the Scheme is either providing, hiring, or otherwise arranging that interoperable transactions are exchanged through a switch. Some of the concepts in these rules apply only to this configuration; others would be useful in bilateral agreements as well. +::: + +### 1.2 Scheme Ownership + +
    Who owns the scheme, what opportunities exist for ownership participation. Reference to other documents (charter, by-laws, etc.)
+ +### 1.3 Defined Associated Documents + +- These rules include the Associated Documents listed in an Appendix to these rules. Associated Documents are part of, and have the force of, the Operating Rules. + +
    Associated Documents should include the Platform Operating Guideline and the Uniform Glossary. This does not include various technical documents that may be referenced in the Business Rules or the Platform Operating Guideline.
+ +### 1.4 Scheme Business Rules are Binding on Participants + +
    This repeats the provision in the Scheme Participation Agreement. Note that Scheme Business Rules are only binding on the DFSPs that participate in the Scheme. The Scheme may write rules that require certain provisions of these rules be passed on to Participant customers (for example, merchants) or partners (for example, processors) - but this is an obligation of the Participant to the Scheme, not the other parties.
+ +### 1.5 Rules May Be Amended + +
    Details of amendment process are specified elsewhere.
+ +### 1.6 Terms are Defined in Uniform Glossary + +
    The glossary is a separate document, rather than be internal to the Business Rules document. This is to ensure consistency in terminology as the service evolves and the Platform Operating Guideline changes.
+ +## 2. Scheme Goals + +
    This is a section that allows a Scheme to state the objectives of the Scheme. We suggest support of interoperable financial transactions, financial inclusion, and gender equality. This is also an opportunity to reference support for the Level One Project Design Principles, a national or regional payments strategy (or digital economy strategy), or a Scheme-specific set of design principles.
+ +## 3. Participation in Scheme + +### 3.1 Participation Eligibility + +- Eligibility Criteria + +
    A statement as to which types of institutions are eligible to apply to be a participant in the Scheme. The Level One design principle is that any licensed provider of transaction accounts in a jurisdiction covered by the Scheme should be eligible to apply
+ +- Approval Criteria + +
    Scheme provisions for acceptance of applications, including high level statements of required information from applicant, such as demonstration of a sustainable ability to meet financial obligations and compliance obligations. The actual application process is in an Appendix to these Rules. The technical certification requirements can be listed in the Platform Operating Guideline.
+ +### 3.2 Licensing + +
    This concept may or may not apply when the Scheme operator is a government entity. If the concept to licensing is not included in the rules, there needs to be a provision in "Participation Eligibility" section with respect to terminating a participant.
+ +- A Participant is granted a License to participate in the Scheme and to use the Scheme Property in accordance with the Scheme Business Rules. + +- A Participant may use Scheme Property only in accordance with the Scheme Business Rules. Licenses will limit use of Scheme Property to the Participant's provision of services in connection with the Scheme and according to the Rules. + +- Licenses will not be exclusive. + +### 3.3 Tiered Access + +
    Schemes may choose to allow some applicants to access join the Scheme as indirect participants. This section specifies the conditions for this. Some Schemes separately enable technical indirect participation and settlement indirect participation.
+ +
    If this is allowed, defined terms (such as Sponsor Bank and Indirect Participant) are required. This section should clearly show what the obligations of each party are; this can refer to the obligation sections appearing later.
+ +### 3.4 Departure from Participation + +
    Provisions for Scheme suspension or termination of a Participant's participation in the Scheme. The Scheme may suspend, limit or disqualify a Participant from participating in the Scheme if it determines that the Participant's inability to observe a Rule unduly burdens the Scheme or other Participants or poses undue risks to the integrity of the Scheme or the reputation of the Scheme
+ +
    Provisions for Participants to terminate their participation in the Scheme
+ +## 4. Scheme Business Rules + +### 4.1 Scope of the Scheme Business Rules + +- These Rules apply to each Participant and govern the rights and responsibilities of Participants and of the Scheme. + +- These Rules may be superseded to the extent that they conflict with any Applicable Laws. Nothing in these Rules shall be applied to require the Scheme or any Participant to violate Applicable Law. + +- All matters regarding interpretation of the Rules and all disputes arising in connection with participation in the Scheme will be subject to the laws of \[xxxx\] + +
    Provisions should be made for resolution of disputes among Participants or between Participants and the Scheme.
+ +### 4.2 Changes to the Scheme Business Rules + +- Participants may from time to time provide suggestions or requests for modification of the Rules. + +- Participant suggestions for modifications to the Rules may be used by the Scheme or by other Participants in connection with the Scheme without compensation or attribution to the Participant who makes the suggestion or request. + +- Changes to the Rules will be made according to a consultative procedure: + +- A Participant(s) or the Scheme may propose a change to the Scheme Business Rules. + +- The Scheme will publish proposals to all Participants and request comments and suggestions on these; all comments received will be published to all participants. + +- The Scheme may include with the publication of a proposed change its independently determined suggestion for the wording of a change in the Rules, + +
    Scheme should have a defined process for adopting changes, which may include Participant voting or decision by the Scheme. If there is voting, rules here should specify the parameters.
+ +- The Scheme may grant variances to the Rules upon application from Participants. + +- Provisions for urgent changes may be made by the Scheme to meet risks or regulatory requirements. + +## 5. Responsibilities and Obligations of the Scheme + +### 5.1 Defining and Providing Scheme Services + +- The Scheme defines the set of Scheme Services that are provided to Participants. The defined list of Scheme Services is shown in an Appendix to these Rules. + +
    Scheme Services
+ +- The Scheme specifies how Scheme Services are provided to Participants - they may be operated by the Scheme entity, by another entity under contract to the Scheme, or there may be some other arrangement. This section gives the Scheme the right to define new services, change existing services, etc. + +- The Scheme may define service level standards for itself, and for participants in using these services + +- For outsourced Platform services, the Scheme specifies services to be provided. The Scheme may specify the service level agreements for providers of these services + +- For the Scheme Settlement Service, the Scheme selects and contracts with a Settlement Bank(s) for inter-Participant Settlement. + +- The Scheme establishes a Transaction Value Limit which sets the maximum value of any Transfer made through the Scheme Platform. DFSPs may set lower values for their customers. + +- The Scheme should consider if it will guaranty to the Payee DFSP any Fulfilled Transfer made in accordance with these Rules + +
    The Scheme should consider if it will guaranty to the Payee DFSP any Fulfilled Transfer made in accordance with these Rules.
+ +### 5.2 Writing, Updating, and Maintaining the Rules + +- The Scheme writes, updates, and maintains the Business Rules. + +- The Scheme is responsible for informing Participants of any changes to the Rules, all fees, policies that may impact Participants' use of the Scheme, or any other important and relevant information. + +- The Scheme is responsible for establishing a policy, and communicating this to Participants, for enforcement of the Rules; + +- The Scheme is responsible for establishing policies with respect to granting variances to the Rules to Participants, + +### 5.3 Other Scheme Responsibilities + +- The Scheme administers Participant on-boarding and exit processes. These processes are listed in an Appendix to these rules. + +- The Scheme monitors the ongoing eligibility of Participants under the requirements established for Participation + +- The Scheme defines a set of Use Cases and Secondary Use Cases. These are listed in an Appendix to these rules + +- The Scheme establishes the Fee Schedule and defines the processes by which Fees are collected. The Fee Schedule is in an Appendix to these rules + +- The Scheme sets the Scheme Brand and establishes guidelines for its use. These guidelines appear in an Associated Document. + +- The Scheme measures the progress of the Scheme and its Participants + +- The Scheme defines policies and procedures for Security, Risk Management, and Data Confidentiality for the Scheme and its Participants. + +- The Scheme defines policies and procedures for the management of Transaction Exceptions. + +- The Scheme engages in activities to promote and encourage the adoption and usage of the Scheme. + +- The Scheme plans for long-term enhancement and expansion of the Platform to meet evolving market needs and opportunities in the advancement of the Scheme's goals. + +## 6. Participant Responsibilities and Obligations of Participants + +- Participants are obliged to comply with these Business Rules and with the Associated Documents to these Rules. + +- Participants must comply with all Applicable Law with respect to their participation in the Scheme within the territories in which they operate and within which they use Scheme Services. The Scheme assumes no responsibility for Participants' compliance with Applicable Law. + +- Participants are required to permit use and disclosure of Personal Information as required by these Business Rules and to provide disclosures to their Customers and obtain consents where necessary regarding such use and disclosure of Personal Information as required by Applicable Law. + +- Participants agree to pay fees to the Scheme and to other Participants as specified in these rules. + +- Participants will adhere to Scheme brand specifications as specified in these rules. + +- Participants will use Scheme Services as specified in these rules. + +
    Schemes will need to consider if they want to: 1) require the use of the scheme for scheme-eligible transactions (assuming the rules authority to do this); 2) require the use of the scheme platform for "on-us" transactions (would require separate, probably zero processing fee for such transactions); if "on-us" transactions don't go through the platform, if the scheme wants to require reporting of "on-us" transactions to the scheme, for use with a fraud utility.
+ +- All transfers made using the Scheme Brand or described as being made with the Scheme will be made using Scheme Services. + +
    Schemes will need to consider if they want to state the above rule. Some Schemes may want Participants to use the Scheme brand for on-us transactions which do not use Scheme Services. This could be worded to say "all interoperable transfers"
+ +- _\[Net Settlement Option\]_ Participants will open a Settlement Bank Account with the scheme-specified Settlement Bank, or make available an existing account for these purposes, as allowed by the Scheme. _\[Continuous Gross Settlement Option\]_ Participants will become a joint owner of the Scheme Pooled Settlement Account and sign Scheme Settlement Bank Account Agreement to that effect. Participants will transfer money into and out of that outcome from their existing reserve, clearing, or trust accounts at the Scheme Settlement Bank, as Scheme Operating Guidelines specify. + +- Participants will share information with the Scheme as strictly necessary for the operation of the Scheme, including for due diligence, technical onboarding, configuration, transactions management and other purposes as specified in the Rules. + +- Participants will be required by the Scheme to meet Security, Risk Management and Data Confidentiality standards specified by the Scheme. + +- Participants will provide adequate customer service to their customers in connection with the Scheme. + +- Participants must exclude customers from use of the Scheme upon request by the Scheme when the Scheme reasonably determines that a customer poses risk to the Scheme, which may include financial, legal, security, reputational risk or any other risk. + +- Participants will not, and will not permit customers, to use the Scheme for illegal purposes, including illegal goods or services; illegal payments, such as bribery, money laundering or financing of terrorism; poaching or trafficking in protected animal species or products. + +
    Schemes can consider if they want to specify that Participants contractually prohibit customers from using Scheme Services for illegal purposes and will discontinue Scheme Services for customers who they know, or suspect are using Scheme Services to initiate or receive transfers for illegal purposes
+ +### 6.1 Responsibilities and Obligations of Participants as Payer DFSPs + +- A Participant who originates a Quote Request or a Transfer Request is acting as a Payer Participant under these Rules. + +- A Participant may initiate a Transaction on behalf of its Payer for any Use Case or Secondary Use Case supported by the Scheme. + +- A Payer Participant is obligated to settle a Transfer upon submission of a Transfer Request, unless such Transfer Request is refused by the Payee DFSP or expires without fulfillment. + +- The Payer Participant warrants upon submission of each Transfer Request, that the Transfer is coming from an account that is KYC- and AML-compliant and is executed in accordance Applicable Law, and that the Payer has been provided all disclosure and has provided all consents necessary to conduct the Transfer in accordance with these Business Rules and under Applicable Law. + +- The Payer Participant warrants upon submission of a Request for Transfer, that the Transfer Request has been authorized by their Payer, and that their communications with their Payer have been properly authenticated in accordance with these Business Rules and Applicable Law. + +- The Payer Participant acknowledges that the Platform will reject a Transfer Request if the proposed Transfer would violate these Business Rules, such as exceeding the Payer Participant's Net Debit Cap. + +### 6.2 Responsibilities and Obligations of Participants as Payee DFSPs + +- A Participant who receives and responds to a Quote Request or a + Transfer Request is acting as a Payee Participant under these Rules. + +- A Payee Participant who receives a Quote Request is required to respond, in the absence of technical issues, with a Quote Response if: + + - The Payee's Transaction Account with the Payee Participant is in good standing and capable of receiving, at that point in time, the Transfer Amount and + + - Acceptance of the Transfer will not put the Payee account into a status not permitted by Applicable Law or the Participant's account policies and agreements. + + - The Payee Participant affirms, upon initiation of a Quote Response other than an error response, that the Payee account has been Validated — it is open, in good standing, and able to accept the proposed Transfer Amount at that point in time. + +- The Payee Participant affirms, upon initiation of a Quote Response other than an error response, that a Transfer to the designated account complies at that point in time with applicable AML/CTF and KYC requirements. + +- A Payee Participant who receives a Transfer Request is required, in the absence of technical issues, to respond with a Transfer Response with the Transaction State "Committed" if: + + - They have received a Quote Request and responded with a Quote Response for the Transaction and + + - The Quote Response has not yet expired + + - The Payee's Transaction Account with the Payee Participant is in good standing and capable of receiving, at that point in time, the Transfer Amount and + + - Acceptance of the Transfer will not put the Payee account into a status not permitted by Applicable Law or the Participant's account policies and agreements and + + - The Transfer Request on the Transaction has not expired. + +- A Payee Participant who sends a Transfer Response with a Transaction State "Committed" must post that Transfer to the Payee's account within \[X time\]. + +- A Payee Participant who receives a Transfer Request which does not meet the above criteria is required to respond with a Transfer Response with the Transaction State "Aborted". + +- The Payee Participant must affirm, upon submission of each Transfer Response with a Transaction State "Committed", that the Transfer is being credited to an account that is AML-compliant and is executed in accordance with any account volume limitations, or any other regulation that apply in the territories in which they operate, and that the Payee has been provided all disclosure and has provided all consents necessary to conduct the Transfer in accordance with the Rules and under Applicable Law. + +## 7. Liability - Allocation of Responsibilities + +- Each Participant is responsible for errors made by them, and for fraud committed by its employees or contractors, in accordance with Applicable Law. + +- The Scheme will not be held responsible for, and each Participant will indemnify and defend the Scheme from claims arising from actions or omissions of the Participants, of their Customers or contractors. + +- The Scheme may elect to defend any claim in circumstances where the Scheme determines that the resolution of a claim may have an adverse impact on the finances, operations or reputation of the Scheme. + +- The Scheme shall be held responsible for its own errors in processing Transfers within limits prescribed by the Rules. + +- The Scheme will compensate Participants for costs of funds to the extent that a Participant is wrongly deprived of funds for a period of time as a result of errors made by the Scheme. + +- Each Participant is responsible for the actions and omissions of any contractors engaged by them to provide services in connection with the Scheme to the same extent as if committed by the Participant. + +- The Scheme may allocate responsibility among Participants for consequences of unauthorized use of or access to data by a Participant or for a Security Incident suffered by one Participant that impacts other Participants or the Scheme in accordance with principles stated in the Rules. + +## 8. Security, Risk Management, and Data Confidentiality + +### 8.1 Confidentiality and Protection of Personal Information + +- Confidential Information of the Scheme that is disclosed to Participants will be held in confidence by Participants and will be used only for the purposes permitted by the Rules. Scheme Confidential Information may include proprietary technology and other matters designated by the Scheme. + +- Transaction data will not be owned by the Scheme and will be owned by a Participant as it relates to its Customer's Transactions. + +- The confidentiality of Transaction data and any Personal Information processed in the Platform will be protected by the Scheme and Participants according to Applicable Law. + +- Statistics or data which identify a Participant or from which the Participant may be identified will not be disclosed to other Participants. The Scheme may prepare for internal use and disclose to third parties for promotional purposes statistics based on aggregate, anonymized data as permitted by Applicable Law. + +- The Scheme will make disclosures of Confidential Information to comply with Applicable Law or the directive of a Regulatory Authority. + +- The Scheme will protect Personal Information in its possession or under its control from misuse and otherwise treat such information in accordance with Applicable Law protecting privacy of individuals. + +- The Scheme will maintain industry leading security measures to protect information from unauthorized access and use. + +- Participants will notify the Scheme and acknowledge that the Scheme may notify other Participants, of any Security Incident in the systems or premises of the Participant, its affiliated entities or any third-party vendor engaged by the Participant to provide services in support of the Participant's participation in the Scheme. + +- The Scheme may conduct investigations into Security Incidents. Participants will cooperate fully and promptly with the investigation. Such investigations will be at the expense of the affected Participant. + +- The Scheme may require a Participant to conduct investigations of Security Incidents and may require that such investigations be conducted by qualified independent security auditors acceptable to the Scheme. + +- The Scheme may impose conditions of continued participation on the affected Participant regarding remedy of the causes of the Security Incident and ongoing security measures. + +- The investigation and report, as well as remedies that may be required will be held confidential to the extent permitted by Applicable Law. + +### 8.2 Risk Management Policies + +
    This section assumes that the development of risk management policies by the Scheme and its participants will be evolving. This section contemplates that some of these policies will (eventually) be in the Rules; others will not.
+ +- Risk management policies and procedures may be stated in the Rules, in Associated Documents, or in other written policy documents created by the Scheme and distributed to Participants + +- Risk management policies and procedures will include fiscal soundness, system integrity, compliance with Applicable Law, particularly as to Anti-Money Laundering/Combatting Terrorism Financing measures, privacy of personal information and data security + +- Risk management functions include procedures applicable to Participants for monitoring of risks, including reporting requirements and audits + +### 8.3 Business Continuity + +- Provisions to ensure business continuity on the part of the Scheme, its vendors, and Participants. + +## 9. Scheme Platform and Services + +- The Scheme defines the set of Scheme Services which Participants access to use the system. These are listed in an Appendix to this document. The core Scheme Services necessary for inter-operability are considered to be the Scheme Platform. + +- Technical and operational details on the use of Scheme Services, including the Scheme Platform, are provided in Associated Documents. This list of Associated Documents is an Appendix to this document. + +## 10. Exception Management + +- Problems may occur during execution of a Transaction that result in exception cases, which may require or may be facilitated by inter-Participant communication. Exception cases may include errors on the part of any party, fraud, or other service anomalies. + +- The Scheme will create and maintain protocols by which Participants may determine the type of exception and suggested or required actions on the part of Participants to resolve the exception. These protocols are contained in an Associated Document. + +- The following principles govern exception management: + + - Participants involved will cooperate in good faith. + + - Each Participant agrees that they will not contact the other Participant's customer directly during the process of dispute resolution. + + - Participants agree to cooperate with each other and with the Scheme to share information about suspected or confirmed fraud. + +### 10.1 Transaction Irrevocability + +- Participants agree that Fulfilled Transfers executed via the Platform are irrevocable. A Transfer which has been credited to a Payee's account as a result of a Scheme Transfer may not be revoked without the consent of the Payee. + +- The Scheme may instruct a Participant to initiate a corrective transaction between Participants in an amount determined by the Scheme to be necessary to correct errors caused by Payer DFSP, the Payee DFSP, or the Scheme.  The conditions under which such corrective transactions may be made are specified by the Rules.  + +- Errors on the part of the Payee DFSP, the Payer DFSP, or the Scheme which result in erroneous or duplicate posting of a Transfer to a Payee's account may be corrected by the Payee Participant, as long as the instructions in the Fulfilled Transfer are not revoked or altered in any way. + +## 11. Appendix: Associated Documents + +- Uniform Glossary + +- Platform Operating Guideline + +- Brand Guideline + +- Exception Management Protocols + +## 12. Appendix: Onboarding and Exit Processes + +## 13. Appendix: Scheme Services + +Scheme Services include: + +- Scheme Platform, which includes + + - The Transfer Service + + - The Directory Service + + - The Settlement Service + + - Scheme Management Service + +- Other Shared Services + + - Fraud Management Utility + +## 14. Appendix: Scheme Supported Use Cases + +
    Use Cases are defined by what type of customer is paying what other type of customer, and by the purpose of the payment. Secondary use cases are sub-sets of Use Cases and are used to demonstrate more finite differences in transfers. All transfers made via Scheme Services may be categorized by one, and only one, Use Case and Secondary Use Case.
+ +
    The Use Case and Secondary Use Case of a Transaction may require different operational and technical details to apply, as specified in the Platform Operating Guideline; different interchange fees to apply, as specified in an Appendix to these rules; different requirements for exception management procedures to apply, as specified in an Associated Document to these rules
+ +
    All Scheme Supported Use Cases and Secondary Use Case are defined by attributes of the transactions, which are specified in the Platform Operating Guide.
+ +
    The following is an example of a table of Use Cases and Secondary Use Cases that a scheme might support.
+ +
    A scheme would only define Secondary Use Cases if it wanted to write rules and/or specify fees that are unique to that Secondary Use Case
+ +| | Use Case | Secondary Use Case | +| :---: | :--------: | :-------------------------- | +| 1.0 | P2P | Person to Person | +| 1.1 | P2P | Wallet to wallet | +| 1.2 | P2P | Bank to bank | +| 1.3 | P2P | Wallet to bank | +| 1.4 | P2P | Bank to Wallet | +| 2.0 | Bulk Payment | | +| 2.1 | B2P | Business to Person | +| 2.2 | G2P | Government to Person | +| 3.0 | P2B | Person to Business | +| 3.1 | P2B | Till Number Purchase | +| 3.2 | P2B | QR code Purchase | +| 3.3 | P2B | Online Purchase | +| 3.4 | P2B | Bill Payment | +| 3.5 | P2B | Person to Business - Other | +| 4.0 | P2G | | +| 4.1 | P2G | Person to Government | +| 4.1 | P2G | Till Number Purchase | +| 4.2 | P2G | QR code Purchase | +| 4.3 | P2G | Online Purchase | +| 4.4 | P2G | Bill Payment | + +## 15. Appendix: Scheme Fee Schedule + +1. Processing Fees + + - Processing fees are calculated by \[define\] + + - Processing fees apply to fulfilled transfers + + - Processing fees are charged to \[which party or parties\] + + - Processing fees for "on-us" transfers (where Payer and Payee DFSP are the same) \[are or are not charged\] + + - Processing fees will be calculated and billed to Participants \[define\] + + - Provision for how Participants will pay processing bills \[define\] + +2. Membership or Participation Fees + + - Membership or Participation Fees are charged to \[define\] + + - Specify basis, how collected, etc. + +3. Interchange Fees + + - Interchange fees are set by the Scheme + + - The amount of the fee and the direction (which Participant pays which) vary by Use Case and by Secondary Use Case. Some Use Cases and Secondary Use Cases will not have interchange. + + - \[Define how the platform will collect and disburse interchange: on a transaction basis or a periodic basis.\] + +## 16. Appendix: Risk Management, Security, Privacy, and Service Standards + +
    Schemes may or may not want to specify standards or require that Participants comply with other established standards. Schemes may furthermore specify different standards for different categories of Participants. The list below is given purely as an example.
+ +Participants must adhere to the following practices of service quality security, data privacy and customer service as they apply to a Participant in connection with the Scheme. + +- Participants will establish a risk management framework for identifying, assessing and controlling risks relative to their use of the Scheme. + +- Participants will ensure that the systems, applications and network that support the use of the Scheme are designed and developed securely. + +- Participants will implement processes to securely manage all systems and operations that support the use of the Scheme. + +- Participants will implement processes to ensure that systems used for the Scheme are secure from unauthorized intrusion or misuse. + +- Participants will implement processes to ensure the authentication + of their customers in creating and approving transactions that use + the Scheme. + +- Participants will develop effective business continuity and + contingency plans. + +- Participants will manage technical and business operations to allow + timely responses to API calls received from the Scheme Platform or + from other Participants via the Scheme Platform. + +- Participants will establish written agreements governing their + relationship with agents, processors, and other entities providing + outsourced services that pertain to the Scheme. + +- Participants will develop policies and processes for ongoing + management and oversight of staff, agents, processors, and other + entities providing outsourced services that pertain to the Scheme. + +- Participants will ensure that customers are provided with clear, + prominent, and timely information regarding fees and terms and + conditions with respect to services using the Scheme. + +- Participants will develop and publish customer service policies and + procedures with respect to services using the Scheme. + +- Participants will provide an appropriate mechanism for customers to + address questions and problems. Participants will specify how + disputes can be resolved if internal resolution fails. + +- Participants will comply with good practices and Applicable Laws + governing customer data privacy. + +- Participants will ensure that Customers are provided with clear, + prominent, and timely information regarding their data privacy + practices. diff --git a/docs/adoption/Scheme/scheme-key-choices.md b/docs/adoption/Scheme/scheme-key-choices.md new file mode 100644 index 000000000..1d4e3fe8e --- /dev/null +++ b/docs/adoption/Scheme/scheme-key-choices.md @@ -0,0 +1,408 @@ +# Scheme Key Choices + +- Version: 5.0 + - Author: Carol Coye Benson (Glenbrook) + - Date: October 2019 + - Description: + +--- + +## **About the Mojaloop Community Business Document Project** + +This document is part of the Mojaloop Community Business Document Project. The project is intended to support entities (countries, regions, associations of providers or commercial enterprises) implementing new payments systems using Mojaloop code. These entities will also need write Business Rules that participants in the system will follow. + +The Mojaloop Community Business Document Project provides templates for Business Rules and related documents. There are many choices involved in implementing a new payment system: the templates show some of the choices and, where appropriate, commentary is provided on how the particular choice is related to the goals of a Level One aligned system. + +The following documents are part of the project: + +- Scheme Key Choices + +- Scheme Participation Agreement Template + +- Scheme Business Rules Template + +- Platform Operating Guideline Template + +- Exception Management Operating Guideline Template + +- Uniform Glossary + +## **Introduction** + +Payments Schemes around the world are in the process of implementing, or considering implementation, of Mojaloop-based payments systems. Mojaloop is open-source software for financial services companies, government regulators, and others taking on the challenges of interoperability and financial inclusion. Mojaloop is based on the specification "Open API for FSP Interoperability Specification", which was developed to provide an open API specification for mobile money interoperability. + +The Bill & Melinda Gates Foundation has provided funding and support for Mojaloop. Mojaloop is open source reference code which demonstrates the principles of the Level One Project, a vision for digital financial markets based on principles of interoperability, collaboration, and inclusion. + +Schemes implementing Mojaloop will need to make a number of business choices about the design of the system. These choices, when made, will affect both the technical implementation of Mojaloop and the Business Rules which the Scheme will write, and which Participant DFSPs will agree to follow. This document describes and discusses some of the most significant of these choices. Where appropriate, recommendations for best practices are made to align with the Level One Project (L1P) Design Principles. + +Although this document is written as a contribution to the Mojaloop community, the issues described here are pertinent to any Level One aligned payments system, regardless of the technical implementation chosen. + +## **Choices Described in this Document** + +[1 - Choice: Ownership of Scheme](#_1-choice-ownership-of-scheme) + +[2 - Choice: Participation in the Scheme](#_2-choice-participation-in-the-scheme) + +[3 - Choice: Relationship of Scheme to Platform](#_3-choice-relationship-of-scheme-to-platform) + +[4 - Choice: Scope of Scheme Rules and Scheme Rules Authority](#_4-choice-scope-of-scheme-rules-and-scheme-rules-authority) + +[5 - Choice: Use Cases](#_5-choice-use-cases) + +[6 - Choice: QR Codes](#_6-choice-qr-codes) + +[7 - Choice: Payments Addressing](#_7-choice-payments-addressing) + +[8 - Choice: Interparticipant Settlement](#_8-choice-interparticipant-settlement) + +[9 - Choice: Tiered Access](#_9-choice-tiered-access) + +[10 - Choice: Scheme Fees and End User Pricing](#_10-choice-scheme-fees-and-end-user-pricing) + +[11 - Choice: Brand Management](#_11-choice-brand-management) + +[12 - Choice: Scheme Connections to Other Schemes](#_12-choice-scheme-connections-to-other-schemes) + +[13 - Choice: Scheme Use by Other FSPs](#_13-choice-scheme-use-by-other-fsps) + +[14 - Choice: Scheme Risk Management Standards](#_14-choice-scheme-risk-management-standards) + +[15 - Choice: Exception Management](#_15-choice-exception-management) + +## 1. Choice: Ownership of Scheme + +The Scheme is the entity that writes the rules for the payment system. As such, the scheme controls multiple aspects of the delivery of scheme services, including how the technical and operational platform will be delivered to participating DFSPs. Common models in for Scheme ownership in the payments industry include: + +- An association of participating DFSPs, with or without partial ownership by the Central bank + +- A Central Bank or other government entity + +- A commercial entity + +The association model maximizes DFSP control of the Scheme and may encourage DFSPs to join and use the scheme. A government or central-bank controlled scheme may make regulatory supervision of DFSPs more effective and may make decision-making simpler: a government body may be willing to make infrastructure decisions that are for the good for the ecosystem as a whole, rather than optimizing individual DFSP benefits. A commercial entity may be faster to implement a new system and may be more effective in some situations in creating a sustainable operating model. + +### 1.1 Level One Alignment — Scheme Ownership + +Any of these ownership structures can deliver on the goals of L1P and financial inclusion. The Level One Design Principles suggest "self-governance by DFSPs" (the first model) as a preferred design, based on a belief that participation in governance can increase DFSP commitment to the scheme. Other designs can work, however, as long as the Scheme and its members have some form of participatory governance and operate with transparency and open communications. + +The most important Level One principle is that the Scheme itself should operate on a "not for loss" (sustainable cost recovery) model. The latter is particularly important in order to deliver on the L1P goal of creating an ultra-low-cost payment system. This principle is predicated on the idea that DFSPs may, of course, operate on a for-profit basis in delivering payment services. The source of their revenues, however, may be primarily from \"[adjacencies](https://docs.gatesfoundation.org/documents/fighting%20poverty%20profitably%20full%20report.pdf)\" rather than fees related to the payment transaction itself. Note that the operating platform may be provided by a commercial entity, even if the Scheme itself is operated on a "not for loss" basis. This is discussed further below in "Choice: Relationship of Scheme to Platform". + +Many legacy bank payments systems worldwide operate on the association model. ACH systems and domestic debit card systems (such as the U.S. ACH and Canada's Interac system) use this model and deliver ultra-low processing costs to participating DFSPs. Some new mobile payments systems, such as India's UPI system and Peru's BIM system also use this model. + +Several countries provide services through the Central Bank: Mexico's SPEI model is notable here. Jordan's JoMoPay system started as a Central Bank system and has moved to the association model. + +The global card networks, notably Visa and MasterCard, started as association models and have moved to a commercial model. Many FinTechs, such as PayPal or WeChat Payments, operate closed-loop systems on a commercial model. + +## 2. Choice: Participation in the Scheme + +Mojaloop and L1P use the term "DFSP" (Digital Financial Services Provider) to mean any entity within the jurisdiction in which the payment system operates that is licensed in some manner to provide end-user transaction accounts which hold funds, and which can be used to make and receive payments. This definition includes bank, other depository financial institutions, and eMoney issuers (sometimes referred to as Mobile Money Operators). + +There are myriad other ecosystem participants who do not hold end-user transaction accounts: these include processors, aggregators, and some types of payments services providers. The relationship of these entities to the scheme and to DFSPs is discussed in [Choice: Scheme Use by Other FSPs](#_13-choice-scheme-use-by-other-fsps). + +The question of participation is twofold: first, which categories of DFSPs are supported by the Scheme, and secondly, what is the process by which DFSPs are allowed to participate. The term "open loop" is used to refer to a structure in which multiple DFSPs join and use the scheme to exchange transactions (interoperate). But an "open loop" scheme can either be one in which any DFSP in a supported category is eligible to join the scheme, or one in which participation is limited, and managed by invitation. An applicant DFSP may face certain eligibility criteria (size, financial health, etc.) before being admitted to the Scheme. + +The term "closed loop" is most often used to refer to a scheme which is not interoperable; in which the scheme entity has direct relationships with all end customers + +L1P is strongly in favor of open loop systems. Furthermore, L1P advocates for all licensed providers of transaction accounts to be eligible: in other words, both bank and eMoney Issuer categories should be included, and allowed to interoperate through the Scheme platform. + +There are a number of arguments which support this recommendation. The very concept of "financial inclusion" implies including previously excluded populations into the financial ecosystem of the country. In many countries, eMoney issuance or other structures have been approved by regulators to provide transaction accounts to populations that have not been able to be served economically by traditional banks. These eMoney issuers have frequently created closed-loop mobile wallets, and one of the goals of L1P and Mojaloop is to enable interoperability of these wallets. However, wallet holders need to pay not just other wallet holders, but merchants and other banked institutions, and banked individuals. Banked individuals and institutions also make payments to wallet holders. It makes sense that the same interoperable payment system should support both for efficiency reasons (why have multiple systems when a single system can connect all players?) and for economic reasons. + +The economic argument revolves around the nature of transactional processing systems: the more volume, the lower the unit cost. This principle is also supported in the [World Bank/CPMI PAFI Report](http://www.worldbank.org/en/topic/financialinclusion/brief/pafi-task-force-and-report): \"the framework promotes innovation and competition by not hindering the entry of new types of PSP\.... Increased interoperability of and access to infrastructures supporting the switching, processing, clearing and settlement of payment instruments of the same kind are promoted\... payment infrastructures, including those operated by central banks, have objective, risk-based participation requirements that permit fair and open access to their services.\" A related and important point is that Scheme rules should specify that an individual Participant cannot discriminate against any other individual Participant: unless constrained by other factors (regulatory account limits, etc.), Participants must receive transactions sent by other Participants in the Scheme. This ensures full interoperability. + +The second question is what eligibility criteria a potential DFSP must meet in order to actually join the scheme. Many payments schemes have fairly elaborate procedures to ensure that applicant DFSPs have the financial resources to comply with rules, and the technical wherewithal to meet the operational requirements of the rules. + +Some form of these requirements is necessary for any scheme. But modern technology and, in particular, pre-funded settlement models greatly reduce the risks to the scheme in dealing with smaller DFSPs. The Level One alignment issue here is to ensure that the scheme is not inadvertently discriminating against smaller DFSPs and in favor of large ones. The goal should be to ensure the minimum necessary qualifications to support the obligations that a DFSP applicant is undertaking. + +## 3. Choice: Relationship of Scheme to Platform + +Our definitions separate the concept of a scheme (the entity that rights the rules for a payment system) and a platform (the set of services that physically enable interoperability). Most often, but not necessarily, the platform operates as a switch which routes transactions from one DFSP to another: the alternative is bilateral physical connections among DFSPs. + +What is the relationship between the scheme and the platform? There are multiple models demonstrated in payments systems globally: + +1. Same entity: the scheme operates the platform. This is seen frequently in commercial systems (e.g. Visa) and also in Central Bank provided systems (e.g. Bank of Mexico SPEI) + +2. The scheme hires the platform: the switch and related services are operated by a separate entity, under contract to the scheme entity. The scheme pays the platform entity; this cost is recouped in fees from the scheme to its participating DFSPs. The U.K. Faster Payments system operates on this model (Faster Payments Scheme Ltd. hires Vocalink to operate the platform). + +3. The scheme sets for the parameters by which operator(s) manage transactions governed by the rules: if there are multiple operators, those entities must interoperate, again as specified in Scheme rules. Individual DFSPs choose the operator they wish to use to access the system. The U.S. ACH system works in this manner, as do several of the SEPA payments systems in Europe. + +4. No switch: this is really a variation of the model 3 above. Each DFSP independently and physically connects to each other DFSP, again within constraints set by the scheme rules. Debit cards in Australia work this way. + +### 3.1 L1P Alignment: Relationship of Scheme to Platform + +There is no single Level One Principle that argues in favor of one of these models vs. the other. Factors for consideration include: + +- The goal is that all of the ecosystem players (Scheme, Platform, DFSPs, etc.) encourage L1P-compliant behavior. A more controlled model (models 1 or 2) arguably makes this easier. + +- Having a low-cost system is a core tenet. However, it is debatable whether this is better achieved through Model 1 or Model 2. Models 3 and 4 bear the risk of excluding or disadvantaging smaller DFSPs or new system entrants. + +- In Models 2 and 3, the platform providers will have their own operating guidelines. There may be situations in which provisions of Scheme rules are not adequately reflected or implemented by the Platform. This is an issue of power and control. Model 1 avoids this problem but could create a \"vendor lock-in\" type of problem, where DFSPs have no choice but to pay the costs of the Scheme-controlled platform. + +## 4. Choice: Scope of Scheme Rules and Scheme Rules Authority + +### 4.1 Scope + +Scheme rules vary widely in scope from scheme to scheme. All cover the essential elements of scheme participation, party obligations, and the mechanics of interoperability. But many schemes go much further in terms of defining how DFSPs make payments services available to their customers, and under which terms. Two areas here are worthy of note: + +- Some schemes specify elements of the end-user experience. Examples of this include the card networks specifying card physical parameters and design requirements. Some systems (for example, Peru\'s BIM) specify how the mobile phone interface appears to a consumer. Other systems (for example, India\'s UPI) go so far as to provide the SKD\'s and API\'s that define what the end-user app can functionally do. Some systems may require that a DFSP receiving a credit-push transaction must post it to a customer\'s account within a specified amount of time +- Some schemes also specify elaborate liability provisions on interoperable transactions. These provisions may vary according to use case and particular attributes of a transaction. For example, in the card networks, liability may pass from the card issuer to the merchant acquirer if the merchant terminal does not meet certain specifications. + +### 4.2 Rules Authority + +As described above, the scheme is the entity that writes the rules for the payment system. But who approves these rules? There are two primary models in the market place: + +- DFSP Authority. In this model, all (or some) rules changes are voted on by participating DFSPs. The voting may be determined on a per-seat basis, or it may be determined on a volume-weighted basis. Many schemes have experimented with variations on this. + +- Scheme Authority with DFSP Participation. In this model, rules authority rests with the scheme entity, but some degree of formal or informal participation by DFSPs is included: this can either be formal (standing committees that meet to consider rule changes, rules amendment commentary periods specified in the rules, etc.) or informal (scheme representatives meet and/or request written feedback on proposed rules changes). + +### 4.3 L1P Alignment — Rules Scope and Authority + +There are two relevant Level One principles: one is for participatory governance, and the other is the mandate to deliver a low-cost system. Level One also recognizes the importance of a system that is convenient and easy for end-user customers to use, particularly poor consumers and merchants. Considerations therefore include: + +- Rules can create costs: the more elaborate the rules are specifying how DFSPs must deliver services to the customer, the higher the costs of complying with these rules will be. + +- Offsetting this is the value of having a common consumer experience - there is considerable evidence that having a common experience can help consumers self-educate in the use of services. Arguably, this is an important factor in scaling the system. But the further a scheme goes in writing rules that effect end-user experience, the more important it is that participating DFSPs have some voice in these rules. + +- Scheme experience has shown that explicit voting rules, although they sound good to DFSPs, often result in very long decision practices: this is one reason why some schemes use the second above, and use participating DFSPs as sounding boards, but do not grant rules authority. + +## 5. Choice: Use Cases + +One of the most important choices a scheme has to make is which use cases to support. Frequently, a real-time credit-push retail scheme starts with person to person (P2P) payments as the first use case: often, a scheme will indicate to the market that it intends to support other use cases in the future. As schemes evolve there are significant "sub use cases" to consider: in some Mojaloop implementations, the term "secondary use case" is used for this: as an example, if P2P is the use case, cross-border P2P might be a secondary use case; wallet-to-wallet and wallet-to-bank account might be secondary use cases. + +Business rules may vary by use case and/or secondary use case. This may include operational details (data fields used, etc.), scheme pricing (in particular, interchange) and even liability provisions. + +The Open API document used by the Mojaloop code includes the following list of use cases: + +- P2P Transfer +- Agent-Initiated Cash In +- Agent-Initiated Cash Out +- Agent-Initiated Cash Out Authorized on POS +- Customer-Initiated Cash Out +- Merchant-Initiated Merchant Payment +- Merchant-Initiated Merchant Payment Authorized on POS +- ATM-Initiated Cash Out +- Refund + +An implementing scheme will choose its own primary and secondary use cases, and the definitions of these will be in the Business Rules. Schemes should consider the following: + +- Eventual scheme-to-scheme interoperability will be easier (especially from one Mojaloop-implemented scheme to another) if the same primary use cases and definitions are used + +- Schemes may need to differentiate between a DFSP's ability to initiate transactions in a specific use case or secondary use case, and requirements that a DFSP needs to be able to support receiving transactions in a specific use case or secondary use case + +- Any rules that are written specific to a use case or secondary use case need to be systemically detectable (by labelling or inference) if the rule will be automatically applied: this is particularly important for business-case-specific interchange fees. How this is done should be part of the business documentation, in the Operating Guidelines. + +### 5.1 L1P Alignment — Use Cases + +There are two considerations here. One significant issue is the relationship between high volumes in a payment system and the ability to deliver ultra-low-cost processing fees to participating DFSPs. Almost all retail payments systems support multiple use cases, including those which started with a single use case. The card networks are an excellent example of this: started to support point of sale purchases, they now support online purchases, bill payment, salary payments, and B2B payments. Payment processing is a scale business: the more volume, the lower the unit costs can be. Level One strongly supports a payment system being used for multiple use cases: ideally, all retail (e.g. excluding large value B2B) use cases in a country. + +The other consideration is making the payment system easy for end-users to access and understand. The same system, with similar user interfaces, etc. for use cases will be easier for end-users (particularly poor or uneducated users) to use. + +## 6 Choice: QR Codes + +QR codes are emerging as a major enabler of merchant payments in developing countries. Both payment schemes and national payment authorities are deciding on formats, protocols, and scope for QR codes. Some of the decisions include: + +- Is the QR code presented by the merchant, and scanned by the consumer, or presented by the consumer and scanned by the merchant? Level One has a preference for merchant-presented QR codes, implemented in conjunction with push, not pull payments. A merchant-presented QR code can be combined with a till number to enable consumers with feature phones to easily pay the same merchant. + +- Is the QR code static (the same for all purchases), or is it dynamic? Rather than a choice, this is being seen as an evolution: most markets are starting with static QR codes, but have plans to move to dynamic codes. Dynamic codes function like a "request to pay" payment message in a push payment system, and can contain purchase-specific data. + +- Does the national approach to QR codes use a "shared QR code" approach, in which a single QR code can represent a merchant's payments credentials across multiple schemes? The most common way in which this approach is implemented is through the use of EMVCo QR code standards. An alternative is a single QR code approach, in which a QR code is used only to access either an interoperable payment scheme (for example, Mexico's CoDi system) or a closed-loop system (for example, China's WeChat Payments). A single QR code approach may create low-cost advantages by driving volume through a single national platform, while a cross-scheme approach may enable competition among multiple schemes. + +- If a shared QR code approach is used, is there a single national entity that controls which schemes a given merchant accepts? If so, who runs this "repository" function and what are its functions? Does it actually issue the QR code data string? If yes, does it sign the string and validate it? There is some speculation that a QR code repository could serve as a point of cross-payments system oversight and management of fraud. It could also tie into a national business registration scheme in some way. It is interesting to consider that a cross-scheme QR code repository might require its own business rules, which would become "meta rules" which would exist above the business rules of the individual schemes. + +- Does the QR code data string (the "payload") contain the merchant's "payment address", or does it point in some way to a place where this is stored? The latter approach provides more flexibility and supports a merchant's ability to change providers. + +- How is the consumer (and the merchant) protected from QR code fraud? + +- What are the economics of the transaction to the merchant? Level One has a strong preference for zero, or near-zero pricing to the small or poor merchant. + +## 7. Choice: Payments Addressing + +Any scheme implementing credit-push payments needs to specify how the payer and their Payer DFSP addresses the payment. The address needs in some way to be resolved into the payee's account number at the DFSP who provides their transaction account. The scheme needs to decide: + +- What types of payments addresses (sometimes called "identifiers") are used. Some payments addresses are institutional ID's and account numbers: a bank routing number and bank account number are an example of this. Other payments addresses may be account numbers without the institutional ID: a mobile phone number used to direct funds to an eMoney wallet provided by an MNO is an example of this. All other types of payments addresses are aliases of some sort. An alias may be an email address, a scheme-assigned merchant ID, a national identity number, or a mobile phone number used to direct funds to account other than that provided by an MNO eMoney issuer. An scheme-supported alias may also be a phrase: "payadamnu123". + +- For each type of payment address supported by the scheme, the scheme needs to determine how that payment address is resolved. At a minimum, the scheme needs to support a mechanism by which the address is mapped to a DFSP scheme participant responsible for the transaction account associated with that payment address. Resolution can be done in a number of different ways: + + - The scheme can maintain a directory mapping addressing to responsible DFSP ID's: this requires some type of DFSP registration process for addresses. + + - The scheme can maintain a directory which maps the address to the responsible DFSP and also specifies the account number: this requires a slightly different registration process. + + - Either of these types of directories can be maintained by a third party: scheme rules would establish how these directories are populated, maintained and used, and what the responsibilities of the various parties are. + + - A scheme may also use a broadcast method to determine the DFSP responsible for a given payment address ("do you claim this address"), but needs to develop a protocol to manage conflicts if more than one DFSP "claims" the address. + +- It is important to note that the resolution method can different for each type of supported payment address. Some supported payment address types may also be accompanied by particular data sets: for example, when a payment is being made in payment of an invoice, the payment address may be some type of alias, and that use of that alias may be tied to accompanying invoice data. Dynamic QR codes, as an example, will create a "request to pay" that may contain the scheme-supported merchant ID (an alias) and accompanying transaction data detail. + +The Open API specification and the Mojaloop reference code support a wide range of different address types: mobile number, bank account, national ID, aliases ("Quickshop\@abc"), etc. + +### 7.1 L1P Alignment — Payments Addressing + +Secure, easy payment addressing relates to two important concepts in Level One: convenience for the end-user and "openness". The latter is particularly important to enable competition and rapid scaling of a payment system. As schemes (Level One and otherwise) worldwide struggle to determine how to best solve the question of payments addressing, a few best practices appear to be emerging: + +- Although the use of the mobile number, in particular, as an address has an obvious appeal, there appears to be a trend to use aliases — identifiers with no additional meaning. This is demonstrated in India with the UPI system and in Australia's new real-time system, where the identifier is referred to as the PAYID. + +- Identifier portability is desirable, both from the perspective of user convenience and as a mechanism to avoid "DFSP lock-in". + +- As mentioned above, the directory needs to ensure uniqueness of the payment address within the payment system: any given address can only map to a single DFSP. However, a single DFSP transaction account can have multiple payment addresses which route to it. DFSPs have the opportunity to create value-added services for their customers, in which they differentiate the treatment of transactions routed to them via different payment addresses (subject, of course, to overall scheme business rules). + +## 8. Choice: Interparticipant Settlement + +Payment schemes need to determine how participant DFSPs will settle their financial obligations to each other arising from interoperable transactions. There are multiple decisions to be made on the settlement model. Existing settlement models used in legacy retail payment systems have important controls over risks. As a general statement, schemes to today have opportunities to make choices leveraging modern technology and connectivity to manage these risks in different ways. Some of the choices are: + +- Net, gross, or continuous gross settlement. Traditionally, net settlement has been used for retail payments systems (practically speaking, all systems except RTGS). Some real-time retail payment systems are now using gross settlement (Mexico's SPEI) or are planning to (Brazil). Some systems are using a continuous gross settlement account (U.S. RTP): in this approach, DFSPs jointly own a single account at the Settlement Bank, and ownership shares in the pooled account are determined, at any point in time, by the DFSPs ledger position at the platform. This approach uses no settlement entries, netting, or settlement entry posting. + +- Choice of settlement bank. Most interoperable retail payment systems use the country's central bank as the settlement bank, but there are examples (card network settlement in the U.S.) where a commercial bank is used as the settlement bank. + +- Dedicated or multi-purpose settlement accounts. Are the DFSP's settlement accounts, held at the settlement bank, dedicated to the purpose of scheme settlement, or are they used for other purposes (other scheme settlements, reserve balances, etc.) as well? In a continuous gross settlement model, the pooled account is always a dedicated account. + +- Same day or deferred settlement. In a net settlement model, are settlement entries posted to settlement bank accounts on the day of the transaction, or later? + +- Multiple or single settlement windows. In a net settlement model, is there a single settlement window per business day, or are there multiple? If multiple, are the windows defined by time periods, volume of transactions, or some other factor? + +- Prefunded or not. Are settlement entries (in a net system) or individual transactions (in a gross system) allowed to occur if there is not sufficient funding in the settlement bank account? If so, what mechanisms (lines of credit, collateral accounts, etc.) are used to support this risk? The term "prefunded" is used when scheme rules specify that the DFSP must have enough money in their settlement account to cover an outbound transaction: if not, the platform will refuse the transaction. + +- Dynamic position management or not. In a net settlement system which uses a switch, does the switch "know" the actual position of the sending DFSP before sending the transaction on to the receiving DFSP? + +- Automated or manual net debit cap calculation. The net debit cap is an amount that the system uses, in conjunction with dynamic position management, to determine whether or not an individual transaction is sent to the receiving DFSP. This can either be manually set by the scheme (individually for each DFSP) or automated: the latter requires a real-time connection between the (dedicated) settlement bank account and the switch. + +- Discretionary components of the net debit camp may be defined by the scheme. There are two types of these. A scheme discretionary component may add to, or subtract from, an individual DFSP's net debit cap. An addition can be used to create a safety margin; a subtraction can be used to extend overdraft capabilities to the DFSP. In the latter case, responsibility for the overdraft needs to be clearly agreed upon between the scheme and the settlement bank. + +### 8.1 L1P Alignment — Interparticipant Settlement + +Level One has a clear principle calling for same day settlement. Other than that, the most important considerations are how a given scheme will manage risk and costs for DFPS — liquidity costs in particular. This is a rapidly evolving area in payment systems, and it is expected that different schemes will make different choices. In general, it can be observed that automation supports scale, and that prefunding and multiple windows support low risk and low cost. + +The Mojaloop reference code supports a variety of different settlement mechanisms. + +## 9. Choice: Tiered Access + +Legacy retail payment systems (and wholesale systems) generally support tiered access — the ability of smaller institutions to access the system through correspondent relationships with larger institutions. This has been considered necessary as smaller institutions frequently had difficulty in meeting either the settlement obligations of full participation or the technical (particularly security) obligations of full participation. + +In countries with eMoney Issuance licenses (or with other non-bank or non-traditional DFSPs, or transaction account providers) the question becomes whether or not these non-traditional providers access the system directly or through a relationship with a traditional bank: in these cases, it is generally the settlement, and not the technical, issue in question. + +### 9.1 L1P Alignment — Tiered Access + +There is no single Level One principle which would direct a scheme on how to handle this issue. There are, however, both cost and risk issues to consider: + +- It should be noted that larger institutions have created very profitable businesses in serving these smaller institutions. These costs, born by the indirect participants, will in some way be passed on to end-users. Because of this, Level One schemes may want to avoid this model where possible. + +- The Level One principle of "Open Loop" suggests that a scheme should support the ability of all DFSPs to participate directly wherever possible: modern technology, such as that used by Mojaloop, and prefunded settlement models should make this simpler. + +- Legacy systems also tend to "hide" the activity of the smaller institution from the scheme or the hub. This may be undesirable from a regulatory or risk management point of view. Some new retail real-time payment systems (notably the U.S. RTP Network) are allowing both technical and settlement indirect access with full transparency of the smaller institution to the scheme and platform. + +- Another factor to consider is particular to countries with eMoney Issuance or other non-traditional DFSP providers. Under the L1P principle of DFSP involvement in governance decisions, it may be that asking eMoney Issuers to access a system "under" a bank participant may leave these DFSPs in a "second tier" position with respect to governance: this is arguably undesirable, and particularly in cases, which appear relevant in some countries, where the eMoney Issuers have a higher transaction volume than do their sponsoring banks. + +Note this section does not discuss access to the system by other FSPs: that is addressed in [Choice: Scheme Use by Other FSPs](#_13-choice-scheme-use-by-other-fsps). + +## 10. Choice: Scheme Fees and End User Pricing + +Fees associated with an interoperable payment scheme can be categorized as: + +- End-User Fees: the fees (or minimum balance requirements, etc.) assessed by a DFSP to their end-user customer. This includes fees charged to consumers, merchants, billers, governments or other enterprises. Some of these fees are specifically attached to the interoperable transfer itself (e.g. a "send transfer" fee, or a "merchant discount fee"); others are related (a "cash-out" fee, an ATM withdrawal fee). These fees are typically set by the DFSP. In some countries and situations, regulation or scheme rule agreements may apply to or influence the fees. Fees may either be fixed amounts; fixed amounts; percent-of-value amounts, or a combination of fixed and percent of value. In either case, fee schedules can differ based on which value-bands (for example, transactions lower than value "X" have this fee) or end-user transaction volume. + +- Processing Fees: the fee that the Scheme, and the Operator of the Platform (if different) charge to the DFSPs for use of the scheme and platform. As with end-user fees, processing fees can be fixed or variable and may also vary by value-band or transaction volume. + +- Interchange Fees: fees that one DFSP pays to another DFSP related to an interoperable transaction. Interchange Fees are normally set by the Scheme (in the Scheme Rules) and are physically tabulated and collected by the Scheme. The scheme and the operator of the Platform do not pay or receive these fees: they are a debit to one DFSP and a credit to the other. Both the rate of interchange fees and direction (does the Payer DFSP pay or receive?) may vary by use case and secondary use case. Interchange fees may be fixed, a percent of value, or a combination of the two. + +In addition to setting fee policies, schemes will need to decide on how fees are collected and (in the case of interchange fees) disbursed. There is an important consideration with interchange: should the fees be collected and disbursed as a part of the settlement of each transaction, or as an end-of-period (such as monthly) billing process? + +### 10.1 L1P Alignment: Fees + +One of the most important Level One concepts is to have an ultra-low-cost platform, with consumer and small merchant fees being as low as possible. An important element in achieving this for a payment system is reaching scale. Schemes will want to consider both of these factors as they set fee policies. Considerations include: + +- **End-user pricing.** Is the scheme in a position to put any controls or limitations on this? The answer will vary by jurisdiction. Some schemes have put limitations on the structure of fees (e.g. must be flat vs. percent of value), which parties can be charged (e.g. payers can be charged but not payees, etc.) or on what overall fees can be. Some schemes have not written this into rules but have encouraged informal agreement on fee policies (subject to regulatory approvals) to incent consumer usage. Other schemes have prohibited certain types of fee actions, such as charging surcharges for interoperable transactions. + +- **Processing Fees.** The goal here is for the scheme fees to DFSPs to be as low as possible (specifically and ideally, a fraction of a U.S. cent.). Best market practices are for these fees to be fixed, rather than percent-of-value: this makes sense given that the scheme and the platform are not taking value risk in processing the transactions. However, there is a challenge with purely fixed fees: how to avoid having fees that are too high for very low-value transactions. Some schemes are addressing this through value bands, with lower fixed charges for transactions under a certain value. Some schemes are establishing volume tiers to incent DFSPs. Schemes may wish to encourage (or even mandate) that DFSPs route "on-us" transactions (where payer and payee DFSP are the same institution) through the platform: if this is the case, the scheme may wish to set a zero fee for these transactions. Some schemes may also charge membership fees and/or onboarding fees to DFSPs. Finally, some schemes may provide a period of time after launch of the scheme in which all fees are waived. + +- **Interchange Fees**. This is a complex and often debated topic in the payment industry worldwide, and one which frequently attracts regulatory scrutiny. Schemes may want to consider: + + - Whether or not to have interchange at all. Some payments systems have this; many do not. Retail real-time payments systems worldwide are split on whether or not they support the use of interchange, and where they do, in which direction interchange flows for use cases such as P2P. + + - Interchange is a useful mechanism for a form of billing: where the receiver of a valuable service (such as a merchant who wants access to a consumer's payment account) has no relationship with the provider of that service (the consumer's DFSP). Another example of this is where one bank's ATM is used to disburse funds to another bank's customer. + + - Interchange is more questionable when it is being used to support legacy business models: for example, if an interoperable transaction causes a paying DFSP to "lose" a cash-out fee they would otherwise have gained, the scheme may specify an interchange rate in which the Payee DFSP pays the Payer DFSP to compensate for this loss. It may be practical to use interchange in these situations in the short run, but in the long run one can argue that the underlying business model needs to evolve. + + - Schemes should keep in mind that wherever interchange is used, a "hard cost" is being created that is being absorbed by, and probably passed on in end-user fees, by the interchange-paying-DFSP. + +## 11. Choice: Brand Management + +Should a scheme brand be used? Should the same brand be used for all use cases? Or should the only brand used be the brand of the DFSP who is offering a service to its customers? Not surprisingly, this is an issue that has been debated in payments systems through the years. + +### 11.1 L1P Alignment — Brand + +Level One has a clear design principle supporting a common brand: this is predicated on making the service understandable and easy to use for both consumers and merchants. A common scheme brand may be used in conjunction with DFSP brands: "Use DFSP SuperPay (DFSP brand) with XPay (Scheme brand) to pay your bills." + +Business rules will need to specify how and where the common brand is used. + +## 12. Choice: Scheme Connections to Other Schemes + +The advent of roughly similar real-time retail payments systems worldwide has led to many discussions about the desirability of connecting these schemes to each other. This can both facilitate transactions within a country, but notably has importance for cross-border payments of all kinds, including workers\' remittances. + +In legacy payment systems, this type of connection is rare on a scheme-to-scheme basis. Notable exceptions to this are the connection domestically of ATM networks, and the connection of domestic card schemes that are owned or controlled by global card networks. What happens, instead, is that DFSPs or other providers who have participation in multiple networks (either directly or through partnerships) create the effect of cross-scheme connection through individual deals: this is, essentially, how cross-border correspondent banking works. + +Mojaloop as a technology is designed to allow system-to-system connectivity. Schemes implementing Mojaloop systems will need to consider the balance between striking scheme-to-scheme business agreements (with concurrent technical connections) and/or allowing DFSPs in their scheme to connect to other schemes or DFSPs bilaterally. + +### 12.1 L1P Alignment — Connections to Other Schemes + +The relevant L1P principles here are low cost and "openness". The Mojaloop code in particular has the potential to turn cross-border transactions from ones that are governed by complex relationships (as in the case of traditional correspondent banking) into ones which are competed for in an open, interconnected marketplace. Schemes will need to evaluate the merits of this (arguably promoting lower costs) with the risks of dominance by major institutions. Scheme-to-scheme business arrangements may have a beneficial "level the playing field" characteristics. Hybrid relationships are also possible. This is an evolving area of the payment industry, and one where considerable variety of arrangements are both possible and likely. + +## 13. Choice: Scheme Use by Other FSPs + +A successful L1P aligned scheme will be used by many enterprises — merchants, billers, government agencies, etc. as well as individual people. There will also be a wide range of other FSPs (Financial Services providers) which are not DFSP's: in other words, which do not hold customer transaction accounts. This includes payments services providers: aggregators, merchant services providers, various DFSP processors, etc., all of which may want to connect to and use the scheme. + +As described in the "participation" choice above, a Level One aligned scheme includes as direct, settling participants only the entities that hold the end-user transaction accounts: the accounts that are debited and credited as a result of the interoperable transaction. + +Other entities may physically connect to the platform under a variety of business arrangements. The scheme will need to decide how involved scheme business rules are in dictating terms or standards for these arrangements. As a general principle, any other FSP connecting to the platform will need to be acting on behalf of a DFSP whose customer's transaction account is being debited (the payer DFSP) or credited (the payee DFSP). In legacy payments models, the DFSP retains all of the financial obligations and liabilities for the transaction: the third party is acting purely on behalf of the DFSP. Scheme business rules may specify requirements for the business arrangements between the DFSP and the third party. In some jurisdictions (notably India and the EU) regulation is driving changes to this model to allow other FSPs to have more direct involvement in schemes. Scheme rules will need to carefully describe and proscribe the parameters of these arrangements. + +Definitional note: we are purposefully not using the term "PSP" (Payment Service Provider) here, as in various jurisdictions this term is used to include transaction account providers, in some cases, and non-transaction account providers in other cases. As a further comment, in many countries today entities such as aggregators hold financial accounts at banks or eMoney Issuers and use those accounts to receive money from customers and disburse money to other customers. In this role, the aggregator is a customer of a DFSP (the bank or eMoney Issuer) and is also acting as a Financial Services Provider. It may be that these aggregators in the future will not need to intermediate the financial transaction, but instead provide directions that lead to direct transfer of funds, through the scheme, from one customer's transaction account to another's. + +### 13.1 L1P Alignment — Use by Other FSPs + +The principles here are, again, low cost and openness. Level One would encourage new players to be able to use and access the scheme, as long as their actions are controlled by the scheme in order to ensure safety and financial stability. + +## 14. Choice: Scheme Risk Management Standards + +Payments schemes, their platforms, and participating DFSPs and third parties all, obviously, need to operate according to strong risk management standards in order to ensure a healthy payments system ecosystem. + +The question for a scheme is the balance between defining these standards itself and relying on other standards. From a Business Rules perspective, this is a significant choice. Schemes may either: + +- Develop detailed risk management standards for DFSPs (and for the Platform) and conduct rigorous certification and/or audit processes to ensure compliance + +- Require DFSPs, the Platform and third parties to follow referenced national or global standards for risk management and security + +### 14.1 L1P Alignment — Risk Management Standards + +The Level One does not address which choice above is the better. But the concepts of a safe system for consumers to use, and a low-cost system clearly apply here. Some considerations: + +- A shared fraud management utility (which Level One principles do support) can cost-effectively handle some of the tasks of fraud management. This does not reduce an individual DFSP's compliance burden, but merely shifts how it meets that burden + +- The global card networks have effectively demonstrated the ability to automate elements of exception processing, focusing on those transactions which occur the most often + +- The Mojaloop community has expressed interest in codifying exceptions, and providing support through code for some processes + +- The Mojaloop community may also develop best practices documents for handling areas of risk management, including cybersecurity + +## 15. Choice: Exception Management + +Exception processing includes a wide variety of non-standard transactions and interactions among users and providers of a payment scheme. These include: + +- Errors on the part of end-users + +- Errors on the part of DFSPs, the Platform, or other FSPs + +- Fraud committed by end-user customers, including individuals, + merchants, billers, or other entities + +- Fraud committed by third parties, including hackers + +- Malicious attacks on the system or on individual DFPSs, including cyber-attacks. + +Schemes have important choices to make about how involved the scheme, and its Business Rules, are in defining how scheme participants handle these exceptions. Legacy payment systems show us a wide variety of models which are used, from systems where the scheme and Business Rules have minimal involvement in handling of exception processing (checking, most ACH systems) to systems where the scheme and its Business Rules are extensively involved (most card networks). Real-time retail payment systems worldwide are generally only in the early stages of deciding on how to handle these matters. + +### 15.1 L1P Alignment — Exception Processing + +There are two very important Level One design principles that relate to this. + +- One is the principle of transaction irrevocability. This means that a payment transaction that is successfully completed (in a Mojaloop implementation, one that has been fulfilled) may not be reversed without the consent of the payee. + +- The other is the commitment to a shared fraud management resource at the platform level. The idea is that the scheme and its platform will have a larger view of all transaction data and will be able to perform fraud detection and management tasks more effectively and at a lower cost than can individual DFSPs. This concept is in its very early stage of evolution as Level One systems are deployed, both with and without Mojaloop technology. + +Schemes will face significant challenges in this area as the long-anticipated rollout of merchant payments occurs, particularly in lesser developed markets that do not have highly penetrated card payments industries. The challenge will be to balance the desire to protect consumers from merchant fraud with the desire to have low-cost end-user pricing. In developed card payments markets, this is often provided by business rules which specify that a merchant's bank is responsible financially for fraud committed by the merchant. This works but results in relatively high transaction charges to the merchant, as their bank must cover their risk exposure under these rules. This financial model may or may not be sustainable in less developed economies. This is another are where we anticipate extensive evolution over the coming years. diff --git a/docs/adoption/Scheme/scheme-participation-agreement.md b/docs/adoption/Scheme/scheme-participation-agreement.md new file mode 100644 index 000000000..3fd84473e --- /dev/null +++ b/docs/adoption/Scheme/scheme-participation-agreement.md @@ -0,0 +1,76 @@ +# Scheme Participation Agreement Template + +- Version: 3.0 + - Author: Carol Coye Benson (Glenbrook) + - Date: October 2019 + - Description: + +--- + +## **About the Mojaloop Community Business Document Project** + +This document is part of the Mojaloop Community Business Document Project. The project is intended to support entities (countries, regions, associations of providers or commercial enterprises) implementing new payments systems using Mojaloop code. These entities will also need write Business Rules that participants in the system will follow. + +The Mojaloop Community Business Document Project provides templates for Business Rules and related documents. There are many choices involved in implementing a new payment system: the templates show some of the choices and, where appropriate, commentary is provided on how the particular choice is related to the goals of a Level One aligned system. + +The following documents are part of the project: + +- Scheme Key Choices + +- Scheme Participation Agreement Template + +- Scheme Business Rules Template + +- Platform Operating Guideline Template + +- Exception Management Operating Guideline Template + +- Uniform Glossary + +# Table Of Content + +[1 - Participation Application and Agreement](#_1-participation-application-and-agreement) + +[1.1 - Applicable Law](#_1-1-applicable-law) + +[1.2 - Signature Block: Applicant and Scheme](#_1-2-signature-block-applicant-and-scheme) + +# 1. Participation Application and Agreement + +::: tip NOTE +The goal of this document is to have it contain the minimal necessary provisions to evidence a DFSP's application to join the Scheme and abide by its Business Rules. In particular, future changes to the Business Rules should not result in a need to re-sign or amend this agreement. +::: + +The undersigned organization ("_Applicant_") hereby applies for participation in the \[Scheme\], a \[a legal form of company\] organized and existing under the laws of \[define\] and if accepted by \[Scheme\] agrees that Applicant's participation in the Scheme will be subject to the following terms and conditions. This Application and Agreement is dated \_\_\_\_\_\_\_\_\_\_\_\_\_\_and shall become effective and binding upon the Applicant as of the date shown below when signed on behalf of the \[Scheme\] (the "*Effective Date*"). From the Effective Date, Applicant shall be called a "*Participant*." Applicant acknowledges that this Participation Application and Agreement is supported by adequate mutual consideration. Terms not defined in this Application and Agreement will have the meanings as set forth in the Business Rules, as defined below. + +- Applicant shall be bound by and shall observe all of the provisions of the Business Rules. + +- The Business Rules comprise the Business Rules and the Associated Documents and other documents that may be designated as Associated Documents from time to time by the Scheme. Business Rules and Associated Documents include all other documents as designated in those documents. + +- The Scheme may amend the Business Rules from time to time as it deems appropriate, providing Participants such reasonable advance notice of changes or additions as the Scheme may find appropriate in the circumstances. + +- Participants will pay Fees as specified in the Business Rules. + +- Termination: + + - A Participant may terminate participation at any time without cause on X days' written notice. Such termination will be subject to provisions in the Business Rules regarding the costs and procedures for winding down the Participant's operations with respect to the Scheme. The Participant will remain liable for all Fees and other charges and liabilities incurred pursuant to the Business Rules through the effective date of termination. + + - The Scheme can terminate a Participant for causes provided in the Business Rules. + + - Termination of a Participant for cause will be subject to obligations upon termination and procedures specified in the Business Rules. + + - License. Participant is granted a license to participate, including use of Scheme Property, upon terms as specified in the Business Rules. Participant is licensed to provide Services using Scheme Processing Components and the Scheme Brand and to use Scheme Property in the following countries: + + - Information Submissions. Applicant warrants and represents that all information submitted to the Scheme in support of this Participation Application and Agreement is correct and complete as of the date of this application. + +## 1.1 Applicable Law + +- Choice of Law. This Application and Agreement and the Business Rules shall be construed and applied in accordance with the laws of \[specify\] and not by provisions of such laws which would determine which jurisdiction's laws would apply in the absence of this choice of law provision. + +- The Scheme and Participant will conduct all performance in connection with the Scheme in compliance with Applicable Law. + +- Business Rules will not be understood to require any action that would cause the Scheme or the Participant to violate Applicable Law. Any conflict between Applicable Law and a provision of the Business Rules will be resolved in accordance with procedures specified in the Business Rules. No such resolution shall require Participant or the Scheme to take any action or refrain from any action that would cause it to violate Applicable Law. + +The Applicant has caused this Application and Participation Agreement to be signed on behalf of Applicant by the individual indicated below subject to the Applicant's warranties and representations that such individual has been authorised by all necessary and appropriate company action to enter into this Application and Participation Agreement as of the date indicated above and that when signed on behalf of Applicant and accepted by the Scheme, will form a binding and enforceable obligation of Applicant as of the date indicated below. + +## 1.2 Signature Block: Applicant and Scheme diff --git a/docs/adoption/Scheme/scheme-uniform-glossary.md b/docs/adoption/Scheme/scheme-uniform-glossary.md new file mode 100644 index 000000000..2cd4d7d8b --- /dev/null +++ b/docs/adoption/Scheme/scheme-uniform-glossary.md @@ -0,0 +1,299 @@ +# Uniform Glossary Template + +- Version: 1.0 + - Author: Carol Coye Benson (Glenbrook) + - Date: October 2019 + - Description: + +--- + +## **About the Mojaloop Community Business Document Project** + +This document is part of the Mojaloop Community Business Document Project. The project is intended to support entities (countries, regions, associations of providers or commercial enterprises) implementing new payments systems using Mojaloop code. These entities will also need write Business Rules that participants in the system will follow. + +The Mojaloop Community Business Document Project provides templates for Business Rules and related documents. There are many choices involved in implementing a new payment system: the templates show some of the choices and, where appropriate, commentary is provided on how the particular choice is related to the goals of a Level One aligned system. + +The following documents are part of the project: + +- Scheme Key Choices + +- Scheme Participation Agreement Template + +- Scheme Business Rules Template + +- Platform Operating Guideline Template + +- Exception Management Operating Guideline Template + +- Uniform Glossary + +## **Introduction** + +This is a glossary of terms used in the Mojaloop Business Community Document Project, and contains other terms related to business topics. A more detailed technical glossary is available as part of the Open API for FSP Interoperability Specification. + +# Uniform Glossary Template + +| Term | Definition | +| :----- | :---------------------------------------------------------------------------------------------- | +| Access Channel | Places or capabilities that are used to initiate or receive a payment. Access channels can include bank branch offices, ATMs, terminals at the POS, agent outlets, mobile phones, and computers. | +| Account Lookup | A process that determines the DFSP responsible for a Transaction Account. | +| Account Lookup System | Account Lookup System is an abstract entity used for retrieving information regarding in which FSP an account, wallet or identity is hosted. The Account Lookup System itself can be hosted in its own server, as part of a financial switch, or in the different FSPs. | +| Account Validation | A status provided by a Quote Response API Call: a Payee DFSP indicates that an account is available to be credited with a proposed transfer amount. | +| Active User | A term used by many providers in describing how many of their account holders are frequent users of their service. | +| Addressing | The use of an identifier to direct a Payment from a Payer to a Payee, typically a mobile phone number or email address. | +| Adjacencies | Ways in which entities and/or DFSPs realize revenue from services that are not directly associated with a Payment---for example, loans made to Transaction Account holders. | +| Agent | An entity authorized by the provider to handle various functions such as customer enrollment, cash-in and cash-out using an agent till. | +| Agent Outlet | A physical location that carries one or more agent tills, enabling it to perform enrollment, cash-in and cash-out transactions for customers on behalf of one or more providers. National law defines whether an agent outlet may remain exclusive to one provider.Agent outlets may have other businesses and support functions. | +| Agent Till | An agent till is a provider-issued registered "line", either a special SIM card or a POS machine, used to perform enrollment, cash-in and cash-out transactions for clients. National law dictates which financial service providers can issue agent tills. | +| Agent-Initiated Cash-In | A Use Case defined in the API Specifications document. | +| Agent-Initiated Cash-Out | A Use Case defined in the API Specifications document. | +| Aggregator | A specialized form of a merchant services provider, who typically handles payments transactions for a large number of small merchants. Scheme rules often specify what aggregators are allowed to do. | +| Alias | A Payee Identifier that is mapped to a Payee DFSP and Transaction Account Number. | +| Anti-Money Laundering (AML) | Anti-Money Laundering refers to Applicable Law and, to the extent expressly adopted by the Scheme, good practice guidance, t regarding mitigation of money laundering risks. | +| API | Application Programming Interface: a technical interface implemented by a software protocol that allows systems to interact with each other via standard structures, without requiring a user system to know the internal implementation details of the system with which it is interacting. | +| Applicable Law | All treaties, conventions, laws, regulations, directives, official guidance or directives of a Regulatory Authority to the extent that they are binding, respectively, upon the Scheme, the Scheme or a Participant with regard to the Scheme\'s Services. | +| Applicant | An organization that has submitted or wishes to submit an application to become a Participant, but whose application has not been acted upon by the Scheme. | +| Application Program Interface (API) | A method of communication to allow interaction and sharing of data between different software or Technical Protocols. | +| Arbitration | The use of an arbitrator, rather than courts, to resolve disputes. | +| Associated Documents | The set of documents listed in Appendix A of these Rules. | +| ATM-Initiated Cash-Out via OTP | A Use Case defined in the API Specifications document. | +| Attribute | A characteristic of a Transaction, it being understood that specific rules may apply to Transactions with specific Attributes. | +| Authentication | The process of ensuring that a person or a transaction is valid for the process (account opening, transaction initiation, and so on) being performed. | +| Authorization | The permission given by the Payer or entity to make a Payment. | +| Authorized /institution entity | Non-financial institutions that have followed the appropriate authorization by State Bank and/or relevant regulatory authorities to partake in the provisioning of mobile financial services. | +| B2P | Business to Person; a Bulk Payment Secondary Use Case. | +| Bank | A chartered financial system within a country that has the ability to accept deposits and make and receive payments into customer accounts. | +| Bank Account | A Transaction Account offered by a Bank. | +| Bank Account Identifier | A type of Payee Identifier. | +| Bank Accounts and Transaction Services | A transaction account held at a bank. This account may be accessible by a mobile phone, in which case it is sometimes referred to as \"mobile banking\". | +| Bank to Bank | A P2P Secondary Use Case. | +| Bank to Wallet | A P2P Secondary Use Case. | +| Bank-Led Model| A reference to a system in which banks are the primary providers of digital financial services to end users.National law may require this.| +| Basic Phone | Minimum device required to use digital financial services. | +| Bill Payment | A P2B Secondary Use Case. | +| Biometric Authentication | The use of a physical characteristic of a person (fingerprint, IRIS, and so on) to authenticate that person. | +| Blacklist| A list or register of entities (registered users) that are being denied/blocked from a particular privilege, service, mobility, access or recognition. | +| Blockchain | A technology that creates distributed architectures. In payments systems, often a reference to a shared ledger that records and validates Transactions. +| Blockchain | The technology underlying bitcoin and other cryptocurrencies - a shared digital ledger, or a continually updated list of all transactions. | +| Brand | A word and/or mark approved by the Scheme for use by Participants. | +| Bulk Disbursement | A Use Case defined in the API Specifications document. | +| Bulk Payment | A Payment from a single Payer to multiple Payees, for example cash transfer programs from a government or NGO to a set of beneficiaries. | +| Bulk upload service | A service allowing the import of multiple transactions per session, most often via a bulk data transfer file which is used to initiate payments.Example: salary payment file. | +| Business | Entity such as a public limited or limited company or corporation that uses mobile money as a service; for example, making and accepting bill payments and disbursing salaries. | +| Cash Management | Management of cash balances at an agent. | +| Cash-In | Receiving eMoney credit in exchange for physical cash - typically done at an agent. | +| Cash-Out | Receiving physical cash in exchange for a debit to an eMoney account - typically done at an agent. | +| Chip Card | A chip card contains a computer chip: it may be either contactless or contact (requires insertion into terminal).Global standards for chip cards are set by EMV. | +| Clearing | The process within a Payment system in which a Payer DFSP and a Payee DFSP debit and credit their End User accounts. | +| Closed-Loop | A payment system used by a single provider, or a very tightly constrained group of providers. | +| Combatting Financing of Terrorism (CFT) | Initiatives to prevent individuals or entities from using payment systems to send funds to individuals or entities associated with terrorism. | +| Commission | An incentive payment made, typically to an agent or other intermediary who acts on behalf of a DFS provider.Provides an incentive for agent. | +| Commit | Part of a 2-phase transfer operation in which the funds that were reserved to be transferred, are released to the payee; the transfer is completed between the originating/payer and destination/payee accounts. | +| Condition | In the Interledger protocol, a cryptographic lock used when a transfer is reserved. Usually in the form of a SHA-256 hash of a secret preimage. When provided as part of a transfer request the transfer must be reserved such that it is only committed if the fulfillment of the condition (the secret preimage) is provided. | +| Corridor | Refers to any two countries in a cross-border Transaction and to the direction of the transfer. | +| Counterparty | The other side of a payment or credit transaction. A payee is the counterparty to a payer, and vice-versa. | +| Coupon | A token that entitles the holder to a discount or that may be exchanged for goods or services. | +| Credit Transfer | A Payment or Transfer of funds initiated by the Payer DFSP to the Payee DFSP. A Credit Transfer is often referred to as a 'credit push transfer' because the funds are 'pushed' from the Payer's Transaction Account. Credit Transfer contrasts with Direct Debit. | +| Cross-Border | A Transfer from a Payer DFSP domiciled in one country, to a Payee DFSP that is domiciled in another country. | +| Cross-FX Transfer | Transfer involving multiple currencies including a foreign exchange calculation. | +| Current Position | A Participant\'s current net position in the Position Ledger for a given Currency. | +| Customer | The Customer of the system. The term is used for both the Payer and the Payee. Individuals, merchants, billers, governments, and other enterprises are all customers. Sometimes refered to as end-users. | +| Customer-Initiated Cash-Out | A Use Case defined in the API Specifications document. | +| Customer-Initiated Purchase | A Use Case defined in the API Specifications document. | +| Customer-Initiated Purchase via QR | A Use Case defined in the API Specifications document. | +| DFSP (Digital Financial Services Provider) | A financial services provider that is licensed by a regulatory authority to provide Transaction Accounts which hold customer funds and are used to make and receive Payments. DFSPs have relationships with consumers, merchants, and other enterprises, and provide digital financial services to End Users. Used interchangably with FSP (Financial Services Provider). | +| Digital | Electronic communications between two individuals or entities that can occur on various electronic devices (e.g., mobile, tablet, computer). | +| Digital Liquidity | A practice of keeping value in Digital form, rather than exchanging the Digital value for cash (physical form). | +| Digital Payment | A broad term including any payment which is executed electronically. Includes payments which are initiated by mobile phone or computer. Card payments in some circumstances are considered to be digital payments. The term \"mobile payment\" is equally broad and includes a wide variety of transaction types which in some way use a mobile phone. | +| Direct Debit | A Payment or Transfer of funds initiated by the Payee DFSP to the Payer DFSP. A Direct Debit is often referred to as a 'debit pull transfer' because the funds are 'pulled' from the Payer's Transaction Account. Direct Debit contrasts with Credit Transfer. | +| Directory | A centralized or decentralized holding of payment identifiers to be used for Addressing, accessible by the payments system or DFSPs. | +| Dispute Resolution | A process specified by a provider or by the rules of a payment scheme to resolve issues between end users and providers, or between an end user and its counter party. | +| Domestic | Describes a Transaction between two DFSPs domiciled in the same country. | +| eMoney | Digital funds or value owned by a Transaction Account holder on a payment device such as chip, prepaid card, mobile phone, or on a computer system. National regulation specifies what types of DFSPs can issue eMoney. | +| eMoney Issuer | A DFSP licensed in the country to act as an eMoney Issuer. | +| End User | The customer of a DFSP. The customer may be a consumer, a merchant, a government, or another form of enterprise. | +| End-User Fees | Fees assessed by a DFSP to their en-end user customer. | +| Enterprise | Any non-individual person who is a customer of a DFSP: includes Merchants, Billers, Government Agencies, and other enterprises. | +| Escrow or Trust Account | An account held by a Non-Bank DFSP at a bank; normally a regulatory requirement to protect consumer deposits at the DFSP. | +| Exceptions | Transactions that are erroneous or fraudulent. | +| FATF | The Financial Action Task Force is an intergovernmental organization to combat money laundering and to act on terrorism financing.| +| Feature Phone | A mobile telephone without significant computational capabilities. | +| Fees | The payments assessed by a provider to their end user. This may either be a fixed fee, a percent-of-value fee, or a mixture. | +| Fiat Currencies | Official money issued by the central bank of a country or region as legal tender. | +| Financial Inclusion | The sustainable provision of affordable Digital financial services that bring the Low Income End Users into the formal economy. | +| Financial Inclusion | The sustainable provision of affordable digital financial services that bring the poor into the formal economy. | +| Financial Literacy | Consumers and businesses having essential financial skills, such as preparing a family budget or an understanding of concepts such as the time value of money, the use of a DFS product or service, or the ability to apply for such a service. | +| Fintech | A term used to describe the intersection of finance and technology. 'Fintechs' are entities providing innovative solutions in the finance space, leveraging technology. | +| Float | This term can mean a variety of different things. In banking, float is created when one party\'s account is debited or credited at a different time than the counterparty to the transaction. eMoney, as an obligation of a non-bank provider, is sometimes referred to as float. | +| Fraud | Criminal use of digital financial services to take funds from another individual or business, or to damage that party in some other way. | +| Fraud Risk Management | Tools to manage providers\' risks, and at times user\'s risks (for example, for merchants or governments) in providing and/or using DFS services. | +| FSP | The entity that provides a digital financial service to an end user (either a consumer, a business, or a government.) Used interchangably with DFSP (Digital Financial Services Provider). | +| Fulfilled Transfer | A transfer that has been accepted by the Payee DFSP and recorded as complete by the Scheme. Once a transfer has been recorded as complete by the Scheme, the Payer is obliged to honour the transaction when it appears in a Settlement. | +| Fulfillment | In the Interledger protocol, a secret that is the preimage of a SHA-256 hash, used as a condition on a transfer. The preimage is required in the commit message to trigger the transfer to be committed. | +| FX | Foreign Exchange. | +| G2P | A Bulk Payment Secondary Use Case. | +| Governance | The collection of management approaches, decisions, and oversight functions within the Scheme. Scheme Governance can set the tone for everything that occurs in the Scheme. | +| Government Agency | Any Transaction Account Holder which is some kind of government agency or department. | +| Government Payments Acceptance Services | Services which enable governments to collect taxes and fees from individuals and businesses. | +| Gross Settlement | A method of settling financial obligations among DFSPs and a Scheme. Gross Settlement processes each Transaction individually. The details of the Gross Settlement model are specified in Scheme rules. Gross Settlement contrasts to Net Settlement. | +| Hub | A term that may be used for the entity that operates the Platform on behalf of the Scheme. | +| Identifier Service | The way in which the Account Lookup Process works for a given type of Identifier. | +| Identity | A credential of some sort that identifies an end user. National identities are issued by national governments. In some countries a financial identity is issued by financial service providers. | +| Immediate Funds Transfer | A digital payment which is received by the payee almost immediately upon the payer having initiated the transaction. | +| Interchange | A structure within some payments schemes which requires one provider to pay the other provider a fee on certain transactions. Typically used in card schemes to effect payment of a fee from a merchant to a consumer\'s card issuing bank. | +| Interledger | The Interledger protocol is a protocol for transferring monetary value across multiple disconnected payment networks using a choreography of conditional transfers on each network. | +| International Remittance | Making and receiving payments to another person in another country. | +| Interoperability | The ability of an Customer with a Transaction Account with one Participant to exchange a transaction with an Customer who has a Transaction Account with a different Participant. | +| Interoperability Service for Transfers (IST) | A switch. | +| Irrevocable | A transaction that cannot be \"called back\" by the payer; an irrevocable payment, once received by a payee, cannot be taken back by the payer. | +| Know Your Customer (KYC) | Regulatory requirements for a DFSP to establish the Identity and activities of an End User or entity, both before opening a Transaction Account and over time. | +| Ledger | A record kept of transactions. | +| Level One Project | An initiative of the Bill & Melinda Gates Foundation to promote financial inclusion. | +| Liability | A legal obligation of one party to another; required by either national law, payment scheme rules, or specific agreements by providers. Some scheme rules transfer liabilities for a transaction from one provider to another under certain conditions. | +| License | The license granted to an Applicant by the Scheme upon acceptance of the Scheme Participation Agreement, which permits the Participant to participate in the Scheme and to use Scheme Property in accordance with the Rules. | +| Liquidity | The availability of liquid assets to support an obligation. Banks and non-bank providers need liquidity to meet their obligations. Agents need liquidity to meet cash-out transactions by consumers and small merchants. | +| Loans | Means by which end users can borrow money. | +| Merchant | An enterprise which sells goods or services and receives payments for such goods or services. | +| Merchant Acquisition | The process of enabling a merchant for the receipt of electronic payments. | +| Merchant Category Codes | A categorization set by a Scheme to differentiate among enterprise customers. | +| Merchant ID | A type of Payee Identifier. | +| Merchant Service Provider | A provider (bank or non-bank) who supports merchants or other payments acceptors requirements to receive payments from customers. The term \"acquirer\" is used specifically in connection with acceptance of card payments transactions. | +| Merchant-Initiated Purchase | A Use Case defined in the API Specifications document. | +| Merchant-Initiated Purchase via POS/OTP | A Use Case defined in the API Specifications document. | +| Merchant-Initiated Purchase via QR | A Use Case defined in the API Specifications document. | +| Microfinance Institution (MFI) | An entity that offers financial services to Low Income populations. Almost all MFIs give loans to their members, and many offer insurance, deposit and other services. MFI's are considered DFSPs in a Level One System if they provide Transaction Accounts to their customers. MFI's who are not DFSPs may connect directly to a Level One Platform, through a relationship with a DFSP. Scheme rules will specify how such MFI's may interact with the Platform. | +| Mobile Network Operator (MNO) | An enterprise which sells mobile phone services, including voice and data communication. | +| Money Transfer Operator | A specialized provider of DFS who handles domestic and/or international remittances. | +| MSISDN | Number uniquely identifying a subscription in a mobile phone network. These numbers use the E.164 standard that defines numbering plan for a world-wide public switched telephone network (PSTN). | +| Multilateral Net Settlement | A type of settlement that manages the positions of a group of participants in a scheme. | +| National Identity Document | A credential that identifies an End User. National Identity Documents are issued by national governments. | +| Near Field Communication | A communication technology used within payments to transmit payment data from an NFC equipped mobile phone to a capable terminal. | +| Net Debit Cap | A value that the Platform uses in determining whether a Payer DFSP can send a Request for Transfer, as defined in the Scheme Operating Rules. | +| Net Debit Cap Margin | A value set by a scheme which increases or decreases the Net Debit Cap of a participant. | +| Net Position | A value in a scheme participant\'s ledger, reflecting the net of obligations owed. | +| Net Settlement | A type of settlement that nets the position of a participant in a scheme, reflecting both obligations owed to and from other participants or the scheme. | +| Non-Bank | An entity that is not a chartered bank, but which is providing financial services to end users. The requirements of non-banks to do this, and the limitations of what they can do, are specified by national law. | +| Non-Bank-Led Model | A reference to a system in which non-banks are the providers of digital financial services to end users. Non-banks typically need to meet criteria established by national law and enforced by regulators. | +| Non-repudiation | Ability to prove the authenticity of a transaction, such as by validating a digital signature. | +| Not-for-Loss | A cost-recovery model with an additional set of funds available to cover investment requirement to operate the Platform. | +| Notification | Notice to a payer or payee regarding the status of transfer. | +| Off-Us Payments | Payments made in a multiple-participant system or scheme, where the payer\'s provider is a different entity as the payee\'s provider. | +| On-Us Payments | Payments made in a multiple-participant system or scheme, where the payer\'s provider is the same entity as the payee\'s provider. | +| Online Purchase | A P2B Secondary Use Case. | +| Open API Specification | The Open API for FSP Interoperability specification. | +| Open-Loop | A payment system or scheme designed for multiple providers to participate in. Payment system rules or national law may restrict participation to certain classes of providers. | +| Operating Rules | Rules written by a scheme which bind scheme participants. Sometimes called \"Business Rules\". | +| Operations Risk Management | Tools to manage providers\' risks in operating a DFS system. | +| Operator | An entity that provides and/or manages the Platform of a payments system. | +| Organization | An entity such as a business, charity or government department that uses mobile money as a service; for example, taking bill payments, making bill payments and disbursing salaries. | +| OTP | One-time Passcode. OTP is a credential which by definition can only be used once. It is generated and later validated by the same FSP for automatic approval. The OTP is usually tied to a specific Payer in a Payment. The generated OTP is usually a numeric between 4 and 6 digits. | +| Over The Counter Services | Services provided by agents when one end party does not have an eMoney account: the (remote) payer may pay the eMoney to the agent\'s account, who then pays cash to the non- account holding payee. | +| P2P | A Use Case defined in the API Specifications document. | +| Participant | A provider who is a member of a payment scheme, and subject to that scheme\'s rules. | +| Participant Discretionary Net Debit Cap Margin | A value set by a participant which decreases their Net Debit Cap. | +| Participation Agreement | An agreement entered into between each Participant and a Scheme. | +| Participation Fees | Fees for participation in a payment scheme (sometimes called membership fees). | +| Parties Query | An API Call to the Scheme Directory Service by which a Payer DFSP requests the identifier of the DFSP to which a payee identifier is registered. | +| Parties Query Response | The response from the Scheme Directory Service to a Parties Query. | +| Partner Bank | Financial institution supporting the FSP and giving it access to the local banking ecosystem. | +| Party | An entity which is using Scheme Services directly or indirectly. | +| Party Identifier | An item of information which uniquely identifies an Customer in an Interoperability implementation. | +| Party Identifier Type | An enumeration which distinguishes different types of Party Identifier. The full range of Party Identifier Types is given in the Open API Specification; the subset of Party Identifier Types supported by any given Schema are given in its Operating Rules. | +| Payee | The recipient of electronic funds in a payment transaction. | +| Payee DFSP | The role of a Participant who receives a Transfer on behalf of its customer Payee. | +| Payer | The payer of electronic funds in a payment transaction. | +| Payer DFSP | The Participant who sends a Transfer. | +| Payment | An exchange of funds, credentials, and other necessary information to complete obligation between End Users. A Transfer is a Payment. | +| Payment Device | Payment device is the abstract notion of an electronic device, other than the Payer's own device, that is capable of letting a Payer accept a transaction through the use of a credential (some kind of OTP).Examples of (Payment) Devices are ATM and POS. | +| Payment System | A broad term to describe the overall system, including the Scheme, Scheme Services, and Scheme Participants. | +| Payment System Operator | The entity that operates a payment system or scheme. | +| Payments Service Provider (PSP) | A term used in two ways: generally, as any company involved in the provision of payments services (including DFSPs); or for a provider that offers branded products or services to End Users, including merchants. PSPs may connect directly to a Level One Platform, through a relationship with a DFSP. Scheme rules will specify how PSPs may interact with the Platform. | +| Personal Information | Information related to any individual person, including Customers or employees of the Scheme or of a Participant from which the individual may be identified or recognized regardless of the form of such information. | +| Platform | The set of operational capabilities, often including a Switch, that implement the exchange of Payments in a Level One aligned interoperable payment system. | +| Platform | A term used to describe the software or service used by a provider, a scheme, or a switch to manage end user accounts and to send and receive payment transactions. | +| Pooled Settlement Account | A bank account at the Bank, which is jointly owned by scheme participants. | +| Position Ledger | A ledger kept by the platform which records Provisional Settlement Entries and Final Settlement Entries for a Participant in a given Currency. | +| Posting | The act of the provider of entering a debit or credit entry into the end user\'s account record. | +| Processing Fees | Fees billed by the Scheme to Participants for Processing done by the Scheme Platform. | +| Processor | An enterprise that manages, on an out-sourced basis, various functions for a DFSP. These functions may include transaction management, customer database management, and risk management. Processors may also do functions on behalf of payments systems, Schemes, or Switches. Processors may connect directly to a Level One Platform, acting on behalf of a DFSP. Scheme rules will specify how Processors may interact with the Platform. | +| Provisional Debit | A record wtihin a scheme Position Ledger of a Transfer Request that has not been fulfilled; recorded only on the Payer DFSP\'s Position Ledger | +| PSP | Payment Service Provider. | +| Pull Payment | A type of Transaction originated by the Payee's DFSP. Direct Debits, checks, and card payments are all Pull Payments. Pull Payments can bounce or fail for insufficient funds unless a separate Authorization is done (e.g., cards). | +| Push Payment | A type of Transaction initiated by the Payer DFSP. This is sometimes called a Credit Transfer. | +| QR Code Purchase | A P2B Secondary Use Case. | +| Quick-Response (QR) Code | A method of encoding and visualizing data in machine-readable form. There are multiple QR models. | +| Quote | A process by which a Payee DFSP acknowledges the validity of the Payee account to accept a transfer, and sets terms (and possibly fees) related to that transfer. | +| Quote Request | A request by a Payer DFSP for data relating to a proposed Transfer. | +| Quote Response | The response of a Payee DFSP to a Request for Quote. | +| Real Time Gross Settlement (RTGS) | A settlement model which settles transfers on an individual, rather than a net, basis. | +| Real Time Retail Payments (RTRP) | Retail Payments that are processed in real time (as initiated). | +| Receive Amount | The amount which is credited to a Payee\'s Transaction Account. | +| Reconciliation | Cross FSP Reconciliation is the process of ensuring that two sets of records, usually the balances of two accounts, are in agreement between FSPs. Reconciliation is used to ensure that the money leaving an account matches the actual money transferred. This is done by making sure the balances match at the end of a particular accounting period. | +| Recourse | Rights given to an end user by law, private operating rules, or specific agreements by providers, allowing end users the ability to do certain things (sometimes revoking a transaction) in certain circumstances. | +| Refund | A transfer which reverses a previous transaction. | +| Regulator | A governmental organization given power through national law to set and enforce standards and practices. Central Banks, Finance and Treasury Departments, Telecommunications Regulators, and Consumer Protection Authorities are all regulators involved in digital financial services. | +| Request for Quote | An API Call that initiates a Transaction in terms of which the Payer DFSP requests the Payee DFSP for information regarding a proposed Transfer. | +| Request for Transfer | A message that is passed from a Payer DFSP through the Platform to a Payee DFSP, that requests that a Transfer be made from the Payer to the Payee. | +| Request to Pay | A message by which a Payee 'requests' Payment from a Payer. A Request to Pay in a Level One System is often used to describe a merchant that requests a Push Payment from an End User. | +| Reserve | Part of a 2-phase transfer operation in which the funds to be transferred are locked (the funds cannot be used for any purpose until either rolled back or committed). This is usually done for a predetermined duration, the expiration of which results in the reservation being rolled back. | +| Retail Payment | A Payment or Transfer between End Users, typically a low value denomination. The term is often used to describe P2P, B2P or P2B Payments. | +| Reversal | The process of reversing a completed transfer. | +| Risk Management | The practices that enterprises do to understand, detect, prevent, and manage various types of risks. Risk management occurs at providers, at payments systems and schemes, at processors, and at many merchants or payments acceptors. | +| Risk-based Approach | A regulatory and/or business management approach that creates different levels of obligation based on the risk of the underlying transaction or customer. | +| Roll back | Roll back means that the electronic funds that were earlier reserved are put back in the original state. The financial transaction is cancelled. The electronic funds are no longer locked for usage. | +| Rules | The practices and standards necessary for the functioning of payment services defined by the Scheme. Rules are sometimes referred to as scheme rules, business rules, or operating rules. | +| Rules Modification | All changes, additions, deletions or other modifications to the Scheme Operating Rules or to any Associated Documents. | +| Saving and Investing | Keeping funds for future needs and financial return. | +| Savings Products | An account at either a bank or non-bank provider, which stores funds with the design of helping end users save money. | +| Scheme | A set of rules, practices, and standards necessary for the functioning of payment services. | +| Secondary Use Case | A subset of a Use Case. Specific Business Rules or Operating Guidelines may apply to Secondary Use Cases. | +| Secure Element | A secure chip on a phone that can be used to store payment data. | +| Security Access Code | A personal identification number (PIN), password/one-time password (OTP), biometric recognition, code or any other device providing a means of certified access to a customer's account for the purposes of, among other things, initiating an electronic fund transfer. | +| Security Incident | (i) Unauthorized access to or disclosure of Personal Information or Transaction Data related to Customers who are eligible to initiate or receive Transfers through the Scheme which has or is reasonably suspected to have occurred; or (ii) a confirmed breach of a Participant\'s networks or systems or their vendor\'s networks or systems that exposes Personal Information or Transaction Data related to the Scheme has or is reasonably expected to have occurred. | +| Send Amount | The amount which a Payer authorizes to be debited from their Transaction Account. | +| Sensitive Consumer Data | Consumer Sensitive Data means any or all information that is used by a consumer to authenticate identity and gain authorization for performing mobile banking services, including but not limited to User ID, Password, Mobile PIN, Transaction PIN. Also includes data relating to religious or other beliefs, sexual orientation, health, race, ethnicity, political views, trades union membership, criminal record. | +| Services | Elements of the scheme platform which delivers interoperability capabilities to scheme participants. | +| Settlement | A process by which Participants settle their obligations to each other and to the Scheme related to the exchange of Transactions as set out in the Settlement Operating Guidelines. | +| Settlement Bank | A bank appointed by the Scheme to be a partner in managing the Settlement and in which each Participant shall have a bank account for the purpose of Settlement. | +| Settlement Bank Account | The bank account held by a Participant at the Settlement Bank or at Bank agreed with the Settlement Bank, that is used for Settlement between the Scheme and the Participant. | +| Settlement Instruction | Means an instruction given to a settlement system by a settlement system participant or by a payment clearing house system operator on behalf of a Central Bank settlement system participant to effect settlement of one or more payment obligations, or to discharge any other obligation of one system participant to another system participant. | +| Settlement Obligation | Means an indebtedness that is owed by one settlement system participant to another as a result of one or more settlement instructions. | +| Settlement Window | A time period between two successive Net Settlements as scheduled in accordance with the Settlement Operating Guidelines. | +| Shared Service | A common set of services that participating DFSPs collaborate to develop and/or use. | +| Smart Phone | A device that combines a mobile phone with a computer. | +| Special Charter Banks | Banks in a country which are permitted to carry out a limited set of functions, as determined by regulation. Special Charter Banks that can only accept deposits and handle Payments are considered DFSPs in a Level One System. | +| Sponsor | An arrangement between an electronic money issuer and a bank, used for payment and collection of interchange fees by the electronic money issuers | +| Standards Body | An organization that creates standards used by providers, payments schemes, and payments systems. | +| Stored Value Account | Account in which funds are kept in a secure, electronic format. May be a bank account or an eMoney account. | +| Suspicious Transaction Report | If a financial institution notes something suspicious about a transaction or activity, it may file a report with the Financial Intelligence Unit that will analyze it and cross check it with other information.The information on an STR varies by jurisdiction. | +| Switch | A processing entity in a payments system that routes a Transaction from one DFSP to another DFSP. A system may operate its own Switch, or this function may be done by one or more third parties. | +| System | A term used to describe the Scheme, services, Platform, and Participants aligned with a Level One Project. | +| Systemic Risk | In payments systems, the risk of collapse of an entire financial system or entire market, as opposed to risk associated with any one individual provider or end user. | +| The Level One Project | An initiative of the Bill & Melinda Gates Foundation, within the Financial Services for the Poor program, that works to support countries or regions building interoperable, low-cost digital financial services systems to bring Low Income persons and merchants into the formal economy. | +| Tiered Acess | A provision set in scheme rules which allows one DFSP to participate in the system under sponsorship of another DFSP. | +| Til Number Purchase | A P2B Secondary Use Case. | +| Transaction | A set of related API Calls that are exchanged between Participants via the Scheme including a Transfer. | +| Transaction Account | A bank account or wallet offered a customer by a DFSP. | +| Transaction Account Holder | The customer of a DFSP who holds the Transaction Account provided by that DFSP. | +| Transaction Account Holder Type | A designation used to define whether or not the Transaction Account Holder is a Consumer, a Business, a Government Agency, or a Non-Profit Agency. | +| Transaction Account Type | A designation used to define a Transaction Account as either a Bank Account or an eMoney Wallet. | +| Transaction Cost | The cost to a DFS provider of delivering a digital financial service. This could be for a bundle of services (for example, a \"wallet\") or for individual transactions. | +| Transaction Fees | Fees for processing interoperable transactions set by a scheme. | +| Transfer | Generic term to describe any financial transaction where value is transferred from one account to another. | +| Transfer Amount | The amount the Payer DFSP Transfers to a Payee DFSP using the Scheme. | +| Transfer Request | A request by a Payer DFSP to make a Transfer. | +| Transfer Response | A Payee DFSP\'s response to a Transfer Request. | +| Trust Account | A means of holding funds for the benefit of another party. eMoney Issuers are usually required by law to hold the value of end users\' eMoney accounts at a bank, typically in a Trust Account. This accomplishes the goals of funds isolation and funds safeguarding. | +| Ubiquity | A term used to describe the ability to pay anyone and be paid by anyone. | +| Unbanked | Unbanked people do not have a transaction account. Underbanked people may have a transaction account but do not actively use it. Underserved is a broad term referring to people who are the targets of financial inclusion initiatives. It is also sometimes used to refer to a person who has a transaction account but does not have additional DFS services. | +| Uncovered Losses | Settlement Obligations that are not met by the responsible DFSP and are not discharged using collateral or other mechanisms. | +| Use Case | A term used to describe the purpose of the Payment. Specific Business Rules or Operating Guidelines may apply to Use Cases. | +| User ID | A unique identifier of a user. This may be an MSISDN, bank account, some form of DFSP-provided ID, national ID, and so on. In a transaction, money is generally addressed to a user ID and not directly to an account ID. | +| USSD | A communication technology that is used to send text between a mobile phone and an application program in the network. | +| Value-Added Services | Services or products provided to End Users that End Users will pay to use or access, often used in coordination with Adjacencies. | +| Voucher | A monetary value instrument commonly used to transfer funds to customers (Payees) who do not have an account at the Payer\'s FSP. This could be Payees with no account or account at another FSP. | +| Wallet | A Transaction Account offered to customers by electronic money issuers. | +| Wallet to Bank | A P2P Secondary Use Case. | +| Wallet to Wallet | A P2P Secondary Use Case. | +| Whitelist | A list or register of entities (registered users) that are being provided a particular privilege, service, mobility, access or recognition, especially those that were initially blacklisted. | +| Women's Economic Empowerment (WEE): | Increasing women's access and rights to economic resources through decent work opportunities, property and assets, Financial Inclusion, and Platforms. | diff --git a/docs/adoption/assets/cla/admin_configure.png b/docs/adoption/assets/cla/admin_configure.png new file mode 100644 index 000000000..1d8281bb4 Binary files /dev/null and b/docs/adoption/assets/cla/admin_configure.png differ diff --git a/docs/adoption/assets/cla/admin_sign_in.png b/docs/adoption/assets/cla/admin_sign_in.png new file mode 100644 index 000000000..a960e2dcd Binary files /dev/null and b/docs/adoption/assets/cla/admin_sign_in.png differ diff --git a/docs/adoption/assets/cla/cla_1.png b/docs/adoption/assets/cla/cla_1.png new file mode 100644 index 000000000..46718fc66 Binary files /dev/null and b/docs/adoption/assets/cla/cla_1.png differ diff --git a/docs/adoption/assets/cla/cla_2_1.png b/docs/adoption/assets/cla/cla_2_1.png new file mode 100644 index 000000000..18ae1809c Binary files /dev/null and b/docs/adoption/assets/cla/cla_2_1.png differ diff --git a/docs/adoption/assets/cla/cla_2_2.png b/docs/adoption/assets/cla/cla_2_2.png new file mode 100644 index 000000000..2e60fb762 Binary files /dev/null and b/docs/adoption/assets/cla/cla_2_2.png differ diff --git a/docs/adoption/assets/cla/cla_3.png b/docs/adoption/assets/cla/cla_3.png new file mode 100644 index 000000000..5e2ddc46d Binary files /dev/null and b/docs/adoption/assets/cla/cla_3.png differ diff --git a/docs/adoption/guides/Role-based-access-control.md b/docs/adoption/guides/Role-based-access-control.md new file mode 100644 index 000000000..ad1dff783 --- /dev/null +++ b/docs/adoption/guides/Role-based-access-control.md @@ -0,0 +1,297 @@ +# RBAC Context + +An individual who needs to access the various Mojaloop Hub management portals can be registered and an "account" generated, which can be used to access various aspects of an operational instance of a Mojaloop Hub and to provide a basis for auditing that access by tying activities to the original registration. For the purposes of this document, an "account" is a digital identity, a means of authenticating (linking) the person asserting that identity to the original registration, and a set of attributes, which will include - among other things - a set of access rights, or rights that are enabled through the possession of those attributes. + +### RBAC Design + +The RBAC design for a hub operator, outlines the security control points that should be considered or extended in order to mitigate risk within a typical Mojaloop hub operations organisation. Some control points are business processes and organisational structure related, some control points are technical relating to the identification, authentication and authorisation layers, and some control points require monitoring. All three should be considered to create accountability and mitigate risk. + +### Audit + +Audit would need to work collaboratively with the business and the IT teams to Segregate these duties wherever possible and assign an appropriate mitigation control in cases wherein it is not feasible to do so. In addition, these controls would need to be monitored on a quarterly basis and the results need to be reported to senior management. + +Some contextual definitions include + +1. **Action** : a distinct event triggered by a user that results in: + +- Creation of a data asset +- Reading or accessing of a data asset +- Update or effecting changes to the state of a data asset +- Delete or the removal of a data asset from an application or database. + +1. **Permission** : authority to perform a specific action in the context of an application or service +2. **Role** : applications, actions and data access required to perform the tasks related to a single role +3. **User - role relationship** : The role (roles) assigned to each user that defines the permissions they have + +## Users, actions and roles in a Mojaloop context + +Mojaloop will have 2 Broad categories of users: + +1. Human – These are hub and DFSP users who through various interfaces will interact with Mojaloop. DFSP users will interact with Mojaloop through the Payment Manager and portals that will be made available during the onboarding process. +2. Non-human – These will automate the business processes and automate tasks that would otherwise be done by a human. These will communicate via API calls that will affect actions to fulfil business requirements. + +The context of this document will focus on Human users only. + +## User Lifecycle Management + +The "User Account Lifecycle" defines the collective management processes for every user account. These processes can be broken down into Creation, Review/Update, and Deactivation—or "CRUD". If any organization utilizes IT resources of any kind, they rely on user accounts to access them. + +## Onboarding + +The Onboarding process will have some activities involving user creation both at DFSP end and at the Hub. These will be as follows: + +1. Hub: The following users will be created + 1.1 Hub Operators + 1.2. Hub Administrators +2. DFSP + 2.1 DFSP Operators + 2.2 DFSP administrators (only applicable to Payment manager). + +## Segregation of Duties + +Segregation of Duties focuses on mitigating the risk of internal fraud by setting boundaries between roles assigned to an employee, and between the conflict of interest that may result from an employee's responsibilities, ensuring no single user can have end to end functional control of a business process and its data. It requires more than one individual to create, process and complete an action. + +### Principle of least privilege + +RBAC uses the security principle of least privilege. Least privilege means that a user has precisely the amount of privilege that is necessary to perform a job. The aim of this is to minimize the likelihood of issuing a user with excess permissions to complete actions in Mojaloop ecosystem. + +### Zero Trust Mojaloop Implementation + +A zero trust network is one in which no person, device, or network enjoys inherent trust. All trust, which allows access to information, must be earned, and the first step of that is demonstrating valid identity. A system needs to know who you are, confidently, before it can determine what you should have access to. + +Mojaloop's inherent design will implement a Zero Trust approach in its architecture and deployment requiring all entities that interact to first authenticate themselves, then seek authorization to access and process data depending on the role they belong to. + +### Process of Segregation Of Duties determination + +1. Define user management workflows and processes. These are all business processes that make up Mojaloop business actions in Mojaloop. Examples include Onboarding. +2. Rationalise all User security access requirements for Applications of Mojaloop as outlined in the table below: + 2.1 Define business and application functions for users and APIs + 2.2 Define role profiles + 2.3 Define function & competence profiles + 2.4 Gather a list of applicable SOD conflicts by defining segregation of duties roles + 2.5 Role profile matrix table (with example data): + +| **Roles and Permissions** **Matrix** | Hub Users | Administrator | Standard Maker User | Standard Checker User | Standard Read Only | DFSP Users | Administrator | Standard Maker User | Standard Checker User | Standard Read Only | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| Onboarding Roles | X | | | | | | | | | | +| Create User Account | X | | | | | | | | | | +| Create DFSP Profile | X | | | | | | | | | | +| Create DFSP User | X | | | | | | | | | | +| +| **Finance Portal** | +| View Reports | | | X | X | X | | | X | X | X | +| Platform Configuration | | | | | | | | | | | +| + +3. Reconfigure any conflicting roles + 3.1 Business approvals + 3.2 Maker checker user creation +4. Periodic System Access & User Authorisation reporting +5. Separation of IT-security and Operational IT security that will support user management activities + +## Best Practices for RBAC and Mojaloop Identity Management + +1. All user ids should be unique and have a unique format that can be correlated in the hub but not meaningful to outsiders. +2. DFSP Users will not have access to any administrative role Hub +3. All non-human users must be restricted from logging on to the application front ends. +4. DFSP users will be trained on the roles and best practices +5. Enforce automated user provisioning and life cycle management. +6. Classify actions performed in Mojaloop to identify business risky actions that require additional controls. +7. Additional controls to mitigate RBAC risks can include: + 7.1 Multifactor authentication (MFA) + 7.2 Audit logging with alerts + 7.3 Auto user profile deactivation / disabling +8. Mojaloop will monitor user inactivity and disable inactive users over a specified period +9. Enforce centralised policy enforcement across identities e.g. Password policy, login policies, MFA, risk based authentication etc. +10. Identify and closely monitor privileged identities that have permissions to perform sensitive actions. The following apply to privileged users: + 10.1 Advanced privileges must be requested for and approved on a case-by-case basis; + 10.2 Administrators should have their privileged permissions for the minimum time possible; + 10.3 Administrators should only have the permissions required to complete a specific task; + 10.4 Membership in administrative groups must be reviewed regularly; + 10.5 Enforce multi-factor authentication for administrative users; + 10.6 Keep access logs, audits, and set-up real-time notifications when access is activated. +11. Mojaloop will configure audit logs and alerts for all user actions in Mojaloop. Where possible explore identity analytics via applicable open source tools. + +## Automated Identity Management and RBAC Control + +The tools preferred for user and identity management in a Mojaloop deployment are: + +1. **KeyCloak Identity Management engine** – Store and process API authentication controls as well as act as API gateway. +2. **WSO2 Identity management engine** – Store and process user role profiles and broker self onboarding of DFSP users. + +------- + +## Context + +An individual who needs to access the various Mojaloop Hub management portals can be registered and an “account” generated, which can be used to access various aspects of an operational instance of a Mojaloop Hub and to provide a basis for auditing that access by tying activities to the original registration. For the purposes of this document, an “account” is a digital identity, a means of authenticating (linking) the person asserting that identity to the original registration, and a set of attributes, which will include - among other things - a set of access rights, or rights that are enabled through the possession of those attributes. + +The registration process involves identity verification, background checking, and so on. The individual is then issued with credentials - a login account ID/digital identity and at least one authentication method, which may include a password and two-factor authentication (2FA). + +::: tip NOTE +The scope of this document is not limited to Mojaloop Hub operators. It also addresses aspects of DFSP operator access to the Payment Manager portals. +::: + +### 2FA considerations + +It should be noted that 2FA via a mobile phone may be inappropriate for some roles, since highly sensitive roles may require that mobile phones are locked away while the individual is “on shift”. This will necessitate other 2FA methods, such as key fobs. + +### Role-Based Access Control + +The Mojaloop Hub uses a Role-Based Access Control (RBAC) method. A user with an account that allows access to the Hub will have roles associated with that account, which define what they can do once they are authenticated themselves and are logged in. + +Many roles apply to multiple portals, however, some roles may be specific to individual portals. + +Care should be taken when assigning multiple roles to an account, or multiple accounts to an individual natural person. This is due to the potential that arises for the circumvention of controls. Part of the purpose of RBAC is to ensure that more than one person must be in the authorization chain for important actions, thereby reducing the vulnerabilities around bad actors. + +## Mojaloop ecosystem portals + +The Mojaloop ecosystem offers a number of portals, which support varying degrees of access control and RBAC. These are split into two groups: + +- Hub portals, which are related to the operation of the Hub itself +- Payment Manager portals, which relate to the management of a specific DFSP’s connection to the Hub + +## RBAC in Mojaloop Hub + +In the Mojaloop Hub environment, RBAC is implemented through a combination of tools - Ory Oathkeeper for identity management, and Keycloak for access control (including roles and maker/checker). + +The Hub itself has the following portals: + +- **Hub Operator onboarding:** +Currently there is no bundled Identity and Access Management (IAM) solution for Hub operators, though the function is partly filled through the use of WSO2. Development work is underway to develop a comprehensive IAM solution based around Ory and Keycloak. This will see an admin operator created alongside the deployment of the Hub, which acts as a first foundational step in this area. +- **Finance Portal:** It has two principal functions: the management of settlement operations, and the management of the liquidity position of individual DFSPs (and related to this, their Net Debit Cap (NDC) value). +Access to the Finance Portal is currently limited to a simple username/password access control function. +- **Participant lifecycle:** Controlling and configuring access to the Hub by DFSPs. +From a technical perspective, this is currently achieved through use of the Mojaloop Connection Manager (MCM). However, it is envisaged that MCM itself will be developed to present an API, which can be used to develop a UI that would be available to Hub Operators and to DFSPs. +- **Hub operations:** These include transaction searches, status and performance monitoring, dashboarding and overall tech ops. +Currently these are achieved through the use of Prometheus/Grafana and a range of other tools, with standard access control embedded in these tools themselves. It is envisaged that this will be migrated into the Ory/Keycloak solution, as this develops. + +Other Hub operations, such as Fraud Management and Case/Dispute Management, are add-on modules that implement their own access control to manage access to their sensitive functions. These are not addressed in this document. + +In addition to the above access control measures, it should be noted that access to all of these functions is only possible via a VPN, with individual credentials controlling access. + +As well as these portals, there are two other primary means of accessing the Hub, neither of which is subject to RBAC: + +- The first of these is transactions, which are strictly controlled according to their own multi-layered cybersecurity measures. +- And secondly, bulk payments (government-to-person - G2P), which are supported by means of an API that is subject to the same controls as other, single transactions. It is envisaged that bulk payments will be a service that is provided to DFSPs (and their customers) by means of a secure API, with the DFSP operating a bulk payment portal for use by their customers. It is possible that the operator of an instance of the Mojaloop Hub might make available a white label bulk payment portal, which interfaces with the Hub bulk payment API, for customization by any DFSP that wishes to offer the service to their customers. (Note that this is not a unique approach: a similar approach has been proposed, for example, for merchant payments, with a white label app for QR code transactions being made available for DFSPs to incorporate into their mobile wallets.) + +The access controls around either single or bulk payments are not therefore discussed further in this document. + +## Payment Manager for integration + +Payment Manager is currently one of the primary mechanisms for integrating DFSPs to a Mojaloop Hub. Whereas the Hub is singular in a scheme, there is a separate instance of Payment Manager for each DFSP. The portals offered by Payment Manager must therefore be secured by means of RBAC to limit access to authorized representatives of the DFSP. + +In the Payment Manager environment, RBAC is implemented solely through Keycloak. + +The following portals are available: + +- **User/Operator onboarding:** +Payment Manager includes Keycloak for IAM. On deployment, a single admin user is created, which can be used to create further user accounts. +- **Hub connection management:** +This includes the ability to configure the Hub connection from the Payment Manager side, and by implication to disable it. It is therefore a controlled function, with different controls for viewing versus modification. +- **Transaction investigation:** +It is possible to investigate transaction queries using the Payment Manager portal. This is potentially an issue if Personally Identifiable Information (PII) is available through the portal. + +## RBAC requirements + +### Mojaloop Hub + +#### Hub Operator onboarding + +##### Foundational accounts + +At the time that a Hub is first stood up, Ory/Keycloak will be used to create a foundational user account with administrator privileges. A system administrator will be assigned this account. Note that the system administrator will not be assigned any operational roles beyond those of a system administrator. + +All functions carried out using Ory/Keycloak are subject to system-level logging for audit purposes. + +The system administrator will then use Ory/Keycloak to create further user accounts, subject to standard identity and background checks for each individual (defined under the Scheme Rules associated with a particular Mojaloop deployment) before their accounts are created. + +These new user accounts will be assigned one of these roles: + +- OPERATOR +- MANAGER + +A user account may not have both OPERATOR and MANAGER roles. + +##### Further accounts + +In addition to the system administrator, the foundational accounts will have the ability to use Ory/Keycloak to add further accounts. However, for these users, this activity will be subject to maker/checker controls. A user with role OPERATOR will be able to set up a user account (with processes in place to ensure that due diligence around identity verification and background checks have taken place). However, this account will not be activated until a person with role MANAGER approves it. + +A role will be assigned to each of these accounts, as they are created. As well as the roles associated with the foundational accounts, the following roles may be assigned to new user accounts: + +- ADMINISTRATOR +- FINANCE_MANAGER + +A user account cannot have more than one of OPERATOR, MANAGER, ADMINISTRATOR or FINANCE_MANAGER, in order to ensure separation of: + +- Financial management from other Hub operations tasks +- Operator and managerial roles in maker/checker functions + +::: tip NOTE +Assigning the ADMINISTRATOR or FINANCE_MANAGER roles is subject to a higher degree of identity verification and background checks than any other roles, due to the sensitive nature of the associated functions. These additional checks are set out in the Scheme Rules. +::: + +#### Finance Portal + +Many functions (such as the viewing of DFSP positions, the status of settlement windows, and so on) of the Finance Portal are available to all logged-in users, regardless of their role. However, the following functions may only be carried out by users with specific roles: + +- Settlement processing + - Close settlement window + - Initiate settlement +- DFSP liquidity management + - Add/withdraw funds + - Change NDC + +All of these are subject to maker/checker controls, so that a user with role ADMINISTRATOR can initiate the action, but it must be approved by a user with role FINANCE_MANAGER. + +#### Participant lifecycle + +This portal provides a single interface for a Hub Operator to add and maintain DFSPs on the Hub ecosystems. + +There are some standardised functions that are subject to RBAC: + +- Create DFSP +- Create DFSP Accounts +- Suspend DFSP + +Each of these is subject to maker/checker controls, so that a user with role OPERATOR can set up the changes, and they must be approved by a user with role MANAGER. + +In addition, there is a significant workload in technical onboarding a DFSP, in particular around the establishment of the technical operating environment (certificates and so on). This is not subject to RBAC. This is not considered a significant risk, since there is no value without being able to create a DFSP and the associated accounts on the Hub itself - activities that are subject to RBAC. + +#### Hub operations + +Access to the reporting functions of Prometheus/Grafana is not subject to RBAC controls - any signed-in/authenticated user, with any RBAC role assigned, may view the reports and dashboards. + +Creating a new report/dashboard is a restricted function, and is only available to users with the MANAGER role. + +As noted earlier, the operations and reporting portals will be migrated into the Ory/Keycloak environment in order to facilitate these controls. + +### Payment Manager + +The Payment Manager operator functionality is subject to RBAC controls, but maker/checker is not required. + +#### User/Operator onboarding + +On deployment of Payment Manager, a single admin user account is created using Keycloak. Note that the admin user will not be assigned any operational roles beyond those of a system administrator. + +All functions carried out using Keycloak are subject to system-level logging for audit purposes. + +The admin user will use Keycloak to create further user accounts, subject to standard identity and background checks for each individual (defined under the Scheme Rules associated with a particular Mojaloop deployment) before their accounts are created. + +These new user accounts will be assigned one of the following roles: + +- OPERATOR +- MANAGER + +A user account may not have both OPERATOR and MANAGER roles. + +#### Dashboards + +The Payment Manager dashboards are available to any logged-in/authenticated user with role OPERATOR or MANAGER. + +#### Hub connection management + +Viewing the settings for the Payment Manager/Hub connection is available to any logged-in/authenticated user with role OPERATOR or MANAGER. However, modifying the settings is a controlled function. Only a user with role MANAGER may modify the settings. + +#### Transaction investigation + +Carrying out transaction investigations using the facilities of the Payment Manager portal is a controlled activity, due to the potential for revealing PII data. It is therefore only available to logged-in/authenticated users with role MANAGER. diff --git a/docs/adoption/index.md b/docs/adoption/index.md new file mode 100644 index 000000000..4f41f162e --- /dev/null +++ b/docs/adoption/index.md @@ -0,0 +1,42 @@ +# About the Mojaloop Adoption documents + +For a hub operator or central bank to use Mojaloop for its inclusive instant payment system (IIPS), the process of adoption and steps in the decision making are often very different compared to hiring a firm to provide a proprietary software. Using Mojaloop to build and own a platform provides greater control but also greater responsibility. Not having dependency on a single vendor means exactly that. + +The documentation and tools in this section are designed to help with the rationale for selecting to use Mojaloop and a recommended process for implementation. + +Building a payment system is far more than the technology platform. The scheme and operations are actually the factors of success. We developed Mojaloop to minimize operational burden and reduce the cost of implementing inclusive scheme rules like irrevocability and certainty. + +The process of building a payment system can be as important as some of the scheme decisions which come out of it. Every scheme owner and operator can develop their own process, but we recommend a process that is inclusive, transparent, and iterative to maximize ownership, trust and long term sustainability. + + + +Tools available for Adopters: + +* [**Scheme Choices**](#scheme-choices): documents that provide assistance with defining scheme rules, operating guidelines, as well as key business and design choices +* [**Hub Operations**](#hub-operations): guides that provide practical information about the various aspects of operating a Mojaloop Hub + +## Scheme Choices + +The [Platform Operating Guideline Template](./Scheme/platform-operating-guideline.md) provides a template for describing how the Scheme Platform will operate, and for specifying the obligations and responsibilities of the Scheme, the Platform Operator, and the DFSPs. + +The [Scheme Business Rules Template](./Scheme/scheme-business-rules.md) provides a template for defining the Business Rules that govern the rights and responsibilities of participants in a Mojaloop scheme. + +The [Scheme Key Choices](./Scheme/scheme-key-choices.md) document describes and discusses some of the most significant business and design choices that affect both the technical implementation of Mojaloop and the Business Rules which the Scheme will write, and which Participant DFSPs will agree to follow. + +The [Scheme Participation Agreement Template](./Scheme/scheme-participation-agreement.md) provides a template of the Scheme Participation Agreement that contains the minimal necessary provisions to evidence a DFSP's application to join the Scheme and abide by its Business Rules. + +The [Uniform Glossary Template](./Scheme/scheme-uniform-glossary.md) acts as a glossary of business terms. + +## Hub Operations + +These documents can serve as reference for adopters to build on and customize the hub operations portals and develop their own subsequently as needed. + +The [Technical Operations Guide](./huboperations/techops/tech-ops-introduction.md) outlines the operations processes that enable the Hub Operator to handle all aspects of managing a live service, such as incident management, problem management, change management, release management, defect triage. + +The [Settlement Management Guide](./huboperations/settlement/settlement-management-introduction.md) describes how settlements are managed by the Mojaloop Hub and the partner settlement bank(s), and introduces the main building blocks of settlement processing. + +The [Guide to Finance Portal v2](./huboperations/portalv2/busops-portal-introduction.md) is aimed at the Operator of a Mojaloop Hub and provides information about the Finance Portal, which facilitates the management of settlement-related processes on a daily basis. + +The [Role-Based Access Control](./huboperations/rbac/Role-based-access-control.md) document discusses the security mechanism employed to control access to various aspects of an operational instance of a Mojaloop Hub. + +The [Onboarding Guide for the Hub Operator](./huboperations/onboarding/onboarding-introduction.md) is aimed at the Operator of a Mojaloop Hub and provides information about the DFSP onboarding process. It provides a high-level overview of the onboarding journey that DFSPs take, acting as a checklist of onboarding activities. diff --git a/docs/community/README.md b/docs/community/README.md new file mode 100644 index 000000000..daf52b3ed --- /dev/null +++ b/docs/community/README.md @@ -0,0 +1,20 @@ +# Welcome to Mojaloop Community + +## How do I get started? + +* A good first place to get started is the [Contributors' Guide](./contributing/contributors-guide.md), which provides information on how you can contribute to the project. +* If you would like an overview of the technologies used in the project, head over to the [Tools and Technologies](./tools/tools-and-technologies.md) section. +* To get a sense of the features we are building, view the [Product Roadmap](./mojaloop-roadmap.md). +* The [Project board](https://github.com/mojaloop/project#zenhub) showcases what is currently being worked on; you can start with a [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). + +## Where can I get help? + +Join the [Mojaloop Slack Discussions](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw) to connect with other members of the community. + +## What if I have more questions? +You can checkout some of our frequently asked questions in the [FAQ](../getting-started/faqs.md) section. Or better still head over to the community on [Slack](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw). + +## How do I stay up to date with the project? +Subscribe by joining the [community](https://community.mojaloop.io/) where you can be notified about upcoming [events](https://community.mojaloop.io/c/events/8) and [product announcements](https://community.mojaloop.io/c/announcements/9). + +You can also join our [Slack Announcements](https://mojaloop.slack.com/messages/CG3MAJZ5J) channel to receive information on the latest release. \ No newline at end of file diff --git a/docs/community/archive/discussion-docs/Mojaloop Performance 2020.pdf b/docs/community/archive/discussion-docs/Mojaloop Performance 2020.pdf new file mode 100644 index 000000000..719dec47e Binary files /dev/null and b/docs/community/archive/discussion-docs/Mojaloop Performance 2020.pdf differ diff --git a/docs/community/archive/discussion-docs/README.md b/docs/community/archive/discussion-docs/README.md new file mode 100644 index 000000000..67fffae5f --- /dev/null +++ b/docs/community/archive/discussion-docs/README.md @@ -0,0 +1,27 @@ +# Discussion Documents (Archive) + +## PI 10 +- [Performance Project](./Mojaloop%20Performance%202020.pdf) +- [Code Improvement Project](./code-improvement.md) +- [Cross Border Project](./cross-border.md) +- [PSIP Project](./pisp.md) + +## PI 9 + +- [Versioning Draft Proposal](./versioning-draft-proposal.md) +- [Code Improvement Project](./code-improvement.md) +- [Performance Project](./performance.md) +- [Cross Border Project](./crossborder.md) +- [PSIP Project](./pisp.md) + +## PI 8 + +- [Cross Border Meeting Notes Day 1](./cross-border-day-1.md) +- [Cross Border Meeting Notes Day 2](./cross-border-day-2.md) +- [ISO integration Overivew](./iso-integration.md) +- [Mojaoop Decimal Type; Based on XML Schema Decimal Type](./mojaloop-decimal.md) + +## PI 7 + +- [Workbench Workstream](./workbench.md) + diff --git a/docs/community/archive/discussion-docs/aws_tagging.md b/docs/community/archive/discussion-docs/aws_tagging.md new file mode 100644 index 000000000..a50c7b2ef --- /dev/null +++ b/docs/community/archive/discussion-docs/aws_tagging.md @@ -0,0 +1,127 @@ +# AWS Tagging Guidelines + Policies + +> **Note:** These guidelines are specific to the Mojaloop Community's AWS Environment for testing and validating Mojaloop installations, and are primarily for internal purposes. They may, however, be a useful reference to others wishing to implement similar tagging strategies in their own organizations. + +To better manage and understand our AWS usage and spending, we are implementing the following tagging guidelines. + +## Contents +- [Proposed tags and their meanings](#proposed-tags-and-their-meanings) + - [mojaloop/cost_center](#mojaloopcost_center) + - [mojaloop/owner](#mojaloopowner) +- [Manual Tagging](#manual-tagging) +- [Automated Tagging](#automated-tagging) +- [AWS Tagging Policies](#aws-tagging-policies) + - [Viewing Tag Reports + Compliance](#viewing-tag-reports--compliance) + - [Editing Tag Policies](#editing-tag-policies) + - [Attaching/Detaching Tag Policies](#attachingdetaching-tag-policies) + +## Proposed tags and their meanings + +We propose the following 2 tag _keys_: + +- `mojaloop/cost_center` +- `mojaloop/owner` + +### `mojaloop/cost_center` + +`mojaloop/cost_center` is a breakdown of different resources in AWS by the workstream or project that is incurring the associated costs. + +It loosely follows the format of `-[-subpurpose]`, where account is something like `oss`, `tips`, or `woccu`. +> Note: It's likely that most of the resources will be under the `oss` "account", but I managed to find some older resources that fall under the `tips` and `woccu` categories. We also want to plan for future types of resources that might be launched in the future. + +Some potential values for `mojaloop/cost_center` are: + +- `oss-qa`: Open source QA work, such as the existing dev1 and dev2 environments +- `oss-perf`: Open source performance work, such as the ongoing performance workstream +- `oss-perf-poc`: Performance/Architecture POC + +We also reserve some special values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/cost_center:unknown` tags and produce a report +- `n/a`: This resource incurrs no cost, so we're not really worried about assigning a `cost_center` to it + - This can be useful for mass tagging resources that are hard to figure out where the belong, such as EC2 Security Groups + +### `mojaloop/owner` + +`mojaloop/owner` is a person who is responsible for the managing and shutdown of a given resource. + +The goal of this tag is to prevent long running resources that everybody else thinks _someone else_ knows about, but we no longer need. By applying this tag, we will be able to have a list of _who to go to_ in order to ask questions about the resource. + +The value can simply be a person's name, all lowercase: +- `lewis` +- `miguel` +- etc. + +Once again, we will reserve the following values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/owner:unknown` tags and see what resources are 'orphaned' + + +## Manual Tagging + +We can use the "Tag Editor" in the AWS console to search for untagged resources. + +1. Log into the AWS Console +2. Under Resource Groups, select "Tag Editor" +![](./images/tagging_01.png) +3. From the tag editor, select a Region (I typically use "All regions"), and Resource Type (I also typically use "All resource types") +4. Now select "Search Resources", and wait for the resources to appear + +You can also search by tags, or the absense of tags to see what resources have not been tagged yet. +![](./images/tagging_02.png) + +5. Once you have a list of the resources, you can select and edit tags for many resources at once! +6. You can also export a `.csv` file of resources found in your search + + +## Automated Tagging + +We currently automate tagging on the following + +As we have a firmer grasp of our tagging guidelines, we need to introduce them into our tooling so that all of the grunt work of manual tagging. + +At the moment, this will look like introducing tags into: +1. Rancher - which currently manages our Kubernetes clusters for both QA and Performance purposes +2. IAC - The upcoming IAC code that will eventually be running our dev environments + + +## AWS Tagging Policies + +As of August 3, 2020, we have started introducing [AWS Tagging Policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) to better enforce tags and monitor our resources (especially with respect to costs). + + +### Viewing Tag Reports + Compliance + +1. Log in to the AWS Console +2. "Resource Groups" > "Tag Editor" +3. On the left sidebar, select "Tag Policies" + +From here you can see the tag policies "compliance report" + +![](./images/tagging_03.png) + + +### Editing Tag Policies + +> Note: This may require special admin priviledges to access these pages + +1. Log in to the AWS Console +2. Select "username@mojaloop" in the top right > "My Organization" +3. Select "Policies" > "Tag Policies" + +![](./images/tagging_04.png) + +4. From here, you can view the current tag policies + +![](./images/tagging_05.png) + +5. In the sidebar, you can click "View details" > "Edit policy" to edit the policy + + +### Attaching/Detaching Tag Policies + +1. Go to the "My Organization" page +2. Select the relevant account > "Tag policies" in the sidebar +3. From here you can Attach + Detach tag policies + +![](./images/tagging_06.png) diff --git a/docs/community/archive/discussion-docs/code-improvement.md b/docs/community/archive/discussion-docs/code-improvement.md new file mode 100644 index 000000000..2cc9a2ff6 --- /dev/null +++ b/docs/community/archive/discussion-docs/code-improvement.md @@ -0,0 +1,26 @@ +# Code_Improvement Project + +## Overview +The purpose is to improve code quality and security for the Mojaloop project. Includes analysis and introduction of new open sources tools, process improvments, gates checks (w/in pull requests and builds) along with documentation. + +Scope: project is focused on quality and security but can lead to other areas such as test automation and DevOps automation and tools. + +## OutPut (phase one by end of January): +- Implementation and analysis of new OSS tools +- Update Release Scripts: Security aspects need to be embedded in release/devops (CI/CD) +- Update rules for Pull Requests: Security aspects embedded in pull requests (before check-ins) +- Update documentations: Standards and contribution guides +  +Slack Channel:#code_security + + ## Discussions: + ### Implement changes at the Dockerfile and CI/CD build process to help bolster our container security + - Create a non-root user within the Dockerfile + - Enable docker-content-trust on the docker host (this will be inside CircleCI) + - Run builds with --no-cache during CircleCI step to ensure that we are pulling in any new security patches each time (I don’t think this is a major issue since we don’t have CircleCI docker image caching on anyway + + ### Move from Javascript to Typescript + - Transition to typescript (mix and match js and ts) for more security/quality + - Typescript is preferred but not required: https://github.com/mojaloop/template-typescript-public + + diff --git a/discussions/cross_border_day_1.md b/docs/community/archive/discussion-docs/cross-border-day-1.md similarity index 100% rename from discussions/cross_border_day_1.md rename to docs/community/archive/discussion-docs/cross-border-day-1.md diff --git a/discussions/cross_border_day_2.md b/docs/community/archive/discussion-docs/cross-border-day-2.md similarity index 100% rename from discussions/cross_border_day_2.md rename to docs/community/archive/discussion-docs/cross-border-day-2.md diff --git a/docs/community/archive/discussion-docs/cross-border.md b/docs/community/archive/discussion-docs/cross-border.md new file mode 100644 index 000000000..4deec6f8d --- /dev/null +++ b/docs/community/archive/discussion-docs/cross-border.md @@ -0,0 +1,396 @@ +**Cross-border Workstream Meeting** + +March 10th & 11th (London/remote) + +**Next Steps for PI:** + +• Proposal for how the CNP query and host oracle services and global goals - Adrian, Michael + +• Compound identifiers, ways in which this is captured in the system or expressed in apis - open + +• What information is captured in the data model or the extension list - Michael + +• Follow-up w/ SWIFT to discuss requirements - Matt + +**Open Items:** + +• Finalize CNP Requirements + +• Has to aggregate information and put them together into a single request & they will need to sign separately + +• Finalize FXP has to manage FX rates, the settlements and what expires when + +• CNPs can extend this and determine additional scheme rules + +• FXP handles rounding errors + +• FXP Guarantee a given rate + +• How do you get non-Mojaloop folks in the schema? + +• How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + +• How do we manage requests for regulatory reasons + +• Investigate identifier mappings (Map pathfinder accounts/mobile accounts to DFSP unique IDs) + +• Investigate Certification (Hash and PKKI) + + +Detailed Meeting Notes: +Day #1: + - Quote response + + ○ How do we code the SLA into the response + + ○ Ask a 2nd CNP to route + + ○ In the API - need to package up how to get it there + + ○ As a CMP in Mowali if I return a quote response the scheme has implications + + ○ Follow the whole route from payer to payee + + ○ Limiting the participation of CNP - they need to be the last hop + + § How to define the requirements of a CNP? + + - Message format + + ○ Http syntax + + ○ Started from the mojaloop scheme + + § Move towards the CNP should manage the conversion + + ○ SWIFT version + + ○ Security - TLS + + ○ Header/content encrypted in JWS + + - Retail system + + ○ Off network - remit to someone hub + + - Data Model + + ○ Structure: Ways in which we added new information, different routes, etc. + + ○ Privacy: Visibility and Security - only accessible to the people that can see it + + ○ Content of the data model + + - Transfer is done through the switch (movement of money) + + ○ In mowali - the amounts are expressed but the rate is important because it impacts settlements + + § Data flow - we add the rate when we send the quote back + + § Added in the extension list - should it be part of the standard? + + § Send and receive amount (differ currency) + + - Data element + + ○ Fee for each participant + + ○ Payer DFSP adds it up + + ○ Fee element for the transaction + + - Proposal + + ○ Account lookup service + + § List of local FSP + + ○ Switch - need to maintain state and lookup requests + + § Should look like a domestic transfer to the sender + + § Collect the information and send it back - + + ○ CNP - making assumptions to meet requirements + + § Do you need to see the route + + § Collecting different information downstream + + § Sending FSPs needs to know who is the receiver + + ○ CNP has to aggregate information and put them together into a single request & they will need to sign separately + + § Condition and fulfillment is part of a PKI structure + + § If there is more than one CNP - there needs to ensure the DFSP payee has to be certain the DFSP payer - connections + + § CNP needs to know everything, regulatory reporting - + + ○ Do we need to duplicate the structure in a Cross-network transfer? + + § Trying to prevent a rouge partner from joining + + § Trust the CNP to meet their SLAs + + ○ Mojaloop to another scheme - we don’t have control + + § Require they confirm receipt + + § How can I tell + + § How can I tell the person at the end got the money + + ○ External signing authority to confirm the money was received + + § If your scheme wants to participate in x-border then all the participants need to get signed + + § Public key - need to join a mojaloop network have to issue public keys + + § Central certificate issuing authority + + § Need a PKI structure in place + + ○ How do you get non-Mojaloop folks in the schema? + + § How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + + § Identify the participants - FSP, DFSP - all have signed + + § Parties - end users (Bob/Alice) + + § Single transaction (with multiple transfers) + + § No one commits their funds to everyone is satisfied + + § How to extend mojaloop and non-mojaloop scheme + + ○ Certification + + § Hash and PKKI + + § Gold and silver network + + § New partner - live on the network + + § Scheme decides requirement on the network + + § Self-signing cert + + ○ Liquidity + + § FXP does position mgmt + + § What requirements do we put on a FXP + + § Mobile money has less flexibility + + § Rules that happened across schemes + + ○ FXP has to manage the settlements, what expires when, etc.. + + § FXP has to manage the shortage of quote validity + + § Allow FXP to reject the requests + + ○ How do we manage requests for regulatory reasons + + § There is a dictionary + + □ Is the a requirement to share KYC? + + □ You can ask for many things - up to the participant + + □ Need to agree on the baseline scheme + +**Day #2:** + + - Switch data + + ○ Account numbers + + ○ Blacklist, white list (oversight and blocking) + + ○ Keeping it simple + + ○ Hub + + ○ Side service for folks that can do this + + § Mobile data capture + + § Side car + + § Digital process + + § Value added services for the hub (managed service) + + - Switch - need to maintain state and lookup requests + + - CNP can be an ordinary DFSP + + ○ All DFSP supports all the use cases + + ○ Full participants (might just provide a CNP or FXP service) + + - FXP definition and requirements + + ○ FXP - require rates/fees as part of the Quoting service - need standard industry rate + + § CNPs can extend this and determine additional scheme rules + + ○ FXP handles rounding errors + + ○ Guarantee a given rate + + ○ Manage settlement across schemas + + ○ FX rates + + ○ Should allow people that just do FX + + ○ Edge cases for failure + + § Details in the error messages to find the errors + + ○ FXP needs to point back the right information + + § How messages passed work + + § Edge cases - share what is done too date + + § Jo owns got a working API - identified + + § Changed the quote (intercepted the quote) -- + + § KYC extension list - extended the quote for this + + § Rates are in the extended list (are the list) + + § Where the FXP is applied ? + + § What do we do with fees downstream + + □ (payee DFSP takes place of the aggregation) + + - How to manage identifier resolution + + ○ 2 types of Identifiers + + § Global ones (pass to CNP) - to get a response + + § Local ones - expect the user to provide + + ○ Mojaloop we use identifiers as proxy + + ○ Merchant numbers might be specific to a scheme + + ○ Multiple identifiers for a single account + + ○ How do we uniquely identify the account? + + ○ Rely on CNP (restrict each identifiers in this scheme) + + ○ What sort of structures in place + + ○ Passport identification - place holders + + ○ Map pathfinder accounts/mobile accounts to DFSP unique IDs + + § Service - primary account is X + + § Each country has a service they provide + + § Each CNP understands the address scheme + + § Global one - need to know which ways to use + + ○ Sends a get parties to the switch + + § ALS never heard of them + + § 2 ways + + □ Global way (path finder and conversion to BIC) + - CNP + + ○ Not hosting anything + + ○ Route through the CNP - ask others + + ○ Constructing the alternative routes + + - Global registry does not exist + + ○ Ultimate beneficiary + + ○ Established communication + + ○ Challenge will we able to have 2 DFSPs share direct communication and will be a stretch? + + - Switch has schemes + + ○ A Hub operator following Scheme Rules may allow names of FSPs as decided by those Rules + + ○ The technology or the Admin API itself doesn’t restrict the names (apart from restrictions on length, type or characters, etc) + + ○ BGP: Border Gateway Protocol  + + - Query each CNP and then come up with optimizations, matrix that provides global route - goal would be not to query the CNP directly + +• How to connect with Mojaloop? + + - Any financial service can connect to Mowali + + - Scheme rules, technical + + - Regulatory + + - How do I assign stuff? - no one knows the steps + + - Mojaloop API - understand this. + + - 2 instances Mojaloop instances - TIPs and Mowali + + ○ WOCCU, Asia, US - applied for instance + + ○ Still pushing the boundries + + - What dos an integration look like + + ○ Need sandbox, simulators + + ○ Standard approach + +• Instance payment service + + - Get the flows flowing in a timely manner + + - Need real-time ledgers; what happens if they are offline? + + - Exception for off network (banks take advantage of float) + +• Discovery process (sending FSP) + + - Switch determines if they need to contact a FXP + + - What currency the receiving account can receive in + + - Multiple lookups + + - Data model - set of accounts, w/ one currency at a DFSP + + +Attendees: + + - Mike, Patricia - Thume + + - Michael R, Rob R, Sam - Modusbox + + - Kim, Lewis - Crosslake + + - Rolland, Greg, Phillip - Sybrin + + - Vanburn -- Terrapay + + - Megan, Simeon - Virtual diff --git a/discussions/images/cb_board_1.jpg b/docs/community/archive/discussion-docs/images/cb_board_1.jpg similarity index 100% rename from discussions/images/cb_board_1.jpg rename to docs/community/archive/discussion-docs/images/cb_board_1.jpg diff --git a/discussions/images/cb_board_2.jpg b/docs/community/archive/discussion-docs/images/cb_board_2.jpg similarity index 100% rename from discussions/images/cb_board_2.jpg rename to docs/community/archive/discussion-docs/images/cb_board_2.jpg diff --git a/discussions/images/cb_board_3.jpg b/docs/community/archive/discussion-docs/images/cb_board_3.jpg similarity index 100% rename from discussions/images/cb_board_3.jpg rename to docs/community/archive/discussion-docs/images/cb_board_3.jpg diff --git a/discussions/images/mojaloop_spokes.png b/docs/community/archive/discussion-docs/images/mojaloop_spokes.png similarity index 100% rename from discussions/images/mojaloop_spokes.png rename to docs/community/archive/discussion-docs/images/mojaloop_spokes.png diff --git a/docs/community/archive/discussion-docs/images/tagging_01.png b/docs/community/archive/discussion-docs/images/tagging_01.png new file mode 100644 index 000000000..4379443ce Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_01.png differ diff --git a/docs/community/archive/discussion-docs/images/tagging_02.png b/docs/community/archive/discussion-docs/images/tagging_02.png new file mode 100644 index 000000000..b86ac0a91 Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_02.png differ diff --git a/docs/community/archive/discussion-docs/images/tagging_03.png b/docs/community/archive/discussion-docs/images/tagging_03.png new file mode 100644 index 000000000..d8ab17646 Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_03.png differ diff --git a/docs/community/archive/discussion-docs/images/tagging_04.png b/docs/community/archive/discussion-docs/images/tagging_04.png new file mode 100644 index 000000000..a2913b226 Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_04.png differ diff --git a/docs/community/archive/discussion-docs/images/tagging_05.png b/docs/community/archive/discussion-docs/images/tagging_05.png new file mode 100644 index 000000000..ba54dbf64 Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_05.png differ diff --git a/docs/community/archive/discussion-docs/images/tagging_06.png b/docs/community/archive/discussion-docs/images/tagging_06.png new file mode 100644 index 000000000..8c4eb717f Binary files /dev/null and b/docs/community/archive/discussion-docs/images/tagging_06.png differ diff --git a/discussions/ISO_Integration.md b/docs/community/archive/discussion-docs/iso-integration.md similarity index 100% rename from discussions/ISO_Integration.md rename to docs/community/archive/discussion-docs/iso-integration.md diff --git a/docs/community/archive/discussion-docs/mojaloop-decimal.md b/docs/community/archive/discussion-docs/mojaloop-decimal.md new file mode 100644 index 000000000..119e51501 --- /dev/null +++ b/docs/community/archive/discussion-docs/mojaloop-decimal.md @@ -0,0 +1,38 @@ +# Mojaloop Decimal Type; Based on XML Schema Decimal Type + +## Decimal value type + + Definition: decimal represents a subset of the real numbers, which can be represented by decimal numerals. The value space of decimal is the set of numbers that can be obtained by multiplying an integer by a non-positive power of ten, i.e., expressible as _i_ × 10-n where _i_ and _n_ are integers and _n_ ≥ 0. Precision is not reflected in this value space; the number 2.0 is not distinct from the number 2.00. The order relation on decimal is the order relation on real numbers, restricted to this subset. + Req: All Level One processors must support decimal numbers with a minimum of 18 decimal digits. However, Level One processors may conform to a scheme-defined limit on the maximum number of decimal digits they are prepared to support, which must be 18 or more digits, in which case that scheme-defined maximum number must be clearly documented. + +## Lexical representation + +decimal has a lexical representation consisting of a finite-length sequence of decimal digits (#x30 – #x39) separated by a period as a decimal indicator. An optional leading sign is allowed. If the sign is omitted, "+" is assumed. Leading and trailing zeroes are optional. If the fractional part is zero, the period and following zero(es) can be omitted. For example: -1.23, 12678967.543233, +100000.00, 210., 452 + +## Canonical representation + + The canonical representation for decimal is defined by prohibiting certain options from the Lexical representation (§3.2.3.1). Specifically, the preceding optional "+" sign is prohibited. The decimal point is required. Leading and trailing zeroes are prohibited subject to the following: there must be at least one digit, which may be a zero, to the right and to the left of the decimal point. + + This canonical form conforms to XML Decimal lexical representation, so it would be accepted by any XML schema conforming system. + + What others write in canonical form, we can read as a lexical representation; what we write in canonical form, others can read as a lexical representation. But we reject exponential formats on reading and we won’t write exponential form. We can directly compare the canonical string representations of two values for equality. + + When exchanging messages, a lexical form that shows implied precision using trailing zeros is preferred to pure canonical form if it improves clarity. E.g. We might write “5.00” instead of “5.0” where the unit of exchange is commonly specified precise to two decimal places, as in USD, EUR, or GBP. This lexical representation option is permitted within valid lexical forms of both XML decimal and Mojaloop decimal. + +## Validators + + Decimal Lexical Validator (what our message receivers accept): + +```^[-+]?(([0-9]+[.]?[0-9]*)|([.]?[0-9]+))$``` + +Decimal Canonical Validator (the form we store and compare; this pattern could be used to assert canonical form in generated messages): + +```^([0]|([-]?[1-9][0-9]*))[.]([0]|([0-9]*[1-9]))$``` + +## Translating Between External and Internal Forms + + When converting from lexical or canonical form to a binary internal representation, the value space of the internal representation must be large enough to hold the scheme-specific range of decimal values, with a significand defined as the signed integer range –10_m_–1..10_m_–1, and a non-positive integer exponent in the range –_m_..0, where _m_ is the maximum number of decimal digits, at least 18, and as defined by the specific Level One scheme. + +An implementation must not translate between decimal external representations and any floating-point binary internal representation. And all calculations on internal representations of decimal values must produce results as if they were performed in decimal long hand on the external representation. + +It should be noted that the value space of a signed 64-bit binary integer is sufficiently large to encode a signed 18-digit decimal significand and the value space of a signed 6-bit binary integer is sufficiently large to encode its required non-positive base-ten exponent. diff --git a/docs/community/archive/discussion-docs/performance-project.md b/docs/community/archive/discussion-docs/performance-project.md new file mode 100644 index 000000000..58f3ee075 --- /dev/null +++ b/docs/community/archive/discussion-docs/performance-project.md @@ -0,0 +1,175 @@ +# Performance Workstream + +Wednesday, March 11, 2020 + +## Performance Goals: + +- Current HW system achieving stable 1k TPS, peak 5k and proven horizontal scalability + 1. More instances = more performance in almost linear fashion. + 1. Validate the minimum infrastructure to do 1K TPS (fin TPS) + 1. Determine the entry level configuration and cost (AWS and on-premise) + +## POCs: + +Test the impact or a direct replace of the mysql DB with an shared memory network service like redis (using redlock alg if locks are required) + +Test a different method of sharing state, using a light version of event-driven with some CQRS + +## Resources: + +- Slack Channel: `#perf-engineering` +- [Mid-PI performance presentation](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/March2020-PI9-MidPI-Review) +- [Setting up the monitoring components](https://github.com/mojaloop/helm/tree/master/monitoring) + +## Action/Follow-up Items: + +- What Kafka metrics (client & server side) should we be reviewing? - Confluent to assist +- Explore Locking and position settlement - Sybrin to assist + 1. Review RedLock - pessimistic locking vs automatic locking + 2. Remove the shared DB in the middle (automatic locking on Redis) + +- Combine prepare/position handler w/ distributed DB +- Review node.js client and how it impacts kafka, configuration of Node and ultimate Kafka client - Nakul +- Turn back on tracing to see how latency and applications are behaving +- Ensure the call counts have been rationalized (at a deeper level) +- Validate the processing times on the handlers and we are hitting the cache +- Async patterns in Node + 1. Missing someone who is excellent on mysql and percona + 2. Are we leveraging this correctly + +- What cache layer are we using (in memory) +- Review the event modeling implementation - identify the domain events +- Node.js/kubernetes - +- Focus on application issues not as much as arch issues +- How we are doing async technology - review this (Node.JS - larger issue) threaded models need to be optimize - Nakul + +## Meeting Notes/Details + +### History + +1. Technology has been put in place, hoped the design solves an enterprise problem + +2. Community effort did not prioritize on making the slices of the system enterprise grade or cheap to run + +3. OSS technology choices + +### Goals + +1. Optimize current system +2. Make it cheaper to run +3. Make it scalable to 5K TPS +4. Ensure value added services can effectively and securely access transaction data + +### Testing Constraints + +1. Only done the golden transfer - transfer leg +2. Flow of transfer +3. Simulators (legacy and advance) - using the legacy one for continuity +4. Disabled the timeout handler +5. 8 DFSP (participant organizations) w/ more DFSPs we would be able to scale + +### Process + +1. Jmeter initiates payer request +2. Legacy simulator Receives fulfill notify callback +3. Legacy simulator Handles Payee processing, initiatives Fulfillment Callback +4. Record in the positions table for each DFSP + - a. Partial algorithm where the locking is done to reserve the funds, do calculations and do the final commits + - b. Position handler is Processing one record at a time + +5. Future algorithm would do a bulk + +- One transfer is handled by one position handler + - Transfers are all pre-funded + +1. Reduced settlement costs +2. Can control how fast DFSPs respond to the fulfill request (complete the transfers committed first before handling new requests) +- System need to timeout transfers that go longer then 30 seconds + - Any redesign of the DBs + - Test Cases + +- Financial transaction + - End-to-end + - Prepare-only + - Fulfil only + +- Individual Mojaloop Characterization + - Services & Handlers + - Streaming Arch & Libraries + - Database + - What changed: 150 to 300 TPS? + +- How we process the messages +- Position handler (run in mixed mode, random + - Latency Measurement + +1. 5 sec for DB to process, X sec for Kafka to process +2. How to measure this? + +### Targets + +1. High enough the system has to function well +2. Crank the system up to add scale (x DFSPs addition) +3. Suspicious cases for investigations +4. Observing contentions around the DB +5. Shared DB, 600MS w/ out any errors + - Contention is fully on the DB + - Bottleneck is the DB (distribute systems so they run independently + + + +- 16 databases run end to end +- GSMA - 500 TPS +- What is the optimal design? + +### Contentions + +1. System handler contention + - Where the system can be scaled +1. If there are arch changes that we need to make we can explore this + - Consistency for each DFSP + - Threading of info flows - open question + +1. Sku'ed results of single DB for all DFSPs +1. Challenge is where get to with additional HW + - What are the limits of the application design +1. Financial transfers (in and out of the system) + - Audit systems + - Settlement activity + - Grouped into DB solves some issues + - Confluent feedback + +1. Shared DB issues, multiple DBs + +1. Application design level issues + +1. Seen situations where we ran a bunch of simulators/sandboxes + - Need to rely on tracers and scans once this gets in productions + - Miguel states we disable tracing for now + +### Known Issues + +1. Load CPU resources on boxes (node waiting around) - reoptimize code +2. Processing times increase over time + +## Optimization + 1. Distributed monolithic - PRISM - getting rid of redundant reads + 2. Combine the handlers - Prepare+Position & Fulfil+Position + +### What are we trying to fix? + 1. Can we scale the system? + 2. What does this cost to do this? (scale unit cost) + 3. Need to understand - how to do this from a small and large scale + 3. Optimized the resources + 4. 2.5 sprints + 5. Need to scale horizontal + 6. Add audit and repeatability - + +### Attendees: + +- Don, Joran (newly hired perf expert) - Coil +- Sam, Miguel, Roman, Valentine, Warren, Bryan, Rajiv - ModusBox +- Pedro - Crosslake +- Rhys, Nakul Mishra - Confluent +- Miller - Gates Foundation +- In-person: Lewis (CL), Rob (MB), Roland (Sybrin), Greg (Sybrin), Megan (V), Simeon (V), Kim (CL) diff --git a/docs/community/archive/discussion-docs/psip-project.md b/docs/community/archive/discussion-docs/psip-project.md new file mode 100644 index 000000000..6fe8e448d --- /dev/null +++ b/docs/community/archive/discussion-docs/psip-project.md @@ -0,0 +1,21 @@ +# PISP (3rd party payment initiation) + +## Goal: + +Updated Mojaloop specification documents, and POC implementation of a PISP + + +## Action Items: + +- Revisit /authorizations resource: [Michael] and raise with CCB +- Identity provider research and follow-up: [Matt de Haast] +- Share all sequence diagrams: [JJ] +- Outline proposal at high level including new API calls - Unassigned +- Mapping account information (info about accounts for PISP) - [Lewis] + +## Links: + +- [London Meeting Notes](./pisp_meeting_march_2020.md) +- [WIP Separate Docs Repo with sequence diagrams](https://github.com/jgeewax/mojaloop-pisp) +- [End to End Sequence Diagram](https://plantuml-server.kkeisuke.app/svg/xLhhRnkv4V--VmKX571iI8eaEx4Z875aoyu9Tt44hz8WWFg1sgMaFQz87ScreXRvtpl3nxuaEx7H5bVW0kJXvN1cE9pvpODvhpILEbkbWKvqoiXu58w9bfIhEPDa9MAMJlcBJ2LyGJuo6Iqfr-IM_P4nfOaMP4otv2DI7GOqqaAImPQf9ILKaSj1i0RUIPIiSLF3i1wirmrSXB_th8PCtZC90eVNuVZG40wxLRfma-XeQPR2wihWjz2o9ZNET0j7GOwECHaurhrTGbOXl724n-vmZOiblOVpmVh5-r2is6R99BD4bnS15veH0IS0rIRBH96r56kXQ4fYmHI1PIB1T8ba10svW6zWmi5uH82tCWTh1oXOaSrIa5mvu9fmefUCg6Z9LeniaZGbdB4Ozw_e7IDw8ppFVj0z9AEveSzl4fH9UA8Ju1MJsPPGSzDD4edrrb3-aQ7oagcru8eXN_oAH47l6UnoohqSVnEB9C8lCqOoPOz1LSIafd1GC2fGIZGAcko7WiV04RwhfTXmD5IQSDOEHXg9gLBP2WKigUu7hNU4WkMYJ6cuF4be1imv69dgH72aZwYK2T2BJ1DXRUwf3nI9sNqICMHZt2FETC9G8JXbQbbWI9H323I0suxP77IAQxSeinHsKmxIrap2VeYnHPP0C06n2XWie4S5Rz-IOQ8YTAmjUVisk1oqta7yz4Ta8x8qXlFUMVCwcLF-jswdWrzAJeeUdDoZAs7emU_Mks6txwBrMNmWCeVTbbNb0znJejj1p2fYO1sbV07Zet6jDB3ZseJa7TkUJ_b8muV1-wjKEG6uAOGzIRIqPePhhL30fXT7Hn-k9kIb2H6cZeuE2xr24eGj8xVNwVN9w01kVC4qcT7e3W-p5LbPJpX628TuL639U2GOj50_exP5aygfaHc8jYj4hHczKsIEm5WwueuDGz2rGpxzsYGBOyaoIpXF0IomOUAYY2Y3bWPR-87EyU2EYqrWvE1F2jq8dGvilW9VxyCFS1M880547q16dC8-gWpS454BzBaKgy0TqpiaUU2AIbxob2jwzWsLvJrwGnUxDtJS7nevzeRC1Urd1zW_F7Otz6DLGoH6xhTC0uxS5-W1iGz2LXObZ3YRIio6iFyBI0LrtKSC4S0EmI5rbFRj6l3u4Ry1pH_onT9HftooB6kPw_149pK-WL0GRfLcAq34jP1QJNdEcbF0l7tySq2w7FGd01M57Pf49ekbFaV8izo_CjK4qS0dnx3BakvBkZO92F16BS6WKux-Zy3gqe_X1yf1MaqW6kg0LGcqK82xRyZ8H1IP2RqqB6131lVY_BhleWEbkp1prOPTk2WlsEeYk35SVRnALqqvFdb6BsAsI0KsyCOfev1HgRehRQgXDWQkByOGmUj6_t48abeCLgiRvWeMj2LBxZ6HaHLJYYwOjNyg17YRpIb0BJY3R9-A3MRc0wI6ofF7LCPGF_vEWNhjzmVZJo40XpaGAY2uApWL-MKo6R_ijhi177lqQTmAHIOZrhTLXVis1Cg4cu3fU_i4_me8_6hiyXp5ZJvfdCN79_CttRWLTqxFMYUTqzFMMU_rSQiNTKvEpqvVpwFvwqRJyZ0N2PiiI_T9wkqe7a6eLXRAYvFj6dT1cJeQX8vNdGPhaNd29DALOhJH95NokLfRlQsBDVBLx-PVtqkQofgc3bRsgng9rJfbtsuWKdSMhU14AksM6zQxQaSnP2ajg2RqBg6D2ittGj_cVzU8fQHRfwxQSF2G3UbAP5nxkRTNbrUZlryrAejL2-VV6X269Q6DA9EIyMYBIv_3OQCYfkIOJbQ99LJ6dCf467FU3cx2wwlRCcTN4GjpvF7WwmEh_X2Ndsx2pn-1gA81XdTng-G-iJMzFohxjawa2Iea0ipej3gzLlVLfDVhTq_xlRFscxDNhKwt3uSsE_uHV2zL327YLWXAC5j_ED0p6Qht7m4qwEQ6lQSawfuHlKSdgBS72yaOGYyPBr4pgBgHFeTUQEpkeL0dfXU3l41D_rGaTyFF7w04kXPpUpzNzlGga3jOG6_Kj9oniI4sM3LBjmMK-YxE7kG6Vp1WZ1cJHsaMCrNKTpKSj1OsM0rPCi7QmpEgeQsh1n_4smiFjqOT6sMdKU-OdNMYdq7OadOEdb_DmIwzUUlupQpNEddJdRNEkgUiTK8xnxtESNmoxvxisVn_1V5_8VnV2FyaX2TFXlWdONWDlQ7LSDXdCSOCH_8H5rQoEsZtpDPf3Aq3bIoVIjdMfsYJV45Th3srBIh3AjRY6rOTfb4tIiCFIrY7W_85zCn2tc57q0w-i5BrZdsEW-LIYrSQTpK39N8OZYZl1_IGVEOn12hYjgtqfO2KerIz0GzcX-JMYd3ZACtaQeUCl63jHPlC6LE7NhHll8hkmIRRkWsBgT_-PFf8osTJw4ZPurFRuxIA0PrXZxE0fCtQTWXQICK43dlsuVNvOK1JJMw4w_NuWVR2XjYKcGi960G-AHh2jYUvJfnHpLJEkwOLaQUqikxbvimEwB1LfSenCHjSKtTk5DiZT9BdvReH_1srfxok_Cu1m_wra1lCv3-OoUuhAIeNjJEBnWdfbclS6D4KYePiaMwRq9D5D0FcPXQon3aWpfAmQmueEJeQVvuS7H7sBM9hRGUTXJBKswPDBZ8DKOGH3a4Yjm6TuG3Lze6WfMotsrKtxFg9Ht5Er00gGB0OHD6JHsH-r3YvFlV__hHi0dqRMcq8EZYIguMA2ieVPihDQKepQtSiWrdOo99iNHzhEpUoedmLwSzYYiAz6wezTQMenFAt7BXeutkQ9Z7LhC9iojri3UVNKApzqq2EUhalb8wEdbz-selwNsbNlkYVIXVMz1-0PbMsFIX4TulmoetX9Cd0eCyp5bHn4uYHvP7_Rbhpuwh7vvT-eFMOc18oU2CN3n8c8AHYwTmy4KI2Gscs0bT57uQb0ydyk4jW-eWW8ULF0owuLbio1x1XSYqJRlnvjRjdPuu67Gy18cXnM5oetIwc_Gy7eX_wXrLkJddFBdSKyp3WqWBSbPyVcOZ3oH6aZh4KCpe3kFezKte7dFqECm_Vm4S0BjsSSYY2uPpADsSp1ZU07dl7J6PsdgaOub8zFBgF5GzTbqH_udZFpAO5bDHTb_1iDSDNA-m4bKPNg7HoVdsHt3FktvfCJBHnokkc_kxDRPwb-D36gvAWFO3BC7wCRV34Vy-xuDA0jES7fFcppepoEpCiLVa8jcgV8F-yeLoRrq_VnLRrADSwWPZ39_lSLyp7CHct2SuXZLH4-0LSx99HI5mGBzvcPRRcKR1mDsSXZZKR68D2DiITK0skayY27LmoP3C0VsFpmc0gYo9mFJHYyLZkVD5C4inCD0v0vThZIQcE6LLAeF95KwL4PAg7ANUfn4EPlUhpwaLyOOW6xZnVyGR5joPHK5qmsIHmFUsg_6gPyVXRxGyhZOT75iRdj11_vje3Id2TxTRJVxvYPCftgf5AhL5r438QJhbnPpHmOlwlnjpNnG_cn3pU3PJcFhx_gUOhfh1vncF05Kno1JrSi1SXRPVauhPTFEHCbXYsQ6RphBtAyFy-r3995NZHBV3tU_WZMwN_1W00.svg) +- [Initial PISP Design Doc, v5](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/January%202020%20OSS%20Community%20Session/%5BEXTERNAL%5D%20Mojaloop_%20PISP%20Credit%20Transactions(3).pdf) diff --git a/docs/community/archive/discussion-docs/versioning-draft-proposal.md b/docs/community/archive/discussion-docs/versioning-draft-proposal.md new file mode 100644 index 000000000..33e36e143 --- /dev/null +++ b/docs/community/archive/discussion-docs/versioning-draft-proposal.md @@ -0,0 +1,281 @@ +--- +Authors: Lewis Daly, Matthew De Haast, Samuel Kummary +Proposal Name: Mojaloop Versioning Proposal +Solution Proposal Status: Draft +Created: 26-Feb-2020 +Last Updated: 17-Mar-2020 +Approved/Rejected Date: N/A +--- + +# Mojaloop Versioning, A Proposal + +_Note: This document is a living draft of a proposal for versioning within Mojaloop. Once the proposal is ready, it will be submitted to the CCB for approval._ + +## Overview + +The aim is to produce a proposal that keeps the versioning Scheme simple to use and clear regarding compatibility issues. However, it needs to include all the details needed for a Mojaloop ecosystem as well. + +Goal: +Propose a standard for a new 'Mojaloop Version', which embodies: +1. Helm: Individual Service Versions, Monitoring Component Versions +2. API Versions: FSPIOP API, Hub Operations / Admin API, Settlement API +3. Internal Schema Versions: Database Schema and Internal Messaging Versions + +## Versioning Strategies/Background (Literature Review) + +How do current systems handle versioning? Give a brief overview of the current space. +* Most best practices follow semantic versioning for APIs, this will be covered more in [#1198](https://github.com/mojaloop/project/issues/1198) + +### Demonstrates zero-downtime deployment approaches with Kubernetes [5] + +Key observations: +* in order to support rollbacks, the services must be both forward and backwards compatible. +consecutive app versions must be schema compatible +* 'Never deploy any breaking schema changes', separate into multiple deployments instead + +For example, start with a PERSON table: +``` +PK ID + NAME + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +And we want to break this down (normalize) into 2 tables, PERSON and ADDRESS: + +``` +#person +PK ID + NAME + +#address +PK ID +FK PERSON_ID + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +If this change were made in one migration, 2 different versions of our application won't be compatible. Instead, the schema changes must be broken down: +1. Create ADDRESS table + * App use the PERSON table data as previously + * Trigger a copy of data to the ADDRESS table +2. The ADDRESS now becomes the 'source of truth' + * App now uses the ADDRESS table data + * Trigger a copy of new added to address to the PERSON table +3. Stop copying data +4. Remove extra columns from PERSON table + +This means for any one change of the database schema, multiple application versions will need to be created, and multiple deployments must be made in succession for this change to be made. +* [5] also notes how simple Kubernetes makes deploying such a change + * rolling upgrade deployments + * Tip: make sure your health endpoint waits for the migrations to finish! +* Q: so how do we make big changes that touch both the database schema and the API? + * this seems really hard, and would need a lot of coordination + * If we don't design it correctly, it could mean that a single schema change could require all DFSPs to be on board + * This is why I think the API version and Service version should be unrelated. We should be able to + deploy a new version of a service (which runs a migration), and supports an old API version + + +### Using a schema registry for Kafka Messages [6] + +* [6] suggests some approaches, such as using a schema registry for kafka messages, such as [Apache Avro](https://docs.confluent.io/current/schema-registry/index.html) +* This adds a certain level of 'strictness' to the messages we produce, and will help enforce versioning +* Adds a separate 'schema registry' component, which ensures messages conform to a given schema. This doesn't really + help enforce versioning, and leaves the work up to us still, but does give more guarantees about the message formats. + +### Backwards and Forwards Compatibility [3], [4] + +* "The Robustness principle states that you should be “liberal in what you accept and conservative in what you send +”. In terms of APIs this implies a certain tolerance in consuming services." [3] +* Backwards Compatibility vs Backwards Incompatibility [4]: + * Generally, additions are considered backwards compatible + * Removing or changing names is backwards incompatible + * It's more something to assess on a case-by-case basis, but [Google's API Design Doc](https://cloud.google.com/apis/design/compatibility) helps lay out the cases. + +## Mojaloop Ecosystem +When discussing versioning we need to be clear that we are versioning interfaces for various parties. + +# Proposal +The following section will outline the versioning proposal. + +## A “Mojaloop Version” +A Mojaloop Version **x.y**.z can be defined that can encompass the versions of all the three APIs included (detailed below). +In the version **x.y**.z, ‘x’ indicates the Major version and ‘y’ a minor version, similar to the Mojaloop FSPIOP API versioning standards; ‘z’ represents the ‘hotfix’ version or a version released with the same major, minor version x.y but to keep things simple, there is a need to bundle all the components included in the Mojaloop ecosystem indicating what all items are included there. + +In effect we may say Mojaloop version **x.y** includes +1. Mojaloop FSPIOP API + * Maintained by the CCB (Change Control Board) + * Uses x.y format + * Currently version v1.0, v1.1 and v2.0 are in the pipeline +2. Settlement API + * Maintained by the CCB + * To use x.y format + * Currently version v1.1 and v2.0 is in the pipeline +3. Admin / Operations API + * Maintained by the CCB + * To use x.y format + * Can use version v1.0 +4. Helm + * Maintained by the Design Authority + * Uses x.y.z format + * PI (Program Increment) + Sprint based versioning. + > *Note:* _PI + Sprint based versioning_ make sense in the context of the current Mojaloop Program Increments, but will need to be revised at a later date. + * Bundles compatible versions of individual services together +5. Internal Schemas + * Maintained by the Design Authority + * DB Schema x.y + * Internal messaging Schema (Kafka) x.y + +| **Mojaloop** | x.y | | | +|---|---|---|--- +| | Owner/Maintainer | Format | Meaning | +| **APIs** | | | | +| - FSPIOP API | CCB | *x.y* | Major.Minor | +| - Settlement API | CCB | *x.y* | Major.Minor | +| - Admin/Operations API | CCB | *x.y* | Major.Minor | +| Helm | Design Authority | *x.y.z* | PI.Sprint.Increment | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *x.y* | Major.Minor | +| - Internal Messaging | Design Authority | *x.y* | Major.Minor | + + + +For example: Mojaloop 1.0 includes +1. APIs + * FSPIOP API v1.0 + * Settlements API v1.1 + * Admin API v1.0 +2. Helm v9.1.0 + * Individual services' versions + * Monitoring components versions +3. Internal Schemas + * DB Schema v1.0 + * Internal messaging version v1.0 + +| **Mojaloop** | v1.0 | | | +|---|---|---|--- +| | Owner/Maintainer | Version | +| **APIs** | | | | +| - FSPIOP API | CCB | *1.0* | +| - Settlement API | CCB | *1.1* | +| - Admin/Operations API | CCB | *1.0* | +| Helm | Design Authority | *9.1.0* | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *1.0* | +| - Internal Messaging | Design Authority | *1.0* | + +### Advantages + +1. The advantage of this strategy is primarily simplicity. A given version say - Mojaloop v1.0 can just be used in + discussions which then refers to specific versions of the three APIs - FSPIOP, Settlements, Admin APIs, along with the Helm version that is a bundle of the individual services which are compatible with each other and can be deployed together. +Along with these, the Schema versions for the DB and Internal messaging to communicate whether any changes have been made to these or not since the previously released version. +2. The other advantage, obviously, is that it caters for everyone who may be interested in differing levels of details +, whether high level or detailed. Because of the nature of the major and minor versions, it should be easy for Users and adopters to understand compatibility issues as well. + +### Compatibility +As described in [section 3.3 of the API Definition v1.0](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning), whether or not a version is backwards compatible is + indicated by the **Major** version. All versions with the same major version must be compatible while those having different major versions, will most likely not be compatible. + +_Important Note: Hub operators will likely need to support multiple versions of the FSPIOP API at the same time, in order to cater for different participants as they can't all be expected to upgrade at the same time._ + +## Breaking down the “Mojaloop Version” +This section aims to break down the above proposed mojaloop version into its constituent parts, and provide support for the above proposed versioning strategy + +### APIs + +The [Mojaloop Spec](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning) already outlines many of the decisions made around versioning APIs. + +In terms of common best practices, there are many approaches for requesting different versions, including adding in a + version in the url, but let's not worry about this because the spec already lays this out for us, using the HTML vendor extension: [3.3.4.1 Http Accept Header](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3341-http-accept-header) + +As for version negotiation, the spec also states that in the event of an unsupported version being requested by a + client, a HTTP status 406 can be returned, along with an error message which describes the supported versions. [3.3.4.3 Non-Acceptable Version Requested by Client](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3343-non-acceptable-version-requested-by-client) + +Another best practice around versioning is specifying to what level clients may request specific apis. +* In a development environment, many APIs will allow specificity up to the BUGFIX version, i.e. vX.X.X +* In production however, this is limited to Major versions only, e.g. v1, v2 +* e.g. The Google API Platform supports only major versions, not minor and patch versions +* Given the new features that may become available with v1.1 of the Mojaloop API, we might want to allow participants + to specify MAJOR and MINOR versions, i.e. vX.X. This practice should be avoided however, since minor versions should be backwards compatible + +Participants using the same MAJOR version of the API should be able to interact. Participants on different MAJOR +versions are not able to interact. For example, a participant on API v1.1 can send transfers to another participant on v1.0, but not to a different participant on v2.0. + +### Helm +This section deals with how Mojaloop services interact within a given deployment. Here, we attempt to propose questions such as "should an instance of central-ledger:v10.0.1 be able to talk to ml-api-adapter:v10.1.0? How about ml-api-adapter:v11.0.0?"? or "how do we make sure both central-ledger:v10.0.1 and central-ledger:v10.1.0 talk to the database at the same time?" + +There are two places where this happens: +1. Where services interact with saved state - MySQL Percona Databases +2. Where services interact with each other - Apache Kakfa and (some) internal APIs + +This implies we need to version: +* the database schema +* messages within Apache kafka + * need to make sure the right services can appropriately read the right messages. E.g. Can mojaloop/ml-api-adapter:v10 +.1.0 publish messages to kafka that mojaloop/central-ledger:v10.0.1 can understand? + * Q: If we decide to make breaking changes to the message format, how can we ensure that messages in the kafka streams + don't get picked up by the wrong services? + +### Internal Schemas + +#### Database + +todo: anything to be said here? + +#### Kafka/Messaging +Currently, we use the lime protocol for our kafka message formats: https://limeprotocol.org/ + +Also refer to the mojaloop/central-services-stream readme for more information about the message format. + +The lime protocol provides for a type, field, which supports MIME type declarations. So we could potentially handle messages in a manner similar to the API above (e.g. application/vnd.specific+json). Versioning messages in this manner means that consumers reading these messages would need to be backwards and forwards compatible (consecutive message versions must be schema compatible). +* Q. does it make sense to put the version in the Kafka topic? + * One example, ml-api-adapter publishes messages to the prepare topic + * If we add versioning to this, ml-api-adapter:v10.0.0 publishes messages to a prepare_v10.0 topic, and a new instance + of the ml-api-adapter:v10.1.0 will publish to the prepare_v10.1 topic. + * subscribers can subscribe to whichever prepare topic they want, or both, depending on their own tolerance to such + messages + * This may have some serious performance side effects +* Another potential option would be to allow for a message 'adapter' in the deployment. Say the ml-api-adapter:v10.1.0 is producing messages to a prepare_v10.1 topic, and there is no corresponding central-ledger in the deployment to read such messages, we could have an adapter, which subscribes to prepare_v10.1, reformats them to be backwards compatible, and publishes them to prepare_v10.0 in the old format. + +Such an approach would allow for incremental schema changes to the messaging format as services are gradually upgraded. + +All in all, I didn't see too much about this subject, so we'll likely need to return later down the line. + +## Version Negotiation +todo: @sam Discuss how to deal with version negotiation strategy + +## Long Term Support +todo: Discuss how long term support fits into the versioning proposal. I don’t think we want to get into too much detail, but more outline what it might look like + +Mention current (lack of) lts support, current PI cadence + +## Appendix A: Definitions + +* **service**: Mojaloop follows a microservices oriented approach, where a large application is broken down into smaller + micro services. In this instance, Service refers to a containerized application running as part of a Mojaloop deployment. At the moment, this takes the form of a Docker container running inside of a Kubernetes cluster. e.g. mojaloop/central-ledger is the central-ledger service +* **service version**: The version of the given service. This currently doesn't follow semantic versioning, but may in the + future e.g. mojaloop/central-ledger:v10.0.1. The current approach is described in more detail in the [standards + /Versioning doc](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/versioning.md). +* **helm**: Helm is an application package manager that runs on top of Kubernetes. It may also be referred to as the + "deployment". A single helm deployment runs many different services, and MAY run multiple versions of the same service simultaneously. We also refer to the deployment as it's repo, mojaloop/helm interchangeably. +* **helm version**: A helm version is the version of the packaged helm charts, e.g.mojaloop/helm:v1.1.0 +* **interface**: An interface is the protocol by which a Mojaloop switch interacts with the outside world. This includes + interactions with Participants (DFSPs) who transfer funds through the switch, hub operators running a Mojaloop switch, and admins performing administrative functions. +* **api**: Application Programming Interface - in most cases referring to the FSPIOP-API a.k.a. Open API for FSP + Interoperability defined [here](https://github.com/mojaloop/mojaloop-specification). +* **api version**: The Version of the FSPIOP-API, e.g. FSPIOP-API v1. For the purposes of this document, it refers to the + contract between a Mojaloop Switch and Participants (DFSPs) who implement the FSPIOP-API + +## References + +[1] LTS versioning within nodejs. This is a great example of an LTS strategy, and how to clearly communicate such a strategy. +[2] Semantic Versioning Reference +[3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ +[4] https://cloud.google.com/apis/design/compatibility +[5] Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway +[6] Stackoverflow - Kafka Topic Message Versioning + diff --git a/docs/community/archive/discussion-docs/workbench.md b/docs/community/archive/discussion-docs/workbench.md new file mode 100644 index 000000000..7a035d746 --- /dev/null +++ b/docs/community/archive/discussion-docs/workbench.md @@ -0,0 +1,246 @@ +# Mojaloop Lab/Workbench Discussion + +___Goal:__ This discussion document aims to lay out the case and align the community around the development of an educational Mojaloop Lab environment._ + + +## 1. Goals for the PI8 Convening: + +1. Define terms and outline assumptions +2. Outline existing efforts and how the OSS Community aligns with them (GSMA, MIFOS, ModusBox) +3. Define users and usecases, and exclude the users we won't worry about +4. Recommendations for a few different solutions to the "Lab Problem" + - Documentation around business cases and personas Dan developed + - Basic implementation of Lab Configurer, help people build labs with different features + - Simple Mojaloop-over-spreadsheets demo, to get people using mojaloop without Postman +5. Basic implementation and demo +6. Pose important questions and discuss next steps + +## 2. Nomenclature + +**1. Tools:** +- 1.1 A device used to carry out a function +- 1.2 Different tools for different functions: You wouldn't use a screwdriver to drive a nail. +- 1.3 In a Mojaloop context, one example of a tool is the Bank Oracle + - The Bank Oracle is a tool that plugs into the Account Lookup Service, can be used to allow Mojaloop to connect to existing bank accounts with an IBAN + +**2. Workbench:** +- 2.1 Combines different tools together in one place +- 2.2 For example, a hand plane, table saw and chisel can make up a woodworking workbench, while a hacksaw, file and angle grinder can make up a metalworking workbench +- 2.3 In the mojaloop parlance, tools to test my DFSP's JWS keys are in a different workbench than tools that demonstrate to a fintech how wholesale api's can work on top of Mojaloop + +**3. Lab:** +- 3.1 A lab is a place you go to run experiments +- 3.2 We run experiments in order to learn, and test our assumptions + - For example, a DFSP can set up and run an _experiment_ where they send and receive Quotes using an in-development API +- 3.3 A single lab combines multiple workbenches together in one place + +**4. Simulator:** +- 4.1 A tool that simplifies or abstracts away some function so you can test one thing at a time +- 4.2 Pilots train with simulators _before_ flying a real life, dangerous and expensive plane. +- 4.3 Within Mojaloop: a simulator can simulate interacting with some component of the system + - Replace an entire switch to test a DFSP implementation + - Simulate 2 DFSPs to test a switch deployment + - A simulator also reduces the need for someone to be with the person testing. So a DFSP can send and receive via the switch, without interaction with the Hub Operator. + + +## 3. Assumptions + +>_Some of these may go without saying, but it's worth noting them here anyway._ + +- 1\. The Gates Foundation wants to encourage adoption for Mojaloop at all levels (not just switches) +- 2\. We don't need a lab environment to serve the needs of a Switch deployment or implementing DFSP - these needs will be met elsewhere +- 3\. The Mojaloop OSS Community wants to make itself attractive + - This doesn't mean removing all barriers to entry; but assessing which barriers we should be removing + + +## 4. Users + +We divide users in 2 camps: Primary users and Secondary users. + +### 4.1 Primary Users +1. DFSPs needing to integrate with Mojaloop: (shorthand: Implementing DFSP) +2. Organisations/Individuals wishing to learn about Mojaloop and wanting to build and test functionality or use cases as a DFSP (shorthand: Evaluating DFSP) +3. Organisations/Individuals wishing to learn about Mojaloop and wanting to build and test functionality or use cases as a Hub Operator (shorthand: Evaluating Hub Operators) +4. Regulators, Organisations or Individuals wishing to understand and evaluate Mojaloop and how it might impact their existing service (shorthand: General Evaluators) + +### 4.2 Secondary Users +5. Systems Integrators wishing to offer Mojaloop as a Service or pieces of Mojaloop integration as a Service (Systems integrator) +6. Individual Contributors (including bug bounty hunters?) (Individual Contributor) +7. Fintechs operating on top of or who will operate on top of a mojaloop-enabled switch (Mojaloop-powered fintech) +8. 3rd Party App Provider interacting with wholesale mobile money APIs, selling integrations to fintechs and the like (3rd party app provider) +9. Financial Advocates, who are interested in promoting Mojaloop and other technologies that help drive financial inclusion (Financial Inclusion Advocates) + +In addition to thinking of each of the above users, it's important to understand at what level these users exist at in relationship to a mojaloop deployment. For that we will borrow from Dan Kleinbaum's [_Fintech primer on Mojaloop_](https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb) + +![the 3 levels of mojaloopyness](./images/mojaloop_spokes.png) +>_The 3 levels of Mojaloopyness, https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb by Dan Kleinbaum_ + +**Level 1:** Running a Mojaloop switch (e.g. Hub Operators) +**Level 2:** Interacting with a Mojaloop Switch directly (e.g. DFSPs, Systems Integrators) +**Level 3:** Interacting with a DFSP over a Mojaloop Switch (e.g. Fintechs) + + +## 5. Use Cases + +__a.__ Test a Mojaloop compatible DFSP implementation +__b.__ Validate assumptions about Mojaloop +__c.__ View and use a reference implementation +__d.__ Learn about Mojaloop internals +__e.__ Learn about Mojaloop-enabled switches and associated use cases (technology) +__f.__ Assess how Mojaloop will change fintech business landscape +__g.__ Be able to demonstrate a value proposition for DFSPs/Fintechs/etc. to use mojaloop (instead of technology _x_) + + +## 6. User/Use Case Matrix: + +We can plot the users and use cases in a matrix: + + +| __Usecase:__ | a. Test DFSP Impl | b. Validate Assumptions | c. Reference Impl | d. Learn Internals | e. Learn about Tech | f. Evaluate Business Cases | g. Demonstrate ML Value | +| :----------------------------------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| __User:__ | | | | | | | | +| __1. Implementing DFSP__ | X | | X | | | | | +| __2. Evalutating DFSP__ | | X | X | | X | X | | +| __3. Evaluating Hub Operator__ | | | X | | X | X | | +| __4. General Evaluator__ | | | | | X | X | | +| __5. Systems Integrator__ | X | X | X | X | | | X | +| __6. Individual Contributor__ | | X | X | X | | | | +| __7. Mojaloop-powered fintech__ | | X | | | X | X | X | +| __8. 3rd Party App Provider__ | | | | X | | | X | +| __9. Financial Inclusion Advocates__ | | X | | | | X | X | + + +## 7. Usecase Inputs and outputs: + +>_Pick 2 or 3 different users/usecases and drill down into the inputs and outputs for what meeting their needs may look like_ +>>_Note: As with anything of this nature, a lot of the users/usecases and associated conclusions are somewhat squishy, and can likely be put into different or altogether new boxes. Nonetheless, we will try to define these as well as possible._ + +### 7.1 Evaluating Hub Operator + Implementing DFSP +As stated in our above assumptions, we aren't going to worry about Hub operators and Implementing DFSPs here. + +### 7.2 Evaluating DFSP + +>_We think of an evaluating DFSP as one who is not necessarily part of a current switch implementation, but a party who is mojaloop-curious, and a potential candidate to evangelize mojaloop to - without the tangible goal of a switch implementation in sight._ + +**7.2.1 Use cases:** +- 1\. Validate assumptions about Mojaloop (how it works, what it does, what it _doesn't_ do) +- 2\. View and play with a reference implementation +- 3\. Learn about mojaloop-enabled hubs and associated use cases (technology perspective) +- 4\. Assess how Mojaloop will affect their business in the future + +**7.2.2 Examples from our user personas:** +- 1\. Carbon - Enable cash-outs and OTC remittances over their agent network +- 2\. Ssnapp - Enable multi payer/payee payments and rewards points over mojaloop +- 3\. Oneload - Simplify onboarding for other DFSPs to utilize OneLoad's agent network +- 4\. Juvo - Plug in to a Mojaloop switch for a credit scoring and lending marketplace + +**7.2.3 Outputs: (How can the Mojaloop OSS Community better serve these players?)** +- 1\. help to onboard to the mojaloop ecosystem +- 2\. help to understand the technology, where it works well, and the potential pitfalls/drawbacks +- 3\. minimize investment in getting things working so they can focus on building out use case prototypes +- 4\. take them from little to no understanding of Mojaloop -> demonstrating real prototypes + +**7.2.4 Inputs: (what are the things that we need to do to meet these goals)** +- 1\. Improved mojaloop documentation specific for this role. + - 1.1 Think about and design the documentation and onboarding flow specifically for *Evaluating DFSPs* + - 1.2 Documentation should be approachable by product manager etc. with little technical knowledge +- 2\. Technical deep dive on the technology behind mojaloop, why, how it works (perhaps we can repurpose the js demonstrator in an interactive walkthrough an end to end transaction) +- 3\. Improved guides for up and running on 2-3 major kubernetes providers, self service and install scripts +- 4\. Helm charts for 1-2 simulators/labs that can be spun up alongside a switch, with opinionated pre-configured settings + + +### 7.3 Mojaloop Powered Fintech + +>_A Mojaloop Powered fintech is a fintech operating or wishing to operate on top of a mojaloop switch. There will definitely be crossover between Fintechs and DFSPs in this classification, but we will focus here on fintechs who are at the third level on the above "Mojaloop Spokes"_ + +**7.3.1 Use cases:** +- 1\. Validate assumptions about Mojaloop (how it works, what it does, what it _doesn't_ do) +- 2\. Learn how mojaloop is aligned with wholesale APIs, and what it would take to get a DFSP using these APIs over a Mojaloop switch +- 3\. Learn about mojaloop-enabled hubs and associated use cases (technology perspective) +- 4\. Assess how Mojaloop will affect their business in the future + +**7.3.2 Examples from our user personas:** +- 1\. EastPay - compare and shop around for banks/payment providers based on Mojaloop's open fee structure +- 2\. Jumo - Open up transparent and fairer lending markets on top of a Mojaloop enabled switch? + +**7.3.3 Outputs: (How can the Mojaloop OSS Community better serve these players?)** +- 1\. Understand how Mojaloop and Wholesale APIs fit together (or don't) +- 2\. Enable fintechs to interact with Mojaloop over 1 or 2 wholesale banking APIs (e.g. GSMA MM api) +- 3\. take them from little to no understanding of Mojaloop -> demonstrating real prototypes + +**7.3.4 Inputs: (what are the things that we need to do to meet these goals)** +- 1\. Improved mojaloop documentation specific for this role. +- 2\. Documentation or working document on how Mojaloop will work with wholesale apis +- 3\. Self-deployed lab environment with DFSP that expose some wholesale apis with basic functionality for fintechs to test against + + +## 8. OSS Lab/Workbench efforts alongside others + +There are others in the community working on some of these needs we outlined above. How can we align ourselves together to: (1) Not duplicate efforts (nor step on each other's toes) and (2) Provide the most impact for end users and the Mojaloop community as a whole + +In general, we reached a consensus around the following: +- any OSS Lab effort should be focused with a specific end user in mind +- Our focus should be further out on the mojaloop spokes (DFSPs, Fintechs, 3rd Party app providers) + + +### 8.1 MIFOS +- 1\. Already extensive work done here with Fineract system, which provides out-of-the-box solution for Mojaloop enabled DFSPs +- 2\. working on open api implementations +- 3\. Working on lowering the barriers to entry for DFSPs and Fintechs +- 4\. Mifos Innovation Lab: "The Locomotion on top of Mojaloop's Rails" + - 4.1 Demonstrate end to end Mojaloop systems with DFSP integration + - 4.2 Build and contribute OS tools +- 5\. Working on real world deployments already +- 6\. See a need for a "Single Point of Entry to the Mojaloop Ecosystem" +- 7\. Have an existing Lab deployment with Mojaloop that is currently being upgraded to work with the latest Helm chart deployments + + +### 8.2 GSMA +- 1\. Have mobile money api, would like to see end to end solution with fintechs/DFSPs talking over a mojaloop switch +- 2\. The GSMA Lab has a very wide scope, Mojaloop is just one piece of this +- 3\. One main goal is the mobile money API- pushing for default standard for 3rd party integration into mobile money +- 4\. where does Mojaloop sit? + - 4.1 Is one of the branches that the GSMA Lab will be working on + - 4.2 Where can GSMA add the most value to Mojaloop? + - 4.2.1 Serve a need from the market to get the most impact + - 4.2.2 See a end-to-end prototype of the MM API talking over a Mojaloop switch + + +### 8.3 ModusBox +- 1\. More on the systems integrator perspective. Building a bunch of tools already to ease the development and onboarding process for switches and DFSPs +- 2\. Have open sourced the Mojaloop JS SDK +- 3\. Interested in showing 'how the engine works' to build confidence in business parters/customers +- 4\. Also interested (especially in WOCCU case) as a Mojaloop lab as a place for Fintechs to learn and test concepts on top of Mojaloop Switches + - 4.1 Once this is connected, the interesting use cases will start to develop beyond tranfers from A to B + - 4.2 MFIs (especially small-medium) don't have much capacity for experimentation or developing new business cases, but these cases can be driven from fintechs first +- 5\. How can we assist orgs. who have little-to-no technical capability to become confident with Mojaloop? + - 5.1 A technical lab environment won't do much in this case + - 5.2 Can we demonstrate Mojaloop over a spreadsheet? Everyone can understand spreadsheets. + +## 9. Questions + +- 1\. So much of this comes back to The Gates Foundation's proposed sales cycle for growing mojaloop adoption + - 1.1 Looking at the technical briefs from the hackathon alone, there are some __big__ players (Famoco, Ethiopay, GrameenPhone) that could really take mojaloop and run with it + - 1.2 How can the initial hurdle be overcome to drive adoption and help these orgs adopt mojaloop and contribute back to the ecosystem? + - 1.3 What does the entrypoint to the industry look like for Hub operators? + +- 2\. For evaluating DFSPs, what is their resource/risk allocation like? + - 2.1 If they think Mojaloop is a viable option for a future product, what type of time and resource investment will they put into it? + - 2.2 What are their alternatives? (This will be a case-by-case thing) + +- 3\. Is a certain amount of technical gatekeeping a good or bad thing? (This is a more philosophical question) + - 3.1 If we don't make it too easy to get up and running, we make sure that only interested and determined parties are using mojaloop, which self-selects for a better community (kinda) + - 3.2 But this locks out a lot of people who aren't up to scratch with kubernetes, docker etc. but may still have a good deal of experience with financial services etc. + +- 4\. Chicken and egg problem(?) between DFSPs and Hub operators. Does it go DFSPs -> Hub Operators or the other way around? + + +## 10. Recommendations + +- 1\. Find a target user that we can build a lab for/with + - 1.1 perhaps one of the more serious hackathon teams? +- 2\. Address and improve documentation gaps: driving from a role-specific (i.e. DFSP, fintech, hub operator) perspective +- 3\. Mojaloop over Spreadsheet demo +- 4\. Build a self-service lab prototype + - 4.1 Opinionated set of helm charts that can be deployed alongside general switch + - 4.2 Gather feedback from the community, and see where and how people are using it \ No newline at end of file diff --git a/docs/community/archive/notes/README.md b/docs/community/archive/notes/README.md new file mode 100644 index 000000000..8f7b7868c --- /dev/null +++ b/docs/community/archive/notes/README.md @@ -0,0 +1,5 @@ +# OSS Meeting Group Notes (Archive) + +- [Change Control Board](./ccb-notes.md) +- [Design Authority](./da-notes.md) +- [Scrum-of-scrum calls](./scrum-of-scrum-notes.md) diff --git a/docs/community/archive/notes/ccb-notes.md b/docs/community/archive/notes/ccb-notes.md new file mode 100644 index 000000000..b8c49a9df --- /dev/null +++ b/docs/community/archive/notes/ccb-notes.md @@ -0,0 +1,6 @@ +## CCB meetings: Overview +The Change Control Board meets every two weeks. + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have Change Requests or Solution Proposals to discuss. + +More details can be found here: https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings . \ No newline at end of file diff --git a/docs/community/archive/notes/da-notes.md b/docs/community/archive/notes/da-notes.md new file mode 100644 index 000000000..e0e85582c --- /dev/null +++ b/docs/community/archive/notes/da-notes.md @@ -0,0 +1,125 @@ +## DA meetings: Overview +The Design Authority meets every week for a weekly update and has ad-hoc or detailed sessions for Specific topics + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have designs to be reviewed or proposals for changes. + +More details can be found [here](https://github.com/mojaloop/design-authority/issues/42#workspaces/da-issue-log-5cdd507422733779191866e9/board?notFullScreen=false&repos=186592307) + +# DA Meeting - 30 September 2020 +Discussion around the topics mentioned started - the newly implemented "patch" in version 1.1 of the API spec was discussed and the majority of the meeting was spent on how to promote wider adoption of this new pattern. + +Concerns about the implementation and use of the "patch" command was raised, stating that further discussion is required to determine if we are not trying to patch a design flaw with another potential implementation flaw. + +See: https://github.com/mojaloop/design-authority/issues/68 + + +# DA Meeting - 2 September 2020 +First we discussed the topic about the "models" folder from being excluded from the unit test coverage checks. The decision taken was that if the folder contains business logic (which generally should not be the case), it must be refactored and moved out. Once at that "business logic isolated" state, coverage testing for that folder can be ignored. See: https://github.com/mojaloop/design-authority/issues/64 + +We concluded discussions on the separate scheme-adapter for a PISP - see issue on board: https://github.com/mojaloop/design-authority/issues/51 +Please have a look at the draft document at this location: https://github.com/mojaloop/pisp/blob/scratch/api-collision/docs/api-collision.md +The above link has a detailed discussion regarding the latest thinking and some examples of mitigations. +The decision has been taken to block this topic until further development on the PoC has been done, in order for the DA to assess if the designs are still aligned with the recommended approach. + +# DA Meeting - 26 August 2020 +We discussed https://github.com/mojaloop/design-authority/issues/51 further on our DA Meeting on 26/08/2020. + +Some of the key points were noted: + +In order to take advantage of Typescript, and to help speed up development, the PISP workstream has gone ahead and separated out the thirdparty-scheme-adapter already. + +One of the challenges identified with the "multi-scheme-adapter" approach was for cases where there are shared resources between the APIs, such as GET /parties/{type}/{id}. + +Our decision to break the Thirdparty API into it's own API (and not extend the FSPIOP-API) was predicated on the idea that "not all participants will want thirdparty functions", and therefore shouldn't have to worry about them. As a part of the decision to keep a separate Thirdparty API, we decided that some resources would be duplicated between the two. + +This could lead to problems down the line, where callbacks to some resources might not be able to reach their desired destination: for example if a DFSP needs to listen for PUT /parties/{type}/{id} callbacks for both the FSPIOP API and the Thirdparty API, it may not be possible for DFSPs to route such callbacks to the right place. + +Lewis Daly will spend more time working on some diagrams and design documents, and come back to the DA shortly + +# DA Meeting (Ad-Hoc) - 24 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/65 +The Ad-Hoc meeting was conducted with a wider issue being addressed relating to recommendations required to be taken to the CCB for consideration to change/enhance the API spec. + +Many valid points were raised and discussed and Michael and Adrian suggested some collaboration on this platform to consolidate the ideas put forward in order to formulate a recommendation to the CCB. + +# DA Meeting - 19 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/61 +The group agreed that there needs to be a balance between the need to eliminate reconciliation and liquidity management of (Payer) FSPs by not holding/reserving funds for longer than necessary. In addition, It was proposed to use 'grace time period' before timing out transfers to compensate for differences in clocks. It was also suggested that for risky transactions, the final notification in the form of a PATCH call that was introduced with FSPIOP API v1.1 can be used to mitigate risk to the Payee FSPs. + +One point made was that after the timeout period (plus the grace period to account for clock difference), a transfer status cannot be changed - it is either finalized or it isn't, but it cannot be changed. For example, if a timeout period (expressed as a time in future and not duration) is 10 seconds, then a Payer FSP (or Switch), may add a grace period of 1second and after waiting for 11seconds can query the downstream entity to find the transfer's status; At this point, if a transfer is finalized (Committed or Aborted), then the Payer FSP can take action accordingly; however if it is in an intermediate state, then the transfer has to be timed-out since the time-out period is done. + +The group agreed on the need to revisit the topic of implementing 'telescopic timeouts', which is not currently supported in favor of end-to-end encryption of (most) messages. + +# DA Meeting - 12 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/63 +The DA discussed the topic of where and how to create and work on issue tickets. With over 50 repositories, it makes sense to create a ticket in the repo where it originated and keep working on it there until it is resolved. The Product Owner and Scrum Master would have context and should replicate a ticket in the Design Authority Repo with a link to the originating ticket. Please have a look at the DA Board for the decisions made here: https://github.com/mojaloop/design-authority#workspaces/da-issue-log-5cdd507422733779191866e9/board?repos=186592307 + +# DA Meeting - 5 August 2020 +The topic for discussion was: https://github.com/mojaloop/project/issues/852 +The "HSM Integration Approach" was touched on a few times, and the workgroup taking care of the design and implementation, tabled this for discussion at this week's DA meeting to answer a few questions arising from the last PI-Planning session where progress on this was again presented. + +As we have not completed the discussion, an ad-hoc DA meeting has been arranged for this Friday with a sub-section of the DA Members. The reason for that was because there were a few specific questions we did not have time to go into detail for, which will be clarified with the individuals who raised those questions. Please drop me a note if you would like to participate in that meeting. + +# DA Meeting - 29 July 2020 +Issue discussed: https://github.com/mojaloop/design-authority/issues/60 +Claudio noted three observations regarding usage of best practices in the Mojaloop Core codebase. One of the issues has an active issue and will be used for tracking it; the other two will be followed up as separate stories/bugs as well (standards). Claudio will provide examples and in some cases sample snippets that can be used. + +Istvan and Michael discussed the usage of a unique ID for lookup requests and proposed to have a follow-up meeting the upcoming week for those interested. The current trace headers (optional) usage for traceability (APM) was brought up as a solution, which after the DA review can be proposed to the CCB (if accepted by the DA). + +# DA Meeting - 22 July 2020 +Canceled as a result of the PI-11 Mojaloop Convening taking place + +# DA Meeting - 15 July 2020 +Sam walked through some of the high-level changes being introduced with Helm v10.4.0 release and various sections from the release notes: https://github.com/mojaloop/helm/releases/tag/v10.4.0 +Please have a look on the DA Topic board: https://github.com/mojaloop/design-authority/issues/56 + +Neal and Michael discussed the issue of shared DB, code between central-settlement and central-ledger; they’re going to continue with the current work on Continuous Gross Settlement but after the convening will get the inputs from the Perf/Arch PoC (Event sourcing / CQRS) and then align. https://github.com/mojaloop/design-authority/issues/58 + +# DA Meeting - 8 July 2020 +The TIPS team did a presentation of the design and implementation of a **Rules Engine** satisfying their requirements of interpretation in the **Settlements Portion**, to extend fees levied as part of a transfer. The implementation allows for rules to be interpreted at any stage during a transaction. A formal presentation will be made at the convening during the week of the 20th July 2020 after which more informed decisions as to the adaption of this implementation into the Core OSS codebase can be considered as a generic approach to implementation of a rules engine. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/53 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting - 1 July 2020 +As part of the "Versioning" workstream, a "zero down-time deployment proposal" PoC is being conducted and feedback from that project has been presented in the form of a problem statement, solution and a demo. The team currently working on that is Lewis Daly, Mat de Haast and Sam Kummary. The feedback was well received and as this work is ongoing, the DA will follow up with any action items to come out of the upcoming presentation for this workstream at the PI 11 Meeting. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/54 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 29 June 2020 +KNEX Discussion - continued. The KNEX discussion extended into talking about the possible use of third-party tools to assist in the generation of queries to help migration efforts. This has no direct bearing on the use of KNEX itself and after exploring a bit deeper, it was decided that there was no compelling reason to continue further investigation into the use of KNEX itself, but to keep an open mind and look out for alternative solutions out there as and when they are introduced. Those libraries will be measured against the current implementation to ensure we deploy the right tools for the right purpose. This issue is now closed. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 25 June 2020 +KNEX Discussion - initiated +Conversations have been started, highlighting the problem statement of difficulty in generating or creating migration scripts when database changes occur, as well as the scenario of having to perform these upgrades on a database which is online at the time. +With this context in place, continued design sessions have been scheduled to determine if KNEX would be capable of handling the above scenario and if there are alternate libraries or tools out there to replace or supplement the current implementation, which may help alleviate this difficult task. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + + +# DA Meeting - 24 June 2020 +Discussion today started with: Deprecation of Helm2 support - Issue #52, where it was agreed that migration to Helm3 should continue. Documentation to assist in the use of tools available to help in the migration should be provided. Find the link to this document at https://github.com/mojaloop/design-authority/issues/52 + +The topic of having a design approach of implementing a generic rules-based system was discussed with some specific reference first, to a requirement of having the capability to interrogate completed or in-flight transactions (either in the transfer stage or even as early in the quoting stage) in order to apply "interchange fees" for that transaction, depending on the transaction type, as interpreted by certain rules. +Various design decisions are going to be discussed around this topic as the requirement is the facility to attach rules at various points of the transaction path. +The current implementation of a Rules Engine in the TIPS project was discussed and a request to demonstrate the capabilities of that solution in order for the DA to see if it was generic anough to incorporate into the core Switch will be made in a follow-up discussion. +Please track the progression of the design decisions surrounding this issue on the board at https://github.com/mojaloop/design-authority/issues/53 + + +# DA Meeting - 17 June 2020 +Topic under discussion was: Understand and Define Mojaloop Roles for PISP, x-network, etc. use cases +The DA is happy for workstreams to go ahead and split out new APIs and Role definitions (e.g. Thirdparty API, CNP API etc.) +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/44 for a detailed problem statement and subsequent decision. + +# DA Meeting - 10 June 2020 +This week, the DA discussed: Discuss the PISP Simulator: https://github.com/mojaloop/design-authority/issues/46 +The decision was made that for the time being, the PISP workstream will work on it's own branch in the sdk-scheme-adapter, and such a division/abstraction of the sdk-scheme-adapter will be revisited at a later date (see #51) + +# DA Meeting - 3 June 2020 +We continued the discussion started last week regarding the separate API for PISP and decided to go with option 4: maximum API Separation, with common swagger/open api files for definition and data model reuse: +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/47 for a detailed problem statement and subsequent decision. + +# DA Meeting - 27 May 2020 +Consensus relating to the issue raised and discussed some time ago, as queried by Adrian, was reached amongst the attendees. The outcome is that the Switch development will not be restrictive and prescriptive but as far as recommendation for new contributions and modules are concerned, it will be preferred if those could be done in TypeScript. + +A new discussion topic was tabled: https://github.com/mojaloop/design-authority/issues/47 seeking to answer the question of whether to have a separate API for PISP, or simply extend the existing Open API. A position statement was prepared and added as a comment. All attendees were brought up to speed with the decision to be made and Issue-#47 will be the topic for the next DA meeting. + +Another, PISP related topic was tabled and will be scheduled for another DA meeting: https://github.com/mojaloop/design-authority/issues/48 - Answer the question of how to manage notifications so that a PISP can be registered as an interested party for notification of the success of a transfer + diff --git a/docs/community/archive/notes/scrum-of-scrum-notes.md b/docs/community/archive/notes/scrum-of-scrum-notes.md new file mode 100644 index 000000000..e53175ac0 --- /dev/null +++ b/docs/community/archive/notes/scrum-of-scrum-notes.md @@ -0,0 +1,154 @@ +# Meeting Notes from Weekly Scrum-of-scrum meetings + +## OSS Scrum-of-scrum call, Thu **May 7th** 2020 + +1. Coil - Don: + a Performance: 'Big Gap' problem; changes to cs-stream; changed results; putting together a doc with changes for review; Joran's work on concurrent message processing on Kafka topics -> try to test it; seeing 40-50% throughput; + b LPS adapter: Working with Renjith (Applied Payments); putting together a lab / envt for partner teams to use it; Exploring collaboration with GSMA lab +2. Crosslake - Lewis: + a. Performance: Had report out with Confluent with Nakul, engagement wrapping up; Disseminating docs Nakul produced + b. PISP: Design discussions going on along with Implementation + c. Versioning: Figuring scope for ZDD deployments + d. Official launch related issues: DNS issues - worked on and were resolved +3. ModusBox - Sam: + a. Performance: Moving / standardizing Perf changes from PI-9 into master (not all PoCs); Working on goals, strategy for PI10 + b. Core-team: Bulk transfers - getting started by providing support in sdk-scheme-adapter + c. Maintenance (Bug Fixes): + i) Accents in names - Ongoing + ii) Mojaloop simulator on AWS deployments - almost done, working on QA scripts (on 'dev2' - second environment) + d. Testing toolkit: Currently available for testing - all resources in ML FSPIOP API Supported. Reports can be generated. Working on providing Command line options and more portability + e. CCB: Publishing v1.1 Spec this week - API Definition and corresponding Swagger (Open API) +4. Virtual / Mojaloop Foundation - Megan: + a. Launch of Mojaloop Foundation + b. Paula H - Executive Director of the Mojaloop Foundation. +5. Mojaloop Foundation - Simeon: + a. Provide feedback on the Community Survey + b. Hackathon possible in early June time-frame in collaboration with Google + c. Mojaloop Newsletter with interesting items such as ML FSPIOP v1.1 Spec, Helm v10.1.0 release, etc. to be launched next week. + +## OSS Scrum-of-scrum call, Thu **April 16th** 2020 + +1. Coil: + a. Don C: Perf - preliminary results - got some numbers - got individual handler numbers, to compare with individual handlers - focusing on DB - a third of time for one leg spent on perf + b. Don C: HSM: Renjith's team presented the demo scheduled for next week - event prep +2. Crosslake: + a. Lewis D: PISP - Sprint planning - iterating designs + b. Lewis D: Hackathons - Discussed a few concepts with Innocent K (HiPiPo) + c. Lewis D: Has access to GSMA lab - will play around + d. Lewis D: Versioning: working on deck for PI10 + e. Kim W: Performance stream overall update - workshop with Confluent + f. Kim W: Performance stream update - Pedro putting together a proposal, presentation +3. Mifos: + a. Ed C: Demo Prep for PI10 meetings +4. Virtual: + a. Megan : Getting ready for the PI10 event and Logistics +5. DA: + a. Nico: Discussing PISP issue which Michael will be the owner of +6. Core team: + a. Sam K: Performance: Preparing Metrics; Doing performance runs to baseline master branches after moving some enhancements to master + b. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing - QA done for current iteration + g. Sam K: Testing toolkit: Improving unit test coverage. Assertions added for various endpoints + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, Reviews in progress +7. Mojaloop Community: + a. Community update by Simeon + +## OSS Scrum-of-scrum call, Thu **April 9th** 2020 + +1. Coil: + a. Don C: perf testing - Under utilization of resources - more tweaking to be done + b. Don C: HSM integration - demo prep + c. Don C: Legacy adapter - docs update - looking for feedback +2. Crosslake: + a. Kim W: FRMS meeting earlier today - proposals made + b. Kim W: PI10 meetings update, registrations - questions + c. Lewis D: PISP: more planning - working on stories, items, but discussing designs on Oauth, Fido + d. Lewis D: Performance: discussion with Pedro about PoC for arch changes, for Event Sourcing, CQRS, etc + e. Lewis D: Code standards - updated + f. Lewis D: Code quality & Security stream: HSM usage, demo, Security in the OSS community + g. Lewis D: Container scans working - will work with Victor, early benchmarks + h. Lewis D: Finally - versioning update +3. Mifos: + a. Ed C: Work on Payment Hub, integrating with Kafka, ML transactions going through, using Elastic Search for back-office ops monitoring + b. Ed C: Demo Prep for PI10 meetings +4. Core team: + a. Sam K: Performance: Drafting reports, Moving metrics, other enhancements to master branches + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Provide tests and validate Merchant "Request to Pay" use case, standardization on-going + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS done, mTLS being added + h. Sam K: Testing toolkit: Usage guide in progress along with adding Golden path related tests + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, waiting for review + +## OSS Scrum-of-scrum call, Thu **April 2nd** 2020 + +1. Mifos: + a. Ed C: Team continuing work on Payment Hub EE, Focus on Operational UI , capabilities for DFSP backends, Error event handling framework +2. Coil: + a. Don C: Performance - setup done and got started - on GCP - getting high latency times - need to troubleshoot and will probably get support from other contributors + b. Don C: ATM - OTP - Encryption +3. Crosslake: + a. Kim W: Agenda for PI10 drafted - email should good out soon + b. Kim W: Schedule for PI10: Tue - Fri; 11am - 4pm GMT - Remote / Virtual event + c. Lewis D: Perf meeting later today - architecture deep dive + d. Lewis D: Versioning - In progress + e. Lewis D: Code quality & Security - Overall Security architecture, HSM covered by Coil + f. Lewis D: Mojaloop in a Vagrant box - in progress +4. Core team: + a. Miguel dB: Performance: Wrapping up Perf work - nearing 900 TPS end-to-end; Currently attempting to identify / understand a single unit that needs this perf + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Fixing issues in /authorizations + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum of scrum call Thu **March 26th** 2020 + +1. DA: Nico - Versioning topic discussed by Lewis, Matt, Sam +2. Crosslake: + a. Kim W: Finalizing Agenda - Monday to Friday + b. Kim W: Reach out if you want to present / speak + c. Kim W: Preparing pre-reads + d. Kim W: Fraud & AML workshop: Justus to post summary and notes to GitHub after the workshops + e. Lewis D: Performance workshop / deep-dive possibly Monday + f. Lewis D: PISP Design discussions ongoing + g: Lewis D: Code quality and security stream: i. Docker container security recommendations. ii. GDPR Scope for Mojaloop +3. Mifos: + a. Ed C / Istvan M: Continue creating Lab + b. Ed C / Istvan M: Fineract , new instance of Payment Hub - good progress + c. Ed C / Istvan M: Working on operational monitoring of backend part (back-office debugging, monitoring, etc) +4. Simeon O - Community Manager in attendance +5. Core team: + a. Sam K: Performance: Finalized phase-3 work. Get to immediate goals for logical conclusion - still ongoing - Phase4 roadmap and kickoff + b. Sam K: Community Support: Fixing bugs, providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Metrics being added, event framework added + e. Sam K: Accents in names issue - Discussing issue, designing solution + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress. Usage guide in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum-of-scrum call, Thu **March 19th** 2020 + +1. Coil: + a. Don C: Looking at performance, network hops (avoid dup checks etc) + b. Adrian hB: Renjith & Matt working on translation ISO20022, (to JWEs, etc) - demo by the time we meet on how to use HSM +2. Crosslake: + a. Kim W: Finishing action items from the Mid-PI Workshop, follow-up items + b. Kim W: April Community event is happening but will be a Virtual event. Kim has a planning event and will confirm details: Suggestions welcome + c. Lewis D: Performance - to include Don in other discussions + d. Lewis D: Code quality - GDPR requirements proposal + e: Lewis D: Versioning - initial draft submitted as a PR - will be presented to DA next week +3. Mifos: + a. Ed C, Istvan M: Payment Hub, envt in Azure, + b. Ed C, Istvan M: Transactions now going through + c. Ed C, Istvan M: Next phase: to implement back office screens to see screens for business users + d. Ed C, Istvan M: Workshop with Google on PISP +4. Core team: + a. Sam K: Perf - Combining prepare+position handler and fulfil+position handlers, characterization work ongoing + b. Sam K: Perf - Working on gaining an understanding of how 1 unit of Infrastructure looks like for a Mojaloop deployment + c. Sam K: Transaction requests service standardization: Added event framework, Adding metrics now + d. Sam K: Community Support: Fixing issues, upgrade issues, issue for allowing accents in names, etc,. diff --git a/docs/community/assets/cla/admin_configure.png b/docs/community/assets/cla/admin_configure.png new file mode 100644 index 000000000..1d8281bb4 Binary files /dev/null and b/docs/community/assets/cla/admin_configure.png differ diff --git a/docs/community/assets/cla/admin_sign_in.png b/docs/community/assets/cla/admin_sign_in.png new file mode 100644 index 000000000..a960e2dcd Binary files /dev/null and b/docs/community/assets/cla/admin_sign_in.png differ diff --git a/docs/community/assets/cla/cla_1.png b/docs/community/assets/cla/cla_1.png new file mode 100644 index 000000000..46718fc66 Binary files /dev/null and b/docs/community/assets/cla/cla_1.png differ diff --git a/docs/community/assets/cla/cla_2_1.png b/docs/community/assets/cla/cla_2_1.png new file mode 100644 index 000000000..18ae1809c Binary files /dev/null and b/docs/community/assets/cla/cla_2_1.png differ diff --git a/docs/community/assets/cla/cla_2_2.png b/docs/community/assets/cla/cla_2_2.png new file mode 100644 index 000000000..2e60fb762 Binary files /dev/null and b/docs/community/assets/cla/cla_2_2.png differ diff --git a/docs/community/assets/cla/cla_3.png b/docs/community/assets/cla/cla_3.png new file mode 100644 index 000000000..5e2ddc46d Binary files /dev/null and b/docs/community/assets/cla/cla_3.png differ diff --git a/docs/community/contributing/assets/consequential-change-process.jpg b/docs/community/contributing/assets/consequential-change-process.jpg new file mode 100644 index 000000000..dffd4091b Binary files /dev/null and b/docs/community/contributing/assets/consequential-change-process.jpg differ diff --git a/docs/community/contributing/assets/critical-change-process.jpg b/docs/community/contributing/assets/critical-change-process.jpg new file mode 100644 index 000000000..6f4ec733d Binary files /dev/null and b/docs/community/contributing/assets/critical-change-process.jpg differ diff --git a/docs/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg b/docs/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg new file mode 100644 index 000000000..9f21aefff Binary files /dev/null and b/docs/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg differ diff --git a/docs/community/contributing/assets/mojaloop-product-feature-flow.jpg b/docs/community/contributing/assets/mojaloop-product-feature-flow.jpg new file mode 100644 index 000000000..464be410d Binary files /dev/null and b/docs/community/contributing/assets/mojaloop-product-feature-flow.jpg differ diff --git a/docs/community/contributing/assets/mojaloop-workstream-sprint-process.jpg b/docs/community/contributing/assets/mojaloop-workstream-sprint-process.jpg new file mode 100644 index 000000000..048b46dd7 Binary files /dev/null and b/docs/community/contributing/assets/mojaloop-workstream-sprint-process.jpg differ diff --git a/docs/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx b/docs/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx new file mode 100644 index 000000000..6f4226afb Binary files /dev/null and b/docs/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx differ diff --git a/docs/community/contributing/code-of-conduct.md b/docs/community/contributing/code-of-conduct.md new file mode 100644 index 000000000..641649471 --- /dev/null +++ b/docs/community/contributing/code-of-conduct.md @@ -0,0 +1,94 @@ +# Mojaloop Code of Conduct + + +## Vision and Mission + +Mojaloop is a portmanteau derived from the Swahili word "Moja" meaning "one" and the English word loop. Mojaloop's vision is to loop digital financial providers and customers together in one inclusive ecosystem. + +The Mojaloop open source project mission is to increase financial inclusion by empowering organizations creating trusted and interoperable payments systems to enable digital financial services for all. We believe an economy that includes everyone, benefits everyone and we are building software that will accelerate full financial inclusion. Succeeding in our mission will require diverse opinions and contributions from people reflecting differing experiences and who come from culturally diverse backgrounds. + +## Community Foundation and Values + +Our goal is a strong and diverse community that welcomes new ideas in a complex field and fosters collaboration between groups and individuals with very different needs, interests, and skills. + +We build a strong and diverse community by actively seeking participation from those who add value to it. + +We treat each other openly and respectfully, we evaluate contributions with fairness and equity, and we seek to create a project that includes everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, and orientation. + +*This code of conduct exists to ensure that diverse groups collaborate to mutual advantage and enjoyment.* + +The Code of Conduct governs how we behave in public or in private, virtually or in person. We expect it to be honoured by everyone who represents the project officially or informally, claims affiliation with the project, or participates directly. + +### We strive to: + +- **Be Considerate**\ + Our work will be used by other people, and we in turn will depend on the work of others. Any decision we take will affect everyone involved in our ecosystem, and we should consider all relevant aspects when making decisions. + +- **Be Respectful**\ + We work together to resolve conflict, assume good intentions, and do our best to act in an empathic fashion. We believe a community where people are respected and feel comfortable is a productive one. + +- **Be Accountable**\ + We are accountable for our words and actions. We all can make mistakes; when we do, we take responsibility for them. If someone has been harmed or offended, we listen carefully and respectfully and work to right the wrong. + +- **Be Collaborative**\ + What we produce is a complex whole made of many parts. Collaboration between teams that each have their own goal and vision is essential; for the whole to be more than the sum of its parts, each part must make an effort to understand the whole.\ + Collaboration reduces redundancy and improves the quality of our work. Internally and externally, we celebrate good collaboration. Wherever possible, we work closely with upstream projects and others in the open-source software community to coordinate our efforts. We prefer to work transparently and involve interested parties as early as possible. + +- **Value Decisiveness, Clarity, and Consensus**\ + Disagreements, social and technical, are normal, but we do not allow them to persist and fester leaving others uncertain of the agreed direction.\ + We expect community members to resolve disagreements constructively. When they face obstacles in doing so, we escalate the matter to structures with designated leaders to arbitrate and provide clarity and direction. + +- **Ask for help when unsure**\ + Nobody is expected to be perfect in this community. Asking questions early avoids many problems later, so questions are encouraged, though they may be directed to the appropriate forum. Those who are asked should be responsive and helpful. + +- **Step Down Considerately**\ + When somebody leaves or disengages from the project, we ask that they do so in a way that minimises disruption to the project. They should tell people they are leaving and take the proper steps to ensure that others can pick up where they left off. + +- **Open Meritocracy**\ +We invite anybody, from any company or organization, to participate in any aspect of the project. Our community is open, and any responsibility can be carried by any contributor who demonstrates the required capacity and competence. + +- **Value Diversity and Inclusion**\ +This is a community that wants to make a real difference to people's lives across the globe; and, in particular, in developing societies and economies. We value our members, first of all, for themselves; and, second, for the help they can give each of us as we work together to transform the world. Each of us will strive never to allow any other considerations to weigh with us, either consciously or unconsciously. In particular, considerations of gender identity or expression, sexual orientation, religion, ethnicity, age, neurodiversity, disability status, language, and citizenship have no place in our collaboration and we will work to eradicate them where we find them: first of all, in ourselves; but after that, and with respect and affection, in those we work with. + +- **Be Transparent**\ +We believe community members will have personal and professional interests in the development of the Mojaloop Open Source Software. These interests will, directly and indirectly, influence perceptions about the best direction of the community. Community members should make every reasonable effort to be transparent about their interests within the limits of confidentiality.  Community members who hold permanent or temporary governance roles should not use those roles in the advancement of personal or professional interests but should base their influence on the best interests of the success of the community. + +This Code of Conduct is not exhaustive or complete. It is not a rulebook; it serves to distill our common understanding of a collaborative, shared environment, and goals. We expect it to be followed in spirit as much as in the letter. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language + +- Being respectful of differing viewpoints and experiences + +- Gracefully accepting constructive criticism + +- Focusing on what is best for the community + +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances + +- Trolling, insulting/derogatory comments, and personal or political attacks + +- Public or private harassment + +- Publishing others' private information, such as a physical or electronic address, without explicit permission + +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Reporting and Resolution + +If you see someone violating the code of conduct, you are encouraged to address the behavior directly with those involved. Many issues can be resolved quickly and easily, and this gives people more control over the outcome of their dispute. If you are unable to resolve the matter for any reason, or if the behavior is threatening or harassing, report it. We are dedicated to providing an environment where participants feel welcome and safe. + +Reports should be directed to the Community Leadership Committee via an email sent to . This email goes to the Mojaloop Foundation Community Manager whose duty it is to receive and address reported violations of the code of conduct. They will then work with the Community Leadership Committee to address and resolve the report. + +We will investigate every complaint, but you may not receive a direct response. Whether we respond to you directly or not, you will always be able to enquire after the status of a complaint by contacting a member of the Community Leadership Committee. We will use our discretion in determining when and how to follow up on reported incidents, which may range from not taking action to permanent expulsion from the community and foundation-sponsored spaces. We will notify the accused of the report and provide them an opportunity to discuss it before any action is taken. The identity of the reporter will be omitted from the details of the report supplied to the accused. In potentially harmful situations, such as ongoing harassment or threats to anyone's safety, we may take action without notice. + +### Attribution + +This Code of Conduct is adapted from the Ubuntu Code of Conduct v2.0, available at diff --git a/docs/community/contributing/consequential-change-process.md b/docs/community/contributing/consequential-change-process.md new file mode 100644 index 000000000..c4f0a3c03 --- /dev/null +++ b/docs/community/contributing/consequential-change-process.md @@ -0,0 +1,72 @@ +# Consequential Change Process + +For changes which are covered by the [consequential change definition](./design-review.md#consequential-changes) the +following process must be followed: + +1. Propose a product change to the Mojaloop Product Council: + 1. Create a 'Product Change Proposal' in the GitHub 'product-council' project + repository [here](https://github.com/mojaloop/product-council-project/issues). + 1. Complete the template as thoroughly as possible to ensure a quick turnaround. + 2. Send a message on the [#product-council](https://mojaloop.slack.com/archives/C01FF8AQUAK) slack channel asking + for a review of your proposal. + 3. The Product Council will discuss your proposal with you in order to understand where it fits within the Mojaloop + product roadmap. +2. Propose code changes to the Mojaloop Design Authority: + 1. Create a 'Consequential Change Proposal' issue in the GitHub 'design-authority-project' + repository [here](https://github.com/mojaloop/design-authority-project/issues). + 1. Complete the template as thoroughly as possible to ensure a quick turnaround. + 2. Send a message on the [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q) slack channel asking for + a review of your proposal. + 3. The design authority will assign one or more members to work with you on your proposal. +3. Take part in a design review: + 1. Your assigned design authority member(s) will guide you through an iterative design review process. + 2. Once the design review process is complete you may proceed with your change. +4. Implement and review your code changes: + 1. Create and work on github/zenhub work items in + your [workstream process](./product-engineering-process.md#mojaloop-workstreams) as necessary. Be sure to + reference the product council ticket and consequential change proposal ticket in your item descriptions to enable + future traceability. + 2. When you are ready to make pull requests on one or more code repositories, contact your assigned design authority + member(s) and ask them to begin the code review phase. + 3. Be ready to respond to questions and make adjustments during this stage. + 4. Once your assigned design authority member(s) approve your pull request(s) your feature is ready for including in + the official Mojaloop release process. + 5. Any changes to the design made during implementation must be recorded on the proposal ticket. + +![Consequential Change Process](./assets/consequential-change-process.jpg) + +## What to expect during the design review process + +_The Mojaloop Design Authority has responsibility for ensuring risks are identified and mitigated appropriately and that +our established standards for tools, patterns and practices are upheld. Your assigned design authority member(s) are +there to help you achieve the best possible outcome for yourself and the entire Mojaloop community._ + +Your assigned design authority member(s) will help you identify and mitigate any risks your change may introduce as well +as discussing how your design aligns with established tools, patterns and practices. + +1. You will be asked to talk through the reason(s) for your proposed change and to explain what you wish to achieve and + how you intend to achieve it. + 1. You should be able to refer to an existing Mojaloop Product Council GitHub ticket showing that you have discussed + your work with them and they are happy for the change to be made. Note that the Product Council has a + responsibility to maintain a coherent roadmap for our technology and will guide you on the most appropriate way + to achieve your business objectives within the Mojaloop context. The Product Council may consult the Design + Authority as part of this process. + 2. You should be able to explain how your change will be implemented, which existing components will be affected, + how they need to change and your designs for any new components. You should present, as a minimum: + 1. UML sequence diagrams showing each significant component involved in your usecase(s) and how they interact to + achieve your desired outcome(s). You should make sure to include error cases as well as "normal" expected + behaviours. + 2. Full details of any third-party components you will use as part of your implementation. + 3. Full details of any changes to existing components highlighting the differences between current behaviours + and your desired changed and/or new behaviours. + 3. Your assigned Design Authority members will likely ask lots of questions in order to fully understand your + proposal and its context. +2. Your assigned design authority member(s) will help you identify any other potentially impacted contributors, teams or + stakeholders to bring them in to the review process. This is done to ensure up and downstream behaviours are not + adversely affected and also, to take into account any upcoming changes in other areas of the system. Mojaloop is a + large system and it is often helpful to bring in experts from other areas to assist. +3. The primary goal of your assigned Design Authority member(s) is to identify and mitigate risks that you may not have + spotted. + 1. Your assigned design authority member(s) may make suggestions to mitigate risk from your design and may ask you + to make specific changes to bring your proposal in line with any established Mojaloop constraints. + diff --git a/docs/community/contributing/contributors-guide.md b/docs/community/contributing/contributors-guide.md new file mode 100644 index 000000000..c79c6f9f0 --- /dev/null +++ b/docs/community/contributing/contributors-guide.md @@ -0,0 +1,94 @@ +# Contributors' Guide + +We are glad that you are considering becoming a part of the Mojaloop community. + +_Note: If you use or are planning to use Artificial Intelligence (AI) tools as part of your Mojaloop contribution workflow, +please ensure you have fully read and comply with our [responsible use of AI policy](../standards/ai_policy.md)._ + +Based on the current phase of the Mojaloop project, we are looking for the following types of contributors: + +## Types of contributors + +- #### Individual Contributors + +These individuals are those that want to start contributing to the Mojaloop community. This could be a software +developer or quality assurance person that wants to write new code or fix a bug. This could also be a business, +compliance or risk specialist that wants to help provide rules, write documentation or participate in requirements +gathering. + +- #### Hub Operators + +Typically these are organizations, individuals or government agencies that are interested in setting up their own +Mojaloop Switch to become part of the ecosystem. + +- #### Implementation Teams + +Implementation teams can assist banks, government offices, mobile operators or credit unions in deploying Mojaloop. + +## How do I contribute? + +* Read and familiarise yourself with our [product engineering processes](./product-engineering-process.md) + and [Mojaloop design and code review processes](./design-review.md). +* Review the [Mojaloop Deployment Guide](https://docs.mojaloop.io/documentation/deployment-guide/) and + the [Onboarding Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md). +* Browse through the [Repository Overview](https://docs.mojaloop.io/documentation/repositories/) to understand how the + Mojaloop code is managed across multiple Github Repositories. +* Get familiar with our [Standards](../standards/guide.md) for contributing to this project. +* Go through the [New Contributor Checklist](./new-contributor-checklist.md), and browse through the project board and + work on + your [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) +* Review the [Roadmap](../mojaloop-roadmap.md) and contribute to future opportunities. +* Familiarize yourself with our Community [Code of Conduct](./code-of-conduct.md). + +## What work is needed? + +Mojaloop follows a structured [product engineering process](./product-engineering-process.md) and we actively maintain +a [roadmap](../mojaloop-roadmap.md) of new feature developments and maintenance work. You can find information about our +currently running official workstreams on +our [community central workstreams page](https://community.mojaloop.io/pi-24-workstreams). + +Each Mojaloop workstream maintains a work item backlog in GitHub and a ZenHub workspace, reach out to the workstream +lead or post a message on the workstream slack channel to introduce yourself and find a good ticket to start work on. +You will find contact details for the workstream leads and slack channel information on +our [community central workstreams page](https://community.mojaloop.io/pi-24-workstreams). + +## Where do I get help? + +Join +the [Mojaloop Slack Discussions](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw) to +connect with other developers. + +Also checkout +the [FAQ](https://github.com/mojaloop/documentation/blob/master/contributors-guide/frequently-asked-questions.md) + +## What is the current release? + +See the [Mojaloop Slack Announcements channel](https://mojaloop.slack.com/messages/CG3MAJZ5J) to find out information on +the latest release. + +## What's here and what's not? + +This is free code provided under an [Apache 2.0 license](https://github.com/mojaloop/mojaloop/blob/master/LICENSE.md). + +The code is released with an Apache 2.0 license but the Specification documents under the 'mojaloop-specification' +documents are published with CC BY-ND 4.0 License + +We don't provide production servers to run it on. That's up to you. You are free \(and encouraged!\) to clone these +repositories, participate in the community of developers, and contribute back to the code. + +We are not trying to replace mobile wallets or financial service providers. We provide a platform to link together new +and existing +financial providers using a common scheme. There are central services for identifying a customer's provider, quoting, +fulfillment, deferred net settlement, and shared fraud management. Each provider can take advantage of these services to +send and receive money with others on the system and there's no cost to them to onboard new providers. We provide code +for a simple example mobile money provider to show how integration can be done, but our example DFSP is not meant to be +a production mobile money provider. + +## Where do I send bugs, questions, and feedback? + +For bugs, see [Reporting bugs](https://github.com/mojaloop/mojaloop/blob/master/contribute/Reporting-Bugs.md). + +## Policy on the Use of Artificial Intelligence (AI) Tools by Community Members + +If you use or are planning to use Artificial Intelligence (AI) tools as part of your Mojaloop contribution workflow, +please ensure you have fully read and comply with our [responsible use of AI policy](../standards/ai_policy.md). \ No newline at end of file diff --git a/docs/community/contributing/critical-change-process.md b/docs/community/contributing/critical-change-process.md new file mode 100644 index 000000000..e2ea9a95c --- /dev/null +++ b/docs/community/contributing/critical-change-process.md @@ -0,0 +1,78 @@ +# Critical Change Process + +_**In Mojaloop, the "critical change process" is similar to the "consequential change process" but with additional +oversight and a formal sign-off requirement, given the high risk nature of such changes in our operating environment.**_ + +For changes which are covered by the [critical change definition](./design-review.md#critical-changes) the +following process must be followed: + +1. Propose a product change to the Mojaloop Product Council: + 1. Create a 'Product Change Proposal' in the GitHub 'product-council' project + repository [here](https://github.com/mojaloop/product-council-project/issues). + 1. Complete the template as thoroughly as possible to ensure a quick turnaround. + 2. Send a message on the [#product-council](https://mojaloop.slack.com/archives/C01FF8AQUAK) slack channel asking + for a review of your proposal. + 3. The Product Council will discuss your proposal with you in order to understand where it fits within the Mojaloop + product roadmap. +2. Propose code changes to the Mojaloop Design Authority: + 1. Create a 'Critical Change Proposal' issue in the GitHub 'design-authority-project' + repository [here](https://github.com/mojaloop/design-authority-project/issues). + 1. Complete the template as thoroughly as possible to ensure a quick turnaround. + 2. Send a message on the [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q) slack channel asking for + a review of your proposal. + 3. The design authority will assign two or more members to work with you on your proposal. +3. Take part in a design review: + 1. Your assigned design authority members will guide you through an iterative design review process. + 2. Once the design review process is complete your assigned design authority members will formally sign-off your + design for implementation to begin + 3. Once your design has been formally signed-off, you may proceed with your change. +4. Implement and review your code changes: + 1. Create and work on github/zenhub work items in + your [workstream process](./product-engineering-process.md#mojaloop-workstreams) as necessary. Be sure to + reference the product council ticket and critical change proposal ticket in your item descriptions to enable + future traceability. + 2. When you are ready to make pull requests on one or more code repositories, contact your assigned design authority + members and ask them to begin the code review phase. + 3. Be ready to respond to questions and make adjustments during this stage. + 4. Once your assigned design authority members approve your pull request(s) your feature is ready for including in + the official Mojaloop release process. + 5. Your assigned design authority members will formally record their approving review of your pull request(s). + 6. Any changes to the design made during implementation must be recorded on the proposal ticket. + +![Critical Change Process](./assets/critical-change-process.jpg) + +## What to expect during the design review process + +_The Mojaloop Design Authority has responsibility for ensuring risks are identified and mitigated appropriately and that +our established standards for tools, patterns and practices are upheld. Your assigned design authority member(s) are +there to help you achieve the best possible outcome for yourself and the entire Mojaloop community._ + +Your assigned design authority members will help you identify and mitigate any risks your change may introduce as well +as discussing how your design aligns with established tools, patterns and practices. + +1. You will be asked to talk through the reason(s) for your proposed change and to explain what you wish to achieve and + how you intend to achieve it. + 1. You should be able to refer to an existing Mojaloop Product Council GitHub ticket showing that you have discussed + your work with them and they are happy for the change to be made. Note that the Product Council has a + responsibility to maintain a coherent roadmap for our technology and will guide you on the most appropriate way + to achieve your business objectives within the Mojaloop context. The Product Council may consult the Design + Authority as part of this process. + 2. You should be able to explain how your change will be implemented, which existing components will be affected, + how they need to change and your designs for any new components. You should present, as a minimum: + 1. UML sequence diagrams showing each significant component involved in your usecase(s) and how they interact to + achieve your desired outcome(s). You should make sure to include error cases as well as "normal" expected + behaviours. + 2. Full details of any third-party components you will use as part of your implementation. + 3. Full details of any changes to existing components highlighting the differences between current behaviours + and your desired changed and/or new behaviours. + 3. Your assigned Design Authority members will likely ask lots of questions in order to fully understand your + proposal and its context. +2. Your assigned design authority members will help you identify any other potentially impacted contributors, teams or + stakeholders to bring them in to the review process. This is done to ensure up and downstream behaviours are not + adversely affected and also, to take into account any upcoming changes in other areas of the system. Mojaloop is a + large system and it is often helpful to bring in experts from other areas to assist. +3. The primary goal of your assigned Design Authority members is to identify and mitigate risks that you may not have + spotted. + 1. Your assigned design authority members may make suggestions to mitigate risk from your design and may ask you + to make specific changes to bring your proposal in line with any established Mojaloop constraints. + diff --git a/docs/community/contributing/cvd.md b/docs/community/contributing/cvd.md new file mode 100644 index 000000000..5ba3111c9 --- /dev/null +++ b/docs/community/contributing/cvd.md @@ -0,0 +1,304 @@ +# Disclosing and Receiving Information Regarding Security Vulnerabilities + +The Mojaloop Foundation and community take the security of Mojaloop software very seriously and operate a number of +processes intended to ensure Mojaloop is a secure platform for conducting business. Please see +our [documentation on cybersecurity architecture](../tools/cybersecurity.md) for more information. + +The Mojaloop Foundation operates +a ["Coordinated Vulnerability Disclosure"](https://github.com/ossf/oss-vulnerability-guide/blob/main/finder-guide.md#what-is-coordinated-vulnerability-disclosure) +process which is a model whereby a discovered vulnerability or issue is disclosed publicly only after responsible and +effected parties have been given sufficient time to patch or remedy the problem. By operating this model, the Mojaloop +Foundation and community aim to minimise the potential impact of such issues on our adopters. + +## Mojaloop Foundation Coordinated Vulnerability Disclosure Policy + +The following sections define the requirements and expectations of various parties involved in the discovery and +remediation of security vulnerabilities in the Mojaloop software. All members of the Mojaloop community are expected to +comply with these policies regardless of which role they are playing in any particular scenario. Participation in the +Mojaloop community implies acceptance of and compliance with these policies. + +### Terminology + +The following definitions apply within the Mojaloop Foundation Coordinated Vulnerability Disclosure Policy: + +#### Terms from RFC 2119 + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and " +OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +#### Terms from ISO, CERT + +The terms "Researcher" or "Reporter" in this document are intended to be consistent with the terms "Finder" and/or " +Reporter" as used in ISO/IEC 29147:2014(E) and the CERT® Guide to Coordinated Vulnerability Disclosure. + +### Reporters Policy + +Reporters MUST adhere to the following guidelines. + +#### General + +* Reporters MUST comply with all applicable local and international laws in connection with security research activities + or other participation in this vulnerability disclosure program. + +* Reporters SHOULD make a good faith effort to notify and work directly with the affected vendor(s) or service providers + prior to publicly disclosing vulnerability reports. + +#### Scope of Authorized Testing + +* Reporters MAY test The Mojaloop open-source software to detect a vulnerability for the sole purpose of providing The + Mojaloop Foundation information about that vulnerability. + +* Reporters SHOULD only test against test accounts owned by the Reporter or with explicit permission from the account + holder. + +* Reporters MUST avoid harm to the information systems and operations of The Mojaloop Foundation, its associates and + users of Mojaloop open-source software. + +* Reporters MUST make every effort to avoid privacy violations, degradation of user experience, disruption to production + systems, and destruction or manipulation of data. + +* Reporters MUST stop testing once that testing has established that a vulnerability exists, or sensitive data has been + encountered. Sensitive data includes personally identifiable information, financial information (e.g., account + numbers), proprietary information or trade secrets. + +* Reporters MUST NOT test any software or services not expressly contained in The Mojaloop open-source software Github + repositories, including any connected services. + +* Reporters MUST NOT exploit any vulnerability beyond the minimal amount of testing required to prove that the + vulnerability exists or to identify an indicator related to that vulnerability. + +* Reporters MUST NOT intentionally access the content of any communications, data, or information transiting or stored + on information systems belonging to The Mojaloop Foundation, its associates or users of Mojaloop open-source + software – except to the extent that the information is directly related to a vulnerability and the access is + necessary to prove that the vulnerability exists. + +* Reporters MUST NOT exfiltrate any data under any circumstances. + +* Reporters MUST NOT intentionally compromise the privacy or safety of The Mojaloop Foundation's personnel, customers, + the general public, users of the Mojaloop open-source software or any legitimate third parties. + +* Reporters MUST NOT use any exploit to compromise, alter, or exfiltrate data + +* Reporters SHOULD NOT establish command line access and/or persistence + +* Reporters MUST NOT exploit any vulnerabilities found to pivot to other systems. + +* Reporters MUST NOT intentionally compromise the intellectual property or other commercial or financial interests of + any The Mojaloop Foundation's personnel or entities, customers, the general public, users of the Mojaloop open-source + software or any legitimate third parties. + +* Reporters MUST NOT cause a denial of any legitimate services in the course of their testing. + +* Reporters MUST NOT perform physical access testing (e.g. office access, open doors, tailgating, or other trespass). + +* Reporters MUST NOT conduct social engineering in any form of The Mojaloop Foundation personnel its contractors, + associates, or user of the Mojaloop open-source software, their personnel, contractors or customers. + +* Reporters SHOULD contact The Mojaloop Foundation by email at [security@mojaloop.io](mailto:security@mojaloop.io) if at + any point you are uncertain of whether to proceed with testing. + +#### Coordination with The Mojaloop Foundation + +* Reporters SHOULD submit vulnerability reports to The Mojaloop Foundation via secure (encrypted) email + to [security@mojaloop.io](mailto:security@mojaloop.io). + +* Reporters SHOULD submit high quality reports. + +* Reporters SHOULD include sufficient descriptive details to permit The Mojaloop Foundation and/or the affected + vendor(s) to accurately reproduce the vulnerable behavior. + +* Reporters SHOULD NOT report unanalyzed crash dumps or fuzzer output unless accompanied by a sufficiently detailed + explanation of how they represent a security vulnerability. + +* Reporters SHOULD report other vulnerabilities found incidental to their in-scope testing even if those vulnerabilities + would be otherwise considered out-of-scope. For example, while testing an in-scope system the reporter finds it to be + exposing data from out-of-scope system. These are still reportable vulnerabilities. + +* Reporters MUST keep confidential any information about vulnerabilities discovered for 90 days after you have notified + The Mojaloop Foundation. Notwithstanding, this expectation does not preclude Reporters from simultaneously + coordinating the vulnerability report with other affected parties (vendors, service providers, coordinators, etc.) + +* Reporters MAY include a proof-of-concept exploit if available. + +* Reporters MAY request that their contact information be withheld from all affected vendor(s). + +* Reporters MAY request not to be named in the acknowledgements of The Mojaloop Foundation's public disclosures. + +* Reporters MUST NOT submit a high-volume of low-quality reports. + +* Reporters MUST NOT require The Mojaloop Foundation to enter into a customer relationship, non-disclosure agreement + (NDA) or any other contractual or financial obligation as a condition of receiving or coordinating vulnerability + reports. + +* Reporters MUST NOT demand compensation in return for reporting vulnerability information reported outside of an + explicit bug bounty program. + +#### Coordination with vendors + +* In the event that the Reporter finds a vulnerability in The Mojaloop Foundation open-source software consequent to a + vulnerability in a generally available product or service, the Reporter MAY report the vulnerability to the affected + vendor(s), service provider(s), or third party vulnerability coordination service(s) in order to enable the product or + service to be fixed. + +#### Coordination with others + +* Reporters MAY engage the services of a third party coordination service (e.g., CERT/CC, DHS CISA) to assist in + resolving any conflicts that cannot be resolved between the Reporter and The Mojaloop Foundation. + +* Reporters SHOULD NOT disclose any details of any extant Mojaloop Foundation open-source software vulnerability, or any + indicators of vulnerability to any party not already aware at the time the report is submitted to The Mojaloop + Foundation. + +#### Public disclosure + +* Reporters MAY disclose to the public the prior existence of vulnerabilities already fixed by The Mojaloop Foundation, + including potentially details of the vulnerability, indicators of vulnerability, or the nature (but not content) of + information rendered available by the vulnerability. + +* Reporters choosing to disclose to the public SHOULD do so in consultation with The Mojaloop Foundation. + +* Reporters MUST NOT disclose any incidental proprietary data revealed during testing or the content of information + rendered available by the vulnerability to any party not already aware at the time the report is submitted to + The Mojaloop Foundation. + +### Receivers Policy + +The Mojaloop Foundation SHALL deal in good faith with Reporters who discover, test, and report vulnerabilities or +indicators of vulnerabilities in accordance with these guidelines. + +#### General + +* The Mojaloop Foundation MAY modify the terms of this policy or terminate the policy at any time. + +* The Mojaloop Foundation SHALL use information reported to this program for defensive purposes only; to mitigate or + remediate vulnerabilities in the Mojaloop open-source software, Mojaloop Foundation networks, applications, the + applications of our vendors and those of users of Mojaloop open-source software. + +#### Case handling + +* The Mojaloop Foundation MAY, at our discretion, decline to coordinate or publish a vulnerability report. This decision + is generally based on the scope and severity of the vulnerability and our ability to add value to the coordination and + disclosure process. + +* In the event that The Mojaloop Foundation declines to coordinate a vulnerability report, the Reporter MAY proceed to + coordinate with any other affected vendor(s). Additionally, the Reporter MAY proceed with public disclosure at their + discretion. + +* The Mojaloop Foundation SHALL investigate every reported vulnerability and strive to ensure that appropriate steps are + taken to mitigate risk and remediate reported vulnerabilities. + +* The Mojaloop Foundation SHALL, to the best of our ability, validate the existence of the vulnerability + +* The Mojaloop Foundation SHALL determine an appropriate timeframe for mitigation development and deployment for + vulnerabilities reported in systems it controls. + +#### Coordination with reporters + +* The Mojaloop Foundation SHALL acknowledge receipt of vulnerability reports via email within 7 working days. + +* The Mojaloop Foundation MAY contact the Reporter for further information. + +* The Mojaloop Foundation SHALL inform the Reporter of the results of our validation, as appropriate, and accordingly + provide status updates as remediation of the vulnerability is underway. + +* The Mojaloop Foundation SHALL include credit to the reporter in any published vulnerability report unless otherwise + requested by the reporter. + +* In the event that The Mojaloop Foundation chooses to publicly disclose the reported vulnerability, The Mojaloop + Foundation SHALL recognize your contribution to improving our security if you are the first to report a unique + vulnerability, and your report triggers a code or configuration change. + +* The Mojaloop Foundation MAY forward the name and contact information of the Reporter to any affected vendors unless + otherwise requested by the reporter. + +* The Mojaloop Foundation SHALL forward the name and contact information of the reporter to the affected vendors unless + otherwise requested by the reporter. + +* The Mojaloop Foundation SHALL advise the reporter of significant changes in the status of any vulnerability he or she + reported to the extent possible without revealing information provided to us in confidence. + +* The Mojaloop Foundation MAY adjust its publication timeframe to accommodate reporter constraints if that timing is + otherwise compatible with this policy. In most cases such an adjustment would be expected to represent a delay rather + than an acceleration of the publication schedule. Examples include delaying publication to coincide with conference + presentations. + +* The Mojaloop Foundation SHALL NOT require Reporters to enter into a customer relationship, non-disclosure agreement + (NDA) or any other contractual or financial obligation as a condition of receiving or coordinating vulnerability + reports. + +#### Coordination with vendors + +* In the event that The Mojaloop Foundation determines the reported vulnerability is consequent to a vulnerability in a + generally available product or service, The Mojaloop Foundation MAY report the vulnerability to the affected + vendor(s), service provider(s), or third party vulnerability coordination service(s) in order to enable the product or + service to be fixed. + +* The Mojaloop Foundation SHALL make a good faith effort to inform vendors of reported vulnerabilities prior to public + disclosure. + +* The Mojaloop Foundation SHALL forward vulnerability reports to the affected vendor(s) as soon as practical after we + receive the report. + +* The Mojaloop Foundation SHALL apprise any affected vendors of our publication plans and negotiate alternate + publication schedules with the affected vendors when required. + +* The Mojaloop Foundation SHALL provide the vendor the opportunity to include a vendor statement within our public + disclosure document. + +* The Mojaloop Foundation SHALL NOT withhold vendor-supplied information simply because it disagrees with our assessment + of the problem. + +* The Mojaloop Foundation SHALL notify affected vendors of any public disclosure plans. + +* The Mojaloop Foundation SHALL NOT reveal information provided in confidence by any vendor. + +* The Mojaloop Foundation SHALL act in accordance with the expectations of Reporters set forth in this policy when + acting as a Reporter to other organizations (vendors, coordinators, etc.). + +#### Coordination with others + +* The Mojaloop Foundation MAY engage the services of a third party coordination service (e.g., CERT/CC, DHS CISA) to + assist in resolving any conflicts that cannot be resolved between the Reporter and The Mojaloop Foundation. + +* The Mojaloop Foundation MAY, at our discretion, provide reported vulnerability information to anyone who can + contribute to the solution and with whom we have a trusted relationship, including vendors (often including vendors + whose products are not vulnerable), service providers, community experts, sponsors, and sites that are part of a + national critical infrastructure, if we believe those sites to be at risk. + +#### Public disclosure + +* The Mojaloop Foundation SHALL determine the type and schedule of our public disclosure of the vulnerability. + +* The Mojaloop Foundation MAY disclose reported vulnerabilities to the public 7 days days after the initial + report, regardless of the existence or availability of patches or workarounds from affected vendors. + +* The Mojaloop Foundation MAY disclose vulnerabilities to the public earlier or later than 7 days due to extenuating + circumstances, including but not limited to active exploitation, threats of an especially serious (or trivial) nature, + or situations that require changes to an established standard. + +* The Mojaloop Foundation MAY consult with the Reporter and any affected vendor(s) to determine the appropriate public + disclosure timing and details. + +* The Mojaloop Foundation SHALL balance the need of the public to be informed of security vulnerabilities with vendors' + and users of Mojaloop open-source software need for time to respond effectively. + +* The Mojaloop Foundation's final determination of a publication schedule SHALL be based on the best interests of the + community overall. + +* The Mojaloop Foundation SHALL publish public disclosures via one or more of email, slack, and/or the Mojaloop + Community Central website. + +* The Mojaloop Foundation MAY disclose to the public the prior existence of vulnerabilities already fixed by The + Mojaloop Foundation, including potentially details of the vulnerability, indicators of vulnerability, or the nature ( + but not content) of information rendered available by the vulnerability. + +* The Mojaloop Foundation SHALL make our disclosure determinations based on relevant factors such as but not limited to: + whether the vulnerability has already been publicly disclosed, the severity of the vulnerability, potential impact to + critical infrastructure, possible threat to public health and safety, immediate mitigations available, vendor + responsiveness and feasibility for creating an upgrade or patch, and vendor estimate of time required for customers to + obtain, test, and apply the patch. Active exploitation, threats of an especially serious nature, or situations that + require changes to an established standard may result in earlier or later disclosure. + +* The Mojaloop Foundation MAY disclose product vulnerabilities 30 days after the initial contact is made, regardless of + the existence or availability of patches or workarounds from affected vendors in cases where a product is affected and + the vendor is unresponsive, or fails to establish a reasonable timeframe for remediation. diff --git a/docs/community/contributing/design-review.md b/docs/community/contributing/design-review.md new file mode 100644 index 000000000..5e3d41835 --- /dev/null +++ b/docs/community/contributing/design-review.md @@ -0,0 +1,231 @@ +# Technical Design Review & Code Review + +Mojaloop software is intended to form the backbone of nation scale inclusive instant payments schemes. These schemes +are important pieces of national financial infrastructure which facilitate the life critical daily activities of a +great number of people, such as purchasing food and clean drinking water. Adopters and users of Mojaloop software demand +and deserve an extremely high level of quality, security, reliability and resilience from our products. + +In order to maintain these qualities and mitigate the many business and technical risks our adopters and their +stakeholders face, the Mojaloop Foundation implements a structured product engineering process based on best +demonstrated industry practices for regulated financial software which includes managed technical and process driven +change control and traceability, technical design and code reviews, high thresholds for testing and multiple levels of +quality assurance gates. + +Our processes are intended to help our contributors identify and mitigate risks while enhancing our products, for the +benefit of the entire Mojaloop community. + +Please read the following information carefully to make sure you understand our definitions and how these processes +apply to the work you want to accomplish **before you begin**. + +**Please note that if you do not follow these processes you may be asked to rework your contribution, or it may be +rejected outright if it does not meet our standards. This may lead to significant delays in getting your work into an +official Mojaloop release. Please read our statements on +the [external donation process](product-engineering-process.md#non-official-workstreams-and-external-contributions).** + +## What is Technical Design Review? + +"Technical design review" is a process whereby one or more senior domain expert engineers who are members of the +Mojaloop Design Authority, familiar with the area(s) of the system effected, discuss proposed changes with contributors +and product representatives **before implementation work is started**, for the following purposes: + +- Risk Management + - To help identify and mitigate technical and/or business risks to any of our stakeholders, users or other + contributors. +- Impact Assessment + - To help identify other areas of the system, teams and stakeholders who may be impacted by the change, and to + facilitate communication with them. +- Standards & Cohesion + - To guide on established Mojaloop standards for tooling, third party component choices and design patterns with a + view to maintaining cohesion across the entire Mojaloop codebase. + +For non-trivial changes, this process involves working collaboratively with the Mojaloop Design Authority to produce a +design document which captures the various elements of the proposed change in a sufficient level of detail. Once the +change is implemented, this document goes on to form part of our community documentation, helping others understand the +rationale behind the design decisions made historically as our software evolves. + +## What is Code Review + +"Code review" is a process whereby one or more other software engineers look over a set of proposed code changes +**before they are merged into the main branch of a repository**, for the following purposes: + +- Quality Assurance + - Code reviews help ensure the quality of the codebase by allowing other team members to identify potential issues, + bugs, or areas for improvement before the code is merged into the main branch. This can lead to higher-quality + software with fewer defects. +- Knowledge Sharing + - Code reviews provide an opportunity for team members to learn from each other. By reviewing code written by their + peers, contributors can gain insights into different approaches, best practices, and coding patterns. This helps + spread knowledge and expertise around the community. +- Consistency + - Code reviews help maintain consistency in coding style, standards, and conventions within the Mojaloop project. By + having multiple community members review each other's code, we hope to ensure that the codebase follows + established standards and remains cohesive. +- Risk Mitigation + - Code reviews can help mitigate risks associated with changes to the codebase. By having multiple sets of eyes + examine the code, potential risks, security vulnerabilities, and performance bottlenecks can be identified early + on and addressed before they cause problems in production deployments. +- Feedback and Improvement + - Code reviews provide an opportunity for constructive feedback and collaboration. Contributors can offer + suggestions for improvement, share alternative solutions, and discuss design decisions. This fosters a culture of + continuous improvement within the community. +- Code Ownership + - Code reviews encourage a sense of collective ownership of the codebase. When multiple community members are + involved in reviewing and contributing to the code, it becomes a shared responsibility rather than the sole + responsibility of individual contributors. + +## Types of Change + +As a Mojaloop contributor, the process you must follow depends on the nature of the change you are making and its +potential impact on various categories of users and the system as a whole. + +Use the definitions below to identify the category of change you are making and select the appropriate process to +follow. It is your responsibility as a contributor to apply the appropriate process and you will be required to sign a +contributors agreement stating that you will adhere to these requirements. + +If you are in any doubt about which of the following categories applies to you change, please consult the Mojaloop +Design Authority via slack here: [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q). Please note that it +is important to engage in any required design review process before proceeding with any code changes to avoid wasting +your own efforts should re-work be requested by the Design Authority. + +### Non-consequential Changes + +#### Definition and Characteristics + +A non-consequential code change is a small, highly isolated modification made to an existing piece of code. These +changes do not affect the internal or external structure, or functionality of the local scope i.e. its inputs or +outputs, and are typically made for reasons such as improving readability, fixing coding style issues and/or minor +performance optimisations. Non-consequential code changes are straightforward and low-risk. + +A non-consequential code change does not alter the external interfaces, functionality or externally observable behaviour +of a component(s) in any way. + +A non-consequential code change does not alter the internal structure of one or more components in any way. + +_Important Note: If your change is an optimisation and involves altering the implementation of any algorithm, consider +carefully if it warrants design review or a more stringent code review than normal. It is far better to be cautious and +seek more eyes on your change than to inadvertently introduce a regression._ + +#### Examples + +Examples include: + +- Renaming variables +- Adjusting indentation +- Adding comments +- Removing unused imports +- Optimising smaller algorithms + +#### Required Design & Code Review Process + +1. No design review is required but can be understaken regardless should you be under any doubts about the consequences + of your changes. +2. At least one approving "code owner" review of all the source files being modified. + 1. Note that if no code owners are defined for any of the source files being modified you must raise an issue with + {contact details} to get code owners defined for you before proceeding. All code files in the Mojaloop GitHub + organisation should have code owners defined. +3. Additional peer code reviews as desired. The more eyes on your proposed change the better. + +### Consequential Changes + +#### Definition and Characteristics + +Consequential changes are modifications that have an impact on the behavior, functionality, operational characteristics +or performance of a sub-system or the system as a whole. These changes typically involve altering the logic of a +component or service, implementing new features, fixing bugs, changing or upgrading dependencies, or refactoring large +sections of code. Consequential changes require a considerable amount of up-front thinking and coordination with other +teams and stakeholders due to their potential system wide impact on stability and functionality of the software. They +typically carry a higher risk and require careful consideration and planning before implementation. + +_Important Note: If you think your change falls into the "Consequential Changes" category, you must also ensure it does +not fall under the ["Critical Changes"](#critical-changes) category. Please review the definition +for ["Critical Changes"](#critical-changes) before proceeding._ + +#### Examples + +Examples include: + +- Changing an existing internal API method implementation +- Adding a new internal API method implementation +- Changing the definition or behaviour of an internal interface +- Changing a backing service dependency such as swapping an existing DBMS type for another +- Changing a code dependency such as replacing one YAML parser package for another +- Refactorings across multiple code files +- Changes to deployment configurations e.g. in Infrastructure as Code. + +#### Required Design & Code Review Process + +Consequential changes must follow the defined [Consequential Change Process](consequential-change-process.md). + +### Critical Changes + +#### Definition and Characteristics + +_**In Mojaloop, "critical changes" have largely the same definition as consequential changes but apply specifically to +areas of the system considered critical to our core functionality and main use cases.**_ + +Critical changes are modifications that have an impact on the behavior, functionality, operational characteristics or +performance of any critical sub-system, system or other artefacts. These changes typically involve altering the logic of +a critical component or service e.g. for implementing new features, fixing bugs, changing or upgrading dependencies, or +refactoring code. Critical changes require a considerable amount of up-front thinking and coordination with other teams +and stakeholders due to their potential system wide impact on stability and functionality of critical aspects of the +software. They typically carry a very high risk and require careful consideration and planning before implementation. + +A change should be considered a critical change if it falls under one or more of the following code repositories, areas +and/or sub-systems: + +- External APIs: + - Any alteration to an external API specification, normal or error paths, including request validation and bug + fixes. + - Any alteration to an external API request handling implementation, normal or error paths, including request + validation and bug fixes. + - Note that "external API" in this case means any API exposed outside the switch boundary e.g. FSPIOP API etc... +- Administrative APIs: + - Any change to any administrative API specification. + - Any change to any administrative API request handling implementation, normal, or error paths, including request + validation and bug fixes. +- Transfer Flow Discovery Phase: + - Any change in discovery phase API request handling e.g.: + - Any change to account lookup API request handling implementation(s) and/or call flows to and from internal or + external "oracles". +- Transfer Flow Agreement Phase: + - Any change in agreement phase API request handling e.g.: + - Any change to the storage, retrieval, processing or display of agreement phase data or meta-data. + - Any change to agreement phase API request handling implementation(s) and/or call flows to and from internal or + external entities. +- Transfer Flow Transfer (clearing) Phase: + - Any change in transfer clearing phase API request handling, e.g.: + - Any change related to the process of deciding whether to clear a transfer of reject it based on the available + liquidity of a participant (liquidity check). + - Any change to the calculation, storage, retrieval, processing or display of participant net debit cap values. + - Any change to the calculation, storage, retrieval, processing or display of a participants available + liquidity. + - Any change to the calculation, storage, retrieval, processing or display of any monetary value. + - Any change to the calculation, storage, retrieval, processing or display of transfer data or meta-data. + - Any change within the transfer prepare request processing pipeline. + - Any change within the transfer fulfil request processing pipeline. +- Settlement: + - Any alteration to an external or internal settlement API specification, normal or error paths, including request + validation and bug fixes. + - Any alteration to an external or internal settlement API request handling implementation, normal or error paths, + including request validation and bug fixes. + - Any change related to the inclusion or exclusion of transfers for settlement batching. + - Any change related to the calculation, storage, retrieval, processing or display of settlement related data or + meta-data. + +#### Examples + +Examples include: + +- Fixing a bug in an FSPIOP API validation method +- Adding a new feature to an administrative API +- Changing the formatting of currency values displayed to users in a web portal +- Upgrading the version of an external code dependency e.g. npm package of a ledger related service +- Optimising calls to backing store services during processing of an external API request + +#### Required Design & Code Review Process + +Critical changes must follow the defined [Critical Change Process](critical-change-process.md). + + + + diff --git a/docs/community/contributing/new-contributor-checklist.md b/docs/community/contributing/new-contributor-checklist.md new file mode 100644 index 000000000..1b6158f33 --- /dev/null +++ b/docs/community/contributing/new-contributor-checklist.md @@ -0,0 +1,50 @@ +# New Contributor Checklist + +This guide summarizes the steps needed to get up and running as a contributor to Mojaloop. They needn't be completed all in one sitting, but by the end of the checklist, you should have learned a good deal about Mojaloop, and be prepared to contribute to the community. + + +## 1. Tools & Documentation + +- Make sure you have a GitHub account already, or sign up for an account [here](https://github.com/join) + +- Join the slack community at the [self-invite link](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw), and join the following channels: + - `#announcements` - Announcements for new Releases and QA Status + - `#design-authority` - Questions + Discussion around Mojaloop Design + - `#general` - General discussion about Mojaloop + - `#help-mojaloop` - Ask for help with installing or running Mojaloop + - `#ml-oss-bug-triage` - Discussion and triage for new bugs and issues + +- Say hi! Feel free to give a short introduction of yourself to the community on the `#general` channel. + +- Review the [Git workflow guide](https://docs.mojaloop.io/community/standards/creating-new-features.html) and ensure you are familiar with git. + - Further reading: [Introduction to Github workflow](https://www.atlassian.com/git/tutorials/comparing-workflows) + +- Familiarize yourself with our standard coding style: https://standardjs.com/ + +- Browse through the [Mojaloop Documentation](https://mojaloop.io/documentation/) and get a basic understanding of how the technology works. + +- Go through the [Developer Tools Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) to get the necessary developer tools up and running on your local environment. + +- (Optional) Get the Central-Ledger up and running on local machines: + - https://github.com/mojaloop/central-ledger/blob/master/Onboarding.md + - https://github.com/mojaloop/ml-api-adapter/blob/master/Onboarding.md + +- (Optional:) Run an entire switch yourself with Kubernetes https://mojaloop.io/documentation/deployment-guide/ _(note: if running locally, your Kubernetes cluster will need 8GB or more of RAM)_ + +## 2. Finding an Issue + +- Review the [good-first-issue](https://github.com/mojaloop/project/labels/good%20first%20issue) list on [`mojaloop/project`](https://github.com/mojaloop/project), to find a good issue to start working on. Alternatively, reach out to the community on Slack at `#general` to ask for help to find an issue. + +- Leave a comment on the issue asking for it to be assigned to you -- this helps make sure we don't duplicate work. As always, reach out to us on Slack if you have any questions or concerns. + +- Fork the relevant repos for the issue, clone and create a new branch for the issue + - Refer to our [Git User Guide](https://docs.mojaloop.io/community/standards/creating-new-features.html) if you get lost + + +## 3. Opening your First PR + +Please see our guidelines on creating pull requests [here](pr-guidance.md). + +## 4. Signing the CLA + +After you open your first PR, our CI/CD pipelines will ask you to sign the CLA. For more information on what the CLA is and how to sign it, see [Signing the CLA](./signing-the-cla.md) diff --git a/docs/community/contributing/pr-guidance.md b/docs/community/contributing/pr-guidance.md new file mode 100644 index 000000000..1e447aa02 --- /dev/null +++ b/docs/community/contributing/pr-guidance.md @@ -0,0 +1,235 @@ +# Pull Request Guidelines + +> **Applies to:** All contributors submitting pull requests to repositories under the [Mojaloop GitHub organisation](https://github.com/mojaloop). +> These guidelines complement the [Contributors' Guide](contributors-guide.md), the [AI Policy](../standards/ai_policy.md), and the [Product Engineering Process](product-engineering-process.md). + +**AI Disclosure** This document includes content generated with assistance from Claude Sonnet 4.6. All content has been reviewed and validated by the author. + + +--- + +## 1. Before You Open a PR + +### 1.1 Start With a GitHub Issue + +Every PR must be linked to a GitHub Issue. Do not open a PR without one. + +- If a relevant issue does not exist, **create it first** and allow time for triage or discussion before beginning implementation — especially for non-trivial changes. +- Issues are the primary space for design discussion, scoping decisions, and alignment with maintainers. Use them. + + +### 1.2 Discuss Consequential or Critical Changes First + +If your change touches shared interfaces, settlement or clearing logic, core APIs, or security-sensitive code, review the [Consequential Change Process](https://docs.mojaloop.io/community/contributing/consequential-change-process.html) and [Critical Change Process](https://docs.mojaloop.io/community/contributing/critical-change-process.html) **before writing any code**. Raising a large architectural change as a surprise PR will result in it being returned for prior discussion. + +--- + +## 2 Pull Request Titles + +Mojaloop uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to help our automated tooling manage releases and deployments. Your Pull Request title **must** conform to the conventional commits specification to pass the CI/CD checks in CircleCI. + +By adopting Conventional Commits + Semantic Versioning we can automatically release a new version for a given component and increment the `MAJOR`, `MINOR` and `BUGFIX` versions based soley on the PR titles, and auto generate rich changelogs. (See [this example](https://github.com/mojaloop/thirdparty-scheme-adapter/releases/tag/v11.20.0) of an auto generated changelog) + +> **Note**: +> When merging (and squashing) a PR, GitHub uses the *title* of the PR for the git commit message. This means that to specify a breaking change, you must use the `!` format: +> "If included in the type/scope prefix, breaking changes MUST be indicated by a ! immediately before the :. If ! is used, BREAKING CHANGE: MAY be omitted from the footer section, and the commit description SHALL be used to describe the breaking change." + +#### Examples of good PR titles + +- feat(api): add ability to handle `PUT /thirdpartyRequests/trasactions/{ID}` endpoint +- fix: update outdated node modules +- feat(models)!: change database schema +- chore: tidy up readme + +--- + +## 3. Keep PRs Small and Focused + +This is the single most important thing you can do to help reviewers and maintainers. + +### 3.1 One PR, One Purpose + +A pull request should do exactly one thing: fix one bug, implement one feature, or address one concern. Mixed-purpose PRs are hard to review, hard to revert if something goes wrong, and create ambiguous commit history. + +**Do not combine:** +- A bug fix and a refactor +- A feature and unrelated test clean-up +- Dependency updates and functional changes +- Whitespace changes with functional changes + +If you find yourself writing "and also..." in the PR description, that is a signal to split the PR. + +Note that changes to lots of whitespace e.g. reindenting, can obscure the purpose of an underlying change. Separate large whitespace changes into their own PRs to ease the review process. + +### 3.2 Target an Appropriate Diff Size + +There is no hard line-count limit, but as a practical guide: + +| Diff size | Expectation | +|---|---| +| < 200 lines | Ideal. Can be reviewed quickly and thoroughly. | +| 200 – 500 lines | Acceptable for well-scoped changes with good context. | +| 500 – 1000 lines | Requires strong justification. Consider splitting. | +| > 1000 lines | Will likely be returned and asked to be broken up unless the change is inherently atomic (e.g. a generated file, a large rename). | + +When a large change is genuinely atomic — such as a schema migration, a code generation output, or a bulk rename — add a note explaining why it cannot be split. + +### 3.3 Separate Refactoring From Functional Changes + +If you need to refactor code before making a functional change, raise the refactor as its own PR first. Mixing refactoring and behaviour changes makes it difficult to verify that no regressions have been introduced. + +### 3.4 Keep Commits Clean + +Squash or reorganise your commits before opening the PR so that each commit represents a logical, self-contained step. Avoid commits like `fix typo`, `wip`, or `try again`. A clean commit history helps reviewers and makes `git bisect` useful. + +--- + +## 4. Writing a Good PR Description + +A well-written description is not optional — it is part of your contribution. Reviewers should not have to reverse-engineer your intent from the diff. + +Your PR description must include: + +### 4.1 What and Why + +Explain **what** the change does and **why** it is needed. Link to the relevant GitHub Issue. Do not simply restate the issue title — add the context a reviewer needs to evaluate your implementation choices. + +### 4.2 How to Test + +Describe how the reviewer can verify the change works correctly. Include: +- Steps to reproduce the issue (for bug fixes) +- How to exercise the new behaviour (for features) +- Pointers to the relevant automated tests + +If a change cannot be automatically tested, explain why and describe the manual verification you performed. + +### 4.3 Breaking Changes + +If your PR introduces any breaking change — to an API, a configuration interface, a database schema, or a shared contract — call this out **explicitly and prominently** at the top of the description. Breaking changes require additional review and may need to follow the [Consequential Change Process](https://docs.mojaloop.io/community/contributing/consequential-change-process.html). + +### 4.4 AI Assistance Disclosure (see Section 4) + +If AI tools were used in producing any part of the PR — code, tests, or PR description — this must be disclosed in the PR description. See Section 4 for the required format. + +--- + +## 5. AI Assistance: Attribution and Accountability + +The [Mojaloop AI Policy](https://docs.mojaloop.io/community/standards/ai_policy.html) applies to all PR contributions. The following rules distil that policy into concrete PR requirements. + +### 5.1 Disclosure Is Mandatory + +If any AI tool (including but not limited to GitHub Copilot, ChatGPT, Claude, Gemini, Cursor, or similar) assisted in producing **any part of your PR** — including code, tests, commit messages, or the PR description itself — you must include the following disclosure block in your PR description: + +``` +**AI Assistance Disclosure** +AI tools were used in producing part of this contribution. +Tools used: [list tool(s) and version(s) where known] +Scope: [brief description of what was AI-assisted, e.g. "unit test scaffolding", "initial implementation of X function", "PR description draft"] +All AI-generated content has been reviewed, understood, and validated by the author. +``` + +All code files in the Mojaloop GitHub org must include a license and contributors header. Ensure any files you change have your name and current email address in the list. If you have used AI you should include details of the tools used alongside your name and email thus: + +``` + - {your name} <{your email}> [Assisted by {model name} {model version}] +``` + +e.g. +``` +/***** + License + -------------- + Copyright © 2026 Mojaloop Foundation + + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Mojaloop Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + + * Mojaloop Foundation + - James Bush [Assisted by Claude Sonnet 4.6] + + -------------- + ******/ +``` + +Omitting this disclosure when AI was used is a violation of the AI Policy and will result in the PR being returned. + +### 5.2 You Are Fully Accountable for All Submitted Code + +Disclosure is not a waiver of responsibility. Whether or not AI assistance was used, the human author of the PR is fully accountable for: + +- The **correctness** of the logic +- The **security** of the implementation +- **Architectural consistency** with Mojaloop standards +- **Licensing compliance** — you must not submit AI-generated code derived from impermissibly licensed training data +- **Long-term maintainability** of what you have introduced + +"The AI wrote it" is not an acceptable response to a review comment. If you cannot explain and defend every part of your PR, it is not ready to submit. + +### 5.3 AI Must Not Substitute for Human Judgment + +AI tools may not be used to make or delegate architectural or design decisions. Where an AI tool proposes an approach that deviates from established Mojaloop patterns or invariants, the human contributor is responsible for recognising this and correcting it before submission. + +### 5.4 Automated Agent Submissions Are Prohibited + +PRs may not be submitted by fully autonomous AI agents. All PRs must be opened by a human contributor. The only exception is officially sanctioned GitHub-native automation already integrated into Mojaloop workflows (e.g. Dependabot, Snyk, Mojaloop Foundation Automated tooling for maintenance). Automated agent submissions will be dismissed without review. + +--- + +## 6. Code Quality Checklist + +Before marking a PR ready for review, confirm the following: + +- The PR is linked to a GitHub Issue with a closing keyword +- The PR does exactly one thing; unrelated changes have been removed or split out +- All automated tests pass locally +- New behaviour is covered by tests +- No new linting errors or warnings have been introduced +- Dependency changes are justified and minimal +- Any breaking changes are clearly flagged +- The PR description explains what, why, and how to test +- AI assistance disclosure is included if applicable (see Section 5.1) +- You have read, understood, and can defend every line of the diff + +--- + +## 7. Reviewer Expectations + +Reviewers are volunteers giving their time. Help them help you. + +- **Respond promptly** to review comments. If you need time, say so. +- **Do not push unrelated changes** to a PR that is already under review without flagging them. +- **Do not rebase or force-push** a PR that has active review comments — it disrupts the reviewer's context. Coordinate first. +- If a reviewer asks you to split a PR, do so. This is not a criticism; it is how Mojaloop maintains a reviewable and bisectable history. +- A PR with no activity for **30 days** may be closed by a maintainer. It can be reopened when you are ready to continue. + +--- + +## 8. Draft PRs + +Use GitHub's **Draft PR** feature for work in progress. This signals to maintainers and reviewers that feedback on overall direction is welcome but a full review is not yet requested. Convert to "Ready for Review" only when all checklist items above are satisfied. + +--- + +## 9. Hotfixes and Urgent Changes + +For critical security fixes or production-breaking bugs, follow the [Critical Change Process](https://docs.mojaloop.io/community/contributing/critical-change-process.html). Even under time pressure, the AI disclosure requirement and the code quality checklist still apply. A fast review is not a licence to skip them. + +--- + +*For questions about these guidelines, post in the relevant workstream Slack channel or open a GitHub Issue against the [documentation repository](https://github.com/mojaloop/documentation).* \ No newline at end of file diff --git a/docs/community/contributing/product-engineering-process.md b/docs/community/contributing/product-engineering-process.md new file mode 100644 index 000000000..1818851e2 --- /dev/null +++ b/docs/community/contributing/product-engineering-process.md @@ -0,0 +1,194 @@ +# Mojaloop Product Engineering Process + +## Introduction + +Mojaloop software is intended to form the backbone of nation scale inclusive instant payments schemes. These schemes are +important pieces of regulated national financial infrastructure which facilitate the life critical daily activities of a +great number of people, such as purchasing food and clean drinking water. Our adopters, their regulators and the people +transacting through Mojaloop schemes demand and deserve an extremely high level of quality, security, reliability and +resilience from our products. + +In order to maintain these qualities and mitigate the many business and technical risks our adopters and their +stakeholders face, the Mojaloop Foundation implements a structured product engineering process based on best +demonstrated industry practices for regulated financial software which includes managed technical and process driven +change control and traceability, technical design and code reviews, high thresholds for testing and multiple levels of +quality assurance gates. + +Our process is intended to help our contributors identify and mitigate risks while enhancing our products, for the +benefit of the entire Mojaloop community. + +## Evolution of our process + +Since 2017 when the Mojaloop project cut its first code, our process model has evolved to cope with the +transition from a single engineering team to a number of community resourced workstreams, each focused on developing +specific areas of a large product suite. + +Our current model is based on the [Scaled Agile Framework](https://scaledagileframework.com/) which we use to facilitate +a number of teams working as independently as possible to deliver a coordinated set of roadmap outcomes across our +entire product space. + +Our model is a cycle of "[program increments](https://v5.scaledagileframework.com/program-increment/)", each lasting +approximately four calendar months. At the end of each increment, workstreams present their accomplishments at a +community meeting, new code is released and planning for the next increment begins. + +![Mojaloop Program Increments](./assets/mojaloop-product-engineering-process-overview.jpg) + +## Product Requirements Flow + +![Mojaloop Feature Flow](./assets/mojaloop-product-feature-flow.jpg) + +Feature requests and new requirements come from a variety of sources, for example: + +- Current Mojaloop adopters and Mojaloop scheme participants +- Payment scheme operators wishing to benefit from Mojaloop technology +- Government departments wishing to implement inclusive payment schemes in their countries +- Financial inclusion experts +- Mojaloop community members + +These new requirements and feature requests are gathered and analysed by the Mojaloop product council. If sufficient +demand and willingness to contribute is evident then these are fed into the Mojaloop Product Roadmap and allocated to an +official Mojaloop workstream. If no appropriate workstream exists then a new one may be created and resourced by the +community. + +Workstreams typically have a set of objectives defined at the beginning of each Mojaloop programme increment, but high +priority feature requests may be inserted during an increment. + +Workstreams deliver their output into a controlled process which periodically makes official releases of the +Mojaloop software. The Mojaloop release process tends to align with program increments; major releases, which +include new features, are typically made close to the end of an increment. Minor and patch releases are made more +frequently and may include high priority features, bug fixes or security patches for example. + +## Mojaloop Workstreams + +Official workstreams are the "production lines" of the Mojaloop community software factory, this is where the bulk of +product development work happens. Typically there are many workstreams running in parallel, each focused on specific +areas or features of the platform. + +### Governance Model & Operating Requirements + +Mojaloop workstreams have a clearly defined governance model and operating requirements to minimize risks to all +stakeholders: + +1. Workstreams must have a clear and concise name which reflects their purpose. +2. Workstreams must have a named individual as leader at all times; in some circumstances the workstream lead position + may be shared by two individuals if neither has sufficient time to contribute. +3. Workstreams must have a named individual as a liaison with the Mojaloop Design Authority. This may be the same + individual(s) as the workstream leader or a different nominated individual. +4. Workstreams must publish and maintain a description which explains their purpose, objectives and scope for each + program increment on community central. +5. Workstreams must have a minimum of two named, active contributors. +6. Workstreams must operate a minimum of one online meeting per week. + 1. Workstream meetings should be considered open for other community members to observe. + 2. Workstream meetings should be recorded and recordings should be published publicly. +7. Workstreams with more than two active contributors should operate a scrum style stand-up online meeting. + 1. Stand-up meetings should be daily, unless the volume of work is low, in which case a less frequent cadence may + be acceptable. +8. Workstreams must maintain a public github repository containing all related code, documentation and work items. +9. Workstreams must adhere to all [Mojaloop design and code review processes](./design-review.md) before, during + and after work has been completed. +10. Workstreams must obtain and use a specific hashtag on community central when making posts. +11. Workstreams must be reviewed by the Mojaloop Product Council before commencement of each program increment. + 1. Workstream objectives must be aligned with the Mojaloop product roadmap. + 2. Workstream objectives must be aligned with the mission of the Mojaloop Foundation. + +### Workstream Leadership Criteria and Responsibilities + +The Mojaloop Foundation appoints leads who are typically volunteers from the community with a high level of relevant +expertise or experience. + +To qualify as a workstream (co)lead, individuals should meet the following criteria: + +1. Commitment and ability to fulfil all workstream lead responsibilities (see below). +2. Demonstrable organizational ability. +3. Demonstrable leadership ability. +4. Demonstrable relevant technical ability. +5. Familiarity with Mojaloop ecosystem. +6. Commitment for the duration of the PI. +7. Commitment to and adherence to the Mojaloop Code of conduct + +Workstream (co)leads must accept the following responsibilities: + +1. To be a primary point of contact for queries. +2. To schedule, hold, record and publish recordings and minutes of workstream meetings. +3. To facilitate liaison between workstream contributors, other workstreams and the rest of the community. +4. To create, publish on community central and maintain a workstream team charter document. +5. Report Progress to... + 1. ...the community regularly on Community Central using assigned hashtag. + 2. ...the Product Manager/Product Council. +6. Ensure all work items adhere to all [Mojaloop design and code review processes](./design-review.md) before, during + and after work has completed. +7. Ensure all work adheres to Mojaloop quality standards such as style, test coverage and documentation. +8. Ensure all work is tracked in GitHub/Zenhub and timelines and progress are updated. +9. Ensure all technical output is tested by the core team before integration into the official release process. For + non-technical workstreams output should be reviewed by the Mojaloop Foundation Product Director. +10. Facilitate building new features and write code as necessary. +11. Triage/review contributions, issues, and respond to users. +12. File bug reports / fixes and resolve conflicts in the workstream. +13. Proactively manage technical debt and improve existing code, while adhering to + all [Mojaloop design and code review processes](./design-review.md). +14. Ensure documentation meets the required standards. +15. Guide the workstream strategic direction in collaboration with the Mojaloop Foundation Product Director and Product + Council. +16. Define SMART objectives at the beginning of each PI. + +### Defining Work + +Workstreams must define and record publicly, via github/zenhub issues, the work they plan to undertake and the +progress they make during implementation: + +1. Work items must be recorded in GitHub as project issues; use of zenhub is not mandatory but is highly encouraged. + 1. Each workstream has its own GitHub project and zenhub workspace for managing work items. +2. Work items, also known as "user stories", should be defined in + the “As a... I want to... So That...” + [behaviour driven development style](https://www.agilealliance.org/glossary/user-story-template/). +3. Work items should include detailed acceptance criteria defined in the "given, when, + then" [behaviour driven development style](https://www.agilealliance.org/glossary/given-when-then/). +4. Work items must be sized so the expected duration of any item or sub item does not exceed a single two week sprint. +5. Work items must adhere to all [Mojaloop design and code review processes](./design-review.md) before, during and + after work has completed. Where design review is required, "spike" tickets should be used to track the design process + before work item tickets are created. + 1. All required design documentation must be approved by the Mojaloop Design Authority before work commences. + +A github/zenhub ticket template is available here: [github-work-item-template.docx](github-work-item-template.docx) + +### Getting Work Done + +Mojaloop workstreams should follow a [scrum](https://www.scrum.org/resources/what-scrum-module)-like process model by +default, running over a two-week sprint cadence. Given the stringent risk management requirements of our users +regulatory environments and best demonstrated practice for financial software, our day-to-day process differs from some +typical agile methodologies in that we implement mandatory oversight functions and stricter change control mechanisms, +more typical of larger technical organisations building and operating critical infrastructure. + +Workstreams have flexibility to adjust working methods to suit their particular circumstances, within sensible +boundaries appropriate for our mission and regulatory domain. The Mojaloop Foundation provides guidance to workstreams +to ensure they remain within our required operating standards. + +Workstreams should operate regular scheduled standup, backlog refinement, sprint planning, sprint review and +retrospective activities. + +![Mojaloop Workstream Sprint Process](./assets/mojaloop-workstream-sprint-process.jpg) + +It is required that every workstream define and maintain a "team charter" document to clearly and unambiguously +communicate agreed ways of working for all contributors. + +A workstream team charter template is available for download +here: [mojaloop-workstream-team-charter-template.pptx](assets/mojaloop-workstream-team-charter-template.pptx) + +### Getting Support + +When things do not go to plan and a resolution cannot be found among workstream contributors, the Mojaloop Foundation +provides support mechanisms. Please contact the Mojaloop Foundation Director of Community who will guide you to find a +resolution. + +## Non-Official Workstreams and External Contributions + +When an appropriate existing workstream may not exist and support is not sufficient to warrant creation of a new +official workstream, contributors may decide to work on features or changes externally to the community processes. In +these circumstances +our [external donation process](../standards/guide.md#adopting-open-source-contributions-into-mojaloop) must be followed +before code, documentation or other artifacts can be adopted by the Mojaloop Foundation. + +Please note that all work done outside of official Mojaloop workstream processes is subject to +our [external donation process](../standards/guide.md#adopting-open-source-contributions-into-mojaloop). This is to +ensure an appropriate amount of rigorous review to ensure our standards are met before inclusion in any official +Mojaloop release. \ No newline at end of file diff --git a/docs/community/contributing/signing-the-cla.md b/docs/community/contributing/signing-the-cla.md new file mode 100644 index 000000000..e74a9152e --- /dev/null +++ b/docs/community/contributing/signing-the-cla.md @@ -0,0 +1,97 @@ +# Signing the CLA + +Mojaloop has a [Contributor License Agreement (CLA)](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) which clarifies the intellectual property rights for contributions from individuals or entities. + +To ensure every developer has signed the CLA, we use [CLA Assistant](https://cla-assistant.io/), a well maintained, open source tool which checks to make sure that a contributor has signed the CLA before allowing a pull request to be merged. + +## How to sign the CLA + +1. Open a pull request to any Mojaloop repository +2. When the pull request performs the standard checks, you will see the `license/cla` check has run, and requests users to sign the CLA: + + + +3. Click 'Details', and you will be directed to the CLA Assistant tool, where you can read the CLA, fill out some personal details, and sign it. + + +
+ + + +4. Once you have clicked "I agree", navigate back to the Pull request, and see that the CLA Assistant check has passed. + + + + + +### Signing For A Company + +Section 3 of the [Mojaloop CLA](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) covers contributions both from individuals and contributions made by individuals on behalf of their employer. If you are contributing to the Mojaloop Community on behalf of your employer, please enter your employer's name in the "Company or Organization" field. If not, feel free to write "OSS Contributor" and leave the "role" field blank. + + +## Administering the CLA tool + +The CLA Tool is easy to install, any GitHub admin can link it with the Mojaloop organization. + +1. Create a new GitHub Gist and enter in the text of the CLA in a new file. +> Since Github doesn't allow Gists to be owned by organizations, [our gist](https://gist.github.com/mojaloopci/9b7133e1ac153a097ae4ff893add8974) is owned by the 'mojaloopci' user. + +2. Go to [CLA Assistant](https://cla-assistant.io/) and click "Sign in with GitHub" + + + +3. You can add a CLA to either a Repo or Organization. Select "Mojaloop", and then select the gist you just created + + + +4. Hit "Link" and that's it! + + +### Requesting Additional Information: + +> Reference: [request-more-information-from-the-cla-signer](https://github.com/cla-assistant/cla-assistant#request-more-information-from-the-cla-signer) + +You can also add a `metadata` file to the CLA gist, to build a custom form for the CLA tool: + +```json +{ + "name": { + "title": "Full Name", + "type": "string", + "githubKey": "name" + }, + "email": { + "title": "E-Mail", + "type": "string", + "githubKey": "email", + "required": true + }, + "country": { + "title": "Country you are based in", + "type": "string", + "required": true + }, + "company": { + "title": "Company or Organization", + "description": "If you're not affiliated with any, please write 'OSS Contributor'", + "type": "string", + "required": true + }, + "role": { + "title": "Your Role", + "description": "What is your role in your company/organization? Skip this if you're not affiliated with any", + "type": "string", + "required": false + }, + "agreement": { + "title": "I have read and agree to the CLA", + "type": "boolean", + "required": true + } +} +``` + +Produces the following form: + + + diff --git a/docs/community/documentation/api-documentation.md b/docs/community/documentation/api-documentation.md new file mode 100644 index 000000000..aaa189fa2 --- /dev/null +++ b/docs/community/documentation/api-documentation.md @@ -0,0 +1,29 @@ +# API Documentation + +All APIs should be documented in RAML or Swagger, see Architecture-Documentation-Guidelines\]\(Architecture-Documentation-Guidelines.md\) + + + +**Section Headings** + +* Do not number headings - for example, "Prepare and Fulfill", not "C - Prepare and Fulfill" +* Make sure section headings \(\# \) match the heading to which they correspond in the comprehensive PDF \(built from the [dactyl config file](https://github.com/Mojaloop/Docs/blob/master/ExportDocs/dactyl-config.yml)\) +* Do not include the word "documentation" in headings + +#### Retrievability + +* For sections that contain many subsections of endpoints or methods, provide a table of contents at the beginning of the section +* Don't say the word project; use component, microservice, interfaces, etc + +#### Language + +Instead of the word "project," use a specific noun such as component, microservice, or interface. + +#### Procedures + +* Introduce procedures with H3 \(\#\#\#\) or H4 \(\#\#\#\#\) headers \(not H2 \(\#\#\)\). +* Do not use numbers in procedure section headings. +* Use ordered-list tagging for procedure steps. For example: +* Step 1 +* Step 2 +* Step 3 diff --git a/docs/community/documentation/standards.md b/docs/community/documentation/standards.md new file mode 100644 index 000000000..5ca3f0ad3 --- /dev/null +++ b/docs/community/documentation/standards.md @@ -0,0 +1,29 @@ +# Documentation + +### Overview + +Mojaloop has set forth several standards to ensure that documentation throughout the project is consistent and kept up to date. + +* All documentation that is relevant for contributors is kept on the "documentation" repository. +* The "documentation" repository is sync'ed with GitBook and all content is consumed in an easily readable format on: [https://www.gitbook.com/mojaloop](https://www.gitbook.com/mojaloop) +* All documentation should include: + * Overview: business overview to provide the value or reason for the documentation page + * Details: appropriate summary information to support the documentation + +### + +[Documentation standards](https://github.com/mojaloop/mojaloop/blob/master/contribute/Documentation-and-Template-Standards.md) + +### Documentation Style Guide + +All new documentation should conform to the documentation and styles as discussed [here](style-guide.md). + +### Code Style Guide + +#### NodeJS + +We follow the [Standard style guidelines](https://github.com/feross/standard). Add `npm install standard` to your package.json. + +#### Java + +For Java we follow [Checkstyle](http://checkstyle.sourceforge.net/).Code Quality Metrics diff --git a/docs/community/documentation/style-guide.md b/docs/community/documentation/style-guide.md new file mode 100644 index 000000000..d9f8aed1c --- /dev/null +++ b/docs/community/documentation/style-guide.md @@ -0,0 +1,229 @@ +# Documentation Style Guide + +In most cases, Mojaloop follows the latest edition of the Associated Press Stylebook. The following are foundation-specific guidelines which have been updated and slightly modified. + +#### Acronyms + +Spell out all acronyms on first reference. Include the acronym in parentheses immediately after the full spelling only if you refer to it again in the document. Example: _Kofi Annan, chairman of the board of the Alliance for a Green Revolution in Africa \(AGRA\), traveled to Nairobi this month. It was his first visit to the AGRA office._ + +#### Ampersand + +Only use an ampersand \(&\) when it's part of a formal name like the Bill & Melinda Gates Foundation. In all other cases, spell out and. + +#### Bill & Melinda Gates Foundation + +Our formal legal name is the Bill & Melinda Gates Foundation. Use it on first reference. Always use the ampersand \(&\) and always capitalize Foundation when Bill & Melinda Gates comes before it. + +Never abbreviate the foundation's name as _BMGF_. + +Never translate the foundation name into other languages, as it is a proper noun. The one exception to this is when translating the foundation's name into Chinese, in which case translation is acceptable. + +Do not capitalize foundation when the word stands alone. Example: _The foundation's new headquarters will be built near Seattle Center._ + +Use Gates Foundation only if you are sure the context makes the foundation's identity clear. There is a Gates Family Foundation in Colorado, so we need to be careful. Example: _The Bill & Melinda Gates Foundation and the Ford Foundation co-sponsored the event. A Gates Foundation staff member gave closing remarks._ + +The entity that manages the endowment is formally and legally known as the Bill & Melinda Gates Foundation Trust. You will not need to refer to this entity often, but when you do, write it out on first reference and refer to it as the asset trust thereafter. + +#### Bold and colons + +Frequently I see structures \(like in this very comment!\) where you have introductory terms or phrases that are bolded and set apart from the contents with a colon. Should the colon also be bolded, or not? \(I frequently see it done both ways.\) + +#### Buffett + +Note the spelling: two fs and two ts \(_i.e., Warren Buffett_\). + +#### Bulleted lists + +Introduce bulleted lists with a colon when the listed items complete the lead-in sentence or phrase. Exception: never use colons in headings or subheadings to introduce bulleted lists. + +Capitalize the first words of and use periods with listed items only if they are full sentences. Examples: + +* _This is a complete sentence._ +* _not a complete sentence_ + +Never link items in a bulleted list with coordinating conjunctions and punctuation \(semicolons or commas\) as you would in a sentence-style list. In other words, never do: + +* _this,_ +* _that, or_ +* _the other thing._ + +#### Captions + +Caption photos whenever possible. It helps people understand our work. + +Write captions as single gerund \(_ing verb_\) phrases, followed by the city, state or country, and year the photo was taken in parentheses. Example: _A doctor preparing a vaccine for delivery_ \(Brazzaville, Congo, 2007\).\_ + +When writing a caption, be sure to introduce the people featured and explain what's happening in the image as it relates to our areas of focus. Be as brief as possible so you don't distract from the image or layout. Avoid verbs that state the obvious about what the photo's subject is doing _\(e.g., smiling, standing, and so on\)._ + +If one of the co-chairs appears in a photo with other people, be sure to identify the co-chair in the caption. Don't assume everyone knows what our co-chairs look like. + +#### Citations + +Most fields have their own citation conventions. Adopt those used by the field in question. When citation conventions are unavailable or uncertain, follow The Chicago Manual of Style. + +When a document uses both footnotes and endnotes, for the footnotes, use the following symbols: + +* 1st note = \* \(asterisk\) +* 2nd note = † \(dagger\) +* 3rd note = ‡ \(double dagger\) +* 4th note = § \(section sign\) +* 5th note = \*\* \(2 asterisks\) +* 6th note = †† \(2 daggers\) +* 7th note = ‡‡ \(2 double daggers\) +* 8th note = §§ \(2 section signs\) + +Separate multiple superscript references \(footnotes, endnotes\) with commas, not semicolons. + +#### Clinical trials + +Use Roman numerals when referring to clinical trial phases and always capitalize Phase. Example: The company will begin Phase III trials on the new drug this spring. + +#### Contact information + +Use periods to separate parts of phone numbers, and begin each number with a plus sign. + +Because we work with people throughout the world, omit the international access code, which differs from country to country \(it's 011 in the United States\). Examples: _+1.206.709.3100 \(United States\)_ _+91.11.4100.3100 \(India\)_ + +#### Copyright and trademark notice + +All publications, media, and materials produced by or for the foundation should contain the notice shown below. The Legal team must approve all exceptions. + + _© \(year\) Bill & Melinda Gates Foundation. All Rights Reserved._ Bill & Melinda Gates Foundation is a registered trademark in the United States and other countries. + +When possible, begin the trademark portion of the notice on a separate line. + +#### Dashes + +Use dashes—those the width of a capital M—to indicate asides or abrupt changes in thought. Use en dashes—those the width of a capital N—with numerical ranges. + +Do not include a space before or after a dash. + +Examples: _We work to make safe, affordable financial services—particularly savings accounts—more widely available to people in developing countries._ + +_In the 2004 presidential election, 76 percent of U.S. college graduates ages 25-44 voted._ + +#### Dollars \($\) + +In Global Health and Global Development materials, because more than a dozen countries use dollars, specify U.S. dollars in parentheses on first mention in a document. Example: _$100,000 \(U.S.\)_. Omit the parenthetical U.S. in subsequent references to dollar amounts in the same document. + +#### Foundation program names + +We have three programs: Global Development Program, Global Health Program, and United States Program. + +_Program_ is capitalized when used with the full name \(Global Development Program\), but not when used alone \(The program makes grants in several areas.\). + +Use periods when abbreviating the name of the United States Program: U.S. Program. + +GH, GD, and USP are fine for internal use, but inappropriate for external publications. + +#### Gates family + +William Gates III is formally referred to as Bill Gates. In internal documents, use Bill—not a nickname or abbreviation. + +Use Melinda Gates when formally referring to Melinda. + +Use William H. Gates Sr. when formally referring to Bill Gates Sr. There is no comma between Gates and Sr. Bill Sr. is acceptable in internal documents. + +Plural: Gateses. Do not use an apostrophe to form the plural of the family's name. Example: The Gateses attended the opening of the new University of Washington law building. + +Possessive: The apostrophe follows Gates when you refer to something owned by either Bill or Melinda. Example: Melinda Gates' speech was well received. The apostrophe follows Gateses when you refer to something Bill and Melinda own jointly. Example: _The Gateses' decision to provide free Internet access in U.S. public libraries has increased library usage and circulation overall._ + +You may also phrase it this way: Bill and Melinda Gates' decision to provide free Internet access … + +See the Titles of people entry for the formal titles of Bill, Melinda, Bill Sr., and other leaders of the foundation. + +#### Hyphens + +There are few hard-and-fast rules when it comes to hyphens. Generally we use them to enhance the reader's understanding. + +Examples: _When writing for the Bill & Melinda Gates Foundation, use real-world poverty examples to illustrate your point._ _When writing for the Bill & Melinda Gates Foundation, use real world-poverty examples to illustrate your point._ + +In the first example, the hyphen in real-world connects real and world to form a single adjective describing poverty. In the second example, the hyphen in world-poverty connects world and poverty to form a single adjective describing examples. + +The meaning changes depending on the placement of the hyphen. In instances where a series of adjectives creates ambiguity about what they refer to, use a hyphen to clarify the intended meaning. + +When capitalizing hyphenated words, only capitalize the first part. Example: _Co-chairs Bill and Melinda Gates._ + +For other uses of hyphens—compound modifiers, prefixes and suffixes, fractions—refer to the Associated Press Stylebook. + +#### Numerals + +When referring to dollar figures, spell out million and billion. Use figures and decimals \(not fractions\). Do not go beyond two decimal places. Example: _The foundation granted 0.45 million to United Way._ + +When using numbers that have nothing to do with dollar figures or percentages, write them out if they are under 10, and use numerals if they are 10 or over. Example: Four program officers went on 13 site visits. + +In cases of grammatical parallelism, parallel construction always trumps this rule. For instance: Mr. Johnson has two children, 5-year-old Kyle and 13-year-old Frances. + +Never begin a sentence with a numeral. Either spell the number out or revise the sentence so it doesn't begin with a number. + +#### Percentages + +When using percentages, write out percent \(don't use %\). Use numerals instead of writing numbers out, even if they're less than 10. + +Example: _This program accounts for 6 percent of our grantmaking._ + +#### Photographer credits + +If the foundation owns the image you are using, you don't need to credit the photographer. All images in our media asset management system are foundation-owned. If the foundation has purchased a license to use the image, you may need to credit the photographer. If you have questions about photo credit requirements, contact the Foundation Communications Service Desk. + +#### Plain language + +We could call out a few specific constructions that are needlessly wordy. One that we frequently catch at Ripple is "in order to" instead of just "to." + +#### Quotation marks + +Use double quotation marks for dialogue and the citation of printed sources. Limit use of scare quotes—quotation marks meant to call attention to a quoted word or phrase and distance the author from its meaning, typically because the language is specialized, idiomatic, ironic, or misused. Example: _The foundation has increasingly used “program-related investments” in recent years._ + +#### Quoted strings and punctuation + +When describing exact strings in technical documentation, should punctuation \(not part of the literal strings\) be included in the quotation marks? For example, valid states include "pending," "in progress," and "completed." + +#### Scientific names + +Capitalize and italicize scientific names in accordance with conventions in the scientific community. Use the full version of a scientific name on first mention and the abbreviated form thereafter. For example, _use Salmonella typhi first and S. typhi for each additional reference._ + +#### Serial commas + +With lists of three or more items in a sentence, add a final comma before the coordinating conjunction and or or. Example: _The foundation's three program areas are Global Development, Global Health, and the United States._ + +#### Spacing after punctuation + +Use only one space after punctuation, including periods, colons, and semicolons. + +#### Spelling and capitalization conventions + +_bed net:_ two words, no hyphen. + +_email:_ one word, no hyphen, lowercase. + +_foundation:_ lowercase, except as part of the full foundation name. + +_grantmaking:_ one word, no hyphen. + +_nongovernmental:_ one word, no hyphen. + +_nonprofit:_ one word, no hyphen. + +_postsecondary:_ one word, no hyphen. + +_Washington state:_ lowercase state \(unless you're referring to Washington State University, the Washington State Legislature, or something similar\). + +_website:_ one word, lowercase + +#### Titles of people + +Formal titles should not be capitalized unless the title precedes a person's name or appears in a headline. Example: _Co-chair Melinda Gates will speak at the Washington Economic Club this year._ + +Lowercase and spell out titles when they are not used with an individual's name. Example: _The foundation co-chair issued a statement._ + +Lowercase and spell out titles in constructions that use commas to set them off from a name. Example: _Bill Gates, co-chair of the foundation, commented on the grant._ + +#### United States + +Spell out United States when using it as a noun. Abbreviate it as U.S. \(including periods\) when using it as an adjective. In certain cases, as when referring to a person from the United States, it's acceptable to use American. + +Examples: _The U.S. State Department is in the United States._ _The foundation's U.S. Program…_ + +#### URL + +Reference web addresses without the http:// as follows: _www.gatesfoundation.org_ diff --git a/docs/community/faqs.md b/docs/community/faqs.md new file mode 100644 index 000000000..71ac45b77 --- /dev/null +++ b/docs/community/faqs.md @@ -0,0 +1,9 @@ +# Using Vue in Markdown + +## Browser API Access Restrictions + +Because VuePress applications are server-rendered in Node.js when generating static builds, any Vue usage must conform to the [universal code requirements](https://ssr.vuejs.org/en/universal.html). In short, make sure to only access Browser / DOM APIs in `beforeMount` or `mounted` hooks. + +If you are using or demoing components that are not SSR friendly (for example containing custom directives), you can wrap them inside the built-in `` component: + +## diff --git a/docs/community/mojaloop-publications.md b/docs/community/mojaloop-publications.md new file mode 100644 index 000000000..6b892bdac --- /dev/null +++ b/docs/community/mojaloop-publications.md @@ -0,0 +1,18 @@ +# Publications + +Publications are stored in the [Documentation Artifacts Github repository](https://github.com/mojaloop/documentation-artifacts). + +See below the listing of current publications. + +## OSS Community Convenings Sessions (Presentations and Notes) + +- [January 2020 (Phase 4 Kickoff) OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202020%20OSS%20Community%20Session) +- [September 2019 PI-8 (Phase 3 Wrap-up) OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/September%202019%20PI-8_OSS_community%20session) +- [June 2019 PI-7 OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/June%202019%20PI-7_OSS_community%20session) +- [April 2019 PI-6_OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/April%202019%20PI-6_OSS_community%20session) +- [January 2010 PI-5 OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202019) + +## Mojaloop Standard Publications + +- [Mojaloop Decimal Type; Based on XML Schema Decimal Type](./discussions/decimal.md) +- [Mojaloop API Specification](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) diff --git a/docs/community/mojaloop-roadmap.md b/docs/community/mojaloop-roadmap.md new file mode 100644 index 000000000..1abbfb243 --- /dev/null +++ b/docs/community/mojaloop-roadmap.md @@ -0,0 +1,53 @@ +# The Mojaloop Roadmap + +The Mojaloop Roadmap is developed and maintained by the Mojaloop foundation, in collaboration with the wider Community. It is reviewed and updated at each Community Meeting, and was last updated at the PI 23 Community meeting in Lusaka, Zambia. + +The roadmap is built around the concept of three pillars.

+ +The Pillars are: + +1. **Make Adoption Easier** – create tools to allow developers and adopters to deploy Mojaloop with minimum fuss and complication, in an environment which meets their technical, operational or regulatory needs. +2. **Achieve Scale** – make available as many “value add” functions as possible, in order to support adopters as they seek to achieve their goals, be these financial profitability or support of social aims; or indeed both. +3. **Connect to Other Systems** – We recognise that Mojaloop is not the only payments interoperability solution, so under this pillar we seek to develop as many options as possible to both interconnect with other payment services and switches, and to ensure that the underlying Mojaloop engine is optimised to support those interconnections. + +The Pillars are themselves supported by a foundational **Quality Product** set of workstreams, which together support the continuing maintenance and enhancement of the Core Mojaloop solution. + +This is the full roadmap for PI-23: ![Mojaloop Roadmap](https://github.com/mojaloop/product-council/blob/main/PI%2023%20Mojaloop%20Roadmap.png?raw=true). + +This revision of the Roadmap extends from the release of Mojaloop 15.1 at the end of PI 21 (June 2023), to the end of PI 26 (February 2025). Mojaloop releases moved from numbering to names during PI 22, so we have Mojaloop Acacia about to be released; this will be followed by Mojaloop Zambezi, at the end of PI 23, building on Acacia and incorporating the outputs of workstreams including Merchant Payments and Foreign Exchange (international transfers). + +We currently anticipate releasing Mojaloop Baobab, based on the vNext development effort and the Reference architecture, at the end of PI 24, the end of June 2024 (though this remains subject to achieving the necessary level of quality and functionality, to be achieved through a transition process which has its own roadmap). In turn, this will be replaced by Mojaloop Meerkat at the end of October 2024, which builds on Baobab by adding the outputs of workstreams that are as yet undefined. Further releases will follow the same process. + +On the right of the Roadmap there are four tables. These list candidate workstreams for each pillar and the quality product foundation. These have been established as desirable features at various Community events, but they have not yet been adopted by the Community. + +All of the Pillars have their own workstreams. For PI 23, the following technical workstreams have been adopted. + +## Make Adoption Easier +* Support for On Premise Deployment + * Improve support for non-Cloud deployment of Mojaloop, where this is required due to regulatory or other reasons +* Participation Tools + * Ensure there is a range of options for Participating DFSPs to connect to a Mojaloop Hub, and that these options offer comparable connectivity capabilities + +## Achieve Scale +* Merchant Payments + * Support for merchant payments using a Mojaloop Hub as the payments element for a merchant scheme that offers payments through either QR codes or USSD. This includes merchant registration and support for merchant acquiring. + +## Connect to Other Systems +* Next Generation Settlement + * Connecting to other payments systems and conducting cross-border transactions increases the complexity of settlement processes needed by a switch, and this workstream is updating Mojaloop’s settlement engine to provide the necessary flexibility. +* Foreign Exchange + * This workstream is enhancing the Mojaloop Hub to support multi-currency transactions, through integration with an external FX Provider (FXP). The initial version will support one model (sender converts) and one FXP; future versions will support multiple models, multiple FXPs, and the use of a reserve currency as intermediary. +* MOSIP Integration + * In order to better support social payments and national payments programs, this workstream is developing a solution which will allow payments to be routed to a MOSIP digital identity, instead of for example a mobile phone number. This workstream also works towards greater integration with other open source DPG projects, including Mifos, PHEE and OpenG2P, in support of using MOSIP IDs to generate payments lists for bulk delivery of social payments. +## Quality Product +* Performance Characterisation + * Identify and implement changes to the Mojaloop Hub core software that can improve performance, as we move towards a number of national deployments. +* Adopt Tigerbeetle + * Use Tigerbeetle for ledger updates during transaction processing to achieve even greater performance (we don’t expect this to be in place before the release of Mojaloop Baobab) +* Core Team + * Maintains the Mojaloop core through fixes to critical bugs, prioritized feature enhancements and upgrades in dependencies, and undertakes the Release process of the core services and some adjacent services or products that are part of the Mojaloop Platform. +* Platform Quality and Security + * Assessment, maintenance and enhancement of the cybersecurity of the Mojaloop platform, encompassing connectivity to participating DFSPs (including transactions) and the security of hub operator portals. + +In addition to these technical workstreams, we have a number of **Strategic Workstreams**, which are intended to address long term, strategic issues, such as a migration to supporting ISO 20022, or monitoring developments in cross-border transactions. It is expected that the outputs of strategic workstreams will include the periodic specification of candidate technical workstreams, for potential adoption in future PIs. + diff --git a/docs/community/standards/ai_policy.md b/docs/community/standards/ai_policy.md new file mode 100644 index 000000000..344575b06 --- /dev/null +++ b/docs/community/standards/ai_policy.md @@ -0,0 +1,163 @@ +# Policy on the Responsible Use of Artificial Intelligence (AI) Tools by Community Members + +- Version: 1.0 +- Effective Date: 2026-04-08 +- Author: James Bush (jbush@mojaloop.io) +- Applies To: All contributors, maintainers, adopters, and participants in the Mojaloop community and its associated projects, including repositories under the Mojaloop GitHub organisation. + +**AI Disclosure** This document includes content generated with assistance from ChatGPT 5.2. All content has been reviewed and validated by the author. + +--- + +## 1. Purpose + +This policy establishes clear and pragmatic guidelines for the responsible use of Artificial Intelligence (AI) tools within the Mojaloop community. + +The Mojaloop Foundation supports innovation and productivity enhancements, including the use of AI-assisted tools. However, transparency, accountability, and community trust remain paramount. This policy ensures that AI use enhances collaboration without undermining openness, authorship integrity, or technical quality. + +--- + +## 2. Guiding Principles + +All AI use within the Mojaloop community must adhere to the following principles: + +1. **Human Accountability** – A human contributor is always responsible for the final output. +2. **Transparency** – Use of AI-generated content must be clearly disclosed. +3. **Quality and Security** – AI-generated outputs must meet Mojaloop’s engineering and documentation standards. +4. **Community Integrity** – AI must not be used in ways that disrupt or overwhelm community processes. + +--- + +## 3. Permitted Uses of AI Tools + +### 3.1 AI as Note-Takers in Community Calls + +AI tools may be used to take notes during **public Mojaloop community calls**, subject to the following conditions: + +- The AI tool user **must be personally present** in the call unless prior authorisation is obtained from the meeting host. +- AI note-taking tools may not join calls independently of a human participant without explicit prior authorisation from the meeting host. +- Anonymous AI bots are not permitted. All AI bots must disclose publicly the human community member they represent. +- AI note-taking tools may only join calls where call recording is enabled. + +**Rationale:** +The Mojaloop community values open discussion and psychological safety. The presence of numerous unattended recording or summarisation bots may discourage participation and negatively affect collaboration. + +--- + +### 3.2 AI Assistance in Documentation + +Community members may use AI tools to assist with: + +- Drafting documentation +- Improving clarity or grammar +- Reformatting content +- Generating summaries +- Translating content + +However: + +- Any document in which AI has generated **any portion of the content** must contain a clear statement in the document header specifying: + - That AI tools were used + - Which AI tool(s) were used + +**Example Disclosure Statement:** + + _This document includes content generated with assistance from [Tool Name]. All content has been reviewed and validated by the author._ + +Failure to disclose AI-assisted generation may result in the document being rejected or returned for correction. + +**Rationale:** +Transparency maintains trust in authorship and allows readers to assess provenance appropriately. + +--- + +### 3.3 AI Assistance in Code Creation and Debugging + +AI tools may be used for: + +- Code generation +- Code suggestions +- Refactoring assistance +- Debugging support +- Test generation +- Documentation generation for code + +However, the following rules strictly apply: + +#### 3.3.1 Human Submission Requirement + +- All pull requests (PRs), issues, and code submissions must be made by human contributors. +- Fully automated AI agents may not submit PRs, bug fixes, or code changes. +- All pull requests (PRs), issues, and code submissions must follow the Mojaloop community product engineering process requirements. +- The only exception is officially supported automated tools already integrated into GitHub workflows (e.g., dependency update bots such as Dependabot). + +Any automated agent submissions beyond approved GitHub-native tools will be **dismissed without review**. + +--- + +#### 3.3.2 Mandatory Human Review + +All AI-assisted code: + +- MUST be thoroughly reviewed by the human submitter. +- MUST be understood in full by the submitter. +- MUST meet Mojaloop coding standards and architectural principles. +- MUST pass all automated tests and validation pipelines. + +Code that is clearly AI-generated and has not been properly reviewed, validated, and understood by the human author will not be accepted into the codebase. + +The human contributor submitting the PR retains full accountability for: + +- Correctness +- Security +- Licensing compliance +- Architectural consistency +- Long-term maintainability + +**Rationale:** +Mojaloop operates in the financial services domain. The integrity, security, and correctness of code are non-negotiable. + +--- + +## 4. Prohibited Uses + +The following uses of AI are not permitted within Mojaloop community processes: + +- Unattended AI bots joining community calls. +- Fully autonomous AI agents submitting PRs or issues. +- Submitting AI-generated content without required disclosure (where applicable). +- Delegating architectural or design decisions to AI tools. +- Using AI tools to scrape, summarise, or redistribute restricted or confidential information without permission. + +--- + +## 5. Enforcement + +Maintainers and reviewers may: + +- Request disclosure statements be added. +- Reject PRs that appear insufficiently reviewed. +- Close automated agent submissions without comment. +- Request clarification regarding AI involvement. + +Repeated or deliberate violations may be escalated in accordance with Mojaloop community governance procedures. + +--- + +## 6. Future Review + +AI capabilities evolve rapidly. This policy will be reviewed periodically by the Mojaloop Foundation and community maintainers to ensure it remains appropriate, practical, and aligned with community values. + +--- + +## 7. Summary + +AI tools are permitted within the Mojaloop community when used responsibly and transparently. + +- Humans must remain accountable. +- AI must not overwhelm community processes. +- Disclosure is required in documentation. +- Code must always be reviewed and submitted by a human. + +The Mojaloop Foundation encourages thoughtful adoption of AI tools in ways that strengthen, not dilute, the quality, trust, and collaborative spirit of the Mojaloop ecosystem. + diff --git a/docs/community/standards/creating-new-features.md b/docs/community/standards/creating-new-features.md new file mode 100644 index 000000000..87ab50b71 --- /dev/null +++ b/docs/community/standards/creating-new-features.md @@ -0,0 +1,192 @@ +# Creating new Features + +## Fork + +Fork the Mojaloop repository into your own personal space. Ensure that you keep the `master` branch in sync. + +Refer to the following documentation for more information: [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/) + +1. Clone repo using Git Fork button \(refer to the above documentation for more information\) +2. Clone your forked repo: `git clone https://github.com//.git` +3. Synchronise your forked repo with Mojaloop + + Add a new upstream repo for Mojaloop `$ git remote add mojaloop https://github.com/mojaloop/.git` + + You should now see that you have two remotes: + + ```bash + git remote -v + origin https://github.com//.git (fetch) + origin https://github.com//.git (push) + mojaloop https://github.com/mojaloop/.git (fetch) + mojaloop https://github.com/mojaloop/.git (push) + ``` + +4. To sync to your current branch: `git pull mojaloop ` This will merge any changes from Mojaloop's repo into your forked repo. +5. Push the changes back to your remote fork: `git push origin ` + +## Creating a Branch + +Create a new branch from the `master` branch with the following format: `/` where `issue#` can be attained from the Github issue, and the `issueDescription` is the issue description formatted in CamelCase. + +1. Create and checkout the branch: `git checkout -b /` +2. Push the branch to your remote: `git push origin /` + +Where `` can be one of the following: + +| branchType | Description | +| :--- | :--- | +| hotfix | A `hotfix` branch is for any urgent fixes. | +| feature | A `development` branch for new or maintenance features that are in active development. | +| fix | A `development` branch that is used to fix a bug. | +| release | A release branch containing a snapshot of a release. | +| backup | A temporary backup branch. Used normally during repo maintenance. | +| major | A `pre-release` branch for major changes. | +| minor | A `pre-release` branch for minor changes. | +| patch | A `pre-release` branch for patch changes. | + +## Main branch + +The main branch must always contain code that is suitable for deployment. +Build automation tools will try to build and test code from this branch and +tag this branch with semver based version tags on success. The resulting +artifacts will be also published on respective repositories (npm, docker, etc.), +so that they can be used by other modules. + +## Hotfix branches + +These branches are created from a tag on main branch, when the corresponding +version has been deployed in production and an issue must be fixed and at the +same time main branch has newer published versions or undergoing development, +where this fix cannot be included in a timely and stable way. These branches are +named by using the pattern `hotfix/`. It is highly +recommended that the fix be first committed in main (or another branch that is +going to be merged to main) and then cherry-picked in the hotfix branch. Hot-fix +branches are usually not merged to main and not deleted, as they may be used +for subsequent fixes. On hot-fix branches build automation tools will create +tags and publish corresponding packages by increasing only the patch version number. + +## Prerelease branches + +Prerelease branches are used when the development process requires artifacts +to be available in the repository for either automated or manual testing of +in-progress features or fixes, that are not ready for a release. +These branches are used to avoid the manual work associated with publishing +in repositories. The published artifacts will have prerelease versions and tags, +as specified by semver. Build automation tools will create and publish these +prerelease versions in the package repository and tag the branch in the git +repository for each commit that is successfully built. Prerelease branches are +usually created from the main branch and later merged into it. The patterns +for prerelease branches are: + +- `major/` - when a branch is expected to include + breaking changes. +- `minor/` - when a branch is expected to include + only new features and no breaking changes. This is the most common kind of + branch, where all new development happens. +- `patch/` - when a branch is expected to include + only fixes and no new features or breaking changes. These can sometimes be + created from hotfix branches, when fixes need to be first published for tests, + before being merged in the hotfix branch. + +The build scripts will automatically publish a prerelease version and tag using +`` as the prerelease identifier, followed by a +sequential number, i.e. something like +`X.Y.Z-.sequence`, where X, Y or Z will be auto +increment once for the first build of the branch, depending on the +major/minor/patch prefix of the branch name and `sequence` will be incremented +on each successful build. For the prerelease branches it is important to ensure +`` complies with the prerelease identifier rules +specified by semver. Sometimes a minor prerelease branch can eventually +include a breaking change, in which case the developers must ensure that +there is no parallel active development happening on another major +branch, as this may end up with both branches trying to release the same major +version. In general, developers should be careful when multiple prerelease +branches are being developed and ensure the version being released in the end +does not conflict with other prerelease branches. In such cases a manual edit +of the version may be needed while resolving a merge conflict for the version property. + +## Development branches + +These branches are used primarily for development of new features, when no +artifacts need to be published to package repositories until the branch is +merged. They are created from the main or prerelease branches. Names of these +branches must not match any of the patterns described above. The frequently +used ones are `feature/` or +`fix/`. Development branches can later +be renamed to prerelease ones, if the development process requires it. Using a +development branch instead of a prerelease branch helps avoid excessive +publishing of artifacts and tags, which take more time and clutter the repository. + +## Working on your Feature + +Before you start working on your Feature, please run through following steps to help ensure Mojaloop's code-base is well maintained and protected against security issues, note that some of these steps will be required for your Pull-Request (*PR*) to pass CI validation checks (as indicated below). + +It is recommended that `npm test` is executed after each of these steps to ensure that no breaking-changes have been introduced. + +1. REQUIRED - Update dependencies + + ```bash + npm run dep:check + ``` + + > + > IMPORTANT + > + > Take note of any Dependencies that have Major Version upgrades, as they may introduce a BREAKING CHANGE. This may require some code-refactoring to accommodate the change. + > + > Refer to [Dependency Management](./guide#dependency-upgrades) on how dependency upgrades can be ignored if/when required. + > + + Run the following to update and install the dependencies + + ```bash + npm run dep:update && npm i + ``` + +2. REQUIRED - Vulnerability Checks + + ```bash + npm run audit:check + ``` + +[npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) can be used to apply any known available fixes: + + ```bash + npm audit fix --package-lock-only + ``` + + > + > IMPORTANT + > + > Take note of any Dependencies that have Version changes, as they may introduce a BREAKING CHANGE. + > + > Refer to [Dependency Management](./guide#dependency-auditing) for more information. + > + + If there is no available working fix for the vulnerability issue, you will need to do one of the following: + + 1. If the repo is using [audit-ci](https://www.npmjs.com/package/audit-ci) - update `audit-ci.jsonc` with the issue by adding it to the `allowlist`, and ensure that you add a comment indicating the reason. + 2. If the repo is using [npm-audit-resolver](https://www.npmjs.com/package/npm-audit-resolver) - Run `npm run audit:resolve` and follow the CLI prompts to try fix or ignore the issue (if there is no fix available) + +3. OPTIONAL - Update NodeJS to `Active LTS` version + + Check the `Active LTS` version as per [Official NodeJS Releases](https://nodejs.org/en/about/releases). + + 1. Update `.nvmrc` + + 2. Update `Dockerfile` (for both the *builder* and *runtime* containers), ref [Runtime Environment - 2.Container (Docker) Operating System (*OS*)](./guide.md#runtime-environment). + + > + > IMPORTANT + > + > Take note that upgrading the NodeJS version may introduce a BREAKING CHANGE. This may require some code-refactoring to accommodate the change. + > + +## Open a Pull Request (PR) + +Once your feature is ready for review, create a Pull Request from you feature branch back into the `main` branch on the Mojaloop Repository. + +Please see our guidelines for specific requirements when creating pull requests [here](../contributing/pr-guidance.md). + + diff --git a/docs/community/standards/guide.md b/docs/community/standards/guide.md new file mode 100644 index 000000000..035d61b23 --- /dev/null +++ b/docs/community/standards/guide.md @@ -0,0 +1,653 @@ +# Standards + +> *Note:* These standards are by no means set in stone, and as a community, we always want to be iterating and improving Mojaloop. If you want to propose a change to these standards, or suggest further improvements, please reach out to the Design Authority Channel on the Mojaloop Slack (#design-authority) + +## Mojaloop Invariants + +Mojaloop has some [invariants](./invariants.md) that are important to understand and adhere to when contributing to the codebase. + +These invariants are derived from [The Level One Principles](https://www.leveloneproject.org/wp-content/uploads/2020/07/L1P_Guide_2019_Final.pdf) and other business requirements as decided upon by the Mojaloop Technical Governance Board, API Change Control Board, Design Authority and Product Council. They are intended to ensure the platform retains certain characteristics important for national infrastructure grade operation. + +Please ensure you are familiar with the invariants before contributing to the codebase. + +## Runtime Environment + +The following runtime standards apply to Mojaloop. + +### Micro-services & Libraries + +1. Javascript + + NodeJS is the standard Runtime for all Mojaloop services and components for the execution of Javascript source-code files. + + Our goal is to ensure that all NodeJS based services run against the latest `Active LTS` (*Long Time Support*) version of NodeJS following the official [NodeJS Release Cycle](https://nodejs.org/en/about/releases/). + +2. Container (Docker) Operating System (*OS*) + + Mojaloop's Micro-services are built on top of the `node:-alpine` base image, where `NODE_ACTIVE_LTS_VERSION` is the current NodeJS LTS following the official [NodeJS Release Cycle](https://nodejs.org/en/about/releases/). Refer to [DockerHub](https://hub.docker.com/_/node?tab=tags&page=1&name=alpine) for a full list of official NodeJS Alpine Docker images. + + > NOTE: When specifying the `NODE_ACTIVE_LTS_VERSION`, use the full semantic version such as `--`. + > + > `node:16.15.0-alpine ` <-- This is OK + > + > `lts-alpine3.16` <-- This is NOT OK + > + + 1. Standard **Javascript** `Dockerfile` example: + + ```docker + FROM node:-alpine as builder + WORKDIR /opt/app + + RUN apk --no-cache add git + RUN apk add --no-cache -t build-dependencies make gcc g++ python3 libtool libressl-dev openssl-dev autoconf automake \ + && cd $(npm root -g)/npm \ + && npm config set unsafe-perm true \ + && npm install -g node-gyp + + COPY package*.json /opt/app/ + + RUN npm ci --production + + FROM node:-alpine + WORKDIR /opt/app + + # Create empty log file & link stdout to the application log file + RUN mkdir ./logs && touch ./logs/combined.log + RUN ln -sf /dev/stdout ./logs/combined.log + + # Create a non-root user: ml-user + RUN adduser -D ml-user + USER ml-user + + # Copy builder artefact + COPY --chown=ml-user --from=builder /opt/app . + + # Copy source files + COPY src /opt/app/src + + # Copy default config + COPY config /opt/app/config + + EXPOSE + CMD ["npm", "run", "start"] + ``` + + 2. Standard **Typescript** `Dockerfile` example: + + ```docker + FROM node:-alpine as builder + USER root + WORKDIR /opt/app + + RUN apk update \ + && apk add --no-cache -t build-dependencies git make gcc g++ python3 libtool autoconf automake openssh \ + && cd $(npm root -g)/npm \ + && npm config set unsafe-perm true \ + && npm install -g node-gyp + + COPY package.json package-lock.json* ./ + + RUN npm ci + + FROM node:-alpine + WORKDIR /opt/app + + # Create empty log file & link stdout to the application log file + RUN mkdir ./logs && touch ./logs/combined.log + RUN ln -sf /dev/stdout ./logs/combined.log + + # Create a non-root user: ml-user + RUN adduser -D ml-user + USER ml-user + + # Copy builder artefact + COPY --chown=ml-user --from=builder /opt/app ./ + + COPY src /opt/app/src + COPY config /opt/app/config + + # NPM script to build source (./src) to destination (./dist) + RUN npm run build + + # Prune devDependencies + RUN npm prune --production + + # Prune source files + RUN rm -rf src + + EXPOSE + CMD ["npm", "run", "start"] + ``` + +### CI (*Continuous Integration*) Pipelines + +Mojaloop's CI Jobs are executed against the current Ubuntu LTS version following the official [Ubuntu Release Cycle](https://ubuntu.com/about/release-cycle). + +### Kubernetes + +Mojaloop's Helm Charts ([mojaloop/helm](https://github.com/mojaloop/helm) [mojaloop/charts](https://github.com/mojaloop/charts)) are deployed and verified against the current Kubernetes LTS version following the official [Kubernetes Release Cycle](https://kubernetes.io/releases/). + +## Style Guide + +The Mojaloop Community provides a set of guidelines for the style of code we write. These standards help ensure that the Mojaloop codebase remains high quality, maintainable and consistent. + +These style guides are chosen because they can be easily enforced and checked using popular tools with minimal customization. While we recognise that developers will have personal preferences that may conflict with these guidelines we favour consistency over [bike-shedding](https://en.wikipedia.org/wiki/Law_of_triviality) these rules. + +The goal of these guides is to ensure an easy developer workflow and reduce code commits that contain changes for the sake of style over content. By reducing the noise in diffs we make the job of reviewers easier. + +## Code Style + +### Naming Conventions + +To avoid confusion and guarantee cross-language interpolation, follow these rules regarding naming conventions: + +- Do not use abbreviations or contractions as parts of identifier names. For example, use `SettlementWindow` instead of `SetWin`. +- Do not use acronyms that are not generally accepted in the computing field. +- Where appropriate, use well-known acronyms to replace lengthy phrase names. For example, use `UI` for `User Interface`. +- Use Pascal case or camel case for names more than two characters long depending on context (e.g. class names vs variable names). For example, use `SettlementWindow` (Class) or `settlementWindow` (Variable). +- You should capitalize abbreviations that consist of only two characters, such as `ID` instead of `Id` when isolated. For example, use `/transfer/{{ID}}` instead of `/transfer/{{Id}}` when representing `ID` as a URI parameter. +- Avoid abbreviations in identifiers or parameter names. If you must use abbreviations, use camel case for abbreviations that consist of more than two characters, even if this contradicts the standard abbreviation of the word. +- Use screaming (capitalized) Snake case for Enumerations. For example, use `RECORD_FUNDS_OUT_PREPARE_RESERVE`. + +Ref: [Microsoft - Design Guidelines for Class Library Developers](https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/141e06ef(v=vs.71)?redirectedfrom=MSDN) + +### Javascript + +Mojaloop uses the Javascript code style dictated by [StandardJS](https://standardjs.com/). For a full set of rules, refer to the [Standard Rules](https://standardjs.com/rules.html), but as a brief set of highlights: + +- Use *2 spaces* for indentation + +```js +function helloWorld (name) { + console.log('hi', name) +} +``` + +- Use *single quotes* for strings except to avoid escaping. + +```js +console.log('hello there') // ✓ ok +console.log("hello there") // ✗ avoid +console.log(`hello there`) // ✗ avoid +``` + +- No semicolons. (see: 1, 2, 3) + +```js +window.alert('hi') // ✓ ok +window.alert('hi'); // ✗ avoid +``` + +### Typescript + +> *Note: Standard and Typescript* +> +> As we start to introduce more Typescript into the codebase, Standard becomes less useful, and can even be detrimental +> to our development workflow if we try to run standard across the Javascript compiled from Typescript. +> We need to evaluate other options for Standard in Typescript, such as a combination of Prettier + ESLint. + +Refer to the [template-typescript-public](https://github.com/mojaloop/template-typescript-public) for the standard typescript configuration. + +### YAML + +While YAML deserializers can vary from one to another, we follow the following rules when writing YAML: +> Credit: these examples were taken from the [flathub style guide](https://github.com/flathub/flathub/wiki/YAML-Style-Guide) + +- 2 space indents +- Always indent child elements + +```yaml +# GOOD: +modules: + - name: foo + sources: + - type: bar + +# BAD: +modules: +- name: foo + sources: + - type: bar +``` + +- Do not align values + +```yaml +# BAD: +id: org.example.Foo +modules: + - name: foo + sources: + - type: git +``` + +### sh + bash + +- The Shebang should respect the user's local environment: + +```bash +#!/usr/bin/env bash +``` + +This ensures that the script will match the `bash` that is defined in the user's environment, instead of hardcoding to a specific bash at `/usr/bin/bash`. + +- When referring to other files, don't use relative paths: + +This is because your script will likely break if somebody runs it from a different directory from where the script is located + +```bash +# BAD: +cat ../Dockerfile | wc -l + +# GOOD: +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cat ${DIR}/../Dockerfile | wc -l +``` + +For other recommended bash conventions, refer to this blog post: [Best Practices for Writing Shell Scripts](https://kvz.io/bash-best-practices.html) + +## Documentation + +- Documentation should be written in Markdown format. +- Hand drawn diagrams should use an editable SVG format (example - architecture / component / block / state transition diagrams) exported from [diagrams.net](https://app.diagrams.net) + > NOTE: Please ensure that you have imbedded the editable diagram when exporting the SVG from [diagrams.net](https://app.diagrams.net)! +- Sequence diagrams should use PlantUML +- All discussion documents should be placed in /community/archive/discussion-docs. +- The use of Google Docs and other private tools is not advised for community wide collaboration + +## Directory Structure + +Along with guidelines for coding styles, the Mojaloop Community recommends the following directory structure. This ensures that developers can easily switch from one project to another, and also ensures that our tools and configs (such as `.circleci/config.yml` and `Dockerfile`s) can be ported easily from one project to another with minor changes. + +The directory structure guide requires: + +```bash +├── README.md # README containing general information about components such as pre-requisites, testing, etc. +├── LICENSE.md # Standard Mojaloop License descriptor. +├── package.json # Project package descriptor. +├── package-lock.json # Project package descriptor describing an exact dependency tree in time. +├── nvmrc.json # NVMRC containing NodeJS runtime. This should preferably reflect the current NodeJS Active LTS version. +├── .ncurc.yaml # Ignore file for dep:check script (npm-check-updates). +├── Dockerfile # Optional - Dockerfile descriptor. +├── docker-compose.yml # Optional - Docker Compose descriptor, inc containing backend dependencies. +├── .npmignore # Optional - NPM ignore file for publishing libraries. +├── .gitignore # Github ignore file. +├── src # Directory containing project source files. +│  ├── index. # Main entry point for component. +│  ├── . # Source file format. +│  └── ... # Other source files and sub-directories +├── dist # Directory containing compiled javascript files (see tsconfig below). +├── test # Directory for tests, containing at least: +│  ├── unit # Unit tests, matching the directory structure in `./src`. +│  │ ├── .test. # Tests file format. +│ │  └── ... # Other test files and sub-directories +│  ├── integration # Integration tests, matching the directory structure in `./src`. +│  ├── functional # Functional tests, matching the directory structure in `./src`. +│  └── util # Generic testing scripts and NodeJS helpers. +└── config + └── default.json # Default config file. +``` + +## Config Files + +The following Config files help to enforce the code styles outlined above: + +### EditorConfig + +> EditorConfig is supported out of the box in many IDEs and Text editors. For more information, refer to the [EditorConfig guide](https://editorconfig.org/). + +`.editorconfig` + +```ini +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[{*.js,*.ts,package.json,*.yml,*.cjson}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false +``` + +### NYC (code coverage tool) + +`.nycrc.yml` + +```yml +temp-directory: "./.nyc_output" +check-coverage: true +per-file: true +lines: 90 +statements: 90 +functions: 90 +branches: 90 +all: true +include: [ + "src/**/*.js" +] +reporter: [ + "lcov", + "text-summary" +] +exclude: [ + "**/node_modules/**", + '**/migrations/**' +] +``` + +### Typescript + +`.tsconfig.json` + +```json +{ + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "lib", + "coverage" + ], + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": [ + "esnext" + ], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "outDir": "./dist", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "baseUrl": "./", + "paths": { + "*": [ + "src/*", + "node_modules/*" + ] + }, + "esModuleInterop": true + } +} +``` + +`.eslintrc.js` + +```js +module.exports = { + parser: '@typescript-eslint/parser', // Specifies the ESLint parser + extends: [ + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier + 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. + // Enforces ES6+ import/export syntax + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', + ], + parserOptions: { + ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off' + }, + overrides: [ + { + // Disable some rules that we abuse in unit tests. + files: ['test/**/*.ts'], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + }, + }, + ], +}; +``` + +For a more detailed list of the recommended typescript configuration, including `package.json`, `jest.config.js` and more, refer to the [Typescript Template Project](https://github.com/mojaloop/template-typescript-public). + +## Dependency Management + +### Dependency Upgrades + +It is important to ensure that the latest Dependencies are used to mitigate security issues. + +#### NodeJS + +NodeJS projects should install [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) using the following command: + +```bash +npm install -D npm-check-updates +``` + +And add the following scripts to `package.json`: + +```json +"scripts": { + "dep:check": "npx ncu -e 2", + "dep:update": "npx ncu -u" +} +``` + +Run the following script to check for any dependencies that need upgrading: + +```bash +npm run dep:check +``` + +If required, one can execute the following command to install the latest dependencies: + +```bash +npm run dep:update && npm i +``` + +If a dependency cannot be upgraded for a valid reason, then `.ncurc.yaml` file should added to the project root with said dependency added to the `reject` list with an appropriate `comment` as follows: + +```yaml +## Add a TODO comment indicating the reason for each rejected dependency upgrade added to this list, and what should be done to resolve it (i.e. handle it through a story, etc). +reject: [ + # TODO: + "", +] +``` + +The following approaches are utilized to enforce that dependencies are kept up-to-date: + +##### Git Pre-Commit Hook + +This will ensure that a validation check will occur on a Developer's local machine when making any Git Commits. + +The `dep:check` should be added as a git commit pre-hook using [Husky](https://www.npmjs.com/package/husky) as follows: + +```bash +npx husky add .husky/pre-commit "npm run dep:check" +``` + +> Note: It is possible to circumvent this by using `-n` parameter when committing using `git commit -nm `. A CI (*Continuous Integration*) `test-dependencies` Validation Check (*see next section*) is thus required to ensure enforcement. + +##### Automated CI Validations + +This will ensure that a validation check occur during reviews and releases, and also ensure that Git Pre-Commit Hook are not circumvented. + +CI Configs (i.e. `.circleci/config.yml`) must contain a `test-dependencies` Validation Check CI Job (i.e. `npm run dep:check`) for all Pull-Request, merges to Main branch, and Tagged Releases. + +### Dependency Auditing + +#### NodeJS + +NodeJS projects should install [audit-ci](https://www.npmjs.com/package/audit-ci) using the following command: + +```bash +npm install -D audit-ci +``` + +And add the following scripts to `package.json`: + +```json +"scripts": { + "audit:check": "npx audit-ci --config ./audit-ci.jsonc" +} +``` + +Run the following script to check for any dependencies that need upgrading: + +```bash +npm run audit:check +``` + +If required, one can execute [npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) to apply any known available fixes: + +```bash +npm audit fix --package-lock-only +``` + +> +> NOTES +> +> 1. Ensure to commit any fixes applied by the above command to the `package-lock.json`. +> 2. Ensure that all tests pass after applying any fixes as they may result in a dependency version change which could introduce breaking changes. +> + +If there is no fix, then `audit-ci.jsonc` file should added to the project root with said `vulnerability advisories ID` added to the `allowlist` with an appropriate `comment` as follows: + +```json +{ + "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json", + // audit-ci supports reading JSON, JSONC, and JSON5 config files. + // Only use one of ["low": true, "moderate": true, "high": true, "critical": true] + "moderate": true, + "allowlist": [ // NOTE: Please add as much information as possible to any items added to the allowList + // Currently no fixes available for the following advisory ID + "" + ] +} +``` + +##### Git Pre-Commit Hook + +This will ensure that a vulnerability checks will occur on a Developer's local machine when making any Git Commits. + +The `audit:check` should be added as a git commit pre-hook using [Husky](https://www.npmjs.com/package/husky) as follows: + +```bash +npx husky add .husky/pre-commit "npm run audit:check" +``` + +> Note: It is possible to circumvent this by using `-n` parameter when committing using `git commit -nm `. A CI (*Continuous Integration*) `vulnerability-check` vulnerability Check (*see next section*) is thus required to ensure enforcement. + +##### Automated CI Validations + +This will ensure that auditing checks occur during reviews and releases, and also ensure that Git Pre-Commit Hook are not circumvented. + +CI Configs (i.e. `.circleci/config.yml`) must contain a `vulnerability-check` vulnerability Check CI Job (i.e. `npm run dep:check`) for all Pull-Request, merges to Main branch, and Tagged Releases. + +## Design + Implementation Guidelines + +These guidelines are meant as recommendations for writing code in the Mojaloop community (or code that will be adopted into the community). If you are writing code that you wish to donate code to the community, we ask that you follow these guidelines as much as possible to aid with the consistency and maintainability of the codebase. Donations that adhere to these guidelines will be adopted more easily and swiftly. + +For more information, refer to the FAQ [below](#faqs). + +## Tools + Frameworks + +In the Mojaloop OSS Community, we prefer the following tools and frameworks: + +- **Web Server:** [`HapiJS`](https://github.com/hapijs/hapi) +- **Web UI Framework:** [`ReactJS`](https://reactjs.org/) +- **Runtime Configuration:** [`convict`](https://www.npmjs.com/package/convict), with [`rc`](https://www.npmjs.com/package/rc) for legacy. (both for env variables and config files) +- **Package Management:** `npm` +- **Logging:** [`@mojaloop/central-services-logger`](https://github.com/mojaloop/central-services-logger#readme) library, built on top of Winston +- **Containers and Orchestration:** [`docker`](https://www.docker.com/) and [`kubernetes`](https://kubernetes.io/) +- **Unit Testing:** For existing tests, [`Tape`](https://github.com/substack/tape), but we are currently moving over to [`Jest`](https://jestjs.io/) for new codebases. +- **Test Coverage:** [`nyc`](https://github.com/istanbuljs/nyc) +- **CI:** [`CircleCI`](https://circleci.com/) + +By using these tools and frameworks, we maintain a high level of consistency and maintainability across the codebase, which keeps our developers productive and happy. While we don't mandate that donated codebases use these same tools and frameworks, we would like to stress that adoptions that use different tools could create an undue maintenance burden on the Community. + +## Adopting Open Source Contributions into Mojaloop + +This section provides guidelines regarding the adoption of a contribution to the Mojaloop Open Source repositories. Adoption is the process where we as the community work with a contributor to bring a contribution into alignment with our standards and guidelines to be a part of the Mojaloop OSS Codebase. + +>*Note:* Code Contributions are evaluated on a **case-by-case** basis. Contributions that don't align to these guidelines will need to go through the incubation phase as described below. Other misalignments to these standards (for example, framework choices) may be added to a roadmap for further improvement and OSS Standardization in the future. + +### Step 0: Prerequisites + +Before a contribution is to be considered for adoption, it: + +1. Should be in-line with the [Level One Project Principles](https://leveloneproject.org/). +1. Should adhere to the above Style and Design + Implementation Guides. +1. Should contain documentation to get started: the more, the better. +1. Contain tests with a high level of coverage. At a minimum, a contribution should contain unit tests, but a test suite with unit, integration and functional tests is preferred. Refer to the [contributors guide](./tools-and-technologies/automated-testing) for more information. + +### Step 1: Incubation + +1. Create a private repo within the Mojaloop GitHub organization for the adopted code. +1. Have a sub-team of the DA take a look to make sure its portable \(to OSS\) - aligns with L1P principles, etc, and ensure design is in line with standards. +1. Check Licensing of the contribution and any new dependencies it requires, and add the standard Mojaloop License with attribution to donor/contributors. +1. Assess the current state of the codebase, including documentation, tests, code quality, and address any shortfalls. +1. Assess Performance impact. +1. Create action items \(stories\) to update naming, remove/sanitize any items that are not generic +1. Inspect and discuss any framework and tooling choices. + +- If a decision is made to make any changes, add them to the roadmap. + +### Step 2: Public Adoption + +1. Make the project public on Mojaloop GitHub. +1. Announce on the slack [`#announcements`](https://mojaloop.slack.com/archives/CG3MAJZ5J) channel. +1. Enable CI/CD Pipelines and publish any relevant artifacts, such as Docker Images or npm modules. +1. Review and recommend a module or course for the Mojaloop Training Program if needed and relevant for this contribution. + +## Versioning + +Review the information on [versioning](./versioning.md) for Mojaloop. + +## Creating new Features + +Process for creating new [features and branches](./creating-new-features.md) in Mojaloop. + +## Pull Request Process + +It's a good idea to ask about major changes on [Slack](https://mojaloop.slack.com). Submit pull requests which include both the change and the reason for the change. Feel free to use GitHub's "Draft Pull Request" feature to open up your changes for comments and review from the community. + +Pull requests will be denied if they violate the [Level One Principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf). + +## Code of conduct + +We use the [Mojaloop Foundation Code of Conduct](https://github.com/mojaloop/mojaloop/blob/master/CODE_OF_CONDUCT.md) + +## Licensing + +See [License](https://github.com/mojaloop/mojaloop/blob/master/contribute/License.md) policy. + +## FAQs + +**1. What if I want to contribute code, but it doesn't align with the code style and framework/tool recommendations in this guide?** + + Contributions are accepted on a *case by case* basis. If your contribution is not yet ready to be fully adopted, we can go through the incubation phase described above, where the code is refactored with our help and brought into alignment with the code and documentation requirements. + +**2. These standards are outdated, and a newer, cooler tool (or framework, method or language) has come along that will solve problem *x* for us. How can I update the standards?** + + Writing high quality, functional code is a moving target, and we always want to be on the lookout for new tools that will improve the Mojaloop OSS codebase. So please talk to us in the design authority slack channel (`#design-authority`) if you have a recommendation. diff --git a/docs/community/standards/invariants.md b/docs/community/standards/invariants.md new file mode 100644 index 000000000..2dea21176 --- /dev/null +++ b/docs/community/standards/invariants.md @@ -0,0 +1,230 @@ +# Mojaloop Invariants + +The following invariants have been established during the course of the platform’s development and based upon the technical requirements inferred from the [Level One Project Principles](https://www.leveloneproject.org/project_guide/level-one-project-design-principles/) and applicable industry best practices. +These invariants should guide any product and technical design discussions related to the architecture of the platform. + +## General Principles + +### 1. The primary function of the platform is to clear credit-push payments in real-time and facilitate regular settlement, by the end of the value day. +#### Notes: +1. The platform allows participants to clear funds immediately to their customers while keeping the risks and costs associated with this to a minimum. +2. The platform supports per-transfer checks on available liquidity where these are required in support of the first objective. +3. The hub is optimized for critical path. +4. Intra-day Automated Settlement; configured by scheme and implementation using recommended settlement models for financial market infrastructure. + + +### 2. The hub supports fully automatic straight-through processing. +#### Notes: +1. "Straight through processing" means that no manual interventions in the execution of payments or settlements should be required, except where acceptance of the terms of a payment is required from an end user in conformity with the Level One Principles +2. Straight through processing helps reduce human errors in the transfer process which ultimately reduces costs. +3. The automated nature of straight through processing leads to faster value transfers between end customers. + +More information here: [Straight Through Processing Definition](https://www.investopedia.com/terms/s/straightthroughprocessing.asp) + + +### 3. The hub requires no manual reconciliation as the protocol for interacting with the hub guarantees deterministic outcomes. +#### Notes: +1. When a transfer is finalized, there can be no doubt about the status of that transfer (alternatively, it is not finalized and active notice provided to participants. The notice provided to participants is on demand: if they enquire, they are informed that status is indeterminate). +2. The hub guarantees deterministic outcomes for transfers and is accepted by all participants as the final authority on the status of transfers. +3. Determinism means individual transfers are traceable, auditable (based on limits, constraints), with final result provided within guaranteed time limit. +4. For the avoidance of doubt, batch transfers are processed line-by-line with potentially differing deterministic outcomes for each. + + +### 4. Transaction setup logic, which is use case-specific, is separated from the policy-free transfer of money. +#### Notes: +1. Transaction details and business rules should be captured and applied between counterparties prior to the agreement of terms phase and is out of scope for Mojaloop. +2. The agreement phase establishes a signed use-case specific transaction object which incorporates all transaction-specific details. +3. The transfer phase orchestrates the transfer of retail value between institutions for the benefit of the counterparties (i.e only system limit checks are applied) and without reference to transaction details. +4. No additional transaction-specific processing during the transfer phase. + + +### 5. The hub doesn’t parse or act on end-to-end transaction details; transfer messages contain only the values required to complete clearing and settlement. +#### Notes: +1. Checks & validations during the transfer step are only for conformance to scheme rules, limit checks, signature authentication, and validation of payment condition and fulfillment. +2. Transfers that are committed for settlement are final and are guaranteed to settle under the scheme rules. + + +### 6. Credit-push transfer semantics are reduced to their simplest form and standardized for all transaction types. +#### Notes: +1. Simplifies implementation and participant integration as many transaction types and use-cases can reuse the same underlying value transfer message flow. +2. Abstracts use-case complexity away from the critical path. + + +### 7. Internet-based API service hub is not a “message switch.” +#### Notes: +1. The service hub provides real-time API services for participants to support retail credit-push instant transfers. + 1. API services such as address resolution, transaction agreement between participants, submission of prepared transfers, and submission of fulfillment advice. +2. Auxiliary API services for participants are provided to support onboarding, position management, reporting for reconciliation, and other non-realtime functions not associated with transfer processing. +3. All messages are validated for conformance to the API specification; non-conforming messages are actively rejected with a standardized machine-interpretable reason code. + + +### 8. The hub exposes asynchronous interfaces to participants +#### Notes: +1. To maximize system throughput. +2. To isolate leaf-node connectivity issues so they don't impact other end-users. +3. To enable the hub system to process requests in its own priority order and without holding an active connection-per-transfer. +4. To handle numerous concurrent long-running processes through internal batching and load balancing. +5. To have a single mechanism for handling requests (Examples are transactions such as bulk or those needing end user input or that span multiple hops). +6. To better support real world networking as issues with connection speed and reliability for one participant should have minimal impact on other participants or system availability more generally. + +### 9. The transfer API is [idempotent](https://docs.mojaloop.io/api/fspiop/v1.1/api-definition.html#idempotent-services-in-server) +#### Notes: +1. This ensures duplicate requests may be made safely by message originators in conditions of degraded network connectivity. + 1. Duplicate requests are recognized and result in the same outcome (valid duplicates) or are rejected as duplicate (when not allowed by specification) with reference to the original. + + +### 10. **_Finalized_** Transfer records are held for a scheme-configurable period to support scheme processes such as reconciliation, billing, and for forensic purposes +#### Notes: +1. It is not possible to query the "sub-status" of an in-process Transfer; the API provides a deterministic outcome with active notice provided within the guaranteed service time. + + +### 11. Transfer records for finalized transfers are held indefinitely in long-term storage to support business analysis by the scheme operator and by participants (through appropriate interfaces) +#### Notes: +1. Availability of Transfer records may lag online process finality to accommodate separation of record-keeping from real-time processing of Transfer requests. + + +### 12. The hub should do the minimum parsing, storing and processing of messages required to execute the services that it provides to the scheme as a whole. +#### Notes: +1. In some messaging flows e.g. party lookup, it may be desirable for participants to have a single point of contact for routing of scheme related messages, even when the messages are not intended for the hub, nor require any inspection or other processing. + + +## Security and Safety of APIs + +### 13. API messages are confidential, tamper-evident, and non-repudiable. +#### Notes: +1. Confidentiality is required to protect the privacy of the participants and their customers. + 1. There are legal requirements in many regulatory domains where Mojaloop is expected to operate and as such, the hub must employ best practices to ensure that the privacy of the participants and their customers is protected. +2. Tamper-evident integrity mechanisms are required to ensure that messages cannot be altered in transit. + 1. To ensure the integrity of the overall system, each recipient of a message should be able to independently tell, with a high degree of confidence, that the message was not altered in transit. + 2. Public key cryptography (digital signing) provides the current best known mechanism for tamper-evident messaging + 1. The security of the sender's private key is critical. + 2. Scheme rules must be established to clarify the responsibilities for key management and the potential for financial liability upon compromise of a private key. +3. Non-repudiation is required to ensure that the message was sent by the party which purported to send it and that provenance can not be repudiated by the sender. + 1. This is important for determining the liable party during audit and dispute resolution processes. + + +### 14. API messages are Authenticated upon receipt prior to acceptance or further processing +#### Notes: +1. Authentication gives a degree of confidence that the message was sent by the party which purported to send it. +2. Authentication gives a degree of confidence that the message was not sent by an unauthorized party. + + +### 15. Authenticated Messages are not acknowledged as accepted until safely recorded to permanent store. +#### Notes: +1. The Mojaloop API assigns significant scheme related business meaning to certain HTTP response codes at various points in transaction flows: + 1. Certain HTTP responses, e.g. "202 Accepted", are intended to provide financial guarantees to participants and as such must only be sent once the receiving entity is confident it has made safe, permanent record(s) in support of: + 1. Facilitating system wide recovery to a consistent state after failure(s) in one or more distributed components/entities. + 2. Accurate settlement processes + 3. Audit and dispute resolution processes + 2. For example a "200 OK" from the hub to the payee participant upon receipt of a transfer fulfilment message indicates a guarantee of transaction settlement to the payee pending validation checks. +2. The Mojaloop API is designed to operate safely under imperfect network conditions and as such has built in support for retries and state synchronisation between participants. + + +### 16. Three levels of communication security to ensure integrity, confidentiality, and non-repudiation of messages between an API server and API client. +#### Notes: +1. Secure Connections: mTLS required for all communications between the scheme and authorized participants. + 1. Ensures communications are confidential, between known correspondents, and communications are protected against tampering. +2. Secure Messages: JSON message content is cryptographically signed according to the JWS specification. + 1. Ensures recipients that messages were sent by the party which purported to send them and that provenance can not be repudiated by the sender. +3. Secure Terms of Transfer: Interledger Protocol (ILP) between Payer and Payee participants. + 1. Protects the integrity of the payment condition and its fulfillment. + 2. Limits the time within which a transfer instruction is valid. + + +### 17. To ensure system is arithmetically consistent, only fixed point arithmetic is used. +#### Notes: +1. For the avoidance of doubt, floating point calculations may lose accuracy and must not be used in any financial calculation. +2. See [Level One Decimal Type](https://docs.mojaloop.io/documentation/discussions/decimal.html) representation and forms. + 1. This specification enables seamless interchange with XML-based financial systems without loss of precision or accuracy + + +## Operational Characteristics + +Mojaloop is designed to function as part of a jurisdictional Instant Payments System. As such, it must demonstrably meet the standards of performance and resilience which are required for such systems. + + +### 1. Baseline system demonstrated on minimal hardware supports clearing 1,000 transfers per second, sustained for one hour, with not more than 1% (of transfer stage) taking more than 1 second through the hub. +#### Notes: +1. This measurement includes all necessary hardware and software components with production grade security and data persistence in place. +2. This measurement includes all three transfer stages: discovery, agreement, and transfer. +3. This measurement does not include any participant introduced latency. +4. A one hour period is a reasonable approximation of a demand peak for a national payment system. +5. The cost of scaling up capacity should be less per unit of capacity than the cost of initial provisioning. +6. 1000 transfers (clearing) per second is a reasonable starting point for a national payment system. +7. 1% of transfers (clearing) taking more than 1 second is a reasonable starting point for a national payment system. +8. Mojaloop schemes should be able to start at a reasonable cost point, for national financial infrastructure, and scale economically as demand grows. + + +### 2. The hub is highly available and resilient to failures. +#### Notes: +1. Definition of "highly available": + 1. In this instance we define the term "_highly available_" as meaning "_the ability to provide and maintain an acceptable level of service in the face of faults and challenges to normal operation._" + 2. Although schemes may determine their own definition of what constitutes an "_acceptable level of service_", Mojaloop makes certain contributing tradeoff choices: + 1. When fault modes permit, service is degraded across the entire participant population rather than individual participants suffering total outages while others remain serviceable. +2. The hub has no single point of failure; meaning that it continues to operate with minimum degradation of service in the event of a failure of any single component. + 1. Multiple active instances of each component are deployed in a distributed manner behind load balancers. + 2. Each active component instance can handle requests from any client/participant meaning no single participant loses the ability to transact in the event of a failure of any single component. +3. Given appropriate infrastructure to operate upon, the Mojaloop software can be deployed in active:active and/or active:passive multiple, geographically distributed data center configurations where both services and data are replicated across multiple physical nodes which are expected to fail independently. +4. Note that it is expected that nodes in replication groups (and/or clusters) will be located in diverse physical locations (racks and/or data centres) with independent power supplies and network interconnects. +5. Should multiple component failures occur which have not been mitigated either in the Mojaloop software, deployment configuration or infrastructure, the Mojaloop API provides mechanisms for each entity in the scheme to recover to a consistent state, with the hub being the ultimate source of truth upon full restoration of service. +6. _Also see further points relating to resistance to data loss in the event of failures._ +7. Given that Mojaloop schemes are intended to form parts of national financial infrastructure they must have as close to zero downtime as possible, given reasonable cost constraints. +8. Failures in hardware and software components are to be expected, even in the highest quality components available. Best practice suggests these failures should be anticipated and planned for as much as possible in the design of the hub with a view to minimising loss or degradation of service and/or data. +9. For the avoidance of doubt this means the tradeoffs chosen favour overall service availability and state consistency over performance. I.e: + 1. All participants can continue to transact at a reduced rate rather than some participants being unable to transact at all. + 2. Inconsistencies in state between scheme entities are resolvable post service restoration via the Mojaloop API, with minimal manual reconciliation necessary; the hub being the ultimate source of truth. +10. In situation where sufficient throughput to handle all incoming requests in a timely manner cannot be sustained, the hub will prioritise processing transfers which are in-flight over new incoming requests. + 1. Transfers which the hub cannot process before specified deadlines expire will be timed out gracefully. + + +### 3. The hub is resistant to loss of data in the event of failures. +#### Notes: +1. Given appropriate infrastructure to operate upon, the Mojaloop software can be deployed in configurations which reliably replicate data across multiple, redundant physical storage nodes prior to processing. + 1. Database engine components which are provided by the Mojaloop deployment mechanisms support the following: + 1. Primary:secondary asynchronous replication + 2. Primary:primary synchronous replication. + 3. Synchronous quorum consensus algorithm based replication. + 2. The replication mechanisms available are dependant on the particular storage layer and database technologies employed. +2. Should multiple component failures occur which have not been mitigated either in the Mojaloop software, deployment configuration or infrastructure, the Mojaloop API provides mechanisms for each entity in the scheme to recover to a consistent state with minimal financial exposure risk. + 1. Transfers become financially binding only when the hub has successfully responded to a transfer fulfilment message from the payee participant. This response is only sent when the hub has persisted the fulfilment message and its outcome to its ledger database. + 2. Expiration timestamps on all financially significant API messages facilitate timely and deterministic failure path outcomes for all participants via automated retry mechanisms. +3. Given that Mojaloop schemes are intended to form parts of national financial infrastructure they must do as much as possible, given reasonable cost constraints, to avoid loss of data in the event of a failure. +4. Failures in hardware and software components are to be expected, even in the highest quality components available. Best practice suggests these failures should be anticipated and planned for in the design of the hub with a view to avoiding data loss. +5. Participants need timely confidence in the status of financial transactions across the scheme in order to minimise exposure risk and deliver excellent customer experiences. + + +## Design Decisions +1. NodeJS is the primary execution environment with TypeScript the preferred language for development. + 1. This platform is free open source + 2. Is widely used and actively supported by the world's largest web-based institutions + 3. Has a massive global portfolio of libraries + 4. Utilizes only the ECMAScript family of architecture-neutral languages and libraries known by millions of skilled web programmers + + +2. Use a micro-service distributed architecture. + 1. [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter) or Principle of Least Knowledge + 2. [Separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) secured by inter-module contracts + 3. [Modular architecture](https://en.wikipedia.org/wiki/Modular_programming) enables distributed development in a community environment and improvement of components with minimal disruption to adjacent components + + +3. [Apache Kafka](https://kafka.apache.org/intro) distributed [Publish–Subscribe](https://en.wikipedia.org/wiki/Publish–subscribe_pattern) for inter-module [Command–Query Separation (CQS)](https://en.wikipedia.org/wiki/Command–query_separation) + + +4. [Apache Kafka](https://kafka.apache.org/intro) for persistent handling of participant API messages + + +5. Mojaloop uses APIs based on Open API 3.0. + 1. Exposes resources that are mapped to functionality to support the defined API use-cases. + 2. Common practice for web API specification + + +## Annexure A : Level One Principles Overview +The [Level One Project](https://www.leveloneproject.org) proposes a new low-cost payments system that supports inclusive, interoperable digital payments. The [Level One Project Guide](https://www.leveloneproject.org/project_guide/03-welcome-to-the-2019-guide/) outlines a vision of how an inclusive digital financial services system can work for the benefit of poor people. The underlying design principles of the Guide include: +* A credit push payment model with immediate funds transfer and same day settlement +* Open-loop interoperability between providers +* Adherence to well-defined and adopted international standards +* Adequate system-wide shared fraud and security protection +* Efficient and proportional identity and know-your-customer (KYC) requirements +* Meeting or exceeding the convenience, cost and utility of cash + +By utilizing an open, digital approach to transactions, and partnering with organizations across the public and private sectors, the Level One Project aims to provide access to a robust, low-cost shared digital financial services infrastructure, sparking innovation from new and existing participants, reducing risk, and generating substantial value for providers, individuals and economies in developing markets. Additional resources have been created to help governments, NGOs and financial service providers successfully implement these changes. diff --git a/docs/community/standards/triaging-bugs.md b/docs/community/standards/triaging-bugs.md new file mode 100644 index 000000000..44bb91484 --- /dev/null +++ b/docs/community/standards/triaging-bugs.md @@ -0,0 +1,22 @@ +# Triaging Mojaloop OSS bugs + +### Raising a bug / issue + +If there is a bug or issue in general an issue is logged as a bug or feature request on the [project](https://github.com/mojaloop/project/issues/new/choose) repository and in some cases linked to an issue logged on the repository for that specific component. + +There is a bug [template](https://github.com/mojaloop/project/issues/new?assignees=&labels=bug&template=bug_report.md&title=) that can be used and encourages use of details such as versions, expected results and other details, which help with triage and reproducing the issue. + +### Once a bug is logged + +1. Typically, the bug is initially triaged in the [#ml-oss-bug-triage](https://mojaloop.slack.com/messages/CMCVBHPUH) public channel on Mojaloop Slack +2. For Security and other sensitive issues, the bug is triaged on a private channel with current contributors, before information is made public at an appropriate time. Details for security issues are covered here: https://docs.mojaloop.io/community/contributing/cvd.html +3. During bug triage, priority and severity are assigned to the bug after majority consensus and consultation with reporter(s) +4. Based on the priority and severity the bug is taken up by the Core team or other contributors based on a collaborative effort. +5. Once it is taken up, conversation and updates happen on GitHub issue and slack channel. + +### Triage + +1. The discussion regarding the issue is open to the public for normal bugs / issues +2. Based on the discussions, a final call on the priority and severity of the issue is made by the Core team in consultation with the reporter(s). +3. The list and the process will be updated as it evolves. +4. Mojaloop bug triage slack channel #[ml-oss-bug-triage](https://mojaloop.slack.com/archives/CMCVBHPUH) diff --git a/docs/community/standards/versioning.md b/docs/community/standards/versioning.md new file mode 100644 index 000000000..b82657f37 --- /dev/null +++ b/docs/community/standards/versioning.md @@ -0,0 +1,126 @@ +# Versioning + +## Versioning of releases made for core Switch services + +This document provides guidelines regarding the versioning strategy used for the releases of Mojaloop Open Source repositories corresponding to the Switch services. + +### Versioning Strategy + + +#### Standard for PI-11 and beyond +1. Starting PI-11 (27th July, 2020) the Versioning guidance is to move to a versioning system that is closely aligned with Semantic versioning by removing the PI/Sprint dependency. So starting 11.x.x, the proposal is to move to pure [SemVer](https://semver.org/). +2. At a high-level, we will still follow the vX.Y.Z format, but X represents ‘Major’ version, Y represents ‘Minor’ version and Z represents ‘patch’ version. Minor fixes, patches affect increments to ‘Z’, whereas non-breaking functionality changes affect changes to ‘Y; breaking changes affect the ‘X’ version. +3. Along with these, suffixes such as “-snapshot”, “-patch”, “-hotfix” are used as relevant and on need basis (supported by CI config). +4. So starting with 11.0.0 (primarily for Helm, but for individual services as well) for PI-11, the proposal is to move to pure [SemVer](https://semver.org/). +5. This implies that for any new release of a package/service below X=11 (for existing repositories and not new ones) will first be baselined to v11.0.0 and from then on follow standard SemVer guidelines as discussed above. For new projects or repositories, versioning can start from v1.0.0 (after they reach release status) + + +#### Versioning Strategy used until PI-10 +1. The Mojaloop (up to PI-10) versioning system is inspired by the [Semantic Versioning](https://semver.org/) numbering system for releases. +2. However, this is customized to depict the timelines of the Mojaloop project, based on the Program Increment \(PI\) and Sprint numbers +3. For example, the release number v5.1.0 implies that this release was the first one made during a Sprint 5.1, where Sprint5.1 is the first Sprint in PI-5. So for a version vX.Y.Z, X.Y is the Sprint number where X is the PI number and Z represents the number of release for this specific repository. Example v4.4.4 implies that the current release is the fourth of four releases made in Sprint 4.4 \(of PI-4\) + + + +### Current Version + +The current version information for Mojaloop can be found [here](../../deployment-guide/releases.md). + +### Sprint schedule for PI-13 + +Below is the Sprint schedule for Program Increment 13 which ends with the PI-14 Community event in April 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-5 Kick-off On-site**|1/25/2021|1/29/2021|5 days| Virtual Zoom Webinars| +|**Sprint 13.1**|02/01/2021|02/14/2021|2 weeks | | +|**Sprint 13.2**|02/15/2021|02/28/2021|2 weeks | | +|**Sprint 13.3**|03/01/2021|03/14/2021|2 weeks | | +|**Sprint 13.4**|03/15/2021|03/28/2021|2 weeks | | +|**Sprint 13.5**|03/29/2021|04/11/2021|2 weeks | | +|**Sprint 13.6**|04/12/2021|04/25/2021|2 weeks | | +|**Phase-5 PI-14**|04/26/2021|04/30/2021|5 days| Virtual meetings | + +### Sprint schedule for PI-12 + +Below is the Sprint schedule for Program Increment 12 which ends with the PI-13 Community event in January 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-12 Virtual**|10/19/2020|10/23/2020|5 days| Virtual Zoom Webinars| +|**Sprint 12.1**|10/26/2020|11/15/2020|3 weeks | | +|**Sprint 12.2**|11/16/2020|11/29/2020|2 weeks | | +|**Sprint 12.3**|11/30/2020|12/13/2020|2 weeks | | +|**Sprint 12.4**|12/14/2020|12/27/2020|2 weeks | | +|**Sprint 12.5**|12/28/2020|01/10/2021|2 weeks | | +|**Sprint 12.6**|01/11/2021|01/24/2021|2 weeks | | +|**Phase-5 Kick-off / PI-13**|01/25/2021|01/29/2021|5 days| TBD | + +### Previous Sprint Schedules: + +### Sprint schedule for PI-11 + +Below is the Sprint schedule for Program Increment 11 which ends with the PI 12 Event. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars | +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars | +|**Sprint 11.1**|7/27/2020|8/9/2020|2 weeks| | +|**Sprint 11.2**|8/10/2020|8/23/2020|2 weeks| | +|**Sprint 11.3**|8/24/2020|9/6/2020|2 weeks| | +|**Sprint 11.4**|9/7/2020|9/20/2020|2 weeks| | +|**Sprint 11.5**|9/21/2020|10/4/2020|2 weeks| | +|**Sprint 11.6**|10/5/2020|10/18/2020|2 weeks | | +|**Phase-4 PI-12**|10/20/2020|10/23/2020|4 days| TBD | + +#### Sprint schedule for PI-10 + +Below is the Sprint schedule for Program Increment 10 which ends with the PI 11 Event. Please use this as guidance during the versioning and release processes. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-3 PI6 On-site**|4/16/2019|4/18/2019|3 days| Johannesburg| +|**Phase-3 PI7 On-site**|6/25/2019|6/27/2019|3 days| Arusha| +|**Phase-3 PI8 On-site**|9/10/2019|9/12/2019|3 days| Abidjan| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI 10 Virtual**|4/21/2020|4/24/2020|5 days| Virtual Zoom Webinars | +|**Sprint 10.1**|4/27/2020|5/10/2020|2 weeks| | +|**Sprint 10.2**|5/11/2020|5/24/2020|2 weeks| | +|**Sprint 10.3**|5/25/2020|6/7/2020|2 weeks| | +|**Sprint 10.4**|6/8/2020|6/21/2020|2 weeks| | +|**Sprint 10.5**|6/22/2020|7/5/2020|2 weeks| | +|**Sprint 10.6**|7/6/2020|7/19/2020|2 weeks | | +|**Phase-4 PI 11 On-Site**|7/21/2020|7/23/2020|3 days| Kenya (Tentative) | + +#### PI-9 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 9.1**|2/3/2020|2/16/2020|2 weeks| | +|**Sprint 9.2**|2/17/2020|3/1/2020|2 weeks| | +|**Sprint 9.3**|3/2/2020|3/15/2020|2 weeks| | +|**Sprint 9.4**|3/16/2020|3/29/2020|2 weeks| | +|**Sprint 9.5**|3/30/2020|4/12/2020|2 weeks| | +|**Sprint 9.6**|4/13/2020|4/19/2020|1 week | | +|**Phase-4 PI 10 Virtual**|4/21/2020|4/23/2020|5 days| Virtual Zoom Webinars | + +#### PI-8 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 8.1**|9/16/2019|9/29/2019|2 weeks| | +|**Sprint 8.2**|9/30/2019|10/13/2019|2 weeks| | +|**Sprint 8.3**|10/14/2019|10/27/2019|2 weeks| | +|**Sprint 8.4**|10/28/2019|11/10/2019|2 weeks| | +|**Sprint 8.5**|11/11/2019|11/24/2019|2 weeks| | +|**Sprint 8.6**|11/25/2019|12/8/2019|2 weeks| | +|**Sprint 8.7**|12/9/2019|1/5/2020|4 weeks| Christmas Break| +|**Sprint 8.8**|1/6/2020|1/26/2020|3 weeks| 1 week prep| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| + +### Notes + +1. A new release for **helm** repo is made based on the feature and configuration changes made to core services and requirements from thhe Community. \ No newline at end of file diff --git a/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml b/docs/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.plantuml similarity index 100% rename from contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml rename to docs/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.plantuml diff --git a/docs/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg b/docs/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg new file mode 100644 index 000000000..1b0b9de1a --- /dev/null +++ b/docs/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg @@ -0,0 +1,164 @@ + + Regression Test Life Cycle + + + + Regression Test Life Cycle + (Self-contained Test Server on EC2) + + + + This could be a manual trigger, + scheduler timer or + an external action like a Pull Request + from the Source Control System + + Test is triggered + + Validate run parameters as expected? + yes + no + + + Set Timestamp + PostmanCollection to execute + List of email recipients + Environment Variables + Execution Timestamp + Output FileName + + Prepare environment for required run + + Abort run with Note stating incorrect Run Parameters + + + + Create Simulator Docker Container + + + This container has node + Newman\email SMTP Server + + Create Regression Test Docker Container + + + Set up any variables for + preparation of the request to follow + + Perform Pre-Request Script + + Execute Postman Request + + Perform Test + + + Inspect the response + against variables set previously during + the run to determine if expected results are obtained + + Log Results + + no + Run Parameter requested 'Abort at First Error'? + yes + + + + yes + Assertion Test Failed? + no + + + Yes + More Postman Requests to run? + No + + + + Destroy Simulator Docker Container + + Finalise Report + + Prepare Notification(s) + + Attach Reports + + + The Attachment (Generated Report) + is sent as an attachment + to the different notification channels. + + Send out Notification(s) + + Destroy Regression Test Docker Container + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/community/tools/assets/images/ci_cd_lib_master.png b/docs/community/tools/assets/images/ci_cd_lib_master.png new file mode 100644 index 000000000..331087be4 Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_lib_master.png differ diff --git a/docs/community/tools/assets/images/ci_cd_lib_pr.png b/docs/community/tools/assets/images/ci_cd_lib_pr.png new file mode 100644 index 000000000..1a64f791f Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_lib_pr.png differ diff --git a/docs/community/tools/assets/images/ci_cd_lib_tag.png b/docs/community/tools/assets/images/ci_cd_lib_tag.png new file mode 100644 index 000000000..13af7e59c Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_lib_tag.png differ diff --git a/docs/community/tools/assets/images/ci_cd_svc_master.png b/docs/community/tools/assets/images/ci_cd_svc_master.png new file mode 100644 index 000000000..6ab54d9d9 Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_svc_master.png differ diff --git a/docs/community/tools/assets/images/ci_cd_svc_pr.png b/docs/community/tools/assets/images/ci_cd_svc_pr.png new file mode 100644 index 000000000..389f5ccba Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_svc_pr.png differ diff --git a/docs/community/tools/assets/images/ci_cd_svc_tag.png b/docs/community/tools/assets/images/ci_cd_svc_tag.png new file mode 100644 index 000000000..934aee684 Binary files /dev/null and b/docs/community/tools/assets/images/ci_cd_svc_tag.png differ diff --git a/docs/community/tools/assets/images/mojaloop_cybersec_architecture.jpg b/docs/community/tools/assets/images/mojaloop_cybersec_architecture.jpg new file mode 100644 index 000000000..aaf8dcca4 Binary files /dev/null and b/docs/community/tools/assets/images/mojaloop_cybersec_architecture.jpg differ diff --git a/docs/community/tools/assets/images/mojaloop_security_layers.jpg b/docs/community/tools/assets/images/mojaloop_security_layers.jpg new file mode 100644 index 000000000..d70949b68 Binary files /dev/null and b/docs/community/tools/assets/images/mojaloop_security_layers.jpg differ diff --git a/docs/community/tools/automated-testing.md b/docs/community/tools/automated-testing.md new file mode 100644 index 000000000..39651c0ad --- /dev/null +++ b/docs/community/tools/automated-testing.md @@ -0,0 +1,144 @@ +# QA and Regression Testing in Mojaloop +An overview of the testing framework set up in Mojaloop + +Contents: +1. [Regression requirements](#regression-topics) +2. [Developer Testing](#developer-testing) +3. [Postman and Newman Testing](#postman-and-newman-testing) +4. [Executing regression test](#executing-regression-test) +5. [Process flow of a typical Scheduled Test](#process-flow-of-a-typical-scheduled-test) +6. [Newman Commands](#newman-commands) + +## Regression Topics + In order for a deployed system to be robust, one of the last checkpoints is to determine if the environment it is deployed in, is in a healthy state and all exposed functionality works exactly the way as intended. + + Prior to that though, there are quite a number of disciplines one must put in place to ensure maximum control. + + To illustrate how the Mojaloop project reaches this goal, we are going to show you the various checkpoints put in place. + +### Developer Testing + Looking at each component and module, inside the code base, you will find a folder named "*test*" which contain three types of tests. + + Firstly, the *coverage test* which alerts one if there are unreachable or redundant code + + Unit Tests, which determines if the intended functionality works as expected + + Integration Tests, which does not test end-to-end functionality, but the immediate neighbouring interaction + + Automated code-standard checks implemented by means of packages that form part of the code base + + These tests are executed by running the command line instructions, by the developer, during the coding process. Also, the tests are automatically executed every time a *check-in* is done and a Github Pull-Request issued for the code to be integrated into the project. + + The procedure described above, falls outside the realm of Quality Assurance (QA) and Regression testing, which this document addresses. + + Once a developer has written new functionality or extended existing functionality, by having to go through the above rigorous tests, one can assume the functionality in question is executing as intended. How does one then ensure that this new portion of code does not negatively affect the project or product as a whole? + + When the code has passed all of the above and is deployed as part of the CI/CD processes implemented by our workflow, the new component(s) are accepted onto the various hosts, cloud-based or on-premise implementations. These hosts ranges from development platforms through to production environments. + +### Postman and Newman Testing + Parallel to the deployment process is the upkeep and maintenance of the [Postman](https://github.com/mojaloop/postman.git "Postman") Collection testing Framework. When a new release is done, as part of the workflow, Release Notes are published listing all of the new and/or enhanced functionality implemented as part of the release. These notes are used by the QA team to extend and enhance the existing Postman Collections where tests are written behind the request/response scripts to test both positive as well as negative scenarios agains the intended behaviour. These tests are then run in the following manner: + + Manually to determine if the tests cover all aspects and angles of the functionality, positive to assert intended behaviour and negative tests to determine if the correct alternate flows work as intended when something unexpected goes wrong + + Scheduled - as part of the Regression regime, to do exactly the same as the manual intent, but fully automated (with the *Newman Package*) with reports and logs produced to highlight any unintended behaviour and to also warn where known behaviour changed from a previous run. + +In order to facilitate the automated and scheduled testing of a Postman Collection, there are various methods one can follow and the one implemented for Mojaloop use is explained further down in this document. + +There is a complete repository containing all of the scripts, setup procedures and anything required in order to set up an automated [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"). This framework allows one to target any Postman Collection, specifying your intended Environment to execute against, as well as a comma-separated list of intended email recipients to receive the generated report. This framework is in daily use by Mojaloop and exists on an EC2 instance on AWS, hosting the required components like Node, Docker, Email Server and Newman, as well as various Bash Scripts and Templates for use by the framework to automatically run the intended collections every day. Using this guide will allow anyone to set up their own Framework. + +#### Postman Collections + +There are a number of Postman collections in use throughout the different processes: + +For Mojaloop Simulator: + ++ [MojaloopHub_Setup](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) : This collection needs to be executed once after a new deployment, normally by the Release Manager. It sets up an empty Mojaloop hub, including things such as the Hub's currency, the settlement accounts. ++ [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) : MojaloopSims_Onboarding sets up the DFSP simulators, and configures things such as the endpoint urls so that the Mojaloop hub knows where to send request callbacks. ++ [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + + Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. ++ [Bulk_API_Transfers_MojaSims](https://github.com/mojaloop/postman/blob/master/Bulk_API_Transfers_MojaSims.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Mojaloop Simulator. + +For Legacy Simulator (encouraged to use Mojaloop Simulator, as this will not be supported starting PI-12 (Oct 2020) ): + ++ [ML_OSS_Setup_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Setup_LegacySim.postman_collection.json) : This collection needs to be executed once after a new deployment (if it uses Legacy Simulator), normally by the Release Manager. It sets up the Mojaloop hub, including things such as the Hub's currency, the settlement accounts along with the Legacy Simulator(s) as FSP(s). ++ [ML_OSS_Golden_Path_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Golden_Path_LegacySim.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + + Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. ++ [Bulk API Transfers.postman_collection](https://github.com/mojaloop/postman/blob/master/Bulk%20API%20Transfers.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Legacy Simulator. + +#### Environment Configuration + +You will need to customize the following environment config file to match your deployment environment: ++ [Local Environment Config](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local.postman_environment.json) + +_Tips:_ +- _The host configurations will be the most likely changes required to match your environment. e.g. `HOST_CENTRAL_LEDGER: http://central-ledger.local`_ +- _Refer to the ingress hosts that have been configured in your `values.yaml` as part of your Helm deployment._ + +### Executing regression test +For the Mojaloop QA and Regression Testing Framework specifically, Postman regression test can be executed by going into the EC2 instance via SSH, for which you need the PEM file, and then by running a script(s). + +Following the requirements and instructions as set out in the detail in [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"), everyone will be able to create their own Framework and gain access to their instance to execute tests against any Postman Collection targeting any Environment they have control over. + +##### Steps to execute the script via Postman UI ++ Import the desired collection into your Postman UI. You can either download the collection from the repo or alternatively use the `RAW` link and import it directly via the **import link** option. ++ Import the environment config into your Postman UI via the Environmental Config setup. Note that you will need to download the environmental config to your machine and customize it to your environment. ++ Ensure that you have pre-loaded all prerequisite test data before executing transactions (party, quotes, transfers) as per the example collection [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json): + + Hub Accounts + + FSP onboarding + + Add any test data to Simulator (if applicable) + + Oracle onboarding ++ The `p2p_money_transfer` test cases from the [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) collection are a good place to start. + +##### Steps to execute the bash script to run the Newman / Postman test via CLI ++ To run a test via this method, you will have to be in posession of the PEM-file of the server on which the Mojaloop QA and Regression Framework was deployed on an EC2 instance on Amazon Cloud. + ++ SSH into the specific EC2 instance and when running the script, it will in turn run the commands via an instantiated Docker container. + ++ You will notice that by using this approach where both the URLs for the Postman-Collection and Environment File are required as input parameters (together with a comma-delimited email recipient list for the report) you have total freedom of executing any Postman Collection you choose. + ++ Also, by having an Environment File, the specific Mojaloop services targeted can be on any server. This means you can execute any Postman test against any Mojaloop installation on any server of your choice. + ++ The EC2 instance we execute these tests from are merely containing all the tools and processes in order to execute your required test and does not host any Mojaloop Services as such. + +``` +./testMojaloop.sh +``` + +## Process flow of a typical Scheduled Test + +![](./assets/automated-testing/QARegressionTestingMojaloop-Complete.svg) + + +## Newman Commands +The following section is a reference, obtained from the Newman Package site itself, highlighting the different commands that may be used in order to have access to the Postman environment by specifying some commands via the CLI. +``` +Example: ++ newman run -e -n 1 -- + +Usage: run [options] + + URL or path to a Postman Collection. + + Options: + + -e, --environment Specify a URL or Path to a Postman Environment. + -g, --globals Specify a URL or Path to a file containing Postman Globals. + --folder Specify folder to run from a collection. Can be specified multiple times to run multiple folders (default: ) + -r, --reporters [reporters] Specify the reporters to use for this run. (default: cli) + -n, --iteration-count Define the number of iterations to run. + -d, --iteration-data Specify a data file to use for iterations (either json or csv). + --export-environment Exports the environment to a file after completing the run. + --export-globals Specify an output file to dump Globals before exiting. + --export-collection Specify an output file to save the executed collection + --postman-api-key API Key used to load the resources from the Postman API. + --delay-request [n] Specify the extent of delay between requests (milliseconds) (default: 0) + --bail [modifiers] Specify whether or not to gracefully stop a collection run on encountering an errorand whether to end the run with an error based on the optional modifier. + -x , --suppress-exit-code Specify whether or not to override the default exit code for the current run. + --silent Prevents newman from showing output to CLI. + --disable-unicode Forces unicode compliant symbols to be replaced by their plain text equivalents + --global-var Allows the specification of global variables via the command line, in a key=value format (default: ) + --color Enable/Disable colored output. (auto|on|off) (default: auto) + --timeout [n] Specify a timeout for collection run (in milliseconds) (default: 0) + --timeout-request [n] Specify a timeout for requests (in milliseconds). (default: 0) + --timeout-script [n] Specify a timeout for script (in milliseconds). (default: 0) + --ignore-redirects If present, Newman will not follow HTTP Redirects. + -k, --insecure Disables SSL validations. + --ssl-client-cert Specify the path to the Client SSL certificate. Supports .cert and .pfx files. + --ssl-client-key Specify the path to the Client SSL key (not needed for .pfx files) + --ssl-client-passphrase Specify the Client SSL passphrase (optional, needed for passphrase protected keys). + -h, --help output usage information +``` \ No newline at end of file diff --git a/docs/community/tools/ci_cd_pipelines.md b/docs/community/tools/ci_cd_pipelines.md new file mode 100644 index 000000000..d0b25a50c --- /dev/null +++ b/docs/community/tools/ci_cd_pipelines.md @@ -0,0 +1,127 @@ +# CI/CD Pipelines + +The Mojaloop Community uses [CircleCI](https://circleci.com/) to automatically build, test and deploy our +software. This document describes how we use CI/CD in Mojaloop, the different checks we perform on the +software, and how we distribute the software. + +Broadly speaking, there are 2 types of workflow we use, depending on the type of project: +- Library: build node project -> test -> publish to [npm](https://www.npmjs.com/search?q=%40mojaloop) +- Service: build docker image -> test -> publish to [Docker Hub](https://hub.docker.com/u/mojaloop) + +Additionally, we also maintain a set of [Mojaloop Helm Charts](http://docs.mojaloop.io/helm/), which are +built from the [mojaloop/helm](https://github.com/mojaloop/helm) + +## Libraries + +> For a good example of this CI/CD pattern see [central-services-shared](https://github.com/mojaloop/central-services-shared/blob/master/.circleci/config.yml) + +### Pull Request (PR) Flow: + +The PR flow runs on pull requests, and during the [PR review process](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/creating-new-features.md#creating-new-features), these checks must be satisfied +for the code to be merged in. + +![](./assets/images/ci_cd_lib_pr.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | Checks that the PR title conforms to the conventional commits specification | Defined in a CircleCI orb here: [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Runs the unit-tests and checks that code coverage is above the specified limit. | Typically this is 90% | +| test-unit | Runs the unit-tests. Fails if any unit test fails. | | +| vulnerability-check | Runs the `npm audit` tool to search for any vulnerabilities in dependencies | `npm audit` is full of false positives, or security issues that don't apply to our codebase. We use `npm-audit-resolver` to give us flexibility over vulnerabilities that may be ignored, e.g `devDependencies` | +| audit-licenses | Runs the mojaloop `license-scanner-tool` and fails if any license found doesn't match an allowlist specified in the `license-scanner-tool` | [license-scanner-tool repo](https://github.com/mojaloop/license-scanner-tool) | + + +### Master and Release Flow: + +This CI/CD pipeline runs on the master/main branch: + +![](./assets/images/ci_cd_lib_master.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| release | Runs a release which creates a git tag and pushes the git tag | | +| github-release | Adds the release metadata (e.g. changelog) to github, sends a slack alert to #announcements | | + + +### Tag Flow: + +Once a git tag is pushed to the repository, it triggers a workflow that ends +in publishing to `npm`. Importantly, the checks are all run again, to ensure +nothing has changed (e.g. dependencies) inbetween the main/master and the actual +artefact that is published to `npm`. + +![](./assets/images/ci_cd_lib_tag.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| publish | Publishes the latest version of the library based on the git tag | | + + +## Services + +> For a good example of this CI/CD pattern see [central-ledger](https://github.com/mojaloop/central-ledger/blob/master/.circleci/config.yml) + +### Pull Request (PR) Flow: + +The PR flow runs on pull requests, and during the PR review process, these checks must be satisfied +for the code to be merged in. + +![](./assets/images/ci_cd_svc_pr.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | Checks that the PR title conforms to the conventional commits specification | Defined in a CircleCI orb here: [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Runs the unit-tests and checks that code coverage is above the specified limit. | Typically this is 90% | +| test-unit | Runs the unit-tests. Fails if any unit test fails. | | +| test-integration | Runs the integration-tests. Typically by building a docker image locally | | +| vulnerability-check | Runs the `npm audit` tool to search for any vulnerabilities in dependencies | `npm audit` is full of false positives, or security issues that don't apply to our codebase. We use `npm-audit-resolver` to give us flexibility over vulnerabilities that may be ignored, e.g `devDependencies` | +| audit-licenses | Runs the mojaloop `license-scanner-tool` and fails if any license found doesn't match an allowlist specified in the `license-scanner-tool` | [license-scanner-tool repo](https://github.com/mojaloop/license-scanner-tool) | + + +### Master and Release Flow: + +This CI/CD pipeline runs on the master/main branch: + +![](./assets/images/ci_cd_svc_master.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| test-integration | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| release | Runs a release which creates a git tag and pushes the git tag | | +| github-release | Adds the release metadata (e.g. changelog) to github, sends a slack alert to #announcements | | + + +### Tag Flow: + +Once a git tag is pushed to the repository, it triggers a workflow that ends +in publishing a docker image to Docker Hub. Importantly, the checks are all run again, +and further scans are made on the docker image before the image is pushed. + +![](./assets/images/ci_cd_svc_tag.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| build | Builds the docker image | | +| image-scan | Runs `anchore/analyze_local_image` to scan the image | See [anchore-engine](https://circleci.com/developer/orbs/orb/anchore/anchore-engine) CircleCI Orb for more information. | +| license-scan | Runs the mojaloop `license-scanner-tool` on the licenses contained in the docker image | | +| publish | Publishes the latest version of the library based on the git tag | | diff --git a/docs/community/tools/code-quality-metrics.md b/docs/community/tools/code-quality-metrics.md new file mode 100644 index 000000000..f155be68f --- /dev/null +++ b/docs/community/tools/code-quality-metrics.md @@ -0,0 +1,30 @@ +# Code Quality Metrics + +## Functional quality metrics + +### Unit test metrics + +High coverage and low dependencies show that the code is testable and therefore well isolated and easy to maintain. Low complexity also makes code readable and maintainable and helps enforce single responsibility. Real unit tests run very fast as they don't call external components. + +| Code Quality Metrics | New and Project Code | +| :--- | :--- | +| Unit test coverage | >= 80% block coverage | +| Unit test speed | <= 10 seconds | +| Dependencies/method | <= 10 | +| Complexity/method | <= 7 | + +### Component + +Functional testing typically covers pair combinations of the system states. + +### Integration + +Functional tests have one test per message and error. Messages and errors that are handled the same way use the same test. + +### Contract + +Limited to what the consuming teams need that isn't covered by existing unit, component, and integration tests. Often added to over time. + +### End to End + +End to end tests cover acceptance tests from scenarios. \ No newline at end of file diff --git a/docs/community/tools/cybersecurity.md b/docs/community/tools/cybersecurity.md new file mode 100644 index 000000000..9ea975a43 --- /dev/null +++ b/docs/community/tools/cybersecurity.md @@ -0,0 +1,121 @@ +## Mojaloop Cybersecurity Architecture + +## Introduction + +Mojaloop takes both secure-by-design and risk based approaches to cybersecurity, meaning the open-source software provided by the Mojaloop Foundation have been designed to be foundationally secure and are continuously evaluated against possible risks by several processes. + +In addition to the cybersecurity initiatives managed by the Mojaloop Foundation, the wider Mojaloop community includes cybersecurity experts who are able to provide consultancy and services to further enhance adopters' own capabilities. + + + +![Figure 1 - Mojaloop Cybersecurity Architecture Layers](./assets/images/mojaloop_cybersec_architecture.jpg "Figure 1 - Mojaloop Cybersecurity Architecture Layers") + +Figure 1 - Mojaloop Cybersecurity Architecture Layers + +_Please note that although the Mojaloop Foundation and the Mojaloop community attempt to provide software that is secure by design and that can be operated in a secure manner, adopters bear the ultimate responsibility for ensuring the security of their operations. With this in mind the Mojaloop Foundation highly recommends that cybersecurity experts be engaged by adopters to ensure that cybersecurity best practice is followed and that all relevant and applicable standards and regulations are adhered to._ + + +## Secure-By-Design + + +### Design Review Processes + +The Mojaloop Foundation and community manage and operate several security aware design review processes which contribute to the secure-by-design and risk management approaches. + + + +1. The Mojaloop Technical Governing Board determines the high-level technical cybersecurity objectives for the Mojaloop project which are implemented by other community bodies and processes. +2. The Mojaloop community operates a design authority which is a managed group of elected subject matter experts from industry who convene weekly to review technical aspects of the platform software, including but not limited to cybersecurity. +3. The Mojaloop community operates an API change control board which is a managed group of elected subject matter experts from industry who convene weekly to review internal and external API related aspects of the platform software. This group has specific responsibility for ensuring all Mojaloop APIs are secure-by-design and support the latest and best industry standards for securing deployments of the Mojaloop platform. +4. The Mojaloop community operates a product council which is a managed group of elected subject matter experts from industry who convene weekly to review product feature designs. This group contributes to the overall cybersecurity architecture of the Mojaloop product(s) by reviewing existing and creating new requirements and specifications for Mojaloop platform and its security. +5. Mojaloop community standards require feature design and code reviews by community and foundation members who are expert in those areas of the system before code changes or new code is accepted from contributors into official releases. + + +## Technical Controls + +The Mojaloop platform employs several technical layers of security, detailed in the following sections, which contribute to an overall secure platform for conducting financial transactions. + + + +1. At network transport level, X.509 Mutually Authenticated Transport Layer Security (mTLS) is employed (best practice guidance is provided for appropriate cipher suites and hash algorithms) to secure connections between scheme participants and the Mojaloop hub. This mechanism, combined with best practice certificate and key management processes prevents eavesdropping and tampering across scheme network connections. Mojaloop provides best practice guidelines for PKI operations: [https://docs.mojaloop.io/api/fspiop/pki-best-practices.html](https://docs.mojaloop.io/api/fspiop/pki-best-practices.html). +2. Json Web Signatures (JWS) are used at the application message layer to ensure tamper evident messaging and non-repudiation. All scheme participants are provided with the means to tell if an incoming message has been tampered with during transmission. Scheme participants can also be confident of the identity of the message originator. Mojaloop services are able to use this same signature validation to ensure messages have not been tampered with before processing in the hub. +3. Mojaloop uses the [InterLedger protocol](https://docs.mojaloop.io/api/fspiop/v1.1/api-definition.html#interledger-payment-request) (aka ILP) during quotation and transfer phases, as a cryptographic key-lock mechanism, which uses asymmetric cryptography to prevent tampering with agreed transfer terms. +4. Mojaloop enforces request idempotency and transaction state transition controls which assist in mitigating replay type attacks. +5. The Mojaloop platform includes an API gateway layer, which facilitates "IP address filtering", OAuth2.0 identity and access management, and role based access controls which offer further protection against infiltration attacks. +6. Internal and external user interfaces e.g. for participants and hub operations users (technical / business), are secured with OAuth2.0 and Role Based Access Control (RBAC) mechanisms in combination with enforceable maker-checker processes (aka 4eyes). +7. Mojaloop supports a scheme wide Fraud and Risk Management Service (FRMS) model (shared between Financial service providers (FSPs) and the Mojaloop Switch / Hub). + + +![Figure 2 - Mojaloop Scheme Transactional Cybersecurity Architecture](./assets/images/mojaloop_security_layers.jpg "Figure 2 - Mojaloop Scheme Transactional Cybersecurity Architecture") + +Figure 2 - Mojaloop Scheme Transactional Cybersecurity Architecture + + +## Risk Management + + +### Security Testing + + +#### Automated Vulnerability Scanning + +Mojaloop employs a number of technical mechanisms to conduct automated vulnerability assessment against all Mojaloop platform source code repositories. These mechanisms scan code dependencies and container images for known vulnerabilities (from various continuously updated industry standard vulnerability databases) periodically and before code changes or additions are accepted to main branches. This reduces the likelihood of a known vulnerability in a Mojaloop dependency making its way into an official release. + + +#### Penetration Testing + +Members of the Mojaloop community periodically conduct penetration testing against their deployments using common security testing frameworks and share the results with the Mojaloop Foundation under a coordinated vulnerability disclosure process, whereby any newly identified risk may be mitigated by technical workstreams and/or adopters before vulnerabilities can be abused by third parties. + + +#### Community Expertise and Support + +The Mojaloop community, following the principles and processes detailed in this document, provides a software platform that embodies numerous cybersecurity features and capabilities. However, in order to realise the best possible secure operations, adopters of the Mojaloop technology are required to deploy and operate the software in a secure manner. This is often a difficult and daunting task with many applicable standards and regulations to adhere to. The Mojaloop community includes organisations with in-depth knowledge and experience in such matters who can be engaged to offer assistance. + + +## Coordinated Vulnerability Disclosure + +The Mojaloop Foundation operates a Coordinated Vulnerability Disclosure process. This process is a vulnerability disclosure model in which a vulnerability or an issue is disclosed to the public only after the responsible parties have been allowed sufficient time to patch or remedy the vulnerability or issue. + +This method is recommended by many governments and respected international organisations as the preferred process for managing software vulnerabilities as it provides protections against third-party exploitation of discovered issues beyond those provided by alternative models. + + +## Organisational Controls + +In addition to the technical cybersecurity controls described elsewhere, Mojaloop provides a range of tools to support organisational controls, reflecting the reality that although hacking attacks and fraud perpetrated by external agents generate the most media coverage, the most successful attacks in terms of the total value of money defrauded are inside jobs by a financial service’s own staff. + +In addition to the tools provided as part of Mojaloop, there are a number of recommendations that can be made regarding the business processes adopted by a hub operator which relate to the operation of the service. + + +### Control Points + +Mojaloop allows the hub operator to define control points, where the actions of an employee are subject to limitations imposed by the hub itself. Underpinning this is Mojaloop’s identity and access management capability, which implements a Role-Based Access Control (RBAC) model. Every employee action at the hub is only allowed if the employee holds a specific privilege; the hub owner defines a set of roles, each of which is a collection of privileges. An employee account is created and given a role (such as financial officer, administrator, operator etc), which then controls the functions they can perform. + +RBAC is then supplemented with maker/checker controls. Sensitive functions (such as funds movements) can be defined (“made”) by an operator, but will only be carried out when authorised (“checked”) by, for example, a financial operator. + +All employee actions are logged/recorded, in an audit log that cannot be tampered with. This allows forensic auditors to view all activity, and if necessary to “follow the money” when an issue arises due to, for example, employee/senior management collusion. + + +### Business Controls + +The operation of a Mojaloop Hub is a financial service, and the security of the service should be treated in the same way as any other financial service, such as that of a bank or an international payments switch. Business controls are the first line of defence, and limit the attack surface before the Control Points are even accessible. + +Business controls should include the following: + + + +* Cybersecurity can be undermined by malicious staff. Hub operators should conduct appropriate background checks when recruiting staff, including checks on police or criminal records and credit reference checks to identify excessive debt (vulnerability to bribery by outside attackers). +* Strict attention to the physical security of the hub operator’s premises (where access to the Mojaloop Hub is carried out - remote access, ie working from home, should **never** be allowed), including: + * There is only one, strictly controlled entrance to the hub operator’s premises. + * Other entrances are secured, and fire exits have alarms. + * All rooms are secured with biometric locks, require touch in **and** touch out to control tailgating, and access is restricted based on job function. + * Staff in customer-facing roles or in the finance department must not be allowed to have their mobile phones with them on the premises; phones should be stored in metal lockers (Faraday cages) during working hours. + * Video surveillance and 24-hour recording of all areas (cameras must face away from screens that might show sensitive information). + * Carefully check and log visitors’ identities. + * Do not permit visitors to bring any electronic equipment into operational areas. + * In non-operational areas **only**, mobile phones and laptops may be allowed. However, the serial numbers of laptops should be logged, and providers should **check to ensure visitors leave with the same equipment they brought**. Switching laptops is the fastest method of stealing data. + * Ensure visitors are accompanied by a staff member who is responsible for their conduct. + * Continually remain aware of visitors’ activity: + * Do not let visitors wander unaccompanied. + * Do not let visitors insert USB drives or other devices into company laptops, printers, etc. + +Note that this is just a subset of the controls we would expect in order to secure a Hub operator’s operations. A prospective Hub operator should seek specialist advice before launching a service. diff --git a/docs/community/tools/pragmatic-rest.md b/docs/community/tools/pragmatic-rest.md new file mode 100644 index 000000000..bb7db5ef3 --- /dev/null +++ b/docs/community/tools/pragmatic-rest.md @@ -0,0 +1,129 @@ +# Pragmatic REST + +## Pragmatic REST For the Mojaloop Project + +With the emergence of API strategy as a scaling tool for Internet service businesses, the focus on interconnect technology has shifted. Building on the principles that enabled the Web to form and scale, REST \(Representational State Transfer\) has become a design preference for Internet service APIs. But while the REST principles, proposed in Roy Fielding's dissertation that defined them, have academic value as a basis for research, a pure REST design is not at present practical for most applications. We are advocating a kind of Pragmatic REST-a design pattern that adopts the beneficial components of RESTful design without requiring strict adherence to academic purity. + +### The Richardson Maturity Model + +Martin Fowler has referenced a structured model of RESTful adoption developed by Leonard Richardson and [explained](http://www.crummy.com/writing/speaking/2008-QCon/act3.html) at a QCon talk. Fowler refers to this as the Richardson Maturity Model of RESTful design. + + + +Martin Fowler, referencing [Rest in Practice](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829),2 summarizes the genesis of RESTful design: + +> use Restful web services to handle many of the integration problems that enterprises face. At its heart . . . is the notion that the web is an existence proof of a massively scalable distributed system that works really well, and we can take ideas from that to build integrated systems more easily. + +A pragmatic approach to RESTful design uses the best parts of Fielding's conceptual framework to allow developers and integrators to understand what they can do with the API as rapidly as possible and without writing extraneous code. + +At its most fundamental, a RESTful design is resource-centric and uses HTTP verbs. At its most advanced, a design that follows pure academic REST utilizes the HATEOAS principle by implementing Hypermedia Controls. We are advocating a Level 2 RESTful design for Mojaloop. + +### Why not Hypermedia Controls? + +Although HATEOAS is a fascinating principle-it advocates that a server should respond to each client action with a list of all possible actions that can lead the client to its next application state. And further, clients _must not_ rely on out of band information \(like a written API spec\) for what actions can be performed on which resources or on the format of URIs. + +It is this final proscription that fails the test of Pragmatic REST: While HATEOAS is an interesting theoretical approach to limit coupling, it does not easily apply to Mojaloop \(or any other contract API design\). When we take into account our audience for the interconnect APIs, we find a group of commercial entities that will be operating under a set of highly specific scheme rules. Interactions between the participants, and between participant and central service hub, will be highly specified to assign acceptable commercial risk that can be priced at very low cost to end-users. This requires _ex-ante_ predictability of the API which is anathema to the HATEOAS principle defined by Fielding. + +### Pragmatic RESTful Principles + +#### URIs Define Resources + +A well-designed URI pattern makes an API easy to consume, discover, and extend, just as a carefully designed API does in a traditional programming language. Pure REST disdains this principle in favor of HATEOAS. But pragmatic REST follows a normal pattern for URI definitions to improve human understanding, even if HATEOAS principles are employed for discovery. + +URI paths that refer to a collection of objects should consist of a plural noun, e.g. /customers, to refer to a set of customers. When a collection can have only one instance, the singular noun should be used to avoid confusion. E.g. GET /transfers/:id/fulfillment is correct, since there is only one fulfillment object per identified transfer. + +URI paths that refer to a single object should consist of a plural noun \(representing the collection\), followed by a predefined unique identifier. E.g., /customers/123456 to refer to the specific customer with number 123456. The identifier must be unique within the containing collection and persist for the life of the object within that collection. IDs must not be ordinal values-ordinal retrieval of objects from a collection is possible using query parameters on the collection URI. + +URI paths may have a prefix to identify the environment, version, or other context of the resource. Nothing should follow the identifying path but collections and object references. + +URI path and query segment identifiers should be chosen from the Roman character set, \[0-9A-Za-z\]. Use _camelCase_ to define the elements of the URI path. Do not use snake\_case. + +For the avoidance of doubt, "\_" \(underscore\) and "-" \(hyphen\) should not be used in URI path or query segment identifiers. + +This probably seems a bit parochial. The purpose is to find a well-defined URI format that is consistent with wide-spread practice, easy to define, predictable, and that maps to native environments and conventions. It isn't going to satisfy everyone. Here is reasoning behind this constraint: + +CapitalCase and camelCase are the defacto standard for NodeJS and JavaScript and are a common constraint in URI definition: URI path segments are often mapped to JS internal resources and so conforming to JS naming conventions makes sense. + +Field names in JSON and SQL should also follow this convention since they are often automatically mapped into variable name space and can be referenced in URIs as path or query segment identifiers. + +We should also avoid the use of "$" unless it is required by a library \(e.g. JQuery\). IBM JCL has passed away; let it rest in peace. There are better scope control tools to separate name spaces than introducing non-roman symbols. + +We should avoid "-" \(hyphen\) in path segment and query parameter names as it does not map into variable names, SQL, or JSON field name identifiers. + +Underscore characters must be escaped in markdown source by prefixing each with a "\" character. + +Snake\_case has been reported to be slightly easier to read than camelCase in variable names, but it actually does not improve readability of URIs, as it visually interferes with path and query segment delimiters making it difficult to visually parse them. And when URIs are underlined in presentation, the underscores become illegible. + +#### URI Parameters + +Use a standard and predictable set of optional parameters in a consistent way. + +A set of standard query parameters should be used for collections to enable caller control over how much of the collection they see. E.g. "count" to determine how many objects to return, "start" to determine where to start counting in the result set, and "q" as a generic free-form search query. We will define the standard set of parameters as we go and will apply them consistently. + +#### Verbs + +Singular objects should support GET for read, PUT for complete replacement \(or creation when the primary key is specified by the client and is persistent, e.g. a payment card PAN\), and DELETE for delete. + +Collections should support GET to read back the whole or part of a collection, and POST to add a new object to the collection. + +Singular objects may support POST as a way to change their state in specified ways. Posting a JSON document to a singular object URI may allow selected field values to be updated or trigger a state change or action without replacing the whole object. + +GET must be implemented in a _nullipotent_ manner-that is, GET never causes side effects and never modifies client-visible system state \(other than logging events or updating instrumentation, e.g.\). + +PUT and DELETE must be implemented in an _idempotent_ manner-that is, changes are applied consistently to the system data in a way that is dependent only on the state of the resource and inputs but on nothing else. The action has no additional effect if it is executed more than once with the same input parameters and does not depend on the order of other operations on a containing collection or other resources held in the collection. For example, removing a resource from a collection can be considered an idempotent operation on the collection. Using PUT to fully replace \(or create\) a uniquely identified resource when the URI is fully known to the client is also idempotent. This implies that the system may reorder operations to improve efficiency, and the client does not need to know whether a resource exists before attempting to replace it. + +POST and PATCH3 are not idempotent operations. POST is used to create new resources where the resource identifier is assigned by the server or where a single identified internal resource is implied by the target URI \(e.g. POST /transfers, but PUT /transfers/:id/fulfillment\). + +#### Data Format + +We favor [JSON](http://json.org/)4 related data formats over XML. In some cases, data formats will be binary or XML, as defined by pre-existing standards, and these will be precisely specified. Binary formats should have a formal syntax to avoid ambiguous representational translations \(e.g. character set translations, big- or little-endian representations of numeric values, etc\). + +Date and time values used in APIs should comply to the ISO 8601 standard, and further profiled by the w3c Note on Date and Time Formats.5 This w3c note should lead to the reduction in complexity and error scope of communicating components that must exchange tangible dates and times. There will be cases where we use non-ISO format date or time as required by an external standard, e.g. ISO 7813 expiry dates. + +Existing standard XML formats should have an XSD schema for the acceptable subset profile used within the project. For particularly complex data formats, we may use a common format profile translator to map between our project subset of the standard format and the wire format used by a standardized protocol \(e.g.\). This will limit coupling to complex formats in a more maintainable way. + +When specifying the PATCH action for a resource, we will use a consistent patch document format \(e.g. [JSON Patch](http://jsonpatch.com/)6\). + +#### Return Codes + +Use HTTP return codes in a consistent way and according to their standard definitions. The standard codes are defined in RFC 2616.7 + +#### Machine Readable Error Format + +The API should provide a machine readable error result in a well-defined JSON format. {TBD whether to use a response envelope and how to format errors, faults, and success envelopes. RESTful design relies on headers to carry protocol-defined errors, debug info can also be carried in headers. We should be clear on why we are using an envelope and how this supports normal production communication between client and server. + +#### Versioning + +API URIs should include a version identifier in the format v_M_ as a leading path element \(where _"M"_ is the Major component of the multi-part version number\). The API and its version identifier element must conform to the [semantic versioning](http://semver.org/)8 2.0 specification for API versioning. + +A client must specify the Major version number in each request. It is not possible for a client to express a requirement for a specific minor version. + +The full API version number is specified in the response header \(TBD\) for all successful and error responses. + +While an API version contract will be influenced by Major, minor, _and_ patch levels, only the Major version number is a production API binding element-that is, a production client cannot request a particular minor version or patch level and a production server will not accept a URI request that specifies these extra elements. + +However, in pre-production environments, it is anticipated that some combination of minor, patch, pre-release, and metadata suffixes would be supported in client requests \(as defined in _semver_ \[3\]\) and _may_ be expressed in _pre-production_ URIs to assist with development and integration scenarios. + +### We May Need to Give REST a Rest + +As we design the interconnection APIs between components and between participating systems, we may find API requirements that don't precisely match the Pragmatic REST pattern defined here. We will evaluate these case-by-case and make the best choice to support the project goals. + +### Non-Functional Requirements + +As we develop the APIs, we will make consistent choices about non-functional requirements to reinforce the project goals. + +1: [http://martinfowler.com/articles/richardsonMaturityModel.html](Richardson%20Maturity%20Model), retrieved August 18, 2016. + +2: [https://www.amazon.com/gp/product/0596805829](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829), retrieved August 18, 2016. + +3: RFC 5789, _PATCH Method for HTTP_, [https://tools.ietf.org/html/rfc5789](https://tools.ietf.org/html/rfc5789), retrieved August 18, 2016. + +4: _Introducing JSON_, [http://json.org/](http://json.org/), retrieved August 18, 2016. + +5: [http://www.w3.org/TR/1998/NOTE-datetime-19980827](http://www.w3.org/TR/1998/NOTE-datetime-19980827), retrieved August 22, 2016. + +6: _JSON Patch_, [http://jsonpatch.com/](http://jsonpatch.com/), retrieved August 18, 2016. + +7: [https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) + +8: _Semantic Versioning 2.0.0_, [http://semver.org/](http://semver.org/), retrieved August 18, 2016. \ No newline at end of file diff --git a/docs/community/tools/test.md b/docs/community/tools/test.md new file mode 100644 index 000000000..0527e6bd2 --- /dev/null +++ b/docs/community/tools/test.md @@ -0,0 +1 @@ +This is a test diff --git a/docs/community/tools/tools-and-technologies.md b/docs/community/tools/tools-and-technologies.md new file mode 100644 index 000000000..b9b3acfa2 --- /dev/null +++ b/docs/community/tools/tools-and-technologies.md @@ -0,0 +1,51 @@ +# Tools and Technologies + +Here we document the reasoning behind certain tools, technology and process choices for Mojaloop. We also have included the recommendation links/versions for each of these tools. + +**TOOL CHOICES** + +* **API Development** + * **Open API 3.0 ** is leveraged for API development (Swagger 2.0 earlier). + * ** ISTIO** as the API Gateway (WSO2 now outdated with Mojaloop v16.0.0 - Congo and IaC v5.0.0 onwards) offers an enterprise platform for integrating APIs, applications, and web services—locally and across the Internet. It also provides Mojaloop with a Security Layer, and Development Portal. +* **Circle-CI** - This tool is used for continuous build and continuous deployment. We needed an online continuous build and testing system that can work with many small projects and a distributed team. Jenkins was considered, but it requires hosting a server and a lot of configuration. CircleCI allowed for a no host solution that could be started with no cost and very limited configuration. We thought we might start with CircleCI and move off later if we outgrew it, but that hasn’t been needed. +* **Dactyl** – We need to be able to print the online documentation. While it’s possible to print markdown files directly one at a time, we’d like to put the files into set of final PDF documents, where one page might end up in more than one final manual. [Dactyl](https://github.com/ripple/dactyl) is a maintained open source conversion tool that converts between markdown and PDF. We originally tried Pandoc, but it had bugs with converting tables. Dactyl fixes that and is much more flexible. +* **DBeaver** - [DBeaver](https://dbeaver.io/) is a free multi-platform database tool for developers, SQL programmers, database administrators and analysts. Supports all popular databases: MySQL, PostgreSQL, MariaDB, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Derby, etc. +* **Docker** - The Docker container engine creates and runs the Docker container from the Docker image file. +* **Docker hub** is used to link, build, test and push the Mojaloop code repositories. We needed to support both local and cloud execution. We have many small microservices that have very simple specific configurations and requirements. The easiest way to guarantee that the service works the same way in every environment from local development, to cloud, to hosted production is to put each microservice in a Docker container along with all the prerequisites it needs to run. The container becomes a secure, closed, pre-configured, runnable unit. +* **Draw.io** – We need to create pictures for our documents and architecture diagrams using an \(ideally free\) open source friendly tool, that is platform agnostic, supports vector and raster formats, allows WYSIWYG drawing, works with markdown, and is easy to use. We looked at many tools including: Visio, Mermaid, PlantUML, Sketchboard.io, LucidChart, Cacoo, Archi, and Google Drawings. Draw.io scored at the top for our needs. It’s free, maintained, easy to use, produces our formats, integrates with DropBox and GitHub, and platform agnostic. In order to save our diagrams, we have to save two copies – one in SVG \(scalable vector\) format and the other in PNG \(raster\). We use the PNG format within the docs since it can be viewed directly in GitHub. The SVG is used as the master copy as it is editable. +* **ESLint** - Within JavaScript code, we use [ESLint](https://eslint.org/) as a code style guide and style enforcement tool. +* **GitHub** – [GitHub](https://github.com/Mojaloop) is a widely-used source code repository service, based on git, the standard source code version control system for open source projects. So the decision to use GitHub was straightforward. We create a story every time for integration work. Create bugs for any issues. Ensure all stories are tracked throughout the pipeline to ensure reliable metrics. +* **Helm** - The Helm package manager for Kubernetes provides templatized deployments and configurations and allow for overall complexity management. +* **IaC** - Infrastructure as Code (IaC) is the tooling, scripts used to deploy a Mojaloop platform at the desired quality level, ranging from development, qa or sandboxes to pre-production or even extended for production quality deployments. This uses the Mojaloop releases as the core and deploys the entire supporting toolset needed to run the Mojaloop Platform for a Mojaloop Switch. +* **Kafka** - This technology is leveraged to support Mojaloop’s demand for a high velocity and high volume data messaging but keep our hardware requirements minimum. +* **JavaScript** - The Mojaloop application is primarily written in JavaScript. +* **Kubectl** - This is a command line interface for running commands against Kubernetes clusters. +* **Kubernetes** - This enterprise tool provides an extraction layer, infrastructure management and a container-orchestration system. +* **Markdown** – Documentation is a deliverable for this project, just like the code, and so we want to treat it like the code in terms of versioning, review, check in, and tracking changes. We also want the documentation to be easily viewable online without constantly opening a viewer. GitHub has a built-in format called Markdown which solves this well. The same files work for the Wiki and the documents. They can be reviewed with the check in using the same tools and viewed directly in GitHub. We considered Google Docs, Word and PDF, but these binary formats aren’t easily diff-able. A disadvantage is that markdown only allows simple formatting – no complex tables or font changes - but this should be fine when our main purpose is clarity. +* **Mojaloop Testing Toolkit (TTK)** – [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit)) is a Swiss-knife tool for Mojaloop related activities, primarily used for end-to-end testing, demonstrations, mocking APIs and in several other extended scenarios. The Mojaloop test collections use the ML TTK and it is the tool of preference for end-to-end testing, which is also integrated into the scripts for automated testing (using TTK CLI in IaC and other dev/qa environments). +* **MySQLWorkbench** – [MySQL Workbench](https://www.mysql.com/products/workbench/) is a unified visual tool for database architects, developers, and DBAs. MySQL Workbench provides data modeling, SQL development, and comprehensive administration tools for server configuration, user administration, backup, and much more. MySQL Workbench is available on Windows, Linux and Mac OS X. +* **NodeJS** - This development tool is a JavaScript runtime built on Chrome's V8 JavaScript engine that runs Mojaloop. NodeJS is designed to create simple microservices and it has a huge set of open source libraries available. Node performance is fine and while Node components don’t scale vertically a great deal, but we plan to scale horizontally, which it does fine. The original Interledger code was written in NodeJS as was the level one prototype. Most teams used Node already, so this made sense as a language. Within NodeJS code, we use [Standard](https://www.npmjs.com/package/standard) as a code style guide and to enforce code style. +* **NPM** - NPM is the package manager for Mojaloop since JavaScript is the default programming language. +* **Percona** for **MySQL** - These tools are leveraged as a relational database management system to ensure high performance and enterprise-grade functionality for the Mojaloop system. We needed a SQL backend that is open source friendly and can scale in a production environment. Thus, we chose MySQL, an open-source relational database management system. +* **Postman** is a Google Chrome application for interacting with HTTP APIs. It presents you with a friendly GUI for constructing requests and reading responses. +* **Rancher 2.0** - The Infrastructure management, provisioning and monitoring is provided by Rancher 2.0 which is an enterprise Kubernetes platform that manage Kubernetes deployments, clusters, on cloud & on-prem. Rancher makes it easy for DevOps teams to test, deploy and manage the Mojaloop system no matter where it is running. +* **Slack** – Slack is used for internal team communication. This was largely picked because several team already used it and liked it as a lightweight approach compared to email. +* **SonarCloud** – We need an online dashboard of code quality \(size, complexity, issues, and coverage\) that can aggregate the code from all the repos. SonarCloud for Mojaloop is free, with some setup. This also offers quality checks on Pull Requests and offers ratings based on the quality gates applied. +* **SourceTree** – [Sourcetree](https://www.sourcetreeapp.com/) simplifies how you interact with your Git repositories so you can focus on coding. Visualize and manage your repositories through Sourcetree's simple Git GUI. But this is up to the developer to use their tool of choice following general GitHub recommendations. +* **Visual Studio Code** - [Visual Studio Code](https://code.visualstudio.com/) is a code editor redefined and optimized for building and debugging modern web and cloud applications. Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows. +* **ZenHub** – We needed a project management solution that was very light weight and cloud based to support distributed teams. It had to support epics, stories, and bugs and a basic project board. VS and Jira online offerings were both considered. For a small distributed development team an online service was better. For an open source project, we didn’t want ongoing maintenance costs of a server. Direct and strong GitHub integration was important. It was very useful to track work for each microservice with that microservice. Jira and VS both have more overhead than necessary for a project this size and don’t integrate as cleanly with GitHub as we’d want. ZenHub allowed us to start work immediately. A disadvantage is the lack of support for cumulative flow diagrams and support for tracking \# of stories instead of points, so we do these manually with a spreadsheet updated daily and the results published to the "Project Management" Slack channel. + +**TECHNOLOGY CHOICES** + +* **Agile development** - This methodology is used to track and run the project. The requirements need to be refined as the project is developed, therefore we picked agile development over waterfall or lean. +* **APIs** - In order to avoid confusion from too many changing microservices, we use strongly defined APIs that conform to our [Pragmatic REST](pragmatic-rest.md) design pattern. APIs will be defined using OpenAPI. Teams document their APIs with Swagger v2.0 or RAML v0.8 so they can automatically test, document, and share their work. Swagger is slightly preferred as there are free tools. Mule will make use of RAML 0.8. Swagger can be automatically converted to RAML v0.8, or manually to RAML v1.0 if additional readability is desired. +* **Automated Testing** - For the most part, most testing will be automated to allow for easy regression testing. See the [automated testing strategy](automated-testing.md) and [code quality metrics](code-quality-metrics.md) for standards. +* **Hosting** - Mojaloop has been designed to be infrastructure agnostic and as such is supported by AWS, Azure and On-Premise installations. +* **Interledger** – Mojaloop needed a lightweight, open, and secure transport protocol for funds. [Interledger.org](http://Interledger.org) provides all that. It also provides the ability to connect to other systems. We also considered block chain systems, but block chain systems send very large messages which will be harder to guarantee delivery of in third world infrastructure. Also, while blockchain systems provide good anonymity, that is not a project goal. To enable fraud detection, regulatory authorities need to be able to request records of transfers by account and person. +* **Open source** - The entire project has been released as open source in accordance with the [Level One Project principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf). All tools and processes must be open source friendly and support projects that use an Apache 2.0 license with no restrictive licenses requirements on developers. +* **Operating System** – Microsoft Windows is widely used in many target countries, but we need an operating system that is free of license fees and is open source compatible. We are using Linux. We don’t have a dependency on the particular flavor, but are using the basic Amazon Linux. In the Docker containers, [Alpine Linux](https://alpinelinux.org/) is used. +* **Microservices** - Because the architecture needs to easily deploy, scale, and have components be easily replaced or upgraded, it will be built as a set of microservices. +* **Scaled Agile Framework** - There were four initial development teams that are geographically separate. To keep the initial phase of the project on track, the [scaled agile framework \(SAFe\)](https://www.scaledagileframework.com/) was picked. This means work is divided into program increments \(PI\) that are typically four 2 week sprints long. As with the sprints, the PI has demo-able objective goals defined in each PI meeting. +* **Services** - Microservices are grouped and deployed in a few services such as the DFSP, Central Directory, etc. Each of these will have simple defined interfaces, configuration scripts, tests, and documentation. +* **Threat Modeling, Resilience Modeling, and Health Modeling** - Since the Mojaloop code needs to exchange money in an environment with very flaky infrastructure it must have good security, resilience, and easily report it's health state and automatically attempt to return to it. +* **USSD** - Smart phones are only 25% of the target market and not currently supported by most money transfer service, so we need a protocol that will work on simple feature phones. Like M-Pesa, we are using USSD between the phone and the digital financial service provider \(DFSP\). diff --git a/docs/fr/adoption/HubOperations/Onboarding/business-onboarding.md b/docs/fr/adoption/HubOperations/Onboarding/business-onboarding.md new file mode 100644 index 000000000..d5aaafb8b --- /dev/null +++ b/docs/fr/adoption/HubOperations/Onboarding/business-onboarding.md @@ -0,0 +1,20 @@ +# Intégration métier des DFSP + +Le parcours d'onboarding des DFSP comprend des étapes qui se déroulent en dehors du Hub Mojaloop. Elles sont liées au volet métier de l'onboarding, et il est utile pour l'opérateur du Hub d'en être informé. + +::: tip NOTE +Les étapes du processus de candidature du DFSP et du parcours d'onboarding métier sont définies par le schéma, en conformité avec les exigences réglementaires financières locales. +::: + +Les étapes clés du parcours d'onboarding métier sont : + +1. Le DFSP découvre le service offert par le schéma et indique son intention et sa raison commerciale de rejoindre le schéma. +1. Le DFSP signe un accord de candidature. +1. La documentation est partagée avec le DFSP, ce qui permet au DFSP d'évaluer l'effort technique d'onboarding, ainsi que sa compatibilité commerciale avec les règles de schéma. +1. L'opérateur du schéma effectue une vérification préalable de l'éligibilité du candidat. +1. Le DFSP comprend et signe un accord de participation (contrat). +1. Le DFSP effectue une procédure KYC auprès de la banque de règlement. Cela fait partie du processus d'ouverture d'un compte bancaire de règlement (également appelé compte de liquidité). +1. Le DFSP développe de nouvelles fonctionnalités d'interface utilisateur / met à jour les fonctionnalités d'interface utilisateur existantes pour exposer le ou les cas d'utilisation pris en charge par le schéma aux utilisateurs finaux. +1. Le DFSP ouvre et pré-alimente son compte de liquidité à la banque de règlement. + +En parallèle des étapes métier, après la signature de l'accord de participation, le DFSP peut commencer son [parcours d'onboarding technique](technical-onboarding.md). diff --git a/docs/fr/adoption/HubOperations/Onboarding/onboarding-introduction.md b/docs/fr/adoption/HubOperations/Onboarding/onboarding-introduction.md new file mode 100644 index 000000000..a64145a9d --- /dev/null +++ b/docs/fr/adoption/HubOperations/Onboarding/onboarding-introduction.md @@ -0,0 +1,5 @@ +# Introduction – Guide d'onboarding pour l'opérateur du Hub + +Ce guide est destiné à l'opérateur d'un Hub Mojaloop et fournit des informations sur le processus d'onboarding des DFSP. Il offre une vue d'ensemble de haut niveau du parcours d'onboarding que suivent les DFSP, servant de liste de contrôle des activités d'onboarding. L'objectif est d'aider les employés du Hub à comprendre les étapes à accomplir lors de la connexion des DFSP aux différents environnements du Hub. + + diff --git a/docs/fr/adoption/HubOperations/Onboarding/technical-onboarding.md b/docs/fr/adoption/HubOperations/Onboarding/technical-onboarding.md new file mode 100644 index 000000000..2b34a271c --- /dev/null +++ b/docs/fr/adoption/HubOperations/Onboarding/technical-onboarding.md @@ -0,0 +1,247 @@ +# Intégration technique des DFSP + +À un niveau élevé, l'onboarding à un Hub Mojaloop nécessite qu'un DFSP concentre ses efforts sur les jalons majeurs suivants : + +* [Intégration](#integration-api) de son backend principal avec le Hub Mojaloop au niveau de l'API (cela implique à la fois le codage et les tests). +* [Connexion](#connexion-aux-environnements-mojaloop) aux environnements de pré-production et de production en suivant les exigences rigoureuses de sécurité de Mojaloop. + +En plus des étapes nécessitant l'implication du DFSP, l'opérateur du Hub doit également effectuer certaines activités d'onboarding dans son [backend](#integration-dans-le-backend-du-hub) indépendamment des DFSP. + +Cette section fournit une vue d'ensemble de haut niveau de tous ces jalons. + +## Intégration API + +Dans le contexte de l'API Mojaloop Financial Service Provider Interoperability (FSPIOP), un transfert se déroule en trois étapes principales : + +1. Identification du bénéficiaire (phase de recherche de partie ou de découverte) +1. Accord sur le transfert (phase de devis ou d'accord) +1. Exécution du transfert (phase de transfert) + +Pour plus de détails sur chacune de ces phases, voir le **Module 2 - Démonstration statique : Un exemple de bout en bout** du [cours de formation Mojaloop](https://learn.mojaloop.io/) **MOJA-102**. + +Ces trois phases correspondent aux ressources clés de l'API Mojaloop FSPIOP : + +* **Service de recherche de partie** : Identification du DFSP desservant le bénéficiaire et du bénéficiaire lui-même (= le destinataire des fonds dans une transaction) sur la base d'un identifiant du bénéficiaire (généralement un MSISDN, c'est-à-dire un numéro de mobile). +* **Service de devis** : Demande d'un devis et échange de preuves cryptographiques pour préparer et sécuriser le transfert. Un devis est un contrat entre un DFSP payeur et un DFSP bénéficiaire pour une transaction financière particulière avant que la transaction ne soit effectuée. Il garantit l'accord établi par les DFSP payeur et bénéficiaire concernant le payeur, le bénéficiaire et le montant du transfert, et est valide pendant la durée de vie d'un devis et d'un transfert d'une transaction financière spécifiée. +* **Service de transferts** : Exécution de la transaction selon les détails convenus et la preuve cryptographique. + +Les DFSP peuvent choisir de : + +* se connecter directement au Hub Mojaloop et implémenter la version asynchrone Mojaloop de ces services API, ou +* tirer parti d'un composant d'intégration open source (le [Mojaloop-SDK](#mojaloop-sdk) ou [Payment Manager OSS](#payment-manager-oss)) et implémenter une version simplifiée et synchrone des services de l'API Mojaloop FSPIOP + +Les DFSP disposant d'une équipe de développement interne et d'une expérience avec les API RESTful seront probablement en mesure de gérer le processus en interne et de développer une connexion directe à Mojaloop. Cependant, il est recommandé que les DFSP utilisent l'un des composants d'intégration open source, car une connexion directe nécessite un développement et une maintenance de code supplémentaires. L'utilisation du Mojaloop-SDK ou de Payment Manager OSS réduit le temps nécessaire à l'intégration avec le Hub Mojaloop et facilite le dépannage pour l'opérateur du Hub, réduisant ainsi le coût global du système. + +Pendant que le DFSP effectue des travaux de développement hors ligne, le rôle de l'opérateur du Hub consiste à répondre aux questions ponctuelles sur les spécificités de l'API, ou - selon l'outil open source choisi et le modèle de déploiement convenu - peut même s'étendre à une partie du développement. + +### Outils open source pour faciliter l'intégration API + +#### Mojaloop-SDK + +Le [Mojaloop-SDK](https://github.com/mojaloop/sdk-scheme-adapter) présente une version simplifiée et synchrone de l'API Mojaloop FSPIOP au système backend d'un DFSP, permettant aux DFSP d'implémenter une API simple en interne pour s'interfacer avec le Hub Mojaloop, tout en restant conforme à la spécification de l'API Mojaloop FSPIOP pour les communications externes interopérables. + +Le modèle asynchrone de l'API Mojaloop FSPIOP (bien qu'il présente de nombreux avantages) peut ne pas convenir aux applications clientes qui fonctionnent en mode requête-réponse synchrone. Le Mojaloop-SDK aide à combler cet écart en offrant une API simplifiée de type requête-réponse, faisant abstraction des complexités de la composition de requêtes multiples et des détails de l'API asynchrone pour les clients finaux. + +![Mojaloop-SDK](../../../../.vuepress/public/mojaloop-sdk.png) + +Le Mojaloop-SDK doit être téléchargé depuis [GitHub](https://github.com/mojaloop/sdk-scheme-adapter) vers l'environnement du DFSP et intégré au backend du DFSP. Il est fourni sous forme d'image de conteneur Docker, et peut être hébergé sur la même infrastructure que l'application bancaire principale ou sur une machine virtuelle provisionnée spécifiquement pour cela. La maintenance continue peut nécessiter un support spécialisé d'un intégrateur de systèmes formé au logiciel. + +En plus d'une API simplifiée, le Mojaloop-SDK fournit également les protocoles de sécurité requis par Mojaloop « prêts à l'emploi », en offrant une interface de configuration simplifiée à ses utilisateurs. Cette fonctionnalité du Mojaloop-SDK aide à l'[étape de connexion](#connexion-aux-environnements-mojaloop) de l'intégration. + +#### Payment Manager OSS + +[Payment Manager OSS](https://pm4ml.github.io/documents/payment_manager_oss/latest/core_connector_rest/introduction.html) présente une version orientée cas d'utilisation, simplifiée et synchrone de l'API Mojaloop FSPIOP au système backend d'un DFSP. Le composant clé d'intégration de Payment Manager s'appelle Core Connector, il agit comme un traducteur entre le backend principal d'un DFSP (CBS) et un composant de Payment Manager (appelé Mojaloop Connector, qui exploite le Mojaloop-SDK) qui communique directement avec le Hub Mojaloop. + +![Payment Manager OSS](../../../../.vuepress/public/PM4ML_system_architecture.png) + +Core Connector est construit en Apache Camel, un langage déclaratif basé sur Java pour les ingénieurs d'intégration qui ne nécessite pas d'écrire du code à partir de zéro. Un modèle de Core Connector prêt à l'emploi est disponible pour simplifier l'effort de développement. Le modèle fournit une base de code de remplacement pour les points d'accès API qui doivent être développés, et il doit être personnalisé pour être aligné avec la technologie CBS appropriée. La flexibilité offerte par le modèle permet d'adapter Core Connector au backend d'un DFSP, plutôt que l'inverse. + +L'effort de personnalisation d'un modèle Core Connector variera selon l'option de déploiement choisie. Lors du déploiement de Payment Manager, deux options sont disponibles : + +* **Géré et hébergé par un intégrateur de systèmes** : Un intégrateur de systèmes déploie Payment Manager dans le cloud, et synchronise le modèle Core Connector avec l'implémentation du backend principal du DFSP. +* **Auto-hébergé par le DFSP** : Le DFSP déploie Payment Manager sur site ou dans le cloud, et la personnalisation du modèle Core Connector peut être effectuée par un certain nombre d'acteurs (selon le résultat d'une évaluation initiale des capacités du DFSP) : + * l'intégrateur de systèmes + * l'intégrateur de systèmes et le fournisseur de la solution backend principale du DFSP + * le DFSP et le fournisseur de la solution backend principale du DFSP + +Payment Manager est fourni sous forme d'un ensemble d'images de conteneurs Linux (Docker) et peut être hébergé sur site à l'aide d'une infrastructure serveur standard ou dans une infrastructure cloud appropriée lorsqu'elle est disponible. + +Si l'opérateur du Hub le souhaite, il peut assumer le rôle d'intégrateur de systèmes. + +Étant donné que Payment Manager intègre les fonctionnalités du Mojaloop-SDK, il implémente également la couche de sécurité requise par Mojaloop. Cette fonctionnalité de Payment Manager aide à l'[étape de connexion](#connexion-aux-environnements-mojaloop) de l'intégration. + +## Connexion aux environnements Mojaloop + +Une fois que le DFSP a terminé le codage, il teste son intégration contre une instance de laboratoire dans un environnement de test fourni par le Hub. C'est là que la phase de connexion du parcours d'onboarding technique commence, avec un nouvel ensemble de responsabilités pour l'opérateur du Hub. + +Les exigences relatives à la connexion sont dictées par les multiples protocoles de sécurité que tout Hub Mojaloop et les DFSP participants doivent implémenter : + +* TLS bidirectionnel avec authentification mutuelle X.509 +* Authentification OAuth 2.0 pour les sessions via la passerelle API du Hub +* Liste blanche basée sur les adresses IP dans les règles de pare-feu et les passerelles API +* Signature des messages par JSON Web Signature (JWS) +* Signature et validation des paquets Interledger Protocol (ILP) + +Si vous souhaitez plus de détails, consultez [Sécurité dans Mojaloop](#securite-dans-mojaloop). + +La mise en pratique des mesures de sécurité ci-dessus nécessite un partage d'informations étendu et une configuration technique de la part de différentes équipes tant du côté du DFSP que du Hub Mojaloop. Des outils open source sont disponibles pour la communauté afin de faciliter ce processus, tant pour les DFSP que pour l'opérateur du Hub. + +### Outils open source pour faciliter la connexion aux environnements Mojaloop + +#### Mojaloop-SDK + +Le Mojaloop-SDK implémente des composants standard qui établissent une manière uniforme de connecter les systèmes DFSP à un Hub Mojaloop. Il implémente les fonctionnalités de sécurité conformes à Mojaloop suivantes : + +* TLS bidirectionnel avec authentification mutuelle X.509 +* Signature des messages par JSON Web Signature (JWS) +* Génération du paquet Interledger Protocol (ILP) avec signature et validation + +Le Mojaloop-SDK peut être téléchargé depuis [GitHub](https://github.com/mojaloop/sdk-standard-components) et hébergé sur la même infrastructure que l'application bancaire principale du DFSP ou sur une machine virtuelle provisionnée spécifiquement pour cela. Après la génération, la signature et l'échange des certificats TLS et JWS, les DFSP sont tenus de configurer les variables d'environnement liées à TLS et JWS dans le Mojaloop-SDK. Enfin, l'installation des certificats dans les pare-feu et la passerelle API du DFSP complète la partie configuration des certificats du processus. + +L'obtention des identifiants de la passerelle API du Hub requis pour collecter les jetons OAuth 2.0 et leur configuration dans le Mojaloop-SDK via des variables d'environnement doit être effectuée manuellement. + +L'échange des détails des points d'accès avec le Hub et leur configuration dans le Mojaloop-SDK via des variables d'environnement, ainsi que dans les listes blanches des pare-feu/passerelles sont également des étapes manuelles. + +#### Payment Manager OSS + +Payment Manager OSS fournit toutes les fonctionnalités de sécurité que le Mojaloop-SDK offre, et plus encore. Payment Manager est livré avec un client Mojaloop Connection Manager (MCM), qui simplifie et automatise la création, la signature et l'échange de certificats, ainsi que la configuration des connexions requises aux différents environnements. Le degré d'automatisation de ces processus variera selon l'option de déploiement choisie. Deux options sont disponibles : + +* **Géré et hébergé par un intégrateur de systèmes** : Un intégrateur de systèmes déploie Payment Manager dans le cloud. +* **Auto-hébergé par le DFSP** : Le DFSP déploie Payment Manager sur site ou dans le cloud. + +Lorsqu'un DFSP opte pour l'**option gérée et hébergée**, l'intégrateur de systèmes (ce rôle peut être rempli par l'opérateur du Hub) peut employer l'Infrastructure-as-Code et des scripts d'intégration pour gérer les éléments suivants du processus de manière automatisée : + +* génération, signature, configuration et installation des certificats TLS +* mise en liste blanche des adresses IP dans les pare-feu et les passerelles API +* génération et configuration du secret/clé client requis pour obtenir des jetons OAuth 2.0 + +Les étapes liées aux certificats JWS sont effectuées via le [portail Connection Wizard](https://pm4ml.github.io/documents/payment_manager_oss/latest/connection_wizard/index.html), un portail facile à utiliser que Payment Manager fournit pour gérer les processus liés aux certificats et aux points d'accès de manière guidée. Les DFSP et l'opérateur du Hub sont tenus de générer des certificats JWS en utilisant l'outil de leur choix, puis de partager leurs clés publiques via le portail Connection Wizard. La configuration des certificats JWS dans Payment Manager se fait via le portail Connection Wizard, tandis que leur installation dans les passerelles est une étape manuelle. + +Lorsqu'un DFSP opte pour l'**option auto-hébergée**, il utilise le [portail Connection Wizard](https://pm4ml.github.io/documents/payment_manager_oss/latest/connection_wizard/index.html) pour gérer les étapes liées aux certificats et aux points d'accès de manière semi-automatisée : + +* Les DFSP saisissent les détails de leurs points d'accès et obtiennent les points d'accès du Hub depuis le portail. Ils configurent ensuite ces informations dans Payment Manager via des variables d'environnement ainsi que dans les listes blanches des pare-feu/passerelles manuellement. +* Les DFSP génèrent, signent et configurent les certificats TLS en un clic via le portail Connection Wizard. +* Les DFSP génèrent des certificats JWS en utilisant un outil de leur choix et les partagent et les configurent dans Payment Manager en un clic dans le portail Connection Wizard. + +L'obtention des identifiants de la passerelle API du Hub requis pour collecter les jetons OAuth 2.0 et leur configuration dans Payment Manager via des variables d'environnement doit être effectuée manuellement. + +#### MCM + +Le produit Mojaloop Connection Manager (MCM) est essentiel pour simplifier et automatiser une grande partie du partage d'informations et de la configuration autour des points d'accès et des certificats. MCM a un composant Client MCM et un composant Serveur MCM, qui communiquent entre eux lors de l'échange des détails des points d'accès et des certificats, et lors de la signature des demandes de signature de certificat. + +Le client MCM est intégré dans Payment Manager, tandis que le serveur MCM se trouve dans les limites du Hub. MCM fournit un portail pour que l'opérateur du Hub soumette les informations des points d'accès du Hub et les certificats du Hub, et récupère les détails des points d'accès et des certificats du DFSP soumis par le DFSP via Payment Manager. + +### Sécurité dans Mojaloop + +Pour comprendre ce qu'implique en détail la connexion d'un DFSP à un environnement Mojaloop, il est important d'examiner de plus près les exigences de sécurité de Mojaloop. + +Mojaloop exige que les mesures de sécurité suivantes soient implémentées afin de protéger les données échangées entre les DFSP : + +* **La sécurité de la couche de transport (TLS)** est un mécanisme sécurisé pour échanger une clé symétrique partagée sur un réseau entre deux pairs anonymes, avec vérification d'identité (c'est-à-dire des certificats de confiance). Elle assure la confidentialité (personne n'a lu le contenu) et l'intégrité (personne n'a modifié le contenu). Mojaloop exige une authentification mutuelle TLS bidirectionnelle utilisant des certificats X.509 pour sécuriser les connexions bidirectionnelles. Les DFSP et le Hub Mojaloop s'authentifient mutuellement pour s'assurer que les deux parties impliquées dans la communication sont de confiance. Les deux parties partagent leurs certificats publics et la vérification/validation est ensuite effectuée sur cette base. +* Une autre mesure de sécurité offerte pour l'authentification est constituée par les **jetons OAuth** que les DFSP sont tenus d'utiliser lors d'une requête d'appel API. OAuth 2 est utilisé pour fournir un accès basé sur les rôles aux points d'accès du Hub Mojaloop (autorisation API). +* **La mise en liste blanche des adresses IP** réduit la surface d'attaque du Hub Mojaloop. +* Pour protéger le niveau applicatif, Mojaloop implémente la **signature JSON Web Signature (JWS)** telle que définie dans la [RFC 7515 (JSON Web Signature (JWS))](https://tools.ietf.org/html/rfc7515), la norme pour l'intégrité et la non-répudiation. La signature des messages garantit que le DFSP payeur et le DFSP bénéficiaire peuvent avoir confiance que les messages partagés entre eux n'ont pas été modifiés par un tiers. +* L'API Mojaloop FSPIOP implémente la prise en charge du **protocole Interledger (ILP)**. ILP est construit sur le concept de transferts conditionnels, dans lesquels les registres impliqués dans une transaction financière du payeur au bénéficiaire peuvent d'abord réserver des fonds sur un compte payeur, puis les valider sur le compte bénéficiaire. Le transfert du compte payeur au compte bénéficiaire est conditionné à la présentation d'un accomplissement qui satisfait la condition attachée à la demande de transfert originale. + +![Vue d'ensemble de la sécurité](../../../../.vuepress/public/security_overview.png) + +Les sections suivantes fournissent des informations de fond sur les étapes impliquées dans la connexion à un environnement Mojaloop. Les informations fournies sont rédigées de manière à ce que les DFSP et le Hub puissent s'appuyer sur les meilleures pratiques PKI et sur les outils et technologies propriétaires qu'ils préfèrent ou auxquels ils ont accès. + +::: tip +Comme mentionné ci-dessus, en utilisant Payment Manager OSS, Mojaloop Connection Manager (MCM) et l'Infrastructure-as-Code (IaC) qui déploie les composants constituant l'écosystème Mojaloop, bon nombre des étapes des processus décrits ci-dessous peuvent être effectuées de manière automatisée. +::: + +#### Création et partage de certificats + +##### Certificats TLS + +L'authentification TLS bidirectionnelle ou mutuelle (mTLS) repose sur le fait que les deux parties (client et serveur) partagent leurs certificats publics et effectuent la vérification/validation sur cette base. + +Les étapes de haut niveau suivantes décrivent comment la connexion est établie et les données sont transférées entre un client et un serveur dans le cas du mTLS : + +1. Le client demande une ressource protégée via le protocole HTTPS et le processus de handshake SSL/TLS commence. +1. Le serveur retourne son certificat public au client avec un message server hello. +1. Le client valide/vérifie le certificat reçu. Le client vérifie le certificat auprès de l'autorité de certification (CA) pour les certificats signés par une CA. +1. Si le certificat du serveur a été validé avec succès, le serveur demande le certificat du client. +1. Le client fournit son certificat public au serveur. +1. Le serveur valide/vérifie le certificat reçu. Le serveur vérifie le certificat auprès de l'autorité de certification pour les certificats signés par une CA. + +Après l'achèvement du processus de handshake, le client et le serveur communiquent et transfèrent des données entre eux, chiffrées avec les clés secrètes partagées entre les deux pendant le handshake. + + + +Le processus ci-dessus exige qu'avant de se connecter à un environnement (pré-production ou production), le DFSP et le Hub Mojaloop complètent chacun les étapes suivantes. + +1. Créer un certificat serveur signé par votre CA. +1. Partager votre certificat serveur et la chaîne CA avec l'autre partie. +1. Installer la chaîne CA de l'autre partie dans votre pare-feu sortant (la validation/vérification se fera par rapport à ces certificats installés). +1. Générer une demande de signature de certificat (CSR) pour votre certificat client TLS et la partager avec l'autre partie. +1. Signer la CSR de l'autre partie en utilisant votre CA. +1. Partager le certificat client signé ainsi que le certificat racine de votre CA avec l'autre partie. +1. Installer votre propre certificat client signé par la CA de l'autre partie dans votre passerelle API sortante. +1. Installer le certificat racine de la CA de l'autre partie dans votre passerelle API sortante. + +##### Certificats JWS + +Chaque fois qu'un client API envoie un message API à une contrepartie, le client API doit signer le message à l'aide de sa clé privée JWS. Après que la contrepartie reçoit le message API, elle doit valider la signature avec la clé publique JWS de la partie émettrice. JWS est utilisé par la partie réceptrice pour valider que le message provient de l'expéditeur attendu et qu'il n'a pas été modifié en transit. + +Le processus ci-dessus exige que tous les DFSP et le Hub Mojaloop lui-même disposent d'un certificat JWS et qu'avant de se connecter à un environnement (pré-production ou production), le DFSP et le Hub Mojaloop complètent chacun les étapes suivantes. + +1. Créer un magasin de clés (pour stocker votre certificat et votre clé privée), une paire de clés asymétriques (une clé publique et une clé privée), et un certificat associé qui vous identifie. +1. Partager votre clé publique JWS. +1. Installer les clés publiques JWS des autres parties (le Hub et tous les autres DFSP) dans votre passerelle entrante. +1. Installer votre clé privée JWS dans votre passerelle sortante. + +#### Partage des informations des points d'accès + +Le Hub Mojaloop et les DFSP partagent les informations des points d'accès pour : + +* mettre en liste blanche les adresses IP publiques de l'autre partie dans les règles de pare-feu afin de permettre le trafic +* configurer les URL de rappel de l'autre partie dans les passerelles API + +En règle générale, l'accès à tout trafic entrant et sortant pour un DFSP sera contrôlé par l'équipe de sécurité concernée. Le pare-feu du DFSP doit être correctement configuré : + +* pour accéder au Hub Mojaloop dans tout environnement où le DFSP et le Hub interagissent, et +* pour que le Hub Mojaloop effectue des rappels vers le DFSP + +En dehors de l'accès vers et depuis le Hub déployé dans un environnement, tout autre accès public doit être bloqué pour empêcher tout accès non autorisé/non justifié. + +En conséquence, l'accès au Hub Mojaloop est également réglementé. Les DFSP doivent partager leur IP/plage d'IP à partir desquelles les appels seront effectués vers le Hub afin que le pare-feu du Hub puisse être configuré de manière appropriée. L'équipe de sécurité au sein du DFSP devrait être en mesure de fournir cette information. + +#### Obtention d'un jeton OAuth + +Le Hub Mojaloop utilise les technologies WSO2 pour l'intégration entre le Hub et les DFSP, et pour fournir une passerelle aux DFSP. Pour se connecter aux différents environnements du Hub, les DFSP doivent obtenir l'accès à WSO2. WSO2 offre un portail API Store où les DFSP peuvent créer des comptes de passerelle API pour l'accès au niveau applicatif, s'abonner aux API et obtenir des jetons OAuth pour une utilisation lors de l'interaction avec le Hub Mojaloop. + +## Intégration dans le backend du Hub + +L'onboarding comprend certaines étapes qui ne nécessitent aucune action de la part des DFSP et sont de la seule responsabilité de l'opérateur du Hub. Ces étapes sont les suivantes : + +1. Configurer les passerelles API du Hub qui gèrent les flux de données entrants et sortants depuis/vers les DFSP. Mojaloop utilise les technologies WSO2 pour l'accès aux passerelles, ainsi que l'autorisation et l'authentification des DFSP pour le passage des messages via les passerelles. La pile de produits WSO2 peut être déployée à partir du code en utilisant une solution d'intégration et de déploiement continus (CI/CD), le provisionnement peut être effectué par des scripts d'automatisation. +1. Créer des utilisateurs et des comptes, configurer le contrôle d'accès basé sur les rôles. +1. Configurer le Hub pour gérer les cas d'utilisation pris en charge par le schéma : + - Configurer les registres du Hub. + - Configurer les e-mails de notification du Hub. + - Configurer le modèle de règlement. + - Intégrer les oracles. \ + Mojaloop fournit un [script de provisionnement](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning/MojaloopHub_Setup) pour effectuer toutes les étapes ci-dessus de manière automatisée en utilisant le [Mojaloop Testing Toolkit (TTK)](https://github.com/mojaloop/ml-testing-toolkit). +1. Configurer des DFSP simulateurs pour les activités de validation initiales. \ + Mojaloop fournit des [scripts de provisionnement](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning/MojaloopSims_Onboarding) pour effectuer cette étape de manière automatisée en utilisant le Mojaloop Testing Toolkit (TTK). +1. Configurer les DFSP dans le backend du Hub. Pour chaque DFSP : + - Ajouter le DFSP et créer une devise pour celui-ci. + - Ajouter les URL de rappel pour tous les services API. + - Ajouter un plafond de débit net et définir la position initiale à 0. + - Configurer les e-mails de notification du DFSP. \ + Comme pour les étapes précédentes, la configuration des détails du DFSP peut également être effectuée via un script de provisionnement. + +## Tests et validation + +Au fur et à mesure que les DFSP avancent dans leur parcours d'onboarding, ils sont tenus d'effectuer des tests dans chaque environnement. Les exigences de validation métier et technique doivent être satisfaites lors des tests. Les détails de la validation métier sont définis dans les règles de schéma. + +Voici quelques exemples d'activités de test que les DFSP sont censés effectuer dans les différents environnements de pré-production : + +* validation de l'intégration de bout en bout et de la couche applicative contre des simulateurs +* validation de l'intégration de bout en bout et de la couche applicative contre des DFSP réels et amicaux +* validation du processus de règlement +* validation de la configuration de sécurité +* validation des accords de niveau de service (SLA) en matière de temps de réponse +* tests de performance diff --git a/docs/fr/adoption/HubOperations/Portalv2/accessing-the-portal.md b/docs/fr/adoption/HubOperations/Portalv2/accessing-the-portal.md new file mode 100644 index 000000000..ad34e5d22 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/accessing-the-portal.md @@ -0,0 +1,92 @@ +# Accéder au portail + +Lorsque vous accédez au portail, vous êtes invité à vous connecter. Saisissez vos identifiants sur la page de connexion. + + + +Le portail met en œuvre un contrôle d'accès basé sur les rôles, ce qui signifie que le rôle qui vous est attribué détermine l'éventail des fonctionnalités du portail auxquelles vous avez accès. Actuellement, les rôles suivants existent : + +* `portaladmin` : a un accès complet à toutes les fonctionnalités du portail +* `portaluser` : a un accès limité aux fonctionnalités du portail + +Le tableau suivant répertorie toutes les fonctionnalités disponibles, les chemins de navigation pour y accéder et les autorisations de rôles correspondantes. + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fonctionnalités du portail et chemins de navigation
FonctionnalitéChemin de navigationportaladminportaluser

Afficher les détails de la fenêtre de règlement

Settlement > Settlement Windows

Fermer des fenêtres de règlement

Settlement > Settlement Windows

Régler des fenêtres de règlement

Settlement > Settlement Windows

Finaliser un règlement

Settlement > Settlement Windows

Afficher les détails du règlement

Settlement > Settlements

Afficher les détails financiers des DFSP

Participants > DFSP Financial Positions

Désactiver et réactiver les transactions pour un DFSP

Participants > DFSP Financial Positions

Enregistrer les dépôts ou retraits sur les comptes de liquidité des DFSP

Participants > DFSP Financial Positions

Mettre à jour le Net Debit Cap d'un DFSP

Participants > DFSP Financial Positions

x

Rechercher des données de transfert

Transfers > Find Transfers

diff --git a/docs/fr/adoption/HubOperations/Portalv2/busops-portal-introduction.md b/docs/fr/adoption/HubOperations/Portalv2/busops-portal-introduction.md new file mode 100644 index 000000000..1ebe7956d --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/busops-portal-introduction.md @@ -0,0 +1,23 @@ +# Introduction – Guide du Finance Portal v2 + +Ce guide est destiné à l'Opérateur d'un Hub Mojaloop et fournit des informations sur le Finance Portal, qui facilite la gestion quotidienne des processus liés au règlement. + +::: tip REMARQUE +Le Finance Portal est désigné sous le nom de « Business Operations Portal » sur l'interface utilisateur du portail. +::: + +Le portail offre les fonctionnalités suivantes : + +* [rechercher des fenêtres de règlement et vérifier les détails des fenêtres de règlement](managing-windows.md) +* [fermer et régler des fenêtres de règlement](settling.md) +* [régler des règlements](settling.md) +* [rechercher des règlements et vérifier les détails des règlements](checking-settlement-details.md) +* [surveiller les détails financiers des DFSP tels que le solde, la Position actuelle, le Net Debit Cap, le pourcentage de NDC utilisé](monitoring-dfsp-financial-details.md) +* [désactiver et réactiver les transactions pour un DFSP](enabling-disabling-transactions.md) +* [mettre à jour le Net Debit Cap d'un DFSP](updating-ndc.md) +* [enregistrer les dépôts ou retraits sur le compte de liquidité d'un DFSP](recording-funds-in-out.md) +* [rechercher des données de transfert](searching-for-transfer-data.md) + +::: tip REMARQUE +Le Finance Portal ne prend actuellement en charge que les processus de règlement basés sur le modèle de règlement net différé (Deferred Net Settlement). +::: diff --git a/docs/fr/adoption/HubOperations/Portalv2/checking-settlement-details.md b/docs/fr/adoption/HubOperations/Portalv2/checking-settlement-details.md new file mode 100644 index 000000000..dce2f8049 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/checking-settlement-details.md @@ -0,0 +1,52 @@ +# Vérification des détails du règlement + +La page **Settlement > Settlements** vous permet de consulter certains détails des règlements, tels que : + +* l'identifiant du règlement +* l'état du règlement +* la valeur totale des transactions +* les identifiants des DFSP impliqués dans les transactions, ainsi que la Position de règlement net multilatérale associée pour la période choisie + +![Vérification des détails du règlement](../../../../.vuepress/public/check_settlement_details.png) + +La page **Settlements** fournit une liste de règlements que vous pouvez filtrer à l'aide de divers critères de recherche : + +* **Date** : Fournit une liste déroulante de plages horaires. La valeur par défaut est **Today**. \ +\ +L'option **Clear** vous permet de supprimer tous les filtres de date déjà appliqués. +* **From** et **To** : Affiche l'heure de début et l'heure de fin de la plage horaire sélectionnée dans le champ **Date**. Lorsque **Date** est défini sur **Custom Range**, vous devez définir la date et l'heure vous-même dans les champs **From** et **To**. +* **State** : Fournit une liste déroulante des états de règlement. + * **Pending Settlement** : Un nouveau règlement composé d'une ou plusieurs fenêtres de règlement a été créé. La Position de règlement net multilatérale due à/par chaque participant a été calculée. + * **Ps Transfers Recorded** : Le Hub a marqué les transferts concernés comme `RECEIVED_PREPARE` dans ses enregistrements internes. + * **Ps Transfers Reserved** : Le Hub a marqué les transferts concernés comme `RESERVED` dans ses enregistrements internes. + * **Ps Transfers Committed** : Le Hub a marqué les transferts concernés comme `COMMITTED` dans ses enregistrements internes. + * **Settling** : Le règlement est en cours. + * **Settled** : Le règlement est terminé. + * **Aborted** : Le règlement n'a pas pu être complété et doit être annulé. +* Bouton **Clear Filters** : Vous permet de supprimer tous les filtres que vous avez appliqués. + +À mesure que vous appliquez des critères de recherche, la liste des résultats (règlements) est mise à jour en continu. + +Les détails suivants sont affichés : + +* **Settlement ID** : L'identifiant unique du règlement. +* **State** : Le statut du règlement. +* **Total Value** : La valeur totale des transactions au sein du lot de règlement. +* **Open Date** : La date et l'heure de création du règlement dans le Hub. +* **Last Action Date** : La date et l'heure de la dernière action effectuée sur le règlement dans le Hub (par exemple, des fonds ont été réservés, des fonds ont été validés). +* **Action** : Bouton **Finalize**. Vous permet de finaliser un règlement. Ce bouton n'est affiché que pour les règlements en attente (Pending Settlements). Pour plus de détails sur la finalisation d'un règlement, voir [Règlement](settling.md#finalizing-a-settlement). + +Pour afficher les détails d'un règlement particulier, cliquez sur le règlement dans la liste des résultats. La fenêtre contextuelle **Settlement Details** s'affiche. + +![Fenêtre contextuelle des détails du règlement](../../../../.vuepress/public/settlement_details_popup.png) + +Les détails supplémentaires suivants sont affichés : + +* **DFSP** : L'identifiant unique du DFSP. +* **Window ID** : L'identifiant unique de la fenêtre de règlement en cours de règlement. +* **Debit** : Montant de débit agrégé résultant des transferts auxquels le DFSP a participé. +* **Credit** : Montant de crédit agrégé résultant des transferts auxquels le DFSP a participé. + +::: tip REMARQUE +Au moment de la rédaction, les informations que devrait afficher le clic sur le bouton **View Net Positions** ne sont pas disponibles. Elles seront ajoutées dans une future version du portail. +::: diff --git a/docs/fr/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md b/docs/fr/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md new file mode 100644 index 000000000..210d99458 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/enabling-disabling-transactions.md @@ -0,0 +1,27 @@ +# Désactivation et réactivation des transactions pour un DFSP + +Dans certains cas, il peut être nécessaire de rendre un DFSP inactif temporairement ou définitivement. Un exemple de scénario est lorsque vous observez un comportement hautement suspect et que la cause réelle nécessite une investigation, le risque de perte d'argent étant trop élevé. + +La page **Participants** > **DFSP Financial Positions** fournit une option pour arrêter l'envoi et la réception de transferts pour un DFSP particulier en désactivant son registre de Position en un clic de bouton. + +(Le Hub maintient un registre de Position pour chaque DFSP. Le registre de Position suit combien un DFSP doit ou combien lui est dû. Chaque fois qu'un transfert est traité, la Position dans le Hub est ajustée en temps réel.) + +Pour désactiver les transactions pour un DFSP particulier, effectuez les étapes suivantes : + +::: warning +La désactivation d'un DFSP arrêtera toutes les transactions entrantes et sortantes pour ce DFSP, assurez-vous donc d'appliquer cette option avec précaution. Une fois le risque écarté, n'oubliez pas de reprendre les services pour le DFSP. +::: + +1. Allez sur la page **Participants** > **DFSP Financial Positions**. +1. Trouvez l'entrée du DFSP que vous souhaitez désactiver. +1. Cliquez sur le bouton **Disable**. + + + +Pour reprendre les services pour le DFSP que vous avez précédemment désactivé, effectuez les étapes suivantes : + +1. Allez sur la page **Participants** > **DFSP Financial Positions**. +1. Trouvez l'entrée du DFSP que vous souhaitez activer. +1. Cliquez sur le bouton **Enable**. + + diff --git a/docs/fr/adoption/HubOperations/Portalv2/managing-windows.md b/docs/fr/adoption/HubOperations/Portalv2/managing-windows.md new file mode 100644 index 000000000..2380e6b8e --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/managing-windows.md @@ -0,0 +1,50 @@ +# Vérification des détails des fenêtres de règlement + +La page **Settlement Windows** vous permet de : + +* rechercher des fenêtres de règlement en fonction de plusieurs critères de recherche +* fermer une fenêtre de règlement ouverte +* régler une seule fenêtre ou régler plusieurs fenêtres à la fois + +::: tip REMARQUE +N'oubliez pas que le règlement doit suivre cette procédure : + +* Fermez la fenêtre de règlement que vous souhaitez régler. +* Réglez la ou les fenêtres fermées de votre choix. Cela crée un nouveau règlement. +* Envoyez les rapports de règlement aux DFSP et à la banque de règlement, puis obtenez une confirmation de la banque attestant qu'elle a transféré les fonds conformément au rapport. +* Finalisez le nouveau règlement créé à l'étape 2. + +Étant donné que la fermeture d'une fenêtre et l'initiation du règlement en réglant les fenêtres sélectionnées font partie intégrante du processus de règlement, elles sont décrites dans une section dédiée au [règlement](settling.md). +::: + +Une fenêtre de règlement est une période de temps entre deux règlements successifs. Elle a une heure de début et une heure de fin, et tous les transferts qui aboutissent (et atteignent l'état `"COMMITTED"`) pendant que la fenêtre de règlement est ouverte seront réglés en lot après la fermeture de la fenêtre de règlement. + +Les transferts effectués dans la même fenêtre de règlement sont réglés en lot après la fin de la fenêtre de règlement. + +Pour accéder à la page **Settlement Windows**, allez dans **Settlement** > **Settlement Windows**. + +![Gestion des fenêtres de règlement](../../../../.vuepress/public/settlement_window_mgmt.png) + +La page **Settlement Windows** fournit une liste de fenêtres de règlement que vous pouvez filtrer à l'aide de divers critères de recherche : + +* **Date** : Fournit une liste déroulante de plages horaires. La valeur par défaut est **Today**. \ +\ +L'option **Clear** vous permet de supprimer tous les filtres de date déjà appliqués. +* **From** et **To** : Affiche l'heure de début et l'heure de fin de la plage horaire sélectionnée dans le champ **Date**. Lorsque **Date** est défini sur **Custom Range**, vous devez définir la date et l'heure vous-même dans les champs **From** et **To**. +* **State** : Fournit une liste déroulante des états des fenêtres de règlement : + * **Open** : La fenêtre de règlement est ouverte, les transferts sont acceptés dans la fenêtre ouverte actuelle. + * **Closed** : La fenêtre de règlement est fermée. Elle n'accepte plus de transferts supplémentaires et tous les nouveaux transferts sont affectés à une nouvelle fenêtre de règlement ouverte. + * **Pending** : La fenêtre de règlement est fermée, mais elle doit encore être réglée. Une fenêtre ne peut être réglée qu'une fois que la banque de règlement a confirmé que tous les DFSP participants ayant effectué des transferts dans la fenêtre de règlement ont réglé leurs paiements. + * **Settled** : La banque de règlement a confirmé que tous les DFSP concernés ont réglé leurs obligations mutuelles. Suite à la confirmation, l'Opérateur du Hub a réglé la fenêtre de règlement. + * **Aborted** : La fenêtre de règlement faisait partie d'un règlement qui a été annulé. Il est possible d'ajouter la fenêtre annulée à un nouveau règlement. + * **Clear** : Vous permet de supprimer tous les filtres d'état de fenêtre déjà appliqués. +* Bouton **Clear Filters** : Vous permet de supprimer tous les filtres que vous avez appliqués. + +À mesure que vous appliquez des critères de recherche, la liste des résultats (fenêtres de règlement) est mise à jour en continu. La liste des résultats de recherche affiche les détails suivants : + +* Sélecteur de fenêtre : Affiché uniquement pour les fenêtres de règlement **Pending**. Cliquer sur le sélecteur de fenêtre active le bouton **Settle Selected Windows**. Pour plus de détails sur le règlement d'une fenêtre de règlement, voir [Règlement](settling.md#settling-a-closed-settlement-window). +* **Window ID** : L'identifiant unique de la fenêtre de règlement. +* **State** : L'état de la fenêtre de règlement. +* **Opened Date** : La date et l'heure d'ouverture de la fenêtre de règlement. +* **Closed Date** : La date et l'heure de fermeture de la fenêtre de règlement. +* **Action** : Bouton **Close Window**. Vous permet de fermer une fenêtre de règlement. Ce bouton n'est affiché que pour les fenêtres de règlement **Open**, car seules les fenêtres ouvertes peuvent être fermées. Pour plus de détails sur la fermeture d'une fenêtre de règlement, voir [Règlement](settling.md#closing-a-settlement-window). diff --git a/docs/fr/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md b/docs/fr/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md new file mode 100644 index 000000000..b6422a2a5 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/monitoring-dfsp-financial-details.md @@ -0,0 +1,24 @@ +# Surveillance des détails financiers des DFSP + +La page **DFSP Financial Positions** vous permet de surveiller les détails financiers des DFSP tels que le solde, la [Position](settlement-basic-concepts#position) actuelle, le [Net Debit Cap](settlement-basic-concepts#liquidity-management-net-debit-cap), le pourcentage de NDC utilisé. + +Pour accéder à la page **DFSP Financial Positions**, allez dans **Participants** > **DFSP Financial Positions**. + +![Surveillance des détails financiers des DFSP](../../../../.vuepress/public/dfsp_financial_positions_2.png) + +Les détails suivants sont affichés pour chaque DFSP : + +* **Balance** : Reflète le solde du compte de liquidité du DFSP auprès de la banque de règlement. +* **Current Position** : La Position actuelle du DFSP. \ +\ +La Position d'un DFSP reflète — à un moment donné — le total des montants de transfert envoyés et reçus par le DFSP. La Position est la somme de toutes les transactions sortantes moins les transactions entrantes depuis le début de la fenêtre de règlement, ainsi que tous les transferts provisoires qui n'ont pas encore été réglés. \ +\ +Chaque tentative de transfert sortant entraîne le recalcul de la Position par le Hub Mojaloop en temps réel, qui est ensuite comparée au Net Debit Cap. \ +\ +Une fois la fenêtre de règlement fermée, les Positions sont ajustées en fonction du règlement — la Position change pour correspondre au montant net des transferts qui n'étaient pas initiés ou pas encore exécutés lorsque la fenêtre de règlement a été fermée. +* **NDC** : Le Net Debit Cap défini pour le DFSP. \ +\ +Lors du pré-financement de leur compte de liquidité, les DFSP définissent le montant maximum qu'ils peuvent « devoir » aux autres DFSP, c'est ce qu'on appelle le Net Debit Cap (NDC). Le NDC agit comme une limite ou un plafond sur les fonds disponibles pour les transactions d'un DFSP, et il ne peut jamais dépasser le solde du compte de liquidité. Cela est nécessaire pour garantir que les obligations d'un DFSP peuvent être honorées avec les fonds immédiatement disponibles auprès de la banque de règlement. \ +\ +La Position est continuellement vérifiée par rapport au Net Debit Cap ((MontantTransfert + Position) < = NDC) et si un transfert devait faire dépasser le montant de la Position par rapport au montant du NDC, le transfert est bloqué. +* **% NDC Used** : Un indicateur Position/NDC pour montrer le pourcentage de NDC utilisé. diff --git a/docs/fr/adoption/HubOperations/Portalv2/recording-funds-in-out.md b/docs/fr/adoption/HubOperations/Portalv2/recording-funds-in-out.md new file mode 100644 index 000000000..51661d0b6 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/recording-funds-in-out.md @@ -0,0 +1,31 @@ +# Enregistrement des entrées et sorties de fonds pour un DFSP + +La page **DFSP Financial Positions** vous permet d'enregistrer les entrées ou sorties de fonds dans les registres du Hub en cas de mouvement de fonds initié par le DFSP : un DFSP dépose des fonds sur son compte de liquidité ou retire des fonds de son compte de liquidité. + +Pour accéder à la page **DFSP Financial Positions**, allez dans **Participants** > **DFSP Financial Positions**. + + + +Pour enregistrer des entrées ou sorties de fonds pour un DFSP, effectuez les étapes suivantes : + +1. Cliquez sur le bouton **Update** à côté du DFSP pour lequel vous souhaitez enregistrer des entrées/sorties de fonds. \ +![](../../../../.vuepress/public/add_withdraw_funds.png) \ +La fenêtre **Update Participant** apparaît. +1. Sélectionnez **Add / Withdraw Funds** dans le menu déroulant **Action**. \ + +1. Sélectionnez l'option **Add Funds** ou **Withdraw Funds** selon l'action que vous souhaitez effectuer. \ +Pour enregistrer un dépôt, utilisez **Add Funds**. \ +Pour enregistrer un retrait, utilisez **Withdraw Funds**. \ + +1. Saisissez le montant ajouté ou retiré par le DFSP dans le champ **Amount**. \ +Ne spécifiez pas de signe plus ou moins lors de la saisie du montant. Assurez-vous plutôt d'avoir sélectionné la bonne action à l'étape précédente. +1. Cliquez sur **Submit**. +1. En cliquant sur **Submit**, une fenêtre de confirmation apparaît vous demandant de confirmer l'action, ou de confirmer et également mettre à jour le Net Debit Cap du DFSP. \ + + +1. Cliquez sur **Confirm Only** ou **Confirm and Update NDC**. \ +\ +En cliquant sur **Confirm Only**, la valeur **Balance** sur la page **DFSP Financial Positions** est mise à jour et le Hub ajuste les registres. \ +\ +En cliquant sur **Confirm and Update NDC**, la fenêtre **Update Participant** change et vous permet de mettre à jour le Net Debit Cap (NDC). \ + diff --git a/docs/fr/adoption/HubOperations/Portalv2/searching-for-transfer-data.md b/docs/fr/adoption/HubOperations/Portalv2/searching-for-transfer-data.md new file mode 100644 index 000000000..a09167bf1 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/searching-for-transfer-data.md @@ -0,0 +1,189 @@ +# Recherche de données de transfert + +Le Finance Portal fournit une page de recherche de transferts, qui vous permet de trouver des données de transfert en fonction des identifiants DFSP, des identifiants d'utilisateur final ou des identifiants de transfert. Cela est utile lors de la résolution de problèmes. + +::: tip REMARQUE +Les valeurs affichées sur la page **Find Transfers** proviennent de la base de données central-ledger du Hub. +::: + +## Recherche de transferts + +Pour rechercher des transferts, effectuez les étapes suivantes : + +1. Allez dans **Transfers** > **Find Transfers**. La page **Find Transfers** s'affiche. \ + +1. Utilisez les filtres de recherche pour spécifier ce que vous recherchez. Vous pouvez remplir n'importe quel nombre de champs de recherche, dans n'importe quelle combinaison. + * **Transfer ID** : Saisissez un `transferId` complet ou un fragment d'un `transferId`. + * **Payer FSP ID** : Saisissez le `fspId` complet ou un fragment du `fspId` du DFSP Payer. + * **Payer ID Type** : À l'aide de la liste déroulante, sélectionnez le type d'identifiant utilisé pour identifier le Payer (par exemple, **MSISDN** ou **ACCOUNT_ID**). + * **Payer ID Value** : Saisissez l'identifiant complet ou un fragment de l'identifiant utilisé pour identifier le Payer (par exemple, un numéro de téléphone ou un numéro de compte bancaire). + * **Payee FSPID** : Saisissez le `fspId` complet ou un fragment du `fspId` du DFSP Payee. + * **Payee ID Type** : À l'aide de la liste déroulante, sélectionnez le type d'identifiant utilisé pour identifier le Payee. + * **Payee ID Value** : Saisissez l'identifiant complet ou un fragment de l'identifiant utilisé pour identifier le Payee. + * **From** et **To** : Saisissez l'heure de début et l'heure de fin de la plage horaire pendant laquelle le ou les transferts que vous recherchez ont eu lieu. +1. Une fois vos filtres de recherche définis, cliquez sur **Find Transfers**. La liste des résultats de recherche correspondant aux critères s'affiche. + +Utilisez les boutons de navigation de page en bas de l'écran pour naviguer entre les pages de résultats de recherche. + +Vous pouvez supprimer tous les filtres que vous avez appliqués et recommencer votre recherche à zéro en cliquant sur **Clear Filters**. + +Les résultats de recherche sont affichés en colonnes. Toutes les colonnes sont triables : + +* Cliquez sur un en-tête de colonne pour modifier l'ordre de tri des valeurs affichées dans la colonne. +* Cliquez sur l'icône de loupe dans l'en-tête de colonne et saisissez une valeur que vous recherchez. + +::: tip +Le nombre total de transferts retournés est limité à mille (1000) (ceci pour limiter la charge sur le backend). Si vous ne parvenez pas à trouver le transfert que vous recherchez parmi les mille premiers résultats, commencez à affiner votre recherche en utilisant les filtres de recherche. \ + \ +Si votre recherche retourne plus de cinq cents (500) résultats, la page affichera un message d'information pour que vous sachiez que vous ne voyez pas nécessairement tous les résultats correspondant à vos critères de recherche initiaux et que vous devriez affiner davantage. +::: + +Les détails suivants sont affichés pour un transfert : + +::: tip REMARQUE +Les transferts sans devis (c'est-à-dire les transferts « ajout/retrait de fonds » et les transferts de règlement) n'afficheront des détails que pour les champs suivants : **Transfer ID**, **Timestamp**, **Amount**, **Currency**, **Status**. +::: + +* **Transfer ID** : L'identifiant unique du transfert (correspond à `transferId`). +* **Type** : Le type de transfert (correspond à `transactionType` dans Payment Manager et `transactionScenario` dans l'API Mojaloop FSPIOP). +* **Timestamp** : La date et l'heure de création de la demande de transfert, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **Payer FSPID** : Le `fspId` du DFSP Payer. +* **Payee FSPID** : Le `fspId` du DFSP Payee. +* **Amount** : Le montant du transfert. +* **Currency** : La devise du transfert. +* **Status** : L'état du transfert (correspond à `transferState` dans Payment Manager et l'API Mojaloop FSPIOP). +* **Payer Acct ID** : Le type d'identifiant et la valeur d'identifiant du compte du Payer. +* **Payee Acct ID** : Le type d'identifiant et la valeur d'identifiant du compte du Payee. + +## Détails du transfert + +Pour obtenir plus de détails sur un résultat de recherche particulier, cliquez sur son entrée dans la liste des résultats de recherche. Une fenêtre contextuelle **Transfer Details** apparaît. Cette section fournit des informations sur les détails affichés pour un transfert. + +### Demandes de devis + +L'onglet **Quote Requests** affiche le `quoteId` et des informations supplémentaires dans des sous-onglets. + +#### Sous-onglet Quote Request + + + +Le sous-onglet **Quote Request** affiche les détails suivants concernant la demande de devis : + +* **quoteId** : L'identifiant unique du devis, décidé par le DFSP Payer. +* **transactionReferenceId** : Correspond au `transactionId` spécifié dans la demande de devis. +* **transactionRequestId** : Facultatif. Identifiant commun entre les DFSP pour l'objet de demande de transaction, décidé par le DFSP Payee. +* **note** : Un mémo facultatif attaché au transfert. +* **expirationDate** : Une date d'expiration facultative de la demande de devis, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **amount** : Le montant pour lequel le devis est demandé. +* **createdDate** : La date et l'heure de création de la demande de devis, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **transactionInitiator** : Indique si l'initiateur du transfert est le **PAYER** (Payer) ou le **PAYEE** (Payee). +* **transactionInitiatorType** : Indique le type de l'initiateur : + * **CONSUMER** : Le consommateur est l'initiateur de la transaction. Par exemple : transfert de personne à personne ou remboursement de prêt depuis un portefeuille. + * **AGENT** : L'agent est l'initiateur de la transaction. Par exemple : remboursement de prêt via un agent. + * **BUSINESS** : L'entreprise est l'initiateur de la transaction. Par exemple : décaissement de prêt. + * **DEVICE** : L'appareil est l'initiateur de la transaction. Par exemple : paiement marchand initié par le commerçant et autorisé sur un TPE. +* **transactionScenario** : Indique le scénario de transaction (correspond à `transactionType` dans Payment Manager). +* **transactionSubScenario** : Indique le sous-scénario de transaction défini par le schéma. +* **balanceOfPaymentsType** : Le code BdP tel que défini dans [le Système de codification de la balance des paiements du FMI](https://www.imf.org/external/np/sta/bopcode/). +* **amountType** : **SEND** pour le montant envoyé, **RECEIVE** pour le montant reçu. +* **currency** : La devise du montant pour lequel le devis est demandé. Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). + +#### Sous-onglet Quote Parties + + + +Le sous-onglet **Quote Parties** affiche les détails suivants concernant le DFSP Payer et le DFSP Payee : + +* **quoteId** : L'identifiant unique du devis, décidé par le DFSP Payer. +* **partyIdentifierType** : Le type d'identifiant utilisé pour identifier la partie (par exemple, **MSISDN** ou **ACCOUNT_ID**). +* **partyIdentifierValue** : La valeur de l'identifiant utilisé pour identifier la partie (par exemple, un numéro de téléphone ou un numéro de compte bancaire). +* **fspId** : L'identifiant unique du DFSP enregistré dans le Hub (correspond à `fspId`) - tel que fourni dans le devis. +* **merchantClassificationCode** : Utilisé lorsque le Payee est un commerçant acceptant les paiements marchands. +* **partyName** : Le nom d'affichage de la partie. +* **transferParticipantRoleType** : Le rôle que le DFSP joue dans le transfert. +* **ledgerEntryType** : Le type d'écriture financière que cette partie présente — valeur principale (c'est-à-dire le montant d'argent que le Payer souhaite que le Payee reçoive) ou commission d'interchange. +* **amount** : Le montant pour lequel le devis est demandé. +* **currency** : La devise du montant pour lequel le devis est demandé. Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **createdDate** : La date et l'heure de création de la demande de devis, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **partySubIdOrTypeId** : Un sous-identifiant ou sous-type pour la partie. +* **participant** : Référence au `fspId` résolu (si fourni/connu). + +#### Sous-onglet Quote Errors + +Le sous-onglet **Quote Errors** n'affiche des informations que s'il y a eu une erreur lors de l'étape des devis. + +### Réponses aux devis + + + +L'onglet **Quote Responses** affiche les détails concernant la réponse au devis : + +* **quoteId** : L'identifiant unique du devis, décidé par le DFSP Payer. +* **transactionReferenceId** : Correspond au `transactionId` spécifié dans la demande de devis. +* **quoteResponseId** : L'identifiant unique de la réponse au devis. +* **transferAmountCurrencyId** : La devise du montant du transfert. Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **transferAmount** : Le montant que le DFSP Payer doit transférer au DFSP Payee. +* **payeeReceiveAmountCurrencyId** : La devise du montant que le Payee doit recevoir dans la transaction de bout en bout. +* **payeeReceiveAmount** : Le montant que le Payee doit recevoir dans la transaction de bout en bout. +* **payeeFspFeeCurrencyId** : La devise de la part des frais de transaction du DFSP Payee (le cas échéant). Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **payeeFspFeeAmount** : La part des frais de transaction du DFSP Payee (le cas échéant). +* **payeeFspCommissionCurrencyId** : La devise de la commission de transaction du DFSP Payee (le cas échéant). Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **payeeFspCommissionAmount** : La commission de transaction du DFSP Payee (le cas échéant). +* **ilpCondition** : La condition ILP qui doit être jointe au transfert par le côté Payer. +* **responseExpirationDate** : La date d'expiration du devis sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **isValid** : Un indicateur indiquant si la réponse au devis a passé la validation de la demande et les vérifications de doublons. +* **createdDate** : La date et l'heure de création de la demande de devis, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **ilpPacket** : Le paquet ILP retourné par le côté Payee en réponse à la demande de devis. + +### Préparations de transfert + + + +L'onglet **Transfer Prepares** affiche les détails concernant la demande de transfert : + +* **transferId** : L'identifiant unique du transfert. +* **amount** : Le montant que le DFSP Payer doit transférer au DFSP Payee. +* **currencyId** : La devise du montant du transfert. Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **ilpCondition** : La condition ILP qui doit être remplie pour valider le transfert. +* **expirationDate** : La date d'expiration du transfert sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **createdDate** : La date et l'heure de création de la demande de transfert, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). + +### Participants au transfert + + + +L'onglet **Transfer Participants** affiche les détails suivants concernant les participants au transfert : + +* **transferParticipantId** : L'identifiant interne du participant au schéma (DFSP) pour lequel le rapport est demandé, correspond à `participantId` tel qu'enregistré dans le Hub. +* **transferId** : L'identifiant unique du transfert. +* **participantCurrencyId** : La devise dans laquelle le participant (DFSP) effectue ses transactions. Un code alphabétique de trois lettres conforme à [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). +* **transferParticipantRoleType** : Le rôle que le DFSP joue dans le transfert. +* **ledgerEntryType** : Le type d'écriture financière que cette partie présente — valeur principale (c'est-à-dire le montant d'argent que le Payer souhaite que le Payee reçoive) ou commission d'interchange. +* **amount** : Le montant du transfert. +* **createdDate** : La date et l'heure de création de la demande de transfert, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). + +### Exécutions de transfert + + + +L'onglet **Transfer Fulfilments** affiche les détails suivants concernant la réponse au transfert : + +* **transferId** : L'identifiant unique du transfert. +* **ilpFulfilment** : L'exécution de la condition ILP spécifiée dans la demande de transfert. +* **completedDate** : La date et l'heure d'achèvement du transfert, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). +* **isValid** : Un indicateur indiquant si l'exécution du transfert est valide. +* **settlementWindowId** : L'identifiant de la fenêtre de règlement à laquelle ce transfert a été assigné. +* **createdDate** : La date et l'heure de création de la réponse au transfert, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). + +### Changements d'état du transfert + + + +L'onglet **Transfer State Changes** affiche les détails suivants concernant les états par lesquels passe un transfert : + +* **transferStateChangeId** : L'identifiant unique de l'état du transfert. +* **transferId** : L'identifiant unique du transfert. +* **enumeration** : L'état du transfert (correspond à `transferState` dans Payment Manager et l'API Mojaloop FSPIOP). +* **description** : La description de la signification de l'état. +* **reason** : La raison pour laquelle le transfert est passé dans un état particulier. +* **createdDate** : La date et l'heure auxquelles le transfert a atteint un état particulier, sous forme d'horodatage au format [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html). diff --git a/docs/fr/adoption/HubOperations/Portalv2/settlement-business-process.md b/docs/fr/adoption/HubOperations/Portalv2/settlement-business-process.md new file mode 100644 index 000000000..f01cedad2 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/settlement-business-process.md @@ -0,0 +1,68 @@ +# Processus de règlement + +Il est important de définir un processus métier autour de la gestion des règlements. Le processus de haut niveau suivant sert d'exemple que vous pouvez personnaliser en fonction des besoins spécifiques de votre organisation. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Processus métier de règlement
ÉtapeDétails

1

L'Opérateur du Hub ferme la fenêtre de règlement et initie le règlement pour les fenêtres sélectionnées à l'aide du Finance Portal.

2

L'Opérateur du Hub récupère un rapport de règlement du DFSP pour chaque DFSP actif dans la fenêtre de règlement.

3

L'Opérateur du Hub envoie par courriel le rapport de règlement du DFSP aux points de contact désignés de chaque DFSP.

4

Les DFSP examinent leur rapport et rapprochent les transactions avec leurs propres enregistrements dans les meilleurs délais.

+

Le rapport fournit des informations sur la position de règlement bilatérale du DFSP avec chaque DFSP avec lequel il a effectué des transactions (soit en tant que DFSP Payer ou DFSP Payee) dans la ou les fenêtres de règlement en cours de règlement. Il fournit également le total des montants de transfert envoyés et reçus par le DFSP dans la ou les fenêtres de règlement.

5

L'Opérateur du Hub récupère le rapport de la banque de règlement.

6

L'Opérateur du Hub informe les points de contact de la banque de règlement que le règlement peut être effectué, en partageant le rapport de la banque de règlement.

Le rapport sert d'instructions de paiement à la banque et fournit la position de règlement bilatérale de chaque DFSP par rapport à chaque autre DFSP ayant effectué des transactions dans la ou les fenêtres de règlement en cours de règlement. Il fournit également le total des montants de transfert envoyés et reçus par chaque DFSP.

7

La banque de règlement transfère les fonds entre le compte de règlement et les comptes de liquidité des DFSP, conformément aux Positions nettes agrégées indiquées dans le rapport de la banque de règlement.

8

La banque de règlement confirme que les fonds ont été transférés et (puisque l'Opérateur du Hub n'a pas de visibilité sur le solde des comptes détenus à la banque de règlement) partage le solde du compte de liquidité de chaque DFSP.

9

L'Opérateur du Hub finalise le règlement à l'aide du Finance Portal.

10

L'Opérateur du Hub vérifie les soldes des comptes de liquidité des DFSP par rapport aux soldes affichés dans le portail, et les met à jour si nécessaire, en utilisant la fonctionnalité « ajouter/retirer des fonds » du portail. Notez que cela peut entraîner un recalcul du NDC du DFSP, ce qui pourrait provoquer le rejet des transactions sortantes du DFSP par le Hub.

11

L'Opérateur du Hub récupère un rapport de résultat de règlement du DFSP pour chaque DFSP.

12

L'Opérateur du Hub informe chaque DFSP du résultat du règlement et du solde de son compte de liquidité en envoyant le rapport de résultat de règlement du DFSP à chaque DFSP.

diff --git a/docs/fr/adoption/HubOperations/Portalv2/settling.md b/docs/fr/adoption/HubOperations/Portalv2/settling.md new file mode 100644 index 000000000..acd8b779b --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/settling.md @@ -0,0 +1,67 @@ +# Règlement + +1. [Fermez la fenêtre de règlement](#closing-a-settlement-window) que vous souhaitez régler. +1. [Réglez la ou les fenêtres fermées de votre choix](#settling-a-closed-settlement-window). Cela crée un nouveau règlement. +1. Envoyez les rapports de règlement aux DFSP et à la banque de règlement, puis obtenez une confirmation de la banque attestant qu'elle a transféré les fonds conformément au rapport. +1. [Finalisez le nouveau règlement](#finalizing-a-settlement) créé à l'étape 2. + +Cette section décrit les étapes du processus (étapes 1, 2 et 4) que vous effectuez via le portail. + +## Fermeture d'une fenêtre de règlement + +Pour fermer une fenêtre de règlement ouverte, effectuez les étapes suivantes : + +1. Allez dans **Settlement** > **Settlement Windows**. La page **Settlement Windows** s'affiche. +1. Trouvez la fenêtre de règlement que vous recherchez, [en utilisant les filtres de recherche](managing-windows.md). +1. La fenêtre ouverte aura un bouton **Close Window** affiché à côté d'elle dans la colonne **Action**. Cliquez sur le bouton **Close Window**. + +![Fermeture d'une fenêtre de règlement](../../../../.vuepress/public/settlement_window_mgmt_close.png) + +La fermeture d'une fenêtre ouvrira automatiquement une nouvelle fenêtre avec l'état **Open**. + +## Règlement d'une fenêtre de règlement fermée + +Pour régler une ou plusieurs fenêtres de règlement, effectuez les étapes suivantes : + +1. Allez dans **Settlement** > **Settlement Windows**. La page **Settlement Windows** s'affiche. +1. Trouvez la fenêtre de règlement que vous recherchez, [en utilisant les filtres de recherche](managing-windows.md). La fenêtre de règlement doit être à l'état **Closed**. +1. Cliquez sur le sélecteur de fenêtre à côté de la ou des fenêtres de règlement que vous souhaitez régler. \ +\ + \ +\ +Cela active le bouton **Settle Selected Windows**. Cliquez sur le bouton **Settle Selected Windows**. \ +\ + +1. Une fenêtre **Settlement Submitted** apparaît, où vous avez les options suivantes : + +* Afficher les règlements soumis +* Continuer à afficher les fenêtres \ +\ + \ +\ +Si vous souhaitez afficher le nouveau règlement que vous venez de créer, cliquez sur le bouton **View Submitted Settlements**. Cela vous amène à la page **Settlements**, où vous pouvez rechercher le nouveau règlement, [en utilisant les filtres de recherche](checking-settlement-details.md). Le règlement sera à l'état **Pending Settlement**. + +## Finalisation d'un règlement + +Pour finaliser le règlement, effectuez les étapes suivantes : + +**Prérequis :** + +* La banque de règlement a confirmé que toutes les Positions MLNS des DFSP ont été réglées. + +**Étapes :** + +1. Allez dans **Settlement** > **Settlements**. La page **Settlements** s'affiche. +1. Trouvez le règlement que vous recherchez, en utilisant les [filtres de recherche](checking-settlement-details.md). Le règlement doit être à l'état **Pending Settlement**. \ +\ + +1. Cliquez sur le bouton **Finalize** à côté du règlement. Une fenêtre de statut apparaît et affiche les états du règlement avec des coches ajoutées au fur et à mesure que le processus de règlement progresse. \ +\ +Lorsque le règlement est finalisé, vous verrez tous les états affichés avec des coches à côté. Le dernier état indiquera **State: SETTLED.** De plus, le bouton **Close** sera activé, vous permettant de revenir à la page **Settlements**. \ +\ + +1. De retour sur la page **Settlements**, en recherchant le règlement, vous devriez voir l'état du règlement affiché comme **Settled**. + +::: tip +Si l'état du règlement est autre que **Settled**, cela signifie que le règlement ne s'est pas terminé pour une raison quelconque. Cliquez à nouveau sur **Finalize** pour terminer le processus de règlement inachevé. +::: diff --git a/docs/fr/adoption/HubOperations/Portalv2/updating-ndc.md b/docs/fr/adoption/HubOperations/Portalv2/updating-ndc.md new file mode 100644 index 000000000..723567eb3 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Portalv2/updating-ndc.md @@ -0,0 +1,22 @@ +# Mise à jour du Net Debit Cap d'un DFSP + +La page **DFSP Financial Positions** vous permet de mettre à jour le Net Debit Cap (NDC) d'un DFSP. + +Pour accéder à la page **DFSP Financial Positions**, allez dans **Participants** > **DFSP Financial Positions**. + +![Mise à jour du NDC d'un DFSP](../../../../.vuepress/public/dfsp_financial_positions_2.png) + +Pour mettre à jour le Net Debit Cap d'un DFSP, effectuez les étapes suivantes : + +1. Cliquez sur le bouton **Update** à côté du DFSP pour lequel vous souhaitez mettre à jour le NDC. \ + +La fenêtre **Update Participant** apparaît. +1. Sélectionnez **Change Net Debit Cap** dans le menu déroulant **Action**. \ + +1. Saisissez le nouveau montant du NDC dans le champ **Amount**. \ + +1. Cliquez sur **Submit**. +1. En cliquant sur **Submit**, une fenêtre de confirmation apparaît vous demandant de confirmer l'action. \ + +1. Cliquez sur **Confirm**. \ +En cliquant sur **Confirm**, la valeur **NDC** sur la page **DFSP Financial Positions** est mise à jour et affiche le nouveau montant du NDC. diff --git a/docs/fr/adoption/HubOperations/RBAC/Role-based-access-control.md b/docs/fr/adoption/HubOperations/RBAC/Role-based-access-control.md new file mode 100644 index 000000000..8de31cd07 --- /dev/null +++ b/docs/fr/adoption/HubOperations/RBAC/Role-based-access-control.md @@ -0,0 +1,311 @@ +# Contexte du RBAC +Le Hub Mojaloop utilise une méthode de contrôle d'accès basé sur les rôles (RBAC) pour atténuer les risques. + +## Qu'est-ce que le RBAC et comment le concevoir ? + +Le contrôle d'accès basé sur les rôles (RBAC) est une méthode de restriction de l'accès au réseau en fonction des rôles des utilisateurs individuels au sein d'une entreprise. Le RBAC permet aux employés d'avoir des droits d'accès uniquement aux informations dont ils ont besoin pour effectuer leur travail et les empêche d'accéder aux informations qui ne les concernent pas. + +La conception RBAC pour un opérateur de hub décrit les points de contrôle de sécurité qui doivent être pris en compte ou étendus afin d'atténuer les risques au sein d'une organisation typique d'exploitation de hub Mojaloop. Certains points de contrôle sont liés aux processus métier et à la structure organisationnelle, certains points de contrôle sont techniques et concernent les couches d'identification, d'authentification et d'autorisation, et certains points de contrôle nécessitent une surveillance. Les trois doivent être pris en compte pour créer la responsabilité et atténuer les risques. + +Ce document couvre : +1. Vue d'ensemble du RBAC.
+Dans lequel nous discutons des principes RBAC et des structures organisationnelles. +2. Implémentation technique des contrôles RBAC.
+Ce qui est spécifiquement important pour une implémentation Mojaloop et comment l'appliquer techniquement. +3. Recommandations de rôles +4. Exigences et approche de surveillance. + +## Vue d'ensemble du RBAC + +### Principe du moindre privilège + +Le RBAC utilise le principe de sécurité du moindre privilège. Le moindre privilège signifie qu'un utilisateur dispose précisément du niveau de privilège nécessaire pour effectuer son travail. L'objectif est de minimiser la probabilité d'attribuer à un utilisateur des permissions excessives pour effectuer des actions dans l'écosystème Mojaloop. + +### Implémentation Zero Trust de Mojaloop + +Un réseau zero trust est un réseau dans lequel aucune personne, appareil ou réseau ne bénéficie d'une confiance inhérente. Toute confiance, qui permet l'accès aux informations, doit être méritée, et la première étape consiste à démontrer une identité valide. Un système doit savoir qui vous êtes, avec certitude, avant de pouvoir déterminer ce à quoi vous devriez avoir accès. + +La conception inhérente de Mojaloop implémentera une approche Zero Trust dans son architecture et son déploiement, exigeant que toutes les entités qui interagissent s'authentifient d'abord, puis demandent l'autorisation d'accéder et de traiter les données en fonction du rôle auquel elles appartiennent. + +### Séparation des fonctions + +La séparation des fonctions vise à atténuer le risque de fraude interne en fixant des limites entre les rôles attribués à un employé, et entre les conflits d'intérêts pouvant résulter des responsabilités d'un employé, en veillant à ce qu'aucun utilisateur unique ne puisse avoir le contrôle fonctionnel de bout en bout d'un processus métier et de ses données. Cela nécessite que plus d'un individu crée, traite et complète une action. + +### Audit + +L'audit devrait travailler en collaboration avec les équipes métier et informatiques pour séparer ces fonctions dans la mesure du possible et attribuer un contrôle d'atténuation approprié dans les cas où cela n'est pas faisable. De plus, ces contrôles devraient être surveillés sur une base trimestrielle et les résultats doivent être signalés à la direction. + +Quelques définitions contextuelles incluent : +1. **Action** : un événement distinct déclenché par un utilisateur qui entraîne : + - La création d'un actif de données + - La lecture ou l'accès à un actif de données + - La mise à jour ou la modification de l'état d'un actif de données + - La suppression ou le retrait d'un actif de données d'une application ou d'une base de données. +2. **Permission** : autorité pour effectuer une action spécifique dans le contexte d'une application ou d'un service +3. **Rôle** : applications, actions et accès aux données nécessaires pour effectuer les tâches liées à un rôle unique +4. **Relation utilisateur - rôle** : Le ou les rôles attribués à chaque utilisateur qui définissent les permissions dont ils disposent + +## Implémentation technique du RBAC + +Un individu qui a besoin d'accéder aux différents portails de gestion du Hub Mojaloop peut être enregistré et un « compte » généré, qui peut être utilisé pour accéder à divers aspects d'une instance opérationnelle d'un Hub Mojaloop et pour fournir une base d'audit de cet accès en liant les activités à l'enregistrement original. Aux fins de ce document, un « compte » est une identité numérique, un moyen d'authentifier (lier) la personne revendiquant cette identité à l'enregistrement original, et un ensemble d'attributs, qui incluront - entre autres - un ensemble de droits d'accès, ou des droits qui sont activés par la possession de ces attributs. + +Le processus d'enregistrement implique la vérification d'identité, la vérification des antécédents, etc. L'individu reçoit ensuite des identifiants - un identifiant de compte de connexion/identité numérique et au moins une méthode d'authentification, qui peut inclure un mot de passe et une authentification à deux facteurs (2FA). + +::: tip NOTE +Le champ d'application de ce document ne se limite pas aux opérateurs du Hub Mojaloop. Il aborde également les aspects de l'accès des opérateurs DFSP aux portails Payment Manager. +::: + +### Considérations relatives à la 2FA + +Il convient de noter que la 2FA via un téléphone mobile peut être inappropriée pour certains rôles, car les rôles très sensibles peuvent exiger que les téléphones mobiles soient rangés sous clé pendant que l'individu est « en service ». Cela nécessitera d'autres méthodes de 2FA, telles que des jetons physiques. + +### Utilisateurs, actions et rôles dans un contexte Mojaloop + +Mojaloop aura 2 grandes catégories d'utilisateurs : + +1. **Humains**
+Ce sont les utilisateurs du hub et des DFSP qui, à travers diverses interfaces, interagiront avec Mojaloop. Les utilisateurs DFSP interagiront avec Mojaloop à travers le Payment Manager et les portails qui seront mis à disposition pendant le processus d'onboarding. +2. **Non-humains**
+Ceux-ci automatiseront les processus métier et les tâches qui seraient autrement effectuées par un humain. Ils communiqueront via des appels API qui effectueront des actions pour répondre aux exigences métier. + +Le contexte de ce document se concentrera uniquement sur les utilisateurs humains. + +### Gestion du cycle de vie des utilisateurs + +Le « cycle de vie du compte utilisateur » définit les processus de gestion collectifs pour chaque compte utilisateur. Ces processus peuvent être décomposés en Création, Révision/Mise à jour et Désactivation — ou « CRUD ». Si une organisation utilise des ressources informatiques de quelque nature que ce soit, elle s'appuie sur des comptes utilisateurs pour y accéder. + +### Intégration + +Le processus d'onboarding comprendra certaines activités impliquant la création d'utilisateurs tant du côté DFSP que du Hub. Celles-ci seront les suivantes : + +1. Hub : Les utilisateurs suivants seront créés + - Opérateurs du Hub + - Administrateurs du Hub +2. DFSP + - Opérateurs DFSP + - Administrateurs DFSP (applicable uniquement au Payment Manager). + + +### Processus de détermination de la séparation des fonctions + +1. Définir les flux de travail et processus de gestion des utilisateurs. Ce sont tous les processus métier qui composent les actions métier Mojaloop dans Mojaloop. Les exemples incluent l'intégration. +1. Rationaliser toutes les exigences d'accès de sécurité des utilisateurs pour les applications de Mojaloop comme indiqué dans le tableau ci-dessous : + - Définir les fonctions métier et applicatives pour les utilisateurs et les API + - Définir les profils de rôles + - Définir les profils de fonctions et de compétences + - Rassembler une liste des conflits de séparation des fonctions applicables en définissant les rôles de séparation des fonctions + - Tableau matriciel des profils de rôles (avec des données d'exemple) : + +| **Rôles et Permissions** **Matrice** | Utilisateurs Hub | Administrateur | Utilisateur Maker Standard | Utilisateur Checker Standard | Lecture Seule Standard | Utilisateurs DFSP | Administrateur | Utilisateur Maker Standard | Utilisateur Checker Standard | Lecture Seule Standard | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| Rôles d'onboarding | X | | | | | | | | | | +| Créer un compte utilisateur | X | | | | | | | | | | +| Créer un profil DFSP | X | | | | | | | | | | +| Créer un utilisateur DFSP | X | | | | | | | | | | +| +| **Portail Financier** | +| Voir les rapports | | | X | X | X | | | X | X | X | +| Configuration de la plateforme | | | | | | | | | | | +| + +3. Reconfigurer les rôles en conflit + - Approbations métier + - Création d'utilisateurs Maker/Checker +4. Rapports périodiques sur l'accès au système et l'autorisation des utilisateurs +5. Séparation de la sécurité informatique et de la sécurité informatique opérationnelle qui soutiendra les activités de gestion des utilisateurs + +### Meilleures pratiques pour le RBAC et la gestion des identités Mojaloop + +1. Tous les identifiants d'utilisateurs doivent être uniques et avoir un format unique qui peut être corrélé dans le hub mais pas significatif pour les personnes extérieures. +2. Les utilisateurs DFSP n'auront accès à aucun rôle administratif au sein du Hub +3. Tous les utilisateurs non-humains doivent être empêchés de se connecter aux interfaces applicatives. +4. Les utilisateurs DFSP seront formés sur les rôles et les meilleures pratiques +5. Appliquer le provisionnement automatisé des utilisateurs et la gestion du cycle de vie. +6. Classer les actions effectuées dans Mojaloop pour identifier les actions métier à risque nécessitant des contrôles supplémentaires. +7. Les contrôles supplémentaires pour atténuer les risques RBAC peuvent inclure : + - Authentification multifacteur (MFA) + - Journalisation d'audit avec alertes + - Désactivation / blocage automatique du profil utilisateur +8. Mojaloop surveillera l'inactivité des utilisateurs et désactivera les utilisateurs inactifs sur une période spécifiée +9. Faire respecter de manière centralisée les politiques applicables à l'ensemble des identités, par ex. politique de mots de passe, politiques de connexion, MFA, authentification basée sur le risque, etc. +10. Identifier et surveiller de près les identités privilégiées qui ont des permissions pour effectuer des actions sensibles. +Les éléments suivants s'appliquent aux utilisateurs privilégiés : + - Les privilèges avancés doivent être demandés et approuvés au cas par cas ; + - Les administrateurs doivent avoir leurs permissions privilégiées pour le minimum de temps possible ; + - Les administrateurs ne doivent avoir que les permissions nécessaires pour accomplir une tâche spécifique ; + - L'appartenance aux groupes administratifs doit être révisée régulièrement ; + - Appliquer l'authentification multifacteur pour les utilisateurs administratifs ; + - Conserver les journaux d'accès, les audits et configurer des notifications en temps réel lorsque l'accès est activé. +11. Mojaloop configurera des journaux d'audit et des alertes pour toutes les actions des utilisateurs dans Mojaloop. Dans la mesure du possible, explorer l'analytique des identités via des outils open source applicables. + +### Gestion automatisée des identités et contrôle RBAC + +Les outils préférés pour la gestion des utilisateurs et des identités dans un déploiement Mojaloop sont : + +1. **Moteur de gestion des identités KeyCloak** – Stocker et traiter les contrôles d'authentification API ainsi qu'agir comme passerelle API. +2. **Moteur de gestion des identités WSO2** – Stocker et traiter les profils de rôles des utilisateurs et gérer l'auto-intégration des utilisateurs DFSP. + +## Conception des rôles au sein de votre organisation + +Un utilisateur avec un compte qui permet l'accès au Hub aura des rôles associés à ce compte, qui définissent ce qu'il peut faire une fois authentifié et connecté. + +De nombreux rôles s'appliquent à plusieurs portails, cependant, certains rôles peuvent être spécifiques à des portails individuels. + +Une attention particulière doit être portée lors de l'attribution de plusieurs rôles à un compte, ou de plusieurs comptes à une même personne physique. Cela est dû au potentiel qui se présente pour le contournement des contrôles. Une partie de l'objectif du RBAC est de s'assurer que plus d'une personne doit être dans la chaîne d'autorisation pour les actions importantes, réduisant ainsi les vulnérabilités liées aux acteurs malveillants. + +### Portails de l'écosystème Mojaloop + +L'écosystème Mojaloop offre un certain nombre de portails, qui prennent en charge divers degrés de contrôle d'accès et de RBAC. Ceux-ci sont divisés en deux groupes : + +- Portails du Hub, qui sont liés au fonctionnement du Hub lui-même +- Portails Payment Manager, qui sont liés à la gestion de la connexion d'un DFSP spécifique au Hub + +### RBAC dans le Hub Mojaloop + +Dans l'environnement du Hub Mojaloop, le RBAC est implémenté à travers une combinaison d'outils - Ory Oathkeeper pour la gestion des identités, et Keycloak pour le contrôle d'accès (y compris les rôles et le maker/checker). + +Le Hub lui-même possède les portails suivants : + +- **Intégration de l'opérateur du Hub :**
+Actuellement, il n'existe pas de solution intégrée de gestion des identités et des accès (IAM) pour les opérateurs du Hub, bien que la fonction soit partiellement remplie par l'utilisation de WSO2. Des travaux de développement sont en cours pour développer une solution IAM complète basée sur Ory et Keycloak. Cela verra un opérateur administrateur créé parallèlement au déploiement du Hub, ce qui constitue une première étape fondamentale dans ce domaine. +- **Portail Financier :**
+Il a deux fonctions principales : la gestion des opérations de règlement, et la gestion de la position de liquidité des DFSP individuels (et en relation avec cela, leur valeur de plafond de débit net (NDC)). +L'accès au portail financier est actuellement limité à une simple fonction de contrôle d'accès par nom d'utilisateur/mot de passe. +- **Cycle de vie du participant :**
+Contrôle et configuration de l'accès au Hub par les DFSP. +D'un point de vue technique, cela est actuellement réalisé par l'utilisation du Mojaloop Connection Manager (MCM). Cependant, il est prévu que le MCM lui-même sera développé pour exposer une API, qui pourra être utilisée pour développer une interface utilisateur disponible pour les opérateurs du Hub et pour les DFSP. +- **Opérations du Hub :**
+Celles-ci comprennent les recherches de transactions, la surveillance de l'état et des performances, les tableaux de bord et l'ensemble des opérations techniques. +Actuellement, celles-ci sont réalisées grâce à l'utilisation de Prometheus/Grafana et d'une gamme d'autres outils, avec un contrôle d'accès standard intégré dans ces outils eux-mêmes. Il est prévu que cela sera migré vers la solution Ory/Keycloak, au fur et à mesure de son développement. + +D'autres opérations du Hub, telles que la gestion de la fraude et la gestion des cas/litiges, sont des modules complémentaires qui implémentent leur propre contrôle d'accès pour gérer l'accès à leurs fonctions sensibles. Ceux-ci ne sont pas abordés dans ce document. + +En plus des mesures de contrôle d'accès ci-dessus, il convient de noter que l'accès à toutes ces fonctions n'est possible que via un VPN, avec des identifiants individuels contrôlant l'accès. + +En plus de ces portails, il existe deux autres moyens principaux d'accéder au Hub, dont aucun n'est soumis au RBAC : + +- Le premier concerne les transactions, qui sont strictement contrôlées selon leurs propres mesures de cybersécurité multicouches. +- Et deuxièmement, les paiements en masse (gouvernement vers personne - G2P), qui sont pris en charge au moyen d'une API soumise aux mêmes contrôles que les autres transactions individuelles. Il est prévu que les paiements en masse seront un service fourni aux DFSP (et à leurs clients) au moyen d'une API sécurisée, le DFSP exploitant un portail de paiements en masse pour l'utilisation par ses clients. Il est possible que l'opérateur d'une instance du Hub Mojaloop puisse mettre à disposition un portail de paiements en masse en marque blanche, qui s'interface avec l'API de paiements en masse du Hub, pour personnalisation par tout DFSP souhaitant offrir le service à ses clients. (Notez que cette approche n'est pas unique : une approche similaire a été proposée, par exemple, pour les paiements marchands, avec une application en marque blanche pour les transactions par code QR mise à disposition des DFSP pour intégration dans leurs portefeuilles mobiles.) + +Les contrôles d'accès autour des paiements individuels ou en masse ne sont donc pas abordés davantage dans ce document. + +### Payment Manager pour l'onboarding + +Payment Manager est actuellement l'un des principaux mécanismes d'onboarding des DFSP à un Hub Mojaloop. Alors que le Hub est unique dans un schéma, il existe une instance distincte de Payment Manager pour chaque DFSP. Les portails offerts par Payment Manager doivent donc être sécurisés au moyen du RBAC pour limiter l'accès aux représentants autorisés du DFSP. + +Dans l'environnement Payment Manager, le RBAC est implémenté uniquement via Keycloak. + +Les portails suivants sont disponibles : + +- **Intégration utilisateur/opérateur :** +Payment Manager inclut Keycloak pour l'IAM. Lors du déploiement, un utilisateur administrateur unique est créé, qui peut être utilisé pour créer d'autres comptes utilisateurs. +- **Gestion de la connexion au Hub :** +Cela inclut la possibilité de configurer la connexion au Hub du côté Payment Manager, et par implication de la désactiver. C'est donc une fonction contrôlée, avec des contrôles différents pour la visualisation par rapport à la modification. +- **Investigation des transactions :** +Il est possible d'investiguer les requêtes de transactions en utilisant le portail Payment Manager. Cela est potentiellement problématique si des informations personnellement identifiables (PII) sont disponibles via le portail. + +### Comptes fondamentaux + +Au moment où un Hub est déployé pour la première fois, Ory/Keycloak sera utilisé pour créer un compte utilisateur fondamental avec des privilèges d'administrateur. Un administrateur système se verra attribuer ce compte. Notez que l'administrateur système ne se verra attribuer aucun rôle opérationnel au-delà de ceux d'un administrateur système. + +Toutes les fonctions exécutées à l'aide d'Ory/Keycloak sont soumises à une journalisation au niveau du système à des fins d'audit. + +L'administrateur système utilisera ensuite Ory/Keycloak pour créer d'autres comptes utilisateurs, sous réserve de vérifications d'identité et de contrôles d'antécédents standard pour chaque individu (définis dans les règles de schéma associées à un déploiement Mojaloop particulier) avant que leurs comptes ne soient créés. + +Ces nouveaux comptes utilisateurs se verront attribuer l'un de ces rôles : + +- OPERATOR +- MANAGER + +Un compte utilisateur ne peut pas avoir à la fois les rôles OPERATOR et MANAGER. + +### Comptes supplémentaires + +En plus de l'administrateur système, les comptes fondamentaux auront la possibilité d'utiliser Ory/Keycloak pour ajouter d'autres comptes. Cependant, pour ces utilisateurs, cette activité sera soumise à des contrôles maker/checker. Un utilisateur avec le rôle OPERATOR pourra mettre en place un compte utilisateur (avec des processus en place pour garantir que la diligence raisonnable en matière de vérification d'identité et de contrôle des antécédents a été effectuée). Cependant, ce compte ne sera pas activé tant qu'une personne avec le rôle MANAGER ne l'aura pas approuvé. + +Un rôle sera attribué à chacun de ces comptes lors de leur création. En plus des rôles associés aux comptes fondamentaux, les rôles suivants peuvent être attribués aux nouveaux comptes utilisateurs : + +- ADMINISTRATOR +- FINANCE_MANAGER + +Un compte utilisateur ne peut pas avoir plus d'un des rôles OPERATOR, MANAGER, ADMINISTRATOR ou FINANCE_MANAGER, afin d'assurer la séparation de : + +- La gestion financière des autres tâches d'exploitation du Hub +- Les rôles d'opérateur et de gestionnaire dans les fonctions maker/checker + +::: tip NOTE +L'attribution des rôles ADMINISTRATOR ou FINANCE_MANAGER est soumise à un degré plus élevé de vérification d'identité et de contrôle des antécédents que tout autre rôle, en raison de la nature sensible des fonctions associées. Ces vérifications supplémentaires sont définies dans les règles de schéma. +::: + +### Portail Financier / Business Operational Framework + +De nombreuses fonctions (telles que la visualisation des positions des DFSP, l'état des fenêtres de règlement, etc.) du portail financier sont disponibles pour tous les utilisateurs connectés, quel que soit leur rôle. Cependant, les fonctions suivantes ne peuvent être exécutées que par des utilisateurs ayant des rôles spécifiques : + +- Traitement des règlements + - Fermer la fenêtre de règlement + - Initier le règlement +- Gestion de la liquidité DFSP + - Ajouter/retirer des fonds + - Modifier le NDC + +Toutes ces fonctions sont soumises à des contrôles maker/checker, de sorte qu'un utilisateur avec le rôle ADMINISTRATOR peut initier l'action, mais elle doit être approuvée par un utilisateur avec le rôle FINANCE_MANAGER. + +### Cycle de vie du participant + +Ce portail fournit une interface unique pour qu'un opérateur du Hub ajoute et maintienne les DFSP sur l'écosystème du Hub. + +Il existe certaines fonctions standardisées qui sont soumises au RBAC : + +- Créer un DFSP +- Créer des comptes DFSP +- Suspendre un DFSP + +Chacune de ces fonctions est soumise à des contrôles maker/checker, de sorte qu'un utilisateur avec le rôle OPERATOR peut mettre en place les modifications, et elles doivent être approuvées par un utilisateur avec le rôle MANAGER. + +De plus, il y a une charge de travail importante dans l'onboarding technique d'un DFSP, en particulier autour de l'établissement de l'environnement technique d'exploitation (certificats, etc.). Cela n'est pas soumis au RBAC. Cela n'est pas considéré comme un risque significatif, car il n'y a pas de valeur sans pouvoir créer un DFSP et les comptes associés sur le Hub lui-même - activités qui sont soumises au RBAC. + +### Opérations du Hub + +L'accès aux fonctions de reporting de Prometheus/Grafana n'est pas soumis aux contrôles RBAC - tout utilisateur connecté/authentifié, avec n'importe quel rôle RBAC attribué, peut consulter les rapports et les tableaux de bord. + +La création d'un nouveau rapport/tableau de bord est une fonction restreinte, et n'est disponible que pour les utilisateurs ayant le rôle MANAGER. + +Comme indiqué précédemment, les portails d'opérations et de reporting seront migrés vers l'environnement Ory/Keycloak afin de faciliter ces contrôles. + +### Payment Manager + +La fonctionnalité opérateur de Payment Manager est soumise aux contrôles RBAC, mais le maker/checker n'est pas requis. + +#### Intégration utilisateur/opérateur + +Lors du déploiement de Payment Manager, un seul compte utilisateur administrateur est créé à l'aide de Keycloak. Notez que l'utilisateur administrateur ne se verra attribuer aucun rôle opérationnel au-delà de ceux d'un administrateur système. + +Toutes les fonctions exécutées à l'aide de Keycloak sont soumises à une journalisation au niveau du système à des fins d'audit. + +L'utilisateur administrateur utilisera Keycloak pour créer d'autres comptes utilisateurs, sous réserve de vérifications d'identité et de contrôles d'antécédents standard pour chaque individu (définis dans les règles de schéma associées à un déploiement Mojaloop particulier) avant que leurs comptes ne soient créés. + +Ces nouveaux comptes utilisateurs se verront attribuer l'un des rôles suivants : + +- OPERATOR +- MANAGER + +Un compte utilisateur ne peut pas avoir à la fois les rôles OPERATOR et MANAGER. + +### Tableaux de bord + +Les tableaux de bord de Payment Manager sont disponibles pour tout utilisateur connecté/authentifié ayant le rôle OPERATOR ou MANAGER. + +### Gestion de la connexion au Hub + +La visualisation des paramètres de la connexion Payment Manager/Hub est disponible pour tout utilisateur connecté/authentifié ayant le rôle OPERATOR ou MANAGER. Cependant, la modification des paramètres est une fonction contrôlée. Seul un utilisateur ayant le rôle MANAGER peut modifier les paramètres. + +### Investigation des transactions + +La réalisation d'investigations de transactions à l'aide des fonctionnalités du portail Payment Manager est une activité contrôlée, en raison du potentiel de révélation de données PII. Elle n'est donc disponible que pour les utilisateurs connectés/authentifiés ayant le rôle MANAGER. + +## Surveillance +La surveillance est le quatrième pilier de l'atténuation du risque RBAC. Sa conception et sa configuration dépendent fortement de la maturité du schéma, des règles de schéma, des cas d'utilisation employés et des classes de participants. +Comme point de départ pour concevoir votre surveillance, considérez ces catégories : +1. Surveillance des menaces de sécurité externes +1. Surveillance des menaces de sécurité internes, par ex. l'audit +1. Surveillance de l'application des règles de schéma diff --git a/docs/fr/adoption/HubOperations/Settlement/ledgers-in-the-hub.md b/docs/fr/adoption/HubOperations/Settlement/ledgers-in-the-hub.md new file mode 100644 index 000000000..e3f446004 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Settlement/ledgers-in-the-hub.md @@ -0,0 +1,367 @@ +# Grands livres dans le Hub + +## Gestion du risque + +Certains éléments du processus de règlement échappent au contrôle du Hub ; il importe donc qu’un ensemble de contrôles soit en place pour éviter la disparition de fonds et garantir qu’il y ait toujours suffisamment de liquidité pour l’exploitation du Hub. Outre le [Net Debit Cap](settlement-basic-concepts.md#liquidity-management-net-debit-cap), le Hub utilise plusieurs grands livres internes pour gérer le risque et assurer la liquidité. Ces grands livres sont les suivants : + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Grand livreDéfinitionType de transfert enregistré dans le grand livre

DFSP Position Ledger

Suit combien un DFSP doit ou a droit de recevoir. Chaque fois qu’un transfert est traité, la Position dans le Hub est ajustée en temps réel.

Transfert P2P : transaction de personne à personne entre utilisateurs finaux de DFSP.
+
+Transfert de règlement : flux de fonds entre DFSP visant à rapprocher les grands livres et à mettre à jour les Positions pour une fenêtre de règlement donnée.

DFSP Settlement Ledger

Compte de liquidité du DFSP détenu à la banque de règlement, reflété dans le Hub. Sert de compte de rapprochement et reflète les mouvements de fonds réels.

Transfert de fonds (entrant et sortant) : mouvement de fonds initié par le DFSP ou confirmation par la banque de règlement que le règlement est terminé.

Hub Multilateral Net Settlement (HMLNS) Ledger

Sert à enregistrer l’écriture d’équilibre pour le règlement net entre les DFSP. Après qu’une fenêtre de règlement a été fermée et réglée entre tous les DFSP, son solde revient à zéro.

Transfert de règlement : flux de fonds entre DFSP visant à rapprocher les grands livres et à mettre à jour les Positions pour une fenêtre de règlement donnée.

Hub Reconciliation Ledger

Garantit que les mouvements entrants et sortants des comptes de liquidité enregistrés dans les grands livres de règlement (Settlement Ledgers) s’équilibrent. Le solde correspond au montant que l’opérateur du Hub administre dans l’ensemble des grands livres de règlement des DFSP participants.
+
+Fait office de compte de contrôle et suit les mouvements de fonds sur l’ensemble des DFSP Settlement Ledgers (qui reflètent les mouvements de fonds réels).

Transfert de fonds (entrant et sortant) : mouvement de fonds initié par le DFSP ou confirmation par la banque de règlement que le règlement est terminé.

+ +## Principes comptables + +En comptabilité, une position nette positive (davantage de débits) est traitée comme un actif, tandis qu’une position nette négative (davantage de crédits) est traitée comme un passif. Le Hub Mojaloop applique ces mêmes principes, mais du point de vue du Hub. Qu’est-ce que cela signifie ? + +Un transfert est enregistré par le Hub comme un débit (DR) du côté du DFSP payeur, car le transfert réduit le montant qui doit être reversé à ce DFSP (passif réduit du point de vue du Hub). Ainsi, alors que le DFSP payeur lui-même traitera le transfert comme une augmentation de son passif dans son propre système, le Hub le traite comme une augmentation de son actif. + +Le même transfert est enregistré par le Hub comme un crédit (CR) du côté du DFSP bénéficiaire, car le transfert augmente le montant dû à ce DFSP (passif accru du point de vue du Hub). + +Enregistrer une transaction sur deux comptes sous forme d’écritures de débit et de crédit opposées (de montants égaux) correspond à ce qu’on appelle en comptabilité la « partie double ». + +En appliquant ces principes comptables à un dépôt effectué par un DFSP sur son compte de liquidité, le montant crée un passif du point de vue du Hub (l’argent doit être remboursé). Le montant saisi dans le Hub est donc négatif. Ainsi, à tout moment, le montant que le Hub doit à un DFSP peut être calculé rapidement en additionnant la Position du DFSP au solde de son compte de liquidité. L’écriture en partie double du DFSP Settlement Ledger est ajoutée au Hub Reconciliation Ledger. + +## Règlement : un exemple + +Cette section montre comment une transaction est enregistrée dans les différents grands livres, à l’aide d’un exemple simple. + +Prenons l’exemple suivant : DFSP1 envoie 50 USD à DFSP2. Voici comment cette transaction d’exemple est enregistrée dans les grands livres du Hub. + +### Étape 1a : Réserver le montant du transfert pour l’émetteur dans le Position Ledger + +Le DFSP Position Ledger sert à suivre les variations de la Position d’un DFSP. Une fois qu’une fenêtre de règlement est fermée et que le processus de règlement est lancé, le montant du transfert est réservé dans les grands livres de Position du Hub tenus pour les DFSP ainsi que dans le Hub Multilateral Net Settlement Ledger. Réserver le montant du transfert pour le DFSP payeur (DFSP1) garantit que les fonds ne peuvent pas être utilisés pour un autre transfert. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 1b : Réserver le montant du transfert pour le bénéficiaire dans le Position Ledger + +De même, la Position du DFSP bénéficiaire est suivie via le DFSP Position Ledger du DFSP. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 2a : Comptabiliser le montant du transfert pour l’émetteur dans le Position Ledger + +Après la réservation du montant du transfert, l’étape suivante consiste à comptabiliser le montant dans les mêmes grands livres qu’auparavant. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 2b : Comptabiliser le montant du transfert pour le bénéficiaire dans le Position Ledger + +La comptabilisation du montant du transfert pour le DFSP bénéficiaire (DFSP2) permet au DFSP d’envoyer des fonds vers d’autres DFSP s’il le souhaite. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Position LedgerHub Multilateral Net Settlement Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 3 : Réserver le montant du transfert pour l’émetteur dans le grand livre de règlement + +Une fois que les Positions sont dans un état contrôlé et que les écritures de débit et de crédit correspondantes ont été enregistrées dans le Hub Multilateral Net Settlement Ledger, la transaction doit aussi être enregistrée et réservée dans les DFSP Settlement Ledgers et le Hub Reconciliation Ledger afin de garantir que des fonds ne sont pas libérés par inadvertance pour une autre opération de sortie de fonds (Funds-Out). + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 4a : Comptabiliser le montant du transfert pour le bénéficiaire dans le grand livre de règlement + +Une fois que l’argent réel a bougé sur les comptes de liquidité des DFSP, les montants de transfert peuvent être comptabilisés dans les DFSP Settlement Ledgers et le Hub Reconciliation Ledger. Le mouvement de fonds est d’abord enregistré pour le DFSP bénéficiaire. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +### Étape 4b : Comptabiliser le montant du transfert pour l’émetteur dans le grand livre de règlement + +Enfin, le montant du transfert est aussi comptabilisé côté émetteur. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

50 USD

50 USD

+ +## Ajouter ou retirer des fonds : un exemple + +### Ajout de fonds + +Les soldes des comptes de liquidité fluctuant, les DFSP ajoutent des fonds pour financer leurs envois nets ou procèdent à des retraits. Les dépôts peuvent intervenir à tout moment, mais le Hub Reconciliation Ledger doit être mis à jour régulièrement pour éviter des problèmes de rapprochement. Chaque fois qu’une modification est apportée au compte externe (c’est-à-dire au compte de liquidité du DFSP), le Net Debit Cap doit aussi être réévalué. + +Dans l’exemple suivant, DFSP1 ajoute 100 000 USD à son compte de liquidité. Voici comment le montant du dépôt est enregistré dans les grands livres du Hub. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP1 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

100,000 USD

100,000 USD

+ +### Retrait de fonds + +Un retrait pouvant avoir une incidence sur le Net Debit Cap et sur la capacité à opérer, le NDC doit être recalculé au regard du nouveau solde du DFSP (le solde ne doit jamais être inférieur au NDC). + +Dans l’exemple suivant, DFSP2 retire 100 000 USD de son compte de liquidité. Voici comment le montant du retrait est enregistré dans les grands livres du Hub. + + ++++++ + + + + + + + + + + + + + + + + + + + + +
DFSP2 Settlement LedgerHub Reconciliation Ledger

DR

CR

DR

CR

100,000 USD

100,000 USD

diff --git a/docs/fr/adoption/HubOperations/Settlement/settlement-basic-concepts.md b/docs/fr/adoption/HubOperations/Settlement/settlement-basic-concepts.md new file mode 100644 index 000000000..15319f4db --- /dev/null +++ b/docs/fr/adoption/HubOperations/Settlement/settlement-basic-concepts.md @@ -0,0 +1,129 @@ +# Concepts de base + +Cette section regroupe les concepts et éléments clés du processus de gestion des règlements. + +## Couverture de liquidité + +Comme décrit dans l’[Introduction](settlement-management-introduction.md), l’une des caractéristiques d’un système de paiements en temps réel est que les DFSP créanciers doivent débourser des fonds à leurs clients avant d’être remboursés par le DFSP débiteur. Pour atténuer le risque qu’un DFSP créancier ne reçoive pas les fonds qui lui sont dus, Mojaloop exige que les DFSP débiteurs fournissent une preuve crédible qu’ils disposent de fonds disponibles suffisants pour honorer les obligations qu’ils contractent du fait des opérations dans le système. + +Cette preuve crédible est appelée *couverture de liquidité*. Le système Mojaloop ne prescrit pas la forme qu’elle doit prendre ; pour un DFSP donné, elle peut prendre plusieurs formes. Il peut s’agir par exemple : + +- de fonds déposés sur un compte sur lequel le Hub Mojaloop exerce un certain contrôle +- d’une ligne de crédit accordée par un autre établissement financier +- d’une autre forme de garantie + +Toute couverture de liquidité utilisée dans un schéma Mojaloop doit toutefois présenter les caractéristiques suivantes : + +- Elle doit pouvoir être convertie en paiements de règlement *immédiatement* sur demande du schéma Mojaloop. +- Elle doit être attestée par des preuves fiables dont dispose le schéma Mojaloop. +- Elle ne doit pas être convertible par le DFSP sous d’autres formes (par exemple en retirant des fonds d’un compte bancaire ou en tirant sur une ligne de crédit) sans que le schéma Mojaloop en ait été informé au préalable et l’ait approuvé. + +La couverture de liquidité attribuée à un DFSP donné est une couverture de liquidité pour un modèle de règlement et une devise donnés, et elle est attribuée au schéma dans son ensemble. Autrement dit, Mojaloop n’autorise pas les participants à détenir une couverture de liquidité qui ne s’appliquerait qu’à leurs transferts avec un ou certains DFSP spécifiques. + +Lorsqu’un DFSP demande au Hub Mojaloop d’effectuer un transfert, le Hub Mojaloop vérifie que le DFSP débiteur dispose d’une couverture de liquidité suffisante pour garantir que le transfert pourra être réglé s’il se termine avec succès. Il le fait en comparant le total des fonds disponibles du DFSP à la somme des éléments suivants : + +1. La somme des transferts qui ont été complétés mais pas encore réglés, et pour lesquels le DFSP est *soit* le créancier *soit* le débiteur. +1. La somme des transferts qui ont été initiés mais ne sont pas encore terminés, et pour lesquels le DFSP est le débiteur. +1. Le montant du transfert proposé. + +Si le total de ces trois éléments est supérieur au montant des fonds disponibles disponibles pour le DFSP débiteur, le transfert sera rejeté par le Hub Mojaloop. Notez que, dans cette configuration, la liquidité d’un DFSP est créditée de l’effet des transferts dont il est le bénéficiaire dès que le transfert est complété, sans attendre le règlement des fonds. Mojaloop agit ainsi pour réduire au minimum le montant de liquidité que les participants doivent détenir. + +## Modèle de règlement + +Les schémas souhaitent régler les fonds entre leurs participants de différentes manières. Cela dépend de qui exploite le schéma, du volume de trafic dans le schéma et de nombreux autres paramètres. + +Mojaloop est conçu pour prendre en charge les modes de règlement entre participants conformes aux standards du secteur. Ils sont les suivants : + +- Règlement net différé multilatéral +- Règlement net différé bilatéral +- Règlement brut immédiat + +La signification des termes composant ces types de règlement est la suivante. + +Les règlements sont *nets différés* si plusieurs transferts sont réglés ensemble. Les règlements nets (dans lesquels plusieurs transferts sont réglés ensemble) sont par définition différés (puisqu’il faut du temps pour constituer un lot). + +Les règlements sont *bruts* si chaque transfert est réglé séparément. Les règlements bruts peuvent être immédiats ou différés. Ils sont *différés* si une approbation externe au Hub est requise pour le règlement, et *immédiats* si le Hub peut procéder au règlement d’un transfert sans approbation externe. À ce jour, Mojaloop ne prend en charge que les règlements bruts immédiats. + +Les règlements sont *bilatéraux* si chaque paire de participants se règle entre elle pour le net de tous les transferts entre eux. Les règlements sont *multilatéraux* si chaque participant se règle avec le Hub pour le net de tous les transferts auxquels il a participé, quelle que soit l’autre partie. + +Un modèle de règlement définit la manière dont un Hub Mojaloop règlera un ensemble de transferts. Dans le cas simple, il n’y a qu’un seul modèle de règlement et il règle tous les transferts traités par le Hub. Mojaloop prend toutefois en charge plus d’un modèle de règlement pour un même schéma. Cela permet, par exemple, à un schéma de définir des modèles de règlement différents selon les devises ou les types de comptes du grand livre. + +Si un schéma définit plus d’un modèle de règlement, il incombe au schéma de veiller à ce qu’un transfert donné ne puisse relever que d’un seul modèle de règlement. Par exemple, supposons qu’un schéma définisse un modèle de règlement pour tous les transferts nécessitant une conversion de devise (définis comme : tous les transferts dont la devise source et la devise cible diffèrent), et un autre modèle pour tous les transferts dont la devise source est le shilling kényan (KES). Dans ce cas, un transfert convertissant des shillings kényans en rand sud-africain pourrait relever des deux modèles. + +## Fenêtre de règlement + +Chaque transfert complété dans le Hub est affecté à la fenêtre de règlement actuellement ouverte. La fenêtre de règlement sert à regrouper des transferts. L’affectation des transferts à une fenêtre de règlement est indépendante des modèles de règlement utilisés pour régler ces transferts. Ainsi, si un schéma a défini plus d’un modèle de règlement, les transferts relevant de modèles différents partageront une même fenêtre de règlement. + +Il n’existe pas de méthode déterministe pour affecter les transferts à une fenêtre de règlement donnée. Lorsqu’un administrateur du schéma crée une nouvelle fenêtre de règlement, on ne peut pas savoir à l’avance quels transferts seront affectés à la nouvelle fenêtre et lesquels resteront dans l’ancienne. + +Une fenêtre de règlement peut présenter les états suivants : + +* `OPEN` : la fenêtre de règlement est ouverte ; les transferts sont acceptés dans la fenêtre ouverte en cours. +* `CLOSED` : la fenêtre de règlement est fermée ; elle n’accepte plus de transferts supplémentaires et tous les nouveaux transferts sont affectés à une nouvelle fenêtre de règlement ouverte. +* `PENDING_SETTLEMENT` : la fenêtre de règlement est fermée, les [positions nettes de règlement multilatéral](#multilateral-net-settlement-position) ont été calculées pour chaque DFSP mais le règlement avec la banque de règlement partenaire n’a pas encore eu lieu. +* `SETTLED` : la banque de règlement a confirmé que tous les DFSP participants ayant effectué des transferts dans la fenêtre de règlement ont réglé leurs paiements, et l’opérateur du Hub a réglé la fenêtre. + +La fermeture d’une fenêtre de règlement ouvre automatiquement la suivante. + +### Règlements et fenêtres de règlement + +Un administrateur du Hub peut demander des règlements pour un modèle de règlement donné et pour une ou plusieurs fenêtres de règlement. + +Si un schéma n’a qu’un seul modèle de règlement, le règlement des transferts pour ce modèle dans une fenêtre de règlement donnée règle tous les transferts de cette fenêtre. En revanche, si un schéma a défini plus d’un modèle de règlement, le règlement des transferts relevant d’un modèle de règlement particulier pour une fenêtre donnée signifie que certains transferts de cette fenêtre ont été réglés et d’autres pas. + +Il est particulièrement important de comprendre les implications lorsqu’un modèle de règlement brut immédiat a été défini. Dans ce cas, les transferts individuels sont réglés dès qu’ils sont complétés. Si le schéma n’a qu’un modèle de règlement brut immédiat, tous les transferts sont réglés à leur complétion et la fenêtre de règlement devient inutile. En revanche, si le schéma combine des modèles brut et net, ou s’il a défini plus d’un modèle net, une fenêtre de règlement donnée peut contenir à la fois des transferts réglés et des transferts non réglés ; et, pour les transferts réglés par un modèle brut, des transferts déjà réglés peuvent apparaître même dans une fenêtre de règlement encore ouverte. Cela complique la définition du statut global d’une fenêtre de règlement. + +Mojaloop gère cette situation en attribuant toujours à la fenêtre de règlement un état qui est l’*état minimal* des transferts qu’elle contient. L’*état minimal* est défini par la séquence des états de fenêtre de règlement indiquée ci-dessus. Ainsi, par exemple, si une fenêtre de règlement contient des transferts déjà réglés (parce qu’ils sont réglés en brut) et d’autres transferts dont le processus de règlement n’a pas encore commencé, l’état de la fenêtre de règlement sera `OPEN`. Si une fenêtre de règlement a été fermée et qu’elle contient des transferts relevant de deux modèles de règlement différents, dont l’un est en cours de règlement (état `PENDING_SETTLEMENT`) et l’autre pas (état `CLOSED`), l’état global de la fenêtre de règlement sera `CLOSED`. + +## Gestion de la liquidité (Net Debit Cap) + +Comme indiqué ci-dessus, Mojaloop exige que les participants préfinancent les transferts lorsqu’ils sont la partie débitrice en fournissant au Hub Mojaloop une preuve crédible qu’ils peuvent honorer l’ensemble de leurs besoins de règlement actuels. Il peut toutefois exister des situations où un participant ne souhaite pas que l’intégralité de sa couverture de liquidité serve de garantie aux transferts. Par exemple, un participant peut être bénéficiaire dans un canal de rémittance et donc créancier net au global ; ou un participant peut déposer des fonds supplémentaires pour couvrir les périodes où ses comptes ne sont pas ouverts pour recevoir des fonds. + +Pour couvrir ces cas, Mojaloop permet aux participants ou aux administrateurs du Hub de réserver une partie de leur couverture de liquidité disponible, de sorte que seule une partie puisse servir de couverture de liquidité pour les transferts. Cela s’appelle le Net Debit Cap (NDC). Le NDC agit comme une limite ou un plafond posé sur les fonds d’un DFSP disponibles pour les opérations ; il ne peut jamais dépasser le solde du compte de liquidité. Cela est nécessaire pour garantir que les passifs d’un DFSP peuvent être couverts avec des fonds immédiatement disponibles auprès de la banque de règlement. + +Lorsqu’il calcule si un transfert est couvert par la liquidité disponible, le Hub tient compte de toute restriction du montant de fonds disponibles fixée par le Net Debit Cap. + +## Position + +La Position d’un DFSP reflète l’ensemble des obligations non réglées de ce DFSP pour un modèle de règlement donné à un instant donné : autrement dit, le montant des fonds qu’un DFSP sera tenu de régler avec le schéma. La Position d’un DFSP pour un modèle de règlement donné est le net des éléments suivants : + +1. Tous les transferts complétés mais non réglés qui relèvent du modèle de règlement et pour lesquels le DFSP est le débiteur. +2. Tous les transferts complétés mais non réglés qui relèvent du modèle de règlement et pour lesquels le DFSP est le créancier. +3. Tous les transferts demandés mais pas encore complétés qui relèvent du modèle de règlement et pour lesquels le DFSP est le débiteur. + +Pour le DFSP payeur, ce total inclut les montants de transfert en attente et pas encore complétés. Notez qu’en cas d’abandon ou de délai d’attente dépassé, les transferts concernés ne se complètent pas et la réservation pour ce transfert est levée. + +La Position est la position totale sur l’ensemble des fenêtres de règlement qui n’ont pas encore été réglées. Le montant de la position d’un participant ne change que lorsque certains des transferts qui la composent sont réglés. + +## Positions nettes de règlement + +Comme indiqué ci-dessus, un règlement net différé peut être multilatéral ou bilatéral. Lorsqu’un administrateur du Hub demande un règlement, le Hub calcule combien chaque participant doit ou a droit de recevoir du fait des transactions à régler. Les transactions à régler sont définies comme toutes les transactions qui : + +- Relèvent de la ou des fenêtre(s) de règlement à régler. +- Relèvent du modèle de règlement en cours de règlement. + +Si le règlement est *multilatéral*, un DFSP ne reçoit qu’un seul montant pour ce qu’il doit ou a droit de recevoir du fait du règlement. Ce montant est le net de toutes les transactions à régler. + +Si le règlement est *bilatéral*, un DFSP peut recevoir plusieurs montants pour ce qu’il doit ou a droit de recevoir du fait du règlement. Chaque montant représente le net des transactions du DFSP avec un DFSP particulier. Le net de toutes ces valeurs sera égal au montant global qu’il devrait payer ou qu’il aurait droit de recevoir dans un règlement net multilatéral. + +## Rapports de règlement + +Pour faciliter le rapprochement des DFSP et le règlement à la banque de règlement, le Hub fournit divers rapports de règlement. Un schéma peut choisir d’avoir plusieurs rapports différents selon les usages. Voici quelques exemples : + +* Rapport de règlement du DFSP : rapport remis à un DFSP lorsque le règlement a été initié. Il indique la position de règlement bilatérale du DFSP avec chaque DFSP avec lequel il a opéré (en tant que DFSP payeur ou DFSP bénéficiaire) dans la ou les fenêtre(s) de règlement concernée(s). Il indique aussi la position nette de règlement multilatéral du DFSP (somme des montants de transferts envoyés et reçus par le DFSP dans la ou les fenêtre(s) de règlement). +* Rapport de la banque de règlement : rapport remis à la banque de règlement lorsque le règlement a été initié. Il indique la position de règlement bilatérale de chaque DFSP par rapport à tout autre DFSP ayant opéré dans la ou les fenêtre(s) de règlement concernée(s). Il indique aussi la position nette de règlement multilatéral de chaque DFSP (somme des montants de transferts envoyés et reçus par le DFSP). +* Rapport de résultat de règlement du DFSP : rapport remis à un DFSP lorsque le règlement est finalisé. Il détaille le solde du compte de liquidité du DFSP et les mouvements de fonds résultant de la clôture de la fenêtre de règlement. + +## Portail Finance + +Le [Portail Finance](busops-portal-introduction.md) (souvent désigné « Finance Portal v2 ») est un portail web utilisé par l’opérateur du Hub pour gérer au quotidien les processus liés au règlement. Le portail offre notamment les fonctionnalités suivantes : + +* consulter des informations telles que le solde, la [Position](#position), le [Net Debit Cap](#liquidity-management-net-debit-cap) des DFSP +* mettre à jour le [Net Debit Cap](#liquidity-management-net-debit-cap) d’un DFSP +* gérer les fenêtres de règlement + +* enregistrer les dépôts ou retraits sur les comptes de liquidité des DFSP + +::: tip NOTE +Le Portail Finance ne prend actuellement en charge que les processus de règlement fondés sur le modèle de règlement net différé. +::: diff --git a/docs/fr/adoption/HubOperations/Settlement/settlement-management-introduction.md b/docs/fr/adoption/HubOperations/Settlement/settlement-management-introduction.md new file mode 100644 index 000000000..ecffa5306 --- /dev/null +++ b/docs/fr/adoption/HubOperations/Settlement/settlement-management-introduction.md @@ -0,0 +1,7 @@ +# Introduction – Guide de gestion du Settlement + +Lorsqu’un paiement est effectué dans un système de paiements en temps réel comme Mojaloop, le DFSP qui est le détenteur du compte du bénéficiaire (le DFSP créancier) accepte de créditer le bénéficiaire des fonds immédiatement. Mais le DFSP créancier n’a pas encore reçu les fonds du DFSP qui est le détenteur du compte du débiteur : tout ce qui s’est produit jusqu’à présent, c’est que le DFSP débiteur a contracté une obligation de rembourser le DFSP créancier, et cette obligation a été enregistrée dans le Hub Mojaloop. + +Le processus de Settlement est le processus par lequel un DFSP débiteur rembourse un DFSP créancier pour les obligations que le DFSP débiteur a contractées du fait des transferts. + +Ce guide décrit comment le Settlement est géré par le Hub Mojaloop et la ou les banques partenaires de règlement, et présente les principaux blocs de construction du traitement du Settlement. diff --git a/docs/fr/adoption/HubOperations/TechOps/change-management.md b/docs/fr/adoption/HubOperations/TechOps/change-management.md new file mode 100644 index 000000000..951afbd5c --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/change-management.md @@ -0,0 +1,388 @@ +# Gestion des changements + +L'objectif du processus de gestion des changements est de contrôler le cycle de vie de tous les changements, permettant d'effectuer des modifications avec un minimum de perturbation des services informatiques. + +::: tip NOTE +Les processus décrits dans cette section représentent les bonnes pratiques et servent de recommandations pour les organisations remplissant un rôle d'opérateur du Hub. +::: + +## Objectifs + +Les objectifs de la gestion des changements sont de : + +* Répondre aux exigences métier changeantes tout en maximisant la valeur et en réduisant les incidents et les retravail +* Répondre aux demandes de changement (RFC) qui aligneront les services sur les besoins métier +* S'assurer que les changements sont enregistrés et évalués, et que les changements autorisés sont gérés de manière contrôlée +* Optimiser le risque métier global + +## Périmètre + +Le périmètre de la gestion des changements doit inclure les changements apportés à toutes les architectures, processus, outils, métriques et documentation, ainsi que les changements apportés à tous les éléments de configuration (CI) tout au long du cycle de vie du service. + +Tous les changements doivent être enregistrés et gérés dans un environnement contrôlé pour tous les CI. Il peut s'agir d'actifs physiques tels que des serveurs ou des réseaux, d'actifs virtuels tels que des serveurs virtuels ou du stockage, ou d'autres types d'actifs tels que des accords ou des contrats. + +La gestion des changements n'est pas responsable de la coordination de tous les processus de gestion des services pour assurer la mise en œuvre fluide des projets. + +## Rôles et responsabilités + +Les rôles énumérés ci-dessous indiquent certaines des parties prenantes essentielles nécessaires pour rendre le processus de gestion des changements efficace. + +### Responsable des changements + +Le responsable des changements agit en tant que chef de file, responsable du processus global de gestion des changements. + +Les principales responsabilités du responsable des changements sont : + +* Piloter l'efficience et l'efficacité du processus de gestion des changements +* Produire des informations de gestion +* Surveiller l'efficacité de la gestion des changements et formuler des recommandations d'amélioration +* Adhésion au processus de gestion des changements +* Planifier et gérer le support des outils et processus de gestion des changements +* Vérifier que les RFC sont correctement complétées et attribuées aux autorités de changement (le cas échéant) +* Communiquer les décisions des autorités de changement aux parties concernées +* Activités de surveillance et de révision +* Publier le calendrier des changements et les interruptions de service prévues +* Mener des revues post-implémentation pour valider les résultats des demandes de changement +* Déterminer la satisfaction métier concernant les demandes de changement + +### Coordinateur des changements + +Les coordinateurs des changements sont des membres du personnel de support qui gèrent les détails d'une demande de changement. + +Les responsabilités d'un coordinateur des changements comprennent : + +* Rassembler les informations appropriées en fonction du type de changement faisant l'objet d'une investigation +* Associer les éléments de configuration, incidents et services connexes à la demande de changement +* Fournir des mises à jour de statut aux demandeurs +* Examiner les plans et calendriers de changement. Les activités de planification comprennent la programmation de la demande de changement, l'évaluation des risques et de l'impact, la création de plans, la définition et le séquencement des tâches nécessaires à l'accomplissement de la demande de changement, et la planification des personnes et des ressources pour chaque tâche. +* Examiner toutes les tâches terminées. À l'étape de [mise en œuvre](#step-4-implement), au moins une tâche liée à la demande de changement est en cours. +* Mener des revues post-implémentation pour valider les résultats de la demande de changement +* Déterminer la satisfaction du demandeur concernant la demande de changement + +### Initiateur du changement + +Un initiateur du changement est une personne qui initie ou demande un changement, depuis un rôle métier ou technique. Différentes personnes peuvent initier un changement, ce rôle n'est pas exclusif à une seule personne. L'initiateur/demandeur du changement est tenu de fournir toutes les informations et justifications nécessaires pour le changement. + +Les autres responsabilités d'un initiateur du changement comprennent : + +* Compléter et soumettre une proposition de changement (si nécessaire) +* Compléter et soumettre une demande de changement (RFC) +* Assister aux réunions du comité consultatif des changements (CAB) pour fournir des informations complémentaires +* Examiner les changements lorsque cela est demandé par la gestion des changements + +### Exécutant du changement + +Il s'agit de la personne désignée comme propriétaire de la demande de changement tout au long du cycle de vie de la demande. La mise en œuvre d'un changement nécessite une approbation maker/checker, c'est-à-dire que tous les changements nécessitent une personne pour effectuer le changement et une autre pour le valider. + +Les responsabilités d'un exécutant du changement comprennent : + +* Assurer la liaison avec le demandeur du changement pour les questions et problèmes métier et techniques, le cas échéant +* Créer une RFC et mettre à jour son statut chaque fois que nécessaire +* Vérifier et décider d'une date de mise en œuvre, en s'assurant qu'elle n'entre pas en conflit avec d'autres activités, par exemple, les délais, les fenêtres de changement, etc. +* Évaluer et gérer les risques impliqués pendant le cycle de vie de la demande de changement +* Tester et mettre en œuvre le changement +* Coordonner et communiquer avec toute autre équipe impactée avant de soumettre le changement (en l'absence du coordinateur des changements) +* Une fois le changement approuvé, créer un cas de remédiation pour le changement programmé +* Exécuter le changement à la date et à l'heure programmées +* Fournir le statut de clôture après l'achèvement réussi +* Documenter la procédure de changement après sa mise en œuvre + +### Approbateur du changement + +Il s'agit d'une personne qui fournit l'approbation de premier niveau à une demande de changement avant qu'elle ne passe en revue au comité consultatif des changements. Les approbateurs des changements sont définis pour différents changements du Hub, ce qui signifie que ce rôle peut être occupé par différentes personnes à divers niveaux hiérarchiques du cadre de gestion des changements, chacune avec son propre domaine où elle agit en tant qu'approbateur. + +Les responsabilités d'un approbateur du changement comprennent : + +* Examiner toutes les RFC soumises par les initiateurs/demandeurs de changement +* S'assurer que la demande de changement a atteint le niveau de préparation nécessaire pour justifier une décision du responsable des changements et du CAB +* Examiner et commenter le contenu de l'enregistrement de changement, à savoir : plan de changement, mise en œuvre, plan de test et de remédiation, et calendrier +* Accorder l'approbation une fois satisfait que tous les critères pertinents ont été remplis et les préoccupations traitées OU rejeter l'approbation en donnant des préoccupations et réserves claires concernant le contenu de l'enregistrement de changement +* Le résultat des changements échoués lorsque le issue négative est le résultat d'une approbation indéterminée + +### Expert technique (SME) + +L'expert technique en la matière (SME) est une personne qui fait autorité dans un domaine ou sujet technique particulier. En relation avec la gestion des changements, le SME est responsable de : + +* Fournir les plans détaillés de mise en œuvre, de test et de remédiation +* Assister à la réunion du CAB pour répondre aux questions et préoccupations concernant le changement auprès des approbateurs et de la gestion des changements (si invité) +* La mise en œuvre des tâches de changement et la mise à jour des enregistrements pertinents dans l'outil de gestion des changements en ce qui concerne le statut de mise en œuvre +* Examiner et retravailler un changement comme demandé, et contribuer à la revue d'un changement post-implémentation + +### Membre du CAB + +Le comité consultatif des changements (CAB) implique des membres de différents domaines, y compris la sécurité de l'information, les opérations, le développement, les réseaux, le Service Desk et les relations commerciales, entre autres. Un membre du CAB a les responsabilités suivantes : + +* Diffuser les RFC dans son domaine de responsabilité et coordonner les retours +* Examiner les RFC et recommander si elles doivent être autorisées +* Examiner les changements réussis, échoués et non autorisés +* Examiner le calendrier des changements et les interruptions de service prévues + +### Président du CAB + +Le président du CAB est responsable de : + +* Convoquer et présider les réunions du CAB +* Superviser le processus global de gestion des changements +* S'assurer que le CAB remplit la charte sur les politiques et procédures relatives aux changements + +## Types de changements + +Le processus de gestion des changements traite les types de changements suivants. + +### Changements standard + +Un changement standard est un changement apporté à un service ou à un autre élément de configuration qui a été préautorisé et n'a donc pas besoin de passer par le processus d'approbation. Pour être considéré comme candidat à devenir un changement standard, au moins trois changements mineurs réussis doivent avoir été mis en œuvre. Une demande de changement standard doit ensuite être soumise au comité consultatif des changements pour approbation. + +Le risque d'un changement standard doit être faible et bien compris, les tâches doivent être bien connues, documentées et éprouvées, et il doit y avoir un déclencheur défini pour l'initier, tel qu'un événement ou une demande de service. + +Exemples de changements standard : mise à niveau du système d'exploitation (OS), déploiement de correctifs, etc. + +### Changements mineurs + +Un changement mineur est un changement non trivial qui a un impact faible et un risque faible. Ce sont des changements non triviaux qui ne se produisent pas fréquemment mais qui passent néanmoins par chaque étape du cycle de vie du changement, y compris l'approbation du CAB. Il est important de documenter les informations pertinentes pour référence future. Au fil du temps, un changement mineur peut être converti en changement standard. + +Exemples de changements mineurs : modifications de site web, améliorations de performance. + +Pour qu'un changement soit classé comme changement mineur, il doit avoir un délai de préparation inférieur à 3 jours. + +### Changements majeurs + +Un changement majeur est un changement à haut risque et à fort impact qui pourrait interrompre les environnements de production en direct s'il n'est pas correctement planifié. L'évaluation du changement est cruciale pour déterminer le calendrier et le flux d'approbation. Un changement majeur nécessite l'approbation de la direction en plus de l'approbation du CAB. La demande de changement (RFC) d'un changement majeur doit contenir une proposition détaillée sur l'analyse coût-bénéfice, l'analyse risque-impact et les implications financières, le cas échéant. + +En pratique, tous les changements qui impliquent un temps d'arrêt, en particulier un temps d'arrêt qui affecte l'onboarding des DFSP et les activités de test sur les environnements non productifs, doivent être classés comme changements majeurs et doivent être examinés par le CAB. Ces changements doivent être mis en œuvre en coordination avec le chef de projet technique. + +Pour qu'un changement soit classé comme changement majeur, il doit avoir un délai de préparation de 5 jours ou plus. + +### Changements d'urgence + +Un changement d'urgence est un changement qui doit être effectué dès que possible. Un changement d'urgence ne sera accepté que s'il est lié à un incident de sévérité 1, qui a un ticket S1 correspondant dans l'outil Service Desk. Le responsable de service initie l'ouverture d'un changement d'urgence et demandera à l'expert technique de le créer. + +### Résumé des délais de préparation et matrice d'approbation + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type de changementDélai de mise en œuvreRevue et approbation

Changement standard

3 jours ouvrés

Pré-approuvé

Changement mineur

3 jours ouvrés

    +
  1. CAB

  2. +
  3. Approbateurs métier (le cas échéant)

  4. +

Changement majeur

5 jours ouvrés

    +
  1. CAB

  2. +
  3. Approbateurs métier (le cas échéant)

  4. +

Changement d'urgence

Dès que possible

CAB d'urgence ou propriétaire métier

+ +## Comité consultatif des changements + +Le comité consultatif des changements (CAB) soutient la gestion des changements dans l'évaluation, la priorisation et la programmation des changements. Le CAB doit avoir une visibilité complète sur tous les changements qui pourraient présenter un risque modéré ou plus élevé pour les services et les éléments de configuration. Il est important qu'au sein du CAB, il y ait des membres qui peuvent fournir une expertise adéquate pour évaluer tous les changements tant du point de vue métier que technique. + +Il y a des membres permanents du CAB qui sont invités à toutes les réunions, mais pour s'assurer qu'il y a une compréhension claire de tous les besoins des parties prenantes, d'autres personnes seront invitées à participer en raison de leur expertise pour un changement qui doit être discuté. Le cas échéant, le fournisseur externe peut également être invité. + +### Réunion du CAB + +La réunion du CAB peut se tenir en personne ou par voie électronique. Il peut être plus pratique de tenir des réunions électroniques, cependant il peut être plus difficile de traiter les questions de cette façon. Ce sera la responsabilité du président du CAB de décider en fonction de la situation. Il est prévu que les réunions du CAB soient électroniques en raison des contraintes de délais. + +Une réunion du CAB est une réunion formelle avec une structure désignée. Avant toute réunion du CAB, les changements à discuter doivent être distribués à tous les membres. Le président du CAB est responsable de s'assurer que cela est effectué, mais peut déléguer la tâche au co-président du CAB ou à tout membre du CAB. + +Tous les représentants des changements doivent assister ou envoyer un délégué. En cas d'absence, le changement ne sera pas discuté et donc pas approuvé. Tous les participants au CAB doivent venir à la réunion préparés à discuter des changements qu'ils représentent et à exprimer des opinions et avis basés sur le domaine particulier qu'ils représentent. + +La réunion du CAB est le forum pour discuter des changements précédents, réussis et échoués, et examiner les leçons apprises. + +Un ordre du jour pour la réunion du CAB doit être distribué avant la réunion. Le président du CAB est responsable de s'assurer que la structure est respectée, que les procès-verbaux sont pris et que les points d'action sont rassemblés pour être distribués après la réunion. + +## Processus de gestion des changements + +Cette section fournit un résumé des activités clés du processus de gestion des changements. Des instructions spécifiques sur la façon d'effectuer les activités du processus dans le contexte d'un service ou d'une fonction peuvent être fournies par des procédures opérationnelles locales dans un manuel de procédures. + +Tous les changements doivent être créés dans l'outil Service Desk. + +La figure suivante fournit un résumé de haut niveau du processus de gestion des changements avec les activités clés : + +![Résumé de haut niveau des activités du processus de gestion des changements](../../../../.vuepress/public/change_mgmt_flow.png) + +### Étape 1 : Créer une demande de changement (RFC) + +#### Objectif + +L'objectif de cette activité est de s'assurer que les types de demandes de changement sont respectés afin que le processus puisse répondre et gérer l'environnement tout en protégeant l'activité. + +La figure suivante fournit un résumé de la première étape du processus de gestion des changements. + +![Processus de gestion des changements – Initier un changement en créant une RFC](../../../../.vuepress/public/raise_rfc.png) + +#### Prérequis + +Les prérequis pour les changements doivent être alignés sur les exigences des releases telles que décrites dans le [processus de gestion des versions](release-management.md). Les éléments suivants doivent être clairement capturés dans l'outil Service Desk lors de la préparation de l'enregistrement de changement : + +* Transfert de l'équipe concernée à l'équipe des opérations, y compris une revue complète des éléments suivants : + * Ticket de changement ou Enregistrement de changement : Raison du changement incluant l'impact, les risques, les limitations. La matrice de catégorisation du changement peut être la même que celle des incidents. Pour les détails sur la matrice de catégorisation des incidents, voir [Matrice de catégorisation des incidents](incident-management.md#incident-categorization-matrix). + * Runbook de changement : Étapes requises pour effectuer le changement et annuler le changement si nécessaire + * Résultats de tests de l'environnement inférieur : Preuve que le changement a été testé avec succès et ne cause pas de régression + * Plan de test pour l'environnement supérieur : Quels tests spécifiques doivent être exécutés pour valider le changement + * Toute la documentation connexe, y compris l'architecture, les diagrammes de flux, les informations de configuration/paramétrage, etc., a été mise à jour +* Tests pré-changement : Vérifier la stabilité de l'environnement en examinant les derniers résultats des tests du Golden Path (GP) +* Tests post-changement : Exécution des tests convenus pour valider le changement, et exécution des tests GP complets pour confirmer l'absence de régression sur l'environnement + +#### Entrées + +Les entrées de la RFC sont : + +* Demandes de service +* Demandes de la [gestion des incidents](incident-management.md) pour appliquer des solutions de contournement/correctifs +* Demandes de la [gestion des incidents](incident-management.md) pour effectuer des changements d'urgence afin de résoudre les incidents de sévérité 1 +* Demandes de nouvelles fonctionnalités du bureau de gestion de projet +* Demandes de maintenance pour changement + +#### Sorties + +Enregistrements de changement contenant les détails des RFC pour examen. + +### Étape 2 : Examiner et autoriser + +#### Objectif + +Les changements sont examinés, et une étape d'approbation technique détermine si les informations minimales obligatoires requises sont capturées pour permettre une phase de planification et de programmation efficace. + +La figure suivante fournit un résumé de l'étape « examiner et autoriser » du processus de gestion des changements. + +![Processus de gestion des changements – Examiner et autoriser](../../../../.vuepress/public/review_authorize.png) + +#### Entrées + +Enregistrement de changement pour examen. + +#### Sorties + +Enregistrement de changement avec approbation technique. + +### Étape 3 : Planifier et approuver + +#### Objectif + +Les enregistrements de changement qualifiés qui ont passé une évaluation initiale dans les étapes précédentes du processus sont planifiés et approuvés. Le niveau de risque du changement orientera le chemin d'approbation. + +La figure suivante fournit un résumé de l'étape « planifier et approuver » du processus de gestion des changements. + +![Processus de gestion des changements – Planifier et approuver](../../../../.vuepress/public/plan_approve.png) + +#### Entrées + +Enregistrement de changement initialement autorisé. + +#### Sorties + +Enregistrement de changement entièrement planifié et approuvé. + +### Étape 4 : Mettre en œuvre + +#### Objectif + +Les experts techniques concernés exécutent les activités planifiées, enregistrent tout écart et entreprennent des activités de remédiation le cas échéant, conformément aux plans de changement, pour mettre en œuvre les changements demandés. + +La figure suivante fournit un résumé de l'étape « mettre en œuvre » du processus de gestion des changements. + +![Processus de gestion des changements – Mettre en œuvre](../../../../.vuepress/public/implement.png) + +#### Entrées + +Enregistrement de changement approuvé. + +#### Sorties + +Changement mis en œuvre, changement échoué, changement annulé, changement échoué remédié. + +### Étape 5 : Clôturer + +L'activité finale du processus garantit que les changements soumis à une revue post-implémentation reçoivent l'attention nécessaire et que les activités de remédiation sont comprises et exécutées. + +La figure suivante fournit un résumé de l'étape « clôturer » du processus de gestion des changements. + +![Processus de gestion des changements – Clôturer](../../../../.vuepress/public/close.png) + +#### Entrées + +Changements réussis, changements échoués, changements échoués avec remédiation. + +#### Sorties + +Changements clôturés. + +## Gouvernance + +**Nom de la réunion :** Réunion du comité consultatif des changements + +**Fréquence de la réunion :** Hebdomadaire + +**Objectif de la réunion :** + +* Examiner et approuver/rejeter les changements proposés dans un contexte métier et technique +* Prioriser les changements proposés selon les besoins métier +* Effectuer une revue post-implémentation des changements terminés et déterminer/documenter les leçons apprises +* Examiner les changements précédemment approuvés mais non mis en œuvre dans la fenêtre de changement précédente et recommander des actions de suivi + +**Président de la réunion (rôle dans le processus) :** Président du CAB + +**Participants recommandés (rôles dans le processus) :** + +* Membres permanents du CAB +* Représentants métier +* Initiateur/exécutant du changement + +**Entrées :** + +* Calendrier des changements +* Enregistrement de changement + +**Sorties :** + +* Approbation/rejet +* Enregistrements de changement mis à jour +* Points d'action + +### Gouvernance pour la communication des changements + +Les directives suivantes s'appliquent à la communication des changements : + +* Les changements standard doivent être communiqués aux parties prenantes internes. +* Les changements majeurs, mineurs et d'urgence doivent être communiqués à toutes les parties prenantes métier et techniques concernées. +* Les changements doivent être communiqués après les approbations du CAB. +* Au début de la fenêtre de changement approuvée, une mise à jour par courriel et une notification Slack (ou similaire) devraient être envoyées aux parties prenantes concernées. +* À la fin de la fenêtre de changement approuvée, une mise à jour par courriel et une notification Slack (ou similaire) devraient être envoyées aux parties prenantes concernées. +* La communication externe aux clients (DFSP) et aux partenaires du Hub sera effectuée par le responsable de service. + +La notification doit inclure les détails suivants : + +* Titre et description du changement +* Impact sur l'activité +* Fenêtre de changement +* Contacts/Coordinateur des changements diff --git a/docs/fr/adoption/HubOperations/TechOps/defect-triage.md b/docs/fr/adoption/HubOperations/TechOps/defect-triage.md new file mode 100644 index 000000000..5c26cc54a --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/defect-triage.md @@ -0,0 +1,93 @@ +# Triage des défauts + +L'objectif du processus de triage des défauts est de garantir que tous les bogues identifiés dans l'environnement de production de l'opérateur du Hub sont capturés, évalués et soumis à une équipe de support Mojaloop, une équipe dédiée à l'exécution des services de support pour les opérations techniques d'un Hub Mojaloop. Cette équipe peut être internalisée ou externalisée (ou même partiellement internalisée et partiellement externalisée), selon le niveau d'expertise ou de capacité au sein de l'organisation d'hébergement du schéma. S'il est décidé d'externaliser cette fonction, il existe des organisations au sein de la communauté Mojaloop qui fournissent différents niveaux de support en tant que service. (Pour plus d'informations et des recommandations, contactez la Fondation Mojaloop.) + +::: tip NOTE +Les processus décrits dans cette section représentent les bonnes pratiques et servent de recommandations pour les organisations remplissant un rôle d'opérateur du Hub. +::: + +::: tip NOTE +Le processus proposé ici s'applique aux bogues identifiés dans l'environnement de production de l'opérateur du Hub, et les nouvelles fonctionnalités ou améliorations sont hors de son périmètre. Cependant, pour faciliter les conversations commerciales, les opérateurs du Hub peuvent soumettre des demandes de nouvelles fonctionnalités ou d'améliorations, et celles-ci seront transmises aux équipes produit de la communauté. +::: + +Il doit y avoir une équipe spécifique responsable de l'évaluation et de la planification de la résolution de chaque bogue signalé dans les différents environnements (Production, Recette, QA, Développement, etc.). Il peut s'agir d'une équipe de support ou d'une équipe QA/Développement. Dans le reste de cette section, cette équipe est appelée « équipe de triage du support Mojaloop ». + +L'équipe de triage est composée des membres suivants : + +* Chef de produit Mojaloop (Mojaloop principal) +* Chef de produit des extensions ou autres composants implémentés dans le Hub - Payment Manager, PortX, etc. +* Expert technique du Hub (livraison produit, c'est-à-dire développement et QA) +* Représentant des opérations (opérations techniques et infrastructure) + +## Bogues identifiés dans un environnement de production de l'opérateur du Hub + +*Étapes de l'opérateur du Hub :* + +1. Un ticket d'incident est créé dans l'outil [Service Desk](key-terms-kpis.md#key-terms) de l'opérateur du Hub par un ingénieur de support L1 du Hub, conformément au [processus de gestion des incidents](incident-management.md). +1. Le ticket est escaladé vers l'équipe L2/L3 du Hub pour une investigation et une analyse approfondies, selon les besoins. +1. L'équipe L2/L3 du Hub évalue si le comportement est un nouveau bogue ou un problème connu, et si un ticket/enregistrement de bogue existe déjà. S'il s'agit d'un bogue connu et qu'un ticket de support Mojaloop existe déjà, alors l'ingénieur L1 doit mettre à jour le ticket existant avec les nouveaux détails et informations, et la priorité et l'impact/sévérité (niveau d'impact sur le Hub ou ses utilisateurs) peuvent être ajustés en conséquence. L'ingénieur L1 doit communiquer cela au rapporteur/client DFSP (comme mentionné au point 6). Les nouveaux bogues suivront le reste du processus ci-dessous. +1. L'équipe L2/L3 du Hub confirme que le problème de production peut être reproduit dans les environnements non productifs exécutant la même version que l'environnement de production (PRD). C'est-à-dire que le bogue n'est pas une erreur utilisateur ou un problème environnemental. +1. L'équipe L3 du Hub peut escalader vers le responsable des opérations techniques du Hub et signaler le bogue via l'outil Service Desk du support Mojaloop, en ajoutant tous les détails de leur analyse (y compris les étapes claires pour reproduire le bogue, le comportement attendu, le comportement réel et tous les fichiers journaux et détails des investigations L2/L3), en plus de l'identifiant du ticket d'incident créé à l'étape 1 pour un suivi facile. +1. Réponse/accusé de réception/communication est renvoyée au client DFSP dans les délais convenus. + +*Étapes de l'équipe de support Mojaloop :* + +1. L'équipe de support Mojaloop examine, attribue un membre de l'équipe comme propriétaire et accuse réception du bogue. +1. Suite à un examen initial du problème soulevé, le membre de l'équipe de support Mojaloop transmet le problème à l'équipe de triage pour une évaluation plus approfondie. \ +L'examen du ticket est effectué pour a) établir une bonne compréhension du problème soulevé, y compris le niveau de sévérité et la priorité définis par l'opérateur du Hub ; b) confirmer l'exhaustivité des informations fournies, y compris les fichiers journaux, la description claire, les étapes de reproduction, les captures d'écran, etc. +1. L'équipe de triage évalue le bogue : les améliorations/demandes de nouvelles fonctionnalités sont transmises aux équipes produit de la communauté. L'impact opérationnel, la sévérité et la priorité sont examinés et la résolution du bogue est attribuée au chef de produit concerné. Pour les détails sur la priorisation, voir [Priorisation des bogues](#prioritization-of-bugs). +1. Le chef de produit clone le bogue dans le backlog produit de son équipe de livraison produit, ce qui lie les deux problèmes pour référence et suivi de la progression. Le chef de produit examine et définit également la priorité par rapport aux autres éléments de son backlog produit. +1. L'ingénieur de support Mojaloop assigné au ticket de bogue du support Mojaloop surveille le ticket cloné et gère toute la communication entre le chef de produit et l'opérateur du Hub sur la progression des bogues, y compris le partage de toute mesure corrective (par exemple, solutions de contournement ou façons alternatives d'utiliser la fonctionnalité affectée). Chaque mise à jour ultérieure de l'équipe de livraison produit doit également être partagée dans le ticket de bogue du Product Manager pour la visibilité de l'opérateur du Hub. Le chef de produit assigné doit rester le propriétaire du ticket de bogue du Product Manager jusqu'à ce que le bogue soit résolu. +1. Le chef de produit communique le plan de résolution et les délais à l'équipe de support via le ticket de bogue original du chef de produit. Le plan de résolution est ensuite communiqué à l'opérateur du Hub. \ +\ +Pour les détails sur ce qui se passe si l'opérateur du Hub n'est pas d'accord avec la priorisation et le plan de résolution proposés, voir [Processus d'escalade](#escalation-process). +1. Le bogue est résolu suivant le processus de développement standard de l'équipe de livraison produit assignée et est inclus dans une version, qui sera mise à disposition de l'opérateur du Hub ou peut être proposée comme une version ad hoc (correctif), si nécessaire. +1. Le ticket de support Mojaloop est clôturé une fois que la version de correction du bogue est déployée et validée dans l'environnement de l'opérateur du Hub. + +## Bogues identifiés pendant la fenêtre de déploiement/changement dans l'environnement du Hub + +Les déploiements dans les environnements du Hub sont de la responsabilité de l'équipe de l'opérateur du Hub, et les bogues identifiés pendant le déploiement doivent être signalés via le processus standard (c'est-à-dire qu'un ticket est créé conformément au processus de gestion des incidents du Hub, puis escaladé vers l'équipe de support Mojaloop si nécessaire). De plus : + +* L'équipe du Hub évaluera si le comportement est un problème connu ou un nouveau défaut. Pour les problèmes connus, la mise en production doit se poursuivre et être complétée comme prévu, le bogue connu étant signalé dans le rapport post-déploiement. +* Pour les nouveaux défauts identifiés, la mise en production/le changement peut faire l'objet d'un rollback en fonction de la sévérité. Cette décision peut être prise par l'équipe de déploiement. En cas de rollback, les tests de régression doivent être exécutés pour confirmer que la version précédente fonctionnelle est stable dans l'environnement, et le bogue est signalé dans le rapport post-déploiement. +* Le bogue est capturé via l'outil Service Desk du support Mojaloop et sera traité via le processus décrit ci-dessus. + +## Processus d'escalade + +S'il y a une divergence entre la priorité attribuée ou les attentes du client (opérateur du Hub) et le plan de résolution fourni par l'équipe de support Mojaloop, la [matrice d'escalade de la gestion des incidents](incident-management-escalation-matrix.md) régit la suite des événements. En conséquence, l'incident sera défini comme priorité P1 ou tout autre type de priorité inférieure et les parties prenantes seront informées. + +Le chef d'équipe du support Mojaloop et le Program Manager de l'opérateur du Hub doivent être informés immédiatement. Le Program Manager de l'opérateur du Hub est un responsable au sein de l'organisation du Hub qui est chargé de traduire les besoins commerciaux du schéma en directives d'opérations techniques. + +## Propriété et responsabilité + +Le créateur du ticket Service Desk (l'ingénieur de support de l'opérateur du Hub) reste le propriétaire jusqu'à ce que le ticket soit résolu. + +La priorité et la sévérité doivent être alignées, discutées et négociées entre l'équipe de triage du support Mojaloop et l'équipe des opérations de l'opérateur du Hub. + +Les informations issues des discussions de triage et de l'équipe de livraison produit doivent être partagées dans le ticket Service Desk par l'ingénieur de support Mojaloop. + +Le chef de produit à qui le bogue est assigné doit s'assurer que le référencement croisé et le suivi sont en place pour garantir le flux d'informations requises ou produites par l'évaluation de l'équipe de livraison produit. + +Le chef de produit à qui le bogue est assigné doit déterminer et communiquer le plan de résolution à l'équipe/ingénieur de support Mojaloop, via le ticket uniquement. + +### Priorisation des bogues + +La priorisation des bogues est de la responsabilité des experts en la matière (SME) de l'équipe de triage du support Mojaloop. + +Tous les bogues sont évalués en fonction du comportement attendu du système et du comportement réel observé (et reproduit). L'impact opérationnel et l'urgence du bogue doivent être capturés par l'équipe des opérations de l'opérateur du Hub afin que cela soit pris en compte par l'équipe de triage dans la priorisation. + +Chaque bogue est évalué par rapport à la feuille de route et au backlog du produit. + +Les demandes de nouvelles fonctionnalités ou d'améliorations sont acheminées vers l'équipe produit et ne sont pas traitées par ce processus. Cela est communiqué au demandeur via l'équipe des opérations. + +::: tip +La priorité est l'ordre dans lequel le bogue sera corrigé. Plus la priorité est élevée, plus le bogue sera résolu rapidement. \ +\ +La sévérité est le niveau d'impact sur le Hub ou sur ses utilisateurs. \ +\ +Ces deux facteurs fonctionnent de concert. Par exemple, un bogue cosmétique comme une faute de frappe sur une page web sera probablement classé comme de faible sévérité mais pourrait être une correction rapide et facile et classé comme de haute priorité. Il est donc important de définir ces valeurs avec le soin nécessaire. +::: + +## Diagramme de flux du processus + + diff --git a/docs/fr/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md b/docs/fr/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md new file mode 100644 index 000000000..e7d12a74e --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/incident-management-escalation-matrix.md @@ -0,0 +1,51 @@ +# Annexe A : Matrice d'escalade de la gestion des incidents + +Cette section fournit des informations sur les rôles clés à contacter lorsqu'un incident survient. + +::: tip NOTE +La matrice d'escalade de la gestion des incidents fournie ci-dessous sert uniquement d'exemple. Les noms réels des rôles peuvent être différents dans votre organisation. +::: + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Chaîne de support pour les incidents
Nom de l'équipeResponsable NEscalade N+1Escalade N+2

Support client niveau 1

Chef d'équipe support opérationnel L1/L2

Responsable de service

Responsable des opérations techniques

Support client niveau 2

Responsable de service

Responsable des opérations techniques

Propriétaire produit du Hub / Responsable de programme

Support client niveau 3

Responsable de service

Responsable des opérations techniques

Propriétaire produit du Hub / Responsable de programme

Support client niveau 4

Responsable de service

Responsable des opérations techniques

Propriétaire produit du Hub / Responsable de programme

diff --git a/docs/fr/adoption/HubOperations/TechOps/incident-management.md b/docs/fr/adoption/HubOperations/TechOps/incident-management.md new file mode 100644 index 000000000..3d429f68b --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/incident-management.md @@ -0,0 +1,695 @@ +# Gestion des incidents + +L'objectif principal de la gestion des incidents est de restaurer le fonctionnement normal du service aussi rapidement que possible et de minimiser l'impact sur les opérations métier, garantissant ainsi que les meilleurs niveaux possibles de qualité et de disponibilité de service sont maintenus. Le « fonctionnement normal du service » est défini ici comme le fonctionnement du service dans le cadre des [accords de niveau de service (SLA)](service-level-agreements.md). + +Cela est réalisé grâce à un processus de gestion des incidents robuste et bien aligné, guidé par un système de Service Desk qui aide à capturer tous les problèmes et à suivre le délai de traitement (TAT) depuis le moment où un problème est signalé jusqu'au moment de la résolution et de la clôture. + +Le processus de gestion des incidents implique la détection d'un incident, son enregistrement avec toutes les informations appropriées, l'analyse du problème, la correction des défauts et la restauration du service conformément au TAT stipulé. + +Cette section rassemble les principaux processus, concepts et principes relatifs à la gestion des incidents. + +::: tip NOTE +Les processus décrits dans cette section représentent les bonnes pratiques et servent de recommandations pour les organisations remplissant un rôle d'opérateur du Hub. +::: + +::: tip NOTE +Tout au long de cette section, les termes « client », « consommateur », « utilisateur final » et « utilisateur » désignent tous un employé de DFSP. Lorsque ces mots sont utilisés dans un autre sens, la signification du mot est précisée et expliquée en détail. +::: + +## La gestion des incidents en une seule image + +La figure suivante définit le flux de processus et les concepts clés de la gestion des incidents en une seule image. + + + + + +## Limites du processus + +Le processus de gestion des incidents commence lorsque : + +* un incident est déclenché par un appel téléphonique/courriel/interaction avec le Service Desk de la part des utilisateurs ou des clients +* un incident est découvert par le biais d'un processus ou d'un outil interne, par exemple, il y a une alerte d'événement provenant de l'un des outils d'alerte ou des systèmes de surveillance +* le personnel de support à tous les niveaux (ingénieurs de support L1, L2, L3) ou le responsable de service signale directement un incident + +Le processus de gestion des incidents se termine : + +* pour le client : lorsque le statut du ticket dans l'outil Service Desk est changé en « Clôturé » +* pour l'équipe du Service Desk : lorsque l'incident est résolu et que la validation de clôture est envoyée au client + +Les limites de la gestion des incidents stipulent que le processus prend en compte les prérequis suivants : + +* Un accord de niveau de service (SLA) entre la communauté (par exemple, Mojaloop), les sociétés mères (par exemple, le Hub) et les fournisseurs de services financiers numériques (DFSP) est en place. +* Un SLA entre le partenaire d'implémentation (le Hub) et les fournisseurs de logiciels tiers (par exemple, Microsoft, Oracle, etc.) est en place. +* Il existe un accord de niveau opérationnel (OLA) existant. Cet accord décrit les responsabilités de chaque groupe de support interne envers les autres groupes de support, y compris le processus et le délai de livraison de leurs services. + +## Gestion des incidents étape par étape + +Cette section fournit une description détaillée du processus de gestion des incidents. Tous les incidents signalés passent par les étapes principales suivantes. + +### Étape 1 : Signaler et enregistrer l'incident, la demande de changement ou la question + +Les problèmes, demandes de changement ou questions peuvent être signalés et enregistrés via l'outil Service Desk dès qu'ils surviennent. L'outil Service Desk est le canal principal pour recevoir les requêtes liées aux incidents. Les courriels, appels téléphoniques et messagerie instantanée peuvent être utilisés comme canaux secondaires. + +Le statut des tickets tels que capturés dans le système Service Desk peut prendre les valeurs suivantes : + +* **En cours** : Un incident qui a été reçu via le Service Desk et assigné à un ingénieur de support. Les efforts de résolution ont commencé. +* **Escaladé** : Un incident qui a été escaladé vers toute partie extérieure à l'équipe des opérations, y compris l'équipe de livraison produit ou les fournisseurs de services externes L4. +* **En attente** : Un incident qui a été temporairement mis en attente ou en attente de retour de l'utilisateur ou d'un autre ticket qui doit être résolu avant que ce ticket puisse être résolu. \ +\ +Gardant à l'esprit que l'utilisation du statut « En attente » arrête le chronomètre SLA, la seule raison qui justifie l'utilisation de « En attente » est lorsqu'une action du client est requise. Il doit s'agir d'une action qui est de la responsabilité du client/consommateur ou de son fournisseur et qui est un prérequis à la continuation du processus ; par exemple, demander des informations essentielles ou l'approbation pour résoudre la demande. Les tickets de sévérité 1 et 2 ne doivent pas être mis au statut « En attente ». La restauration d'un service ou d'une fonction d'un service dépend rarement de l'action du client. La seule exception est lorsque le client arrête l'investigation ou la mise en œuvre d'une solution ou refuse une approbation nécessaire. Dans tous les cas, la décision du client doit être documentée. +* **Annulé** : Un incident qui a été annulé. Un incident ne peut être annulé que lorsque le client en fait la demande. +* **Résolu** : Un incident qui a été traité par un ingénieur de support et a été corrigé, et une alerte a été déclenchée à l'utilisateur pour réouvrir si non satisfait. +* **Clôturé** : Un incident qui a été clôturé une fois que la résolution a été reconnue par l'utilisateur final. + +Toutes les informations pertinentes relatives aux incidents doivent être enregistrées afin qu'un historique complet soit maintenu. En maintenant des enregistrements d'incidents précis et complets, le personnel des groupes de support assignés est mieux en mesure de résoudre les incidents enregistrés. + +### Étape 2 : Catégoriser et prioriser + +L'utilisateur final/demandeur se voit attribuer un numéro de ticket pour référence et facilité d'accès lorsque le problème est reconnu et pris en charge par l'équipe de support. Le ticket doit être visible par le demandeur (l'employé DFSP qui a soulevé le problème) à tous les niveaux de support. + +Le demandeur sera automatiquement notifié par courriel de tout changement, mise à jour de statut, demande d'informations supplémentaires, disponibilité pour test ou résolution finale concernant le ticket. + +Nous classifions généralement les demandes de support en : + +* Incident +* Demande de service +* Demande de changement ou Request for Change (RFC, tels que fonctionnalités, améliorations) + +Les incidents sont catégorisés et sous-catégorisés en fonction du service informatique ou du domaine métier pour lequel l'incident cause une perturbation. + +Voici quelques exemples de catégories de service : + +* Infrastructure +* Mojaloop +* Sécurité +* Settlement +* Onboarding + +La sévérité d'un incident peut être déterminée à l'aide d'une [matrice de catégorisation](#incident-categorization-matrix). En fonction de leur sévérité, les incidents peuvent être catégorisés comme : + +* Critique = S1 +* Grave = S2 +* Moyenne = S3 +* Mineur = S4 + +Une fois l'incident catégorisé, il est automatiquement acheminé vers un ingénieur de support L1 possédant l'expertise pertinente. + +### Étape 3 : Investiguer et résoudre + +La ressource de support assignée sera chargée d'investiguer le problème, ainsi que de préparer l'enregistrement de l'incident et de communiquer avec le client sur la façon de résoudre le problème. + +L'investigation d'un incident peut inclure l'une des actions suivantes : + +* Collecte et analyse d'informations +* Recherche, y compris la reproduction du problème +* Acquisition d'informations supplémentaires auprès d'autres sources + +La résolution d'un incident peut inclure l'une des actions suivantes : + +* Fournir une résolution ou des étapes vers une résolution +* Modifications de configuration + +En fonction de la complexité de l'incident, il peut être nécessaire de le décomposer en sous-tâches ou tâches. Les tâches sont généralement créées lorsque la résolution d'un incident nécessite la contribution de plusieurs techniciens de différents départements. + +Pendant le traitement de l'incident, l'ingénieur de support doit s'assurer que l'accord de niveau de service n'est pas violé. Un SLA est le délai acceptable dans lequel un incident nécessite une réponse (SLA de réponse) ou une résolution (SLA de résolution). Les SLA peuvent être attribués aux incidents en fonction de leurs paramètres comme la catégorie de service, le demandeur, l'impact, l'urgence, etc. Dans les cas où un SLA est sur le point d'être violé ou a déjà été violé, l'incident peut être escaladé fonctionnellement ou hiérarchiquement pour garantir qu'il soit résolu au plus tôt. + +Un incident est considéré comme résolu lorsque l'équipe de support L1/L2/L3 a trouvé une solution de contournement temporaire ou une solution permanente au problème. Les solutions de contournement peuvent être : + +* des instructions fournies au client sur la façon d'accomplir son travail en utilisant une méthode alternative +* des correctifs temporaires qui aident un système à fonctionner comme prévu mais qui ne résolvent pas le problème de manière permanente + +Les solutions de contournement doivent être documentées et communiquées au Service Desk afin qu'elles puissent être ajoutées à la base de connaissances. (Il est recommandé de maintenir un référentiel d'articles de base de connaissances, décrivant la solution de contournement ou les étapes de résolution des incidents survenus par le passé.) Cela garantira que les solutions de contournement sont accessibles au Service Desk pour faciliter la résolution lors de récurrences futures de l'incident. + +### Étape 4 : Escalader + +L'escalade d'un incident est la reconnaissance qu'il existe la possibilité qu'un incident dépasse les délais de résolution convenus à chaque niveau de support. Une gestion claire de l'escalade permet à l'équipe de support d'identifier, de suivre, de surveiller et de gérer les situations nécessitant une sensibilisation accrue et une action rapide. + +Il existe deux types d'escalade : + +* **Escalade fonctionnelle** : Ce type d'escalade intervient lorsqu'une équipe de niveau de support (par exemple, L1) est incapable de résoudre le problème ou de respecter le délai convenu (ce qui signifie que le temps ciblé pour la résolution est dépassé). Par conséquent, le cas est proactivement assigné au niveau de service suivant (par exemple, L2). +* **Escalade hiérarchique** : Ce type d'escalade sert de moyen pour informer toutes les parties impliquées, de manière proactive, d'une violation potentielle du SLA. Cela aide à apporter de l'ordre, de la structure, de la responsabilité, de l'appropriation, une gestion ciblée et une mobilisation des ressources dans le but de fournir des services efficaces et efficients. + +### Étape 5 : Clôturer l'incident + +Un incident peut être clôturé une fois que le problème est résolu et que l'utilisateur reconnaît la résolution et en est satisfait. + +## Matrice de catégorisation des incidents + +L'une des étapes les plus importantes de la gestion des incidents est la catégorisation des incidents. Cela aide non seulement à trier les tickets entrants, mais garantit également que les tickets sont acheminés vers les ingénieurs de support les plus qualifiés pour traiter le problème. La catégorisation des incidents aide également le système de Service Desk à appliquer les SLA les plus appropriés aux incidents et à communiquer ces priorités aux utilisateurs finaux. Une fois qu'un incident est catégorisé, les ingénieurs de support peuvent diagnostiquer l'incident et fournir à l'utilisateur final une résolution. + +Le tableau suivant fournit des orientations sur la façon de classifier la sévérité d'un incident. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrice de catégorisation des incidents
Code de sévéritéCritères

Sévérité 1

    +
  • Impact étendu sur l'activité, panne du système de production, le fonctionnement normal n'est pas possible.

  • +
  • Tout incident ayant entraîné une panne majeure du Hub, y compris la connectivité de plusieurs partenaires/DFSP.

  • +
  • Tout incident présentant des risques financiers majeurs et ayant des implications contractuelles.

  • +
  • Un incident de sécurité ayant un impact majeur sur la confidentialité ou la disponibilité du Hub, des partenaires/DFSP ou des données clients.

  • +

Sévérité 2

    +
  • Panne partielle du Hub.

  • +
  • Une fonctionnalité clé est altérée sans solution de contournement disponible.

  • +

Sévérité 3

    +
  • Impact fonctionnel mineur/modéré sur un seul utilisateur ou un petit groupe d'utilisateurs. Une solution de contournement existe.

  • +

Sévérité 4

    +
  • Un incident mineur avec (presque) aucun impact ou préjudice sur la fonctionnalité du système mais néanmoins un bogue valide.

  • +
+ +Légende : + +* Sévérité 1 = Critique +* Sévérité 2 = Grave +* Sévérité 3 = Moyen +* Sévérité 4 = Mineur + +Le code de sévérité attribué à un incident déterminera le temps de résolution et sera utilisé par le Service Desk pour attribuer des ressources à la demande. + +En plus de la sévérité, dans certains cas, la priorité d'un incident peut également devoir être prise en compte. La priorité est attribuée par l'opérateur du Hub (plutôt que par le client) et représente l'ordre dans lequel l'incident sera corrigé. Plus la priorité est élevée, plus l'incident sera résolu rapidement. Considérez l'exemple suivant : un bogue cosmétique comme une faute de frappe sur une page web sera probablement classé comme de faible sévérité mais pourrait être une correction rapide et facile et classé comme de haute priorité. Il est donc important d'accorder à la sévérité et à la priorité la considération nécessaire. + +Le tableau suivant fournit des orientations sur la façon d'attribuer une priorité à un incident. + + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrice de priorité
Code de prioritéCritères

Priorité 1

Un problème grave est survenu affectant plusieurs utilisateurs au sein d'un bénéficiaire de service (>50% des utilisateurs du bénéficiaire de service) dans la mesure où ils sont incapables d'exécuter leurs fonctions de travail assignées, OU le bénéficiaire de service ou des domaines extérieurs au bénéficiaire de service sont affectés.

Priorité 2

Un problème est survenu affectant soit plusieurs utilisateurs (affecte >10 mais pas plus de 50% de tous les utilisateurs du bénéficiaire de service) SOIT un utilisateur clé nommé du service dans la mesure où ils sont incapables d'exécuter leurs fonctions de travail assignées et une unité métier est affectée.

Priorité 3

Un problème est survenu affectant un seul utilisateur OU (affecte <10 utilisateurs OU pas plus de 25% de tous les utilisateurs) dans la mesure où ils sont incapables d'exécuter leurs fonctions de travail assignées.

Priorité 4

Un problème est survenu affectant un seul utilisateur, causant une fonctionnalité réduite d'une seule application. Il existe une solution de contournement pour que l'utilisateur puisse exécuter ses fonctions de travail assignées, mais la panne entraîne une diminution de sa productivité.
+ +## Incidents de sécurité + +Cette section décrit la procédure qu'il est recommandé à un opérateur du Hub de mettre en œuvre pour le traitement des événements/incidents de sécurité. Les incidents de sécurité peuvent être classés comme incidents de sévérité 1, sévérité 2, sévérité 3 ou sévérité 4. Quelle que soit sa catégorisation, suivez les étapes décrites dans le tableau ci-dessous si un incident est lié à la sécurité. + + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Gestion des incidents de sécurité
ÉtapeAction ou information supplémentaireRôle

Étape 1 : Un événement/incident de sécurité suspecté est reçu via le Service Desk par le biais d'un ticket assigné à l'équipe de sécurité (L1) pour examen initial et triage.

Étape 2 : Invoquer le processus de triage.

Étape 2a :

+
    +
  • Identifier les artefacts de l'incident.

  • +
  • Identifier les appareils, systèmes ou utilisateurs affectés.

  • +
    +
  • Rassembler les indicateurs clés d'une menace.

  • +
  • Récupérer les journaux.

  • +
  • Rechercher les artefacts (adresses IP, noms d'utilisateurs, URL, noms d'hôtes, etc.).

  • +
  • Examiner les journaux pour déterminer s'il y a une loi/réglementation violée par l'incident (s'il s'agit d'un incident grave, il pourrait nuire à la réputation de l'organisation).

  • +

L1 Responsable de la sécurité de l'information (ISO)

Étape 2b :

+
    +
  • Évaluer la situation : évaluation de l'impact.

  • +
  • Estimer l'effet potentiel de l'événement ou de l'incident.

  • +
    +
  • Examiner les indicateurs de compromission disponibles.

  • +
  • Évaluer l'impact en fonction de la criticité du système affecté.

  • +
  • Examiner les journaux d'audit.

  • +
  • Établir une chronologie des événements.

  • +

L1 ISO

Étape 2c :

+

Collecter les preuves.

    +
  • Collecter et rassembler toutes les informations disponibles pour permettre la catégorisation.

  • +

L1 ISO

Étape 2d :

+

Déterminer la catégorisation.

    +
  • Sur la base des informations collectées, attribuer une catégorie au ticket.

  • +
  • La sécurité L1 mettra à jour les catégorisations selon les besoins.

  • +
+

Les exemples de catégories sont :

+
    +
  • Déni de service (DOS)

  • +
  • Code malveillant

  • +
  • Accès non autorisé

  • +
  • Fuite/perte de données

  • +
  • Violation de données (violation de la réglementation relative à la protection des données)

  • +
  • Utilisation inappropriée

  • +

L1 ISO

Étape 2e :

+

Prendre les mesures de base pour atténuer l'effet sur l'environnement.

Les mesures de base peuvent inclure des tâches telles que : +
    +
  • Verrouiller un endpoint.

  • +
  • Déployer un anti-malware si nécessaire.

  • +
  • Examiner les procédures opérationnelles standard de sécurité (SOP) (le cas échéant) pour toute étape supplémentaire qui pourrait être nécessaire.

  • +
+

Si les mesures d'atténuation prises réussissent à résoudre le problème signalé, la sécurité L1 mettra à jour le ticket et passera à l'étape 8 (Clôturer l'incident).

L1/L2 ISO

Étape 3 : Évaluer si le problème signalé est un événement ou un incident.

La décision d'évaluation est prise par l'équipe de sécurité L1 en collaboration avec la sécurité L2.

L1/L2 ISO

Étape 4.1 : Si le problème signalé est catégorisé comme un « événement », suivre ces étapes :

Étape 4.1a :

+

Effectuer le suivi de l'événement.

Les exemples de suivi d'événement incluent : +
    +
  • Vérifier et installer un anti-malware sur tous les hôtes.

  • +
  • Déclencher des tickets demandant la correction des systèmes et/ou la révision de l'événement par l'équipe des opérations.

  • +

L1/L2 ISO

Étape 4.1b :

+

Passer à l'étape 8.

L1 ISO

Étape 4.2 : Si le problème signalé est catégorisé comme un « incident », suivre ces étapes :

Étape 4.2a :

+

L'ISO L1 escalade vers l'ISO L2 pour une investigation plus approfondie en réattribuant le ticket au groupe de sécurité L2 pour suivi.

L1 ISO

Étape 4.2b :

+

L'ISO L2 accuse réception du ticket de L1 et procède à l'ouverture du rapport d'incident de sécurité.

L2 ISO

Étape 4.2c :

+

L'ISO L2 examine et vérifie la sévérité et la catégorisation de l'incident.

L2 ISO

Étape 5.1 : Si l'incident signalé est catégorisé comme un incident « S1 », suivre ces étapes :

Étape 5.1a :

+

Mettre à jour le rapport d'incident de sécurité.

L2 ISO

Étape 5.1b :

+

Informer les parties prenantes par courriel sécurisé.

Les parties prenantes sont documentées dans l'Annexe A : Matrice d'escalade de la gestion des incidents.

L2 ISO

Étape 5.1c :

+

Passer à l'étape 6.

L2 ISO

Étape 5.2 : Si l'incident signalé est catégorisé comme un incident « S4 », suivre ces étapes :

Étape 5.2a :

+

Passer à l'étape 6.

L2 ISO

Étape 6 : Contenir et éradiquer.

Étape 6a :

+

Examiner et mettre à jour les actions d'atténuation pour réduire l'impact.

Les exemples d'actions d'atténuation incluent :

+
    +
  • Changer les mots de passe.

  • +
  • Verrouiller l'accès.

  • +

L2 ISO

Étape 6b :

+

Collecter les preuves.

L2 ISO

Étape 6c :

+

Effectuer l'analyse des causes premières et identifier/mettre en œuvre un correctif.

L2 ISO

Étape 6d :

+

Mettre à jour les procédures opérationnelles standard (SOP) de l'incident selon les besoins.

Les mises à jour des SOP sont examinées par L3 avant adoption.

L2 ISO

Étape 6.1 : Si l'étape 6 est réussie, suivre ces étapes :

Étape 6.1a :

+

Mettre à jour le rapport d'incident de sécurité et le ticket.

S'assurer que le ticket ne contient pas d'informations de sécurité sensibles.

L2 ISO

Étape 6.1b :

+

Communiquer avec les parties prenantes par courriel sécurisé.

Les parties prenantes sont documentées dans l'Annexe A : Matrice d'escalade de la gestion des incidents.

L2 ISO

Étape 6.1c :

+

Mettre fin au verrouillage du système ou du service.

L2 ISO

Étape 6.1d :

+

Passer à l'étape 8.

L2 ISO

Étape 6.2 : Si l'étape 6 échoue, suivre ces étapes :

Étape 6.2a :

+

Escalader vers l'équipe de sécurité L3.

L2 ISO

Étape 6.2b :

+

Informer l'équipe métier.

L2 ISO

Étape 6.2c :

+

L3 procède à l'étape 7.

L3 ISO

Étape 7 : L3 examine et résout le problème.

Étape 7a :

+

Examiner les activités et l'historique de l'incident documentés par L1 et L2.

L3 ISO

Étape 7b :

+

Fournir des orientations pour des actions de confinement supplémentaires.

L3 ISO

Étape 7c :

+

Si L3 résout le problème, passer à l'étape 8.

L3 ISO

Étape 7d :

+

Si L3 ne peut pas résoudre le problème, il peut escalader vers l'OEM du système/logiciel ou obtenir des services spécialisés (sous réserve d'approbation) pour le support.

Si L3 ne peut pas résoudre le problème, il peut escalader vers l'OEM du système/logiciel ou obtenir des services spécialisés (sous réserve d'approbation) pour le support. Une décision peut être nécessaire sur le déclenchement du plan de reprise après sinistre, y compris la formation d'une « cellule de crise ».

Un plan de reprise après sinistre (DRP) est un arrangement sur mesure, basé sur les capacités techniques de l'opérateur du Hub, ainsi que sur l'appétit pour le risque. Il fait partie des politiques de sécurité informatique d'un opérateur du Hub. Il est nécessaire d'évaluer les détails de la politique et des attentes du DRP de l'opérateur du Hub, et d'affiner le déploiement pour répondre à ses besoins. Les détails doivent être élaborés pendant la mise en œuvre (de préférence pendant la phase de conception) car les différentes options disponibles peuvent avoir des implications financières.

L3 ISO

Étape 8 : Clôturer l'incident.

Étape 8a :

+

Restaurer les systèmes affectés.

L1 / L2 / L3 ISO

Étape 8b :

+

Mettre à jour le rapport d'incident de sécurité.

L2 / L3 ISO

Étape 8c :

+

Identifier et communiquer les leçons apprises.

L2 / L3 ISO

Étape 8d :

+

L'équipe de réponse aux incidents examine les recommandations pertinentes pour une adoption éventuelle.

Cette session de revue peut inclure les équipes des opérations techniques et de gestion des services, selon la sévérité.

L1 / L2 / L3 ISO

Étape 8e :

+

Informer les parties prenantes.

L2 / L3 ISO

Étape 8f :

+

Clôturer l'incident.

L1 / L2 / L3 ISO

Étape 9 : L'ISO L3 modifie et révise les politiques et procédures relatives aux violations.

L3 ISO

+ +La figure suivante présente un résumé du processus décrit ci-dessus. + +![Gestion des incidents de sécurité](../../../../.vuepress/public/security_incident_process.png) + +### Modèle de rapport d'incident de sécurité + +Lors de la rédaction d'un rapport d'incident de sécurité, il est recommandé d'utiliser un modèle créé à cet effet. + +## Rôles et responsabilités + +Cette section fournit des directives génériques sur les rôles et responsabilités proposés au sein du processus de gestion des incidents. + +::: tip NOTE +Il est pratique de décrire le support continu pour les opérations techniques du Hub Mojaloop en niveaux. Ce document décrit quatre niveaux. Les niveaux sont pratiques car chaque niveau de support nécessite un degré différent de connaissance et d'accès au système. En d'autres termes, les niveaux font référence à différents rôles/équipes de support au sein de votre organisation. + +Certaines de ces équipes peuvent éventuellement être externalisées, selon le niveau d'expertise ou de capacité au sein de votre organisation. Si vous décidez d'externaliser des fonctions de support, il existe des organisations au sein de la communauté Mojaloop qui fournissent différents niveaux de support en tant que service. (Pour plus d'informations et des recommandations, contactez la Fondation Mojaloop.) +::: + +### Utilisateur final/utilisateur/demandeur/L0 + +*Rôle* + +Il s'agit de la partie prenante qui subit une perturbation de service et crée un ticket d'incident pour initier le processus de gestion des incidents. + +*Responsabilités* + +* Contacter le Service Desk pour créer une nouvelle demande d'incident. +* Suivre une demande existante. +* Surveiller le canal de communication pour tout retour des ingénieurs de support. +* Communiquer clairement toutes les informations requises ou demandées aux ingénieurs de support. +* Reconnaître la restauration du service et l'achèvement du ticket. +* Répondre aux enquêtes de suivi après la résolution du ticket en complétant la boucle de rétroaction. + +### Équipe niveau 1/Service Desk + +*Rôle* + +Il s'agit du premier point de contact (support niveau 1) pour les demandeurs ou les utilisateurs finaux lorsqu'ils souhaitent créer une demande ou un incident. Ce rôle est responsable de la résolution de base au Service Desk, des diagnostics initiaux et de l'investigation des tickets du Service Desk. + +*Responsabilités* + +* Enregistrer toutes les demandes d'incident entrantes avec les paramètres appropriés, tels que la sévérité et la priorité (si cette dernière est applicable). +* Attribuer les tickets aux ingénieurs de support en fonction des paramètres ci-dessus (sévérité et priorité). +* Analyser et résoudre l'incident pour restaurer le service. +* Escalader les incidents non résolus vers l'équipe niveau 2. +* Rassembler toutes les informations requises auprès des demandeurs et leur envoyer des mises à jour régulières sur le statut de leur demande. +* Agir comme point de contact pour les demandeurs et, si nécessaire, coordonner entre l'équipe niveau 2 et les utilisateurs finaux. +* Vérifier la résolution avec l'utilisateur final et recueillir les retours tout en mettant à jour les tickets. +* Surveiller les retours et enquêtes liés aux actions que L1 a prises pour résoudre le problème dans le but d'analyser la qualité du service offert. + +### Équipe niveau 2 (Support application, infrastructure, sécurité et opérations métier L2) (Équipe de support client) + +*Rôles* + +Cette fonction de support est composée d'ingénieurs ou d'experts métier en la matière (SME) ayant une connaissance approfondie du Hub. L'équipe L2 est censée fournir un dépannage approfondi, une analyse technique, une analyse des transactions et un support pour résoudre les incidents signalés. Ils reçoivent généralement des demandes plus complexes des utilisateurs finaux ; ils reçoivent également des demandes sous forme d'escalades de l'équipe L1. + +*Responsabilités* + +* Effectuer le diagnostic de l'incident. +* Documenter les étapes suivies pour résoudre l'incident et soumettre des articles de base de connaissances. (Pour chaque incident, l'équipe de support met à jour la base de connaissances. L'objectif des articles de base de connaissances est de permettre aux utilisateurs finaux et au personnel de support de résoudre les problèmes par eux-mêmes.) +* Traiter les incidents intermédiaires, par exemple les incidents liés aux applications, à l'infrastructure, à l'analyse des journaux, à l'analyse des transactions, etc. +* Si l'incident est résolu, confirmer la résolution avec l'utilisateur final. +* Soutenir l'onboarding des DFSP. + +### Équipe niveau 3 (Support application, infrastructure et sécurité L3) (Équipe de support technique) + +*Rôles* + +Ce niveau est généralement composé d'ingénieurs spécialisés ayant une connaissance approfondie de domaines particuliers du Hub – par exemple, connaissance des composants d'infrastructure ou des applications système, ou expertise en ingénierie de sécurité. + +*Responsabilités* + +* Effectuer une analyse approfondie et/ou reproduire le problème dans un environnement de test afin de diagnostiquer correctement le problème et de tester la solution. +* Interpréter et analyser le code et les données en utilisant les informations triées depuis L1 et L2. +* Si non résolu, escalader l'incident vers les partenaires de support « L4 » pour identifier le problème sous-jacent ou vers les fournisseurs externes, DFSP ou banque de règlement (requêtes de transactions ou rapports de transferts) selon le cas. +* Fournir une expertise en la matière. +* Documenter l'incident et mettre à jour la base de connaissances. (Pour chaque incident, l'équipe de support met à jour la base de connaissances. L'objectif des articles de base de connaissances est de permettre aux utilisateurs finaux et au personnel de support de résoudre les problèmes par eux-mêmes.) + +### Responsable des incidents/Responsable de service + +*Rôle* + +Le responsable de service surveille l'efficacité du processus. Le responsable de service gère le processus pour restaurer le fonctionnement normal du service aussi rapidement que possible et pour minimiser l'impact sur les opérations métier. + +*Responsabilités* + +* Servir de point de contact pour tous les incidents S1 signalés. +* Planifier et faciliter toutes les activités impliquées dans le processus de gestion des incidents. +* S'assurer que le processus correct est suivi pour tous les tickets et corriger tout écart. +* Coordonner et communiquer avec le propriétaire du processus. +* Aligner les attentes des clients avec les SLA en étant l'interface entre les clients et l'équipe des opérations. +* Identifier les incidents qui doivent être examinés et effectuer l'examen. + +### Propriétaire du processus : Responsable des opérations techniques + +*Rôle* + +Il s'agit du propriétaire du processus suivi pour la gestion des incidents. Ce rôle agit également comme coordinateur entre les équipes et les organisations. Le responsable des opérations techniques analyse, modifie et améliore le processus pour s'assurer qu'il sert au mieux les intérêts de l'organisation. + +*Responsabilités* + +* Responsable de la qualité globale du processus. Supervise la gestion et la conformité aux procédures, modèles de données, politiques et technologies associés au processus. +* Propriétaire du processus et de la documentation de soutien pour le processus d'un point de vue stratégique et tactique. +* S'assure que le processus de gestion des incidents s'aligne sur les autres politiques de l'organisation, par exemple la politique RH, la politique de sécurité, les principes directeurs de niveau 1, etc. +* Définit les [indicateurs clés de performance (KPI)](key-terms-kpis.md) et les aligne sur les facteurs critiques de succès (CSF), et s'assure que ces objectifs sont atteints. +* Conçoit, documente, examine et améliore les processus. +* Établit l'amélioration continue du service (CSI) et s'assure que les procédures, politiques, rôles, technologies et autres aspects du processus de gestion des incidents sont examinés et améliorés. +* Se tient informé des bonnes pratiques de l'industrie et les intègre dans le processus de gestion des incidents. + +## Résultats du processus de gestion des incidents + +Le processus de gestion des incidents produit les résultats suivants. Notez que le seul résultat obligatoire pour les incidents de sécurité ou S1 est l'analyse des causes premières (RCA), et tous les autres résultats énumérés ci-dessous peuvent alimenter la RCA. + +* Incidents résolus ou clôturés. Il s'agit du résultat le plus souhaité du processus de gestion des incidents. L'enregistrement d'incident clôturé contient des détails précis sur les attributs de l'incident et les étapes prises pour la résolution ou la solution de contournement. +* Demandes de changement (RFC). +* Métriques de résolution (temps moyen entre les pannes, temps moyen de réparation, temps moyen de prise en compte et temps moyen jusqu'à la défaillance). Pour les détails sur les KPI, voir le [Glossaire](key-terms-kpis.md). +* Changement mis en œuvre avec succès à travers le processus de gestion des changements. +* Document RCA conforme au modèle RCA. +* Service restauré. +* Base de connaissances mise à jour. +* Notification par divers canaux (Service Desk, courriel, appel, etc.) sur l'initiation, la résolution et la clôture d'un incident S1 aux différentes parties prenantes. +* Rapport d'opérations quotidiennes et rapport de gestion mis à jour pour vérifier les décisions prises concernant les améliorations de service, l'allocation/réaffectation des ressources. +* Détails d'interruption de service et/ou de composant enregistrés avec précision (par exemple, début, fin, durée, classification de l'interruption, etc.). + +## Impact sur les autres processus + +Le processus de gestion des incidents interagit avec un certain nombre d'autres processus, alimentant et impactant chacun d'entre eux : + +* **Processus de gestion des changements** : L'objectif du processus de gestion des changements est de s'assurer que des méthodes et procédures standardisées sont utilisées pour le traitement efficace et rapide de tous les changements, afin de minimiser l'impact des incidents liés aux changements sur la disponibilité ou la qualité du service, et par conséquent d'améliorer les opérations quotidiennes de l'organisation. +* **Processus de gestion des versions** : La gestion des versions et du déploiement est définie comme le processus de gestion, de planification et de programmation du déploiement des services informatiques, des mises à jour et des versions dans l'environnement de production. L'objectif principal de ce processus est de s'assurer que l'intégrité de l'environnement de production est protégée et que les composants corrects et les fonctionnalités validées sont mis à disposition pour l'utilisation par les clients. +* **Processus de communication des incidents** : La communication des incidents est le processus d'alerte des utilisateurs qu'un service connaît un type d'interruption ou une performance dégradée. Cela est particulièrement important pour les services où une disponibilité 24h/24 et 7j/7 est attendue. La communication des incidents est importante pour tous les partenaires, clients et leurs clients. diff --git a/docs/fr/adoption/HubOperations/TechOps/key-terms-kpis.md b/docs/fr/adoption/HubOperations/TechOps/key-terms-kpis.md new file mode 100644 index 000000000..3bc662f33 --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/key-terms-kpis.md @@ -0,0 +1,80 @@ +# Glossaire + +Cette section sert de glossaire des termes des opérations techniques et fournit des définitions : + +* des termes clés guidés par les bonnes pratiques de la bibliothèque d'infrastructure des technologies de l'information (ITIL) +* des indicateurs clés de performance (KPI), c'est-à-dire des métriques qui aident à déterminer si les objectifs spécifiques de gestion des incidents sont atteints + +## Termes clés + +**Gestion des changements :** La gestion des changements est le processus d'enregistrement, d'approbation, d'exécution, de clôture et de révision de tous les changements. Le changement peut être soit contractuel (comme la signature initiale d'un contrat, une mise à niveau de SLA, de nouvelles ressources nécessaires, etc.), soit opérationnel résultant d'une demande de changement. + +**Escalade :** La reconnaissance du fait qu'un incident nécessite des ressources supplémentaires pour respecter les objectifs de niveau de service ou les attentes des utilisateurs, en tenant compte de la criticité, de l'impact et de l'urgence de l'incident. + +**Centre d'assistance/Service Desk :** Le point de contact unique entre le fournisseur de services et les utilisateurs. Un Service Desk typique gère les incidents et les demandes de service, et assure également la communication avec les utilisateurs. + +**Incident :** Une interruption non planifiée d'un service informatique, ou une réduction de la qualité d'un service informatique. La défaillance d'un élément de configuration qui n'a pas encore impacté le service est également un incident ; par exemple, la défaillance d'un disque dans un ensemble en miroir. + +**Processus de gestion des incidents (IMP) :** Le processus de gestion du cycle de vie de tous les incidents. L'objectif principal de la gestion des incidents est de restaurer le fonctionnement normal du service informatique aussi rapidement que possible avec le soutien de l'ensemble de l'organisation en place. + +**Enregistrement/ticket d'incident :** Un enregistrement contenant les détails d'un incident. Chaque enregistrement d'incident (également appelé ticket) documente le cycle de vie d'un seul incident. + +**Priorité :** Une catégorie utilisée pour identifier l'importance relative d'un incident ou d'un changement. La priorité est utilisée pour identifier les délais requis pour les actions à entreprendre. + +**Gestion des versions :** La gestion des versions est le processus de gestion, de planification, de programmation, de mise en œuvre et de contrôle d'une version logicielle à travers différentes étapes et environnements, dans le but de fournir des fonctionnalités aux clients ou aux utilisateurs finaux. + +**Demande de changement (RFC) :** La demande de changement (ou simplement demande de modification) est une demande formelle pour la mise en œuvre d'un changement. La RFC est un précurseur de l'« Enregistrement de changement » et contient toutes les informations nécessaires pour approuver et exécuter un changement. + +**Rôle :** Un ensemble de responsabilités, d'activités et d'autorisations accordées à une personne ou une équipe. Les rôles sont utilisés pour attribuer des propriétaires aux différents processus de gestion des incidents et pour définir les responsabilités des activités dans les définitions détaillées des processus. + +**Analyse des causes premières (RCA) :** La RCA est un terme collectif qui décrit un large éventail d'approches, d'outils et de techniques utilisés pour découvrir les causes des incidents. Elle est déclenchée lors de chaque incident urgent et chaque fois qu'un incident se produit plus d'une fois. + +**Accord de niveau de service (SLA) :** Un accord entre un fournisseur de services informatiques et un client. Le SLA décrit le service informatique, documente les objectifs de niveau de service et précise les responsabilités du fournisseur de services informatiques et du client. + +**Sévérité :** Une mesure de l'effet d'un incident sur les processus métier. + +**TAT (Turnaround Time) :** Il s'agit du temps écoulé entre le moment où l'incident est signalé et le moment où il est résolu et clôturé. Il comprend le temps d'intervention garanti (GIT) et le temps de résolution garanti (GRT). + +## Indicateurs clés de performance (KPI) + +**Taux de disponibilité (Taux de disponibilité du service) :** La disponibilité de l'ensemble de la solution technique pour fournir le service par DFSP. + +**Durée moyenne de clôture des incidents :** Durée moyenne entre l'enregistrement des incidents et leur clôture. + +**Temps moyen de réponse aux incidents :** La durée moyenne (par exemple, en minutes) entre la détection d'un incident et la première action entreprise pour réparer l'incident. + +**Nombre moyen d'incidents résolus par le Service Desk :** Nombre moyen d'incidents résolus par le Service Desk par rapport à tous les incidents ouverts. + +**Temps d'intervention garanti (GIT) :** Le temps écoulé entre le moment où un incident est signalé (par exemple, un courriel est envoyé à l'outil Service Desk) et le moment où une réponse d'accusé de réception est renvoyée au signaleur du problème. + +**Temps de résolution garanti (GRT) :** Somme du temps total consacré à la résolution d'un problème par toutes les parties. (Le statut du problème doit être « En cours » ou « Escaladé » pour être comptabilisé dans la somme totale. Les statuts « En attente » ou « Clôturé » ne sont pas pris en compte dans le calcul de la somme totale.) + +**Incidents résolus sans escalade :** Le pourcentage (%) d'incidents résolus dans le cadre du SLA sans aucune escalade. + +**Taux de file d'attente des incidents :** Le nombre d'incidents clôturés par rapport au nombre d'incidents ouverts sur une période donnée. + +**Temps moyen entre les pannes (MTBF) :** Le temps moyen entre les pannes réparables d'un produit technologique. Cette métrique est utilisée pour suivre à la fois la disponibilité et la fiabilité d'un service informatique ou de tout autre élément de configuration, afin d'évaluer s'ils peuvent remplir leur fonction convenue sans interruption. Plus le temps entre les pannes est élevé, plus le système est fiable. + +**Temps moyen de prise en compte (MTTA) :** Le temps moyen entre le déclenchement d'une alerte et le début du travail sur le problème. Cela mesure le temps qu'il faut à une organisation pour répondre aux plaintes, pannes ou incidents dans tous les départements en moyenne. Cette métrique est utile pour suivre la réactivité d'une équipe et l'efficacité d'un système d'alerte. + +**Temps moyen de détection (MTTD) – « Actions proactives » :** La différence entre le début de tout événement considéré comme ayant un impact sur les revenus et sa détection effective par le technicien qui initie ensuite une action spécifique pour rétablir l'événement à son état d'origine. Ce n'est pas la même chose que de démarrer le chronomètre du temps moyen de réparation (MTTR) (c'est-à-dire une fois que le technicien reçoit un ticket). Le début de tout événement ayant un impact sur les revenus est presque toujours enregistré à un moment précis par un équipement spécifique. L'élément clé est d'intégrer l'outil de détection dans l'environnement du technicien, puis de mesurer la différence entre l'horodatage de l'événement et la première action du technicien indiquant la reconnaissance de l'événement (MTTD). + +**Temps moyen avant défaillance (MTTF) :** Le temps moyen entre les pannes non réparables d'un produit technologique (principalement le matériel). + +**Temps moyen de réparation (MTTR) :** Fait référence au temps moyen nécessaire pour réparer un système et le restaurer à sa pleine fonctionnalité. \ +\ +Le chronomètre MTTR commence à tourner lorsque les réparations commencent et continue jusqu'à ce que les opérations soient restaurées. Cela inclut le temps de réparation, la période de test et le retour à la condition de fonctionnement normal. + +**Temps moyen de récupération :** Le temps moyen de récupération est une mesure du temps entre le moment où la panne est découverte pour la première fois et le moment où le service reprend son fonctionnement. Ainsi, en plus du temps de réparation, de la période de test et du retour à la condition de fonctionnement normal, il capture le temps de notification de la panne et le diagnostic. + +**Backlog d'incidents anciens :** Nombre d'incidents ouverts de plus de 28 jours (ou tout autre délai donné) par rapport à tous les incidents ouverts. + +**Pourcentage d'incidents résolus dans les délais/objectifs :** Nombre d'incidents clôturés dans le délai autorisé, par rapport au nombre total d'incidents clôturés sur une période donnée. Un délai est appliqué à chaque incident lors de sa réception et fixe une limite au temps disponible pour résoudre l'incident. Le délai appliqué est dérivé des accords conclus avec le client concernant la résolution des incidents. + +**Pourcentage d'incidents résolus dans le délai SLA :** Nombre total d'incidents résolus dans le délai SLA, divisé par le nombre total d'incidents. + +**Pourcentage d'indisponibilité due aux incidents :** Pourcentage d'indisponibilité due aux incidents, par rapport aux heures de service. + +**Pourcentage d'incidents en retard :** Nombre d'incidents en retard (non clôturés et non résolus dans le délai établi) par rapport au nombre d'incidents ouverts (non clôturés). + +**Pourcentage d'incidents répétés :** Pourcentage d'incidents pouvant être classés comme incidents répétés, par rapport à tous les incidents signalés au cours de la période de mesure. Un incident répété est un incident qui s'est déjà produit (plusieurs fois) au cours de la période de mesure. diff --git a/docs/fr/adoption/HubOperations/TechOps/problem-management.md b/docs/fr/adoption/HubOperations/TechOps/problem-management.md new file mode 100644 index 000000000..962b6145f --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/problem-management.md @@ -0,0 +1,131 @@ +# Gestion des problèmes + +L'objectif global de la gestion des problèmes est d'identifier la cause première des incidents (incidents de sévérité 1 ou incidents survenus plus d'une fois) ou les causes potentielles des incidents, puis de mettre en œuvre immédiatement des actions pour améliorer ou corriger la situation. + +La procédure de gestion des problèmes garantit que : + +* les problèmes sont correctement enregistrés +* les problèmes sont correctement acheminés +* le statut des problèmes est rapporté avec précision +* la file d'attente des problèmes non résolus est visible et rapportée +* les problèmes sont correctement priorisés et traités dans l'ordre approprié +* la résolution fournie répond aux exigences de l'accord de niveau de service (SLA) convenu +* la résolution des causes premières ou des problèmes est effectuée + + +## Identification des problèmes + +Un problème est déclaré par la partie prenante concernée de la gestion des services dans les situations suivantes : + +* lorsqu'il y a un incident dont le propriétaire de l'incident ne peut pas établir la cause dans les délais définis par l'accord de niveau de service +* lorsqu'il y a des occurrences répétées d'un incident avec un impact important sur l'activité +* lorsqu'il y a une dégradation du service ou un écart par rapport au comportement attendu susceptible d'affecter l'activité à l'avenir s'il n'est pas atténué, et dont l'atténuation n'est pas bien établie + +Dans l'un des scénarios ci-dessus, ou tout autre scénario que le responsable des problèmes peut juger applicable, un enregistrement de problème sera ouvert et le processus de gestion des problèmes sera lancé. + +Si un problème s'avère être causé par un défaut du produit, un bogue est signalé conformément au [processus de triage des défauts](defect-triage.md). + +## Catégorisation et priorisation des problèmes + +Afin de déterminer si les SLA sont respectés, il est nécessaire de catégoriser et prioriser les problèmes rapidement et correctement. + +L'objectif d'une catégorisation appropriée est de : + +* identifier le service impacté +* associer les problèmes aux incidents connexes +* indiquer quels groupes de support doivent être impliqués +* fournir des métriques significatives sur la fiabilité du système + +Pour chaque problème, le service spécifique sera identifié. + +La priorité attribuée à un problème déterminera la rapidité avec laquelle il sera programmé pour résolution. La priorité est définie en fonction d'une combinaison de la sévérité et de l'impact des incidents associés. + +Le tableau ci-dessous fournit des orientations sur la façon de classifier un problème. Pour savoir comment lire ce tableau, voir les exemples suivants : + +* Un problème de sévérité élevée et impact faible sera classé comme un problème de priorité moyenne (vérifier la cellule à l'intersection de sévérité élevée et impact faible). +* Un problème de sévérité moyenne et d'impact élevé sera classé comme un problème de priorité élevée (vérifier la cellule à l'intersection de sévérité moyenne et impact élevé). + + + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Matrice de priorité des problèmes
SÉVÉRITÉ

Faible
+
+Le problème empêche l'utilisateur d'accomplir une partie de ses tâches.

Moyenne
+
+Le problème empêche l'utilisateur d'exécuter des fonctions critiques sensibles au temps.

Élevée
+
+Un service ou une partie majeure d'un service est indisponible.

IMPACT

Faible
+
+Le problème affecte un ou deux membres du personnel.

+

Niveaux de service dégradés mais toujours dans les limites des SLA.

Faible

Faible

Moyenne

Moyenne
+
+Niveaux de service dégradés mais ne respectant pas les contraintes SLA ou ne pouvant fournir qu'un niveau minimum de service.

+

La cause du problème semble affecter plusieurs domaines fonctionnels.

Moyenne

Moyenne

Élevée

Élevée
+
+Tous les utilisateurs d'un service spécifique sont affectés.

+

Un service destiné aux clients est indisponible.

Élevée

Élevée

Élevée

+ +## Documentation des solutions de contournement + +Une solution de contournement définit un moyen temporaire de surmonter les effets négatifs d'un problème. Les solutions de contournement peuvent être : + +* des instructions fournies au client sur la façon d'accomplir son travail en utilisant une méthode alternative +* des correctifs temporaires qui aident un système à fonctionner comme prévu mais qui ne résolvent pas le problème de manière permanente + +Les solutions de contournement doivent être documentées et communiquées au Service Desk afin qu'elles puissent être ajoutées à la base de connaissances. Cela garantira que les solutions de contournement sont accessibles au Service Desk pour faciliter la résolution lors de récurrences futures de l'incident. + +Dans les cas où une solution de contournement est trouvée, il est important de documenter tous les détails de la solution de contournement dans l'Enregistrement de problème et que l'Enregistrement de problème reste ouvert. + +## Documentation des erreurs connues + +Lorsqu'un diagnostic est établi pour identifier un problème et ses symptômes, un Enregistrement d'erreur connue doit être créé et placé dans la documentation des erreurs connues. Si des incidents ou des problèmes récurrents surviennent, ils peuvent être identifiés et le service restauré plus rapidement. Toute solution de contournement ou résolution doit également être documentée dans l'Enregistrement d'erreur connue du problème concerné. + +Dans certains cas, il peut être avantageux de créer un Enregistrement d'erreur connue encore plus tôt dans le processus global – à titre informatif par exemple – même si le diagnostic n'est pas terminé ou qu'une solution de contournement n'a pas encore été trouvée. + +L'Enregistrement d'erreur connue doit contenir tous les symptômes connus afin que, lorsqu'un nouvel incident survient, une recherche dans les erreurs connues puisse être effectuée et la correspondance appropriée trouvée. + +## Processus + +La figure suivante présente un résumé du processus décrit ci-dessus. + +![Gestion des problèmes](../../../../.vuepress/public/problem_mgmt.png) diff --git a/docs/fr/adoption/HubOperations/TechOps/release-management.md b/docs/fr/adoption/HubOperations/TechOps/release-management.md new file mode 100644 index 000000000..3679097d6 --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/release-management.md @@ -0,0 +1,108 @@ +# Gestion des versions + +La gestion des versions gère les processus de gestion, de planification, de programmation et de contrôle d'une modification logicielle à travers le déploiement et les tests dans divers environnements. + +::: tip NOTE +Les processus décrits dans cette section représentent les bonnes pratiques et servent de recommandations pour les organisations remplissant un rôle d'opérateur du Hub. +::: + +::: tip NOTE +Cette section fait référence à une « équipe de support Mojaloop » : une équipe dédiée à l'exécution des services de support pour les opérations techniques d'un Hub Mojaloop. Notez que cette équipe peut être une unité internalisée ou externalisée, selon le niveau d'expertise ou de capacité au sein de votre organisation. Si vous décidez d'externaliser les fonctions de support, il existe des organisations au sein de la communauté Mojaloop qui fournissent différents niveaux de support en tant que service. (Pour plus d'informations et des recommandations, contactez la Fondation Mojaloop.) +::: + +## Composants de mise en production et environnements + +Lors de l'acceptation de nouvelles versions de Mojaloop Open Source pour les services Switch et autres composants nécessaires, les versions passent par une série d'activités de test dans des environnements de pré-production successifs, en commençant par les environnements de développement/QA et en terminant par les tests de niveau production. + +La configuration d'environnement recommandée comprend plusieurs environnements servant tous des objectifs différents, comme illustré dans le diagramme ci-dessous. + + + +Une implémentation spécifique au Hub de Mojaloop est construite sur un certain nombre de composants de service (Mojaloop OSS, extensions ou autres composants, personnalisations potentielles), et les versions incluront de nouvelles fonctionnalités, des améliorations ou des corrections de bogues de tous ces composants. + + + +## Développement et tests (Définition de terminé) + +Les pratiques standard de développement et de QA – suivies par l'équipe de développement/livraison produit Mojaloop – incluent les éléments suivants dans le cadre de la Définition de fini. La recommandation est que l'opérateur du Hub adopte une stratégie similaire. + +* Tests unitaires développés pour chaque morceau de code écrit. +* Le code, les tests unitaires et la documentation ont été revus par les pairs. +* Les tests d'intégration ont été développés et exécutés. +* Les tests de régression complets ont été exécutés avec succès lors du commit (fusion dans la branche master). +* Les notes de version ont été créées avec les détails suivants : + * Description des changements + * Liste des composants/services modifiés + * Liste des user stories et bogues dans la version + * Mise en évidence de tout breaking change impactant toute fonctionnalité, solution API ou architecture système +* Runbook de déploiement créé, avec les instructions de déploiement et de retour en arrière, y compris les variables d'environnement, les scripts de mise à jour de base de données et les prérequis de déploiement. +* Maintenance des définitions de tests de régression, des résultats de tests de référence de Mojaloop OSS et des critères de validation spécifiques au schéma (tests) ajoutés en complément. +* Maintenance d'une base de connaissances sur tout changement nouveau ou significatif concernant les fonctionnalités, produits, architecture, etc., relatifs à Mojaloop OSS et autres composants, ainsi que les personnalisations effectuées pour le schéma. La base de connaissances sert de base pour le transfert de connaissances à l'équipe des opérations. Ce transfert comprend un examen complet du runbook de déploiement et d'autres artefacts de version, tels que les packages de version et les scripts de base de données, qui aideront grandement l'équipe des opérations dans les opérations quotidiennes, la validation, le débogage des problèmes et la maintenance. + +## Versions de Mojaloop + +La pratique standard pour les versions de Mojaloop est la suivante : + +* Toutes les nouvelles versions des applications individuelles, composants et microservices qui composent Mojaloop sont disponibles via les charts Helm dans les dépôts publics ici : +* Les tests unitaires et certains tests d'intégration fonctionnels sont produits avec chaque version de composant. +* La version de Mojaloop inclut également des tests de régression automatisés de bout en bout. Les suites de tests sont versionnées, le numéro de version correspondant au numéro de version de la version de Mojaloop. +* Un package de version est produit, une fois par incrément de programme (PI), pour les nouvelles versions de Mojaloop. Cela inclut les mises à niveau des applications individuelles, composants et microservices au sein de Mojaloop. \ +\ +Un incrément de programme est un intervalle limité dans le temps pendant lequel une équipe Agile livre une valeur incrémentale. +* Toutes les mises à jour de maintenance de Mojaloop, les nouvelles fonctionnalités et les corrections de bogues sont mises à disposition des utilisateurs de Mojaloop dans le cadre des cycles de publication, une fois par période PI. + +## Versions de produits d'extensions/composants supplémentaires + +Il est recommandé que la pratique standard pour les versions de produits d'extensions/composants supplémentaires soit alignée sur le processus de publication de Mojaloop [ci-dessus](release-management.md#mojaloop-releases) : + +* Toutes les nouvelles versions de produits sont mises à disposition via des packages de version et décrites dans les notes de version. +* Un package de version inclut des tests automatisés de bout en bout pour chaque version de produit. Les suites de tests sont versionnées, le numéro de version correspondant au numéro de version de la version du produit. +* Les versions de produits sont alignées sur la cadence de publication de Mojaloop, une fois par période PI. +* Toutes les mises à jour de maintenance des produits, les nouvelles fonctionnalités et les corrections de bogues sont mises à disposition des clients DFSP des extensions/produits supplémentaires dans le cadre du cycle de publication, une fois par période PI. + +## Bogues et hotfixes + +Les bogues et hotfixes sont traités de la manière suivante : + +* Toutes les corrections de bogues (à la fois Mojaloop et autres produits) sont incluses dans les packages de version. +* De même, les hotfixes sont également fournis via une version. Il n'est pas recommandé de déployer des hotfixes directement à partir des versions de packages d'applications spécifiques, car le déploiement d'un seul composant d'une version (par opposition au déploiement de la version qui inclut le composant mis à jour) peut entraîner une désynchronisation du Hub avec la version du package d'application. +* Les bogues sont suivis, gérés et priorisés comme défini dans le [processus de triage des défauts](defect-triage.md) : + * L'outil Service Desk est utilisé pour la gestion de tous les bogues. + * Une équipe de triage du support Mojaloop avec des représentants des équipes de livraison produit et de gestion de produit de Mojaloop et d'autres produits est impliquée dans l'analyse de l'urgence et de l'impact pour déterminer la priorisation des bogues, y compris la planification/programmation de la résolution et la communication à l'opérateur du Hub. + +## Environnements et stratégie QA + +Afin de valider un déploiement d'une version nouvellement publiée de Mojaloop par rapport aux derniers autres produits (extensions/composants supplémentaires), un environnement doit être mis en place par le schéma avec tous les composants nécessaires ainsi que la configuration spécifique que le schéma utilise. Cela permet aux équipes de QA/validation et/ou de support Mojaloop (une équipe dédiée à l'exécution des services de support pour les opérations techniques d'un Hub Mojaloop) d'effectuer le déploiement et les tests des versions de Mojaloop par rapport aux dernières versions des autres produits. + +::: tip NOTE +L'environnement mis en place par l'équipe de support Mojaloop pour la validation doit suivre une infrastructure standard, reproduisant ou simulant une configuration de production correspondante autant que possible, afin que tout problème ou bogue puisse être identifié tôt dans le processus. Une configuration de production comprend généralement des passerelles API, des DMZ, une configuration de cluster basée sur des zones de sécurité, ainsi que tous les composants et personnalisations nécessaires (y compris les règles de schéma) effectuées par le schéma. L'opérateur du Hub doit s'assurer que son infrastructure de production est entièrement synchronisée avec les normes d'infrastructure de l'équipe de support Mojaloop. +::: + +Suite au déploiement et à la validation réussis d'une version sur l'infrastructure et l'architecture standard, et après avoir exécuté avec succès la dernière version de Mojaloop et des autres produits, la version est approuvée et peut être partagée/mise à disposition (via le serveur/dépôt client de l'équipe de support). L'équipe du Hub peut alors programmer le déploiement dans l'environnement (potentiellement personnalisé) de l'opérateur du Hub. + +La stratégie QA employée par les équipes de livraison produit de Mojaloop et des produits d'extension garantit que le nouveau code de chaque composant de service a subi des tests complets avant sa publication. La stratégie QA de l'équipe de support Mojaloop, en revanche, doit se concentrer sur la validation de la déployabilité des composants de service intégrés et l'interopérabilité des produits, garantissant qu'il existe un switch Mojaloop fonctionnel, qui peut ensuite être déployé dans l'environnement d'un opérateur du Hub. + +## Processus de mise en production + +La recommandation pour les implémentations de Hub est de rester alignée sur la cadence de publication de Mojaloop d'une version par période PI et d'éviter de déployer des changements individuels directement depuis la branche master d'applications, composants ou services spécifiques au sein de Mojaloop. Cette recommandation garantit que l'intégrité des applications reste plus propre et alignée sur les dépôts sources. + +Pour chaque version, il est recommandé que l'équipe de support Mojaloop suive les étapes suivantes : + +::: tip NOTE +Les opérateurs du Hub doivent être informés de la date de publication cible bien à l'avance. +::: + +1. L'équipe de support Mojaloop examine tous les artefacts de version, y compris les notes de version et la documentation associée, et crée ou améliore le runbook de déploiement dès que la version est disponible. +1. L'équipe de support Mojaloop effectue le déploiement et la validation des versions planifiées de Mojaloop et d'autres produits dans un environnement de support Mojaloop temporaire (utilisant l'infrastructure de support Mojaloop standard mais correspondant aux versions d'applications du client – c'est-à-dire de l'opérateur du Hub). +1. Suite au déploiement et à la validation réussis d'une version sur l'infrastructure et l'architecture de support Mojaloop standard, et après avoir testé avec succès la dernière version de Mojaloop et des autres produits, la version est approuvée et mise à disposition de l'opérateur du Hub. +1. L'équipe de l'opérateur du Hub confirme la disponibilité (et éventuellement, la fenêtre de déploiement cible) pour le déploiement dans l'environnement de développement de l'opérateur du Hub. \ +\ +Il est de la responsabilité de l'opérateur du Hub d'effectuer le déploiement dans l'environnement de développement et la validation ultérieure. Alternativement, il peut demander au support Mojaloop d'effectuer ces activités en son nom. + +### Déploiements par l'équipe de support Mojaloop + +Si l'opérateur du Hub demande à l'équipe de support Mojaloop d'effectuer le déploiement dans l'environnement de développement de l'opérateur du Hub, alors l'équipe de support Mojaloop envoie un courriel (ou toute autre forme de communication selon les préférences de l'opérateur du Hub) avec des informations sur la date de publication cible, l'éventail des fonctionnalités incluses dans la version et la fenêtre de déploiement. Suite au déploiement, une communication supplémentaire est envoyée pour confirmer que le déploiement a été effectué, validé et que la fenêtre de déploiement est fermée. + +## Diagramme de flux du processus + + diff --git a/docs/fr/adoption/HubOperations/TechOps/service-level-agreements.md b/docs/fr/adoption/HubOperations/TechOps/service-level-agreements.md new file mode 100644 index 000000000..f71579142 --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/service-level-agreements.md @@ -0,0 +1,35 @@ +# Annexe B : Accords de niveau de service + +Les délais indiqués dans le tableau suivant sont des exemples de temps de réponse cibles pour le traitement des incidents. Ils peuvent servir de point de départ pour que l'opérateur du Hub définisse ses propres délais. + +::: tip NOTE +La réponse ne peut pas être une réponse automatisée. +::: + + + ++++ + + + + + + + + + + + + + + + + + + + + +
Exemples de délais de réponse aux incidents et SLA
Sévérité de l'incidentTemps de réponse cible

Sévérité 1

Dans les 2 heures

Sévérité 2

Dans les 4 heures ouvrées

Sévérité 3-4

Dans les 8 heures ouvrées

diff --git a/docs/fr/adoption/HubOperations/TechOps/tech-ops-introduction.md b/docs/fr/adoption/HubOperations/TechOps/tech-ops-introduction.md new file mode 100644 index 000000000..ab1ec7878 --- /dev/null +++ b/docs/fr/adoption/HubOperations/TechOps/tech-ops-introduction.md @@ -0,0 +1,31 @@ +# Introduction – Guide des opérations techniques + +Le Hub Mojaloop exploite un certain nombre d'environnements qui nécessitent une gestion et une maintenance quotidiennes. Les procédures standard décrites dans ce document présentent les processus opérationnels qui permettent à l'opérateur du Hub de gérer tous les aspects d'un service en production. + +Les procédures suivantes doivent être mises en place : + +- [**Gestion des incidents**](./incident-management.md) : Gestion des incidents qui ont été signalés à l'équipe des opérations techniques ou qui sont parvenus à l'équipe via des alertes ou des activités de surveillance. + +- [**Gestion des problèmes**](./problem-management.md) : Identification de la cause première des incidents ou des causes potentielles des incidents, et mise en œuvre immédiate d'actions pour améliorer ou corriger la situation. + +- [**Gestion des changements**](./change-management.md) : Contrôle du cycle de vie de tous les changements, permettant d'effectuer des modifications avec un minimum de perturbation des services informatiques. + +- [**Gestion des versions**](./release-management.md) : Gestion, planification, programmation et contrôle d'une modification logicielle à travers le déploiement et les tests dans divers environnements. + +- [**Triage des défauts**](./defect-triage.md) : S'assurer que tous les bogues identifiés dans l'environnement de production du client sont capturés, évalués, priorisés et soumis au Service Desk. + +Un aperçu rapide des environnements gérés par l'opérateur du Hub est fourni ci-dessous : + +- **Développement** : Environnement de développement logiciel hors production où le code OSS de Mojaloop est fusionné avec les personnalisations. Fournit aux développeurs un retour rapide sur les nouvelles soumissions de code. Les fournisseurs de services financiers numériques (DFSP) n'interagissent pas avec cet environnement. Accès réservé aux développeurs et au QA uniquement. + +- **Tests d'acceptation utilisateur (UAT)** : Environnement de test pour l'acceptation utilisateur et les tests de régression afin de valider les nouvelles versions. + +- **Bac à sable (SBX)** : Environnement de test pour valider la connectivité des DFSP en termes d'exigences API et de sécurité. + +- **Recette (STG)** : Environnement de recette qui reflète la production aussi fidèlement que possible. Validation des nouvelles versions et de l'onboarding des DFSP. + +- **Production (PRD)** : Environnement de production compatible avec la release en production. + +::: tip +Un [Glossaire](./key-terms-kpis.md) est fourni pour aider à clarifier les termes courants des opérations techniques utilisés dans ce document. Si vous rencontrez un terme nécessitant une explication, il est utile de consulter le glossaire pour vérifier si une définition a été fournie. +::: diff --git a/docs/fr/adoption/Scheme/platform-operating-guideline.md b/docs/fr/adoption/Scheme/platform-operating-guideline.md new file mode 100644 index 000000000..af6b36cdc --- /dev/null +++ b/docs/fr/adoption/Scheme/platform-operating-guideline.md @@ -0,0 +1,553 @@ +# Modèle de directive opérationnelle de la plateforme + +- Version : 2.0 + - Auteur : Carol Coye Benson (Glenbrook), Michael Richards (ModusBox) + - Date : Octobre 2019 + - Description : + +--- + +## **À propos du projet de documents métier de la communauté Mojaloop** + +Ce document fait partie du projet de documents métier de la communauté Mojaloop. Le projet est destiné à soutenir les entités (pays, régions, associations de fournisseurs ou entreprises commerciales) mettant en œuvre de nouveaux systèmes de paiement utilisant le code Mojaloop. Ces entités devront également rédiger des règles métier que les participants au système suivront. + +Le projet de documents métier de la communauté Mojaloop fournit des modèles pour les règles métier et les documents associés. De nombreux choix sont impliqués dans la mise en œuvre d'un nouveau système de paiement : les modèles présentent certains de ces choix et, le cas échéant, des commentaires sont fournis sur la manière dont le choix particulier est lié aux objectifs d'un système conforme Level One. + +Les documents suivants font partie du projet : + +- Choix clés du schéma + +- Modèle d'accord de participation au schéma + +- Modèle de règles métier du schéma + +- Modèle de directive opérationnelle de la plateforme + +- Modèle de directive opérationnelle de gestion des exceptions + +- Glossaire standard + +## **Introduction** + +Un schéma mettant en œuvre un système conforme Level One, y compris ceux utilisant le code de référence Mojaloop dans la plateforme, devra rédiger des règles métier pour le schéma. Un modèle pour ces règles métier est inclus dans ce projet. Les règles métier introduisent le concept de documents associés, qui font partie des règles métier et ont la même force — les DFSP signant les règles métier sont également tenus de suivre les dispositions des documents associés. + +La directive opérationnelle de la plateforme est un document associé important qui décrit comment la plateforme du schéma fonctionnera et précise les obligations et responsabilités du schéma, de l'opérateur de la plateforme et des DFSP. + +Ce document est un modèle pour une telle directive opérationnelle de la plateforme. Cependant, de nombreuses dispositions varieront en fonction des choix effectués par le schéma : certains de ces choix sont décrits dans le document « Choix clés du schéma » qui fait partie de ce projet. + +Le modèle de règles métier qui fait partie de ce projet peut être utilisé indépendamment du choix de plateforme d'un schéma. Cette directive opérationnelle de la plateforme est plus spécifique à l'utilisation de Mojaloop comme plateforme. + +## **Table des matières — Modèle de directive opérationnelle de la plateforme** + +[1 - À propos de ce document](#_1-a-propos-de-ce-document) + +[1.1 - Services du schéma](#_1-1-services-du-schema) + +[1.2 - Spécification Open API](#_1-2-specification-open-api) + +[1.3 - Cas d'utilisation du schéma](#_1-3-cas-d-utilisation-du-schema) + +[1.4 - Identifiants pris en charge par le schéma](#_1-4-identifiants-pris-en-charge-par-le-schema) + +[2 - Le service de recherche de compte](#_2-le-service-de-recherche-de-compte) + +[2.1 - Description du service de recherche de compte](#_2-1-description-du-service-de-recherche-de-compte) + +[2.2 - Requête de partie](#_2-2-requete-de-partie) + +[2.3 - Requête Parties](#_2-3-requete-parties) + +[2.4 - Réponse à la requête Parties](#_2-4-reponse-a-la-requete-parties) + +[3 - Le service de devis](#_3-le-service-de-devis) + +[3.1 - Description du service de devis](#_3-1-description-du-service-de-devis) + +[3.2 - Demande de devis](#_3-2-demande-de-devis) + +[3.3 - Réponse au devis](#_3-3-reponse-au-devis) + +[4 - Le service de transfert](#_4-le-service-de-transfert) + +[4.1 - Description du service de transfert](#_4-1-description-du-service-de-transfert) + +[4.2 - Demande de transfert](#_4-2-demande-de-transfert) + +[4.3 - Request to pay](#_4-3-request-to-pay) + +[5 - Le service de règlement](#_5-le-service-de-reglement) + +[5.1 - Règlement des transferts](#_5-1-reglement-des-transferts) + +[5.2 - Règlement des frais : frais de traitement](#_5-2-reglement-des-frais-frais-de-traitement) + +[5.3 - Règlement des frais : frais d'interchange](#_5-3-reglement-des-frais-frais-d-interchange) + +[6 - Le service de gestion du schéma](#_6-le-service-de-gestion-du-schema) + +[6.1 - Description du service de gestion du schéma](#_6-1-description-du-service-de-gestion-du-schema) + +[6.2 - Le processus d'inscription](#_6-2-le-processus-d-inscription) + +[6.3 - Service client DFSP](#_6-3-service-client-dfsp) + +[6.4 - Gestion du système du schéma](#_6-4-gestion-du-systeme-du-schema) + +[7 - Le service de gestion de la fraude](#_7-le-service-de-gestion-de-la-fraude) + +[8 - Annexe : Cas d'utilisation pris en charge par le schéma et paramètres système](#_8-annexe-cas-d-utilisation-pris-en-charge-par-le-schema-et-parametres-systeme) + +[9 - Annexe : Codes de catégorie de commerçants](#_9-annexe-codes-de-categorie-de-commercants) + +## 1. À propos de ce document + +Ces directives opérationnelles de la plateforme spécifient les exigences opérationnelles et techniques pour les DFSP et pour le schéma. De temps à autre, le schéma publiera des bulletins opérationnels supplémentaires, qui décriront des fonctionnalités opérationnelles supplémentaires du schéma et spécifieront des exigences supplémentaires pour les DFSP. + +### 1.1 Services du schéma + +- Les services du schéma sont utilisés par les DFSP pour échanger des transactions interopérables et pour gérer leur participation au schéma. + +- Le service de recherche de compte du schéma permet aux DFSP du système d'identifier le DFSP qui gère le compte de transaction d'un bénéficiaire prévu ou d'une autre contrepartie à un transfert. + +- Le service de transfert du schéma permet à un DFSP payeur d'envoyer un transfert à un DFSP bénéficiaire, effectuant ainsi un transfert de fonds d'un payeur à un bénéficiaire. + +- Le service de règlement du schéma permet aux DFSP de régler leurs obligations financières envers le schéma en ce qui concerne les transferts. + +- Le service de gestion du schéma permet au schéma d'accorder et de révoquer l'accès au schéma par les DFSP, gère les interactions continues des DFSP avec le schéma, surveille le fonctionnement efficace du schéma et fournit des outils aux DFSP pour gérer leur participation au schéma. + +- Le service de gestion de la fraude du schéma permet aux DFSP de collaborer sur certains éléments de la gestion de la fraude afin de réduire les coûts et d'améliorer les résultats. + +- Les DFSP sont tenus de suivre les procédures détaillées ci-dessous pour l'utilisation du schéma. + +### 1.2 Spécification Open API + +Les protocoles du schéma sont basés sur les modèles opérationnels et de données définis dans le document de spécifications « Open API for FSP Interoperability Specification » version 1.0 daté du \[xx\]. Lorsque le schéma s'écarte de cette spécification, ces écarts sont documentés ici et remplaceront les sections pertinentes de ce document. Le schéma peut mettre à jour la version utilisée en publiant un bulletin opérationnel. + +### 1.3 Cas d'utilisation du schéma + +Certaines règles et spécifications opérationnelles varient selon les cas d'utilisation et les cas d'utilisation secondaires pris en charge par le schéma. Le schéma reconnaît les cas d'utilisation et les cas d'utilisation secondaires par une combinaison de composants de données requis et d'inférence système. Cela est détaillé dans une annexe à ce document. + +### 1.4 Identifiants pris en charge par le schéma + +Le schéma prend en charge certains identifiants, ou adresses de paiement, à utiliser pour effectuer des transferts. L'identifiant identifie le bénéficiaire dont le compte de transaction est crédité pour le transfert. Les identifiants pris en charge par le schéma sont répertoriés dans une annexe aux règles métier. + +Pour chaque identifiant pris en charge par le schéma, ce document doit spécifier ce qu'est l'identifiant et comment il est résolu (comment il est déterminé quel DFSP bénéficiaire est responsable du compte de transaction associé à cet identifiant). + +#### 1.4.1 Exemple : L'identifiant MSISDN + +Chaque schéma aura ses propres directives pour chaque identifiant ; les dispositions ci-dessous pourraient varier considérablement en fonction des choix effectués. + +- Les MSISDN sont des numéros mobiles qui sont globalement uniques. Les MSISDN sont l'identifiant de compte de transaction pour les DFSP qui sont des opérateurs de réseau mobile et qui fournissent des comptes de transaction à leurs clients. + +- L'utilisation du MSISDN comme identifiant de bénéficiaire est limitée aux comptes de transaction fournis par les DFSP qui sont l'opérateur de réseau mobile responsable de ce MSISDN. + +::: tip NOTE +Si les MSISDN sont utilisés pour d'autres comptes de transaction, ce sont des alias, et un protocole distinct pour les résoudre doit être spécifié. +::: + +- Une requête de partie pour un MSISDN est résolue par un service de répertoire MSISDN déterminé par le schéma. Le schéma peut spécifier des obligations de maintenance du service de répertoire pour les DFSP opérateurs de réseau mobile de temps à autre. + +#### 1.4.2 Exemple : L'identifiant du numéro de compte bancaire + +Chaque schéma aura ses propres directives pour chaque identifiant ; les dispositions ci-dessous pourraient varier considérablement en fonction des choix effectués. + +- Les numéros de compte bancaire sont attribués aux clients par les DFSP bancaires qui fournissent des comptes de transaction à leurs clients. + +- Le numéro de compte bancaire, associé à un code bancaire, forme l'identifiant de numéro de compte bancaire du schéma. Les DFSP payeurs sont responsables du formatage correct de l'identifiant de numéro de compte bancaire selon les formats qui seront spécifiés par le schéma. + +- L'utilisation de l'identifiant de numéro de compte bancaire est limitée aux comptes de transaction fournis par les DFSP qui sont des banques. + +- Une requête de partie pour un identifiant de compte bancaire est envoyée par le DFSP payeur au schéma. Le schéma vérifie que le code bancaire dans l'identifiant de compte bancaire est associé à une banque active dans le schéma. + +#### 1.4.3 Exemple : L'identifiant commerçant du schéma + +Chaque schéma aura ses propres directives pour chaque identifiant ; les dispositions ci-dessous pourraient varier considérablement en fonction des choix effectués. + +- L'identifiant commerçant est un identifiant défini par le schéma utilisé pour les paiements de personne à entreprise. + +- L'utilisation de l'identifiant commerçant est limitée aux DFSP qui fournissent des comptes de transaction aux commerçants, émetteurs de factures, agences gouvernementales ou autres entités commerciales qui reçoivent des paiements de leurs clients via le schéma. Il peut être utilisé pour les paiements en personne et à distance. Le terme « commerçant » utilisé dans cette section inclut tous ces types de receveurs de paiements. + +- L'utilisation de l'identifiant commerçant est limitée aux transferts des cas d'utilisation P2B ou P2G. + +- Un commerçant peut demander plusieurs identifiants commerçant à son DFSP ; ceux-ci peuvent être utilisés par le commerçant pour différents points de vente, caisses ou magasins. Il n'y a pas de limite au nombre d'identifiants commerçant pouvant être liés à un seul compte de transaction. Cependant, un identifiant commerçant donné ne peut être lié qu'à un seul compte de transaction. + +- L'identifiant commerçant est émis par le schéma au DFSP qui fournit au commerçant le compte de transaction dans lequel les paiements seront effectués. + +- L'identifiant commerçant est émis sous forme de numéro, qui peut être affiché par un commerçant physiquement ou numériquement. + +- Les identifiants commerçant peuvent être rendus sous forme de codes QR par les DFSP ou leurs clients commerçants. Les codes QR doivent être rendus selon les directives de format et de marque qui seront publiées par le schéma. Il est interdit aux DFSP d'utiliser d'autres formats de données de code QR ou marques pour recevoir des paiements via le schéma. + +- Les DFSP sont tenus d'afficher la marque du schéma. Les exigences de marque du schéma seront spécifiées par le schéma. La marque du schéma doit être visible pour le client dans le magasin du commerçant, ou sur l'appareil que le client payeur utilise pour acheter à distance. + +- Exigences d'inscription. Les DFSP demanderont un identifiant commerçant pour un client en utilisant une API du schéma spécifique à cet effet. Les DFSP devront fournir : + + - Identifiant DFSP + + - Le numéro de compte de transaction qui recevra les fonds payés au commerçant. Il peut s'agir soit d'un MSISDN, soit d'un numéro de compte bancaire. + + - Le \[numéro d'enregistrement commercial ou d'identification fiscale\] du commerçant. N'importe quel nombre d'identifiants commerçant peut être associé au même numéro d'enregistrement commercial ou d'identification fiscale. + + - Le nom du commerçant + +- Les DFSP demandant un identifiant commerçant au schéma garantissent qu'ils ont complété les informations KYC requises pour le compte du commerçant au moment de la demande. + +- Les DFSP sont tenus de fournir des informations de formation adéquates à leurs clients. + +- Désactivation des identifiants commerçant. Les DFSP peuvent demander la désactivation d'un identifiant commerçant. Le schéma désactivera immédiatement cet identifiant commerçant, mais le conservera dans le système du schéma à des fins de reporting. Les demandes de devis ou les demandes de transfert effectuées vers cet identifiant commerçant seront refusées par le schéma et renvoyées au DFSP payeur. + +Le schéma peut souhaiter fournir un mécanisme permettant le portage d'un identifiant commerçant d'un DFSP à un autre. + +#### 1.4.4 L'identifiant Scheme ID + +Cet identifiant serait similaire à l'identifiant commerçant ci-dessus mais serait destiné aux consommateurs ainsi qu'aux entreprises, et pourrait être exprimé en phrases plutôt qu'en numéro. Notez que chaque schéma aura ses propres directives pour chaque identifiant ; les dispositions ci-dessous pourraient varier considérablement en fonction des choix effectués. + +- Le Scheme ID est un identifiant défini par le schéma. + +- Les DFSP sont tenus d'offrir à leurs clients l'option de demander un Scheme ID. + +- Les Scheme ID peuvent prendre n'importe quelle forme, sous réserve uniquement de restrictions de longueur que le schéma spécifiera de temps à autre. Le schéma se réserve le droit de refuser l'utilisation de tout Scheme ID spécifique demandé. + +Les schémas peuvent souhaiter activer les Scheme ID. + +- Les clients peuvent demander un nombre quelconque de Scheme ID, sous réserve des limites imposées par leur DFSP. Plusieurs Scheme ID peuvent être associés à un seul compte de transaction. Cependant, chaque Scheme ID ne peut être associé qu'à un seul compte de transaction. + +- Exigences d'inscription. Les DFSP demanderont un Scheme ID pour un client en utilisant une API du schéma spécifique à cet effet. Les DFSP devront fournir dans cette API : + + - Identifiant DFSP + + - Le Scheme ID demandé + + - Le numéro de compte de transaction qui recevra les fonds payés au client. Il peut s'agir soit d'un MSISDN, soit d'un numéro de compte bancaire. + + - Si le titulaire du compte de transaction est un commerçant ou une entreprise, le \[numéro d'enregistrement commercial ou d'identification fiscale\] du titulaire du compte. N'importe quel nombre de Scheme ID peut être associé au même numéro d'enregistrement commercial ou d'identification fiscale. + +- Les DFSP demandant un Scheme ID au schéma garantissent qu'ils ont complété les informations KYC requises pour le compte du client au moment de la demande. + +- Désactivation des identifiants du schéma. Les DFSP peuvent demander la désactivation d'un Scheme ID. Le schéma désactivera immédiatement ce Scheme ID, mais le conservera dans le système du schéma à des fins de reporting. Les demandes de devis ou les demandes de transfert effectuées vers ce Scheme ID seront refusées par le schéma et renvoyées au DFSP payeur. + +Le schéma peut souhaiter fournir un mécanisme permettant le portage d'un Scheme ID d'un DFSP à un autre. + +Les sections suivantes décrivent chaque service ainsi que les obligations et responsabilités des parties prenantes. Chaque service est composé de processus : la plupart des processus sont liés à des appels API spécifiques spécifiés dans la section [Spécification Open API](#_1-2-specification-open-api) de ce document. + +## 2. Le service de recherche de compte + +### 2.1 Description du service de recherche de compte + +- Le service de recherche de compte permet aux DFSP de faire correspondre des identifiants spécifiques pour des clients individuels au DFSP qui fournit un compte de transaction pour ce client. Les identifiants sont utilisés pour identifier des individus, commerçants, émetteurs de factures, agences gouvernementales ou autres entreprises. Tout type d'identifiant pris en charge par le schéma dispose d'un service d'identifiant défini, dont les paramètres sont indiqués dans la section « Identifiants pris en charge par le schéma » de ce document. + +- Tous les services d'identifiant garantissent que les identifiants utilisés pour les transactions du schéma sont uniques au sein du schéma et sont associés à un seul DFSP qui fournit le compte de transaction pertinent pour ce client. Tout identifiant doit être associé à un seul compte de transaction. + +- Les DFSP doivent compléter le processus de recherche de compte immédiatement avant d'initier un processus de devis, sauf autorisation contraire dans ces directives. + +### 2.2 Requête de partie + +- Une requête de partie est envoyée par un DFSP payeur à la plateforme. La requête de partie doit contenir les éléments de données clés suivants : + + - L'identifiant du bénéficiaire prévu + + - L'identifiant du DFSP payeur + +Le schéma peut définir des éléments de données clés supplémentaires qui seront requis dans la requête de partie. + +- La requête est transmise de la plateforme au service de recherche de compte pour ce type d'identifiant. + +- Le service d'identifiant renvoie au service de recherche de compte l'identification du DFSP associé à cet identifiant, si une référence est trouvée. Si ce n'est pas le cas, une réponse négative est renvoyée et cela est communiqué par la plateforme au DFSP payeur. Si une référence est trouvée, le service de recherche de compte associe alors le DFSP identifié à l'identifiant DFSP correct du schéma. + +### 2.3 Requête Parties + +- Si la requête de partie réussit à identifier un DFSP bénéficiaire, la plateforme exécute alors une requête Parties au DFSP identifié pour déterminer si le DFSP est disposé à accepter une demande de devis dirigée vers cet identifiant. + +### 2.4 Réponse à la requête Parties + +- Le DFSP identifié répond soit avec une réponse positive à la requête Parties, soit avec une réponse d'erreur. Si positive, la réponse à la requête Parties doit contenir les éléments de données clés suivants : + + - Le nom complet du bénéficiaire + + - L'identifiant du DFSP payeur + + - Le type de compte de transaction, qui précise si le compte est un compte bancaire ou un portefeuille + + - Le type de titulaire du compte de transaction, qui précise si le titulaire du compte de transaction est un consommateur, un commerçant (y compris d'autres types d'entreprises) ou une agence gouvernementale. + + - Si le bénéficiaire est un commerçant, le code de catégorie de commerçant. Ces codes se trouvent dans une annexe à ce document. + +Le schéma peut définir des éléments de données supplémentaires requis dans la réponse à la requête Parties. + +- La plateforme répond au DFSP payeur avec le résultat de la réponse à la requête Parties + +## 3. Le service de devis + +#### 3.1 Description du service de devis + +- Le processus de devis précède le processus de transfert et permet au DFSP payeur et au DFSP bénéficiaire d'échanger certaines informations avant le transfert. + +- Le processus de devis doit être complété avant qu'un DFSP payeur n'initie le processus de transfert. Cela est vrai pour tous les cas d'utilisation et cas d'utilisation secondaires. + +- Les étapes du processus de devis sont présentées ci-dessous. + +#### 3.2 Demande de devis + +- Une demande de devis est envoyée par un DFSP payeur au DFSP bénéficiaire ; la demande de devis est enregistrée par la plateforme. La demande de devis doit contenir les éléments de données clés suivants : + + - Le montant du transfert + + - Le type de montant défini comme montant d'envoi. + + - L'ensemble complet des informations de partie renvoyées par la réponse à la requête Parties. + + - Le nom complet du payeur (le titulaire du compte de transaction au DFSP payeur) + + - Les données de type de transaction requises pour le cas d'utilisation et le cas d'utilisation secondaire de la transaction, comme spécifié dans l'annexe des cas d'utilisation de ce document. + + - Un délai d'expiration, dont les paramètres autorisés seront spécifiés par le schéma de temps à autre. + +Le schéma peut définir des éléments de données clés supplémentaires qui seront requis dans la réponse à la requête Parties. + +- Une demande de devis pour un montant supérieur à la limite de valeur de transaction du schéma sera rejetée par la plateforme et renvoyée au DFSP payeur. + +### 3.3 Réponse au devis + +- Une réponse au devis est envoyée par le DFSP bénéficiaire au DFSP payeur ; la réponse au devis est enregistrée par la plateforme. Le DFSP bénéficiaire est tenu de répondre à une demande de devis. + +- La réponse au devis doit contenir les éléments de données clés suivants : + + - Le montant du transfert + + - Un délai d'expiration, dont les paramètres autorisés seront spécifiés par le schéma de temps à autre. + + - L'objet de transaction signé qui contient les paramètres du transfert. L'objet de transaction est la description faisant autorité de la transaction aux fins du reporting du schéma, de la gestion de la fraude et de la résolution des litiges. + +Le schéma peut définir des éléments de données clés supplémentaires qui seront requis dans la réponse à la requête Parties. + +- La réponse au devis est signée par le DFSP bénéficiaire et définit les paramètres de la transaction ; le DFSP payeur ne peut pas modifier ces paramètres dans le processus de transfert. + +## 4. Le service de transfert + +### 4.1 Description du service de transfert + +- Le service de transfert est le moyen par lequel le transfert effectif de fonds est accompli entre le DFSP payeur et le DFSP bénéficiaire. La demande de transfert est le processus clé au sein du service. Une demande de transfert doit être précédée d'un processus de devis. + +### 4.2 Demande de transfert + +- Une demande de transfert est envoyée par un DFSP payeur au DFSP bénéficiaire via le service de transfert du schéma. La plateforme enregistre la demande de transfert. La demande de transfert doit contenir les éléments de données clés suivants : + + - Les identifiants du DFSP payeur et du DFSP bénéficiaire + + - Le montant de la transaction + + - Un paquet ILP représentant l'objet de transaction + + - Un délai d'expiration, dont les paramètres autorisés seront spécifiés par le schéma de temps à autre. + +Le schéma peut définir des éléments de données clés supplémentaires qui seront requis dans la demande de transfert. + +- La demande de transfert est signée par le DFSP payeur + +- La plateforme effectue un processus d'approbation de transfert pour déterminer si le transfert proposé peut être réglé. Le processus d'approbation de transfert est défini plus en détail dans la section du service de règlement de ce document. + +- Si la demande de transfert échoue au processus d'approbation de transfert, la demande de transfert est renvoyée au DFSP payeur. + +- Si la demande de transfert réussit le processus d'approbation de transfert, la plateforme réserve les fonds spécifiés dans la demande de transfert dans le grand livre de position du DFSP payeur. Cela est défini plus en détail dans la section du service de règlement de ce document. + +- Le DFSP bénéficiaire détermine s'il acceptera le transfert. + +- S'il n'est pas accepté, une réponse d'erreur est renvoyée à la plateforme. La plateforme libère la réservation de fonds dans le grand livre de position du DFSP payeur et renvoie une condition d'erreur au DFSP payeur. + +- S'il est accepté, le DFSP bénéficiaire renvoie une réponse de transfert signée indiquant que le transfert a été exécuté. La plateforme remplace le débit provisoire par un débit dans le grand livre de position du DFSP payeur et crédite le grand livre de position du DFSP bénéficiaire d'un crédit du montant du transfert. + +- La plateforme envoie ensuite une confirmation du transfert exécuté au DFSP payeur et au DFSP bénéficiaire. + +- Si la plateforme ne reçoit pas de réponse de transfert signée dans le délai d'expiration de la demande de transfert, le transfert sera annulé et le schéma en informera les DFSP bénéficiaire et payeur. + +- Les DFSP payeurs et bénéficiaires sont tenus : + + - De notifier leurs clients de l'état d'un transfert en temps opportun + + - De débiter et créditer immédiatement les comptes de transaction de leurs clients lors de l'exécution du transfert + + - De libérer immédiatement tout fonds réservé si un transfert a été refusé ou annulé + +### 4.3 Request to pay + +_Cette section n'a pas encore été rédigée._ + +## 5. Le service de règlement + +Ce document présente un modèle pour les processus de règlement tant pour les transferts que pour les frais du schéma. Il existe de multiples approches possibles pour le règlement, qui sont discutées dans le document « Choix clés » qui fait partie de ce projet. Le modèle ci-dessous couvre deux modèles : le règlement net et le règlement brut continu. Le code de référence Mojaloop prend en charge un certain nombre de modèles de règlement différents, y compris ceux-ci. + +### 5.1 Règlement des transferts + +#### 5.1.1 Description du service de règlement des transferts + +- Le règlement des transferts est le moyen par lequel les DFSP règlent leurs obligations financières les uns envers les autres. Il y a cinq processus dans le règlement des transferts : le processus de grand livre, le processus de plafond de débit net, le processus d'approbation de transfert, le processus de comptabilisation du règlement et le processus de gestion du compte de règlement. + +- \[_Option de règlement net_\] Les DFSP sont tenus d'ouvrir un compte bancaire de règlement auprès de la banque de règlement du schéma. \[_Option de règlement brut continu_\] Les DFSP sont tenus de devenir copropriétaires du compte bancaire de règlement mutualisé du schéma auprès de la banque de règlement du schéma, et d'utiliser ou d'ouvrir tout autre compte bancaire individuel auprès de la banque de règlement du schéma si nécessaire pour transférer des fonds vers et depuis le compte bancaire de règlement mutualisé du schéma. + +#### 5.1.2 Le grand livre de la plateforme + +- La plateforme est responsable du maintien d'un grand livre de position DFSP pour chaque DFSP. Cette opération fonctionne en continu. \[_Option de règlement brut continu_\] Le grand livre de position DFSP de chaque DFSP, moins les écritures provisoires, représente la part de propriété de ce DFSP dans le compte bancaire de règlement mutualisé du schéma. + +- Le grand livre de position enregistre : + + - Tous les transferts exécutés comme débits dans le grand livre du DFSP payeur et crédits dans le grand livre du DFSP bénéficiaire + + - Toutes les demandes de transfert comme débits provisoires dans le grand livre du DFSP payeur. Ces débits provisoires sont supprimés lorsque le transfert est exécuté, refusé par le DFSP bénéficiaire ou expire. + + - \[_Option de règlement net uniquement_\] Les écritures de règlement livrées et acceptées par la banque de règlement du schéma pour ce DFSP. + + - \[_Option de règlement brut continu uniquement_\] Les transferts vers et depuis le compte bancaire de règlement mutualisé du schéma effectués par les DFSP. + +- La position du grand livre DFSP est la somme de tous les éléments énumérés ci-dessus. Cela est utilisé dans le processus d'approbation de transfert. + +#### 5.1.3 Processus de plafond de débit net + +- Le plafond de débit net d'un DFSP est une valeur que la plateforme utilise pendant le processus d'approbation de transfert. Le débit net d'un DFSP est la somme de : + + - \[_Option de règlement net uniquement_\] Une valeur fixée par le schéma qui est destinée à représenter les fonds que le DFSP a disponibles sur son compte bancaire de règlement + +Notez que le schéma peut être en mesure d'automatiser le calcul de la valeur décrite ci-dessus, ou il peut choisir de la saisir manuellement dans la section Opérateur de la plateforme du portail du schéma. + +- La marge du schéma pour ce DFSP. Il s'agit d'une valeur, déterminée par le schéma, qui est spécifique à un DFSP donné. Cette valeur peut être un pourcentage de la position du grand livre DFSP ou peut être une valeur absolue. Le schéma peut modifier la marge du schéma pour tout DFSP à sa discrétion. Elle peut avoir pour effet d'augmenter ou de diminuer la capacité d'un DFSP à exécuter des transactions. + +- La marge discrétionnaire du DFSP. Il s'agit d'une valeur, déterminée par un DFSP individuel, qui diminue la valeur absolue du plafond de débit net. La marge discrétionnaire du DFSP est fixée dans les paramètres autorisés définis par le schéma. Cela a pour effet de diminuer la capacité du DFSP à exécuter des transactions. + +#### 5.1.4 Processus d'approbation de transfert + +- Approbation de transfert. Lorsque la plateforme reçoit une demande de transfert d'un DFSP payeur, la plateforme approuvera ou rejettera la demande sur la base d'une comparaison du montant du transfert demandé avec la position actuelle du grand livre du DFSP payeur moins le plafond de débit net du DFSP payeur. + +- Si le transfert demandé est inférieur à cette somme, la plateforme transmettra la demande au DFSP bénéficiaire. S'il est supérieur à la valeur du plafond de débit net, la plateforme rejettera la demande et la renverra au DFSP payeur. + +#### 5.1.5 Processus de comptabilisation du règlement + +- \[_Option de règlement net uniquement_\] Le schéma définira les paramètres des fenêtres de règlement utilisées pour le schéma ; cela inclura la fréquence des fenêtres ou d'autres paramètres (limites de valeur, etc.) choisis pour définir les fenêtres de règlement. + +- \[_Option de règlement net uniquement_\] À la fin de chaque fenêtre de règlement définie, la plateforme calculera la position nette de règlement de chaque DFSP : cette position est le solde du grand livre de position DFSP. Ces soldes deviennent les écritures de règlement pour cette fenêtre. + +- \[_Option de règlement net uniquement_\] La plateforme enverra les écritures de règlement pour chaque DFSP à la banque de règlement choisie par le schéma. + +- \[_Option de règlement net uniquement_\] La banque de règlement comptabilisera les écritures de règlement sur le compte bancaire de règlement de chaque DFSP, et enverra une confirmation à la plateforme de l'achèvement de ce processus. + +Les règles de schéma devront tenir compte des dispositions et procédures en cas d'échec du processus décrit ci-dessus. + +#### 5.1.6 Processus de gestion du compte de règlement + +- \[_Option de règlement net_\] Les DFSP peuvent ajouter des fonds à leur compte bancaire de règlement du schéma à leur discrétion. Le schéma fournira des instructions sur la manière de procéder. \[_Option de règlement brut continu_\] Les DFSP peuvent transférer des fonds vers le compte bancaire de règlement mutualisé du schéma à leur discrétion. Le schéma fournira des instructions sur la manière de procéder. + +- \[_Option de règlement brut continu uniquement_\] Le schéma fournira un rapport de fin de journée aux DFSP montrant leur part de propriété dans le compte bancaire de règlement mutualisé du schéma. + +- Les DFSP peuvent demander le retrait de fonds de leur \[_Option de règlement net_\] compte bancaire de règlement via le portail du schéma. \[_Option de règlement brut continu_\] Les DFSP peuvent demander le retrait de fonds du compte bancaire de règlement mutualisé du schéma via le portail du schéma. Le schéma examinera le retrait demandé et, s'il est approuvé, exécutera le transfert pour le compte du DFSP. L'objectif de cet examen est de s'assurer que la part du DFSP dans le compte bancaire de règlement est suffisante pour prendre en charge les transferts en cours : cette approbation ne sera pas refusée de manière déraisonnable. + +#### 5.1.7 Rapports de règlement du schéma + +- Le schéma fournira, via le portail DFSP du schéma, des informations aux DFSP qui incluent pour chaque DFSP : + + - Le plafond de débit net actuel et ses composantes + + - La position actuelle du grand livre et ses composantes, y compris les transferts exécutés pour tous les DFSP et les transferts provisoires pour les DFSP payeurs + + - Des alertes à certains niveaux de la position actuelle du grand livre : ces niveaux seront déterminés par les DFSP et/ou le schéma de temps à autre + +- Des outils pour permettre aux DFSP de prévoir leur volume de transfert anticipé sur la base de données historiques + +### 5.2 Règlement des frais : frais de traitement + +Cette section n'a pas encore été rédigée. + +### 5.3 Règlement des frais : frais d'interchange + +Cette section n'a pas encore été rédigée. + +## 6. Le service de gestion du schéma + +::: tip NOTE +Il existe un service parallèle d'opérateur de plateforme nécessaire au fonctionnement de la plateforme qui n'est pas décrit dans ce document. +::: + +### 6.1 Description du service de gestion du schéma + +- Le service de gestion du schéma est fourni par le schéma pour aider les DFSP dans leur utilisation des services du schéma. Bon nombre de ces fonctions sont fournies via le portail du schéma, qui est mis à la disposition des DFSP du schéma. + +- Les processus suivants font partie du service de gestion du schéma : + +### 6.2 Le processus d'inscription + +- Le processus d'inscription permet la demande de participation d'un DFSP et l'intégration opérationnelle et technique. Il couvre les domaines suivants : + + - Formulaires et processus de demande de participation d'un DFSP au schéma. + + - Formulaires et processus d'obtention de certificats numériques et de signatures numériques pour une utilisation avec la plateforme. + + - Processus de téléchargement des artefacts logiciels fournis par le schéma, y compris les SDK et les API. + + - Processus de test de la préparation technique pour accéder à la plateforme et aux services. + + - Processus de réception de l'approbation et de la certification du schéma pour l'accès à la plateforme et aux services. + +### 6.3 Service client DFSP + +- Le schéma fournira un service d'assistance en ligne et téléphonique pour les DFSP. + +- Le portail du schéma fournira des moyens par lesquels les DFSP peuvent désigner des administrateurs et des utilisateurs du portail, et mettre à jour les informations du profil DFSP. + +### 6.4 Gestion du système du schéma + +- Le schéma fournira, via le portail du schéma, des moyens par lesquels les DFSP peuvent consulter leur grand livre de position actuel, leur plafond de débit net et leur activité récente et historique avec le schéma. + +- Le schéma fournira, via le portail du schéma, des moyens par lesquels les DFSP peuvent utiliser les données historiques, y compris leurs positions et historiques de plafond de débit net, pour prévoir les volumes à venir et les niveaux de financement de règlement requis. + +- Le schéma fournira des moyens par lesquels les DFSP peuvent obtenir des mises à jour des artefacts logiciels qu'ils ont précédemment téléchargés. + +- Le schéma fournira, via le portail du schéma, des moyens par lesquels les DFSP peuvent demander un retrait de leur part du compte bancaire de règlement du schéma. + +- Le schéma fournira, via le portail du schéma, des moyens par lesquels les DFSP peuvent consulter leur part du solde du compte bancaire de règlement du schéma. + +## 7. Le service de gestion de la fraude + +_Cette section n'a pas encore été rédigée, mais devrait inclure les sections suivantes :_ + +1. _Description de l'utilitaire de gestion de la fraude — Objet et portée_ + +2. _La base de données de transactions partagée_ + +3. _Schéma de catégorisation de la fraude_ + +4. _Signalement des acteurs ou transactions connus comme malveillants_ + +5. _Algorithmes et processus de détection des anomalies et de la fraude_ + +6. _Rapports DFSP_ + +7. _Options d'interception de transactions en temps réel_ + +## 8. Annexe : Cas d'utilisation pris en charge par le schéma et paramètres système + +_Il s'agit du même tableau que celui qui apparaît dans le document des règles métier, mais il a ajouté les codes systémiques nécessaires pour que la plateforme reconnaisse une transaction comme appartenant à un cas d'utilisation ou un cas d'utilisation secondaire donné. Un schéma ne définirait des cas d'utilisation secondaires que s'il souhaitait rédiger des règles et/ou spécifier des frais propres à ce cas d'utilisation secondaire._ + +_Ce tableau est un exemple de tableau de cas d'utilisation et de cas d'utilisation secondaires qu'un schéma pourrait prendre en charge._ + +| Code du cas d'utilisation | Cas d'utilisation | Cas d'utilisation secondaire | Éléments de données requis | Autres méthodes de détermination du cas d'utilisation | +| :--- | :----- | :--------- | :-------------------------- | :------------------------------------------- | +| 1.0 | P2P | Personne à personne | Paramètre API
Scenario=Transfer

Initiator = Payer

Initiator Type = Consumer

Recipient Type = Consumer
| | +| 1.1 | P2P | Portefeuille à portefeuille | Le type de compte de transaction pour le DFSP payeur est Portefeuille et pour le DFSP bénéficiaire est Portefeuille | +| 1.2 | P2P | Banque à banque | Le type de compte de transaction pour le DFSP payeur est Banque et pour le DFSP bénéficiaire est Portefeuille | +| 1.3 | P2P | Portefeuille à banque | Le type de compte de transaction pour le DFSP payeur est Portefeuille et pour le DFSP bénéficiaire est Banque | +| 1.4 | P2P | Banque à portefeuille | Le type de compte de transaction pour le DFSP payeur est Banque et pour le DFSP bénéficiaire est Portefeuille. | +| 2.0 | Paiement en masse | | Paramètres API
Scenario=Transfer

Initiator = Payer

Recipient Type = Consumer
| +| 2.1 | B2P | Banque à banque | Initiator Type = Business | +| 2.2 | G2P | Gouvernement à personne | Initiator Type = Government | +| 3.0 | P2B | Personne à entreprise | Paramètres API
Scenario=Transfer

Initiator = Payer

Initiator Type = Consumer

Recipient Type = Business
| +| 3.1 | P2B | Achat par numéro de caisse | Initiator Type = Device | | +| 3.2 | P2B | Achat par code QR | à déterminer | | +| 3.3 | P2B | Achat en ligne | Merchant ID Code = à déterminer | | +| 3.4 | P2B | Paiement de facture | | à déterminer : un élément de données dans la demande de devis inclura le numéro de compte du payeur chez l'émetteur de factures | +| 3.5 | P2B | Personne à entreprise - Autre | | | +| 4.0 | P2G | | Paramètres API
Scenario=Transfer

Initiator = Payer

Recipient Type = Government
| +| 4.1 | P2G | Personne à gouvernement | | | +| 4.1 | P2G | Achat par numéro de caisse | Initiator Type = Device | | +| 4.2 | P2G | Achat par code QR | à déterminer | | +| 4.3 | P2G | Achat en ligne | Merchant ID Code = à déterminer | | +| 4.4 | P2G | Paiement de facture | | à déterminer : un élément de données dans la demande de devis inclura le numéro de compte du payeur chez l'émetteur de factures | + +## 9. Annexe : Codes de catégorie de commerçants + +_Le schéma voudra spécifier des codes pour reconnaître le type de commerçant payé. Le terme « commerçant » est ici utilisé au sens large pour inclure tous les types d'accepteurs de paiements non-consommateurs. Un système de codes de catégorie de commerçants pourrait vouloir reconnaître les industries, les domaines (magasins en personne vs à distance ou en ligne) et/ou la taille des commerçants._ diff --git a/docs/fr/adoption/Scheme/scheme-business-rules.md b/docs/fr/adoption/Scheme/scheme-business-rules.md new file mode 100644 index 000000000..137764b18 --- /dev/null +++ b/docs/fr/adoption/Scheme/scheme-business-rules.md @@ -0,0 +1,525 @@ +# Modèle de règles métier du schéma + +- Version : 4.0 + - Auteur : Carol Coye Benson (Glenbrook) + - Date : Octobre 2019 + - Description : + +--- + +## **À propos du projet de documents métier de la communauté Mojaloop** + +Ce document fait partie du projet de documents métier de la communauté Mojaloop. Le projet est destiné à soutenir les entités (pays, régions, associations de fournisseurs ou entreprises commerciales) mettant en œuvre de nouveaux systèmes de paiement utilisant le code Mojaloop. Ces entités devront également rédiger des règles métier que les participants au système suivront. + +Le projet de documents métier de la communauté Mojaloop fournit des modèles pour les règles métier et les documents associés. De nombreux choix sont impliqués dans la mise en œuvre d'un nouveau système de paiement : les modèles présentent certains de ces choix et, le cas échéant, des commentaires sont fournis sur la manière dont le choix particulier est lié aux objectifs d'un système conforme Level One. + +Les documents suivants font partie du projet : + +- Choix clés du schéma + +- Modèle d'accord de participation au schéma + +- Modèle de règles métier du schéma + +- Modèle de directive opérationnelle de la plateforme + +- Modèle de directive opérationnelle de gestion des exceptions + +- Glossaire standard + +## **Introduction** + +Des systèmes de paiement à travers le monde sont en cours de mise en œuvre, ou envisagent la mise en œuvre, de systèmes de paiement basés sur Mojaloop. Mojaloop est un logiciel open source pour les sociétés de services financiers, les régulateurs gouvernementaux et d'autres acteurs relevant les défis de l'interopérabilité et de l'inclusion financière. La Fondation Bill & Melinda Gates a fourni un financement et un soutien à Mojaloop à travers le Level One Project, une vision pour les marchés financiers numériques basée sur les principes d'interopérabilité, de collaboration et d'inclusion. + +Les systèmes mettant en œuvre Mojaloop devront rédiger des règles métier qui régissent les droits et responsabilités des participants au système. Ce document fournit un modèle pour ces règles métier. Le modèle est structuré sous forme de plan détaillé : la formulation réelle des règles sera déterminée par les schémas qui les mettent en œuvre et les juridictions dans lesquelles ils opèrent. Dans de nombreuses parties du document, nous suggérons simplement un sujet sur lequel un schéma pourrait vouloir envisager de rédiger une règle : encore une fois, les spécificités de la règle varieront selon le schéma. + +Avant la rédaction des règles métier, les schémas doivent prendre des décisions commerciales majeures sur le fonctionnement du système et de ses partenaires de l'écosystème. Ces décisions sont décrites dans un document séparé au sein du projet de documents métier de la communauté Mojaloop, « Choix clés du schéma ». Les lecteurs sont encouragés à lire ce document en premier. + +Modèle de règles métier du schéma + +## **Table des matières** + +[1 - À propos de ces règles métier du schéma](#_1-a-propos-de-ces-regles-metier-du-schema) + +[2 - Objectifs du schéma](#_2-objectifs-du-schema) + +[3 - Participation au schéma](#_3-participation-au-schema) + +[4 - Règles métier du schéma](#_4-regles-metier-du-schema) + +[5 - Responsabilités et obligations du schéma](#_5-responsabilites-et-obligations-du-schema) + +[6 - Responsabilités et obligations des participants](#_6-responsabilites-et-obligations-des-participants) + +[7 - Responsabilité - Répartition des responsabilités](#_7-responsabilite-repartition-des-responsabilites) + +[8 - Sécurité, gestion des risques et confidentialité des données](#_8-securite-gestion-des-risques-et-confidentialite-des-donnees) + +[9 - Plateforme et services du schéma](#_9-plateforme-et-services-du-schema) + +[10 - Gestion des exceptions](#_10-gestion-des-exceptions) + +[11 - Annexe : Documents associés](#_11-annexe-documents-associes) + +[12 - Annexe : Processus d'intégration et de sortie](#_12-annexe-processus-d-integration-et-de-sortie) + +[13 - Annexe : Services du schéma](#_13-annexe-services-du-schema) + +[14 - Annexe : Cas d'utilisation pris en charge par le schéma](#_14-annexe-cas-d-utilisation-pris-en-charge-par-le-schema) + +[15 - Annexe : Grille tarifaire du schéma](#_15-annexe-grille-tarifaire-du-schema) + +[16 - Annexe : Gestion des risques, sécurité, confidentialité et normes de service](#_16-annexe-gestion-des-risques-securite-confidentialite-et-normes-de-service) + +## **Guide de ce document** + +Les titres de section et les entrées à puces sous les titres de section sont des formulations réellement proposées, ou des sections suggérées pour un document de règles. Le texte en italique constitue des commentaires qui peuvent être utilisés lorsqu'un schéma rédige la formulation réelle d'un document de règles. + +## 1. À propos de ces règles métier du schéma + +### 1.1 Ceci constitue les règles métier du schéma + +::: tip NOTE +Le logiciel Mojaloop peut être utilisé pour des échanges bilatéraux entre DFSP, ainsi que dans une structure de schéma qui utilise un commutateur. Ce document suppose cette dernière option ; que le schéma fournit, engage ou organise autrement l'échange de transactions interopérables via un commutateur. Certains concepts de ces règles ne s'appliquent qu'à cette configuration ; d'autres seraient utiles dans des accords bilatéraux également. +::: + +### 1.2 Propriété du schéma + +

    Qui est propriétaire du schéma, quelles sont les possibilités de participation à la propriété. Référence à d'autres documents (charte, statuts, etc.)
+ +### 1.3 Documents associés définis + +- Ces règles incluent les documents associés répertoriés dans une annexe à ces règles. Les documents associés font partie des règles opérationnelles et ont la force de celles-ci. + +
    Les documents associés devraient inclure la directive opérationnelle de la plateforme et le glossaire standard. Cela n'inclut pas les divers documents techniques qui peuvent être référencés dans les règles métier ou la directive opérationnelle de la plateforme.
+ +### 1.4 Les règles métier du schéma sont contraignantes pour les participants + +
    Cela répète la disposition de l'accord de participation au schéma. Notez que les règles métier du schéma ne sont contraignantes que pour les DFSP qui participent au schéma. Le schéma peut rédiger des règles exigeant que certaines dispositions de ces règles soient transmises aux clients des participants (par exemple, les commerçants) ou aux partenaires (par exemple, les processeurs) - mais il s'agit d'une obligation du participant envers le schéma, et non des autres parties.
+ +### 1.5 Les règles peuvent être modifiées + +
    Les détails du processus de modification sont spécifiés ailleurs.
+ +### 1.6 Les termes sont définis dans le glossaire standard + +
    Le glossaire est un document séparé, plutôt qu'interne au document des règles métier. Cela permet d'assurer la cohérence de la terminologie à mesure que le service évolue et que la directive opérationnelle de la plateforme change.
+ +## 2. Objectifs du schéma + +
    Il s'agit d'une section qui permet à un schéma d'énoncer les objectifs du schéma. Nous suggérons le soutien aux transactions financières interopérables, l'inclusion financière et l'égalité des genres. C'est également l'occasion de référencer le soutien aux principes de conception du Level One Project, une stratégie nationale ou régionale de paiement (ou stratégie d'économie numérique), ou un ensemble de principes de conception spécifiques au schéma.
+ +## 3. Participation au schéma + +### 3.1 Éligibilité à la participation + +- Critères d'éligibilité + +
    Une déclaration indiquant quels types d'institutions sont éligibles pour postuler comme participant au schéma. Le principe de conception Level One est que tout fournisseur autorisé de comptes de transaction dans une juridiction couverte par le schéma devrait être éligible pour postuler.
+ +- Critères d'approbation + +
    Dispositions du schéma pour l'acceptation des candidatures, y compris des déclarations de haut niveau sur les informations requises du candidat, telles que la démonstration d'une capacité durable à respecter les obligations financières et les obligations de conformité. Le processus de candidature réel figure dans une annexe à ces règles. Les exigences de certification technique peuvent être répertoriées dans la directive opérationnelle de la plateforme.
+ +### 3.2 Licence + +
    Ce concept peut ou non s'appliquer lorsque l'opérateur du schéma est une entité gouvernementale. Si le concept de licence n'est pas inclus dans les règles, il doit y avoir une disposition dans la section « Éligibilité à la participation » concernant la résiliation d'un participant.
+ +- Un participant se voit accorder une licence pour participer au schéma et utiliser la propriété du schéma conformément aux règles métier du schéma. + +- Un participant ne peut utiliser la propriété du schéma que conformément aux règles métier du schéma. Les licences limiteront l'utilisation de la propriété du schéma à la fourniture de services par le participant en lien avec le schéma et conformément aux règles. + +- Les licences ne seront pas exclusives. + +### 3.3 Accès par paliers + +
    Les schémas peuvent choisir de permettre à certains candidats de rejoindre le schéma en tant que participants indirects. Cette section précise les conditions pour cela. Certains schémas permettent séparément la participation technique indirecte et la participation indirecte au règlement.
+ +
    Si cela est autorisé, des termes définis (tels que banque sponsor et participant indirect) sont requis. Cette section doit clairement montrer quelles sont les obligations de chaque partie ; cela peut faire référence aux sections d'obligations apparaissant ultérieurement.
+ +### 3.4 Départ de la participation + +
    Dispositions pour la suspension ou la résiliation par le schéma de la participation d'un participant au schéma. Le schéma peut suspendre, limiter ou exclure un participant de la participation au schéma s'il détermine que l'incapacité du participant à respecter une règle constitue une charge excessive pour le schéma ou les autres participants ou pose des risques excessifs pour l'intégrité du schéma ou la réputation du schéma.
+ +
    Dispositions permettant aux participants de mettre fin à leur participation au schéma.
+ +## 4. Règles métier du schéma + +### 4.1 Portée des règles métier du schéma + +- Ces règles s'appliquent à chaque participant et régissent les droits et responsabilités des participants et du schéma. + +- Ces règles peuvent être remplacées dans la mesure où elles entrent en conflit avec toute loi applicable. Rien dans ces règles ne sera appliqué de manière à exiger que le schéma ou tout participant viole la loi applicable. + +- Toutes les questions relatives à l'interprétation des règles et tous les litiges découlant de la participation au schéma seront soumis aux lois de \[xxxx\] + +
    Des dispositions devraient être prises pour la résolution des litiges entre participants ou entre les participants et le schéma.
+ +### 4.2 Modifications des règles métier du schéma + +- Les participants peuvent de temps à autre fournir des suggestions ou des demandes de modification des règles. + +- Les suggestions des participants pour des modifications des règles peuvent être utilisées par le schéma ou par d'autres participants en lien avec le schéma sans compensation ni attribution au participant qui fait la suggestion ou la demande. + +- Les modifications des règles seront effectuées selon une procédure consultative : + +- Un ou plusieurs participants ou le schéma peuvent proposer une modification des règles métier du schéma. + +- Le schéma publiera les propositions à tous les participants et demandera des commentaires et suggestions à ce sujet ; tous les commentaires reçus seront publiés à tous les participants. + +- Le schéma peut inclure, avec la publication d'un changement proposé, sa suggestion déterminée de manière indépendante pour la formulation d'un changement dans les règles. + +
    Le schéma devrait avoir un processus défini pour l'adoption des changements, qui peut inclure le vote des participants ou une décision du schéma. S'il y a un vote, les règles ici devraient spécifier les paramètres.
+ +- Le schéma peut accorder des dérogations aux règles sur demande des participants. + +- Des dispositions pour des changements urgents peuvent être prises par le schéma pour répondre à des risques ou des exigences réglementaires. + +## 5. Responsabilités et obligations du schéma + +### 5.1 Définition et fourniture des services du schéma + +- Le schéma définit l'ensemble des services du schéma qui sont fournis aux participants. La liste définie des services du schéma est présentée dans une annexe à ces règles. + +
    Services du schéma
+ +- Le schéma précise comment les services du schéma sont fournis aux participants - ils peuvent être exploités par l'entité du schéma, par une autre entité sous contrat avec le schéma, ou il peut y avoir un autre arrangement. Cette section donne au schéma le droit de définir de nouveaux services, de modifier les services existants, etc. + +- Le schéma peut définir des normes de niveau de service pour lui-même et pour les participants dans l'utilisation de ces services. + +- Pour les services de plateforme externalisés, le schéma spécifie les services à fournir. Le schéma peut spécifier les accords de niveau de service pour les fournisseurs de ces services. + +- Pour le service de règlement du schéma, le schéma sélectionne et contracte avec une ou plusieurs banques de règlement pour le règlement inter-participants. + +- Le schéma établit une limite de valeur de transaction qui fixe la valeur maximale de tout transfert effectué via la plateforme du schéma. Les DFSP peuvent fixer des valeurs inférieures pour leurs clients. + +- Le schéma devrait examiner s'il garantira au DFSP bénéficiaire tout transfert exécuté conformément à ces règles. + +
    Le schéma devrait examiner s'il garantira au DFSP bénéficiaire tout transfert exécuté conformément à ces règles.
+ +### 5.2 Rédaction, mise à jour et maintenance des règles + +- Le schéma rédige, met à jour et maintient les règles métier. + +- Le schéma est responsable d'informer les participants de toute modification des règles, de tous les frais, des politiques susceptibles d'affecter l'utilisation du schéma par les participants, ou de toute autre information importante et pertinente. + +- Le schéma est responsable de l'établissement d'une politique, et de sa communication aux participants, pour l'application des règles. + +- Le schéma est responsable de l'établissement de politiques concernant l'octroi de dérogations aux règles aux participants. + +### 5.3 Autres responsabilités du schéma + +- Le schéma administre les processus d'onboarding et de sortie des participants. Ces processus sont répertoriés dans une annexe à ces règles. + +- Le schéma surveille l'éligibilité continue des participants selon les exigences établies pour la participation. + +- Le schéma définit un ensemble de cas d'utilisation et de cas d'utilisation secondaires. Ceux-ci sont répertoriés dans une annexe à ces règles. + +- Le schéma établit la grille tarifaire et définit les processus par lesquels les frais sont collectés. La grille tarifaire figure dans une annexe à ces règles. + +- Le schéma définit la marque du schéma et établit des directives pour son utilisation. Ces directives figurent dans un document associé. + +- Le schéma mesure la progression du schéma et de ses participants. + +- Le schéma définit des politiques et procédures en matière de sécurité, de gestion des risques et de confidentialité des données pour le schéma et ses participants. + +- Le schéma définit des politiques et procédures pour la gestion des exceptions de transaction. + +- Le schéma entreprend des activités pour promouvoir et encourager l'adoption et l'utilisation du schéma. + +- Le schéma planifie l'amélioration et l'expansion à long terme de la plateforme pour répondre aux besoins et opportunités du marché en évolution dans l'avancement des objectifs du schéma. + +## 6. Responsabilités et obligations des participants + +- Les participants sont tenus de se conformer à ces règles métier et aux documents associés à ces règles. + +- Les participants doivent se conformer à toute loi applicable en ce qui concerne leur participation au schéma dans les territoires dans lesquels ils opèrent et dans lesquels ils utilisent les services du schéma. Le schéma n'assume aucune responsabilité quant à la conformité des participants à la loi applicable. + +- Les participants sont tenus de permettre l'utilisation et la divulgation d'informations personnelles comme l'exigent ces règles métier et de fournir des informations à leurs clients et d'obtenir les consentements nécessaires concernant cette utilisation et divulgation d'informations personnelles comme l'exige la loi applicable. + +- Les participants acceptent de payer des frais au schéma et aux autres participants comme spécifié dans ces règles. + +- Les participants adhéreront aux spécifications de marque du schéma comme spécifié dans ces règles. + +- Les participants utiliseront les services du schéma comme spécifié dans ces règles. + +
    Les schémas devront examiner s'ils souhaitent : 1) exiger l'utilisation du schéma pour les transactions éligibles au schéma (en supposant l'autorité des règles pour ce faire) ; 2) exiger l'utilisation de la plateforme du schéma pour les transactions « on-us » (nécessiterait des frais de traitement séparés, probablement nuls pour ces transactions) ; si les transactions « on-us » ne passent pas par la plateforme, si le schéma souhaite exiger le reporting des transactions « on-us » au schéma, pour utilisation avec un utilitaire de fraude.
+ +- Tous les transferts effectués en utilisant la marque du schéma ou décrits comme étant effectués avec le schéma seront effectués en utilisant les services du schéma. + +
    Les schémas devront examiner s'ils souhaitent énoncer la règle ci-dessus. Certains schémas peuvent vouloir que les participants utilisent la marque du schéma pour les transactions on-us qui n'utilisent pas les services du schéma. Cela pourrait être formulé comme « tous les transferts interopérables ».
+ +- _\[Option de règlement net\]_ Les participants ouvriront un compte bancaire de règlement auprès de la banque de règlement spécifiée par le schéma, ou mettront à disposition un compte existant à ces fins, comme autorisé par le schéma. _\[Option de règlement brut continu\]_ Les participants deviendront copropriétaires du compte de règlement mutualisé du schéma et signeront l'accord de compte bancaire de règlement du schéma à cet effet. Les participants transféreront des fonds vers et depuis ce compte à partir de leurs comptes de réserve, de compensation ou de fiducie existants auprès de la banque de règlement du schéma, comme spécifié dans les directives opérationnelles du schéma. + +- Les participants partageront des informations avec le schéma dans la mesure strictement nécessaire au fonctionnement du schéma, y compris pour la diligence raisonnable, l'intégration technique, la configuration, la gestion des transactions et d'autres fins spécifiées dans les règles. + +- Les participants seront tenus par le schéma de respecter les normes de sécurité, de gestion des risques et de confidentialité des données spécifiées par le schéma. + +- Les participants fourniront un service client adéquat à leurs clients en lien avec le schéma. + +- Les participants doivent exclure les clients de l'utilisation du schéma à la demande du schéma lorsque le schéma détermine raisonnablement qu'un client présente un risque pour le schéma, qui peut inclure un risque financier, juridique, de sécurité, de réputation ou tout autre risque. + +- Les participants ne permettront pas, et ne permettront pas à leurs clients, d'utiliser le schéma à des fins illégales, y compris les biens ou services illégaux ; les paiements illégaux, tels que la corruption, le blanchiment d'argent ou le financement du terrorisme ; le braconnage ou le trafic d'espèces animales protégées ou de produits dérivés. + +
    Les schémas peuvent examiner s'ils souhaitent spécifier que les participants interdisent contractuellement aux clients d'utiliser les services du schéma à des fins illégales et interrompront les services du schéma pour les clients dont ils savent, ou soupçonnent, qu'ils utilisent les services du schéma pour initier ou recevoir des transferts à des fins illégales.
+ +### 6.1 Responsabilités et obligations des participants en tant que DFSP payeurs + +- Un participant qui initie une demande de devis ou une demande de transfert agit en tant que participant payeur en vertu de ces règles. + +- Un participant peut initier une transaction pour le compte de son payeur pour tout cas d'utilisation ou cas d'utilisation secondaire pris en charge par le schéma. + +- Un participant payeur est tenu de régler un transfert lors de la soumission d'une demande de transfert, à moins que cette demande de transfert ne soit refusée par le DFSP bénéficiaire ou n'expire sans exécution. + +- Le participant payeur garantit, lors de la soumission de chaque demande de transfert, que le transfert provient d'un compte conforme aux exigences KYC et AML et est exécuté conformément à la loi applicable, et que le payeur a reçu toutes les informations et a donné tous les consentements nécessaires pour effectuer le transfert conformément à ces règles métier et à la loi applicable. + +- Le participant payeur garantit, lors de la soumission d'une demande de transfert, que la demande de transfert a été autorisée par son payeur, et que ses communications avec son payeur ont été correctement authentifiées conformément à ces règles métier et à la loi applicable. + +- Le participant payeur reconnaît que la plateforme rejettera une demande de transfert si le transfert proposé violerait ces règles métier, comme le dépassement du plafond de débit net du participant payeur. + +### 6.2 Responsabilités et obligations des participants en tant que DFSP bénéficiaires + +- Un participant qui reçoit et répond à une demande de devis ou une demande de transfert agit en tant que participant bénéficiaire en vertu de ces règles. + +- Un participant bénéficiaire qui reçoit une demande de devis est tenu de répondre, en l'absence de problèmes techniques, avec une réponse au devis si : + + - Le compte de transaction du bénéficiaire auprès du participant bénéficiaire est en règle et capable de recevoir, à ce moment-là, le montant du transfert et + + - L'acceptation du transfert ne mettra pas le compte du bénéficiaire dans un état non autorisé par la loi applicable ou les politiques et accords de compte du participant. + + - Le participant bénéficiaire affirme, lors de l'initiation d'une réponse au devis autre qu'une réponse d'erreur, que le compte du bénéficiaire a été validé — il est ouvert, en règle et capable d'accepter le montant du transfert proposé à ce moment-là. + +- Le participant bénéficiaire affirme, lors de l'initiation d'une réponse au devis autre qu'une réponse d'erreur, qu'un transfert vers le compte désigné est conforme à ce moment-là aux exigences applicables en matière d'AML/CFT et de KYC. + +- Un participant bénéficiaire qui reçoit une demande de transfert est tenu, en l'absence de problèmes techniques, de répondre avec une réponse de transfert avec l'état de transaction « Committed » si : + + - Il a reçu une demande de devis et a répondu avec une réponse au devis pour la transaction et + + - La réponse au devis n'a pas encore expiré + + - Le compte de transaction du bénéficiaire auprès du participant bénéficiaire est en règle et capable de recevoir, à ce moment-là, le montant du transfert et + + - L'acceptation du transfert ne mettra pas le compte du bénéficiaire dans un état non autorisé par la loi applicable ou les politiques et accords de compte du participant et + + - La demande de transfert sur la transaction n'a pas expiré. + +- Un participant bénéficiaire qui envoie une réponse de transfert avec un état de transaction « Committed » doit comptabiliser ce transfert sur le compte du bénéficiaire dans un délai de \[X temps\]. + +- Un participant bénéficiaire qui reçoit une demande de transfert ne répondant pas aux critères ci-dessus est tenu de répondre avec une réponse de transfert avec l'état de transaction « Aborted ». + +- Le participant bénéficiaire doit affirmer, lors de la soumission de chaque réponse de transfert avec un état de transaction « Committed », que le transfert est crédité sur un compte conforme aux exigences AML et est exécuté conformément à toute limitation de volume de compte, ou toute autre réglementation s'appliquant dans les territoires dans lesquels il opère, et que le bénéficiaire a reçu toutes les informations et a donné tous les consentements nécessaires pour effectuer le transfert conformément aux règles et à la loi applicable. + +## 7. Responsabilité - Répartition des responsabilités + +- Chaque participant est responsable des erreurs commises par lui, et de la fraude commise par ses employés ou sous-traitants, conformément à la loi applicable. + +- Le système (ou le scheme) ne sera pas tenu responsable et chaque participant indemnisera et défendra le schéma contre les réclamations découlant des actions ou omissions des participants, de leurs clients ou sous-traitants. + +- Le schéma peut choisir de défendre toute réclamation dans les circonstances où le schéma détermine que la résolution d'une réclamation pourrait avoir un impact défavorable sur les finances, les opérations ou la réputation du schéma. + +- Le schéma sera tenu responsable de ses propres erreurs dans le traitement des transferts dans les limites prescrites par les règles. + +- Le schéma compensera les participants pour les coûts de fonds dans la mesure où un participant est injustement privé de fonds pendant une période de temps résultant d'erreurs commises par le schéma. + +- Chaque participant est responsable des actions et omissions de tout sous-traitant engagé par lui pour fournir des services en lien avec le schéma dans la même mesure que s'ils avaient été commis par le participant. + +- Le schéma peut répartir la responsabilité entre les participants pour les conséquences de l'utilisation non autorisée ou de l'accès aux données par un participant ou pour un incident de sécurité subi par un participant qui impacte d'autres participants ou le schéma conformément aux principes énoncés dans les règles. + +## 8. Sécurité, gestion des risques et confidentialité des données + +### 8.1 Confidentialité et protection des informations personnelles + +- Les informations confidentielles du schéma divulguées aux participants seront tenues confidentielles par les participants et ne seront utilisées qu'aux fins autorisées par les règles. Les informations confidentielles du schéma peuvent inclure la technologie propriétaire et d'autres éléments désignés par le schéma. + +- Les données de transaction n'appartiendront pas au schéma et appartiendront à un participant en ce qui concerne les transactions de ses clients. + +- La confidentialité des données de transaction et de toute information personnelle traitée dans la plateforme sera protégée par le schéma et les participants conformément à la loi applicable. + +- Les statistiques ou données qui identifient un participant ou à partir desquelles le participant peut être identifié ne seront pas divulguées à d'autres participants. Le schéma peut préparer pour un usage interne et divulguer à des tiers à des fins promotionnelles des statistiques basées sur des données agrégées et anonymisées, comme autorisé par la loi applicable. + +- Le schéma effectuera des divulgations d'informations confidentielles pour se conformer à la loi applicable ou à la directive d'une autorité de régulation. + +- Le schéma protégera les informations personnelles en sa possession ou sous son contrôle contre toute utilisation abusive et traitera ces informations conformément à la loi applicable protégeant la vie privée des individus. + +- Le schéma maintiendra des mesures de sécurité de premier plan dans l'industrie pour protéger les informations contre tout accès et utilisation non autorisés. + +- Les participants informeront le schéma et reconnaissent que le schéma peut informer d'autres participants, de tout incident de sécurité dans les systèmes ou locaux du participant, de ses entités affiliées ou de tout fournisseur tiers engagé par le participant pour fournir des services en soutien de la participation du participant au schéma. + +- Le schéma peut mener des enquêtes sur les incidents de sécurité. Les participants coopéreront pleinement et rapidement avec l'enquête. Ces enquêtes seront aux frais du participant concerné. + +- Le schéma peut exiger qu'un participant mène des enquêtes sur les incidents de sécurité et peut exiger que ces enquêtes soient menées par des auditeurs de sécurité indépendants qualifiés acceptables pour le schéma. + +- Le schéma peut imposer des conditions de participation continue au participant concerné concernant la remédiation des causes de l'incident de sécurité et les mesures de sécurité en cours. + +- L'enquête et le rapport, ainsi que les remèdes qui peuvent être requis, seront tenus confidentiels dans la mesure autorisée par la loi applicable. + +### 8.2 Politiques de gestion des risques + +
    Cette section suppose que l'élaboration de politiques de gestion des risques par le schéma et ses participants sera évolutive. Cette section envisage que certaines de ces politiques seront (éventuellement) dans les règles ; d'autres ne le seront pas.
+ +- Les politiques et procédures de gestion des risques peuvent être énoncées dans les règles, dans les documents associés ou dans d'autres documents de politique écrits créés par le schéma et distribués aux participants. + +- Les politiques et procédures de gestion des risques incluront la solidité fiscale, l'intégrité du système, la conformité à la loi applicable, en particulier en ce qui concerne les mesures de lutte contre le blanchiment d'argent/le financement du terrorisme, la protection de la vie privée des informations personnelles et la sécurité des données. + +- Les fonctions de gestion des risques incluent les procédures applicables aux participants pour la surveillance des risques, y compris les exigences de reporting et les audits. + +### 8.3 Continuité des activités + +- Dispositions pour assurer la continuité des activités de la part du schéma, de ses fournisseurs et des participants. + +## 9. Plateforme et services du schéma + +- Le schéma définit l'ensemble des services du schéma auxquels les participants accèdent pour utiliser le système. Ceux-ci sont répertoriés dans une annexe à ce document. Les services essentiels du schéma nécessaires à l'interopérabilité sont considérés comme la plateforme du schéma. + +- Les détails techniques et opérationnels sur l'utilisation des services du schéma, y compris la plateforme du schéma, sont fournis dans les documents associés. Cette liste de documents associés est une annexe à ce document. + +## 10. Gestion des exceptions + +- Des problèmes peuvent survenir lors de l'exécution d'une transaction, entraînant des cas d'exception, qui peuvent nécessiter ou être facilités par une communication inter-participants. Les cas d'exception peuvent inclure des erreurs de la part de toute partie, des fraudes ou d'autres anomalies de service. + +- Le schéma créera et maintiendra des protocoles par lesquels les participants peuvent déterminer le type d'exception et les actions suggérées ou requises de la part des participants pour résoudre l'exception. Ces protocoles sont contenus dans un document associé. + +- Les principes suivants régissent la gestion des exceptions : + + - Les participants impliqués coopéreront de bonne foi. + + - Chaque participant accepte de ne pas contacter directement le client de l'autre participant pendant le processus de résolution des litiges. + + - Les participants acceptent de coopérer entre eux et avec le schéma pour partager des informations sur les fraudes suspectées ou confirmées. + +### 10.1 Irrévocabilité des transactions + +- Les participants conviennent que les transferts exécutés via la plateforme sont irrévocables. Un transfert qui a été crédité sur le compte d'un bénéficiaire à la suite d'un transfert du schéma ne peut pas être révoqué sans le consentement du bénéficiaire. + +- Le schéma peut ordonner à un participant d'initier une transaction corrective entre participants pour un montant déterminé par le schéma comme nécessaire pour corriger les erreurs causées par le DFSP payeur, le DFSP bénéficiaire ou le schéma. Les conditions dans lesquelles de telles transactions correctives peuvent être effectuées sont spécifiées par les règles. + +- Les erreurs de la part du DFSP bénéficiaire, du DFSP payeur ou du schéma qui entraînent une comptabilisation erronée ou en double d'un transfert sur le compte d'un bénéficiaire peuvent être corrigées par le participant bénéficiaire, tant que les instructions du transfert exécuté ne sont pas révoquées ou modifiées de quelque manière que ce soit. + +## 11. Annexe : Documents associés + +- Glossaire standard + +- Directive opérationnelle de la plateforme + +- Directive de marque + +- Protocoles de gestion des exceptions + +## 12. Annexe : Processus d'intégration et de sortie + +## 13. Annexe : Services du schéma + +Les services du schéma incluent : + +- Plateforme du schéma, qui comprend + + - Le service de transfert + + - Le service de répertoire + + - Le service de règlement + + - Service de gestion du schéma + +- Autres services partagés + + - Utilitaire de gestion de la fraude + +## 14. Annexe : Cas d'utilisation pris en charge par le schéma + +
    Les cas d'utilisation sont définis par le type de client qui paie quel autre type de client, et par l'objectif du paiement. Les cas d'utilisation secondaires sont des sous-ensembles des cas d'utilisation et sont utilisés pour démontrer des différences plus précises dans les transferts. Tous les transferts effectués via les services du schéma peuvent être catégorisés par un, et un seul, cas d'utilisation et cas d'utilisation secondaire.
+ +
    Le cas d'utilisation et le cas d'utilisation secondaire d'une transaction peuvent nécessiter l'application de différents détails opérationnels et techniques, comme spécifié dans la directive opérationnelle de la plateforme ; différents frais d'interchange, comme spécifié dans une annexe à ces règles ; différentes exigences pour les procédures de gestion des exceptions, comme spécifié dans un document associé à ces règles.
+ +
    Tous les cas d'utilisation et cas d'utilisation secondaires pris en charge par le schéma sont définis par les attributs des transactions, qui sont spécifiés dans la directive opérationnelle de la plateforme.
+ +
    Ce qui suit est un exemple de tableau de cas d'utilisation et de cas d'utilisation secondaires qu'un schéma pourrait prendre en charge.
+ +
    Un schéma ne définirait des cas d'utilisation secondaires que s'il souhaitait rédiger des règles et/ou spécifier des frais propres à ce cas d'utilisation secondaire.
+ +| | Cas d'utilisation | Cas d'utilisation secondaire | +| :---: | :--------: | :-------------------------- | +| 1.0 | P2P | Personne à personne | +| 1.1 | P2P | Portefeuille à portefeuille | +| 1.2 | P2P | Banque à banque | +| 1.3 | P2P | Portefeuille à banque | +| 1.4 | P2P | Banque à portefeuille | +| 2.0 | Paiement en masse | | +| 2.1 | B2P | Entreprise à personne | +| 2.2 | G2P | Gouvernement à personne | +| 3.0 | P2B | Personne à entreprise | +| 3.1 | P2B | Achat par numéro de caisse | +| 3.2 | P2B | Achat par code QR | +| 3.3 | P2B | Achat en ligne | +| 3.4 | P2B | Paiement de facture | +| 3.5 | P2B | Personne à entreprise - Autre | +| 4.0 | P2G | | +| 4.1 | P2G | Personne à gouvernement | +| 4.1 | P2G | Achat par numéro de caisse | +| 4.2 | P2G | Achat par code QR | +| 4.3 | P2G | Achat en ligne | +| 4.4 | P2G | Paiement de facture | + +## 15. Annexe : Grille tarifaire du schéma + +1. Frais de traitement + + - Les frais de traitement sont calculés par \[définir\] + + - Les frais de traitement s'appliquent aux transferts exécutés + + - Les frais de traitement sont facturés à \[quelle partie ou parties\] + + - Les frais de traitement pour les transferts « on-us » (où le DFSP payeur et le DFSP bénéficiaire sont les mêmes) \[sont ou ne sont pas facturés\] + + - Les frais de traitement seront calculés et facturés aux participants \[définir\] + + - Disposition sur la manière dont les participants paieront les factures de traitement \[définir\] + +2. Frais d'adhésion ou de participation + + - Les frais d'adhésion ou de participation sont facturés à \[définir\] + + - Spécifier la base, le mode de collecte, etc. + +3. Frais d'interchange + + - Les frais d'interchange sont fixés par le schéma + + - Le montant du frais et la direction (quel participant paie quel autre) varient selon le cas d'utilisation et le cas d'utilisation secondaire. Certains cas d'utilisation et cas d'utilisation secondaires n'auront pas d'interchange. + + - \[Définir comment la plateforme collectera et distribuera l'interchange : sur une base transactionnelle ou périodique.\] + +## 16. Annexe : Gestion des risques, sécurité, confidentialité et normes de service + +
    Les schémas peuvent ou non vouloir spécifier des normes ou exiger que les participants se conforment à d'autres normes établies. Les schémas peuvent en outre spécifier des normes différentes pour différentes catégories de participants. La liste ci-dessous est donnée purement à titre d'exemple.
+ +Les participants doivent adhérer aux pratiques suivantes en matière de qualité de service, de sécurité, de confidentialité des données et de service client en ce qui concerne leur participation au schéma. + +- Les participants établiront un cadre de gestion des risques pour identifier, évaluer et contrôler les risques relatifs à leur utilisation du schéma. + +- Les participants s'assureront que les systèmes, applications et réseaux prenant en charge l'utilisation du schéma sont conçus et développés de manière sécurisée. + +- Les participants mettront en œuvre des processus pour gérer de manière sécurisée tous les systèmes et opérations prenant en charge l'utilisation du schéma. + +- Les participants mettront en œuvre des processus pour s'assurer que les systèmes utilisés pour le schéma sont protégés contre les intrusions ou utilisations non autorisées. + +- Les participants mettront en œuvre des processus pour assurer l'authentification de leurs clients lors de la création et de l'approbation des transactions utilisant le schéma. + +- Les participants élaboreront des plans efficaces de continuité des activités et de contingence. + +- Les participants géreront les opérations techniques et commerciales pour permettre des réponses rapides aux appels API reçus de la plateforme du schéma ou d'autres participants via la plateforme du schéma. + +- Les participants établiront des accords écrits régissant leurs relations avec les agents, processeurs et autres entités fournissant des services externalisés liés au schéma. + +- Les participants élaboreront des politiques et processus pour la gestion et la supervision continues du personnel, des agents, des processeurs et des autres entités fournissant des services externalisés liés au schéma. + +- Les participants s'assureront que les clients reçoivent des informations claires, visibles et opportunes concernant les frais et les conditions générales liés aux services utilisant le schéma. + +- Les participants élaboreront et publieront des politiques et procédures de service client liées aux services utilisant le schéma. + +- Les participants fourniront un mécanisme approprié pour que les clients puissent poser des questions et résoudre des problèmes. Les participants préciseront comment les litiges peuvent être résolus si la résolution interne échoue. + +- Les participants se conformeront aux bonnes pratiques et aux lois applicables régissant la confidentialité des données des clients. + +- Les participants s'assureront que les clients reçoivent des informations claires, visibles et opportunes concernant leurs pratiques de confidentialité des données. diff --git a/docs/fr/adoption/Scheme/scheme-key-choices.md b/docs/fr/adoption/Scheme/scheme-key-choices.md new file mode 100644 index 000000000..8be43c8d1 --- /dev/null +++ b/docs/fr/adoption/Scheme/scheme-key-choices.md @@ -0,0 +1,407 @@ +# Choix clés du schéma + +- Version : 5.0 + - Auteur : Carol Coye Benson (Glenbrook) + - Date : Octobre 2019 + - Description : + +--- + +## **À propos du projet de documents métier de la communauté Mojaloop** + +Ce document fait partie du projet de documents métier de la communauté Mojaloop. Le projet est destiné à soutenir les entités (pays, régions, associations de fournisseurs ou entreprises commerciales) mettant en œuvre de nouveaux systèmes de paiement utilisant le code Mojaloop. Ces entités devront également rédiger des règles métier que les participants au système suivront. + +Le projet de documents métier de la communauté Mojaloop fournit des modèles pour les règles métier et les documents associés. De nombreux choix sont impliqués dans la mise en œuvre d'un nouveau système de paiement : les modèles présentent certains de ces choix et, le cas échéant, des commentaires sont fournis sur la manière dont le choix particulier est lié aux objectifs d'un système conforme Level One. + +Les documents suivants font partie du projet : + +- Choix clés du schéma + +- Modèle d'accord de participation au schéma + +- Modèle de règles métier du schéma + +- Modèle de directive opérationnelle de la plateforme + +- Modèle de directive opérationnelle de gestion des exceptions + +- Glossaire standard + +## **Introduction** + +Des systèmes de paiement à travers le monde sont en cours de mise en œuvre, ou envisagent la mise en œuvre, de systèmes de paiement basés sur Mojaloop. Mojaloop est un logiciel open source pour les sociétés de services financiers, les régulateurs gouvernementaux et d'autres acteurs relevant les défis de l'interopérabilité et de l'inclusion financière. Mojaloop est basé sur la Spécification Open API pour l'interopérabilité des FSP, qui a été développée pour fournir une spécification d'API ouverte pour l'interopérabilité de la monnaie mobile. + +La Fondation Bill & Melinda Gates a fourni un financement et un soutien à Mojaloop. Mojaloop est un code de référence open source qui démontre les principes du Level One Project, une vision pour les marchés financiers numériques basée sur les principes d'interopérabilité, de collaboration et d'inclusion. + +Les systèmes mettant en œuvre Mojaloop devront faire un certain nombre de choix commerciaux concernant la conception du système. Ces choix, une fois effectués, affecteront à la fois la mise en œuvre technique de Mojaloop et les règles métier que le schéma rédigera, et auxquelles les DFSP participants accepteront de se conformer. Ce document décrit et examine certains des choix les plus significatifs. Le cas échéant, des recommandations de bonnes pratiques sont formulées pour se conformer aux principes de conception du Level One Project (L1P). + +Bien que ce document soit rédigé en tant que contribution à la communauté Mojaloop, les questions décrites ici sont pertinentes pour tout système de paiement conforme Level One, quelle que soit la mise en œuvre technique choisie. + +## **Choix décrits dans ce document** + +[1 - Choix : Propriété du schéma](#_1-choix-propriete-du-schema) + +[2 - Choix : Participation au schéma](#_2-choix-participation-au-schema) + +[3 - Choix : Relation entre le schéma et la plateforme](#_3-choix-relation-entre-le-schema-et-la-plateforme) + +[4 - Choix : Portée des règles de schéma et autorité des règles de schéma](#_4-choix-portee-des-regles-du-schema-et-autorite-des-regles-du-schema) + +[5 - Choix : Cas d'utilisation](#_5-choix-cas-d-utilisation) + +[6 - Choix : Codes QR](#_6-choix-codes-qr) + +[7 - Choix : Adressage des paiements](#_7-choix-adressage-des-paiements) + +[8 - Choix : Règlement inter-participants](#_8-choix-reglement-inter-participants) + +[9 - Choix : Accès par paliers](#_9-choix-acces-par-paliers) + +[10 - Choix : Frais du schéma et tarification pour l'utilisateur final](#_10-choix-frais-du-schema-et-tarification-pour-l-utilisateur-final) + +[11 - Choix : Gestion de la marque](#_11-choix-gestion-de-la-marque) + +[12 - Choix : Connexions inter-schémas du schéma](#_12-choix-connexions-du-schema-avec-d-autres-schemas) + +[13 - Choix : Utilisation du schéma par d'autres FSP](#_13-choix-utilisation-du-schema-par-d-autres-fsp) + +[14 - Choix : Normes de gestion des risques du schéma](#_14-choix-normes-de-gestion-des-risques-du-schema) + +[15 - Choix : Gestion des exceptions](#_15-choix-gestion-des-exceptions) + +## 1. Choix : Propriété du schéma + +Le schéma est l'entité qui rédige les règles du système de paiement. En tant que tel, le schéma contrôle de multiples aspects de la fourniture des services du schéma, y compris la manière dont la plateforme technique et opérationnelle sera fournie aux DFSP participants. Les modèles courants de propriété de schéma dans l'industrie des paiements incluent : + +- Une association de DFSP participants, avec ou sans participation de la banque centrale + +- Une banque centrale ou une autre entité gouvernementale + +- Une entité commerciale + +Le modèle associatif maximise le contrôle des DFSP sur le schéma et peut encourager les DFSP à rejoindre et utiliser le schéma. Un schéma contrôlé par le gouvernement ou la banque centrale peut rendre la supervision réglementaire des DFSP plus efficace et simplifier la prise de décision : un organisme gouvernemental peut être disposé à prendre des décisions d'infrastructure qui sont bénéfiques pour l'ensemble de l'écosystème, plutôt que d'optimiser les avantages individuels des DFSP. Une entité commerciale peut être plus rapide à mettre en œuvre un nouveau système et peut être plus efficace dans certaines situations pour créer un modèle opérationnel durable. + +### 1.1 Alignement Level One — Propriété du schéma + +Chacune de ces structures de propriété peut atteindre les objectifs du L1P et de l'inclusion financière. Les principes de conception Level One suggèrent « l'auto-gouvernance par les DFSP » (le premier modèle) comme conception privilégiée, sur la base de la conviction que la participation à la gouvernance peut renforcer l'engagement des DFSP envers le schéma. D'autres conceptions peuvent fonctionner, cependant, tant que le schéma et ses membres disposent d'une certaine forme de gouvernance participative et fonctionnent avec transparence et communications ouvertes. + +Le principe Level One le plus important est que le schéma lui-même devrait fonctionner sur un modèle « sans perte » (recouvrement durable des coûts). Ce dernier point est particulièrement important pour atteindre l'objectif du L1P de créer un système de paiement à très faible coût. Ce principe repose sur l'idée que les DFSP peuvent, bien entendu, opérer à but lucratif en fournissant des services de paiement. La source de leurs revenus, cependant, peut provenir principalement des « [services adjacents](https://docs.gatesfoundation.org/documents/fighting%20poverty%20profitably%20full%20report.pdf) » plutôt que des frais liés à la transaction de paiement elle-même. Notez que la plateforme opérationnelle peut être fournie par une entité commerciale, même si le schéma lui-même est exploité sur une base « sans perte ». Ceci est discuté plus loin dans « Choix : Relation entre le schéma et la plateforme ». + +De nombreux systèmes de paiement bancaires hérités dans le monde fonctionnent sur le modèle associatif. Les systèmes ACH et les systèmes de carte de débit nationaux (tels que le système ACH américain et le système Interac du Canada) utilisent ce modèle et offrent des coûts de traitement ultra-faibles aux DFSP participants. Certains nouveaux systèmes de paiement mobile, tels que le système UPI de l'Inde et le système BIM du Pérou, utilisent également ce modèle. + +Plusieurs pays fournissent des services par l'intermédiaire de la banque centrale : le modèle SPEI du Mexique est notable ici. Le système JoMoPay de la Jordanie a commencé comme un système de banque centrale et est passé au modèle associatif. + +Les réseaux de cartes mondiaux, notamment Visa et MasterCard, ont commencé comme des modèles associatifs et sont passés à un modèle commercial. De nombreuses FinTechs, telles que PayPal ou WeChat Payments, exploitent des systèmes en boucle fermée sur un modèle commercial. + +## 2. Choix : Participation au schéma + +Mojaloop et le L1P utilisent le terme « DFSP » (Fournisseur de services financiers numériques) pour désigner toute entité dans la juridiction où le système de paiement opère, qui est autorisée à fournir des comptes de transaction aux utilisateurs finaux, détenant des fonds et pouvant être utilisés pour effectuer et recevoir des paiements. Cette définition inclut les banques, les autres institutions financières de dépôt et les émetteurs de monnaie électronique (parfois appelés opérateurs de monnaie mobile). + +Il existe de nombreux autres participants de l'écosystème qui ne détiennent pas de comptes de transaction des utilisateurs finaux : ceux-ci incluent les processeurs, les agrégateurs et certains types de fournisseurs de services de paiement. La relation de ces entités avec le schéma et les DFSP est abordée dans [Choix : Utilisation du schéma par d'autres FSP](#_13-choix-utilisation-du-schema-par-d-autres-fsp). + +La question de la participation est double : premièrement, quelles catégories de DFSP sont prises en charge par le schéma, et deuxièmement, quel est le processus par lequel les DFSP sont autorisés à participer. Le terme « boucle ouverte » est utilisé pour désigner une structure dans laquelle plusieurs DFSP rejoignent et utilisent le schéma pour échanger des transactions (interopérer). Mais un schéma en « boucle ouverte » peut être soit un schéma dans lequel tout DFSP d'une catégorie prise en charge est éligible à rejoindre le schéma, soit un schéma dans lequel la participation est limitée et gérée sur invitation. Un DFSP candidat peut être soumis à certains critères d'éligibilité (taille, santé financière, etc.) avant d'être admis au schéma. + +Le terme « boucle fermée » est le plus souvent utilisé pour désigner un schéma qui n'est pas interopérable, dans lequel l'entité du schéma entretient des relations directes avec tous les clients finaux. + +Le L1P est fortement en faveur des systèmes en boucle ouverte. De plus, le L1P préconise que tous les fournisseurs autorisés de comptes de transaction soient éligibles : en d'autres termes, les catégories de banques et d'émetteurs de monnaie électronique devraient être incluses et autorisées à interopérer via la plateforme du schéma. + +Il y a un certain nombre d'arguments qui soutiennent cette recommandation. Le concept même d'« inclusion financière » implique l'intégration de populations précédemment exclues dans l'écosystème financier du pays. Dans de nombreux pays, l'émission de monnaie électronique ou d'autres structures ont été approuvées par les régulateurs pour fournir des comptes de transaction à des populations que les banques traditionnelles n'ont pas pu desservir de manière économique. Ces émetteurs de monnaie électronique ont fréquemment créé des portefeuilles mobiles en boucle fermée, et l'un des objectifs du L1P et de Mojaloop est de permettre l'interopérabilité de ces portefeuilles. Cependant, les détenteurs de portefeuilles doivent payer non seulement d'autres détenteurs de portefeuilles, mais aussi des commerçants et d'autres institutions bancaires, ainsi que des individus bancarisés. Les individus et institutions bancarisés effectuent également des paiements aux détenteurs de portefeuilles. Il est logique que le même système de paiement interopérable prenne en charge les deux pour des raisons d'efficacité (pourquoi avoir plusieurs systèmes quand un seul peut connecter tous les acteurs ?) et pour des raisons économiques. + +L'argument économique tourne autour de la nature des systèmes de traitement transactionnel : plus le volume est important, plus le coût unitaire est faible. Ce principe est également soutenu dans le [Rapport PAFI de la Banque mondiale/CPMI](http://www.worldbank.org/en/topic/financialinclusion/brief/pafi-task-force-and-report) : « le cadre promeut l'innovation et la concurrence en ne faisant pas obstacle à l'entrée de nouveaux types de PSP... L'interopérabilité accrue des infrastructures soutenant la commutation, le traitement, la compensation et le règlement des instruments de paiement du même type est encouragée... les infrastructures de paiement, y compris celles exploitées par les banques centrales, ont des exigences de participation objectives, fondées sur les risques, qui permettent un accès juste et ouvert à leurs services. » Un point connexe et important est que les règles de schéma devraient spécifier qu'un participant individuel ne peut pas discriminer un autre participant individuel : sauf contrainte par d'autres facteurs (limites réglementaires de compte, etc.), les participants doivent recevoir les transactions envoyées par d'autres participants du schéma. Cela garantit une interopérabilité totale. + +La deuxième question est de savoir quels critères d'éligibilité un DFSP potentiel doit remplir pour rejoindre effectivement le schéma. De nombreux systèmes de paiement ont des procédures assez élaborées pour s'assurer que les DFSP candidats disposent des ressources financières pour se conformer aux règles et des moyens techniques pour répondre aux exigences opérationnelles des règles. + +Une certaine forme de ces exigences est nécessaire pour tout schéma. Mais la technologie moderne et, en particulier, les modèles de règlement préfinancés réduisent considérablement les risques pour le schéma dans ses relations avec les DFSP plus petits. La question d'alignement Level One ici est de s'assurer que le schéma ne discrimine pas involontairement les petits DFSP au profit des grands. L'objectif devrait être de garantir les qualifications minimales nécessaires pour soutenir les obligations qu'un DFSP candidat entreprend. + +## 3. Choix : Relation entre le schéma et la plateforme + +Nos définitions séparent le concept de schéma (l'entité qui rédige les règles d'un système de paiement) et de plateforme (l'ensemble des services qui permettent physiquement l'interopérabilité). Le plus souvent, mais pas nécessairement, la plateforme fonctionne comme un commutateur qui achemine les transactions d'un DFSP à un autre : l'alternative est des connexions physiques bilatérales entre les DFSP. + +Quelle est la relation entre le schéma et la plateforme ? Il existe de multiples modèles démontrés dans les systèmes de paiement à l'échelle mondiale : + +1. Même entité : le schéma exploite la plateforme. Cela se voit fréquemment dans les systèmes commerciaux (par ex. Visa) et également dans les systèmes fournis par la banque centrale (par ex. Banque du Mexique SPEI). + +2. Le schéma recrute la plateforme : le commutateur et les services associés sont exploités par une entité distincte, sous contrat avec l'entité du schéma. Le schéma paie l'entité de la plateforme ; ce coût est recouvré par les frais du schéma auprès de ses DFSP participants. Le système Faster Payments du Royaume-Uni fonctionne sur ce modèle (Faster Payments Scheme Ltd. mandate Vocalink pour exploiter la plateforme). + +3. Le schéma définit les paramètres selon lesquels le(s) opérateur(s) gèrent les transactions régies par les règles : s'il y a plusieurs opérateurs, ces entités doivent interopérer, encore une fois comme spécifié dans les règles de schéma. Les DFSP individuels choisissent l'opérateur qu'ils souhaitent utiliser pour accéder au système. Le système ACH américain fonctionne de cette manière, tout comme plusieurs des systèmes de paiement SEPA en Europe. + +4. Pas de commutateur : c'est en réalité une variation du modèle 3 ci-dessus. Chaque DFSP se connecte indépendamment et physiquement à chaque autre DFSP, toujours dans les contraintes fixées par les règles de schéma. Les cartes de débit en Australie fonctionnent de cette manière. + +### 3.1 Alignement L1P : Relation entre le schéma et la plateforme + +Il n'y a pas de principe Level One unique qui plaiderait en faveur de l'un de ces modèles par rapport à l'autre. Les facteurs à considérer incluent : + +- L'objectif est que tous les acteurs de l'écosystème (schéma, plateforme, DFSP, etc.) encouragent un comportement conforme au L1P. Un modèle plus contrôlé (modèles 1 ou 2) rend cela sans doute plus facile. + +- Avoir un système à faible coût est un principe fondamental. Cependant, il est discutable de savoir si cela est mieux réalisé par le modèle 1 ou le modèle 2. Les modèles 3 et 4 comportent le risque d'exclure ou de désavantager les petits DFSP ou les nouveaux entrants du système. + +- Dans les modèles 2 et 3, les fournisseurs de plateforme auront leurs propres directives opérationnelles. Il peut y avoir des situations dans lesquelles les dispositions des règles de schéma ne sont pas adéquatement reflétées ou mises en œuvre par la plateforme. Il s'agit d'une question de pouvoir et de contrôle. Le modèle 1 évite ce problème mais pourrait créer un problème de type « verrouillage fournisseur », où les DFSP n'ont d'autre choix que de payer les coûts de la plateforme contrôlée par le schéma. + +## 4. Choix : Portée des règles de schéma et autorité des règles de schéma + +### 4.1 Portée + +Les règles de schéma varient considérablement en portée d'un schéma à l'autre. Toutes couvrent les éléments essentiels de la participation au schéma, les obligations des parties et les mécanismes d'interopérabilité. Mais de nombreux schémas vont beaucoup plus loin en termes de définition de la manière dont les DFSP mettent les services de paiement à la disposition de leurs clients, et selon quelles conditions. Deux domaines méritent d'être notés : + +- Certains schémas spécifient des éléments de l'expérience de l'utilisateur final. Des exemples incluent les réseaux de cartes spécifiant les paramètres physiques et les exigences de conception des cartes. Certains systèmes (par exemple, le BIM du Pérou) spécifient comment l'interface du téléphone mobile apparaît au consommateur. D'autres systèmes (par exemple, le UPI de l'Inde) vont jusqu'à fournir les SDK et API qui définissent ce que l'application de l'utilisateur final peut fonctionnellement faire. Certains systèmes peuvent exiger qu'un DFSP recevant une transaction de crédit-push doive la comptabiliser sur le compte d'un client dans un délai spécifié. +- Certains schémas spécifient également des dispositions élaborées en matière de responsabilité sur les transactions interopérables. Ces dispositions peuvent varier selon le cas d'utilisation et les attributs particuliers d'une transaction. Par exemple, dans les réseaux de cartes, la responsabilité peut passer de l'émetteur de la carte à l'acquéreur du commerçant si le terminal du commerçant ne répond pas à certaines spécifications. + +### 4.2 Autorité des règles + +Comme décrit ci-dessus, le schéma est l'entité qui rédige les règles du système de paiement. Mais qui approuve ces règles ? Il existe deux modèles principaux sur le marché : + +- Autorité des DFSP. Dans ce modèle, tous (ou certains) changements de règles sont votés par les DFSP participants. Le vote peut être déterminé sur une base par siège, ou sur une base pondérée par le volume. De nombreux schémas ont expérimenté des variations à ce sujet. + +- Autorité du schéma avec participation des DFSP. Dans ce modèle, l'autorité des règles repose sur l'entité du schéma, mais un certain degré de participation formelle ou informelle des DFSP est inclus : cela peut être formel (comités permanents qui se réunissent pour examiner les changements de règles, périodes de commentaires sur les modifications des règles spécifiées dans les règles, etc.) ou informel (les représentants du schéma se réunissent et/ou demandent des retours écrits sur les changements de règles proposés). + +### 4.3 Alignement L1P — Portée et autorité des règles + +Il y a deux principes Level One pertinents : l'un est la gouvernance participative, et l'autre est le mandat de fournir un système à faible coût. Level One reconnaît également l'importance d'un système pratique et facile à utiliser pour les clients utilisateurs finaux, en particulier les consommateurs et commerçants pauvres. Les considérations incluent donc : + +- Les règles peuvent créer des coûts : plus les règles sont élaborées pour spécifier comment les DFSP doivent fournir des services au client, plus les coûts de conformité à ces règles seront élevés. + +- En contrepartie, il y a la valeur d'avoir une expérience utilisateur commune — il existe des preuves considérables qu'avoir une expérience commune peut aider les consommateurs à s'autoformer dans l'utilisation des services. On peut argumenter que c'est un facteur important dans la mise à l'échelle du système. Mais plus un schéma va loin dans la rédaction de règles qui affectent l'expérience de l'utilisateur final, plus il est important que les DFSP participants aient une voix dans ces règles. + +- L'expérience des schémas a montré que les règles de vote explicites, bien qu'elles semblent bonnes pour les DFSP, aboutissent souvent à des pratiques de décision très longues : c'est l'une des raisons pour lesquelles certains schémas utilisent le second modèle ci-dessus, et utilisent les DFSP participants comme groupes de réflexion, mais ne leur accordent pas l'autorité sur les règles. + +## 5. Choix : Cas d'utilisation + +L'un des choix les plus importants qu'un schéma doit faire est de déterminer quels cas d'utilisation prendre en charge. Fréquemment, un schéma de crédit-push en temps réel pour le commerce de détail commence par les paiements de personne à personne (P2P) comme premier cas d'utilisation : souvent, un schéma indiquera au marché qu'il a l'intention de prendre en charge d'autres cas d'utilisation à l'avenir. À mesure que les schémas évoluent, il y a des « sous-cas d'utilisation » significatifs à considérer : dans certaines mises en œuvre de Mojaloop, le terme « cas d'utilisation secondaire » est utilisé pour cela : par exemple, si le P2P est le cas d'utilisation, le P2P transfrontalier pourrait être un cas d'utilisation secondaire ; wallet-to-wallet et wallet-to-bank account pourraient être des cas d'utilisation secondaires. + +Les règles métier peuvent varier selon le cas d'utilisation et/ou le cas d'utilisation secondaire. Cela peut inclure des détails opérationnels (champs de données utilisés, etc.), la tarification du schéma (en particulier, l'interchange) et même des dispositions de responsabilité. + +Le document Open API utilisé par le code Mojaloop inclut la liste suivante de cas d'utilisation : + +- Transfert P2P +- Dépôt initié par un agent +- Retrait initié par un agent +- Retrait initié par un agent autorisé sur TPE +- Retrait initié par le client +- Paiement commerçant initié par le commerçant +- Paiement commerçant initié par le commerçant autorisé sur TPV +- Retrait initié par GAB +- Remboursement + +Un schéma en cours de mise en œuvre choisira ses propres cas d'utilisation primaires et secondaires, et les définitions de ceux-ci figureront dans les règles métier. Les schémas devraient considérer les éléments suivants : + +- L'interopérabilité éventuelle entre schémas sera plus facile (surtout d'un schéma implémenté par Mojaloop à un autre) si les mêmes cas d'utilisation primaires et définitions sont utilisés. + +- Les schémas peuvent avoir besoin de différencier entre la capacité d'un DFSP à initier des transactions dans un cas d'utilisation ou cas d'utilisation secondaire spécifique, et les exigences qu'un DFSP doit être en mesure de prendre en charge pour recevoir des transactions dans un cas d'utilisation ou cas d'utilisation secondaire spécifique. + +- Toute règle rédigée spécifiquement pour un cas d'utilisation ou un cas d'utilisation secondaire doit être détectable systémiquement (par étiquetage ou inférence) si la règle doit être appliquée automatiquement : cela est particulièrement important pour les frais d'interchange spécifiques aux cas d'utilisation. La manière dont cela est fait devrait faire partie de la documentation commerciale, dans les directives opérationnelles. + +### 5.1 Alignement L1P — Cas d'utilisation + +Il y a deux considérations ici. Une question significative est la relation entre les volumes élevés dans un système de paiement et la capacité à offrir des frais de traitement ultra-faibles aux DFSP participants. Presque tous les systèmes de paiement de détail prennent en charge plusieurs cas d'utilisation, y compris ceux qui ont commencé avec un seul cas d'utilisation. Les réseaux de cartes sont un excellent exemple de cela : ayant commencé pour prendre en charge les achats en point de vente, ils prennent maintenant en charge les achats en ligne, le paiement de factures, les paiements de salaires et les paiements B2B. Le traitement des paiements est une activité d'échelle : plus le volume est important, plus les coûts unitaires peuvent être faibles. Level One soutient fortement l'utilisation d'un système de paiement pour plusieurs cas d'utilisation : idéalement, tous les cas d'utilisation de détail (c'est-à-dire excluant les grands montants B2B) dans un pays. + +L'autre considération est de rendre le système de paiement facile d'accès et de compréhension pour les utilisateurs finaux. Le même système, avec des interfaces utilisateur similaires, etc., pour les cas d'utilisation sera plus facile à utiliser pour les utilisateurs finaux (en particulier les utilisateurs pauvres ou peu instruits). + +## 6. Choix : Codes QR + +Les codes QR émergent comme un facilitateur majeur des paiements commerçants dans les pays en développement. Les systèmes de paiement et les autorités nationales de paiement décident des formats, protocoles et de la portée des codes QR. Certaines des décisions incluent : + +- Le code QR est-il présenté par le commerçant et scanné par le consommateur, ou présenté par le consommateur et scanné par le commerçant ? Level One a une préférence pour les codes QR présentés par le commerçant, mis en œuvre en conjonction avec des paiements push, et non pull. Un code QR présenté par le commerçant peut être combiné avec un numéro de caisse pour permettre aux consommateurs disposant de téléphones basiques de payer facilement le même commerçant. + +- Le code QR est-il statique (le même pour tous les achats) ou dynamique ? Plutôt qu'un choix, cela est perçu comme une évolution : la plupart des marchés commencent avec des codes QR statiques, mais ont des plans pour passer à des codes dynamiques. Les codes dynamiques fonctionnent comme un message de « request to pay » dans un système de paiement push, et peuvent contenir des données spécifiques à l'achat. + +- L'approche nationale des codes QR utilise-t-elle une approche de « code QR partagé », dans laquelle un seul code QR peut représenter les identifiants de paiement d'un commerçant à travers plusieurs schémas ? La manière la plus courante dont cette approche est mise en œuvre est par l'utilisation des normes de code QR EMVCo. Une alternative est une approche de code QR unique, dans laquelle un code QR est utilisé uniquement pour accéder soit à un schéma de paiement interopérable (par exemple, le système CoDi du Mexique) soit à un système en boucle fermée (par exemple, WeChat Payments en Chine). Une approche de code QR unique peut créer des avantages de coût faible en dirigeant le volume à travers une seule plateforme nationale, tandis qu'une approche inter-schémas peut permettre la concurrence entre plusieurs schémas. + +- Si une approche de code QR partagé est utilisée, y a-t-il une entité nationale unique qui contrôle quels schémas un commerçant donné accepte ? Si oui, qui gère cette fonction de « répertoire » et quelles sont ses fonctions ? Émet-elle réellement la chaîne de données du code QR ? Si oui, signe-t-elle la chaîne et la valide-t-elle ? Il y a des spéculations selon lesquelles un répertoire de codes QR pourrait servir de point de surveillance inter-systèmes de paiement et de gestion de la fraude. Il pourrait également être lié à un registre national des entreprises d'une certaine manière. Il est intéressant de considérer qu'un répertoire de codes QR inter-schémas pourrait nécessiter ses propres règles métier, qui deviendraient des « méta-règles » existant au-dessus des règles métier des schémas individuels. + +- La chaîne de données du code QR (la « charge utile ») contient-elle l'« adresse de paiement » du commerçant, ou pointe-t-elle d'une certaine manière vers un endroit où celle-ci est stockée ? Cette dernière approche offre plus de flexibilité et prend en charge la capacité d'un commerçant à changer de fournisseur. + +- Comment le consommateur (et le commerçant) est-il protégé contre la fraude par code QR ? + +- Quels sont les aspects économiques de la transaction pour le commerçant ? Level One a une forte préférence pour une tarification nulle ou quasi nulle pour le petit commerçant ou le commerçant pauvre. + +## 7. Choix : Adressage des paiements + +Tout schéma mettant en œuvre des paiements credit-push doit spécifier comment le payeur et son DFSP payeur adressent le paiement. L'adresse doit d'une certaine manière être résolue en numéro de compte du bénéficiaire auprès du DFSP qui fournit son compte de transaction. Le schéma doit décider : + +- Quels types d'adresses de paiement (parfois appelées « identifiants ») sont utilisés. Certaines adresses de paiement sont des identifiants institutionnels et des numéros de compte : un numéro de routage bancaire et un numéro de compte bancaire en sont un exemple. D'autres adresses de paiement peuvent être des numéros de compte sans l'identifiant institutionnel : un numéro de téléphone mobile utilisé pour diriger des fonds vers un portefeuille de monnaie électronique fourni par un opérateur de réseau mobile en est un exemple. Tous les autres types d'adresses de paiement sont des alias de quelque sorte. Un alias peut être une adresse e-mail, un identifiant commerçant attribué par le schéma, un numéro d'identité national ou un numéro de téléphone mobile utilisé pour diriger des fonds vers un compte autre que celui fourni par un émetteur de monnaie électronique opérateur de réseau mobile. Un alias pris en charge par le schéma peut également être une phrase : « payadamnu123 ». + +- Pour chaque type d'adresse de paiement pris en charge par le schéma, le schéma doit déterminer comment cette adresse de paiement est résolue. Au minimum, le schéma doit prendre en charge un mécanisme par lequel l'adresse est mappée à un identifiant DFSP participant au schéma responsable du compte de transaction associé à cette adresse de paiement. La résolution peut être effectuée de plusieurs manières différentes : + + - Le schéma peut maintenir un répertoire mappant les adresses aux identifiants DFSP responsables : cela nécessite un certain type de processus d'enregistrement DFSP pour les adresses. + + - Le schéma peut maintenir un répertoire qui mappe l'adresse au DFSP responsable et spécifie également le numéro de compte : cela nécessite un processus d'enregistrement légèrement différent. + + - L'un ou l'autre de ces types de répertoires peut être maintenu par un tiers : les règles de schéma établiraient comment ces répertoires sont alimentés, maintenus et utilisés, et quelles sont les responsabilités des différentes parties. + + - Un schéma peut également utiliser une méthode de diffusion pour déterminer le DFSP responsable d'une adresse de paiement donnée (« revendiquez-vous cette adresse »), mais doit développer un protocole pour gérer les conflits si plus d'un DFSP « revendique » l'adresse. + +- Il est important de noter que la méthode de résolution peut être différente pour chaque type d'adresse de paiement pris en charge. Certains types d'adresses de paiement pris en charge peuvent également être accompagnés d'ensembles de données particuliers : par exemple, lorsqu'un paiement est effectué en règlement d'une facture, l'adresse de paiement peut être un certain type d'alias, et l'utilisation de cet alias peut être liée à des données de facture accompagnantes. Les codes QR dynamiques, par exemple, créeront une « request to pay » qui peut contenir l'identifiant commerçant pris en charge par le schéma (un alias) et le détail des données de transaction accompagnantes. + +La spécification Open API et le code de référence Mojaloop prennent en charge un large éventail de différents types d'adresses : numéro de mobile, compte bancaire, identité nationale, alias (« Quickshop\@abc »), etc. + +### 7.1 Alignement L1P — Adressage des paiements + +Un adressage de paiement sécurisé et facile se rapporte à deux concepts importants dans Level One : la commodité pour l'utilisateur final et l'« ouverture ». Ce dernier point est particulièrement important pour permettre la concurrence et la mise à l'échelle rapide d'un système de paiement. Alors que les schémas (Level One et autres) à travers le monde luttent pour déterminer comment résoudre au mieux la question de l'adressage des paiements, quelques meilleures pratiques semblent émerger : + +- Bien que l'utilisation du numéro de mobile, en particulier, comme adresse ait un attrait évident, il semble y avoir une tendance à utiliser des alias — des identifiants sans signification supplémentaire. Cela est démontré en Inde avec le système UPI et dans le nouveau système en temps réel de l'Australie, où l'identifiant est appelé PAYID. + +- La portabilité des identifiants est souhaitable, tant du point de vue de la commodité de l'utilisateur que comme mécanisme pour éviter le « verrouillage DFSP ». + +- Comme mentionné ci-dessus, le répertoire doit assurer l'unicité de l'adresse de paiement au sein du système de paiement : toute adresse donnée ne peut mapper qu'à un seul DFSP. Cependant, un seul compte de transaction DFSP peut avoir plusieurs adresses de paiement qui y dirigent. Les DFSP ont la possibilité de créer des services à valeur ajoutée pour leurs clients, dans lesquels ils différencient le traitement des transactions acheminées vers eux via différentes adresses de paiement (sous réserve, bien sûr, des règles métier globales du schéma). + +## 8. Choix : Règlement inter-participants + +Les systèmes de paiement doivent déterminer comment les DFSP participants régleront leurs obligations financières les uns envers les autres découlant des transactions interopérables. Il y a de multiples décisions à prendre concernant le modèle de règlement. Les modèles de règlement existants utilisés dans les systèmes de paiement de détail hérités comportent des contrôles importants sur les risques. En règle générale, les systèmes d'aujourd'hui ont la possibilité de faire des choix en tirant parti de la technologie moderne et de la connectivité pour gérer ces risques de différentes manières. Certains des choix sont : + +- Règlement net, brut ou brut continu. Traditionnellement, le règlement net a été utilisé pour les systèmes de paiement de détail (pratiquement parlant, tous les systèmes sauf le RTGS). Certains systèmes de paiement de détail en temps réel utilisent maintenant le règlement brut (le SPEI du Mexique) ou prévoient de le faire (le Brésil). Certains systèmes utilisent un compte de règlement brut continu (le réseau RTP américain) : dans cette approche, les DFSP possèdent conjointement un compte unique à la banque de règlement, et les parts de propriété dans le compte mutualisé sont déterminées, à tout moment, par la position du grand livre du DFSP à la plateforme. Cette approche n'utilise pas d'écritures de règlement, de compensation ou de comptabilisation d'écritures de règlement. + +- Choix de la banque de règlement. La plupart des systèmes de paiement de détail interopérables utilisent la banque centrale du pays comme banque de règlement, mais il existe des exemples (règlement par réseau de cartes aux États-Unis) où une banque commerciale est utilisée comme banque de règlement. + +- Comptes de règlement dédiés ou polyvalents. Les comptes de règlement des DFSP, détenus à la banque de règlement, sont-ils dédiés au but du règlement du schéma, ou sont-ils utilisés à d'autres fins (autres règlements de schéma, soldes de réserve, etc.) également ? Dans un modèle de règlement brut continu, le compte mutualisé est toujours un compte dédié. + +- Règlement le jour même ou différé. Dans un modèle de règlement net, les écritures de règlement sont-elles comptabilisées sur les comptes de la banque de règlement le jour de la transaction, ou plus tard ? + +- Fenêtres de règlement multiples ou uniques. Dans un modèle de règlement net, y a-t-il une seule fenêtre de règlement par jour ouvrable, ou y en a-t-il plusieurs ? Si multiples, les fenêtres sont-elles définies par des périodes de temps, le volume de transactions ou un autre facteur ? + +- Pré-financé ou non. Les écritures de règlement (dans un système net) ou les transactions individuelles (dans un système brut) sont-elles autorisées si le financement du compte de la banque de règlement n'est pas suffisant ? Si oui, quels mécanismes (lignes de crédit, comptes de garantie, etc.) sont utilisés pour couvrir ce risque ? Le terme « préfinancé » est utilisé lorsque les règles de schéma spécifient que le DFSP doit avoir suffisamment d'argent sur son compte de règlement pour couvrir une transaction sortante : sinon, la plateforme refusera la transaction. + +- Gestion dynamique de la position ou non. Dans un système de règlement net qui utilise un commutateur, le commutateur « connaît-il » la position réelle du DFSP émetteur avant d'envoyer la transaction au DFSP récepteur ? + +- Calcul automatisé ou manuel du plafond de débit net. Le plafond de débit net est un montant que le système utilise, en conjonction avec la gestion dynamique de la position, pour déterminer si une transaction individuelle est envoyée ou non au DFSP récepteur. Cela peut être soit fixé manuellement par le schéma (individuellement pour chaque DFSP) soit automatisé : ce dernier nécessite une connexion en temps réel entre le compte de la banque de règlement (dédié) et le commutateur. + +- Des composantes discrétionnaires du plafond de débit net peuvent être définies par le schéma. Il en existe deux types. Une composante discrétionnaire du schéma peut s'ajouter ou se soustraire au plafond de débit net d'un DFSP individuel. Un ajout peut être utilisé pour créer une marge de sécurité ; une soustraction peut être utilisée pour étendre les capacités de découvert au DFSP. Dans ce dernier cas, la responsabilité du découvert doit être clairement convenue entre le schéma et la banque de règlement. + +### 8.1 Alignement L1P — Règlement inter-participants + +Level One a un principe clair appelant au règlement le jour même. En dehors de cela, les considérations les plus importantes sont la manière dont un schéma donné gérera le risque et les coûts pour les DFSP — les coûts de liquidité en particulier. Il s'agit d'un domaine en évolution rapide dans les systèmes de paiement, et il est prévu que différents schémas feront des choix différents. En général, on peut observer que l'automatisation soutient la mise à l'échelle, et que le pré-financement et les fenêtres multiples soutiennent un risque et un coût faibles. + +Le code de référence Mojaloop prend en charge une variété de mécanismes de règlement différents. + +## 9. Choix : Accès par paliers + +Les systèmes de paiement de détail hérités (et les systèmes de gros) prennent généralement en charge l'accès par paliers — la capacité pour les institutions plus petites d'accéder au système via des relations de correspondance avec des institutions plus grandes. Cela a été considéré nécessaire car les institutions plus petites avaient fréquemment des difficultés à remplir les obligations de règlement de la participation directe ou les obligations techniques (en particulier la sécurité) de la participation directe. + +Dans les pays disposant de licences d'émission de monnaie électronique (ou d'autres DFSP non traditionnels, ou de fournisseurs de comptes de transaction), la question devient de savoir si ces fournisseurs non traditionnels accèdent au système directement ou par le biais d'une relation avec une banque traditionnelle : dans ces cas, c'est généralement la question du règlement, et non la question technique, qui est en jeu. + +### 9.1 Alignement L1P — Accès par paliers + +Il n'y a pas de principe Level One unique qui orienterait un schéma sur la manière de traiter cette question. Il y a, cependant, des questions de coût et de risque à considérer : + +- Il convient de noter que les grandes institutions ont créé des activités très rentables en servant ces institutions plus petites. Ces coûts, supportés par les participants indirects, seront d'une certaine manière répercutés sur les utilisateurs finaux. Pour cette raison, les schémas Level One pourraient vouloir éviter ce modèle lorsque c'est possible. + +- Le principe Level One de « boucle ouverte » suggère qu'un schéma devrait soutenir la capacité de tous les DFSP à participer directement partout où c'est possible : la technologie moderne, telle que celle utilisée par Mojaloop, et les modèles de règlement préfinancés devraient rendre cela plus simple. + +- Les systèmes hérités tendent également à « cacher » l'activité de l'institution plus petite au schéma ou au Hub. Cela peut être indésirable du point de vue réglementaire ou de la gestion des risques. Certains nouveaux systèmes de paiement de détail en temps réel (notamment le réseau RTP américain) permettent à la fois l'accès indirect technique et de règlement avec une transparence totale de l'institution plus petite vis-à-vis du schéma et de la plateforme. + +- Un autre facteur à considérer est particulier aux pays disposant d'émetteurs de monnaie électronique ou d'autres fournisseurs DFSP non traditionnels. Selon le principe L1P d'implication des DFSP dans les décisions de gouvernance, il se peut que demander aux émetteurs de monnaie électronique d'accéder à un système « sous » un participant bancaire puisse laisser ces DFSP dans une position de « second rang » en ce qui concerne la gouvernance : cela est sans doute indésirable, et en particulier dans les cas, qui semblent pertinents dans certains pays, où les émetteurs de monnaie électronique ont un volume de transactions plus élevé que leurs banques sponsors. + +Notez que cette section ne traite pas de l'accès au système par d'autres FSP : cela est abordé dans [Choix : Utilisation du schéma par d'autres FSP](#_13-choix-utilisation-du-schema-par-d-autres-fsp). + +## 10. Choix : Frais du schéma et tarification pour l'utilisateur final + +Les frais associés à un schéma de paiement interopérable peuvent être catégorisés comme : + +- Frais pour l'utilisateur final : les frais (ou exigences de solde minimum, etc.) évalués par un DFSP à son client utilisateur final. Cela inclut les frais facturés aux consommateurs, commerçants, émetteurs de factures, gouvernements ou autres entreprises. Certains de ces frais sont spécifiquement liés au transfert interopérable lui-même (par ex. un frais d'« envoi de transfert » ou un « frais d'escompte commerçant ») ; d'autres sont connexes (un frais de « décaissement », un frais de retrait au GAB). Ces frais sont généralement fixés par le DFSP. Dans certains pays et situations, la réglementation ou les accords de règles de schéma peuvent s'appliquer ou influencer les frais. Les frais peuvent être des montants fixes ; des pourcentages de valeur, ou une combinaison de montants fixes et de pourcentage de valeur. Dans tous les cas, les grilles tarifaires peuvent différer en fonction des tranches de valeur (par exemple, les transactions inférieures à la valeur « X » ont ce frais) ou du volume de transactions de l'utilisateur final. + +- Frais de traitement : les frais que le schéma et l'opérateur de la plateforme (si différent) facturent aux DFSP pour l'utilisation du schéma et de la plateforme. Comme pour les frais pour l'utilisateur final, les frais de traitement peuvent être fixes ou variables et peuvent également varier selon la tranche de valeur ou le volume de transactions. + +- Frais d'interchange : frais qu'un DFSP paie à un autre DFSP liés à une transaction interopérable. Les frais d'interchange sont normalement fixés par le schéma (dans les règles de schéma) et sont physiquement tabulés et collectés par le schéma. Le schéma et l'opérateur de la plateforme ne paient ni ne reçoivent ces frais : ils constituent un débit pour un DFSP et un crédit pour l'autre. Tant le taux des frais d'interchange que la direction (le DFSP payeur paie-t-il ou reçoit-il ?) peuvent varier selon le cas d'utilisation et le cas d'utilisation secondaire. Les frais d'interchange peuvent être fixes, un pourcentage de la valeur, ou une combinaison des deux. + +En plus de fixer les politiques de frais, les schémas devront décider de la manière dont les frais sont collectés et (dans le cas des frais d'interchange) distribués. Il y a une considération importante avec l'interchange : les frais doivent-ils être collectés et distribués dans le cadre du règlement de chaque transaction, ou sous forme de facturation en fin de période (comme mensuellement) ? + +### 10.1 Alignement L1P : Frais + +L'un des concepts Level One les plus importants est d'avoir une plateforme à coût ultra-faible, avec des frais pour les consommateurs et les petits commerçants aussi bas que possible. Un élément important pour y parvenir dans un système de paiement est d'atteindre l'échelle. Les schémas voudront considérer ces deux facteurs lorsqu'ils fixeront les politiques de frais. Les considérations incluent : + +- **Tarification pour l'utilisateur final.** Le schéma est-il en position de mettre des contrôles ou des limitations à ce sujet ? La réponse variera selon la juridiction. Certains schémas ont mis des limitations sur la structure des frais (par ex. doit être fixe vs pourcentage de la valeur), sur les parties pouvant être facturées (par ex. les payeurs peuvent être facturés mais pas les bénéficiaires, etc.) ou sur ce que les frais globaux peuvent être. Certains schémas n'ont pas écrit cela dans les règles mais ont encouragé des accords informels sur les politiques de frais (sous réserve des approbations réglementaires) pour inciter l'utilisation par les consommateurs. D'autres schémas ont interdit certains types d'actions tarifaires, comme facturer des surcharges pour les transactions interopérables. + +- **Frais de traitement.** L'objectif ici est que les frais du schéma aux DFSP soient aussi bas que possible (spécifiquement et idéalement, une fraction d'un cent américain). Les meilleures pratiques du marché sont que ces frais soient fixes, plutôt qu'un pourcentage de la valeur : cela a du sens étant donné que le schéma et la plateforme ne prennent pas de risque de valeur dans le traitement des transactions. Cependant, il y a un défi avec des frais purement fixes : comment éviter d'avoir des frais trop élevés pour les transactions de très faible valeur. Certains schémas abordent cela par des tranches de valeur, avec des frais fixes inférieurs pour les transactions en dessous d'une certaine valeur. Certains schémas établissent des paliers de volume pour inciter les DFSP. Les schémas peuvent souhaiter encourager (ou même imposer) que les DFSP acheminent les transactions « on-us » (où le DFSP payeur et le DFSP bénéficiaire sont la même institution) via la plateforme : si tel est le cas, le schéma peut souhaiter fixer un frais nul pour ces transactions. Certains schémas peuvent également facturer des frais d'adhésion et/ou d'intégration aux DFSP. Enfin, certains schémas peuvent prévoir une période après le lancement du schéma pendant laquelle tous les frais sont supprimés. + +- **Frais d'interchange**. Il s'agit d'un sujet complexe et souvent débattu dans l'industrie du paiement mondial, et qui attire fréquemment l'attention des régulateurs. Les schémas peuvent vouloir considérer : + + - S'il faut ou non avoir de l'interchange. Certains systèmes de paiement en ont ; beaucoup n'en ont pas. Les systèmes de paiement de détail en temps réel dans le monde sont partagés sur la question de savoir s'ils prennent en charge l'utilisation de l'interchange, et là où ils le font, dans quelle direction l'interchange circule pour des cas d'utilisation tels que le P2P. + + - L'interchange est un mécanisme utile pour une forme de facturation : lorsque le receveur d'un service de valeur (comme un commerçant qui veut accéder au compte de paiement d'un consommateur) n'a pas de relation avec le fournisseur de ce service (le DFSP du consommateur). Un autre exemple est celui où le GAB d'une banque est utilisé pour distribuer des fonds au client d'une autre banque. + + - L'interchange est plus discutable lorsqu'il est utilisé pour soutenir des modèles commerciaux hérités : par exemple, si une transaction interopérable fait « perdre » à un DFSP payeur un frais de décaissement qu'il aurait autrement gagné, le schéma peut spécifier un taux d'interchange dans lequel le DFSP bénéficiaire paie le DFSP payeur pour compenser cette perte. Il peut être pratique d'utiliser l'interchange dans ces situations à court terme, mais à long terme on peut argumenter que le modèle commercial sous-jacent doit évoluer. + + - Les schémas doivent garder à l'esprit que partout où l'interchange est utilisé, un « coût dur » est créé qui est absorbé par, et probablement répercuté dans les frais pour l'utilisateur final, par le DFSP payant l'interchange. + +## 11. Choix : Gestion de la marque + +Faut-il utiliser une marque de schéma ? La même marque doit-elle être utilisée pour tous les cas d'utilisation ? Ou la seule marque utilisée doit-elle être la marque du DFSP qui offre un service à ses clients ? Sans surprise, c'est une question qui a été débattue dans les systèmes de paiement au fil des ans. + +### 11.1 Alignement L1P — Marque + +Level One a un principe de conception clair soutenant une marque commune : cela repose sur le fait de rendre le service compréhensible et facile à utiliser pour les consommateurs et les commerçants. Une marque commune de schéma peut être utilisée en conjonction avec les marques des DFSP : « Utilisez DFSP SuperPay (marque DFSP) avec XPay (marque du schéma) pour payer vos factures. » + +Les règles métier devront spécifier comment et où la marque commune est utilisée. + +## 12. Choix : Connexions inter-schémas du schéma + +L'avènement de systèmes de paiement de détail en temps réel à peu près similaires dans le monde a conduit à de nombreuses discussions sur l'opportunité de connecter ces schémas entre eux. Cela peut faciliter les transactions au sein d'un pays, mais a notamment une importance pour les paiements transfrontaliers de toutes sortes, y compris les transferts de fonds des travailleurs. + +Dans les systèmes de paiement hérités, ce type de connexion est rare sur une base de schéma à schéma. Des exceptions notables incluent la connexion domestique des réseaux de GAB, et la connexion de schémas de cartes domestiques qui sont détenus ou contrôlés par des réseaux de cartes mondiaux. Ce qui se passe, au lieu de cela, c'est que les DFSP ou d'autres fournisseurs qui participent à plusieurs réseaux (soit directement, soit par le biais de partenariats) créent l'effet d'une connexion inter-schémas par des accords individuels : c'est, essentiellement, le fonctionnement de la banque correspondante transfrontalière. + +Mojaloop en tant que technologie est conçu pour permettre la connectivité système à système. Les systèmes mettant en œuvre Mojaloop devront considérer l'équilibre entre conclure des accords commerciaux de schéma à schéma (avec des connexions techniques concomitantes) et/ou permettre aux DFSP de leur schéma de se connecter bilatéralement à d'autres schémas ou DFSP. + +### 12.1 Alignement L1P — Connexions avec d'autres schémas + +Les principes L1P pertinents ici sont le faible coût et l'« ouverture ». Le code Mojaloop en particulier a le potentiel de transformer les transactions transfrontalières, qui sont régies par des relations complexes (comme dans le cas de la banque correspondante traditionnelle), en transactions qui font l'objet de concurrence dans un marché ouvert et interconnecté. Les schémas devront évaluer les mérites de cela (promouvant sans doute des coûts plus bas) avec les risques de dominance par les grandes institutions. Les arrangements commerciaux de schéma à schéma peuvent avoir des caractéristiques bénéfiques d'« égalisation des chances ». Des relations hybrides sont également possibles. Il s'agit d'un domaine en évolution de l'industrie du paiement, et un domaine où une variété considérable d'arrangements sont à la fois possibles et probables. + +## 13. Choix : Utilisation du schéma par d'autres FSP + +Un schéma aligné L1P réussi sera utilisé par de nombreuses entreprises — commerçants, émetteurs de factures, agences gouvernementales, etc. — ainsi que par des individus. Il y aura également un large éventail d'autres FSP (fournisseurs de services financiers) qui ne sont pas des DFSP : en d'autres termes, qui ne détiennent pas de comptes de transaction des clients. Cela inclut les fournisseurs de services de paiement : agrégateurs, fournisseurs de services aux commerçants, divers processeurs de DFSP, etc., qui peuvent tous vouloir se connecter et utiliser le schéma. + +Comme décrit dans le choix « participation » ci-dessus, un schéma aligné Level One inclut comme participants directs et réglants uniquement les entités qui détiennent les comptes de transaction des utilisateurs finaux : les comptes qui sont débités et crédités à la suite de la transaction interopérable. + +D'autres entités peuvent se connecter physiquement à la plateforme dans le cadre de divers arrangements commerciaux. Le schéma devra décider à quel point les règles métier du schéma sont impliquées dans la dictée des termes ou normes de ces arrangements. En règle générale, tout autre FSP se connectant à la plateforme devra agir pour le compte d'un DFSP dont le compte de transaction du client est débité (le DFSP payeur) ou crédité (le DFSP bénéficiaire). Dans les modèles de paiement hérités, le DFSP conserve toutes les obligations financières et responsabilités de la transaction : le tiers agit purement pour le compte du DFSP. Les règles métier du schéma peuvent spécifier des exigences pour les arrangements commerciaux entre le DFSP et le tiers. Dans certaines juridictions (notamment l'Inde et l'UE), la réglementation pousse à des changements de ce modèle pour permettre aux autres FSP d'avoir une implication plus directe dans les schémas. Les règles de schéma devront décrire et prescrire soigneusement les paramètres de ces arrangements. + +Note de définition : nous n'utilisons intentionnellement pas le terme « PSP » (Prestataire de services de paiement) ici, car dans diverses juridictions, ce terme est utilisé pour inclure les fournisseurs de comptes de transaction, dans certains cas, et les fournisseurs de comptes non-transactionnels dans d'autres cas. En commentaire supplémentaire, dans de nombreux pays aujourd'hui, des entités telles que les agrégateurs détiennent des comptes financiers dans des banques ou chez des émetteurs de monnaie électronique et utilisent ces comptes pour recevoir de l'argent des clients et distribuer de l'argent à d'autres clients. Dans ce rôle, l'agrégateur est un client d'un DFSP (la banque ou l'émetteur de monnaie électronique) et agit également en tant que fournisseur de services financiers. Il se peut que ces agrégateurs, à l'avenir, n'aient pas besoin d'intermédier la transaction financière, mais fournissent plutôt des instructions conduisant au transfert direct de fonds, via le schéma, du compte de transaction d'un client à celui d'un autre. + +### 13.1 Alignement L1P — Utilisation par d'autres FSP + +Les principes ici sont, encore une fois, le faible coût et l'ouverture. Level One encouragerait les nouveaux acteurs à pouvoir utiliser et accéder au schéma, tant que leurs actions sont contrôlées par le schéma afin d'assurer la sécurité et la stabilité financière. + +## 14. Choix : Normes de gestion des risques du schéma + +Les systèmes de paiement, leurs plateformes et les DFSP participants ainsi que les tiers doivent tous, évidemment, fonctionner selon des normes de gestion des risques solides afin d'assurer un écosystème de systèmes de paiement sain. + +La question pour un schéma est l'équilibre entre définir ces normes lui-même et s'appuyer sur d'autres normes. Du point de vue des règles métier, c'est un choix significatif. Les schémas peuvent soit : + +- Développer des normes détaillées de gestion des risques pour les DFSP (et pour la plateforme) et mener des processus rigoureux de certification et/ou d'audit pour assurer la conformité + +- Exiger que les DFSP, la plateforme et les tiers suivent les normes nationales ou mondiales référencées en matière de gestion des risques et de sécurité + +### 14.1 Alignement L1P — Normes de gestion des risques + +Level One ne traite pas de quel choix ci-dessus est le meilleur. Mais les concepts d'un système sûr pour les consommateurs et d'un système à faible coût s'appliquent clairement ici. Quelques considérations : + +- Un utilitaire partagé de gestion de la fraude (que les principes Level One soutiennent) peut gérer de manière rentable certaines des tâches de gestion de la fraude. Cela ne réduit pas la charge de conformité individuelle d'un DFSP, mais déplace simplement la manière dont il remplit cette charge. + +- Les réseaux de cartes mondiaux ont effectivement démontré la capacité d'automatiser des éléments du traitement des exceptions, en se concentrant sur les transactions qui se produisent le plus fréquemment. + +- La communauté Mojaloop a exprimé son intérêt pour la codification des exceptions et la fourniture d'un support par le code pour certains processus. + +- La communauté Mojaloop peut également développer des documents de meilleures pratiques pour traiter les domaines de la gestion des risques, y compris la cybersécurité. + +## 15. Choix : Gestion des exceptions + +Le traitement des exceptions comprend une grande variété de transactions et d'interactions non standard parmi les utilisateurs et les fournisseurs d'un schéma de paiement. Celles-ci incluent : + +- Les erreurs de la part des utilisateurs finaux + +- Les erreurs de la part des DFSP, de la plateforme ou d'autres FSP + +- La fraude commise par les clients utilisateurs finaux, y compris les individus, les commerçants, les émetteurs de factures ou d'autres entités + +- La fraude commise par des tiers, y compris les pirates informatiques + +- Les attaques malveillantes sur le système ou sur des DFSP individuels, y compris les cyberattaques. + +Les schémas ont des choix importants à faire sur le degré d'implication du schéma et de ses règles métier dans la définition de la manière dont les participants au schéma gèrent ces exceptions. Les systèmes de paiement hérités nous montrent une grande variété de modèles utilisés, allant de systèmes où le schéma et les règles métier ont une implication minimale dans le traitement des exceptions (chèques, la plupart des systèmes ACH) à des systèmes où le schéma et ses règles métier sont largement impliqués (la plupart des réseaux de cartes). Les systèmes de paiement de détail en temps réel dans le monde n'en sont généralement qu'aux premiers stades de la décision sur la manière de traiter ces questions. + +### 15.1 Alignement L1P — Traitement des exceptions + +Il y a deux principes de conception Level One très importants qui s'y rapportent. + +- L'un est le principe d'irrévocabilité des transactions. Cela signifie qu'une transaction de paiement qui est complétée avec succès (dans une implémentation Mojaloop, une qui a été exécutée) ne peut pas être annulée sans le consentement du bénéficiaire. + +- L'autre est l'engagement envers une ressource partagée de gestion de la fraude au niveau de la plateforme. L'idée est que le schéma et sa plateforme auront une vue plus large de toutes les données de transaction et seront en mesure d'effectuer des tâches de détection et de gestion de la fraude plus efficacement et à moindre coût que les DFSP individuels. Ce concept en est à ses tout premiers stades d'évolution à mesure que les systèmes Level One sont déployés, tant avec que sans la technologie Mojaloop. + +Les schémas feront face à des défis significatifs dans ce domaine alors que le déploiement tant attendu des paiements commerçants se produit, en particulier dans les marchés moins développés qui ne disposent pas d'industries de paiement par carte très pénétrées. Le défi sera d'équilibrer le désir de protéger les consommateurs contre la fraude des commerçants avec le désir d'avoir une tarification à faible coût pour l'utilisateur final. Sur les marchés développés de paiement par carte, cela est souvent assuré par des règles métier qui spécifient que la banque du commerçant est financièrement responsable de la fraude commise par le commerçant. Cela fonctionne mais entraîne des frais de transaction relativement élevés pour le commerçant, car sa banque doit couvrir son exposition au risque en vertu de ces règles. Ce modèle financier peut ou non être viable dans les économies moins développées. C'est un autre domaine où nous anticipons une évolution considérable dans les années à venir. diff --git a/docs/fr/adoption/Scheme/scheme-participation-agreement.md b/docs/fr/adoption/Scheme/scheme-participation-agreement.md new file mode 100644 index 000000000..6f2def25f --- /dev/null +++ b/docs/fr/adoption/Scheme/scheme-participation-agreement.md @@ -0,0 +1,76 @@ +# Modèle d'accord de participation au schéma + +- Version : 3.0 + - Auteur : Carol Coye Benson (Glenbrook) + - Date : Octobre 2019 + - Description : + +--- + +## **À propos du projet de documents métier de la communauté Mojaloop** + +Ce document fait partie du projet de documents métier de la communauté Mojaloop. Le projet est destiné à soutenir les entités (pays, régions, associations de fournisseurs ou entreprises commerciales) mettant en œuvre de nouveaux systèmes de paiement utilisant le code Mojaloop. Ces entités devront également rédiger des règles métier que les participants au système suivront. + +Le projet de documents métier de la communauté Mojaloop fournit des modèles pour les règles métier et les documents associés. De nombreux choix sont impliqués dans la mise en œuvre d'un nouveau système de paiement : les modèles présentent certains de ces choix et, le cas échéant, des commentaires sont fournis sur la manière dont le choix particulier est lié aux objectifs d'un système conforme Level One. + +Les documents suivants font partie du projet : + +- Choix clés du schéma + +- Modèle d'accord de participation au schéma + +- Modèle de règles métier du schéma + +- Modèle de directive opérationnelle de la plateforme + +- Modèle de directive opérationnelle de gestion des exceptions + +- Glossaire standard + +# Table des matières + +[1 - Demande de participation et accord](#_1-demande-de-participation-et-accord) + +[1.1 - Droit applicable](#_1-1-droit-applicable) + +[1.2 - Bloc de signature : Candidat et schéma](#_1-2-bloc-de-signature-candidat-et-schema) + +# 1. Demande de participation et accord + +::: tip NOTE +L'objectif de ce document est qu'il contienne les dispositions minimales nécessaires pour attester de la demande d'un DFSP de rejoindre le schéma et de respecter ses règles métier. En particulier, les modifications futures des règles métier ne devraient pas entraîner la nécessité de signer à nouveau ou de modifier cet accord. +::: + +L'organisation soussignée (« _Candidat_ ») demande par la présente à participer au \[Schéma\], une \[forme juridique de société\] constituée et existant selon les lois de \[définir\] et, s'il est accepté par le \[Schéma\], le Candidat accepte que sa participation au schéma soit soumise aux termes et conditions suivants. Cette demande et cet accord sont datés du \_\_\_\_\_\_\_\_\_\_\_\_\_\_ et deviendront effectifs et contraignants pour le Candidat à compter de la date indiquée ci-dessous lorsqu'ils seront signés au nom du \[Schéma\] (la « *Date d'effet* »). À compter de la date d'effet, le Candidat sera appelé un « *Participant* ». Le Candidat reconnaît que cette demande de participation et cet accord sont fondés sur une contrepartie mutuelle adéquate. Les termes non définis dans cette demande et cet accord auront les significations telles que définies dans les règles métier, comme défini ci-dessous. + +- Le Candidat sera lié par et respectera toutes les dispositions des règles métier. + +- Les règles métier comprennent les règles métier et les documents associés et autres documents qui peuvent être désignés comme documents associés de temps à autre par le schéma. Les règles métier et les documents associés incluent tous les autres documents tels que désignés dans ces documents. + +- Le schéma peut modifier les règles métier de temps à autre comme il le juge approprié, en fournissant aux participants un préavis raisonnable des changements ou ajouts que le schéma peut juger appropriés dans les circonstances. + +- Les participants paieront les frais tels que spécifiés dans les règles métier. + +- Résiliation : + + - Un participant peut résilier sa participation à tout moment sans motif, moyennant un préavis écrit de X jours. Cette résiliation sera soumise aux dispositions des règles métier concernant les coûts et les procédures de cessation des opérations du participant par rapport au schéma. Le participant restera responsable de tous les frais et autres charges et responsabilités encourus en vertu des règles métier jusqu'à la date effective de la résiliation. + + - Le schéma peut résilier un participant pour les motifs prévus dans les règles métier. + + - La résiliation d'un participant pour motif sera soumise aux obligations de résiliation et aux procédures spécifiées dans les règles métier. + + - Licence. Le participant se voit accorder une licence pour participer, y compris l'utilisation de la propriété du schéma, selon les termes spécifiés dans les règles métier. Le participant est autorisé à fournir des services en utilisant les composants de traitement du schéma et la marque du schéma et à utiliser la propriété du schéma dans les pays suivants : + + - Soumissions d'informations. Le candidat garantit et représente que toutes les informations soumises au schéma à l'appui de cette demande de participation et de cet accord sont correctes et complètes à la date de cette demande. + +## 1.1 Droit applicable + +- Choix du droit. Cette demande et cet accord et les règles métier seront interprétés et appliqués conformément aux lois de \[spécifier\] et non par les dispositions de ces lois qui détermineraient les lois de quelle juridiction s'appliqueraient en l'absence de cette clause de choix du droit. + +- Le schéma et le participant exécuteront toutes les prestations en rapport avec le schéma conformément au droit applicable. + +- Les règles métier ne seront pas comprises comme exigeant toute action qui amènerait le schéma ou le participant à violer le droit applicable. Tout conflit entre le droit applicable et une disposition des règles métier sera résolu conformément aux procédures spécifiées dans les règles métier. Aucune résolution de ce type n'exigera du participant ou du schéma qu'il prenne une mesure ou s'abstienne de toute mesure qui l'amènerait à violer le droit applicable. + +Le candidat a fait signer cette demande et cet accord de participation au nom du candidat par la personne indiquée ci-dessous sous réserve des garanties et représentations du candidat selon lesquelles cette personne a été autorisée par toutes les mesures nécessaires et appropriées de la société à conclure cette demande et cet accord de participation à la date indiquée ci-dessus et que, lorsqu'ils seront signés au nom du candidat et acceptés par le schéma, ils constitueront une obligation contraignante et exécutoire du candidat à compter de la date indiquée ci-dessous. + +## 1.2 Bloc de signature : Candidat et schéma diff --git a/docs/fr/adoption/Scheme/scheme-uniform-glossary.md b/docs/fr/adoption/Scheme/scheme-uniform-glossary.md new file mode 100644 index 000000000..0a75385c0 --- /dev/null +++ b/docs/fr/adoption/Scheme/scheme-uniform-glossary.md @@ -0,0 +1,299 @@ +# Modèle de glossaire standard + +- Version : 1.0 + - Auteur : Carol Coye Benson (Glenbrook) + - Date : Octobre 2019 + - Description : + +--- + +## **À propos du projet de documents métier de la communauté Mojaloop** + +Ce document fait partie du projet de documents métier de la communauté Mojaloop. Le projet est destiné à soutenir les entités (pays, régions, associations de fournisseurs ou entreprises commerciales) mettant en œuvre de nouveaux systèmes de paiement utilisant le code Mojaloop. Ces entités devront également rédiger des règles métier que les participants au système suivront. + +Le projet de documents métier de la communauté Mojaloop fournit des modèles pour les règles métier et les documents associés. De nombreux choix sont impliqués dans la mise en œuvre d'un nouveau système de paiement : les modèles présentent certains de ces choix et, le cas échéant, des commentaires sont fournis sur la manière dont le choix particulier est lié aux objectifs d'un système conforme Level One. + +Les documents suivants font partie du projet : + +- Choix clés du schéma + +- Modèle d'accord de participation au schéma + +- Modèle de règles métier du schéma + +- Modèle de directive opérationnelle de la plateforme + +- Modèle de directive opérationnelle de gestion des exceptions + +- Glossaire standard + +## **Introduction** + +Ceci est un glossaire des termes utilisés dans le projet de documents métier de la communauté Mojaloop, et contient d'autres termes liés aux sujets commerciaux. Un glossaire technique plus détaillé est disponible dans le cadre de la spécification Open API for FSP Interoperability. + +# Modèle de glossaire standard + +| Terme | Définition | +| :----- | :---------------------------------------------------------------------------------------------- | +| Canal d'accès | Lieux ou capacités utilisés pour initier ou recevoir un paiement. Les canaux d'accès peuvent inclure les succursales bancaires, les GAB, les terminaux au point de vente, les points d'agents, les téléphones mobiles et les ordinateurs. | +| Recherche de compte | Un processus qui détermine le DFSP responsable d'un compte de transaction. | +| Système de recherche de compte | Le système de recherche de compte est une entité abstraite utilisée pour récupérer des informations concernant le FSP dans lequel un compte, un portefeuille ou une identité est hébergé. Le système de recherche de compte lui-même peut être hébergé sur son propre serveur, dans le cadre d'un commutateur financier, ou dans les différents FSP. | +| Validation de compte | Un statut fourni par un appel API de réponse au devis : un DFSP bénéficiaire indique qu'un compte est disponible pour être crédité du montant de transfert proposé. | +| Utilisateur actif | Un terme utilisé par de nombreux fournisseurs pour décrire combien de leurs titulaires de compte sont des utilisateurs fréquents de leur service. | +| Adressage | L'utilisation d'un identifiant pour diriger un paiement d'un payeur vers un bénéficiaire, généralement un numéro de téléphone mobile ou une adresse e-mail. | +| Adjacences | Moyens par lesquels les entités et/ou les DFSP réalisent des revenus à partir de services qui ne sont pas directement associés à un paiement — par exemple, les prêts accordés aux titulaires de comptes de transaction. | +| Agent | Une entité autorisée par le fournisseur à gérer diverses fonctions telles que l'inscription des clients, l'encaissement et le décaissement à l'aide d'une caisse d'agent. | +| Point d'agent | Un emplacement physique qui possède une ou plusieurs caisses d'agent, lui permettant d'effectuer des transactions d'inscription, d'encaissement et de décaissement pour les clients au nom d'un ou plusieurs fournisseurs. La législation nationale définit si un point d'agent peut rester exclusif à un seul fournisseur. Les points d'agent peuvent avoir d'autres activités commerciales et fonctions de support. | +| Caisse d'agent | Une caisse d'agent est une « ligne » enregistrée émise par le fournisseur, soit une carte SIM spéciale, soit une machine TPV, utilisée pour effectuer des transactions d'inscription, d'encaissement et de décaissement pour les clients. La législation nationale dicte quels fournisseurs de services financiers peuvent émettre des caisses d'agent. | +| Encaissement initié par l'agent | Un cas d'utilisation défini dans le document des spécifications API. | +| Décaissement initié par l'agent | Un cas d'utilisation défini dans le document des spécifications API. | +| Agrégateur | Une forme spécialisée de fournisseur de services aux commerçants, qui gère généralement les transactions de paiement pour un grand nombre de petits commerçants. Les règles de schéma précisent souvent ce que les agrégateurs sont autorisés à faire. | +| Alias | Un identifiant de bénéficiaire qui est mappé à un DFSP bénéficiaire et à un numéro de compte de transaction. | +| Lutte contre le blanchiment d'argent (AML) | La lutte contre le blanchiment d'argent fait référence au droit applicable et, dans la mesure expressément adoptée par le schéma, aux guides de bonnes pratiques, concernant l'atténuation des risques de blanchiment d'argent. | +| API | Interface de programmation d'applications : une interface technique mise en œuvre par un protocole logiciel qui permet aux systèmes d'interagir les uns avec les autres via des structures standard, sans qu'un système utilisateur ait besoin de connaître les détails de mise en œuvre interne du système avec lequel il interagit. | +| Droit applicable | Tous les traités, conventions, lois, règlements, directives, orientations officielles ou directives d'une autorité de régulation dans la mesure où ils sont contraignants, respectivement, pour le schéma ou un participant en ce qui concerne les services du schéma. | +| Candidat | Une organisation qui a soumis ou souhaite soumettre une demande pour devenir participant, mais dont la demande n'a pas été traitée par le schéma. | +| Interface de programmation d'applications (API) | Une méthode de communication permettant l'interaction et le partage de données entre différents logiciels ou protocoles techniques. | +| Arbitrage | L'utilisation d'un arbitre, plutôt que des tribunaux, pour résoudre les litiges. | +| Documents associés | L'ensemble des documents répertoriés dans l'annexe A de ces règles. | +| Décaissement initié par GAB via OTP | Un cas d'utilisation défini dans le document des spécifications API. | +| Attribut | Une caractéristique d'une transaction, étant entendu que des règles spécifiques peuvent s'appliquer aux transactions avec des attributs spécifiques. | +| Authentification | Le processus consistant à s'assurer qu'une personne ou une transaction est valide pour le processus (ouverture de compte, initiation de transaction, etc.) en cours. | +| Autorisation | La permission donnée par le payeur ou l'entité d'effectuer un paiement. | +| Institution/entité autorisée | Institutions non financières qui ont suivi l'autorisation appropriée de la banque d'État et/ou des autorités réglementaires compétentes pour participer à la fourniture de services financiers mobiles. | +| B2P | Entreprise à personne ; un cas d'utilisation secondaire de paiement en masse. | +| Banque | Un système financier agréé dans un pays qui a la capacité d'accepter des dépôts et d'effectuer et de recevoir des paiements sur les comptes des clients. | +| Compte bancaire | Un compte de transaction offert par une banque. | +| Identifiant de compte bancaire | Un type d'identifiant de bénéficiaire. | +| Services de comptes et de transactions bancaires | Un compte de transaction détenu dans une banque. Ce compte peut être accessible par un téléphone mobile, auquel cas il est parfois appelé « banque mobile ». | +| Banque à banque | Un cas d'utilisation secondaire P2P. | +| Banque à portefeuille | Un cas d'utilisation secondaire P2P. | +| Modèle piloté par les banques | Une référence à un système dans lequel les banques sont les principaux fournisseurs de services financiers numériques aux utilisateurs finaux. La législation nationale peut l'exiger. | +| Téléphone basique | Appareil minimum requis pour utiliser les services financiers numériques. | +| Paiement de facture | Un cas d'utilisation secondaire P2B. | +| Authentification biométrique | L'utilisation d'une caractéristique physique d'une personne (empreinte digitale, iris, etc.) pour authentifier cette personne. | +| Liste noire | Une liste ou un registre d'entités (utilisateurs enregistrés) auxquelles un privilège, un service, une mobilité, un accès ou une reconnaissance particulière est refusé/bloqué. | +| Blockchain | Une technologie qui crée des architectures distribuées. Dans les systèmes de paiement, souvent une référence à un registre partagé qui enregistre et valide les transactions. | +| Blockchain | La technologie sous-jacente au bitcoin et à d'autres cryptomonnaies - un registre numérique partagé, ou une liste continuellement mise à jour de toutes les transactions. | +| Marque | Un mot et/ou une marque approuvée par le schéma pour utilisation par les participants. | +| Décaissement en masse | Un cas d'utilisation défini dans le document des spécifications API. | +| Paiement en masse | Un paiement d'un seul payeur à plusieurs bénéficiaires, par exemple des programmes de transfert d'argent d'un gouvernement ou d'une ONG à un ensemble de bénéficiaires. | +| Service de téléchargement en masse | Un service permettant l'importation de plusieurs transactions par session, le plus souvent via un fichier de transfert de données en masse utilisé pour initier des paiements. Exemple : fichier de paiement des salaires. | +| Entreprise | Entité telle qu'une société publique à responsabilité limitée ou une société qui utilise la monnaie mobile comme service ; par exemple, effectuer et accepter des paiements de factures et verser des salaires. | +| Gestion de la trésorerie | Gestion des soldes de trésorerie chez un agent. | +| Encaissement | Recevoir un crédit en monnaie électronique en échange d'espèces physiques - généralement effectué chez un agent. | +| Décaissement | Recevoir des espèces physiques en échange d'un débit sur un compte de monnaie électronique - généralement effectué chez un agent. | +| Carte à puce | Une carte à puce contient une puce informatique : elle peut être soit sans contact, soit à contact (nécessite l'insertion dans un terminal). Les normes mondiales pour les cartes à puce sont définies par EMV. | +| Compensation | Le processus au sein d'un système de paiement par lequel un DFSP payeur et un DFSP bénéficiaire débitent et créditent les comptes de leurs utilisateurs finaux. | +| Boucle fermée | Un système de paiement utilisé par un seul fournisseur, ou un groupe très restreint de fournisseurs. | +| Lutte contre le financement du terrorisme (CFT) | Initiatives visant à empêcher les individus ou les entités d'utiliser les systèmes de paiement pour envoyer des fonds à des individus ou des entités associés au terrorisme. | +| Commission | Un paiement incitatif effectué, généralement à un agent ou à un autre intermédiaire qui agit au nom d'un fournisseur de services financiers numériques. Fournit une incitation pour l'agent. | +| Engagement | Partie d'une opération de transfert en deux phases dans laquelle les fonds qui étaient réservés pour être transférés sont libérés au bénéficiaire ; le transfert est complété entre les comptes d'origine/payeur et de destination/bénéficiaire. | +| Condition | Dans le protocole Interledger, un verrou cryptographique utilisé lorsqu'un transfert est réservé. Généralement sous la forme d'un hachage SHA-256 d'une pré-image secrète. Lorsqu'elle est fournie dans le cadre d'une demande de transfert, le transfert doit être réservé de telle sorte qu'il ne soit engagé que si l'accomplissement de la condition (la pré-image secrète) est fourni. | +| Corridor | Désigne deux pays quelconques dans une transaction transfrontalière et la direction du transfert. | +| Contrepartie | L'autre partie dans une transaction de paiement ou de crédit. Un bénéficiaire est la contrepartie d'un payeur, et vice versa. | +| Coupon | Un jeton qui donne droit au porteur à une réduction ou qui peut être échangé contre des biens ou des services. | +| Virement | Un paiement ou un transfert de fonds initié par le DFSP payeur au DFSP bénéficiaire. Un virement est souvent appelé « transfert credit-push » car les fonds sont transférés depuis le compte de transaction du payeur. Le virement contraste avec le prélèvement automatique. | +| Transfrontalier | Un transfert d'un DFSP payeur domicilié dans un pays, vers un DFSP bénéficiaire domicilié dans un autre pays. | +| Transfert multi-devises | Transfert impliquant plusieurs devises, y compris un calcul de change. | +| Position actuelle | La position nette actuelle d'un participant dans le grand livre de position pour une devise donnée. | +| Client | Le client du système. Le terme est utilisé tant pour le payeur que pour le bénéficiaire. Les individus, les commerçants, les émetteurs de factures, les gouvernements et les autres entreprises sont tous des clients. Parfois désignés comme utilisateurs finaux. | +| Décaissement initié par le client | Un cas d'utilisation défini dans le document des spécifications API. | +| Achat initié par le client | Un cas d'utilisation défini dans le document des spécifications API. | +| Achat initié par le client via QR | Un cas d'utilisation défini dans le document des spécifications API. | +| DFSP (Fournisseur de services financiers numériques) | Un fournisseur de services financiers autorisé par une autorité de régulation à fournir des comptes de transaction qui détiennent les fonds des clients et sont utilisés pour effectuer et recevoir des paiements. Les DFSP ont des relations avec les consommateurs, les commerçants et d'autres entreprises, et fournissent des services financiers numériques aux utilisateurs finaux. Utilisé de manière interchangeable avec FSP (Fournisseur de services financiers). | +| Numérique | Communications électroniques entre deux individus ou entités pouvant se produire sur divers appareils électroniques (par ex. mobile, tablette, ordinateur). | +| Liquidité numérique | Une pratique consistant à conserver la valeur sous forme numérique, plutôt que d'échanger la valeur numérique contre des espèces (forme physique). | +| Paiement numérique | Un terme large incluant tout paiement exécuté électroniquement. Comprend les paiements initiés par téléphone mobile ou ordinateur. Les paiements par carte dans certaines circonstances sont considérés comme des paiements numériques. Le terme « paiement mobile » est tout aussi large et comprend une grande variété de types de transactions qui utilisent d'une manière ou d'une autre un téléphone mobile. | +| Prélèvement automatique | Un paiement ou un transfert de fonds initié par le DFSP bénéficiaire au DFSP payeur. Un prélèvement automatique est souvent appelé « transfert debit-pull » car les fonds sont prélevés du compte de transaction du payeur. Le prélèvement automatique contraste avec le virement. | +| Répertoire | Un registre centralisé ou décentralisé d'identifiants de paiement à utiliser pour l'adressage, accessible par le système de paiement ou les DFSP. | +| Résolution des litiges | Un processus spécifié par un fournisseur ou par les règles d'un schéma de paiement pour résoudre les problèmes entre les utilisateurs finaux et les fournisseurs, ou entre un utilisateur final et sa contrepartie. | +| Domestique | Décrit une transaction entre deux DFSP domiciliés dans le même pays. | +| Monnaie électronique | Fonds ou valeur numériques détenus par un titulaire de compte de transaction sur un dispositif de paiement tel qu'une puce, une carte prépayée, un téléphone mobile ou un système informatique. La réglementation nationale précise quels types de DFSP peuvent émettre de la monnaie électronique. | +| Émetteur de monnaie électronique | Un DFSP autorisé dans le pays à agir en tant qu'émetteur de monnaie électronique. | +| Utilisateur final | Le client d'un DFSP. Le client peut être un consommateur, un commerçant, un gouvernement ou une autre forme d'entreprise. | +| Frais pour l'utilisateur final | Frais évalués par un DFSP à son client utilisateur final. | +| Entreprise | Toute personne non individuelle qui est cliente d'un DFSP : comprend les commerçants, les émetteurs de factures, les agences gouvernementales et d'autres entreprises. | +| Compte séquestre ou de fiducie | Un compte détenu par un DFSP non bancaire dans une banque ; normalement une exigence réglementaire pour protéger les dépôts des consommateurs auprès du DFSP. | +| Exceptions | Transactions erronées ou frauduleuses. | +| FATF | Le Groupe d'action financière est une organisation intergouvernementale pour lutter contre le blanchiment d'argent et agir contre le financement du terrorisme. | +| Téléphone basique | Un téléphone mobile sans capacités de calcul significatives. | +| Frais | Les paiements évalués par un fournisseur à son utilisateur final. Il peut s'agir d'un frais fixe, d'un frais en pourcentage de la valeur, ou d'un mélange. | +| Monnaies fiduciaires | Monnaie officielle émise par la banque centrale d'un pays ou d'une région comme monnaie légale. | +| Inclusion financière | La fourniture durable de services financiers numériques abordables qui intègrent les utilisateurs finaux à faible revenu dans l'économie formelle. | +| Inclusion financière | La fourniture durable de services financiers numériques abordables qui intègrent les personnes pauvres dans l'économie formelle. | +| Littératie financière | Consommateurs et entreprises possédant des compétences financières essentielles, telles que la préparation d'un budget familial ou la compréhension de concepts tels que la valeur temporelle de l'argent, l'utilisation d'un produit ou service de services financiers numériques, ou la capacité de postuler pour un tel service. | +| Fintech | Un terme utilisé pour décrire l'intersection de la finance et de la technologie. Les « fintechs » sont des entités fournissant des solutions innovantes dans le domaine financier, en tirant parti de la technologie. | +| Flottant | Ce terme peut signifier une variété de choses différentes. En banque, le flottant est créé lorsque le compte d'une partie est débité ou crédité à un moment différent de celui de la contrepartie à la transaction. La monnaie électronique, en tant qu'obligation d'un fournisseur non bancaire, est parfois désignée comme flottant. | +| Fraude | Utilisation criminelle des services financiers numériques pour prendre des fonds à un autre individu ou entreprise, ou pour nuire à cette partie d'une autre manière. | +| Gestion du risque de fraude | Outils pour gérer les risques des fournisseurs, et parfois les risques des utilisateurs (par exemple, pour les commerçants ou les gouvernements) dans la fourniture et/ou l'utilisation des services de services financiers numériques. | +| FSP | L'entité qui fournit un service financier numérique à un utilisateur final (soit un consommateur, une entreprise ou un gouvernement). Utilisé de manière interchangeable avec DFSP (Fournisseur de services financiers numériques). | +| Transfert exécuté | Un transfert qui a été accepté par le DFSP bénéficiaire et enregistré comme terminé par le schéma. Une fois qu'un transfert a été enregistré comme terminé par le schéma, le payeur est tenu d'honorer la transaction lorsqu'elle apparaît dans un règlement. | +| Accomplissement | Dans le protocole Interledger, un secret qui est la pré-image d'un hachage SHA-256, utilisé comme condition sur un transfert. La pré-image est requise dans le message d'engagement pour déclencher l'engagement du transfert. | +| FX | Change (Foreign Exchange). | +| G2P | Un cas d'utilisation secondaire de paiement en masse. | +| Gouvernance | L'ensemble des approches de gestion, des décisions et des fonctions de surveillance au sein du schéma. La gouvernance du schéma peut donner le ton de tout ce qui se passe dans le schéma. | +| Agence gouvernementale | Tout titulaire de compte de transaction qui est une sorte d'agence ou de département gouvernemental. | +| Services d'acceptation des paiements gouvernementaux | Services qui permettent aux gouvernements de collecter des impôts et des frais auprès des individus et des entreprises. | +| Règlement brut | Une méthode de règlement des obligations financières entre les DFSP et un schéma. Le règlement brut traite chaque transaction individuellement. Les détails du modèle de règlement brut sont spécifiés dans les règles de schéma. Le règlement brut contraste avec le règlement net. | +| Hub | Un terme qui peut être utilisé pour l'entité qui exploite la plateforme au nom du schéma. | +| Service d'identifiant | La manière dont le processus de recherche de compte fonctionne pour un type d'identifiant donné. | +| Identité | Un justificatif d'identité de quelque sorte qui identifie un utilisateur final. Les identités nationales sont délivrées par les gouvernements nationaux. Dans certains pays, une identité financière est délivrée par les fournisseurs de services financiers. | +| Transfert de fonds immédiat | Un paiement numérique qui est reçu par le bénéficiaire presque immédiatement après que le payeur a initié la transaction. | +| Interchange | Une structure au sein de certains systèmes de paiement qui obligent un fournisseur à payer à l'autre fournisseur des frais sur certaines transactions. Généralement utilisé dans les schémas de cartes pour effectuer le paiement d'un frais d'un commerçant à la banque émettrice de la carte du consommateur. | +| Interledger | Le protocole Interledger est un protocole pour transférer de la valeur monétaire à travers plusieurs réseaux de paiement déconnectés en utilisant une chorégraphie de transferts conditionnels sur chaque réseau. | +| Transfert de fonds international | Effectuer et recevoir des paiements vers une autre personne dans un autre pays. | +| Interopérabilité | La capacité d'un client disposant d'un compte de transaction chez un participant à échanger une transaction avec un client qui a un compte de transaction chez un participant différent. | +| Service d'interopérabilité pour les transferts (IST) | Un commutateur. | +| Irrévocable | Une transaction qui ne peut pas être « rappelée » par le payeur ; un paiement irrévocable, une fois reçu par un bénéficiaire, ne peut pas être repris par le payeur. | +| Connaissance du client (KYC) | Exigences réglementaires pour qu'un DFSP établisse l'identité et les activités d'un utilisateur final ou d'une entité, tant avant l'ouverture d'un compte de transaction que dans le temps. | +| Grand livre | Un registre tenu des transactions. | +| Level One Project | Une initiative de la Fondation Bill & Melinda Gates pour promouvoir l'inclusion financière. | +| Responsabilité | Une obligation légale d'une partie envers une autre ; requise soit par la législation nationale, les règles du système de paiement, ou des accords spécifiques entre fournisseurs. Certaines règles de schéma transfèrent les responsabilités d'une transaction d'un fournisseur à un autre dans certaines conditions. | +| Licence | La licence accordée à un candidat par le schéma lors de l'acceptation de l'accord de participation au schéma, qui autorise le participant à participer au schéma et à utiliser la propriété du schéma conformément aux règles. | +| Liquidité | La disponibilité d'actifs liquides pour soutenir une obligation. Les banques et les fournisseurs non bancaires ont besoin de liquidité pour honorer leurs obligations. Les agents ont besoin de liquidité pour faire face aux transactions de décaissement des consommateurs et des petits commerçants. | +| Prêts | Moyens par lesquels les utilisateurs finaux peuvent emprunter de l'argent. | +| Commerçant | Une entreprise qui vend des biens ou des services et reçoit des paiements pour ces biens ou services. | +| Acquisition de commerçants | Le processus d'activation d'un commerçant pour la réception de paiements électroniques. | +| Codes de catégorie de commerçants | Un ensemble de catégorisation défini par un schéma pour différencier les clients entreprises. | +| Identifiant commerçant | Un type d'identifiant de bénéficiaire. | +| Fournisseur de services aux commerçants | Un fournisseur (banque ou non-banque) qui soutient les exigences des commerçants ou d'autres accepteurs de paiements pour recevoir des paiements de clients. Le terme « acquéreur » est utilisé spécifiquement en lien avec l'acceptation des transactions de paiement par carte. | +| Achat initié par le commerçant | Un cas d'utilisation défini dans le document des spécifications API. | +| Achat initié par le commerçant via TPV/OTP | Un cas d'utilisation défini dans le document des spécifications API. | +| Achat initié par le commerçant via QR | Un cas d'utilisation défini dans le document des spécifications API. | +| Institution de microfinance (IMF) | Une entité qui offre des services financiers aux populations à faible revenu. Presque toutes les IMF accordent des prêts à leurs membres, et beaucoup offrent des services d'assurance, de dépôt et autres. Les IMF sont considérées comme des DFSP dans un système Level One si elles fournissent des comptes de transaction à leurs clients. Les IMF qui ne sont pas des DFSP peuvent se connecter directement à une plateforme Level One, par le biais d'une relation avec un DFSP. Les règles de schéma préciseront comment ces IMF peuvent interagir avec la plateforme. | +| Opérateur de réseau mobile (ORM) | Une entreprise qui vend des services de téléphonie mobile, y compris les communications vocales et de données. | +| Opérateur de transfert d'argent | Un fournisseur spécialisé de services financiers numériques qui gère les transferts de fonds nationaux et/ou internationaux. | +| MSISDN | Numéro identifiant de manière unique un abonnement dans un réseau de téléphonie mobile. Ces numéros utilisent la norme E.164 qui définit le plan de numérotation pour un réseau téléphonique public commuté (RTPC) mondial. | +| Règlement net multilatéral | Un type de règlement qui gère les positions d'un groupe de participants dans un schéma. | +| Document d'identité national | Un justificatif qui identifie un utilisateur final. Les documents d'identité nationaux sont délivrés par les gouvernements nationaux. | +| Communication en champ proche | Une technologie de communication utilisée dans les paiements pour transmettre des données de paiement d'un téléphone mobile équipé NFC à un terminal compatible. | +| Plafond de débit net | Une valeur que la plateforme utilise pour déterminer si un DFSP payeur peut envoyer une demande de transfert, comme défini dans les règles opérationnelles du schéma. | +| Marge du plafond de débit net | Une valeur fixée par un schéma qui augmente ou diminue le plafond de débit net d'un participant. | +| Position nette | Une valeur dans le grand livre d'un participant au schéma, reflétant le solde net des obligations dues. | +| Règlement net | Un type de règlement qui compense la position d'un participant dans un schéma, reflétant à la fois les obligations dues à et par d'autres participants ou le schéma. | +| Non-banque | Une entité qui n'est pas une banque agréée, mais qui fournit des services financiers aux utilisateurs finaux. Les exigences pour que les non-banques fassent cela, et les limitations de ce qu'elles peuvent faire, sont spécifiées par la législation nationale. | +| Modèle piloté par les non-banques | Une référence à un système dans lequel les non-banques sont les fournisseurs de services financiers numériques aux utilisateurs finaux. Les non-banques doivent généralement répondre à des critères établis par la législation nationale et appliqués par les régulateurs. | +| Non-répudiation | Capacité de prouver l'authenticité d'une transaction, par exemple en validant une signature numérique. | +| Sans perte | Un modèle de recouvrement des coûts avec un ensemble supplémentaire de fonds disponibles pour couvrir les besoins d'investissement pour exploiter la plateforme. | +| Notification | Avis à un payeur ou un bénéficiaire concernant l'état du transfert. | +| Paiements off-us | Paiements effectués dans un système ou schéma à participants multiples, où le fournisseur du payeur est une entité différente de celle du fournisseur du bénéficiaire. | +| Paiements on-us | Paiements effectués dans un système ou schéma à participants multiples, où le fournisseur du payeur est la même entité que le fournisseur du bénéficiaire. | +| Achat en ligne | Un cas d'utilisation secondaire P2B. | +| Spécification Open API | La spécification Open API for FSP Interoperability. | +| Boucle ouverte | Un système ou schéma de paiement conçu pour que plusieurs fournisseurs y participent. Les règles du système de paiement ou la législation nationale peuvent restreindre la participation à certaines catégories de fournisseurs. | +| Règles opérationnelles | Règles rédigées par un schéma qui lient les participants au schéma. Parfois appelées « règles métier ». | +| Gestion des risques opérationnels | Outils pour gérer les risques des fournisseurs dans l'exploitation d'un système de services financiers numériques. | +| Opérateur | Une entité qui fournit et/ou gère la plateforme d'un système de paiement. | +| Organisation | Une entité telle qu'une entreprise, une œuvre de bienfaisance ou un département gouvernemental qui utilise la monnaie mobile comme service ; par exemple, recevoir des paiements de factures, effectuer des paiements de factures et verser des salaires. | +| OTP | Code à usage unique. L'OTP est un identifiant qui, par définition, ne peut être utilisé qu'une seule fois. Il est généré puis validé par le même FSP pour une approbation automatique. L'OTP est généralement lié à un payeur spécifique dans un paiement. L'OTP généré est généralement un nombre entre 4 et 6 chiffres. | +| Services au guichet | Services fournis par des agents lorsqu'une partie finale n'a pas de compte de monnaie électronique : le payeur (distant) peut payer la monnaie électronique sur le compte de l'agent, qui paie ensuite en espèces au bénéficiaire ne disposant pas de compte. | +| P2P | Un cas d'utilisation défini dans le document des spécifications API. | +| Participant | Un fournisseur qui est membre d'un schéma de paiement et soumis aux règles de ce schéma. | +| Marge discrétionnaire du participant sur le plafond de débit net | Une valeur fixée par un participant qui diminue son plafond de débit net. | +| Accord de participation | Un accord conclu entre chaque participant et un schéma. | +| Frais de participation | Frais pour la participation à un schéma de paiement (parfois appelés frais d'adhésion). | +| Requête Parties | Un appel API au service de répertoire du schéma par lequel un DFSP payeur demande l'identifiant du DFSP auprès duquel un identifiant de bénéficiaire est enregistré. | +| Réponse à la requête Parties | La réponse du service de répertoire du schéma à une requête Parties. | +| Banque partenaire | Institution financière soutenant le FSP et lui donnant accès à l'écosystème bancaire local. | +| Partie | Une entité qui utilise les services du schéma directement ou indirectement. | +| Identifiant de partie | Un élément d'information qui identifie de manière unique un client dans une mise en œuvre d'interopérabilité. | +| Type d'identifiant de partie | Une énumération qui distingue les différents types d'identifiants de partie. La gamme complète des types d'identifiants de partie est donnée dans la spécification Open API ; le sous-ensemble des types d'identifiants de partie pris en charge par un schéma donné est indiqué dans ses règles opérationnelles. | +| Bénéficiaire | Le destinataire de fonds électroniques dans une transaction de paiement. | +| DFSP bénéficiaire | Le rôle d'un participant qui reçoit un transfert au nom de son client bénéficiaire. | +| Payeur | Le payeur de fonds électroniques dans une transaction de paiement. | +| DFSP payeur | Le participant qui envoie un transfert. | +| Paiement | Un échange de fonds, d'identifiants et d'autres informations nécessaires pour compléter une obligation entre les utilisateurs finaux. Un transfert est un paiement. | +| Dispositif de paiement | Le dispositif de paiement est la notion abstraite d'un appareil électronique, autre que le propre appareil du payeur, capable de permettre à un payeur d'accepter une transaction via l'utilisation d'un identifiant (une sorte d'OTP). Des exemples de dispositifs (de paiement) sont les GAB et les TPV. | +| Système de paiement | Un terme large pour décrire le système global, y compris le schéma, les services du schéma et les participants au schéma. | +| Opérateur de système de paiement | L'entité qui exploite un système ou schéma de paiement. | +| Prestataire de services de paiement (PSP) | Un terme utilisé de deux manières : généralement, pour toute entreprise impliquée dans la fourniture de services de paiement (y compris les DFSP) ; ou pour un fournisseur qui offre des produits ou services de marque aux utilisateurs finaux, y compris les commerçants. Les PSP peuvent se connecter directement à une plateforme Level One, par le biais d'une relation avec un DFSP. Les règles de schéma préciseront comment les PSP peuvent interagir avec la plateforme. | +| Informations personnelles | Informations relatives à toute personne individuelle, y compris les clients ou les employés du schéma ou d'un participant, à partir desquelles l'individu peut être identifié ou reconnu, quelle que soit la forme de ces informations. | +| Plateforme | L'ensemble des capacités opérationnelles, incluant souvent un commutateur, qui mettent en œuvre l'échange de paiements dans un système de paiement interopérable conforme Level One. | +| Plateforme | Un terme utilisé pour décrire le logiciel ou le service utilisé par un fournisseur, un schéma ou un commutateur pour gérer les comptes des utilisateurs finaux et envoyer et recevoir des transactions de paiement. | +| Compte de règlement mutualisé | Un compte bancaire à la banque, détenu conjointement par les participants au schéma. | +| Grand livre de position | Un grand livre tenu par la plateforme qui enregistre les écritures de règlement provisoires et définitives pour un participant dans une devise donnée. | +| Comptabilisation | L'acte du fournisseur d'enregistrer une écriture de débit ou de crédit dans le relevé de compte de l'utilisateur final. | +| Frais de traitement | Frais facturés par le schéma aux participants pour le traitement effectué par la plateforme du schéma. | +| Processeur | Une entreprise qui gère, sur une base externalisée, diverses fonctions pour un DFSP. Ces fonctions peuvent inclure la gestion des transactions, la gestion de la base de données clients et la gestion des risques. Les processeurs peuvent également effectuer des fonctions pour le compte de systèmes de paiement, de schémas ou de commutateurs. Les processeurs peuvent se connecter directement à une plateforme Level One, agissant au nom d'un DFSP. Les règles de schéma préciseront comment les processeurs peuvent interagir avec la plateforme. | +| Débit provisoire | Un enregistrement dans le grand livre de position du schéma d'une demande de transfert qui n'a pas été exécutée ; enregistré uniquement dans le grand livre de position du DFSP payeur. | +| PSP | Prestataire de services de paiement. | +| Paiement pull | Un type de transaction initiée par le DFSP du bénéficiaire. Les prélèvements automatiques, les chèques et les paiements par carte sont tous des paiements pull. Les paiements pull peuvent être rejetés ou échouer pour insuffisance de fonds sauf si une autorisation séparée est effectuée (par ex. cartes). | +| Paiement push | Un type de transaction initié par le DFSP payeur. Ceci est parfois appelé un virement. | +| Achat par code QR | Un cas d'utilisation secondaire P2B. | +| Code QR (Quick-Response) | Une méthode d'encodage et de visualisation de données sous forme lisible par machine. Il existe de multiples modèles de QR. | +| Devis | Un processus par lequel un DFSP bénéficiaire reconnaît la validité du compte du bénéficiaire pour accepter un transfert, et définit les termes (et éventuellement les frais) liés à ce transfert. | +| Demande de devis | Une demande par un DFSP payeur de données relatives à un transfert proposé. | +| Réponse au devis | La réponse d'un DFSP bénéficiaire à une demande de devis. | +| Règlement brut en temps réel (RTGS) | Un modèle de règlement qui règle les transferts sur une base individuelle, plutôt que nette. | +| Paiements de détail en temps réel (RTRP) | Paiements de détail qui sont traités en temps réel (au moment de l'initiation). | +| Montant reçu | Le montant qui est crédité sur le compte de transaction du bénéficiaire. | +| Rapprochement | Le rapprochement inter-FSP est le processus consistant à s'assurer que deux ensembles d'enregistrements, généralement les soldes de deux comptes, sont en accord entre les FSP. Le rapprochement est utilisé pour s'assurer que l'argent quittant un compte correspond à l'argent réellement transféré. Cela se fait en s'assurant que les soldes correspondent à la fin d'une période comptable particulière. | +| Recours | Droits accordés à un utilisateur final par la loi, les règles opérationnelles privées ou des accords spécifiques entre fournisseurs, permettant aux utilisateurs finaux de faire certaines choses (parfois révoquer une transaction) dans certaines circonstances. | +| Remboursement | Un transfert qui annule une transaction précédente. | +| Régulateur | Une organisation gouvernementale investie du pouvoir par la législation nationale de fixer et d'appliquer des normes et des pratiques. Les banques centrales, les départements des finances et du trésor, les régulateurs des télécommunications et les autorités de protection des consommateurs sont tous des régulateurs impliqués dans les services financiers numériques. | +| Demande de devis | Un appel API qui initie une transaction par laquelle le DFSP payeur demande au DFSP bénéficiaire des informations concernant un transfert proposé. | +| Demande de transfert | Un message qui est transmis d'un DFSP payeur via la plateforme à un DFSP bénéficiaire, qui demande qu'un transfert soit effectué du payeur au bénéficiaire. | +| Request to pay | Un message par lequel un bénéficiaire « demande » un paiement à un payeur. Une request to pay dans un système Level One est souvent utilisée pour décrire un commerçant qui demande un paiement push à un utilisateur final. | +| Réservation | Partie d'une opération de transfert en deux phases dans laquelle les fonds à transférer sont bloqués (les fonds ne peuvent être utilisés à aucune fin jusqu'à ce qu'ils soient annulés ou engagés). Cela est généralement fait pour une durée prédéterminée, dont l'expiration entraîne l'annulation de la réservation. | +| Paiement de détail | Un paiement ou un transfert entre utilisateurs finaux, généralement de faible valeur. Le terme est souvent utilisé pour décrire les paiements P2P, B2P ou P2B. | +| Annulation | Le processus d'annulation d'un transfert terminé. | +| Gestion des risques | Les pratiques que les entreprises mettent en œuvre pour comprendre, détecter, prévenir et gérer divers types de risques. La gestion des risques se fait chez les fournisseurs, dans les systèmes de paiement, chez les processeurs et chez de nombreux commerçants ou accepteurs de paiements. | +| Approche fondée sur les risques | Une approche réglementaire et/ou de gestion commerciale qui crée différents niveaux d'obligation en fonction du risque de la transaction ou du client sous-jacent. | +| Annulation | L'annulation signifie que les fonds électroniques qui étaient précédemment réservés sont remis dans leur état d'origine. La transaction financière est annulée. Les fonds électroniques ne sont plus bloqués pour utilisation. | +| Règles | Les pratiques et normes nécessaires au fonctionnement des services de paiement définies par le schéma. Les règles sont parfois appelées règles de schéma, règles métier ou règles opérationnelles. | +| Modification des règles | Tous les changements, ajouts, suppressions ou autres modifications des règles opérationnelles du schéma ou de tout document associé. | +| Épargne et investissement | Conserver des fonds pour les besoins futurs et le rendement financier. | +| Produits d'épargne | Un compte chez un fournisseur bancaire ou non bancaire, qui stocke des fonds dans le but d'aider les utilisateurs finaux à économiser de l'argent. | +| Schéma | Un ensemble de règles, pratiques et normes nécessaires au fonctionnement des services de paiement. | +| Cas d'utilisation secondaire | Un sous-ensemble d'un cas d'utilisation. Des règles métier ou des directives opérationnelles spécifiques peuvent s'appliquer aux cas d'utilisation secondaires. | +| Élément sécurisé | Une puce sécurisée sur un téléphone qui peut être utilisée pour stocker des données de paiement. | +| Code d'accès de sécurité | Un numéro d'identification personnel (PIN), un mot de passe/mot de passe à usage unique (OTP), une reconnaissance biométrique, un code ou tout autre dispositif fournissant un moyen d'accès certifié au compte d'un client aux fins, entre autres, d'initier un transfert électronique de fonds. | +| Incident de sécurité | (i) Accès non autorisé ou divulgation d'informations personnelles ou de données de transaction relatives aux clients éligibles pour initier ou recevoir des transferts via le schéma qui s'est produit ou dont on soupçonne raisonnablement qu'il s'est produit ; ou (ii) une violation confirmée des réseaux ou systèmes d'un participant ou des réseaux ou systèmes de son fournisseur qui expose des informations personnelles ou des données de transaction relatives au schéma qui s'est produite ou dont on s'attend raisonnablement à ce qu'elle se soit produite. | +| Montant envoyé | Le montant qu'un payeur autorise à être débité de son compte de transaction. | +| Données sensibles du consommateur | Les données sensibles du consommateur désignent toute ou toutes les informations utilisées par un consommateur pour authentifier son identité et obtenir l'autorisation d'effectuer des services bancaires mobiles, y compris mais sans s'y limiter, l'identifiant utilisateur, le mot de passe, le PIN mobile, le PIN de transaction. Comprend également les données relatives aux croyances religieuses ou autres, à l'orientation sexuelle, à la santé, à la race, à l'origine ethnique, aux opinions politiques, à l'appartenance syndicale, au casier judiciaire. | +| Services | Éléments de la plateforme du schéma qui fournissent des capacités d'interopérabilité aux participants du schéma. | +| Règlement | Un processus par lequel les participants règlent leurs obligations les uns envers les autres et envers le schéma liées à l'échange de transactions tel qu'énoncé dans les directives opérationnelles de règlement. | +| Banque de règlement | Une banque désignée par le schéma pour être partenaire dans la gestion du règlement et dans laquelle chaque participant doit avoir un compte bancaire aux fins du règlement. | +| Compte bancaire de règlement | Le compte bancaire détenu par un participant auprès de la banque de règlement ou auprès d'une banque convenue avec la banque de règlement, qui est utilisé pour le règlement entre le schéma et le participant. | +| Instruction de règlement | Désigne une instruction donnée à un système de règlement par un participant au système de règlement ou par un opérateur de système de compensation de paiement au nom d'un participant au système de règlement de la banque centrale pour effectuer le règlement d'une ou plusieurs obligations de paiement, ou pour acquitter toute autre obligation d'un participant au système envers un autre participant au système. | +| Obligation de règlement | Désigne une dette due par un participant au système de règlement à un autre à la suite d'une ou plusieurs instructions de règlement. | +| Fenêtre de règlement | Une période de temps entre deux règlements nets successifs tels que planifiés conformément aux directives opérationnelles de règlement. | +| Service partagé | Un ensemble commun de services que les DFSP participants collaborent pour développer et/ou utiliser. | +| Smartphone | Un appareil qui combine un téléphone mobile avec un ordinateur. | +| Banques à charte spéciale | Banques dans un pays qui sont autorisées à effectuer un ensemble limité de fonctions, tel que déterminé par la réglementation. Les banques à charte spéciale qui ne peuvent qu'accepter des dépôts et gérer des paiements sont considérées comme des DFSP dans un système Level One. | +| Sponsor | Un arrangement entre un émetteur de monnaie électronique et une banque, utilisé pour le paiement et la collecte des frais d'interchange par les émetteurs de monnaie électronique. | +| Organisme de normalisation | Une organisation qui crée des normes utilisées par les fournisseurs, les systèmes de paiement. | +| Compte de valeur stockée | Compte dans lequel les fonds sont conservés dans un format électronique sécurisé. Peut être un compte bancaire ou un compte de monnaie électronique. | +| Rapport de transaction suspecte | Si une institution financière remarque quelque chose de suspect dans une transaction ou une activité, elle peut déposer un rapport auprès de la cellule de renseignement financier qui l'analysera et le recoupera avec d'autres informations. Les informations dans un RTS varient selon la juridiction. | +| Commutateur | Une entité de traitement dans un système de paiement qui achemine une transaction d'un DFSP à un autre DFSP. Un système peut exploiter son propre commutateur, ou cette fonction peut être effectuée par un ou plusieurs tiers. | +| Système | Un terme utilisé pour décrire le schéma, les services, la plateforme et les participants alignés sur un Level One Project. | +| Risque systémique | Dans les systèmes de paiement, le risque d'effondrement d'un système financier entier ou d'un marché entier, par opposition au risque associé à un fournisseur individuel ou un utilisateur final individuel. | +| Le Level One Project | Une initiative de la Fondation Bill & Melinda Gates, au sein du programme Services financiers pour les pauvres, qui travaille à soutenir les pays ou régions construisant des systèmes de services financiers numériques interopérables et à faible coût pour intégrer les personnes et les commerçants à faible revenu dans l'économie formelle. | +| Accès par paliers | Une disposition établie dans les règles de schéma qui permet à un DFSP de participer au système sous le parrainage d'un autre DFSP. | +| Achat par numéro de caisse | Un cas d'utilisation secondaire P2B. | +| Transaction | Un ensemble d'appels API connexes qui sont échangés entre les participants via le schéma, y compris un transfert. | +| Compte de transaction | Un compte bancaire ou un portefeuille offert à un client par un DFSP. | +| Titulaire du compte de transaction | Le client d'un DFSP qui détient le compte de transaction fourni par ce DFSP. | +| Type de titulaire du compte de transaction | Une désignation utilisée pour définir si le titulaire du compte de transaction est un consommateur, une entreprise, une agence gouvernementale ou une agence à but non lucratif. | +| Type de compte de transaction | Une désignation utilisée pour définir un compte de transaction comme étant soit un compte bancaire, soit un portefeuille de monnaie électronique. | +| Coût de transaction | Le coût pour un fournisseur de services financiers numériques de fournir un service financier numérique. Cela pourrait être pour un ensemble de services (par exemple, un « portefeuille ») ou pour des transactions individuelles. | +| Frais de transaction | Frais pour le traitement des transactions interopérables fixés par un schéma. | +| Transfert | Terme générique pour décrire toute transaction financière où de la valeur est transférée d'un compte à un autre. | +| Montant du transfert | Le montant que le DFSP payeur transfère à un DFSP bénéficiaire en utilisant le schéma. | +| Demande de transfert | Une demande par un DFSP payeur d'effectuer un transfert. | +| Réponse au transfert | La réponse d'un DFSP bénéficiaire à une demande de transfert. | +| Compte de fiducie | Un moyen de détenir des fonds au profit d'une autre partie. Les émetteurs de monnaie électronique sont généralement tenus par la loi de détenir la valeur des comptes de monnaie électronique des utilisateurs finaux dans une banque, généralement dans un compte de fiducie. Cela accomplit les objectifs d'isolation et de protection des fonds. | +| Ubiquité | Un terme utilisé pour décrire la capacité de payer n'importe qui et d'être payé par n'importe qui. | +| Non bancarisé | Les personnes non bancarisées n'ont pas de compte de transaction. Les personnes sous-bancarisées peuvent avoir un compte de transaction mais ne l'utilisent pas activement. Sous-desservi est un terme large désignant les personnes qui sont les cibles des initiatives d'inclusion financière. Il est également parfois utilisé pour désigner une personne qui a un compte de transaction mais ne dispose pas de services supplémentaires de services financiers numériques. | +| Pertes non couvertes | Obligations de règlement qui ne sont pas satisfaites par le DFSP responsable et ne sont pas acquittées par le biais de garanties ou d'autres mécanismes. | +| Cas d'utilisation | Un terme utilisé pour décrire l'objet du paiement. Des règles métier ou des directives opérationnelles spécifiques peuvent s'appliquer aux cas d'utilisation. | +| Identifiant utilisateur | Un identifiant unique d'un utilisateur. Il peut s'agir d'un MSISDN, d'un compte bancaire, d'une forme d'identifiant fourni par le DFSP, d'une identité nationale, etc. Dans une transaction, l'argent est généralement adressé à un identifiant utilisateur et non directement à un identifiant de compte. | +| USSD | Une technologie de communication utilisée pour envoyer du texte entre un téléphone mobile et un programme d'application dans le réseau. | +| Services à valeur ajoutée | Services ou produits fournis aux utilisateurs finaux que les utilisateurs finaux paieront pour utiliser ou accéder, souvent utilisés en coordination avec les adjacences. | +| Bon | Un instrument de valeur monétaire couramment utilisé pour transférer des fonds à des clients (bénéficiaires) qui n'ont pas de compte auprès du FSP du payeur. Cela pourrait être des bénéficiaires sans compte ou ayant un compte auprès d'un autre FSP. | +| Portefeuille | Un compte de transaction offert aux clients par les émetteurs de monnaie électronique. | +| Portefeuille à banque | Un cas d'utilisation secondaire P2P. | +| Portefeuille à portefeuille | Un cas d'utilisation secondaire P2P. | +| Liste blanche | Une liste ou un registre d'entités (utilisateurs enregistrés) auxquelles un privilège, un service, une mobilité, un accès ou une reconnaissance particulière est accordé, en particulier celles qui étaient initialement sur liste noire. | +| Autonomisation économique des femmes (WEE) : | Augmenter l'accès et les droits des femmes aux ressources économiques par des opportunités de travail décent, la propriété et les actifs, l'inclusion financière et les plateformes. | diff --git a/docs/fr/adoption/guides/Role-based-access-control.md b/docs/fr/adoption/guides/Role-based-access-control.md new file mode 100644 index 000000000..d7e894ca2 --- /dev/null +++ b/docs/fr/adoption/guides/Role-based-access-control.md @@ -0,0 +1,297 @@ +# Contexte du RBAC + +Un individu qui a besoin d'accéder aux différents portails de gestion du Hub Mojaloop peut être enregistré et un "compte" généré, qui peut être utilisé pour accéder à divers aspects d'une instance opérationnelle d'un Hub Mojaloop et pour fournir une base d'audit de cet accès en liant les activités à l'enregistrement original. Aux fins de ce document, un "compte" est une identité numérique, un moyen d'authentifier (lier) la personne revendiquant cette identité à l'enregistrement original, et un ensemble d'attributs, qui incluront - entre autres - un ensemble de droits d'accès, ou des droits qui sont activés par la possession de ces attributs. + +### Conception du RBAC + +La conception RBAC pour un opérateur de hub décrit les points de contrôle de sécurité qui doivent être pris en compte ou étendus afin d'atténuer les risques au sein d'une organisation typique d'exploitation de hub Mojaloop. Certains points de contrôle sont liés aux processus métier et à la structure organisationnelle, certains points de contrôle sont techniques et concernent les couches d'identification, d'authentification et d'autorisation, et certains points de contrôle nécessitent une surveillance. Les trois doivent être pris en compte pour créer la responsabilité et atténuer les risques. + +### Audit + +L'audit devrait travailler en collaboration avec les équipes métier et informatiques pour séparer ces fonctions dans la mesure du possible et attribuer un contrôle d'atténuation approprié dans les cas où cela n'est pas faisable. De plus, ces contrôles devraient être surveillés sur une base trimestrielle et les résultats doivent être signalés à la direction. + +Quelques définitions contextuelles incluent + +1. **Action** : un événement distinct déclenché par un utilisateur qui entraîne : + +- La création d'un actif de données +- La lecture ou l'accès à un actif de données +- La mise à jour ou la modification de l'état d'un actif de données +- La suppression ou le retrait d'un actif de données d'une application ou d'une base de données. + +1. **Permission** : autorité pour effectuer une action spécifique dans le contexte d'une application ou d'un service +2. **Rôle** : applications, actions et accès aux données nécessaires pour effectuer les tâches liées à un rôle unique +3. **Relation utilisateur - rôle** : Le ou les rôles attribués à chaque utilisateur qui définissent les permissions dont ils disposent + +## Utilisateurs, actions et rôles dans un contexte Mojaloop + +Mojaloop aura 2 grandes catégories d'utilisateurs : + +1. Humains – Ce sont les utilisateurs du hub et des DFSP qui, à travers diverses interfaces, interagiront avec Mojaloop. Les utilisateurs DFSP interagiront avec Mojaloop à travers le Payment Manager et les portails qui seront mis à disposition pendant le processus d'onboarding. +2. Non-humains – Ceux-ci automatiseront les processus métier et les tâches qui seraient autrement effectuées par un humain. Ils communiqueront via des appels API qui effectueront des actions pour répondre aux exigences métier. + +Le contexte de ce document se concentrera uniquement sur les utilisateurs humains. + +## Gestion du cycle de vie des utilisateurs + +Le "cycle de vie du compte utilisateur" définit les processus de gestion collectifs pour chaque compte utilisateur. Ces processus peuvent être décomposés en Création, Révision/Mise à jour et Désactivation — ou "CRUD". Si une organisation utilise des ressources informatiques de quelque nature que ce soit, elle s'appuie sur des comptes utilisateurs pour y accéder. + +## Intégration + +Le processus d'onboarding comprendra certaines activités impliquant la création d'utilisateurs tant du côté DFSP que du Hub. Celles-ci seront les suivantes : + +1. Hub : Les utilisateurs suivants seront créés + 1.1 Opérateurs du Hub + 1.2. Administrateurs du Hub +2. DFSP + 2.1 Opérateurs DFSP + 2.2 Administrateurs DFSP (applicable uniquement au Payment Manager). + +## Séparation des fonctions + +La séparation des fonctions vise à atténuer le risque de fraude interne en fixant des limites entre les rôles attribués à un employé, et entre les conflits d'intérêts pouvant résulter des responsabilités d'un employé, en veillant à ce qu'aucun utilisateur unique ne puisse avoir le contrôle fonctionnel de bout en bout d'un processus métier et de ses données. Cela nécessite que plus d'un individu crée, traite et complète une action. + +### Principe du moindre privilège + +Le RBAC utilise le principe de sécurité du moindre privilège. Le moindre privilège signifie qu'un utilisateur dispose précisément du niveau de privilège nécessaire pour effectuer son travail. L'objectif est de minimiser la probabilité d'attribuer à un utilisateur des permissions excessives pour effectuer des actions dans l'écosystème Mojaloop. + +### Implémentation Zero Trust de Mojaloop + +Un réseau zero trust est un réseau dans lequel aucune personne, appareil ou réseau ne bénéficie d'une confiance inhérente. Toute confiance, qui permet l'accès aux informations, doit être méritée, et la première étape consiste à démontrer une identité valide. Un système doit savoir qui vous êtes, avec certitude, avant de pouvoir déterminer ce à quoi vous devriez avoir accès. + +La conception inhérente de Mojaloop implémentera une approche Zero Trust dans son architecture et son déploiement, exigeant que toutes les entités qui interagissent s'authentifient d'abord, puis demandent l'autorisation d'accéder et de traiter les données en fonction du rôle auquel elles appartiennent. + +### Processus de détermination de la séparation des fonctions + +1. Définir les flux de travail et processus de gestion des utilisateurs. Ce sont tous les processus métier qui composent les actions métier Mojaloop dans Mojaloop. Les exemples incluent l'intégration. +2. Rationaliser toutes les exigences d'accès de sécurité des utilisateurs pour les applications de Mojaloop comme indiqué dans le tableau ci-dessous : + 2.1 Définir les fonctions métier et applicatives pour les utilisateurs et les API + 2.2 Définir les profils de rôles + 2.3 Définir les profils de fonctions et de compétences + 2.4 Rassembler une liste des conflits de séparation des fonctions applicables en définissant les rôles de séparation des fonctions + 2.5 Tableau matriciel des profils de rôles (avec des données d'exemple) : + +| **Rôles et Permissions** **Matrice** | Utilisateurs Hub | Administrateur | Utilisateur Maker Standard | Utilisateur Checker Standard | Lecture Seule Standard | Utilisateurs DFSP | Administrateur | Utilisateur Maker Standard | Utilisateur Checker Standard | Lecture Seule Standard | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| Rôles d'onboarding | X | | | | | | | | | | +| Créer un compte utilisateur | X | | | | | | | | | | +| Créer un profil DFSP | X | | | | | | | | | | +| Créer un utilisateur DFSP | X | | | | | | | | | | +| +| **Portail Financier** | +| Voir les rapports | | | X | X | X | | | X | X | X | +| Configuration de la plateforme | | | | | | | | | | | +| + +3. Reconfigurer les rôles en conflit + 3.1 Approbations métier + 3.2 Création d'utilisateurs Maker/Checker +4. Rapports périodiques sur l'accès au système et l'autorisation des utilisateurs +5. Séparation de la sécurité informatique et de la sécurité informatique opérationnelle qui soutiendra les activités de gestion des utilisateurs + +## Meilleures pratiques pour le RBAC et la gestion des identités Mojaloop + +1. Tous les identifiants d'utilisateurs doivent être uniques et avoir un format unique qui peut être corrélé dans le hub mais pas significatif pour les personnes extérieures. +2. Les utilisateurs DFSP n'auront accès à aucun rôle administratif au sein du Hub +3. Tous les utilisateurs non-humains doivent être empêchés de se connecter aux interfaces applicatives. +4. Les utilisateurs DFSP seront formés sur les rôles et les meilleures pratiques +5. Appliquer le provisionnement automatisé des utilisateurs et la gestion du cycle de vie. +6. Classer les actions effectuées dans Mojaloop pour identifier les actions métier à risque nécessitant des contrôles supplémentaires. +7. Les contrôles supplémentaires pour atténuer les risques RBAC peuvent inclure : + 7.1 Authentification multifacteur (MFA) + 7.2 Journalisation d'audit avec alertes + 7.3 Désactivation / blocage automatique du profil utilisateur +8. Mojaloop surveillera l'inactivité des utilisateurs et désactivera les utilisateurs inactifs sur une période spécifiée +9. Faire respecter de manière centralisée les politiques applicables à l'ensemble des identités, par ex. politique de mots de passe, politiques de connexion, MFA, authentification basée sur le risque, etc. +10. Identifier et surveiller de près les identités privilégiées qui ont des permissions pour effectuer des actions sensibles. Les éléments suivants s'appliquent aux utilisateurs privilégiés : + 10.1 Les privilèges avancés doivent être demandés et approuvés au cas par cas ; + 10.2 Les administrateurs doivent avoir leurs permissions privilégiées pour le minimum de temps possible ; + 10.3 Les administrateurs ne doivent avoir que les permissions nécessaires pour accomplir une tâche spécifique ; + 10.4 L'appartenance aux groupes administratifs doit être révisée régulièrement ; + 10.5 Appliquer l'authentification multifacteur pour les utilisateurs administratifs ; + 10.6 Conserver les journaux d'accès, les audits et configurer des notifications en temps réel lorsque l'accès est activé. +11. Mojaloop configurera des journaux d'audit et des alertes pour toutes les actions des utilisateurs dans Mojaloop. Dans la mesure du possible, explorer l'analytique des identités via des outils open source applicables. + +## Gestion automatisée des identités et contrôle RBAC + +Les outils préférés pour la gestion des utilisateurs et des identités dans un déploiement Mojaloop sont : + +1. **Moteur de gestion des identités KeyCloak** – Stocker et traiter les contrôles d'authentification API ainsi qu'agir comme passerelle API. +2. **Moteur de gestion des identités WSO2** – Stocker et traiter les profils de rôles des utilisateurs et gérer l'auto-intégration des utilisateurs DFSP. + +------- + +## Contexte + +Un individu qui a besoin d'accéder aux différents portails de gestion du Hub Mojaloop peut être enregistré et un « compte » généré, qui peut être utilisé pour accéder à divers aspects d'une instance opérationnelle d'un Hub Mojaloop et pour fournir une base d'audit de cet accès en liant les activités à l'enregistrement original. Aux fins de ce document, un « compte » est une identité numérique, un moyen d'authentifier (lier) la personne revendiquant cette identité à l'enregistrement original, et un ensemble d'attributs, qui incluront - entre autres - un ensemble de droits d'accès, ou des droits qui sont activés par la possession de ces attributs. + +Le processus d'enregistrement implique la vérification d'identité, la vérification des antécédents, etc. L'individu reçoit ensuite des identifiants - un identifiant de compte de connexion/identité numérique et au moins une méthode d'authentification, qui peut inclure un mot de passe et une authentification à deux facteurs (2FA). + +::: tip NOTE +La portée de ce document ne se limite pas aux opérateurs du Hub Mojaloop. Il aborde également les aspects de l'accès des opérateurs DFSP aux portails Payment Manager. +::: + +### Considérations relatives à la 2FA + +Il convient de noter que la 2FA via un téléphone mobile peut être inappropriée pour certains rôles, car les rôles très sensibles peuvent exiger que les téléphones mobiles soient rangés sous clé pendant que l'individu est « en service ». Cela nécessitera d'autres méthodes de 2FA, telles que des jetons physiques. + +### Contrôle d'accès basé sur les rôles + +Le Hub Mojaloop utilise une méthode de contrôle d'accès basé sur les rôles (RBAC). Un utilisateur avec un compte qui permet l'accès au Hub aura des rôles associés à ce compte, qui définissent ce qu'il peut faire une fois authentifié et connecté. + +De nombreux rôles s'appliquent à plusieurs portails, cependant, certains rôles peuvent être spécifiques à des portails individuels. + +Une attention particulière doit être portée lors de l'attribution de plusieurs rôles à un compte, ou de plusieurs comptes à une même personne physique. Cela est dû au potentiel qui se présente pour le contournement des contrôles. Une partie de l'objectif du RBAC est de s'assurer que plus d'une personne doit être dans la chaîne d'autorisation pour les actions importantes, réduisant ainsi les vulnérabilités liées aux acteurs malveillants. + +## Portails de l'écosystème Mojaloop + +L'écosystème Mojaloop offre un certain nombre de portails, qui prennent en charge divers degrés de contrôle d'accès et de RBAC. Ceux-ci sont divisés en deux groupes : + +- Portails du Hub, qui sont liés au fonctionnement du Hub lui-même +- Portails Payment Manager, qui sont liés à la gestion de la connexion d'un DFSP spécifique au Hub + +## RBAC dans le Hub Mojaloop + +Dans l'environnement du Hub Mojaloop, le RBAC est implémenté à travers une combinaison d'outils - Ory Oathkeeper pour la gestion des identités, et Keycloak pour le contrôle d'accès (y compris les rôles et le maker/checker). + +Le Hub lui-même possède les portails suivants : + +- **Intégration de l'opérateur du Hub :** +Actuellement, il n'existe pas de solution intégrée de gestion des identités et des accès (IAM) pour les opérateurs du Hub, bien que la fonction soit partiellement remplie par l'utilisation de WSO2. Des travaux de développement sont en cours pour développer une solution IAM complète basée sur Ory et Keycloak. Cela verra un opérateur administrateur créé parallèlement au déploiement du Hub, ce qui constitue une première étape fondamentale dans ce domaine. +- **Portail Financier :** Il a deux fonctions principales : la gestion des opérations de règlement, et la gestion de la position de liquidité des DFSP individuels (et en relation avec cela, leur valeur de plafond de débit net (NDC)). +L'accès au portail financier est actuellement limité à une simple fonction de contrôle d'accès par nom d'utilisateur/mot de passe. +- **Cycle de vie des participants :** Contrôle et configuration de l'accès au Hub par les DFSP. +D'un point de vue technique, cela est actuellement réalisé par l'utilisation du Mojaloop Connection Manager (MCM). Cependant, il est prévu que le MCM lui-même sera développé pour présenter une API, qui pourra être utilisée pour développer une interface utilisateur disponible pour les opérateurs du Hub et pour les DFSP. +- **Opérations du Hub :** Celles-ci comprennent les recherches de transactions, la surveillance de l'état et des performances, les tableaux de bord et l'ensemble des opérations techniques. +Actuellement, celles-ci sont réalisées grâce à l'utilisation de Prometheus/Grafana et d'une gamme d'autres outils, avec un contrôle d'accès standard intégré dans ces outils eux-mêmes. Il est prévu que cela sera migré vers la solution Ory/Keycloak, au fur et à mesure de son développement. + +D'autres opérations du Hub, telles que la gestion de la fraude et la gestion des cas/litiges, sont des modules complémentaires qui implémentent leur propre contrôle d'accès pour gérer l'accès à leurs fonctions sensibles. Ceux-ci ne sont pas abordés dans ce document. + +En plus des mesures de contrôle d'accès ci-dessus, il convient de noter que l'accès à toutes ces fonctions n'est possible que via un VPN, avec des identifiants individuels contrôlant l'accès. + +En plus de ces portails, il existe deux autres moyens principaux d'accéder au Hub, dont aucun n'est soumis au RBAC : + +- Le premier concerne les transactions, qui sont strictement contrôlées selon leurs propres mesures de cybersécurité multicouches. +- Et deuxièmement, les paiements en masse (gouvernement vers personne - G2P), qui sont pris en charge au moyen d'une API soumise aux mêmes contrôles que les autres transactions individuelles. Il est prévu que les paiements en masse seront un service fourni aux DFSP (et à leurs clients) au moyen d'une API sécurisée, le DFSP exploitant un portail de paiements en masse pour l'utilisation par ses clients. Il est possible que l'opérateur d'une instance du Hub Mojaloop puisse mettre à disposition un portail de paiements en masse en marque blanche, qui s'interface avec l'API de paiements en masse du Hub, pour personnalisation par tout DFSP souhaitant offrir le service à ses clients. (Notez que cette approche n'est pas unique : une approche similaire a été proposée, par exemple, pour les paiements marchands, avec une application en marque blanche pour les transactions par code QR mise à disposition des DFSP pour intégration dans leurs portefeuilles mobiles.) + +Les contrôles d'accès autour des paiements individuels ou en masse ne sont donc pas abordés davantage dans ce document. + +## Payment Manager pour l'onboarding + +Payment Manager est actuellement l'un des principaux mécanismes d'onboarding des DFSP à un Hub Mojaloop. Alors que le Hub est unique dans un schéma, il existe une instance distincte de Payment Manager pour chaque DFSP. Les portails offerts par Payment Manager doivent donc être sécurisés au moyen du RBAC pour limiter l'accès aux représentants autorisés du DFSP. + +Dans l'environnement Payment Manager, le RBAC est implémenté uniquement via Keycloak. + +Les portails suivants sont disponibles : + +- **Intégration utilisateur/opérateur :** +Payment Manager inclut Keycloak pour l'IAM. Lors du déploiement, un utilisateur administrateur unique est créé, qui peut être utilisé pour créer d'autres comptes utilisateurs. +- **Gestion de la connexion au Hub :** +Cela inclut la possibilité de configurer la connexion au Hub du côté Payment Manager, et par implication de la désactiver. C'est donc une fonction contrôlée, avec des contrôles différents pour la visualisation par rapport à la modification. +- **Investigation des transactions :** +Il est possible d'investiguer les requêtes de transactions en utilisant le portail Payment Manager. Cela est potentiellement problématique si des informations personnellement identifiables (PII) sont disponibles via le portail. + +## Exigences RBAC + +### Hub Mojaloop + +#### Intégration de l'opérateur du Hub + +##### Comptes fondamentaux + +Au moment où un Hub est mis en place pour la première fois, Ory/Keycloak sera utilisé pour créer un compte utilisateur fondamental avec des privilèges d'administrateur. Un administrateur système se verra attribuer ce compte. Notez que l'administrateur système ne se verra attribuer aucun rôle opérationnel au-delà de ceux d'un administrateur système. + +Toutes les fonctions exécutées à l'aide d'Ory/Keycloak sont soumises à une journalisation au niveau du système à des fins d'audit. + +L'administrateur système utilisera ensuite Ory/Keycloak pour créer d'autres comptes utilisateurs, sous réserve de vérifications d'identité et de contrôles d'antécédents standard pour chaque individu (définis dans les règles de schéma associées à un déploiement Mojaloop particulier) avant que leurs comptes ne soient créés. + +Ces nouveaux comptes utilisateurs se verront attribuer l'un de ces rôles : + +- OPERATOR +- MANAGER + +Un compte utilisateur ne peut pas avoir à la fois les rôles OPERATOR et MANAGER. + +##### Comptes supplémentaires + +En plus de l'administrateur système, les comptes fondamentaux auront la possibilité d'utiliser Ory/Keycloak pour ajouter d'autres comptes. Cependant, pour ces utilisateurs, cette activité sera soumise à des contrôles maker/checker. Un utilisateur avec le rôle OPERATOR pourra créer un compte utilisateur (avec des processus en place pour garantir que la diligence raisonnable en matière de vérification d'identité et de contrôle des antécédents a été effectuée). Cependant, ce compte ne sera pas activé tant qu'une personne avec le rôle MANAGER ne l'aura pas approuvé. + +Un rôle sera attribué à chacun de ces comptes lors de leur création. En plus des rôles associés aux comptes fondamentaux, les rôles suivants peuvent être attribués aux nouveaux comptes utilisateurs : + +- ADMINISTRATOR +- FINANCE_MANAGER + +Un compte utilisateur ne peut pas avoir plus d'un des rôles OPERATOR, MANAGER, ADMINISTRATOR ou FINANCE_MANAGER, afin d'assurer la séparation de : + +- La gestion financière des autres tâches d'exploitation du Hub +- Les rôles d'opérateur et de gestionnaire dans les fonctions maker/checker + +::: tip NOTE +L'attribution des rôles ADMINISTRATOR ou FINANCE_MANAGER est soumise à un degré plus élevé de vérification d'identité et de contrôle des antécédents que tout autre rôle, en raison de la nature sensible des fonctions associées. Ces vérifications supplémentaires sont définies dans les règles du système. +::: + +#### Portail Financier + +De nombreuses fonctions (telles que la visualisation des positions des DFSP, l'état des fenêtres de règlement, etc.) du portail financier sont disponibles pour tous les utilisateurs connectés, quel que soit leur rôle. Cependant, les fonctions suivantes ne peuvent être exécutées que par des utilisateurs ayant des rôles spécifiques : + +- Traitement des règlements + - Fermer la fenêtre de règlement + - Initier le règlement +- Gestion de la liquidité DFSP + - Ajouter/retirer des fonds + - Modifier le NDC + +Toutes ces fonctions sont soumises à des contrôles maker/checker, de sorte qu'un utilisateur avec le rôle ADMINISTRATOR peut initier l'action, mais elle doit être approuvée par un utilisateur avec le rôle FINANCE_MANAGER. + +#### Cycle de vie des participants + +Ce portail fournit une interface unique pour qu'un opérateur du Hub ajoute et maintienne les DFSP sur les écosystèmes du Hub. + +Il existe certaines fonctions standardisées qui sont soumises au RBAC : + +- Créer un DFSP +- Créer des comptes DFSP +- Suspendre un DFSP + +Chacune de ces fonctions est soumise à des contrôles maker/checker, de sorte qu'un utilisateur avec le rôle OPERATOR peut mettre en place les modifications, et elles doivent être approuvées par un utilisateur avec le rôle MANAGER. + +De plus, il y a une charge de travail importante dans l'onboarding technique d'un DFSP, en particulier autour de l'établissement de l'environnement technique d'exploitation (certificats, etc.). Cela n'est pas soumis au RBAC. Cela n'est pas considéré comme un risque significatif, car il n'y a pas de valeur sans pouvoir créer un DFSP et les comptes associés sur le Hub lui-même - activités qui sont soumises au RBAC. + +#### Opérations du Hub + +L'accès aux fonctions de reporting de Prometheus/Grafana n'est pas soumis aux contrôles RBAC - tout utilisateur connecté/authentifié, avec n'importe quel rôle RBAC attribué, peut consulter les rapports et les tableaux de bord. + +La création d'un nouveau rapport/tableau de bord est une fonction restreinte, et n'est disponible que pour les utilisateurs ayant le rôle MANAGER. + +Comme indiqué précédemment, les portails d'opérations et de reporting seront migrés vers l'environnement Ory/Keycloak afin de faciliter ces contrôles. + +### Payment Manager + +La fonctionnalité opérateur de Payment Manager est soumise aux contrôles RBAC, mais le maker/checker n'est pas requis. + +#### Intégration utilisateur/opérateur + +Lors du déploiement de Payment Manager, un seul compte utilisateur administrateur est créé à l'aide de Keycloak. Notez que l'utilisateur administrateur ne se verra attribuer aucun rôle opérationnel au-delà de ceux d'un administrateur système. + +Toutes les fonctions exécutées à l'aide de Keycloak sont soumises à une journalisation au niveau du système à des fins d'audit. + +L'utilisateur administrateur utilisera Keycloak pour créer d'autres comptes utilisateurs, sous réserve de vérifications d'identité et de contrôles d'antécédents standard pour chaque individu (définis dans les règles de schéma associées à un déploiement Mojaloop particulier) avant que leurs comptes ne soient créés. + +Ces nouveaux comptes utilisateurs se verront attribuer l'un des rôles suivants : + +- OPERATOR +- MANAGER + +Un compte utilisateur ne peut pas avoir à la fois les rôles OPERATOR et MANAGER. + +#### Tableaux de bord + +Les tableaux de bord de Payment Manager sont disponibles pour tout utilisateur connecté/authentifié ayant le rôle OPERATOR ou MANAGER. + +#### Gestion de la connexion au Hub + +La visualisation des paramètres de la connexion Payment Manager/Hub est disponible pour tout utilisateur connecté/authentifié ayant le rôle OPERATOR ou MANAGER. Cependant, la modification des paramètres est une fonction contrôlée. Seul un utilisateur ayant le rôle MANAGER peut modifier les paramètres. + +#### Investigation des transactions + +La réalisation d'investigations de transactions à l'aide des fonctionnalités du portail Payment Manager est une activité contrôlée, en raison du potentiel de révélation de données PII. Elle n'est donc disponible que pour les utilisateurs connectés/authentifiés ayant le rôle MANAGER. diff --git a/docs/fr/adoption/index.md b/docs/fr/adoption/index.md new file mode 100644 index 000000000..593025e9e --- /dev/null +++ b/docs/fr/adoption/index.md @@ -0,0 +1,42 @@ +# À propos de la documentation sur l'adoption de Mojaloop + +Pour un opérateur de Hub ou une banque centrale souhaitant utiliser Mojaloop pour son système de paiement instantané inclusif (IIPS), le processus d'adoption et les étapes de la prise de décision diffèrent souvent fortement de celles consistant à faire appel à une entreprise pour fournir un logiciel propriétaire. Utiliser Mojaloop pour construire et posséder une plateforme offre davantage de contrôle mais aussi davantage de responsabilités. C'est exactement ce que cela signifie : ne pas dépendre d'un seul fournisseur. + +La documentation et les outils de cette section visent à aider à justifier le choix de Mojaloop et à proposer une démarche de mise en œuvre recommandée. + +Construire un système de paiement dépasse largement la plateforme technologique. Le système (ou le scheme) et les opérations sont en réalité les facteurs de succès. Nous avons développé Mojaloop pour réduire la charge opérationnelle et le coût de mise en œuvre de règles du système inclusives telles que l'irrévocabilité et la certitude. + +Le processus de construction d'un système de paiement peut être aussi important que certaines décisions relatives au système (ou au scheme) qui en découlent. Chaque propriétaire et opérateur de scheme peut définir son propre processus, mais nous recommandons une démarche inclusive, transparente et itérative afin de maximiser l'appropriation, la confiance et la durabilité à long terme. + + + +Outils à la disposition des adoptants : + +* [**Choix relatifs au système**](#scheme-choices) : documents d'aide pour définir les règles de schéma, les lignes directrices d'exploitation, ainsi que les choix commerciaux et de conception majeurs +* [**Opérations du Hub**](#hub-operations) : guides fournissant des informations pratiques sur les différents aspects des opérations d'un Hub Mojaloop + +## Choix relatifs au système + +Le [modèle de lignes directrices d'exploitation de la plateforme](./Scheme/platform-operating-guideline.md) fournit un modèle pour décrire le fonctionnement de la plateforme du système et pour préciser les obligations et responsabilités du système, de l'opérateur de la plateforme et des DFSP. + +Le [modèle de règles métier du schéma](./Scheme/scheme-business-rules.md) fournit un modèle pour définir les règles métier qui encadrent les droits et obligations des participants à un scheme Mojaloop. + +Le document [des choix clés du schéma](./Scheme/scheme-key-choices.md) décrit et examine certains des choix commerciaux et de conception les plus importants qui influencent à la fois la mise en œuvre technique de Mojaloop et les règles métier que le système rédigera et auxquelles les DFSP participants accepteront de se conformer. + +Le [modèle de convention de participation au schéma](./Scheme/scheme-participation-agreement.md) fournit un modèle de convention de participation au schéma contenant les dispositions minimales nécessaires pour attester de la demande d'un DFSP de rejoindre le scheme et de respecter ses règles métier. + +Le [modèle de glossaire standard](./Scheme/scheme-uniform-glossary.md) sert de glossaire des termes métier. + +## Opérations du Hub + +Ces documents peuvent servir de référence aux adoptants pour s'appuyer dessus et adapter les portails d'exploitation du Hub, puis développer les leurs ultérieurement selon les besoins. + +Le [guide des opérations techniques](./huboperations/techops/tech-ops-introduction.md) décrit les processus opérationnels qui permettent à l'opérateur du Hub de couvrir tous les aspects de la gestion d'un service en production, tels que la gestion des incidents, la gestion des problèmes, la gestion du changement, la gestion des versions et le triage des défauts. + +Le [guide de gestion du Settlement](./huboperations/settlement/settlement-management-introduction.md) explique comment le Settlement est géré par le Hub Mojaloop et la ou les banques partenaires de règlement, et présente les principaux éléments du traitement du Settlement. + +Le [Guide du Finance Portal v2](./huboperations/portalv2/busops-portal-introduction.md) s'adresse à l'opérateur d'un Hub Mojaloop et fournit des informations sur le Finance Portal, qui facilite la gestion au quotidien des processus liés aux règlements. + +Le document [de contrôle d'accès basé sur les rôles (RBAC)](./huboperations/rbac/Role-based-access-control.md) traite du mécanisme de sécurité utilisé pour contrôler l'accès aux différents aspects d'une instance opérationnelle d'un Hub Mojaloop. + +Le [guide d'onboarding pour l'opérateur du Hub](./huboperations/onboarding/onboarding-introduction.md) s'adresse à l'opérateur d'un Hub Mojaloop et fournit des informations sur le processus d'onboarding des DFSP. Il offre une vue d'ensemble du parcours d'onboarding suivi par les DFSP, en servant de liste de contrôle des activités d'onboarding. diff --git a/docs/fr/community/README.md b/docs/fr/community/README.md new file mode 100644 index 000000000..6ba1c41bc --- /dev/null +++ b/docs/fr/community/README.md @@ -0,0 +1,20 @@ +# Bienvenue dans la communauté Mojaloop + +## Comment puis-je commencer ? + +* Un bon point de départ est le [Guide des Contributeurs](./contributing/contributors-guide.md), qui fournit des informations sur la manière dont vous pouvez contribuer au projet. +* Si vous souhaitez obtenir un aperçu des technologies utilisées dans le projet, consultez la section [Outils et Technologies](./tools/tools-and-technologies.md). +* Pour vous faire une idée des fonctionnalités que nous développons, consultez la [Feuille de Route Produit](./mojaloop-roadmap.md). +* Le [Tableau de projet](https://github.com/mojaloop/project#zenhub) présente ce sur quoi nous travaillons actuellement ; vous pouvez commencer par une [bonne première tâche (issue)](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). + +## Où puis-je obtenir de l’aide ? + +Rejoignez les [Discussions Slack Mojaloop](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw) pour entrer en contact avec les autres membres de la communauté. + +## Et si j'ai d'autres questions ? +Vous pouvez consulter certaines de nos questions fréquemment posées dans la section [FAQ](../getting-started/faqs.md). Ou encore mieux, rejoignez la communauté directement sur [Slack](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw). + +## Comment puis-je rester informé sur le projet ? +Abonnez-vous en rejoignant la [communauté](https://community.mojaloop.io/) où vous pourrez être notifié à propos des prochains [événements](https://community.mojaloop.io/c/events/8) et des [annonces produit](https://community.mojaloop.io/c/announcements/9). + +Vous pouvez également rejoindre notre canal [Annonces Slack](https://mojaloop.slack.com/messages/CG3MAJZ5J) pour recevoir des informations sur la dernière version publiée. \ No newline at end of file diff --git a/docs/fr/community/archive/discussion-docs/Mojaloop Performance 2020.pdf b/docs/fr/community/archive/discussion-docs/Mojaloop Performance 2020.pdf new file mode 100644 index 000000000..719dec47e Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/Mojaloop Performance 2020.pdf differ diff --git a/docs/fr/community/archive/discussion-docs/README.md b/docs/fr/community/archive/discussion-docs/README.md new file mode 100644 index 000000000..8f7db475c --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/README.md @@ -0,0 +1,27 @@ +# Documents de discussion (archive) + +## PI 10 +- [Projet performance](./performance-project.md) +- [Projet d’amélioration du code](./code-improvement.md) +- [Transfrontalier](./cross-border.md) +- [PSIP / PISP](./psip-project.md) + +## PI 9 + +- [Proposition de versionnement (brouillon)](./versioning-draft-proposal.md) +- [Projet d’amélioration du code](./code-improvement.md) +- [Projet performance](./performance-project.md) +- [Transfrontalier](./cross-border.md) +- [PSIP / PISP](./psip-project.md) + +## PI 8 + +- [Notes réunion transfrontalier — jour 1](./cross-border-day-1.md) +- [Notes réunion transfrontalier — jour 2](./cross-border-day-2.md) +- [Aperçu intégration ISO](./iso-integration.md) +- [Type décimal Mojaloop (basé sur le type décimal XML Schema)](./mojaloop-decimal.md) + +## PI 7 + +- [Fil de travail Lab / établi](./workbench.md) + diff --git a/docs/fr/community/archive/discussion-docs/aws_tagging.md b/docs/fr/community/archive/discussion-docs/aws_tagging.md new file mode 100644 index 000000000..8f739caad --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/aws_tagging.md @@ -0,0 +1,127 @@ +# Lignes directrices et politiques d’étiquetage AWS + +> **Note :** Ces lignes directrices concernent l’environnement AWS de la communauté Mojaloop pour les tests et la validation des installations Mojaloop ; elles sont surtout internes. Elles peuvent toutefois servir de référence pour des stratégies d’étiquetage similaires dans d’autres organisations. + +Pour mieux gérer et comprendre notre usage et nos dépenses AWS, nous appliquons les règles d’étiquetage suivantes. + +## Sommaire +- [Étiquettes proposées et signification](#proposed-tags) + - [mojaloop/cost_center](#tag-cost-center) + - [mojaloop/owner](#tag-owner) +- [Étiquetage manuel](#manual-tagging) +- [Étiquetage automatisé](#automated-tagging) +- [Politiques d’étiquetage AWS](#aws-tagging-policies) + - [Rapports de conformité des étiquettes](#tag-reports-compliance) + - [Modifier les politiques d’étiquetage](#editing-tag-policies) + - [Attacher / détacher des politiques d’étiquetage](#attach-detach-tag-policies) + +## Étiquettes proposées et signification + +Nous proposons les deux clés d’étiquette suivantes : + +- `mojaloop/cost_center` +- `mojaloop/owner` + +### `mojaloop/cost_center` + +`mojaloop/cost_center` ventile les ressources AWS par fil de travail ou projet qui génère les coûts associés. + +Le format suit approximativement `-[-sous-objectif]`, où le compte est par ex. `oss`, `tips` ou `woccu`. +> Note : la plupart des ressources seront probablement sous le « compte » `oss` ; des ressources plus anciennes peuvent relever de `tips` ou `woccu`. Prévoir aussi de futurs types de ressources. + +Exemples de valeurs pour `mojaloop/cost_center` : + +- `oss-qa` : travail QA open source (environnements dev1, dev2 existants) +- `oss-perf` : performance open source (fil performance en cours) +- `oss-perf-poc` : POC performance / architecture + +Valeurs spéciales réservées : +- `unknown` : la ressource a été évaluée (manuellement ou par outil) et aucun `cost_center` approprié n’a pu être déterminé. + - Permet de filtrer `mojaloop/cost_center:unknown` et d’éditer un rapport. +- `n/a` : la ressource ne génère pas de coût ; l’assignation d’un `cost_center` importe peu. + - Utile pour étiqueter en masse des ressources difficiles à classer (ex. groupes de sécurité EC2). + +### `mojaloop/owner` + +`mojaloop/owner` désigne la personne responsable de la gestion et de l’arrêt d’une ressource donnée. + +L’objectif est d’éviter les ressources longues durée que tout le monde croit connues alors qu’elles ne sont plus nécessaires. Cette étiquette indique à qui s’adresser pour des questions sur la ressource. + +La valeur est le nom de la personne, tout en minuscules : +- `lewis` +- `miguel` +- etc. + +Valeurs réservées : +- `unknown` : la ressource a été évaluée et aucun propriétaire approprié n’a pu être déterminé (à noter : dans l’original anglais, le texte répétait par erreur « cost_center » au lieu de « owner » pour cette puce). + - Permet de filtrer `mojaloop/owner:unknown` et d’identifier les ressources « orphelines ». + + +## Étiquetage manuel + +Utiliser le « Tag Editor » dans la console AWS pour rechercher les ressources non étiquetées. + +1. Connexion à la console AWS +2. Sous Resource Groups, sélectionner « Tag Editor » +![](./images/tagging_01.png) +3. Choisir une région (souvent « All regions ») et un type de ressource (souvent « All resource types ») +4. Cliquer sur « Search Resources » et attendre la liste + +On peut aussi rechercher par étiquettes ou par absence d’étiquettes. +![](./images/tagging_02.png) + +5. Une fois la liste obtenue, sélectionner et modifier les étiquettes pour plusieurs ressources à la fois +6. Exporter un fichier `.csv` des ressources trouvées + + +## Étiquetage automatisé + +Nous automatisons l’étiquetage pour les éléments suivants (liste évolutive). + +À mesure que les règles se stabilisent, il faut les intégrer dans l’outillage pour limiter l’étiquetage manuel. + +Pour l’instant, cela inclut notamment : +1. Rancher — gestion des clusters Kubernetes QA et performance +2. IaC — code IaC à venir pour les environnements de développement + + +## Politiques d’étiquetage AWS + +Depuis le 3 août 2020, nous introduisons les [politiques d’étiquetage AWS](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) pour renforcer les étiquettes et le suivi des ressources (notamment les coûts). + + +### Rapports de conformité des étiquettes + +1. Connexion à la console AWS +2. « Resource Groups » > « Tag Editor » +3. Dans la barre latérale gauche, « Tag Policies » + +On y voit le rapport de conformité des politiques d’étiquettes. + +![](./images/tagging_03.png) + + +### Modifier les politiques d’étiquetage + +> Note : peut nécessiter des droits administrateur. + +1. Connexion à la console AWS +2. En haut à droite : « username@mojaloop » > « My Organization » +3. « Policies » > « Tag Policies » + +![](./images/tagging_04.png) + +4. Consulter les politiques d’étiquetage en vigueur + +![](./images/tagging_05.png) + +5. Dans la barre latérale : « View details » > « Edit policy » pour modifier + + +### Attacher / détacher des politiques d’étiquetage + +1. Page « My Organization » +2. Sélectionner le compte concerné > « Tag policies » dans la barre latérale +3. Attacher ou détacher les politiques d’étiquetage + +![](./images/tagging_06.png) diff --git a/docs/fr/community/archive/discussion-docs/code-improvement.md b/docs/fr/community/archive/discussion-docs/code-improvement.md new file mode 100644 index 000000000..2058bd2b7 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/code-improvement.md @@ -0,0 +1,25 @@ +# Projet d’amélioration du code (Code_Improvement) + +## Aperçu +Objectif : améliorer la qualité et la sécurité du code du projet Mojaloop. Analyse et introduction d’outils open source, amélioration des processus, contrôles aux étapes (pull requests et builds), documentation. + +Périmètre : qualité et sécurité, avec extensions possibles vers l’automatisation des tests, DevOps et outils associés. + +## Livrables (phase 1 fin janvier) +- Mise en œuvre et analyse de nouveaux outils OSS +- Mise à jour des scripts de release : intégrer la sécurité dans release / DevOps (CI/CD) +- Mise à jour des règles pour les pull requests : aspects sécurité avant validation +- Mise à jour de la documentation : normes et guides de contribution + +Canal Slack : `#code_security` + +## Discussions +### Modifier Dockerfile et processus CI/CD pour renforcer la sécurité des conteneurs +- Créer un utilisateur non root dans le Dockerfile +- Activer docker-content-trust sur l’hôte Docker (dans CircleCI) +- Lancer les builds avec `--no-cache` à l’étape CircleCI pour récupérer les correctifs de sécurité à chaque fois (cela ne devrait pas poser de problème majeur puisque le cache d’images Docker n’est de toute façon pas activé dans notre CircleCI) + +### Passer de Javascript à Typescript +- Transition vers Typescript (coexistence js/ts) pour plus de sécurité et de qualité +- Typescript préféré mais non obligatoire : https://github.com/mojaloop/template-typescript-public + diff --git a/docs/fr/community/archive/discussion-docs/cross-border-day-1.md b/docs/fr/community/archive/discussion-docs/cross-border-day-1.md new file mode 100644 index 000000000..7b3b89092 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/cross-border-day-1.md @@ -0,0 +1,268 @@ +# Discussion transfrontalière — jour 1 + +>**Liens** +>- [Notes du jour 2](./cross-border-day-2.md) +>- [Ticket pertinent sur le tableau DA](https://github.com/mojaloop/design-authority/issues/32) +>- [Pull request sur la spec Mojaloop](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Participants : + +Présents sur place +- Lewis, Crosslake +- Adrian, Coil +- Nico, MB +- Sam, MB +- Miguel, MB +- Carol Benson, Glenbrook +- Michael Richards, MB +- Henrik Karlsson, Ericsson +- Rob Reeve, MB +- Vanburn, Terra Pay +- Razin, Terra Pay +- Ram, Terra Pay +- JJ, Google +- Matt Bohan, Gates Foundation +- David Power, EY +- James Bush, MB +- Warren, MB +- Judit, MB +- Bart-Jan et Bruno de la GSMA — jour n°2 + +Téléphone +- Kim Walters, Crosslake +- Istvan Molnar, DPC +- Innocent Ephraim, MB + +## Session 1 + +**Objectif : mettre à jour les définitions d’API** + +- Confidentialité : + - Puis-je envoyer des USD ? _oui/non_ + - Que puis-je envoyer ? _liste des devises_ + +Accords commerciaux : plusieurs possibilités +- Schéma global, composé d’accords schéma à schéma +- Accords schéma bilatéraux +- Schéma à schéma +- Région + + +Définitions : +- Gateway FSP : un FSP qui « fait le pont » entre 2 réseaux +ex. Mowali + - 2 réseaux logiques (USD, XOF ?) + - un seul réseau Mojaloop + +- Cross Network Provider (CNP) + - FXP, la même chose ? + +Michael : +- il y a une raison à cette hypothèse +- autres implications juridiques ici… + +- entité unique, juridiquement dans 2 juridictions différentes + - proche analogie d’un schéma sans juridiction + +- participant : + - a un compte de transaction qui peut être débité ou crédité + - banque, fxp, etc. + +>Q : Peut-on avoir un participant qui ne règle pas ? Ou est-ce couvert par un CNP qui est partie +>ex. Visa, ne règle pas toujours sur un marché donné, mais détient un compte + +- Résident vs non-résident + - exigences de reporting différentes + +- quelles exigences techniques pour les reporters ? + +- règlement + - pas trop d’inquiétude à ce stade (focus sur les changements d’API) + - on suppose que le règlement est possible, mais il faut d’abord cadrer le périmètre avec l’API + +- Pas seulement Mojaloop + - il faut permettre les transferts non-Mojaloop → Mojaloop et l’inverse (entrant et sortant) + - doit rester interopérable + + +- qui fournit le routage ? + - switch ? + - ALS ? + - CNP ? + + +>*Suivi :* Besoin d’une définition formelle des rôles FXP et CNP, avec exigences et responsabilités + + +Au niveau schéma + - le schéma doit-il tenir une liste des autres schémas avec lesquels il autorise ses FSP à se connecter ? + - ou le CNP s’en charge-t-il ? + +- pas schéma → schéma, mais partie du processus d’onboarding CNP +- mais le schéma peut / doit toujours maintenir des règles + +- comment fonctionnera le devis ? Un FSP envoie-t-il plusieurs devis, un par CNP ? Ou le switch a-t-il un moteur de règles pour déterminer vers qui envoyer ? + +James : Nous voulons de la flexibilité. On peut imaginer les deux cas ; ne pas trop présumer à ce stade. + +Option la plus simple : le switch parle à l’ALS, détermine que le transfert n’est pas dans notre réseau, puis obtient une liste de CNP + +CNP + FXP → essentiellement la même chose +- ce sont des *rôles*, et un DFSP peut en assumer plusieurs +- les fxps peuvent aussi exister dans plusieurs zones (ex. cas Mowali) + - fxp sur un seul réseau = juste un fxp, + - fxp multi-réseaux est probablement aussi un CNP + + +## Session 2 + +- débat sur recherche unique ou multiples + - on ne devrait jamais renvoyer un « résultat vide » + +- les portefeuilles sont-ils adressables par MSISDN ? + - un seul compte pour l’instant + - mais c’est interne au switch + - le rôle de l’oracle est de convertir MSISDN → adresse Mojaloop + +- à l’avenir : MSISDN + comptes seront moins liés + - ce sujet touche à l’adressage + +- « sortir » de Mojaloop pour l’adressage sera un peu délicat +- Standardiser l’adressage ? + - pas quelque chose que nous voulons + +Ram : Il existe déjà des outils (pas besoin de réinventer la roue), hors schéma Mojaloop + +- envoi vers devise inconnue + - actuellement : 1 réponse de table de routage + - futur : plusieurs réponses + +- confidentialité : + - pas besoin de règles strictes pour l’instant (au moins pas au niveau API ; les règles viennent avec les schémas) + - il nous faut une méthode pour médiatiser les informations qu’un switch exige d’un autre (et refuser les devis si les prérequis ne sont pas remplis) + +--- +- Domestique vs transfrontalier : l’utilisateur a / a besoin d’informations différentes + - ex. voulons-nous limiter la découverte au cas domestique ? +--- + +Adrian : Beaucoup de choses relèvent des règles métier et du schéma spécifique +- maintient l’espace concurrentiel +- Quelle quantité d’information dans le : + - lookup ? + - devis ? + +--- +- Proposition : recherche d’adresse → renvoie plusieurs réponses ? +- MSISDN → ID, pas une adresse. Quelqu’un, pas un compte + +- il ne devrait y avoir qu’une seule réponse de l’ALS +- Michael n’est pas d’accord + +- il faut séparer *l’adressage* du *routage* + +- il faut réfléchir aux effets en aval sur les tests + - trouver un moyen clair de tester ces recherches + + +Par exemple, le cas Airtel UPI (où des MSISDN existants ont été remplacés lors du passage des clients mobiles vers l’argent mobile) + - il faut éviter une situation de ce type + +--- + +Revenir aux principes L1P +- les transferts doivent s’apurer immédiatement +- pas de « futur » + +- Pour le domestique : on peut garantir la livraison, mais le transfrontalier est beaucoup plus difficile +- il faut maintenir l’exigence de transparence sur les CNP + - cela revient aux règles métier + +- Transactions réversibles ou règles sur les problèmes en aval + - ILP gère *la plupart* de cela pour nous + +- dans le cas TIPS : 1 ID mappe vers 1 compte +- comme toujours, compromis entre confidentialité et fonctionnalités (et c’est acceptable !) + +--- + +À la fin d’un devis : +- ValueDate +- combien sera reçu +- quels sont les frais ? (détail par étape et devise) + +--- + +Comment prendre en charge les protocoles qui ne supportent pas les devis (question pour les systèmes moja vers non-moja) + +Risque : CNP : ils portent le risque dans ce type de transaction + +CNP comme participant ? + - détient un compte chez un participant + - approche directe vs indirecte + - cela n’affecte pas les exigences techniques (hors périmètre de cette discussion) + + +--- + +- envoi fixe et réception fixe : + - Dans quel sens faut-il ajouter les données au devis ? Cela dépend du fait qu’on fixe l’envoi ou la réception + +- Soit : « A envoie 20 USD à B » OU « B reçoit 1000 PHP » + +- traduire les frais pour l’utilisateur : le FXP __doit__ appliquer le même taux aux frais qu’au transfert principal + +- Du point de vue L1P : __l’objectif est la transparence__ + +- et les devis hors Mojaloop ? + - le CNP doit s’en charger — c’est le dernier bastion de « mojaloopitude » + +--- + +- Objet Participant + - Attaché aux devis, une entrée par saut ? + - Donc les devis multi-sauts contiennent _n_ objets participant, où _n_ = nombre de sauts + 1 + +Pour cela il nous faut : +- morceaux de données interopérables (définitions communes) +- schéma pour le chiffrement +- un endroit pour les données (dans l’objet devis) + +Devons-nous nous préoccuper du chiffrement pour l’instant ? +- peut-être pas, mais il faut tout de même le prévoir dans l’API + +Le chiffrement ajoute un défi d’intégration +- quel besoin d’avoir les données en clair ? + - perspective technique : utiliser une clé de chiffrement vide + +Devons-nous chiffrer pour que le(s) switch ne voie pas les données ? + - peut-être pas à ce stade + + +>### Décision : +>- Pas de chiffrement pour l’instant +>- dans la requête de devis sortant : liste de données requises +>- pour la requête de devis entrant : les participants remplissent ces exigences +>- si les exigences ne sont pas remplies : abandonner le devis +>- Ne pas coder en dur les exigences de données ; utiliser les normes existantes + + +- il faut préciser si les champs _ont_ été vérifiés ou non + - lié aux processus KYC par niveaux + +- besoin d’un dictionnaire commun des données pouvant / devant être demandées + + +## Tableaux : + +_tableau 1 : flux envoi fixe_ +![board_1](./images/cb_board_1.jpg) + +_tableau 2 : flux réception fixe_ +![board_2](./images/cb_board_2.jpg) + + + + + + diff --git a/docs/fr/community/archive/discussion-docs/cross-border-day-2.md b/docs/fr/community/archive/discussion-docs/cross-border-day-2.md new file mode 100644 index 000000000..b2bcacb51 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/cross-border-day-2.md @@ -0,0 +1,123 @@ +# Discussion transfrontalière — jour 2 + +>**Liens** +>- [Notes du jour 1](./cross-border-day-1.md) +>- [Ticket pertinent sur le tableau DA](https://github.com/mojaloop/design-authority/issues/32) +>- [Pull request sur la spec Mojaloop](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Prochaines étapes : + +- Mettre à jour les API proposées +- Présenter le changement consolidé au CCB par écrit +- Quelques semaines pour assembler les changements (Michael / Adrian de partager le travail) +- Appel CCB mi-novembre + + +## Session 1 + +Questions sans réponse : +- adressage + - le décomposer ? + - inter-mojaloop + - que fait un PayerFSP avec une adresse ? + +- ALS + routage + - quelles optimisations l’API doit-elle faire / permettre ? + +- identifiants DFSP locaux vs distants + +- Défaillances en aval + - Quand le paiement s’apure, le payeur reçoit-il une notification (surtout avec des paiements « retardés » qui peuvent interfacer avec des systèmes non Mojaloop) + - Un CNP peut-il envoyer un `PATCH` de la transaction pour mettre à jour le bénéficiaire ? + +--- + +- plusieurs devis et réponses de route : + - comment les afficher à l’utilisateur ? + - Il faut des règles de filtrage des routes + - difficile : ex. blacklist d’un switch ? ou préférence pour certaines routes + +- comment le DFSP émetteur découvre-t-il les règles du système du bénéficiaire ? +- le DFSP émetteur doit-il « connaître » le switch final ? Ou seulement le suivant ? + +--- + +Tensions entre hypothèses ML et non-ML +- cela signifie-t-il que le CNP doit faire plus de travail en se connectant au non-ML ? + - ex. connaître le schéma / switch résultant ? + - pourquoi ? Gestion des échecs + - selon la décision d’hier : le CNP doit-il faire ce travail ici ? + +- Tirer une leçon de SWIFT : + - la banque ne sait pas où va l’argent + - peut-on éviter cela dans ML ? + +--- + +CNP : objectif de « se comporter » comme un membre normal du réseau + - Cela minimise les responsabilités que le schéma assume + +Quand la transaction est-elle considérée comme terminée ? + - Il peut y avoir des cas où le schéma la considère faite mais ce n’est pas techniquement fini bout à bout + +Comment gérer la dégradation de service ? + - Règles du schéma + +--- + +Retour aux devis : + +- comment exprimer l’information de devis ? + - devis et routes séparés ? Probablement oui + +- Les devis sont l’étape la plus coûteuse + - Peut-on fournir des informations QOS ici dans le cadre du lookup ? + +Adressage : +- Besoin d’une adresse globalement unique + - Permettre un espace d’adresse pour les DFSP et les personnes / comptes uniques +- le schéma dit « ce n’est pas dans mon espace » +- le CNP détermine les routes pour atteindre cet espace + +--- + +### Digression de Michael : + +- avons-nous fait les mauvaises hypothèses sur le CNP ? + +**switch :** connaît les CNP + FXP +**CNP :** détient la table de routage et le lookup + +- si l’émetteur ou le bénéficiaire est un FXP, la transaction *n’est pas* une transaction multi-devises + +--- + +## Session 2 + +*Décision :* +- la valeur d’en-tête est l’id CNP +- l’objet partId est le FSP final + +valueDate +- sous-entendu que les fonds doivent s’apurer avant la valueDate +- on peut encore avoir des durées de vie courtes sur la transaction + +- CNP : + - renvoie un ensemble de frais obfusqué + - s’intègre à notre modèle actuel + + +- condition : + - objet existant lié cryptographiquement à l’objet transaction + - mais pour multi-sauts, on ne connaît pas seulement cela + - la réception fixe complique (ce que les données echo cherchent à résoudre) + + - Nous voulons **une seule condition pour tous les sauts** + - l’idée de conditions multiples est une « perversion » (selon certains) + + +## Tableaux : + +_tableau 3 : flux de recherche et devis inter-réseaux, réception fixe de 1000 PHP depuis USD_ +![board_3](./images/cb_board_3.jpg) + diff --git a/docs/fr/community/archive/discussion-docs/cross-border.md b/docs/fr/community/archive/discussion-docs/cross-border.md new file mode 100644 index 000000000..a7c338fe2 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/cross-border.md @@ -0,0 +1,396 @@ +**Réunion du fil transfrontalier** + +10 et 11 mars (Londres / à distance) + +**Prochaines étapes pour le PI :** + +• Proposition sur la requête CNP, l’hébergement des services oracle et les objectifs mondiaux — Adrian, Michael + +• Identifiants composés, façon de les capturer dans le système ou de les exprimer dans les API — ouvert + +• Quelles informations figurer dans le modèle de données ou la liste d’extensions — Michael + +• Suite avec SWIFT sur les exigences — Matt + +**Points ouverts :** + +• Finaliser les exigences CNP + +• Il faut agréger les informations et les regrouper en une seule requête ; ils devront signer séparément + +• Finaliser le fait que le FXP gère les taux de change, les règlements et ce qui expire quand + +• Les CNP peuvent étendre cela et définir des règles de schéma supplémentaires + +• Le FXP gère les erreurs d’arrondi + +• Le FXP garantit un taux donné + +• Comment intégrer des acteurs non Mojaloop au schéma ? + +• Comment intégrer Mojaloop et un schéma Mojaloop pour des paiements PVT complets — groupe de travail avec Michael, Adrian, Sybrin, autres au besoin + +• Comment gérer les demandes pour motifs réglementaires + +• Étudier les correspondances d’identifiants (comptes Pathfinder / mobile vers identifiants uniques DFSP) + +• Étudier la certification (hachage et PKI) + + +Notes détaillées de réunion : +Jour n°1 : + - Réponse de devis + + ○ Comment coder le SLA dans la réponse + + ○ Demander à un 2e CNP de router + + ○ Dans l’API — il faut empaqueter comment y parvenir + + ○ En tant que CMP dans Mowali, si je renvoie une réponse de devis, le schéma a des implications + + ○ Suivre tout le parcours du payeur au bénéficiaire + + ○ Limiter la participation du CNP — il doit être le dernier saut + + § Comment définir les exigences d’un CNP ? + + - Format des messages + + ○ Syntaxe HTTP + + ○ Parti du schéma Mojaloop + + § Évoluer vers le fait que le CNP gère la conversion + + ○ Version SWIFT + + ○ Sécurité — TLS + + ○ En-tête / contenu chiffrés en JWS + + - Système de détail + + ○ Hors réseau — envoi vers un hub + + - Modèle de données + + ○ Structure : façons d’ajouter de nouvelles informations, routes différentes, etc. + + ○ Confidentialité : visibilité et sécurité — accessible seulement aux personnes autorisées + + ○ Contenu du modèle de données + + - Le transfert passe par le switch (mouvement d’argent) + + ○ Dans Mowali — les montants sont exprimés mais le taux est important car il impacte les règlements + + § Flux de données — on ajoute le taux quand on renvoie le devis + + § Ajouté dans la liste d’extensions — doit-il faire partie du standard ? + + § Montant envoyé et reçu (devises différentes) + + - Élément de données + + ○ Frais pour chaque participant + + ○ Le DFSP payeur les additionne + + ○ Élément de frais pour la transaction + + - Proposition + + ○ Service de recherche de compte + + § Liste des FSP locaux + + ○ Switch — doit maintenir l’état et les requêtes de recherche + + § Doit ressembler à un transfert domestique pour l’émetteur + + § Collecter les informations et les renvoyer + + ○ CNP — faire des hypothèses pour satisfaire les exigences + + § Faut-il voir la route + + § Collecter des informations différentes en aval + + § Les FSP émetteurs doivent savoir qui est le bénéficiaire + + ○ Le CNP doit agréger les informations et les regrouper en une seule requête ; signatures séparées + + § Condition et exécution font partie d’une structure PKI + + § S’il y a plus d’un CNP — il faut s’assurer que le DFSP bénéficiaire est certain du DFSP payeur — connexions + + § Le CNP doit tout savoir, reporting réglementaire + + ○ Faut-il dupliquer la structure dans un transfert inter-réseaux ? + + § Empêcher un partenaire indésirable de se joindre + + § Faire confiance au CNP pour respecter ses SLA + + ○ Mojaloop vers un autre schéma — nous n’avons pas le contrôle + + § Exiger qu’ils confirment la réception + + § Comment le savoir + + § Comment savoir que la personne en bout de chaîne a reçu l’argent + + ○ Autorité de signature externe pour confirmer la réception des fonds + + § Si votre schéma veut participer au transfrontalier, tous les participants doivent être signés + + § Clé publique — pour rejoindre un réseau Mojaloop il faut émettre des clés publiques + + § Autorité centrale de certification + + § Besoin d’une structure PKI en place + + ○ Comment intégrer des acteurs non Mojaloop au schéma ? + + § Comment intégrer Mojaloop et un schéma Mojaloop pour des paiements PVT complets — groupe de travail avec Michael, Adrian, Sybrin, autres au besoin + + § Identifier les participants — FSP, DFSP — tous signés + + § Parties — utilisateurs finaux (Bob / Alice) + + § Transaction unique (avec plusieurs transferts) + + § Personne n’engage ses fonds tant que tout le monde n’est pas satisfait + + § Comment étendre Mojaloop et un schéma non Mojaloop + + ○ Certification + + § Hachage et PKI + + § Réseau or et argent + + § Nouveau partenaire — en ligne sur le réseau + + § Le schéma décide des exigences sur le réseau + + § Certificat auto-signé + + ○ Liquidité + + § Le FXP fait la gestion de position + + § Quelles exigences imposer à un FXP + + § L’argent mobile a moins de flexibilité + + § Règles qui s’appliquent entre schémas + + ○ Le FXP doit gérer les règlements, ce qui expire quand, etc. + + § Le FXP doit gérer le manque de validité des devis + + § Permettre au FXP de rejeter les requêtes + + ○ Comment gérer les demandes pour motifs réglementaires + + § Il existe un dictionnaire + + □ Exigence de partager le KYC ? + + □ On peut demander beaucoup de choses — à la charge du participant + + □ Besoin d’accord sur le schéma de base + +**Jour n°2 :** + + - Données du switch + + ○ Numéros de compte + + ○ Liste noire, liste blanche (supervision et blocage) + + ○ Garder la simplicité + + ○ Hub + + ○ Service annexe pour ceux qui peuvent faire cela + + § Capture de données mobiles + + § Sidecar + + § Processus numérique + + § Services à valeur ajoutée pour le hub (service géré) + + - Switch — doit maintenir l’état et les requêtes de recherche + + - Le CNP peut être un DFSP ordinaire + + ○ Tous les DFSP supportent tous les cas d’usage + + ○ Participants complets (peuvent fournir seulement un service CNP ou FXP) + + - Définition et exigences du FXP + + ○ FXP — exiger taux / frais dans le service de devis — besoin d’un taux industrie standard + + § Les CNP peuvent étendre et définir des règles de schéma supplémentaires + + ○ Le FXP gère les erreurs d’arrondi + + ○ Garantir un taux donné + + ○ Gérer le règlement entre schémas + + ○ Taux de change + + ○ Devrait permettre aux acteurs qui ne font que du FX + + ○ Cas limites en cas d’échec + + § Détails dans les messages d’erreur pour localiser les erreurs + + ○ Le FXP doit renvoyer les bonnes informations + + § Comment les messages circulent + + § Cas limites — partager ce qui est fait à ce jour + + § Jo a une API fonctionnelle — identifiée + + § Modifier le devis (intercepter le devis) — + + § Liste d’extensions KYC — étendu le devis pour cela + + § Les taux sont dans la liste étendue (sont la liste) + + § Où le FXP s’applique-t-il ? + + § Que faire des frais en aval + + □ (le DFSP bénéficiaire prend la place de l’agrégation) + + - Comment gérer la résolution d’identifiants + + ○ 2 types d’identifiants + + § Globaux (passés au CNP) — pour obtenir une réponse + + § Locaux — on attend que l’utilisateur fournisse + + ○ Dans Mojaloop nous utilisons les identifiants comme proxy + + ○ Les numéros marchands peuvent être spécifiques à un schéma + + ○ Plusieurs identifiants pour un seul compte + + ○ Comment identifier de façon unique le compte ? + + ○ S’appuyer sur le CNP (restreindre chaque identifiant dans ce schéma) + + ○ Quelles structures mettre en place + + ○ Identification passeport — espaces réservés + + ○ Cartographier comptes Pathfinder / mobile vers identifiants uniques DFSP + + § Service — compte principal est X + + § Chaque pays a un service qu’il fournit + + § Chaque CNP comprend le schéma d’adresse + + § Identifiant global — savoir quelles voies utiliser + + ○ Envoie un get parties au switch + + § L’ALS ne les a jamais connus + + § 2 voies + + □ Voie globale (pathfinder et conversion vers BIC) + - CNP + + ○ N’héberge rien + + ○ Route via le CNP — solliciter d’autres acteurs + + ○ Construire des routes alternatives + + - Pas de registre global + + ○ Bénéficiaire ultime + + ○ Communication établie + + ○ Défi : deux DFSP pourront-ils partager une communication directe — ce sera difficile ? + + - Le switch a des schémas + + ○ Un opérateur de hub suivant les règles du système peut autoriser les noms de FSP selon ces règles + + ○ La technologie ou l’Admin API elle-même ne restreint pas les noms (sauf longueur, type, caractères, etc.) + + ○ BGP : Border Gateway Protocol + + - Interroger chaque CNP puis optimiser, matrice de route globale — objectif : ne pas interroger le CNP directement + +• Comment se connecter à Mojaloop ? + + - Tout service financier peut se connecter à Mowali + + - Règles techniques et du schéma + + - Réglementaire + + - Comment assigner les choses ? — personne ne connaît les étapes + + - API Mojaloop — comprendre cela. + + - 2 instances Mojaloop — TIPs et Mowali + + ○ WOCCU, Asie, US — demande d’instance + + ○ On repousse encore les limites + + - À quoi ressemble une intégration + + ○ Besoin de bac à sable, simulateurs + + ○ Approche standard + +• Service de paiement par instance + + - Faire circuler les flux en temps utile + + - Besoin de grands livres en temps réel ; que se passe-t-il s’ils sont hors ligne ? + + - Exception pour hors réseau (les banques profitent du float) + +• Processus de découverte (FSP émetteur) + + - Le switch détermine s’il doit contacter un FXP + + - Dans quelle devise le compte bénéficiaire peut recevoir + + - Recherches multiples + + - Modèle de données — ensemble de comptes, avec une devise par DFSP + + +Participants : + + - Mike, Patricia — Thume + + - Michael R, Rob R, Sam — Modusbox + + - Kim, Lewis — Crosslake + + - Rolland, Greg, Phillip — Sybrin + + - Vanburn — Terrapay + + - Megan, Simeon — Virtual diff --git a/docs/fr/community/archive/discussion-docs/images/cb_board_1.jpg b/docs/fr/community/archive/discussion-docs/images/cb_board_1.jpg new file mode 100644 index 000000000..e53cad0b9 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/cb_board_1.jpg differ diff --git a/docs/fr/community/archive/discussion-docs/images/cb_board_2.jpg b/docs/fr/community/archive/discussion-docs/images/cb_board_2.jpg new file mode 100644 index 000000000..8afa47d94 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/cb_board_2.jpg differ diff --git a/docs/fr/community/archive/discussion-docs/images/cb_board_3.jpg b/docs/fr/community/archive/discussion-docs/images/cb_board_3.jpg new file mode 100644 index 000000000..7cce85870 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/cb_board_3.jpg differ diff --git a/docs/fr/community/archive/discussion-docs/images/mojaloop_spokes.png b/docs/fr/community/archive/discussion-docs/images/mojaloop_spokes.png new file mode 100644 index 000000000..b0c67eb08 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/mojaloop_spokes.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_01.png b/docs/fr/community/archive/discussion-docs/images/tagging_01.png new file mode 100644 index 000000000..4379443ce Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_01.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_02.png b/docs/fr/community/archive/discussion-docs/images/tagging_02.png new file mode 100644 index 000000000..b86ac0a91 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_02.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_03.png b/docs/fr/community/archive/discussion-docs/images/tagging_03.png new file mode 100644 index 000000000..d8ab17646 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_03.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_04.png b/docs/fr/community/archive/discussion-docs/images/tagging_04.png new file mode 100644 index 000000000..a2913b226 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_04.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_05.png b/docs/fr/community/archive/discussion-docs/images/tagging_05.png new file mode 100644 index 000000000..ba54dbf64 Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_05.png differ diff --git a/docs/fr/community/archive/discussion-docs/images/tagging_06.png b/docs/fr/community/archive/discussion-docs/images/tagging_06.png new file mode 100644 index 000000000..8c4eb717f Binary files /dev/null and b/docs/fr/community/archive/discussion-docs/images/tagging_06.png differ diff --git a/docs/fr/community/archive/discussion-docs/iso-integration.md b/docs/fr/community/archive/discussion-docs/iso-integration.md new file mode 100644 index 000000000..ffa45ef8f --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/iso-integration.md @@ -0,0 +1,58 @@ +# Discussions d’intégration Mojaloop — ISO + +# Intégration Mojaloop — ISO + +La solution proposée pourrait gérer la traduction ISO vers Open API et inversement via un connecteur ou plug-in « ISO–Open API », sur le modèle du Scheme Adapter Mojaloop. Comme le Scheme Adapter convertit l’API Mojaloop vers l’API FSP, le plug-in personnalisé ferait office de traducteur de protocole et de messages entre l’interface ISO et l’API ML ou le Scheme Adapter. + +## Périmètre + +Définir les flux de messages sur les réseaux ISO et Open API et les correspondances entre messages. + - Documenter les scénarios d’échec et les flux associés. + - Définir un mécanisme de routage basé sur le MSISDN. + - Les transactions Mojaloop pourraient transiter par des rails de paiement existants conformes à leurs normes (ex. ISO). + - Développer un scheme adapter / plug-ins capables d’effectuer ISO ↔ Open API. + - Permettre d’envoyer des transactions Mojaloop issues d’ATM et de TPE sur des réseaux ISO, entre systèmes Mojaloop. + +## ISO 8583 — Mojaloop — Étude de cas inter-réseaux + +L’Afrique compte de nombreux fournisseurs de services financiers axés sur l’inclusion régionale. Parmi les réseaux notables : + +- InterSwitch (Nigeria) +- eProcess (Ghana) +- Umoja Switch (Tanzanie) +- KenSwitch (Kenya) +- ZimSwitch (Zimbabwe) +- RSwitch (Rwanda) + +La plupart utilisent une plateforme de traitement basée sur ISO 8583 (Postilion Switch) pour les canaux ATM, TPE et mobile, et les transactions carte / non carte côté acquisition et émission. + +La proposition est de permettre à ces réseaux existants de s’intégrer à un système basé Mojaloop comme Mowali sans modifier leur infrastructure actuelle. + +Dans cette étude de cas, on considère Umoja Switch en Tanzanie et une solution permettant d’acheminer des transactions Mojaloop via leurs ATM déployés. + +### Umoja Switch + +Umoja Switch a été créé en 2006 par six banques en Tanzanie pour une infrastructure financière partagée et des économies d’échelle. + +L’objectif était une plateforme commune où les institutions financières s’intègrent via un switch partagé. + +Le nombre de membres a augmenté ; environ 27 banques font partie du consortium aujourd’hui. + +## Réseaux ISO vers Open API + +L’objectif du POC est de montrer comment une transaction Mojaloop transite par un switch / réseau ISO standard jusqu’à un système Mojaloop tel que Mowali. + +Un adaptateur ISO–Open API traiterait les messages ISO issus d’un réseau type InterSwitch et les enverrait vers un réseau Open API comme Mowali. + +## Solution proposée + +La solution comprend une interface ou un adaptateur / plug-in traitant les transactions entre réseaux ISO et systèmes Mojaloop. + +La plateforme de paiement ISO utilise une interface ISO sur TCP/IP pour envoyer et recevoir des messages ISO depuis les canaux. Pour accepter ces connexions, la solution inclurait un écouteur TCP/IP recevant les transactions du réseau ISO, les mappant vers Open API, puis les envoyant vers Mojaloop (ex. Mowali) via une URL. + +Les réseaux s’appuient souvent sur le numéro de carte ou de compte (Visa, MasterCard, Verve, etc.) et des tables BIN pour le routage. Une option est de réserver une plage BIN (ex. 757575) identifiant les transactions Mojaloop et de router tout le trafic « Moja » vers le réseau Open API. + +L’adaptateur ISO–Open API convertirait le message ISO reçu du switch ISO au format Open API pour Mojaloop. + +Cela implique des changements de configuration sur les applications des ATM et terminaux, comparables aux changements opérationnels habituels selon les besoins métier. + diff --git a/docs/fr/community/archive/discussion-docs/mojaloop-decimal.md b/docs/fr/community/archive/discussion-docs/mojaloop-decimal.md new file mode 100644 index 000000000..984fc8560 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/mojaloop-decimal.md @@ -0,0 +1,39 @@ +# Type décimal Mojaloop (basé sur le type décimal XML Schema) + +## Type de valeur décimal + +**Définition :** `decimal` représente un sous-ensemble des nombres réels exprimables en notation décimale. L’espace de valeurs est l’ensemble des nombres obtenus en multipliant un entier par une puissance non positive de dix, c’est-à-dire de la forme _i_ × 10−n où _i_ et _n_ sont des entiers et _n_ ≥ 0. La précision n’apparaît pas dans cet espace de valeurs : 2,0 n’est pas distinct de 2,00. La relation d’ordre est celle des réels, restreinte à ce sous-ensemble. + +**Exigence :** tous les processeurs Level One doivent prendre en charge des nombres décimaux avec au minimum 18 chiffres décimaux. Les processeurs Level One peuvent toutefois se conformer à une limite maximale définie par le schéma sur le nombre de chiffres décimaux pris en charge, cette limite devant être ≥ 18 et être clairement documentée. + +## Représentation lexicale + +`decimal` a une représentation lexicale constituée d’une suite finie de chiffres décimaux (#x30 – #x39) séparés par un point comme séparateur décimal. Un signe initial optionnel est autorisé ; s’il est omis, « + » est supposé. Les zéros de tête et de fin sont optionnels. Si la partie fractionnaire est nulle, le point et les zéros suivants peuvent être omis. Exemples : -1,23, 12678967,543233, +100000,00, 210., 452 + +## Représentation canonique + +La représentation canonique de `decimal` est définie en interdisant certaines options de la représentation lexicale (§3.2.3.1). En particulier, le signe « + » optionnel en tête est interdit. Le point décimal est obligatoire. Les zéros de tête et de fin sont interdits, sous réserve qu’il existe au moins un chiffre (éventuellement zéro) à gauche et à droite du point décimal. + +Cette forme canonique est conforme à la représentation lexicale décimale XML ; tout système conforme aux schémas XML l’accepte. + +Ce que d’autres écrivent en forme canonique, nous pouvons le lire comme représentation lexicale ; ce que nous écrivons en forme canonique, d’autres peuvent le lire comme représentation lexicale. Nous rejetons les formats exponentiels en lecture et n’écrivons pas en notation exponentielle. On peut comparer directement les chaînes canoniques de deux valeurs pour l’égalité. + +Lors des échanges, une forme lexicale qui exprime la précision implicite avec des zéros de fin est préférable à la seule forme canonique si cela clarifie le message. Ex. : écrire « 5,00 » plutôt que « 5,0 » lorsque l’unité d’échange est en général précisée à deux décimales (USD, EUR, GBP). Cette option est permise dans les formes lexicales valides du décimal XML et du décimal Mojaloop. + +## Validateurs + +Validateur lexical décimal (ce que nos récepteurs de messages acceptent) : + +```^[-+]?(([0-9]+[.]?[0-9]*)|([.]?[0-9]+))$``` + +Validateur décimal canonique (forme stockée et comparée ; peut servir à vérifier la forme canonique des messages générés) : + +```^([0]|([-]?[1-9][0-9]*))[.]([0]|([0-9]*[1-9]))$``` + +## Traduction entre formes externes et internes + +Lors du passage de la forme lexicale ou canonique vers une représentation binaire interne, l’espace de valeurs de la représentation interne doit être suffisant pour couvrir la plage décimale définie par le schéma, avec une mantisse signée dans l’intervalle −10_m_−1..10_m_−1 et un exposant entier non positif dans l’intervalle −_m_..0, où _m_ est le nombre maximal de chiffres décimaux, au moins 18, tel que défini par le schéma Level One spécifique. + +Une implémentation ne doit pas traduire entre représentations décimales externes et une représentation binaire en virgule flottante. Tous les calculs sur les représentations internes des valeurs décimales doivent produire des résultats comme s’ils étaient effectués « à la main » en décimal sur la représentation externe. + +L’espace de valeurs d’un entier signé 64 bits suffit pour encoder une mantisse décimale signée sur 18 chiffres ; un entier signé 6 bits suffit pour encoder l’exposant en base dix non positif requis. diff --git a/docs/fr/community/archive/discussion-docs/performance-project.md b/docs/fr/community/archive/discussion-docs/performance-project.md new file mode 100644 index 000000000..5a3dad788 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/performance-project.md @@ -0,0 +1,171 @@ +# Fil de travail performance + +Mercredi 11 mars 2020 + +## Objectifs performance + +- Système matériel actuel : 1 k TPS stable en régime établi, pic 5 k, scalabilité horizontale démontrée + 1. Plus d’instances ≈ plus de performance, de façon quasi linéaire. + 1. Valider l’infrastructure minimale pour 1 k TPS (TPS financiers). + 1. Déterminer la configuration d’entrée et le coût (AWS et sur site) + +## POC + +Tester l’impact d’un remplacement direct de MySQL par un service réseau mémoire partagée type Redis (algorithme Redlock si des verrous sont nécessaires). + +Tester une autre façon de partager l’état : version allégée orientée événements avec du CQRS. + +## Ressources + +- Canal Slack : `#perf-engineering` +- [Présentation performance mi-PI](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/March2020-PI9-MidPI-Review) +- [Mise en place des composants de monitoring](https://github.com/mojaloop/helm/tree/master/monitoring) + +## Actions / suivi + +- Quelles métriques Kafka (client et broker) suivre ? — assistance Confluent +- Explorer verrouillage et règlement de position — assistance Sybrin + 1. Examiner RedLock — verrouillage pessimiste vs automatique + 2. Supprimer la base partagée centrale (verrouillage automatique sur Redis) + +- Combiner prepare / position handler avec une base distribuée +- Examiner le client Node.js et son impact sur Kafka, la configuration de Node et le client Kafka final — Nakul +- Réactiver le tracing pour la latence et le comportement des applications +- Vérifier que les comptes d’appels ont été rationalisés (niveau détaillé) +- Valider les temps de traitement sur les handlers et l’utilisation du cache +- Modèles asynchrones dans Node + 1. Manque d’expert MySQL / Percona approfondi + 2. Exploitons-nous correctement ces briques ? + +- Quelle couche de cache (en mémoire) ? +- Examiner la modélisation événementielle — identifier les événements du domaine +- Node.js / Kubernetes — +- Prioriser les problèmes applicatifs plutôt que purement d’architecture +- Revue de l’approche asynchrone (problème Node.js plus large) — modèles à threads à optimiser — Nakul + +## Notes de réunion / détails + +### Historique + +1. Mise en place technologique ; l’espoir était que la conception réponde à un besoin entreprise +2. L’effort communautaire n’a pas priorisé des « tranches » du système de niveau entreprise ou peu coûteuses à exploiter +3. Choix technologiques OSS + +### Objectifs + +1. Optimiser le système actuel +2. Réduire les coûts d’exploitation +3. Permettre de scaler jusqu’à 5 k TPS +4. Garantir que les services à valeur ajoutée accèdent de façon efficace et sécurisée aux données de transaction + +### Contraintes de test + +1. Seulement le « golden transfer » — jambe de transfert +2. Flux de transfert +3. Simulateurs (ancien et avancé) — ancien pour continuité +4. Gestionnaire de timeout désactivé +5. 8 DFSP (organisations participantes) — avec plus de DFSP on pourrait scaler davantage + +### Processus + +1. Jmeter initie la requête payeur +2. L’ancien simulateur reçoit le callback fulfill notify +3. L’ancien simulateur traite le payé, initie le callback d’exécution +4. Enregistrement dans la table positions pour chaque DFSP + - a. Algorithme partiel avec verrouillage pour réserver les fonds, calculs et commits finaux + - b. Le gestionnaire de positions traite un enregistrement à la fois + +5. Un algorithme futur pourrait traiter en lot + +- Un transfert est géré par un gestionnaire de positions + - Les transferts sont tous préfinancés + +1. Réduction des coûts de règlement +2. Contrôle de la vitesse de réponse des DFSP à la requête fulfill (finaliser les transferts engagés avant les nouvelles requêtes) +- Le système doit expirer les transferts dépassant 30 secondes + - Toute refonte des bases + - Cas de test + +- Transaction financière + - Bout en bout + - Prepare seulement + - Fulfil seulement + +- Caractérisation Mojaloop par service + - Services et handlers + - Architecture streaming et bibliothèques + - Base de données + - Qu’est-ce qui a changé : 150 à 300 TPS ? + +- Traitement des messages +- Gestionnaire de positions (mode mixte, aléatoire + - Mesure de latence + +1. 5 s pour la base, X s pour Kafka +2. Comment mesurer ? + +### Cibles + +1. Assez haut pour que le système fonctionne correctement +2. Monter en charge (ajout de x DFSP) +3. Cas suspects à investiguer +4. Observer les contentions autour de la base +5. Base partagée, 600 ms sans erreur + - Contention entièrement sur la base + - Goulot : base (distribuer les systèmes pour indépendance) + +- 16 bases de données bout en bout +- GSMA — 500 TPS +- Quelle conception optimale ? + +### Contentions + +1. Contention au niveau handler système + - Où le système peut scaler +2. Si des changements d’architecture sont nécessaires, on peut explorer + - Cohérence par DFSP + - Parallélisation des flux d’information — question ouverte + +1. Résultats « sku » d’une seule base pour tous les DFSP +1. Défi : où arrive-t-on avec du matériel supplémentaire ? + - Limites de la conception applicative +1. Transferts financiers (entrants / sortants du système) + - Systèmes d’audit + - Activité de règlement + - Regrouper en base résout certains problèmes + - Retour Confluent + +1. Problèmes de base partagée, bases multiples + +1. Problèmes au niveau conception applicative + +1. Cas où de nombreux simulateurs / bacs à sable ont été lancés + - S’appuyer sur traceurs et scans en production + - Miguel : tracing désactivé pour l’instant + +### Problèmes connus + +1. Charge CPU sur les machines (Node en attente) — réoptimiser le code +2. Les temps de traitement augmentent avec le temps + +## Optimisation + 1. Monolithe distribué — PRISM — supprimer les lectures redondantes + 2. Fusionner les handlers — Prepare+Position et Fulfil+Position + +### Qu’est-ce qu’on cherche à corriger ? + 1. Pouvons-nous scaler le système ? + 2. Quel coût pour scaler ? (coût unitaire de scale) + 3. Comprendre comment faire petit et grand scale + 4. Ressources optimisées + 5. 2,5 sprints + 6. Besoin de scaler horizontalement + 7. Ajouter audit et reproductibilité + +### Participants + +- Don, Joran (nouvel expert perf) — Coil +- Sam, Miguel, Roman, Valentine, Warren, Bryan, Rajiv — ModusBox +- Pedro — Crosslake +- Rhys, Nakul Mishra — Confluent +- Miller — Gates Foundation +- Présents : Lewis (CL), Rob (MB), Roland (Sybrin), Greg (Sybrin), Megan (V), Simeon (V), Kim (CL) diff --git a/docs/fr/community/archive/discussion-docs/psip-project.md b/docs/fr/community/archive/discussion-docs/psip-project.md new file mode 100644 index 000000000..d0a1701de --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/psip-project.md @@ -0,0 +1,20 @@ +# PISP (initiation de paiement par un tiers) + +## Objectif + +Mettre à jour les documents de spécification Mojaloop et réaliser une POC PISP. + +## Actions + +- Reprendre la ressource `/authorizations` : [Michael] et remonter au CCB +- Recherche sur le fournisseur d’identité et suivi : [Matt de Haast] +- Partager tous les diagrammes de séquence : [JJ] +- Esquisse de proposition de haut niveau incluant les nouveaux appels API — non assigné +- Correspondance des informations de compte (infos compte pour PISP) : [Lewis] + +## Liens + +- Notes de réunion Londres : `./pisp_meeting_march_2020.md` *(document d’archive ; le fichier peut être absent du dépôt)* +- [Dépôt WIP avec diagrammes de séquence](https://github.com/jgeewax/mojaloop-pisp) +- [Diagramme de séquence bout en bout](https://plantuml-server.kkeisuke.app/svg/xLhhRnkv4V--VmKX571iI8eaEx4Z875aoyu9Tt44hz8WWFg1sgMaFQz87ScreXRvtpl3nxuaEx7H5bVW0kJXvN1cE9pvpODvhpILEbkbWKvqoiXu58w9bfIhEPDa9MAMJlcBJ2LyGJuo6Iqfr-IM_P4nfOaMP4otv2DI7GOqqaAImPQf9ILKaSj1i0RUIPIiSLF3i1wirmrSXB_th8PCtZC90eVNuVZG40wxLRfma-XeQPR-2wihWjz2o9ZNET0j7GOwECHaurhrTGbOXl724n-vmZOiblOVpmVh5-r2is6R99BD4bnS15veH0IS0rIRBH96r56kXQ4fYmHI1PIB1T8ba10svW6zWmi5uH82tCWTh1oXOaSrIa5mvu9fmefUCg6Z9LeniaZGbdB4Ozw_e7IDw8ppFVj0z9AEveSzl4fH9UA8Ju1MJsPPGSzDD4edrrb3-aQ7oagcru8eXN_oAH47l6UnoohqSVnEB9C8lCqOoPOz1LSIafd1GC2fGIZGAcko7WiV04RwhfTXmD5IQSDOEHXg9gLBP2WKigUu7hNU4WkMYJ6cuF4be1imv69dgH72aZwYK2T2BJ1DXRUwf3nI9sNqICMHZt2FETC9G8JXbQbbWI9H323I0suxP77IAQxSeinHsKmxIrap2VeYnHPP0C06n2XWie4S5Rz-IOQ8YTAmjUVisk1oqta7yz4Ta8x8qXlFUMVCwcLF-jswdWrzAJeeUdDoZAs7emU_Mks6txwBrMNmWCeVTbbNb0znJejj1p2fYO1sbV07Zet6jDB3ZseJa7TkUJ_b8muV1-wjKEG6uAOGzIRIqPePhhL30fXT7Hn-k9kIb2H6cZeuE2xr24eGj8xVNwVN9w01kVC4qcT7e3W-p5LbPJp628TuL639U2GOj50_exP5aygfaHc8jYj4hHczKsIEm5WwueuDGz2rGpxzsYGBOyaoIpXF0IomOUAYY2Y3bWPR-87EyU2EYqrWvE1F2jq8dGvilW9VxyCFS1M880547q16dC8-gWpS454BzBaKgy0TqpiaUU2AIbxob2jwzWsLvJrwGnUxDtJS7nevzeRC1Urd1zW_F7Otz6DLGoH6xhTC0uxS5-W1iGz2LXObZ3YRIio6iFyBI0LrtKSC4S0EmI5rbFRj6l3u4Ry1pH_onT9HftooB6kPw_149pK-WL0GRfLcAq34jP1QJNdEcbF0l7tySq2w7FGd01M57Pf49ekbFaV8izo_CjK4qS0dnx3BakvBkZO92F16BS6WKux-Zy3gqe_X1yf1MaqW6kg0LGcqK82xRyZ8H1IP2RqqB6131lVY_BhleWEbkp1prOPTk2WlsEeYk35SVRnALqqvFdb6BsAsI0KsyCOfev1HgRehRQgXDWQkByOGmUj6_t48abeCLgiRvWeMj2LBxZ6HaHLJYYwOjNyg17YRpIb0BJY3R9-A3MRc0wI6ofF7LCPGF_vEWNhjzmVZJo40XpaGAY2uApWL-MKo6R_ijhi177lqQTmAHIOZrhTLXVis1Cg4cu3fU_i4_me8_6hiyXp5ZJvfdCN79_CttRWLTqxFMYUTqzFMMU_rSQiNTKvEpqvVpwFvwqRJyZ0N2PiiI_T9wkqe7a6eLXRAYvFj6dT1cJeQX8vNdGPhaNd29DALOhJH95NokLfRlQsBDVBLx-PVtqkQofgc3bRsgng9rJfbtsuWKdSMhU14AksM6zQxQaSnP2ajg2RqBg6D2ittGj_cVzU8fQHRfwxQSF2G3UbAP5nxkRTNbrUZlryrAejL2-VV6X269Q6DA9EIyMYBIv_3OQCYfkIOJbQ99LJ6dCf467FU3cx2wwlRCcTN4GjpvF7WwmEh_X2Ndsx2pn-1gA81XdTng-G-iJMzFohxjawa2Iea0ipej3gzLlVLfDVhTq_xlRFscxDNhKwt3uSsE_uHV2zL327YLWXAC5j_ED0p6Qht7m4qwEQ6lQSawfuHlKSdgBS72yaOGYyPBr4pgBgHFeTUQEpkeL0dfXU3l41D_rGaTyFF7w04kXPpUpzNzlGga3jOG6_Kj9oniI4sM3LBjmMK-YxE7kG6Vp1WZ1cJHsaMCrNKTpKSj1OsM0rPCi7QmpEgeQsh1n_4smiFjqOT6sMdKU-OdNMYdq7OadOEdb_DmIwzUUlupQpNEddJdRNEkgUiTK8xnxtESNmoxvxisVn_1V5_8VnV2FyaX2TFXlWdONWDlQ7LSDXdCSOCH_8H5rQoEsZtpDPf3Aq3bIoVIjdMfsYJV45Th3srBIh3AjRY6rOTfb4tIiCFIrY7W_85zCn2tc57q0w-i5BrZdsEW-LIYrSQTpK39N8OZYZl1_IGVEOn12hYjgtqfO2KerIz0GzcX-JMYd3ZACtaQeUCl63jHPlC6LE7NhHll8hkmIRRkWsBgT_-PFf8osTJw4ZPurFRuxIA0PrXZxE0fCtQTWXQICK43dlsuVNvOK1JJMw4w_NuWVR2XjYKcGi960G-AHh2jYUvJfnHpLJEkwOLaQUqikxbvimEwB1LfSenCHjSKtTk5DiZT9BdvReH_1srfxok_Cu1m_wra1lCv3-OoUuhAIeNjJEBnWdfbclS6D4KYePiaMwRq9D5D0FcPXQon3aWpfAmQmueEJeQVvuS7H7sBM9hRGUTXJBKswPDBZ8DKOGH3a4Yjm6TuG3Lze6WfMotsrKtxFg9Ht5Er00gGB0OHD6JHsH-r3YvFlV__hHi0dqRMcq8EZYIguMA2ieVPihDQKepQtSiWrdOo99iNHzhEpUoedmLwSzYYiAz6wezTQMenFAt7BXeutkQ9Z7LhC9iojri3UVNKApzqq2EUhalb8wEdbz-selwNsbNlkYVIXVMz1-0PbMsFIX4TulmoetX9Cd0eCyp5bHn4uYHvP7_Rbhpuwh7vvT-eFMOc18oU2CN3n8c8AHYwTmy4KI2Gscs0bT57uQb0ydyk4jW-eWW8ULF0owuLbio1x1XSYqJRlnvjRjdPuu67Gy18cXnM5oetIwc_Gy7eX_wXrLkJddFBdSKyp3WqWBSbPyVcOZ3oH6aZh4KCpe3kFezKte7dFqECm_Vm4S0BjsSSYY2uPpADsSp1ZU07dl7J6PsdgaOub8zFBgF5GzTbqH_udZFpAO5bDHTb_1iDSDNA-m4bKPNg7HoVdsHt3FktvfCJBHnokkc_kxDRPwb-D36gvAWFO3BC7wCRV34Vy-xuDA0jES7fFcppepoEpCiLVa8jcgV8F-yeLoRrq_VnLRrADSwWPZ39_lSLyp7CHct2SuXZLH4-0LSx99HI5mGBzvcPRRcKR1mDsSXZZKR68D2DiITK0skayY27LmoP3C0VsFpmc0gYo9mFJHYyLZkVD5C4inCD0v0vThZIQcE6LLAeF95KwL4PAg7ANUfn4EPlUhpwaLyOOW6xZnVyGR5joPHK5qmsIHmFUsg_6gPyVXRxGyhZOT75iRdj11_vje3Id2TxTRJVxvYPCftgf5AhL5r438QJhbnPpHmOlwlnjpNnG_cn3pU3PJcFhx_gUOhfh1vncF05Kno1JrSi1SXRPVauhPTFEHCbXYsQ6RphBtAyFy-r3995NZHBV3tU_WZMwN_1W00.svg) +- [Document de conception PISP initial, v5](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/January%202020%20OSS%20Community%20Session/%5BEXTERNAL%5D%20Mojaloop_%20PISP%20Credit%20Transactions(3).pdf) diff --git a/docs/fr/community/archive/discussion-docs/versioning-draft-proposal.md b/docs/fr/community/archive/discussion-docs/versioning-draft-proposal.md new file mode 100644 index 000000000..f0ac4d8be --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/versioning-draft-proposal.md @@ -0,0 +1,267 @@ +--- +Authors: Lewis Daly, Matthew De Haast, Samuel Kummary +Proposal Name: Mojaloop Versioning Proposal +Solution Proposal Status: Draft +Created: 26-Feb-2020 +Last Updated: 17-Mar-2020 +Approved/Rejected Date: N/A +--- + +# Versionnement Mojaloop — une proposition + +_Note : ce document est un brouillon vivant de proposition de versionnement au sein de Mojaloop. Une fois prêt, il sera soumis au CCB pour approbation._ + +## Vue d’ensemble + +L’objectif est de produire une proposition qui garde le schéma de versionnement simple à utiliser et clair sur la compatibilité, tout en couvrant les détails nécessaires à un écosystème Mojaloop. + +Objectif : +Proposer une norme pour une nouvelle « Mojaloop Version », qui regroupe : +1. Helm : versions des services individuels, versions des composants de supervision +2. Versions d’API : FSPIOP API, Hub Operations / Admin API, Settlement API +3. Versions de schémas internes : schéma de base de données et messagerie interne + +## Stratégies de versionnement / contexte (revue de littérature) + +Comment les systèmes actuels gèrent-ils le versionnement ? Aperçu rapide. +* La plupart des bonnes pratiques suivent le versionnement sémantique pour les API ; voir [#1198](https://github.com/mojaloop/project/issues/1198) + +### Approches de déploiement sans interruption avec Kubernetes [5] + +Observations clés : +* pour permettre les retours arrière, les services doivent être compatibles en avant et en arrière. +les versions d’application consécutives doivent être compatibles au niveau schéma +* « Ne jamais déployer de changements de schéma rupteurs », les séparer en plusieurs déploiements + +Par exemple, à partir d’une table PERSON : +``` +PK ID + NAME + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +Et nous souhaitons la normaliser en deux tables PERSON et ADDRESS : + +``` +#person +PK ID + NAME + +#address +PK ID +FK PERSON_ID + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +Si ce changement était fait en une seule migration, deux versions de l’application ne seraient pas compatibles. Les changements de schéma doivent être découpés : +1. Créer la table ADDRESS + * L’app utilise les données PERSON comme avant + * Déclencher une copie des données vers ADDRESS +2. ADDRESS devient la « source de vérité » + * L’app utilise les données ADDRESS + * Déclencher une copie des nouveaux ajouts vers ADDRESS vers PERSON +3. Arrêter la copie des données +4. Supprimer les colonnes superflues de PERSON + +Cela signifie qu’un seul changement de schéma de base de données nécessite plusieurs versions d’application et plusieurs déploiements successifs. +* [5] note aussi la simplicité Kubernetes pour déployer ce type de changement + * déploiements rolling upgrade + * Astuce : s’assurer que le point de santé attend la fin des migrations ! +* Q : comment faire de grands changements qui touchent à la fois le schéma et l’API ? + * cela semble difficile et exige beaucoup de coordination + * si mal conçu, un seul changement de schéma pourrait exiger que tous les DFSP soient alignés + * d’où l’idée que la version d’API et la version de service devraient être indépendantes. On doit pouvoir + déployer une nouvelle version de service (avec migration) tout en supportant une ancienne version d’API + + +### Utiliser un registre de schémas pour les messages Kafka [6] + +* [6] propose des approches comme un registre de schémas pour Kafka, par ex. [Apache Avro](https://docs.confluent.io/current/schema-registry/index.html) +* Cela ajoute un niveau de « rigidité » aux messages produits et aide à imposer le versionnement +* Ajoute un composant « registre de schémas » qui garantit la conformité des messages. Cela n’impose pas à lui seul le versionnement, mais renforce les garanties sur les formats. + +### Compatibilité arrière et avant [3], [4] + +* « Le principe de robustesse : être libéral dans ce que l’on accepte et conservateur dans ce que l’on envoie ». Pour les API, cela implique une certaine tolérance côté consommateurs. [3] +* Compatibilité arrière vs incompatibilité arrière [4] : + * En général, les ajouts sont considérés compatibles arrière + * Supprimer ou renommer est incompatible arrière + * C’est souvent au cas par cas ; la [doc de conception d’API Google](https://cloud.google.com/apis/design/compatibility) aide à lister les cas. + +## Écosystème Mojaloop +En parlant de versionnement, il faut préciser que nous versionnons des interfaces pour différentes parties. + +# Proposition +La section suivante décrit la proposition de versionnement. + +## Une « Mojaloop Version » +Une Mojaloop Version **x.y**.z peut englober les versions des trois APIs (détail ci-dessous). +Dans **x.y**.z, « x » est la version majeure et « y » mineure, comme pour le standard FSPIOP ; « z » est le correctif ou une release avec le même x.y ; pour simplifier, il faut regrouper tous les composants de l’écosystème pour indiquer ce qui est inclus. + +En pratique Mojaloop version **x.y** inclut +1. Mojaloop FSPIOP API + * Maintenue par le CCB (Change Control Board) + * Format x.y + * Actuellement v1.0, v1.1 et v2.0 en pipeline +2. Settlement API + * Maintenue par le CCB + * Format x.y + * Actuellement v1.1 et v2.0 en pipeline +3. Admin / Operations API + * Maintenue par le CCB + * Format x.y + * Peut utiliser v1.0 +4. Helm + * Maintenu par la Design Authority + * Format x.y.z + * Versionnement basé sur PI (Program Increment) + Sprint. + > *Note :* le versionnement PI + Sprint a du sens dans le cadre actuel des Program Increments Mojaloop, mais devra être revu plus tard. + * Regroupe des versions compatibles de services individuels +5. Schémas internes + * Maintenus par la Design Authority + * Schéma DB x.y + * Schéma de messagerie interne (Kafka) x.y + +| **Mojaloop** | x.y | | | +|---|---|---|--- +| | Propriétaire / mainteneur | Format | Signification | +| **APIs** | | | | +| - FSPIOP API | CCB | *x.y* | Majeur.Mineur | +| - Settlement API | CCB | *x.y* | Majeur.Mineur | +| - Admin/Operations API | CCB | *x.y* | Majeur.Mineur | +| Helm | Design Authority | *x.y.z* | PI.Sprint.Incrément | +| **Schémas internes** | | | | +| - Schéma DB | Design Authority | *x.y* | Majeur.Mineur | +| - Messagerie interne | Design Authority | *x.y* | Majeur.Mineur | + + + +Par exemple : Mojaloop 1.0 inclut +1. APIs + * FSPIOP API v1.0 + * Settlements API v1.1 + * Admin API v1.0 +2. Helm v9.1.0 + * Versions des services individuels + * Versions des composants de supervision +3. Schémas internes + * Schéma DB v1.0 + * Version messagerie interne v1.0 + +| **Mojaloop** | v1.0 | | | +|---|---|---|--- +| | Propriétaire / mainteneur | Version | +| **APIs** | | | | +| - FSPIOP API | CCB | *1.0* | +| - Settlement API | CCB | *1.1* | +| - Admin/Operations API | CCB | *1.0* | +| Helm | Design Authority | *9.1.0* | +| **Schémas internes** | | | | +| - Schéma DB | Design Authority | *1.0* | +| - Messagerie interne | Design Authority | *1.0* | + +### Avantages + +1. La stratégie privilégie la simplicité. Une version donnée — Mojaloop v1.0 — sert de référence commune aux trois APIs — FSPIOP, Settlements, Admin — ainsi qu’à la version Helm qui regroupe des services compatibles déployables ensemble. +Avec cela, les versions de schéma DB et messagerie interne indiquent si des changements ont eu lieu depuis la release précédente. +2. L’autre avantage, évident, est de répondre aux besoins de toutes les parties prenantes, qu’elles s’intéressent à une vue d’ensemble ou au détail. Grâce à la nature des versions majeures et mineures, utilisateurs et adopteurs pourront plus aisément appréhender les questions de compatibilité. + +### Compatibilité +Comme décrit dans [la section 3.3 de l’API Definition v1.0](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning), la compatibilité arrière est +indiquée par la version **majeure**. Toutes les versions partageant la même majeure doivent être compatibles ; des majeures différentes ne le seront probablement pas. + +_Note importante : les opérateurs de hub devront probablement supporter plusieurs versions de la FSPIOP API en parallèle, car tous les participants ne peuvent pas monter de version simultanément._ + +## Décomposition de la « Mojaloop Version » +Cette section décompose la « Mojaloop Version » proposée et étaye la stratégie. + +### APIs + +La [spec Mojaloop](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning) couvre déjà plusieurs choix de versionnement. + +En pratique courante, plusieurs approches existent pour demander une version, y compris dans l’URL ; la spec le définit déjà via l’extension HTML vendor : [3.3.4.1 Http Accept Header](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3341-http-accept-header) + +Pour la négociation de version, la spec indique qu’en cas de version non prise en charge demandée par le client, + une réponse HTTP 406 peut être renvoyée avec un message décrivant les versions prises en charge. [3.3.4.3 Non-Acceptable Version Requested by Client](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3343-non-acceptable-version-requested-by-client) + +Autre bonne pratique : préciser jusqu’où les clients peuvent cibler une version. +* En développement, beaucoup d’APIs permettent jusqu’au niveau BUGFIX, ex. vX.X.X +* En production, souvent limité aux majeures seulement, ex. v1, v2 +* ex. Google API Platform ne supporte que les majeures +* Avec les nouveautés possibles en v1.1 de l’API Mojaloop, on pourrait vouloir permettre MAJEURE et MINEURE, ex. vX.X. À éviter en principe car les mineures doivent rester compatibles arrière + +Les participants sur la même version MAJEURE de l’API doivent pouvoir interagir. Les majeures différentes ne le peuvent pas. Ex. un participant en v1.1 peut envoyer des transferts vers un autre en v1.0, mais pas vers un participant en v2.0. + +### Helm +Cette section traite les interactions entre services Mojaloop dans un déploiement. Questions du type : une instance cent-ledger:v10.0.1 peut-elle parler à ml-api-adapter:v10.1.0 ? Et ml-api-adapter:v11.0.0 ? Ou comment cent-ledger:v10.0.1 et v10.1.0 accèdent-ils à la base en parallèle ? + +Deux cas : +1. Interactions avec l’état persisté — bases MySQL Percona +2. Interactions entre services — Apache Kafka et (certaines) APIs internes + +Il faut donc versionner : +* le schéma de base de données +* les messages dans Apache Kafka + * s’assurer que les bons services lisent les bons messages. Ex. mojaloop/ml-api-adapter:v10 +.1.0 publie-t-il des messages Kafka que mojaloop/central-ledger:v10.0.1 comprend ? + * Q : si le format de message change de façon incompatible, comment éviter que des messages dans les flux Kafka + soient consommés par les mauvais services ? + +### Schémas internes + +#### Base de données + +todo : à compléter ? + +#### Kafka / messagerie +Nous utilisons actuellement le protocole lime pour les formats Kafka : https://limeprotocol.org/ + +Voir aussi le readme mojaloop/central-services-stream pour le format des messages. + +Le protocole lime prévoit un champ type, qui supporte des déclarations de type MIME. On pourrait gérer les messages comme pour l’API (ex. application/vnd.specific+json). Versionner ainsi implique que les consommateurs soient compatibles en avant et en arrière (versions consécutives compatibles schéma). +* Q. mettre la version dans le topic Kafka ? + * Ex. ml-api-adapter publie sur le topic prepare + * Avec versionnement, ml-api-adapter:v10.0.0 publie sur prepare_v10.0, et une nouvelle instance + ml-api-adapter:v10.1.0 sur prepare_v10.1. + * les abonnés choisissent le(s) topic(s) ou les deux selon tolérance + * effets de bord possibles sur les performances +* Autre option : un « adaptateur » de messages dans le déploiement. Si ml-api-adapter:v10.1.0 produit sur prepare_v10.1 sans central-ledger correspondant, un adaptateur s’abonne à prepare_v10.1, reformate en compatible arrière, et republie sur prepare_v10.0. + +Cela permettrait des changements de schéma incrémentaux pendant la montée de version des services. + +En somme, je n’ai pas trouvé grand-chose sur ce sujet ; il faudra y revenir ultérieurement. + +## Négociation de version +todo : @sam discuter de la stratégie de négociation de version + +## Support long terme (LTS) +todo : discuter comment le LTS s’intègre. Pas trop de détail, plutôt une esquisse. + +Mentionner le (manque de) LTS actuel, le rythme des PI + +## Annexe A : définitions + +* **service** : Mojaloop suit une approche orientée microservices, où une grande application est décomposée en services plus petits. Dans ce contexte, Service désigne une application conteneurisée dans un déploiement Mojaloop, typiquement un conteneur Docker dans un cluster Kubernetes. ex. mojaloop/central-ledger est le service central-ledger +* **version de service** : version du service. Ne suit pas encore le versionnement sémantique ; pourrait évoluer + ex. mojaloop/central-ledger:v10.0.1. Voir le [doc + Versioning](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/versioning.md). +* **helm** : gestionnaire de paquets pour Kubernetes. Souvent appelé aussi « déploiement ». Un déploiement Helm exécute plusieurs services et PEUT exécuter plusieurs versions du même service. On utilise aussi le dépôt mojaloop/helm. +* **version helm** : version du chart packagé, ex. mojaloop/helm:v1.1.0 +* **interface** : protocole par lequel un switch Mojaloop interagit avec l’extérieur — participants (DFSP), opérateurs de hub, administrateurs. +* **api** : interface de programmation — souvent le FSPIOP-API défini [ici](https://github.com/mojaloop/mojaloop-specification). +* **version d’api** : version du FSPIOP-API, ex. FSPIOP-API v1. Ici, contrat entre le switch Mojaloop et les participants (DFSP) qui implémentent le FSPIOP-API + +## Références + +[1] LTS dans nodejs — bon exemple de stratégie LTS et communication. +[2] Référence Semantic Versioning +[3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ +[4] https://cloud.google.com/apis/design/compatibility +[5] Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway +[6] Stackoverflow - Kafka Topic Message Versioning diff --git a/docs/fr/community/archive/discussion-docs/workbench.md b/docs/fr/community/archive/discussion-docs/workbench.md new file mode 100644 index 000000000..01c91fa59 --- /dev/null +++ b/docs/fr/community/archive/discussion-docs/workbench.md @@ -0,0 +1,247 @@ +# Discussion Lab / établi Mojaloop + +___Objectif :__ Ce document de discussion vise à exposer les arguments et à aligner la communauté autour du développement d’un environnement Lab Mojaloop à vocation pédagogique._ + + +## 1. Objectifs de la réunion PI8 + +1. Définir les termes et poser les hypothèses +2. Dresser l’état des efforts existants et la manière dont la communauté OSS s’aligne (GSMA, MIFOS, ModusBox) +3. Définir les utilisateurs et cas d’usage, et exclure ceux dont on ne s’occupera pas +4. Recommandations pour plusieurs pistes de solution au « problème du Lab » + - Documentation sur les cas métier et personas développés par Dan + - Implémentation de base du configurateur de Lab, pour aider à construire des labs avec différentes fonctionnalités + - Démo simple Mojaloop-sur-tableur, pour faire utiliser Mojaloop sans Postman +5. Implémentation et démo de base +6. Poser les questions importantes et discuter des prochaines étapes + +## 2. Nomenclature + +**1. Outils :** +- 1.1 Un dispositif utilisé pour accomplir une fonction +- 1.2 Des outils différents pour des fonctions différentes : on n’utilise pas un tournevis pour enfoncer un clou. +- 1.3 Dans le contexte Mojaloop, un exemple d’outil est la Bank Oracle + - La Bank Oracle est un outil qui se branche sur le Account Lookup Service et permet à Mojaloop de se connecter à des comptes bancaires existants avec un IBAN + +**2. Établi (Workbench) :** +- 2.1 Regroupe plusieurs outils au même endroit +- 2.2 Par exemple, rabot, scie sur table et ciseau constituent un établi de menuiserie, alors que scie à métaux, lime et meuleuse d’angle peuvent constituer un établi de métallerie +- 2.3 En langage Mojaloop, les outils pour tester les clés JWS de mon DFSP sont dans un autre établi que les outils qui montrent à une fintech comment les API de gros peuvent fonctionner au-dessus de Mojaloop + +**3. Lab :** +- 3.1 Un lab est un lieu où l’on mène des expériences +- 3.2 On mène des expériences pour apprendre et tester nos hypothèses + - Par exemple, un DFSP peut mettre en place et exécuter une _expérience_ où il envoie et reçoit des Quotes via une API en cours de développement +- 3.3 Un seul lab combine plusieurs établis au même endroit + +**4. Simulateur :** +- 4.1 Un outil qui simplifie ou abstrait une fonction pour tester une chose à la fois +- 4.2 Les pilotes s’entraînent sur simulateur _avant_ de piloter un avion réel, dangereux et coûteux. +- 4.3 Dans Mojaloop : un simulateur peut simuler l’interaction avec un composant du système + - Remplacer tout un switch pour tester une implémentation DFSP + - Simuler 2 DFSP pour tester un déploiement de switch + - Un simulateur réduit aussi le besoin qu’une personne accompagne celle qui teste. Un DFSP peut ainsi envoyer et recevoir via le switch sans interaction avec l’opérateur de hub. + + +## 3. Hypothèses + +>_Certaines semblent évidentes, mais on les note quand même._ + +- 1\. La Gates Foundation souhaite encourager l’adoption de Mojaloop à tous les niveaux (pas seulement les switches) +- 2\. Nous n’avons pas besoin d’un lab pour couvrir le déploiement d’un Switch ou l’implémentation DFSP — ces besoins seront couverts ailleurs +- 3\. La communauté OSS Mojaloop veut se rendre attractive + - Cela ne signifie pas supprimer toutes les barrières à l’entrée ; il s’agit d’identifier lesquelles lever + + +## 4. Utilisateurs + +Nous distinguons deux groupes : utilisateurs primaires et secondaires. + +### 4.1 Utilisateurs primaires +1. DFSP qui doivent s’intégrer à Mojaloop (raccourci : DFSP en implémentation) +2. Organisations / personnes souhaitant découvrir Mojaloop et construire ou tester des fonctionnalités ou cas d’usage en tant que DFSP (raccourci : DFSP en évaluation) +3. Organisations / personnes souhaitant découvrir Mojaloop et construire ou tester en tant qu’opérateur de hub (raccourci : opérateurs de hub en évaluation) +4. Régulateurs, organisations ou personnes souhaitant comprendre et évaluer Mojaloop et son impact sur leurs services existants (raccourci : évaluateurs généraux) + +### 4.2 Utilisateurs secondaires +5. Intégrateurs souhaitant proposer Mojaloop as a Service ou des briques d’intégration (intégrateur système) +6. Contributeurs individuels (y compris chasseurs de primes ?) (contributeur individuel) +7. Fintechs opérant ou qui opéreront au-dessus d’un switch activé Mojaloop (fintech propulsée par Mojaloop) +8. Fournisseur d’applications tiers interagissant avec les API wholesale de l’argent mobile, vendant des intégrations aux fintechs, etc. (fournisseur d’apps tiers) +9. Acteurs de l’inclusion financière intéressés à promouvoir Mojaloop et d’autres technologies favorisant l’inclusion (défenseurs de l’inclusion financière) + +En plus de chaque profil ci-dessus, il importe de situer le niveau auquel ces utilisateurs se rapportent à un déploiement Mojaloop. Nous empruntons à Dan Kleinbaum son article [_Fintech primer on Mojaloop_](https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb) + +![les 3 niveaux de « mojaloopitude »](./images/mojaloop_spokes.png) +>_Les 3 niveaux de Mojaloopitude, https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb par Dan Kleinbaum_ + +**Niveau 1 :** Exploiter un switch Mojaloop (ex. opérateurs de hub) +**Niveau 2 :** Interagir directement avec un switch Mojaloop (ex. DFSP, intégrateurs) +**Niveau 3 :** Interagir avec un DFSP via un switch Mojaloop (ex. fintechs) + + +## 5. Cas d’usage + +__a.__ Tester une implémentation DFSP compatible Mojaloop +__b.__ Valider des hypothèses sur Mojaloop +__c.__ Consulter et utiliser une implémentation de référence +__d.__ Comprendre les mécanismes internes de Mojaloop +__e.__ Comprendre les switches activés Mojaloop et les cas d’usage associés (technologie) +__f.__ Évaluer l’impact de Mojaloop sur le paysage des fintechs +__g.__ Pouvoir démontrer une proposition de valeur pour les DFSP / fintech / etc. d’utiliser Mojaloop (plutôt qu’une technologie _x_) + + +## 6. Matrice utilisateurs / cas d’usage + +Nous pouvons croiser utilisateurs et cas d’usage : + + +| __Cas d’usage :__ | a. Test impl. DFSP | b. Valider hypothèses | c. Impl. réf. | d. Internes | e. Tech | f. Cas métier | g. Démontrer valeur ML | +| :----------------------------------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| __Utilisateur :__ | | | | | | | | +| __1. DFSP en implémentation__ | X | | X | | | | | +| __2. DFSP en évaluation__ | | X | X | | X | X | | +| __3. Opérateur de hub en évaluation__ | | | X | | X | X | | +| __4. Évaluateur général__ | | | | | X | X | | +| __5. Intégrateur système__ | X | X | X | X | | | X | +| __6. Contributeur individuel__ | | X | X | X | | | | +| __7. Fintech propulsée Mojaloop__ | | X | | | X | X | X | +| __8. Fournisseur d’app tiers__ | | | | X | | | X | +| __9. Défenseurs inclusion financière__ | | X | | | | X | X | + + +## 7. Entrées et sorties par cas d’usage + +>_Choisir 2 ou 3 couples utilisateur / cas d’usage et détailler les entrées et sorties pour répondre à leurs besoins_ +>>_Comme souvent, une partie des profils et conclusions reste floue et pourrait être reclasseée. Nous essayons néanmoins de les définir au mieux._ + +### 7.1 Opérateur de hub en évaluation + DFSP en implémentation +Comme indiqué dans nos hypothèses, nous ne traitons pas ici les opérateurs de hub ni les DFSP en implémentation. + +### 7.2 DFSP en évaluation + +>_Un DFSP en évaluation n’est pas forcément déjà rattaché à un switch ; c’est un acteur curieux de Mojaloop, candidat à l’évangélisation — sans objectif tangible de déploiement switch à court terme._ + +**7.2.1 Cas d’usage :** +- 1\. Valider des hypothèses sur Mojaloop (fonctionnement, périmètre, ce qu’il _ne_ fait pas) +- 2\. Explorer une implémentation de référence +- 3\. Comprendre les hubs activés Mojaloop et les cas d’usage (angle technique) +- 4\. Évaluer l’impact futur sur leur activité + +**7.2.2 Exemples issus des personas :** +- 1\. Carbon — Encaissements et envois de fonds OTC via leur réseau d’agents +- 2\. Ssnapp — Paiements multi payeur / payé et points de fidélité sur Mojaloop +- 3\. Oneload — Simplifier l’onboarding d’autres DFSP vers le réseau d’agents OneLoad +- 4\. Juvo — Se brancher à un switch Mojaloop pour un marché du crédit et du scoring + +**7.2.3 Sorties : (comment la communauté OSS Mojaloop peut mieux servir ces acteurs ?)** +- 1\. Aider à rejoindre l’écosystème Mojaloop +- 2\. Aider à comprendre la technologie, où elle excelle et les pièges possibles +- 3\. Minimiser l’investissement pour obtenir quelque chose qui tourne, afin de se concentrer sur des prototypes de cas d’usage +- 4\. Les faire passer de peu ou pas de connaissance Mojaloop à des prototypes réels + +**7.2.4 Entrées : (ce qu’il faut faire pour atteindre ces objectifs)** +- 1\. Documentation Mojaloop améliorée pour ce rôle. + - 1.1 Concevoir le parcours doc et d’onboarding pour les *DFSP en évaluation* + - 1.2 Documentation accessible aux profils produit, etc., avec peu de bagage technique +- 2\. Plongée technique sur le « pourquoi » et le « comment » (réutiliser éventuellement le démonstrateur JS en parcours interactif bout en bout) +- 3\. Guides pour monter l’environnement sur 2–3 fournisseurs Kubernetes majeurs, self-service et scripts d’installation +- 4\. Charts Helm pour 1–2 simulateurs / labs déployables à côté d’un switch, avec réglages préconfigurés + + +### 7.3 Fintech propulsée par Mojaloop + +>_Une fintech « Mojaloop-powered » opère ou souhaite opérer au-dessus d’un switch Mojaloop. Il existera inévitablement un chevauchement entre les fintechs et les DFSP dans cette classification, mais nous nous concentrons sur les fintechs au troisième niveau des « Mojaloop Spokes »._ + +**7.3.1 Cas d’usage :** +- 1\. Valider des hypothèses sur Mojaloop +- 2\. Comprendre l’alignement avec les API wholesale et ce qu’il faut pour qu’un DFSP les utilise via un switch Mojaloop +- 3\. Comprendre les hubs activés Mojaloop et les cas d’usage (technique) +- 4\. Évaluer l’impact futur sur leur activité + +**7.3.2 Exemples issus des personas :** +- 1\. EastPay — Comparer et choisir banques / prestataires selon la structure de frais ouverte de Mojaloop +- 2\. Jumo — Ouvrir des marchés du crédit plus transparents au-dessus d’un switch Mojaloop ? + +**7.3.3 Sorties :** +- 1\. Comprendre comment Mojaloop et les API wholesale s’articulent (ou non) +- 2\. Permettre aux fintechs d’interagir avec Mojaloop via 1 ou 2 API wholesale (ex. API MM GSMA) +- 3\. Passer de peu de connaissance à des prototypes réels + +**7.3.4 Entrées :** +- 1\. Documentation Mojaloop adaptée à ce rôle. +- 2\. Documentation ou document de travail sur Mojaloop et les API wholesale +- 3\. Lab auto-déployé avec DFSP exposant des API wholesale de base pour tests fintech + + +## 8. Efforts OSS Lab / établi aux côtés d’autres acteurs + +D’autres travaillent déjà sur une partie de ces besoins. Comment s’aligner pour : (1) ne pas dupliquer les efforts (ni se marcher sur les pieds) et (2) maximiser l’impact pour les utilisateurs finaux et la communauté ? + +Consensus général : +- tout effort OSS Lab doit cibler un utilisateur final précis +- notre focus doit être plus loin sur les « spokes » (DFSP, fintechs, fournisseurs d’apps tiers) + + +### 8.1 MIFOS +- 1\. Travail déjà important avec Fineract, solution clé en main pour DFSP activés Mojaloop +- 2\. Travail sur des implémentations Open API +- 3\. Réduction des barrières pour DFSP et fintechs +- 4\. Mifos Innovation Lab : « La locomotion sur les rails Mojaloop » + - 4.1 Démontrer des systèmes Mojaloop bout en bout avec intégration DFSP + - 4.2 Construire et contribuer des outils OS +- 5\. Déploiements réels en cours +- 6\. Besoin d’un « point d’entrée unique » vers l’écosystème Mojaloop +- 7\. Déploiement Lab existant avec Mojaloop, en cours de mise à niveau vers les derniers charts Helm + + +### 8.2 GSMA +- 1\. API mobile money ; souhait d’une solution bout en bout fintech / DFSP via un switch Mojaloop +- 2\. Le Lab GSMA a une portée large ; Mojaloop n’en est qu’une facette +- 3\. Objectif majeur : API mobile money — standard par défaut pour l’intégration tiers +- 4\. Où se place Mojaloop ? + - 4.1 Une des branches du Lab GSMA + - 4.2 Où GSMA apporte-t-elle le plus de valeur à Mojaloop ? + - 4.2.1 Répondre à un besoin marché pour maximiser l’impact + - 4.2.2 Prototype bout en bout de l’API MM au-dessus d’un switch Mojaloop + + +### 8.3 ModusBox +- 1\. Perspective intégrateur : nombreux outils pour faciliter dev et onboarding switches / DFSP +- 2\. Mojaloop JS SDK open source +- 3\. Montrer « comment le moteur fonctionne » pour rassurer partenaires et clients +- 4\. Intérêt (notamment WOCCU) pour un lab où les fintechs apprennent et testent au-dessus des switches Mojaloop + - 4.1 Une fois connecté, les cas d’usage intéressants dépassent les transferts A vers B + - 4.2 Les IMF (surtout PME) ont peu de capacité d’expérimentation ; les fintechs peuvent porter les nouveaux cas +- 5\. Comment aider les org. peu techniques à gagner confiance avec Mojaloop ? + - 5.1 Un lab technique ne suffit pas seul + - 5.2 Mojaloop sur tableur ? Les tableurs sont universels. + + +## 9. Questions + +- 1\. Beaucoup revient au cycle de vente proposé par la Gates Foundation pour l’adoption Mojaloop + - 1.1 Les briefs techniques du hackathon montrent des acteurs __majeurs__ (Famoco, Ethiopay, GrameenPhone) qui pourraient emporter Mojaloop + - 1.2 Comment franchir le premier obstacle pour accélérer l’adoption et l’open source ? + - 1.3 À quoi ressemble le point d’entrée industrie pour les opérateurs de hub ? + +- 2\. Pour les DFSP en évaluation, quel est leur arbitrage ressources / risque ? + - 2.1 S’ils jugent Mojaloop viable pour un futur produit, quel investissement temps / ressources ? + - 2.2 Quelles alternatives ? (cas par cas) + +- 3\. Un certain niveau de contrôle d’accès technique est-il souhaitable ou non ? (question plus philosophique) + - 3.1 Si démarrer est trop difficile, seuls les acteurs intéressés et déterminés utilisent Mojaloop — ce qui crée une auto-sélection vers une meilleure communauté (en quelque sorte) + - 3.2 Mais cela exclut des profils peu à l’aise avec Kubernetes, Docker, etc., pourtant expérimentés en services financiers + +- 4\. Problème œuf / poule entre DFSP et opérateurs de hub : d’abord les DFSP ou d’abord les hubs ? + + +## 10. Recommandations + +- 1\. Identifier un utilisateur cible pour construire un lab avec / pour + - 1.1 Peut-être une équipe hackathon sérieuse ? +- 2\. Combler et améliorer les lacunes documentaires : angle par rôle (DFSP, fintech, opérateur de hub) +- 3\. Démo Mojaloop sur tableur +- 4\. Prototype de lab en self-service + - 4.1 Jeu de charts Helm opinionné déployable à côté d’un switch générique + - 4.2 Collecter les retours communauté et observer les usages diff --git a/docs/fr/community/archive/notes/README.md b/docs/fr/community/archive/notes/README.md new file mode 100644 index 000000000..f8e847f11 --- /dev/null +++ b/docs/fr/community/archive/notes/README.md @@ -0,0 +1,5 @@ +# Notes des groupes de réunion OSS (Archive) + +- [Comité de Contrôle des Changements (CCB)](./ccb-notes.md) +- [Autorité de Conception (DA)](./da-notes.md) +- [Réunions Scrum-of-scrum](./scrum-of-scrum-notes.md) diff --git a/docs/fr/community/archive/notes/ccb-notes.md b/docs/fr/community/archive/notes/ccb-notes.md new file mode 100644 index 000000000..bd6bca1b9 --- /dev/null +++ b/docs/fr/community/archive/notes/ccb-notes.md @@ -0,0 +1,7 @@ +## Réunions du CCB : Vue d'ensemble + +Le Comité de Contrôle des Changements (CCB) se réunit toutes les deux semaines. + +Les réunions sont ouvertes au public, bien que les discussions soient généralement limitées aux membres du comité. Cependant, les participants seront promus au rang de panélistes s'ils ont des demandes de changement ou des propositions de solution à discuter. + +Plus de détails sont disponibles ici : https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings \ No newline at end of file diff --git a/docs/fr/community/archive/notes/da-notes.md b/docs/fr/community/archive/notes/da-notes.md new file mode 100644 index 000000000..11c97240e --- /dev/null +++ b/docs/fr/community/archive/notes/da-notes.md @@ -0,0 +1,125 @@ +## Réunions DA : Aperçu +L’Authority Design (DA) se réunit chaque semaine pour une mise à jour hebdomadaire et tient également des sessions ad hoc ou détaillées sur des sujets spécifiques. + +Les réunions sont ouvertes au public, bien que les discussions soient généralement limitées aux membres du Conseil. Cependant, les participants sont promus au rang de panélistes lors des réunions s'ils ont des conceptions à examiner ou des propositions de changement. + +Plus de détails peuvent être trouvés [ici](https://github.com/mojaloop/design-authority/issues/42#workspaces/da-issue-log-5cdd507422733779191866e9/board?notFullScreen=false&repos=186592307) + +# Réunion DA - 30 septembre 2020 +La discussion sur les sujets mentionnés a débuté – le "patch" nouvellement implémenté dans la version 1.1 de la spécification de l'API a été discuté et la majeure partie de la réunion a été consacrée à la manière de promouvoir une adoption plus large de ce nouveau modèle. + +Des inquiétudes concernant l'implémentation et l'utilisation de la commande "patch" ont été soulevées, indiquant qu'une discussion supplémentaire est nécessaire pour déterminer si nous n'essayons pas de corriger une erreur de conception par une autre potentielle erreur de mise en œuvre. + +Voir : https://github.com/mojaloop/design-authority/issues/68 + + +# Réunion DA - 2 septembre 2020 +Nous avons d'abord discuté du dossier "models" devant être exclu des vérifications de couverture des tests unitaires. La décision prise était que si le dossier contient de la logique métier (ce qui ne devrait généralement pas être le cas), il doit être refactoré et déplacé. Une fois dans cet état "logique métier isolée", la couverture de tests pour ce dossier peut être ignorée. Voir : https://github.com/mojaloop/design-authority/issues/64 + +Nous avons conclu la discussion sur l’adaptateur de schéma séparé pour un PISP – voir le sujet sur le tableau : https://github.com/mojaloop/design-authority/issues/51 +Veuillez consulter le document de travail à cette adresse : https://github.com/mojaloop/pisp/blob/scratch/api-collision/docs/api-collision.md +Le lien ci-dessus contient une discussion détaillée sur les réflexions les plus récentes et certains exemples de mesures d’atténuation. +La décision a été prise de bloquer ce sujet jusqu’à ce que d’autres développements sur la PoC aient été réalisés, afin que la DA puisse évaluer si les conceptions sont toujours alignées avec l’approche recommandée. + +# Réunion DA - 26 août 2020 +Nous avons poursuivi la discussion sur https://github.com/mojaloop/design-authority/issues/51 lors de la réunion DA du 26/08/2020. + +Quelques points clés ont été notés : + +Afin de profiter de TypeScript et d’accélérer le développement, le groupe de travail PISP a déjà séparé l’adaptateur de schéma tiers. + +L’un des défis identifiés avec l’approche "multi-scheme-adapter" était pour les cas où des ressources sont partagées entre les APIs, comme GET /parties/{type}/{id}. + +Notre décision de séparer l’API Thirdparty en sa propre API (et de ne pas étendre la FSPIOP-API) était basée sur l’idée que "tous les participants ne voudront pas des fonctions tierces", ils ne devraient donc pas avoir à s’en soucier. Dans le cadre de cette décision, certaines ressources seront donc dupliquées. + +Cela pourrait poser problème à l’avenir, où les callbacks de certaines ressources pourraient ne pas, par exemple, arriver à la bonne destination : si un DFSP doit écouter les callbacks PUT /parties/{type}/{id} pour les deux APIs (FSPIOP et Thirdparty), il se peut qu'il ne soit pas possible de router correctement ces callbacks. + +Lewis Daly va consacrer plus de temps à travailler sur des diagrammes et des documents de conception, et reviendra vers la DA prochainement. + +# Réunion DA (Ad-Hoc) - 24 août 2020 +Le sujet de discussion était : https://github.com/mojaloop/design-authority/issues/65 +La réunion ad hoc a été menée pour aborder un problème plus large relatif aux recommandations devant être remontées au CCB pour examiner un changement/une amélioration de la spécification de l’API. + +De nombreux points valides ont été soulevés et discutés, et Michael et Adrian ont suggéré une collaboration sur cette plateforme pour consolider les idées avancées afin de formuler une recommandation au CCB. + +# Réunion DA - 19 août 2020 +Le sujet de la réunion était : https://github.com/mojaloop/design-authority/issues/61 +Le groupe a convenu qu'il fallait trouver un équilibre entre la nécessité d’éliminer la conciliation et la gestion des liquidités des FSPs (payeurs) en évitant de bloquer/réserver des fonds plus longtemps que nécessaire. Il a également été proposé d'utiliser une "période de grâce" avant de faire expirer un transfert pour compenser les différences d'horloge. Il a aussi été suggéré que pour les transactions à risque, la notification finale sous forme d'appel PATCH, introduite avec FSPIOP API v1.1, puisse être utilisée pour atténuer le risque côté FSP bénéficiaire. + +Un point a été soulevé : après la période de timeout (plus la période de grâce pour les différences d’horloge), le statut d’un transfert ne peut plus être modifié – il est soit finalisé, soit non, mais on ne peut pas le changer. Par exemple, si la période de timeout (exprimée comme un moment futur et non une durée) est de 10 secondes, alors un FSP payeur (ou Switch) peut ajouter une période de grâce d’1 seconde et, après 11 secondes, interroger l’entité en aval pour connaitre le statut du transfert ; À ce point, si le transfert est finalisé (Commit ou Abandon), le FSP payeur peut agir en conséquence ; sinon, si l’état est intermédiaire, le transfert doit être expiré puisque la période de timeout est dépassée. + +Le groupe a convenu qu’il fallait réexaminer la mise en œuvre des "timeouts télescopiques", qui n’est pas actuellement prise en charge au profit du chiffrement de bout en bout de (la plupart) des messages. + +# Réunion DA - 12 août 2020 +Le sujet de la réunion était : https://github.com/mojaloop/design-authority/issues/63 +La DA a discuté de la création et du suivi des tickets d’anomalie. Avec plus de 50 dépôts, il est logique de créer un ticket dans le dépôt d’origine et de continuer à le traiter là jusqu’à sa résolution. Le Product Owner et le Scrum Master, ayant le contexte, doivent répliquer un ticket dans le dépôt Design Authority avec un lien vers le ticket d'origine. Merci de consulter le tableau DA pour les décisions prises ici : https://github.com/mojaloop/design-authority#workspaces/da-issue-log-5cdd507422733779191866e9/board?repos=186592307 + +# Réunion DA - 5 août 2020 +Le sujet de la réunion était : https://github.com/mojaloop/project/issues/852 +L'approche d’intégration HSM a été évoquée à plusieurs reprises, et le groupe prenant en charge la conception et la mise en œuvre l’a soumis à discussion à la réunion DA pour répondre à quelques questions issues de la dernière session PI-Planning où l’avancée du projet a été présentée. + +Comme la discussion n’a pas pu être terminée, une réunion DA ad hoc est prévue ce vendredi avec une sous-section des membres DA. La raison est qu’il y avait quelques questions spécifiques qui n’ont pas pu être abordées en détail, ce qui sera clarifié avec les personnes concernées. Contactez-moi si vous souhaitez participer à cette réunion. + +# Réunion DA - 29 juillet 2020 +Sujet abordé : https://github.com/mojaloop/design-authority/issues/60 +Claudio a noté trois observations concernant les meilleures pratiques dans le code Mojaloop Core. L'un des problèmes bénéficie déjà d'un ticket actif et servira à son suivi ; les deux autres feront l'objet de nouvelles stories/bugs (normes). Claudio doit fournir des exemples, parfois des extraits de code, pouvant être utilisés. + +Istvan et Michael ont discuté de l’utilisation d’un identifiant unique pour les requêtes de recherche et proposé de tenir une session de suivi la semaine suivante pour les personnes intéressées. L’utilisation actuelle d’entêtes de trace (optionnel) pour la traçabilité (APM) a été proposée, pouvant, après examen DA, être retenue et proposée au CCB (si acceptée par la DA). + +# Réunion DA - 22 juillet 2020 +Annulée pour cause du PI-11 Mojaloop Convening + +# Réunion DA - 15 juillet 2020 +Sam a présenté les changements majeurs de la version Helm v10.4.0 et des extraits des notes de version : https://github.com/mojaloop/helm/releases/tag/v10.4.0 +Merci de consulter le tableau des sujets DA : https://github.com/mojaloop/design-authority/issues/56 + +Neal et Michael ont discuté du partage de base de données/code entre central-settlement et central-ledger ; ils vont continuer le travail courant sur la "Continuous Gross Settlement", mais après le convening ils récupèreront les retours du PoC Perf/Arch (event sourcing / CQRS) pour s'aligner : https://github.com/mojaloop/design-authority/issues/58 + +# Réunion DA - 8 juillet 2020 +L’équipe TIPS a présenté la conception et la mise en œuvre d’un **moteur de règles** répondant aux exigences d'interprétation sur la **partie règlements**, pour étendre les frais perçus lors d'un transfert. L’implémentation permet d’interpréter des règles à chaque étape d’une transaction. Une présentation officielle sera faite lors du convening de la semaine du 20 juillet 2020, après quoi l’adaptation éventuelle dans le code OSS Core sera envisagée comme approche générique de la mise en œuvre d’un moteur de règles. +Voyez le lien sur le tableau Design Authority ici : https://github.com/mojaloop/design-authority/issues/53 pour un exposé du problème, le déroulement des réunions, les remarques, et aussi, une fois prise, la décision finale. + +# Réunion DA - 1er juillet 2020 +Dans le cadre du "workstream Versioning", une PoC de "déploiement sans interruption" est en cours et les retours sont présentés sous forme d’un exposé du problème, de la solution et d’une démo. L’équipe à l’œuvre comprend Lewis Daly, Mat de Haast et Sam Kummary. Les retours ont été bien accueillis et, le travail se poursuivant, la DA assurera le suivi des tâches à venir après la prochaine présentation lors du PI 11 Meeting. +Voyez le lien sur le tableau Design Authority ici : https://github.com/mojaloop/design-authority/issues/54 pour un exposé détaillé du problème, le suivi des réunions etc. + +# Réunion DA (Ad-Hoc) - 29 juin 2020 +Discussion KNEX – suite. Cette discussion a débordé sur l'éventuelle utilisation d'outils tiers pour l’assistance à la génération de requêtes et faciliter les migrations. Cela n’a pas d’impact direct sur l'usage de KNEX lui-même, et après un examen approfondi, il a été décidé qu’il n’y avait pas de raison suffisamment impérieuse pour continuer l’enquête sur KNEX, mais de rester ouvert à d’autres solutions à l’avenir. Ces bibliothèques seront évaluées en regard de l’implémentation actuelle pour garantir que les bons outils servent le bon but. Ce sujet est désormais clos. +Voyez le lien sur le tableau Design Authority ici : https://github.com/mojaloop/design-authority/issues/27 pour un exposé du problème, les réunions, remarques, et la décision le cas échéant. + +# Réunion DA (Ad-Hoc) - 25 juin 2020 +Discussion KNEX – initiée. +Les échanges ont débuté, mettant en avant la difficulté à générer/créer des scripts de migration lors de changements sur la base de données, ainsi que le scénario de devoir effectuer ces mises à jour sur une base en ligne. +Dans ce contexte, des ateliers de conception sont planifiés pour déterminer si KNEX permet de gérer ce scénario et s’il existe d’autres bibliothèques pouvant compléter ou remplacer l’implémentation actuelle, pour réduire cette difficulté. +Voyez le lien sur le tableau Design Authority ici : https://github.com/mojaloop/design-authority/issues/27 pour un exposé détaillé du problème, les réunions, remarques, et la décision finale. + + +# Réunion DA - 24 juin 2020 +La discussion a débuté sur la dépréciation du support Helm2 (Issue #52), où il a été convenu que la migration vers Helm3 devait se poursuivre. Une documentation pour faciliter l'utilisation des outils d’aide à cette migration doit être fournie. Retrouvez le lien vers ce document ici : https://github.com/mojaloop/design-authority/issues/52 + +Le sujet de l’approche conception visant à implémenter un système de règles générique a été abordé, d’abord en lien avec un besoin de pouvoir interroger les transactions terminées ou en cours (que ce soit lors du transfert ou même au stade du devis), afin d’appliquer des "frais d’interchange" selon le type de transaction et des règles associées. +Différentes décisions de conception autour de ce sujet seront discutées, la nécessité étant de pouvoir attacher des règles à différentes étapes du parcours de transaction. +L’implémentation actuelle d’un moteur de règles dans le projet TIPS a été évoquée, ainsi qu’une demande de démonstration des capacités de cette solution afin de voir si cela pourrait s’intégrer de façon générique dans le Switch principal. +Merci de suivre l’avancée de ce sujet sur le tableau : https://github.com/mojaloop/design-authority/issues/53 + + +# Réunion DA - 17 juin 2020 +Sujet en discussion : comprendre et définir les rôles Mojaloop pour les cas d’utilisation PISP, x-network, etc. +La DA encourage les groupes de travail à créer de nouvelles APIs et définitions de rôles (ex : Thirdparty API, CNP API, etc.) +Voir le sujet sur le tableau Design Authority : https://github.com/mojaloop/design-authority/issues/44 pour l’énoncé du problème et la décision prise. + +# Réunion DA - 10 juin 2020 +Cette semaine, la DA a discuté : le simulateur PISP : https://github.com/mojaloop/design-authority/issues/46 +La décision a été prise que pour l’instant le groupe de travail PISP continuera sur sa propre branche dans le sdk-scheme-adapter, et cette abstraction/partition sera revue ultérieurement (voir #51) + +# Réunion DA - 3 juin 2020 +Nous avons poursuivi la discussion de la semaine passée concernant l’API séparée pour PISP et décidé d’opter pour l’option 4 : séparation maximale des APIs, avec fichiers swagger/OpenAPI communs pour la définition et la réutilisation du modèle de données : +Voir le sujet sur le tableau Design Authority : https://github.com/mojaloop/design-authority/issues/47 pour l’énoncé du problème et la décision prise. + +# Réunion DA - 27 mai 2020 +Un consensus a été atteint parmi les participants sur le sujet discuté il y a quelque temps, tel que soulevé par Adrian. Il en ressort que le développement du Switch ne sera pas restrictif ni prescriptif mais, pour les recommandations concernant les nouvelles contributions et les nouveaux modules, il est préféré que ceux-ci soient réalisés en TypeScript. + +Un nouveau sujet a été proposé : https://github.com/mojaloop/design-authority/issues/47 pour répondre à la question de savoir s’il faut une API séparée pour PISP, ou simplement étendre l’OpenAPI existant. Une prise de position a été rédigée et ajoutée en commentaire. Tous les participants ont été informés sur la décision à prendre et ce sujet (#47) sera traité à la prochaine réunion DA. + +Un autre sujet, relatif à PISP, sera programmé lors d’une prochaine réunion DA : https://github.com/mojaloop/design-authority/issues/48 - Comment gérer les notifications pour qu’un PISP puisse être inscrit comme partie intéressée à la notification du succès d’un transfert + diff --git a/docs/fr/community/archive/notes/scrum-of-scrum-notes.md b/docs/fr/community/archive/notes/scrum-of-scrum-notes.md new file mode 100644 index 000000000..ea98a613a --- /dev/null +++ b/docs/fr/community/archive/notes/scrum-of-scrum-notes.md @@ -0,0 +1,154 @@ +# Notes de réunion des Scrum-of-scrum hebdomadaires + +## Réunion OSS Scrum du jeudi **7 mai** 2020 + +1. Coil - Don : + a. Performance : Problème de « Grand Écart » ; modifications sur cs-stream ; résultats modifiés ; préparation d’un document récapitulant les changements pour examen / révision technique ; travail de Joran sur le traitement concurrent des messages sur les topics Kafka → essais à venir ; observation d’un débit de 40-50% ; + b. Adaptateur LPS : Collaboration avec Renjith (Applied Payments) ; mise en place d’un labo / environnement pour les équipes partenaires ; exploration d’une collaboration avec le GSMA lab. +2. Crosslake - Lewis : + a. Performance : Rapport présenté à Confluent avec Nakul, fin de l’engagement ; diffusion des documents produits par Nakul ; + b. PISP : Discussions sur la conception en cours ainsi que l’implémentation ; + c. Versionnage : Définition du périmètre pour les déploiements ZDD ; + d. Problèmes liés au lancement officiel : problèmes DNS - gérés et résolus. +3. ModusBox - Sam : + a. Performance : Migration / standardisation des changements de performance de PI-9 vers la master (pas tous les PoC) ; travail sur les objectifs et la stratégie pour PI10 ; + b. Core-team : Transferts groupés - début d’accompagnement sur sdk-scheme-adapter ; + c. Maintenance (Corrections de bugs) : + i) Accents dans les noms - en cours ; + ii) Simulateur Mojaloop sur déploiements AWS - presque fini, travail sur les scripts de QA (sur ‘dev2’ - deuxième environnement) ; + d. Outil de test : Actuellement disponible pour tests - toutes les ressources de l’API ML FSPIOP sont supportées. Rapports générés. Ajout d’options en ligne de commande et meilleure portabilité en cours ; + e. CCB : Publication de la spécification v1.1 cette semaine - définition de l’API et Swagger correspondant (OpenAPI). +4. Virtual / Fondation Mojaloop - Megan : + a. Lancement de la Fondation Mojaloop ; + b. Paula H - Directrice exécutive de la Fondation Mojaloop. +5. Fondation Mojaloop - Simeon : + a. Demande de retours sur l’enquête communautaire ; + b. Hackathon envisagé dans le courant du début juin, en collaboration avec Google ; + c. Lancement la semaine prochaine de la Newsletter Mojaloop avec des articles intéressants comme la Spec v1.1 ML FSPIOP, la release Helm v10.1.0, etc. + +## Réunion OSS Scrum du jeudi **16 avril** 2020 + +1. Coil : + a. Don C : Performance - résultats préliminaires - quelques chiffres obtenus - résultats individuels sur les handlers, comparaison en cours, focus sur la base de données - un tiers du temps d’un parcours dédié à la perf ; + b. Don C : HSM : L’équipe de Renjith a présenté la démo pour la semaine prochaine - préparation de l’événement. +2. Crosslake : + a. Lewis D : PISP - Planification de sprint - itération sur les designs ; + b. Lewis D : Hackathons - Discussions de concepts avec Innocent K (HiPiPo) ; + c. Lewis D : Accès au GSMA lab – pour essais ; + d. Lewis D : Versionnage : préparation du deck pour PI10 ; + e. Kim W : Mise à jour globale du flux performance - atelier avec Confluent ; + f. Kim W : Mise à jour du flux performance - Pedro prépare une proposition et une présentation ; +3. Mifos : + a. Ed C : Préparation Démo pour les réunions PI10 ; +4. Virtual : + a. Megan : Préparation de l’événement PI10 & logistique ; +5. DA : + a. Nico : Discussion autour du problème PISP dont Michael sera le responsable ; +6. Core team : + a. Sam K : Performance : Préparation des métriques ; executions de tests pour établir base de référence après migration d’améliorations sur master ; + b. Sam K : Problème des accents dans les noms - implémentation en cours ; + f. Sam K : Implémentation de Settlements V2 par OSS-TIPS en cours - QA effectuée pour l’itération actuelle ; + g. Sam K : Outil de test : amélioration de la couverture des tests unitaires. Ajout d’assertions pour divers endpoints ; + i. Sam K : CCB : V1.1 de la définition de l’API ML FSPIOP - premier brouillon terminé, relectures en cours ; +7. Communauté Mojaloop : + a. Mise à jour communautaire par Simeon ; + +## Réunion OSS Scrum du jeudi **9 avril** 2020 + +1. Coil : + a. Don C : Tests de performance – sous-utilisation des ressources – optimisations à prévoir ; + b. Don C : Intégration HSM – préparation de la démo ; + c. Don C : Adaptateur Legacy – mise à jour docs – recherche de retours ; +2. Crosslake : + a. Kim W : Réunion FRMS ce matin – propositions faites ; + b. Kim W : Mise à jour sur les réunions PI10, inscriptions – réponses aux questions ; + c. Lewis D : PISP : planification avancée – travail sur les stories, items, discussions sur les designs Oauth, Fido ; + d. Lewis D : Performance : Discussion avec Pedro sur PoC pour changements d’architecture, Event Sourcing, CQRS, etc ; + e. Lewis D : Standards du code – mis à jour ; + f. Lewis D : Qualité & sécurité du code : Utilisation de HSM, démo, sécurité dans l’écosystème OSS ; + g. Lewis D : Scans de conteneurs fonctionnels – collaboration avec Victor, premiers benchmarks ; + h. Lewis D : Pour finir – mise à jour sur le versionnage ; +3. Mifos : + a. Ed C : Travail sur Payment Hub, intégration avec Kafka, transactions ML fonctionnelles, usage d’Elastic Search pour le monitoring des opérations back-office ; + b. Ed C : Préparation Démo pour PI10 ; +4. Core team : + a. Sam K : Performance : Rédaction de rapports, migration de métriques et autres améliorations sur master ; + b. Sam K : Performance : Finalisation de la dernière série de tests ; feuille de route Phase4 et lancement ; + c. Sam K : Support communauté : correction de bugs (plusieurs gros sujets réglés), clarification des décisions d’implémentation, etc. ; + d. Sam K : Support des paiements commerçants – tests et validation de l’usage « Request to Pay », standardisation en cours ; + e. Sam K : Problème des accents dans les noms – en cours ; + f. Sam K : Implémentation Settlements V2 par OSS-TIPS en cours ; + g. Sam K : Outil de test : Ajout d’assertions pour ressources API, JWS fait, mTLS en cours ; + h. Sam K : Outil de test : rédaction d’un guide d’utilisation et ajout de tests pour Golden Path ; + i. Sam K : CCB : V1.1 de l’API ML FSPIOP – premier brouillon prêt, attente de relecture ; + +## Réunion OSS Scrum du jeudi **2 avril** 2020 + +1. Mifos : + a. Ed C : L’équipe continue de développer Payment Hub EE, focus sur l’UI opérationnelle, capacités pour l’arrière-plan DFSP, cadre de gestion des erreurs ; +2. Coil : + a. Don C : Performance – installation terminée et démarrée – sur GCP – latence élevée, besoin de dépannage, possible recours à d’autres contributeurs pour aider ; + b. Don C : ATM – OTP – chiffrement ; +3. Crosslake : + a. Kim W : Agenda PI10 rédigé – envoi d’email prochainement ; + b. Kim W : Calendrier PI10 : mar-ven ; 11h-16h GMT – événement en ligne ; + c. Lewis D : Réunion performance plus tard aujourd’hui – approfondissement de l’architecture ; + d. Lewis D : Versionnage – En cours ; + e. Lewis D : Qualité & sécurité du code – architecture sécurité générale, HSM traité par Coil ; + f. Lewis D : Mojaloop dans un Vagrant box – en cours ; +4. Core team : + a. Miguel dB : Performance : finalisation du travail de perf – près de 900 TPS bout-en-bout ; actuellement, essai d’identifier/comprendre une unité cible pour ce niveau de performance ; + b. Sam K : Performance : finalisation de la dernière série de tests ; feuille de route Phase4, lancement ; + c. Sam K : Support communauté : corrections de bugs (certains points majeurs résolus), clarification de décisions d’implémentation, etc. ; + d. Sam K : Support paiement commerçant – standardisation en cours – corrections dans /authorizations ; + e. Sam K : Accents dans les noms – en cours ; + f. Sam K : Implémentation Settlements V2 par OSS-TIPS en cours ; + g. Sam K : Outil de test : Ajout d’assertions pour ressources API, JWS en cours ; + h. Sam K : CCB : V1.1 de l’API ML FSPIOP – rédaction en cours ; + +## Réunion OSS Scrum du jeudi **26 mars** 2020 + +1. DA : Nico – Sujet versionnage discuté par Lewis, Matt, Sam ; +2. Crosslake : + a. Kim W : Finalisation de l’agenda – lundi à vendredi ; + b. Kim W : Disponible pour ceux qui souhaitent présenter/intervenir ; + c. Kim W : Préparation de lectures préalables ; + d. Kim W : Atelier Fraude & LBC : Justus postera un résumé et les notes sur GitHub après l’atelier ; + e. Lewis D : Atelier performance / approfondissement probablement lundi ; + f. Lewis D : Discussions Design PISP en cours ; + g. Lewis D : Flux qualité et sécurité du code : i. Recommandations sécurité conteneurs Docker. ii. Portée GDPR pour Mojaloop ; +3. Mifos : + a. Ed C / Istvan M : Poursuite de la création du Lab ; + b. Ed C / Istvan M : Fineract, nouvelle instance de Payment Hub – bonne progression ; + c. Ed C / Istvan M : Travail sur la supervision opérationnelle du backend (débogage et supervision back-office, etc) ; +4. Simeon O – Community Manager présent ; +5. Core team : + a. Sam K : Performance : Phase-3 finalisée. Objectifs immédiats en cours d’atteinte – toujours en cours – feuille de route Phase4, lancement ; + b. Sam K : Support de la communauté : correction de bugs, clarification des décisions d’implémentation, etc. ; + d. Sam K : Support paiement commerçant – standardisation en cours – ajout de métriques, ajout du framework d’événements ; + e. Sam K : Problème accents dans les noms – discussion, conception de solution ; + f. Sam K : Mise en œuvre Settlements V2 par OSS-TIPS en cours ; + g. Sam K : Outil de test : Ajouts d’assertions pour les ressources API, JWS en cours. Rédaction du guide d’utilisation en cours ; + h. Sam K : CCB : Rédaction en cours de la V1.1 de la définition d’API ML FSPIOP ; + +## Réunion OSS Scrum du jeudi **19 mars** 2020 + +1. Coil : + a. Don C : Analyse de la performance, optimisations réseau (éviter les doubles vérifications, etc.) ; + b. Adrian hB : Renjith & Matt travaillent sur la traduction ISO20022 (vers JWEs, etc.) – démo prévue sur l’utilisation du HSM ; +2. Crosslake : + a. Kim W : Finalisation des actions issues du Mid-PI Workshop, items de suivi ; + b. Kim W : L’événement communautaire d’avril sera virtuel ; événement de planification à confirmer – suggestions bienvenues ; + c. Lewis D : Performance – inclusion de Don dans d’autres discussions ; + d. Lewis D : Qualité du code – proposition des exigences GDPR ; + e. Lewis D : Versionnage – premier brouillon fait en PR – sera présenté au DA la semaine prochaine ; +3. Mifos : + a. Ed C, Istvan M : Payment Hub, environnement sur Azure ; + b. Ed C, Istvan M : Les transactions passent désormais ; + c. Ed C, Istvan M : Prochaine phase : implémentation d’écrans back-office pour utilisateurs métier ; + d. Ed C, Istvan M : Atelier avec Google sur PISP ; +4. Core team : + a. Sam K : Performance – combiner prepare+position handler et fulfil+position handler, caractérisation en cours ; + b. Sam K : Performance – travail pour comprendre à quoi ressemble une unité d’infrastructure pour un déploiement Mojaloop ; + c. Sam K : Standardisation du service de requêtes transactionnelles : ajout du framework d’événements, ajout de métriques en cours ; + d. Sam K : Support communauté : correction de bugs, gestion des mises à jour, prise en charge des accents pour les noms, etc. ; diff --git a/docs/fr/community/assets/cla/admin_configure.png b/docs/fr/community/assets/cla/admin_configure.png new file mode 100644 index 000000000..1d8281bb4 Binary files /dev/null and b/docs/fr/community/assets/cla/admin_configure.png differ diff --git a/docs/fr/community/assets/cla/admin_sign_in.png b/docs/fr/community/assets/cla/admin_sign_in.png new file mode 100644 index 000000000..a960e2dcd Binary files /dev/null and b/docs/fr/community/assets/cla/admin_sign_in.png differ diff --git a/docs/fr/community/assets/cla/cla_1.png b/docs/fr/community/assets/cla/cla_1.png new file mode 100644 index 000000000..46718fc66 Binary files /dev/null and b/docs/fr/community/assets/cla/cla_1.png differ diff --git a/docs/fr/community/assets/cla/cla_2_1.png b/docs/fr/community/assets/cla/cla_2_1.png new file mode 100644 index 000000000..18ae1809c Binary files /dev/null and b/docs/fr/community/assets/cla/cla_2_1.png differ diff --git a/docs/fr/community/assets/cla/cla_2_2.png b/docs/fr/community/assets/cla/cla_2_2.png new file mode 100644 index 000000000..2e60fb762 Binary files /dev/null and b/docs/fr/community/assets/cla/cla_2_2.png differ diff --git a/docs/fr/community/assets/cla/cla_3.png b/docs/fr/community/assets/cla/cla_3.png new file mode 100644 index 000000000..5e2ddc46d Binary files /dev/null and b/docs/fr/community/assets/cla/cla_3.png differ diff --git a/docs/fr/community/contributing/assets/consequential-change-process.jpg b/docs/fr/community/contributing/assets/consequential-change-process.jpg new file mode 100644 index 000000000..dffd4091b Binary files /dev/null and b/docs/fr/community/contributing/assets/consequential-change-process.jpg differ diff --git a/docs/fr/community/contributing/assets/critical-change-process.jpg b/docs/fr/community/contributing/assets/critical-change-process.jpg new file mode 100644 index 000000000..6f4ec733d Binary files /dev/null and b/docs/fr/community/contributing/assets/critical-change-process.jpg differ diff --git a/docs/fr/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg b/docs/fr/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg new file mode 100644 index 000000000..9f21aefff Binary files /dev/null and b/docs/fr/community/contributing/assets/mojaloop-product-engineering-process-overview.jpg differ diff --git a/docs/fr/community/contributing/assets/mojaloop-product-feature-flow.jpg b/docs/fr/community/contributing/assets/mojaloop-product-feature-flow.jpg new file mode 100644 index 000000000..464be410d Binary files /dev/null and b/docs/fr/community/contributing/assets/mojaloop-product-feature-flow.jpg differ diff --git a/docs/fr/community/contributing/assets/mojaloop-workstream-sprint-process.jpg b/docs/fr/community/contributing/assets/mojaloop-workstream-sprint-process.jpg new file mode 100644 index 000000000..048b46dd7 Binary files /dev/null and b/docs/fr/community/contributing/assets/mojaloop-workstream-sprint-process.jpg differ diff --git a/docs/fr/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx b/docs/fr/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx new file mode 100644 index 000000000..6f4226afb Binary files /dev/null and b/docs/fr/community/contributing/assets/mojaloop-workstream-team-charter-template.pptx differ diff --git a/docs/fr/community/contributing/code-of-conduct.md b/docs/fr/community/contributing/code-of-conduct.md new file mode 100644 index 000000000..25b266bee --- /dev/null +++ b/docs/fr/community/contributing/code-of-conduct.md @@ -0,0 +1,94 @@ +# Code de conduite Mojaloop + + +## Vision et mission + +Mojaloop est un mot-valise formé du swahili « Moja » (« un ») et du mot anglais « loop ». La vision de Mojaloop est de réunir en un écosystème inclusif les prestataires financiers numériques et leurs clients. + +La mission du projet open source Mojaloop est d’accroître l’inclusion financière en donnant les moyens aux organisations qui créent des systèmes de paiement fiables et interopérables d’offrir des services financiers numériques à tous. Nous croyons qu’une économie qui inclut tout le monde profite à tous ; nous construisons un logiciel qui accélère une inclusion financière complète. Atteindre cette mission exige des avis et des contributions variés, de personnes aux expériences et aux origines culturelles diverses. + +## Fondations et valeurs de la communauté + +Notre objectif est une communauté forte et diverse qui accueille de nouvelles idées dans un domaine complexe et favorise la collaboration entre groupes et individus aux besoins, intérêts et compétences très différents. + +Nous construisons une communauté forte et diverse en cherchant activement la participation de ceux qui lui apportent de la valeur. + +Nous nous traitons avec ouverture et respect, nous évaluons les contributions avec impartialité et équité, et nous visons un projet qui inclut chacun, quel que soient l’âge, la corpulence, le handicap, l’origine ethnique, l’identité et l’expression de genre, le niveau d’expérience, la formation, la situation socio-économique, la nationalité, l’apparence personnelle, la race, la religion ou l’orientation. + +*Ce code de conduite existe pour que des groupes divers collaborent dans leur intérêt mutuel et avec plaisir.* + +Le code de conduite régit notre comportement en public comme en privé, virtuellement ou en personne. Nous attendons qu’il soit respecté par toute personne qui représente le projet officiellement ou non, revendique une affiliation au projet ou y participe directement. + +### Nous nous efforçons de : + +- **Être attentifs**\ + Notre travail sera utilisé par d’autres, et nous dépendrons du travail d’autrui. Chaque décision que nous prenons affecte toutes les personnes impliquées dans notre écosystème ; nous tenons compte de tous les aspects pertinents au moment de décider. + +- **Être respectueux**\ + Nous résolvons les conflits ensemble, présupposons de bonnes intentions et agissons avec empathie. Nous croyons qu’une communauté où les personnes se respectent et se sentent à l’aise est une communauté productive. + +- **Être responsables**\ + Nous sommes responsables de nos paroles et de nos actes. Nous pouvons tous nous tromper ; lorsque c’est le cas, nous en assumons la responsabilité. Si quelqu’un est lésé ou offensé, nous écoutons avec soin et respect et cherchons à réparer. + +- **Être collaboratifs**\ + Ce que nous produisons est un tout complexe fait de parties nombreuses. La collaboration entre équipes ayant chacune leurs objectifs est essentielle ; pour que le tout dépasse la somme des parties, chaque partie doit chercher à comprendre le tout.\ + La collaboration réduit la redondance et améliore la qualité. En interne comme en externe, nous célébrons la bonne collaboration. Nous travaillons autant que possible avec les projets amont et la communauté open source pour coordonner nos efforts. Nous préférons la transparence et impliquer les parties prenantes le plus tôt possible. + +- **Valoriser la décision, la clarté et le consensus**\ + Les désaccords, sociaux et techniques, sont normaux, mais nous ne les laissons pas pourrir ni laisser d’autres dans l’incertitude sur la direction retenue.\ + Nous attendons des membres qu’ils résolvent les désaccords de façon constructive. Face à des obstacles, nous faisons remonter la question vers des instances avec des responsables désignés pour arbitrer, clarifier et donner une orientation. + +- **Demander de l’aide en cas de doute**\ + Personne n’est censé être parfait. Poser des questions tôt évite bien des problèmes ; les questions sont encouragées, même si elles doivent être orientées vers le bon forum. Ceux qui sont sollicités doivent répondre et aider. + +- **Se retirer avec égards**\ + Lorsque quelqu’un quitte ou se désengage du projet, nous lui demandons de le faire en minimisant la perturbation : prévenir, et permettre à d’autres de reprendre le travail. + +- **Méritocratie ouverte**\ + Nous invitons toute personne, de toute organisation, à participer à tout aspect du projet. La communauté est ouverte ; toute responsabilité peut être assumée par un contributeur qui démontre la capacité et la compétence requises. + +- **Valoriser la diversité et l’inclusion**\ + Cette communauté veut changer concrètement la vie des gens dans le monde, notamment dans les sociétés et économies en développement. Nous valorisons nos membres d’abord pour ce qu’ils sont, ensuite pour l’aide qu’ils apportent à transformer le monde. Chacun s’efforcera de ne laisser aucune autre considération peser sur lui, consciemment ou inconsciemment. + +- **Être transparents**\ + Les membres peuvent avoir des intérêts personnels et professionnels dans le développement du logiciel Mojaloop open source, influençant les vues sur l’orientation de la communauté. Chacun doit autant que raisonnablement possible être transparent sur ces intérêts dans les limites de la confidentialité. Les membres qui occupent des rôles de gouvernance, permanents ou temporaires, ne doivent pas utiliser ces rôles pour servir des intérêts personnels ou professionnels ; leur influence doit être guidée par l’intérêt supérieur du succès de la communauté. + +Ce code de conduite n’est ni exhaustif ni figé. Ce n’est pas un recueil de règles toutes faites ; il exprime notre compréhension commune d’un environnement collaboratif et d’objectifs partagés. Nous attendons qu’on le suive dans l’esprit autant que dans la lettre. + +### Nos normes + +Exemples de comportements qui contribuent à un environnement positif : + +- Utiliser un langage accueillant et inclusif + +- Respecter les points de vue et expériences différents + +- Accepter avec grâce les critiques constructives + +- Se concentrer sur l’intérêt de la communauté + +- Faire preuve d’empathie envers les autres membres + +Exemples de comportements inacceptables : + +- Langage ou imagerie à connotation sexuelle, attentions ou avances sexuelles non désirées + +- Trolling, commentaires insultants ou dégradants, et attaques personnelles ou politiques + +- Harcèlement public ou privé + +- Publier des informations privées d’autrui (adresse physique ou électronique, etc.) sans permission explicite + +- Tout autre comportement raisonnablement inapproprié dans un cadre professionnel + +### Signalement et résolution + +Si vous constatez une violation du code de conduite, vous êtes encouragé à aborder le comportement directement avec les personnes concernées. Beaucoup de situations se règlent ainsi rapidement et facilement, et cela donne aux personnes davantage de maîtrise sur l’issue de leur différend. Si vous ne pouvez pas résoudre le problème ou si le comportement est menaçant ou harcelant, signalez-le. Nous nous engageons à offrir un environnement où les participants se sentent bienvenus et en sécurité. + +Les signalements doivent être adressés au comité de direction communautaire par e-mail à . Ce message est reçu par le responsable communauté de la Fondation Mojaloop, chargé de traiter les violations du code de conduite. Il travaille ensuite avec le comité pour traiter et résoudre le signalement. + +Nous examinons chaque plainte, mais vous pouvez ne pas recevoir de réponse directe. Que nous vous répondions directement ou non, vous pourrez toujours vous enquérir de l’état d’une plainte en contactant un membre du comité de direction communautaire. Nous décidons avec discernement du suivi, de l’inaction à l’exclusion définitive de la communauté et des espaces parrainés par la fondation. Nous informons la personne concernée du signalement et lui donnons l’occasion d’en discuter avant toute mesure. L’identité du plaignant est omise dans les détails communiqués à la personne visée. En cas de danger (harcèlement en cours, menaces pour la sécurité), nous pouvons agir sans préavis. + +### Attribution + +Ce code de conduite est adapté du Code de conduite Ubuntu v2.0, disponible sur diff --git a/docs/fr/community/contributing/consequential-change-process.md b/docs/fr/community/contributing/consequential-change-process.md new file mode 100644 index 000000000..263fa126b --- /dev/null +++ b/docs/fr/community/contributing/consequential-change-process.md @@ -0,0 +1,47 @@ +# Processus des changements conséquents + +Pour les changements couverts par la [définition de changement conséquent](./design-review.md#consequential-changes), suivez ce processus : + +1. Proposer un changement produit au Product Council Mojaloop : + 1. Créez une « Product Change Proposal » dans le dépôt GitHub `product-council` + [ici](https://github.com/mojaloop/product-council-project/issues). + 1. Remplissez le modèle aussi complètement et rigoureusement que possible afin de garantir un traitement rapide. + 2. Envoyez un message sur le canal Slack [#product-council](https://mojaloop.slack.com/archives/C01FF8AQUAK) pour demander une revue de votre proposition. + 3. Le Product Council discutera avec vous afin de comprendre où votre proposition s'inscrit dans la feuille de route produit Mojaloop. +2. Proposer les changements de code à la Design Authority Mojaloop : + 1. Créez un ticket « Consequential Change Proposal » dans le dépôt `design-authority-project` + [ici](https://github.com/mojaloop/design-authority-project/issues). + 1. Remplissez le modèle aussi complètement et rigoureusement que possible afin de garantir un traitement rapide. + 2. Envoyez un message sur [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q) pour demander une revue. + 3. La design authority assignera un ou plusieurs membres pour travailler avec vous. +3. Participer à une revue de conception : + 1. Les membres assignés vous guident dans un processus itératif de revue de conception. + 2. À l’issue, vous pouvez poursuivre le changement. +4. Implémenter et faire revue du code : + 1. Créez et traitez les tickets GitHub/Zenhub dans votre + [processus de workstream](./product-engineering-process.md#mojaloop-workstreams) ; référencez les tickets Product Council et Consequential Change pour la traçabilité. + 2. Lorsque vous ouvrez des pull requests, contactez les membres assignés de la Design Authority et demandez-leur de lancer la phase de revue de code. + 3. Soyez prêt à répondre aux questions et à effectuer des ajustements au cours de cette étape. + 4. Une fois les PR approuvées par les membres assignés, la fonctionnalité est prête à être intégrée dans le processus de release officiel Mojaloop. + 5. Tout changement apporté à la conception pendant l’implémentation doit être consigné sur le ticket de proposition. + +![Processus des changements conséquents](./assets/consequential-change-process.jpg) + +## À quoi s’attendre pendant la revue de conception + +_La Design Authority Mojaloop a la responsabilité de s’assurer que les risques sont identifiés et atténués de manière appropriée, et que nos normes établies en matière d’outils, de motifs et de pratiques sont respectées. Les membres assignés sont là pour vous aider à obtenir le meilleur résultat possible pour vous-même et pour l’ensemble de la communauté Mojaloop._ + +Ils vous aident à identifier et réduire les risques et à aligner la conception sur les pratiques établies. + +1. Il vous sera demandé d’exposer les raisons de votre changement proposé, d’expliquer ce que vous souhaitez atteindre et comment vous entendez y parvenir. + 1. Vous devez pouvoir vous référer à un ticket GitHub du Product Council montrant que le travail a été discuté et que le changement est accepté. Notez que le Product Council a la responsabilité de maintenir une feuille de route cohérente pour notre technologie et vous guidera sur la façon la plus appropriée d’atteindre vos objectifs métier dans le contexte Mojaloop. Le Product Council peut consulter la Design Authority dans le cadre de ce processus. + 2. Vous expliquerez l’implémentation, les composants impactés, les évolutions et les nouveaux composants. Présentez au minimum : + 1. Des diagrammes de séquence UML illustrant chaque composant significatif impliqué dans vos cas d’usage et leurs interactions pour atteindre les résultats souhaités. Veillez à inclure les cas d’erreur ainsi que les comportements nominaux attendus. + 2. Le détail des composants tiers utilisés. + 3. Le détail des changements sur les composants existants (comportement actuel vs souhaité). + 3. Les membres poseront probablement de nombreuses questions pour comprendre la proposition et son contexte. +2. Ils vous aideront à identifier d’autres contributeurs, équipes ou parties prenantes à impliquer pour éviter des effets de bord en amont ou en aval et tenir compte d’évolutions ailleurs dans le système. + Mojaloop est un système de grande envergure et il est souvent utile de faire appel à des experts d’autres domaines pour apporter leur assistance. +3. L’objectif principal de votre ou vos membres assignés de la Design Authority est d’identifier et d’atténuer les risques que vous n’avez peut-être pas repérés. + 1. Ils peuvent suggérer des atténuations ou des modifications pour respecter les contraintes Mojaloop. + diff --git a/docs/fr/community/contributing/contributors-guide.md b/docs/fr/community/contributing/contributors-guide.md new file mode 100644 index 000000000..b41f8f5d8 --- /dev/null +++ b/docs/fr/community/contributing/contributors-guide.md @@ -0,0 +1,75 @@ +# Guide des contributeurs + +Nous sommes heureux que vous envisagiez de rejoindre la communauté Mojaloop. + +_Note : si vous utilisez ou envisagez d’utiliser des outils d’intelligence artificielle (IA) dans le cadre de votre contribution à Mojaloop, assurez-vous d’avoir entièrement lu et de respecter notre [politique d’usage responsable de l’IA](../standards/ai_policy.md)._ + +Compte tenu de la phase actuelle du projet Mojaloop, nous recherchons notamment les types de contributeurs suivants : + +## Types de contributeurs + +- #### Contributeurs individuels + +Ces personnes souhaitent commencer à contribuer à la communauté Mojaloop. Il peut s’agir d’un développeur ou d’un responsable assurance qualité souhaitant écrire du nouveau code ou corriger un bug. Il peut également s’agir d’un spécialiste métier, conformité ou risques souhaitant contribuer à l’élaboration de règles, à la rédaction de documentation ou au recueil d’exigences. + +- #### Opérateurs de hub + +En général des organisations, des individus ou des agences gouvernementales qui souhaitent déployer leur propre switch Mojaloop au sein de l’écosystème. + +- #### Équipes d’implémentation + +Équipes pouvant aider banques, administrations, opérateurs mobiles ou caisses de crédit à déployer Mojaloop. + +## Comment contribuer ? + +* Lisez et familiarisez-vous avec nos [processus d’ingénierie produit](./product-engineering-process.md) + ainsi qu'avec les [pratiques de revue de conception et de code Mojaloop](./design-review.md). +* Consultez le [guide de déploiement Mojaloop](https://docs.mojaloop.io/documentation/deployment-guide/) et + le [guide d’intégration](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md). +* Parcourez la [vue d’ensemble des dépôts](https://docs.mojaloop.io/documentation/repositories/) pour comprendre comment le + code Mojaloop est géré sur plusieurs dépôts GitHub. +* Prenez connaissance de nos [normes](../standards/guide.md) pour contribuer à ce projet. +* Parcourez la [liste de contrôle du nouveau contributeur (New Contributor Checklist)](./new-contributor-checklist.md), explorez le tableau de projet et + travaillez sur une [bonne première tâche (issue)](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). +* Consultez la [feuille de route](../mojaloop-roadmap.md) et participez aux opportunités à venir. +* Lisez le [code de conduite](./code-of-conduct.md) de la communauté. + +## De quel travail a-t-on besoin ? + +Mojaloop suit un [processus d’ingénierie produit](./product-engineering-process.md) structuré et maintient activement une +[feuille de route](../mojaloop-roadmap.md) de développement de nouvelles fonctionnalités et de travaux de maintenance. Les fils de travail officiels en cours sont décrits sur la +[page centrale des workstreams communautaires](https://community.mojaloop.io/pi-24-workstreams). + +Chaque fil de travail maintient un backlog dans GitHub et un espace ZenHub ; contactez le responsable du workstream ou publiez un message sur le canal Slack du workstream pour vous présenter et trouver un bon ticket sur lequel commencer à travailler. + +Vous trouverez les coordonnées des responsables et les canaux Slack sur la +[page centrale des workstreams](https://community.mojaloop.io/pi-24-workstreams). + +## Où obtenir de l’aide ? + +Rejoignez les [discussions Slack Mojaloop](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw) pour entrer en contact et échanger avec d’autres développeurs. + +Voir aussi la [FAQ](https://github.com/mojaloop/documentation/blob/master/contributors-guide/frequently-asked-questions.md). + +## Quelle est la release en cours ? + +Consultez le [canal Annonces Slack Mojaloop](https://mojaloop.slack.com/messages/CG3MAJZ5J) pour obtenir des informations sur la dernière version publiée (release). + +## Qu’est-ce qui est fourni ou non ? + +C’est du code libre sous [licence Apache 2.0](https://github.com/mojaloop/mojaloop/blob/master/LICENSE.md). + +Le code est publié en Apache 2.0 ; les documents de spécification du dépôt « mojaloop-specification » sont publiés sous licence CC BY-ND 4.0. + +Nous ne fournissons pas de serveurs de production : c’est à vous. Vous êtes libre (et encouragé !) de cloner ces dépôts, de participer à la communauté de développeurs et de contribuer en retour au code. + +Nous ne cherchons pas à remplacer les portefeuilles mobiles ou les fournisseurs de services financiers. Nous fournissons une plateforme pour relier les nouveaux et anciens fournisseurs de services financiers via un schéma commun. Il existe des services centraux (identification du fournisseur du client, devis, exécution, règlement net différé, lutte contre la fraude partagée). Chaque fournisseur peut les utiliser pour envoyer et recevoir de l’argent sur le système, sans frais d’intégration des nouveaux fournisseurs. Nous fournissons du code d’exemple pour un fournisseur d’argent mobile simple pour illustrer l’intégration ; cet exemple de DFSP n’est pas destiné à être un fournisseur d’argent mobile en production. + +## Où signaler bugs, questions et retours ? + +Pour les bugs : [Reporting bugs](https://github.com/mojaloop/mojaloop/blob/master/contribute/Reporting-Bugs.md). + +## Politique relative à l’usage d’outils d’intelligence artificielle (IA) par les membres de la communauté + +Si vous utilisez ou envisagez d’utiliser des outils d’intelligence artificielle (IA) dans le cadre de votre contribution à Mojaloop, +assurez-vous d’avoir entièrement lu et de respecter notre [politique d’usage responsable de l’IA](../standards/ai_policy.md). diff --git a/docs/fr/community/contributing/critical-change-process.md b/docs/fr/community/contributing/critical-change-process.md new file mode 100644 index 000000000..e239c2be1 --- /dev/null +++ b/docs/fr/community/contributing/critical-change-process.md @@ -0,0 +1,51 @@ +# Processus des changements critiques + +_**Pour Mojaloop, le « processus des changements critiques » est proche du processus des changements conséquents, mais avec une supervision supplémentaire et une exigence de validation formelle, compte tenu de la nature hautement risquée de ces changements dans notre environnement d’exploitation.**_ + +Pour les changements couverts par la [définition de changement critique](./design-review.md#critical-changes), suivez ce processus : + +1. Proposer un changement produit au Product Council Mojaloop : + 1. Créez une « Product Change Proposal » dans le dépôt GitHub `product-council` + [ici](https://github.com/mojaloop/product-council-project/issues). + 1. Remplissez le modèle aussi complètement et rigoureusement que possible afin de garantir un traitement rapide. + 2. Envoyez un message sur le canal Slack [#product-council](https://mojaloop.slack.com/archives/C01FF8AQUAK) pour demander une revue de votre proposition. + 3. Le Product Council discutera avec vous afin de comprendre où votre proposition s'inscrit dans la feuille de route produit Mojaloop. +2. Proposer les changements de code à la Design Authority Mojaloop : + 1. Créez un ticket « Critical Change Proposal » dans le dépôt `design-authority-project` + [ici](https://github.com/mojaloop/design-authority-project/issues). + 1. Remplissez le modèle aussi complètement et rigoureusement que possible afin de garantir un traitement rapide. + 2. Envoyez un message sur [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q) pour demander une revue. + 3. La design authority assignera au moins deux membres pour travailler avec vous. +3. Participer à une revue de conception : + 1. Les membres assignés vous guident dans un processus itératif de revue de conception. + 2. À l’issue du processus de revue de conception, les membres assignés procèdent à la validation formelle (sign-off) de votre conception, ce qui autorise le démarrage de l’implémentation. + 3. Après cette validation formelle, vous pouvez poursuivre le changement. +4. Implémenter et faire revue du code : + 1. Créez et traitez les tickets GitHub/Zenhub dans votre + [processus de workstream](./product-engineering-process.md#mojaloop-workstreams) ; référencez les tickets Product Council et Critical Change pour la traçabilité. + 2. Lorsque vous ouvrez des pull requests, contactez les membres assignés de la Design Authority et demandez-leur de lancer la phase de revue de code. + 3. Soyez prêt à répondre aux questions et à effectuer des ajustements au cours de cette étape. + 4. Une fois les PR approuvées par les membres assignés, la fonctionnalité est prête à être intégrée dans le processus de release officiel Mojaloop. + 5. Les membres assignés enregistrent formellement leur revue d'approbation de votre ou vos pull requests. + 6. Tout changement apporté à la conception pendant l’implémentation doit être consigné sur le ticket de proposition. + +![Processus des changements critiques](./assets/critical-change-process.jpg) + +## À quoi s’attendre pendant la revue de conception + +_La Design Authority Mojaloop a la responsabilité de s’assurer que les risques sont identifiés et atténués de manière appropriée, et que nos normes établies en matière d’outils, de motifs et de pratiques sont respectées. Les membres assignés sont là pour vous aider à obtenir le meilleur résultat possible pour vous-même et pour l’ensemble de la communauté Mojaloop._ + +Ils vous aident à identifier et réduire les risques et à aligner la conception sur les pratiques établies. + +1. Il vous sera demandé d’exposer les raisons de votre changement proposé, d’expliquer ce que vous souhaitez atteindre et comment vous entendez y parvenir. + 1. Vous devez pouvoir vous référer à un ticket GitHub du Product Council montrant que le travail a été discuté et que le changement est accepté. Notez que le Product Council a la responsabilité de maintenir une feuille de route cohérente pour notre technologie et vous guidera sur la façon la plus appropriée d’atteindre vos objectifs métier dans le contexte Mojaloop. Le Product Council peut consulter la Design Authority dans le cadre de ce processus. + 2. Vous expliquerez l’implémentation, les composants impactés, les évolutions et les nouveaux composants. Présentez au minimum : + 1. Des diagrammes de séquence UML illustrant chaque composant significatif impliqué dans vos cas d’usage et leurs interactions pour atteindre les résultats souhaités. Veillez à inclure les cas d’erreur ainsi que les comportements nominaux attendus. + 2. Le détail des composants tiers utilisés. + 3. Le détail des changements sur les composants existants (comportement actuel vs souhaité). + 3. Les membres poseront probablement de nombreuses questions pour comprendre la proposition et son contexte. +2. Ils vous aideront à identifier d’autres contributeurs, équipes ou parties prenantes à impliquer pour éviter des effets de bord en amont ou en aval et tenir compte d’évolutions ailleurs dans le système. + Mojaloop est un système de grande envergure et il est souvent utile de faire appel à des experts d’autres domaines pour apporter leur assistance. +3. L’objectif principal de votre ou vos membres assignés de la Design Authority est d’identifier et d’atténuer les risques que vous n’avez peut-être pas repérés. + 1. Ils peuvent suggérer des atténuations ou des modifications pour respecter les contraintes Mojaloop. + diff --git a/docs/fr/community/contributing/cvd.md b/docs/fr/community/contributing/cvd.md new file mode 100644 index 000000000..b5b324abb --- /dev/null +++ b/docs/fr/community/contributing/cvd.md @@ -0,0 +1,205 @@ +# Divulgation et réception d’informations sur les vulnérabilités de sécurité + +La Fondation Mojaloop et la communauté prennent très au sérieux la sécurité du logiciel Mojaloop et mettent en œuvre plusieurs processus pour en faire une plateforme sûre pour les activités économiques. Voir aussi notre [documentation sur l’architecture de cybersécurité](../tools/cybersecurity.md). + +La Fondation Mojaloop applique un processus de [« divulgation coordonnée des vulnérabilités »](https://github.com/ossf/oss-vulnerability-guide/blob/main/finder-guide.md#what-is-coordinated-vulnerability-disclosure) : une vulnérabilité ou un problème n’est rendu public qu’après que les parties responsables et concernées ont eu le temps de corriger ou de remédier au problème. En appliquant ce modèle, la Fondation Mojaloop et la communauté visent à minimiser l’impact potentiel de ces problèmes sur nos adoptants. + +## Politique de divulgation coordonnée des vulnérabilités de la Fondation Mojaloop + +Les sections suivantes définissent les exigences et attentes des différentes parties impliquées dans la découverte et la remédiation des vulnérabilités de sécurité du logiciel Mojaloop. Tous les membres de la communauté Mojaloop sont tenus de respecter cette politique, quel que soit le rôle joué dans un scénario donné. Participer à la communauté Mojaloop implique l’acceptation et le respect de ces politiques. + +### Terminologie + +Les définitions suivantes s’appliquent au sein de cette politique : + +#### Termes issus de la RFC 2119 + +Les termes « MUST », « MUST NOT », « REQUIRED », « SHALL », « SHALL NOT », « SHOULD », « SHOULD NOT », « RECOMMENDED », « MAY » et « OPTIONAL » dans ce document doivent être interprétés comme décrit dans la RFC 2119. + +#### Termes issus de l’ISO, du CERT + +Les termes « Researcher » ou « Reporter » visent à être cohérents avec « Finder » et/ou « Reporter » tels qu’utilisés dans l’ISO/IEC 29147:2014(E) et le CERT® Guide to Coordinated Vulnerability Disclosure. + +### Politique à l’égard des rapporteurs + +Les rapporteurs DOIVENT respecter les lignes directrices suivantes. + +#### Général + +* Les rapporteurs DOIVENT respecter toutes les lois locales et internationales applicables aux activités de recherche en sécurité ou à toute autre participation à ce programme de divulgation des vulnérabilités. + +* Les rapporteurs DEVRAIENT de bonne foi notifier et travailler directement avec le ou les fournisseurs ou prestataires concernés avant toute divulgation publique de rapports de vulnérabilité. + +#### Périmètre des tests autorisés + +* Les rapporteurs PEUVENT tester le logiciel open source Mojaloop pour détecter une vulnérabilité dans le seul but de fournir à la Fondation Mojaloop des informations sur cette vulnérabilité. + +* Les rapporteurs DEVRAIENT ne tester qu’avec des comptes de test appartenant au rapporteur ou avec l’autorisation explicite du titulaire du compte. + +* Les rapporteurs DOIVENT éviter de nuire aux systèmes d’information et aux opérations de la Fondation Mojaloop, de ses partenaires et des utilisateurs du logiciel open source Mojaloop. + +* Les rapporteurs DOIVENT s’efforcer d’éviter les atteintes à la vie privée, la dégradation de l’expérience utilisateur, les perturbations des systèmes de production, ainsi que la destruction ou la manipulation de données. + +* Les rapporteurs DOIVENT cesser les tests dès qu’ils ont établi l’existence d’une vulnérabilité ou rencontré des données sensibles. Les données sensibles incluent les informations personnellement identifiables, les informations financières (ex. numéros de compte), les informations propriétaires ou secrets d’affaires. + +* Les rapporteurs NE DOIVENT PAS tester de logiciels ou services non expressément contenus dans les dépôts GitHub du logiciel open source Mojaloop, y compris les services connectés. + +* Les rapporteurs NE DOIVENT PAS exploiter une vulnérabilité au-delà du minimum de tests nécessaire pour prouver son existence ou identifier un indicateur lié à cette vulnérabilité. + +* Les rapporteurs NE DOIVENT PAS accéder intentionnellement au contenu de communications, données ou informations en transit ou stockées sur les systèmes appartenant à la Fondation Mojaloop, à ses partenaires ou aux utilisateurs du logiciel open source Mojaloop — sauf dans la mesure où l’information est directement liée à une vulnérabilité et que l’accès est nécessaire pour prouver son existence. + +* Les rapporteurs NE DOIVENT en aucun cas exfiltrer de données. + +* Les rapporteurs NE DOIVENT PAS compromettre intentionnellement la vie privée ou la sécurité du personnel de la Fondation Mojaloop, des clients, du grand public, des utilisateurs du logiciel open source Mojaloop ou de tiers légitimes. + +* Les rapporteurs NE DOIVENT PAS utiliser d’exploit pour compromettre, altérer ou exfiltrer des données. + +* Les rapporteurs NE DEVRAIENT PAS établir d’accès en ligne de commande ni de persistance. + +* Les rapporteurs NE DOIVENT PAS exploiter des vulnérabilités pour pivoter vers d’autres systèmes. + +* Les rapporteurs NE DOIVENT PAS compromettre intentionnellement la propriété intellectuelle ou d’autres intérêts commerciaux ou financiers du personnel ou entités de la Fondation Mojaloop, des clients, du grand public, des utilisateurs du logiciel open source Mojaloop ou de tiers légitimes. + +* Les rapporteurs NE DOIVENT PAS provoquer de déni de service légitime dans le cadre de leurs tests. + +* Les rapporteurs NE DOIVENT PAS effectuer de tests d’accès physique (ex. accès aux bureaux, ouvrir des portes, suivre quelqu’un sans autorisation, intrusion). + +* Les rapporteurs NE DOIVENT PAS mener d’ingénierie sociale à l’encontre du personnel de la Fondation Mojaloop, de ses sous-traitants, associés ou utilisateurs du logiciel open source Mojaloop, ni de leur personnel, sous-traitants ou clients. + +* Les rapporteurs DEVRAIENT contacter la Fondation Mojaloop par e-mail à [security@mojaloop.io](mailto:security@mojaloop.io) s’ils ont un doute sur la poursuite des tests. + +#### Coordination avec la Fondation Mojaloop + +* Les rapporteurs DEVRAIENT transmettre les rapports de vulnérabilité à la Fondation Mojaloop par e-mail sécurisé (chiffré) à [security@mojaloop.io](mailto:security@mojaloop.io). + +* Les rapporteurs DEVRAIENT fournir des rapports de haute qualité. + +* Les rapporteurs DEVRAIENT inclure suffisamment de détails pour permettre à la Fondation Mojaloop et/ou aux fournisseurs concernés de reproduire fidèlement le comportement vulnérable. + +* Les rapporteurs NE DEVRAIENT PAS signaler des vidages mémoire non analysés ou des sorties de fuzzer sans explication suffisante montrant qu’il s’agit d’une vulnérabilité de sécurité. + +* Les rapporteurs DEVRAIENT signaler d’autres vulnérabilités trouvées incidentellement pendant des tests dans le périmètre, même si elles seraient sinon hors périmètre (ex. exposition de données d’un système hors périmètre lors d’un test sur un système couvert). + +* Les rapporteurs DOIVENT garder confidentielles les informations sur les vulnérabilités découvertes pendant 90 jours après notification à la Fondation Mojaloop. Cela n’empêche pas une coordination simultanée avec d’autres parties affectées (fournisseurs, prestataires, coordinateurs, etc.). + +* Les rapporteurs PEUVENT joindre une preuve de concept si disponible. + +* Les rapporteurs PEUVENT demander que leurs coordonnées ne soient pas transmises à tous les fournisseurs affectés. + +* Les rapporteurs PEUVENT demander à ne pas être nommé dans les remerciements des divulgations publiques de la Fondation Mojaloop. + +* Les rapporteurs NE DOIVENT PAS soumettre un grand volume de rapports de faible qualité. + +* Les rapporteurs NE DOIVENT PAS exiger que la Fondation Mojaloop entre dans une relation client, signe un NDA ou toute autre obligation contractuelle ou financière comme condition pour recevoir ou coordonner des rapports de vulnérabilité. + +* Les rapporteurs NE DOIVENT PAS exiger une compensation en échange d’informations sur des vulnérabilités signalées en dehors d’un programme de bug bounty explicite. + +#### Coordination avec les fournisseurs + +* Si le rapporteur trouve une vulnérabilité dans le logiciel open source de la Fondation Mojaloop consécutive à une vulnérabilité dans un produit ou service grand public, il PEUT signaler la vulnérabilité au ou aux fournisseurs, prestataires ou services tiers de coordination pour permettre une correction. + +#### Coordination avec d’autres acteurs + +* Les rapporteurs PEUVENT faire appel à un service tiers de coordination (ex. CERT/CC, DHS CISA) pour résoudre des conflits entre le rapporteur et la Fondation Mojaloop. + +* Les rapporteurs NE DEVRAIENT PAS divulguer de détails sur une vulnérabilité existante du logiciel open source de la Fondation Mojaloop, ni d’indicateurs de vulnérabilité, à une partie qui n’en était pas déjà informée au moment du signalement à la Fondation Mojaloop. + +#### Divulgation publique + +* Les rapporteurs PEUVENT divulguer au public l’existence antérieure de vulnérabilités déjà corrigées par la Fondation Mojaloop, y compris des détails potentiels sur la vulnérabilité, des indicateurs, ou la nature (mais pas le contenu) des informations rendues accessibles. + +* Les rapporteurs qui choisissent une divulgation publique DEVRAIENT le faire en consultation avec la Fondation Mojaloop. + +* Les rapporteurs NE DOIVENT PAS divulguer de données propriétaires accessoires révélées pendant les tests, ni le contenu d’informations rendues accessibles par la vulnérabilité, à une partie qui n’en était pas déjà informée au moment du signalement à la Fondation Mojaloop. + +### Politique à l’égard des destinataires (Fondation Mojaloop) + +La Fondation Mojaloop traitera de bonne foi les rapporteurs qui découvrent, testent et signalent des vulnérabilités conformément à ces lignes directrices. + +#### Général + +* La Fondation Mojaloop PEUT modifier les termes de cette politique ou y mettre fin à tout moment. + +* La Fondation Mojaloop utilisera les informations signalées à des fins défensives uniquement : atténuer ou remédier aux vulnérabilités du logiciel open source Mojaloop, des réseaux et applications de la Fondation, des applications des fournisseurs et des utilisateurs du logiciel open source Mojaloop. + +#### Traitement des cas + +* La Fondation Mojaloop PEUT, à sa discrétion, refuser de coordonner ou de publier un rapport de vulnérabilité. Cette décision est généralement fondée sur le périmètre et la gravité de la vulnérabilité ainsi que sur la capacité de la Fondation à apporter une valeur ajoutée au processus de coordination et de divulgation. + +* Si la Fondation Mojaloop refuse de coordonner, le rapporteur PEUT coordonner avec d’autres fournisseurs affectés et PEUT procéder à une divulgation publique à sa discrétion. + +* La Fondation Mojaloop examinera chaque vulnérabilité signalée et s’efforcera de prendre les mesures appropriées pour atténuer les risques et corriger les vulnérabilités. + +* La Fondation Mojaloop s’efforcera, dans la mesure du possible, de valider l’existence de la vulnérabilité. + +* La Fondation Mojaloop déterminera un délai approprié pour le développement et le déploiement des correctifs pour les vulnérabilités sur les systèmes qu’elle contrôle. + +#### Coordination avec les rapporteurs + +* La Fondation Mojaloop accusera réception des rapports par e-mail dans un délai de 7 jours ouvrés. + +* La Fondation Mojaloop PEUT contacter le rapporteur pour des informations complémentaires. + +* La Fondation Mojaloop informera le rapporteur des résultats de sa validation, le cas échéant, et lui fournira des mises à jour régulières tout au long de la remédiation de la vulnérabilité. + +* La Fondation Mojaloop créditera le rapporteur dans toute publication sauf demande contraire. + +* En cas de divulgation publique, la Fondation Mojaloop reconnaîtra votre contribution si vous êtes le premier à signaler une vulnérabilité unique et que le rapport entraîne un changement de code ou de configuration. + +* La Fondation Mojaloop PEUT transmettre le nom et les coordonnées du rapporteur aux fournisseurs affectés sauf demande contraire. + +* La Fondation Mojaloop transmettra le nom et les coordonnées du rapporteur aux fournisseurs affectés sauf demande contraire. + +* La Fondation Mojaloop informera le rapporteur des changements importants dans le statut d’une vulnérabilité dans la mesure du possible sans révéler des informations reçues en confidence. + +* La Fondation Mojaloop PEUT ajuster le calendrier de publication pour tenir compte de contraintes du rapporteur si compatible avec cette politique (souvent un report, ex. pour une conférence). + +* La Fondation Mojaloop N’exigera PAS que les rapporteurs entrent dans une relation client, signent un NDA ou toute autre obligation contractuelle ou financière comme condition pour recevoir ou coordonner des rapports. + +#### Coordination avec les fournisseurs + +* Si la vulnérabilité signalée résulte d’un produit ou service grand public, la Fondation Mojaloop PEUT signaler la vulnérabilité aux fournisseurs, prestataires ou services de coordination concernés. + +* La Fondation Mojaloop s’efforcera de bonne foi d’informer les fournisseurs avant divulgation publique. + +* La Fondation Mojaloop transmettra les rapports aux fournisseurs affectés dès que pratique après réception. + +* La Fondation Mojaloop informera les fournisseurs affectés de ses plans de publication et négociera des calendriers alternatifs si nécessaire. + +* La Fondation Mojaloop donnera au fournisseur l’occasion d’inclure une déclaration dans le document de divulgation publique. + +* La Fondation Mojaloop ne retiendra pas d’informations fournies par un fournisseur uniquement parce qu’elles contredisent notre évaluation. + +* La Fondation Mojaloop notifiera les fournisseurs affectés de tout plan de divulgation publique. + +* La Fondation Mojaloop ne révélera pas d’informations fournies en confidence par un fournisseur. + +* La Fondation Mojaloop respectera les attentes des rapporteurs énoncées dans cette politique lorsqu’elle agit elle-même comme rapporteur auprès d’autres organisations. + +#### Coordination avec d’autres acteurs + +* La Fondation Mojaloop PEUT faire appel à un service tiers (ex. CERT/CC, DHS CISA) pour résoudre des conflits avec le rapporteur. + +* La Fondation Mojaloop PEUT, à sa discrétion, communiquer des informations sur les vulnérabilités à toute partie pouvant contribuer à la solution et avec laquelle elle entretient une relation de confiance, notamment des fournisseurs (y compris souvent des fournisseurs dont les produits ne sont pas vulnérables), prestataires de services, experts de la communauté, sponsors et sites faisant partie d’une infrastructure nationale critique, si elle estime que ces sites sont à risque. + +#### Divulgation publique + +* La Fondation Mojaloop déterminera le type et le calendrier de sa divulgation publique. + +* La Fondation Mojaloop PEUT divulguer des vulnérabilités au public 7 jours après le premier rapport, indépendamment de l’existence ou de la disponibilité de correctifs ou contournements des fournisseurs affectés. + +* La Fondation Mojaloop PEUT divulguer plus tôt ou plus tard en raison de circonstances particulières (exploitation active, menaces graves ou mineures, nécessité de modifier une norme établie). + +* La Fondation Mojaloop PEUT consulter le rapporteur et les fournisseurs affectés sur le calendrier et le détail de la divulgation publique. + +* La Fondation Mojaloop équilibrera le besoin du public d’être informé des vulnérabilités de sécurité avec le besoin des fournisseurs et des utilisateurs du logiciel open source Mojaloop de disposer du temps nécessaire pour répondre efficacement. + +* La décision finale sur le calendrier de publication sera fondée sur le meilleur intérêt global de la communauté. + +* La Fondation Mojaloop publiera les divulgations par e-mail, Slack et/ou le site Community Central. + +* La Fondation Mojaloop PEUT divulguer au public l’existence antérieure de vulnérabilités déjà corrigées, y compris des détails ou indicateurs, ou la nature (mais pas le contenu) des informations rendues accessibles. + +* La Fondation Mojaloop fondera ses décisions sur des facteurs pertinents tels que, sans s’y limiter : divulgation publique préalable, gravité de la vulnérabilité, impact potentiel sur l’infrastructure critique, menace possible pour la santé publique et la sécurité, atténuations immédiates disponibles, réactivité du fournisseur et faisabilité de la création d’une mise à niveau ou d’un correctif, et estimation du délai nécessaire pour que les clients obtiennent, testent et appliquent le correctif. Exploitation active ou menaces graves peuvent accélérer ou retarder la divulgation. + +* La Fondation Mojaloop PEUT divulguer des vulnérabilités produit 30 jours après le premier contact si le produit est affecté et que le fournisseur ne répond pas ou n’établit pas un délai raisonnable de remédiation, indépendamment de l’existence de correctifs ou contournements. diff --git a/docs/fr/community/contributing/design-review.md b/docs/fr/community/contributing/design-review.md new file mode 100644 index 000000000..1a1c971c2 --- /dev/null +++ b/docs/fr/community/contributing/design-review.md @@ -0,0 +1,152 @@ +# Revue de conception technique et revue de code + +Le logiciel Mojaloop est conçu pour constituer l’épine dorsale de schémas de paiements instantanés inclusifs à l’échelle nationale. Ces schémas sont des éléments majeurs d’infrastructure financière nationale réglementée qui soutiennent des activités quotidiennes vitales pour de nombreuses personnes, comme l’achat de nourriture ou d’eau potable. Les adoptants et utilisateurs du logiciel Mojaloop exigent et méritent un niveau très élevé de qualité, sécurité, fiabilité et résilience. + +Pour préserver ces qualités et atténuer les risques, la Fondation Mojaloop applique un processus d’ingénierie produit structuré, fondé sur les meilleures pratiques éprouvées du secteur pour les logiciels financiers réglementés, incluant : contrôle des changements et traçabilité, revues de conception et de code, seuils de tests élevés et plusieurs niveaux d’assurance qualité. + +Ces processus aident les contributeurs à identifier et réduire les risques tout en améliorant les produits. + +Veuillez lire attentivement les informations suivantes pour vous assurer de bien comprendre nos définitions et la façon dont ces processus s’appliquent au travail que vous souhaitez réaliser, **avant de commencer**. + +**Si vous ne suivez pas ces processus, il pourra vous être demandé de refaire le travail, ou la contribution pourra être purement et simplement rejetée si elle ne respecte pas nos normes, avec des retards importants pour une release officielle Mojaloop. Veuillez consulter nos explications sur le [processus de don externe](product-engineering-process.md#non-official-workstreams-and-external-contributions).** + +## Qu’est-ce que la revue de conception technique ? + +La « revue de conception technique » est un processus par lequel un ou plusieurs ingénieurs seniors experts du domaine, membres de la Design Authority Mojaloop, familiers des zones du système concernées, discutent des changements proposés avec les contributeurs et les représentants produit **avant le début de l’implémentation**, pour : + +- Gestion des risques + - Identifier et atténuer les risques techniques et/ou métier pour les parties prenantes, utilisateurs ou autres contributeurs. +- Évaluation d’impact + - Repérer d’autres zones du système, équipes et parties prenantes impactées et faciliter la communication. +- Normes et cohérence + - Orienter vers les normes Mojaloop (outils, composants tiers, motifs de conception) pour préserver la cohérence de la base de code. + +Pour les changements non triviaux, le processus consiste à collaborer avec la Design Authority pour produire un document de conception détaillant le changement. Après implémentation, ce document vient enrichir la documentation communautaire et aide à comprendre le raisonnement derrière les décisions de conception prises au fil de l’évolution du logiciel. + +## Qu’est-ce que la revue de code ? + +La « revue de code » est un processus par lequel un ou plusieurs ingénieurs examinent des changements de code proposés **avant fusion dans la branche principale**, pour : + +- Assurance qualité + - Les revues de code contribuent à garantir la qualité de la base de code en permettant aux autres membres de l’équipe d’identifier les problèmes potentiels, bugs ou pistes d’amélioration avant la fusion. Cela peut conduire à un logiciel de meilleure qualité, avec moins de défauts. +- Partage des connaissances + - Apprendre des approches des pairs, bonnes pratiques et motifs ; diffusion de l’expertise. +- Cohérence + - Maintenir style, normes et conventions ; base de code homogène. +- Réduction des risques + - Plusieurs regards pour risques, sécurité et performances avant la production. +- Retours et amélioration + - Feedback constructif, alternatives, discussion des choix de conception ; amélioration continue. +- Propriété collective du code + - Responsabilité partagée plutôt qu’individuelle. + +## Types de changement + +Le processus dépend de la nature du changement et de son impact sur les utilisateurs et le système. + +Identifiez la catégorie ci-dessous et suivez le processus correspondant. En tant que contributeur, il est de votre responsabilité d’appliquer le processus approprié ; vous devrez signer un accord de contributeur attestant de votre engagement à respecter ces exigences. + +En cas de doute, consultez la Design Authority sur Slack : [#design-authority](https://mojaloop.slack.com/archives/CARJFMH3Q). Veuillez noter qu’il est important d’engager tout processus de revue de conception requis avant de procéder à des modifications de code, afin d’éviter de gaspiller vos propres efforts si la Design Authority venait à demander un travail à refaire. + +### Changements non conséquentiels + +#### Définition et caractéristiques + +Un changement de code non conséquentiel est une modification petite et très isolée sur du code existant. Il n’affecte pas la structure interne ou externe ni la fonctionnalité au niveau local (entrées/sorties) ; il vise souvent la lisibilité, le style ou de petites optimisations. Les changements non conséquentiels sont simples à traiter et présentent un faible risque. + +Il ne modifie pas les interfaces externes, la fonctionnalité ou le comportement observable externe d’un ou plusieurs composants. + +Il ne modifie pas la structure interne des composants. + +_Note importante : si votre changement est une optimisation qui modifie l’implémentation d’un algorithme, évaluez si une revue de conception ou une revue de code renforcée est nécessaire. Mieux vaut solliciter plus de regards qu’introduire une régression._ + +#### Exemples + +- Renommer des variables +- Ajuster l’indentation +- Ajouter des commentaires +- Supprimer des imports inutilisés +- Optimiser de petits algorithmes + +#### Processus de revue de conception et de code requis + +1. Aucune revue de conception n’est obligatoire, mais elle peut être entreprise si vous avez le moindre doute quant aux conséquences de vos changements. +2. Au moins une approbation d’un « code owner » sur tous les fichiers modifiés. + 1. S’il n’y a pas de code owners pour certains fichiers, ouvrez un ticket auprès de {coordonnées} pour en définir. Tous les fichiers de l’organisation GitHub Mojaloop devraient avoir des code owners. +3. Revues par les pairs supplémentaires souhaitées ; plus il y a de regards, mieux c’est. + +### Changements conséquents + +#### Définition et caractéristiques + +Les changements conséquents modifient le comportement, la fonctionnalité, les caractéristiques opérationnelles ou les performances d’un sous-système ou du système dans son ensemble : logique métier, nouvelles fonctionnalités, correctifs, dépendances, refactorings importants. Ils exigent réflexion et coordination en amont en raison de l’impact potentiel sur la stabilité et les fonctionnalités. Risque plus élevé. + +_Note importante : si vous pensez être dans les changements conséquents, vérifiez aussi la catégorie [« Changements critiques »](#critical-changes)._ + +#### Exemples + +- Modifier l’implémentation d’une méthode d’API interne existante +- Ajouter une nouvelle méthode d’API interne +- Modifier la définition ou le comportement d’une interface interne +- Changer une dépendance de service de fond (ex. type de SGBDR) +- Changer une dépendance de code (ex. remplacer un parseur YAML) +- Refactorings sur plusieurs fichiers +- Changements de configuration de déploiement (ex. Infrastructure as Code) + +#### Processus de revue de conception et de code requis + +Les changements conséquents doivent suivre le [processus des changements conséquents](consequential-change-process.md). + +### Changements critiques + +#### Définition et caractéristiques + +_**Dans Mojaloop, les « changements critiques » recouvrent en grande partie la même définition que les changements conséquents, mais s’appliquent aux zones considérées comme critiques pour les fonctionnalités cœur et les cas d’usage principaux.**_ + +Ils impactent le comportement, la fonctionnalité, les caractéristiques opérationnelles ou les performances d’un sous-système critique, du système ou d’autres artefacts. Ils impliquent souvent la logique d’un composant ou service critique (nouvelles fonctionnalités, bugs, dépendances, refactoring). Coordination importante en amont ; risque très élevé. + +Un changement est critique s’il touche notamment : + +- APIs externes : + - Toute modification de spécification d’API externe, chemins nominaux ou d’erreur, y compris validation et correctifs. + - Toute modification de l’implémentation de gestion des requêtes d’API externe, chemins nominaux ou d’erreur, y compris validation et correctifs. + - « API externe » : toute API exposée hors du périmètre du switch (ex. FSPIOP API, etc.). +- APIs d’administration : + - Tout changement de spécification d’API d’administration. + - Tout changement d’implémentation des requêtes d’API d’administration (chemins nominaux ou d’erreur, validation, correctifs). +- Phase de découverte du flux de transfert : + - Tout changement dans la gestion des requêtes de la phase de découverte, ex. : + - Gestion des requêtes de recherche de compte et flux vers des « oracles » internes ou externes. +- Phase d’accord du flux de transfert : + - Tout changement dans la gestion des requêtes de la phase d’accord, ex. : + - Stockage, récupération, traitement ou affichage des données ou métadonnées d’accord. + - Implémentations et flux d’appels vers des entités internes ou externes. +- Phase de transfert (compensation) : + - Tout changement dans la gestion des requêtes de la phase de compensation, ex. : + - Décision de compenser ou rejeter selon la liquidité disponible (contrôle de liquidité). + - Calcul, stockage, récupération, traitement ou affichage des plafonds de débit net des participants. + - Calcul, stockage, récupération, traitement ou affichage de la liquidité disponible. + - Calcul, stockage, récupération, traitement ou affichage de toute valeur monétaire. + - Calcul, stockage, récupération, traitement ou affichage des données ou métadonnées de transfert. + - Tout changement dans le pipeline de préparation de transfert. + - Tout changement dans le pipeline d’exécution de transfert. +- Règlement : + - Toute modification de spécification d’API de règlement interne ou externe (chemins nominaux ou d’erreur, validation, correctifs). + - Toute modification d’implémentation de gestion des requêtes de règlement (idem). + - Tout changement concernant l’inclusion ou l’exclusion de transferts pour le batch de règlement. + - Tout changement sur le calcul, stockage, récupération, traitement ou affichage des données ou métadonnées de règlement. + +#### Exemples + +- Corriger un bug dans une méthode de validation de l’API FSPIOP +- Ajouter une fonctionnalité à une API d’administration +- Modifier le format d’affichage des devises dans un portail web +- Mettre à niveau une dépendance externe (ex. paquet npm d’un service lié au grand livre) +- Optimiser les appels au stockage pendant le traitement d’une requête d’API externe + +#### Processus de revue de conception et de code requis + +Les changements critiques doivent suivre le [processus des changements critiques](critical-change-process.md). + + + diff --git a/docs/fr/community/contributing/new-contributor-checklist.md b/docs/fr/community/contributing/new-contributor-checklist.md new file mode 100644 index 000000000..78de110bc --- /dev/null +++ b/docs/fr/community/contributing/new-contributor-checklist.md @@ -0,0 +1,50 @@ +# Checklist nouveau contributeur + +Ce guide résume les étapes pour démarrer en tant que contributeur Mojaloop. Elles n’ont pas besoin d’être effectuées en une seule fois ; à la fin de cette checklist, vous devriez avoir acquis une bonne connaissance de Mojaloop et être prêt à contribuer à la communauté. + + +## 1. Outils et documentation + +- Assurez-vous de disposer d’un compte GitHub, ou créez-en un ici : [inscription](https://github.com/join). + +- Rejoignez le Slack via le [lien d’invitation](https://join.slack.com/t/mojaloop/shared_invite/zt-1qy6f3fs0-xYfqfIHJ6zFfNXb0XRpiHw), et ces canaux : + - `#announcements` — Annonces des nouvelles releases et statut QA + - `#design-authority` — Questions et discussions autour de la conception Mojaloop + - `#general` — Discussion générale sur Mojaloop + - `#help-mojaloop` — Aide à l’installation ou à l’exécution de Mojaloop + - `#ml-oss-bug-triage` — Discussion et triage des nouveaux bugs et tickets + +- Dites bonjour ! N’hésitez pas à vous présenter brièvement à la communauté sur le canal `#general`. + +- Lisez le [guide de workflow Git](https://docs.mojaloop.io/community/standards/creating-new-features.html) et assurez-vous d’être à l’aise avec Git. + - Pour aller plus loin : [Introduction au workflow GitHub](https://www.atlassian.com/git/tutorials/comparing-workflows) + +- Familiarisez-vous avec notre style de code : https://standardjs.com/ + +- Parcourez la [documentation Mojaloop](https://mojaloop.io/documentation/) pour acquérir une compréhension de base du fonctionnement de la technologie. + +- Suivez le [guide des outils développeur](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) pour installer et mettre en service les outils nécessaires sur votre environnement local. + +- (Optionnel) Faire tourner Central-Ledger en local : + - https://github.com/mojaloop/central-ledger/blob/master/Onboarding.md + - https://github.com/mojaloop/ml-api-adapter/blob/master/Onboarding.md + +- (Optionnel) Déployer un switch complet avec Kubernetes : https://mojaloop.io/documentation/deployment-guide/ *(en local, le cluster Kubernetes nécessite en général 8 Go de RAM ou plus)* + +## 2. Trouver un ticket + +- Parcourez la liste [good-first-issue](https://github.com/mojaloop/project/labels/good%20first%20issue) sur [`mojaloop/project`](https://github.com/mojaloop/project) pour trouver un bon ticket pour commencer. Vous pouvez aussi contacter la communauté sur Slack sur `#general` pour demander de l’aide à en trouver un. + +- Laissez un commentaire sur le ticket pour demander à ce qu’il vous soit assigné — cela permet d’éviter le travail en double. Comme toujours, n’hésitez pas à nous contacter sur Slack si vous avez des questions ou des préoccupations. + +- Forkez les dépôts concernés, clonez et créez une branche pour le ticket. + - Voir le [guide utilisateur Git](https://docs.mojaloop.io/community/standards/creating-new-features.html) si besoin. + + +## 3. Ouvrir votre première PR + +Consultez nos directives pour créer des pull requests [ici](pr-guidance.md). + +## 4. Signer la CLA + +Après votre première PR, la CI vous demandera de signer la CLA. Pour plus d’informations sur ce qu’est la CLA et la procédure pour la signer, consultez [Signer la CLA](./signing-the-cla.md). diff --git a/docs/fr/community/contributing/pr-guidance.md b/docs/fr/community/contributing/pr-guidance.md new file mode 100644 index 000000000..940d4d54a --- /dev/null +++ b/docs/fr/community/contributing/pr-guidance.md @@ -0,0 +1,235 @@ +# Directives pour les pull requests + +> **S’applique à :** Tous les contributeurs soumettant des pull requests aux dépôts de l’[organisation GitHub Mojaloop](https://github.com/mojaloop). +> Ces directives complètent le [guide des contributeurs](contributors-guide.md), la [politique d’usage responsable de l’IA](../standards/ai_policy.md) et le [processus d’ingénierie produit](product-engineering-process.md). + +**Divulgation IA** Ce document inclut du contenu généré avec l’assistance de Claude Sonnet 4.6. L’ensemble du contenu a été relu et validé par l’auteur. + + +--- + +## 1. Avant d’ouvrir une PR + +### 1.1 Commencer par un ticket GitHub + +Chaque PR doit être liée à un ticket GitHub. N’ouvrez pas de PR sans ticket. + +- Si aucun ticket pertinent n’existe, **créez-le d’abord** et laissez le temps au triage ou à la discussion avant de commencer l’implémentation — en particulier pour les changements non triviaux. +- Les tickets sont l’espace principal pour la discussion de conception, les décisions de périmètre et l’alignement avec les mainteneurs. Utilisez-les. + + +### 1.2 Discuter d’abord des changements conséquents ou critiques + +Si votre changement touche des interfaces partagées, la logique de règlement ou de compensation, les API centrales ou du code sensible à la sécurité, consultez le [processus de changement conséquent](https://docs.mojaloop.io/community/contributing/consequential-change-process.html) et le [processus de changement critique](https://docs.mojaloop.io/community/contributing/critical-change-process.html) **avant d’écrire du code**. Soumettre un changement architectural majeur en PR surprise entraînera son renvoi pour discussion préalable. + +--- + +## 2. Titres des pull requests + +Mojaloop utilise [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) pour l’outillage automatisé de releases et déploiements. Le titre de votre pull request **doit** respecter la spécification des commits conventionnels pour passer les contrôles CI/CD dans CircleCI. + +Avec Conventional Commits et le versionnement sémantique, une nouvelle version peut être publiée automatiquement pour un composant, avec incrément `MAJOR`, `MINOR` ou correctif selon les titres de PR, et génération de changelogs détaillés. (Voir [cet exemple](https://github.com/mojaloop/thirdparty-scheme-adapter/releases/tag/v11.20.0) de changelog auto-généré.) + +> **Note** : +> Lors de la fusion (avec squash), GitHub utilise le *titre* de la PR comme message de commit. Pour indiquer un changement rupturiste, utilisez le format avec `!` : +> « Si inclus dans le préfixe type/scope, les changements rupturistes DOIVENT être indiqués par un ! immédiatement avant les deux-points. Si ! est utilisé, BREAKING CHANGE: peut être omis du pied de page, et la description du commit DOIT décrire le changement rupturiste. » + +#### Exemples de bons titres de PR + +- feat(api): add ability to handle `PUT /thirdpartyRequests/trasactions/{ID}` endpoint +- fix: update outdated node modules +- feat(models)!: change database schema +- chore: tidy up readme + +--- + +## 3. Garder les PR petites et ciblées + +C’est la chose la plus importante que vous puissiez faire pour aider les reviewers et les mainteneurs. + +### 3.1 Une PR, un objectif + +Une pull request doit faire exactement une chose : corriger un bug, implémenter une fonctionnalité ou traiter un sujet précis. Les PR à objectifs multiples sont difficiles à revoir, difficiles à annuler en cas de problème et créent un historique de commits ambigu. + +**Ne combinez pas :** +- Un correctif de bug et un refactoring +- Une fonctionnalité et un nettoyage de tests sans lien +- Des mises à jour de dépendances et des changements fonctionnels +- Des changements d’espacement et des changements fonctionnels + +Si vous vous surprenez à écrire « et aussi… » dans la description de la PR, c’est le signe qu’il faut la scinder. + +Notez que des changements massifs d’espacement, par exemple une réindentation, peuvent masquer l’objectif d’un changement sous-jacent. Séparez les grands changements d’espacement dans leurs propres PR pour faciliter la revue. + +### 3.2 Viser une taille de diff appropriée + +Il n’existe pas de limite stricte en nombre de lignes, mais voici un guide pratique : + +| Taille du diff | Attente | +|---|---| +| < 200 lignes | Idéal. Peut être revu rapidement et en profondeur. | +| 200 – 500 lignes | Acceptable pour des changements bien cadrés et bien contextualisés. | +| 500 – 1000 lignes | Nécessite une justification solide. Envisagez de scinder. | +| > 1000 lignes | Sera probablement renvoyée pour être découpée, sauf si le changement est intrinsèquement atomique (par ex. un fichier généré, un renommage massif). | + +Lorsqu’un changement important est réellement atomique — par exemple une migration de schéma, une sortie de génération de code ou un renommage en masse — ajoutez une note expliquant pourquoi il ne peut pas être scindé. + +### 3.3 Séparer le refactoring des changements fonctionnels + +Si vous devez refactoriser du code avant d’apporter un changement fonctionnel, soumettez d’abord le refactoring dans sa propre PR. Mélanger refactoring et changements de comportement rend difficile la vérification qu’aucune régression n’a été introduite. + +### 3.4 Garder des commits propres + +Squashez ou réorganisez vos commits avant d’ouvrir la PR afin que chaque commit représente une étape logique et autonome. Évitez les commits du type `fix typo`, `wip` ou `try again`. Un historique de commits propre aide les reviewers et rend `git bisect` utile. + +--- + +## 4. Rédiger une bonne description de PR + +Une description bien rédigée n’est pas optionnelle — elle fait partie de votre contribution. Les reviewers ne doivent pas avoir à reconstruire votre intention à partir du diff. + +Votre description de PR doit inclure : + +### 4.1 Quoi et pourquoi + +Expliquez **ce que** fait le changement et **pourquoi** il est nécessaire. Liez le ticket GitHub pertinent. Ne vous contentez pas de reprendre le titre du ticket — ajoutez le contexte dont un reviewer a besoin pour évaluer vos choix d’implémentation. + +### 4.2 Comment tester + +Décrivez comment le reviewer peut vérifier que le changement fonctionne correctement. Incluez : +- Les étapes pour reproduire le problème (pour les correctifs de bug) +- Comment exercer le nouveau comportement (pour les fonctionnalités) +- Des indications vers les tests automatisés pertinents + +Si un changement ne peut pas être testé automatiquement, expliquez pourquoi et décrivez la vérification manuelle que vous avez effectuée. + +### 4.3 Changements rupturistes + +Si votre PR introduit un changement rupturiste — sur une API, une interface de configuration, un schéma de base de données ou un contrat partagé — signalez-le **explicitement et de façon visible** en tête de la description. Les changements rupturistes nécessitent une revue supplémentaire et peuvent devoir suivre le [processus de changement conséquent](https://docs.mojaloop.io/community/contributing/consequential-change-process.html). + +### 4.4 Divulgation de l’assistance IA (voir section 5) + +Si des outils d’IA ont été utilisés pour produire une partie de la PR — code, tests ou description de PR — cela doit être divulgué dans la description de la PR. Voir la section 5 pour le format requis. + +--- + +## 5. Assistance IA : attribution et responsabilité + +La [politique IA Mojaloop](https://docs.mojaloop.io/community/standards/ai_policy.html) s’applique à toutes les contributions par PR. Les règles suivantes en distillent les exigences concrètes pour les PR. + +### 5.1 La divulgation est obligatoire + +Si un outil d’IA (y compris, sans s’y limiter, GitHub Copilot, ChatGPT, Claude, Gemini, Cursor ou équivalent) a assisté la production de **toute partie de votre PR** — y compris le code, les tests, les messages de commit ou la description de PR elle-même — vous devez inclure le bloc de divulgation suivant dans la description de votre PR : + +``` +**Divulgation de l’assistance IA** +Des outils d’IA ont été utilisés pour produire une partie de cette contribution. +Outils utilisés : [liste des outils et versions si connues] +Périmètre : [brève description de ce qui a été assisté par l’IA, par ex. « échafaudage de tests unitaires », « implémentation initiale de la fonction X », « brouillon de description de PR »] +L’ensemble du contenu généré par l’IA a été relu, compris et validé par l’auteur. +``` + +Tous les fichiers de code de l’organisation GitHub Mojaloop doivent inclure un en-tête de licence et de contributeurs. Assurez-vous que les fichiers que vous modifiez contiennent votre nom et votre adresse e-mail actuelle dans la liste. Si vous avez utilisé l’IA, vous devez inclure les détails des outils utilisés à côté de votre nom et de votre e-mail, ainsi : + +``` + - {votre nom} <{votre e-mail}> [Assisté par {nom du modèle} {version du modèle}] +``` + +Par exemple : +``` +/***** + License + -------------- + Copyright © 2026 Mojaloop Foundation + + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Mojaloop Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + + * Mojaloop Foundation + - James Bush [Assisted by Claude Sonnet 4.6] + + -------------- + ******/ +``` + +Omettre cette divulgation lorsque l’IA a été utilisée constitue une violation de la politique IA et entraînera le renvoi de la PR. + +### 5.2 Vous êtes entièrement responsable de tout le code soumis + +La divulgation n’est pas une décharge de responsabilité. Que l’assistance IA ait été utilisée ou non, l’auteur humain de la PR est entièrement responsable de : + +- La **justesse** de la logique +- La **sécurité** de l’implémentation +- La **cohérence architecturale** avec les normes Mojaloop +- La **conformité aux licences** — vous ne devez pas soumettre de code généré par l’IA issu de données d’entraînement sous licence non autorisée +- La **maintenabilité à long terme** de ce que vous avez introduit + +« L’IA l’a écrit » n’est pas une réponse acceptable à un commentaire de revue. Si vous ne pouvez pas expliquer et défendre chaque partie de votre PR, elle n’est pas prête à être soumise. + +### 5.3 L’IA ne doit pas se substituer au jugement humain + +Les outils d’IA ne peuvent pas être utilisés pour prendre ou déléguer des décisions architecturales ou de conception. Lorsqu’un outil d’IA propose une approche qui s’écarte des motifs ou invariants Mojaloop établis, le contributeur humain est responsable de le reconnaître et de le corriger avant la soumission. + +### 5.4 Les soumissions par agents automatisés sont interdites + +Les PR ne peuvent pas être soumises par des agents IA entièrement autonomes. Toutes les PR doivent être ouvertes par un contributeur humain. La seule exception concerne l’automatisation GitHub native officiellement approuvée déjà intégrée aux workflows Mojaloop (par ex. Dependabot, Snyk, outillage automatisé de maintenance de la Mojaloop Foundation). Les soumissions par agents automatisés seront rejetées sans revue. + +--- + +## 6. Checklist de qualité du code + +Avant de marquer une PR prête pour revue, confirmez les points suivants : + +- La PR est liée à un ticket GitHub avec un mot-clé de clôture +- La PR fait exactement une chose ; les changements sans lien ont été retirés ou scindés +- Tous les tests automatisés passent localement +- Le nouveau comportement est couvert par des tests +- Aucune nouvelle erreur ou alerte de linting n’a été introduite +- Les changements de dépendances sont justifiés et minimaux +- Tout changement rupturiste est clairement signalé +- La description de la PR explique quoi, pourquoi et comment tester +- La divulgation de l’assistance IA est incluse le cas échéant (voir section 5.1) +- Vous avez lu, compris et pouvez défendre chaque ligne du diff + +--- + +## 7. Attentes envers les reviewers + +Les reviewers sont des bénévoles qui donnent de leur temps. Aidez-les à vous aider. + +- **Répondez rapidement** aux commentaires de revue. Si vous avez besoin de temps, dites-le. +- **N’ajoutez pas de changements sans lien** à une PR déjà en cours de revue sans les signaler. +- **Ne rebasez pas et ne force-push pas** une PR qui fait l’objet de commentaires de revue actifs — cela perturbe le contexte du reviewer. Coordonnez-vous d’abord. +- Si un reviewer vous demande de scinder une PR, faites-le. Ce n’est pas une critique ; c’est ainsi que Mojaloop maintient un historique revueable et bisectable. +- Une PR sans activité pendant **30 jours** peut être fermée par un mainteneur. Elle peut être rouverte lorsque vous êtes prêt à continuer. + +--- + +## 8. PR brouillon + +Utilisez la fonctionnalité GitHub **Draft PR** pour les travaux en cours. Cela indique aux mainteneurs et reviewers qu’un retour sur l’orientation générale est le bienvenu, mais qu’une revue complète n’est pas encore demandée. Passez à « Ready for Review » uniquement lorsque tous les éléments de la checklist ci-dessus sont satisfaits. + +--- + +## 9. Correctifs urgents et changements critiques + +Pour les correctifs de sécurité critiques ou les bugs bloquants en production, suivez le [processus de changement critique](https://docs.mojaloop.io/community/contributing/critical-change-process.html). Même sous la pression du temps, l’exigence de divulgation IA et la checklist de qualité du code s’appliquent toujours. Une revue rapide n’est pas une autorisation de les contourner. + +--- + +*Pour toute question sur ces directives, publiez sur le canal Slack du workstream concerné ou ouvrez un ticket GitHub contre le [dépôt documentation](https://github.com/mojaloop/documentation).* diff --git a/docs/fr/community/contributing/product-engineering-process.md b/docs/fr/community/contributing/product-engineering-process.md new file mode 100644 index 000000000..2ff777bd2 --- /dev/null +++ b/docs/fr/community/contributing/product-engineering-process.md @@ -0,0 +1,135 @@ +# Processus d’ingénierie produit Mojaloop + +## Introduction + +Le logiciel Mojaloop est conçu pour constituer l’épine dorsale de schémas de paiements instantanés inclusifs à l’échelle nationale. Ces schémas sont des éléments majeurs d’infrastructure financière nationale réglementée qui soutiennent des activités quotidiennes vitales pour un grand nombre de personnes (achat de nourriture, d’eau potable, etc.). Nos adoptants, leurs régulateurs et les personnes effectuant des transactions via les schémas Mojaloop exigent et méritent un niveau très élevé de qualité, sécurité, fiabilité et résilience. + +Pour préserver ces qualités et atténuer les risques métier et techniques, la Fondation Mojaloop applique un processus d’ingénierie produit structuré, fondé sur les meilleures pratiques éprouvées du secteur pour les logiciels financiers réglementés, incluant un contrôle des changements géré et traçable, piloté à la fois par des processus et des mécanismes techniques, revues de conception et de code, seuils de tests élevés et plusieurs niveaux d’assurance qualité. + +Ce processus aide les contributeurs à identifier et réduire les risques tout en améliorant les produits, au bénéfice de toute la communauté Mojaloop. + +## Évolution du processus + +Depuis 2017 et les premières lignes de code, le modèle a évolué pour s’adapter à la transition d’une seule équipe d’ingénierie vers plusieurs fils de travail dotés en ressources par la communauté, chacun centré sur des parties du large portefeuille produit. + +Le modèle actuel s’appuie sur le [Scaled Agile Framework](https://scaledagileframework.com/) pour permettre à plusieurs équipes de travailler aussi indépendamment que possible tout en livrant un ensemble coordonné de résultats de feuille de route sur l’ensemble du périmètre produit. + +Le cycle repose sur des « [program increments](https://v5.scaledagileframework.com/program-increment/) » d’environ quatre mois. À la fin de chaque incrément, les fils présentent leurs réalisations en réunion communautaire, le nouveau code est publié et la planification du suivant commence. + +![Program increments Mojaloop](./assets/mojaloop-product-engineering-process-overview.jpg) + +## Flux des exigences produit + +![Flux de fonctionnalité Mojaloop](./assets/mojaloop-product-feature-flow.jpg) + +Les demandes de fonctionnalités et nouvelles exigences proviennent de sources variées, par exemple : + +- Adoptants Mojaloop actuels et participants au schéma +- Opérateurs de schémas de paiement souhaitant tirer parti de la technologie Mojaloop +- Administrations publiques mettant en place des schémas de paiement inclusifs +- Experts en inclusion financière +- Membres de la communauté Mojaloop + +Le conseil produit Mojaloop les recueille et les analyse. S’il existe une demande suffisante et une volonté de contribuer, elles sont intégrées à la feuille de route produit et affectées à un fil de travail officiel Mojaloop. À défaut de fil adapté, un nouveau fil peut être créé et doté en ressources par la communauté. + +Les fils ont en général des objectifs fixés au début de chaque incrément de programme ; des demandes prioritaires peuvent toutefois être insérées en cours d’incrément. + +Les livrables des fils entrent dans un processus maîtrisé qui publie périodiquement des releases officielles du logiciel Mojaloop. Le processus de release s’aligne souvent sur les incréments de programme ; les releases majeures (nouvelles fonctionnalités) ont lieu en fin d’incrément. Les releases mineures et correctifs sont plus fréquentes (fonctionnalités prioritaires, correctifs de bugs ou correctifs de sécurité, etc.). + +## Fils de travail Mojaloop + +Les fils officiels sont les « chaînes de production » de la « fabrique » logicielle communautaire Mojaloop ; c’est là que se concentre l’essentiel du développement produit. Plusieurs fils tournent en parallèle, chacun sur des domaines ou fonctionnalités précis de la plateforme. + +### Modèle de gouvernance et exigences de fonctionnement + +Les fils Mojaloop ont un modèle de gouvernance et des exigences d’exploitation clairs pour limiter les risques pour toutes les parties prenantes : + +1. Nom clair et concis reflétant l’objectif du fil. +2. Un responsable désigné en permanence ; dans certains cas, la fonction peut être partagée entre deux personnes si aucune n’a assez de disponibilité. +3. Une personne désignée comme liaison avec la Design Authority Mojaloop (il peut s’agir du ou des responsables du fil, ou d’une autre personne spécifiquement nommée à cet effet). +4. Publication et mise à jour sur Community Central d’une description : objectif, buts et périmètre pour chaque incrément de programme. +5. Au moins deux contributeurs actifs nommés. +6. Au moins une réunion en ligne par semaine. + 1. Les réunions du fil devraient être ouvertes en observation aux autres membres de la communauté. + 2. Les réunions devraient être enregistrées et les enregistrements publiés. +7. Les fils avec plus de deux contributeurs actifs devraient tenir un stand-up de type Scrum en ligne. + 1. Stand-up quotidien sauf si le volume de travail est faible (cadence moindre acceptable). +8. Dépôt GitHub public contenant code, documentation et tickets de travail. +9. Respect de tous les [processus de revue de conception et de code Mojaloop](./design-review.md) avant, pendant et après le travail. +10. Utilisation d’un hashtag dédié sur Community Central pour les publications. +11. Revue par le Product Council Mojaloop avant le début de chaque incrément de programme. + 1. Les objectifs du fil doivent être alignés sur la feuille de route produit Mojaloop. + 2. Les objectifs du fil doivent être alignés sur la mission de la Fondation Mojaloop. + +### Critères et responsabilités des responsables de fil + +La Fondation Mojaloop désigne des responsables, en général des bénévoles de la communauté avec une forte expertise ou expérience pertinente. + +Pour être responsable (ou co-responsable) de fil, une personne devrait : + +1. S’engager et pouvoir assumer toutes les responsabilités ci-dessous. +2. Avoir démontré des capacités d’organisation. +3. Avoir démontré des capacités de leadership. +4. Avoir démontré des compétences techniques pertinentes. +5. Connaître l’écosystème Mojaloop. +6. S’engager pour la durée du PI. +7. Respecter le code de conduite Mojaloop. + +Les responsables de fil doivent notamment : + +1. Servir de point de contact principal pour les questions. +2. Planifier, tenir, enregistrer et publier les enregistrements et comptes rendus des réunions du fil. +3. Faciliter la liaison entre contributeurs du fil, autres fils et le reste de la communauté. +4. Créer, publier sur Community Central et maintenir une charte d’équipe du fil. +5. Rendre compte de l’avancement… + 1. …à la communauté régulièrement sur Community Central avec le hashtag assigné. + 2. …au Product Manager / Product Council. +6. Veiller à ce que tout le travail respecte les [processus de revue de conception et de code Mojaloop](./design-review.md) avant, pendant et après réalisation. +7. Veiller au respect des normes de qualité Mojaloop (style, couverture de tests, documentation). +8. Veiller au suivi dans GitHub/Zenhub et à la mise à jour des échéanciers et de l’avancement. +9. Veiller à ce que toute sortie technique soit testée par l’équipe cœur avant intégration au processus de release officiel. Pour les fils non techniques, revue par le directeur produit de la Fondation Mojaloop. +10. Faciliter le développement de nouvelles fonctionnalités et coder si nécessaire. +11. Trier les contributions et tickets, répondre aux utilisateurs. +12. Déclarer des bugs, proposer des correctifs et résoudre les conflits dans le fil. +13. Gérer proactivement la dette technique et améliorer le code existant, en respectant les [processus de revue de conception et de code Mojaloop](./design-review.md). +14. Veiller à ce que la documentation respecte les normes requises. +15. Orienter stratégiquement le fil avec le directeur produit et le Product Council de la Fondation Mojaloop. +16. Définir des objectifs SMART au début de chaque PI. + +### Définir le travail + +Les fils doivent définir et enregistrer publiquement (issues GitHub/Zenhub) le travail prévu et l’avancement : + +1. Les éléments de travail doivent être des issues GitHub ; L’utilisation de Zenhub n’est pas obligatoire, mais est fortement encouragée. + 1. Chaque fil a son projet GitHub et son espace Zenhub. +2. Les éléments (« user stories ») devraient suivre le style « En tant que… je veux… afin de… » du [développement piloté par le comportement](https://www.agilealliance.org/glossary/user-story-template/). +3. Ils devraient inclure des critères d’acceptation détaillés au format « étant donné, quand, alors » du [BDD](https://www.agilealliance.org/glossary/given-when-then/). +4. La taille doit être telle qu’aucun élément ou sous-élément ne dépasse un sprint de deux semaines. +5. Respect des [processus de revue de conception et de code Mojaloop](./design-review.md) avant, pendant et après. Lorsqu’une revue de conception est requise, utiliser des tickets « spike » pour le design avant les tickets d’implémentation. + 1. Toute la documentation de conception requise doit être approuvée par la Design Authority Mojaloop avant le début du travail. + +Modèle de ticket GitHub/Zenhub : [github-work-item-template.docx](github-work-item-template.docx) + +### Mener le travail à bien + +Les fils Mojaloop suivent par défaut un modèle proche de [Scrum](https://www.scrum.org/resources/what-scrum-module), avec des sprints de deux semaines. Compte tenu des exigences de gestion des risques des utilisateurs, des cadres réglementaires et des pratiques du secteur financier, le fonctionnement quotidien inclut des fonctions de supervision obligatoires et un contrôle des changements plus strict que dans certaines méthodes agiles classiques, comparable aux grandes organisations techniques qui exploitent une infrastructure critique. + +Les fils peuvent adapter leurs méthodes dans des limites raisonnables pour la mission et le domaine réglementaire. La Fondation Mojaloop oriente les fils pour qu’ils restent dans les normes d’exploitation requises. + +Les fils devraient tenir régulièrement stand-up, affinage de backlog, planification de sprint, revue de sprint et rétrospectives. + +![Processus de sprint d’un fil Mojaloop](./assets/mojaloop-workstream-sprint-process.jpg) + +Chaque fil doit définir et maintenir une « charte d’équipe » qui fixe clairement les modalités de travail pour tous les contributeurs. + +Modèle de charte : [mojaloop-workstream-team-charter-template.pptx](assets/mojaloop-workstream-team-charter-template.pptx) + +### Obtenir du soutien + +Lorsque les choses ne se déroulent pas comme prévu et qu’aucune résolution ne peut être trouvée au sein des contributeurs du fil, la Fondation Mojaloop met à disposition des mécanismes de soutien. Contactez le directeur communauté de la Fondation Mojaloop pour être orienté vers une résolution. + +## Fils non officiels et contributions externes + +Lorsqu’aucun fil existant ne convient et que le besoin ne justifie pas un nouveau fil officiel, les contributeurs peuvent travailler en dehors des processus communautaires. Dans ce cas, notre [processus de don externe](../standards/guide.md#adopting-open-source-contributions-into-mojaloop) doit être suivi avant que code, documentation ou autres artefacts ne soient adoptés par la Fondation Mojaloop. + +Veuillez noter que tout travail réalisé hors des fils officiels Mojaloop est soumis au [processus de don externe](../standards/guide.md#adopting-open-source-contributions-into-mojaloop). Ceci afin de garantir un niveau de revue rigoureuse approprié et le respect de nos normes avant toute inclusion dans une release officielle Mojaloop. diff --git a/docs/fr/community/contributing/signing-the-cla.md b/docs/fr/community/contributing/signing-the-cla.md new file mode 100644 index 000000000..cae674533 --- /dev/null +++ b/docs/fr/community/contributing/signing-the-cla.md @@ -0,0 +1,97 @@ +# Signer la CLA + +Mojaloop dispose d’une [Contributor License Agreement (CLA)](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) qui clarifie les droits de propriété intellectuelle relatifs sur les contributions des personnes physiques ou morales. + +Pour vérifier que chaque développeur a signé la CLA, nous utilisons [CLA Assistant](https://cla-assistant.io/), un outil open source bien maintenu qui vérifie que le contributeur a signé la CLA avant d’autoriser la fusion d’une pull request. + +## Comment signer la CLA + +1. Ouvrez une pull request sur n’importe quel dépôt Mojaloop. +2. Lors des vérifications habituelles, le contrôle `license/cla` s’affiche et demande à l'utilisateur de signer la CLA : + + + +3. Cliquez sur « Details » : vous serez redirigé vers CLA Assistant, où vous pourrez lire la CLA, renseigner quelques informations personnelles et signer. + + +
+ + + +4. Après « I agree », retournez sur la pull request : vérifiez que le contrôle CLA Assistant est bien passé. + + + + + +### Signature pour une entreprise + +La section 3 de la [CLA Mojaloop](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) couvre les contributions individuelles et celles faites pour le compte d’un employeur. Si vous contribuez au nom de votre employeur, veuillez saisir le nom de celui-ci dans le champ « Company or Organization ». Sinon, n’hésitez pas à indiquer « OSS Contributor » et laisser le champ « role » vide. + + +## Administration de l’outil CLA + +L’outil CLA est simple à installer ; tout administrateur GitHub peut le lier à l’organisation Mojaloop. + +1. Créez un nouveau Gist GitHub et y collez le texte de la CLA. +> Comme GitHub n’autorise pas les Gists détenus par des organisations, [notre gist](https://gist.github.com/mojaloopci/9b7133e1ac153a097ae4ff893add8974) appartient à l’utilisateur « mojaloopci ». + +2. Allez sur [CLA Assistant](https://cla-assistant.io/) et cliquez sur « Sign in with GitHub ». + + + +3. Vous pouvez ajouter une CLA à un dépôt ou à une organisation. Sélectionnez « Mojaloop », puis le gist créé. + + + +4. Cliquez sur « Link », c’est terminé. + + +### Demander des informations supplémentaires + +> Référence : [request-more-information-from-the-cla-signer](https://github.com/cla-assistant/cla-assistant#request-more-information-from-the-cla-signer) + +Vous pouvez également ajouter un fichier `metadata` au gist de la CLA pour créer un formulaire personnalisé pour l’outil CLA : + +```json +{ + "name": { + "title": "Full Name", + "type": "string", + "githubKey": "name" + }, + "email": { + "title": "E-Mail", + "type": "string", + "githubKey": "email", + "required": true + }, + "country": { + "title": "Country you are based in", + "type": "string", + "required": true + }, + "company": { + "title": "Company or Organization", + "description": "If you're not affiliated with any, please write 'OSS Contributor'", + "type": "string", + "required": true + }, + "role": { + "title": "Your Role", + "description": "What is your role in your company/organization? Skip this if you're not affiliated with any", + "type": "string", + "required": false + }, + "agreement": { + "title": "I have read and agree to the CLA", + "type": "boolean", + "required": true + } +} +``` + +Le formulaire généré est le suivant : + + + diff --git a/docs/fr/community/documentation/api-documentation.md b/docs/fr/community/documentation/api-documentation.md new file mode 100644 index 000000000..ce7d5291c --- /dev/null +++ b/docs/fr/community/documentation/api-documentation.md @@ -0,0 +1,27 @@ +# Documentation des API + +Toutes les API devraient être documentées en RAML ou Swagger, voir [Architecture-Documentation-Guidelines](Architecture-Documentation-Guidelines.md). + +**En-têtes de section** + +* Ne numérotez pas les titres de sections - par exemple, utilisez « Préparer et Exécuter », et non « C - Préparer et Exécuter » +* Assurez-vous que les titres de section (\#) correspondent à ceux du PDF complet (généré à partir du [fichier de configuration dactyl](https://github.com/Mojaloop/Docs/blob/master/ExportDocs/dactyl-config.yml)) +* N’incluez pas le mot « documentation » dans les titres + +#### Repérabilité + +* Pour les sections qui contiennent de nombreux sous-ensembles de points de terminaison ou méthodes, fournissez une table des matières au début de la section +* N’utilisez pas le mot « projet » ; préférez des termes comme composant, microservice, interface, etc. + +#### Langage + +Au lieu du mot « projet », utilisez un nom spécifique comme composant, microservice ou interface. + +#### Procédures + +* Introduisez les procédures avec des titres H3 (\#\#\#) ou H4 (\#\#\#\#), pas des H2 (\#\#). +* N’utilisez pas de numéros dans les titres de section concernant les procédures. +* Utilisez la numérotation ordonnée (liste numérotée) pour les étapes des procédures. Par exemple : +* Étape 1 +* Étape 2 +* Étape 3 diff --git a/docs/fr/community/documentation/standards.md b/docs/fr/community/documentation/standards.md new file mode 100644 index 000000000..170f53d2e --- /dev/null +++ b/docs/fr/community/documentation/standards.md @@ -0,0 +1,29 @@ +# Documentation + +### Vue d’ensemble + +Mojaloop a défini plusieurs standards afin de garantir que la documentation à travers l’ensemble du projet reste cohérente et à jour. + +* Toute la documentation pertinente pour les contributeurs est conservée dans le dépôt "documentation". +* Le dépôt "documentation" est synchronisé avec GitBook et tout le contenu est consultable dans un format facilement lisible à l’adresse : [https://www.gitbook.com/mojaloop](https://www.gitbook.com/mojaloop) +* Toute documentation devrait inclure : + * Vue d’ensemble : contexte métier pour expliquer la valeur ou la raison d’être de la page de documentation + * Détails : informations de synthèse appropriées pour soutenir la documentation + +### + +[Standards de documentation](https://github.com/mojaloop/mojaloop/blob/master/contribute/Documentation-and-Template-Standards.md) + +### Guide de style de la documentation + +Toute nouvelle documentation devrait être conforme à la documentation et aux styles discutés [ici](style-guide.md). + +### Guide de style du code + +#### NodeJS + +Nous suivons les [standard style guidelines](https://github.com/feross/standard). Ajoutez `npm install standard` à votre package.json. + +#### Java + +Pour Java, nous suivons [Checkstyle](http://checkstyle.sourceforge.net/). Mesures de qualité du code diff --git a/docs/fr/community/documentation/style-guide.md b/docs/fr/community/documentation/style-guide.md new file mode 100644 index 000000000..ae0e7bfc8 --- /dev/null +++ b/docs/fr/community/documentation/style-guide.md @@ -0,0 +1,229 @@ +# Guide de style de la documentation + +Dans la plupart des cas, Mojaloop suit la dernière édition de l’Associated Press Stylebook. Les lignes directrices suivantes sont spécifiques à la fondation, mises à jour et légèrement modifiées. + +#### Acronymes + +Épelez tous les acronymes lors de la première mention. Incluez l’acronyme entre parenthèses immédiatement après la forme développée uniquement si vous y faites à nouveau référence dans le document. Exemple : _Kofi Annan, président du conseil d’administration de l’Alliance pour une Révolution Verte en Afrique (AGRA), s’est rendu à Nairobi ce mois-ci. C’était sa première visite au bureau de l’AGRA._ + +#### Esperluette + +N’utilisez une esperluette (&) que lorsqu’elle fait partie d’un nom officiel, comme dans Bill & Melinda Gates Foundation. Dans tous les autres cas, écrivez “et”. + +#### Bill & Melinda Gates Foundation + +Notre nom légal officiel est “Bill & Melinda Gates Foundation”. Utilisez-le pour la première mention. Utilisez toujours l’esperluette (&) et mettez une majuscule à “Foundation” lorsque “Bill & Melinda Gates” la précède. + +Ne jamais abréger le nom de la fondation en _BMGF_. + +Ne traduisez jamais le nom de la fondation dans d’autres langues, car il s’agit d’un nom propre. La seule exception concerne la traduction du nom de la fondation en chinois, qui est autorisée. + +Ne mettez pas de majuscule à “foundation” lorsqu’il est utilisé seul. Exemple : _Le nouveau siège de la fondation sera construit près du Seattle Center._ + +Utilisez “Gates Foundation” uniquement si le contexte le rend clair. Notez qu’il existe une “Gates Family Foundation” au Colorado, il faut donc être prudent. Exemple : _La Bill & Melinda Gates Foundation et la Ford Foundation ont co-organisé l’événement. Un membre du personnel de la Gates Foundation a prononcé les remarques de clôture._ + +L’entité qui gère la dotation est appelée officiellement « Bill & Melinda Gates Foundation Trust ». Vous n’aurez pas souvent besoin de mentionner cette entité, mais si c’est le cas, écrivez le nom complet la première fois et faites référence ensuite à “l’asset trust”. + +#### Gras et deux-points + +Il est fréquent de voir des structures (comme dans ce commentaire même !) où des termes introductifs sont en gras et séparés du contenu par un deux-points. Le deux-points doit-il également être en gras ou non ? (On observe les deux usages.) + +#### Buffett + +Notez l’orthographe : deux “f” et deux “t” (_c’est-à-dire Warren Buffett_). + +#### Listes à puces + +Introduisez les listes à puces par un deux-points lorsque les éléments listés complètent la phrase ou l’expression d’introduction. Exception : n’utilisez jamais de deux-points dans les titres ou sous-titres pour introduire une liste à puces. + +Mettez une majuscule au premier mot et terminez par un point les éléments listés uniquement s’il s’agit de phrases complètes. Exemples : + +* _Ceci est une phrase complète._ +* _pas une phrase complète_ + +Ne reliez jamais les éléments d’une liste à puces par des conjonctions de coordination ni par une ponctuation (points-virgules ou virgules) comme c’est le cas pour une liste style phrase. Autrement dit, à ne pas faire : + +* _cela,_ +* _ça, ou_ +* _autre chose._ + +#### Légendes + +Légendez les photos autant que possible. Les légendes aident à comprendre notre travail. + +Rédigez les légendes sous forme de phrases courtes commençant par un verbe au gérondif (_verbe en -ant_), suivies de la ville, de l’État ou du pays et de l’année entre parenthèses. Exemple : _Un médecin préparant un vaccin pour la livraison (Brazzaville, Congo, 2007)._ + +En rédigeant une légende, présentez les personnes figurant sur l’image et expliquez brièvement la scène en rapport avec nos axes d’intervention. Soyez concis pour ne pas détourner l’attention de l’image ou de la mise en page. Évitez les verbes qui énoncent l’évidence sur le sujet (_ex. : souriant, debout, etc._). + +Si un des co-présidents figure sur une photo avec d’autres personnes, veillez à l’identifier dans la légende. N’assumez pas que tout le monde sait à quoi ressemblent nos co-présidents. + +#### Citations + +La majorité des disciplines ont leurs propres conventions de citation. Adoptez celles du domaine concerné. Si ces conventions ne sont pas disponibles ou claires, référez-vous au “Chicago Manual of Style”. + +Si un document utilise à la fois des notes de bas de page et de fin, pour les notes de bas de page, utilisez les symboles suivants : + +* 1re note = \* (astérisque) +* 2e note = † (obèle) +* 3e note = ‡ (double obèle) +* 4e note = § (paragraphe) +* 5e note = \*\* (2 astérisques) +* 6e note = †† (2 obèles) +* 7e note = ‡‡ (2 doubles obèles) +* 8e note = §§ (2 paragraphes) + +Séparez plusieurs références (notes de bas de page ou de fin) par des virgules, pas des points-virgules. + +#### Essais cliniques + +Utilisez des chiffres romains pour les phases d’essais cliniques et mettez toujours une majuscule à “Phase”. Exemple : _L’entreprise commencera les essais de Phase III sur le nouveau médicament ce printemps._ + +#### Coordonnées + +Séparez les différentes parties des numéros de téléphone par des points et commencez chaque numéro par un signe plus. + +Comme nous travaillons avec le monde entier, omettez l’indicatif d’accès international, qui varie d’un pays à l’autre (par exemple, 011 aux États-Unis). Exemples : _+1.206.709.3100 (États-Unis)_ _+91.11.4100.3100 (Inde)_ + +#### Avis de droits d’auteur et de marque déposée + +Toutes les publications, tous les médias et matériels produits par ou pour la fondation doivent comporter l’avis ci-dessous. Toute exception doit être approuvée par l’équipe juridique. + + _© (année) Bill & Melinda Gates Foundation. Tous droits réservés._ Bill & Melinda Gates Foundation est une marque déposée aux États-Unis et dans d’autres pays. + +Lorsque c’est possible, commencez l’avis de marque sur une ligne séparée. + +#### Tirets + +Utilisez le tiret cadratin (—) pour indiquer une incise ou un changement brusque d’idée. Utilisez le tiret demi-cadratin (–) pour les intervalles numériques. + +N’ajoutez pas d’espace avant ou après le tiret. + +Exemples : _Nous œuvrons pour rendre les services financiers sûrs et abordables—en particulier les comptes d’épargne—plus accessibles aux populations des pays en développement._ + +_Au cours de l’élection présidentielle de 2004, 76 pour cent des diplômés de l’enseignement supérieur américain âgés de 25 à 44 ans ont voté._ + +#### Dollars ($) + +Dans les documents sur la santé mondiale et le développement, comme plus d’une douzaine de pays utilisent des dollars, précisez “dollars américains” (U.S.) lors de la première mention. Exemple : _$100 000 (U.S.)_. Omettez la mention (U.S.) pour les autres montants dans le même document. + +#### Noms des programmes de la fondation + +Nous avons trois programmes : Global Development Program, Global Health Program et United States Program. + +“Program” prend une majuscule lorsqu’il est utilisé avec le nom complet (_Global Development Program_) mais pas seul (_le programme accorde des subventions dans plusieurs domaines._). + +Utilisez des points lors de l’abréviation “United States Program” : U.S. Program. + +GH, GD et USP conviennent pour un usage interne, mais sont inappropriés pour des publications externes. + +#### Famille Gates + +William Gates III est officiellement appelé Bill Gates. Dans les documents internes, utilisez Bill, sans surnom ni abréviation. + +Parlez de Melinda Gates (nom complet) pour toute référence formelle. + +Utilisez William H. Gates Sr. pour Bill Gates Sr. Il n’y a pas de virgule entre Gates et Sr. “Bill Sr.” est acceptable dans les documents internes. + +Pluriel : Gateses. N’ajoutez pas d’apostrophe pour le pluriel. Exemple : _Les Gateses ont assisté à l’inauguration du nouveau bâtiment de la Faculté de droit de l’Université de Washington._ + +Possessif : L’apostrophe suit Gates pour une possession au singulier. Exemple : _Le discours de Melinda Gates a été bien accueilli._ L’apostrophe suit Gateses pour ce qui appartient à Bill et Melinda ensemble. Exemple : _La décision des Gateses d’offrir un accès Internet gratuit dans les bibliothèques publiques américaines a augmenté la fréquentation._ + +Vous pouvez aussi écrire : _La décision de Bill et Melinda Gates d’offrir un accès Internet gratuit…_ + +Voir la section Titres de personnes pour les titres formels de Bill, Melinda, Bill Sr. et d’autres dirigeants de la fondation. + +#### Traits d’union + +Il existe peu de règles strictes concernant les traits d’union. En général, nous les utilisons pour faciliter la compréhension. + +Exemples : _En rédigeant pour la Bill & Melinda Gates Foundation, utilisez des exemples de pauvreté du monde réel pour illustrer votre propos._ _En rédigeant pour la Bill & Melinda Gates Foundation, utilisez des exemples de pauvreté mondiale réelle pour illustrer votre propos._ + +Dans le premier, le trait d’union dans “monde réel” relie “monde” et “réel” pour former un seul adjectif décrivant “pauvreté”. Dans le second, le trait d’union dans “pauvreté mondiale” relie “mondiale” et “pauvreté” pour décrire “exemples”. + +Le sens change selon le placement des traits d’union. Là où une série d’adjectifs crée une ambiguïté, utilisez un trait d’union pour clarifier le sens. + +Pour les mots composés à trait d’union, ne mettez une majuscule qu’au premier mot. Exemple : _Coprésidents Bill et Melinda Gates._ + +Pour d’autres usages—modificateurs composés, préfixes/suffixes, fractions—référez-vous à l’Associated Press Stylebook. + +#### Nombres + +Pour les montants en dollars, écrivez en toutes lettres “million” et “milliard”. Utilisez des chiffres et des décimales (pas de fractions). N’allez pas au-delà de deux décimales. Exemple : _La fondation a octroyé 0,45 million à United Way._ + +Pour les nombres qui n’ont rien à voir avec des montants ou des pourcentages, écrivez-les en toutes lettres en dessous de 10 et utilisez des chiffres à partir de 10. Exemple : _Quatre responsables de programme ont effectué 13 visites de terrain._ + +En cas de parallélisme grammatical, la construction parallèle prime. Exemple : _M. Johnson a deux enfants, Kyle, 5 ans, et Frances, 13 ans._ + +Ne jamais commencer une phrase par un chiffre. Écrivez le nombre en toutes lettres ou modifiez la phrase. + +#### Pourcentages + +Écrivez toujours “pour cent” (n’utilisez pas %) et utilisez des chiffres même s’ils sont inférieurs à 10. + +Exemple : _Ce programme représente 6 pour cent de nos subventions._ + +#### Crédits photographiques + +Si la fondation possède l’image que vous utilisez, il n’est pas nécessaire de créditer le photographe. Toutes les images de notre système de gestion des médias sont détenues par la fondation. Si la fondation a acheté une licence d’utilisation, il peut être nécessaire de créditer le photographe. En cas de doute, contactez le Service Communication de la fondation. + +#### Langage clair + +Nous pouvons relever quelques constructions inutilement verbeuses. Par exemple, chez Ripple, nous corrigeons fréquemment “afin de” en simplement “pour”. + +#### Guillemets + +Utilisez les guillemets doubles pour les dialogues et la citation de sources imprimées. Limitez l’utilisation des guillemets de distanciation—destinés à attirer l’attention sur un mot/expression employé(e) dans un sens spécialisé, particulier, ironique, idiomatique ou erroné. Exemple : _La fondation a de plus en plus utilisé les “investissements liés aux programmes” ces dernières années._ + +#### Chaînes citées et ponctuation + +Lorsque vous décrivez des chaînes de caractères exactes dans la documentation technique, la ponctuation (non comprise dans la chaîne) doit-elle être incluse dans les guillemets ? Exemple : les états valides incluent « pending », « in progress » et « completed ». + +#### Noms scientifiques + +Mettez les noms scientifiques en italique et majuscule selon les conventions du domaine scientifique. Première mention en entier, puis abréviations par la suite. Exemple : _utiliser d’abord Salmonella typhi puis S. typhi pour les suivantes._ + +#### Virgule de série + +Dans les listes de trois éléments ou plus, ajoutez une virgule avant la conjonction de coordination “et” ou “ou”. Exemple : _Les trois axes d’intervention de la fondation sont Global Development, Global Health, et le United States Program._ + +#### Espaces après la ponctuation + +Utilisez un seul espace après chaque signe de ponctuation, y compris après les points, les deux-points et les points-virgules. + +#### Conventions d’orthographe et de capitalisation + +_bed net_ : deux mots, pas de trait d’union. + +_email_ : un seul mot, sans trait d’union, en minuscules. + +_foundation_ : en minuscules sauf dans le nom complet de la fondation. + +_grantmaking_ : un seul mot, sans trait d’union. + +_nongovernmental_ : un seul mot, sans trait d’union. + +_nonprofit_ : un seul mot, sans trait d’union. + +_postsecondary_ : un seul mot, sans trait d’union. + +_Washington state_ : “state” en minuscules (sauf dans “Washington State University”, “Washington State Legislature”, etc.). + +_website_ : un mot, en minuscules. + +#### Titres de personnes + +Les titres officiels ne doivent pas comporter de majuscule sauf s’ils précèdent le nom d’une personne ou figurent dans un titre. Exemple : _La coprésidente Melinda Gates prendra la parole au Washington Economic Club cette année._ + +Mettez en minuscules et écrivez les titres en toutes lettres s’ils ne sont pas associés à un nom. Exemple : _Le coprésident de la fondation a publié une déclaration._ + +Mettez en minuscules et écrivez les titres en toutes lettres si la construction est en apposition. Exemple : _Bill Gates, coprésident de la fondation, a commenté la subvention._ + +#### États-Unis + +Écrivez en toutes lettres « États-Unis » lorsqu’il s’agit d’un nom, utilisez l’abréviation « U.S. » (avec points) en adjectif. Dans certains cas, pour désigner une personne venant des États-Unis, « Américain » est acceptable. + +Exemples : _Le ministère américain des Affaires étrangères se trouve aux États-Unis._ _Le programme américain de la fondation…_ + +#### URL + +Référencez les adresses de sites web sans http:// comme ceci : _www.gatesfoundation.org_ diff --git a/docs/fr/community/faqs.md b/docs/fr/community/faqs.md new file mode 100644 index 000000000..375d6b5ab --- /dev/null +++ b/docs/fr/community/faqs.md @@ -0,0 +1,9 @@ +# Utilisation de Vue dans le Markdown + +## Restrictions d'accès à l'API du navigateur + +Étant donné que les applications VuePress sont rendues côté serveur avec Node.js lors de la génération de builds statiques, toute utilisation de Vue doit respecter les [exigences universelles du code](https://ssr.vuejs.org/en/universal.html). En résumé, assurez-vous d’accéder aux API du navigateur / DOM uniquement dans les hooks `beforeMount` ou `mounted`. + +Si vous utilisez ou faites une démonstration de composants qui ne sont pas compatibles avec le SSR (par exemple ceux qui contiennent des directives personnalisées), vous pouvez les envelopper dans le composant intégré `` : + +## diff --git a/docs/fr/community/mojaloop-publications.md b/docs/fr/community/mojaloop-publications.md new file mode 100644 index 000000000..823eff9d9 --- /dev/null +++ b/docs/fr/community/mojaloop-publications.md @@ -0,0 +1,18 @@ +# Publications + +Les publications sont stockées dans le [dépôt Github Documentation Artifacts](https://github.com/mojaloop/documentation-artifacts). + +Voir ci-dessous la liste des publications actuellement disponibles. + +## Sessions de la communauté OSS (présentations et notes) + +- [Janvier 2020 (Lancement de la Phase 4) Session de la communauté OSS](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202020%20OSS%20Community%20Session) +- [Septembre 2019 PI-8 (Clôture de la Phase 3) Session de la communauté OSS](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/September%202019%20PI-8_OSS_community%20session) +- [Juin 2019 PI-7 Session de la communauté OSS](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/June%202019%20PI-7_OSS_community%20session) +- [Avril 2019 PI-6 Session de la communauté OSS](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/April%202019%20PI-6_OSS_community%20session) +- [Janvier 2019 PI-5 Session de la communauté OSS](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202019) + +## Publications standards Mojaloop + +- [Type décimal Mojaloop ; basé sur le type décimal de XML Schema](./discussions/decimal.md) +- [Spécification de l'API Mojaloop](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) diff --git a/docs/fr/community/mojaloop-roadmap.md b/docs/fr/community/mojaloop-roadmap.md new file mode 100644 index 000000000..e495e3ab0 --- /dev/null +++ b/docs/fr/community/mojaloop-roadmap.md @@ -0,0 +1,54 @@ +# La feuille de route Mojaloop + + +La feuille de route Mojaloop est élaborée et maintenue par la fondation Mojaloop, en collaboration avec la grande Communauté. Elle est examinée et mise à jour lors de chaque réunion communautaire, et la dernière mise à jour date de la réunion PI 23 à Lusaka, Zambie. + +La feuille de route est construite autour du concept des trois piliers.

+ +Les piliers sont : + +1. **Faciliter l'adoption** – créer des outils permettant aux développeurs et aux adoptants de déployer Mojaloop avec un minimum de tracas et de complications, dans un environnement adapté à leurs besoins techniques, opérationnels ou réglementaires. +2. **Atteindre l'échelle** – mettre à disposition autant de fonctionnalités "à valeur ajoutée" que possible, afin de soutenir les adoptants dans la réalisation de leurs objectifs, que ce soit pour la rentabilité financière, le soutien à des objectifs sociaux, ou même les deux à la fois. +3. **Connecter à d'autres systèmes** – Nous reconnaissons que Mojaloop n'est pas la seule solution d'interopérabilité de paiements, donc dans ce pilier nous cherchons à développer autant d'options que possible pour s'interconnecter avec d'autres services de paiement et commutateurs (switches), et nous assurer que le moteur Mojaloop sous-jacent est optimisé pour supporter ces interconnexions. + +Les Piliers sont eux-mêmes appuyés par des **Travaux Fondamentaux de Produit Qualité**, qui soutiennent ensemble la maintenance continue et l'amélioration de la solution de base Mojaloop. + +Voici la feuille de route complète pour PI-23 : ![Mojaloop Roadmap](https://github.com/mojaloop/product-council/blob/main/PI%2023%20Mojaloop%20Roadmap.png?raw=true). + +Cette révision de la feuille de route s'étend de la sortie de Mojaloop 15.1 à la fin du PI 21 (juin 2023), jusqu'à la fin du PI 26 (février 2025). Les versions de Mojaloop sont passées de numéros à des noms au cours du PI 22 ; Mojaloop Acacia est donc sur le point d'être publié ; il sera suivi par Mojaloop Zambezi, à la fin du PI 23, construit sur Acacia et intégrant les résultats de travaux comme les Paiements Commerçants et l'échange de devises (Foreign Exchange) (transferts internationaux). + +Nous prévoyons actuellement de publier Mojaloop Baobab, basé sur l'effort de développement vNext et l'architecture de référence, à la fin du PI 24, soit fin juin 2024 (bien que cela reste conditionné par l'atteinte du niveau requis de qualité et de fonctionnalité, à réaliser via un processus de transition disposant de sa propre feuille de route). À son tour, il sera remplacé par Mojaloop Meerkat à la fin d'octobre 2024, qui enrichira Baobab en ajoutant de nouveaux résultats de travaux, encore à définir. D'autres versions suivront le même processus. + +À droite de la feuille de route se trouvent quatre tableaux. Ils listent les travaux candidats pour chaque pilier et pour la fondation produit qualité. Ceux-ci ont été identifiés comme des fonctionnalités souhaitables lors de divers événements communautaires, mais n'ont pas encore été adoptés par la Communauté. + +Chacun des piliers a ses propres travaux techniques. Pour PI 23, les travaux techniques suivants ont été adoptés. + +## Faciliter l’adoption +* Support pour le déploiement sur site + * Améliorer la prise en charge du déploiement non Cloud de Mojaloop, lorsque cela est requis pour des raisons réglementaires ou autres. +* Outils de participation + * Garantir une gamme d’options pour que les DFSP participants puissent se connecter à un Hub Mojaloop, et que ces options offrent des capacités de connectivité comparables. + +## Atteindre l’échelle +* Paiements commerçants + * Support des paiements commerçants utilisant un Hub Mojaloop comme moteur de paiement pour un schéma marchand offrant des paiements via code QR ou USSD. Cela inclut l’enregistrement des commerçants et la prise en charge de l’acquisition de commerçants. + +## Connecter à d’autres systèmes +* Règlement de nouvelle génération + * Se connecter à d'autres systèmes de paiement et effectuer des transactions transfrontalières augmente la complexité des processus de règlement dont un commutateur (switch) a besoin, et ce travail met à jour le moteur de règlement de Mojaloop pour offrir la flexibilité requise. +* Change (Foreign Exchange) + * Ce travail améliore le Hub Mojaloop pour supporter des transactions multi-devises, via l’intégration à un fournisseur de change externe (FXP). La première version supportera un modèle (l’expéditeur convertit) et un FXP ; les prochaines versions supporteront plusieurs modèles et plusieurs FXP, ainsi que l’utilisation d’une devise de réserve en intermédiaire. +* Intégration MOSIP + * Afin de mieux soutenir les paiements sociaux et les programmes nationaux de paiement, ce travail développe une solution qui permettra de diriger les paiements vers une identité numérique MOSIP, au lieu par exemple d’un numéro de téléphone mobile. Ce travail vise aussi une plus grande intégration avec d’autres projets open source DPG, dont Mifos, PHEE et OpenG2P, pour permettre l’utilisation des identifiants MOSIP lors de la génération de listes de paiements pour les versements sociaux de masse. + +## Produit Qualité +* Caractérisation des performances + * Identifier et implémenter les modifications du logiciel principal du Hub Mojaloop pouvant améliorer les performances, à l’approche de plusieurs déploiements nationaux. +* Adoption de Tigerbeetle + * Utiliser Tigerbeetle pour mettre à jour les registres lors du traitement des transactions afin d’obtenir des performances encore meilleures (cela n’est pas attendu avant la sortie de Mojaloop Baobab). +* Équipe principale (Core Team) + * Maintient le cœur de Mojaloop par la correction de bogues critiques, l’amélioration de fonctionnalités prioritaires, la mise à jour des dépendances, et assure le processus de publication des services centraux ainsi que de certains services ou produits adjacents à la plateforme Mojaloop. +* Qualité et sécurité de la plateforme + * Évaluation, maintenance et amélioration de la cybersécurité de la plateforme Mojaloop, couvrant la connectivité avec les DFSP participants (y compris les transactions) et la sécurité des portails opérateurs du hub. + +En plus de ces travaux techniques, il existe plusieurs **Travaux Stratégiques**, qui visent à traiter des problématiques à long terme, comme la migration vers la norme ISO 20022 ou la veille sur les évolutions des transactions transfrontalières. Il est prévu que les livrables de ces workstreams stratégiques incluent notamment la spécification périodique de workstreams techniques candidats, susceptibles d’être adoptés dans de futurs PI. diff --git a/docs/fr/community/standards/ai_policy.md b/docs/fr/community/standards/ai_policy.md new file mode 100644 index 000000000..428f64474 --- /dev/null +++ b/docs/fr/community/standards/ai_policy.md @@ -0,0 +1,163 @@ +# Politique relative à l’usage responsable d’outils d’intelligence artificielle (IA) par les membres de la communauté + +- Version : 1.0 +- Date d’entrée en vigueur : 2026-04-08 +- Auteur : James Bush (jbush@mojaloop.io) +- S’applique à : Tous les contributeurs, mainteneurs, adoptants et participants à la communauté Mojaloop et à ses projets associés, y compris les dépôts sous l’organisation GitHub Mojaloop. + +**Divulgation relative à l’IA** Ce document comporte du contenu produit avec l’aide de ChatGPT 5.2. L’ensemble du contenu a été relu et validé par l’auteur. + +--- + +## 1. Objet + +Cette politique définit des lignes directrices claires et pragmatiques pour l’usage responsable d’outils d’intelligence artificielle (IA) au sein de la communauté Mojaloop. + +La Fondation Mojaloop soutient l’innovation et le gain de productivité, y compris l’usage d’outils assistés par l’IA. Toutefois, la transparence, la responsabilité et la confiance de la communauté demeurent essentielles. Cette politique vise à ce que l’usage de l’IA renforce la collaboration sans compromettre l’ouverture, l’intégrité de la paternité des contenus ni la qualité technique. + +--- + +## 2. Principes directeurs + +Tout usage de l’IA au sein de la communauté Mojaloop doit respecter les principes suivants : + +1. **Responsabilité humaine** – Un contributeur humain assume toujours la responsabilité du résultat final. +2. **Transparence** – L’usage de contenu généré par l’IA doit être clairement indiqué. +3. **Qualité et sécurité** – Les productions assistées par l’IA doivent respecter les normes d’ingénierie et de documentation de Mojaloop. +4. **Intégrité de la communauté** – L’IA ne doit pas être utilisée de manière à perturber ou submerger les processus communautaires. + +--- + +## 3. Usages autorisés des outils d’IA + +### 3.1 L’IA comme prise de notes lors des appels communautaires + +Les outils d’IA peuvent servir à prendre des notes pendant les **appels publics de la communauté Mojaloop**, sous réserve des conditions suivantes : + +- L’utilisateur de l’outil d’IA **doit être personnellement présent** à l’appel, sauf autorisation préalable de l’animateur ou de l’animatrice de la réunion. +- Les outils de prise de notes par l’IA ne peuvent pas rejoindre les appels indépendamment d’un participant humain sans autorisation préalable explicite de l’animateur ou de l’animatrice. +- Les robots IA anonymes ne sont pas autorisés. Tout robot IA doit indiquer publiquement le membre humain de la communauté qu’il représente. +- Les outils de prise de notes par l’IA ne peuvent rejoindre que les appels pour lesquels l’enregistrement est activé. + +**Justification :** +La communauté Mojaloop valorise la discussion ouverte et la sécurité psychologique. La présence de nombreux robots d’enregistrement ou de synthèse sans supervision peut décourager la participation et nuire à la collaboration. + +--- + +### 3.2 Assistance par l’IA pour la documentation + +Les membres de la communauté peuvent utiliser des outils d’IA pour : + +- Rédiger de la documentation +- Améliorer la clarté ou la grammaire +- Reformater le contenu +- Produire des synthèses +- Traduire du contenu + +Toutefois : + +- Tout document dans lequel l’IA a généré **une partie du contenu** doit comporter, dans l’en-tête du document, une mention claire indiquant : + - que des outils d’IA ont été utilisés ; + - quels outils d’IA ont été utilisés. + +**Exemple de mention de divulgation :** + + _Ce document comporte du contenu produit avec l’aide de [Nom de l’outil]. L’ensemble du contenu a été relu et validé par l’auteur._ + +Le défaut de divulgation d’une génération assistée par l’IA peut entraîner le rejet du document ou son renvoi pour correction. + +**Justification :** +La transparence préserve la confiance dans la paternité des textes et permet aux lecteurs et lectrices d’évaluer correctement la provenance. + +--- + +### 3.3 Assistance par l’IA pour la création et le débogage du code + +Les outils d’IA peuvent être utilisés pour : + +- Génération de code +- Suggestions de code +- Aide au refactoring +- Support au débogage +- Génération de tests +- Génération de documentation pour le code + +Les règles suivantes s’appliquent toutefois strictement : + +#### 3.3.1 Obligation de soumission par un humain + +- Toutes les pull requests (PR), issues et soumissions de code doivent être effectuées par des contributeurs humains. +- Les agents IA entièrement automatisés ne peuvent pas soumettre de PR, correctifs de bogues ou modifications de code. +- Toutes les pull requests (PR), issues et soumissions de code doivent respecter les exigences du processus d’ingénierie produit de la communauté Mojaloop. +- La seule exception concerne les outils automatisés officiellement pris en charge et déjà intégrés aux flux de travail GitHub (par ex. robots de mise à jour des dépendances tels que Dependabot). + +Toute soumission par un agent automatisé autre que les outils natifs GitHub approuvés sera **rejetée sans examen**. + +--- + +#### 3.3.2 Revue humaine obligatoire + +Pour tout code assisté par l’IA : + +- il **DOIT** être soigneusement relu par la personne qui le soumet ; +- il **DOIT** être entièrement compris par cette personne ; +- il **DOIT** respecter les normes de codage et les principes d’architecture de Mojaloop ; +- il **DOIT** réussir l’ensemble des tests automatisés et des pipelines de validation. + +Un code manifestement généré par l’IA et qui n’a pas été correctement relu, validé et compris par le contributeur humain ne sera pas accepté dans la base de code. + +La personne qui soumet la PR demeure entièrement responsable de : + +- l’exactitude ; +- la sécurité ; +- le respect des licences ; +- la cohérence architecturale ; +- la maintenabilité à long terme. + +**Justification :** +Mojaloop évolue dans le domaine des services financiers. L’intégrité, la sécurité et l’exactitude du code sont non négociables. + +--- + +## 4. Usages interdits + +Les usages suivants de l’IA ne sont pas autorisés dans les processus de la communauté Mojaloop : + +- Robots IA non supervisés rejoignant les appels communautaires. +- Agents IA entièrement autonomes soumettant des PR ou des issues. +- Soumission de contenu généré par l’IA sans la divulgation requise (lorsqu’elle s’applique). +- Déléguer des décisions d’architecture ou de conception à des outils d’IA. +- Utiliser des outils d’IA pour extraire, résumer ou redistribuer des informations restreintes ou confidentielles sans autorisation. + +--- + +## 5. Application + +Les mainteneurs et les personnes chargées de la revue peuvent : + +- Demander l’ajout de mentions de divulgation ; +- Rejeter des PR qui semblent insuffisamment relues ; +- Fermer sans commentaire les soumissions d’agents automatisés ; +- Demander des précisions sur le recours à l’IA. + +Les manquements répétés ou délibérés peuvent être escaladés conformément aux procédures de gouvernance de la communauté Mojaloop. + +--- + +## 6. Révision future + +Les capacités de l’IA évoluent rapidement. Cette politique sera réexaminée périodiquement par la Fondation Mojaloop et les mainteneurs de la communauté afin qu’elle reste adaptée, pratique et alignée sur les valeurs de la communauté. + +--- + +## 7. Synthèse + +Les outils d’IA sont autorisés au sein de la communauté Mojaloop lorsqu’ils sont utilisés de manière responsable et transparente. + +- Les humains doivent demeurer responsables. +- L’IA ne doit pas submerger les processus communautaires. +- La divulgation est requise dans la documentation. +- Le code doit toujours être relu et soumis par un humain. + +La Fondation Mojaloop encourage une adoption réfléchie des outils d’IA de manière à renforcer, et non à diluer, la qualité, la confiance et l’esprit collaboratif de l’écosystème Mojaloop. + diff --git a/docs/fr/community/standards/creating-new-features.md b/docs/fr/community/standards/creating-new-features.md new file mode 100644 index 000000000..79eb9c2b0 --- /dev/null +++ b/docs/fr/community/standards/creating-new-features.md @@ -0,0 +1,141 @@ +# Créer de nouvelles fonctionnalités + +## Fork + +Créez un fork du dépôt Mojaloop dans votre espace personnel. Veillez à maintenir la branche `master` à jour. + +Voir la documentation : [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/) + +1. Clonez le dépôt via le bouton Fork de Git (voir la doc ci-dessus). +2. Clonez votre fork : `git clone https://github.com//.git` +3. Synchronisez votre fork avec Mojaloop + + Ajoutez un nouveau dépôt distant amont pour Mojaloop : `$ git remote add mojaloop https://github.com/mojaloop/.git` + + Vous devez voir deux remotes : + + ```bash + git remote -v + origin https://github.com//.git (fetch) + origin https://github.com//.git (push) + mojaloop https://github.com/mojaloop/.git (fetch) + mojaloop https://github.com/mojaloop/.git (push) + ``` + +4. Pour synchroniser votre branche courante : `git pull mojaloop ` — cela fusionnera tous les changements du dépôt Mojaloop dans votre fork. +5. Poussez les changements vers votre fork : `git push origin ` + +## Créer une branche + +Créez une nouvelle branche à partir de `master` avec le format : `/` où `issue#` provient du ticket GitHub et `issueDescription` est la description du ticket en CamelCase. + +1. Créez et basculez sur la branche : `git checkout -b /` +2. Poussez la branche vers votre remote : `git push origin /` + +Où `` peut être l’un des suivants : + +| branchType | Description | +| :--- | :--- | +| hotfix | Branche `hotfix` pour les correctifs urgents. | +| feature | Branche de `développement` pour les nouvelles fonctionnalités ou la maintenance en cours. | +| fix | Branche de `développement` pour corriger un bug. | +| release | Branche de release contenant un instantané d’une release. | +| backup | Branche de sauvegarde temporaire, en général lors de la maintenance du dépôt. | +| major | Branche de `pré-release` pour les changements majeurs. | +| minor | Branche de `pré-release` pour les changements mineurs. | +| patch | Branche de `pré-release` pour les correctifs. | + +## Branche principale + +La branche principale doit toujours contenir du code exploitable en déploiement. +Les outils d’automatisation de build tentent de construire et tester le code de cette branche et d’y apposer des étiquettes de version semver en cas de succès. Les artefacts résultants seront également publiés sur les dépôts concernés (npm, Docker, etc.) afin de pouvoir être utilisés par d’autres modules. + +## Branches hotfix + +Ces branches sont créées à partir d’une étiquette sur la branche principale lorsque la version correspondante est en production et qu’un problème doit être corrigé alors que la branche principale contient déjà des versions publiées plus récentes ou est en développement actif, de sorte que le correctif ne peut pas être intégré de façon stable et opportune. Elles sont nommées selon le motif `hotfix/`. Il est fortement recommandé de valider d’abord le correctif sur `main` (ou une branche fusionnée vers `main`) puis de le cherrer-piquer sur la branche hotfix. Les branches hotfix ne sont en général pas fusionnées dans `main` et ne sont pas supprimées, car elles peuvent servir à des correctifs ultérieurs. Sur ces branches, les outils de build créent des étiquettes et publient les paquets en n’incrémentant que le numéro de patch. + +## Branches de pré-release + +Les branches de pré-release servent lorsque le développement exige des artefacts disponibles dans le dépôt pour des tests automatisés ou manuels de fonctionnalités ou correctifs en cours, non prêts pour une release. +Elles permettent d'éviter le travail manuel associé à la publication dans les dépôts. Les artefacts publiés ont des versions et étiquettes de pré-release selon semver. Les outils de build créent et publient ces versions de pré-release et étiquettent la branche dans Git pour chaque commit construit avec succès. Les branches de pré-release sont en général créées depuis `main` puis fusionnées dedans. Les motifs sont : + +- `major/` — lorsque la branche doit inclure des changements rupturistes. +- `minor/` — lorsqu’elle n’inclut que des nouvelles fonctionnalités sans rupture. C’est le cas le plus courant pour le nouveau développement. +- `patch/` — lorsqu’elle n’inclut que des correctifs sans nouvelles fonctionnalités ni rupture. Peuvent parfois partir de branches hotfix lorsque des correctifs doivent d’abord être publiés pour les tests avant fusion dans la hotfix. + +Les scripts de build publient automatiquement une version de pré-release et une étiquette en utilisant `` comme identifiant de pré-release suivi d’un numéro séquentiel, par ex. `X.Y.Z-.sequence`, où X, Y ou Z est incrémenté automatiquement une seule fois au premier build de la branche selon le préfixe major/minor/patch, et `sequence` augmente à chaque build réussi. Pour les branches de pré-release, il faut que `` respecte les règles d’identifiant de pré-release de semver. Une branche minor de pré-release peut finir par inclure une rupture ; les développeurs doivent alors s’assurer qu’il n’y a pas en parallèle un autre développement majeur actif, les deux branches pourraient viser la même version majeure. En général, les développeurs doivent être vigilants lorsque plusieurs branches de pré-release sont en cours de développement, et s’assurer que la version finale publiée n’entre pas en conflit avec d’autres branches de pré-release ; une modification manuelle de la version peut être nécessaire lors de la résolution d’un conflit de fusion sur la propriété `version`. + +## Branches de développement + +Ces branches servent surtout au développement de nouvelles fonctionnalités lorsqu’aucun artefact ne doit être publié dans les dépôts de paquets tant que la branche n’est pas fusionnée. Elles sont créées depuis `main` ou des branches de pré-release. Leurs noms ne doivent correspondre à aucun des motifs ci-dessus. Les formes fréquentes sont `feature/` ou `fix/`. Une branche de développement peut ultérieurement être renommée en branche de pré-release si le processus l’exige. Utiliser une branche de développement plutôt qu’une pré-release limite les publications et étiquettes excessives, plus longues et qui encombrent le dépôt. + +## Travailler sur votre fonctionnalité + +Avant de commencer à travailler sur votre fonctionnalité, veuillez parcourir les étapes suivantes pour contribuer à maintenir la base de code Mojaloop en bon état et protégée contre les problèmes de sécurité. Notez que certaines de ces étapes sont obligatoires pour que votre PR passe les contrôles de validation CI (comme indiqué ci-dessous). + +Il est recommandé d’exécuter `npm test` après chaque étape pour éviter d’introduire de régressions. + +1. OBLIGATOIRE — Mettre à jour les dépendances + + ```bash + npm run dep:check + ``` + + > + > IMPORTANT + > + > Notez toute mise à jour de dépendance en version majeure : elle peut introduire un CHANGEMENT RUPTURISTE et nécessiter du refactoring de code pour s'adapter au changement. + > + > Voir [Gestion des dépendances](./guide.md#dependency-upgrades) pour ignorer une mise à jour si nécessaire. + > + + Puis pour mettre à jour et installer : + + ```bash + npm run dep:update && npm i + ``` + +2. OBLIGATOIRE — Vérifications de vulnérabilités + + ```bash + npm run audit:check + ``` + +[npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) peut appliquer les correctifs connus disponibles : + + ```bash + npm audit fix --package-lock-only + ``` + + > + > IMPORTANT + > + > Notez que tout changement de version de dépendance peut introduire un CHANGEMENT RUPTURISTE. + > + > Voir [Gestion des dépendances](./guide.md#dependency-auditing) pour plus d’informations. + > + + S’il n’existe pas de correctif utilisable pour la vulnérabilité : + + 1. Si le dépôt utilise [audit-ci](https://www.npmjs.com/package/audit-ci) — mettez à jour `audit-ci.jsonc` en ajoutant l’entrée à la liste `allowlist` avec un commentaire expliquant la raison. + 2. Si le dépôt utilise [npm-audit-resolver](https://www.npmjs.com/package/npm-audit-resolver) — exécutez `npm run audit:resolve` et suivez les invites CLI pour tenter de corriger ou d'ignorer le problème (s'il n'existe pas de correctif disponible). + +3. FACULTATIF — Mettre à jour NodeJS vers la version `Active LTS` + + Consultez la version `Active LTS` sur [les releases officielles NodeJS](https://nodejs.org/en/about/releases). + + 1. Mettre à jour `.nvmrc` + + 2. Mettre à jour le `Dockerfile` (conteneurs *builder* et *runtime*), voir [Environnement d’exécution — 2. Conteneur (Docker) et système d’exploitation](./guide.md#runtime-environment). + + > + > IMPORTANT + > + > La montée de version de NodeJS peut introduire un CHANGEMENT RUPTURISTE et nécessiter du refactoring de code pour s’adapter au changement. + > + +## Ouvrir une pull request (PR) + +Lorsque votre fonctionnalité est prête pour revue, créez une pull request depuis votre branche de fonctionnalité vers la branche `main` du dépôt Mojaloop. + +Consultez nos directives pour les exigences spécifiques lors de la création de pull requests [ici](../contributing/pr-guidance.md). diff --git a/docs/fr/community/standards/guide.md b/docs/fr/community/standards/guide.md new file mode 100644 index 000000000..de314023d --- /dev/null +++ b/docs/fr/community/standards/guide.md @@ -0,0 +1,652 @@ +# Normes + +> *Note :* Ces normes ne sont en aucun cas figées dans le marbre ; en tant que communauté, nous souhaitons toujours les faire évoluer et améliorer Mojaloop. Pour proposer une modification de ces normes ou suggérer des améliorations supplémentaires, n’hésitez pas à contacter le canal Design Authority sur le Slack Mojaloop (#design-authority). + +## Invariants Mojaloop + +Mojaloop définit des [invariants](./invariants.md) importants à comprendre et à respecter lorsque vous contribuez à la base de code. + +Ces invariants découlent des [principes Level One](https://www.leveloneproject.org/wp-content/uploads/2020/07/L1P_Guide_2019_Final.pdf) et d’autres exigences métier telles qu’arrêtées par le conseil de gouvernance technique Mojaloop, le comité de contrôle des changements d’API, la Design Authority et le conseil produit. Ils visent à ce que la plateforme conserve des caractéristiques adaptées à une exploitation de type infrastructure nationale. + +Assurez-vous de connaître ces invariants avant de contribuer. + +## Environnement d’exécution + +Les normes d’exécution suivantes s’appliquent à Mojaloop. + +### Microservices et bibliothèques + +1. Javascript + + NodeJS est l’environnement d’exécution standard pour tous les services et composants Mojaloop pour l’exécution des fichiers de code source Javascript. + + Notre objectif est que tous les services NodeJS tournent sur la dernière version `Active LTS` (*Long Time Support*) de NodeJS, conformément au [cycle de release NodeJS](https://nodejs.org/en/about/releases/). + +2. Conteneur (Docker) et système d’exploitation (*OS*) + + Les microservices Mojaloop sont construits à partir de l’image de base `node:-alpine`, où `NODE_ACTIVE_LTS_VERSION` est la LTS NodeJS courante selon le [cycle de release NodeJS](https://nodejs.org/en/about/releases/). Voir [DockerHub](https://hub.docker.com/_/node?tab=tags&page=1&name=alpine) pour la liste des images officielles Node Alpine. + + > NOTE : pour `NODE_ACTIVE_LTS_VERSION`, utilisez la version sémantique complète `--`. + > + > `node:16.15.0-alpine ` <-- correct + > + > `lts-alpine3.16` <-- incorrect + > + + 1. Exemple de `Dockerfile` **Javascript** standard : + + ```docker + FROM node:-alpine as builder + WORKDIR /opt/app + + RUN apk --no-cache add git + RUN apk add --no-cache -t build-dependencies make gcc g++ python3 libtool libressl-dev openssl-dev autoconf automake \ + && cd $(npm root -g)/npm \ + && npm config set unsafe-perm true \ + && npm install -g node-gyp + + COPY package*.json /opt/app/ + + RUN npm ci --production + + FROM node:-alpine + WORKDIR /opt/app + + # Create empty log file & link stdout to the application log file + RUN mkdir ./logs && touch ./logs/combined.log + RUN ln -sf /dev/stdout ./logs/combined.log + + # Create a non-root user: ml-user + RUN adduser -D ml-user + USER ml-user + + # Copy builder artefact + COPY --chown=ml-user --from=builder /opt/app . + + # Copy source files + COPY src /opt/app/src + + # Copy default config + COPY config /opt/app/config + + EXPOSE + CMD ["npm", "run", "start"] + ``` + + 2. Exemple de `Dockerfile` **Typescript** standard : + + ```docker + FROM node:-alpine as builder + USER root + WORKDIR /opt/app + + RUN apk update \ + && apk add --no-cache -t build-dependencies git make gcc g++ python3 libtool autoconf automake openssh \ + && cd $(npm root -g)/npm \ + && npm config set unsafe-perm true \ + && npm install -g node-gyp + + COPY package.json package-lock.json* ./ + + RUN npm ci + + FROM node:-alpine + WORKDIR /opt/app + + # Create empty log file & link stdout to the application log file + RUN mkdir ./logs && touch ./logs/combined.log + RUN ln -sf /dev/stdout ./logs/combined.log + + # Create a non-root user: ml-user + RUN adduser -D ml-user + USER ml-user + + # Copy builder artefact + COPY --chown=ml-user --from=builder /opt/app ./ + + COPY src /opt/app/src + COPY config /opt/app/config + + # NPM script to build source (./src) to destination (./dist) + RUN npm run build + + # Prune devDependencies + RUN npm prune --production + + # Prune source files + RUN rm -rf src + + EXPOSE + CMD ["npm", "run", "start"] + ``` + +### Pipelines CI (Intégration Continue) + +Les jobs CI Mojaloop s’exécutent sur la version Ubuntu LTS courante selon le [cycle de release Ubuntu](https://ubuntu.com/about/release-cycle). + +### Kubernetes + +Les charts Helm Mojaloop ([mojaloop/helm](https://github.com/mojaloop/helm), [mojaloop/charts](https://github.com/mojaloop/charts)) sont déployés et vérifiés sur la version Kubernetes LTS courante selon le [cycle de release Kubernetes](https://kubernetes.io/releases/). + +## Guide de style + +La communauté Mojaloop fournit des lignes directrices pour le style de code. Elles contribuent à maintenir une base de code de qualité, maintenable et cohérente. + +Ces guides sont choisis car ils peuvent être appliqués et vérifiés avec des outils courants et peu de personnalisation. Bien que nous reconnaissions que les développeurs ont des préférences personnelles pouvant entrer en conflit avec ces règles, nous privilégions la cohérence au [bike-shedding](https://en.wikipedia.org/wiki/Law_of_triviality). + +L’objectif est de faciliter le flux de travail des développeurs et de réduire les commits dont les changements sont motivés par le seul style plutôt que par le fond. En réduisant le bruit dans les diffs, on facilite le travail des relecteurs. + +## Style de code + +### Conventions de nommage + +Pour éviter toute confusion et garantir la cohérence des conventions entre les différents langages : + +- N’utilisez pas d’abréviations ou de contractions dans les identifiants. Ex. : `SettlementWindow` plutôt que `SetWin`. +- N’utilisez pas d’acronymes non universellement acceptés en informatique. +- Lorsque c’est pertinent, utilisez des acronymes reconnus pour raccourcir. Ex. : `UI` pour *User Interface*. +- Utilisez le Pascal case ou le camel case pour les noms de plus de deux caractères, selon le contexte (classes vs variables). Ex. : `SettlementWindow` (classe) ou `settlementWindow` (variable). +- Mettez en majuscules les acronymes de deux lettres isolés, ex. `ID` plutôt que `Id`. Ex. : `/transfer/{{ID}}` plutôt que `/transfer/{{Id}}` pour un paramètre d’URI. +- Évitez les abréviations dans les identifiants ou paramètres. Si vous devez en utiliser, camel case pour les abréviations de plus de deux caractères, même si cela diverge de l’abréviation usuelle. +- Utilisez le SCREAMING_SNAKE_CASE pour les énumérations. Ex. : `RECORD_FUNDS_OUT_PREPARE_RESERVE`. + +Réf. : [Microsoft - Design Guidelines for Class Library Developers](https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/141e06ef(v=vs.71)?redirectedfrom=MSDN) + +### Javascript + +Mojaloop suit le style Javascript défini par [StandardJS](https://standardjs.com/). Règles complètes : [Standard Rules](https://standardjs.com/rules.html). Extraits : + +- *2 espaces* pour l’indentation + +```js +function helloWorld (name) { + console.log('hi', name) +} +``` + +- *Guillemets simples* pour les chaînes sauf pour éviter d’échapper. + +```js +console.log('hello there') // ✓ ok +console.log("hello there") // ✗ avoid +console.log(`hello there`) // ✗ avoid +``` + +- Pas de point-virgules. (voir : 1, 2, 3) + +```js +window.alert('hi') // ✓ ok +window.alert('hi'); // ✗ avoid +``` + +### Typescript + +> *Note : Standard et Typescript* +> +> À mesure que nous introduisons davantage de TypeScript dans la base de code, Standard devient moins adapté et peut même nuire à notre flux de travail si l’on tente d’appliquer Standard au Javascript compilé depuis TypeScript. +> Il faudra évaluer d’autres options pour Typescript, par ex. Prettier + ESLint. + +Voir le dépôt [template-typescript-public](https://github.com/mojaloop/template-typescript-public) pour la configuration Typescript de référence. + +### YAML + +Les désérialiseurs YAML peuvent varier ; règles suivantes : +> Crédit : exemples issus du [guide de style Flathub](https://github.com/flathub/flathub/wiki/YAML-Style-Guide) + +- Indentation de 2 espaces +- Toujours indenter les éléments enfants + +```yaml +# BON : +modules: + - name: foo + sources: + - type: bar + +# MAUVAIS : +modules: +- name: foo + sources: + - type: bar +``` + +- N’alignez pas les valeurs sur des colonnes + +```yaml +# MAUVAIS : +id: org.example.Foo +modules: + - name: foo + sources: + - type: git +``` + +### sh + bash + +- Le shebang doit respecter l’environnement local de l’utilisateur : + +```bash +#!/usr/bin/env bash +``` + +Le script utilisera le `bash` défini dans l’environnement plutôt qu’un chemin codé en dur. + +- Pour référencer d’autres fichiers, évitez les chemins relatifs simples : + +En effet, si quelqu'un exécute le script depuis un répertoire différent de celui où il se trouve, le script risque fort de ne pas fonctionner. + +```bash +# MAUVAIS : +cat ../Dockerfile | wc -l + +# BON : +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cat ${DIR}/../Dockerfile | wc -l +``` + +Autres bonnes pratiques bash : [Best Practices for Writing Shell Scripts](https://kvz.io/bash-best-practices.html) + +## Documentation + +- Rédiger la documentation en Markdown. +- Les schémas dessinés à la main doivent utiliser un format SVG éditable (ex. : architecture / composants / blocs / diagrammes de transition d'état), exportés depuis [diagrams.net](https://app.diagrams.net) + > NOTE : intégrez le diagramme éditable lors de l’export SVG depuis [diagrams.net](https://app.diagrams.net) ! +- Diagrammes de séquence : PlantUML +- Les documents de discussion doivent être placés dans `/community/archive/discussion-docs`. +- Il est déconseillé d’utiliser Google Docs et autres outils propriétaires pour la collaboration à l’échelle de la communauté. + +## Structure de répertoires + +Outre le style de code, la communauté recommande la structure suivante afin que les développeurs puissent passer facilement d’un projet à l’autre, et que nos outils et configurations (`.circleci/config.yml`, `Dockerfiles`, etc.) puissent être portés d’un projet à l’autre avec des modifications mineures. + +Structure attendue : + +```bash +├── README.md # Infos générales : prérequis, tests, etc. +├── LICENSE.md # Descripteur de licence Mojaloop standard. +├── package.json # Descripteur npm du projet. +├── package-lock.json # Arbre de dépendances exact dans le temps. +├── nvmrc.json # NVMRC : runtime NodeJS (de préférence Active LTS). +├── .ncurc.yaml # Ignore pour le script dep:check (npm-check-updates). +├── Dockerfile # Optionnel +├── docker-compose.yml # Optionnel (dépendances backend, etc.) +├── .npmignore # Optionnel — publication des bibliothèques npm. +├── .gitignore # Fichier ignore GitHub. +├── src # Sources du projet. +│ ├── index. # Point d’entrée principal. +│ ├── . # Convention des fichiers sources. +│ └── ... +├── dist # Javascript compilé (voir tsconfig). +├── test # Tests, au minimum : +│ ├── unit # Tests unitaires, structure alignée sur `./src`. +│ │ ├── .test. +│ │ └── ... +│ ├── integration # Tests d’intégration. +│ ├── functional # Tests fonctionnels. +│ └── util # Scripts et helpers de test. +└── config + └── default.json # Configuration par défaut. +``` + +## Fichiers de configuration + +Ces fichiers renforcent les styles de code ci-dessus : + +### EditorConfig + +> EditorConfig est pris en charge nativement dans de nombreux IDE. Voir le [guide EditorConfig](https://editorconfig.org/). + +`.editorconfig` + +```ini +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[{*.js,*.ts,package.json,*.yml,*.cjson}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false +``` + +### NYC (couverture de code) + +`.nycrc.yml` + +```yml +temp-directory: "./.nyc_output" +check-coverage: true +per-file: true +lines: 90 +statements: 90 +functions: 90 +branches: 90 +all: true +include: [ + "src/**/*.js" +] +reporter: [ + "lcov", + "text-summary" +] +exclude: [ + "**/node_modules/**", + '**/migrations/**' +] +``` + +### Typescript + +`.tsconfig.json` + +```json +{ + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "lib", + "coverage" + ], + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": [ + "esnext" + ], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "outDir": "./dist", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "baseUrl": "./", + "paths": { + "*": [ + "src/*", + "node_modules/*" + ] + }, + "esModuleInterop": true + } +} +``` + +`.eslintrc.js` + +```js +module.exports = { + parser: '@typescript-eslint/parser', // Specifies the ESLint parser + extends: [ + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier + 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. + // Enforces ES6+ import/export syntax + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', + ], + parserOptions: { + ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off' + }, + overrides: [ + { + // Disable some rules that we abuse in unit tests. + files: ['test/**/*.ts'], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + }, + }, + ], +}; +``` + +Configuration Typescript détaillée (`package.json`, `jest.config.js`, etc.) : [Typescript Template Project](https://github.com/mojaloop/template-typescript-public). + +## Gestion des dépendances + +### Mises à jour des dépendances + +Il est important d’utiliser des dépendances à jour afin d’atténuer les risques de sécurité. + +#### NodeJS + +Installez [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) : + +```bash +npm install -D npm-check-updates +``` + +Ajoutez dans `package.json` : + +```json +"scripts": { + "dep:check": "npx ncu -e 2", + "dep:update": "npx ncu -u" +} +``` + +Pour vérifier les mises à jour : + +```bash +npm run dep:check +``` + +Pour installer les dernières versions : + +```bash +npm run dep:update && npm i +``` + +Si une dépendance ne peut pas être mise à jour pour une raison valide, ajoutez `.ncurc.yaml` à la racine avec la dépendance dans `reject` et un `comment` : + +```yaml +## TODO : raison pour chaque rejet et comment le traiter (story, etc.). +reject: [ + # TODO: + "", +] +``` + +Moyens pour maintenir les dépendances à jour : + +##### Hook Git pre-commit + +Validation locale à chaque commit Git. + +Ajoutez `dep:check` comme hook pre-commit avec [Husky](https://www.npmjs.com/package/husky) : + +```bash +npx husky add .husky/pre-commit "npm run dep:check" +``` + +> On peut contourner avec `git commit -nm `. Un job CI `test-dependencies` (section suivante) est donc nécessaire. + +##### Validations CI automatisées + +Contrôles lors des revues et releases ; évite le contournement du hook. + +Les configs CI (`.circleci/config.yml`) doivent inclure un job `test-dependencies` (`npm run dep:check`) pour les PR, fusions vers la branche principale et releases étiquetées. + +### Audit des dépendances + +#### NodeJS + +Installez [audit-ci](https://www.npmjs.com/package/audit-ci) : + +```bash +npm install -D audit-ci +``` + +Ajoutez dans `package.json` : + +```json +"scripts": { + "audit:check": "npx audit-ci --config ./audit-ci.jsonc" +} +``` + +Pour vérifier les mises à jour : + +```bash +npm run audit:check +``` + +Correctifs connus via [npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) : + +```bash +npm audit fix --package-lock-only +``` + +> +> NOTES +> +> 1. Commitez les correctifs appliqués au `package-lock.json`. +> 2. Relancez les tests : un changement de version peut introduire des ruptures. +> + +Sans correctif, ajoutez `audit-ci.jsonc` à la racine avec l’ID d’avis dans `allowlist` et un commentaire : + +```json +{ + "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json", + // audit-ci supports reading JSON, JSONC, and JSON5 config files. + // Only use one of ["low": true, "moderate": true, "high": true, "critical": true] + "moderate": true, + "allowlist": [ // NOTE: Please add as much information as possible to any items added to the allowList + // Currently no fixes available for the following advisory ID + "" + ] +} +``` + +##### Hook Git pre-commit + +Exécute les contrôles de vulnérabilités localement à chaque commit. + +Ajoutez `audit:check` avec [Husky](https://www.npmjs.com/package/husky) : + +```bash +npx husky add .husky/pre-commit "npm run audit:check" +``` + +> Contournement possible avec `git commit -nm`. Un job CI `vulnerability-check` (section suivante) est requis. + +##### Validations CI automatisées + +Audits lors des revues et releases ; évite le contournement du hook. + +Les configs CI (`.circleci/config.yml`) doivent inclure un job `vulnerability-check` (`npm run audit:check`) pour les PR, fusions vers la branche principale et releases étiquetées. + +## Lignes directrices de conception et d’implémentation + +Recommandations pour le code au sein de la communauté Mojaloop (ou le code qui y sera intégré). Si vous souhaitez donner du code à la communauté, suivez ces lignes directrices autant que possible pour la cohérence et la maintenabilité. Les contributions alignées seront intégrées plus facilement. + +Voir la FAQ [ci-dessous](#faqs). + +## Outils et frameworks + +La communauté OSS Mojaloop privilégie les outils et frameworks suivants : + +- **Serveur web :** [`HapiJS`](https://github.com/hapijs/hapi) +- **Framework UI web :** [`ReactJS`](https://reactjs.org/) +- **Configuration d’exécution :** [`convict`](https://www.npmjs.com/package/convict), avec [`rc`](https://www.npmjs.com/package/rc) pour l’existant. (variables d’environnement et fichiers de config) +- **Gestion des paquets :** `npm` +- **Journalisation :** bibliothèque [`@mojaloop/central-services-logger`](https://github.com/mojaloop/central-services-logger#readme), basée sur Winston +- **Conteneurs et orchestration :** [`docker`](https://www.docker.com/) et [`kubernetes`](https://kubernetes.io/) +- **Tests unitaires :** pour l’existant, [`Tape`](https://github.com/substack/tape) ; les nouvelles bases passent progressivement à [`Jest`](https://jestjs.io/). +- **Couverture de tests :** [`nyc`](https://github.com/istanbuljs/nyc) +- **CI :** [`CircleCI`](https://circleci.com/) + +En utilisant ces outils et frameworks, nous maintenons un haut niveau de cohérence et de maintenabilité sur l’ensemble de la base de code, ce qui permet à nos développeurs de rester productifs et sereins. Nous n’imposons pas leur usage aux dépôts fournis en contribution, mais d’autres choix peuvent alourdir la maintenance pour la communauté. + +## Adopter des contributions open source dans Mojaloop + +Lignes directrices pour l’adoption d’une contribution dans les dépôts open source Mojaloop. L’adoption est le processus par lequel la communauté accompagne un contributeur pour aligner sa contribution sur nos normes afin qu’elle rejoigne la base de code OSS Mojaloop. + +>*Note :* les contributions sont évaluées **au cas par cas**. Celles qui ne respectent pas ces lignes directrices passent par la phase d’incubation ci-dessous. D’autres écarts (p. ex. choix de framework) peuvent figurer sur une feuille de route pour standardisation ultérieure. + +### Étape 0 : prérequis + +Avant qu’une contribution soit considérée pour adoption : + +1. Elle doit être alignée avec les [principes du Level One Project](https://leveloneproject.org/). +1. Elle doit respecter le guide de style et les lignes directrices de conception et d’implémentation ci-dessus. +1. Elle doit inclure de la documentation de démarrage : plus il y en a, mieux c’est. +1. Elle doit inclure des tests avec une bonne couverture. Au minimum des tests unitaires ; une suite unitaire, d’intégration et fonctionnelle est préférée. Voir le [guide des contributeurs](../tools/automated-testing.md). + +### Étape 1 : incubation + +1. Créer un dépôt privé dans l’organisation GitHub Mojaloop pour le code adopté. +1. Faire examiner par une sous-équipe de la DA pour vérifier la portabilité (vers l’OSS), l’alignement avec les principes L1P, etc., et la conformité de la conception aux normes. +1. Vérifier les licences de la contribution et des nouvelles dépendances ; ajouter la licence Mojaloop standard avec attribution aux donateur(s)/contributeur(s). +1. Évaluer l’état du code : documentation, tests, qualité ; combler les lacunes. +1. Évaluer l’impact sur les performances. +1. Créer des actions (stories) pour renommer, retirer ou anonymiser tout élément non générique. +1. Examiner et discuter les choix de frameworks et d’outils. + +- En cas de décision de changement, les ajouter à la feuille de route. + +### Étape 2 : adoption publique + +1. Rendre le projet public sur GitHub Mojaloop. +1. Annoncer sur le canal Slack [`#announcements`](https://mojaloop.slack.com/archives/CG3MAJZ5J). +1. Activer les pipelines CI/CD et publier les artefacts pertinents (images Docker, modules npm, etc.). +1. Examiner et recommander un module ou une formation pour le programme de formation Mojaloop si pertinent. + +## Versionnement + +Voir [versionnement](./versioning.md) pour Mojaloop. + +## Créer de nouvelles fonctionnalités + +Processus pour les [fonctionnalités et branches](./creating-new-features.md) dans Mojaloop. + +## Processus de pull request + +Pour les changements importants, demandez conseil sur [Slack](https://mojaloop.slack.com). Les PR doivent décrire le changement et sa motivation. Vous pouvez utiliser les brouillons de PR GitHub pour recueillir commentaires et revue. + +Les PR qui violent les [principes Level One](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf) seront refusées. + +## Code de conduite + +Nous appliquons le [code de conduite de la Fondation Mojaloop](https://github.com/mojaloop/mojaloop/blob/master/CODE_OF_CONDUCT.md). + +## Licence + +Voir la politique [License](https://github.com/mojaloop/mojaloop/blob/master/contribute/License.md). + +## FAQ + +**1. Je veux contribuer du code qui ne suit pas le style ou les outils recommandés dans ce guide.** + + Les contributions sont acceptées *au cas par cas*. Si la contribution n’est pas prête pour une adoption complète, nous pouvons passer par la phase d’incubation : refactoring avec notre aide pour aligner code et documentation. + +**2. Ces normes sont dépassées et un outil (ou framework, méthode, langage) plus récent résoudrait le problème *x*. Comment mettre à jour les normes ?** + + Écrire du code de qualité est une cible en constante évolution, et nous cherchons toujours activement de nouveaux outils susceptibles d’améliorer la base de code OSS Mojaloop. N’hésitez donc pas à nous en parler sur le canal Slack design authority (`#design-authority`) si vous avez une recommandation. diff --git a/docs/fr/community/standards/invariants.md b/docs/fr/community/standards/invariants.md new file mode 100644 index 000000000..23ad24ac5 --- /dev/null +++ b/docs/fr/community/standards/invariants.md @@ -0,0 +1,230 @@ +# Invariants Mojaloop + +Les invariants suivants ont été établis au fil du développement de la plateforme, sur la base des exigences techniques déduites des [principes du Level One Project](https://www.leveloneproject.org/project_guide/level-one-project-design-principles/) et des bonnes pratiques applicables du secteur. +Ils doivent guider toute discussion produit et technique sur l’architecture de la plateforme. + +## Principes généraux + +### 1. La fonction principale de la plateforme est de compenser en temps réel les paiements en poussée de crédit et de faciliter le règlement régulier, avant la fin du jour de valeur. +#### Notes : +1. La plateforme permet aux participants de compenser des fonds immédiatement en faveur de leurs clients, tout en minimisant les risques et coûts associés. +2. La plateforme prend en charge des contrôles de liquidité disponible par transfert, lorsque ceux-ci sont requis en soutien au premier objectif. +3. Le hub est optimisé pour le chemin critique. +4. Règlement automatisé intrajournalier ; configuré par le schéma et l’implémentation selon les modèles de règlement recommandés pour l’infrastructure des marchés financiers. + + +### 2. Le hub prend en charge un traitement entièrement automatique de bout en bout (straight-through). +#### Notes : +1. « Straight-through processing » signifie qu’aucune intervention manuelle sur l’exécution des paiements ou des règlements n’est requise, sauf lorsque l’acceptation des conditions d’un paiement par l’utilisateur final est exigée conformément aux principes Level One. +2. Le traitement de bout en bout contribue à réduire les erreurs humaines dans le processus de transfert, ce qui réduit in fine les coûts. +3. Le caractère automatisé accélère les transferts de valeur entre clients finaux. + +Plus d’informations : [Straight Through Processing (Investopedia)](https://www.investopedia.com/terms/s/straightthroughprocessing.asp) + + +### 3. Le hub ne nécessite pas de rapprochement manuel : le protocole d’interaction avec le hub garantit des résultats déterministes. +#### Notes : +1. Lorsqu’un transfert est finalisé, le statut de ce transfert ne peut faire l’objet d’aucun doute (dans le cas contraire, il n’est pas finalisé et un avis actif est communiqué aux participants). L’avis est à la demande : en cas de demande, ils sont informés que le statut est indéterminé). +2. Le hub garantit des résultats déterministes pour les transferts et est accepté par tous les participants comme autorité finale sur le statut des transferts. +3. Le déterminisme signifie que chaque transfert est traçable, auditable (selon les limites et les contraintes applicables), avec un résultat final fourni dans un délai garanti. +4. Pour lever toute ambiguïté, les transferts par lots sont traités ligne par ligne avec des résultats déterministes potentiellement différents pour chaque ligne. + + +### 4. La logique de mise en place des transactions, propre aux cas d’usage, est séparée du transfert d’argent sans politique métier. +#### Notes : +1. Les détails de transaction et les règles métier doivent être saisis et appliqués entre contreparties avant la phase d’accord sur les conditions ; cela hors périmètre Mojaloop. +2. La phase d’accord établit un objet de transaction signé et spécifique au cas d’usage, intégrant tous les détails propres à la transaction. +3. La phase de transfert orchestre le transfert de valeur de détail entre institutions au profit des contreparties (seuls des contrôles de limites système sont appliqués), sans référence aux détails de transaction. +4. Aucun traitement supplémentaire propre à la transaction pendant la phase de transfert. + + +### 5. Le hub n’analyse pas et n’agit pas sur les détails de transaction de bout en bout ; les messages de transfert ne contiennent que les valeurs nécessaires à la compensation et au règlement. +#### Notes : +1. Les contrôles et validations à l’étape de transfert portent uniquement sur la conformité aux règles du système, les limites, l’authentification par signature, et la validation de la condition et de l’exécution du paiement. +2. Les transferts engagés pour le règlement sont définitifs et garantis pour s’exécuter selon les règles du système. + + +### 6. La sémantique des transferts en poussée de crédit est réduite à sa forme la plus simple et standardisée pour tous les types de transaction. +#### Notes : +1. Simplifie l’implémentation et l’intégration des participants car de nombreux types de transaction et cas d’usage peuvent réutiliser le même flux de message de transfert de valeur sous-jacent. +2. Abstrait la complexité des cas d’usage hors du chemin critique. + + +### 7. Le hub de services API sur Internet n’est pas un « commutateur de messages ». +#### Notes : +1. Le hub de services fournit des services API en temps réel aux participants pour les transferts instantanés de détail en poussée de crédit. + 1. Services tels que résolution d’adresse, accord de transaction entre participants, soumission de transferts préparés, soumission d’avis d’exécution. +2. Des services API auxiliaires sont fournis aux participants pour faciliter l’intégration, la gestion de position, le reporting de rapprochement et d’autres fonctions non temps réel n’entrant pas dans le traitement des transferts. +3. Tous les messages sont validés par rapport à la spécification API ; les messages non conformes sont rejetés avec un code de motif interprétable par machine. + + +### 8. Le hub expose des interfaces asynchrones aux participants +#### Notes : +1. Pour maximiser le débit du système. +2. Pour isoler les problèmes de connectivité en feuille afin qu’ils n’impactent pas les autres utilisateurs finaux. +3. Pour permettre au hub de traiter les requêtes selon sa propre priorité sans maintenir une connexion active par transfert. +4. Pour gérer de nombreux processus longs concurrents via le traitement par lots interne et la répartition de charge. +5. Pour disposer d’un mécanisme unique pour le traitement des requêtes (par exemple : transactions en masse, requêtes nécessitant une saisie de l’utilisateur final, ou encore requêtes couvrant plusieurs sauts). +6. Pour mieux prendre en charge les contraintes des réseaux réels : les problèmes de vitesse ou de fiabilité d'un participant devraient avoir un impact minimal sur les autres participants ou sur la disponibilité globale du système. + +### 9. L’API de transfert est [idempotente](https://docs.mojaloop.io/api/fspiop/v1.1/api-definition.html#idempotent-services-in-server) +#### Notes : +1. Les requêtes dupliquées peuvent être émises en toute sécurité par l’émetteur en cas de réseau dégradé. + 1. Les doublons sont reconnus et produisent le même résultat (doublons valides) ou sont rejetés en tant que doublons, avec référence à la requête originale (lorsque la spécification ne l’autorise pas). + + +### 10. Les enregistrements de transfert **_finalisés_** sont conservés pendant une période configurable par le schéma pour les processus du schéma (rapprochement, facturation, forensics) +#### Notes : +1. Il n’est pas possible d’interroger le « sous-statut » d’un transfert en cours ; l’API fournit un résultat déterministe avec avis actif dans le délai de service garanti. + + +### 11. Les enregistrements de transfert des transferts finalisés sont conservés indéfiniment dans un stockage long terme pour l’analyse métier par l’opérateur du schéma et les participants (via les interfaces appropriées) +#### Notes : +1. La disponibilité des enregistrements peut être en retard sur la finalité du traitement en ligne, afin de permettre la séparation entre la conservation des données et le traitement temps réel des requêtes de transfert. + + +### 12. Le hub doit effectuer le minimum d’analyse, de stockage et de traitement des messages nécessaire pour exécuter les services qu’il fournit au schéma dans son ensemble. +#### Notes : +1. Dans certains flux de messagerie (p. ex. recherche de partie), les participants peuvent souhaiter un point de contact unique pour le routage des messages liés au schéma, même lorsque les messages ne sont pas destinés au hub et ne nécessitent pas d’inspection. + + +## Sécurité et sûreté des API + +### 13. Les messages API sont confidentiels, à intégrité vérifiable (anti-falsification) et non répudiables. +#### Notes : +1. La confidentialité est requise pour protéger la vie privée des participants et de leurs clients. + 1. De nombreux domaines réglementaires où Mojaloop doit opérer imposent des obligations légales ; le hub doit appliquer les bonnes pratiques pour garantir la protection de la vie privée des participants et de leurs clients. +2. Des mécanismes d’intégrité anti-falsification garantissent que les messages ne peuvent être altérés en transit. + 1. Pour l’intégrité du système, chaque destinataire doit pouvoir vérifier de façon fiable que le message n’a pas été modifié. + 2. La cryptographie asymétrique (signature numérique) est aujourd’hui le mécanisme le plus courant pour une messagerie à intégrité vérifiable. + 1. La sécurité de la clé privée de l’émetteur est critique. + 2. Les règles du système doivent préciser les responsabilités en matière de gestion des clés et l’exposition financière en cas de compromission d’une clé privée. +3. La non-répudiation garantit que le message a bien été envoyé par l’émetteur présumé et que celui-ci ne peut répudier la provenance. + 1. Cela est essentiel pour identifier la partie responsable lors des processus d'audit et de résolution des litiges. + + +### 14. Les messages API sont authentifiés à réception avant acceptation ou traitement ultérieur +#### Notes : +1. L’authentification donne un niveau de confiance sur l’émetteur présumé du message. +2. Elle donne un niveau de confiance que le message n’a pas été envoyé par une partie non autorisée. + + +### 15. Les messages authentifiés ne sont pas acquittés comme acceptés tant qu’ils ne sont pas enregistrés de façon sûre sur un stockage permanent. +#### Notes : +1. L’API Mojaloop attache une signification métier importante liée au schéma à certains codes HTTP à différentes étapes des flux : + 1. Certaines réponses HTTP, p. ex. « 202 Accepted », sont destinées à fournir des garanties financières aux participants et ne doivent être envoyées qu’une fois l’entité réceptrice assurée d’avoir enregistré de façon sûre et permanente ce qui permet : + 1. La reprise système vers un état cohérent après défaillance d’un ou plusieurs composants distribués. + 2. Des processus de règlement exacts. + 3. L’audit et le règlement des litiges. + 2. Par exemple un « 200 OK » du hub vers le participant bénéficiaire à réception d’un message d’exécution de transfert indique une garantie de règlement de la transaction pour le bénéficiaire, sous réserve des contrôles de validation. +2. L’API Mojaloop est conçue pour fonctionner en sécurité sous réseau imparfait, avec reprises et synchronisation d’état entre participants. + + +### 16. Trois niveaux de sécurité des communications pour l’intégrité, la confidentialité et la non-répudiation des messages entre serveur API et client API. +#### Notes : +1. Connexions sécurisées : mTLS obligatoire pour toutes les communications entre le schéma et les participants autorisés. + 1. Garantit la confidentialité des communications, leur échange entre correspondants identifiés, et leur protection contre la falsification. +2. Messages sécurisés : contenu JSON signé cryptographiquement selon JWS. + 1. Garantit aux destinataires l’origine des messages et la non-répudiation par l’émetteur. +3. Conditions de transfert sécurisées : protocole Interledger (ILP) entre participants payeur et bénéficiaire. + 1. Protège l’intégrité de la condition de paiement et de son exécution. + 2. Limite la durée de validité d’une instruction de transfert. + + +### 17. Pour garantir la cohérence arithmétique du système, seule l’arithmétique en virgule fixe est utilisée. +#### Notes : +1. Les calculs en virgule flottante peuvent perdre en précision et ne doivent servir à aucun calcul financier. +2. Voir la représentation [Level One Decimal Type](https://docs.mojaloop.io/documentation/discussions/decimal.html) et ses formes. + 1. Cette spécification permet un échange transparent avec les systèmes financiers basés sur XML, sans perte de précision ni d’exactitude. + + +## Caractéristiques opérationnelles + +Mojaloop est conçu pour s’intégrer à un système de paiements instantanés au niveau d’une juridiction. Il doit donc démontrablement respecter les normes de performance et de résilience requises pour de tels systèmes. + + +### 1. Sur une configuration matérielle minimale de référence, le système permet de compenser 1 000 transferts par seconde, de façon soutenue pendant une heure, avec au plus 1 % (à l’étape de transfert) dépassant 1 seconde à travers le hub. +#### Notes : +1. La mesure inclut tous les composants matériels et logiciels nécessaires, avec sécurité et persistance de niveau production. +2. Elle inclut les trois étapes de transfert : découverte, accord et transfert. +3. Elle n’inclut pas la latence introduite par les participants. +4. Une période d’une heure approxime un pic de charge pour un système national de paiement. +5. Le coût de la montée en capacité (scale-up) par unité de capacité devrait être inférieur au coût du provisionnement initial. +6. 1 000 transferts (compensation) par seconde est un point de départ raisonnable pour un système national. +7. 1 % des transferts dépassant 1 seconde est un point de départ raisonnable. +8. Les schémas Mojaloop doivent pouvoir démarrer à un coût raisonnable pour une infrastructure financière nationale et évoluer économiquement avec la demande. + + +### 2. Le hub est hautement disponible et résilient aux défaillances. +#### Notes : +1. Définition de « haute disponibilité » : + 1. Ici, « _hautement disponible_ » signifie « _la capacité à fournir et maintenir un niveau de service acceptable face aux pannes et perturbations du fonctionnement normal_ ». + 2. Les schémas peuvent définir leur propre « niveau de service acceptable » ; Mojaloop fait certains arbitrages : + 1. Lorsque les modes de panne le permettent, le service est dégradé pour l’ensemble des participants plutôt que certains participants individuels subissent une panne totale pendant que d’autres restent opérationnels. +2. Le hub n’a pas de point de défaillance unique : il continue d’opérer avec une dégradation minimale si un composant unique tombe en panne. + 1. Plusieurs instances actives de chaque composant sont déployées de façon distribuée derrière des répartiteurs de charge. + 2. Chaque instance peut traiter les requêtes de n’importe quel client/participant : aucun participant ne perd la capacité de transacter à cause d’un seul composant. +3. Avec une infrastructure adaptée, le logiciel Mojaloop peut être déployé en configurations actif:actif et/ou actif:passif sur plusieurs centres de données géographiquement distincts, avec services et données répliqués sur des nœuds physiques susceptibles de tomber en panne indépendamment. +4. Les nœuds des groupes de réplication (et/ou grappes) doivent être dans des emplacements physiques divers (baies et/ou centres de données), alimentations et interconnexions réseau indépendantes. +5. En cas de défaillances multiples non couvertes par le logiciel, le déploiement ou l’infrastructure, l’API Mojaloop permet à chaque entité du schéma de retrouver un état cohérent, le hub faisant autorité après restauration complète. +6. _Voir aussi les points sur la résistance à la perte de données._ +7. Les schémas Mojaloop visent une infrastructure financière nationale : le temps d’indisponibilité doit être aussi proche de zéro que raisonnable compte tenu des coûts. +8. Les pannes matérielles et logicielles sont attendues même avec du matériel de haute qualité ; elles doivent être anticipées et planifiées pour minimiser la perte ou la dégradation de service et/ou de données. +9. Les arbitrages privilégient la disponibilité globale du service et la cohérence d’état plutôt que la performance. C’est-à-dire : + 1. Tous les participants peuvent continuer à effectuer des transactions à un débit réduit plutôt que certains se trouvent dans l'incapacité totale d'en traiter. + 2. Les incohérences d’état entre entités du schéma sont résolubles après restauration via l’API Mojaloop, avec un rapprochement manuel minimal ; le hub fait autorité. +10. Si le débit ne suffit pas à traiter toutes les requêtes à temps, le hub priorise les transferts en cours plutôt que les nouvelles requêtes. + 1. Les transferts que le hub ne peut traiter avant expiration des délais sont expirés proprement. + + +### 3. Le hub résiste à la perte de données en cas de défaillances. +#### Notes : +1. Avec une infrastructure adaptée, Mojaloop peut être déployé de façon à répliquer les données de manière fiable sur plusieurs nœuds de stockage redondants avant traitement. + 1. Les moteurs de base fournis par les mécanismes de déploiement Mojaloop prennent en charge notamment : + 1. Réplication asynchrone primaire:secondaire. + 2. Réplication synchrone primaire:primaire. + 3. Réplication par quorum / consensus synchrone. + 2. Les mécanismes disponibles dépendent de la couche de stockage et des technologies de base de données. +2. En cas de défaillances multiples non couvertes, l’API Mojaloop permet de retrouver un état cohérent avec une exposition financière minimale. + 1. Les transferts ne deviennent juridiquement contraignants que lorsque le hub a répondu avec succès au message d’exécution du participant bénéficiaire. Cette réponse n’est envoyée qu’après persistance du message d’exécution et de son résultat dans la base du grand livre. + 2. Les horodatages d’expiration sur les messages financièrement significatifs permettent des échecs déterministes et opportuns pour tous les participants via mécanismes de nouvelle tentative automatisés. +3. Les schémas Mojaloop visent une infrastructure nationale : il faut autant que possible, compte tenu des coûts, éviter la perte de données. +4. Les pannes sont attendues ; la conception du hub doit les anticiper pour limiter la perte de données. +5. Les participants ont besoin d’une information rapide et fiable sur le statut des opérations financières dans le schéma, afin de minimiser leur exposition au risque et d’offrir une excellente expérience à leurs clients. + + +## Décisions de conception +1. NodeJS est l’environnement d’exécution principal ; TypeScript est le langage préféré pour le développement. + 1. Plateforme libre et open source. + 2. Très répandue et soutenue par les plus grandes institutions web. + 3. Écosystème mondial massif de bibliothèques. + 4. Utilise uniquement la famille ECMAScript, connue de millions de développeurs web. + + +2. Architecture distribuée microservices. + 1. [Loi de Déméter](https://en.wikipedia.org/wiki/Law_of_Demeter) ou principe de moindre connaissance. + 2. [Séparation des responsabilités](https://en.wikipedia.org/wiki/Separation_of_concerns) (Separation of Concerns), garantie par des contrats inter-modules. + 3. [Architecture modulaire](https://en.wikipedia.org/wiki/Modular_programming) : développement distribué en communauté et évolution des composants avec peu d’impact sur les voisins. + + +3. [Apache Kafka](https://kafka.apache.org/intro) en [pub/sub](https://en.wikipedia.org/wiki/Publish–subscribe_pattern) distribué pour la [séparation commande / requête (CQS)](https://en.wikipedia.org/wiki/Command–query_separation) entre modules. + + +4. [Apache Kafka](https://kafka.apache.org/intro) pour la persistance des messages API des participants. + + +5. Mojaloop utilise des API basées sur Open API 3.0. + 1. Expose des ressources mappées aux fonctionnalités des cas d’usage définis. + 2. Pratique courante pour les spécifications d’API web. + + +## Annexe A : aperçu des principes Level One +Le [Level One Project](https://www.leveloneproject.org) propose un système de paiements à faible coût pour des paiements numériques inclusifs et interopérables. Le [guide Level One Project](https://www.leveloneproject.org/project_guide/03-welcome-to-the-2019-guide/) décrit une vision de système de services financiers numériques inclusifs au service des populations à faible revenu. Les principes de conception incluent notamment : +* Modèle de paiement en poussée de crédit avec transfert immédiat des fonds et règlement le jour même +* Interopérabilité en boucle ouverte entre fournisseurs +* Respect de normes internationales bien définies et adoptées +* Protection partagée contre la fraude et la sécurité à l’échelle du système +* Exigences d’identité et KYC efficaces et proportionnées +* Convenance, coût et utilité au moins équivalents à l’espèce + +En s’appuyant sur une approche numérique ouverte des transactions et en s’associant à des acteurs des secteurs public et privé, le Level One Project vise à fournir l’accès à une infrastructure partagée de services financiers numériques, robuste et peu coûteuse, stimulant l’innovation chez les nouveaux acteurs comme chez les acteurs existants, réduisant les risques et créant une valeur considérable pour les prestataires, les particuliers et les économies des marchés en développement. Des ressources complémentaires aident gouvernements, ONG et fournisseurs de services financiers à mettre en œuvre ces changements. diff --git a/docs/fr/community/standards/triaging-bugs.md b/docs/fr/community/standards/triaging-bugs.md new file mode 100644 index 000000000..c830f5de7 --- /dev/null +++ b/docs/fr/community/standards/triaging-bugs.md @@ -0,0 +1,22 @@ +# Triage des anomalies Mojaloop OSS + +### Signaler un bug / un ticket + +En cas de bug ou de problème, un ticket est en général ouvert comme bug ou demande de fonctionnalité sur le dépôt [project](https://github.com/mojaloop/project/issues/new/choose) et, dans certains cas, lié à un ticket sur le dépôt du composant concerné. + +Un modèle de rapport de bug est disponible et peut être utilisé ; il encourage à fournir des détails tels que les versions, les résultats attendus et d’autres informations utiles pour le triage et la reproduction du problème. + +### Une fois le bug enregistré + +1. En général, le bug est d’abord trié sur le canal public [#ml-oss-bug-triage](https://mojaloop.slack.com/messages/CMCVBHPUH) du Slack Mojaloop. +2. Pour les problèmes de sécurité et autres sujets sensibles, le triage se fait sur un canal privé avec les contributeurs actuels, avant une communication publique au moment opportun. Les détails sur la sécurité sont couverts ici : https://docs.mojaloop.io/community/contributing/cvd.html +3. Lors du triage du bug, la priorité et la gravité sont attribuées au bug après consensus majoritaire et consultation du ou des rapporteurs. +4. Selon la priorité et la gravité, le bug est pris en charge par l’équipe cœur ou d’autres contributeurs, dans le cadre d’un effort collaboratif. +5. Une fois pris en charge, les échanges et mises à jour se font sur le ticket GitHub et sur le canal Slack. + +### Triage + +1. La discussion concernant le problème est ouverte au public pour les bugs et tickets habituels. +2. À l’issue des discussions, la décision finale sur la priorité et la gravité est prise par l’équipe cœur en consultation avec le ou les rapporteurs. +3. La liste et le processus seront mis à jour au fur et à mesure de leur évolution. +4. Canal Slack de triage des bugs Mojaloop : #[ml-oss-bug-triage](https://mojaloop.slack.com/archives/CMCVBHPUH) diff --git a/docs/fr/community/standards/versioning.md b/docs/fr/community/standards/versioning.md new file mode 100644 index 000000000..e3a9fa8f6 --- /dev/null +++ b/docs/fr/community/standards/versioning.md @@ -0,0 +1,126 @@ +# Versionnement + +## Versionnement des releases des services cœur du Switch + +Ce document présente les lignes directrices de la stratégie de versionnement des dépôts open source Mojaloop correspondant aux services du Switch. + +### Stratégie de versionnement + + +#### Référence à partir de PI-11 +1. À partir de PI-11 (27 juillet 2020), la directive de versionnement est de migrer vers un système étroitement aligné sur le [SemVer](https://semver.org/) en supprimant la dépendance PI/Sprint. À partir de 11.x.x, la proposition est donc de passer à un [SemVer](https://semver.org/) strict. +2. À haut niveau, on conserve le format vX.Y.Z, où X représente la version 'Major', Y la version 'Minor' et Z la version 'patch'. Les corrections mineures et patchs incrémentent Z ; les évolutions fonctionnelles non rupturistes modifient Y ; les changements rupturistes modifient X. +3. Des suffixes tels que « -snapshot », « -patch », « -hotfix » sont utilisés lorsque pertinent et selon les besoins (pris en charge par la configuration CI). +4. À partir de 11.0.0 (principalement pour Helm, mais aussi pour les services individuels) pour PI-11, la proposition est de passer à un [SemVer](https://semver.org/) pur. +5. Cela implique que toute nouvelle release d’un paquet ou service avec X < 11 (pour les dépôts existants, pas les nouveaux) sera d’abord portée à v11.0.0 comme version de base, puis suivra les règles SemVer standard évoquées ci-dessus. Pour les nouveaux projets ou dépôts, le versionnement peut commencer à v1.0.0 (une fois qu’ils ont atteint le statut de release). + + +#### Stratégie utilisée jusqu’à PI-10 +1. Le versionnement Mojaloop (jusqu’à PI-10) s'inspire du système de numérotation des releases du [versionnement sémantique](https://semver.org/). +2. Il est toutefois adapté pour refléter le calendrier du projet Mojaloop, selon les numéros d’incrément de programme (PI) et de sprint. +3. Par exemple, le numéro de release v5.1.0 indique la première release du sprint 5.1, où Sprint 5.1 est le premier sprint du PI-5. Pour une version vX.Y.Z, X.Y est le numéro de sprint (X = numéro de PI) et Z le numéro de release pour ce dépôt. Exemple : v4.4.4 = quatrième release sur quatre dans le sprint 4.4 (du PI-4). + + + +### Version actuelle + +Les informations de version actuelles pour Mojaloop se trouvent [ici](../../deployment-guide/releases.md). + +### Calendrier des sprints PI-13 + +Ci-dessous le calendrier des sprints du Program Increment 13, qui se termine par l’événement communautaire PI-14 en avril 2021. + +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Lancement Phase-5 sur site**|25/01/2021|29/01/2021|5 jours| Webinaires Zoom virtuels| +|**Sprint 13.1**|01/02/2021|14/02/2021|2 semaines | | +|**Sprint 13.2**|15/02/2021|28/02/2021|2 semaines | | +|**Sprint 13.3**|01/03/2021|14/03/2021|2 semaines | | +|**Sprint 13.4**|15/03/2021|28/03/2021|2 semaines | | +|**Sprint 13.5**|29/03/2021|11/04/2021|2 semaines | | +|**Sprint 13.6**|12/04/2021|25/04/2021|2 semaines | | +|**Phase-5 PI-14**|26/04/2021|30/04/2021|5 jours| Réunions virtuelles | + +### Calendrier des sprints PI-12 + +Ci-dessous le calendrier des sprints du Program Increment 12, qui se termine par l’événement communautaire PI-13 en janvier 2021. + +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Lancement Phase-4 sur site**|28/01/2020|30/01/2020|3 jours| Johannesbourg| +|**Phase-4 PI-10 virtuelle**|21/04/2020|24/04/2020|4 jours| Webinaires Zoom virtuels| +|**Phase-4 PI-11 virtuelle**|21/07/2020|24/07/2020|4 jours| Webinaires Zoom virtuels| +|**Phase-4 PI-12 virtuelle**|19/10/2020|23/10/2020|5 jours| Webinaires Zoom virtuels| +|**Sprint 12.1**|26/10/2020|15/11/2020|3 semaines | | +|**Sprint 12.2**|16/11/2020|29/11/2020|2 semaines | | +|**Sprint 12.3**|30/11/2020|13/12/2020|2 semaines | | +|**Sprint 12.4**|14/12/2020|27/12/2020|2 semaines | | +|**Sprint 12.5**|28/12/2020|10/01/2021|2 semaines | | +|**Sprint 12.6**|11/01/2021|24/01/2021|2 semaines | | +|**Lancement Phase-5 / PI-13**|25/01/2021|29/01/2021|5 jours| À confirmer | + +### Calendriers de sprints antérieurs : + +### Calendrier des sprints PI-11 + +Ci-dessous le calendrier des sprints du Program Increment 11, qui se termine par l’événement PI 12. + +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Lancement Phase-4 sur site**|28/01/2020|30/01/2020|3 jours| Johannesbourg| +|**Phase-4 PI-10 virtuelle**|21/04/2020|24/04/2020|4 jours| Webinaires Zoom virtuels | +|**Phase-4 PI-11 virtuelle**|21/07/2020|24/07/2020|4 jours| Webinaires Zoom virtuels | +|**Sprint 11.1**|27/07/2020|09/08/2020|2 semaines| | +|**Sprint 11.2**|10/08/2020|23/08/2020|2 semaines| | +|**Sprint 11.3**|24/08/2020|06/09/2020|2 semaines| | +|**Sprint 11.4**|07/09/2020|20/09/2020|2 semaines| | +|**Sprint 11.5**|21/09/2020|04/10/2020|2 semaines| | +|**Sprint 11.6**|05/10/2020|18/10/2020|2 semaines | | +|**Phase-4 PI-12**|20/10/2020|23/10/2020|4 jours| À confirmer | + +#### Calendrier des sprints PI-10 + +Ci-dessous le calendrier du Program Increment 10, qui se termine par l’événement PI 11. Veuillez utiliser ceci comme guide lors des processus de versionnement et de release. + +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Phase-3 PI6 sur site**|16/04/2019|18/04/2019|3 jours| Johannesbourg| +|**Phase-3 PI7 sur site**|25/06/2019|27/06/2019|3 jours| Arusha| +|**Phase-3 PI8 sur site**|10/09/2019|12/09/2019|3 jours| Abidjan| +|**Lancement Phase-4 sur site**|28/01/2020|30/01/2020|3 jours| Johannesbourg| +|**Phase-4 PI 10 virtuelle**|21/04/2020|24/04/2020|5 jours| Webinaires Zoom virtuels | +|**Sprint 10.1**|27/04/2020|10/05/2020|2 semaines| | +|**Sprint 10.2**|11/05/2020|24/05/2020|2 semaines| | +|**Sprint 10.3**|25/05/2020|07/06/2020|2 semaines| | +|**Sprint 10.4**|08/06/2020|21/06/2020|2 semaines| | +|**Sprint 10.5**|22/06/2020|05/07/2020|2 semaines| | +|**Sprint 10.6**|06/07/2020|19/07/2020|2 semaines | | +|**Phase-4 PI 11 sur site**|21/07/2020|23/07/2020|3 jours| Kenya (provisoire) | + +#### PI-9 +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Sprint 9.1**|03/02/2020|16/02/2020|2 semaines| | +|**Sprint 9.2**|17/02/2020|01/03/2020|2 semaines| | +|**Sprint 9.3**|02/03/2020|15/03/2020|2 semaines| | +|**Sprint 9.4**|16/03/2020|29/03/2020|2 semaines| | +|**Sprint 9.5**|30/03/2020|12/04/2020|2 semaines| | +|**Sprint 9.6**|13/04/2020|19/04/2020|1 semaine | | +|**Phase-4 PI 10 virtuelle**|21/04/2020|23/04/2020|5 jours| Webinaires Zoom virtuels | + +#### PI-8 +|Phase / jalon|Début|Fin|Semaines|Notes| +|---|---|---|---|---| +|**Sprint 8.1**|16/09/2019|29/09/2019|2 semaines| | +|**Sprint 8.2**|30/09/2019|13/10/2019|2 semaines| | +|**Sprint 8.3**|14/10/2019|27/10/2019|2 semaines| | +|**Sprint 8.4**|28/10/2019|10/11/2019|2 semaines| | +|**Sprint 8.5**|11/11/2019|24/11/2019|2 semaines| | +|**Sprint 8.6**|25/11/2019|08/12/2019|2 semaines| | +|**Sprint 8.7**|09/12/2019|05/01/2020|4 semaines| Pause de Noël| +|**Sprint 8.8**|06/01/2020|26/01/2020|3 semaines| 1 semaine de préparation| +|**Lancement Phase-4 sur site**|28/01/2020|30/01/2020|3 jours| Johannesbourg| + +### Notes + +1. Une nouvelle release du dépôt **helm** est produite en fonction des évolutions de fonctionnalités et de configuration des services cœur et des besoins de la communauté. diff --git a/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.plantuml b/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.plantuml new file mode 100644 index 000000000..92c109ee7 --- /dev/null +++ b/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.plantuml @@ -0,0 +1,70 @@ +@startuml + +skinparam TitleFontColor #819FF7 +skinparam TitleFontSize 23 + +title Cycle de vie d'un test de régression\n(Serveur de test autonome sur EC2) + +skinparam backgroundColor #353B42 +skinparam activity { + StartColor #40FF00 + EndColor #FF0000 + BackgroundColor #2E9AFE + BorderColor #A9D0F5 + LineColor #AAAAAA +} + +skinparam Arrow{ + Color #BFA350 + FontSize 10 + FontColor #6CBF50 +} + +start + +:Le test est déclenché; +note right: Cela peut être un déclenchement manuel, \nun minuteur de planification ou \nune action externe telle qu'une Pull Request \nà partir du système de gestion de code source + +if (Valider les paramètres d'exécution comme attendu ?) then (oui) + :Préparer l'environnement pour l'exécution requise; + note left: Définir l'horodatage\nPostmanCollection à exécuter\nListe des destinataires e-mail\nVariables d'environnement\nHorodatage d'exécution\nNom du fichier de sortie +else (non) + -[#red]-> + :Arrêter l'exécution avec une note indiquant des paramètres d'exécution incorrects; + -[#red]-> + stop +endif + +:Créer le conteneur Docker du simulateur; +:Créer le conteneur Docker du test de régression; +note left: Ce conteneur contient node\nNewman\nServeur SMTP e-mail + +while (Plus de requêtes Postman à exécuter ?) is (Oui) + :Exécuter le script pré-requête; + note right: Configurer les variables nécessaires pour\npréparer la requête à venir + :Exécuter la requête Postman; + :Exécuter le test; + :Enregistrer les résultats; + note right: Inspecter la réponse\nen fonction des variables définies précédemment lors de\nl'exécution pour déterminer si les résultats attendus sont obtenus + if (Échec du test d'assertion ?) then (oui) + if (Paramètre d'exécution demandant 'Arrêter à la première erreur' ?) then (oui) + -[#red]-> + (A) + detach + else (non) + endif + else (non) + endif +endwhile (Non) + +(A) +:Détruire le conteneur Docker du simulateur; +:Finaliser le rapport; +:Préparer les notifications; +:Joindre les rapports; +:Envoyer les notifications; +note right: La pièce jointe (rapport généré)\nest envoyée en pièce jointe\naux différents canaux de notification. +:Détruire le conteneur Docker du test de régression; +stop + +@enduml \ No newline at end of file diff --git a/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg b/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg new file mode 100644 index 000000000..58484b778 --- /dev/null +++ b/docs/fr/community/tools/assets/automated-testing/QARegressionTestingMojaloop-Complete.svg @@ -0,0 +1,165 @@ + + Cycle de vie d'un test de régression + + + + Cycle de vie d'un test de régression + (Serveur de test autonome sur EC2) + + + + Cela peut être un déclenchement manuel, + un minuteur de planification ou + une action externe telle qu'une Pull Request + à partir du système de gestion de code source + + Le test est déclenché + + Valider les paramètres d'exécution comme attendu ? + oui + non + + + Définir l'horodatage + PostmanCollection à exécuter + Liste des destinataires e-mail + Variables d'environnement + Horodatage d'exécution + Nom du fichier de sortie + + Préparer l'environnement pour l'exécution requise + + Arrêter l'exécution avec une note indiquant des paramètres d'exécution incorrects + + + + Créer le conteneur Docker du simulateur + + + Ce conteneur contient node + Newman + Serveur SMTP e-mail + + Créer le conteneur Docker du test de régression + + + Configurer les variables nécessaires pour + préparer la requête à venir + + Exécuter le script pré-requête + + Exécuter la requête Postman + + Exécuter le test + + + Inspecter la réponse + en fonction des variables définies précédemment lors de + l'exécution pour déterminer si les résultats attendus sont obtenus + + Enregistrer les résultats + + non + Paramètre d'exécution demandant 'Arrêter à la première erreur' ? + oui + + + + oui + Échec du test d'assertion ? + non + + + Oui + Plus de requêtes Postman à exécuter ? + Non + + + + Détruire le conteneur Docker du simulateur + + Finaliser le rapport + + Préparer les notifications + + Joindre les rapports + + + La pièce jointe (rapport généré) + est envoyée en pièce jointe + aux différents canaux de notification. + + Envoyer les notifications + + Détruire le conteneur Docker du test de régression + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fr/community/tools/assets/images/ci_cd_lib_master.png b/docs/fr/community/tools/assets/images/ci_cd_lib_master.png new file mode 100644 index 000000000..331087be4 Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_lib_master.png differ diff --git a/docs/fr/community/tools/assets/images/ci_cd_lib_pr.png b/docs/fr/community/tools/assets/images/ci_cd_lib_pr.png new file mode 100644 index 000000000..1a64f791f Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_lib_pr.png differ diff --git a/docs/fr/community/tools/assets/images/ci_cd_lib_tag.png b/docs/fr/community/tools/assets/images/ci_cd_lib_tag.png new file mode 100644 index 000000000..13af7e59c Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_lib_tag.png differ diff --git a/docs/fr/community/tools/assets/images/ci_cd_svc_master.png b/docs/fr/community/tools/assets/images/ci_cd_svc_master.png new file mode 100644 index 000000000..6ab54d9d9 Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_svc_master.png differ diff --git a/docs/fr/community/tools/assets/images/ci_cd_svc_pr.png b/docs/fr/community/tools/assets/images/ci_cd_svc_pr.png new file mode 100644 index 000000000..389f5ccba Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_svc_pr.png differ diff --git a/docs/fr/community/tools/assets/images/ci_cd_svc_tag.png b/docs/fr/community/tools/assets/images/ci_cd_svc_tag.png new file mode 100644 index 000000000..934aee684 Binary files /dev/null and b/docs/fr/community/tools/assets/images/ci_cd_svc_tag.png differ diff --git a/docs/fr/community/tools/assets/images/mojaloop_cybersec_architecture.jpg b/docs/fr/community/tools/assets/images/mojaloop_cybersec_architecture.jpg new file mode 100644 index 000000000..aaf8dcca4 Binary files /dev/null and b/docs/fr/community/tools/assets/images/mojaloop_cybersec_architecture.jpg differ diff --git a/docs/fr/community/tools/assets/images/mojaloop_security_layers.jpg b/docs/fr/community/tools/assets/images/mojaloop_security_layers.jpg new file mode 100644 index 000000000..d70949b68 Binary files /dev/null and b/docs/fr/community/tools/assets/images/mojaloop_security_layers.jpg differ diff --git a/docs/fr/community/tools/automated-testing.md b/docs/fr/community/tools/automated-testing.md new file mode 100644 index 000000000..d1e223fea --- /dev/null +++ b/docs/fr/community/tools/automated-testing.md @@ -0,0 +1,144 @@ +# Tests QA et de régression dans Mojaloop +Vue d’ensemble du cadre de tests mis en place dans Mojaloop + +Sommaire : +1. [Exigences de régression](#sujets-de-régression) +2. [Tests développeur](#tests-développeur) +3. [Tests Postman et Newman](#postman-et-newman) +4. [Exécuter les tests de régression](#exécuter-les-tests-de-régression) +5. [Flux d’un test planifié typique](#flux-dun-test-planifié-typique) +6. [Commandes Newman](#commandes-newman) + +## Sujets de régression +Pour qu’un système déployé soit robuste, l’un des derniers points de contrôle consiste à vérifier que l’environnement de déploiement est sain et que toutes les fonctionnalités exposées fonctionnent exactement conformément aux spécifications. + +Auparavant, on doit mettre en place un certain nombre de disciplines pour garantir un contrôle maximal. + +Pour illustrer comment le projet Mojaloop atteint cet objectif, nous présentons les différents points de contrôle mis en place. + +### Tests développeur +Pour chaque composant et module, dans la base de code, vous trouverez un dossier nommé « test » qui contient trois types de tests. ++ D’abord, le *test de couverture* qui signale le code inaccessible ou redondant ++ Les tests unitaires, qui vérifient que la fonctionnalité prévue se comporte comme attendu ++ Les tests d’intégration, qui ne testent pas le bout en bout mais les interactions avec les composants adjacents ++ Des vérifications automatiques des normes de code implémentées via des paquets intégrés à la base de code + +Ces tests sont exécutés via des instructions en ligne de commande par le développeur pendant le développement. Ils sont également lancés automatiquement à chaque *commit* et lors de l’ouverture d’une pull request GitHub pour intégrer le code au projet. + +La procédure décrite ci-dessus sort du périmètre de l’assurance qualité (QA) et des tests de régression, objet du présent document. + +Une fois qu’un développeur a écrit une nouvelle fonctionnalité ou étendu une fonctionnalité existante, les tests rigoureux ci-dessus permettent de supposer que le comportement concerné est correct. Comment alors s’assurer que ce nouveau code ne dégrade pas le projet ou le produit dans son ensemble ? + +Lorsque le code a passé toutes ces étapes et est déployé dans le cadre des processus CI/CD de notre flux de travail, les nouveaux composants sont acceptés sur les différents hébergeurs, déploiements cloud ou sur site. Ces hébergeurs vont des plateformes de développement jusqu’aux environnements de production. + +### Postman et Newman +En parallèle du déploiement, l’entretien et la maintenance du cadre de tests se poursuivent [Postman](https://github.com/mojaloop/postman.git "Postman"). Lors d’une nouvelle release, les notes de version publiées dans le flux de travail listent les fonctionnalités nouvelles ou améliorées. L’équipe QA s’en sert pour étendre et enrichir les collections Postman existantes, où des tests sont écrits dans les scripts requête/réponse pour couvrir les scénarios positifs et négatifs par rapport au comportement attendu. Ces tests sont ensuite exécutés ainsi : ++ Manuellement, pour vérifier que les tests couvrent tous les aspects et angles de la fonctionnalité, les tests positifs pour valider par assertion le comportement attendu, et les tests négatifs pour vérifier que les flux alternatifs corrects s’appliquent en cas de problème imprévu ++ De façon planifiée — dans le cadre de la régression — pour reproduire la même intention que le manuel mais entièrement automatisée (avec le *paquet Newman*), avec rapports et journaux pour signaler tout comportement non voulu et avertir lorsque le comportement connu a changé par rapport à une exécution précédente. + +Pour faciliter les tests automatisés et planifiés d’une collection Postman, plusieurs méthodes existent ; celle implémentée pour Mojaloop est expliquée plus bas dans ce document. + +Un dépôt complet contient tous les scripts, procédures d’installation et éléments nécessaires pour mettre en place un [cadre automatisé de tests QA et de régression](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"). Ce cadre permet de cibler n’importe quelle collection Postman, de préciser l’environnement d’exécution et une liste d’adresses e-mail séparées par des virgules pour recevoir le rapport généré. Ce cadre est utilisé quotidiennement par Mojaloop sur une instance EC2 AWS hébergeant Node, Docker, un serveur de messagerie et Newman, ainsi que des scripts Bash et des modèles pour exécuter automatiquement les collections prévues chaque jour. Ce guide permet à tout le monde de déployer son propre cadre. + +#### Collections Postman + +Plusieurs collections Postman sont utilisées selon les processus : + +Pour le simulateur Mojaloop : + ++ [MojaloopHub_Setup](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) : à exécuter une fois après un nouveau déploiement, en général par le responsable de release. Elle configure un hub Mojaloop vide, notamment la devise du hub et les comptes de règlement. ++ [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) : configure les simulateurs DFSP ainsi que les URLs des points de terminaison pour que le hub Mojaloop sache où envoyer les callbacks de requête. ++ [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) : pack de régression bout en bout qui exerce l’ensemble des fonctionnalités déployées. Peut être lancé manuellement mais est véritablement conçu pour une exécution automatisée du début à la fin, les valeurs de réponse étant transmises de chaque requête à la suivante. (L’équipe cœur s’en sert pour valider releases et déploiements) + + Remarques : dans certains cas, un délai de `250 ms` à `500 ms` est nécessaire si l’exécution passe par le Test Runner de l’interface Postman, pour laisser le temps aux tests de valider les requêtes contre le simulateur. Ce n’est pas toujours nécessaire. ++ [Bulk_API_Transfers_MojaSims](https://github.com/mojaloop/postman/blob/master/Bulk_API_Transfers_MojaSims.postman_collection.json) : peut servir à tester les transferts de masse ciblant le simulateur Mojaloop. + +Pour l’ancien simulateur (il est recommandé d’utiliser le simulateur Mojaloop ; le support s’arrête à partir de PI-12 (oct. 2020)) : + ++ [ML_OSS_Setup_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Setup_LegacySim.postman_collection.json) : à exécuter une fois après un nouveau déploiement (si l’ancien simulateur est utilisé), en général par le responsable de release. Configure le hub Mojaloop (devise, comptes de règlement) avec l’ancien simulateur (FSP). ++ [ML_OSS_Golden_Path_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Golden_Path_LegacySim.postman_collection.json) : pack de régression bout en bout pour l’ensemble des fonctionnalités déployées. Peut être lancé manuellement mais est conçu pour une exécution automatisée du début à la fin avec chaînage des réponses. (L’équipe cœur s’en sert pour valider releases et déploiements) + + Remarques : dans certains cas, un délai de `250 ms` à `500 ms` peut être nécessaire via le Test Runner Postman. Ce n’est pas toujours nécessaire. ++ [Bulk API Transfers.postman_collection](https://github.com/mojaloop/postman/blob/master/Bulk%20API%20Transfers.postman_collection.json) : peut servir à tester les transferts de masse ciblant l’ancien simulateur. + +#### Configuration d’environnement + +Vous devrez adapter le fichier de configuration d’environnement suivant à votre déploiement : ++ [Configuration locale](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local.postman_environment.json) + +_Conseils :_ +- _Les paramètres d’hôte sont les plus souvent à modifier pour correspondre à votre environnement, p. ex. `HOST_CENTRAL_LEDGER: http://central-ledger.local`_ +- _Reportez-vous aux hôtes d’ingress configurés dans votre `values.yaml` dans le déploiement Helm._ + +### Exécuter les tests de régression +Pour le cadre QA et de régression Mojaloop spécifiquement, les tests Postman peuvent être exécutés en se connectant en SSH à l’instance EC2 (fichier PEM requis), puis en lançant un ou plusieurs scripts. + +En suivant les exigences et instructions détaillées dans le dépôt [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"), chacun peut créer son propre cadre et accéder à son instance pour exécuter des tests contre toute collection Postman et tout environnement sous son contrôle. + +##### Étapes pour exécuter via l’interface Postman ++ Importer la collection souhaitée dans Postman. Vous pouvez la télécharger depuis le dépôt ou utiliser le lien `RAW` et l’import par **lien d’import**. ++ Importer la configuration d’environnement dans Postman via la configuration d’environnement. Téléchargez le fichier sur votre machine et adaptez-le à votre environnement. ++ Préchargez toutes les données de test nécessaires avant d’exécuter les transactions (parties, devis, transferts), comme dans la collection d’exemple [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json) : + + Comptes du hub + + Intégration FSP + + Données de test sur le simulateur (le cas échéant) + + Intégration des oracles ++ Les cas de test `p2p_money_transfer` de la collection [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) sont un bon point de départ. + +##### Étapes pour exécuter le script bash qui lance Newman / Postman en CLI ++ Pour cette méthode, vous devez être en possession du fichier PEM du serveur sur lequel le cadre a été déployé sur une instance EC2 sur Amazon Cloud. + ++ Connectez-vous en SSH à l’instance EC2 ; l’exécution du script lancera les commandes dans un conteneur Docker instancié. + ++ Les URL de la collection Postman et du fichier d’environnement sont des paramètres d’entrée (ainsi qu’une liste d’e-mails pour le rapport), ce qui permet d’exécuter librement la collection de votre choix. + ++ Avec un fichier d’environnement, les services Mojaloop ciblés peuvent être sur n’importe quel serveur. Vous pouvez donc exécuter tout test Postman contre toute installation Mojaloop sur le serveur de votre choix. + ++ L’instance EC2 utilisée pour ces tests ne fait qu’héberger les outils et processus d’exécution ; elle n’héberge pas les services Mojaloop eux-mêmes. + +``` +./testMojaloop.sh +``` + +## Flux d’un test planifié typique + +![](./assets/automated-testing/QARegressionTestingMojaloop-Complete.svg) + + +## Commandes Newman +La section suivante est une référence, issue du site du paquet Newman, présentant les commandes utilisables pour accéder à l’environnement Postman via la CLI. +``` +Exemple : ++ newman run -e -n 1 -- + +Usage : run [options] + + URL ou chemin vers une collection Postman. + + Options : + + -e, --environment URL ou chemin vers un environnement Postman. + -g, --globals URL ou chemin vers un fichier de globales Postman. + --folder Dossier à exécuter dans une collection. Peut être répété pour plusieurs dossiers (défaut : ) + -r, --reporters [reporters] Rapporteurs à utiliser pour cette exécution. (défaut : cli) + -n, --iteration-count Nombre d’itérations à exécuter. + -d, --iteration-data Fichier de données pour les itérations (json ou csv). + --export-environment Exporte l’environnement dans un fichier après l’exécution. + --export-globals Fichier de sortie pour les globales à la fin. + --export-collection Fichier de sortie pour sauvegarder la collection exécutée + --postman-api-key Clé API pour charger les ressources depuis l’API Postman. + --delay-request [n] Délai entre les requêtes (millisecondes) (défaut : 0) + --bail [modifiers] Arrêt propre ou non de l’exécution sur erreur et code de sortie selon le modificateur optionnel. + -x , --suppress-exit-code Remplacer ou non le code de sortie par défaut pour cette exécution. + --silent N’affiche pas la sortie Newman dans la CLI. + --disable-unicode Remplace les symboles Unicode par du texte brut + --global-var Variables globales en ligne de commande, format clé=valeur (défaut : ) + --color Activer/désactiver la couleur. (auto|on|off) (défaut : auto) + --timeout [n] Délai d’exécution de la collection (millisecondes) (défaut : 0) + --timeout-request [n] Délai pour les requêtes (millisecondes). (défaut : 0) + --timeout-script [n] Délai pour les scripts (millisecondes). (défaut : 0) + --ignore-redirects Si présent, Newman ne suit pas les redirections HTTP. + -k, --insecure Désactive la validation SSL. + --ssl-client-cert Chemin vers le certificat client SSL (.cert ou .pfx). + --ssl-client-key Chemin vers la clé client SSL (non nécessaire pour .pfx) + --ssl-client-passphrase Passphrase client SSL (optionnel, pour clés protégées). + -h, --help Affiche l’aide +``` diff --git a/docs/fr/community/tools/ci_cd_pipelines.md b/docs/fr/community/tools/ci_cd_pipelines.md new file mode 100644 index 000000000..72f125478 --- /dev/null +++ b/docs/fr/community/tools/ci_cd_pipelines.md @@ -0,0 +1,117 @@ +# Pipelines CI/CD + +La communauté Mojaloop utilise [CircleCI](https://circleci.com/) pour construire, tester et déployer automatiquement notre logiciel. Ce document décrit comment nous utilisons la CI/CD dans Mojaloop, les différentes vérifications effectuées sur le logiciel et la façon dont nous le distribuons. + +Globalement, nous utilisons deux types de flux de travail selon le type de projet : +- Bibliothèque : construire le projet Node → tester → publier sur [npm](https://www.npmjs.com/search?q=%40mojaloop) +- Service : construire l’image Docker → tester → publier sur [Docker Hub](https://hub.docker.com/u/mojaloop) + +Nous maintenons également un ensemble de [charts Helm Mojaloop](http://docs.mojaloop.io/helm/), construits à partir du dépôt [mojaloop/helm](https://github.com/mojaloop/helm). + +## Bibliothèques + +> Pour un bon exemple de ce modèle CI/CD, voir [central-services-shared](https://github.com/mojaloop/central-services-shared/blob/master/.circleci/config.yml) + +### Flux des pull requests (PR) : + +Le flux PR s’exécute sur les pull requests ; pendant le [processus de revue des PR](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/creating-new-features.md#creating-new-features), ces contrôles doivent être satisfaits pour que le code soit fusionné. + +![](./assets/images/ci_cd_lib_pr.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Vérifie que le titre de la PR respecte la spécification des commits conventionnels | Défini dans un orb CircleCI ici : [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Lance les tests unitaires et vérifie que la couverture de code dépasse la limite fixée. | En général 90 % | +| test-unit | Lance les tests unitaires. Échec si un test unitaire échoue. | | +| vulnerability-check | Lance l’outil `npm audit` pour rechercher des vulnérabilités dans les dépendances | `npm audit` comporte beaucoup de faux positifs ou de problèmes de sécurité qui ne s’appliquent pas à notre base de code. Nous utilisons `npm-audit-resolver` pour pouvoir ignorer certaines vulnérabilités, par ex. les `devDependencies` | +| audit-licenses | Lance l’outil Mojaloop `license-scanner-tool` et échoue si une licence trouvée ne figure pas sur la liste autorisée dans `license-scanner-tool` | [Dépôt license-scanner-tool](https://github.com/mojaloop/license-scanner-tool) | + + +### Flux master et release : + +Ce pipeline CI/CD s’exécute sur la branche master/main : + +![](./assets/images/ci_cd_lib_master.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Voir ci-dessus | | +| test-coverage | Voir ci-dessus | | +| test-unit | Voir ci-dessus | | +| vulnerability-check | Voir ci-dessus | | +| audit-licenses | Voir ci-dessus | | +| release | Exécute une release qui crée une étiquette Git et la pousse | | +| github-release | Ajoute les métadonnées de release (p. ex. changelog) sur GitHub, envoie une alerte Slack sur #announcements | | + + +### Flux des étiquettes : + +Une fois une étiquette Git poussée vers le dépôt, elle déclenche un flux de travail qui se termine par une publication sur `npm`. Les contrôles sont tous relancés pour s’assurer que rien n’a changé (p. ex. dépendances) entre main/master et l’artefact effectivement publié sur `npm`. + +![](./assets/images/ci_cd_lib_tag.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Voir ci-dessus | | +| test-coverage | Voir ci-dessus | | +| test-unit | Voir ci-dessus | | +| vulnerability-check | Voir ci-dessus | | +| audit-licenses | Voir ci-dessus | | +| publish | Publie la dernière version de la bibliothèque selon l’étiquette Git | | + + +## Services + +> Pour un bon exemple de ce modèle CI/CD, voir [central-ledger](https://github.com/mojaloop/central-ledger/blob/master/.circleci/config.yml) + +### Flux des pull requests (PR) : + +Le flux PR s’exécute sur les pull requests ; pendant la revue des PR, ces contrôles doivent être satisfaits pour que le code soit fusionné. + +![](./assets/images/ci_cd_svc_pr.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Vérifie que le titre de la PR respecte la spécification des commits conventionnels | Défini dans un orb CircleCI ici : [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Lance les tests unitaires et vérifie que la couverture de code dépasse la limite fixée. | En général 90 % | +| test-unit | Lance les tests unitaires. Échec si un test unitaire échoue. | | +| test-integration | Lance les tests d’intégration. En général en construisant une image Docker localement | | +| vulnerability-check | Lance l’outil `npm audit` pour rechercher des vulnérabilités dans les dépendances | `npm audit` comporte beaucoup de faux positifs ou de problèmes de sécurité qui ne s’appliquent pas à notre base de code. Nous utilisons `npm-audit-resolver` pour pouvoir ignorer certaines vulnérabilités, par ex. les `devDependencies` | +| audit-licenses | Lance l’outil Mojaloop `license-scanner-tool` et échoue si une licence trouvée ne figure pas sur la liste autorisée dans `license-scanner-tool` | [Dépôt license-scanner-tool](https://github.com/mojaloop/license-scanner-tool) | + + +### Flux master et release : + +Ce pipeline CI/CD s’exécute sur la branche master/main : + +![](./assets/images/ci_cd_svc_master.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Voir ci-dessus | | +| test-coverage | Voir ci-dessus | | +| test-unit | Voir ci-dessus | | +| test-integration | Voir ci-dessus | | +| vulnerability-check | Voir ci-dessus | | +| audit-licenses | Voir ci-dessus | | +| release | Exécute une release qui crée une étiquette Git et la pousse | | +| github-release | Ajoute les métadonnées de release (p. ex. changelog) sur GitHub, envoie une alerte Slack sur #announcements | | + + +### Flux des étiquettes : + +Une fois une étiquette Git poussée vers le dépôt, elle déclenche un flux de travail qui se termine par la publication d’une image Docker sur Docker Hub. Les contrôles sont tous relancés et des analyses supplémentaires sont effectuées sur l’image Docker avant son envoi. + +![](./assets/images/ci_cd_svc_tag.png) + +| Étape | Description | Plus d’infos | +| --- | ----------- | --------- | +| pr-title-check | Voir ci-dessus | | +| test-coverage | Voir ci-dessus | | +| test-unit | Voir ci-dessus | | +| vulnerability-check | Voir ci-dessus | | +| audit-licenses | Voir ci-dessus | | +| build | Construit l’image Docker | | +| image-scan | Lance `anchore/analyze_local_image` pour analyser l’image | Voir l’orb CircleCI [anchore-engine](https://circleci.com/developer/orbs/orb/anchore/anchore-engine) pour plus d’informations. | +| license-scan | Lance l’outil Mojaloop `license-scanner-tool` sur les licences contenues dans l’image Docker | | +| publish | Publie la dernière version de la bibliothèque selon l’étiquette Git | | diff --git a/docs/fr/community/tools/code-quality-metrics.md b/docs/fr/community/tools/code-quality-metrics.md new file mode 100644 index 000000000..1372c4dcf --- /dev/null +++ b/docs/fr/community/tools/code-quality-metrics.md @@ -0,0 +1,30 @@ +# Métriques de qualité du code + +## Métriques de qualité fonctionnelle + +### Métriques des tests unitaires + +Une couverture élevée et des dépendances faibles indiquent que le code est testable, donc bien isolé et facile à maintenir. Une faible complexité rend le code lisible et maintenable et contribue à imposer le respect du principe de responsabilité unique. Les vrais tests unitaires s’exécutent très rapidement car ils n’appellent pas de composants externes. + +| Métriques de qualité du code | Code nouveau et code du projet | +| :--- | :--- | +| Couverture des tests unitaires | ≥ 80 % de couverture par blocs | +| Vitesse des tests unitaires | ≤ 10 secondes | +| Dépendances / méthode | ≤ 10 | +| Complexité / méthode | ≤ 7 | + +### Composant + +Les tests fonctionnels couvrent en général des combinaisons par paires des états du système. + +### Intégration + +Les tests fonctionnels comportent un test par message et par erreur. Les messages et erreurs traités de la même manière utilisent le même test. + +### Contrat + +Limité à ce dont les équipes consommatrices ont besoin et qui n’est pas déjà couvert par les tests unitaires, de composant et d’intégration existants. Souvent enrichi au fil du temps. + +### Bout en bout + +Les tests bout en bout couvrent les tests d’acceptation à partir de scénarios. diff --git a/docs/fr/community/tools/cybersecurity.md b/docs/fr/community/tools/cybersecurity.md new file mode 100644 index 000000000..d58ce5a66 --- /dev/null +++ b/docs/fr/community/tools/cybersecurity.md @@ -0,0 +1,121 @@ +## Architecture de cybersécurité Mojaloop + +## Introduction + +Mojaloop adopte à la fois une approche sécurisée par conception et une approche fondée sur les risques en matière de cybersécurité : les logiciels open source fournis par la Fondation Mojaloop sont conçus pour être fondamentalement sécurisés et sont évalués en continu par rapport aux risques possibles via plusieurs processus. + +Outre les initiatives de cybersécurité gérées par la Fondation Mojaloop, la communauté élargie compte des experts en cybersécurité capables de fournir du conseil et des services pour renforcer encore les capacités des adoptants. + + + +![Figure 1 - Couches de l’architecture de cybersécurité Mojaloop](./assets/images/mojaloop_cybersec_architecture.jpg "Figure 1 - Couches de l’architecture de cybersécurité Mojaloop") + +Figure 1 - Couches de l’architecture de cybersécurité Mojaloop + +_À noter que bien que la Fondation Mojaloop et la communauté Mojaloop s’efforcent de fournir un logiciel sécurisé par conception et exploitable de manière sécurisée, les adoptants assument la responsabilité ultime de la sécurité de leurs opérations. La Fondation Mojaloop recommande vivement aux adoptants de faire appel à des experts en cybersécurité afin de respecter les bonnes pratiques et l’ensemble des normes et réglementations applicables._ + + +## Sécurisé par conception + + +### Processus de revue de conception + +La Fondation Mojaloop et la communauté gèrent et exploitent plusieurs processus de revue de conception sensibles à la sécurité, qui contribuent aux approches sécurisées par conception et de gestion des risques. + + + +1. Le conseil de gouvernance technique Mojaloop fixe les objectifs techniques de haut niveau en matière de cybersécurité pour le projet Mojaloop ; ils sont mis en œuvre par d’autres instances et processus de la communauté. +2. La communauté Mojaloop exploite une autorité de conception : un groupe structuré d’experts du secteur élus qui se réunissent chaque semaine pour examiner les aspects techniques du logiciel de plateforme, y compris, mais sans s’y limiter, la cybersécurité. +3. La communauté Mojaloop exploite un comité de contrôle des changements d’API : un groupe structuré d’experts du secteur élus qui se réunissent chaque semaine pour examiner les aspects internes et externes des API de la plateforme. Ce groupe a la responsabilité spécifique de veiller à ce que toutes les API Mojaloop soient sécurisées par conception et conformes aux normes industrielles les plus récentes et les plus avancées pour sécuriser les déploiements de la plateforme Mojaloop. +4. La communauté Mojaloop exploite un conseil produit : un groupe structuré d’experts du secteur élus qui se réunissent chaque semaine pour examiner les conceptions de fonctionnalités produit. Ce groupe contribue à l’architecture globale de cybersécurité du ou des produits Mojaloop en examinant et en créant des exigences et spécifications pour la plateforme Mojaloop et sa sécurité. +5. Les normes de la communauté Mojaloop exigent des revues de conception de fonctionnalités et de code par des membres de la communauté et de la fondation experts dans les domaines concernés du système avant que les changements ou le nouveau code soumis par des contributeurs soient acceptés dans les versions officielles. + + +## Contrôles techniques + +La plateforme Mojaloop emploie plusieurs couches techniques de sécurité, détaillées dans les sections suivantes, qui contribuent à une plateforme globalement sécurisée pour les transactions financières. + + + +1. Au niveau du transport réseau, le protocole TLS avec authentification mutuelle X.509 (mTLS) est employé (des recommandations de bonnes pratiques sont fournies pour les suites de chiffrement et algorithmes de hachage appropriés) afin de sécuriser les connexions entre les participants au schéma et le hub Mojaloop. Ce mécanisme, combiné à des processus de gestion des certificats et des clés conformes aux bonnes pratiques, empêche l’écoute et la falsification sur les connexions du schéma. Mojaloop fournit des lignes directrices pour les opérations PKI : [https://docs.mojaloop.io/api/fspiop/pki-best-practices.html](https://docs.mojaloop.io/api/fspiop/pki-best-practices.html). +2. Les signatures Web JSON (JWS) sont utilisées au niveau des messages applicatifs pour garantir l’intégrité des messages et la non-répudiation. Tous les participants au schéma disposent des moyens de détecter si un message entrant a été altéré pendant la transmission. Les participants peuvent également être assurés de l’identité de l’émetteur du message. Les services Mojaloop peuvent utiliser cette même validation de signature pour s’assurer que les messages n’ont pas été altérés avant traitement dans le hub. +3. Mojaloop utilise le [protocole InterLedger](https://docs.mojaloop.io/api/fspiop/v1.1/api-definition.html#interledger-payment-request) (ILP) pendant les phases de devis et de transfert, comme mécanisme cryptographique de type clé-cadenas utilisant la cryptographie asymétrique pour empêcher la falsification des conditions de transfert convenues. +4. Mojaloop applique l’idempotence des requêtes et des contrôles de transition d’état des transactions, ce qui aide à atténuer les attaques par rejeu. +5. La plateforme Mojaloop inclut une couche de passerelle API qui facilite le filtrage par adresse IP, la gestion des identités et des accès OAuth2.0 et les contrôles d’accès par rôles, offrant une protection supplémentaire contre les infiltrations. +6. Les interfaces utilisateur internes et externes (p. ex. pour les participants et les opérateurs du hub, techniques ou métiers) sont sécurisées par OAuth2.0 et des mécanismes de contrôle d’accès par rôles (RBAC), combinés à des processus maker-checker applicables (principe des quatre yeux). +7. Mojaloop prend en charge un modèle de service de gestion de la fraude et des risques (FRMS) à l’échelle du schéma (partagé entre les fournisseurs de services financiers (FSP) et le switch / hub Mojaloop). + + +![Figure 2 - Architecture transactionnelle de cybersécurité du schéma Mojaloop](./assets/images/mojaloop_security_layers.jpg "Figure 2 - Architecture transactionnelle de cybersécurité du schéma Mojaloop") + +Figure 2 - Architecture transactionnelle de cybersécurité du schéma Mojaloop + + +## Gestion des risques + + +### Tests de sécurité + + +#### Analyse automatisée des vulnérabilités + +Mojaloop emploie plusieurs mécanismes techniques pour réaliser une évaluation automatisée des vulnérabilités sur tous les dépôts de code source de la plateforme. Ces mécanismes analysent les dépendances du code et les images de conteneur pour détecter les vulnérabilités connues (à partir de bases de données de vulnérabilités mises à jour en continu selon les standards du secteur) de façon périodique et avant l’acceptation des changements ou ajouts sur les branches principales. Cela réduit la probabilité qu’une vulnérabilité connue dans une dépendance Mojaloop atteigne une version officielle. + + +#### Tests d’intrusion + +Des membres de la communauté Mojaloop réalisent périodiquement des tests d’intrusion sur leurs déploiements à l’aide de cadres de test de sécurité courants et partagent les résultats avec la Fondation Mojaloop dans le cadre d’un processus coordonné de divulgation des vulnérabilités, permettant d’atténuer tout nouveau risque identifié par les flux techniques et/ou les adoptants avant que des tiers puissent exploiter les vulnérabilités. + + +#### Expertise et soutien de la communauté + +La communauté Mojaloop, suivant les principes et processus décrits dans ce document, fournit une plateforme logicielle qui intègre de nombreuses fonctionnalités et capacités de cybersécurité. Pour toutefois concrétiser les meilleures opérations sécurisées possibles, les adoptants de la technologie Mojaloop doivent déployer et exploiter le logiciel de manière sécurisée — tâche souvent difficile et intimidante compte tenu des nombreuses normes et réglementations applicables. La communauté Mojaloop comporte des organisations disposant d’une connaissance et d’une expérience approfondies sur ces sujets et pouvant être sollicitées pour de l’assistance. + + +## Divulgation coordonnée des vulnérabilités + +La Fondation Mojaloop applique un processus de divulgation coordonnée des vulnérabilités. Il s’agit d’un modèle dans lequel une vulnérabilité ou un problème n’est rendu public qu’après que les parties responsables ont disposé d’un délai suffisant pour corriger ou remédier au problème. + +Cette méthode est recommandée par de nombreux gouvernements et organisations internationales reconnues comme processus privilégié pour gérer les vulnérabilités logicielles, car elle offre une protection contre l’exploitation par des tiers au-delà de ce que permettent d’autres modèles. + + +## Contrôles organisationnels + +Outre les contrôles techniques de cybersécurité décrits ailleurs, Mojaloop fournit un ensemble d’outils pour soutenir les contrôles organisationnels, reflétant le fait que si les attaques par piratage et la fraude perpétrées par des acteurs externes attirent le plus les médias, les attaques les plus « réussies » en valeur totale d’argent détourné sont des actions internes commises par le personnel d’un établissement financier. + +Outre les outils fournis dans le cadre de Mojaloop, plusieurs recommandations peuvent être faites concernant les processus métier adoptés par un opérateur de hub, liés à l’exploitation du service. + + +### Points de contrôle + +Mojaloop permet à l’opérateur du hub de définir des points de contrôle où les actions d’un employé sont soumises à des limitations imposées par le hub lui-même. Sous-jacent à cela se trouve la capacité de gestion des identités et des accès de Mojaloop, qui met en œuvre un modèle de contrôle d’accès par rôles (RBAC). Chaque action d’employé au hub n’est autorisée que si l’employé dispose d’un privilège spécifique ; le propriétaire du hub définit un ensemble de rôles, chacun étant une collection de privilèges. Un compte employé est créé et reçoit un rôle (p. ex. responsable financier, administrateur, opérateur, etc.), ce qui contrôle les fonctions qu’il peut exécuter. + +Le RBAC est complété par des contrôles maker/checker. Les fonctions sensibles (p. ex. mouvements de fonds) peuvent être définies (« made ») par un opérateur, mais ne sont exécutées qu’après autorisation (« checked ») par, par exemple, un opérateur financier. + +Toutes les actions des employés sont enregistrées dans un journal d’audit inviolable. Cela permet aux auditeurs forensiques de consulter toute l’activité et, si nécessaire, de « suivre l’argent » lorsqu’un problème survient, par exemple en cas de collusion employés / direction. + + +### Contrôles métier + +L’exploitation d’un hub Mojaloop est un service financier ; la sécurité du service doit être traitée comme pour tout autre service financier, par exemple une banque ou un switch de paiements international. Les contrôles métier constituent la première ligne de défense et limitent la surface d’attaque avant même que les points de contrôle ne soient accessibles. + +Les contrôles métier devraient notamment inclure : + + + +* La cybersécurité peut être compromise par du personnel malveillant. Les opérateurs de hub devraient effectuer des vérifications d’antécédents appropriées lors du recrutement, y compris casier judiciaire et solvabilité pour repérer une dette excessive (vulnérabilité au chantage par des attaquants externes). +* Une attention stricte à la sécurité physique des locaux de l’opérateur du hub (où l’accès au hub Mojaloop est effectué — l’accès à distance, c’est-à-dire le télétravail, ne doit **jamais** être autorisé), notamment : + * Une seule entrée, strictement contrôlée, vers les locaux de l’opérateur du hub. + * Les autres entrées sont sécurisées et les issues de secours sont équipées d’alarmes. + * Toutes les salles sont sécurisées par serrures biométriques, avec entrée **et** sortie enregistrées pour limiter le « tailgating », et l’accès est restreint selon la fonction. + * Le personnel en contact client ou au service financier ne doit pas avoir de téléphone portable sur les locaux ; les téléphones doivent être rangés dans des casiers métalliques (cages de Faraday) pendant les heures de travail. + * Vidéosurveillance et enregistrement 24 h/24 de toutes les zones (les caméras doivent être orientées pour ne pas filmer des écrans pouvant afficher des informations sensibles). + * Vérifier et enregistrer soigneusement l’identité des visiteurs. + * Ne pas autoriser les visiteurs à apporter du matériel électronique dans les zones opérationnelles. + * Dans les zones **non** opérationnelles uniquement, téléphones portables et ordinateurs portables peuvent être autorisés. Cependant, les numéros de série des portables doivent être enregistrés et les hôtes doivent **vérifier que les visiteurs repartent avec le même matériel qu’à l’arrivée**. L’échange d’ordinateurs portables est l’un des moyens les plus rapides de voler des données. + * Veiller à ce que les visiteurs soient accompagnés par un employé responsable de leur comportement. + * Rester attentivement informé de l’activité des visiteurs : + * Ne pas laisser les visiteurs se déplacer seuls. + * Ne pas laisser les visiteurs insérer des clés USB ou autres périphériques dans les ordinateurs portables, imprimantes, etc. de l’entreprise. + +Notez qu’il ne s’agit que d’un sous-ensemble des contrôles attendus pour sécuriser les opérations d’un opérateur de hub. Un opérateur de hub potentiel devrait solliciter un avis spécialisé avant de lancer un service. diff --git a/docs/fr/community/tools/pragmatic-rest.md b/docs/fr/community/tools/pragmatic-rest.md new file mode 100644 index 000000000..5e60c9c3b --- /dev/null +++ b/docs/fr/community/tools/pragmatic-rest.md @@ -0,0 +1,129 @@ +# REST pragmatique + +## REST pragmatique pour le projet Mojaloop + +Avec l’émergence de la stratégie API comme levier de montée en charge pour les services Internet, l’attention portée aux technologies d’interconnexion a évolué. S’appuyant sur les principes qui ont permis au Web de se structurer et de scaler, REST (Representational State Transfer) est devenu un choix de conception privilégié pour les API de services Internet. Mais si les principes REST, proposés dans la thèse de doctorat de Roy Fielding qui les a définis, ont une valeur académique pour la recherche, un design REST pur n’est pas aujourd’hui praticable pour la plupart des applications. Nous préconisons une forme de REST pragmatique — un patron de conception qui adopte les éléments utiles du design RESTful sans exiger une pureté académique stricte. + +### Le modèle de maturité de Richardson + +Martin Fowler a cité un modèle structuré d’adoption RESTful élaboré par Leonard Richardson et [exposé](http://www.crummy.com/writing/speaking/2008-QCon/act3.html) lors d’une conférence QCon. Fowler l’appelle le modèle de maturité de Richardson du design RESTful. + + + +Martin Fowler, en référence à [Rest in Practice](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829)², résume ainsi la genèse du design RESTful : + +> utiliser des services web RESTful pour traiter une grande partie des problèmes d’intégration auxquels les entreprises sont confrontées. Au cœur du propos se trouve l’idée que le Web est une preuve par l’existence d’un système distribué massivement scalable qui fonctionne très bien, et que nous pouvons en tirer des idées pour construire des systèmes intégrés plus facilement. + +Une approche pragmatique du design RESTful emprunte les meilleures parties du cadre conceptuel de Fielding pour permettre aux développeurs et intégrateurs de comprendre aussi rapidement que possible ce qu’ils peuvent faire avec l’API, sans avoir à écrire de code superflu. + +Au plus fondamental, un design RESTful est centré sur les ressources et utilise les verbes HTTP. Au plus avancé, un design REST académique pur applique HATEOAS via des contrôles hypermédia. Nous recommandons un design RESTful de niveau 2 pour Mojaloop. + +### Pourquoi pas les contrôles hypermédia ? + +Bien que HATEOAS soit un principe fascinant — il préconise qu’un serveur réponde à chaque action client par une liste de toutes les actions possibles menant le client vers son prochain état applicatif — et que les clients _ne doivent pas_ s’appuyer sur des informations hors bande (comme une spécification API écrite) pour savoir quelles actions sont possibles sur quelles ressources ni sur le format des URI. + +C’est cette dernière interdiction qui fait échouer le test du REST pragmatique : si HATEOAS est une approche théorique intéressante pour limiter le couplage, elle ne s’applique pas facilement à Mojaloop (ni à tout autre design d’API contractuelle). Si l’on considère le public des API d’interconnexion, on trouve des acteurs commerciaux soumis à des règles de schéma très précises. Les interactions entre participants, et entre participant et hub de services central, sont fortement spécifiées pour fixer un risque commercial acceptable, pour proposer aux utilisateurs finaux des transactions tarifées à très faible coût. Cela exige une prévisibilité _ex ante_ de l’API, incompatible avec le principe HATEOAS défini par Fielding. + +### Principes REST pragmatiques + +#### Les URI définissent les ressources + +Un schéma d’URI bien conçu rend une API facile à consommer, à découvrir et à étendre, comme une API soignée dans un langage classique. Le REST pur dédaigne ce principe au profit de HATEOAS. Mais le REST pragmatique suit un schéma d’URI habituel pour faciliter la compréhension humaine, même si des principes HATEOAS sont employés pour la découverte. + +Les chemins d’URI qui désignent une collection d’objets doivent être un nom pluriel, p. ex. `/customers`, pour un ensemble de clients. Lorsqu’une collection ne peut avoir qu’une seule instance, on utilise le singulier pour éviter la confusion. P. ex. `GET /transfers/:id/fulfillment` est correct, car il n’y a qu’un objet fulfillment par transfert identifié. + +Les chemins d’URI qui désignent un objet unique doivent être un nom pluriel (la collection) suivi d’un identifiant unique prédéfini. P. ex. `/customers/123456` pour le client numéro 123456. L’identifiant doit être unique dans la collection et persister pendant la vie de l’objet dans cette collection. Les identifiants ne doivent pas être des valeurs ordinales — un parcours ordinal dans une collection se fait via des paramètres de requête sur l’URI de collection. + +Les chemins d’URI peuvent avoir un préfixe pour l’environnement, la version ou un autre contexte de la ressource. Après le chemin d’identification, il ne doit suivre que des collections et des références d’objets. + +Les identifiants de segments de chemin et de requête doivent être choisis dans l’ensemble des caractères romains `[0-9A-Za-z]`. Utiliser _camelCase_ pour les éléments du chemin d’URI. Ne pas utiliser snake_case. + +Pour lever toute ambiguïté, le caractère « _ » (tiret bas) et « - » (tiret) ne doivent pas être utilisés dans les identifiants de segments de chemin ou de requête. + +Cela peut sembler un peu étroit. L’objectif est d’avoir un format d’URI bien défini, cohérent avec les usages répandus, simple à décrire, prévisible, et qui se mappe aux environnements et conventions natifs. Cela ne satisfera pas tout le monde. Voici la logique de cette contrainte : + +CapitalCase et camelCase sont la norme de facto pour NodeJS et JavaScript et une contrainte courante pour les URI : les segments de chemin sont souvent mappés vers des ressources internes JS ; respecter les conventions JS est cohérent. + +Les noms de champs en JSON et SQL doivent suivre la même convention, car ils sont souvent mappés automatiquement vers l’espace de noms des variables et peuvent être référencés dans les URI comme segments de chemin ou de requête. + +Il faut aussi éviter « $ » sauf si une bibliothèque l’exige (p. ex. jQuery). Le JCL IBM est révolu ; laissons-le en paix. Il existe de meilleurs outils de portée pour séparer les espaces de noms que d’introduire des symboles non romains. + +Il faut éviter « - » (tiret) dans les noms de segments de chemin et de paramètres de requête car cela ne se mappe pas aux noms de variables, SQL ou champs JSON. + +Les caractères tiret bas doivent être échappés dans le source Markdown en les préfixant par « \ ». + +On a signalé que snake_case serait légèrement plus lisible que camelCase dans les noms de variables, mais cela n’améliore pas la lisibilité des URI : cela gêne visuellement la lecture des délimiteurs de segments de chemin et de requête. Et lorsque les URI sont soulignées à l’affichage, les tirets bas deviennent illisibles. + +#### Paramètres d’URI + +Utiliser un ensemble standard et prévisible de paramètres optionnels de manière cohérente. + +Un ensemble standard de paramètres de requête doit servir pour les collections afin de laisser l’appelant contrôler la portion de collection retournée. « count » pour définir le nombre d’objets à retourner, « start » pour définir le point de départ dans le jeu de résultats, et « q » comme requête de recherche libre. Nous définirons l’ensemble standard au fil du temps et l’appliquerons de façon uniforme. + +#### Verbes + +Les objets singuliers doivent prendre en charge GET pour la lecture, PUT pour le remplacement complet (ou la création lorsque la clé primaire est fournie par le client et persistante, p. ex. un PAN de carte de paiement), et DELETE pour la suppression. + +Les collections doivent prendre en charge GET pour lire tout ou partie d’une collection, et POST pour ajouter un nouvel objet à la collection. + +Les objets singuliers peuvent prendre en charge POST pour modifier leur état de façon déterminée. Poster un document JSON vers l’URI d’un objet singulier peut mettre à jour des champs sélectionnés ou déclencher un changement d’état ou une action sans remplacer tout l’objet. + +GET doit être implémenté de manière _nullipotente_ — c’est-à-dire que GET ne provoque jamais d’effets de bord ni ne modifie l’état visible par le client hors journalisation ou mise à jour des métriques d’instrumentation. + +PUT et DELETE doivent être implémentés de manière _idempotente_ — les changements s’appliquent de façon cohérente aux données du système en ne dépendant que de l’état de la ressource et des entrées, rien d’autre. L’action n’a pas d’effet supplémentaire si elle est répétée avec les mêmes paramètres et ne dépend pas de l’ordre d’autres opérations sur une collection ou d’autres ressources. Par exemple, retirer une ressource d’une collection peut être idempotent sur la collection. Utiliser PUT pour remplacer (ou créer) entièrement une ressource identifiée de façon unique lorsque l’URI est entièrement connue du client est aussi idempotent. Le système peut donc réordonner les opérations pour gagner en efficacité ; le client n’a pas besoin de savoir si la ressource existe avant de tenter un remplacement. + +POST et PATCH ne sont pas des opérations idempotentes. POST sert à créer des ressources dont l’identifiant est assigné par le serveur ou lorsqu’une ressource interne unique est impliquée par l’URI cible (p. ex. `POST /transfers`, mais `PUT /transfers/:id/fulfillment`). Voir la note 3 (RFC 5789). + +#### Format des données + +Nous privilégions les formats liés à [JSON](http://json.org/) plutôt que XML (voir note 4). Dans certains cas, les formats seront binaires ou XML, selon des normes préexistantes, et seront précisément spécifiés. Les formats binaires doivent avoir une syntaxe formelle pour éviter des ambiguïtés de représentation (jeux de caractères, représentations big-endian ou little-endian des valeurs numériques, etc.). + +Les dates et heures utilisées dans les API doivent respecter la norme ISO 8601, avec le profil du document W3C sur les formats date et heure (voir note 5). Cette note W3C doit réduire la complexité et les erreurs lorsque des composants échangent des dates et heures concrètes. Il existera des cas où un format non ISO sera requis par une norme externe, p. ex. dates d’expiration ISO 7813. + +Les formats XML standard existants doivent disposer d’un schéma XSD pour le sous-ensemble de profil acceptable dans le projet. Pour des formats particulièrement complexes, on peut utiliser un traducteur de profil commun pour mapper entre le sous-ensemble projet du format standard et le format fil utilisé par un protocole normalisé. Cela limite le couplage aux formats complexes de façon plus maintenable. + +Lorsque l’action PATCH est spécifiée pour une ressource, nous utiliserons un format de document de patch cohérent (p. ex. [JSON Patch](http://jsonpatch.com/), voir note 6). + +#### Codes de retour + +Utiliser les codes HTTP de façon cohérente et conformément à leurs définitions standard. Les codes standard sont définis dans la RFC 2616 (voir note 7). + +#### Format d’erreur lisible par machine + +L’API doit fournir un résultat d’erreur lisible par machine dans un format JSON bien défini. {À définir : enveloppe de réponse et format des erreurs, défauts et enveloppes de succès. Le design RESTful s’appuie sur les en-têtes pour les erreurs de protocole ; les infos de débogage peuvent aussi transiter dans les en-têtes. Il faut être clair sur l’usage d’une enveloppe et comment elle soutient la communication production normale entre client et serveur.} + +#### Versionnement + +Les URI d’API doivent inclure un identifiant de version au format `vM` comme premier segment de chemin (où _M_ est la composante majeure du numéro de version). L’API et son identifiant de version doivent respecter la spécification [versionnement sémantique](http://semver.org/) 2.0 pour le versionnement d’API (voir note 8). + +Un client doit indiquer le numéro de version majeure dans chaque requête. Un client ne peut pas exprimer l’exigence d’une version mineure précise. + +Le numéro de version complet de l’API est indiqué dans l’en-tête de réponse (À définir) pour toutes les réponses réussies et en erreur. + +Bien que le contrat de version d’une API soit influencé par les niveaux majeur, mineur _et_ correctif, seul le numéro majeur lie l’API en production — un client de production ne peut pas demander une version mineure ou un niveau de correctif particulier, et un serveur de production n’accepte pas une requête URI qui spécifierait ces éléments supplémentaires. + +En revanche, dans les environnements de préproduction, on prévoit qu’une combinaison de suffixes mineur, correctif, pré-release et métadonnées puisse être prise en charge dans les requêtes client (comme défini dans _semver_ [3]) et _peut_ figurer dans les URI de _préproduction_ pour faciliter le développement et l’intégration. + +### Il sera peut-être temps de mettre REST de côté + +En concevant les API d’interconnexion entre composants et systèmes participants, nous pourrions rencontrer des exigences qui ne correspondent pas exactement au modèle REST pragmatique défini ici. Nous évaluerons au cas par cas et choisirons ce qui sert le mieux les objectifs du projet. + +### Exigences non fonctionnelles + +En développant les API, nous ferons des choix cohérents sur les exigences non fonctionnelles pour renforcer les objectifs du projet. + +1: [http://martinfowler.com/articles/richardsonMaturityModel.html](Richardson%20Maturity%20Model), consulté le 18 août 2016. + +2: [https://www.amazon.com/gp/product/0596805829](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829), consulté le 18 août 2016. + +3: RFC 5789, _PATCH Method for HTTP_, [https://tools.ietf.org/html/rfc5789](https://tools.ietf.org/html/rfc5789), consulté le 18 août 2016. + +4: _Introducing JSON_, [http://json.org/](http://json.org/), consulté le 18 août 2016. + +5: [http://www.w3.org/TR/1998/NOTE-datetime-19980827](http://www.w3.org/TR/1998/NOTE-datetime-19980827), consulté le 22 août 2016. + +6: _JSON Patch_, [http://jsonpatch.com/](http://jsonpatch.com/), consulté le 18 août 2016. + +7: [https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) + +8: _Semantic Versioning 2.0.0_, [http://semver.org/](http://semver.org/), consulté le 18 août 2016. diff --git a/docs/fr/community/tools/tools-and-technologies.md b/docs/fr/community/tools/tools-and-technologies.md new file mode 100644 index 000000000..cebea8844 --- /dev/null +++ b/docs/fr/community/tools/tools-and-technologies.md @@ -0,0 +1,51 @@ +# Outils et technologies + +Nous documentons ici les raisons des choix d’outils, de technologies et de processus pour Mojaloop, ainsi que les liens et versions recommandés pour chacun. + +**CHOIX D’OUTILS** + +* **Développement d’API** + * **Open API 3.0** est utilisé pour le développement d’API (Swagger 2.0 auparavant). + * **ISTIO** en tant que passerelle API (WSO2 est désormais obsolète avec Mojaloop v16.0.0 - Congo et IaC v5.0.0 et suivants) offre une plateforme d’entreprise pour intégrer API, applications et services web — localement et sur Internet. Il fournit à Mojaloop une couche de sécurité et un portail de développement. +* **Circle-CI** — Outil utilisé pour l’intégration et le déploiement continus. Il nous fallait un système de build et de tests en ligne pouvant fonctionner avec de nombreux petits projets et une équipe distribuée. Jenkins a été envisagé, mais il impose d’héberger un serveur et une configuration lourde. CircleCI permet une solution sans hébergement propre, démarrable sans coût et avec une configuration minimale. Nous pensions pouvoir commencer avec CircleCI et migrer plus tard si nécessaire — ce besoin ne s’est pas présenté. +* **Dactyl** — Nous devons pouvoir imprimer la documentation en ligne. Bien qu’on puisse imprimer des fichiers Markdown un par un, nous souhaitons regrouper les fichiers en un ensemble de documents PDF finaux, où une même page peut se retrouver dans plus d’un manuel. [Dactyl](https://github.com/ripple/dactyl) est un outil open source maintenu de conversion Markdown vers PDF. Nous avions d’abord essayé Pandoc, mais il gérait mal les tableaux. Dactyl corrige cela et est plus flexible. +* **DBeaver** — [DBeaver](https://dbeaver.io/) est un outil multi-plateforme gratuit pour développeurs, programmeurs SQL, administrateurs et analystes de bases de données. Il prend en charge les bases courantes : MySQL, PostgreSQL, MariaDB, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Derby, etc. +* **Docker** — Le moteur de conteneurs Docker crée et exécute des conteneurs à partir de fichiers d'images Docker. +* **Docker Hub** sert à lier, construire, tester et pousser les dépôts de code Mojaloop. Nous devions prendre en charge l’exécution locale et cloud. Nous avons de nombreux microservices à configurations simples et spécifiques. Le moyen le plus simple de garantir le même comportement dans chaque environnement — du développement local au cloud jusqu’à la production hébergée — est de placer chaque microservice dans un conteneur Docker avec tous les prérequis nécessaires à son exécution. Le conteneur devient une unité fermée, sécurisée, préconfigurée et exécutable. +* **Draw.io** — Nous devons produire des schémas et diagrammes d’architecture pour la documentation avec un outil idéalement gratuit, compatible open source, multi-plateforme, vectoriel et matriciel, WYSIWYG, utilisable avec Markdown et simple. Nous avons évalué de nombreux outils : Visio, Mermaid, PlantUML, Sketchboard.io, LucidChart, Cacoo, Archi, Google Drawings. Draw.io correspond le mieux à nos besoins : gratuit, maintenu, simple, formats adaptés, intégration Dropbox et GitHub, multi-plateforme. Pour archiver nos diagrammes, nous sauvegardons deux copies — une en SVG (vectoriel) et une en PNG (matriciel). Nous utilisons le PNG dans la doc car il s’affiche directement sur GitHub. Le SVG sert de maître car il est éditable. +* **ESLint** — Dans le code JavaScript, nous utilisons [ESLint](https://eslint.org/) comme guide de style et outil d’application du style. +* **GitHub** — [GitHub](https://github.com/Mojaloop) est un service de dépôt de code très répandu, basé sur git, le standard des projets open source. Le choix de GitHub était donc naturel. Nous créons une story pour chaque travail d’intégration, des bugs pour les problèmes, et suivons les stories dans tout le pipeline pour des métriques fiables. +* **Helm** — Le gestionnaire de paquets Helm pour Kubernetes fournit des déploiements et configurations modélisés et permet de maîtriser la complexité globale. +* **IaC** — L’infrastructure as code (IaC) regroupe les outils et scripts pour déployer une plateforme Mojaloop au niveau de qualité souhaité, du développement, QA ou sandbox jusqu’à la préproduction ou une qualité de production étendue. Elle s’appuie sur les releases Mojaloop comme cœur et déploie tout l’écosystème nécessaire au fonctionnement d’un switch Mojaloop. +* **Kafka** — Cette technologie répond au besoin de messagerie à fort débit et volume tout en limitant les exigences matérielles. +* **JavaScript** — L’application Mojaloop est principalement écrite en JavaScript. +* **Kubectl** — Interface en ligne de commande pour exécuter des commandes sur les clusters Kubernetes. +* **Kubernetes** — Outil d’entreprise fournissant une couche d’abstraction, la gestion d’infrastructure et l’orchestration de conteneurs. +* **Markdown** — La documentation est un livrable du projet au même titre que le code : nous voulons la versionner, la revue, le commit et le suivi des changements comme le code. Nous voulons aussi une consultation en ligne simple sans ouvrir constamment un lecteur dédié. GitHub intègre Markdown, ce qui convient bien. Les mêmes fichiers servent au wiki et aux documents. Ils peuvent être revus au commit avec les mêmes outils et lus directement sur GitHub. Google Docs, Word et PDF ont été écartés car ces formats binaires se différencient mal. Inconvénient : Markdown n’autorise qu’un formatage simple — pas de tableaux complexes ni de polices variables — mais cela suffit lorsque la priorité est la clarté. +* **Mojaloop Testing Toolkit (TTK)** — Le [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit) est un outil couteau-suisse pour les activités Mojaloop, surtout pour les tests bout en bout, les démonstrations, le mock d’API et d’autres scénarios. Les collections de tests Mojaloop utilisent le ML TTK ; c’est l’outil privilégié pour les tests bout en bout, intégré aussi aux scripts de tests automatisés (TTK CLI dans l’IaC et autres environnements dev/qa). +* **MySQLWorkbench** — [MySQL Workbench](https://www.mysql.com/products/workbench/) est un outil visuel unifié pour architectes, développeurs et DBA. Il couvre la modélisation, le développement SQL et l’administration (configuration serveur, utilisateurs, sauvegardes, etc.). Disponible sous Windows, Linux et macOS. +* **NodeJS** — Environnement d’exécution JavaScript basé sur le moteur V8 de Chrome qui exécute Mojaloop. NodeJS convient aux microservices simples et dispose d’un vaste écosystème de bibliothèques open source. Les performances sont correctes ; les composants Node ne montent pas beaucoup en vertical, mais nous prévoyons de scaler horizontalement, ce qu’il gère bien. Le code Interledger d’origine et le prototype de niveau un étaient en NodeJS. La plupart des équipes utilisaient déjà Node, ce qui a motivé ce choix. Dans le code NodeJS, nous utilisons [Standard](https://www.npmjs.com/package/standard) comme guide et application du style. +* **NPM** — Gestionnaire de paquets pour Mojaloop, le JavaScript étant le langage par défaut. +* **Percona** pour **MySQL** — Ces outils servent de SGBDR pour assurer haute performance et fonctionnalités de niveau entreprise au système Mojaloop. Il nous fallait un backend SQL compatible open source et scalable en production ; nous avons choisi MySQL. +* **Postman** — Application Google Chrome pour interagir avec des API HTTP. Elle offre une interface conviviale pour construire des requêtes et lire les réponses. +* **Rancher 2.0** — La gestion, le provisionnement et la supervision de l’infrastructure sont assurés par Rancher 2.0, plateforme Kubernetes d’entreprise pour gérer déploiements et clusters sur cloud et sur site. Rancher facilite pour les équipes DevOps le test, le déploiement et l’exploitation de Mojaloop où qu’il tourne. +* **Slack** — Slack sert à la communication interne d’équipe, en partie parce que plusieurs équipes l’utilisaient déjà et le préféraient au courriel pour rester léger. +* **SonarCloud** — Nous avions besoin d’un tableau de bord en ligne sur la qualité du code (taille, complexité, problèmes, couverture) agrégeant tous les dépôts. SonarCloud pour Mojaloop est gratuit avec un peu de configuration. Il propose aussi des contrôles sur les pull requests et des notes selon les quality gates. +* **SourceTree** — [Sourcetree](https://www.sourcetreeapp.com/) simplifie le travail avec les dépôts Git pour se concentrer sur le code. Visualisation et gestion via une interface graphique Git. Chaque développeur reste libre de son outil, dans le respect des recommandations GitHub générales. +* **Visual Studio Code** — [Visual Studio Code](https://code.visualstudio.com/) est un éditeur orienté développement et débogage d’applications web et cloud modernes. Gratuit et disponible sur Linux, macOS et Windows. +* **ZenHub** — Il nous fallait une gestion de projet légère et cloud pour équipes distribuées, avec epics, stories, bugs et un tableau projet simple. Les offres en ligne VS et Jira ont été envisagées. Pour une petite équipe distribuée, un service en ligne convenait mieux. Pour un projet open source, nous voulions éviter les coûts récurrents d’un serveur dédié. Une intégration forte avec GitHub était importante ; suivre le travail par microservice avec ce microservice était très utile. Jira et VS apportaient plus de lourdeur que nécessaire pour cette taille de projet et s’intègrent moins bien à GitHub. ZenHub nous a permis de démarrer tout de suite. Inconvénient : pas de diagrammes de flux cumulatif ni de suivi du nombre de stories plutôt que des points — nous le faisons manuellement avec une feuille de calcul mise à jour quotidiennement et publiée sur le canal Slack « Project Management ». + +**CHOIX TECHNOLOGIQUES** + +* **Développement agile** — Méthodologie utilisée pour piloter le projet. Les exigences doivent être affinées au fil du développement ; nous avons préféré l’agile au waterfall ou au lean. +* **APIs** — Pour limiter la confusion due à de nombreux microservices changeants, nous utilisons des API fortement définies conformes à notre modèle [REST pragmatique](pragmatic-rest.md). Les API sont définies avec OpenAPI. Les équipes documentent leurs API avec Swagger v2.0 ou RAML v0.8 pour tester, documenter et partager automatiquement. Swagger est légèrement privilégié grâce aux outils gratuits. Mule utilisera RAML 0.8. Swagger peut être converti automatiquement en RAML v0.8, ou manuellement en RAML v1.0 pour plus de lisibilité. +* **Tests automatisés** — La majorité des tests sont automatisés pour faciliter la régression. Voir la [stratégie de tests automatisés](automated-testing.md) et les [métriques de qualité du code](code-quality-metrics.md). +* **Hébergement** — Mojaloop est conçu pour être agnostique vis-à-vis de l’infrastructure ; il est pris en charge sur AWS, Azure et en installation sur site. +* **Interledger** — Mojaloop avait besoin d’un protocole de transport léger, ouvert et sécurisé pour les fonds. [Interledger.org](http://Interledger.org) répond à ce besoin et permet de se connecter à d’autres systèmes. Les blockchains ont aussi été envisagées, mais elles envoient des messages très volumineux, difficiles à livrer de façon fiable sur des infrastructures fragiles. De plus, l’anonymat fort des blockchains ne correspond pas à un objectif du projet : pour la lutte contre la fraude, les autorités réglementaires doivent pouvoir consulter les données de transferts par compte et par personne. +* **Open source** — L’ensemble du projet est publié en open source conformément aux [principes Level One Project](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf). Tous les outils et processus doivent être compatibles open source et favoriser les projets sous licence Apache 2.0 sans contraintes de licences restrictives pour les développeurs. +* **Système d’exploitation** — Windows est très répandu dans les pays cibles, mais nous avions besoin d’un OS sans frais de licence et compatible open source : nous utilisons Linux. Nous ne dépendons pas d’une distribution particulière ; nous nous basons sur Amazon Linux de base. Dans les conteneurs Docker, [Alpine Linux](https://alpinelinux.org/) est utilisé. +* **Microservices** — L’architecture doit se déployer et scaler facilement, avec des composants remplaçables ou mis à jour simplement ; elle est donc découpée en microservices. +* **Scaled Agile Framework** — Quatre équipes de développement initiales étaient géographiquement séparées. Pour garder la première phase du projet sur les rails, le [Scaled Agile Framework (SAFe)](https://www.scaledagileframework.com/) a été choisi. Le travail est découpé en program increments (PI) d’environ quatre sprints de deux semaines. Comme pour les sprints, chaque PI a des objectifs démontrables définis en réunion de PI. +* **Services** — Les microservices sont regroupés et déployés en quelques services (DFSP, annuaire central, etc.). Chacun dispose d’interfaces simples, de scripts de configuration, de tests et de documentation. +* **Modélisation des menaces, de la résilience et de la santé** — Le code Mojaloop échange de l’argent dans des environnements à infrastructure très instable ; il doit donc être sécurisé, résilient, exposer facilement son état de santé et tenter automatiquement d’y revenir. +* **USSD** — Les smartphones ne représentent qu’environ 25 % du marché cible et ne sont pas actuellement pris en charge par la plupart des services de transfert d’argent ; nous avons besoin d’un protocole fonctionnant sur les téléphones basiques. Comme M-Pesa, nous utilisons USSD entre le téléphone et le fournisseur de services financiers numériques (DFSP). diff --git a/docs/fr/getting-started/README.md b/docs/fr/getting-started/README.md new file mode 100644 index 000000000..3f3d9657e --- /dev/null +++ b/docs/fr/getting-started/README.md @@ -0,0 +1,24 @@ +# Votre première action + +Pour vous aider à bien démarrer avec Mojaloop, choisissez l’option ci-dessous qui correspond le mieux à vos besoins : + + +1. [Foire aux questions](./faqs) +2. [Licence](./license.md) +3. [Consulter les API Mojaloop](/api/) +4. [Suivre un programme de formation](https://mojaloop.io/mojaloop-training-program/) +5. [Contribuer à Mojaloop](/community/) +6. [Installer Mojaloop](./installation/installing-mojaloop.md) +7. [Démos](./demos/mojaloop-overview.md) + + 7.1. [Pourquoi Mojaloop ?](./demos/why-mojaloop.md) + + 7.2. [Comment travailler avec Mojaloop ?](./demos/working-with-mojaloop.md) + + 7.3. [Inclusion financière 101](./demos/financial-inclusion-101.md) + + 7.4. [Qu’est-ce que le RTP ?](./demos/what-is-rtp.md) + + 7.5. [Qu’est-ce qui fait un écosystème financier réussi ?](./demos/what-makes-a-successful-financial-ecosystem.md) + + 7.6. [Dans la boucle](./demos/inside-the-loop.md) diff --git a/docs/fr/getting-started/demos/financial-inclusion-101.md b/docs/fr/getting-started/demos/financial-inclusion-101.md new file mode 100644 index 000000000..2a3642c63 --- /dev/null +++ b/docs/fr/getting-started/demos/financial-inclusion-101.md @@ -0,0 +1,11 @@ +# Inclusion financière 101 + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/inside-the-loop.md b/docs/fr/getting-started/demos/inside-the-loop.md new file mode 100644 index 000000000..db8283c7f --- /dev/null +++ b/docs/fr/getting-started/demos/inside-the-loop.md @@ -0,0 +1,26 @@ +# Dans la boucle + + +## Partie 1 + + + +## Partie 2 + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/mojaloop-overview.md b/docs/fr/getting-started/demos/mojaloop-overview.md new file mode 100644 index 000000000..509291755 --- /dev/null +++ b/docs/fr/getting-started/demos/mojaloop-overview.md @@ -0,0 +1,11 @@ +# Présentation de Mojaloop + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/what-is-rtp.md b/docs/fr/getting-started/demos/what-is-rtp.md new file mode 100644 index 000000000..ea83a016b --- /dev/null +++ b/docs/fr/getting-started/demos/what-is-rtp.md @@ -0,0 +1,11 @@ +# Qu’est-ce que le RTP ? + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/what-makes-a-successful-financial-ecosystem.md b/docs/fr/getting-started/demos/what-makes-a-successful-financial-ecosystem.md new file mode 100644 index 000000000..943586bd0 --- /dev/null +++ b/docs/fr/getting-started/demos/what-makes-a-successful-financial-ecosystem.md @@ -0,0 +1,11 @@ +# Qu’est-ce qui fait le succès d’un écosystème financier ? + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/why-mojaloop.md b/docs/fr/getting-started/demos/why-mojaloop.md new file mode 100644 index 000000000..9cc51c6b0 --- /dev/null +++ b/docs/fr/getting-started/demos/why-mojaloop.md @@ -0,0 +1,11 @@ +# Pourquoi Mojaloop ? + + \ No newline at end of file diff --git a/docs/fr/getting-started/demos/working-with-mojaloop.md b/docs/fr/getting-started/demos/working-with-mojaloop.md new file mode 100644 index 000000000..579114127 --- /dev/null +++ b/docs/fr/getting-started/demos/working-with-mojaloop.md @@ -0,0 +1,11 @@ +# Comment travailler avec Mojaloop ? + + \ No newline at end of file diff --git a/docs/fr/getting-started/faqs.md b/docs/fr/getting-started/faqs.md new file mode 100644 index 000000000..021f0eee5 --- /dev/null +++ b/docs/fr/getting-started/faqs.md @@ -0,0 +1,6 @@ +# Foire aux questions + +Ce document rassemble certaines des questions les plus fréquemment posées par la communauté. + +- [FAQ générales](./general-faqs) +- [FAQ techniques](./technical-faqs) \ No newline at end of file diff --git a/docs/fr/getting-started/general-faqs.md b/docs/fr/getting-started/general-faqs.md new file mode 100644 index 000000000..c1664f3c6 --- /dev/null +++ b/docs/fr/getting-started/general-faqs.md @@ -0,0 +1,59 @@ +# FAQ générales + +Ce document rassemble certaines des questions les plus fréquemment posées par la communauté. + +## 1. Qu’est-ce que Mojaloop ? + +Mojaloop est un logiciel open source permettant de construire des plateformes de paiements numériques interopérables à l’échelle nationale. Il facilite l’interconnexion de services fournis par différents types d’acteurs et le déploiement de services financiers à faible coût sur de nouveaux marchés. + + +## 2. Comment ça fonctionne ? + +La plupart des fournisseurs de services financiers numériques opèrent sur leurs propres réseaux, ce qui empêche les clients utilisant des services différents d’effectuer des transactions entre eux. Mojaloop agit comme un « commutateur » universel, acheminant les paiements de manière sécurisée entre tous les clients, quel que soit leur réseau. Il comprend plusieurs couches principales, chacune avec une fonction spécifique : une couche d’interopérabilité, qui relie comptes bancaires, portefeuilles de monnaie électronique et commerçants en boucle ouverte ; une couche de services d’annuaire, qui gère les différentes méthodes d’identification des comptes de part et d’autre de la transaction ; une couche de règlement des transactions, qui rend les paiements instantanés et irrévocables ; ainsi que des composants de protection contre la fraude. + +## 3. À qui s’adresse Mojaloop ? + +Le code comporte de nombreux composants, et toute personne travaillant directement ou indirectement sur des transactions financières numériques (développeurs fintech, banquiers, entrepreneurs, startups, etc.) est invitée à explorer et utiliser les parties qui lui sont utiles. Le logiciel, dans son ensemble, est conçu pour être mis en œuvre à l’échelle nationale ; il est donc particulièrement pertinent pour les fournisseurs de monnaie mobile, les associations de paiement, les banques centrales et les régulateurs. + +Les développeurs des fintechs et des services financiers peuvent utiliser le code de trois manières : l’adapter aux standards d’un pays, l’utiliser pour mettre à jour leurs produits et services (ou en créer de nouveaux), et l’améliorer en proposant des mises à jour et de nouvelles versions pour les autres utilisateurs. + +Par exemple : + +- Une banque centrale peut mandater l’usage du logiciel par ses partenaires commerciaux afin d’accélérer le déploiement d’une passerelle nationale de paiement. +- Un grand processeur de paiement peut utiliser le logiciel pour moderniser son offre et réduire ses coûts de transaction sans investissements R&D majeurs. +- Une startup fintech peut utiliser le code pour comprendre concrètement comment se conformer à des API de paiement interopérables. +- Une banque peut utiliser le code pour adapter ses systèmes internes afin d’interopérer plus facilement avec d’autres fournisseurs de paiement. + +## 4. Pourquoi Mojaloop existe-t-il ? + +Les acteurs qui cherchent à proposer des services financiers numériques innovants et à faible coût sur des marchés en développement doivent souvent tout construire eux-mêmes. Cela augmente les coûts et cloisonne les services. Mojaloop peut servir de fondation pour construire des plateformes interopérables, réduire les coûts pour les fournisseurs et permettre l’intégration de leurs services avec ceux des autres acteurs du marché. + +## 5. Qui est à l’origine de Mojaloop ? + +Mojaloop a été construit en collaboration avec un groupe d’entreprises technologiques et fintech de premier plan : [Ripple](https://github.com/ripple), [Dwolla](https://github.com/dwolla), [Software Group](http://www.softwaregroup-bg.com/), [ModusBox](http://www.modusbox.com/) et [Crosslake Technologies](http://www.crosslaketech.com/). Mojaloop a été initié par la Fondation Gates afin de « rééquilibrer le terrain économique » en mobilisant expertise et ressources pour construire des modèles de paiement inclusifs au bénéfice des populations les plus pauvres. Il est mis gratuitement à disposition du public en tant que logiciel open source sous la [licence Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +## 6. Sur quelles plateformes Mojaloop fonctionne-t-il ? + +La plateforme Mojaloop a été conçue pour des environnements cloud modernes. Des méthodes open source et des plateformes largement utilisées, comme Node.js, constituent la couche de base. Les microservices sont empaquetés avec Docker et peuvent être déployés sur du matériel local ou dans des environnements cloud tels qu’Amazon Web Services ou Azure. + +## 7. Est-ce vraiment open source ? + +Oui, Mojaloop est réellement open source. Tous les modules principaux, la documentation et les livres blancs sont disponibles sous la [licence Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0). Mojaloop s’appuie sur des logiciels open source largement utilisés, notamment Node.js, MuleCE, Java et PostgreSQL. Mojaloop utilise également le [protocole Interledger](https://github.com/interledger) pour orchestrer des transferts d’argent sécurisés. Les licences de ces plateformes et de leurs dépendances permettent de nombreux usages légitimes du logiciel. + +## 8. Comment contribuer à Mojaloop ? + +Vous pouvez contribuer en aidant à créer de nouvelles fonctionnalités prévues sur la feuille de route, ou en aidant à améliorer la plateforme. Pour consulter la feuille de route, voir la [Mojaloop Roadmap](../mojaloop-roadmap.md). Nous recommandons de commencer par le guide d’onboarding et l’exemple de problème, conçus pour présenter les idées clés de la plateforme et du logiciel, les méthodes de build et le processus de contribution. + +## 9. Peut-on utiliser Mojaloop pour des paiements en cryptomonnaie ? + +Pas avec la spécification actuelle et cette plateforme. Aujourd’hui, cela se limite aux devises répertoriées dans l’ISO 4217. Comme la spécification et la plateforme portent sur des transferts numériques, il serait possible d’étudier un cas d’usage pour ce besoin. Sinon, un FSP peut assurer la conversion (comme c’est déjà souvent le cas) entre la crypto et une devise prise en charge. + +## 10. Comment accéder au code source de Mojaloop ? + +Voici quelques ressources pour commencer : +1. Documentation : https://github.com/mojaloop/documentation. +2. Consultez les dépôts dont la description contient « CORE COMPONENT (Mojaloop) » : ce sont les composants cœur. Les dépôts « CORE RELATED (Mojaloop) » sont ceux nécessaires pour supporter l’implémentation/déploiement actuel du Switch Mojaloop. +3. Remarque générale : pour le code le plus récent, utilisez pour l’instant la branche `develop`. +4. Architecture actuelle : https://github.com/mojaloop/docs/tree/master/Diagrams/ArchitectureDiagrams. Note : ces éléments sont en cours de migration vers https://github.com/mojaloop/documents. +5. Informations sur l’architecture et le déploiement : https://github.com/mojaloop/documentation/tree/master/deployment-guide. + diff --git a/docs/fr/getting-started/installation/installing-mojaloop.md b/docs/fr/getting-started/installation/installing-mojaloop.md new file mode 100644 index 000000000..31bf460c5 --- /dev/null +++ b/docs/fr/getting-started/installation/installing-mojaloop.md @@ -0,0 +1,16 @@ +# Installer Mojaloop + +Mojaloop est packagé et publié sous forme d’un ensemble de [charts Helm](https://github.com/mojaloop/helm), avec différentes options de déploiement et de personnalisation. +Que vous découvriez Mojaloop et que vous ne soyez pas familier avec [Helm](https://helm.sh) / [Kubernetes](https://kubernetes.io), ou que vous souhaitiez simplement mettre le logiciel en service rapidement, plusieurs options sont disponibles pour déployer Mojaloop. + +1. **Déploiement manuel** - Le [guide de déploiement](../../technical/deployment-guide/) Mojaloop s’adresse aux personnes familières avec [Kubernetes](https://kubernetes.io) et [Helm](https://helm.sh). C’est un excellent point de départ si vous envisagez de déployer Mojaloop sur un environnement Kubernetes existant, ou si vous souhaitez en mettre un en place vous-même. + +2. **IaC (Infrastructure as Code)** - Un déploiement Mojaloop complet visant à fournir une base de départ pour la production. L’IaC est fortement automatisée ([Terraform](https://www.terraform.io), [Ansible](https://www.ansible.com)) et extensible. Pour en savoir plus, consultez le [billet de blog sur le déploiement IaC](https://infitx.com/deploying-mojaloop-using-iac). + + L’IaC prend actuellement en charge les configurations modulaires suivantes : + - [Plateforme IaC AWS (Amazon Web Services)](https://github.com/mojaloop/iac-aws-platform) + - On-Prem (à venir) + +3. **Mini-Loop** - Des utilitaires d’installation Mojaloop offrant une manière simple et efficace de démarrer. Les scripts [mini-Loop](https://github.com/tdaly61/mini-loop) permettent de déployer Mojaloop dans le cloud ou sur votre ordinateur/serveur avec seulement quelques commandes. Vous pouvez ensuite exécuter facilement le [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit#mojaloop-testing-toolkit) pour interagir avec votre déploiement et le tester. + +4. **Azure Marketplace** - Un déploiement natif Azure AKS, visant à fournir une base pour un POC ou un pilote. Il s’agit d’un déploiement simple, basé sur des templates Microsoft ARM fortement automatisés, et déployé sur Kubernetes managé pour faciliter l’exploitation. Exécutez le [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit#mojaloop-testing-toolkit) pour interagir avec votre déploiement et le tester. Pour plus d’informations, voir la [présentation Mojaloop Azure (PI 21)](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/pi_21_march_2023/presentations/Mojaloop%20Azure%20Deployment.pdf). diff --git a/docs/fr/getting-started/license.md b/docs/fr/getting-started/license.md new file mode 100644 index 000000000..fb844f464 --- /dev/null +++ b/docs/fr/getting-started/license.md @@ -0,0 +1,10 @@ +# LICENCE + +Copyright © 2020-2024 Mojaloop Foundation + +Les fichiers Mojaloop sont mis à disposition par la Fondation Mojaloop sous la licence Apache, version 2.0 +(la « Licence ») et vous ne pouvez pas utiliser ces fichiers autrement qu’en conformité avec la [Licence](http://www.apache.org/licenses/LICENSE-2.0). + +Vous pouvez obtenir une copie de la Licence à l’adresse [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Sauf si la loi applicable l’exige ou si cela a été convenu par écrit, les fichiers Mojaloop sont distribués « EN L’ÉTAT », SANS GARANTIE NI CONDITION D’AUCUNE SORTE, expresse ou implicite. Voir la Licence pour connaître la langue spécifique régissant les autorisations et limitations prévues par la [Licence](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/docs/fr/getting-started/technical-faqs.md b/docs/fr/getting-started/technical-faqs.md new file mode 100644 index 000000000..194cb3750 --- /dev/null +++ b/docs/fr/getting-started/technical-faqs.md @@ -0,0 +1,161 @@ +# FAQ techniques + +Ce document contient certaines des questions techniques fréquemment posées par la communauté. + +## 1. Qu’est-ce qui est pris en charge ? + +Actuellement, les composants Central Ledger sont pris en charge par l’équipe. Les composants DFSP sont obsolètes ; par conséquent, l’environnement de bout en bout et l’installation complète sont difficiles à mettre en place. + +## 2. Peut-on se connecter directement à Pathfinder dans un environnement de développement ? + +Pour les environnements local et de test, nous recommandons plutôt d’utiliser le service « mock-pathfinder ». Pathfinder est un service « facturé à l’usage ». + +Accédez au dépôt https://github.com/mojaloop/mock-pathfinder pour télécharger et installer mock-pathfinder. Exécutez la commande `npm install` dans le répertoire mock-pathfinder pour installer les dépendances, puis mettez à jour `Database_URI` dans `mock-pathfinder/src/lib/config.js`. + +## 3. Dois-je enregistrer le DFSP via l’URL http://central-directory/commands/register ou mettre à jour la configuration dans default.json ? + +Vous devez enregistrer via l’API fournie, en utilisant Postman ou curl. Le client utilise du code Level One. Il faut implémenter la version Mojaloop actuelle avec les scripts Postman à jour. + +## 4. Le pod pi3-kafka-0 est toujours en CrashLoopBackOff ? + +- More background related to the question: + + Quand j’ai essayé d’obtenir les logs du conteneur `centralledger-handler-admin-transfer`, j’obtiens l’erreur suivante : + Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing + Et le statut du pod pi3-kafka-0 est toujours en CrashLoopBackOff. + J’utilise un VPS sous Ubuntu 16.04 avec 12 Go de RAM, 2 vCores, 2,4 GHz et 50 Go de disque chez OVH pour le déploiement. + +Le fait d’augmenter la RAM à 24 Go et le CPU à 4 a résolu le problème. Il semble s’agir d’un timeout sur Zookeeper dû à un manque de ressources disponibles, entraînant l’arrêt des services. + +## 5. Pourquoi ai-je une erreur quand j’essaie de créer un nouveau DFSP via l’Admin ? + +Assurez-vous d’utiliser les scripts Postman les plus récents disponibles sur le dépôt https://github.com/mojaloop/mock-pathfinder. + + +## 6. Puis-je répartir les composants Mojaloop sur plusieurs machines physiques et VM ? + +Vous devriez pouvoir déployer sur différentes VM ou machines physiques. La répartition dépend fortement de vos exigences et sera spécifique à votre implémentation. Nous utilisons Kubernetes pour l’orchestration de conteneurs. Cela permet de planifier les déploiements sur des nœuds spécifiques si nécessaire et de demander des ressources spécifiques. Les charts Helm du dépôt Helm peuvent servir de guide pour allouer et regrouper au mieux les composants dans votre déploiement. Bien sûr, vous devrez adapter les configurations à votre implémentation. + +## 7. Peut-on s’attendre à ce que tous les endpoints définis dans le document d’API soient implémentés dans Mojaloop ? + +L’API de la spécification Mojaloop (transfers) et l’implémentation open source du Switch Mojaloop sont deux flux indépendants, même si l’implémentation s’appuie évidemment sur la spécification. Les implémentations se font en fonction des cas d’usage priorisés sur une période donnée et des endpoints nécessaires pour les supporter. Si certains endpoints ne sont pas prioritaires, ils peuvent ne pas être disponibles. L’objectif est toutefois de supporter, à terme, tous les endpoints spécifiés, même si cela peut prendre du temps. Merci pour la liste. Certains éléments existent aussi dans le dépôt « postman » de l’organisation Mojaloop sur GitHub. + +## 8. Mojaloop stocke-t-il les informations de devis/statut du FSP initiateur du paiement ? + +À ce jour, l’implémentation open source du Switch Mojaloop *ne stocke pas* les informations liées aux quotes. Il revient au payeur et au bénéficiaire impliqués dans le processus de stocker les informations pertinentes. + +## 9. Mojaloop gère-t-il la validation du workflow ? + +Pas pour le moment, mais cela pourrait arriver à l’avenir. Pour corréler les requêtes liées à un transfert donné, vous pouvez consulter la ressource/endpoint « transaction » dans la spécification. Par ailleurs, des travaux sont en cours côté spécification pour rendre cette corrélation plus simple, par exemple pour relier les requêtes de quote et de transfer au sein d’une transaction unique. + + +## 10. Comment enregistrer une nouvelle « party » dans Mojaloop ? + +Il n’existe pas de `POST` sur la ressource `/parties`, comme indiqué dans la section 6.1.1 de l’API Definition. Référez-vous plutôt à la section 6.2.2.3 : `POST /participants//` dans l’API Definition. + +” _The HTTP request `POST /participants//` (or `POST /participants///`) is used to create information on the server regarding the provided identity, defined by ``, ``, and optionally `` (for example, POST_ + _/participants/MSISDN/123456789 or POST /participants/BUSINESS/shoecompany/employee1). See Section 5.1.6.11 for more information regarding addressing of a Party._ ”. + +## 11. Le participant représente-t-il un compte d’un client dans une banque ? + +Pour plus d'informations, veuillez consulter ce document (Section 3.2) : https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +” _Dans l’API, un Participant est équivalent à un PSP (Prestataire de Services de Paiement/FSP) qui participe à un schéma d’interopérabilité. L’objectif principal de la ressource logique Participants de l’API est de permettre aux PSP de savoir dans quel autre PSP se trouve la contrepartie d’une transaction financière interopérable. Il existe également des services définis pour que les PSP fournissent des informations à un système commun._ ” + +En résumé, un participant est tout PSP impliqué dans le schéma (généralement pas un client). Pour la recherche de compte, un service d’annuaire tel que *Pathfinder* peut être utilisé, qui permet de rechercher un utilisateur et d’établir la correspondance. Si un tel service d’annuaire n’est pas fourni, la spécification propose une alternative où le Switch héberge un service de lookup de comptes (ALS) auquel les participants doivent enregistrer les parties. J’ai déjà évoqué ce point. Mais il faut noter que le Switch ne conserve pas les détails, uniquement la correspondance entre un identifiant et un FSP, et les requêtes de résolution de la partie sont redirigées vers ce FSP. + +https://github.com/mojaloop/mojaloop-specification LIÉ AU CŒUR (Mojaloop) : + +Ce dépôt contient le jeu de documents de spécification de l’Open API pour l’interopérabilité des PSP - mojaloop/mojaloop-specification. + +## 12. Comment enregistrer un bénéficiaire _de confiance_ auprès d’un payeur pour éviter l’OTP ? + +Pour éviter la saisie de l’OTP, la demande initiale sur /transactionRequests initiée par le bénéficiaire peut être approuvée de façon programmatique (ou même manuelle) sans passer par le endpoint /authorizations (utilisé habituellement pour la validation OTP). C’est en effet au PSP de gérer cela, le Switch ne le fait pas. Ceci est évoqué brièvement en section 6.4 de la spécification. + +## 13. J’obtiens une erreur 404 lorsque j’essaie d’accéder ou de charger le fichier kubernetes-dashboard.yaml ? + +Selon le README.md officiel du dépôt github de kubernetes, le lien le plus récent à utiliser est : "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Veillez toujours à vérifier les liens tiers avant toute utilisation. Les applications open source évoluent constamment. + +## 14. Lors de l’installation de nginx-ingress pour la répartition de charge & l’accès externe – Erreur : no available release name found ? + +Merci de consulter la page suivante qui aborde une problématique similaire. Pour résumer, il s’agit très probablement d’un problème RBAC. Consultez la documentation pour configurer Tiller avec RBAC : https://docs.helm.sh/using_helm/#role-based-access-control détaille la procédure. Voir également l’issue enregistrée : helm/helm#3839. + +## 15. Message reçu "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" lors de l’exécution de la commande `npm start`. + +Solution trouvée ici : https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Sous Ubuntu 14, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. Je souhaite d’abord compiler la dernière version stable (il semble que ce soit 0.9.2) de librdkafka dans /opt/librdkafka : +curl https://codeload.github.com/ede... + +Voici les étapes pour reconstruire librdkafka : + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout `` + +cd librdkafka && ./configure && make && make install && ldconfig + +Après cela, je peux importer les dépendances sans avoir à spécifier LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +La bibliothèque Apache Kafka C/C++. Contribuez à edenhill/librdkafka sur GitHub. + +## 16. Peut-on utiliser mojaloop comme logiciel open source de portefeuille mobile ou mojaloop gère-t-il uniquement l’interopérabilité ? + +Nous pouvons utiliser mojaloop pour l’interopérabilité afin de supporter les portefeuilles mobiles et autres transferts d’argent. Ce n’est pas un logiciel pour les DFSP (il existe d’autres projets open source pour cela, comme Finserv, etc). Mojaloop sert principalement de Hub/Switch et fournit une API à implémenter côté DFSP, mais ne sert pas à gérer directement des portefeuilles mobiles. + +## 17. Quelles sont les sociétés qui aident à déployer et à supporter mojaloop ? + +Mojaloop est un logiciel et une spécification open source. + +## 18. Que pouvez-vous dire au sujet de mojaloop et de la sécurité ? + +La spécification est assez standard et dispose de bonnes pratiques de sécurité. Mais leur mise en œuvre incombe aux intégrateurs et déployeurs. En complément, des mesures de sécurité opérationnelle et de déploiement doivent être appliquées. Par ailleurs, les prochains mois se concentreront sur la sécurité au sein de la communauté open source. + +## 19. Quels sont les avantages d’utiliser mojaloop comme plateforme d’interopérabilité ? + +Bénéfices : À ce jour, par exemple, un utilisateur Airtel mobile money ne peut transférer qu’à un autre utilisateur Airtel. Avec ce système, il/elle peut transférer à tout autre prestataire financier comme un autre opérateur mobile money, une banque ou un commerçant connecté au Hub, quelle que soit l’implémentation. Il suffit qu’ils soient connectés au même Switch. De plus, la plateforme est conçue pour être utilisable sur les téléphones basiques (feature phones), donc accessible à tous. + +## 20. Quels sont les principaux défis auxquels font face les entreprises utilisant mojaloop ? + +Actuellement, les difficultés majeures sont liées aux attentes. Les attentes des adopteurs de mojaloop et la réalité de ce qu’est mojaloop. Beaucoup ont une compréhension différente de mojaloop et de ses capacités. Avec une bonne compréhension, de nombreux défis actuels disparaissent. +Oui, la journalisation forensic (forensic logging) est aussi une mesure de sécurité pour l’audit, elle permet d’assurer qu’il existe un registre traçable des actions, que toute action notable soit consignée et conservée en toute sécurité après chiffrement à plusieurs niveaux. + +## 21. L’audit/journalisation forensic dans mojaloop est-il/elle lié(e) à la sécurisation de la plateforme d’interopérabilité ? + +Cela garantit aussi que tous les services exécutent toujours le code attendu et que toute anomalie est empêchée de démarrer. Pour le reporting et les auditeurs, des rapports peuvent intégrer un journal forensic retraçable. + +## 22. Comment les fournisseurs de services financiers se connectent-ils à mojaloop ? + +Il existe un schéma architectural qui présente clairement l’intégration des différentes entités : https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +## 23. Existe-t-il un convertisseur/connecteur open source ISO8583-OpenAPI ? + +Je ne crois pas qu’il existe à ce jour une intégration générique ISO8583 `<-> Mojaloop`. Nous travaillons actuellement sur certaines intégrations de « canaux de paiement traditionnels » à Mojaloop (POS et GAB) que nous espérons présenter lors de la prochaine réunion. Celles-ci pourraient former la base d’une intégration ISO8583 à ajouter à la stack open source, mais gardez à l’esprit que ces intégrations sont très spécifiques à chaque cas d’usage. + +## 24. Comment connaître les endpoints à utiliser dans postman pour tester le déploiement ? + +Dans le dashboard Kubernetes, sélectionnez le NAMESPACE approprié. Allez dans Ingresses. Selon la manière dont vous avez déployé les charts Helm, recherchez 'moja-centralledger-service'. Cliquez sur "éditer", et cherchez la balise ``. Celle-ci contient l’endpoint du service. + +En ligne de commande, repérez la colonne 'Host' dans la commande : `kubectl describe ingress moja-centralledger-service` + +## 25. Pourquoi les rétrocessions ne sont-elles pas autorisées sur Mojaloop ? + +*L’irrévocabilité* est un principe fondamental du projet Level One (édité) et il est essentiel qu’aucune rétrocession ne soit permise. Extrait pertinent issu de la définition d’API ci-dessous : + +_*6.7.1.2 Irrévocabilité des transactions*_ +_L’API est conçue pour ne supporter que des transactions financières irrévocables ; cela signifie qu’une transaction ne peut ni être modifiée, annulée ou rétrocédée après sa création. L’objectif est de simplifier et de réduire les coûts pour les PSP utilisant l’API. Une grande part du coût opérationnel d’un système financier classique est liée aux rétrocessions._ +_Aussitôt qu’un PSP payeur envoie une transaction financière à un PSP bénéficiaire (via POST /transfers avec la transaction financière de bout en bout), la transaction devient irrévocable du point de vue du PSP payeur. Elle peut toujours être rejetée côté bénéficiaire, mais le payeur ne peut plus la rejeter ou la modifier. Seule exception : si l’expiration du transfert est atteinte avant la réponse du bénéficiaire (voir Sections 6.7.1.3 et 6.7.1.5 pour plus de détails). Dès qu’une transaction est acceptée par le bénéficiaire, elle devient irrévocable pour toutes les parties._ + +Cependant, *les remboursements* sont un cas d’usage supporté par l’API. + +## 26. Erreur "MountVolume.SetUp failed" lors de l’installation de microk8s ? + +Ce message peut apparaître en cas de problème d’espace disque, même si plus de 100Go d’espace EBS ont été alloués. +Le problème s’est résolu de lui-même après 45 minutes. La mise en place initiale du projet mojaloop peut mettre un certain temps à se stabiliser. + +## 27. Pourquoi cette erreur lors de la création d’un participant : "Hub reconciliation account for the specified currency does not exist" ? + +Vous devez d’abord créer les comptes Hub correspondants (HUB_MULTILATERAL_SETTLEMENT et HUB_RECONCILIATION) pour la devise concernée avant de configurer les participants. +Dans cette collection Postman vous trouverez les requêtes pour effectuer l’opération dans le dossier "Hub Account" : https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Trouvez également les environnements correspondants dans le dépôt Postman : https://github.com/mojaloop/postman diff --git a/docs/fr/index.md b/docs/fr/index.md new file mode 100644 index 000000000..eca262440 --- /dev/null +++ b/docs/fr/index.md @@ -0,0 +1,25 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: Ceci est la documentation officielle du projet Mojaloop +# actionText: Premiers pas → +# actionLink: /getting-started/ +# features: +# - title: Business +# details: Making the business case for Mojaloop +# - title: Community +# details: Learn about the community behind the tech +# - title: Technical +# details: See inside the different components, and deploy Mojaloop for yourself! +# - title: Product +# details: Mojaloop product features, requirements and roadmap +--- + +
+
+ +| | | | | +|:----:|:----:|:----:|:----:| +|

**[Adoption](adoption/)**

|

**[Communauté](community/)**

|

**[Produit](product/)**

|

**[Technique](technical/)**

| +| Présenter l'argumentaire commercial de Mojaloop | Découvrez la communauté derrière la technologie | Fonctionnalités produit, exigences et feuille de route de Mojaloop | Explorez les différents composants et déployez Mojaloop vous-même ! | +
\ No newline at end of file diff --git a/docs/fr/product/README.md b/docs/fr/product/README.md new file mode 100644 index 000000000..4d7afbe9c --- /dev/null +++ b/docs/fr/product/README.md @@ -0,0 +1,5 @@ +# Bienvenue dans la documentation produit Mojaloop + +Cette section est consacrée à la documentation produit de Mojaloop : elle présente, du point de vue fonctionnel, l’ensemble des fonctionnalités, les API, l'intégration des institutions financières (DFSP), la mise en place de schémas de paiement marchands basés sur Mojaloop, les transactions transfrontalières, ISO 20022, etc. — en résumé, tout ce qu’un adopteur potentiel doit savoir pour concevoir le schéma. Cette section ne couvre pas les détails techniques, disponibles ailleurs sur ce site. + +Elle reflète les travaux de la communauté open source Mojaloop sur plusieurs années. Si vous souhaitez contribuer, devenir membres de la communauté, n’hésitez pas à rejoindre les discussions sur le canal Slack #product-council et sur Community Central (https://community.mojaloop.io/). diff --git a/docs/fr/product/features/ComplexXB.svg b/docs/fr/product/features/ComplexXB.svg new file mode 100644 index 000000000..4e87239dd --- /dev/null +++ b/docs/fr/product/features/ComplexXB.svg @@ -0,0 +1,4 @@ + + + +
Jurisdiction B
Jurisdiction B
Jurisdiction A
Jurisdiction A
Scheme 1
Scheme 1
Scheme 2
Scheme 2
DFSP 2
DFSP 2
Proxy
Proxy
FXP 1
FXP 1
FXP 3
FXP 3
FXP 2
FXP 2
Proxy
Proxy
Existing Scheme 1.1
Existing Scheme 1.1
DFSP 1
DFSP 1
DFSP 3
DFSP 3
\ No newline at end of file diff --git a/docs/fr/product/features/CrossBorder.md b/docs/fr/product/features/CrossBorder.md new file mode 100644 index 000000000..0429d813f --- /dev/null +++ b/docs/fr/product/features/CrossBorder.md @@ -0,0 +1,29 @@ +--- +sidebarTitle: Transactions transfrontalières +--- + +# Transactions transfrontalières + +*Cette page suppose que le lecteur connaît les [**capacités inter-schémas**](./InterconnectingSchemes.md) de Mojaloop et le fonctionnement du [**change**](./ForeignExchange.md).* + +La version actuelle de Mojaloop considère une transaction transfrontalière comme une opération qui quitte un schéma de paiement pour être transmise à un autre relevant d’une juridiction réglementaire différente. Il s’agit donc, en termes Mojaloop, d’une transaction inter-schémas incluant une opération de change. + +Le schéma suivant illustre la mise en œuvre de cette fonctionnalité. + +![Transactions transfrontalières](./XB.svg) + +Dans ce contexte, un proxy fait le lien entre deux schémas Mojaloop opérant dans des pays (juridictions) distincts, en facilitant les transactions et en assurant la non-répudiation de bout en bout. Plusieurs FXP sont représentés — deux dans la juridiction A et un dans la juridiction B — afin de couvrir les différents modèles économiques envisageables pour les opérations de change. + +Ce modèle peut être étendu pour interconnecter des systèmes nationaux de paiement instantané déjà existants, comme suit : + +![Interconnexion de schémas nationaux pour des transactions transfrontalières](./ComplexXB.svg) + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22 avril 2025| Paul Makin|Ajout de l’historique des versions ; précisions rédactionnelles| +|1.0|14 avril 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.plantuml new file mode 100644 index 000000000..9bb681e08 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.plantuml @@ -0,0 +1,216 @@ +@startuml FXAPI_Discovery + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Découverte — intégration du connecteur Mojaloop +actor "$senderName" as A1 + participant "CBS payeur" as PayerCBS +box "DFSP payeur" #LightBlue + participant "Connecteur principal" as PayerCC + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +box "Service de découverte" #LightYellow + participant "Oracle ALS" as ALS +end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +' participant "API FX backend" as FXPBackend +'end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 + participant "Connecteur principal" as PayeeCC +end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:Je voudrais payer $receiverName\n$payerSendAmount $payerCurrency, s'il vous plaît +PayerCBS->PayerCC: Lancer le transfert de fonds +!if ($advancedCoreConnectorFlow != true) + PayerCC->D1: **POST /transfers** + !if ($simplified != true) + note left + { + "homeTransactionId": "$homeTransactionId", + "from": { + "dateOfBirth": "$senderDOB", + "displayName": "$senderName", + "firstName": "$senderFirstName", + "middleName": "$senderMiddleName", + "lastName": "$senderLastName" + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" + }, + "to": { + "idType": "MSISDN", + "idValue": "$payeeMSISDN" + }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + } + end note + !endif +!else +PayerCC->D1: **GET /parties/MSISDN/$payeeMSISDN** +!endif + +activate D1 +D1->>S1:Je veux envoyer vers le MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +S1->ALS:À qui appartient le MSISDN $payeeMSISDN ? +activate ALS +ALS-->S1:C'est $payeeFSPID +deactivate ALS +S1->>D2:Le MSISDN $payeeMSISDN vous appartient-il ? +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +deactivate S1 +!endif +D2->PayeeCC: **GET** /parties +PayeeCC->PayeeCC: Valider si la partie \n peut recevoir le transfert +PayeeCC->PayeeCC: Vérifier le compte et\nobtenir le type de devise +!if ($simplified != true) +PayeeCC-->D2: Résultat +!endif +deactivate S1 +D2->>S1:Oui, c'est $receiverName.\n Il peut recevoir en $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +note right + PUT /parties + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName" + }, + "supportedCurrencies": [ "$payeeCurrency" ] + } +end note +!else +!endif +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +deactivate D2 +S1->>D1:Oui, c'est $receiverName. \nIl peut recevoir en $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +D1-->>S1:200 — OK +!endif +deactivate S1 + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC: Voici les informations sur la partie\net les devises prises en charge + note right + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" + }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_PARTY_ACCEPTANCE**", + "getPartiesResponse": { + "body": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } + } + } + end note +!else + D1-->PayerCC: Voici les informations sur la partie\net les devises prises en charge + !if ($simplified != true) + note right of PayerCC + { + "party": { + "body": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif +deactivate D1 +PayerCC-->PayerCBS:Voici les \ndétails du bénéficiaire +PayerCBS->A1:Bonjour, $senderName : \nLe numéro appartient à $receiverName \nDites-moi si vous souhaitez\n continuer +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.svg new file mode 100644 index 000000000..dd017b8a2 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Discovery.svg @@ -0,0 +1,247 @@ + + Découverte — intégration du connecteur Mojaloop + + + Découverte — intégration du connecteur Mojaloop + + DFSP payeur + + Service de découverte + + DFSP bénéficiaire + + + + + + + + + + + + + + John + + + John + + + + CBS payeur + + CBS payeur + + Connecteur principal + + Connecteur principal + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Oracle ALS + + Oracle ALS + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + Connecteur principal + + Connecteur principal + + + + + + + + 1 + Je voudrais payer Yaro + 300 BWP, s'il vous plaît + + + 2 + Lancer le transfert de fonds + + + 3 + POST /transfers + + + { + "homeTransactionId": "string", + "from": { + "dateOfBirth": "1966-06-16", + "displayName": "John", + "firstName": "$senderFirstName", + "middleName": "$senderMiddleName", + "lastName": "" + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321" + }, + "to": { + "idType": "MSISDN", + "idValue": "2551234567890" + }, + "amountType": "SEND", + "currency": "BWP", + "amount": "300" + } + + + + 4 + Je veux envoyer vers le MSISDN 2551234567890 + GET /parties/MSISDN/2551234567890 + + + + 5 + 202 — Je vous recontacte + + + 6 + À qui appartient le MSISDN 2551234567890 ? + + + 7 + C'est PayeeFSP + + + + 8 + Le MSISDN 2551234567890 vous appartient-il ? + + + + 9 + 202 — Je vous recontacte + + + 10 + GET + /parties + + + + + 11 + Valider si la partie + peut recevoir le transfert + + + + + 12 + Vérifier le compte et + obtenir le type de devise + + + 13 + Résultat + + + + 14 + Oui, c'est Yaro. + Il peut recevoir en TZS + PUT /parties/MSISDN/2551234567890 + + + PUT /parties + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890", + "fspId": "PayeeFSP" + }, + "name": "Yaro" + }, + "supportedCurrencies": [ "TZS" ] + } + + + + 15 + 200 — OK + + + + 16 + Oui, c'est Yaro. + Il peut recevoir en TZS + PUT /parties/MSISDN/2551234567890 + + + + 17 + 200 — OK + + + 18 + Voici les informations sur la partie + et les devises prises en charge + + + { + "transferId": "d9ce59d4359843968630581bb0", + "homeTransactionId": "string", + "from": { + "displayName": "John", + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321" + }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "2551234567890", + "displayName": "Yaro", + "fspId": "PayeeFSP" + "supportedCurrencies": [ "TZS" ] + }, + "amountType": "SEND", + "currency": "BWP", + "amount": "300" + "currentState": " + WAITING_FOR_PARTY_ACCEPTANCE + ", + "getPartiesResponse": { + "body": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890", + "fspId": "PayeeFSP" + }, + "name": "Yaro", + "supportedCurrencies": [ "TZS" ] + } + } + } + + + 19 + Voici les + détails du bénéficiaire + + + 20 + Bonjour, John : + Le numéro appartient à Yaro + Dites-moi si vous souhaitez + continuer + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml new file mode 100644 index 000000000..5364328ae --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml @@ -0,0 +1,236 @@ +@startuml FXAPI_Payer_Agreement + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415..." +!$conversionId = "581f68efb54f41..." +!$homeTransactionId = "string" +!$quoteId = "382987a875ce403..." +!$transactionId = "d9ce59d43598439..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843..." +!$transferId = "d9ce59d43598439..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Phase d'accord — intégration du connecteur Mojaloop +'actor "$senderName" as A1 +' participant "CBS payeur" as PayerCBS +box "DFSP payeur" #LightBlue + participant "Connecteur principal" as PayerCC + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +' participant "API FX backend" as FXPBackend +'end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 + participant "Connecteur principal" as PayeeCC +end box + +'actor "$receiverName" as A2 +autonumber + +!if ($advancedCoreConnectorFlow != true) +PayerCC->D1: Je souhaite obtenir un devis du FSP\n**PUT /transfers** +note left +{"acceptConversion": true} +end note +!else +PayerCC->D1: Je souhaite obtenir un devis du FSP\n**POST /quotes** + !if ($simplified != true) + note right of PayerCC + { + "fspId": "$payeeFSPID", + "quotesPostRequest": { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID" + }, + "name": "$senderName", + }, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" + } + } + end note + !endif +!endif + + +D1->>S1:Merci de coter un transfert qui \nenvoie $fxpTargetAmount $payeeCurrency.\n**POST /quotes** +!if ($simplified != true) +note left +**POST /quotes** +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID"}, + "name": "$senderName"}, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif + +S1->>D2:**POST /quotes** +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +D2->PayeeCC:**POST /quoterequests** +!if ($simplified != true) +note left +**POST /quoterequests** +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ]}, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID"}, + "name": "$senderName"}, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" +} +end note +!endif +PayeeCC->PayeeCC:OK, je facturerai $payeeFee $payeeCurrency pour cela.\nJe crée maintenant les conditions du transfert +PayeeCC-->D2:Voici les conditions +!if ($simplified != true) +note right +**POST /quoterequests** response +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayerExpiration" +} +end note +!endif +D2->D2:Je signe maintenant l'objet de transaction +D2->>S1:Voici le devis signé +note right +**put /quotes/$quoteId** +{ + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition" +} + +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +deactivate D2 +S1->>D1:Voici le devis signé\n**PUT /quotes/$quoteId** +activate D1 +!if ($simplified != true) +D1-->>S1:200 — OK +!endif +deactivate S1 +D1->D1:OK, je vois qu'il y aura \n$payeeFee $payeeCurrency de frais. +@enduml diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg new file mode 100644 index 000000000..bd03b9f04 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg @@ -0,0 +1,212 @@ + + Phase d'accord — intégration du connecteur Mojaloop + + + Phase d'accord — intégration du connecteur Mojaloop + + DFSP payeur + + DFSP bénéficiaire + + + + + + + + + + + Connecteur principal + + Connecteur principal + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + Connecteur principal + + Connecteur principal + + + + + + + 1 + Je souhaite obtenir un devis du FSP + PUT /transfers + + + {"acceptConversion": true} + + + + 2 + Merci de coter un transfert qui + envoie 48000 TZS. + POST /quotes + + + POST /quotes + { + "quoteId": "382987a875ce403...", + "transactionId": "d9ce59d43598439...", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890", + "fspId": "PayeeFSP"}, + "name": "Yaro", + "supportedCurrencies": [ "TZS" ] }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "26787654321", + "fspId": "PayerFSP"}, + "name": "John"}, + "amountType": "SEND", + "amount": { + "currency": "TZS", + "amount": "48000"}, + "converter": "PAYER", + "expiration": "2021-08-25T14:17:09.663+01:00" + } + + + + 3 + 202 — Je vous recontacte + + + + 4 + POST /quotes + + + + 5 + 202 — Je vous recontacte + + + 6 + POST /quoterequests + + + POST /quoterequests + { + "quoteId": "382987a875ce403...", + "transactionId": "d9ce59d43598439...", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890", + "fspId": "PayeeFSP"}, + "name": "Yaro", + "supportedCurrencies": [ "TZS" ]}, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "26787654321", + "fspId": "PayerFSP"}, + "name": "John"}, + "amountType": "SEND", + "amount": { + "currency": "TZS", + "amount": "48000"}, + "converter": "PAYER", + "expiration": "2021-08-25T14:17:09.663+01:00" + } + + + + + 7 + OK, je facturerai 4000 TZS pour cela. + Je crée maintenant les conditions du transfert + + + 8 + Voici les conditions + + + POST /quoterequests + response + { + "quoteId": "382987a875ce403...", + "transactionId": "d9ce59d43598439...", + "payeeFspFeeAmount": "4000", + "payeeFspFeeAmountCurrency": "TZS", + "payeeReceiveAmount": "44000", + "payeeReceiveAmountCurrency": "TZS", + "transferAmount": "48000", + "transferAmountCurrency": "TZS" + "expiration": "2021-08-25T14:17:09.663+01:00" + } + + + + + 9 + Je signe maintenant l'objet de transaction + + + + 10 + Voici le devis signé + + + put /quotes/382987a875ce403... + { + "transferAmount": { + "currency": "TZS", + "amount": "48000"}, + "payeeReceiveAmount": { + "currency": "TZS", + "amount": "44000"}, + "payeeFspFee": { + "currency": "TZS", + "amount": "4000"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "<Objet de transaction encodé>", + "condition": "HOr22-H3AfTDHrSkP..." + } +   + + + + 11 + 200 — OK + + + + 12 + Voici le devis signé + PUT /quotes/382987a875ce403... + + + + 13 + 200 — OK + + + + + 14 + OK, je vois qu'il y aura + 4000 TZS de frais. + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml new file mode 100644 index 000000000..4f843b4e5 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml @@ -0,0 +1,384 @@ +@startuml FXAPI_Payer_CurrencyConversion + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Phase d'accord — conversion de devises — intégration du connecteur Mojaloop +actor "$senderName" as A1 +participant "CBS payeur" as PayerCBS +box "DFSP payeur" #LightBlue + participant "Connecteur principal" as PayerCC + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP + participant "Backend FX API \n(Core Connector)" as FXPBackend +end box + +'box "DFSP bénéficiaire" #LightBlue +' participant "Connecteur Mojaloop\nbénéficiaire" as D2 +' participant "Connecteur principal" as PayeeCC +'end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:Oui, continuez s'il vous plaît +PayerCBS->PayerCC: Le payeur a accepté\n les informations sur la partie + +!if ($shortCutSingleFXP != true) + +!if ($advancedCoreConnectorFlow != true) +PayerCC->>D1:Obtenir le devis\n**PUT /transfers/$transferId** +note left +{ "acceptParty": true } +end note +D1->D1:Hmm. Je ne peux envoyer qu'en $payerCurrency.\nJ'ai besoin d'une conversion de devises +!else +PayerCC->PayerCC:Hmm. Je ne peux envoyer qu'en $payerCurrency.\nJ'ai besoin d'une conversion de devises +PayerCC->>PayerCC:Consulter les FXP en cache localement\npouvant assurer la conversion +!endif + +D1->>D1:Consulter les FXP en cache localement\npouvant assurer la conversion + + +!if ($advancedCoreConnectorFlow != true) +' TODO : on peut suspendre l'exécution ici si besoin pour permettre au connecteur principal de sélectionner le FXP +D1->D1:Je vais demander à FDH FX d'effectuer ma conversion +!else +D1->>PayerCC:Voici les FXP disponibles +note right of PayerCC + { + "providers": [ + "$fxpID" + ] + } +end note + +PayerCC->PayerCC:Je vais demander à FDH FX d'effectuer ma conversion +PayerCC->D1: Je souhaite obtenir un devis de ce FXP\n**POST /fxQuotes** + !if ($simplified != true) + note right of PayerCC + { + "homeTransactionId": "$homeTransactionId", + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency" + }, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } + end note + !endif +!endif +!endif + +deactivate S1 + +!if ($shortCutSingleFXP != true) +D1->>S1:Voici la version initiale du transfert.\nMerci de me coter la conversion de devises. +!else +D1->>FXP:Voici la version initiale du transfert.\nMerci de me coter la conversion de devises. +!endif +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note +!if ($shortCutSingleFXP != true) +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D1 +S1->>FXP:Voici la version initiale du transfert.\nMerci de me coter la conversion de devises.\n**POST /fxQuote** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +!else +!if ($simplified != true) +FXP-->>D1:202 — Je vous recontacte +!endif +!endif +FXP->FXPBackend:Consulter le taux de change +!if ($simplified != true) +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note +!endif +note over FXPBackend + J'ajouterai des frais de $fxpChargesSource $payerCurrency pour la conversion. + Je fixe maintenant une heure d'expiration et je signe l'objet de devis, +end note +FXPBackend-->FXP:Renvoyer le taux de change +!if ($simplified != true) +note right + **post /fxQuotes** response + { + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +!endif + +note over FXP + Je signe maintenant l'objet de devis, + je crée un paquet ILP prepare et le renvoie dans l'objet intermédiaire. + + **REMARQUE :** le paquet ILP prepare contient les éléments suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion +end note + +!if ($shortCutSingleFXP != true) +FXP->>S1:Voici l'objet de conversion signé +note right + **PUT /fxQuotes/$conversionRequestId** + { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +deactivate FXP +S1->>D1:Voici l'objet de conversion signé\n**PUT /fxQuotes/$conversionRequestId** +activate D1 +!if ($simplified != true) +D1-->>S1:Compris +!endif +deactivate S1 +!else +FXP-->>D1:Voici l'objet de conversion signé\n**PUT /fxQuotes/$conversionRequestId** +!if ($simplified != true) +D1-->>FXP:202 — Je vous recontacte +!endif +activate D1 +!endif + + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC: Voici les conditions de conversion + note right + **POST/PUT /transfers** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ]}, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_CONVERSION_ACCEPTANCE**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": { + "body": { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [{ + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]}} + }, + "fxQuotesResponseSource": "$payeeFSPID", + } + end note +!else + D1->PayerCC: Voici les conditions de conversion + !if ($simplified != true) + note right of PayerCC + { + "homeTransactionId": "$homeTransactionId", + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget" + } + } + ] + } + } + end note + !endif +!endif + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg new file mode 100644 index 000000000..e960cc853 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg @@ -0,0 +1,317 @@ + + Phase d'accord — conversion de devises — intégration du connecteur Mojaloop + + + Phase d'accord — conversion de devises — intégration du connecteur Mojaloop + + DFSP payeur + + Fournisseur de change + + + + + + + + + + + John + + + John + + + + CBS payeur + + CBS payeur + + Connecteur principal + + Connecteur principal + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + Backend FX API + (Core Connector) + + Backend FX API + (Core Connector) + + + + + + 1 + Oui, continuez s'il vous plaît + + + 2 + Le payeur a accepté + les informations sur la partie + + + + 3 + Obtenir le devis + PUT /transfers/d9ce59d4359843968630581bb0 + + + { "acceptParty": true } + + + + + 4 + Hmm. Je ne peux envoyer qu'en BWP. + J'ai besoin d'une conversion de devises + + + + + + 5 + Consulter les FXP en cache localement + pouvant assurer la conversion + + + + + 6 + Je vais demander à FDH FX d'effectuer ma conversion + + + + 7 + Voici la version initiale du transfert. + Merci de me coter la conversion de devises. + + + post /fxQuotes + { + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } + + + + 8 + 202 — Je vous recontacte + + + + 9 + Voici la version initiale du transfert. + Merci de me coter la conversion de devises. + POST /fxQuote + + + + 10 + 202 — Je vous recontacte + + + 11 + Consulter le taux de change + + + post /fxQuotes + { + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } + + + J'ajouterai des frais de 33 BWP pour la conversion. + Je fixe maintenant une heure d'expiration et je signe l'objet de devis, + + + 12 + Renvoyer le taux de change + + + post /fxQuotes + response + { + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "BWP", + "amount": "33"}, + "targetAmount": { + "currency": "TZS", + "amount": "6000"} + }]} + } + + + Je signe maintenant l'objet de devis, + je crée un paquet ILP prepare et le renvoie dans l'objet intermédiaire. +   + REMARQUE : + le paquet ILP prepare contient les éléments suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion + + + + 13 + Voici l'objet de conversion signé + + + PUT /fxQuotes/828cc75f1654415e8fcddf76cc + { + "condition": "GRzLaTP7DJ9t4P-a_B...", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "BWP", + "amount": "33"}, + "targetAmount": { + "currency": "TZS", + "amount": "6000"} + }]} + } + + + + 14 + 200 — OK + + + + 15 + Voici l'objet de conversion signé + PUT /fxQuotes/828cc75f1654415e8fcddf76cc + + + + 16 + Compris + + + 17 + Voici les conditions de conversion + + + POST/PUT /transfers + response + { + "transferId": "d9ce59d4359843968630581bb0", + "homeTransactionId": "string", + "from": { + "displayName": "John", + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "2551234567890", + "displayName": "Yaro", + "fspId": "PayeeFSP" + "supportedCurrencies": [ "TZS" ]}, + "amountType": "SEND", + "currency": "BWP", + "amount": "300" + "currentState": " + WAITING_FOR_CONVERSION_ACCEPTANCE + ", + "getPartiesResponse": {<Same as the previous responses>}, + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "fxQuotesResponse": { + "body": { + "condition": "GRzLaTP7DJ9t4P-a_B...", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [{ + "chargeType": "string", + "sourceAmount": { + "currency": "BWP", + "amount": "33"}, + "targetAmount": { + "currency": "TZS", + "amount": "6000"} + }]}} + }, + "fxQuotesResponseSource": "PayeeFSP", + } + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml new file mode 100644 index 000000000..bdf1afcfa --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml @@ -0,0 +1,241 @@ +@startuml FXAPI_Payer_Receive_Agreement + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Accord — conversion de devises avec type de montant RÉCEPTION +'actor "$senderName" as A1 +box "DFSP payeur" #LightBlue +' participant "CBS payeur" as PayerCBS + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP + participant "API FX backend" as FXPBackend +end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +' participant "CBS bénéficiaire" as PayeeCBS +end box + +'actor "$receiverName" as A2 +autonumber + +D1->>S1:Merci de coter un paiement\nde $payeeReceiveAmount $payeeCurrency.\n**POST /quotes** +!if ($simplified != true) +note left + **POST /quotes** + { + "quoteId": "382987a875ce...", + "transactionId": "d9ce59d43598...", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN" }} + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}}, + "amountType": **"RECEIVE"**, + "amount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"} + "validity": "2021-08-25T14:17:09.663+01:00" + } +end note +!endif +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D1 +S1->>D2:**POST /quotes** +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +deactivate S1 +!endif +D2->D2: Je vais obtenir un devis pour la conversion +!if ($shortCutSingleFXP != true) + + +D2->D2:OK, je facturerai $payeeFee $payeeCurrency pour cela.\nJe crée maintenant les conditions du transfert \net je signe l'objet de transaction +D2->>S1:Voici le devis signé +note right +**put /quotes/382987a875ce...** +{ + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" }, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "2021-08-25T14:17:09.663+01:00, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "$payeeFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}}, + "payer": { + "fspId": "$payerFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}}, + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "converter": "PAYER"}, + "condition": "BfNFPRgfKF8Ke9kpo..." +} +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +deactivate D2 +S1->>D1:Voici le devis signé\n**PUT /quotes/382987a875ce...** +activate D1 +!if ($simplified != true) +D1-->>S1:200 — OK +!endif +deactivate S1 +D1->D1:OK, je vois qu'il y aura\n $payeeFee $payeeCurrency de frais et \nque je dois envoyer $targetAmount $payeeCurrency pour \neffectuer ce transfert + +group Conversion de devises +D1->D1:Je dois maintenant connaître le \ntaux de change +deactivate S1 +D1->D1:Je vais demander à FDH FX\nd'effectuer ma conversion + +!if ($shortCutSingleFXP != true) +D1->>S1:Voici la version initiale \ndu transfert. Merci de me coter\n la conversion de devises. +!else +D1->>FXP:Voici la version initiale\n du transfert. Merci de me coter\n la conversion de devises. +!endif +note left + **post /fxQuotes** + { + "conversionRequestId": "828cc75f1654...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "counterPartyFsp": "FDH_FX", + "amountType": "RECEIVE", + "sourceAmount": { + "currency": "$payerCurrency"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "validity": "2021-08-25T14:17:09.663+01:00"} + } +end note +!if ($shortCutSingleFXP != true) +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D1 +S1->>FXP:Voici la version initiale\n du transfert. Merci de me coter\n la conversion de devises.\n**POST /fxQuote** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +!else +!endif +FXP->FXPBackend:Consulter le taux de change +FXPBackend-->FXP:Renvoyer le taux de change +' !if ($shortCutSingleFXP != true) + +note right + J'ajoute des frais de $fxpChargesSource $payerCurrency pour + la conversion. Je fixe maintenant une heure d'expiration, + je signe l'objet de devis, je crée un paquet ILP prepare + et je le renvoie dans l'objet intermédiaire. + + **REMARQUE :** le paquet ILP prepare contient les éléments + suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion + + **PUT /fxQuotes/828cc75f1654...** + { + "condition": "bdbcf517cfc7e...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "initiatingFsp": "$payerFSPID" + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency"", + "amount": "$fxpTargetAmount" + }, + "charges": [{ + "chargeType": "Conversion fee", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"}}], + "validity": "2021-08-25T14:17:09.663+01:00"} + } +end note +!if ($shortCutSingleFXP != true) +FXP->>S1:Voici l'objet \nde conversion signé +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +deactivate FXP +S1->>D1:Voici l'objet de conversion signé\n**PUT /fxQuotes/828cc75f1654...** +activate D1 +!if ($simplified != true) +D1-->>S1:Compris +!endif +deactivate S1 +!else +FXP-->>D1:Voici l'objet de conversion signé\n**PUT /fxQuotes/828cc75f1654...** +activate D1 +!endif + +end group + +@enduml diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg new file mode 100644 index 000000000..1abd590c0 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg @@ -0,0 +1,309 @@ + + Accord — conversion de devises avec type de montant RÉCEPTION + + + Accord — conversion de devises avec type de montant RÉCEPTION + + DFSP payeur + + Fournisseur de change + + DFSP bénéficiaire + + + + + + + + + + + + + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + API FX backend + + API FX backend + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + + + + + + + + + 1 + Merci de coter un paiement + de 50000 TZS. + POST /quotes + + + POST /quotes + { + "quoteId": "382987a875ce...", + "transactionId": "d9ce59d43598...", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890" }} + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "26787654321"}}, + "amountType": + "RECEIVE" + , + "amount": { + "currency": "TZS", + "amount": "50000"} + "validity": "2021-08-25T14:17:09.663+01:00" + } + + + + 2 + 202 — Je vous recontacte + + + + 3 + POST /quotes + + + + 4 + 202 — Je vous recontacte + + + + + 5 + Je vais obtenir un devis pour la conversion + + + + + 6 + OK, je facturerai 4000 TZS pour cela. + Je crée maintenant les conditions du transfert + et je signe l'objet de transaction + + + + 7 + Voici le devis signé + + + put /quotes/382987a875ce... + { + "transferAmount": { + "currency": "TZS", + "amount": "54000" }, + "payeeReceiveAmount": { + "currency": "TZS", + "amount": "50000"}, + "payeeFspFee": { + "currency": "TZS", + "amount": "4000"}, + "expiration": "2021-08-25T14:17:09.663+01:00, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "PayeeFSP", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890"}}, + "payer": { + "fspId": "PayerFSP", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "26787654321"}}, + "amount": { + "currency": "TZS", + "amount": "54000"}, + "payeeReceiveAmount": { + "currency": "TZS", + "amount": "50000"}, + "converter": "PAYER"}, + "condition": "BfNFPRgfKF8Ke9kpo..." + } + + + + 8 + 200 — OK + + + + 9 + Voici le devis signé + PUT /quotes/382987a875ce... + + + + 10 + 200 — OK + + + + + 11 + OK, je vois qu'il y aura + 4000 TZS de frais et + que je dois envoyer 54000 TZS pour + effectuer ce transfert + + + Conversion de devises + + + + + 12 + Je dois maintenant connaître le + taux de change + + + + + 13 + Je vais demander à FDH FX + d'effectuer ma conversion + + + + 14 + Voici la version initiale + du transfert. Merci de me coter + la conversion de devises. + + + post /fxQuotes + { + "conversionRequestId": "828cc75f1654...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "counterPartyFsp": "FDH_FX", + "amountType": "RECEIVE", + "sourceAmount": { + "currency": "BWP"}, + "targetAmount": { + "currency": "TZS", + "amount": "54000"}, + "validity": "2021-08-25T14:17:09.663+01:00"} + } + + + + 15 + 202 — Je vous recontacte + + + + 16 + Voici la version initiale + du transfert. Merci de me coter + la conversion de devises. + POST /fxQuote + + + + 17 + 202 — Je vous recontacte + + + 18 + Consulter le taux de change + + + 19 + Renvoyer le taux de change + + + J'ajoute des frais de 33 BWP pour + la conversion. Je fixe maintenant une heure d'expiration, + je signe l'objet de devis, je crée un paquet ILP prepare + et je le renvoie dans l'objet intermédiaire. +   + REMARQUE : + le paquet ILP prepare contient les éléments + suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion +   + PUT /fxQuotes/828cc75f1654... + { + "condition": "bdbcf517cfc7e...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "initiatingFsp": "PayerFSP" + "sourceAmount": { + "currency": "BWP", + "amount": "330" + }, + "targetAmount": { + "currency": "TZS"", + "amount": "54000" + }, + "charges": [{ + "chargeType": "Conversion fee", + "sourceAmount": { + "currency": "BWP", + "amount": "33"}, + "targetAmount": { + "currency": "TZS", + "amount": "6000"}}], + "validity": "2021-08-25T14:17:09.663+01:00"} + } + + + + 20 + Voici l'objet + de conversion signé + + + + 21 + 200 — OK + + + + 22 + Voici l'objet de conversion signé + PUT /fxQuotes/828cc75f1654... + + + + 23 + Compris + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml new file mode 100644 index 000000000..b6fb42d04 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml @@ -0,0 +1,112 @@ +@startuml FXAPI_Payer_Receive_Discovery + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "267876..." +!$payeeMSISDN = "255123..." +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Découverte — conversion de devises avec type de montant RÉCEPTION +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "CBS payeur" as PayerCBS + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +box "Service de découverte" #LightYellow + participant "Oracle ALS" as ALS +end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +' participant "API FX backend" as FXPBackend +'end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 + participant "CBS bénéficiaire" as PayeeCBS +end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:Je voudrais payer $receiverName\n$payeeReceiveAmount $payeeCurrency pour \nson dernier livre, s'il vous plaît +PayerCBS->D1: Lancer le paiement marchand +activate D1 +D1->>S1:Je veux envoyer vers le MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D1 +S1->ALS:À qui appartient le MSISDN $payeeMSISDN ? +activate ALS +ALS-->S1:C'est $payeeFSPID +deactivate ALS +S1->>D2:Le MSISDN $payeeMSISDN vous appartient-il ? +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +D2->D2: Vérifier le statut de liste de sanctions \net déclencher une actualisation +D2->PayeeCBS: Vérifier le compte et obtenir\nle type de devise +!if ($simplified != true) +PayeeCBS-->D2: Résultat +!endif +D2->>S1:Oui, c'est $receiverName. Il peut recevoir en $payeeCurrency,\n et je peux convertir depuis $payerCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +note right + **PUT /parties** + { + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}, + "name": "$receiverName", + "supportedCurrencies":["$payeeCurrency"]} + } +end note +!else +note over D2 + Informations bénéficiaire avec données KYC chiffrées +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +deactivate D2 +S1->>D1:Oui, c'est $receiverName. Il peut recevoir en $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +activate D1 +!if ($simplified != true) +D1-->>S1:200 — OK +!endif +deactivate S1 + +D1->D1: Je devrai effectuer une conversion de devises. +note left +Je dois calculer +de combien de devise j'ai besoin. +Je vais trouver un fournisseur +de conversion de devises avant de commencer. +end note + +@enduml diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg new file mode 100644 index 000000000..84c07f371 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg @@ -0,0 +1,167 @@ + + Découverte — conversion de devises avec type de montant RÉCEPTION + + + Découverte — conversion de devises avec type de montant RÉCEPTION + + DFSP payeur + + Service de découverte + + DFSP bénéficiaire + + + + + + + + + + + + + + Keeya + + + Keeya + + + + CBS payeur + + CBS payeur + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Oracle ALS + + Oracle ALS + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + CBS bénéficiaire + + CBS bénéficiaire + + + + + + + + + 1 + Je voudrais payer Yaro + 50000 TZS pour + son dernier livre, s'il vous plaît + + + 2 + Lancer le paiement marchand + + + + 3 + Je veux envoyer vers le MSISDN 255123... + GET /parties/MSISDN/255123... + + + + 4 + 202 — Je vous recontacte + + + 5 + À qui appartient le MSISDN 255123... ? + + + 6 + C'est PayeeFSP + + + + 7 + Le MSISDN 255123... vous appartient-il ? + + + + 8 + 202 — Je vous recontacte + + + + + 9 + Vérifier le statut de liste de sanctions + et déclencher une actualisation + + + 10 + Vérifier le compte et obtenir + le type de devise + + + 11 + Résultat + + + + 12 + Oui, c'est Yaro. Il peut recevoir en TZS, + et je peux convertir depuis BWP + PUT /parties/MSISDN/255123... + + + PUT /parties + { + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "255123..."}, + "name": "Yaro", + "supportedCurrencies":["TZS"]} + } + + + + 13 + 200 — OK + + + + 14 + Oui, c'est Yaro. Il peut recevoir en TZS + PUT /parties/MSISDN/255123... + + + + 15 + 200 — OK + + + + + 16 + Je devrai effectuer une conversion de devises. + + + Je dois calculer + de combien de devise j'ai besoin. + Je vais trouver un fournisseur + de conversion de devises avant de commencer. + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml new file mode 100644 index 000000000..24aa8c4dc --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml @@ -0,0 +1,57 @@ +@startuml FXAPI_Payer_Receive_SenderConfirmation + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Conversion de devises avec type de montant RÉCEPTION +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "CBS payeur" as PayerCBS + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +'participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +' participant "API FX backend" as FXPBackend +'end box + +'box "DFSP bénéficiaire" #LightBlue +' participant "Connecteur Mojaloop\nbénéficiaire" as D2 +' participant "Payee CBS" as PayeeCBS +'end box + +'actor "$receiverName" as A2 +autonumber + + +D1->PayerCBS:Voici le devis pour le transfert\nIl expire le 2021-08-25T14:17:09.663+01:00 +PayerCBS->A1:Bonjour, $senderName : je peux effectuer le transfert.\nCela vous coûtera $totalChargesSourceCurrency $payerCurrency de frais\n$fxpSourceAmount $payerCurrency seront débités de votre compte,\net $receiverName recevra\n$payeeReceiveAmount $payeeCurrency.\nDites-moi si vous souhaitez continuer +A1-->PayerCBS:Parfait ! Oui, continuez s'il vous plaît + +PayerCBS-->D1: Le payeur a accepté les conditions — merci de poursuivre + +@enduml diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg new file mode 100644 index 000000000..d862ceb60 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg @@ -0,0 +1,50 @@ + + Conversion de devises avec type de montant RÉCEPTION + + + Conversion de devises avec type de montant RÉCEPTION + + DFSP payeur + + + + Keeya + + + Keeya + + + + CBS payeur + + CBS payeur + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + + 1 + Voici le devis pour le transfert + Il expire le 2021-08-25T14:17:09.663+01:00 + + + 2 + Bonjour, Keeya : je peux effectuer le transfert. + Cela vous coûtera 55 BWP de frais + 330 BWP seront débités de votre compte, + et Yaro recevra + 50000 TZS. + Dites-moi si vous souhaitez continuer + + + 3 + Parfait ! Oui, continuez s'il vous plaît + + + 4 + Le payeur a accepté les conditions — merci de poursuivre + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml new file mode 100644 index 000000000..48f9dc6cd --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml @@ -0,0 +1,254 @@ +@startuml FXAPI_Payer_Receive_TransferPhase + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Transfert — conversion de devises avec type de montant RÉCEPTION +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue +' participant "CBS payeur" as PayerCBS + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP + participant "API FX backend" as FXPBackend +end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +end box + participant "CBS bénéficiaire" as PayeeCBS + +'actor "$receiverName" as A2 +autonumber + +D1->D1:D'abord, activer la conversion +D1->>S1:Merci de confirmer votre\npart du transfert +note left +**POST /fxTransfers** +{ + "commitRequestId": "77c9d78dc26a4474...", + "determiningTransactionId": "d9ce59d435...", + "requestingFsp": "$payerFSPID", + "respondingFxp": "FDH_FX", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "bdbcf517cfc7..." +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:OK, il s'agit d'une confirmation FX. +S1->S1: L'émetteur a-t-il un compte \ndans cette devise ? Oui. +!endif +S1->S1: Contrôle de liquidité et réserve sur\nle compte du DFSP payeur +!if ($hideSwitchDetail != true) +note over S1 +Réservations : + +**$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Merci de confirmer la partie\nconversion de devises du transfert\n **POST /fxTransfers** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +FXP->FXPBackend:Réserver les fonds pour\n la conversion FX +FXPBackend->FXP:Succès +FXP->>S1:Confirmé. Voici l'exécution (fulfilment) +note right +**PUT /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "188909ceb6cd5c...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00" + "conversionState": "RESERVED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +deactivate FXP +!if ($simplified != true) +S1->S1:Vérifier que l'exécution \ncorrespond et annuler sinon. +alt Échec de la conversion +S1->FXP:Désolé. La conversion a échoué +note left +**PATCH /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "188909ceb6cd5c35...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Accusé de réception +FXP->FXP:Supprimer les réservations\nou obligations +deactivate FXP + +S1->>D1:Désolé. La conversion a échoué +note right +**PUT /fxTransfers/77c9d78dc26a.../error** +{ + "errorCode": "9999", + "errorDescription": "Description de l'erreur (variable)" +} +end note +activate D1 +else Conversion réussie +S1->D1:Conversion réussie sous réserve\ndu succès du transfert\n**PUT /fxTransfers/77c9d78dc26a...** + +end +!else +S1->D1:Conversion réussie sous réserve\ndu succès du transfert\n**PUT /fxTransfers/77c9d78dc26a...** +!endif +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif +deactivate S1 +D1->D1:OK, tout est bon\nJe peux maintenant envoyer le transfert proprement dit + +D1->S1:Merci d'effectuer le transfert \n**POST /transfers** +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "c720ae14fc72...", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "$payeeFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}}, + "payer": { + "fspId": "$payerFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}} + } +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 — Je vous recontacte +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ? Oui +!endif +S1->S1:Effectuer le contrôle de liquidité et\nréserver les fonds en faveur de la partie\ncréancière du transfert dépendant +note over S1 +**Réservations :** + +$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency +**FDH_FX a une réservation de $targetAmount $payeeCurrency** +end note + +S1->D2:Merci d'effectuer le transfert\n**POST /transfers** +activate D2 +!if ($simplified != true) +D2-->S1:202 — Je vous recontacte +!endif +deactivate S1 +D2->D2:Je vérifie que les conditions \ndu transfert dépendant sont\n les mêmes que celles acceptées\n et que l'exécution\n et la condition concordent +D2->D2:Oui. \nJ'approuve le transfert +D2->PayeeCBS:Merci de créditer le compte de $receiverName\nde $payeeReceiveAmount $payeeCurrency +D2->S1:Transfert confirmé, voici l'exécution +note right +**PUT /transfers/c720ae14fc72...** +{ + "fulfilment": "mhPUT9ZAwdXLfe...", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" +} +end note +activate S1 +!if ($simplified != true) +S1-->D2:200 — OK +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ?\nOui. +S1->S1:Cette dépendance concerne-t-elle le\ndébiteur du transfert ?\nOui. +S1->S1:Créer une obligation du\ndébiteur vers la partie nommée\ndans la dépendance (le FXP) +S1->S1:Le transfert est-il libellé dans\nla devise du montant \nreçu par le bénéficiaire ? Oui. +S1->S1:Créer une obligation de la\npartie nommée dans la dépendance\nvers le créancier du transfert +!else +S1->S1:Créer des obligations du\npayeur vers le FXP et du \nFXP vers le bénéficiaire +!endif +S1->FXP:Le transfert a réussi.\nVous pouvez le compenser dans vos livres +note left +**PATCH /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "2e6870fb4ed...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Vérifions : \ncela correspond-il à ce que j'ai envoyé ? +FXP->FXP:Oui. Parfait. \nJe compense la conversion +FXP-->S1:200 — OK +deactivate FXP +note over S1 + **Positions du grand livre :** + $payerFSPID a un débit de $fxpSourceAmount $payerCurrency + FDH_FX a un crédit de $fxpSourceAmount $payerCurrency + FDH_FX a un débit de $fxpTargetAmount $payeeCurrency + $payeeFSPID a un crédit de $targetAmount $payeeCurrency +end note +S1->D1:Transfert terminé\n**PUT /transfers/c720ae14fc72...** +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif +deactivate S1 +D1->D1:Comptabiliser les fonds dans mes livres +D1->A1:Le transfert s'est terminé avec succès +deactivate D1 + +@enduml diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg new file mode 100644 index 000000000..836e972dc --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg @@ -0,0 +1,437 @@ + + Transfert — conversion de devises avec type de montant RÉCEPTION + + + Transfert — conversion de devises avec type de montant RÉCEPTION + + DFSP payeur + + Fournisseur de change + + DFSP bénéficiaire + + + + + + + + + + + + + + + + + + + Keeya + + + Keeya + + + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + API FX backend + + API FX backend + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + CBS bénéficiaire + + CBS bénéficiaire + + + + + + + + + + + + + + + 1 + D'abord, activer la conversion + + + + 2 + Merci de confirmer votre + part du transfert + + + POST /fxTransfers + { + "commitRequestId": "77c9d78dc26a4474...", + "determiningTransactionId": "d9ce59d435...", + "requestingFsp": "PayerFSP", + "respondingFxp": "FDH_FX", + "sourceAmount": { + "currency": "BWP", + "amount": "330"}, + "targetAmount": { + "currency": "TZS", + "amount": "54000"}, + "condition": "bdbcf517cfc7..." + } + + + + 3 + 202 — Je vous recontacte + + + + + 4 + OK, il s'agit d'une confirmation FX. + + + + + 5 + L'émetteur a-t-il un compte + dans cette devise ? Oui. + + + + + 6 + Contrôle de liquidité et réserve sur + le compte du DFSP payeur + + + Réservations : +   + PayerFSP a une réservation de 330 BWP + + + + 7 + Merci de confirmer la partie + conversion de devises du transfert +   + POST /fxTransfers + + + + 8 + 202 — Je vous recontacte + + + 9 + Réserver les fonds pour + la conversion FX + + + 10 + Succès + + + + 11 + Confirmé. Voici l'exécution (fulfilment) + + + PUT /fxTransfers/77c9d78dc26a... + { + "fulfilment": "188909ceb6cd5c...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00" + "conversionState": "RESERVED" + } + + + + 12 + 200 — OK + + + + + 13 + Vérifier que l'exécution + correspond et annuler sinon. + + + alt + [Échec de la conversion] + + + 14 + Désolé. La conversion a échoué + + + PATCH /fxTransfers/77c9d78dc26a... + { + "fulfilment": "188909ceb6cd5c35...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + + + 15 + Accusé de réception + + + + + 16 + Supprimer les réservations + ou obligations + + + + 17 + Désolé. La conversion a échoué + + + PUT /fxTransfers/77c9d78dc26a.../error + { + "errorCode": "9999", + "errorDescription": "Description de l'erreur (variable)" + } + + [Conversion réussie] + + + 18 + Conversion réussie sous réserve + du succès du transfert + PUT /fxTransfers/77c9d78dc26a... + + + 19 + 200 — OK + + + + + 20 + OK, tout est bon + Je peux maintenant envoyer le transfert proprement dit + + + 21 + Merci d'effectuer le transfert + POST /transfers + + + POST /transfers + { + "transferId": "c720ae14fc72...", + "payeeFsp": "PayeeFSP", + "payerFsp": "PayerFSP", + "amount": { + "currency": "TZS", + "amount": "54000"}, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "PayeeFSP", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890"}}, + "payer": { + "fspId": "PayerFSP", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "26787654321"}} + } + } + + + 22 + 202 — Je vous recontacte + + + + + 23 + Y a-t-il un transfert dépendant ? Oui + + + + + 24 + Effectuer le contrôle de liquidité et + réserver les fonds en faveur de la partie + créancière du transfert dépendant + + + Réservations : +   + PayerFSP a une réservation de 330 BWP + FDH_FX a une réservation de 54000 TZS + + + 25 + Merci d'effectuer le transfert + POST /transfers + + + 26 + 202 — Je vous recontacte + + + + + 27 + Je vérifie que les conditions + du transfert dépendant sont + les mêmes que celles acceptées + et que l'exécution + et la condition concordent + + + + + 28 + Oui. + J'approuve le transfert + + + 29 + Merci de créditer le compte de Yaro + de 50000 TZS + + + 30 + Transfert confirmé, voici l'exécution + + + PUT /transfers/c720ae14fc72... + { + "fulfilment": "mhPUT9ZAwdXLfe...", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" + } + + + 31 + 200 — OK + + + + + 32 + Y a-t-il un transfert dépendant ? + Oui. + + + + + 33 + Cette dépendance concerne-t-elle le + débiteur du transfert ? + Oui. + + + + + 34 + Créer une obligation du + débiteur vers la partie nommée + dans la dépendance (le FXP) + + + + + 35 + Le transfert est-il libellé dans + la devise du montant + reçu par le bénéficiaire ? Oui. + + + + + 36 + Créer une obligation de la + partie nommée dans la dépendance + vers le créancier du transfert + + + 37 + Le transfert a réussi. + Vous pouvez le compenser dans vos livres + + + PATCH /fxTransfers/77c9d78dc26a... + { + "fulfilment": "2e6870fb4ed...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "COMMITTED" + } + + + + + 38 + Vérifions : + cela correspond-il à ce que j'ai envoyé ? + + + + + 39 + Oui. Parfait. + Je compense la conversion + + + 40 + 200 — OK + + + Positions du grand livre : + PayerFSP a un débit de 330 BWP + FDH_FX a un crédit de 330 BWP + FDH_FX a un débit de 54000 TZS + PayeeFSP a un crédit de 54000 TZS + + + 41 + Transfert terminé + PUT /transfers/c720ae14fc72... + + + 42 + 200 — OK + + + + + 43 + Comptabiliser les fonds dans mes livres + + + 44 + Le transfert s'est terminé avec succès + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml new file mode 100644 index 000000000..387a7f76e --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml @@ -0,0 +1,157 @@ +@startuml FXAPI_Payer_SenderConfirmation + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Le DFSP payeur demande une conversion avec montant ENVOI +actor "$senderName" as A1 +participant "CBS payeur" as PayerCBS + +box "DFSP payeur" #LightBlue + participant "Connecteur principal" as PayerCC + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +'participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow + 'participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +' participant "API FX backend" as FXPBackend +'end box + +'box "DFSP bénéficiaire" #LightBlue +' participant "Connecteur Mojaloop\nbénéficiaire" as D2 +' participant "Connecteur principal" as PayeeCC +'end box + +'actor "$receiverName" as A2 +autonumber + + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC:Voici le devis pour le transfert\nIl expire le $quotePayeeExpiration + note right + **POST/PUT /transfers** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ] }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_QUOTE_ACCEPTANCE**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": {}, + "fxQuotesResponseSource": "$payeeFSPID", + "quoteId": "$quoteId", + "quoteResponse": { + "body": { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition"},}, + "quoteResponseSource": "$payeeFSPID", + } + end note +!else + D1-->PayerCC:Voici le devis pour le transfert\nIl expire le $quotePayeeExpiration + !if ($simplified != true) + note right of PayerCC + { + "quotes": { + "body": { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" + }, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount" + }, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee" + }, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": " + + ", + "condition": "$condition" + }, + "headers": {} + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif +PayerCC->PayerCBS:Voici le devis +PayerCBS->A1:Bonjour, $senderName : je peux effectuer le transfert.\nCela vous coûtera $totalChargesSourceCurrency $payerCurrency ($totalChargesTargetCurrency $payeeCurrency) de frais\net $receiverName recevra\n$payeeReceiveAmount $payeeCurrency.\nDites-moi si vous souhaitez continuer +A1->PayerCBS:Parfait ! Oui, continuez s'il vous plaît + +PayerCBS->PayerCC: Le payeur a accepté les conditions — merci de poursuivre + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg new file mode 100644 index 000000000..bcf406cf1 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg @@ -0,0 +1,104 @@ + + Le DFSP payeur demande une conversion avec montant ENVOI + + + Le DFSP payeur demande une conversion avec montant ENVOI + + DFSP payeur + + + + + John + + + John + + + + CBS payeur + + CBS payeur + + Connecteur principal + + Connecteur principal + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + + 1 + Voici le devis pour le transfert + Il expire le 2021-08-25T14:17:09.663+01:00 + + + POST/PUT /transfers + response + { + "transferId": "d9ce59d4359843968630581bb0", + "homeTransactionId": "string", + "from": { + "displayName": "John", + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321" }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "2551234567890", + "displayName": "Yaro", + "fspId": "PayeeFSP" + "supportedCurrencies": [ "TZS" ] }, + "amountType": "SEND", + "currency": "BWP", + "amount": "300" + "currentState": " + WAITING_FOR_QUOTE_ACCEPTANCE + ", + "getPartiesResponse": {<Same as the previous responses>}, + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "fxQuotesResponse": {<Same as the previous responses>}, + "fxQuotesResponseSource": "PayeeFSP", + "quoteId": "382987a875ce4037b500c475e0", + "quoteResponse": { + "body": { + "transferAmount": { + "currency": "TZS", + "amount": "48000"}, + "payeeReceiveAmount": { + "currency": "TZS", + "amount": "44000"}, + "payeeFspFee": { + "currency": "TZS", + "amount": "4000"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "<Objet de transaction encodé>", + "condition": "HOr22-H3AfTDHrSkP..."},}, + "quoteResponseSource": "PayeeFSP", + } + + + 2 + Voici le devis + + + 3 + Bonjour, John : je peux effectuer le transfert. + Cela vous coûtera 55 BWP (10000 TZS) de frais + et Yaro recevra + 44000 TZS. + Dites-moi si vous souhaitez continuer + + + 4 + Parfait ! Oui, continuez s'il vous plaît + + + 5 + Le payeur a accepté les conditions — merci de poursuivre + + diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml new file mode 100644 index 000000000..fea62e343 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml @@ -0,0 +1,466 @@ +@startuml FXAPI_Payer_Transfer + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Phase de transfert — connecteur Mojaloop +actor "$senderName" as A1 + participant "CBS payeur" as PayerCBS +box "DFSP payeur" #LightBlue + participant "Connecteur principal" as PayerCC + participant "Connecteur Mojaloop\npayeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP + participant "API FX backend" as FXPBackend +end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 + participant "Connecteur principal" as PayeeCC +end box + +actor "$receiverName" as A2 +autonumber + +!if ($advancedCoreConnectorFlow != true) +PayerCC->D1: Poursuivre le transfert\nPUT /transfers +note left +{"acceptQuote": true} +end note +!else +PayerCC->D1: Poursuivre le transfert\n**POST /fxTransfers** + !if ($simplified != true) + note left + { + "homeTransactionId": "$homeTransactionId", + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" + } + end note + !endif +!endif + +!if ($advancedCoreConnectorFlow != true) +D1->D1:D'abord, activer la conversion +!endif +D1->>S1:Merci de confirmer votre part du transfert +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:OK, il s'agit d'une confirmation FX. +S1->S1: Existe-t-il un transfert avec determiningTransactionId ?\nNon. +!endif +S1->S1: Contrôle de liquidité et réserve sur le compte du DFSP payeur +!if ($hideSwitchDetail != true) +note over S1 +Réservations : + +**$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Merci de confirmer la partie conversion de devises du transfert\n** POST /fxTransfers** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +deactivate S1 +FXP->FXPBackend:Réserver les fonds pour la conversion FX +note left +**POST /fxTransfers** +{ + "homeTransactionId": "$homeTransactionId", + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +FXPBackend-->FXP:Succès +note right +{ + "homeTransactionId": "$homeTransactionId", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +FXP->>S1:Confirmé. Voici l'exécution (fulfilment) +note right +**PUT /fxTransfers/$commitRequestId** +{ + "fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +deactivate FXP +!if ($simplified != true) +S1->S1:Vérifier que l'exécution correspond et annuler sinon. +alt Échec de la conversion +S1->FXP:Désolé. La conversion a échoué +note right +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Accusé de réception +FXP->FXPBackend:Supprimer les réservations ou obligations +note left +**PUT /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +FXPBackend-->FXP:Ok +deactivate FXP + +S1->>D1:Désolé. La conversion a échoué +note right +**PUT /fxTransfers/$commitRequestId/error** +{ + "errorCode": "9999", + "errorDescription": "Description de l'erreur (variable)" +} +end note +else Conversion réussie +S1->D1:Conversion réussie sous réserve du succès du transfert\n**PUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc** + +end +!else +S1->D1:Conversion réussie sous réserve du succès du transfert\n**PUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc** +!endif +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif +deactivate S1 + +!if ($advancedCoreConnectorFlow != true) + D1->D1:OK, tout est bon\nJe peux maintenant envoyer le transfert proprement dit + ' TODO : ajouter ici la réponse PUT /transfers +!else + D1-->PayerCC:Confirmé. Vous pouvez poursuivre le transfert. + note right of PayerCC + **PUT /fxTransfers/$commitRequestId** + { + "fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + end note + + PayerCC-->D1:Merci d'effectuer le transfert **POST /simpleTransfers** + !if ($simplified != true) + note right of PayerCC + { + "fspId": "$payeeFSPID", + "transfersPostRequest": { + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" + }, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" + } + } + end note + !endif +!endif + +D1->S1:Merci d'effectuer le transfert **POST /transfers** +!if ($simplified != true) +note over D1 +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 — Je vous recontacte +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ? Oui +!endif +S1->S1:Effectuer le contrôle de liquidité et réserver les fonds\nen faveur de la partie créancière du transfert dépendant +note over S1 +Réservations : + +$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency +**$fxpID a une réservation de $targetAmount $payeeCurrency** +end note + +S1->D2:Merci d'effectuer le transfert\n**POST /transfers** +activate D2 +!if ($simplified != true) +D2-->S1:202 — Je vous recontacte +!endif +deactivate S1 +D2->D2:Je vérifie que les conditions du transfert dépendant\ncorrespondent à celles auxquelles j'ai souscrit\net que l'exécution et la condition concordent + +D2->PayeeCC:Merci de créditer le compte de $receiverName de $payeeReceiveAmount $payeeCurrency +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "$transferId", + "amount": "$targetAmount", + "currency": "$payeeCurrency", + "amountType": "SEND", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "displayName": "$receiverName", + "fspId": "$payeeFSPID", + "idType": "MSISDN", + "idValue": "$payeeMSISDN"}, + "quote": { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayeeExpiration"}, + "transactionType": "TRANSFER", + "ilpPacket": {"data": } +} +end note +!endif + +PayeeCC-->D2:Fait +PayeeCC->A2:Vous avez reçu $payeeReceiveAmount $payeeCurrency +!if ($simplified != true) +note right of D2 +{ + "homeTransactionId": "string", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + **Note: fulfilment is optional: SDK will create if not found** + "transferState": "COMMITTED" +} +end note +!endif + +D2->>S1:Transfert confirmé, voici l'exécution (fulfilment) +note over D2 +**PUT /transfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ?\nOui. +S1->S1:Cette dépendance concerne-t-elle \nle débiteur du transfert ?\nOui. +S1->S1:Créer une obligation du\ndébiteur vers la partie nommée dans la dépendance (le FXP) +S1->S1:Le transfert est-il libellé dans\nla devise du montant reçu par le bénéficiaire ?\nOui. +S1->S1:Créer une obligation de la \npartie nommée dans la dépendance\nvers le créancier du transfert +!else +S1->S1:Créer des obligations du payeur vers le FXP et du FXP vers le bénéficiaire +!endif +S1->>FXP:Le transfert a réussi.\nVous pouvez le compenser dans vos livres +note over S1 +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Vérifions : cela correspond-il à ce que j'ai envoyé ? +FXP->FXP:Oui. Parfait. Je compense la conversion +FXP-->>S1:200 — OK +deactivate FXP +note over S1 + Ledger positions: + $payerFSPID a un débit de $fxpSourceAmount $payerCurrency + $fxpID a un crédit de $fxpSourceAmount $payerCurrency + $fxpID a un débit de $fxpTargetAmount $payeeCurrency + $payeeFSPID a un crédit de $targetAmount $payeeCurrency +end note +S1->>D1:Transfert terminé\n**PUT /transfers/$commitRequestId** +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif +deactivate S1 +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC:Le transfert s'est terminé avec succès + note right of PayerCC + **POST/PUT /transfers/** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ]}, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**COMPLETED**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": {}, + "fxQuotesResponseSource": "$payeeFSPID", + "quoteId": "$quoteId", + "quoteResponse": {}, + "quoteResponseSource": "$payeeFSPID", + "fulfil": { + "body": { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED"},}, + } + end note +!else + D1-->PayerCC:Le transfert s'est terminé avec succès + !if ($simplified != true) + note right of PayerCC + { + "transfer": { + "body": { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" + }, + "headers": {} + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif + +PayerCC->PayerCBS:Le transfert s'est terminé avec succès +PayerCBS->PayerCBS:Comptabiliser les fonds dans mes livres +PayerCBS->A1:Votre transfert a réussi +deactivate D1 +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg new file mode 100644 index 000000000..59afcbdbd --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg @@ -0,0 +1,564 @@ + + Phase de transfert — connecteur Mojaloop + + + Phase de transfert — connecteur Mojaloop + + DFSP payeur + + Fournisseur de change + + DFSP bénéficiaire + + + + + + + + + + + + + + + + + + + + + + John + + + John + + + + CBS payeur + + CBS payeur + + Connecteur principal + + Connecteur principal + + Connecteur Mojaloop + payeur + + Connecteur Mojaloop + payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + API FX backend + + API FX backend + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + Connecteur principal + + Connecteur principal + Yaro + + + Yaro + + + + + + + + + + + + + + + 1 + Poursuivre le transfert + PUT /transfers + + + {"acceptQuote": true} + + + + + 2 + D'abord, activer la conversion + + + + 3 + Merci de confirmer votre part du transfert + + + POST /fxTransfers + { + "commitRequestId": "77c9d78dc26a44748b3c99b96a", + "determiningTransferId": "d9ce59d4359843968630581bb0", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "condition": "GRzLaTP7DJ9t4P-a_B..." + } + + + + 4 + 202 — Je vous recontacte + + + + + 5 + OK, il s'agit d'une confirmation FX. + + + + + 6 + Existe-t-il un transfert avec determiningTransactionId ? + Non. + + + + + 7 + Contrôle de liquidité et réserve sur le compte du DFSP payeur + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + + + + 8 + Merci de confirmer la partie conversion de devises du transfert + + POST /fxTransfers** + + + + 9 + 202 — Je vous recontacte + + + 10 + Réserver les fonds pour la conversion FX + + + POST /fxTransfers + { + "homeTransactionId": "string", + "commitRequestId": "77c9d78dc26a44748b3c99b96a", + "determiningTransferId": "d9ce59d4359843968630581bb0", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "condition": "GRzLaTP7DJ9t4P-a_B..." + } + + + 11 + Succès + + + { + "homeTransactionId": "string", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + + + + 12 + Confirmé. Voici l'exécution (fulfilment) + + + PUT /fxTransfers/77c9d78dc26a44748b3c99b96a + { + "fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + + + + 13 + 200 — OK + + + + + 14 + Vérifier que l'exécution correspond et annuler sinon. + + + alt + [Échec de la conversion] + + + 15 + Désolé. La conversion a échoué + + + PATCH /fxTransfers/77c9d78dc26a44748b3c99b96a + { + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + + + 16 + Accusé de réception + + + 17 + Supprimer les réservations ou obligations + + + PUT /fxTransfers/77c9d78dc26a44748b3c99b96a + { + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + + + 18 + Ok + + + + 19 + Désolé. La conversion a échoué + + + PUT /fxTransfers/77c9d78dc26a44748b3c99b96a/error + { + "errorCode": "9999", + "errorDescription": "Description de l'erreur (variable)" + } + + [Conversion réussie] + + + 20 + Conversion réussie sous réserve du succès du transfert + PUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc + + + 21 + 200 — OK + + + + + 22 + OK, tout est bon + Je peux maintenant envoyer le transfert proprement dit + + + 23 + Merci d'effectuer le transfert + POST /transfers + + + POST /transfers + { + "transferId": "d9ce59d4359843968630581bb0", + "payeeFsp": "PayeeFSP", + "payerFsp": "PayerFSP", + "amount": { + "currency": "TZS", + "amount": "48000"}, + "ilpPacket": "<Objet de transaction encodé>", + "condition": "HOr22-H3AfTDHrSkP...", + "expiration": "2016-05-24T08:38:08.699-04:00" + } + + + 24 + 202 — Je vous recontacte + + + + + 25 + Y a-t-il un transfert dépendant ? Oui + + + + + 26 + Effectuer le contrôle de liquidité et réserver les fonds + en faveur de la partie créancière du transfert dépendant + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + FDH_FX a une réservation de 48000 TZS + + + 27 + Merci d'effectuer le transfert + POST /transfers + + + 28 + 202 — Je vous recontacte + + + + + 29 + Je vérifie que les conditions du transfert dépendant + correspondent à celles auxquelles j'ai souscrit + et que l'exécution et la condition concordent + + + 30 + Merci de créditer le compte de Yaro de 44000 TZS + + + POST /transfers + { + "transferId": "d9ce59d4359843968630581bb0", + "amount": "48000", + "currency": "TZS", + "amountType": "SEND", + "from": { + "displayName": "John", + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321"}, + "to": { + "displayName": "Yaro", + "fspId": "PayeeFSP", + "idType": "MSISDN", + "idValue": "2551234567890"}, + "quote": { + "quoteId": "382987a875ce4037b500c475e0", + "transactionId": "d9ce59d4359843968630581bb0", + "payeeFspFeeAmount": "4000", + "payeeFspFeeAmountCurrency": "TZS", + "payeeReceiveAmount": "44000", + "payeeReceiveAmountCurrency": "TZS", + "transferAmount": "48000", + "transferAmountCurrency": "TZS" + "expiration": "2021-08-25T14:17:09.663+01:00"}, + "transactionType": "TRANSFER", + "ilpPacket": {"data": <decoded ilpPacket>} + } + + + 31 + Fait + + + 32 + Vous avez reçu 44000 TZS + + + { + "homeTransactionId": "string", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", +      + Note: fulfilment is optional: SDK will create if not found + "transferState": "COMMITTED" + } + + + + 33 + Transfert confirmé, voici l'exécution (fulfilment) + + + PUT /transfers/77c9d78dc26a44748b3c99b96a + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" + } + + + + 34 + 200 — OK + + + + + 35 + Y a-t-il un transfert dépendant ? + Oui. + + + + + 36 + Cette dépendance concerne-t-elle + le débiteur du transfert ? + Oui. + + + + + 37 + Créer une obligation du + débiteur vers la partie nommée dans la dépendance (le FXP) + + + + + 38 + Le transfert est-il libellé dans + la devise du montant reçu par le bénéficiaire ? + Oui. + + + + + 39 + Créer une obligation de la + partie nommée dans la dépendance + vers le créancier du transfert + + + + 40 + Le transfert a réussi. + Vous pouvez le compenser dans vos livres + + + PATCH /fxTransfers/77c9d78dc26a44748b3c99b96a + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" + } + + + + + 41 + Vérifions : cela correspond-il à ce que j'ai envoyé ? + + + + + 42 + Oui. Parfait. Je compense la conversion + + + + 43 + 200 — OK + + + Ledger positions: + PayerFSP a un débit de 300 BWP + FDH_FX a un crédit de 300 BWP + FDH_FX a un débit de 48000 TZS + PayeeFSP a un crédit de 48000 TZS + + + + 44 + Transfert terminé + PUT /transfers/77c9d78dc26a44748b3c99b96a + + + 45 + 200 — OK + + + 46 + Le transfert s'est terminé avec succès + + + POST/PUT /transfers/ + response + { + "transferId": "d9ce59d4359843968630581bb0", + "homeTransactionId": "string", + "from": { + "displayName": "John", + "fspId": "PayerFSP", + "idType": "MSISDN", + "idValue": "26787654321"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "2551234567890", + "displayName": "Yaro", + "fspId": "PayeeFSP" + "supportedCurrencies": [ "TZS" ]}, + "amountType": "SEND", + "currency": "BWP", + "amount": "300" + "currentState": " + COMPLETED + ", + "getPartiesResponse": {<Same as the previous responses>}, + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "fxQuotesResponse": {<Same as the previous responses>}, + "fxQuotesResponseSource": "PayeeFSP", + "quoteId": "382987a875ce4037b500c475e0", + "quoteResponse": {<Same as the previous responses>}, + "quoteResponseSource": "PayeeFSP", + "fulfil": { + "body": { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED"},}, + } + + + 47 + Le transfert s'est terminé avec succès + + + + + 48 + Comptabiliser les fonds dans mes livres + + + 49 + Votre transfert a réussi + + diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml new file mode 100644 index 000000000..83d1eef75 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml @@ -0,0 +1,182 @@ +@startuml PAYER_SEND_Agreement + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Le DFSP payeur demande un devis au DFSP bénéficiaire +'actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +'end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +end box + +'actor "$receiverName" as A2 +autonumber + + +D1->>S1:Veuillez coter un transfert qui envoie $fxpTargetAmount $payeeCurrency.\n**POST /quotes** +deactivate D1 +!if ($simplified != true) +note left +POST /quotes + + { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "personalInfo": { + "complexName": { + "firstName": "$receiverFirstName", + "middleName": "$receiverMiddleName", + "lastName": "$receiverLastName" + }, + "dateOfBirth": "$receiverDOB", + "kycInformation": "" + }, + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID" + }, + "name": "$senderName", + "personalInfo": { + "complexName": { + "firstName": "$senderFirstName", + "middleName": "$senderMiddleName", + "lastName": "$senderLastName" + }, + "dateOfBirth": "$senderDOB" + } + }, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" + } +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif + +S1->>D2:**POST /quotes** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +!endif + +D2->D2:OK, je facturerai $payeeFee $payeeCurrency pour cela.\nJe crée maintenant les conditions du transfert +!if ($simplified != true) +note right of D2 +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayerExpiration" +} +end note +!endif +D2->D2:Je signe maintenant l'objet de transaction +D2->>S1:Voici le devis signé +note right + **put /quotes/$quoteId** + { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition" + } +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +S1->>D1:Voici le devis signé\n**PUT /quotes/$quoteId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:200 — OK +!endif +D1->D1:OK, je vois qu'il y aura $payeeFee $payeeCurrency de frais. + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg new file mode 100644 index 000000000..1cfb07880 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg @@ -0,0 +1,92 @@ + + Le DFSP payeur demande un devis au DFSP bénéficiaire + + + Le DFSP payeur demande un devis au DFSP bénéficiaire + + DFSP payeur + + DFSP bénéficiaire + + + + + + + + DFSP payeur + + DFSP payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + + + + + + 1 + Veuillez coter un transfert qui envoie 48000 TZS. + POST /quotes + + + + 2 + POST /quotes + + + + + 3 + OK, je facturerai 4000 TZS pour cela. + Je crée maintenant les conditions du transfert + + + + + 4 + Je signe maintenant l'objet de transaction + + + + 5 + Voici le devis signé + + + put /quotes/382987a875ce4037b500c475e0 + { + "transferAmount": { + "currency": "TZS", + "amount": "48000"}, + "payeeReceiveAmount": { + "currency": "TZS", + "amount": "44000"}, + "payeeFspFee": { + "currency": "TZS", + "amount": "4000"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "<Objet de transaction encodé>", + "condition": "HOr22-H3AfTDHrSkP..." + } + + + + 6 + Voici le devis signé + PUT /quotes/382987a875ce4037b500c475e0 + + + + + 7 + OK, je vois qu'il y aura 4000 TZS de frais. + + diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml new file mode 100644 index 000000000..c2c9301a6 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml @@ -0,0 +1,78 @@ +@startuml PAYER_SEND_Confirmation +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Le DFSP payeur présente les conditions au payeur +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +'participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +'end box + +'box "DFSP bénéficiaire" #LightBlue +' participant "Connecteur Mojaloop\nbénéficiaire" as D2 +'end box + +'actor "$receiverName" as A2 +autonumber + +D1->A1: Présenter les conditions du transfert au payeur +note right +Bonjour, $senderName : +Je peux effectuer le transfert. +Cela vous coûtera $totalChargesSourceCurrency $payerCurrency ($totalChargesTargetCurrency $payeeCurrency) de frais +et $receiverName recevra $payeeReceiveAmount $payeeCurrency. +**Souhaitez-vous continuer ?** +end note +A1->D1: Parfait ! Oui, continuez s'il vous plaît + +D1->D1: Le payeur a accepté les conditions — merci de poursuivre +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg new file mode 100644 index 000000000..82d3d4244 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg @@ -0,0 +1,42 @@ + + Le DFSP payeur présente les conditions au payeur + + + Le DFSP payeur présente les conditions au payeur + + DFSP payeur + + + John + + + John + + + + DFSP payeur + + DFSP payeur + + + 1 + Présenter les conditions du transfert au payeur + + + Bonjour, John : + Je peux effectuer le transfert. + Cela vous coûtera 55 BWP (10000 TZS) de frais + et Yaro recevra 44000 TZS. + Souhaitez-vous continuer ? + + + 2 + Parfait ! Oui, continuez s'il vous plaît + + + + + 3 + Le payeur a accepté les conditions — merci de poursuivre + + diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml new file mode 100644 index 000000000..8a915811c --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml @@ -0,0 +1,193 @@ +@startuml PAYER_SEND_CurrencyConversion + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Le DFSP payeur demande une conversion avec montant ENVOI +' actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP +end box + +'box "DFSP bénéficiaire" #LightBlue +' participant "Connecteur Mojaloop\nbénéficiaire" as D2 +'end box + +'actor "$receiverName" as A2 +autonumber + + +D1->D1:Hmm. Je ne peux envoyer qu'en $payerCurrency.\nJ'ai besoin d'une conversion de devises +D1->D1: Consulter les FXP mis en cache localement\npouvant assurer la conversion +D1->D1:Je vais demander à FDH FX d'effectuer ma conversion + + +D1->>S1:Voici la version initiale du transfert.\nMerci de me coter la conversion de devises. + +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note + +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +S1->>FXP:Voici la version initiale du transfert.\nMerci de me coter la conversion de devises.\n**POST /fxQuote** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif + +note over FXP + J'ajouterai des frais de $fxpChargesSource $payerCurrency pour la conversion. + Je fixe maintenant une heure d'expiration et je signe l'objet de devis, +end note +!if ($simplified != true) +note right of FXP + { + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +!endif + +note over FXP + Je signe maintenant l'objet de devis, + je crée un paquet ILP prepare et le renvoie dans l'objet intermédiaire. + + **REMARQUE :** le paquet ILP prepare contient les éléments suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion +end note + + +FXP->>S1:Voici l'objet de conversion signé +note right + **PUT /fxQuotes/$conversionRequestId** + { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +deactivate FXP +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +S1->>D1:Voici l'objet de conversion signé\n**PUT /fxQuotes/$conversionRequestId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:Compris +!endif +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg new file mode 100644 index 000000000..358b27ddc --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg @@ -0,0 +1,140 @@ + + Le DFSP payeur demande une conversion avec montant ENVOI + + + Le DFSP payeur demande une conversion avec montant ENVOI + + DFSP payeur + + Fournisseur de change + + + + + + + + DFSP payeur + + DFSP payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + + + + + + + 1 + Hmm. Je ne peux envoyer qu'en BWP. + J'ai besoin d'une conversion de devises + + + + + 2 + Consulter les FXP mis en cache localement + pouvant assurer la conversion + + + + + 3 + Je vais demander à FDH FX d'effectuer ma conversion + + + + 4 + Voici la version initiale du transfert. + Merci de me coter la conversion de devises. + + + post /fxQuotes + { + "conversionRequestId": "828cc75f1654415e8fcddf76cc", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } + + + + 5 + Voici la version initiale du transfert. + Merci de me coter la conversion de devises. + POST /fxQuote + + + J'ajouterai des frais de 33 BWP pour la conversion. + Je fixe maintenant une heure d'expiration et je signe l'objet de devis, + + + Je signe maintenant l'objet de devis, + je crée un paquet ILP prepare et le renvoie dans l'objet intermédiaire. +   + REMARQUE : + le paquet ILP prepare contient les éléments suivants, tous encodés : + - Le montant envoyé (c.-à-d. dans la devise source) + - Une heure d'expiration + - La condition + - Le nom du FXP + - Le contenu des conditions de conversion + + + + 6 + Voici l'objet de conversion signé + + + PUT /fxQuotes/828cc75f1654415e8fcddf76cc + { + "condition": "GRzLaTP7DJ9t4P-a_B...", + "conversionTerms": { + "conversionId": "581f68efb54f416f9161ac34e8", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "BWP", + "amount": "33"}, + "targetAmount": { + "currency": "TZS", + "amount": "6000"} + }]} + } + + + + 7 + Voici l'objet de conversion signé + PUT /fxQuotes/828cc75f1654415e8fcddf76cc + + diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml new file mode 100644 index 000000000..eac44a8e7 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml @@ -0,0 +1,259 @@ +@startuml PAYER_SEND_Transfer + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f165441..." +!$conversionId = "581f68efb5..." +!$homeTransactionId = "string" +!$quoteId = "382987a875ce..." +!$transactionId = "d9ce59d4359843..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26..." +!$determiningTransferId = "d9ce59d4359843..." +!$transferId = "d9ce59d4359843..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Transfert de fonds POC avec les API FX Mojaloop\nLe DFSP payeur demande une conversion avec montant ENVOI +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP +end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +end box + +actor "$receiverName" as A2 +autonumber + +D1->>S1:Merci de confirmer votre part\ndu transfert +deactivate D1 +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +!if ($hideSwitchDetail != true) +S1->S1:OK, il s'agit d'une confirmation FX. +S1->S1: Existe-t-il un transfert avec\ndeterminingTransactionId ?\nNon. +!endif +S1->S1: Contrôle de liquidité et réserve\nsur le compte du DFSP payeur +!if ($hideSwitchDetail != true) +note over S1 +**Réservations :** + +**$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Merci de confirmer la partie\nconversion de devises du transfert\n **POST /fxTransfers** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +FXP->FXP:Réserver les fonds pour la conversion FX +FXP->>S1:Confirmé. Voici l'exécution (fulfilment) +note right +**PUT /fxTransfers/$commitRequestId** +{ + "fulfilment": "188909ceb6cd5c35d..", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +deactivate FXP +activate S1 +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +!if ($simplified != true) +S1->S1:Vérifier que l'exécution correspond et annuler sinon. +alt Échec de la conversion +S1->FXP:Désolé. La conversion a échoué +note left +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Accusé de réception +FXP->FXP:Supprimer les réservations ou obligations +deactivate FXP + +S1->>D1:Désolé. La conversion a échoué +note right +**PUT /fxTransfers/$commitRequestId/error** +{ + "errorCode": "9999", + "errorDescription": "Description de l'erreur (variable)" +} +end note +else Conversion réussie +S1->D1:Conversion réussie sous réserve\ndu succès du transfert\n**PUT /fxTransfers/$commitRequestId** + +end +!else +S1->D1:Conversion réussie sous réserve\ndu succès du transfert\n**PUT /fxTransfers/$commitRequestId** +!endif +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif + +D1->D1:OK, tout est bon\nJe peux maintenant envoyer le transfert proprement dit + +D1->S1:Merci d'effectuer le transfert\n **POST /transfers** +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->D1:202 — Je vous recontacte +!endif +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ? \nOui +!endif +S1->S1:Effectuer le contrôle de liquidité et\nréserver les fonds contre la partie\ncréancière du transfert dépendant +note over S1 +**Réservations :** + +$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency +**$fxpID a une réservation de $targetAmount $payeeCurrency** +end note + +S1->D2:Merci d'effectuer le transfert\n**POST /transfers** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->S1:202 — Je vous recontacte +!endif +D2->D2:Je vérifie que les conditions\ndu transfert dépendant\nsont les mêmes que celles\nauxquelles j'ai souscrit et que\nl'exécution et la condition correspondent + +D2->A2: Bonjour $receiverName, vous avez reçu un transfert entrant \nde $payeeReceiveAmount $payeeCurrency + +D2->>S1:Transfert confirmé, voici l'exécution (fulfilment) +note right +**PUT /transfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08...", + "fulfilment": "mhPUT9ZAwd-BXLfeSd...", + "transferState": "COMMITTED" +} +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ?\nOui. +S1->S1:Cette dépendance concerne-t-elle le\ndébiteur du transfert ?\nOui. +S1->S1:Créer une obligation du\ndébiteur vers la partie nommée\ndans la dépendance (le FXP) +S1->S1:Le transfert est-il libellé dans\nla devise du montant \nreçu par le bénéficiaire ? Oui. +S1->S1:Créer une obligation de la\n partie nommée dans la\ndépendance vers le créancier\ndu transfert +!else +S1->S1:Créer des obligations du payeur vers le FXP et du FXP vers le bénéficiaire +!endif +note over S1 + **Positions du grand livre :** + $payerFSPID a un débit de $fxpSourceAmount $payerCurrency + $fxpID a un crédit de $fxpSourceAmount $payerCurrency + $fxpID a un débit de $fxpTargetAmount $payeeCurrency + $payeeFSPID a un crédit de $targetAmount $payeeCurrency +end note +S1->>FXP:Le transfert a réussi.\nVous pouvez le compenser dans vos livres +note left +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Vérifions : cela correspond-il à ce que j'ai envoyé ? +FXP->FXP:Oui. Parfait. Je compense la conversion +FXP-->>S1:200 — OK +deactivate FXP +S1->>D1:Transfert terminé\n**PUT /transfers/$commitRequestId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->S1:200 — OK +!endif + +D1->A1:Votre transfert a réussi +deactivate D1 + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg new file mode 100644 index 000000000..b68205a42 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg @@ -0,0 +1,306 @@ + + Transfert de fonds POC avec les API FX Mojaloop + + + Transfert de fonds POC avec les API FX Mojaloop + Le DFSP payeur demande une conversion avec montant ENVOI + + DFSP payeur + + Fournisseur de change + + DFSP bénéficiaire + + + + + + + + + + + + + + + + John + + + John + + + + DFSP payeur + + DFSP payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + Yaro + + + Yaro + + + + + + + + + + + + + + + 1 + Merci de confirmer votre part + du transfert + + + POST /fxTransfers + { + "commitRequestId": "77c9d78dc26...", + "determiningTransferId": "d9ce59d4359843...", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "condition": "GRzLaTP7DJ9t4P-a_B..." + } + + + + + 2 + OK, il s'agit d'une confirmation FX. + + + + + 3 + Existe-t-il un transfert avec + determiningTransactionId ? + Non. + + + + + 4 + Contrôle de liquidité et réserve + sur le compte du DFSP payeur + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + + + + 5 + Merci de confirmer la partie + conversion de devises du transfert +   + POST /fxTransfers + + + + + 6 + Réserver les fonds pour la conversion FX + + + + 7 + Confirmé. Voici l'exécution (fulfilment) + + + PUT /fxTransfers/77c9d78dc26... + { + "fulfilment": "188909ceb6cd5c35d..", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + + + 8 + Conversion réussie sous réserve + du succès du transfert + PUT /fxTransfers/77c9d78dc26... + + + + + 9 + OK, tout est bon + Je peux maintenant envoyer le transfert proprement dit + + + 10 + Merci d'effectuer le transfert +   + POST /transfers + + + + + 11 + Y a-t-il un transfert dépendant ? + Oui + + + + + 12 + Effectuer le contrôle de liquidité et + réserver les fonds contre la partie + créancière du transfert dépendant + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + FDH_FX a une réservation de 48000 TZS + + + 13 + Merci d'effectuer le transfert + POST /transfers + + + + + 14 + Je vérifie que les conditions + du transfert dépendant + sont les mêmes que celles + auxquelles j'ai souscrit et que + l'exécution et la condition correspondent + + + 15 + Bonjour Yaro, vous avez reçu un transfert entrant + de 44000 TZS + + + + 16 + Transfert confirmé, voici l'exécution (fulfilment) + + + PUT /transfers/77c9d78dc26... + { + "completedTimestamp": "2021-08-25T14:17:08...", + "fulfilment": "mhPUT9ZAwd-BXLfeSd...", + "transferState": "COMMITTED" + } + + + + + 17 + Y a-t-il un transfert dépendant ? + Oui. + + + + + 18 + Cette dépendance concerne-t-elle le + débiteur du transfert ? + Oui. + + + + + 19 + Créer une obligation du + débiteur vers la partie nommée + dans la dépendance (le FXP) + + + + + 20 + Le transfert est-il libellé dans + la devise du montant + reçu par le bénéficiaire ? Oui. + + + + + 21 + Créer une obligation de la + partie nommée dans la + dépendance vers le créancier + du transfert + + + Positions du grand livre : + PayerFSP a un débit de 300 BWP + FDH_FX a un crédit de 300 BWP + FDH_FX a un débit de 48000 TZS + PayeeFSP a un crédit de 48000 TZS + + + + 22 + Le transfert a réussi. + Vous pouvez le compenser dans vos livres + + + PATCH /fxTransfers/77c9d78dc26... + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" + } + + + + + 23 + Vérifions : cela correspond-il à ce que j'ai envoyé ? + + + + + 24 + Oui. Parfait. Je compense la conversion + + + + 25 + 200 — OK + + + + 26 + Transfert terminé + PUT /transfers/77c9d78dc26... + + + 27 + Votre transfert a réussi + + diff --git a/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml b/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml new file mode 100644 index 000000000..4f688de63 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml @@ -0,0 +1,337 @@ +@startuml Payer_SEND_ABORT_TransferPhase + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f16..." +!$conversionId = "581f68efb..." +!$homeTransactionId = "string" +!$quoteId = "382987a875..." +!$transactionId = "d9ce59d435..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc2..." +!$determiningTransferId = "d9ce59d43..." +!$transferId = "d9ce59d435..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Phase de transfert de conversion de devises — flux d'ABANDON +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +box "Fournisseur de change" + participant "Connecteur\nFXP" as FXP +end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +end box + +actor "$receiverName" as A2 +autonumber + +D1->>S1:Merci de confirmer votre part du transfert +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:OK, il s'agit d'une confirmation FX. +S1->S1: Existe-t-il un transfert avec determiningTransactionId ?\nNon. +!endif +S1->S1: Contrôle de liquidité et réserve sur le compte du DFSP payeur +!if ($hideSwitchDetail != true) +note over S1 +Réservations : + +**$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Merci de confirmer la partie\nconversion de devises du transfert\n **POST /fxTransfers** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 — Je vous recontacte +!endif +alt échec de la conversion + FXP->>S1:Échec. + note right + **PUT /fxTransfers/$commitRequestId**/error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( **or** ) + **PUT /fxTransfers/$commitRequestId** + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + end note +else conversion réussie + FXP->FXP:Réserver les fonds pour la conversion FX + FXP->>S1:Confirmé. Voici l'exécution (fulfilment) + note right + **PUT /fxTransfers/$commitRequestId** + { + "fulfilment": "188909ceb6cd5...", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + end note + deactivate FXP + S1->S1:Vérifier que l'exécution correspond et annuler sinon. + alt Échec de la conversion + S1->FXP:Désolé. La conversion a échoué + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + end note + activate FXP + FXP-->S1:Accusé de réception + FXP->FXP:Supprimer les réservations ou obligations + deactivate FXP + end +end +!if ($simplified != true) +S1-->>FXP:200 — OK +!endif +deactivate FXP + +alt Échec de la conversion + S1->S1: Abandonner le fxTransfer. Annuler \nles changements de position liés à ce\n fxTransfer. + note over S1 + **Remarque :** + En cas de conversion côté bénéficiaire, il y aura un transfert dépendant. + N'annulez pas ce transfert car le DFSP peut tenter une conversion avec + un autre FXP. Veillez à ce que, lors du traitement de l'exécution du transfert + d'origine, ce fxTransfer ne soit pas pris comme transfert dépendant + (par ex. en retirant l'entrée de la liste de surveillance). + end note + S1->>D1:Désolé. La conversion a échoué + note right + **PUT /fxTransfers/$commitRequestId/error** + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( **or** ) + **PUT /fxTransfers/$commitRequestId** + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + end note +else Conversion réussie + S1->D1:Conversion réussie sous réserve\ndu succès du transfert\n**PUT /fxTransfers/77c9d78dc26a...** + activate D1 +end + +!if ($simplified != true) +D1-->S1:200 — OK +!endif +D1->D1:OK, tout est bon\nJe peux maintenant envoyer le transfert proprement dit + +D1->S1:Merci d'effectuer le transfert\n **POST /transfers** +deactivate D1 +!if ($simplified != true) +note over D1 +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 — Je vous recontacte +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Y a-t-il un transfert dépendant ? Oui +!endif +S1->S1:Effectuer le contrôle de liquidité et réserver les fonds\nen faveur de la partie créancière du transfert dépendant +note over S1 +Réservations : + +$payerFSPID a une réservation de $fxpSourceAmount $payerCurrency +**$fxpID a une réservation de $targetAmount $payeeCurrency** +end note + +S1->D2:Merci d'effectuer le transfert\n**POST /transfers** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->S1:202 — Je vous recontacte +!endif +D2->D2:Je vérifie que les conditions \ndu transfert dépendant sont \nles mêmes que celles acceptées\n et que l'exécution et la \ncondition correspondent + +D2->A2: Bonjour $receiverName, vous avez reçu un transfert entrant \nde $payeeReceiveAmount $payeeCurrency +deactivate D2 + +alt échec du transfert + D2->>S1:Transfert refusé + note right + **PUT /transfers/$commitRequestId**/error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( **or** ) + { + "transferState": "ABORETED" + } + end note + + activate S1 + !if ($simplified != true) + S1-->>D2:200 — OK + !endif + + S1->S1: Annuler les changements de position \nliés à ce transfert + S1->S1: S'il existe des fxTransfers dépendants,\n les abandonner également et \nannuler les changements de position \nassociés à ces fxTransfers + + S1->>FXP: Le transfert lié a échoué.\nSupprimer les réservations ou obligations + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "ABORTED" + } + end note + activate FXP + FXP->FXP: Oups ! + FXP-->>S1:200 — OK + deactivate FXP + S1->>D1:Transfer is complete\n**PUT /transfers/$commitRequestId/error** + activate D1 + !if ($simplified != true) + D1-->S1:200 — OK + !endif + deactivate S1 + D1->A1:Votre transfert a échoué + deactivate D1 +else transfert réussi + D2->>S1:Transfert confirmé, voici l'exécution (fulfilment) + note right + **PUT /transfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + end note + activate S1 + !if ($simplified != true) + S1-->>D2:200 — OK + !endif + + !if ($hideSwitchDetail != true) + S1->S1:Y a-t-il un transfert dépendant ?\nOui. + S1->S1:Cette dépendance concerne-t-elle le\ndébiteur du transfert ?\nOui. + S1->S1:Créer une obligation du \ndébiteur vers la partie nommée \ndans la dépendance (le FXP) + S1->S1:Le transfert est-il libellé dans \nla devise du montant reçu par le\nbénéficiaire ?\nOui. + S1->S1:Créer une obligation de la \npartie nommée dans la dépendance\nvers le créancier du transfert + !else + S1->S1:Créer des obligations du payeur vers le FXP et du FXP vers le bénéficiaire + !endif + S1->>FXP:Le transfert a réussi.\nVous pouvez le compenser dans vos livres + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + end note + activate FXP + FXP->FXP:Vérifions : cela correspond-il à ce que j'ai envoyé ? + FXP->FXP:Oui. Parfait. Je compense la conversion + FXP-->>S1:200 — OK + deactivate FXP + note over S1 + **Positions du grand livre :** + $payerFSPID a un débit de $fxpSourceAmount $payerCurrency + $fxpID a un crédit de $fxpSourceAmount $payerCurrency + $fxpID a un débit de $fxpTargetAmount $payeeCurrency + $payeeFSPID a un crédit de $targetAmount $payeeCurrency + end note + S1->>D1:Transfert terminé\n**PUT /transfers/$commitRequestId** + activate D1 + !if ($simplified != true) + D1-->S1:200 — OK + !endif + deactivate S1 + + D1->A1:Votre transfert a réussi + deactivate D1 +end + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg b/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg new file mode 100644 index 000000000..0c895cfb8 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg @@ -0,0 +1,489 @@ + + Phase de transfert de conversion de devises — flux d'ABANDON + + + Phase de transfert de conversion de devises — flux d'ABANDON + + DFSP payeur + + Fournisseur de change + + DFSP bénéficiaire + + + + + + + + + + + + + + + + + + + + + + + John + + + John + + + + DFSP payeur + + DFSP payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur + FXP + + Connecteur + FXP + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + Yaro + + + Yaro + + + + + + + + + + + + + + + + + + 1 + Merci de confirmer votre part du transfert + + + POST /fxTransfers + { + "commitRequestId": "77c9d78dc2...", + "determiningTransferId": "d9ce59d43...", + "initiatingFsp": "PayerFSP", + "counterPartyFsp": "FDH_FX", + "amountType": "SEND", + "sourceAmount": { + "currency": "BWP", + "amount": "300"}, + "targetAmount": { + "currency": "TZS", + "amount": "48000"}, + "condition": "GRzLaTP7DJ9t4P-a_B..." + } + + + + + 2 + OK, il s'agit d'une confirmation FX. + + + + + 3 + Existe-t-il un transfert avec determiningTransactionId ? + Non. + + + + + 4 + Contrôle de liquidité et réserve sur le compte du DFSP payeur + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + + + + 5 + Merci de confirmer la partie + conversion de devises du transfert +   + POST /fxTransfers + + + alt + [échec de la conversion] + + + + 6 + Échec. + + + PUT /fxTransfers/77c9d78dc2... + /error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( + or + ) + PUT /fxTransfers/77c9d78dc2... + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + + [conversion réussie] + + + + + 7 + Réserver les fonds pour la conversion FX + + + + 8 + Confirmé. Voici l'exécution (fulfilment) + + + PUT /fxTransfers/77c9d78dc2... + { + "fulfilment": "188909ceb6cd5...", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + + + + + 9 + Vérifier que l'exécution correspond et annuler sinon. + + + alt + [Échec de la conversion] + + + 10 + Désolé. La conversion a échoué + + + PATCH /fxTransfers/77c9d78dc2... + { + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + + + 11 + Accusé de réception + + + + + 12 + Supprimer les réservations ou obligations + + + alt + [Échec de la conversion] + + + + + 13 + Abandonner le fxTransfer. Annuler + les changements de position liés à ce + fxTransfer. + + + Remarque : + En cas de conversion côté bénéficiaire, il y aura un transfert dépendant. + N'annulez pas ce transfert car le DFSP peut tenter une conversion avec + un autre FXP. Veillez à ce que, lors du traitement de l'exécution du transfert + d'origine, ce fxTransfer ne soit pas pris comme transfert dépendant + (par ex. en retirant l'entrée de la liste de surveillance). + + + + 14 + Désolé. La conversion a échoué + + + PUT /fxTransfers/77c9d78dc2.../error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( + or + ) + PUT /fxTransfers/77c9d78dc2... + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + + [Conversion réussie] + + + 15 + Conversion réussie sous réserve + du succès du transfert + PUT /fxTransfers/77c9d78dc26a... + + + + + 16 + OK, tout est bon + Je peux maintenant envoyer le transfert proprement dit + + + 17 + Merci d'effectuer le transfert +   + POST /transfers + + + + + 18 + Y a-t-il un transfert dépendant ? Oui + + + + + 19 + Effectuer le contrôle de liquidité et réserver les fonds + en faveur de la partie créancière du transfert dépendant + + + Réservations : +   + PayerFSP a une réservation de 300 BWP + FDH_FX a une réservation de 48000 TZS + + + 20 + Merci d'effectuer le transfert + POST /transfers + + + + + 21 + Je vérifie que les conditions + du transfert dépendant sont + les mêmes que celles acceptées + et que l'exécution et la + condition correspondent + + + 22 + Bonjour Yaro, vous avez reçu un transfert entrant + de 44000 TZS + + + alt + [échec du transfert] + + + + 23 + Transfert refusé + + + PUT /transfers/77c9d78dc2... + /error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "message d'erreur"} + } + ( + or + ) + { + "transferState": "ABORETED" + } + + + + + 24 + Annuler les changements de position + liés à ce transfert + + + + + 25 + S'il existe des fxTransfers dépendants, + les abandonner également et + annuler les changements de position + associés à ces fxTransfers + + + + 26 + Le transfert lié a échoué. + Supprimer les réservations ou obligations + + + PATCH /fxTransfers/77c9d78dc2... + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "ABORTED" + } + + + + + 27 + Oups ! + + + + 28 + 200 — OK + + + + 29 + Transfer is complete + PUT /transfers/77c9d78dc2.../error + + + 30 + Votre transfert a échoué + + [transfert réussi] + + + + 31 + Transfert confirmé, voici l'exécution (fulfilment) + + + PUT /transfers/77c9d78dc2... + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + + + + + 32 + Y a-t-il un transfert dépendant ? + Oui. + + + + + 33 + Cette dépendance concerne-t-elle le + débiteur du transfert ? + Oui. + + + + + 34 + Créer une obligation du + débiteur vers la partie nommée + dans la dépendance (le FXP) + + + + + 35 + Le transfert est-il libellé dans + la devise du montant reçu par le + bénéficiaire ? + Oui. + + + + + 36 + Créer une obligation de la + partie nommée dans la dépendance + vers le créancier du transfert + + + + 37 + Le transfert a réussi. + Vous pouvez le compenser dans vos livres + + + PATCH /fxTransfers/77c9d78dc2... + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + + + + + 38 + Vérifions : cela correspond-il à ce que j'ai envoyé ? + + + + + 39 + Oui. Parfait. Je compense la conversion + + + + 40 + 200 — OK + + + Positions du grand livre : + PayerFSP a un débit de 300 BWP + FDH_FX a un crédit de 300 BWP + FDH_FX a un débit de 48000 TZS + PayeeFSP a un crédit de 48000 TZS + + + + 41 + Transfert terminé + PUT /transfers/77c9d78dc2... + + + 42 + Votre transfert a réussi + + diff --git a/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml b/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml new file mode 100644 index 000000000..ed9ed99b1 --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml @@ -0,0 +1,113 @@ +@startuml Payer_SEND_Discovery +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Découverte — conversion de devises +actor "$senderName" as A1 +box "DFSP payeur" #LightBlue + participant "DFSP payeur" as D1 +end box + +participant "Commutateur Mojaloop" as S1 + +'box "Service de découverte" #LightYellow +' participant "Oracle ALS" as ALS +'end box + +'box "Fournisseur de change" +' participant "Connecteur\nFXP" as FXP +'end box + +box "DFSP bénéficiaire" #LightBlue + participant "Connecteur Mojaloop\nbénéficiaire" as D2 +end box + +'actor "$receiverName" as A2 +autonumber + +A1->D1:Je voudrais payer $receiverName\n$payerSendAmount $payerCurrency, s'il vous plaît + +activate D1 +D1->>S1:Je veux envoyer vers le MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->>D1:202 — Je vous recontacte +!endif +S1->S1:Who owns MSISDN $payeeMSISDN?\nIt's $payeeFSPID +S1->>D2:Le MSISDN $payeeMSISDN vous appartient-il ? +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->>S1:202 — Je vous recontacte +!endif +D2->D2: Vérifier le statut de liste de sanctions et déclencher une actualisation +D2->>S1:Oui, c'est $receiverName. Il peut recevoir en $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +note right + **PUT /parties** + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } +end note + +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 — OK +!endif +S1->>D1:Oui, c'est $receiverName. Il peut recevoir en $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:200 — OK +!endif + +D1->A1: Bonjour, $senderName : le numéro appartient à $receiverName \nDites-moi si vous souhaitez continuer +deactivate D1 +A1->D1: Le payeur a accepté les informations sur la partie + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.svg b/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.svg new file mode 100644 index 000000000..1be2953fd --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/Payer_SEND_Discovery.svg @@ -0,0 +1,106 @@ + + Découverte — conversion de devises + + + Découverte — conversion de devises + + DFSP payeur + + DFSP bénéficiaire + + + + + + + + + + John + + + John + + + + DFSP payeur + + DFSP payeur + + Commutateur Mojaloop + + Commutateur Mojaloop + + Connecteur Mojaloop + bénéficiaire + + Connecteur Mojaloop + bénéficiaire + + + + + + + + 1 + Je voudrais payer Yaro + 300 BWP, s'il vous plaît + + + + 2 + Je veux envoyer vers le MSISDN 2551234567890 + GET /parties/MSISDN/2551234567890 + + + + + 3 + Who owns MSISDN 2551234567890? + It's PayeeFSP + + + + 4 + Le MSISDN 2551234567890 vous appartient-il ? + + + + + 5 + Vérifier le statut de liste de sanctions et déclencher une actualisation + + + + 6 + Oui, c'est Yaro. Il peut recevoir en TZS + PUT /parties/MSISDN/2551234567890 + + + PUT /parties + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "2551234567890", + "fspId": "PayeeFSP"}, + "name": "Yaro", + "supportedCurrencies": [ "TZS" ] + } + + + + 7 + Oui, c'est Yaro. Il peut recevoir en TZS + PUT /parties/MSISDN/2551234567890 + + + 8 + Bonjour, John : le numéro appartient à Yaro + Dites-moi si vous souhaitez continuer + + + 9 + Le payeur a accepté les informations sur la partie + + diff --git a/docs/fr/product/features/CurrencyConversion/README.md b/docs/fr/product/features/CurrencyConversion/README.md new file mode 100644 index 000000000..7c044813e --- /dev/null +++ b/docs/fr/product/features/CurrencyConversion/README.md @@ -0,0 +1,9 @@ +--- +sidebarTitle: Diagrammes de conversion +--- + +# Diagrammes de conversion de devises + +Ce dossier contient les diagrammes de séquence au format **PlantUML** (fichiers `.plantuml`) et leurs exports **SVG** utilisés par la page [Change étranger – conversion de devises](../fx.md). + +Pour modifier un schéma, éditez le fichier `.plantuml` correspondant puis régénérez le SVG avec [PlantUML](https://plantuml.com/) afin de conserver une mise en page cohérente (les libellés plus longs peuvent nécessiter un réajustement manuel des positions dans le SVG généré). diff --git a/docs/fr/product/features/FXP.svg b/docs/fr/product/features/FXP.svg new file mode 100644 index 000000000..396e2ff2a --- /dev/null +++ b/docs/fr/product/features/FXP.svg @@ -0,0 +1,4 @@ + + + +
Scheme
Scheme
DFSP 1
DFSP 1
DFSP 2
DFSP 2
FXP
FXP
\ No newline at end of file diff --git a/docs/fr/product/features/ForeignExchange.md b/docs/fr/product/features/ForeignExchange.md new file mode 100644 index 000000000..3e928e94e --- /dev/null +++ b/docs/fr/product/features/ForeignExchange.md @@ -0,0 +1,55 @@ +--- +sidebarTitle: Change +--- + +# Change + +Un système de paiement moderne doit pouvoir prendre en charge des transactions dans plusieurs devises ; Mojaloop ne fait pas exception, avec une prise en charge native de plusieurs devises de transaction. Un principe important est que ces devises restent indépendantes : une transaction débitée sur le débiteur en devise X est toujours créditée sur le créancier en devise X. + +Il est toutefois parfois nécessaire de créer un « pont » entre ces devises. C’est le rôle du change, avec l’intervention d’un tiers appelé, dans le vocabulaire Mojaloop, fournisseur de change (*Foreign Exchange Provider*, FXP). + +Cette fonction n’est pas nécessairement liée à l’envoi transfrontalier de fonds : une personne dans une même juridiction peut légitimement détenir des fonds dans plusieurs devises, d’autant plus dans les pays où plusieurs devises circulent couramment. + +Le schéma suivant illustre la mise en œuvre dans Mojaloop. + +![Change](./FXP.svg) + +À ce jour, Mojaloop ne prend en charge qu’un seul modèle économique pour le change : le modèle « le payeur décide » (*Payer Decides*). + +### Le payeur décide + +1. Un client du DFSP1 souhaite envoyer 10 unités du devise X au bénéficiaire. +2. La phase de découverte indique que le compte du bénéficiaire est hébergé par le DFSP2. +3. Le DFSP1 propose la transaction au DFSP2, qui indique que le paiement doit être effectué en devise Y. +4. Le DFSP1 envoie 10 X au FXP, qui transmet la contre-valeur en Y au DFSP2, puis le versement au bénéficiaire (hors frais, écart de change, etc.). + +Les détails d’implémentation de cette capacité de change figurent dans la [**documentation FX**](./fx.md). + +D’autres modèles, plus complexes, seront pris en charge dans une prochaine version. Il est notamment prévu : + +### Plusieurs FXP + +1. Un client du DFSP1 souhaite envoyer 10 unités du devise X au bénéficiaire. +2. La découverte montre que le compte du bénéficiaire est hébergé par le DFSP2. +3. Le DFSP1 propose la transaction au DFSP2, qui indique que le paiement doit être effectué en devise Y. +4. Le DFSP1 sollicite plusieurs FXP, retient celui offrant les conditions les plus favorables, envoie 10 X à ce FXP, qui transmet la contre-valeur en Y au DFSP2 et règle le bénéficiaire (hors frais, écart de change, etc.). + +### Le bénéficiaire décide + +1. Un client du DFSP1 souhaite envoyer 10 unités du devise X au bénéficiaire. +2. La découverte montre que le compte du bénéficiaire est hébergé par le DFSP2. +3. Le DFSP1 propose la transaction au DFSP2, qui indique que le paiement doit être effectué dans la devise du payeur, X. +4. Le DFSP1 envoie 10 X au DFSP2. +5. Le DFSP2 sollicite plusieurs FXP, en retient un selon les conditions les plus favorables et envoie 10 X à ce FXP, qui renvoie la contre-valeur en Y au DFSP2, lequel règle ensuite le bénéficiaire (hors frais, écart de change, etc.). + +Pour la suite du lien entre capacités inter-schémas et change, voir les [**transactions transfrontalières**](./CrossBorder.md). + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22 avril 2025| Paul Makin|Ajout de l’historique des versions| +|1.0|13 mars 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/InterconnectingSchemes.md b/docs/fr/product/features/InterconnectingSchemes.md new file mode 100644 index 000000000..2ff11a9b4 --- /dev/null +++ b/docs/fr/product/features/InterconnectingSchemes.md @@ -0,0 +1,36 @@ +--- +sidebarTitle: Interconnexion de schémas +--- + +# Interconnexion de schémas de paiement + +Mojaloop, dans un déploiement unique, sert à exploiter un ou plusieurs schémas de paiement sur une même plateforme. Il est courant qu’un pays héberge plusieurs schémas sur des plateformes distinctes, répondant à des besoins sectoriels différents. + +À mesure qu’un schéma se développe, le besoin d’interconnexion ou d’interopérabilité avec d’autres schémas nationaux augmente. Mojaloop y répond par un mécanisme appelé « Interscheme ». + +L’approche Interscheme de Mojaloop s’appuie sur un type particulier de participant DFSP : le *Proxy*. Un Proxy est un DFSP léger présent dans les deux schémas interconnectés, avec les caractéristiques suivantes : +- le Proxy ne traite pas les messages ; il les relaie entre les schémas connectés ; +- pour préserver la non-répudiation entre schémas, le proxy ne participe pas à l’accord sur les conditions, ce qui contribue à réduire les coûts ; +- il ne joue aucun rôle dans la compensation des transactions. + +Ainsi, un Proxy conserve les trois phases d’un transfert Mojaloop et assure la non-répudiation de bout en bout. L’accord conclu lors d’un transfert reste donc entre les DFSP d’origine et de réception, quel que soit le schéma auquel ils sont rattachés. + +![Interconnexion inter-schémas simple](./SimpleInterscheme.svg) + +Par ailleurs, le modèle d’interconnexion Mojaloop prend en charge la découverte inter-schémas : un alias utilisé dans un schéma peut servir à router un paiement depuis un autre. + +La version actuelle de Mojaloop ne prend en charge que l’interconnexion de schémas basés sur Mojaloop. Des travaux visent à étendre cette capacité à d’autres schémas de paiement connectés à un schéma Mojaloop. + +Les détails d’implémentation de cette interconnexion figurent dans la [**documentation inter-schéma**](./interscheme.md). + +Pour le lien avec le [**change**](./ForeignExchange.md) et les [**transactions transfrontalières**](./CrossBorder.md), voir les pages correspondantes. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22 avril 2025| Paul Makin|Ajout de l’historique ; précisions rédactionnelles| +|1.0|14 avril 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/Interscheme/Interscheme-Agreement.plantuml b/docs/fr/product/features/Interscheme/Interscheme-Agreement.plantuml new file mode 100644 index 000000000..7b48dc683 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Agreement.plantuml @@ -0,0 +1,72 @@ +@startuml Interscheme-Agreement + +title Inter-schéma — accord + + +participant "DFSP payeur" as payerDFSP +box Schéma A #LightBlue + participant "Mojaloop\nSchéma A" as schemeA + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box Schéma B #d1e0c3 + participant "Mojaloop\nSchéma B" as schemeB + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: POST /quotes +schemeA -->> payerDFSP: 202 OK +note left +en-tête + source : payerDFSP + destination : payeeDFSP +JWS signé par payerDFSP +end note +schemeA -> pc_A: Destination hors schéma\n Recherche du proxy pour payeeDFSP = Proxy AB +schemeA ->> xnp: POST /quotes +xnp ->> schemeB: POST /quotes\nmessage non modifié +note left +en-tête + source : payerDFSP + destination : payeeDFSP + fxpiop-proxy: proxyAB +JWS signé par payerDFSP +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK +schemeB->>payeeDFSP: POST /quotes +payeeDFSP-->>schemeB: 202 OK +note right +Vérifie le JWS signé par payerDFSP +end note +payeeDFSP->>schemeB: PUT /quotes +note right +en-tête + source : payeeDFSP + destination : payerDFSP +JWS signé par payeeDFSP +end note +schemeB-->>payeeDFSP: 200 OK +schemeB -> pc_B: Destination hors schéma\n Recherche du proxy pour payerDFSP = Proxy AB +schemeB->>xnp: PUT /quotes +xnp->>schemeA: PUT /quotes\nmessage non modifié +note right +en-tête + source : payeeDFSP + destination : payerDFSP + fxpiop-proxy: proxyAB +JWS signé par payeeDFSP +end note +schemeA-->>xnp: 200 OK +xnp-->>schemeB: 200 OK +schemeA->>payerDFSP: PUT /quotes +note left +Vérifie le JWS signé par payeeDFSP +end note +payerDFSP -->> schemeA: 200 OK + + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-Agreement.svg b/docs/fr/product/features/Interscheme/Interscheme-Agreement.svg new file mode 100644 index 000000000..74ddc35be --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Agreement.svg @@ -0,0 +1,178 @@ + + Inter-schéma — accord + + + Inter-schéma — accord + + Schéma A + + Schéma B + + + + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + Schéma A + + Mojaloop + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + Mojaloop + Schéma B + + Mojaloop + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + [1] + POST /quotes + + + + [2] + 202 OK + + + en-tête + source : payerDFSP + destination : payeeDFSP + JWS signé par payerDFSP + + + [3] + Destination hors schéma + Recherche du proxy pour payeeDFSP = Proxy AB + + + + [4] + POST /quotes + + + + [5] + POST /quotes + message non modifié + + + en-tête + source : payerDFSP + destination : payeeDFSP + fxpiop-proxy: proxyAB + JWS signé par payerDFSP + + + + [6] + 202 OK + + + + [7] + 202 OK + + + + [8] + POST /quotes + + + + [9] + 202 OK + + + Vérifie le JWS signé par payerDFSP + + + + [10] + PUT /quotes + + + en-tête + source : payeeDFSP + destination : payerDFSP + JWS signé par payeeDFSP + + + + [11] + 200 OK + + + [12] + Destination hors schéma + Recherche du proxy pour payerDFSP = Proxy AB + + + + [13] + PUT /quotes + + + + [14] + PUT /quotes + message non modifié + + + en-tête + source : payeeDFSP + destination : payerDFSP + fxpiop-proxy: proxyAB + JWS signé par payeeDFSP + + + + [15] + 200 OK + + + + [16] + 200 OK + + + + [17] + PUT /quotes + + + Vérifie le JWS signé par payeeDFSP + + + + [18] + 200 OK + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.plantuml b/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.plantuml new file mode 100644 index 000000000..4316cfb8d --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.plantuml @@ -0,0 +1,114 @@ +@startuml Interscheme-ErrorCases + +title Inter-schéma — cas d'erreur + +participant "DFSP payeur" as payerDFSP +box "Schéma A" #LightBlue + participant "ALS\nSchéma A" as schemeA + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box "Schéma B" #d1e0c3 + participant "ALS\nSchéma B" as schemeB + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +== Phase POST == +payerDFSP ->> schemeA: POST/GET/PATCH/PUT /xxx +note left +en-tête + source : payerDFSP + destination : payeeDFSP +end note + +alt en cas d'erreur OpenAPI + schemeA -->> payerDFSP: 400 requête incorrecte +end +schemeA-->>payerDFSP: 202 OK + + alt en cas d'erreur dans schémaA + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + note right + Codes d'erreur : 2xxx, 3xxx, 4xxx, 5xxx + end note + payerDFSP -->> schemeA: 200 OK + end + + schemeA -> pc_A: recherche du proxy pour payeeDFSP = Proxy AB + alt si absent du cache proxy + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + note right + Code d'erreur : 3201 + end note + payerDFSP -->> schemeA: 200 OK + end + schemeA ->> xnp: POST/GET/PATCH/PUT /xxx + + alt en cas d'erreur dans le proxy xnp + xnp -->> schemeA: 503 { ErrorCode: 3100} + + xnp ->> schemeA: PUT /xxx/{ID}/error + note right + en-tête + source : Proxy AB + destination : payerDFSP + JWS signé par Proxy AB + Codes d'erreur : 3100 + end note + schemeA -->> xnp: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> schemeB: POST/GET/PATCH/PUT /xxx + schemeB -->> xnp: 202 OK + xnp -->> schemeA: 202 OK + + alt en cas d'erreur dans schémaB + schemeB ->> xnp: PUT /xxx/{ID}/error + note right + Codes d'erreur : 2xxx, 3xxx, 4xxx, 5xxx + end note + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> schemeA: PUT /xxx/{ID}/error + schemeA -->> xnp: 200 OK + xnp -->> schemeB: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + + schemeB ->> payeeDFSP: POST/GET/PATCH/PUT /xxx + payeeDFSP -->> schemeB: 200 OK + + alt en cas d'erreur dans payeeDFSP + payeeDFSP->> schemeB: PUT /xxx/{ID}/error + note right + en-tête destination : PayerDFSP + Codes d'erreur : 5xxx + end note + schemeB -->> payeeDFSP: 200 OK + schemeB -> schemeB: Recherche du proxy pour payerDFSP = Proxy AB + schemeB ->> xnp: PUT /xxx/{ID}/error + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> schemeA: PUT /xxx/{ID}/error + schemeA -->> xnp: 200 OK + xnp -->> schemeB: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.svg b/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.svg new file mode 100644 index 000000000..757be21e5 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-ErrorCases.svg @@ -0,0 +1,311 @@ + + Inter-schéma — cas d'erreur + + + Inter-schéma — cas d'erreur + + Schéma A + + Schéma B + + + + + + + + + + + + + + + DFSP payeur + + DFSP payeur + + ALS + Schéma A + + ALS + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + ALS + Schéma B + + ALS + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + + Phase POST + + + + [1] + POST/GET/PATCH/PUT /xxx + + + en-tête + source : payerDFSP + destination : payeeDFSP + + + alt + [en cas d'erreur OpenAPI] + + + + [2] + 400 requête incorrecte + + + + [3] + 202 OK + + + alt + [en cas d'erreur dans schémaA] + + + + [4] + PUT /xxx/{ID}/error + + + Codes d'erreur : 2xxx, 3xxx, 4xxx, 5xxx + + + + [5] + 200 OK + + + [6] + recherche du proxy pour payeeDFSP = Proxy AB + + + alt + [si absent du cache proxy] + + + + [7] + PUT /xxx/{ID}/error + + + Code d'erreur : 3201 + + + + [8] + 200 OK + + + + [9] + POST/GET/PATCH/PUT /xxx + + + alt + [en cas d'erreur dans le proxy xnp] + + + + [10] + 503 { ErrorCode: 3100} + + + + [11] + PUT /xxx/{ID}/error + + + en-tête + source : Proxy AB + destination : payerDFSP + JWS signé par Proxy AB + Codes d'erreur : 3100 + + + + [12] + 200 OK + + + + [13] + PUT /xxx/{ID}/error + + + + [14] + 200 OK + + + + + [15] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [16] + POST/GET/PATCH/PUT /xxx + + + + [17] + 202 OK + + + + [18] + 202 OK + + + alt + [en cas d'erreur dans schémaB] + + + + [19] + PUT /xxx/{ID}/error + + + Codes d'erreur : 2xxx, 3xxx, 4xxx, 5xxx + + + + + [20] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [21] + PUT /xxx/{ID}/error + + + + [22] + 200 OK + + + + [23] + 200 OK + + + + [24] + PUT /xxx/{ID}/error + + + + [25] + 200 OK + + + + [26] + POST/GET/PATCH/PUT /xxx + + + + [27] + 200 OK + + + alt + [en cas d'erreur dans payeeDFSP] + + + + [28] + PUT /xxx/{ID}/error + + + en-tête destination : PayerDFSP + Codes d'erreur : 5xxx + + + + [29] + 200 OK + + + + + [30] + Recherche du proxy pour payerDFSP = Proxy AB + + + + [31] + PUT /xxx/{ID}/error + + + + + [32] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [33] + PUT /xxx/{ID}/error + + + + [34] + 200 OK + + + + [35] + 200 OK + + + + [36] + PUT /xxx/{ID}/error + + + + [37] + 200 OK + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.plantuml b/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.plantuml new file mode 100644 index 000000000..b447143a5 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.plantuml @@ -0,0 +1,57 @@ +@startuml Interscheme-GETTransfer + +title Inter-schéma — GET /transfers + +participant "DFSP payeur" as payerDFSP +box Schéma A #LightBlue + participant "Mojaloop\nSchéma A" as schemeA + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box Schéma B #d1e0c3 + participant "Mojaloop\nSchéma B" as schemeB + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: GET /transfers/1234 +note left +en-tête + source : payerDFSP + destination : payeeDFSP +JWS signé par payerDFSP +end note +schemeA -->> payerDFSP: 202 OK +schemeA -> schemeA: Charger les informations du transfert + + +schemeA->>payerDFSP: PUT /transfers/1234 +note right +en-tête + source : schemeB + destination : payerDFSP +JWS signé par schémaB +end note +payerDFSP -->> schemeA: 200 OK + +payeeDFSP->>schemeB: GET /transfers/1234 +note right +en-tête + source : scheme A +JWS signé par schémaA +end note +schemeB -->> payeeDFSP: 202 OK +schemeB -> schemeB: Charger les informations du transfert\net vérifier si payeeDFSP est dans le schéma +schemeB->>payeeDFSP: Oui ; renvoi des informations\nPUT /transfers/1234 +note left +en-tête + source : schemeB + destination : payeeDFSP +JWS signé par schémaB +end note +schemeB -->> payeeDFSP: 200 OK + + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.svg b/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.svg new file mode 100644 index 000000000..bd40545e0 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-GETTransfer.svg @@ -0,0 +1,131 @@ + + Inter-schéma — GET /transfers + + + Inter-schéma — GET /transfers + + Schéma A + + Schéma B + + + + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + Schéma A + + Mojaloop + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + Mojaloop + Schéma B + + Mojaloop + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + [1] + GET /transfers/1234 + + + en-tête + source : payerDFSP + destination : payeeDFSP + JWS signé par payerDFSP + + + + [2] + 202 OK + + + + + [3] + Charger les informations du transfert + + + + [4] + PUT /transfers/1234 + + + en-tête + source : schemeB + destination : payerDFSP + JWS signé par schémaB + + + + [5] + 200 OK + + + + [6] + GET /transfers/1234 + + + en-tête + source : scheme A + JWS signé par schémaA + + + + [7] + 202 OK + + + + + [8] + Charger les informations du transfert + et vérifier si payeeDFSP est dans le schéma + + + + [9] + Oui ; renvoi des informations + PUT /transfers/1234 + + + en-tête + source : schemeB + destination : payeeDFSP + JWS signé par schémaB + + + + [10] + 200 OK + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-Happypath.plantuml b/docs/fr/product/features/Interscheme/Interscheme-Happypath.plantuml new file mode 100644 index 000000000..eaed780da --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Happypath.plantuml @@ -0,0 +1,106 @@ +@startuml Interscheme-Happypath + +title Inter-schéma — schéma général + +participant "DFSP payeur" as payerDFSP +box "Schéma A" #LightBlue + participant "Gestionnaire\nSchéma A" as schemeA + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box "Schéma B" #d1e0c3 + participant "Gestionnaire\nSchéma B" as schemeB + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +== Phase POST == +payerDFSP ->> schemeA: POST /xxx +note left +en-tête + source : payerDFSP + destination : payeeDFSP +corps + {ID: 1234} +end note +schemeA-->>payerDFSP: réponse HTTP 202 +schemeA -> pc_A: Destination hors schéma :\n payeeDFSP a un proxy mappé\n envoyer vers « Proxy AB » +schemeA ->> xnp: POST /xxx +xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note +xnp ->> schemeB: POST /xxx +note left +Message transmis à schéma B sans modification +end note + +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK + +schemeB ->> payeeDFSP: POST /xxx +payeeDFSP-->>schemeB: réponse HTTP 202 + +== Phase GET == +payerDFSP -> schemeA: GET /xxx/{ID} \nsans destination +note left + source : payerDFSP +end note +schemeA-->>payerDFSP: réponse HTTP 202 + +schemeA->schemeA: recherche du résultat par ID et déclenchement du PUT + +payerDFSP -> schemeA: GET /xxx/{ID} \navec destination +note left + source : payerDFSP + destination : payeeDFSP +end note +schemeA-->>payerDFSP: réponse HTTP 202 + +schemeA -> pc_A: Destination hors schéma :\n payeeDFSP a un proxy mappé\n envoyer vers « Proxy AB » +schemeA ->> xnp: GET /xxx +xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note +xnp ->> schemeB: GET /xxx +note left +Message transmis à schéma B sans modification +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK + +schemeB ->> payeeDFSP: GET /xxx +payeeDFSP-->>schemeB: réponse HTTP 202 + + + +== Phase PUT == + + +payeeDFSP -> schemeB: PUT /xxx +note right + source: payeeDFSP + destination: payerDFSP +end note +schemeB-->>payeeDFSP: réponse HTTP 200 + +schemeB -> pc_B: Destination hors schéma :\n payerDFSP a un proxy mappé\n envoyer vers « Proxy AB » +schemeB -> xnp: PUT /xxx +xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note +xnp -> schemeA: PUT /xxx +note right +Message transmis à schéma A sans modification +end note +schemeA -->> xnp: 200 OK +xnp -->> schemeB: 200 OK + +schemeA -> payerDFSP: PUT /xxx +payerDFSP-->>schemeA: réponse HTTP 200 + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-Happypath.svg b/docs/fr/product/features/Interscheme/Interscheme-Happypath.svg new file mode 100644 index 000000000..0b2218090 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Happypath.svg @@ -0,0 +1,273 @@ + + Inter-schéma — schéma général + + + Inter-schéma — schéma général + + Schéma A + + Schéma B + + + + + + + + + DFSP payeur + + DFSP payeur + + Gestionnaire + Schéma A + + Gestionnaire + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + Gestionnaire + Schéma B + + Gestionnaire + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + + Phase POST + + + + [1] + POST /xxx + + + en-tête + source : payerDFSP + destination : payeeDFSP + corps + {ID: 1234} + + + + [2] + réponse HTTP 202 + + + [3] + Destination hors schéma : + payeeDFSP a un proxy mappé + envoyer vers « Proxy AB » + + + + [4] + POST /xxx + + + + + [5] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [6] + POST /xxx + + + Message transmis à schéma B sans modification + + + + [7] + 202 OK + + + + [8] + 202 OK + + + + [9] + POST /xxx + + + + [10] + réponse HTTP 202 + + + + + Phase GET + + + [11] + GET /xxx/{ID} + sans destination + + + source : payerDFSP + + + + [12] + réponse HTTP 202 + + + + + [13] + recherche du résultat par ID et déclenchement du PUT + + + [14] + GET /xxx/{ID} + avec destination + + + source : payerDFSP + destination : payeeDFSP + + + + [15] + réponse HTTP 202 + + + [16] + Destination hors schéma : + payeeDFSP a un proxy mappé + envoyer vers « Proxy AB » + + + + [17] + GET /xxx + + + + + [18] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [19] + GET /xxx + + + Message transmis à schéma B sans modification + + + + [20] + 202 OK + + + + [21] + 202 OK + + + + [22] + GET /xxx + + + + [23] + réponse HTTP 202 + + + + + Phase PUT + + + [24] + PUT /xxx + + + source: payeeDFSP + destination: payerDFSP + + + + [25] + réponse HTTP 200 + + + [26] + Destination hors schéma : + payerDFSP a un proxy mappé + envoyer vers « Proxy AB » + + + [27] + PUT /xxx + + + + + [28] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + [29] + PUT /xxx + + + Message transmis à schéma A sans modification + + + + [30] + 200 OK + + + + [31] + 200 OK + + + [32] + PUT /xxx + + + + [33] + réponse HTTP 200 + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml b/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml new file mode 100644 index 000000000..cd3bc25c6 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml @@ -0,0 +1,140 @@ +@startuml Interscheme-OnDemandDiscovery + +title Inter-schéma — découverte à la demande + +participant "DFSP payeur" as payerDFSP +box "Schéma A" #LightBlue + participant "ALS\nSchéma A" as ALS_A + participant "Cache proxy\nSchéma A" as pc_A + participant "Oracle\nSchéma A" as Oracle_A +end box +participant "autres proxys" as dfspsA +participant "Proxy AB" as xnp +box "Schéma B" #d1e0c3 + participant "ALS\nSchéma B" as ALS_B + participant "Cache proxy\nSchéma B" as pc_B + participant "Oracle\nSchéma B" as Oracle_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> ALS_A: GET /parties/{Type}/{ID} +note left + en-tête source = payerDFSP +end note +ALS_A -->> payerDFSP: 202 OK +ALS_A-> Oracle_A: GET /participant/{ID} +alt si introuvable dans Oracle + +Oracle_A--> ALS_A: aucun dfsp trouvé +ALS_A ->> ALS_A: Y a-t-il des proxys\n dans le schéma A ? + ALS_A ->> ALS_A: Mettre en cache les proxys\nqui recevront les messages + note left + SentToProxies[{ID}] = + {['Proxy AB', 'Proxy CD', 'Proxy EF']} + end note + + loop pour chaque proxy du schéma A (hors source) + alt si Proxy AB + ALS_A ->> xnp: GET /parties/{Type}/{ID} + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_B: GET /parties/{Type}/{ID} + ALS_B -->> xnp: 202 OK + xnp -->> ALS_A: 202 OK + ALS_B -> pc_B: Source hors schéma : \nfxpiop-proxy = "Proxy AB"\nAjouter « DFSP payeur » au\nmappage « Proxy AB » + pc_B -> pc_B: Ajouter un nouveau mappage\nau cache + note left + DFSP payeur : Proxy AB + end note + + ALS_B-> Oracle_B: GET /participant/{ID} + Oracle_B--> ALS_B: dfsp = payeeDFSP + ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID} + payeeDFSP -->> ALS_B: 202 OK + payeeDFSP ->> ALS_B: PUT /parties/{ID} + note right + en-tête destination = payerDFSP + source = payeeDFSP + end note + ALS_B -->> payeeDFSP: 200 OK + ALS_B -> pc_B: Recherche du proxy payerDFSP + ALS_B ->> xnp: PUT /parties/{ID} + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_A: PUT /parties/{ID} + ALS_A -->> xnp: 200 OK + xnp -->> ALS_B: 200 OK + ALS_A -> pc_A: Source hors schéma : \nfxpiop-proxy = "Proxy AB"\nAjouter « DFSP bénéficiaire » au\nmappage « Proxy AB » + pc_A -> pc_A: Nouveau mappage\nVérifier la signature JWS\net ajouter au cache + note left + DFSP bénéficiaire : Proxy AB + end note + ALS_A -> Oracle_A: Mettre à jour Oracle avec le mappage\n**POST /participants/{Type}/{ID}** \n{{"fspId": "DFSP bénéficiaire"}} + Oracle_A--> ALS_A: retour + ALS_A ->> payerDFSP: PUT /parties/{ID} + payerDFSP -->> ALS_A: 200 OK + else si autre proxy dans le schéma A + ALS_A ->> dfspsA: GET /parties/{Type}/{ID} + dfspsA -->> ALS_A: 202 OK + dfspsA ->> ALS_A: PUT /parties/{ID}/error + ALS_A -->> dfspsA: 200 OK + ALS_A ->> ALS_A: Marquer le message comme\nreçu du proxy + note left + retirer l'autre proxy de + liste SentToProxies[{ID}] + end note + + alt si SentToProxies[{ID}] est vide + ALS_A ->> payerDFSP: PUT /parties/{ID}/error + note right + SentToProxies[{ID}] est vide + end note + payerDFSP -->> ALS_A: 200 OK + end + end +end loop +else si trouvé dans Oracle + Oracle_A--> ALS_A: dfsp = payeeDFSP + + ALS_A->ALS_A: Le DFSP bénéficiaire n'est\npas dans le schéma A + ALS_A-> pc_A: Recherche du proxy pour\nle DFSP bénéficiaire + alt si la source de l'en-tête est membre du schéma A + ALS_A->ALS_A: Ajouter la destination à l'en-tête + note left + dfsp destination : DFSP bénéficiaire + end note + + ALS_A ->> xnp: GET /parties/{Type}/{ID} + xnp ->> ALS_B: GET /parties/{Type}/{ID} + ALS_B -->> xnp: 202 OK + xnp -->> ALS_A: 202 OK + end + ALS_B->ALS_B: Transférer vers la destination + ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID} + payeeDFSP -->> ALS_B: 202 OK + payeeDFSP ->> ALS_B: PUT /parties/{ID} + note right + en-tête destination = payerDFSP + end note + ALS_B -->> payeeDFSP: 200 OK + ALS_B -> pc_B: Recherche du proxy payerDFSP + ALS_B ->> xnp: PUT /parties/{ID} + xnp ->> ALS_A: PUT /parties/{ID} + ALS_A -->> xnp: 200 OK + xnp -->> ALS_B: 200 OK + ALS_A -> pc_A: Source hors schéma : \nAjouter « DFSP bénéficiaire » au\nmappage « Proxy AB » + pc_A -> pc_A: Mappage obtenu + ALS_A ->> payerDFSP: PUT /parties/{ID} + payerDFSP -->> ALS_A: 200 OK +end + + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg b/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg new file mode 100644 index 000000000..d725826b2 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg @@ -0,0 +1,458 @@ + + Inter-schéma — découverte à la demande + + + Inter-schéma — découverte à la demande + + Schéma A + + Schéma B + + + + + + + + + + + + + + + + + DFSP payeur + + DFSP payeur + + ALS + Schéma A + + ALS + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Oracle + Schéma A + + Oracle + Schéma A + + autres proxys + + autres proxys + + Proxy AB + + Proxy AB + + ALS + Schéma B + + ALS + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + Oracle + Schéma B + + Oracle + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + [1] + GET /parties/{Type}/{ID} + + + en-tête source = payerDFSP + + + + [2] + 202 OK + + + [3] + GET /participant/{ID} + + + alt + [si introuvable dans Oracle] + + + [4] + aucun dfsp trouvé + + + + + + [5] + Y a-t-il des proxys + dans le schéma A ? + + + + + + [6] + Mettre en cache les proxys + qui recevront les messages + + + SentToProxies[{ID}] = + {['Proxy AB', 'Proxy CD', 'Proxy EF']} + + + loop + [pour chaque proxy du schéma A (hors source)] + + + alt + [si Proxy AB] + + + + [7] + GET /parties/{Type}/{ID} + + + + + [8] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [9] + GET /parties/{Type}/{ID} + + + + [10] + 202 OK + + + + [11] + 202 OK + + + [12] + Source hors schéma : + fxpiop-proxy = "Proxy AB" + Ajouter « DFSP payeur » au + mappage « Proxy AB » + + + + + [13] + Ajouter un nouveau mappage + au cache + + + DFSP payeur : Proxy AB + + + [14] + GET /participant/{ID} + + + [15] + dfsp = payeeDFSP + + + + [16] + GET /parties/{Type}/{ID} + + + + [17] + 202 OK + + + + [18] + PUT /parties/{ID} + + + en-tête destination = payerDFSP + source = payeeDFSP + + + + [19] + 200 OK + + + [20] + Recherche du proxy payerDFSP + + + + [21] + PUT /parties/{ID} + + + + + [22] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [23] + PUT /parties/{ID} + + + + [24] + 200 OK + + + + [25] + 200 OK + + + [26] + Source hors schéma : + fxpiop-proxy = "Proxy AB" + Ajouter « DFSP bénéficiaire » au + mappage « Proxy AB » + + + + + [27] + Nouveau mappage + Vérifier la signature JWS + et ajouter au cache + + + DFSP bénéficiaire : Proxy AB + + + [28] + Mettre à jour Oracle avec le mappage + POST /participants/{Type}/{ID} +   + {{"fspId": "DFSP bénéficiaire"}} + + + [29] + retour + + + + [30] + PUT /parties/{ID} + + + + [31] + 200 OK + + [si autre proxy dans le schéma A] + + + + [32] + GET /parties/{Type}/{ID} + + + + [33] + 202 OK + + + + [34] + PUT /parties/{ID}/error + + + + [35] + 200 OK + + + + + + [36] + Marquer le message comme + reçu du proxy + + + retirer l'autre proxy de + liste SentToProxies[{ID}] + + + alt + [si SentToProxies[{ID}] est vide] + + + + [37] + PUT /parties/{ID}/error + + + SentToProxies[{ID}] est vide + + + + [38] + 200 OK + + [si trouvé dans Oracle] + + + [39] + dfsp = payeeDFSP + + + + + [40] + Le DFSP bénéficiaire n'est + pas dans le schéma A + + + [41] + Recherche du proxy pour + le DFSP bénéficiaire + + + alt + [si la source de l'en-tête est membre du schéma A] + + + + + [42] + Ajouter la destination à l'en-tête + + + dfsp destination : DFSP bénéficiaire + + + + [43] + GET /parties/{Type}/{ID} + + + + [44] + GET /parties/{Type}/{ID} + + + + [45] + 202 OK + + + + [46] + 202 OK + + + + + [47] + Transférer vers la destination + + + + [48] + GET /parties/{Type}/{ID} + + + + [49] + 202 OK + + + + [50] + PUT /parties/{ID} + + + en-tête destination = payerDFSP + + + + [51] + 200 OK + + + [52] + Recherche du proxy payerDFSP + + + + [53] + PUT /parties/{ID} + + + + [54] + PUT /parties/{ID} + + + + [55] + 200 OK + + + + [56] + 200 OK + + + [57] + Source hors schéma : + Ajouter « DFSP bénéficiaire » au + mappage « Proxy AB » + + + + + [58] + Mappage obtenu + + + + [59] + PUT /parties/{ID} + + + + [60] + 200 OK + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml b/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml new file mode 100644 index 000000000..a503c3a98 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml @@ -0,0 +1,90 @@ +@startuml Interscheme-StalePartyIdentifierCache + +title Cache d'identifiants de partie obsolètes + +participant "DFSP payeur" as payerDFSP +box "Schéma A" #LightBlue + participant "ALS\nSchéma A" as ALS_A + participant "Oracle\nSchéma A" as Oracle_A + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box "Schéma B" #d1e0c3 + participant "ALS\nSchéma B" as ALS_B + participant "Oracle\nSchéma B" as Oracle_B + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> ALS_A: **GET** /parties/{Type}/{ID} +note left + en-tête source = payerDFSP +end note + + ALS_A-> Oracle_A: **GET** /participant/{ID} + Oracle_A--> ALS_A: DFSP trouvé = payeeDFSP + ALS_A ->> ALS_A: DFSP absent du schéma + ALS_A -> pc_A: Quel est le proxy du DFSP bénéficiaire ? + alt représentant du proxy introuvable + pc_A --> ALS_A: Proxy introuvable + ALS_A -> Oracle_A: Supprimer le mappage dans Oracle\n **DELETE** \participants\{Type}\{ID} + note left + **Autoréparation** si le proxy + de référence est introuvable + end note + ALS_A ->> ALS_A: Redémarrer le processus ALS get parties + else + pc_A --> ALS_A: transmettre vers Proxy AB + end + + ALS_A ->> xnp: **GET** /parties/{Type}/{ID} + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_B: **GET** /parties/{Type}/{ID} + ALS_B ->> pc_B: Source hors schéma : \nfxpiop-proxy = "Proxy AB"\nAjouter « DFSP payeur » au mappage « Proxy AB » +alt hors périmètre MVP + pc_B -> pc_B: Vérifier la signature JWS +end + pc_B -> pc_B: Ajouter un nouveau mappage au cache +note left +DFSP payeur : Proxy AB +end note +ALS_B-> Oracle_B: **GET** /participant/{ID} + Oracle_B--> ALS_B: dfsp = payeeDFSP + alt si le dfsp est membre du schéma B + ALS_B ->> payeeDFSP: **GET** /parties/{Type}/{ID} + payeeDFSP ->> ALS_B: **PUT** /parties/{ID}/error + note right + en-tête destination = payerDFSP + end note + end + ALS_B -> pc_B: Recherche du proxy payerDFSP + ALS_B ->> xnp: **PUT** /parties/{ID}/error + xnp->xnp: Ajouter l'en-tête + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> ALS_A: **PUT** /parties/{ID}/error + alt message du proxy et erreur et pas de cache de message proxy + note left ALS_A + **Autoréparation** en cas d'erreur de routage + fxpiop-proxy = "Proxy AB" + PUT /parties error + SentToProxies[{ID}] list undefined + end note + ALS_A -> Oracle_A: Supprimer le mappage dans Oracle\n **DELETE** \participants\{Type}\{ID} + ALS_A ->> payerDFSP: **PUT** /parties/{ID}/error + note right + {ErrorCode: "2003"} + (Service indisponible) + end note + else + ALS_A->>payerDFSP: **PUT** /parties/{ID}/error +end + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg b/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg new file mode 100644 index 000000000..37e3c97c4 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg @@ -0,0 +1,268 @@ + + Cache d'identifiants de partie obsolètes + + + Cache d'identifiants de partie obsolètes + + Schéma A + + Schéma B + + + + + + + + + + + + + + + DFSP payeur + + DFSP payeur + + ALS + Schéma A + + ALS + Schéma A + + Oracle + Schéma A + + Oracle + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + ALS + Schéma B + + ALS + Schéma B + + Oracle + Schéma B + + Oracle + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + [1] + GET + /parties/{Type}/{ID} + + + en-tête source = payerDFSP + + + [2] + GET + /participant/{ID} + + + [3] + DFSP trouvé = payeeDFSP + + + + + + [4] + DFSP absent du schéma + + + [5] + Quel est le proxy du DFSP bénéficiaire ? + + + alt + [représentant du proxy introuvable] + + + [6] + Proxy introuvable + + + [7] + Supprimer le mappage dans Oracle +   + DELETE + \participants\{Type}\{ID} + + + Autoréparation + si le proxy + de référence est introuvable + + + + + + [8] + Redémarrer le processus ALS get parties + + + + [9] + transmettre vers Proxy AB + + + + [10] + GET + /parties/{Type}/{ID} + + + + + [11] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [12] + GET + /parties/{Type}/{ID} + + + + [13] + Source hors schéma : + fxpiop-proxy = "Proxy AB" + Ajouter « DFSP payeur » au mappage « Proxy AB » + + + alt + [hors périmètre MVP] + + + + + [14] + Vérifier la signature JWS + + + + + [15] + Ajouter un nouveau mappage au cache + + + DFSP payeur : Proxy AB + + + [16] + GET + /participant/{ID} + + + [17] + dfsp = payeeDFSP + + + alt + [si le dfsp est membre du schéma B] + + + + [18] + GET + /parties/{Type}/{ID} + + + + [19] + PUT + /parties/{ID}/error + + + en-tête destination = payerDFSP + + + [20] + Recherche du proxy payerDFSP + + + + [21] + PUT + /parties/{ID}/error + + + + + [22] + Ajouter l'en-tête + + + fxpiop-proxy = "Proxy AB" + + + + [23] + PUT + /parties/{ID}/error + + + alt + [message du proxy et erreur et pas de cache de message proxy] + + + Autoréparation + en cas d'erreur de routage + fxpiop-proxy = "Proxy AB" + PUT /parties error + SentToProxies[{ID}] list undefined + + + [24] + Supprimer le mappage dans Oracle +   + DELETE + \participants\{Type}\{ID} + + + + [25] + PUT + /parties/{ID}/error + + + {ErrorCode: "2003"} + (Service indisponible) + + + + + [26] + PUT + /parties/{ID}/error + + diff --git a/docs/fr/product/features/Interscheme/Interscheme-Transfer.plantuml b/docs/fr/product/features/Interscheme/Interscheme-Transfer.plantuml new file mode 100644 index 000000000..6878fa4ad --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Transfer.plantuml @@ -0,0 +1,80 @@ +@startuml Interscheme-Transfer + +title Inter-schéma — transfert + +participant "DFSP payeur" as payerDFSP +box Schéma A #LightBlue + participant "Mojaloop\nSchéma A" as schemeA + participant "Cache proxy\nSchéma A" as pc_A +end box +participant "Proxy AB" as xnp +box Schéma B #d1e0c3 + participant "Mojaloop\nSchéma B" as schemeB + participant "Cache proxy\nSchéma B" as pc_B +end box +participant "DFSP bénéficiaire" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: POST /transfers +note left +en-tête + source : payerDFSP + destination : payeeDFSP +JWS signé par payerDFSP +corps + transferId: 1234 +end note +schemeA -->> payerDFSP: 202 OK +schemeA -> schemeA: DFSP payeur\n - Contrôle des limites\n - Mise à jour de la position +schemeA -> pc_A: Destination hors schéma\nRecherche du proxy pour payeeDFSP = Proxy AB +schemeA ->> xnp: POST /transfers +xnp ->> schemeB: POST /transfers +note left +en-tête + source : payerDFSP + destination : payeeDFSP + fxpiop-proxy: proxyAB +JWS signé par payerDFSP +corps + transferId: 1234 +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK +schemeA -> schemeA: Désactiver le délai d'expiration + +schemeB -> schemeB: Proxy AB\n **- Pas de contrôle de limite**\n - Mise à jour de la position +schemeB->>payeeDFSP: POST /transfers +note right +Vérifie le JWS signé par payerDFSP +end note +payeeDFSP->>schemeB: PUT /transfers \n{fulfilment: "xyz", transferState: "RESERVED"} +note right +en-tête + source : payeeDFSP + destination : payerDFSP +JWS signé par payeeDFSP +end note +schemeB -> schemeB: DFSP payeur\n - Mise à jour de la position +schemeB -> pc_B: Recherche du proxy pour payerDFSP = Proxy AB +schemeB->>xnp: PUT /transfers +xnp->>schemeA: PUT /transfers +note right +en-tête + source : payeeDFSP + destination : payerDFSP + fxpiop-proxy: proxyAB +JWS signé par payeeDFSP +end note +schemeA-->>xnp: 200 OK +xnp-->>schemeB: 200 OK +schemeB->>payeeDFSP: PATCH /transfers \n{transferState: "COMMITTED"} +payeeDFSP-->>schemeB: 200 OK +schemeA -> schemeA: Proxy NX\n - Mise à jour de la position +schemeA->>payerDFSP: PUT /transfers +note left +Vérifie le JWS signé par payeeDFSP +end note +payerDFSP -->> schemeA: 200 OK + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/Interscheme-Transfer.svg b/docs/fr/product/features/Interscheme/Interscheme-Transfer.svg new file mode 100644 index 000000000..a6608f2f5 --- /dev/null +++ b/docs/fr/product/features/Interscheme/Interscheme-Transfer.svg @@ -0,0 +1,218 @@ + + Inter-schéma — transfert + + + Inter-schéma — transfert + + Schéma A + + Schéma B + + + + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + Schéma A + + Mojaloop + Schéma A + + Cache proxy + Schéma A + + Cache proxy + Schéma A + + Proxy AB + + Proxy AB + + Mojaloop + Schéma B + + Mojaloop + Schéma B + + Cache proxy + Schéma B + + Cache proxy + Schéma B + + DFSP bénéficiaire + + DFSP bénéficiaire + + + + [1] + POST /transfers + + + en-tête + source : payerDFSP + destination : payeeDFSP + JWS signé par payerDFSP + corps + transferId: 1234 + + + + [2] + 202 OK + + + + + [3] + DFSP payeur + - Contrôle des limites + - Mise à jour de la position + + + [4] + Destination hors schéma + Recherche du proxy pour payeeDFSP = Proxy AB + + + + [5] + POST /transfers + + + + [6] + POST /transfers + + + en-tête + source : payerDFSP + destination : payeeDFSP + fxpiop-proxy: proxyAB + JWS signé par payerDFSP + corps + transferId: 1234 + + + + [7] + 202 OK + + + + [8] + 202 OK + + + + + [9] + Désactiver le délai d'expiration + + + + + [10] + Proxy AB +   + - Pas de contrôle de limite + - Mise à jour de la position + + + + [11] + POST /transfers + + + Vérifie le JWS signé par payerDFSP + + + + [12] + PUT /transfers + {fulfilment: "xyz", transferState: "RESERVED"} + + + en-tête + source : payeeDFSP + destination : payerDFSP + JWS signé par payeeDFSP + + + + + [13] + DFSP payeur + - Mise à jour de la position + + + [14] + Recherche du proxy pour payerDFSP = Proxy AB + + + + [15] + PUT /transfers + + + + [16] + PUT /transfers + + + en-tête + source : payeeDFSP + destination : payerDFSP + fxpiop-proxy: proxyAB + JWS signé par payeeDFSP + + + + [17] + 200 OK + + + + [18] + 200 OK + + + + [19] + PATCH /transfers + {transferState: "COMMITTED"} + + + + [20] + 200 OK + + + + + [21] + Proxy NX + - Mise à jour de la position + + + + [22] + PUT /transfers + + + Vérifie le JWS signé par payeeDFSP + + + + [23] + 200 OK + + diff --git a/docs/fr/product/features/Interscheme/InterschemeAccounts-Clearing.png b/docs/fr/product/features/Interscheme/InterschemeAccounts-Clearing.png new file mode 100644 index 000000000..a219b4c67 Binary files /dev/null and b/docs/fr/product/features/Interscheme/InterschemeAccounts-Clearing.png differ diff --git a/docs/fr/product/features/Interscheme/SettingUpProxys.plantuml b/docs/fr/product/features/Interscheme/SettingUpProxys.plantuml new file mode 100644 index 000000000..d19ab0936 --- /dev/null +++ b/docs/fr/product/features/Interscheme/SettingUpProxys.plantuml @@ -0,0 +1,31 @@ +@startuml SettingUpProxys +title API du grand livre central / API d'administration + +participant "Script d'intégration" as script +participant "Mojaloop\nSchéma A" as schemeA +participant "Proxy XN" as xnp +participant "Mojaloop\nSchéma B" as schemeB + +autonumber 1 "[0]" + +== Création des types de participants == + +script -> schemeA: POST /participants +note left +{ + "name": "XN Proxy", + "currency": "USD", + "isProxy": true +} +end note + +script -> schemeB: POST /participants +note left +{ + "name": "XN Proxy", + "currency": "USD", + "isProxy": true +} +end note + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Interscheme/SettingUpProxys.svg b/docs/fr/product/features/Interscheme/SettingUpProxys.svg new file mode 100644 index 000000000..567d67523 --- /dev/null +++ b/docs/fr/product/features/Interscheme/SettingUpProxys.svg @@ -0,0 +1,60 @@ + + API du grand livre central / API d'administration + + + API du grand livre central / API d'administration + + + + + + Script d'intégration + + Script d'intégration + + Mojaloop + Schéma A + + Mojaloop + Schéma A + + Proxy XN + + Proxy XN + + Mojaloop + Schéma B + + Mojaloop + Schéma B + + + + + Création des types de participants + + + [1] + POST /participants + + + { + "name": "XN Proxy", + "currency": "USD", +    + "isProxy": true + } + + + [2] + POST /participants + + + { + "name": "XN Proxy", + "currency": "USD", +    + "isProxy": true + } + + diff --git a/docs/fr/product/features/Iso20022/v1.0/Appendix.md b/docs/fr/product/features/Iso20022/v1.0/Appendix.md new file mode 100644 index 000000000..561cf3a4b --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/Appendix.md @@ -0,0 +1,54 @@ +--- +sidebarTitle: Annexe ISO 20022 +--- + +# 8. Annexe A : codes de type d’identifiant de paiement +## 8.1 Types d’identifiant FSPIOP +|Code|Description| +| -- | -- | +|MSISDN|Un MSISDN (*Mobile Station International Subscriber Directory Number*, c’est-à-dire le numéro de téléphone) sert de référence à un participant. Le MSISDN doit être au format international selon la norme UIT-T E.164. Optionnellement, le MSISDN peut être préfixé d’un seul signe plus, indiquant le préfixe international.| +|EMAIL|Une adresse e-mail sert de référence à un participant. Le format doit suivre la RFC 3696 (informatif).| +|PERSONAL_ID|Un identifiant personnel sert de référence à un participant. Exemples : numéro de passeport, d’acte de naissance, d’enregistrement national. Le numéro figure dans l’élément PartyIdentifier ; le type d’identifiant personnel dans PartySubIdOrType.| +|BUSINESS|Une entité commerciale précise (organisation, entreprise, etc.) sert de référence. L’identifiant BUSINESS peut prendre tout format. Pour lier une transaction à un nom d’utilisateur ou un numéro de facture dans une entreprise, utiliser PartySubIdOrType.| +|DEVICE|Un identifiant d’appareil (terminal de paiement, GAB, etc.) rattaché à une entreprise ou organisation sert de référence à une partie. Pour un appareil sous une entreprise ou organisation donnée, utiliser PartySubIdOrType.| +|ACCOUNT_ID|Un numéro de compte bancaire ou identifiant de compte FSP sert de référence. L’identifiant ACCOUNT_ID peut prendre tout format selon pays et FSP.| +|IBAN|Un numéro de compte ou identifiant FSP sert de référence. L’IBAN comporte jusqu’à 34 caractères alphanumériques, sans espace.| +|ALIAS|Un alias sert de référence à un participant. L’alias est créé chez le FSP comme référence alternative au titulaire du compte ; un autre exemple est un nom d’utilisateur dans le système FSP. L’identifiant ALIAS peut prendre tout format ; PartySubIdOrType peut identifier un compte sous un alias défini par PartyIdentifier.| + + +## 8.2 Table des codes d’identifiant personnel +Ces types ne sont pas encore pris en charge. + +|Code|Description| +| -- | -- | +|ARNU|AlienRegistrationNumber| +|CCPT|PassportNumber| +|CUST|CustomerIdentificationNumber| +|DRLC|DriversLicenseNumber| +|EMPL|EmployeeIdentificationNumber| +|NIDN|NationalIdentityNumber| +|SOSE|SocialSecurityNumber| +|TELE|TelephoneNumber| +|TXID|TaxIdentificationNumber| +|POID|PersonCommercialIdentification| + + +## 8.3 Table des codes d’identifiant d’organisation +Ces types ne sont pas encore pris en charge. + +|Code|Description +| -- | -- | +|BANK|BankPartyIdentification| +|CBID|CentralBankIdentificationNumber| +|CHID|ClearingIdentificationNumber| +|CINC|CertificateOfIncorporationNumber| +|COID|CountryIdentificationCode| +|CUST|CustomerNumber| +|DUNS|DataUniversalNumberingSystem| +|EMPL|EmployerIdentificationNumber| +|GS1G|GS1GLNIdentifier| +|SREN|SIREN| +|SRET|SIRET| +|TXID|TaxIdentificationNumber| +|BDID|BusinessDomainIdentifier| +|BOID|BusinessOtherIdentification| diff --git a/assets/.gitkeep b/docs/fr/product/features/Iso20022/v1.0/IntegrationPatterns.md similarity index 100% rename from assets/.gitkeep rename to docs/fr/product/features/Iso20022/v1.0/IntegrationPatterns.md diff --git a/docs/fr/product/features/Iso20022/v1.0/MarketPracticeDocument.md b/docs/fr/product/features/Iso20022/v1.0/MarketPracticeDocument.md new file mode 100644 index 000000000..630e844dc --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/MarketPracticeDocument.md @@ -0,0 +1,240 @@ +--- +sidebarTitle: MPD ISO 20022 v1.0 +--- + +# v1.0 : document de pratique de marché ISO 20022 Mojaloop + + + +- [2. Introduction](#_2-introduction) + - [2.1. How to Use This Document?](#_2-1-comment-utiliser-ce-document) + - [2.1.1. Relationship with Scheme-Specific Rules Documents](#_2-1-1-lien-avec-les-documents-de-regles-propres-au-schema) + - [2.1.2. Distinction Between Generic Practices and Scheme-Specific Requirements](#_2-1-2-distinction-entre-pratiques-generiques-et-exigences-propres-au-schema) +- [3. Message Expectations, Obligations, and Rules](#_3-attentes-obligations-et-regles-applicables-aux-messages) + - [3.1. Currency Conversion](#_3-1-conversion-de-devises) + - [3.2. JSON Messages](#_3-2-messages-json) + - [3.3. APIs](#_3-3-api) + - [3.3.1. Header Details](#_3-3-1-details-des-en-tetes) + - [3.3.2. Supported HTTP Responses](#_3-3-2-reponses-http-prises-en-charge) + - [3.3.3. Common Error Payload](#_3-3-3-charge-utile-d-erreur-commune) + - [3.4. ULIDs as Unique Identifiers](#_3-4-ulid-comme-identifiants-uniques) + - [3.5. Inter-ledger Protocol v4 to represent the Cryptographic Terms](#_3-5-protocole-interledger-v4-pour-les-termes-cryptographiques) + - [3.6. ISO 20022 Supplementary Data Fields](#_3-6-champs-de-donnees-supplementaires-iso-20022) +- [4. Discovery Phase](#_4-phase-de-decouverte) + - [4.1. Message flow](#_4-1-flux-de-messages) + - [4.2. Parties Resource](#_4-2-ressource-parties) +- [5. Agreement Phase](#_5-phase-d-accord) + - [5.1. Currency Conversion Agreement Sub-Phase](#_5-1-sous-phase-d-accord-sur-la-conversion-de-devises) + - [5.1.1. Message flow](#_5-1-1-flux-de-messages) + - [5.1.2. fxQuotes Resource](#_5-1-2-ressource-fxquotes) + - [5.2. Transfer Terms Agreement Sub-Phase](#_5-2-sous-phase-d-accord-sur-les-conditions-de-transfert) + - [5.2.1. Message flow](#_5-2-1-flux-de-messages) + - [5.2.2. Quotes Resource](#_5-2-2-ressource-quotes) +- [6. Transfer Phase](#_6-phase-de-transfert) + - [6.1. Accepting Currency Conversion terms](#_6-1-acceptation-des-conditions-de-conversion-de-devises) + - [6.1.1. Message flow](#_6-1-1-flux-de-messages) + - [6.1.2. fxTransfers Resource](#_6-1-2-ressource-fxtransfers) + - [6.2. Transfer Execution and Clearing](#_6-2-execution-et-compensation-du-transfert) + - [6.2.1. Message flow](#_6-2-1-flux-de-messages) + - [6.2.2. Transfers Resource](#_6-2-2-ressource-transfers) + + +# 2. Introduction + +En combinant les principes d’inclusion financière et les capacités d’ISO 20022, Mojaloop permet aux DFSP et autres parties prenantes de proposer des paiements en temps réel, économiques, sécurisés et évolutifs pour les écosystèmes financiers inclusifs. Ce document est la version 1.0 de la pratique de marché Mojaloop ISO 20022. + +## 2.1 Comment utiliser ce document ? +Ce document constitue une référence de base pour mettre en œuvre la messagerie ISO 20022 pour les SIIP dans les schémas basés sur Mojaloop. Il décrit des lignes directrices et pratiques générales communes à tous les schémas Mojaloop, centrées sur les exigences de base. Il doit toutefois être complété par des documents de règles propres au schéma, pouvant définir des champs de message, validations et règles supplémentaires pour répondre aux réglementations et besoins spécifiques. Cette approche par couches permet d’adapter les détails d’implémentation tout en restant aligné sur le cadre Mojaloop. + +### 2.1.1 Lien avec les documents de règles propres au schéma +Ce document pose les fondations de l’application d’ISO 20022 dans Mojaloop (principes et pratiques cœur). Il ne prescrit pas les exigences métier détaillées, validations et cadres de gouvernance propres à chaque schéma. Les règles de schéma couvrent ces aspects : champs obligatoires et facultatifs, protocoles de conformité sur mesure, procédures de gestion des erreurs, règles métier sur les flux de messages, rôles et responsabilités des participants. La flexibilité du présent document permet aux administrateurs de schéma d’adapter et d’étendre les orientations selon leurs besoins opérationnels. + +### 2.1.2 Distinction entre pratiques génériques et exigences propres au schéma +Le document sépare clairement pratiques génériques et exigences de schéma pour concilier cohérence et adaptabilité des implémentations ISO 20022 dans Mojaloop. Les pratiques génériques établissent les principes fondateurs : attentes sur les structures de messages, champs requis pour le switch, champs supportés et flux transactionnels, ainsi qu’une vue d’ensemble du cycle de vie d’un transfert P2P avec change Mojaloop. + +Les exigences propres au schéma, documentées séparément, détaillent mappages de champs supplémentaires, validations renforcées et règles précises de règlement, rapprochement et résolution de litiges, ainsi que politiques de gouvernance et obligations de conformité. + +Cette distinction permet aux DFSP d’implémenter un noyau de messagerie cohérent tout en laissant aux administrateurs de schéma la flexibilité sur les détails opérationnels. Les pratiques génériques sont conçues pour être extensibles et s’intégrer aux règles de schéma, conformément aux standards Mojaloop ISO 20022 pour les SIIP. + +# 3 Attentes, obligations et règles applicables aux messages +Le processus de transfert Mojaloop comporte trois phases clés pour des transactions sûres et efficaces. Chaque phase s’appuie sur des ressources spécifiques pour les interactions entre participants, assurant communication, accord et exécution. Certaines phases et ressources sont facultatives ; l’objectif reste que chaque transfert soit exact, sécurisé et conforme aux conditions convenues. +1. [Découverte](#_4-phase-de-decouverte) +2. [Accord](#_5-phase-d-accord) +3. [Transfert](#_6-phase-de-transfert) + +## 3.1 Conversion de devises +La conversion de devises prend en charge les transactions multi-devises. Comme elle n’est pas toujours nécessaire, les messages et flux associés ne sont utilisés qu’en cas de besoin, pour la flexibilité mono- ou multi-devises. + +## 3.2 Messages JSON +Mojaloop adopte une variante JSON des messages ISO 20022 plutôt que le XML traditionnel, pour l’efficacité et la compatibilité avec les API modernes. L’organisation ISO 20022 développe une représentation JSON canonique ; Mojaloop entend s’y aligner à mesure de son évolution. + +## 3.3 API +Les messages ISO 20022 sont échangés dans Mojaloop via des appels de type REST. Cela favorise l’interopérabilité, réduit le volume de données grâce au JSON léger et soutient des implémentations modulaires et évolutives. L’intégration d’ISO 20022 avec des API REST offre un cadre robuste et adaptable, entre normes mondiales et contraintes de mise en œuvre. + +### 3.3.1 Détails des en-têtes +L’en-tête du message API doit contenir les éléments suivants. Les en-têtes obligatoires sont marqués d’un astérisque `*`. + +| Nom                                | Description | +|--|--| +|**Content-Length**
*integer*
(header)|The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body.**Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes).| +| * **Type**
*string*
(path)|The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`.| +| * **ID**
*string*
(path)| The identifier value.| +| * **Content-Type**
*string*
(header)|The `Content-Type` header indicates the specific version of the API used to send the payload body.| +| * **Date**
*string*
(header)|The `Date` header field indicates the date when the request was sent.| +| **X-Forwarded-For**
*string*
(header)|The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API.**Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`.| +| * **FSPIOP-Source**
*string*
(header)|The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`).| +| **FSPIOP-Destination**
*string*
(header)|The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.| +| **FSPIOP-Encryption**
*string*
(header) | The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request.| +| **FSPIOP-Signature**
*string*
(header)| The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature.| +| **FSPIOP-URI**
*string*
(header) | The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://docs.mojaloop.io/technical/api/fspiop/).| +| **FSPIOP-HTTP-Method**
*string*
(header) | The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://docs.mojaloop.io/technical/api/fspiop/).| + +### 3.3.2 Réponses HTTP prises en charge + +| **Code d’erreur HTTP** | **Description et causes fréquentes** | +|---|----| +|**400 Bad Request** | **Description** : le serveur n’a pas pu interpréter la requête (syntaxe invalide). La requête est mal formée ou contient des paramètres invalides.
**Causes fréquentes** : champs obligatoires manquants, valeurs invalides, format incorrect. | +|**401 Unauthorized** | **Description** : le client doit s’authentifier. La requête ne comporte pas d’identifiants valides.
**Causes fréquentes** : jeton d’authentification manquant ou invalide. | +|**403 Forbidden** | **Description** : le client n’a pas les droits d’accès. Le serveur a compris la requête mais refuse de l’autoriser.
**Causes fréquentes** : permissions insuffisantes sur la ressource. | +|**404 Not Found** | **Description** : la ressource demandée est introuvable.
**Causes fréquentes** : identifiant incorrect ou ressource supprimée. | +|**405 Method Not Allowed** | **Description** : la méthode HTTP n’est pas autorisée pour cette ressource.
**Causes fréquentes** : méthode non supportée (ex. POST au lieu de PUT). | +|**406 Not Acceptable** | **Description** : le serveur ne peut pas produire une réponse acceptable selon les en-têtes de négociation (Accept, etc.).
**Causes fréquentes** : type ou format média non supporté dans Accept. | +|**501 Not Implemented** | **Description** : le serveur ne prend pas en charge la fonctionnalité requise.
**Causes fréquentes** : fonctionnalité non implémentée. | +|**503 Service Unavailable** | **Description** : le serveur ne peut pas traiter la requête temporairement (maintenance ou surcharge).
**Causes fréquentes** : maintenance, surcharge ou indisponibilité. | + +### 3.3.3 Charge utile d’erreur commune + +Toutes les réponses d’erreur renvoient une structure commune incluant un message explicite. La charge contient en général : + +- **errorCode** : code de l’erreur. +- **errorDescription** : description de l’erreur. +- **extensionList** : liste facultative de paires clé-valeur avec des informations complémentaires. + +Cette charge aide les clients à comprendre l’erreur et à réagir de façon appropriée. + + + +## 3.4 ULID comme identifiants uniques +Mojaloop utilise des identifiants uniques lexicographiquement triables (ULID) comme standard d’identifiants dans sa messagerie. Les ULID constituent une alternative solide aux UUID, avec unicité globale et ordre naturel par date de création, ce qui facilite traçabilité, diagnostic et analyses opérationnelles. + +## 3.5 Protocole Interledger (v4) pour les termes cryptographiques +Mojaloop s’appuie sur ILP version 4 pour définir et représenter les termes cryptographiques dans les transferts. ILP v4 offre un cadre normalisé pour l’échange sécurisé et interopérable d’instructions de paiement, avec intégrité et non-répudiation. L’intégration des capacités cryptographiques d’ILP permet des accords précis et inviolables entre participants et l’exécution sécurisée de transferts de bout en bout, tout en restant compatible avec les écosystèmes de paiement mondiaux. + +## 3.6 Champs de données supplémentaires ISO 20022 + +Aucun message utilisé ne devrait exiger de champs de données supplémentaires ISO 20022. Si des données supplémentaires sont fournies, le switch ne rejette pas le message mais ignore leur contenu, comme si elles étaient absentes. + +
+ +# 4. Phase de découverte +La phase de découverte est une étape facultative du transfert, nécessaire uniquement lorsque le bénéficiaire (partie finale) doit être identifié et confirmé avant d’engager un accord. Elle s’appuie sur la ressource *parties*, qui permet d’obtenir et de valider les informations du bénéficiaire pour vérifier son éligibilité au transfert. Les contrôles clés incluent : compte actif, devises pouvant être créditées sur le compte, détails du titulaire. Le payeur peut ainsi vérifier les informations du bénéficiaire, limiter les erreurs et sécuriser les phases suivantes. + +## 4.1 Flux de messages + +Le diagramme de séquence illustre des messages d’exemple de découverte pour un transfert P2P initié par le payeur. +![Discovery Flow](./SequenceDiagrams/Discovery.svg) + +## 4.2 Ressource Parties +La ressource Parties regroupe les fonctions nécessaires à la phase de découverte. Le flux démarre toujours par un appel GET /parties ; les réponses sont renvoyées à l’initiateur via le rappel PUT /parties. Les erreurs passent par PUT /parties/.../error. Ces points de terminaition prennent en charge un type de sous-identifiant facultatif. + + +| Point de terminaison | Message | +|--- | --- | +|[GET /parties/{type}/{partyIdentifier}[/{subId}]](./script/parties_GET.md) | | +|[PUT /parties/{type}/{partyIdentifier}[/{subId}]](./script/parties_PUT.md) | acmt.024.001.04 | +|[PUT /parties/{type}/{partyIdentifier}[/{subId}]/error](./script/parties_error_PUT.md) | acmt.024.001.04 | + +
+ +# 5. Phase d’accord +La **phase d’accord** est une étape critique : toutes les parties doivent partager la même compréhension des conditions du transfert avant tout engagement de fonds. Elle remplit notamment les objectifs suivants : +1. **Calcul et accord sur les frais**
+Permet de calculer et d’accepter mutuellement les frais applicables, pour la transparence et pour limiter les litiges après le lancement du transfert. +1. **Validation avant engagement**
+Chaque organisation vérifie si le transfert peut avoir lieu, ce qui permet de détecter tôt les problèmes et de réduire erreurs et écarts de rapprochement. +1. **Signature cryptographique des conditions**
+Les conditions du transfert sont signées cryptographiquement, assurant la non-répudiation. Le protocole Interledger est utilisé ; la production de paquets ILP est décrite dans la [documentation API FSPIOP Mojaloop](https://docs.mojaloop.io/technical/api/fspiop/). +1. **Soutien à l’inclusion financière**
+En exposant clairement l’ensemble des conditions en amont, la phase d’accord garantit que les participants décident en connaissance de cause, pour des choix équitables et éclairés. + +La phase d’accord renforce fiabilité et efficacité des transferts Mojaloop et la confiance dans les écosystèmes financiers numériques inclusifs. + +Elle se subdivise en deux sous-phases. + +## 5.1 Sous-phase d’accord sur la conversion de devises +Cette sous-phase est facultative ; elle s’active seulement si le transfert implique une conversion de devises. Le DFSP payeur coordonne alors un fournisseur de change pour sécuriser la liquidité inter-devises nécessaire. Les taux de change et frais associés sont fixés de façon transparente et acceptée par le DFSP et le FXP. Traiter la conversion avant l’engagement du transfert limite retards et écarts, notamment pour les opérations transfrontalières. + +### 5.1.1 Flux de messages + + +Le diagramme de séquence illustre des messages d’exemple pour un transfert P2P initié par le payeur. +![Agreement Conversion Flow](./SequenceDiagrams/AgreementConversion.svg) + +### 5.1.2 Ressource fxQuotes + +| Point de terminaison | Message | +|--- | --- | +|[POST /fxQuotes/{ID}](./script/fxquotes_POST.md) | **pacs.091.001** | +|[PUT /fxQuotes/{ID}](./script/fxquotes_PUT.md) | **pacs.092.001** | +|[PUT /fxQuotes/{ID}/error](./script/fxquotes_error_PUT.md) | **pacs.002.001.15** | + +## 5.2 Sous-phase d’accord sur les conditions de transfert +Cette sous-phase établit de concert les conditions du transfert entre le DFSP payeur et le DFSP bénéficiaire : montant, frais, délais, etc. Elle permet aussi la signature cryptographique de ces conditions pour la non-répudiation et la responsabilité. Finaliser les conditions de façon transparente limite erreurs et litiges et renforce l’efficacité et la confiance dans le processus Mojaloop. + +### 5.2.1 Flux de messages + +Le diagramme de séquence illustre des messages d’exemple pour un transfert P2P initié par le payeur. +![Agreement Flow](./SequenceDiagrams/Agreement.svg) + +### 5.2.2 Ressource Quotes + +| Point de terminaison | Message | +| ------------- | --- | +|[POST /quotes/{ID}](./script/quotes_POST.md) | **pacs.081.001** | +|[PUT /quotes/{ID}](./script/quotes_PUT.md) | **pacs.082.001** | +|[PUT /quotes/{ID}/error](./script/quotes_error_PUT.md) | **pacs.002.001.15** | + +
+ +# 6. Phase de transfert +Une fois les accords conclus pendant la phase d’accord, leur acceptation déclenche la phase de transfert, où intervient le mouvement effectif des fonds. Elle est exécutée avec précision pour respecter les conditions convenues et les engagements de chaque participant. Elle comporte deux sous-phases : exécution de la conversion de devises et compensation du transfert, en miroir des sous-phases d’accord correspondantes. + +## 6.1 Acceptation des conditions de conversion de devises +Cette sous-phase a lieu si le transfert comporte un change. Le fournisseur de change convenu pendant la phase d’accord exécute la conversion ; la liquidité inter-devises est fournie et les fonds convertis sont préparés pour la suite vers le DFSP bénéficiaire. Le FXP vérifie le respect des taux et frais convenus, pour l’intégrité financière et la transparence. + +### 6.1.1 Flux de messages + + +Le diagramme de séquence illustre des messages d’exemple de transfert pour un P2P initié par le payeur. +![Conversion Transfer Flow](./SequenceDiagrams/ConversionTransfer.svg) + +### 6.1.2 Ressource fxTransfers + +| Point de terminaison | Message | +| -------- | --- | +|[POST /fxTransfers/{ID}](./script/fxtransfers_POST.md) | **pacs.009.001** | +|[PUT /fxTransfers/{ID}](./script/fxtransfers_PUT.md) | **pacs.002.001.15** | +|[PUT /fxTransfers/{ID}/error](./script/fxtransfers_error_PUT.md) | **pacs.002.001.15** | +|[PATCH /fxTransfers/{ID}/error](./script/fxtransfers_PATCH.md) | **pacs.002.001.15** | + +## 6.2 Exécution et compensation du transfert +Cette sous-phase couvre le transfert effectif des fonds entre le DFSP payeur et le DFSP bénéficiaire : le montant convenu, y compris les frais, est compensé sur les comptes appropriés. Elle achève l’opération financière et honore les engagements de la phase d’accord, via des mécanismes de mouvement de fonds sécurisés et efficaces. + +### 6.2.1 Flux de messages + + +Le diagramme de séquence illustre des messages d’exemple pour un transfert P2P initié par le payeur. +![Transfer Flow](./SequenceDiagrams/Transfer.svg) + +### 6.2.2 Ressource Transfers + +| Point de terminaison | Message | +| --------- | --- | +|[POST /transfers/{ID}](./script/transfers_POST.md) | **pacs.008.001** | +|[PUT /transfers/{ID}](./script/transfers_PUT.md) | **pacs.002.001.15** | +|[PUT /transfers/{ID}/error](./script/transfers_error_PUT.md) | **pacs.002.001.15** | +|[PATCH /transfers/{ID}/error](./script/transfers_PATCH.md) | **pacs.002.001.15** | + + + + diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml new file mode 100644 index 000000000..d79b2330f --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml @@ -0,0 +1,96 @@ +@startuml + +Title Accord (devis) — flux de messages ISO 20022 +participant PayerDFSP as "DFSP payeur" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "DFSP bénéficiaire" + +autonumber + +PayerDFSP -> Mojaloop: POST /quotes +note left +**pacs.081.001.01** +**D'une institution financière à une autre** +**Demande de devis de transfert de crédit client** +{ +"GrpHdr": { + "MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y", + "CreDtTm": "2024-11-04T12:57:42.066Z", + "NbOfTxs": "1", + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z", + "SttlmInf": { "SttlmMtd": "CLRG" } + }, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM19DFKNRWC21FGJNTHRAT", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002" }}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}}, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001" }}}, + "Name": "Joe Blogs"}, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}, + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "Purp": { "Prtry": "TRANSFER"}, + "ChrgBr": "CRED"} +} +end note +Mojaloop -> PayeeDFSP: POST /quotes +PayeeDFSP -> PayeeDFSP: Vérifier si le bénéficiaire peut recevoir le paiement. +alt si le bénéficiaire peut recevoir le paiement +PayeeDFSP -> Mojaloop: PUT /quotes/{ID} +note right +**pacs.082.001.01** +**D'une institution financière à une autre** +**Réponse de devis de transfert de crédit client** +"GrpHdr": { + "MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD", + "CreDtTm": "2024-11-04T12:57:42.455Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z" +}, +"CdtTrfTxInf": { "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" }, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001"} } }, + "Name": "Payer Joe" }, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"} } }, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002"} } }, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } }, + "ChrgBr": "CRED", + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080" }, + "InstdAmt": { + "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "1080" }, + "ChrgsInf": { + "Amt": { "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "0" }, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } } }, + "VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." } } +} +end note +Mojaloop -> PayerDFSP: PUT/quotes/{ID} + +else + +PayeeDFSP -> Mojaloop: PUT/quotes/{ID}/error +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +end note +Mojaloop -> PayerDFSP: PUT/quotes/{ID}/error + +end + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg new file mode 100644 index 000000000..f8544ea5d --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg @@ -0,0 +1,133 @@ + + Accord (devis) — flux de messages ISO 20022 + + + Accord (devis) — flux de messages ISO 20022 + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + + Mojaloop + + DFSP bénéficiaire + + DFSP bénéficiaire + + + 1 + POST /quotes + + + pacs.081.001.01 + D'une institution financière à une autre +   + Demande de devis de transfert de crédit client + { + "GrpHdr": { + "MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y", + "CreDtTm": "2024-11-04T12:57:42.066Z", + "NbOfTxs": "1", + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z", + "SttlmInf": { "SttlmMtd": "CLRG" } + }, + "CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM19DFKNRWC21FGJNTHRAT", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002" }}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}}, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001" }}}, + "Name": "Joe Blogs"}, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}, + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "Purp": { "Prtry": "TRANSFER"}, + "ChrgBr": "CRED"} + } + + + 2 + POST /quotes + + + + + 3 + Vérifier si le bénéficiaire peut recevoir le paiement. + + + alt + [si le bénéficiaire peut recevoir le paiement] + + + 4 + PUT /quotes/{ID} + + + pacs.082.001.01 + D'une institution financière à une autre +   + Réponse de devis de transfert de crédit client + "GrpHdr": { + "MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD", + "CreDtTm": "2024-11-04T12:57:42.455Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z" + }, + "CdtTrfTxInf": { "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" }, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001"} } }, + "Name": "Payer Joe" }, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"} } }, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002"} } }, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } }, + "ChrgBr": "CRED", + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080" }, + "InstdAmt": { + "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "1080" }, + "ChrgsInf": { + "Amt": { "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "0" }, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } } }, + "VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." } } + } + + + 5 + PUT/quotes/{ID} + + + + 6 + PUT/quotes/{ID}/error + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + "GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, + "TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} + + + 7 + PUT/quotes/{ID}/error + + diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml new file mode 100644 index 000000000..40a1991ab --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml @@ -0,0 +1,92 @@ +@startuml + +Title Phase d'accord sur l'apport de liquidité — flux de messages ISO 20022 +participant PayerDFSP as "DFSP payeur" +participant Mojaloop as "Mojaloop" +participant FXP as "Fournisseur de change" + +autonumber + +PayerDFSP -> Mojaloop: POST /fxQuotes +note left +**pacs.091.001.01** +**Demande de devis de transfert de crédit interinstitutions** +"GrpHdr": { + "MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2", + "CreDtTm": "2024-11-04T12:57:39.427Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM16V1ZXP2DM34BQT40NW9", + "InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" }, + "Dbtr": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** } } }, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": {"Ccy": **"ZMW"**, + "ActiveOrHistoricCurrencyAndAmount": **"21"**}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": **"fxp"**}}}, + "IntrBkSttlmAmt": { "Ccy": **"MWK"**, + "ActiveCurrencyAndAmount": "0"}, + "InstrForCdtrAgt": {"InstrInf": **"SEND"**}} +} +end note +Mojaloop -> FXP: POST /fxQuotes +FXP -> FXP: Vérifier si la liquidité peut être fournie \n et fournir les taux. +alt si le FXP peut fournir la liquidité du paiement +FXP -> Mojaloop: PUT /fxQuotes/{ID} +note right +**pacs.092.001.01** +**Réponse de devis de transfert de crédit interinstitutions** +{ +"GrpHdr": { + "MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8", + "CreDtTm": "2024-11-04T12:57:39.791Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z"}, +"CdtTrfTxInf": { + "VrfctnOfTerms": {"Sh256Sgntr": **"KVHFmdTD6A..."**}, + "PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "TxId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr": {"FinInstnId": {"Othr": {"Id": **"payer-dfsp"**}}}, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": { "Ccy": **"ZMW"**, + "ActiveOrHistoricCurrencyAndAmount": **"21"**}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": **"fxp"**}}}, + "IntrBkSttlmAmt": {"Ccy": **"MWK"**, + "ActiveCurrencyAndAmount": **"1080"**}, + "InstrForCdtrAgt": {"InstrInf": **"SEND"**}} +} +end note +Mojaloop -> PayerDFSP: PUT /fxQuotes/{ID} + +else + +FXP -> Mojaloop: PUT /fxQuotes/{ID}/error +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +end note +Mojaloop -> PayerDFSP: PUT /fxQuotes/{ID}/error +end + + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg new file mode 100644 index 000000000..bc6e70152 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg @@ -0,0 +1,156 @@ + + Phase d'accord sur l'apport de liquidité — flux de messages ISO 20022 + + + Phase d'accord sur l'apport de liquidité — flux de messages ISO 20022 + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + + Mojaloop + + Fournisseur de change + + Fournisseur de change + + + 1 + POST /fxQuotes + + + pacs.091.001.01 + Demande de devis de transfert de crédit interinstitutions + "GrpHdr": { + "MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2", + "CreDtTm": "2024-11-04T12:57:39.427Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" + }, + "CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM16V1ZXP2DM34BQT40NW9", + "InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" }, + "Dbtr": { "FinInstnId": { "Othr": { "Id": + "payer-dfsp" + } } }, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": {"Ccy": + "ZMW" + , + "ActiveOrHistoricCurrencyAndAmount": + "21" + }}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": + "fxp" + }}}, + "IntrBkSttlmAmt": { "Ccy": + "MWK" + , + "ActiveCurrencyAndAmount": "0"}, + "InstrForCdtrAgt": {"InstrInf": + "SEND" + }} + } + + + 2 + POST /fxQuotes + + + + + 3 + Vérifier si la liquidité peut être fournie + et fournir les taux. + + + alt + [si le FXP peut fournir la liquidité du paiement] + + + 4 + PUT /fxQuotes/{ID} + + + pacs.092.001.01 + Réponse de devis de transfert de crédit interinstitutions + { + "GrpHdr": { + "MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8", + "CreDtTm": "2024-11-04T12:57:39.791Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z"}, + "CdtTrfTxInf": { + "VrfctnOfTerms": {"Sh256Sgntr": + "KVHFmdTD6A..." + }, + "PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "TxId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr": {"FinInstnId": {"Othr": {"Id": + "payer-dfsp" + }}}, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": { "Ccy": + "ZMW" + , + "ActiveOrHistoricCurrencyAndAmount": + "21" + }}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": + "fxp" + }}}, + "IntrBkSttlmAmt": {"Ccy": + "MWK" + , + "ActiveCurrencyAndAmount": + "1080" + }, + "InstrForCdtrAgt": {"InstrInf": + "SEND" + }} + } + + + 5 + PUT /fxQuotes/{ID} + + + + 6 + PUT /fxQuotes/{ID}/error + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + { + "GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, + "TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} + } + + + 7 + PUT /fxQuotes/{ID}/error + + diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml new file mode 100644 index 000000000..ade4eb3f3 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml @@ -0,0 +1,88 @@ +@startuml + +Title Engagement à fournir de la liquidité — flux de messages ISO 20022 +participant PayerDFSP as "DFSP payeur" +participant Mojaloop as "Mojaloop" +participant FXP as "Fournisseur de change" + +autonumber + +PayerDFSP -> Mojaloop: POST /fxTransfers +note left +**pacs.009.001.12** +**Exécution du transfert de crédit interinstitutions** +{ +"GrpHdr":{ + "MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT", + "CreDtTm":"2024-11-04T12:57:44.580Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "UndrlygCstmrCdtTrf":{ + "Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "InstdAmt":{"Ccy":"ZMW", + "ActiveOrHistoricCurrencyAndAmount":"21"}}, + "Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}} +} +end note +Mojaloop -> FXP: POST /fxTransfers +FXP -> FXP: Vérifier si la liquidité pour le transfert peut encore être fournie. +alt si le FXP peut fournir la liquidité du paiement +FXP -> Mojaloop: PUT /fxTransfers/{ID} +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +end note +Mojaloop -> PayerDFSP: PUT /fxTransfers/{ID} + +else + +FXP -> Mojaloop: PUT /fxTransfers/{ID}/error +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}} +end note +Mojaloop -> PayerDFSP: PUT /fxTransfer/{ID}/error +end + +Mojaloop -> Mojaloop: Lorsque le transfert déterminant est engagé, \n la conversion de devises est engagée. + +Mojaloop->FXP: PATCH /fxTransfers/{ID} +note left +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{"PrcgDt":{ + "DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" +end note + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg new file mode 100644 index 000000000..26282a44a --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg @@ -0,0 +1,132 @@ + + Engagement à fournir de la liquidité — flux de messages ISO 20022 + + + Engagement à fournir de la liquidité — flux de messages ISO 20022 + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + + Mojaloop + + Fournisseur de change + + Fournisseur de change + + + 1 + POST /fxTransfers + + + pacs.009.001.12 + Exécution du transfert de crédit interinstitutions + { + "GrpHdr":{ + "MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT", + "CreDtTm":"2024-11-04T12:57:44.580Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"}, + "CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "UndrlygCstmrCdtTrf":{ + "Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "InstdAmt":{"Ccy":"ZMW", + "ActiveOrHistoricCurrencyAndAmount":"21"}}, + "Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}} + } + + + 2 + POST /fxTransfers + + + + + 3 + Vérifier si la liquidité pour le transfert peut encore être fournie. + + + alt + [si le FXP peut fournir la liquidité du paiement] + + + 4 + PUT /fxTransfers/{ID} + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + { + "GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, + "TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} + } + + + 5 + PUT /fxTransfers/{ID} + + + + 6 + PUT /fxTransfers/{ID}/error + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + "GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, + "TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}} + + + 7 + PUT /fxTransfer/{ID}/error + + + + + 8 + Lorsque le transfert déterminant est engagé, + la conversion de devises est engagée. + + + 9 + PATCH /fxTransfers/{ID} + + + pacs.002.001.15 + D'une institution financière à une autre + Rapport d'état de paiement + "GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, + "TxInfAndSts":{"PrcgDt":{ + "DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" + + diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml new file mode 100644 index 000000000..07136e2e9 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml @@ -0,0 +1,59 @@ +@startuml + +Title Découverte — flux de messages ISO 20022 +participant PayerDFSP as "DFSP payeur" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "DFSP bénéficiaire" + +autonumber + +PayerDFSP -> Mojaloop: GET /parties/{type}/{PartyIdentifier} +Mojaloop -> PayeeDFSP: GET /parties/{type}/{PartyIdentifier} +PayeeDFSP -> PayeeDFSP: Valider l'état du compte du bénéficiaire. +alt si le compte est actif +PayeeDFSP -> Mojaloop: PUT /parties/{type}/{PartyIdentifier} \n Renvoie les devises prises en charge et les détails du titulaire du compte. +note right +**acmt.024.001.04** +**Rapport de vérification d'identification de compte** +{ +"Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQB5", + "CreDtTm": "2024-11-04T12:57:37.318Z", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfps"** }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** }}}}} +"Rpt": { + "Vrfctn": true, + "OrgnlId": **"MSISDN/16665551002"**, + "UpdtdPtyAndAcctId": {"Pty": {"Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry": **"MSISDN"**}, + "Id": **"16665551002"**}}}, + "Nm": **"Chikondi Banda"**}, + "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfsp"** }}}, + "Acct": { "Ccy": **"MWK"** }} +} +end note +Mojaloop -> PayerDFSP: PUT /parties/{type}/{PartyIdentifier} + +else si le compte est inactif + +PayeeDFSP -> Mojaloop: PUT /parties/{type}/{PartyIdentifier}/error \n Renvoie le code d'erreur 3204 — partie introuvable. +note right +**acmt.024.001.04** +**Rapport de vérification d'identification de compte** +{ + "Assgnmt": { + "Id": 123, + "CreDtTm": "2013-03-07T16:30:00", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfsp"** }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** }}}}}, + "Rpt": { + "Vrfctn": false, + "OrgnlId": **"MSISDN/16665551002"**, + "CreDtTm": "2013-03-07T16:30:00", + "Rsn": { "Prtry": **3204** }} +} +end note +Mojaloop -> PayerDFSP: PUT /parties/{type}/{PartyIdentifier}/error + +end + +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg new file mode 100644 index 000000000..e0a9a91f6 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg @@ -0,0 +1,120 @@ + + Découverte — flux de messages ISO 20022 + + + Découverte — flux de messages ISO 20022 + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + + Mojaloop + + DFSP bénéficiaire + + DFSP bénéficiaire + + + 1 + GET /parties/{type}/{PartyIdentifier} + + + 2 + GET /parties/{type}/{PartyIdentifier} + + + + + 3 + Valider l'état du compte du bénéficiaire. + + + alt + [si le compte est actif] + + + 4 + PUT /parties/{type}/{PartyIdentifier} + Renvoie les devises prises en charge et les détails du titulaire du compte. + + + acmt.024.001.04 + Rapport de vérification d'identification de compte + { + "Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQB5", + "CreDtTm": "2024-11-04T12:57:37.318Z", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": + "payee-dfps" + }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": + "payer-dfsp" + }}}}} + "Rpt": { + "Vrfctn": true, + "OrgnlId": + "MSISDN/16665551002" + , + "UpdtdPtyAndAcctId": {"Pty": {"Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry": + "MSISDN" + }, + "Id": + "16665551002" + }}}, + "Nm": + "Chikondi Banda" + }, + "Agt": { "FinInstnId": { "Othr": { "Id": + "payee-dfsp" + }}}, + "Acct": { "Ccy": + "MWK" + }} + } + + + 5 + PUT /parties/{type}/{PartyIdentifier} + + [si le compte est inactif] + + + 6 + PUT /parties/{type}/{PartyIdentifier}/error + Renvoie le code d'erreur 3204 — partie introuvable. + + + acmt.024.001.04 + Rapport de vérification d'identification de compte + { + "Assgnmt": { + "Id": 123, + "CreDtTm": "2013-03-07T16:30:00", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": + "payee-dfsp" + }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": + "payer-dfsp" + }}}}}, + "Rpt": { + "Vrfctn": false, + "OrgnlId": + "MSISDN/16665551002" + , + "CreDtTm": "2013-03-07T16:30:00", + "Rsn": { "Prtry": + 3204 + }} + } + + + 7 + PUT /parties/{type}/{PartyIdentifier}/error + + diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml new file mode 100644 index 000000000..f5d7b7d99 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml @@ -0,0 +1,88 @@ +@startuml + +Title Transfert — flux de messages ISO 20022 +participant PayerDFSP as "DFSP payeur" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "DFSP bénéficiaire" + +autonumber + +PayerDFSP -> Mojaloop: POST /transfers +note left +**pacs.008.001.13** +**D'une institution financière à une autre** +**Transfert de crédit client** +{ +"GrpHdr":{ + "MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM", + "CreDtTm":"2024-11-04T12:57:45.812Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "ChrgBr":"CRED", + "Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16665551002"}}}}, + "Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16135551001"}}}, + "Name":"Joe Blogs"}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}} +} +end note +Mojaloop -> PayeeDFSP: POST /transfers +PayeeDFSP -> PayeeDFSP: Vérifier si le bénéficiaire peut recevoir le paiement. +alt si le bénéficiaire peut recevoir le paiement +PayeeDFSP -> Mojaloop: PUT /transfers/{ID} +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +{ +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{ + "ExctnConf":"-rL3liKeLrsNy7GHJaKgAzeDL_8IVnvER5zUlP1YAoc", + "PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"} +} +end note +Mojaloop -> PayerDFSP: PUT/transfers/{ID} + +else + +Mojaloop -> PayerDFSP: PUT/transfers/{ID}/error +note right +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +end note +end + +Mojaloop->Mojaloop: Si le transfert échoue, expire \n ou est réservé — message PUT /transfers. + +Mojaloop->PayeeDFSP: PATCH /transfers/{ID} +note left +**pacs.002.001.15** +**D'une institution financière à une autre** +**Rapport d'état de paiement** +{ +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{"PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" +} +end note +@enduml \ No newline at end of file diff --git a/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg new file mode 100644 index 000000000..0f800b082 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg @@ -0,0 +1,131 @@ + + Transfert — flux de messages ISO 20022 + + + Transfert — flux de messages ISO 20022 + + + + + + DFSP payeur + + DFSP payeur + + Mojaloop + + Mojaloop + + DFSP bénéficiaire + + DFSP bénéficiaire + + + 1 + POST /transfers + + + pacs.008.001.13 + D'une institution financière à une autre +   + Transfert de crédit client + { + "GrpHdr":{ + "MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM", + "CreDtTm":"2024-11-04T12:57:45.812Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"}, + "CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "ChrgBr":"CRED", + "Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16665551002"}}}}, + "Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16135551001"}}}, + "Name":"Joe Blogs"}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}} + } + + + 2 + POST /transfers + + + + + 3 + Vérifier si le bénéficiaire peut recevoir le paiement. + + + alt + [si le bénéficiaire peut recevoir le paiement] + + + 4 + PUT /transfers/{ID} + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + { + "GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, + "TxInfAndSts":{ + "ExctnConf":"-rL3liKeLrsNy7GHJaKgAzeDL_8IVnvER5zUlP1YAoc", + "PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"} + } + + + 5 + PUT/transfers/{ID} + + + + 6 + PUT/transfers/{ID}/error + + + pacs.002.001.15 + D'une institution financière à une autre +   + Rapport d'état de paiement + { + "GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, + "TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} + } + + + + + 7 + Si le transfert échoue, expire + ou est réservé — message PUT /transfers. + + + 8 + PATCH /transfers/{ID} + + + pacs.002.001.15 + D'une institution financière à une autre + Rapport d'état de paiement + { + "GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, + "TxInfAndSts":{"PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" + } + + diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_POST.md b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_POST.md new file mode 100644 index 000000000..ece9bafb8 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_POST.md @@ -0,0 +1,783 @@ +--- +sidebarTitle: POST /fxQuotes +--- + +## 7.4 POST /fxQuotes/ +| Financial Institution Credit Transfer Quote Request - **pacs.091.001.01**| +|--| + +#### Contexte +*(DFSP -> FXP)* + +This message is initiated by a DFSP who is requesting liquidity cover in another currency to fund a transfer. The message is sent to a foreign exchange provider and is a request for conversion terms. The source currency is specified in `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.Ccy` and the target currency is specified in `CdtTrfTxInf.IntrBkSttlmAmt.Ccy`. + +#### Conversion Type `SEND` +If the `CdtTrfTxInf.InstrForCdtrAgt.InstrInf` is defined as `SEND`, then the source currency amount is expected to be defined `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount`, and the target currency amount will be calculated based on the source currency amount and fees. (The target amount `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` should be specified as 0 and will not be used in the calculation.) + +#### Conversion Type `RECEIVE` +If the `CdtTrfTxInf.InstrForCdtrAgt.InstrInf` is defined as `RECEIVE`, then the target currency amount is expected to be defined `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount`, and the source currency amount will be calculated based on the target currency amount and fees. (The source amount `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount` should be specified as 0 and will not be used in the calculation.) + +In this phase of the transfer all participants to agree on the terms, and are expected to validate whether the transfer will be able to proceed. The Foreign Exchange provider is expected to respond to this request with a PUT /fxQuotes callback. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2", + "CreDtTm": "2024-11-04T12:57:39.427Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM16V1ZXP2DM34BQT40NW9", + "InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" }, + "Dbtr": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" } } }, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": {"Ccy": "ZMW", + "ActiveOrHistoricCurrencyAndAmount": "21"}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "IntrBkSttlmAmt": { "Ccy": "MWK", + "ActiveCurrencyAndAmount": "0"}, + "InstrForCdtrAgt": {"InstrInf": "SEND"}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - FxRequest_FICreditTransferProposal[1..1]Credit Transfer Transaction Information
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstrForCdtrAgt - InstructionForCreditorAgent[1..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
     Purp - Purpose[0..1]Underlying reason for the payment transaction.
         Cd - Code[0..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[0..1]
Purpose, in a proprietary form.
     RmtInf - RemittanceInformation2[0..0]
     UndrlygAllcn - TransactionAllocation1[0..0]
     UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
TBD
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
         RmtInf - RemittanceInformation22[0..0]
         InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_PUT.md new file mode 100644 index 000000000..6d8caa391 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_PUT.md @@ -0,0 +1,780 @@ +--- +sidebarTitle: "PUT /fxQuotes/{ID}" +--- + +## 7.5 PUT /fxQuotes/{ID} +|Financial Institution Credit Transfer Quote Response - **pacs.092.001.01**| +|--| + +#### Contexte +*(FXP -> DFSP)* + +This is triggered as a callback response to the POST /fxQuotes call. The message is generated by the foreign exchange provider and is a message response that includes the conversion terms. The FXP is expected to respond with this message if a terms requested are favorable and the FXP would like to participate in the transaction. + +The source currency amount is expected to be defined `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount`, and the target currency amount is provided in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` field. These are clearing amounts and must have fees already included in their calculation. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the terms presented. It is the responsibility of the FXP to enforce this expiry in the transfer phase of a transaction. + +The `CdtTrfTxInf.VrfctnOfTerms.Sh256Sgntr` must contain the ILPv4 cryptographically signed condition, which is a cryptographic version of the conversion terms. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8", + "CreDtTm": "2024-11-04T12:57:39.791Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "VrfctnOfTerms": {"Sh256Sgntr": "KVHFmdTD6A..."}, + "PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "TxId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": { "Ccy": "ZMW", + "ActiveOrHistoricCurrencyAndAmount": "21"}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "IntrBkSttlmAmt": {"Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "InstrForCdtrAgt": {"InstrInf": "SEND"}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction68_FX_Quotes[1..1]Set of elements providing information specific to the individual credit transfer(s).
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstrForCdtrAgt - InstructionForCreditorAgent[1..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
     Purp - Purpose[0..1]Underlying reason for the payment transaction.
         Cd - Code[0..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[0..1]
Purpose, in a proprietary form.
     RmtInf - RemittanceInformation2[0..0]
     UndrlygAllcn - TransactionAllocation1[0..0]
     UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
TBD
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
         RmtInf - RemittanceInformation22[0..0]
         InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md new file mode 100644 index 000000000..6eddbf22a --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md @@ -0,0 +1,184 @@ +--- +sidebarTitle: "PUT /fxQuotes/{ID}/error" +--- + + +## 7.6 PUT /fxQuotes/{ID}/error + +|Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15** | +|--| + +#### Contexte +*(DFSP -> FXP, FXP -> DFSP, HUB -> DFSP, HUB -> FXP)* + +This is triggered as a callback response to the POST /fxQuotes call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, the HUB, or the FPX. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[1..1]Specifies the reason for the status report.
             Cd - Code[1..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[0..1]Specified date.
         DtTm - DateTime[0..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md new file mode 100644 index 000000000..23580f341 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md @@ -0,0 +1,186 @@ +--- +sidebarTitle: "PATCH /fxTransfers/{ID}" +--- + +## 7.13 PATCH /fxTransfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(HUB -> FXP)* + +This message use by the HUB to inform the foreign exchange provider participant in a cross currency transfer of the successful conclusion of the conversion. This message is only generated if the dependent transfer is committed in the hub. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "PrcgDt":{ + "DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"COMM"} +} +``` + +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[1..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[0..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[0..1]Specifies the reason for the status report.
             Cd - Code[0..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[0..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[1..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[1..1]Specified date.
         DtTm - DateTime[1..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_POST.md b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_POST.md new file mode 100644 index 000000000..e9e8796c8 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_POST.md @@ -0,0 +1,780 @@ +--- +sidebarTitle: POST /fxTransfers +--- + +## 7.10 POST /fxTransfers +| Execute Financial Institution Credit Transfer - **pacs.009.001.12**| +|--| + +#### Contexte +*(DFSP -> FXP)* + +This message is initiated by a DFSP who is requesting to transfer funds in another currency. The message is sent to the foreign exchange provider who provided the conversion terms. This message is an acknowledgement that the terms of the conversion are accepted, and is thus an instruction to proceed with the conversion. + +The source amount and currency are defined here `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount` and here `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.Ccy`, and the target amount and currency are defined `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and here `CdtTrfTxInf.IntrBkSttlmAmt.Ccy`. + +This message includes can be seen as an agreement to the terms that have previously been set up and established in the fxQuotes resource. The `CdtTrfTxInf.UndrlygCstmrCdtTrf.VrfctnOfTerms.Sh256Sgntr` field is a reference to the ILPv4 cryptographic condition of those terms. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the this transfer message. It is the responsibility of the HUB to enforce this expiry. The status of which a DFSP can query by making a `GET /fxTransfers/{ID}` request. + +The currency conversion is dependent on a transfer (the determiningTransferId) and is specified in the `CdtTrfTxInf.PmtId.EndToEndId` field. + +Voici un exemple de message : +```json +{ +"GrpHdr":{ + "MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT", + "CreDtTm":"2024-11-04T12:57:44.580Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "UndrlygCstmrCdtTrf":{ + "Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "InstdAmt":{"Ccy":"ZMW", + "ActiveOrHistoricCurrencyAndAmount":"21"}}, + "Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader.[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransactionInformation.[1..1]Set of elements providing information specific to the individual credit transfer(s).
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[0..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
     Purp - Purpose[0..1]Underlying reason for the payment transaction.
         Cd - Code[0..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[0..1]
Purpose, in a proprietary form.
     RmtInf - RemittanceInformation2[0..0]
     UndrlygAllcn - TransactionAllocation1[0..0]
     UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
TBD
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
         RmtInf - RemittanceInformation22[0..0]
         InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md new file mode 100644 index 000000000..60363b96d --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md @@ -0,0 +1,102 @@ +--- +sidebarTitle: "PUT /fxTransfers/{ID}" +--- + +## 7.11 PUT /fxTransfers/{ID} + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(FXP -> DFSP)* + +This message is a response to the `POST \fxTransfers` call initiated by the DFSP who is requesting to proceed with the conversion terms presented in the `PUT \fxquotes`. It is the FXP's responsibility to check that the clearing amounts align with the agreed conversion terms, and if all requirements are met, use this message to lock-in the agreed terms. Once the hub receives this acceptance message, the conversion can no-longer timeout. Final completion of the conversion will only occur once the dependent transfer is committed. + +The cryptographic ILP fulfillment provided in the `TxInfAndSts.ExctnConf` field, is released by the FXP as an indication to the HUB that the terms have been met. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader113[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[0..0]Specifies a numeric string with a maximum length of 15 digits.
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - SettlementInstruction15[0..0]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction62[0..0]
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md new file mode 100644 index 000000000..9812ec868 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md @@ -0,0 +1,182 @@ +--- +sidebarTitle: "PUT /fxTransfers/{ID}/error" +--- + +## 7.12 PUT /fxTransfers/{ID}/error + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(FXP -> DFSP, FXP -> HUB, DFSP -> HUB, DFSP -> FXP, HUB -> DFSP)* + +This is triggered as a callback response to the POST /fxTransfers call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[1..1]Specifies the reason for the status report.
             Cd - Code[1..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[0..1]Specified date.
         DtTm - DateTime[0..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
diff --git a/docs/fr/product/features/Iso20022/v1.0/script/parties_GET.md b/docs/fr/product/features/Iso20022/v1.0/script/parties_GET.md new file mode 100644 index 000000000..4953d2df0 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/parties_GET.md @@ -0,0 +1,16 @@ +--- +sidebarTitle: "GET /parties" +--- + +## 7.1 GET /parties/{type}/{partyIdentifier}[/{subId}] + +L’endpoint GET /parties ne prend pas en charge et n’exige pas de charge utile ; il peut être vu comme une instruction pour déclencher un rapport de vérification d’identification de compte. + +- **{type}** — Types d’identifiant de partie
+ Le **{type}** désigne la classification du type d’identifiant de partie. Chaque schéma ne prend en charge qu’un sous-ensemble de ces codes. Les codes pris en charge par le schéma peuvent provenir des codes ISO 20022 d’identification externe d’organisation ou de personne, ou de codes pris en charge par FSPIOP. La liste complète des codes pris en charge figure dans [**l’annexe A**](../Appendix.md). + +- **partyIdentifier**
+ Il s’agit de l’identifiant de la partie représentée, du type indiqué par le {type} ci-dessus. + +- **{subId}**
+ Sous-identifiant ou sous-type pour la partie ; certaines implémentations l’exigent pour garantir l’unicité de l’identifiant. diff --git a/docs/fr/product/features/Iso20022/v1.0/script/parties_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/parties_PUT.md new file mode 100644 index 000000000..101f407b9 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/parties_PUT.md @@ -0,0 +1,680 @@ +--- +sidebarTitle: PUT /parties +--- + +## 7.2 PUT /Parties/{type}/{partyIdentifier}[/{subId}] +|**Account Identification Verification Report - acmt.024.001.04**| +|--| + +#### Contexte +*(DFSP -> DFSP)* + +This is triggers as a callback response to the GET /parties call. The message is between DFSPs connected in the scheme and is a check that validates that the account represented is active. + +Voici un exemple de message : +``` json +{ +"Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQB5", + "CreDtTm": "2024-11-04T12:57:37.318Z", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfps" }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}}}, +"Rpt": { + "Vrfctn": true, + "OrgnlId": "MSISDN/16665551002", + "UpdtdPtyAndAcctId": { + "Pty": { + "Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry": "MSISDN"}, + "Id": "16665551002"}}}, + "Nm": "Chikondi Banda"}, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp" }}}, + "Acct": { "Ccy": "MWK" }}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
Assgnmt - Assignment[1..1]Identifies the identification assignment.
     MsgId - MessageIdentification[1..1]Unique identification, as assigned by the assigner, to unambiguously identify the message.
     CreDtTm - CreationDateTime[1..1]Date and time at which the identification assignment was created.
     Cretr - Party50Choice[0..0]
     FrstAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     Assgnr - Assignor[1..1]Party that assigns the identification assignment to another party. This is also the sender of the message.
         Pty - Party[1..1]Identification of a person or an organisation.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Agt - Agent[1..1]Identification of a financial institution.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
     Assgne - Assignee[1..1]Party that the identification assignment is assigned to. This is also the receiver of the message.
         Pty - Party[1..1]Identification of a person or an organisation.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Agt - Agent[1..1]Identification of a financial institution.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
OrgnlAssgnmt - MessageIdentification8[0..0]
Rpt - Report[1..1]Information concerning the verification of the identification data for which verification was requested.
     OrgnlId - OriginalIdentification[1..1]Unique identification, as assigned by a sending party, to unambiguously identify the party and account identification information group within the original message.
     Vrfctn - Verification[1..1]Identifies whether the party and/or account information received is correct. Boolean value.
     Rsn - Reason[0..1]Specifies the reason why the verified identification information is incorrect.
         Cd - Code[0..1]Reason why the verified identification information is incorrect, as published in an external reason code list.
         Prtry - Proprietary[0..1]Reason why the verified identification information is incorrect, in a free text form.
     OrgnlPtyAndAcctId - OriginalPartyAndAccountIdentification[0..1]Provides party and/or account identification information as given in the original message.
         Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Acct - Account[0..1]Unambiguous identification of the account of a party.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         Agt - Agent[0..1]Financial institution servicing an account for a party.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
     UpdtdPtyAndAcctId - UpdatedPartyAndAccountIdentification[1..1]Provides party and/or account identification information.
         Pty - Party[1..1]Account owner that owes an amount of money or to whom an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Acct - Account[0..1]Unambiguous identification of the account of a party.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         Agt - Agent[0..1]Financial institution servicing an account for a party.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
SplmtryData - SupplementaryData[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/parties_error_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/parties_error_PUT.md new file mode 100644 index 000000000..36eb4634c --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/parties_error_PUT.md @@ -0,0 +1,679 @@ +--- +sidebarTitle: "PUT /parties/{ID}/error" +--- + + +## 7.3 PUT /parties/{type}/{partyIdentifier}[/{subId}]/error +|**Account Identification Verification Report - acmt.024.001.04**| +|--| + +#### Contexte +*(DFSP -> DFSP)* + +This is triggered as a callback response to the GET /parties call when an error occurs. The message is between DFSPs connected in the scheme and indicates an error in the account verification process. All DFSP participating the the scheme are expected to respond with this message. + +Voici un exemple de message : +```json +{ + "Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQBW", + "CreDtTm": "2013-03-07T16:30:00", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp" } } } }, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" } } } } + }, + "Rpt": { + "Vrfctn": false, + "OrgnlId": "MSISDN/16665551002", + "CreDtTm": "2013-03-07T16:30:00", + "Rsn": { "Prtry": 3204 } + } +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
Assgnmt - Assignment[1..1]Information related to the identification assignment.
     MsgId - MessageIdentification[1..1]Unique identification, as assigned by the assigner, to unambiguously identify the message.
     CreDtTm - CreationDateTime[1..1]Date and time at which the identification assignment was created.
     Cretr - Party50Choice[0..0]
     FrstAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     Assgnr - Assignor[1..1]Party that assigns the identification assignment to another party. This is also the sender of the message.
         Pty - Party[1..1]Identification of a person or an organisation.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Agt - Agent[1..1]Identification of a financial institution.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
     Assgne - Assignee[1..1]Party that the identification assignment is assigned to. This is also the receiver of the message.
         Pty - Party[1..1]Identification of a person or an organisation.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Agt - Agent[1..1]Identification of a financial institution.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
OrgnlAssgnmt - MessageIdentification8[0..0]
Rpt - Report[1..1]Information concerning the verification of the identification data for which verification was requested.
     OrgnlId - OriginalIdentification[1..1]Unique identification, as assigned by a sending party, to unambiguously identify the party and account identification information group within the original message.
     Vrfctn - Verification[1..1]Identifies whether the party and/or account information received is correct. Boolean value.
     Rsn - Reason[1..1]Specifies the reason why the verified identification information is incorrect.
         Cd - Code[1..1]Reason why the verified identification information is incorrect, as published in an external reason code list.
         Prtry - Proprietary[1..1]Reason why the verified identification information is incorrect, in a free text form.
     OrgnlPtyAndAcctId - OriginalPartyAndAccountIdentification[0..1]Provides party and/or account identification information as given in the original message.
         Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Acct - Account[0..1]Unambiguous identification of the account of a party.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         Agt - Agent[0..1]Financial institution servicing an account for a party.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
     UpdtdPtyAndAcctId - UpdatedPartyAndAccountIdentification[0..1]Provides party and/or account identification information.
         Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - Other[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
         Acct - Account[0..1]Unambiguous identification of the account of a party.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         Agt - Agent[0..1]Financial institution servicing an account for a party.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEIIdentifier[0..1]Legal Entity Identifier
Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
SplmtryData - SupplementaryData[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ + diff --git a/docs/fr/product/features/Iso20022/v1.0/script/quotes_POST.md b/docs/fr/product/features/Iso20022/v1.0/script/quotes_POST.md new file mode 100644 index 000000000..825920265 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/quotes_POST.md @@ -0,0 +1,635 @@ +--- +sidebarTitle: POST /quotes +--- + +## 7.7 POST /quotes +|**Financial Institution to Financial Institution Customer Credit Transfer Quote Request - pacs.081.001.01**| +|--| + +#### Contexte +*(DFSP -> DFSP)* + +This request for quote message that is initiated by the payer DFSP who is requesting the payee DFSP to provide the terms of the transfer. The reply to this request is a callback made on the PUT /quotes endpoint. In this phase of the transfer all participants present and agree on the terms of the transfer, and are expected to validate whether the transfer will be able to proceed. + +If this transaction includes currency conversion, then the transfer amount and currency specified must be in target currency. The transfer amounts is specified in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` fields. +Both the `ChrgBr` type `CRED` and `DEBT` are supported. +#### Charge Type `CRED` +If the `CdtTrfTxInf.ChrgBr` is defined as `CRED`, then the transfer amount is expected to remain the same in the returned transfer terms and the payee party receive amount is adjusted to account for any fees. + +#### Charge Type `DEBT` +If the `CdtTrfTxInf.ChrgBr` is defined as `DEBT`, then the amount the payee party receives must equal the transfer amount specified. The transfer amount in returned transfer terms is adjusted to account for any fees. + +The Identifier for this request must be a ULID generated identifier and is specified in the `CdtTrfTxInf.PmtId.TxId` field. If this transfer is part of a wider transaction, then that too is represented by a ULID specified in the `CdtTrfTxInf.PmtId.EndToEndId` field. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y", + "CreDtTm": "2024-11-04T12:57:42.066Z", + "NbOfTxs": "1", + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z", + "SttlmInf": { "SttlmMtd": "CLRG" } + }, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM19DFKNRWC21FGJNTHRAT", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002" }}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}}, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001" }}}, + "Name": "Joe Blogs"}, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}, + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "Purp": { "Prtry": "TRANSFER"}, + "ChrgBr": "CRED"} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
date and a mandatory time component, expressed in either UTC time
format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
(YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
(YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
"XML Schema Part 2: Datatypes Second Edition -
W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

Note on the time format:
1) beginning / end of calendar day
00:00:00 = the beginning of a calendar day
24:00:00 = the end of a calendar day

2) fractions of second in time format
Decimal fractions of seconds may be included. In this case, the
involved parties shall agree on the maximum number of digits that are allowed.
     PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
     ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
     ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
         Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
         Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         Tp - Type[0..1]Defines the type of charges.
             Cd - Code[0..1]Charge type, in a coded form.
             Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                 Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                 Issr - Issuer[0..1]Entity that assigns the identification.
     MndtRltdInf - CreditTransferMandateData1[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
     Purp - Purpose[1..1]Underlying reason for the payment transaction.
         Cd - Code[1..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[1..1]
Purpose, in a proprietary form.
     RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
         DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
         Authrty - Authority[0..1]
Entity requiring the regulatory reporting information.
             Nm - Name[0..1]
Name of the entity requiring the regulatory reporting information.
             Ctry - Country[0..1]
Country of the entity that requires the regulatory reporting information.
         Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Tp - Type[0..1]
Specifies the type of the information supplied in the regulatory reporting details.
             Dt - Date[0..1]
Date related to the specified type of regulatory reporting details.
             Ctry - Country[0..1]
Country related to the specified type of regulatory reporting details.
             Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
             Amt - Amount[0..1]
Amount of money to be reported for regulatory and statutory requirements.
             Inf - Information[0..1]
Additional details that cater for specific domestic regulatory requirements.
     Tax - Tax[0..1]Provides details on the tax.
         Cdtr - Creditor[0..1]
Party on the credit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the creditor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
         Dbtr - Debtor[0..1]
Party on the debit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         UltmtDbtr - UltimateDebtor[0..1]
Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         AdmstnZone - AdministrationZone[0..1]
Territorial part of a country to which the tax payment is related.
         RefNb - ReferenceNumber[0..1]
Tax reference information that is specific to a taxing agency.
         Mtd - Method[0..1]
Method used to indicate the underlying business or how the tax is paid.
         TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
Total amount of money on which the tax is based.
         TtlTaxAmt - TotalTaxAmount[0..1]
Total amount of money as result of the calculation of the tax.
         Dt - Date[0..1]
Date by which tax is due.
         SeqNb - SequenceNumber[0..1]
Sequential number of the tax report.
         Rcrd - Record[0..1]
Details of the tax record.
             Tp - Type[0..1]
High level code to identify the type of tax details.
             Ctgy - Category[0..1]
Specifies the tax code as published by the tax authority.
             CtgyDtls - CategoryDetails[0..1]
Provides further details of the category tax code.
             DbtrSts - DebtorStatus[0..1]
Code provided by local authority to identify the status of the party that has drawn up the settlement document.
             CertId - CertificateIdentification[0..1]
Identification number of the tax report as assigned by the taxing authority.
             FrmsCd - FormsCode[0..1]
Identifies, in a coded form, on which template the tax report is to be provided.
             Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                 Yr - Year[0..1]
Year related to the tax payment.
                 Tp - Type[0..1]
Identification of the period related to the tax payment.
                 FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                     FrDt - FromDate[0..1]Start date of the range.
                     ToDt - ToDate[0..1]End date of the range.
             TaxAmt - TaxAmount[0..1]
Set of elements used to provide information on the amount of the tax record.
                 Rate - Rate[0..1]
Rate used to calculate the tax.
                 TaxblBaseAmt - TaxableBaseAmount[0..1]
Amount of money on which the tax is based.
                 TtlAmt - TotalAmount[0..1]
Total amount that is the result of the calculation of the tax for the record.
                 Dtls - Details[0..1]
Set of elements used to provide details on the tax period and amount.
                     Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                         Yr - Year[0..1]
Year related to the tax payment.
                         Tp - Type[0..1]
Identification of the period related to the tax payment.
                         FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                             FrDt - FromDate[0..1]Start date of the range.
                             ToDt - ToDate[0..1]End date of the range.
                     Amt - Amount[0..1]
Underlying tax amount related to the specified period.
             AddtlInf - AdditionalInformation[0..1]
Further details of the tax record.
     RltdRmtInf - RemittanceLocation8[0..0]
     RmtInf - RemittanceInformation22[0..0]
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/quotes_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/quotes_PUT.md new file mode 100644 index 000000000..07a1e91c5 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/quotes_PUT.md @@ -0,0 +1,638 @@ +--- +sidebarTitle: "PUT /quotes/{ID}" +--- + +## 7.8 PUT /quotes/{ID} +|Financial Institution to Financial Institution Customer Credit Transfer Quote Response - **pacs.082.001.01**| +|--| + +#### Contexte +*(DFSP -> DFSP)* + +This is triggered as a callback response to the POST /quotes call. The message is generated by the payee DFSP and is a message response that includes the transfer terms. The payee DFSP is expected to respond with this message if a terms requested are favorable and the payee DFSP would like to participate in the transaction. + +The transfer amounts is specified in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` fields. These are clearing amounts and must have fees already included in their calculation. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the terms presented. It is the responsibility of the payee DFSP to enforce this expiry in the transfer phase of a transaction. + +The `CdtTrfTxInf.PmtId.TxId` must reference the message that this is a response to and is the same as what is included in the path as `{ID}`. + +The `CdtTrfTxInf.VrfctnOfTerms.IlpV4PrepPacket` must contain the ILPv4 cryptographically signed packet, which is a cryptographic version of the transfers terms. These are the terms against with the payer DFSP agrees, and against which the non-repudiation of the transfer is base. It is thus important that the payer DFSP inspects these terms. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD", + "CreDtTm": "2024-11-04T12:57:42.455Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z" +}, +"CdtTrfTxInf": { + "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" }, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001"}}}, + "Name": "Payer Joe" }, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"}}}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002"}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"}}}, + "ChrgBr": "CRED", + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080" }, + "InstdAmt": { + "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "1080" }, + "ChrgsInf": { + "Amt": { "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "0" }, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"}}}}, + "VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." }}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
Set of elements providing information specific to the individual credit transfer(s).
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
date and a mandatory time component, expressed in either UTC time
format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
(YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
(YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
"XML Schema Part 2: Datatypes Second Edition -
W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

Note on the time format:
1) beginning / end of calendar day
00:00:00 = the beginning of a calendar day
24:00:00 = the end of a calendar day

2) fractions of second in time format
Decimal fractions of seconds may be included. In this case, the
involved parties shall agree on the maximum number of digits that are allowed.
     PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
     ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
     ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
         Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
         Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         Tp - Type[0..1]Defines the type of charges.
             Cd - Code[0..1]Charge type, in a coded form.
             Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                 Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                 Issr - Issuer[0..1]Entity that assigns the identification.
     MndtRltdInf - CreditTransferMandateData1[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
     Purp - Purpose[0..1]Underlying reason for the payment transaction.
         Cd - Code[0..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[0..1]
Purpose, in a proprietary form.
     RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
         DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
         Authrty - Authority[0..1]
Entity requiring the regulatory reporting information.
             Nm - Name[0..1]
Name of the entity requiring the regulatory reporting information.
             Ctry - Country[0..1]
Country of the entity that requires the regulatory reporting information.
         Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Tp - Type[0..1]
Specifies the type of the information supplied in the regulatory reporting details.
             Dt - Date[0..1]
Date related to the specified type of regulatory reporting details.
             Ctry - Country[0..1]
Country related to the specified type of regulatory reporting details.
             Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
             Amt - Amount[0..1]
Amount of money to be reported for regulatory and statutory requirements.
             Inf - Information[0..1]
Additional details that cater for specific domestic regulatory requirements.
     Tax - Tax[0..1]Provides details on the tax.
         Cdtr - Creditor[0..1]
Party on the credit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the creditor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
         Dbtr - Debtor[0..1]
Party on the debit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         UltmtDbtr - UltimateDebtor[0..1]
Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         AdmstnZone - AdministrationZone[0..1]
Territorial part of a country to which the tax payment is related.
         RefNb - ReferenceNumber[0..1]
Tax reference information that is specific to a taxing agency.
         Mtd - Method[0..1]
Method used to indicate the underlying business or how the tax is paid.
         TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
Total amount of money on which the tax is based.
         TtlTaxAmt - TotalTaxAmount[0..1]
Total amount of money as result of the calculation of the tax.
         Dt - Date[0..1]
Date by which tax is due.
         SeqNb - SequenceNumber[0..1]
Sequential number of the tax report.
         Rcrd - Record[0..1]
Details of the tax record.
             Tp - Type[0..1]
High level code to identify the type of tax details.
             Ctgy - Category[0..1]
Specifies the tax code as published by the tax authority.
             CtgyDtls - CategoryDetails[0..1]
Provides further details of the category tax code.
             DbtrSts - DebtorStatus[0..1]
Code provided by local authority to identify the status of the party that has drawn up the settlement document.
             CertId - CertificateIdentification[0..1]
Identification number of the tax report as assigned by the taxing authority.
             FrmsCd - FormsCode[0..1]
Identifies, in a coded form, on which template the tax report is to be provided.
             Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                 Yr - Year[0..1]
Year related to the tax payment.
                 Tp - Type[0..1]
Identification of the period related to the tax payment.
                 FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                     FrDt - FromDate[0..1]Start date of the range.
                     ToDt - ToDate[0..1]End date of the range.
             TaxAmt - TaxAmount[0..1]
Set of elements used to provide information on the amount of the tax record.
                 Rate - Rate[0..1]
Rate used to calculate the tax.
                 TaxblBaseAmt - TaxableBaseAmount[0..1]
Amount of money on which the tax is based.
                 TtlAmt - TotalAmount[0..1]
Total amount that is the result of the calculation of the tax for the record.
                 Dtls - Details[0..1]
Set of elements used to provide details on the tax period and amount.
                     Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                         Yr - Year[0..1]
Year related to the tax payment.
                         Tp - Type[0..1]
Identification of the period related to the tax payment.
                         FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                             FrDt - FromDate[0..1]Start date of the range.
                             ToDt - ToDate[0..1]End date of the range.
                     Amt - Amount[0..1]
Underlying tax amount related to the specified period.
             AddtlInf - AdditionalInformation[0..1]
Further details of the tax record.
     RltdRmtInf - RemittanceLocation8[0..0]
     RmtInf - RemittanceInformation22[0..0]
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/quotes_error_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/quotes_error_PUT.md new file mode 100644 index 000000000..aca4b1d12 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/quotes_error_PUT.md @@ -0,0 +1,184 @@ +--- +sidebarTitle: "PUT /quotes/{ID}/error" +--- + + +## 7.9 PUT /quotes/{ID}/error +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(DFSP -> DFSP, HUB -> DFSP)* + +This is triggered as a callback response to the POST /quotes call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` + +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[1..1]Specifies the reason for the status report.
             Cd - Code[1..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[0..1]Specified date.
         DtTm - DateTime[0..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/transfers_PATCH.md b/docs/fr/product/features/Iso20022/v1.0/script/transfers_PATCH.md new file mode 100644 index 000000000..39186dc49 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/transfers_PATCH.md @@ -0,0 +1,184 @@ +--- +sidebarTitle: "PATCH /transfers/{ID}" +--- + +## 7.17 PATCH /transfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(HUB -> DFSP)* + +This message use by the HUB to inform a payee DFSP participant of the successful conclusion of a transfer. This message is only generated if the payee DFSP response with a Reserved status when providing the fulfillment in the `PUT \transfers` message. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"COMM"} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[1..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[0..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[0..1]Specifies the reason for the status report.
             Cd - Code[0..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[0..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[1..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[1..1]Specified date.
         DtTm - DateTime[1..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/transfers_POST.md b/docs/fr/product/features/Iso20022/v1.0/script/transfers_POST.md new file mode 100644 index 000000000..90736be69 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/transfers_POST.md @@ -0,0 +1,627 @@ +--- +sidebarTitle: POST /transfers +--- + +## 7.14 POST /transfers +| Financial Institution to Financial Institution Customer Credit Transfer - **pacs.008.001.13**| +|--| + +#### Contexte +*(DFSP -> DFSP)* + +This message is initiated by a payer DFSP who is requesting to transfer funds. The message is sent to the payee DFSP who provided the transfer terms in the `PUT /quotes` message. This message is an acknowledgement that the terms of the transfer are accepted, and is thus an instruction to proceed with the transfer. + +The transfer amount which is the clearing amount that the payee DFSP receives is defined in the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` and `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` fields. If this transfer includes currency conversion, then this amount an currency must correspond with the target amount and currency. + +This message can be seen as an agreement to the terms that have previously been set up and established in the `PUT \quotes` message. The `CdtTrfTxInf.VrfctnOfTerms.IlpV4PrepPacket` field is the ILP packet containing the terms that have been agreed to. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the this transfer message. It is the responsibility of the HUB to enforce this expiry. The status of which a DFSP can query by making a `GET /transfers/{ID}` request. + +Voici un exemple de message : +```json +{ +"GrpHdr":{ + "MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM", + "CreDtTm":"2024-11-04T12:57:45.812Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "ChrgBr":"CRED", + "Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16665551002"}}}}, + "Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16135551001"}}}, + "Name":"Joe Blogs"}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
     CreDtTm - ISODateTime[1..1]Creation Date and Time
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[1..1]Number of Transactions
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
         SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
         ClrSys - ClearingSystemIdentification3Choice[0..0]
         InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
Set of elements providing information specific to the individual credit transfer(s).
     PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
         InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

Definition: Unique identification, as assigned by an instructing party for an instructed party, to
unambiguously identify the instruction.

Usage: The instruction identification is a point to point reference that can be used between the
instructing party and the instructed party to refer to the individual instruction. It can be included in
several messages related to the instruction.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
transaction. It can be included in several messages related to the transaction.

Usage: In case there are technical limitations to pass on multiple references, the end-to-end
identification must be passed on throughout the entire end-to-end chain.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
transaction that is passed on, unchanged, throughout the entire interbank chain.

Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
the transaction on the interbank level.

Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
         UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
         ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
     PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
         InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
would like the instructed party to apply to the processing of the instruction.

HIGH: High priority
NORM: Normal priority
         ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
the payment type identification.

RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
BOOK: BookTransfer Payment through internal book transfer.
         SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
             Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
             Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
         LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
             Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
             Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
         CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
             Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
             Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
     IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmPrty - Priority3Code[0..0]
     SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
     SttlmTmReq - SettlementTimeRequest2[0..0]
     AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
date and a mandatory time component, expressed in either UTC time
format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
(YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
(YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
"XML Schema Part 2: Datatypes Second Edition -
W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

Note on the time format:
1) beginning / end of calendar day
00:00:00 = the beginning of a calendar day
24:00:00 = the end of a calendar day

2) fractions of second in time format
Decimal fractions of seconds may be included. In this case, the
involved parties shall agree on the maximum number of digits that are allowed.
     PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
     XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
     ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
     ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
         Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
         Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         Tp - Type[0..1]Defines the type of charges.
             Cd - Code[0..1]Charge type, in a coded form.
             Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                 Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                 Issr - Issuer[0..1]Entity that assigns the identification.
     MndtRltdInf - CreditTransferMandateData1[0..0]
     PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
     IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
     UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
         FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
             ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                 ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                     Cd - Code[0..1]Clearing system identification code, as published in an external list.
                     Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                 MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
             LEI - LEI[0..1]Legal entity identifier of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                 Id - Identification[1..1]Unique and unambiguous identification of a person.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
             Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
             LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
             Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
             PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
     CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
     Cdtr - Creditor[1..1]Party to which an amount of money is due.
         Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
         PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
             AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                 Cd - Code[0..1]Type of address expressed as a code.
                 Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                     Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                     Issr - Issuer[0..1]Entity that assigns the identification.
                     SchmeNm - SchemeName[0..1]Short textual description of the scheme.
             CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
             Dept - Max70Text[0..1]Name of a department within an organization.
             SubDept - Max70Text[0..1]Name of a sub-department within a department.
             StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
             BldgNb - Max16Text[0..1]Number that identifies a building on the street.
             BldgNm - Max140Text[0..1]Name of the building, if applicable.
             Flr - Max70Text[0..1]Floor number or identifier within a building.
             UnitNb - Max16Text[0..1]Unit or apartment number within a building.
             PstBx - Max16Text[0..1]Post office box number.
             Room - Max70Text[0..1]Room number or identifier within a building.
             PstCd - Max16Text[0..1]Postal code or ZIP code.
             TwnNm - Max140Text[0..1]Name of the town or city.
             TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
             DstrctNm - Max140Text[0..1]Name of the district or region.
             CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
             Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
             AdrLine - Max70Text[0..1]Free-form text line for the address.
         Id - Identification[1..1]Unique and unambiguous identification of a party.
             OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                 AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                 LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                 Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                 DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                     BirthDt - BirthDate[0..1]Date on which a person was born.
                     PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                     CityOfBirth - CityOfBirth[0..1]City where a person was born.
                     CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                 Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
         CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
             NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
             MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
             FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
             URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
             EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
             EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
             JobTitl - JobTitle[0..1]Title of the function.
             Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
             Dept - Department[0..1]Identification of a division of a large organisation or building.
             Othr - OtherContact[0..1]Contact details in another form.
                 ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                 Id - Identifier[0..1]Communication value such as phone number or email address.
             PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
     CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
         Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
             IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
             Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                 Id - Identification[0..1]Identification assigned by an institution.
                 SchmeNm - SchemeName[0..1]Name of the identification scheme.
                     Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                 Issr - Issuer[0..1]Entity that assigns the identification.
         Tp - Type[0..1]Specifies the nature, or use of the account.
             Cd - Code[0..1]Account type, in a coded form.
             Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
         Ccy - Currency[0..1]Identification of the currency in which the account is held.
Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
         Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
         Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
             Tp - Type[0..1]Type of the proxy identification.
                 Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                 Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
             Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
     UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
     InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
     InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
         Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
     Purp - Purpose[0..1]Underlying reason for the payment transaction.
         Cd - Code[0..1]
Underlying reason for the payment transaction, as published in an external purpose code list.
         Prtry - Proprietary[0..1]
Purpose, in a proprietary form.
     RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
         DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
         Authrty - Authority[0..1]
Entity requiring the regulatory reporting information.
             Nm - Name[0..1]
Name of the entity requiring the regulatory reporting information.
             Ctry - Country[0..1]
Country of the entity that requires the regulatory reporting information.
         Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Tp - Type[0..1]
Specifies the type of the information supplied in the regulatory reporting details.
             Dt - Date[0..1]
Date related to the specified type of regulatory reporting details.
             Ctry - Country[0..1]
Country related to the specified type of regulatory reporting details.
             Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
             Amt - Amount[0..1]
Amount of money to be reported for regulatory and statutory requirements.
             Inf - Information[0..1]
Additional details that cater for specific domestic regulatory requirements.
     Tax - Tax[0..1]Provides details on the tax.
         Cdtr - Creditor[0..1]
Party on the credit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the creditor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
         Dbtr - Debtor[0..1]
Party on the debit side of the transaction to which the tax applies.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         UltmtDbtr - UltimateDebtor[0..1]
Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
             TaxId - TaxIdentification[0..1]
Tax identification number of the debtor.
             RegnId - RegistrationIdentification[0..1]
Unique identification, as assigned by an organisation, to unambiguously identify a party.
             TaxTp - TaxType[0..1]
Type of tax payer.
             Authstn - Authorisation[0..1]
Details of the authorised tax paying party.
                 Titl - Title[0..1]
Title or position of debtor or the debtor's authorised representative.
                 Nm - Name[0..1]
Name of the debtor or the debtor's authorised representative.
         AdmstnZone - AdministrationZone[0..1]
Territorial part of a country to which the tax payment is related.
         RefNb - ReferenceNumber[0..1]
Tax reference information that is specific to a taxing agency.
         Mtd - Method[0..1]
Method used to indicate the underlying business or how the tax is paid.
         TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
Total amount of money on which the tax is based.
         TtlTaxAmt - TotalTaxAmount[0..1]
Total amount of money as result of the calculation of the tax.
         Dt - Date[0..1]
Date by which tax is due.
         SeqNb - SequenceNumber[0..1]
Sequential number of the tax report.
         Rcrd - Record[0..1]
Details of the tax record.
             Tp - Type[0..1]
High level code to identify the type of tax details.
             Ctgy - Category[0..1]
Specifies the tax code as published by the tax authority.
             CtgyDtls - CategoryDetails[0..1]
Provides further details of the category tax code.
             DbtrSts - DebtorStatus[0..1]
Code provided by local authority to identify the status of the party that has drawn up the settlement document.
             CertId - CertificateIdentification[0..1]
Identification number of the tax report as assigned by the taxing authority.
             FrmsCd - FormsCode[0..1]
Identifies, in a coded form, on which template the tax report is to be provided.
             Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                 Yr - Year[0..1]
Year related to the tax payment.
                 Tp - Type[0..1]
Identification of the period related to the tax payment.
                 FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                     FrDt - FromDate[0..1]Start date of the range.
                     ToDt - ToDate[0..1]End date of the range.
             TaxAmt - TaxAmount[0..1]
Set of elements used to provide information on the amount of the tax record.
                 Rate - Rate[0..1]
Rate used to calculate the tax.
                 TaxblBaseAmt - TaxableBaseAmount[0..1]
Amount of money on which the tax is based.
                 TtlAmt - TotalAmount[0..1]
Total amount that is the result of the calculation of the tax for the record.
                 Dtls - Details[0..1]
Set of elements used to provide details on the tax period and amount.
                     Prd - Period[0..1]
Set of elements used to provide details on the period of time related to the tax payment.
                         Yr - Year[0..1]
Year related to the tax payment.
                         Tp - Type[0..1]
Identification of the period related to the tax payment.
                         FrToDt - FromToDate[0..1]
Range of time between a start date and an end date for which the tax report is provided.
                             FrDt - FromDate[0..1]Start date of the range.
                             ToDt - ToDate[0..1]End date of the range.
                     Amt - Amount[0..1]
Underlying tax amount related to the specified period.
             AddtlInf - AdditionalInformation[0..1]
Further details of the tax record.
     RltdRmtInf - RemittanceLocation8[0..0]
     RmtInf - RemittanceInformation22[0..0]
     SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/transfers_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/transfers_PUT.md new file mode 100644 index 000000000..fac05f53a --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/transfers_PUT.md @@ -0,0 +1,103 @@ +--- +sidebarTitle: "PUT /transfers/{ID}" +--- + +## 7.15 PUT /transfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(DFSP -> DFSP, DFSP -> HUB, HUB -> DFSP)* + +This message is a response to the `POST \transfers` call initiated by the DFSP who is requesting to proceed with the transfer terms presented in the `PUT \quotes`. It is the payee DFSPs responsibility to check that the clearing amounts align with the agreed transfer terms, and if all requirements are met, this message is used to lock-in the agreed terms. Once the hub receives this acceptance message, the transfer can no-longer timeout and will be committed. If this transfer is a dependent transfer in a currency conversion, then that currency conversion will be committed at the same time as this transfer. + +The cryptographic ILP fulfillment provided in the `TxInfAndSts.ExctnConf` field, is released by the payee DFSP as an indication to the HUB that the terms have been met. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{ + "DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +``` + +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader113[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     BtchBookg - BatchBookingIndicator[0..0]
     NbOfTxs - Max15NumericText[0..0]Specifies a numeric string with a maximum length of 15 digits.
     CtrlSum - DecimalNumber[0..0]
     TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
     IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
     SttlmInf - SettlementInstruction15[0..0]Only the CLRG: Clearing option is supported.
Specifies the details on how the settlement of the original transaction(s) between the
instructing agent and the instructed agent was completed.
     PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
CdtTrfTxInf - CreditTransferTransaction64[0..0]
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Iso20022/v1.0/script/transfers_error_PUT.md b/docs/fr/product/features/Iso20022/v1.0/script/transfers_error_PUT.md new file mode 100644 index 000000000..e2439ff78 --- /dev/null +++ b/docs/fr/product/features/Iso20022/v1.0/script/transfers_error_PUT.md @@ -0,0 +1,183 @@ +--- +sidebarTitle: "PUT /transfers/{ID}/error" +--- + +## 7.16 PUT /transfers/{ID}/error + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Contexte +*(DFSP -> DFSP, DFSP -> HUB, HUB -> DFSP)* + +This is triggered as a callback response to the POST /transfers call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Voici un exemple de message : +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Détails du message +La composition et l’utilisation de cette API sont décrites dans les sections suivantes : +1. [Éléments de données principaux](#core-data-elements)
Cette section précise quels champs sont obligatoires, facultatifs ou non pris en charge pour satisfaire les exigences de validation du message. +2. [Détails d’en-tête](../MarketPracticeDocument.md#_3-3-1-header-details)
Cette section générale décrit les exigences d’en-tête pour l’API. +3. [Réponses HTTP prises en charge](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
Cette section générale décrit les réponses HTTP qui doivent être prises en charge. +4. [Charge utile d’erreur commune](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
Cette section générale décrit la charge utile d’erreur fournie dans la réponse HTTP d’erreur synchrone. + +#### Éléments de données principaux +Voici les éléments de données principaux nécessaires pour satisfaire cette exigence de pratique du marché. + +Les couleurs de fond indiquent la classification de l’élément de données. + + + + + + + +
Clé de type du modèle de données Description
obligatoireCes champs sont obligatoires pour satisfaire les exigences de validation du message.
facultatifCes champs peuvent être inclus facultativement dans le message. (Certains peuvent être obligatoires pour un schéma donné, selon les règles du système.)
non pris en chargeCes champs ne sont pas pris en charge. Les fonctionnalités associées à ces données ne sont pas compatibles avec un schéma Mojaloop ; leur fourniture entraînera un échec de validation du message.
+

+ + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Champ ISO 20022Modèle de donnéesDescription
GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
     MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
     CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlBizQry - OriginalBusinessQuery1[0..0]
OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
     StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
     OrgnlGrpInf - OriginalGroupInformation29[0..0]
     OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original instruction.

(FSPIOP equivalent: transactionRequestId)
     OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original end-to-end transaction.

(FSPIOP equivalent: transactionId)
     OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
unambiguously identify the original transaction.

(FSPIOP equivalent: quoteId)
     OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
     TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
     StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
         Orgtr - Originator[0..1]Party that issues the status.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[0..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         Rsn - Reason[1..1]Specifies the reason for the status report.
             Cd - Code[1..1]Reason for the status, as published in an external reason code list.
             Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
         AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
     ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

Seemingly a generic schema for charges, with an amount, agent, and type.
     AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
     PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
         Dt - Date[0..1]Specified date.
         DtTm - DateTime[0..1]Specified date and time.
     FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
     AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
     ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
     InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
     OrgnlTxRef - OriginalTransactionReference42[0..0]
     SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
     PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
     Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
+ diff --git a/docs/fr/product/features/Production_Readiness_Technical_Assessment.md b/docs/fr/product/features/Production_Readiness_Technical_Assessment.md new file mode 100644 index 000000000..7226f21f9 --- /dev/null +++ b/docs/fr/product/features/Production_Readiness_Technical_Assessment.md @@ -0,0 +1,32 @@ +--- +sidebarTitle: Préparation production +--- + +# Évaluation technique de préparation à la production + +| Catégorie | Description de l’exigence | +| --- | --- | +| Général | Votre instance Mojaloop de production sur cluster Kubernetes compte au moins 3 nœuds *master* et 3 nœuds *worker* répondant aux spécifications minimales suivantes :

- 3 nœuds master/worker : serveur entreprise milieu de gamme, minimum 128 cœurs CPU, 1024 Go RAM, 4 × 500 Go NVMe en RAID miroir, 2 × 10 GbE
- 5 nœuds worker et plus : serveur entreprise milieu de gamme, minimum 64 cœurs CPU, 512 Go RAM, 4 × 500 Go NVMe en RAID miroir, 2 × 10 GbE

Remarques :
- Les nœuds worker peuvent aussi être des masters, ce qui n’est pas recommandé pour la charge de production.
- Les spécifications des nœuds doivent être plus élevées s’il y en a moins. | +| Sécurité | Vous utilisez l’une des méthodes suivantes pour terminer le mTLS entre participants et switch :
- Passerelle applicative du fournisseur cloud
- Pare-feu du fournisseur cloud
- Répartiteur de charge du fournisseur cloud
- Ingress NGINX Kubernetes
- Passerelle API Kubernetes, ex. ISTIO
- Pare-feu matériel entreprise | +| | Vous utilisez une ou plusieurs des méthodes suivantes pour sécuriser les secrets en production :
- Hashicorp Vault dans le cluster
- Coffre de secrets du fournisseur cloud
- Appliance entreprise de stockage sécurisé des secrets | +| | Vous utilisez une ou plusieurs des méthodes suivantes pour exploiter votre autorité de certification pour la génération de paires de clés mTLS et la signature des certificats participants :

- Mojaloop Connection Manager
- Hashicorp Vault dans le cluster
- Plateforme CA entreprise
- Autorité de certification tierce de confiance, ex. DigiCert, GlobalSign, etc. | +| | Vous avez configuré le RBAC sur tous les portails Mojaloop pour limiter l’accès au personnel autorisé. | +| | Vous utilisez une liste d’adresses IP autorisées pour contrôler l’accès aux services Mojaloop.

(par défaut = blocage) | +| | Vous utilisez un pare-feu IP pour contrôler l’accès à votre infrastructure de production. | +| Gestion des utilisateurs | Tous vos participants signent les messages JWS et vérifient les signatures. | +| | Vous appliquez des contrôles de processus et techniques pour tout le personnel accédant à l’infrastructure et aux services applicatifs Mojaloop. | +| Résilience et fiabilité | Vous exécutez au minimum 3 instances saines en permanence des pods suivants :

ml-api-adapter, ml-api-adapter-handler-notification, central-ledger-service, central-ledger-handler-admin, central-ledger-handler-prepare, central-ledger-handler-position, central-ledger-handler-fulfil, central-ledger-handler-get, account-lookup-service, account-lookup-service-admin, moja-quoting-service, moja-centralsettlement-handler-deferred, moja-centralsettlement-handler-gross, moja-centralsettlement-handler-rules, moja-centralsettlement-service, (moja-cl-handler-bulk-transfer-fulfil, moja-cl-handler-bulk-transfer-get, moja-cl-handler-bulk-transfer-prepare, moja-cl-handler-bulk-transfer-processing)

Remarque : les éléments entre parenthèses dépendent de fonctionnalités optionnelles. | +| | Vous avez testé avec succès les mécanismes de récupération des pods Kubernetes pour faire face aux pannes et remplacer rapidement les pods dégradés afin de respecter vos SLA. | +| | Toutes les bases de données Mojaloop tournent en instances répliquées de façon synchrone avec au minimum 3 réplicas sains en permanence. | +| | Tous les pods avec état Mojaloop utilisent l’une des technologies de stockage sous-jacentes suivantes :

- Stockage NVMe sur nœud chiffré, en RAID miroir (voir spécifications des nœuds, section générale)
- Stockage cloud du fournisseur chiffré et répliqué.
- SAN entreprise chiffré et répliqué (non recommandé en production). | +| | Tous les pods de base de données Mojaloop sont planifiés sur des nœuds physiques distincts et y stockent leurs données. | +| | Tous les pods ZooKeeper Kafka sont planifiés sur des nœuds physiques distincts et y stockent leurs données. | +| | Tous les pods courtier Kafka sont planifiés sur des nœuds physiques distincts et y stockent leurs données. | +| | Un processus d’archivage des données est défini pour que les magasins de données de production ne dépassent pas une taille nuisible aux performances ou au risque d’épuisement d’espace libre. | +| | Votre stockage d’archives est chiffré au repos, répliqué et d’un niveau suffisant pour vos exigences métier et réglementaires. | +| Tests | Vous avez exécuté avec succès la suite de tests *golden path* Mojaloop et tous les tests passent. | +| Remarque : cette section est en cours d’extension par le workstream QA Framework | Vous avez exécuté avec succès des suites de tests adjacentes pour des fonctionnalités personnalisées ou complémentaires et tous les tests passent. | +| | Vous avez mené un test de charge réussi démontrant que votre instance de production supporte le trafic normal et de pointe attendu tout en respectant vos SLA. | +| | Vous avez mené un test d’endurance (*soak*) réussi démontrant la stabilité de votre instance sur de longues périodes sans défaillance inattendue ni erreur irrécupérable. | +| | Vous avez mené un test d’intrusion réussi sur votre instance de production et l’infrastructure associée, sans vulnérabilité identifiée. | +| | Vous avez mené des tests de chaos réussis sur votre instance de production et prouvé que la défaillance simultanée de plusieurs composants est tolérée sans états incohérents ou irrécupérables.

Remarque : le nombre et la nature des pannes simultanées tolérées sont en partie subjectifs, mais vous devez pouvoir démontrer qu’un ensemble de pannes « raisonnablement anticipées » est toléré sans rupture de vos SLA définis. | diff --git a/docs/fr/product/features/SimpleInterscheme.svg b/docs/fr/product/features/SimpleInterscheme.svg new file mode 100644 index 000000000..33e945028 --- /dev/null +++ b/docs/fr/product/features/SimpleInterscheme.svg @@ -0,0 +1,4 @@ + + + +
Scheme 1
Scheme 1
Scheme 2
Scheme 2
DFSP 1
DFSP 1
DFSP 2
DFSP 2
Proxy
Proxy
\ No newline at end of file diff --git a/docs/fr/product/features/Test.png b/docs/fr/product/features/Test.png new file mode 100644 index 000000000..c68bb2e19 Binary files /dev/null and b/docs/fr/product/features/Test.png differ diff --git a/docs/fr/product/features/XB.svg b/docs/fr/product/features/XB.svg new file mode 100644 index 000000000..ac97cc76a --- /dev/null +++ b/docs/fr/product/features/XB.svg @@ -0,0 +1,4 @@ + + + +
Jurisdiction B
Jurisdiction B
Jurisdiction A
Jurisdiction A
Scheme 1
Scheme 1
Scheme 2
Scheme 2
DFSP 1
DFSP 1
DFSP 2
DFSP 2
Proxy
Proxy
FXP 1
FXP 1
FXP 3
FXP 3
FXP 2
FXP 2
\ No newline at end of file diff --git a/docs/fr/product/features/connectivity.md b/docs/fr/product/features/connectivity.md new file mode 100644 index 000000000..a7720393c --- /dev/null +++ b/docs/fr/product/features/connectivity.md @@ -0,0 +1,50 @@ +--- +sidebarTitle: Onboarding des DFSP +--- + +# Intégration des DFSP (onboarding) + +En principe, le développement et la documentation des [API Mojaloop](./transaction.md#mojaloop-apis) devraient suffire pour permettre aux DFSP de se connecter à un Hub Mojaloop. Toutefois, dans le cadre de la mission de la communauté Mojaloop en faveur de l’inclusion financière, il est depuis longtemps considéré que la clé pour réduire le coût et la complexité de la connexion du back office d’un DFSP à un Hub Mojaloop réside dans une offre de solutions de connectivité, permettant à un DFSP de choisir l’approche qui répond le mieux à ses besoins. Ces éléments sont complétés par un *DFSP Onboarding Playbook*, qui encapsule les processus métier nécessaires à l’intégration d’un DFSP. + +## Intégration métier (onboarding) + +De nombreuses étapes de l’intégration d’un DFSP à un Hub Mojaloop ne relèvent pas de la technologie ; elles sont traitées dans le DFSP Onboarding Playbook. + +Ce playbook, offert par Thitsaworks, rassemble des outils et modèles pour aider à planifier et exécuter un déploiement Mojaloop, en se concentrant sur l’onboarding des DFSP. Les éléments proposés sont : +- un modèle de plan de travail, avec des exemples issus de déploiements passés ; +- un cas de test de bout en bout, ici pour l’intégration côté bénéficiaire ; +- un formulaire d’évaluation technique, pour définir l’assistance technique dont les DFSP candidats ont besoin ; +- une liste de contrôle d’intégration technique ; +- un modèle de cartographie des API, pour relier les éléments d’API du Hub Mojaloop aux actions correspondantes du système d’information du DFSP ; +- un plan de configuration de la sécurité de la connexion du DFSP au Hub Mojaloop. + +Vous pouvez [télécharger le DFSP Onboarding Playbook de Thitsaworks via ce lien](https://github.com/mojaloop/product-council/tree/main/Documentation/DFSP%20Playbook). + +## Intégration technique (onboarding) + +L’offre actuelle de connectivité comprend l’Integration Toolkit (ITK), qui permet à un intégrateur système (SI) de créer une connexion en combinant les différents éléments d’un toolkit de la manière la plus adaptée aux besoins du DFSP. Ces éléments incluent : + - Mojaloop Connection Manager (MCM) ; + - Mojaloop Connector (pour l’intégration au Hub Mojaloop) ; + - un ensemble d’exemples de Core Connectors (pour le lien avec le système d’information du DFSP) ; + - de la documentation, dont des guides pratiques et des modèles. + +Pour les DFSP de grande taille, la communauté Mojaloop propose Payment Manager en alternative à l’ITK. Également appelé Payment Manager for Mojaloop (PM4ML), il offre l’ensemble des fonctionnalités et de la flexibilité qu’une grande banque peut exiger. + +Les différents outils de connectivité pour intégrer un DFSP à un Hub Mojaloop sont détaillés dans les [mini-guides](./connectivity/participation_tools_mini_guides.md) ; le choix de solution selon le type de participant et les exigences est présenté dans la [matrice des fonctionnalités par participant](./connectivity/participant-matrix.md). + +Tous les DFSP doivent avoir à l’esprit que les bénéfices d’une solution de paiement instantané inclusive comme Mojaloop reposent sur une démarche « écosystème complet » : il faut étendre la portée du service Mojaloop dans les domaines des DFSP, leur offrant ainsi à eux et à leurs clients l’assurance de finalité des transactions, des coûts plus bas et une exécution fiable de chaque transaction valide. + +Notez que le mode de déploiement de l’ITK influe sur le type de service qu’un DFSP peut offrir à ses clients, comme le soulignent les [mini-guides](./connectivity/participation_tools_mini_guides.md). Les options les plus exigeantes en ressources conviennent aux DFSP à fort débit et à fortes exigences de disponibilité ; une option de déploiement modérée impose certaines limites sur le débit et la disponibilité et peut mieux convenir aux DFSP moyens ou petits ; l’option la plus légère impose des limites strictes sur le débit et la disponibilité et supprime la possibilité d’initier des paiements de masse, et ne convient donc qu’aux petits DFSP. + +## Applicabilité + +La présente version de ce document se rapporte à Mojaloop version [17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.4|17 décembre 2025| Paul Makin |Ajout du lien vers les mini-guides ; clarification du texte pour mettre en évidence le rôle de l’ITK| +|1.3|6 novembre 2025| Paul Makin|Lien ajouté vers le DFSP Onboarding Playbook de Thitsaworks| +|1.2|9 juin 2025| Tony Williams|Ajout d’une référence à la matrice des fonctionnalités par participant| +|1.1|14 avril 2025| Paul Makin|Mises à jour liées à la publication de la V17| +|1.0|5 février 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/connectivity/images/ITK_architecture.png b/docs/fr/product/features/connectivity/images/ITK_architecture.png new file mode 100644 index 000000000..fdc1aa0e6 Binary files /dev/null and b/docs/fr/product/features/connectivity/images/ITK_architecture.png differ diff --git a/docs/fr/product/features/connectivity/images/PM4ML_system_architecture.png b/docs/fr/product/features/connectivity/images/PM4ML_system_architecture.png new file mode 100644 index 000000000..568cb6cdf Binary files /dev/null and b/docs/fr/product/features/connectivity/images/PM4ML_system_architecture.png differ diff --git a/docs/fr/product/features/connectivity/participant-matrix.md b/docs/fr/product/features/connectivity/participant-matrix.md new file mode 100644 index 000000000..101dcc318 --- /dev/null +++ b/docs/fr/product/features/connectivity/participant-matrix.md @@ -0,0 +1,180 @@ +--- +sidebarTitle: Matrice des participants +--- + +# Matrice des fonctionnalités par participant + +Ce document présente une matrice détaillée des types de participants, de leurs exigences et des solutions de connectivité recommandées pour l’intégration Mojaloop. + + + +## DFSP et cas d’usage paiement + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Catégorie de participantDescriptionCas d’usage attendusExigences d’infrastructure pour l’intégration MojaloopSLA de production attenduRéglementation probablement pertinenteExigences de sécurité particulièresOptions de solution
Petit DFSP en auto-hébergement- Petite institution financière à agence unique.
- Postes de travail propres
- Cloud et/ou SaaS minimaux.
- Tous les types de transfert Mojaloop sauf masse.
- Open banking (y compris PISP, AISP)
- Mini-PC dédié bon marché bas de gamme (p. ex. RPi)
- Connexion Internet haut débit petite entreprise unique
- Système bancaire cœur auto-hébergé p. ex. Mifos
- Pare-feu OS/logiciel sur le même nœud matériel que la couche d’intégration.
- Une certaine indisponibilité acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- L’achat de matériel de remplacement en cas de panne totale peut prendre plusieurs jours/semaines.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- ~10 TPS de pic soutenu pendant 1 heure.
- Capacité max. 864000 sur 24 heures.
- Tenue des registres ?
- Sécurité ?
- Pas besoin d’intégration avec les plateformes de sécurité d’entreprise existantes.
- Solution entièrement sécurisée « prête à l’emploi » suivant les bonnes pratiques du secteur pour les services exposés à Internet, y compris pare-feu.
Le « Standard Service Manager » est recommandé : solution minimale basée sur l’Integration Toolkit (accessible localement via un outil BI). Elle peut être hébergée sur un serveur de base, d’un serveur milieu de gamme pour une grande IMF ou une petite banque jusqu’à un Raspberry Pi pour les plus petits DFSP avec des exigences de continuité de service moins strictes et des volumes de transaction plus faibles. Le Standard Service Manager ne prend pas en charge les paiements de masse.
- Couche d’intégration basée sur Docker Compose.
- Couche d’intégration minimale autonome.
DFSP faible-moyen en auto-hébergement- Petite institution financière à une ou deux agences.
- Propre « centre de données », c.-à-d. placard à balais avec quelques serveurs, routeur, pare-feu, etc.
- Quelques connaissances cloud et/ou usage SaaS.
- Tous les types de transfert Mojaloop
- Masse (milliers de transferts).
- Open banking (y compris PISP, AISP)
- Nœud matériel serveur de qualité entreprise unique.
- Pare-feu OS/logiciel sur le même nœud matériel que la couche d’intégration OU pare-feu matériel dédié.
- Une certaine indisponibilité acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- Le remplacement du matériel en cas de panne totale peut prendre des heures.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- ~50 TPS de pic soutenu pendant 1 heure.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.
?? à préciser
Le « Enhanced Service Manager » est recommandé : il étend le « Standard Service Manager » décrit précédemment en ajoutant un déploiement Kafka et la prise en charge des paiements de masse. Il peut être hébergé au minimum sur un serveur de base dans le « centre de données » du DFSP.
- Couche d’intégration basée sur Docker Compose ou Docker Swarm.
- Couche d’intégration minimale autonome.
DFSP moyen-élevé en auto-hébergement- Petite institution financière à une ou deux agences.
- Propre « centre de données », c.-à-d. placard à balais avec quelques serveurs, routeur, pare-feu, etc.
- Quelques connaissances cloud et/ou usage SaaS.
- Tous les types de transfert Mojaloop
- Masse (milliers de transferts).
- Open banking (y compris PISP, AISP)
- Pour tolérer la panne d’un nœud matériel, 3 nœuds matériels ou plus sont requis (2n+1).- Indisponibilité limitée (minutes) acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- Matériel de rechange disponible ou services de remplacement très rapides en cas de panne.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- ~50 TPS de pic soutenu pendant 1 heure.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.Le « Enhanced Service Manager » est recommandé : il étend le « Standard Service Manager » décrit précédemment en ajoutant un déploiement Kafka et la prise en charge des paiements de masse. Il peut être hébergé au minimum dans une configuration multi-serveurs redondante du « centre de données » du DFSP.
- Couche d’intégration basée sur Kubernetes
- Peut disposer déjà d’une technologie d’intégration.
Grand DFSP en auto-hébergement- Institution financière mature multi-agences avec forte capacité informatique interne
- Dispose de son propre centre de données et d’experts pour gérer les systèmes
- À l’aise avec le cloud et les applications hybrides
- Dispose d’une capacité d’ingénierie logicielle interne.
- Tous les types de transfert Mojaloop y compris masse.
- Masse (millions de transferts dans une transaction par paquets de 1000, triés par DFSP bénéficiaire).
- Open banking (y compris PISP, AISP)
- Haute disponibilité de l’infrastructure interne nécessaire
- Plusieurs instances actives de tous les services d’intégration critiques réparties sur plusieurs nœuds matériels.
- Stockage de données répliqué haute disponibilité.
- peut être multi-site / zone de disponibilité / région.
- Aucune indisponibilité acceptable
- Haute disponibilité de la connectivité.
- plusieurs connexions actives par des routes diversifiées.
- Stockage persistant facultatif.
- Le SLA de connexion au schéma et de la couche d’intégration doit s’aligner sur le SLA de l’infrastructure interne existante.
- Jusqu’à 800 TPS de pic soutenu pendant 1 heure pour les FXP par exemple.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.Le « Premium Service Manager » est recommandé : service de type Payment Manager pleinement fonctionnel pour les grands DFSP. Son exploitation demande des ressources importantes ; il doit être hébergé soit dans le centre de données existant du DFSP, soit dans le cloud.
- Couche d’intégration basée sur Kubernetes
- Peut disposer déjà d’une technologie d’intégration.
+ +## Fintechs utilisant PISP et/ou AISP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Catégorie de participantDescriptionCas d’usage attendusExigences d’infrastructure pour l’intégration MojaloopSLA de production attenduRéglementation probablement pertinenteExigences de sécurité particulièresOptions de solution
Petit PISP/AISP en auto-hébergement- Petite organisation « agence » unique avec un ou deux produits.
- Postes de travail / serveurs propres
- Cloud et/ou SaaS minimaux.
- Paiements de masse relativement modestes, p. ex. salaires pour PME- Mini-PC dédié bon marché bas de gamme (p. ex. RPi)
- Connexion Internet haut débit petite entreprise unique
- Système bancaire cœur auto-hébergé p. ex. Mifos
- Pare-feu OS/logiciel sur le même nœud matériel que la couche d’intégration.
- Une certaine indisponibilité acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- L’achat de matériel de remplacement en cas de panne totale peut prendre plusieurs jours/semaines.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- SLA interface masse ?
- Comment le définir ? Taille de lot ? Temps d’envoi du lot via API ? Délai de réponse aux callbacks ?
- Taille max. de lot ~10k paiements
- L’envoi de 10k paiements via l’API masse doit prendre < 30 secondes.
- La réponse aux callbacks doit prendre < 5 secondes.
- Tenue des registres ?
- Sécurité ?
- Pas besoin d’intégration avec les plateformes de sécurité d’entreprise existantes.
- Solution entièrement sécurisée « prête à l’emploi » suivant les bonnes pratiques du secteur pour les services exposés à Internet, y compris pare-feu.
- Couche d’intégration basée sur Docker Compose.
- Couche d’intégration minimale autonome.
PISP/AISP faible-moyen en auto-hébergement- Petite organisation à une ou deux agences.
- Propre « centre de données », c.-à-d. placard à balais avec quelques serveurs, routeur, pare-feu, etc.
- Quelques connaissances cloud et/ou usage SaaS.
- Paiements de masse relativement modestes, p. ex. salaires pour PME
- Agrégation de comptes
- Nœud matériel serveur de qualité entreprise unique.
- Pare-feu OS/logiciel sur le même nœud matériel que la couche d’intégration OU pare-feu matériel dédié.
- Une certaine indisponibilité acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- Le remplacement du matériel en cas de panne totale peut prendre des heures.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- SLA interface masse ?
- Comment le définir ? Taille de lot ? Temps d’envoi du lot via API ? Délai de réponse aux callbacks ?
- Taille max. de lot ~25k paiements
- L’envoi de 25k paiements via l’API masse doit prendre < 60 secondes.
- La réponse aux callbacks doit prendre < 10 secondes.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.
?? à préciser
- Couche d’intégration basée sur Docker Compose ou Docker Swarm.
- Couche d’intégration minimale autonome.
PISP/AISP moyen-élevé en auto-hébergement- Petite organisation à une ou deux agences.
- Propre « centre de données », c.-à-d. placard à balais avec quelques serveurs, routeur, pare-feu, etc.
- Quelques connaissances cloud et/ou usage SaaS.
- Paiement de masse pour grandes organisations, p. ex. ministères
- Agrégation de comptes
- Pour tolérer la panne d’un nœud matériel, 3 nœuds matériels ou plus sont requis (2n+1).- Indisponibilité limitée (minutes) acceptable en cas de panne matérielle.
- Certains schémas peuvent exclure les DFSP qui ne respectent pas un SLA d’indisponibilité donné.
- Matériel de rechange disponible ou services de remplacement très rapides en cas de panne.
- Jeu complet de fonctions de sécurité Mojaloop : mTLS, JWS, ILP
- SLA interface masse ?
- Comment le définir ? Taille de lot ? Temps d’envoi du lot via API ? Délai de réponse aux callbacks ?
- Taille max. de lot ~100-200k paiements
- L’envoi de 100-200k paiements via l’API masse doit prendre < 300 secondes.
- La réponse aux callbacks doit prendre < 120 secondes.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.- Couche d’intégration basée sur Kubernetes
- Peut disposer déjà d’une technologie d’intégration.
Grand PISP/AISP en auto-hébergement- Organisation mature multi-agences avec forte capacité informatique interne
- Dispose de son propre centre de données et d’experts pour gérer les systèmes
- À l’aise avec le cloud et les applications hybrides
- Dispose d’une capacité d’ingénierie logicielle interne.
- Paiement de masse pour grandes organisations, p. ex. ministères- Haute disponibilité de l’infrastructure interne nécessaire
- Plusieurs instances actives de tous les services d’intégration critiques réparties sur plusieurs nœuds matériels.
- Stockage de données répliqué haute disponibilité.
- peut être multi-site / zone de disponibilité / région.
- Aucune indisponibilité acceptable
- Haute disponibilité de la connectivité.
- plusieurs connexions actives par des routes diversifiées.
- Stockage persistant facultatif.
- Le SLA de connexion au schéma et de la couche d’intégration doit s’aligner sur le SLA de l’infrastructure interne existante.
- SLA interface masse ?
- Comment le définir ? Taille de lot ? Temps d’envoi du lot via API ? Délai de réponse aux callbacks ?
- Taille max. de lot ~1M paiements
- L’envoi de 1M paiements via l’API masse doit prendre < 600 secondes.
- La réponse aux callbacks doit prendre < 300 secondes.
- Tenue des registres ?
- Sécurité ?
- Peut nécessiter une intégration avec les plateformes de sécurité d’entreprise existantes, p. ex. pare-feu, passerelles, etc.- Couche d’intégration basée sur Kubernetes
- Peut disposer déjà d’une technologie d’intégration.
+ +## Historique du document +|Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|9 juin 2025|Tony Williams|Version initiale| diff --git a/docs/fr/product/features/connectivity/participation_tools_mini_guides.md b/docs/fr/product/features/connectivity/participation_tools_mini_guides.md new file mode 100644 index 000000000..453f3b043 --- /dev/null +++ b/docs/fr/product/features/connectivity/participation_tools_mini_guides.md @@ -0,0 +1,133 @@ +--- +sidebarTitle: Guides des outils de participation +--- + +# Guide de sélection et d’utilisation des outils de participation + +# Contexte + +La communauté Mojaloop a développé une gamme d’outils à l’usage des DFSP participants, qui facilitent la connexion entre le système d’information du DFSP et un schéma basé sur Mojaloop (le Hub). Chacun joue le rôle d’une couche d’adaptation qui prend en charge la complexité des API Mojaloop et des exigences de sécurité, permettant au DFSP de connecter plus aisément son système d’information. Cela peut grandement faciliter l’intégration, en réduisant à la fois le coût direct (les outils de participation sont en open source et peuvent être téléchargés librement) et le coût indirect (le temps d’intégration est fortement réduit, car la complexité est gérée au sein de l’outil). Le coût de maintenance courant est également bien moindre, car les outils de participation sont maintenus par la communauté Mojaloop et ne nécessitent qu’une « personnalisation » par chaque DFSP. + +Contrairement au Hub Mojaloop lui-même, les outils de participation sont destinés à être déployés dans le périmètre du DFSP ; leur mise en œuvre et leur utilisation restent de la responsabilité de chaque DFSP, avec toutefois l’appui de la communauté Mojaloop. + +La communauté a pris acte du fait que les DFSP ont des exigences et contraintes différentes vis-à-vis des outils de participation, ce qui se reflète dans la diversité des offres. + +# Fonctionnalités + +L’un des objectifs centraux des outils de participation est de masquer la complexité de l’API Mojaloop. Outre toute la dimension sécurité, les outils prennent en charge des procédures Mojaloop complexes et multi-étapes — telles que la recherche de parties, l’accord sur les conditions et les transferts — et les présentent aux systèmes du DFSP de manière plus simple. + +Pour cela, tous les outils de participation offrent les services suivants : + +1. Gestion de la connexion entre le DFSP et le Hub Mojaloop, notamment la mise en place et l’exploitation de la sécurité, y compris l’échange de certificats de clés. +2. Intégration complète des API avec le Hub Mojaloop, couvrant : + 1. L’administration, par exemple la configuration du routage ou des alias pour les clients du DFSP ; + 2. La participation aux transactions en tant qu’institution débitrice ou créditrice ; + 3. La prise en charge de l’autorisation (y compris l’autorisation continue) pour les transactions initiées par des tiers (par exemple les fintechs). +3. Une série d’outils open source pour faciliter la connexion entre l’outil de participation et le système d’information du DFSP (directement au système bancaire cœur, au moteur de paiements ou à une plateforme de messagerie). + +# Éléments architecturaux communs + +L’architecture commune à tous les outils de participation repose sur plusieurs composants clés qui coopèrent pour faciliter la connexion et la gestion des transactions. + +## Connecteur cœur (*Core Connector*) + +C’est le composant d’intégration central qui agit comme « traducteur » entre le système d’information du DFSP et l’outil de participation. Des modèles sont fournis dans le cadre Apache Camel, qui offre un langage déclaratif orienté intégration, et en TypeScript, langage largement connu. Les intégrateurs système et/ou les participants peuvent utiliser ces modèles ou créer un connecteur sur mesure dans la pile technologique de leur choix. L’usage de modèles permet d’adapter le connecteur cœur à la technologie dorsale existante du DFSP sans l’obliger à modifier ses propres systèmes. + +## Connecteur Mojaloop (*Mojaloop Connector*) + +Ce composant communique directement avec le Hub Mojaloop et comprend deux sous-composants essentiels : +**Mojaloop-SDK :** fournit les éléments de sécurité nécessaires et traite les en-têtes HTTP de manière conforme à Mojaloop. + +**API simplifiée :** propose une version plus synchrone et orientée cas d’usage de l’API FSPIOP Mojaloop, plus facile à consommer pour les systèmes dorsaux du DFSP. + +## Client Mojaloop Connection Manager (MCM) + +Ce client automatise et simplifie la configuration des connexions vers différents environnements Mojaloop. Il gère la création, la signature et l’échange des certificats numériques, exigence de sécurité critique pour l’écosystème Mojaloop. + +# Flux de transaction de haut niveau + +Les outils de participation facilitent le processus de transaction en servant de passerelle du DFSP vers le Hub Mojaloop : + +* Une transaction est initiée par le système d’information du DFSP. +* Le système d’information envoie la demande au connecteur cœur au sein de l’outil de participation. +* Le connecteur cœur traduit la demande pour le connecteur Mojaloop et son API simplifiée. +* Le connecteur Mojaloop communique de manière sécurisée avec le switch Mojaloop (Hub) via le Mojaloop-SDK. +* Les paiements sont routés et orchestrés par le Hub Mojaloop vers le DFSP destinataire. +* L’outil de participation fournit des mises à jour de statut et des informations de rapprochement au DFSP via les portails de supervision, lorsque ceux-ci sont mis en œuvre. + +# Outils de participation disponibles + +On distingue deux grandes familles d’outils de participation : d’abord Payment Manager, qui offre toute la fonctionnalité et la flexibilité qu’une grande banque peut exiger ; ensuite un ensemble de solutions autour de l’Integration Toolkit Mojaloop, dimensionnables et hébergeables pour répondre aux besoins variés d’un large éventail d’autres DFSP. + +## Payment Manager + +Également connu sous le nom de Payment Manager for Mojaloop (PM4ML), Payment Manager est un outil de participation Mojaloop complet qui offre toutes les fonctionnalités qu’attendrait une grande banque. Il peut être déployé dans le cloud ou dans le centre de données de la banque et prend en charge toutes les options de reprise après sinistre habituelles dans ce contexte. Il dispose aussi de capacités étendues de gestion et de reporting. + +

+ Architecture PM4ML +

+**Figure 1 : architecture de Payment Manager** + +Le schéma ci-dessus représente une vue de haut niveau de l’architecture de Payment Manager et indique les éléments du Hub Mojaloop avec lesquels il interagit. + +### Portails de Payment Manager + +Les portails métier et techniques de PM4ML offrent des interfaces conviviales avec des tableaux de bord pour suivre les informations critiques : +- **Supervision des transactions :** affiche les statuts de transaction en temps réel et historiques. +- **État des services :** permet aux DFSP de suivre la santé et les performances de leurs connexions. +- **Gestion de la configuration :** point unique pour gérer les clés de sécurité, les certificats et la configuration des points de terminaison. + +## Integration Toolkit + +La famille d’outils de participation Integration Toolkit est conçue pour offrir une grande flexibilité dans la manière dont un DFSP se connecte à un Hub Mojaloop, et peut être déployée sur divers environnements pour couvrir des besoins allant de la plus petite IMF à la plus grande banque. + +### Vue d’ensemble + +

+ Architecture ITK +

+**Figure 2 : architecture ITK** + +Comme on peut s’y attendre, et comme l’illustre le schéma ci-dessus, il existe des points communs avec Payment Manager : + +* Le connecteur cœur et le connecteur Mojaloop fonctionnent comme décrit précédemment. +* Le client Mojaloop Connection Manager (MCM Client) reste chargé de la création, de la signature et de l’échange des certificats numériques, socle de la sécurité de la connexion au Hub Mojaloop. + +Il existe toutefois des différences notables. Le fonctionnement du MCM Client est désormais soumis au contrôle des MCM Agent Services, qui orchestrent la gestion de la sécurité via une machine à états. Le contrôle et la configuration des Agent Services s’effectuent via l’ITK Configuration Utility, qui propose une interface de type console au personnel opérationnel du DFSP. Elle remplit le même rôle que le portail de configuration de Payment Manager. + +La sécurité de l’ITK Configuration Utility / console relève de l’infrastructure de sécurité propre au DFSP. Le serveur (ou la machine virtuelle) sur lequel s’exécutent les composants ITK doit être sécurisé comme tout autre serveur du périmètre administratif du DFSP. + +Contrairement à Payment Manager, l’ITK n’inclut pas de portails de supervision des transactions (prévu pour être pris en charge par les systèmes dorsaux existants du DFSP) ni d’état de service, tandis que l’ITK Configuration Utility remplit le même rôle que le portail de gestion de configuration de Payment Manager. + +### Options de déploiement ITK + +Les options de déploiement de l’ITK sont cataloguées dans la [matrice des fonctionnalités par participant](./participant-matrix.md) et se résument comme suit : + +* **Un petit DFSP**, tel qu’une petite IMF ou banque, devrait en principe auto-héberger l’ITK. Cette approche couvre tous les cas d’usage sauf l’initiation des paiements de masse (la réception des paiements de masse reste possible). Des volumes de transaction modestes sont attendus (10 TPS au maximum), et une certaine indisponibilité (éventuellement de quelques heures) est acceptable. + * Il est recommandé de déployer une version à fonctionnalités minimales de l’ITK sur un petit serveur, jusqu’à un ordinateur monocarte tel qu’un Raspberry Pi pour les plus petits DFSP. + * La supervision des transactions doit passer par le système d’information existant du DFSP. + * Le déploiement s’effectue via Docker Compose. + +* **Un DFSP de taille faible à moyenne**, tel qu’une banque ou une IMF avec une ou deux agences et son propre centre de données « placard à balais », devrait en principe auto-héberger l’ITK. Cette approche couvre tous les cas d’usage, y compris l’initiation de paiements de masse à petite échelle. Des pics d’environ 50 TPS sont pris en charge, et une indisponibilité limitée (de l’ordre de quelques heures) est acceptable. + * Il est recommandé de déployer une version pleinement fonctionnelle de l’ITK sur un serveur de base, hébergé dans le centre de données du DFSP. + * Un déploiement Kafka est nécessaire pour les paiements de masse. + * Le déploiement s’effectue via Docker Compose ou Docker Swarm. + * Intégration minimale avec les plateformes de sécurité d’entreprise existantes. + * La supervision des transactions doit passer par le système d’information existant du DFSP. + +* **Un DFSP de taille moyenne à grande**, tel qu’une institution financière moyenne avec quelques agences, son propre centre de données et des compétences informatiques internes raisonnables, devrait héberger l’ITK. Cette approche couvre tous les cas d’usage, y compris l’initiation de paiements de masse à petite / moyenne échelle. Des pics d’environ 50 TPS sont pris en charge, et une indisponibilité limitée (de l’ordre de quelques minutes) est acceptable. + * Pour respecter les exigences d’indisponibilité les plus strictes, une configuration multi-serveurs est nécessaire, gérée avec Kubernetes. + * Il est recommandé de déployer une version pleinement fonctionnelle de l’ITK, la supervision des transactions passant par le système d’information existant du DFSP. + * Un déploiement Kafka est nécessaire pour les paiements de masse. + * Le déploiement s’effectue via Kubernetes. + * Intégration possible avec les plateformes de sécurité d’entreprise existantes. +* **Un grand DFSP**, tel qu’une institution financière mature multi-agences disposant d’un centre de données aux standards du secteur et de compétences informatiques internes avancées, est invité à utiliser Payment Manager. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|17 décembre 2025| Paul Makin |Version initiale| diff --git a/docs/fr/product/features/deployment.md b/docs/fr/product/features/deployment.md new file mode 100644 index 000000000..614d24975 --- /dev/null +++ b/docs/fr/product/features/deployment.md @@ -0,0 +1,27 @@ +--- +sidebarTitle: Déploiement +--- + +# Déployer Mojaloop + +Les raisons de déployer Mojaloop sont multiples : apprendre à le connaître, évaluer son adéquation à un besoin, faire évoluer ou tester des fonctionnalités par des développeurs, permettre à un adopteur d’examiner fonctionnalités et connectivité, ou encore mettre en production un système national de paiements. + +## Guide de déploiement + +Pour chaque scénario, la communauté Mojaloop a développé des outils de déploiement adaptés. Le [guide de déploiement](./deployment/deploying.md) propose une matrice croisant types d’utilisateurs et objectifs du déploiement, avec des indications sur l’empreinte / le matériel attendu et les SLA associés. Pour chaque cas, un outil de déploiement est recommandé ; un second tableau présente brièvement chaque outil. + +## Outils de déploiement + +Une fois l’outil adapté à vos besoins identifié, le [guide des outils de déploiement](./deployment/tools.md) détaille chaque solution, y compris les aspects performance et sécurité. + +## Préparation à la production + +La communauté a élaboré une matrice d’auto-évaluation permettant aux adopteurs d’évaluer la maturité de leur déploiement Mojaloop et de leur organisation pour passer en production. Ce document ne constitue pas la base d’une évaluation formelle de la préparation à la production ; il propose un ensemble de contrôles de base sur des aspects importants d’un système en production. L’évaluation complète de l’adéquation opérationnelle d’un déploiement Mojaloop reste de la responsabilité exclusive de l’opérateur du système. + +Vous pouvez [consulter la matrice ici](./Production_Readiness_Technical_Assessment.md) ; le formulaire est [téléchargeable ici](https://github.com/mojaloop/product-council/tree/main/Documentation/Deployment%20Readiness) lorsque vous souhaitez lancer une évaluation. + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|18 décembre 2025| Paul Makin, Julie Guetta|Ajout d’un lien vers le document de préparation à la production| +|1.0|3 juin 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/deployment/deploying.md b/docs/fr/product/features/deployment/deploying.md new file mode 100644 index 000000000..0d2e9c2d9 --- /dev/null +++ b/docs/fr/product/features/deployment/deploying.md @@ -0,0 +1,237 @@ +--- +sidebarTitle: Déployer Mojaloop +--- + +# Déploiement de Mojaloop + +Cette section décrit les aspects de déploiement du Hub Mojaloop. + +## Déploiement du Hub Mojaloop (hors intégrations participants) + +Le tableau suivant indique quel scénario de déploiement Mojaloop convient le mieux selon le type d’utilisateur et le cas d’usage. + +Pour le détail de chaque outil de déploiement, voir la documentation [Outils de déploiement](./tools.md). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Scénario de déploiement / type d’utilisateurApprentissageÉvaluation (choix de Mojaloop)Tests de cas d’usageDéveloppement de fonctionnalités et tests de développementProduction
ÉtudiantEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
N/AEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
N/A
DéveloppeurEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
N/AEmpreinte :
- Machine unique, p. ex. portable ou VM unique.
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Machine unique, p. ex. portable ou VM unique.
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
N/A
Analyste métierEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte :
- Machine unique, p. ex. portable ou VM unique.
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
N/A
Adopteur potentielEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
N/A
Auditeur / QA externe / analyste sécuritéEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
N/AN/A
Intégrateur systèmeEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Déploiement entièrement redondant, répliqué, haute disponibilité
- Sur site ou cloud
SLA : SLA élevé sur de nombreux axes.
Opérateur de hubEmpreinte : machine unique, p. ex. portable ou VM unique.
SLA : aucun
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Faible consommation de ressources, cluster unique
- Environnement proche de la production (bac à sable ? SLA inférieur à la prod)
SLA :
- Inférieur à la prod mais possibilité de tester les exigences non fonctionnelles.
Empreinte :
- Déploiement entièrement redondant, répliqué, haute disponibilité
- Sur site ou cloud
SLA : SLA élevé sur de nombreux axes.
+ +## Outils de déploiement + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutilFonctionnalitésExigences minimales en ressourcesSécuritéDocumentationSLARéserves, hypothèses, limites, etc.
core test harness- nœud unique
- docker-compose
- « profils » disponibles
- Pas de HELM
- Pas de passerelle
- Pas de composants entrée/sortie
- Pas de pile IAM
- Déploie :
- services cœur et services sous-jacents
- portails (facultatif)
- pile de supervision (facultatif)

Utilisé dans les pipelines CI pour les tests d’intégration.
Portable ou poste de travail milieu de gammeAucune sécurité- Documentation orientée développeurs.
- Documentation pour utilisateurs non techniques à des fins pédagogiques.
- Documentation produit pour expliquer les fonctionnalités (rôle et pertinence)
- Aucun SLA- Ne jamais utiliser en production.
- Ne jamais utiliser pour traiter des transactions impliquant de l’argent réel.
déploiement HELM- Seuls les charts HELM sont nécessaires pour déployer les services Mojaloop et les services sous-jacents.- Portable ou poste haut de gamme
- Petit cluster Kubernetes cloud.
L’utilisateur doit durcir son propre cluster Kubernetes.- Documentation orientée développeurs
- Documentation semi-technique / orientée analyste métier pour l’expérimentation et les tests de cas d’usage.
- Documentation produit pour expliquer les fonctionnalités (rôle et pertinence).
- Doit permettre d’atteindre des SLA (pour une configuration matérielle de référence) :
- Disponibilité :
- ? 4 ou 5 neufs ?
- RTO/RPO : ? aussi proche de zéro que possible.
- Débit / performance
- TPS : 1000+ (soutenu pendant 1 heure)
- Latence (percentiles) (hors latences externes) :
- Compensation : 99 % < 1 seconde.
- Recherche : 99 % < 1 seconde.
- Accord sur les conditions : 99 % < 1 seconde.
- Gestion des données :
- Mesures contre la perte de données (réplication, reprise après sinistre).
- Conservation (audit, conformité)
- Archivage.

NB : la stratégie privilégie la haute disponibilité par rapport à la reprise après sinistre.
- Peut être utilisé en production.
- Adapté au traitement d’opérations en argent réel.
- L’utilisateur / adopteur doit déployer et configurer sa propre infrastructure, y compris cluster(s) Kubernetes, entrée/sortie, pare-feu, etc.
- La sécurité se limite à ce que fournissent les charts HELM ; une conception et une configuration de sécurité complémentaires sont nécessaires.
Infrastructure as Code- plusieurs cibles de plateforme de déploiement
- AWS, sur site, autres clouds (modulaire)
- plusieurs options de couche d’orchestration
- k8s managé, microk8s, EKS
- modèle GitOps (centre de contrôle)
- peut déployer et gérer plusieurs instances / environnements de hub
- Déploie :
- centre de contrôle
- services cœur et services sous-jacents (options pour services sous-jacents managés)
- portails
- pile IAM
- pile de supervision
- pm4ml
- modèle GitOps
- Infrastructure cloud haut de gamme ou sur site.Sécurité complète- Plusieurs niveaux de documentation pour tous types d’« utilisateurs ».
- Documentation développeur pour utilisation, maintenance, évolution, extension des capacités IaC (nouvelles cibles / services / fonctionnalités).
- Schémas d’architecture détaillés et explications pour une compréhension approfondie.
- Documentation orientée exploitation technique pour permettre aux profils « ingénieur infrastructure » d’utiliser l’IaC pour déployer et maintenir plusieurs instances Mojaloop en développement, test et production.
- Documentation produit pour présenter l’IaC (rôle et pertinence).
- Doit permettre d’atteindre des SLA (pour une configuration matérielle de référence) :
- Disponibilité :
- ? 4 ou 5 neufs ?
- RTO/RPO : ? aussi proche de zéro que possible.
- Débit / performance
- TPS : 1000+ (soutenu pendant 1 heure)
- Latence (percentiles) (hors latences externes) :
- Compensation : 99 % < 1 seconde.
- Recherche : 99 % < 1 seconde.
- Accord sur les conditions : 99 % < 1 seconde.
- Gestion des données :
- Mesures contre la perte de données (réplication, reprise après sinistre).
- Conservation (audit, conformité)
- Archivage.

NB : la stratégie privilégie la haute disponibilité par rapport à la reprise après sinistre.
- Peut être utilisé en production.
- Adapté au traitement d’opérations en argent réel.
+ +## Historique du document +|Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.2|20 août 2025|Sam Kummary|Mise à jour des sections pour utiliser Helm comme option de déploiement le cas échéant| +|1.1|3 juin 2025|Paul Makin|Suppression de la section performance, déplacée vers un nouveau document| +|1.0|7 mai 2025|Tony Williams|Version initiale| diff --git a/docs/fr/product/features/deployment/tools.md b/docs/fr/product/features/deployment/tools.md new file mode 100644 index 000000000..9f2cac6cd --- /dev/null +++ b/docs/fr/product/features/deployment/tools.md @@ -0,0 +1,138 @@ +--- +sidebarTitle: Outils de déploiement +--- + +# Outils de déploiement Mojaloop + +Ce document présente les trois options de déploiement de Mojaloop, classées par complexité et maturité production. Chaque outil correspond à des cas d’usage et des scénarios de déploiement précis. + +## Core Test Harness + +
+
+ Environnement de développement et de test +
+ +Le Core Test Harness fournit un environnement de développement sur un seul nœud avec docker-compose. Il met en œuvre une pile Mojaloop minimale sans les composants production, ce qui le rend adapté au développement et aux tests. + +> **Documentation technique :** +> **LACUNE** — Pas de documentation technique dédiée identifiée pour le Core Test Harness. Références associées dans : +> - [Guide de déploiement — déploiement Helm des prérequis backend](../../../technical/technical/deployment-guide/README.md#_5-1-prerequisite-backend-helm-deployment) (mentionne des exemples docker-compose) +> - [Notes de version](../../../technical/technical/releases.md) (mentionne la validation du Core Test Harness) + +### Détails de mise en œuvre + +Le Core Test Harness s’exécute sur une machine unique en s’appuyant sur docker-compose pour l’orchestration. Il déploie les services cœur et les services sous-jacents sans composants de niveau production (passerelles, entrée/sortie, pile IAM, etc.). La mise en œuvre s’appuie sur des profils configurables pour gérer différents scénarios de déploiement. + +Les besoins en ressources correspondent à un portable ou poste de travail milieu de gamme avec une mémoire suffisante pour l’orchestration des conteneurs. L’outil s’intègre aux pipelines CI pour les tests et validations automatisés. + +### Flux de travail de développement + +Les développeurs interagissent avec le Core Test Harness via les commandes docker-compose. L’outil prend en charge le développement local avec rechargement à chaud. La configuration passe par des variables d’environnement et des fichiers d’override docker-compose. + +### Capacités de test + +Le Core Test Harness permet les tests unitaires, d’intégration et de bout en bout des composants Mojaloop. Il offre un environnement contrôlé pour tester les interactions entre services et valider la logique métier. + +## Déploiement HELM + +
+
+ Solution de déploiement en production +
+ +Le déploiement HELM fournit des capacités prêtes pour la production via les charts HELM. Cette mise en œuvre exige un cluster Kubernetes préconfiguré et satisfait aux exigences de sécurité et de performances de production. + +> **Documentation technique :** +> - [Guide de déploiement Mojaloop](../../../technical/technical/deployment-guide/README.md) — Documentation complète du déploiement HELM +> - [Guide de stratégie de mise à niveau](../../../technical/technical/deployment-guide/upgrade-strategy-guide.md) — Procédures de mise à niveau HELM +> - [Dépannage du déploiement](../../../technical/technical/deployment-guide/deployment-troubleshooting.md) — Problèmes courants et solutions + +### Exigences d’infrastructure + +Le déploiement requiert : +- Un cluster Kubernetes durci +- Des politiques réseau et des paramètres de sécurité +- Des définitions de classes de stockage +- Des quotas et limites de ressources + +### Spécifications de performance + +La mise en œuvre doit respecter les critères suivants : +- Plus de 1000 TPS soutenus pendant une heure +- Latence au 99e percentile inférieure à 1 seconde pour : + - Les opérations de compensation (*clearing*) + - Les recherches (*lookup*) + - L’accord sur les conditions (*Agreement of Terms*) +- Disponibilité de 99,99 % +- RTO/RPO nuls pour les opérations critiques + +### Mise en œuvre de la sécurité + +La sécurité comprend notamment : +- Application des politiques réseau +- Politiques de sécurité des pods +- Intégration d’un service mesh +- Gestion des secrets +- Gestion des certificats + +## Infrastructure as Code + +
+
+ Solution de déploiement d’entreprise +
+ +La mise en œuvre Infrastructure as Code (IaC) offre une solution de déploiement complète pour plusieurs plateformes et couches d’orchestration. Elle applique des modèles GitOps pour gérer plusieurs instances de hub. + +> **Documentation technique :** +> **LACUNE** — Documentation interne limitée pour l’installation et la configuration IaC +> - [Guide d’installation IaC](../../../getting-started/installation/installing-mojaloop.md) — Vue d’ensemble IaC de base (voir point 2) +> - [Article sur le déploiement IaC](https://infitx.com/deploying-mojaloop-using-iac) — Guide détaillé externe +> - [Dépôt plateforme AWS IaC](https://github.com/mojaloop/iac-aws-platform) — Mise en œuvre spécifique AWS + +### Prise en charge des plateformes + +La mise en œuvre prend en charge : +- Déploiement AWS via CloudFormation/Terraform +- Déploiement sur site via Terraform +- Déploiement multicloud via des modules fournisseurs-agnostes +- Plusieurs distributions Kubernetes : + - Services Kubernetes managés + - Microk8s + - EKS + +### Architecture du centre de contrôle + +Le centre de contrôle applique GitOps pour : +- La gestion multi-environnements +- Le versionnement de la configuration +- L’automatisation du déploiement +- La gestion d’état +- La détection de dérive (*drift*) + +### Déploiement des composants + +La mise en œuvre déploie : +- Les services du centre de contrôle +- Les services cœur Mojaloop +- Les services sous-jacents +- Les applications portail +- L’infrastructure IAM +- La pile de supervision +- Les composants PM4ML + +### Performance et sécurité + +La mise en œuvre IaC impose : +- Des contrôles de sécurité de niveau production +- Des exigences de performance alignées sur le déploiement HELM +- Des configurations haute disponibilité +- Des procédures de reprise après sinistre +- Des exigences de conformité + +## Historique du document +|Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|5 juin 2025| Tony Williams|Ajout de liens vers la documentation technique| +|1.0|14 mai 2025| Tony Williams|Version initiale| diff --git a/docs/fr/product/features/development.md b/docs/fr/product/features/development.md new file mode 100644 index 000000000..5fddd562d --- /dev/null +++ b/docs/fr/product/features/development.md @@ -0,0 +1,49 @@ +--- +sidebarTitle: Développement en cours +--- + +# Développement en cours + +Aucun logiciel n’est jamais « terminé », et Mojaloop ne fait pas exception : nouvelles fonctionnalités, nouvelles API, nouveaux portails, et bien sûr il y a toujours une maintenance continue, tandis que la sécurité exige une vigilance constante. + +La feuille de route Mojaloop identifie et priorise ces besoins dans le temps sous forme de *workstreams*. Chaque flux de travail a un responsable, chargé de le définir, le piloter et le livrer à la communauté Mojaloop, avec le soutien de contributeurs (ingénierie, documentation, cadrage des besoins, etc.). + +## Workstreams actifs + +Les workstreams actuellement actifs sont : + +- [Outils de participation](./workstreams/participation.md) +- [Outils de participation pour les fintechs](./workstreams/fintech_participation.md) +- [Outils de déploiement](./workstreams/deployment.md) +- [Cadre QA](./workstreams/qa.md) +- [Gestion des litiges](./workstreams/dispute.md) +- [Adressage LEI](./workstreams/lei.md) +- [Affinage ISO 20022](./workstreams/iso20022.md) +- [Évolution Mojaloop](./workstreams/evolution.md) +- [Performance](./workstreams/performance.md) +- [Qualité et sécurité de plateforme](./workstreams/pqs.md) +- [Cœur et versions](./workstreams/core.md) + +Cliquez sur chaque lien pour les objectifs et les contributeurs. + +## Workstreams candidats + +Outre les workstreams actifs, plusieurs sont identifiés comme « suiveurs rapprochés » : priorité élevée, mais capacité insuffisante dans la communauté pour l’instant. Il s’agit notamment de : + +- Mise en œuvre de PISP V2.0 +- Mise en œuvre de Settlement V3.0 +- Améliorations du portail opérateur (interface, fonctionnalités manquantes perçues) +- Renforcement de l’audit forensic +- Paiements commerçants : enrichir la solution actuelle d’enregistrement commerçant et de QR présenté par le commerçant avec des éléments plus complets pour un schéma en production + +Contactez le directeur produit pour échanger sur ces workstreams candidats et sur les moyens de les activer. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|25 novembre 2025| Paul Makin|Relecture / mise à jour de la liste des workstreams candidats| +|1.0|4 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/ecosystem.svg b/docs/fr/product/features/ecosystem.svg new file mode 100644 index 000000000..e18dc9867 --- /dev/null +++ b/docs/fr/product/features/ecosystem.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/fr/product/features/engineering.md b/docs/fr/product/features/engineering.md new file mode 100644 index 000000000..c26419f24 --- /dev/null +++ b/docs/fr/product/features/engineering.md @@ -0,0 +1,71 @@ +--- +sidebarTitle: Principes d’ingénierie +--- + +# Principes d’ingénierie + +Cette section présente les principes qui sous-tendent les choix d’ingénierie du Hub Mojaloop. + +## Journalisation + +La journalisation standard des conteneurs (*stdout*, *stderr*) est utilisée par défaut. + +## Transferts + +1. Les identifiants de ressources sont uniques dans un schéma et imposés par le hub. + +2. Les méthodes d’API pouvant retourner de grands ensembles de résultats sont paginées par défaut. + +3. Les recherches de modèle de règlement utilisent les devises des DFSP payeur et bénéficiaire. + +4. Les ressources / entités sont typées pour être distinguées. + +5. Les noms (objets, méthodes, types, fonctions, etc.) sont clairs et non ambigus. + +## Comptes et soldes + +1. Le grand livre repose sur un magasin de données sous-jacent **fortement cohérent**. + +2. Les données financières critiques sont répliquées vers plusieurs nœuds géographiquement distribués de manière **fortement cohérente** et performante, de sorte que la défaillance de plusieurs nœuds physiques n’entraîne **aucune perte de données**. + +## Participants + +1. Les problématiques de connectivité des participants sont traitées au niveau passerelle pour faciliter l’usage d’outils standard du secteur. + +## Évolutivité et résilience + +1. Le débit global des transferts (les trois phases) est évolutif de manière quasi linéaire par ajout de nœuds matériels modestes et génériques. + +2. Les données critiques métier peuvent être répliquées sur plusieurs nœuds géographiquement distribués de façon fortement cohérente et performante ; la défaillance de plusieurs nœuds physiques n’entraîne aucune perte de données. + +## Spécification Mojaloop + +1. Prise en charge de JWS. + +2. TLS mutuellement authentifié (x.509) en version 1.2 doit être pris en charge entre participants et hub. + +## Généralités + +1. Les traitements dépendant du contexte sont effectués une fois et les résultats mis en cache en mémoire si nécessaire plus tard dans la même pile d’appels. + +2. Tous les messages de journal contiennent des informations contextuelles. + +3. Les défaillances sont anticipées et gérées de la manière la plus élégante possible. + +4. Les requêtes inter-processus / réseau ne demandent que les données nécessaires. + +5. Les couches d’abstraction sont réduites au minimum. + +6. La communication inter-processus utilise le même mécanisme de transport partout où c’est possible. + +7. Les agrégats sont sans état. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document +|Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14 avril 2025| Paul Makin|Suppression des sections déploiement| +|1.0|5 février 2025| James Bush|Version initiale| diff --git a/docs/fr/product/features/fx.md b/docs/fr/product/features/fx.md new file mode 100644 index 000000000..612703b2f --- /dev/null +++ b/docs/fr/product/features/fx.md @@ -0,0 +1,160 @@ +--- +sidebarTitle: Change de devises +--- + +# Change étranger – conversion de devises + +La fonctionnalité de conversion de devises de Mojaloop permet les opérations de change (FX) et prend en charge plusieurs approches de conversion au sein de l’écosystème. À ce jour, le système met en œuvre la **conversion de devises côté DFSP payeur**, où le DFSP payeur (*Digital Financial Services Provider*) coordonne son action avec un fournisseur de change (FXP) pour obtenir la liquidité dans une autre devise et faciliter le transfert. + +Les évolutions futures prévues pour la conception de la conversion de devises comprennent : +1. **Conversion côté DFSP bénéficiaire** — Le DFSP bénéficiaire organise la conversion de devises. +1. **Conversion via devise de référence** — Le DFSP payeur et le DFSP bénéficiaire s’adressent chacun à des FXP pour convertir les fonds via une devise de référence. +1. **Conversion de masse** — Les DFSP peuvent se procurer de la liquidité en devises auprès d’un FXP par opérations de masse. + +## Rôle du fournisseur de change (FXP) + +Un élément central de la capacité de conversion de Mojaloop est la prise en charge d’un marché du change concurrentiel, où plusieurs FXP peuvent fournir des devis de taux en temps réel. Cette conception favorise un environnement ouvert et dynamique pour les opérations de change. + +Le processus de conversion de devises suit une chaîne en trois étapes : +1. **Demande de devis** — Le DFSP payeur demande une devis à un FXP. Par exemple, un DFSP zambien peut obtenir une devis de conversion pour un transfert donné. +1. **Accord sur le devis** — Le DFSP payeur examine le taux de change et les conditions proposés par le FXP. Une fois acceptés, le FXP bloque le taux. +1. **Finalisation du transfert** — Sur notification du schéma Mojaloop que le transfert dépendant est achevé, le processus de conversion est finalisé. + +Cette approche clarifiée favorise la transparence et la concurrence sur les opérations FX, au bénéfice des DFSP et des utilisateurs finaux. + +## Incidence du type de montant sur la conversion de devises + +La mise en œuvre de la conversion côté DFSP payeur couvre deux scénarios distincts selon le type de montant indiqué dans la transaction : +1. **Envoi de fonds dans la devise source (locale)** +1. **Paiement dans la devise cible (étrangère)** + +### Envoi de fonds vers un compte dans une autre devise + +Dans ce cas d’usage, le **DFSP payeur** initie un transfert avec le type de montant **SEND**, en indiquant le montant dans la devise locale du payeur (devise source). Cette méthode est courante pour les transferts de **rémittance P2P**, où l’émetteur envoie des fonds dans sa devise locale et le bénéficiaire reçoit l’équivalent dans sa devise après conversion. + +### Transfert avec conversion de devises (devise source) + +Ci-dessous, un diagramme de séquence simplifié des flux entre les organisations participantes, les fournisseurs de change et le switch Mojaloop pour un transfert avec conversion de devises exprimé en **devise source**. + +Le flux se décompose ainsi : +1. [Phase de découverte](#discovery-phase) +1. [Phase d’accord – conversion de devises](#agreement-phase---currency-conversion) +1. [Phase d’accord](#agreement-phase) +1. [Le DFSP payeur présente les conditions au payeur](#payer-dfsp-presents-terms-to-payer) +1. [Phase de transfert](#transfer-phase) + +#### Phase de découverte + +Le DFSP payeur identifie l’organisation DFSP bénéficiaire et confirme la validité du compte et la devise. + +![Phase de découverte](./CurrencyConversion/Payer_SEND_Discovery.svg) + +#### Phase d’accord – conversion de devises + +Le DFSP payeur adresse une demande au FXP pour la couverture de liquidité du transfert. Les conditions de conversion de devises sont renvoyées. + +![Conversion de devises](./CurrencyConversion/PAYER_SEND_CurrencyConversion.svg) + +#### Phase d’accord + +Le DFSP payeur demande au DFSP bénéficiaire les conditions du transfert. + +![Accord](./CurrencyConversion/PAYER_SEND_Agreement.svg) + +#### Le DFSP payeur présente les conditions au payeur + +À ce stade, les informations sur la partie, les conditions de conversion et les conditions de transfert ont été fournies au DFSP payeur. Le DFSP payeur les présente au payeur et lui demande s’il souhaite poursuivre. + +![Confirmation d’envoi](./CurrencyConversion/PAYER_SEND_Confirmation.svg) + +#### Phase de transfert + +Les conditions du transfert ayant été acceptées, le transfert peut avoir lieu. Les conditions de conversion et de transfert sont engagées conjointement. + +![Transfert](./CurrencyConversion/PAYER_SEND_Transfer.svg) + + +### Intégration du connecteur Mojaloop pour la conversion de devises + +Le diagramme de séquence détaillé ci-dessous présente le flux complet, avec le **connecteur Mojaloop** et les API d’intégration pour toutes les organisations participantes. (Vue utile si vous réalisez des intégrations en tant qu’organisation participante.) + +#### Phase de découverte – connecteur Mojaloop + +Mojaloop s’appuie sur un oracle pour identifier l’organisation DFSP associée à l’identifiant de partie. Le DFSP bénéficiaire doit répondre au GET /parties pour confirmer que le compte existe et est actif pour cet identifiant. Les devises prises en charge pour ce compte sont renvoyées. + +![Phase de découverte](./CurrencyConversion/FXAPI_Discovery.svg) + + +#### Phase d’accord – conversion de devises – connecteur Mojaloop + +Le DFSP payeur n’effectue pas d’opérations dans les devises prises en charge par le DFSP bénéficiaire. Cela déclenche le besoin de conversion de devises au sein du connecteur Mojaloop. Le DFSP payeur utilise son cache local des FXP pour en sélectionner un et envoie une demande au fournisseur de change pour couverture de liquidité et taux de conversion. + +![Conversion de devises](./CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg) + +#### Phase d’accord – connecteur Mojaloop + +La liquidité en devise cible est assurée. Le DFSP payeur peut demander l’accord sur les conditions au DFSP bénéficiaire. Ces conditions sont exprimées en devise cible. + +![Phase d’accord](./CurrencyConversion/FXAPI_Payer_Agreement.svg) + +#### Confirmation par l’émetteur + +Toutes les conditions de conversion et de transfert ont été obtenues par le DFSP payeur et le FXP. Il s’agit maintenant de les regrouper et de les présenter au payeur pour confirmation. + +![Confirmation](./CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg) + +#### Phase de transfert + +Les conditions du transfert ont été acceptées. La phase de transfert peut commencer. + +![Transfert](./CurrencyConversion/FXAPI_Payer_Transfer.svg) + +## Transfert avec conversion de devises (devise cible) + +Pour ce cas d’usage, le DFSP payeur indique le transfert avec le type de montant **RECEIVE** et définit le montant dans la **devise locale du bénéficiaire** (devise cible). Un autre exemple est le paiement commerçant transfrontalier. + +Ci-dessous, un diagramme de séquence détaillé du flux complet, avec le connecteur Mojaloop et les API d’intégration pour toutes les organisations participantes. + +#### Découverte + +Mojaloop s’appuie sur un oracle pour identifier l’organisation DFSP associée à l’identifiant de partie. Le DFSP bénéficiaire doit répondre au GET /parties pour confirmer que le compte existe et est actif pour cet identifiant. Les devises prises en charge pour ce compte sont renvoyées. + +![Découverte](./CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg) + + +#### Accord + +Le DFSP payeur ne prend en charge aucune des devises du DFSP bénéficiaire, ce qui impose une conversion de devises dans le connecteur Mojaloop. Comme la demande de paiement est en devise cible, un accord avec le DFSP bénéficiaire doit être établi avant d’initier la demande de liquidité auprès du fournisseur de change. Le DFSP payeur négocie d’abord les conditions de transfert avec le DFSP bénéficiaire, puis utilise son cache local de fournisseurs de change pour en choisir un et demander couverture de liquidité et taux de conversion. + +![Accord](./CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg) + +#### Confirmation par l’émetteur + +Toutes les conditions de conversion et de transfert ont été obtenues par le DFSP payeur et le FXP. Il s’agit maintenant de les regrouper et de les présenter au payeur pour confirmation. + +![Confirmation par l’émetteur](./CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg) + +#### Transfert + +Les conditions du transfert ont été acceptées. La phase de transfert peut commencer. + +![Transfert](./CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg) + + +## Flux d’abandon + +Ce diagramme de séquence illustre la manière dont la conception prend en charge les messages d’abandon pendant la phase de transfert avec conversion de devises. + +![Transfert](./CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg) + +## Références OpenAPI + +Ces références OpenAPI sont rédigées pour être lisibles tant par les équipes logicielles que par les relecteurs. Elles décrivent les exigences détaillées et la mise en œuvre de la conception d’API. + +- [Spécification FSPIOP v2.0](https://mojaloop.github.io/api-snippets/?urls.primaryName=v2.0) — [définition OpenAPI](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v2.0-document-set/fspiop-v2.0-openapi3-implementation-draft.yaml). +- [Spécification FSPIOP v2.0 ISO 20022](https://mojaloop.github.io/api-snippets/?urls.primaryName=v2.0_ISO20022) — [définition OpenAPI](https://github.com/mojaloop/api-snippets/blob/main/docs/fspiop-rest-v2.0-ISO20022-openapi3-snippets.yaml). +- [Définition OpenAPI API Snippets](https://github.com/mojaloop/api-snippets/blob/main/docs/fspiop-rest-v2.0-openapi3-snippets.yaml) +- [Backend connecteur Mojaloop](https://mojaloop.github.io/api-snippets/?urls.primaryName=SDK%20Backend%20v2.1.0) — [définition OpenAPI](https://github.com/mojaloop/api-snippets/blob/main/docs/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets.yaml) +- [Connecteur Mojaloop sortant](https://mojaloop.github.io/api-snippets/?urls.primaryName=SDK%20Outbound%20v2.1.0) — [définition OpenAPI](https://github.com/mojaloop/api-snippets/blob/main/docs/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets.yaml) + + diff --git a/docs/fr/product/features/htlc.md b/docs/fr/product/features/htlc.md new file mode 100644 index 000000000..5a2b9f2d7 --- /dev/null +++ b/docs/fr/product/features/htlc.md @@ -0,0 +1,41 @@ +--- +sidebarTitle: Contrats HTLC +--- + +# Contrats à secret et délai (*Hashed Timelock Contracts*) + +Mojaloop utilise les verrous cryptographiques d’ILP pour garantir des transferts atomiques et conditionnels entre DFSP. Le mécanisme repose sur les contrats à secret et délai (HTLC), qui permettent des transferts conditionnels : un transfert se termine entièrement pour toutes les parties ou pas du tout. + +Un contrat est conclu entre les DFSP payeur et bénéficiaire pendant la phase d’accord sur les conditions d’une transaction Mojaloop, ouverte lorsque le DFSP payeur propose une transaction via une demande de devis. + +Lorsque le DFSP bénéficiaire estime que la transaction peut avoir lieu (après ses contrôles internes), il : +- modifie les conditions proposées pour préciser celles auxquelles il accepte d’exécuter la transaction (par exemple frais et conditions de conformité) ; +- crée l’objet *Transaction*, qui définit les conditions auxquelles il est prêt à honorer la demande de paiement ; +- crée et conserve le *Fulfilment*, haché de l’objet Transaction, signé avec la clé privée du DFSP bénéficiaire (clé dédiée et limitée à cet usage) ; +- crée la *Condition*, haché du *Fulfilment* ; +- ajoute la *Condition* à l’objet Transaction ; +- et le renvoie au DFSP payeur dans la réponse de devis. + +Si le DFSP payeur accepte les conditions, il envoie une demande de transfert comprenant l’objet Transaction, la *Condition* reçue et une heure d’expiration, au Hub Mojaloop. + +Le Hub Mojaloop enregistre la *Condition*, transmet la demande de transfert au DFSP bénéficiaire et démarre un temporisateur aligné sur l’expiration indiquée. + +À réception de la demande de transfert, le DFSP bénéficiaire : +- vérifie que la *Condition* reçue correspond à celle convenue (y compris que le montant demandé est celui convenu) et que les conditions de conformité sont remplies ; +- renvoie le *Fulfilment* au Hub Mojaloop dans la réponse de transfert. + +Le Hub Mojaloop hache le *Fulfilment* retourné pour vérifier qu’il correspond à la *Condition* reçue du DFSP payeur ; en cas de succès, il notifie le DFSP payeur (et le DFSP bénéficiaire si demandé) qu’une obligation a été créée entre eux — autrement dit que le paiement a été compensé. + +La notification au DFSP payeur inclut le *fulfilment*, preuve cryptographique d’achèvement irrévocable. Si le DFSP payeur recalcule la *Condition* et constate un écart avec celle convenue, il doit ouvrir un litige avec le DFSP bénéficiaire. + +Si le temporisateur du Hub expire avant réception du *Fulfilment* du DFSP bénéficiaire, le Hub notifie chaque DFSP que la transaction est annulée. + +## Applicabilité + +Ce document concerne Mojaloop version 17.0.0. + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|2 juillet 2025| Paul Makin|Mise à jour après relecture par Michael Richards| +|1.0|30 juin 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/interscheme.md b/docs/fr/product/features/interscheme.md new file mode 100644 index 000000000..ad260dfa8 --- /dev/null +++ b/docs/fr/product/features/interscheme.md @@ -0,0 +1,86 @@ +--- +sidebarTitle: Inter-schéma +--- + +# Inter-schéma (*Interscheme*) + +L’inter-schéma est l’approche de la communauté Mojaloop pour relier des schémas tout en préservant les trois phases d’un transfert Mojaloop et la non-répudiation de bout en bout. L’accord conclu lors d’un transfert reste ainsi entre les organisations DFSP/FXP d’origine et de réception, quel que soit le chemin de routage ou le nombre de schémas traversés. + + +:::tip Non-répudiation +Garantir la non-répudiation entre schémas implique que le proxy ne participe pas à l’accord sur les conditions, ce qui contribue à réduire les coûts. +::: + +La première mise en œuvre de cette fonctionnalité permet de connecter plusieurs schémas Mojaloop. L’écosystème devrait s’élargir avec l’adoption du protocole par de nouveaux schémas nationaux et le développement de connecteurs pour renforcer l’interopérabilité. + +À cette fin, Mojaloop a introduit une organisation participante de type proxy. L’adaptateur proxy matérialise la composante de connexion Mojaloop-à-Mojaloop. + +## Rôle du proxy + +Les schémas sont reliés par un participant proxy, enregistré comme intermédiaire dans le schéma pour les DFSP/FXP adjacents des autres schémas. + +## Routage dynamique des parties + +Cette implémentation utilise un routage dynamique : aucune maintenance initiale ni continue des identifiants de parties entre schémas n’est requise. Le système s’appuie sur une diffusion vers la découverte de schéma pour cet identifiant et met en cache l’organisation associée à un identifiant de partie. + +## Hypothèses + +L’approche repose sur les hypothèses suivantes : +1. Deux participants connectés ne partagent pas le même identifiant. +1. Chaque schéma connecté est responsable du routage des identifiants de parties dans son propre système. (Sous Mojaloop, chaque schéma maintient les oracles nécessaires pour router les paiements des parties participantes sur son réseau.) + +## Schémas généraux +Certains schémas récurrents apparaissent. +### Cas nominaux +![Cas nominaux](./Interscheme/Interscheme-Happypath.svg) + +### Cas d’erreur +![Cas d’erreur](./Interscheme/Interscheme-ErrorCases.svg) + +## Conception de la découverte inter-schéma à la demande +Les flux de découverte se résument ainsi : +1. Chargement à la demande des identifiants inter-réseaux — oracles pour les recherches d’identifiants dans le schéma local. +2. Chargement à la demande pour tous les identifiants. + +### Utilisation des oracles pour mettre en cache les identifiants +- Le schéma utilise des oracles pour associer les identifiants locaux aux participants du schéma. +- Les identifiants d’autres schémas sont découverts par parcours en profondeur en interrogeant tous les participants. Le participant proxy transmet ensuite la requête au schéma connecté. +- Le schéma montre deux schémas connectés ; la conception s’étend à un nombre quelconque de schémas connectés. + +![Diagramme de séquence — découverte à la demande inter-schéma](./Interscheme/Interscheme-OnDemandDiscovery.svg) + + +### Découverte à la demande avec résultats incorrectement mis en cache +- Lorsqu’un identifiant est déplacé vers un autre fournisseur DFSP, le cache de ce participant peut router vers un appel GET /parties infructueux. +- Auto-guérison en cas d’erreur de routage du paiement ou de perte de référence du cache proxy. + +Diagramme de séquence illustrant la mise à jour. +#### Diagramme de séquence +![Inter-schéma — gestion d’un cache de parties obsolète](./Interscheme/Interscheme-StalePartyIdentifierCache.svg) + +## Inter-schéma — phase d’accord +La phase d’accord utilise le cache du proxy pour router les messages. +Détails d’implémentation ci-dessous. + +![Inter-schéma — accord](./Interscheme/Interscheme-Agreement.svg) + +## Inter-schéma — phase de transfert +La phase de transfert utilise le cache du proxy pour router les messages. +Détails d’implémentation ci-dessous. + +![Inter-schéma — transferts](./Interscheme/Interscheme-Transfer.svg) + +## Inter-schéma — GET Transfer +Le GET Transfer est résolu localement pour renvoyer l’état du transfert dans le schéma local. +Détails d’implémentation ci-dessous. +![Inter-schéma — GET Transfers](./Interscheme/Interscheme-GETTransfer.svg) + +## API d’administration — définition des participants proxy +Définition des proxys. +![API d’administration](./Interscheme/SettingUpProxys.svg) + +## Comptes de compensation pour les transferts FX inter-schémas +Ce schéma illustre la mise à jour des obligations pendant la compensation de la transaction. + +![Comptes de compensation](./Interscheme/InterschemeAccounts-Clearing.png) + diff --git a/docs/fr/product/features/invariants.md b/docs/fr/product/features/invariants.md new file mode 100644 index 000000000..6ecc6468b --- /dev/null +++ b/docs/fr/product/features/invariants.md @@ -0,0 +1,181 @@ +--- +sidebarTitle: Invariants +--- + +# Invariants + +## Principes généraux + +**La fonction première de la plateforme est de compenser les paiements en temps réel et de faciliter un règlement régulier, au plus tard à la fin du jour de valeur.** + +1. La plateforme permet aux participants de compenser immédiatement des fonds au profit de leurs clients tout en limitant les risques et coûts associés. + +2. La plateforme prend en charge des contrôles par transfert sur la liquidité disponible lorsque cela est nécessaire au premier objectif. + +3. Le hub est optimisé pour le chemin critique. + +4. Règlement automatisé intrajournalier ; configuré par schéma et implémentation à partir des modèles de règlement recommandés pour l’infrastructure des marchés financiers. + +**Le hub prend en charge un traitement de bout en bout automatique (STP).** + +1. Le traitement de bout en bout automatique (STP) limite les erreurs humaines dans le transfert et réduit les coûts. + +2. Le caractère automatisé du traitement STP accélère les transferts de valeur entre clients finaux. + +**Aucun rapprochement manuel n’est requis : le protocole d’interaction avec le hub garantit des résultats déterministes.** + +1. Lorsqu’un transfert est finalisé, son statut est sans ambiguïté ; sinon il ne l’est pas et une notification active est envoyée aux participants. +2. Le hub garantit des résultats déterministes pour les transferts et est accepté par tous les participants comme autorité finale (« système d’enregistrement ») du statut des transferts. +3. Le déterminisme signifie que chaque transfert est traçable et auditable (selon limites et contraintes), avec un résultat final dans un délai garanti. +4. Les transferts par lot sont traités ligne par ligne, avec des résultats déterministes potentiellement distincts pour chaque ligne. + +**La logique de mise en place de transaction, propre aux cas d’usage, est séparée du transfert d’argent sans logique métier.** + +1. Les détails de transaction et règles métier sont capturés et convenus comme règles du système et guides d’exploitation technique ; ils peuvent être appliqués pendant le devis par les contreparties et sont portés entre elles par le Hub. +2. La phase d’accord établit un objet de transaction signé, spécifique au cas d’usage, intégrant tous les détails propres à la transaction. +3. La phase de transfert orchestre la compensation de la valeur de détail entre institutions au profit des contreparties (seuls des contrôles de limites système s’appliquent), sans référence aux détails métier de la transaction. +4. Aucun traitement supplémentaire propre à la transaction pendant la phase de transfert. + +**Le hub n’analyse ni n’agit sur les détails de bout en bout de la transaction ; les messages de transfert ne contiennent que les valeurs nécessaires à la compensation et au règlement.** + +1. Les contrôles pendant l’étape de transfert portent uniquement sur la conformité aux règles du système, les limites, l’authentification des signatures et la validation de la condition de paiement et de son accomplissement. +2. Les transferts engagés pour le règlement sont définitifs et garantis de se régler selon les règles du système. + +**La sémantique de transfert par poussée de crédit est réduite à sa forme la plus simple et normalisée pour tous les types de transaction.** + +1. Cela simplifie l’implémentation et l’intégration des participants : de nombreux types de transaction et cas d’usage réutilisent le même flux sous-jacent de transfert de valeur. +2. La complexité des cas d’usage est écartée du chemin critique. + +**Le hub de services API sur Internet n’est pas un « commutateur de messages ».** + +1. Le hub fournit des services API en temps réel aux participants pour les transferts instantanés par poussée de crédit de détail. +2. Services tels que résolution identifiant → participant, accord de transaction entre participants, soumission de transferts préparés et d’avis d’accomplissement. +3. Des services API auxiliaires couvrent l’intégration, la gestion des positions, le reporting pour rapprochement et d’autres fonctions non temps réel hors traitement de transfert. +4. Tous les messages sont validés par rapport à la spécification API ; les messages non conformes sont rejetés avec un code de raison normalisé interprétable par machine. + +**Le hub expose des interfaces asynchrones** + +1. Pour maximiser le débit et l’efficacité globale. +2. Pour isoler les problèmes de connectivité des nœuds feuilles afin qu’ils n’affectent pas les autres utilisateurs finaux. +3. Pour permettre au hub de traiter les demandes selon ses propres priorités sans conserver une connexion active par transfert. +4. Pour gérer de nombreux processus longs concurrents via un traitement par lots interne et une répartition de charge. +5. Pour disposer d’un mécanisme unique (ex. masse, saisie utilisateur finale, plusieurs sauts). +6. Pour mieux refléter le réseau réel : les problèmes de vitesse ou de fiabilité pour un participant ont un impact minimal sur les autres et sur la disponibilité globale. + +**L’API de transfert est idempotente** + +1. Les demandes dupliquées peuvent être émises sans risque par l’émetteur en cas de réseau dégradé. +2. Les doublons sont reconnus et conduisent au même résultat (doublons valides) ou sont rejetés comme doublons (si interdits par la spécification) avec référence à l’original. + +**Les enregistrements de transferts finalisés sont conservés pendant une période configurable par schéma pour le rapprochement, la facturation et à des fins d’investigation ou de litige** + +1. On ne peut pas interroger un « sous-statut » d’un transfert en cours ; l’API fournit un résultat déterministe avec notification active dans le délai de service garanti. + +**Les enregistrements des transferts finalisés sont conservés sans limite de durée dans un stockage long pour l’analyse métier par l’opérateur du système et les participants (via des interfaces appropriées)** + +1. La disponibilité des enregistrements peut être retardée par rapport à la finalité en ligne pour séparer tenue des registres et traitement temps réel des demandes de transfert. + +**Le hub peut servir de relais pour certains messages inter-participants (p.ex. pendant la phase d’accord) pour simplifier l’interconnexion, sans analyser ni stocker (au-delà du relais) ni traiter davantage les messages.** + +1. Dans certains flux (p.ex. recherche de partie), un point de contact unique pour router les messages liés au schéma peut être souhaitable même si le message n’est pas destiné au hub et ne nécessite pas d’inspection. + +**Pour garantir la cohérence arithmétique du système, seule l’arithmétique en virgule fixe est utilisée.** + +1. Les calculs en virgule flottante peuvent perdre en précision et ne doivent servir à aucun calcul financier. +2. Voir la représentation et les formes du type décimal Level One. +3. Cette spécification permet l’échange sans perte de précision avec les systèmes financiers basés sur XML. + +## Sécurité et sûreté + +**Les messages API sont confidentiels, à intégrité vérifiable et non répudiables.** + +1. La confidentialité protège la vie privée des participants et de leurs clients. +2. De nombreuses juridictions imposent des exigences légales ; le hub doit appliquer les bonnes pratiques pour protéger cette confidentialité. +3. Des mécanismes d’intégrité à détection d’altération garantissent que les messages ne sont pas modifiés en transit. +4. Chaque destinataire doit pouvoir vérifier de façon fiable que le message n’a pas été altéré en transit. +5. La cryptographie à clé publique (signature numérique) est aujourd’hui le meilleur mécanisme connu pour des messages à intégrité vérifiable. +6. La sécurité de la clé privée (de signature) de l’émetteur est critique. +7. Les règles du système doivent préciser les responsabilités en matière de gestion des clés et l’exposition financière en cas de compromission. +8. La non-répudiation garantit que le message a bien été envoyé par l’émetteur déclaré et que ce dernier ne peut nier cette provenance. +9. Ceci est essentiel pour identifier la partie responsable lors d’audits et de résolution de litiges. + +**Les messages API sont authentifiés dès réception avant acceptation ou traitement ultérieur** + +1. L’authentification renforce la confiance dans l’identité de l’émetteur déclaré. +2. Elle renforce aussi la confiance que le message n’a pas été envoyé par une partie non autorisée. + +**Les messages authentifiés ne sont pas acquittés comme acceptés tant qu’ils ne sont pas enregistrés en toute sécurité sur un stockage permanent** + +1. L’API Mojaloop confère une signification métier importante à certains codes de réponse HTTP à différentes étapes des flux. +2. Certaines réponses, p.ex. « 202 Accepted », portent des garanties financières pour les participants et ne doivent être envoyées que lorsque l’entité réceptrice est assurée d’avoir effectué des enregistrements permanents sûrs permettant : + - la reprise système vers un état cohérent après défaillance(s) de composants distribués ; + - des processus de règlement exacts ; + - l’audit et la résolution de litiges. +3. Par exemple, un « 202 Accepted » du hub vers le participant bénéficiaire à réception d’un message d’accomplissement de transfert indique une garantie de règlement de la transaction pour le bénéficiaire. +4. L’API Mojaloop est conçue pour fonctionner en conditions réseau imparfaites, avec nouvelles tentatives et synchronisation d’état intégrées. + +**Trois niveaux de sécurité des communications pour l’intégrité, la confidentialité et la non-répudiation entre serveur et client API.** + +1. Connexions sécurisées : mTLS obligatoire entre le hub et les participants autorisés — confidentialité, correspondants connus, protection contre l’altération. +2. Messages sécurisés : contenu JSON signé cryptographiquement selon JWS — origine vérifiable et non répudiable par l’émetteur. +3. Conditions de transfert sécurisées : protocole Interledger (ILP) entre payeur et bénéficiaire — intégrité de la condition de paiement et de son accomplissement ; durée de validité limitée de l’instruction de transfert. + +## Caractéristiques opérationnelles + +**Sur matériel minimal, la base démontrée supporte la compensation de 1 000 transferts par seconde pendant une heure, avec au plus 1 % (étape de transfert) dépassant 1 seconde dans le hub.** + +1. La mesure inclut matériel et logiciel nécessaires, sécurité de production et persistance des données. +2. Elle couvre les trois étapes : découverte, accord et transfert. +3. Elle exclut la latence introduite par les participants. +4. Une heure est une approximation raisonnable d’un pic de demande pour un système national de paiement. +5. Le coût unitaire de montée en charge est inférieur au coût de provisionnement initial. +6. 1 000 transferts (compensation) par seconde est un point de départ raisonnable pour un système national. +7. 1 % des transferts (compensation) au-delà de 1 seconde est un point de départ raisonnable. +8. Les schémas Mojaloop doivent pouvoir démarrer à un coût raisonnable pour une infrastructure financière nationale et évoluer économiquement avec la demande. + +**Correctement déployé, le hub est hautement disponible et résilient aux défaillances.** + +1. Ici « hautement disponible » signifie « capacité à fournir et maintenir un niveau de service acceptable face aux pannes et perturbations ». +2. Chaque schéma peut définir ce qu’est un « niveau acceptable » ; Mojaloop fait des arbitrages contributeurs : + - lorsque les modes de défaillance le permettent, le service se dégrade pour l’ensemble des participants plutôt que certains subissant des coupures totales pendant que d’autres restent servis ; + - pas de point de défaillance unique : dégradation minimale si un composant unique tombe en panne ; + - plusieurs instances actives par composant, réparties derrière des répartiteurs de charge ; + - chaque instance peut traiter les demandes de tout client / participant : aucun participant ne perd toute capacité de transaction à la suite de la panne d’un seul composant. +3. Avec une infrastructure adaptée, des configurations atteignant 99,999 % de disponibilité (« cinq neufs ») sont possibles. +4. Cela inclut des configurations multi-centres de données géographiquement distribuées actif:actif et actif:passif, services et données répliqués sur des nœuds physiques censés échouer indépendamment. +5. Les nœuds des groupes de réplication (et/ou grappes) doivent être dans des emplacements physiques distincts (baies et/ou centres de données), alimentations et interconnexions réseau indépendantes. +6. En cas de défaillances multiples non couvertes par le logiciel Mojaloop, la configuration ou l’infrastructure, l’API Mojaloop permet à chaque entité du schéma de retrouver un état cohérent, le hub étant la source de vérité ultime après restauration complète. +7. Voir aussi les points sur la résistance à la perte de données. +8. Les schémas Mojaloop, en tant qu’éléments d’infrastructures nationales, doivent viser une indisponibilité quasi nulle dans des limites de coût raisonnables. +9. Les pannes matérielles et logicielles sont attendues, même sur les composants de la plus haute qualité. Les bonnes pratiques préconisent qu’elles soient anticipées et prévues autant que possible dans la conception du hub pour limiter perte ou dégradation de service et/ou de données. +10. Les arbitrages privilégient la disponibilité globale et la cohérence d’état par rapport à la performance : + + - tous les participants peuvent continuer à moins grande cadence plutôt que certains être totalement bloqués ; + - les incohérences d’état entre entités du schéma sont récupérables après restauration via l’API Mojaloop, avec un rapprochement manuel minimal ; le hub reste la source de vérité. + +**Le hub résiste à la perte de données en cas de défaillances.** + +1. Avec une infrastructure adaptée, le logiciel Mojaloop peut répliquer de façon fiable les données sur plusieurs nœuds de stockage physiques redondants avant traitement. +2. Les moteurs de base fournis par les mécanismes de déploiement Mojaloop supportent notamment : + + - réplication primaire/secondaire asynchrone ; + - réplication primaire/primaire synchrone ; + - réplication par algorithme de consensus par quorum synchrone. + +3. Les mécanismes disponibles dépendent de la couche de stockage et des technologies de base de données employées. +4. En cas de défaillances multiples non couvertes, l’API Mojaloop permet de retrouver un état cohérent avec une exposition financière minimale. +5. Les transferts deviennent contraignants financièrement lorsque le hub a répondu avec succès à un message d’accomplissement de transfert du participant bénéficiaire — réponse émise seulement après persistance du message d’accomplissement et de son issue dans la base du grand livre. +6. Les horodatages d’expiration sur les messages API financièrement significatifs permettent des chemins d’échec déterministes et opportuns pour tous les participants, avec mécanismes de nouvelle tentative automatisés. +7. Les schémas Mojaloop, en infrastructures nationales, doivent autant que possible, dans des limites de coût raisonnables, éviter toute perte de données. +8. Les pannes sont attendues, même sur les composants de la plus haute qualité. Les bonnes pratiques préconisent qu’elles soient anticipées et prévues dans la conception du hub pour éviter la perte de données. +9. Les participants ont besoin d’une confiance rapide dans le statut des opérations financières sur le système pour limiter l’exposition et offrir une excellente expérience client. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14 avril 2025| Paul Makin|Ajout du contrôle de version| +|1.0|5 février 2025| James Bush|Version initiale| diff --git a/docs/fr/product/features/iso20022.md b/docs/fr/product/features/iso20022.md new file mode 100644 index 000000000..c490328b3 --- /dev/null +++ b/docs/fr/product/features/iso20022.md @@ -0,0 +1,34 @@ +--- +sidebarTitle: ISO 20022 +footerCopyright: Apache 2.0 Licensed | Copyright © 2020 - 2024 Mojaloop Foundation +--- + +# Pratiques de marché ISO 20022 + +Les pratiques de marché ISO 20022 pour Mojaloop définissent un cadre de messagerie normalisé permettant aux institutions financières de participer à l’écosystème Mojaloop avec les normes ISO 20022 reconnues mondialement. Cette spécification décrit comment les messages ISO 20022 sont mis en œuvre dans Mojaloop en alternative à l’API FSPIOP. + +## Documents de pratique de marché + +* Document de pratique de marché + * [ISO 20022 v1.0 (actuel)](./Iso20022/v1.0/MarketPracticeDocument.md) + +## Principales caractéristiques + +L’implémentation ISO 20022 de Mojaloop offre notamment : + +- **Format JSON** : variante JSON des messages ISO 20022 pour une meilleure adéquation aux API +- **Flux transactionnel en trois phases** : conservation des phases Découverte, Accord et Transfert Mojaloop +- **Prise en charge de la conversion de devises** : transactions multi-devises avec intégration des fournisseurs de change +- **Sécurité cryptographique** : ILP v4 pour la signature des messages et la non-répudiation +- **Intégration API REST** : intégration avec les architectures API REST modernes + +## Souplesse de schéma + +Les documents de pratique de marché apportent : + +- **Pratiques génériques** : lignes directrices universelles pour tous les schémas Mojaloop +- **Cadre extensible** : personnalisations et exigences propres à chaque schéma +- **Soutien à la conformité** : alignement sur exigences réglementaires et standards du secteur +- **Gestion des versions** : approche structurée pour l’évolution des normes et des exigences + +Pour toute question ou assistance, adressez-vous à la communauté Mojaloop par les canaux officiels. diff --git a/docs/fr/product/features/merchant-payments.md b/docs/fr/product/features/merchant-payments.md new file mode 100644 index 000000000..cae55cee2 --- /dev/null +++ b/docs/fr/product/features/merchant-payments.md @@ -0,0 +1,37 @@ +--- +sidebarTitle: Paiements commerçants +--- + +# Paiements commerçants + +!!!! **TRAVAUX EN COURS — SERA COMPLÉTÉ SOUS PEU** !!!! + +## Place des paiements commerçants + +Dans l’univers Mojaloop, les paiements commerçants ne sont pas intégrés au Hub lui-même : il s’agit d’un **service superposé** qui s’appuie sur les services du Hub et fait partie du progiciel open source Mojaloop complet. + +Côté exploitation de schéma, un schéma de paiements commerçants peut être proposé dans le cadre d’un service de paiements global par l’opérateur du Hub Mojaloop. Un schéma distinct peut aussi être opéré par un autre acteur, en collaboration avec l’opérateur du Hub. + +## Concepts + +Les commerçants doivent être enregistrés comme tels dans le modèle Mojaloop (ce qui diffère d’un simple enregistrement « entreprise » ; le modèle auto-entrepreneur est pris en charge). Les données KYB sont saisies dans le registre commerçant et un identifiant commerçant indépendant du DFSP est généré. Cet identifiant peut être affiché sur place pour des paiements USSD par des clients avec téléphones basiques ; il est aussi prévu pour être intégré dans des QR statiques, scannés par les clients dont l’application du DFSP le permet. + +Le modèle repose sur un paiement poussé P2B. La résolution d’alias du Hub Mojaloop associe les identifiants commerçants (extraits d’un QR ou saisis en USSD) aux comptes commerçants chez les DFSP participants, sans exposer le DFSP ni le numéro de compte. Avec un QR, les bonnes pratiques recommandent d’afficher le nom commercial du commerçant pour vérification par le client, de lui demander de saisir le montant et de s’authentifier (ex. PIN) pour autoriser la transaction. Une fois le paiement effectué, le client et le commerçant reçoivent une notification ; le commerçant peut remettre le bien ou le service. + +## Enregistrement + +L’enregistrement commerçant est prévu pour être réalisé par les DFSP, dans le cadre de leur relation avec le commerçant en tant qu’« émetteur ». Les données sont conservées dans un registre commerçant partagé, tout en conservant la relation DFSP–commerçant. + +Les données saisies lors de l’enregistrement + +![Schéma entité-relation des paiements commerçants](./ecosystem.svg) + +À l’enregistrement, une quantité substantielle d’informations est collectée dans le registre commerçant. + +Adressage : +USSD vs QR +Registre commerçant — lien avec les LEI +Création d’un QR (référence EMVCo) +Personnalisation du QR — conformité aux standards du schéma ou du pays. + +À venir : lien vers GLEIF diff --git a/docs/fr/product/features/metadata.md b/docs/fr/product/features/metadata.md new file mode 100644 index 000000000..af325a738 --- /dev/null +++ b/docs/fr/product/features/metadata.md @@ -0,0 +1,22 @@ +--- +sidebarTitle: Métadonnées +--- + +# Métadonnées + +La nature même de Mojaloop, en tant que switch reliant des DFSP, fait que le Hub ne peut pas attribuer de sens métier à la transaction. En revanche, les transactions peuvent transporter des **métadonnées** en complément des données de paiement ; le schéma peut s’en servir pour rattacher le paiement à des opérations extérieures à Mojaloop, favorisant l’interopérabilité en conservant le contexte entre DFSP. Cela vaut pour un paiement poussé ou une demande de paiement (*RTP*). + +Les métadonnées décrivent, contextualisent ou gèrent le paiement au-delà du montant, de l’émetteur et du bénéficiaire. Elles ne sont pas strictement nécessaires au mouvement de fonds, mais elles sont essentielles au rapprochement, à l’automatisation, à la conformité et à l’expérience client. + +Au plus simple, elles permettent par exemple d’associer un paiement à une facture (ex. facture d’électricité), de transporter un numéro de facture avec un règlement B2B, ou de préciser l’objet du paiement (« Scolarité T3 2025 », « Salaire juin 2025 », « Remboursement de prêt », etc.). + +Lorsque ces métadonnées servent à l’automatisation des paiements, leur « signification » est définie par l’opérateur du schéma et les DFSP participants, pas par le Hub Mojaloop. L’automatisation est en principe mise en œuvre dans le cadre de la [personnalisation du Core Connector dans les outils de participation](./connectivity.md). + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|16 juillet 2025| Paul Makin|Première version.| diff --git a/docs/fr/product/features/ml-feature-list.md b/docs/fr/product/features/ml-feature-list.md new file mode 100644 index 000000000..7d8fbe688 --- /dev/null +++ b/docs/fr/product/features/ml-feature-list.md @@ -0,0 +1,116 @@ +--- +sidebarTitle: Introduction Mojaloop +--- + +# Introduction à Mojaloop + +Mojaloop est un logiciel open source de paiements instantanés qui interconnecte des institutions financières variées avec pour objectif l’inclusion financière tout en limitant le risque systémique pour tous les participants. La plateforme peut être téléchargée pour toute entité souhaitant l’utiliser pour mettre en œuvre et exploiter un système de paiements instantanés inclusif (SPII, *Système de paiement instantané inclusif*). + +## Point de vue des régulateurs et des opérateurs +Mojaloop fournit les fondations nécessaires pour qu’un opérateur de paiement national établisse un système de paiements instantanés inclusif (SPII). La plateforme est conçue pour s’intégrer à une chambre de compensation interbancaire publique ou privee. Ce partenaire peut être le RTGS national, bien que d’autres mécanismes de compensation soient également Supportés. Ainsi, Mojaloop permet d’offrir un service complet d’interopérabilité de paiements aux institutions financières (IF) participantes. + +Une fois déployé, Mojaloop permet à l’opérateur du schéma de : +- intégrer, suspendre ou réactiver les institutions financières participantes selon les besoins ; +- fixer des plafonds de débit net par participant afin de gérer le risque et la liquidité ; +- implémenter une compensation adaptée au besoin du schéma ; +- définir plusieurs périodes de compensation interbancaire au sein de la journée, la clôture de chaque période générant un fichier de compensation interbancaire qui sera consommé par la chambre de compensation. + +Le Hub Mojaloop supporte ces fonctions en : +- traitant en continu 24h/24 et 7j/7 les paiements entre institutions financières débitrices et créditrices ; +- mettant à jour en temps réel la position de chaque participant à chaque débit et crédit ; +- validant chaque paiement (liquidité suffisante, respect du plafond de débit net du participant), en rejetant les transactions non conformes ; +- mettant à jour les positions des participants à la clôture de chaque fenêtre de compensation interbancaire pour refléter la valeur des fonds compensés. + +Mojaloop prend aussi en charge un **modèle de participation indirecte**, pour élargir l’accès aux petites institutions — notamment des acteurs non bancaires comme les IMF — non éligibles à une participation directe au RTGS (système de règlement brut en temps réel). Cela garantit ainsi une large inclusion au sein de l’écosystème de paiements, tout en préservant la stabilité financière. + + +## Perspective technique + +Pour délivrer le SPII décrit ci-dessus, Mojaloop met en œuvre un ensemble de fonctions cœur : + + |Résolution d’alias|Compensation|compensation| +|:--------------:|:--------------:|:--------------:| +|Résolution d’adresse ou **d’alias** du bénéficiaire, pour identifier de façon fiable l’institution détentrice du compte — et donc le bon compte bénéficiaire|**Compensation** des paiements de bout en bout, grâce à des mécanismes robustes qui lèvent tout doute quant au succès d’une transaction|Orchestration du **compensation** des transactions compensées entre institutions selon un modèle convenu entre elles et un calendrier prédéfini.| + +  + +Ces fonctions s’appuient sur des [caractéristiques distinctives](./transaction.md#unique-transaction-characteristics), qui font de Mojaloop un système de paiements instantanés inclusif à coût maîtrisé : + +1. **Un flux transactionnel en trois phases** : + + **Découverte**, lorsque le DFSP du payeur collabore avec le Hub Mojaloop pour déterminer où envoyer le paiement, garantissant ainsi que les paiements ne sont pas envoyés à un mauvais destinataire. L’alias est résolu vers un DFSP bénéficiaire précis et, avec ce DFSP, un compte individuel. + + + **Accord sur les conditions (devis)**, lorsque les deux DFSP conviennent tous deux que la transaction peut avoir lieu (avec par exemple des restrictions liées à un KYC par paliers) et à quelles conditions (dont frais), **avant** que l’une ou l’autre ne s’engage. + + + **Transfert**, lorsque la transaction entre les deux DFSP (et, par procuration, les comptes clients) est compensée, avec la garantie que les deux parties partagent la même vision en temps réel du succès ou de l’échec. +  + +2. **La non-répudiation de bout en bout** garantit à chaque partie destinataire qu’un message n’a pas été altéré et qu’il émane bien de l’expéditeur présumé. Mojaloop s’en sert pour n’engager une transaction que si *les deux* DFSP payeur et bénéficiaire l’acceptent, sans qu’aucun puisse la nier. Aucun tiers ne peut non plus altérer la transaction. +3. **L’API PISP est exposée par le Hub Mojaloop**, et non par chaque DFSP. Une fintech se connecte au Hub et accède **immédiatement** à **toutes** les institutions financières intégrées (DFSP).  + +**Note** Dans le vocabulaire Mojaloop, une **IF** (*institution financière*) désigne tout établissement participant au schéma — banque, établissement de paiement ou autre acteur habilité. Le terme « IF » est utilisé dans la perspective régulateurs et opérateurs. Un **DFSP** (*Digital Financial Service Provider*) désigne toute institution financière, quelle que soit sa taille ou son statut, capable d’opérer par voie numérique — de la plus grande banque internationale à la plus petite IMF ou opérateur de portefeuille mobile. Le terme « DFSP » est utilisé dans le reste de ce document. +  + +# L’écosystème Mojaloop +## Le cœur +Pour lire ce document, il est utile de connaître la terminologie des acteurs et leurs interactions. Le schéma suivant donne une vue d’ensemble de l’écosystème Mojaloop. + +![Écosystème Mojaloop](./ecosystem.svg) + +## Services superposés +Autour du cœur illustré ci-dessus s’ajoutent des services superposés, eux aussi dans le progiciel open source Mojaloop complet : +- le **Account Lookup Service** (ALS) et des oracles utilisés par l’ALS pour la résolution d’alias ; +- des **portails**, construits sur le Business Operations Framework, pour que l’opérateur du hub gère le Hub Mojaloop ; +- un module **Paiements commerçants**, pour l’enregistrement des commerçants et l’émission d’identifiants commerçants, y compris la génération de QR scannables pour initier une transaction commerçant ; +- le **Testing Toolkit** (TTK), pour simuler tout aspect de l’écosystème cœur Mojaloop et faciliter développement, intégration et tests ; +- l’**Integration Toolkit** (ITK), dans la bibliothèque [support de connectivité](./connectivity.md), pour le lien entre un DFSP et un Hub Mojaloop ; +- l’**intégration ISO 8583**, pour raccorder des DAB (ou un commutateur DAB) au Hub Mojaloop pour les retraits d’espèces ; +- l’[**intégration MOSIP**](https://www.mosip.io), pour router les paiements vers une identité numérique basée sur MOSIP plutôt que vers (par exemple) un numéro de téléphone mobile. + +## Liste des fonctionnalités + +Ce document présente une liste de fonctionnalités couvrant les aspects suivants de Mojaloop : + +- [**Cas d’usage**](./use-cases.md), pour les cas Supportés par tout déploiement Mojaloop. +- [**Transactions**](./transaction.md), pour les API Mojaloop, le déroulement d’une transaction et les particularités adaptées à un service de paiements instantanés inclusif. + +- [**Gestion des risques**](./risk.md), pour les mesures évitant tout risque de contrepartie entre DFSP d’un schéma Mojaloop et protégeant l’intégrité du schéma. + +- [**Support de connectivité**](./connectivity.md), pour les outils et options d’intégration simple des DFSP participants. + +- [**Portails et fonctions opérationnelles**](./product.md) : portails de gestion des utilisateurs et des services, configuration et exploitation d’un Hub Mojaloop. +- [**Frais et tarifs**](./tariffs.md) : mécanismes pour différents modèles tarifaires et possibilités de facturation pour participants et opérateurs de hub. + +- [**Performance**](./performance.md), pour les ordres de grandeur de performance transactionnelle que les adopteurs peuvent raisonnablement anticiper. +- [**Déploiement**](./deployment.md), pour les modes de déploiement selon l’objectif et les outils associés. +- [**Sécurité**](./security.md), pour la sécurité des transactions entre DFSP et Hub, celle du Hub (y compris portails opérateur), et le cadre QA en cours pour valider sécurité et qualité d’un déploiement. +- [**Principes d’ingénierie**](./engineering.md) : respect de la spécification Mojaloop, qualité du code, pratiques de sécurité, schémas d’évolutivité et de performance, etc. + +- [**Invariants**](./invariants.md), pour les principes de développement et d’exploitation auxquels toute implémentation Mojaloop doit se conformer, y compris pour la sécurité et l’intégrité du déploiement. + +  +## Développement continu +Aucun logiciel n’est jamais terminé, et Mojaloop ne fait pas exception : nouvelles fonctionnalités, API, portails, maintenance, vigilance sécurité. + +La feuille de route Mojaloop recense et priorise ces besoins selon un calendrier, les organisant en workstreams. Chaque workstream est piloté par un responsable chargé de le définir, le gérer et le livrer à la Communauté Mojaloop. Ce responsable est soutenu par des contributeurs — ingénieurs, rédacteurs ou analystes — qui participent à la mise en œuvre, à la documentation ou à la définition des exigences. + +Vous pouvez consulter l’état actuel des workstreams et leurs derniers comptes rendus dans la section [**Développement en cours**](./development.md). + +# À propos de ce document + +## Objectif + +Ce document recense les fonctionnalités de Mojaloop, indépendamment de l’implémentation. Il vise à informer les adopteurs potentiels des capacités attendues et, le cas échéant, du fonctionnement prévu, ainsi qu’à informer les développeurs des exigences pour qu’une implémentation soit reconnue comme instance officielle Mojaloop. + +La Mojaloop Foundation (MLF) définit comme instance officielle Mojaloop une implémentation qui met en œuvre **toutes** les fonctionnalités, sans exception, et réussit la batterie de tests standard Mojaloop. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.5|4 décembre 2025| Paul Makin|Ajout de la sous-section « Développement continu »| +|1.4|28 août 2025| Paul Makin|Ajout du point de vue « Régulateurs et opérateurs »| +|1.3|23 juin 2025| Paul Makin|Ajout du texte et du schéma sur l’écosystème| +|1.2|14 avril 2025| Paul Makin|Mises à jour liées à la sortie de la V17| diff --git a/docs/fr/product/features/mojaloop_security_layers.jpg b/docs/fr/product/features/mojaloop_security_layers.jpg new file mode 100644 index 000000000..d70949b68 Binary files /dev/null and b/docs/fr/product/features/mojaloop_security_layers.jpg differ diff --git a/docs/fr/product/features/performance.md b/docs/fr/product/features/performance.md new file mode 100644 index 000000000..f899b0968 --- /dev/null +++ b/docs/fr/product/features/performance.md @@ -0,0 +1,30 @@ +--- +sidebarTitle: Performance +--- + +# Performance + +Le débit des transactions — souvent exprimé en transactions par seconde — est une métrique clé pour les adopteurs, qui doivent être assurés que Mojaloop répond à leurs besoins, qu’il s’agisse d’un déploiement national, sectoriel ou multinational. + +Pour cette raison, la communauté Mojaloop a défini une base de référence en matière de performance et travaille continuellement à affiner et améliorer l’efficacité du traitement des transactions. + +## Base de référence + +La version 17.0.0 du Hub Mojaloop a démontré les caractéristiques suivantes sur un matériel ***minimal*** : + +- Compensation de 1 000 transferts par seconde +- Maintenu pendant une heure +- Avec au plus 1 % (étape de transfert) des opérations dépassant 1 seconde dans le hub + +Cette base peut servir de repère pour le dimensionnement et la planification de capacité. + +Des performances supérieures peuvent être attendues avec davantage de ressources matérielles. + +## Perspectives + +Des travaux visent à remplacer la technologie de grand livre actuelle de Mojaloop par la base de transactions financières [TigerBeetle](https://tigerbeetle.com/). La performance du grand livre étant un facteur majeur de la performance globale, une nette amélioration est attendue avec TigerBeetle, dont l’adoption est visée pour la sortie de Mojaloop version 19.0. + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|3 juin 2025| Paul Makin|Version initiale ; texte sur la performance extrait de la doc déploiement| diff --git a/docs/fr/product/features/product.md b/docs/fr/product/features/product.md new file mode 100644 index 000000000..1f266e41c --- /dev/null +++ b/docs/fr/product/features/product.md @@ -0,0 +1,149 @@ +--- +sidebarTitle: Portails et exploitation +--- + +# Portails et fonctions opérationnelles + +Les aspects des portails et autres fonctionnalités opérationnelles abordés sont les suivants : + +- Gestion des utilisateurs + +- Gestion des participants + +- Consultation des transactions + +- Compensation + +- Journalisation et audit + +- Gestion du hub + +- Gestion des oracles + +- Portail participant + +- Reporting + +Ces fonctionnalités sont fournies par le **Business Operations Framework** (BOF) de Mojaloop, qui fournit non seulement les fonctions cœur décrites ici, mais aussi un ensemble d’API permettant à l’opérateur du Hub d’étendre ces portails et d’en créer de nouveaux selon ses besoins. + +Le BOF canalise toutes les activités via un cadre unique de gestion des identités et des accès (IAM), qui intègre des contrôles d’accès basés sur les rôles (RBAC), offrant à l’opérateur du hub un contrôle granulaire de l’accès d’un individu aux capacités de gestion du Hub Mojaloop. + +L’accès à chacune des fonctions ci-dessus passe par le BOF, géré via l’IAM et le RBAC. + +## Gestion des utilisateurs + +Ces fonctionnalités concernent la gestion du **personnel de l’opérateur du hub** via le module IAM intégré, et non la gestion du service lui-même. + +1. Créer et gérer des comptes utilisateurs pour le personnel de l’opérateur du hub et les participants, via le portail IAM. +2. Définir des rôles associés à l’accès aux différents sous-éléments des portails. +3. Attribuer des rôles aux comptes utilisateurs, définissant quels utilisateurs ont accès à quelles fonctionnalités des portails. +4. Pour les fonctions sensibles, définir une exigence maker/checker, y compris les rôles devant être détenus par le maker et le checker, ainsi que toute restriction. +5. Activer / désactiver des comptes utilisateurs. +6. Créer des comptes pour les participants, afin de faciliter le libre-service via le portail participant (lorsqu’il est implémenté). +7. Permettre à un utilisateur d’être à la fois maker et checker (mais pas de ses propres travaux). + +Le portail participant n’est à ce jour implémenté sur aucun hub Mojaloop ; ce n’est donc pas une exigence actuelle. + +## Gestion des participants + +Fonctionnalités permettant à l’opérateur du hub de gérer un DFSP participant (distinct du portail participant). + +1. Intégration d’un DFSP participant (onboarding). +2. Définir et gérer des points de terminaison (y compris la spécification des certificats et des adresses IP sources). +3. Gérer les contacts du participant (nom, e-mail, MSISDN, rôle, etc.). +4. Définir des seuils (pour les notifications). +5. Définir et gérer des comptes pour le participant par type et devise. +6. Désactiver un DFSP participant (bien qu’il ne devrait pas être possible de désactiver un DFSP avec des transactions en cours / non compensées). +7. Mettre en pause / reprendre la connexion d’un participant. +8. Attribuer / ajuster la liquidité (pour plusieurs devises), contrôlé par maker/checker. +9. Attribuer / ajuster un plafond de débit net (NDC) pour chaque participant, contrôlé par maker/checker, avec deux options pour le NDC : valeur fixe (ajustement manuel après chaque changement de liquidité) ou variable (en tant que pourcentage fixe de la liquidité disponible). +10. Restreindre la connexion du participant à l’envoi ou à la réception uniquement. + +## Consultation des transactions + +Le personnel de l’opérateur du hub doit pouvoir retrouver le détail d’une transaction, quel que soit son statut. La recherche peut se faire par : + +- Plage de dates / heures + +- DFSP payeur ou bénéficiaire (participant) + +- Valeur — identifiant de transaction Mojaloop + +- État du transfert + +- Identifiant de lot de compensation + +- Type de transaction + +- Code d’erreur + +La recherche renvoie la liste de toutes les transactions correspondant aux critères ; chaque ligne cliquable donne accès à une vue détaillée contenant : + +- Toutes les données détenues par le Hub Mojaloop, regroupées en sous-fenêtres pour améliorer l’ergonomie + +Cela inclura l’identifiant de fenêtre / lot de compensation, qui est lui-même cliquable pour permettre à l’opérateur de consulter le statut de compensation du lot et donc de la transaction elle-même. + +## Compensation + +La gestion de la compensation sur le Hub Mojaloop doit être robuste et fiable. Les fonctionnalités associées : + +1. Définir le modèle de compensation du service. +2. Clôturer une fenêtre ou un lot de compensation manuellement ou automatiquement, selon un calendrier prédéfini. +3. Générer automatiquement tous les fichiers de compensation nécessaires pour l’intégration avec le ou les chambres de compensation lorsqu’une fenêtre de compensation est clôturée. +4. Consulter les positions de tous les participants dans la fenêtre / le lot. +5. Une fois la compensation achevée / finalisée, mettre à jour automatiquement les positions et la liquidité disponible actuelle sur la base des rapports du ou des chambres de compensation. +6. Fournir des outils pour prendre en charge l’intégration entre le Hub Mojaloop et le ou les chambres de compensation. + +Notez qu’au moins une fenêtre ou un lot de compensation sera toujours ouvert, et les transactions y seront ajoutées au fur et à mesure qu’elles sont traitées. La création d’une nouvelle fenêtre est donc automatique à la clôture de la précédente. + +## Journalisation et audit + +Le Hub Mojaloop fournit une gamme d’outils prenant en charge la journalisation et l’audit de l’activité des opérateurs du hub, en complément des fonctions d’audit de bas niveau pour l’analyse détaillée du traitement des transactions (qui sont définies ailleurs dans ce document). Ces outils ont été développés en tenant compte des exigences tant de la direction de l’opérateur du hub que des auditeurs externes. + +1. Toutes les modifications découlant de l’activité des opérateurs du hub (y compris la gestion des utilisateurs) sont enregistrées dans un magasin de données non modifiable, avec les informations d’identification de l’opérateur attachées. + +2. « Auditeur » est un rôle utilisateur du hub par défaut ; les auditeurs ont un accès en lecture illimité aux journaux. + +3. Un portail d’audit est disponible, qui dispose d’une fonctionnalité de recherche et d’affinage. + +4. Les entrées de journal / audit incluent les changements de configuration du Hub. + +## Gestion du hub + +Exigences de base pour la configuration d’un Hub Mojaloop définissant le service supporté. + +1. Un Hub Mojaloop prend en charge par défaut toutes les devises définies par l’ISO. Chacune est activée pour une utilisation par un déploiement particulier par la création de comptes de compensation et de position pour cette devise. Pour appuyer cela, il est nécessaire de pouvoir consulter les soldes des comptes d’exploitation du Hub (compensation et position, répliqués par devise prise en charge). + +2. Ajouter / consulter / supprimer les certificats de CA nécessaires au fonctionnement normal. + +## Gestion des oracles + +Gestion des oracles utilisés par l’Account Lookup Service (ALS) pour la résolution des alias en DFSP / participants (puis, en collaboration avec le DFSP identifié, en un compte spécifique). + +1. Consulter les oracles enregistrés. + +2. Enregistrer un oracle. + +3. Définir un endpoint. + +4. Tester l’état de santé d’un oracle. + +## Portail participant + +Actuellement, le Hub Mojaloop ne propose pas de portail participant. À la place, cette fonctionnalité est fournie par un autre projet open source, Payment Manager (). D’autres outils, comme l’Integration Toolkit Mojaloop, exposent une API permettant aux DFSP d’accéder aux mêmes informations. + +## Rapports + +Mojaloop fournit un moteur de rapports flexible dans le cadre du Business Operations Framework, qui permet au personnel de l’opérateur du hub de concevoir et générer un large éventail de rapports basés sur les données stockées dans les bases de données et les grands livres de Mojaloop. Le Framework prend aussi en charge l’intégration de ces rapports dans n’importe lequel des portails opérateur, permettant de générer les rapports selon les besoins du personnel d’exploitation. + +Cela inclut les rapports liés à la compensation. + +## Applicabilité + +La présente version de ce document se rapporte à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14 avril 2025| Paul Makin|Mises à jour liées à la publication de la V17| +|1.0|5 février 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/risk.md b/docs/fr/product/features/risk.md new file mode 100644 index 000000000..1f9e8c476 --- /dev/null +++ b/docs/fr/product/features/risk.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Gestion des risques +--- + +# Gestion des risques + +Un aspect fondamental de l’exploitation d’un schéma de paiement construit autour d’un hub Mojaloop est la gestion du risque entre les parties transactionnelles, qui ont elles-mêmes des appétences différentes pour le risque. Les principes appliqués sont les suivants : + +1. Tous les Participants (FSP) sont tenus de déposer une forme de liquidité convenue auprès du partenaire de règlement du Schéma. Cette liquidité ne peut être retirée, en tout ou partie, du schéma qu’avec l’accord de l’opérateur de schéma. +   +2. Une transaction n’est compensée (phase de transfert) que s’il existe une liquidité disponible suffisante pour la couvrir, calculée au regard du solde de liquidité, de la Position courante du DFSP (solde net des transactions déjà compensées depuis la dernière activité de règlement, en tant que payeur ou bénéficiaire) et des fonds réservés. +   +3. La valeur d’une transaction compensée est ajoutée à la Position du DFSP payeur et déduite de la Position du DFSP bénéficiaire. +   +4. Lors du règlement, pour chaque DFSP, une position négative est débitée du solde de liquidité et transférée au partenaire de règlement pour distribution aux créanciers ; une position positive est créditée sur le solde de liquidité par le partenaire de règlement à partir des fonds des débiteurs. +   +5. Un règlement réussi solde la valeur représentée par les transactions de la fenêtre ou du lot de règlement associé dans la position de chaque DFSP. +   +6. Un DFSP est tenu de gérer sa liquidité : l’augmenter si elle tombe à un niveau où les valeurs de transaction anticipées risquent d’entraîner des échecs de transaction, ou en retirer une partie (sur demande formelle adressée à l’Opérateur de Schéma) si elle est trop élevée. Ces opérations ont lieu en dehors de Mojaloop, mais il est exigé qu’elles soient déclarées au sein du Schéma Mojaloop, par le DFSP ou par le partenaire de règlement. +   +7. Si le partenaire de règlement n’est pas disponible 24h/24, un DFSP peut déposer un excédent sur son compte de liquidité, par exemple pour couvrir les transactions prévues pendant une période de fermeture ou de jours fériés. Ce reliquat peut être géré via un plafond de débit net (NDC), par exemple pour limiter l’usage de la liquidité au niveau attendu un jour donné et préserver la capacité à traiter pendant toute la période de fermeture. Le NDC s’utilise conjointement avec le solde de liquidité pour l’autorisation des transactions pendant la phase de devis. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14 avril 2025| Paul Makin|Mises à jour liées à la sortie de la V17| +|1.0|13 mars 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/security.md b/docs/fr/product/features/security.md new file mode 100644 index 000000000..c6ef9662c --- /dev/null +++ b/docs/fr/product/features/security.md @@ -0,0 +1,91 @@ +--- +sidebarTitle: Sécurité +--- + +# Sécurité + +## Open source et sécurité + +Une idée reçue veut que le logiciel open source soit intrinsèquement moins sûr que le logiciel propriétaire, parce que le code est visible, tout simplement. L’argument avancé est le suivant : si le code est public, il doit être plus facile de découvrir des vulnérabilités. En réalité, cette vision méconnaît le fonctionnement de la cybersécurité moderne. + +La sécurité de Mojaloop ne repose pas sur l’obscurité du code. Elle s’appuie sur des algorithmes cryptographiques open source éprouvés, élaborés par des experts et publiés pour relecture par les pairs. Ils sont testés en profondeur par la communauté cryptographique mondiale ; lorsqu’une faille est trouvée, les correctifs sont partagés ouvertement et rapidement, au bénéfice de tous les utilisateurs, Mojaloop y compris. + +C’est comparable aux serrures physiques : le mécanisme d’une serrure Yale n’est pas secret — les brevets sont publics et chacun peut étudier son fonctionnement. Pourtant la serrure reste sûre, non parce que le mécanisme est caché, mais parce que seule la bonne clé unique peut l’ouvrir. La cryptographie fonctionne de la même manière : les algorithmes modernes reposent sur le secret des clés, pas sur la dissimulation de l’algorithme. + +Il en va de même pour l’ensemble du code Mojaloop : en open source, chacun peut examiner le code et signaler des vulnérabilités. Des équipes de la communauté Mojaloop participent activement à ce processus et font remonter les problèmes identifiés dans le cadre qualité / sécurité pour examen et correction. Des vulnérabilités potentielles sont régulièrement signalées par des acteurs extérieurs au noyau de la communauté ; elles sont analysées et traitées par les équipes qualité et sécurité. Le lecteur peut trouver des informations plus détaillées et techniques dans la section [Maintien de la sécurité](#maintien-de-la-securite) ci-dessous. + +## Sécurité Mojaloop + +Mojaloop s’appuie sur ces pratiques et algorithmes pour un modèle de sécurité multicouche, complexe et soumis à une veille et des revues continues. + +On peut le décomposer en trois domaines : + +- la sécurité de la connexion entre le Hub Mojaloop et les DFSP participants (transactions et établissement / maintien de la connexion) ; +- la sécurité de l’exploitation du Hub, notamment des actions des opérationnels ; +- la qualité et la sécurité du déploiement du Hub Mojaloop. + +Les sections suivantes détaillent chaque axe. + +## Sécurité de la connexion DFSP + +La connexion entre un DFSP participant et le Hub Mojaloop combine trois niveaux de sécurité pour l’intégrité, la confidentialité et la non-répudiation des messages entre un DFSP, le Hub et, le cas échéant, l’autre DFSP de la transaction. + +Le schéma suivant illustre ces trois niveaux. + +![Couches de sécurité des connexions Mojaloop](./mojaloop_security_layers.jpg) + +Au niveau le plus bas, la connexion point à point entre un DFSP (participant autorisé) et le Hub Mojaloop est sécurisée par **mTLS**, ce qui garantit la confidentialité, l’authenticité des correspondants et la protection contre l’altération des échanges. + +Ensuite, le contenu des messages JSON est **signé cryptographiquement** selon **JWS** ([RFC 7515](https://www.rfc-editor.org/rfc/rfc7515.html)), ce qui assure aux destinataires que les messages ont bien été envoyés par la partie qui prétend les avoir envoyés, et simultanément que cette provenance ne peut être répudiée par l’émetteur. + +Enfin, les conditions du transfert sont sécurisées par le **protocole Interledger (ILP)** entre payeur et bénéficiaire. ILP utilise un [contrat à secret de hachage et délai (HTLC)](./htlc.md) pour protéger l’intégrité de la condition de paiement et de son accomplissement (*fulfilment*). Ainsi, Mojaloop garantit qu’un transfert se termine entièrement pour toutes les parties ou pas du tout, et limite la durée de validité de l’instruction de transfert. + +Ces trois couches sont intégrées au Hub Mojaloop. Côté DFSP, elles peuvent être mises en œuvre directement par les équipes d’ingénierie. La communauté Mojaloop propose aussi [un ensemble d’outils](./connectivity.md) qui établissent et maintiennent ces couches et orchestrent les communications / API avec le Hub, tout en restant dans le périmètre du DFSP (et donc hors Hub Mojaloop). + +## Sécurité opérationnelle du Hub + +La sécurité du Hub Mojaloop dépasse les connexions aux DFSP et inclut la sécurité des actions des opérateurs via les différents [portails Hub](./product.md). + +Les portails s’appuient sur le Business Operations Framework (BOF) de Mojaloop, qui fournit les portails cœur et des API permettant à l’opérateur du Hub d’étendre ces portails ou d’en créer de nouveaux selon ses besoins. + +Pour gérer la sécurité de ces portails, le BOF canalise l’activité via un cadre unique d’**identité et d’accès (IAM)** intégrant le **contrôle d’accès basé sur les rôles (RBAC)** et, nativement, le principe **émetteur / contrôleur** (*Maker/Checker*, ou « quatre yeux »). + +L’opérateur du Hub Mojaloop dispose ainsi d’un contrôle granulaire de l’accès d’un individu aux capacités de gestion et des contrôles sur chaque activité. Il reste toutefois responsable du filtrage du personnel, de l’inscription sur l’IAM, de l’attribution des rôles et du fait que le cadre RBAC assigne correctement les rôles aux fonctions de gestion des portails (y compris émetteur / contrôleur le cas échéant). Des politiques telles que expiration des mots de passe, longueur et complexité, réutilisation, etc. sont prises en charge par l’IAM, ainsi que l’**authentification multi-facteur (MFA)** pour tous les opérateurs, selon les choix de l’opérateur (l’usage du SMS ou USSD comme canal MFA est fortement déconseillé). + +Il incombe également à l’opérateur de mettre en place les points de contrôle adaptés à un service financier (accès physique aux serveurs, usage des téléphones portables par les opérateurs, vidéosurveillance, chaîne d’approvisionnement, gestion des visiteurs, etc.) et de définir les processus métier associés. + +## Maintien de la sécurité + +La communauté Mojaloop a défini procédures et moyens pour maintenir la sécurité des déploiements face à l’évolution des attaques et à l’identification de vulnérabilités dans Mojaloop ou dans les nombreux programmes open source dont il dépend. C’est le **processus de gestion des vulnérabilités**, qui comprend notamment : + +- un **comité de sécurité**, dont le rôle est la coordination de tous les aspects de la gestion des vulnérabilités ; +- des processus de traitement des vulnérabilités potentielles lorsqu’elles ont été portées à l’attention du comité de sécurité ; +- des processus d’identification proactive des vulnérabilités et de gestion, dont : + - la surveillance continue des composants open source ; + - le **SAST** avec plusieurs outils s’appuyant sur des bases publiques de vulnérabilités ; + - la maintenance automatisée d’un **SBOM** pour l’inventaire et la gestion des dépendances ; + - l’analyse des images conteneur avant publication ; + - l’utilisation d’un scanner de licences automatisé pour n’utiliser que des composants aux licences compatibles ; + - à partir de Mojaloop Release v17.1.0, signature des charts Helm à la publication et vérification à l’installation / déploiement pour la traçabilité des artefacts ; + - une chaîne CI/CD intégrant des contrôles de sécurité ; + - un processus de **divulgation coordonnée des vulnérabilités (CVD)**, garantissant que les parties responsables disposent d’un délai suffisant pour traiter et corriger les vulnérabilités avant divulgation publique ; + - des rapports complets sont générés après chaque analyse, détaillant les résultats, les actions de remédiation et leur efficacité. Tous les rapports sont stockés pour l’audit et la conformité, garantissant la transparence et la responsabilité. + +Le lecteur peut trouver des informations plus détaillées et techniques sur le [processus de gestion des vulnérabilités Mojaloop](https://docs.mojaloop.io/technical/technical/security/security-overview.html). + +## Qualité et sécurité du déploiement + +Des membres de la communauté Mojaloop développent un **cadre d’évaluation de la qualité**, dont le but est de développer une boîte à outils pour valider la configuration, les fonctionnalités, la sécurité, la préparation à l’interopérabilité et les performances d’un déploiement. + +Il pourra servir à l’auto-certification des adopteurs ou à un examen externe pour renforcer l’assurance auprès des autorités de tutelle et des participants. + +## Applicabilité + +Ce document concerne Mojaloop version 17.1.0. + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.2|13 octobre 2025| Paul Makin|Ajout de l’introduction « Open source et sécurité ».| +|1.1|15 juillet 2025| Paul Makin|Ajout de la section « Maintenir la sécurité ».| +|1.0|24 juin 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/tariffs.md b/docs/fr/product/features/tariffs.md new file mode 100644 index 000000000..c49521981 --- /dev/null +++ b/docs/fr/product/features/tariffs.md @@ -0,0 +1,57 @@ +--- +sidebarTitle: Frais et tarifs +--- + +# Frais et tarifs + +Mojaloop prend en charge les frais de transaction grâce à une architecture pilotée par des règles, pour la transparence et l’accord à chaque étape du paiement. + +## Accord sur les conditions — négociation des frais + +Avant la transaction, Mojaloop utilise la phase **Accord sur les conditions** pour permettre aux DFSP de calculer et d’accepter tous les frais et commissions associés. + +Au début de cette phase, le DFSP payeur propose la transaction au DFSP bénéficiaire, avec un modèle de facturation : soit les frais s’ajoutent au montant payé par l’émetteur, soit ils sont déduits du montant reçu par le bénéficiaire. + +Si le DFSP payeur souhaite poursuivre, il envoie une confirmation. Le DFSP bénéficiaire transmet alors ses frais (et autres conditions) au DFSP payeur sous forme de contrat, en acceptant ou en refusant le modèle de facturation choisi. + +Si le DFSP payeur accepte les conditions du DFSP bénéficiaire, il présente les conditions du transfert au payeur, y compris le total à payer selon le modèle retenu. + +| Modèle de facturation | Payeur paie | Bénéficiaire reçoit | +| -------------- | ---------------------- | -------------------- | +| Frais à charge de l’émetteur | Montant + frais DFSP payeur + frais DFSP bénéficiaire | Montant | +| Frais à charge du bénéficiaire | Montant + frais DFSP payeur | Montant − frais DFSP bénéficiaire | + +Si le payeur accepte et souhaite poursuivre, le montant convenu du transfert est débité sur son compte par le DFSP payeur, qui retient ses propres frais et soumet au Hub Mojaloop une demande de transfert pour le reliquat, avec le contrat du bénéficiaire. + +À l’issue du transfert, le DFSP bénéficiaire retient ses frais convenus et crédite le compte du bénéficiaire du reliquat. + +Ainsi, tous les frais sont regroupés dans un seul devis : le payeur connaît le coût exact avant de valider, y compris si les frais du DFSP bénéficiaire sont payés par le payeur ou le bénéficiaire. + +## Rules Handler — frais d’interchange + +Mojaloop prend en charge des règles de frais avancées, comme les **frais d’interchange**, via son *Rules Handler*, qui évalue les transactions en cours de traitement. Par exemple, dans un paiement P2P portefeuille à portefeuille entre DFSP distincts, Mojaloop peut appliquer automatiquement 0,6 % de frais facturés par le DFSP bénéficiaire au DFSP payeur. Ils sont enregistrés au grand livre et règlés ultérieurement. + +## Frais de hub (opérateur) + +Outre les frais par transaction, les opérateurs de hub peuvent facturer des frais d’usage d’infrastructure ou d’abonnement aux DFSP participants. Ces « frais de hub » sont en général modestes — de quoi couvrir les coûts opérationnels — dans une logique de « coûts de service récupérés plus marge légère » pour limiter les frais finaux. + +--- + +### En résumé + +| Type de frais | Géré par | Quand et comment | +| ----------------------- | ---------------------- | --------------------------------------------- | +| Frais de transaction | Service d’accord sur les conditions | Cotés à l’avance, acceptés avant exécution | +| Frais d’interchange | Rules Handler + grand livre | Appliqués pendant le traitement selon les règles | +| Frais d’infrastructure hub | Opérateur de hub | Facturés séparément pour couvrir l’exploitation | + +Cette approche par couches offre à Mojaloop une forte transparence des frais, de la configurabilité, de l’automatisation et de la cohérence de règlement — essentiel pour l’interopérabilité et l’inclusion financière à coût maîtrisé. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|17 juillet 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/transaction.md b/docs/fr/product/features/transaction.md new file mode 100644 index 000000000..728196ca1 --- /dev/null +++ b/docs/fr/product/features/transaction.md @@ -0,0 +1,91 @@ +--- +sidebarTitle: Transactions +--- + + +# Transactions Mojaloop + +Cette section couvre les aspects d’une transaction Mojaloop. + +## Phases d’une transaction Mojaloop + +Un hub de paiements basé sur Mojaloop compense (route et garantit) les paiements entre comptes détenus par des parties finales (personnes, entreprises, administrations, etc.) chez les DFSP, et s’intègre à un partenaire de règlement pour orchestrer les mouvements de fonds entre DFSP participants, soit de manière simultanée (règlement brut en continu), soit de façon différée (diverses formes de règlement net), selon un calendrier de règlement convenu. + +Toutes les transactions Mojaloop sont **asynchrones** (afin de garantir l’utilisation la plus efficiente possible des ressources) et suivent **trois phases** : + +1. **Découverte**, pendant laquelle le DFSP du payeur collabore avec le Hub Mojaloop pour déterminer où envoyer le paiement. Cette phase résout un alias vers un DFSP bénéficiaire précis et, avec ce DFSP, un compte individuel. +   +2. **Accord sur les conditions (devis)**, pendant laquelle les deux DFSP parties à la transaction conviennent que la transaction peut avoir lieu (sous réserve, par exemple, de restrictions liées à un KYC par paliers) et à quelles conditions (dont frais). +   + +3. **Transfert**, lorsque la transaction entre les deux DFSP (et, par procuration, les comptes clients) est compensée. +  + +Ces phases s’inscrivent dans l’asynchronisme de Mojaloop : une transaction est toujours unique, ce qui garantit qu’elle ne sera traitée qu’une seule fois, quel que soit le nombre de fois où elle est soumise au traitement. Cette propriété est l’**idempotence** : même en cas de connectivité intermittente, le client a la garantie que son compte ne sera débité qu’une seule fois, quel que soit le nombre de tentatives. + +Cette approche en trois phases, complétée par l’idempotence, a été conçue pour minimiser le risque d’échecs transactionnels ou de doublons. Mojaloop supprime ainsi le besoin technique de rapprochement transactionnel par les DFSP, réduit la plupart des causes de litiges et minimise ainsi les coûts pour toutes les parties. + +Associée à l’approche Mojaloop de la [gestion des risques](./risk.md), elle garantit que la plus petite IMF et la plus grande banque internationale peuvent participer à égalité, sans qu’aucune n’impose de risque à l’autre ni au Hub lui-même. + +  +## API Mojaloop + +Le Hub Mojaloop expose quatre API. Les deux premières concernent les transactions clients ; les deux autres, l’administration des relations avec les DFSP participants et le règlement des transactions compensées : + +1. **API transactionnelle** +Mojaloop propose deux API transactionnelles fonctionnellement équivalentes pour les connexions directes avec les participants aux fins de transaction. Elles couvrent tous les [**cas d’usage Mojaloop**](./use-cases.md) et respectent les [principes Level One](https://www.leveloneproject.org/project_guide/level-one-project-design-principles/). Il s’agit de : + - l’**API FSP Interoperability (FSPIOP)**, une API ancienne et solidement éprouvée ; +  + - un **schéma de messages ISO 20022**, fondé sur un jeu de messages ISO 20022 provisoirement aligné entre la Mojaloop Foundation et le *Registration Management Group* (RMG) ISO 20022, adapté aux besoins d’un système de paiements instantanés inclusifs (SPII) tel que Mojaloop. Elle est proposée comme alternative à FSPIOP. Les détails complets de l’implémentation du schéma de messages ISO 20022 par Mojaloop et les modalités d’utilisation attendues de la part des DFSP participants figurent dans le [**document de pratiques de marché ISO 20022 Mojaloop**](./iso20022.md). + +2. **API d’initiation de paiement par des tiers (3PPI / PISP)** + + Cette API gère les arrangements de paiement par des tiers — paiements initiés par des fintechs pour le compte de leurs clients depuis des comptes détenus chez des DFSP connectés au Hub Mojaloop — et permet d’initier ces paiements une fois autorisés. + + +3. **API d’administration** + + Elle permet aux opérateurs de hub de gérer notamment : + + - création / activation / désactivation des participants dans le Hub ; + + - ajout et mise à jour des informations de endpoint des participants ; + + - gestion des comptes, plafonds et positions des participants ; + + - création des comptes du Hub ; + + - opérations d’entrée et de sortie de fonds ; + + - création / mise à jour / consultation des modèles de règlement, pour gestion ultérieure via l’API de règlement ; + + - consultation des détails des transferts ; + +4. **API de règlement** + + Elle sert à gérer le processus de règlement. Elle n’est pas destinée à la gestion des modèles de règlement. + +  + +## Caractéristiques distinctives des transactions + +La plupart des fonctions de Mojaloop existent aussi sur d’autres hubs de compensation. Ce qui distingue Mojaloop : + +1. **Le flux transactionnel en trois phases et l’idempotence**, décrits ci-dessus.   +2. **La phase d’accord sur les conditions (devis)**, qui permet aux deux DFSP de convenir qu’une transaction peut avoir lieu *avant* tout engagement. Cela prend en charge certains des aspects les plus complexes des transactions entre participants de types différents ; le DFSP bénéficiaire peut vérifier que le compte peut recevoir le paiement, qu’il n’est pas suspendu, que les plafonds ne seront pas dépassés. S’il accepte, il indique les frais éventuels (les frais de hub sont hors transaction). Ce n’est qu’après accord du DFSP payeur et du payeur lui-même sur ces frais et toute autre condition posée par le DFSP bénéficiaire que la transaction est initiée. L’incertitude est ainsi réduite et la probabilité de succès augmentée *avant* exécution. + +3. **La non-répudiation de bout en bout** pendant la phase de transfert garantit à chaque partie qu’un message n’a pas été modifié et qu’il provient bien de l’émetteur déclaré. Mojaloop s’appuie sur cette technologie pour que la transaction ne soit engagée que si *les deux* DFSP payeur et bénéficiaire l’acceptent, sans qu’aucun puisse la nier. Cela rend le rapprochement au niveau transactionnel inutile, ce qui réduit fortement les litiges, supprime le traitement d’exceptions et diminue substantiellement les coûts pour tous les participants. Cela soutient directement les objectifs d’inclusion financière de la Mojaloop Foundation, en levant l’un des principaux obstacles à l’inclusion : le manque de certitude, et donc de confiance, dans les paiements. + + La communauté Mojaloop met à disposition des outils gratuits pour connecter les DFSP au Hub ; ils restent dans le périmètre du DFSP. Outre la connexion et les transactions, ils assurent la sécurité du lien et notamment le chaînage à cette capacité de non-répudiation. +   +4. **L’API PISP est exposée par le Hub Mojaloop**, et non par chaque participant. Une fintech s’intègre au Hub et est immédiatement reliée à **tous** les DFSP connectés, sans intégration API individuelle avec chacun — ce qui réduit considérablement les coûts et améliore la fiabilité pour les fintechs et leurs clients. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.3|30 juin 2025| Paul Makin|Précisions mineures sur la description de l’accord sur les conditions| +|1.2|14 avril 2025| Paul Makin|Mises à jour liées à la sortie de la V17| diff --git a/docs/fr/product/features/use-cases.md b/docs/fr/product/features/use-cases.md new file mode 100644 index 000000000..7c3918fba --- /dev/null +++ b/docs/fr/product/features/use-cases.md @@ -0,0 +1,102 @@ +--- +sidebarTitle: Cas d’usage +--- + +# Cas d’usage + +La fonction centrale d’un hub Mojaloop est la compensation du transfert de fonds entre deux comptes, chacun détenu chez un DFSP connecté au hub, couramment désigné sous le terme de virement initié par le payeur (*push payment*). Cela lui permet de prendre en charge un large éventail de cas d’usage. Ce n’est toutefois pas le seul type de transfert pris en charge par Mojaloop. + +La description ci-dessous des cas d’usage pris en charge par Mojaloop est regroupée selon les types de protocole sous-jacents, afin de montrer le caractère extensible d’un hub Mojaloop. On distingue notamment : +- les **paiements poussés**, qui couvrent les cas d’usage fondamentaux P2P, B2B, etc. ; +- la **demande de paiement** (*Request To Pay*), qui prend en charge certains paiements commerçants, le commerce électronique et les recouvrements ; +- une gamme de **services d’espèces**, dont le CICO et l’hors ligne ; +- les **protocoles PISP/3PPI**, qui permettent aux fintechs et à d’autres acteurs de proposer des services tels que paiements commerçants, versements salariaux à petite échelle, recouvrements, etc. ; +- les **paiements de masse**, pour les versements sociaux à l’échelle nationale et les salaires ; +- les **paiements transfrontaliers**, y compris les envois de fonds et les paiements commerçants. + +Ces éléments sont détaillés ci-dessous. En lisant ces descriptions, il convient de garder à l’esprit que nombre de ces types de transaction [permettent le transport de métadonnées au sein même du flux de paiement](./metadata.md). + +(Pour une vision centrée sur les API, voir la [section cas d’usage de la documentation API Mojaloop](https://docs.mojaloop.io/api/fspiop/use-cases.html#table-1).) +## Cas d’usage « paiement poussé » (*Push Payment*) +Un hub Mojaloop prend directement en charge les cas d’usage suivants, qui sont autant de variantes de paiements poussés : +- personne à personne (**P2P**) ; +- personne à entreprise (**P2B**), y compris des formes simples de paiement commerçant, en présentiel et à distance (en ligne) ; +- entreprise à entreprise (**B2B**) ; +- entreprise à administration (**B2G**) ; +- formes simples de paiements personne à administration (**P2G**). + +Pour tous les types de paiement commerçant, le paiement peut être facilité par des identifiants commerçant (pour l’USSD) ou des codes QR (smartphones). + +## Cas d’usage « demande de paiement » (*Request To Pay*) + +Outre les paiements poussés, Mojaloop prend en charge les transactions de demande de paiement (RTP), dans lesquelles un bénéficiaire demande un paiement à un payeur et, _lorsque le payeur consent_, son DFSP exécute le paiement vers le bénéficiaire au nom du payeur. Cela couvre notamment les cas d’usage suivants : + +- **Paiements commerçants**, en environnement de face à face, par exemple via un code QR ; + - Les aspects pratiques de la configuration de la solution Paiements commerçants Mojaloop, y compris le contenu des codes QR, sont traités dans [**Comment configurer les paiements commerçants pour Mojaloop**](./merchant-payments.md). + - Pour tous les paiements commerçants en face à face, le paiement peut être facilité par des identifiants commerçant (USSD) ou des codes QR (smartphones). +- **Commerce électronique**, parfois appelé paiement commerçant à distance, lorsque par exemple une page de paiement (site web ou application mobile) inclut un bouton du type « payer depuis mon compte bancaire », déclenchant une RTP. + +- **Recouvrements**, y compris P2G, P2B, B2B et B2G, couramment utilisés pour le règlement de factures d’utilités. Cela peut aussi passer par l’interface fintech/3PPI décrite ci-dessous — la décision relève de l’opérateur de schéma. + +## Services d’espèces +Un hub Mojaloop prend directement en charge les opérations d’entrée/sortie d’espèces interopérables courantes attendues par tout DFSP (et ses clients) : +- **Distributeur sans carte**, par intégration aux réseaux de GAB, via le protocole ISO 8583 ; +- **Entrée / sortie d’espèces (CICO) chez un agent hors réseau** (*off-us agent*) ; +- **Espèces hors ligne** : + - Un hub Mojaloop peut soutenir les schémas de paiement **espèces hors ligne**, car ce type de schéma est traité comme des espèces, bien que sous forme numérique. Un retrait vers un portefeuille espèces hors ligne (chargement) s’apparente ainsi à une sortie d’espèces ; un dépôt depuis un tel portefeuille (versement) s’apparente à une entrée d’espèces. L’opérateur du schéma peut toutefois exiger que toutes ces opérations de chargement/versement de portefeuille, qu’elles soient sur son réseau ou hors réseau, transitent par le hub Mojaloop pour faciliter la réconciliation du schéma hors ligne. + +## Cas d’usage « 3PPI » — Fintechs et autres +Un hub Mojaloop prend directement en charge l’initiation de paiement par un tiers (3PPI), afin que les prestataires de services d’initiation de paiement (PISP) — souvent appelés fintechs — puissent, via leurs propres applications mobiles, recruter des clients et leur proposer un service de paiement unifié ou enrichi. La plupart des DFSP connectés à un hub Mojaloop peuvent proposer des services 3PPI s’ils disposent d’un back-office relativement moderne. + +Une fintech peut utiliser le service 3PPI pour lancer une demande de paiement (RTP) — en demandant au DFSP de son client d’initier un paiement vers un bénéficiaire. Cela couvre notamment : +- les **recouvrements**, en particulier P2G et P2B ; +- les **paiements de salaires**, essentiellement le traitement d’une liste de paiements de masse pour le compte de petites et moyennes entreprises ; +- les **paiements commerçants** (P2B), avec initiation par code QR. + +## Cas d’usage « paiement de masse » (*Bulk Payment*) +Tout service de paiement doit permettre les paiements de masse ; Mojaloop le propose selon un modèle très efficace. Tous les DFSP, à l’exception des plus petits d’entre eux, peuvent offrir ce service à leurs clients, qui peuvent soumettre des listes de paiements atteignant tout client de tout DFSP connecté. Cela sert notamment à : +- **pensions, prestations sociales et autres versements** (G2P) ; +- **salaires** (G2P et B2P). + +En outre, la fonctionnalité de paiement de masse est disponible via le **service 3PPI** (ci-dessus), ce qui permet à tous les DFSP — y compris les plus petits — d’offrir un service de paiements de masse à plus petite échelle, par l’intermédiaire d’une fintech ou directement via leur propre service 3PPI. + + +## Cas d’usage « transfrontalier » (*Cross Border*) + +Un hub Mojaloop peut permettre aux clients d’un DFSP d’envoyer de l’argent à l’étranger à moindre coût, en intégrant le processus de change (FX) dans la transaction. Cela couvre notamment : +- **P2P** et **P2B** (envoi à la famille et aux proches à l’étranger, ou règlement d’une facture dans un autre pays) ; +- **paiements commerçants**, via RTP transfrontalier (par exemple un petit commerçant qui franchit une frontière proche pour vendre sur un marché local et encaisser dans la monnaie locale). + +Pour explorer les éléments de l’écosystème Mojaloop qui le rendent possible, il est recommandé de consulter : +1. La possibilité de connecter un hub Mojaloop à des schémas de paiement voisins, dans le même pays ou ailleurs, pour assurer l’interopérabilité. Cette capacité [**est présentée ici**](./InterconnectingSchemes.md). + +2. La prise en charge des fournisseurs de change (FXP) se connectant à un hub Mojaloop pour proposer des services FX. Ni le payeur ni le bénéficiaire n’a besoin de spécifier la devise à utiliser pour la transaction ; chacun opère dans sa propre devise, et le ou les hub(s) Mojaloop assure(nt) l’échange. Cette capacité [**est présentée ici**](./ForeignExchange.md). + +3. La manière dont l’interconnexion / l’inter-schéma et le change sont combinés pour soutenir les [**transactions transfrontalières**](./CrossBorder.md). +## Autres ; paiements par carte +De nombreux adopteurs potentiels se demandent s’il est possible d’utiliser Mojaloop pour commuter des transactions carte. La réponse est que, techniquement, commuter une transaction carte est tout à fait envisageable ; le numéro de compte personnel (PAN) de la carte peut servir d’alias pour initier une RTP, d’autant que le numéro d’identification bancaire (BIN), partie du PAN, identifie le DFSP qui détient le compte du client, vers lequel la RTP doit être routée. + +En pratique toutefois, le terminal point de vente (PoS) carte devrait être adapté pour router les transactions en conséquence : transactions domestiques via une RTP vers le commutateur Mojaloop, le reste vers le réseau carte émetteur. Ces terminaux appartiennent souvent aux banques acquéreuses, peu enclines à en ouvrir l’accès (les grandes enseignes, qui possèdent souvent leurs propres PoS, souvent intégrés, peuvent être plus favorables). + +De plus, rediriger des transactions initiées avec une carte portant le logo d’un réseau international serait totalement inapproprié et exposerait quasi certainement toutes les parties impliquées à une situation juridique précaire. Cette approche ne devrait donc être envisagée que lorsqu’un schéma carte domestique est utilisé et que son propriétaire accepte que ses cartes servent de la sorte. + +Enfin, une telle approche se rapproche davantage d’une transaction RTP Mojaloop pour les cartes de débit ; l’utiliser pour une carte de crédit — impliquant par exemple une mise en réserve de fonds (comme lors d’un enregistrement à l’hôtel) — ajouterait une complexité supplémentaire. + +## Cas d’usage étendus + +Outre ces cas d’usage standard, Mojaloop permet aux adopteurs de mettre en œuvre des cas d’usage plus complexes, qui ajoutent des fonctionnalités et se superposent aux cas standard. + +Ces cas propres à un schéma peuvent être ajoutés aisément par chaque opérateur de schéma. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.6|24 juillet 2025| Paul Makin|Correction de liens cassés.| +|1.5|16 juillet 2025| Paul Makin|Sous-titres alignés sur l’introduction ; descriptions affinées ; lien vers les métadonnées ; note sur les transactions par carte.| +|1.4|12 juin 2025| Paul Makin|Introduction étendue pour expliquer le regroupement des cas d’usage.| +|1.3|10 juin 2025| Paul Makin|Description des paiements e-commerce via RTP ; 3PPI intitulé paiements fintech ; précision sur l’initiation des paiements de masse via 3PPI ; mises en forme des liens.| +|1.2|14 avril 2025| Paul Makin|Mises à jour liées à la sortie de la V17, y compris liens vers la documentation inter-schéma et FX.| diff --git a/docs/fr/product/features/workstreams/core.md b/docs/fr/product/features/workstreams/core.md new file mode 100644 index 000000000..8f6514ebe --- /dev/null +++ b/docs/fr/product/features/workstreams/core.md @@ -0,0 +1,39 @@ +--- +sidebarTitle: Cœur et versions +--- + +# Workstream Cœur et versions + +Le workstream Cœur et versions maintient le cœur Mojaloop (correctifs de bugs critiques, évolutions prioritaires, montées de version des nœuds) et conduit les versions des services cœur et de certains services ou produits adjacents de la plateforme Mojaloop. + +Il aide aussi les autres workstreams à livrer des fonctionnalités dans le cœur ou les services de support en empaquetant des services prêts pour la release (tests automatisés, documentation, charts Helm, etc.), avec l’appui de la communauté. + +# Justification métier + +La gestion du cœur Mojaloop et des versions open source de la plateforme est fondamentale pour l’offre. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Sam Kummary | Shashi Hirugade
Juan Correa | + +## Dernière mise à jour (résumé) +Le code de la RC 17.2.0 passe environ 80 % des tests automatisés sur huit collections majeures ; les tests restants sont bloqués par des changements sécurité du Testing Toolkit. Une fois levés et les vulnérabilités traitées, la sortie pourra suivre. + +La version 17.2.0 apportera notamment : +- des gains de performance majeurs ; +- la prise en charge LEI dans les services commerçants ; +- l’intégration de Connection Manager dans Helm ; +- des correctifs importants issus de DRPP. + +L’équipe évaluera début 2026 si la prochaine version sera mineure ou la v18 basée sur TigerBeetle. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/deployment.md b/docs/fr/product/features/workstreams/deployment.md new file mode 100644 index 000000000..c22e174ce --- /dev/null +++ b/docs/fr/product/features/workstreams/deployment.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Workstream déploiement +--- + +# Workstream Outils de déploiement + +Ce workstream fournit outils, documentation et accompagnement pour permettre aux adopteurs de déployer Mojaloop dans des environnements variés, cloud et sur site. + +# Justification métier + +Une suite d’outils bien documentée et complète, permettant d’explorer, développer, tester, évaluer et exploiter le logiciel, est essentielle à la pérennité des SIIP basés sur Mojaloop. + +L’objectif est de permettre un déploiement simple, dans l’environnement de choix, avec un minimum d’appui de la communauté. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| James Bush | Tony Williams
Vanda Illyes
Sam Kummary
Paul Makin
Paul Baker
Michael Richards| + +## Dernière mise à jour (résumé) +Des contributions DRPP à l’IaC ont accru les coûts d’infrastructure en optimisant de gros déploiements multi-instances. Pour les petits schémas, l’équipe a développé une alternative allégée — provisoirement « IAC Lite ». Des tests de déploiement tournent sur AWS et sur le lab de la Foundation. Objectif : une expérience open source rationalisée, peu gourmande, avec un minimum d’étapes manuelles. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/dispute.md b/docs/fr/product/features/workstreams/dispute.md new file mode 100644 index 000000000..53768ba14 --- /dev/null +++ b/docs/fr/product/features/workstreams/dispute.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Litiges +--- + +# Workstream Gestion des litiges + +Ce workstream vise une solution de gestion des litiges intégrable au cœur Mojaloop et aux DFSP connectés, pour les opérateurs de hub et les DFSP participants, sur l’ensemble des types de déploiement. + +# Justification métier + +La fiabilité des transactions Mojaloop appelle une solution dédiée open source de gestion des litiges. + +Les solutions génériques supposent souvent une découverte limitée et peu ou pas d’accord sur les conditions, ce qui multiplie les litiges ; elles ne correspondent pas bien à un déploiement Mojaloop. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Promesse Ishimwe | Derrick Wamatu | + +## Dernière mise à jour (résumé) +Aucune mise à jour du workstream Gestion des litiges sur ce cycle. Promesse n’a pas pu assister à l’appel et aucune mise à jour écrite n’a été fournie. Une mise à jour est attendue à la prochaine session. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/evolution.md b/docs/fr/product/features/workstreams/evolution.md new file mode 100644 index 000000000..0dedc1704 --- /dev/null +++ b/docs/fr/product/features/workstreams/evolution.md @@ -0,0 +1,41 @@ +--- +sidebarTitle: Évolution Mojaloop +--- + +# Workstream Évolution Mojaloop + +Ce workstream vise une évolution majeure des services centraux critiques de Mojaloop : +- remplacer la fonctionnalité de comptabilité au cœur de Mojaloop par TigerBeetle ; +- remplacer le cœur du moteur de règlement par des capacités TigerBeetle alignées avec Settlement V3. + +# Justification métier + +TigerBeetle est la technologie de grand livre de nouvelle génération pensée pour Mojaloop, avec un potentiel d’amélioration du débit d’au moins un ordre de grandeur. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Michael Richards | James Bush
Lewis Daley
Sam Kummary
Paul Makin | + +## Dernière mise à jour (résumé) +### Audit forensic +La refonte de l’audit forensic est prête à être implémentée mais attend le financement de projets d’adoption à venir. Peu de progrès attendus avant mi-T1 2026. + +### Nouveau modèle comptable +Le nouveau modèle est largement validé et marque un alignement majeur sur les normes comptables internationales, répondant aux préoccupations des institutions mondiales et renforçant la crédibilité de Mojaloop comme infrastructure financière. Cible initiale : TigerBeetle ; la production d’une version MySQL du nouveau modèle n’est pas encore tranchée. + +### Intégration TigerBeetle +Compte tenu de la complexité accrue du modèle comptable, TigerBeetle est le moteur de grand livre privilégié. La planification d’intégration est en cours ; les travaux devraient démarrer avant fin d’année. + +### Settlement v3 +Settlement v3 introduit des lots de règlement déterministes, pour des problèmes de rapprochement de longue date et une montée en charge multi-schémas. TigerBeetle stockera les clés de lot de règlement ; les composants SQL et les API d’administration devront évoluer fortement pour la configuration du modèle, le suivi des lots et les opérations de règlement. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/fintech_participation.md b/docs/fr/product/features/workstreams/fintech_participation.md new file mode 100644 index 000000000..34f64d65f --- /dev/null +++ b/docs/fr/product/features/workstreams/fintech_participation.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Participation fintech +--- + +# Workstream Outils de participation pour les fintechs + +L’objectif de ce workstream est de développer une offre « outils Fintech » pour aider les fintechs et acteurs assimilés à intégrer leurs systèmes à un Hub Mojaloop via l’interface PISP. + +# Justification métier + +Faciliter l’offre de services par les fintechs connectées à un schéma de paiements Mojaloop en réduisant temps, coût et complexité — techniques et métier. + +Cela devrait favoriser des schémas Mojaloop plus dynamiques et inclusifs, avec un impact sur l’accès aux paiements instantanés pour plus de personnes. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Alain Kajangwe | Jean de Dieu Uwizeye
Bonaparte Ituze
Yvan Rugwe | + +## Dernière mise à jour (résumé) +Aucune mise à jour du workstream Participation fintech (*Open Banking*) sur ce cycle. Alain n’a pas pu assister à l’appel et aucune mise à jour écrite n’a été fournie. Une mise à jour est attendue à la prochaine session. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/iso20022.md b/docs/fr/product/features/workstreams/iso20022.md new file mode 100644 index 000000000..4e74db840 --- /dev/null +++ b/docs/fr/product/features/workstreams/iso20022.md @@ -0,0 +1,28 @@ +--- +sidebarTitle: ISO 20022 +--- + +# Workstream Affinage ISO 20022 + +Ce workstream affine l’implémentation ISO 20022 livrée avec Mojaloop V17.0.0 à partir du retour des adopteurs, y compris les messages ISO 20022 définis dans le *Market Practice Document* (MPD) et les mises à jour du MPD lui-même. + +# Justification métier + +ISO 20022 devient rapidement la norme mondiale de messagerie pour les systèmes de paiement ; les messages SIIP Mojaloop en ISO 20022, dont l’accord sur les conditions (*Agreement of Terms*), s’inscrivent dans ce mouvement. Les détails ne sont toutefois pas encore figés et des affinements restent probables. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Michael Richards |Paul Baker
Julie Guetta | + +## Dernière mise à jour (résumé) +Pas de mise à jour récente. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/lei.md b/docs/fr/product/features/workstreams/lei.md new file mode 100644 index 000000000..b055ded6d --- /dev/null +++ b/docs/fr/product/features/workstreams/lei.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Adressage LEI +--- + +# Workstream Adressage LEI + +Ce workstream soutient les transactions commerçants nationales et transfrontalières par l’adoption de l’identifiant international LEI. C’est une collaboration entre la Mojaloop Foundation et GLEIF, devant aboutir à un pilote avec un adopteur Mojaloop. + +# Justification métier + +La collaboration avec GLEIF est stratégique pour la Foundation : GLEIF bénéficie du soutien de l’« establishment » financier (FSB, G20). + +Elle renforce aussi la crédibilité sur les paiements commerçants transfrontaliers et complète le travail ISO 20022 en introduisant les LEI dans l’écosystème Mojaloop. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Clare Rowley
Ololade Osunsanya | Michael Richards
Paul Makin
Shuchita Prakash
Sam Kummary
James Bush
Xiaodi Wang | + +## Dernière mise à jour (résumé) +La documentation est la priorité : intégration des flux LEI dans l’introduction à Mojaloop, et préparation de la collaboration avec le workstream ISO 20022 sur des exemples de messages, notamment un cas P2B avec LEI comme identifiant bénéficiaire. Les questions plus larges sur l’application des LEI aux identités DFSP sont reportées compte tenu de la complexité et des implications réglementaires. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/participation.md b/docs/fr/product/features/workstreams/participation.md new file mode 100644 index 000000000..ed9e8979d --- /dev/null +++ b/docs/fr/product/features/workstreams/participation.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Outils de participation +--- + +# Workstream Outils de participation + +L’objectif global du workstream Outils de participation est de constituer une offre « outils DFSP » pour aider les DFSP et les intégrateurs à intégrer leurs systèmes à un Hub Mojaloop. Au-delà de solutions semi-finales, le portefeuille comprend les outils nécessaires à l’intégration et des implémentations exemplaires adaptées à différents profils de DFSP. + +Il convient de rappeler à tous les DFSP que les bénéfices d’une solution de paiement instantané inclusive comme Mojaloop reposent sur une démarche « écosystème complet » : étendre la portée du service Mojaloop dans leurs environnements pour offrir à eux et à leurs clients finalité des transactions, coûts réduits et exécution fiable de chaque transaction valide. + +# Justification métier + +En réduisant les obstacles de temps, de coût et de complexité — techniques et métier — pour des DFSP de profils variés, on favorise la croissance et l’ampleur des schémas Mojaloop, avec un impact sur l’accès de plus de personnes aux paiements instantanés inclusifs. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| James Bush | Sam Kummary
Yevhen Kryiukha
Paul Baker
Vijay Kumar
Phil Green
Steve Haley
Paul Makin | + +## Dernière mise à jour (résumé) +Le workstream progresse sur l’intégration des participants, notamment grâce au Mojaloop Connection Manager (MCM). Découplé du code IaC, le MCM peut être adopté séparément par les schémas, ce qui élargit son usage. La documentation est la priorité la plus urgente ; un rédacteur technique prépare des contenus couvrant MCM, Payment Manager et l’Integration Toolkit. De la documentation donnée par Infitx sera généralisée pour la communauté. De nouveaux mini-guides ont été publiés pour faciliter la navigation dans les outils Mojaloop. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/performance.md b/docs/fr/product/features/workstreams/performance.md new file mode 100644 index 000000000..2ca02dd72 --- /dev/null +++ b/docs/fr/product/features/workstreams/performance.md @@ -0,0 +1,31 @@ +--- +sidebarTitle: Workstream performance +--- + +# Workstream Optimisation des performances + +Démontrer les performances de Mojaloop dans diverses configurations de déploiement, produire et publier un livre blanc. Utiliser une configuration de référence sur site pour mesurer l’évolution des performances entre versions Mojaloop. + +# Justification métier + +Un livre blanc montrant que Mojaloop dépasse les exigences de performance des adopteurs serait un atout majeur pour la communauté. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| James Bush | Julie Guetta
Shashi Hirugade
Sam Kummary
Nathan Delma
Ablipay (Jerome, équipe)| + +## Dernière mise à jour (résumé) +Le workstream a atteint 1 000 TPS avant la rencontre de Nairobi. Avec réplication, le débit reste élevé (950 TPS). L’équipe vise 2 000 et 2 500 TPS pour le livre blanc, avec des recommandations de dimensionnement matériel. Les premiers tests TigerBeetle suggèrent des gains de performance importants et une baisse des coûts d’infrastructure. + +Le *tiering* du stockage à long terme a été identifié comme essentiel aux obligations de conservation réglementaire dans les schémas à fort volume. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/pqs.md b/docs/fr/product/features/workstreams/pqs.md new file mode 100644 index 000000000..cfc1b9d88 --- /dev/null +++ b/docs/fr/product/features/workstreams/pqs.md @@ -0,0 +1,29 @@ +--- +sidebarTitle: Qualité et sécurité +--- + +# Workstream Qualité et sécurité de plateforme (PQS) + +Le workstream PQS est dédié à l’évaluation, au maintien et aux renforcements de la sécurité et de la qualité de la plateforme Mojaloop : connectivité des DFSP participants (y compris transactions), sécurité des portails opérateur, et qualité / sécurité du code open source Mojaloop et des artefacts associés. + +# Justification métier + +Maintenir la qualité et la sécurité de la plateforme Mojaloop ; assurer la gestion des vulnérabilités et planifier les correctifs. Travailler avec adopteurs et membres de la communauté pour améliorer progressivement sécurité et qualité. Fournir des fonctionnalités favorisant la conformité et combler les lacunes. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Sam Kummary | Juan Correa
Devarsh Shah
Shuchita Prakash
Shashi Hirugade | + +## Dernière mise à jour (résumé) +L’équipe vise une release candidate 17.2.0 avant fin d’année : durcissement sécurité, mises à jour des dépendances, fiabilité CI. Des outils d’IA génèrent désormais des PR automatiques pour les dépendances internes Mojaloop, réduisant fortement la charge manuelle. Le portail Finance nécessite une refonte plus large (technologie obsolète). Le workstream a aussi évalué le bac à sable IaC Mojaloop par rapport au nouveau cadre QA. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/product/features/workstreams/qa.md b/docs/fr/product/features/workstreams/qa.md new file mode 100644 index 000000000..34e01a1ed --- /dev/null +++ b/docs/fr/product/features/workstreams/qa.md @@ -0,0 +1,34 @@ +--- +sidebarTitle: Cadre QA +--- + +# Workstream Cadre QA + +L’objectif est de développer un cadre QA pour valider la configuration, les fonctionnalités, la sécurité, la préparation à l’interopérabilité et les performances d’un déploiement. Il pourra servir à l’auto-évaluation des adopteurs ou à un examen externe pour rassurer autorités de tutelle et participants. + +# Justification métier + +Un cadre QA offre une approche cohérente pour évaluer qualité et maturité des déploiements Mojaloop, y compris par des évaluations indépendantes de résilience, sécurité et intégrité fonctionnelle. Une démarche structurée permet : + +- aux équipes de déploiement d’identifier et combler les lacunes tôt ; +- aux participants d’évaluer la préparation opérationnelle avant intégration ; +- aux régulateurs d’interpréter la qualité d’implémentation à partir d’éléments objectifs ; +- à la communauté Mojaloop de partager les bonnes pratiques et d’aligner les attentes minimales. + +## Contributeurs +|Responsable du workstream|Contributeurs| +|:--------------:|:--------------:| +| Moses Kipchirchir | Denis Mariru
Brian Njoroge
Ei Nghon Phoo
Sam Kummary | + +## Dernière mise à jour (résumé) +L’ébauche du cadre QA est publiée sur GitHub et Slack et utilisable immédiatement par la communauté. Les retours des adopteurs guideront les affinements. Des discussions explorent une version automatisée du cadre dans le pipeline de déploiement ; l’automatisation complète reste un objectif à plus long terme. + +## Applicabilité + +La présente version de ce document correspond à Mojaloop [version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0). + +## Historique du document + |Version|Date|Auteur|Détail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4 décembre 2025| Paul Makin|Ajout de la dernière mise à jour| +|1.0|25 novembre 2025| Paul Makin|Version initiale| diff --git a/docs/fr/quickstarts/README.md b/docs/fr/quickstarts/README.md new file mode 100644 index 000000000..5dbb11c50 --- /dev/null +++ b/docs/fr/quickstarts/README.md @@ -0,0 +1,10 @@ +# Votre première action + +Pour vous aider à bien démarrer avec Mojaloop, choisissez l’option ci-dessous qui correspond le mieux à vos besoins : + +1. [Voir les guides de démarrage rapide](/1-overview/) +1. [Regarder une démo](/99-demos/) +1. [Lire la documentation](/1-overview/) +1. [Tester les API Mojaloop](/1-overview/#apis) +1. [Suivre un programme de formation](/3-guides/1_dfsp_setup/) +1. [Contribuer à Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/docs/fr/technical/README.md b/docs/fr/technical/README.md new file mode 100644 index 000000000..dfd204124 --- /dev/null +++ b/docs/fr/technical/README.md @@ -0,0 +1,16 @@ +# Vue d'ensemble technique de Mojaloop + +## Services Mojaloop + +L'idée principale derrière Mojaloop est de connecter plusieurs fournisseurs de services financiers numériques (DFSP: de l'anglais, Digital Financial Services Providers) au sein d'un réseau compétitif et interopérable, afin de maximiser les possibilités pour les populations à faible revenu d'accéder à des services financiers à faibles coûts ou sans frais. Nous ne souhaitons pas qu'une seule entité ait le monopole sur tous les paiements d'un pays, ni qu'un système exclue de nouveaux entrants. Avoir trop de sous-réseaux isolés n’est pas non plus une solution. Les schémas suivants illustrent les interconnexions Mojaloop entre les DFSP et le Hub Mojaloop (exemple de schéma d’implémentation) pour un transfert pair-à-pair (P2P) : + +Mojaloop répond à ces défis de plusieurs façons clés : +* Un ensemble de services centraux fournit un hub permettant à l’argent de circuler d’un DFSP à un autre. Ceci est similaire au fonctionnement d’une banque centrale ou d’une chambre de compensation dans les pays développés. Outre le registre central, ces services peuvent fournir la résolution d'identité, la gestion de la fraude et l’application des règles du système. +* Un ensemble standardisé d’interfaces qu’un DFSP peut mettre en œuvre pour se connecter au système, ainsi que des exemples de code montrant comment utiliser le système. Un DFSP souhaitant se connecter peut adapter notre exemple de code ou implémenter les interfaces standardisées dans son propre logiciel. L'objectif est que la connexion au réseau interopérable soit aussi simple que possible pour un DFSP. +* Des implémentations open-source complètes et fonctionnelles des deux côtés des interfaces : un exemple de DFSP qui peut envoyer et recevoir des paiements, ainsi qu’un client que tout DFSP existant pourrait héberger pour se connecter au réseau. + +![Flux d’architecture de bout en bout Mojaloop PI5](./technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg) + +Le Hub Mojaloop est le conteneur principal et la référence que nous utilisons pour décrire l’écosystème Mojaloop, qui est réparti en les domaines suivants: +* Services Open Source Mojaloop : logiciel open source (OSS) central de Mojaloop soutenu par la Fondation Bill & Melinda Gates en partenariat avec la communauté open source. +* Hub Mojaloop: implémentation globale de référence (et personnalisable) de Mojaloop pour les opérateurs de hub, basée sur la solution OSS ci-dessus. \ No newline at end of file diff --git a/docs/fr/technical/api/README.md b/docs/fr/technical/api/README.md new file mode 100644 index 000000000..2499da750 --- /dev/null +++ b/docs/fr/technical/api/README.md @@ -0,0 +1,17 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# Catalogue des APIs + +La famille des APIs Mojaloop regroupe plusieurs APIs différentes qui répondent à divers besoins métier ou transactionnels. Jusqu'à présent, les APIs bien définies et adoptées sont : + +- [APIs d’Interopérabilité FSP (FSPIOP)](./fspiop/) +- [API d’Administration](./administration/) +- [API de Règlement](./settlement/) +- [API d’Initiation de Paiement Tiers (3PPI/PISP)](./thirdparty/) + +D’autres APIs sont soit en cours de développement et de conception, soit prévues sur la feuille de route : + +- API inter-réseaux (FX) +- API de reporting diff --git a/docs/fr/technical/api/administration/README.md b/docs/fr/technical/api/administration/README.md new file mode 100644 index 000000000..0c61903f7 --- /dev/null +++ b/docs/fr/technical/api/administration/README.md @@ -0,0 +1,15 @@ +# API d'Administration + +L'API d'Administration comprend les documents suivants. + +## API d'Administration du Central Ledger + +[La spécification de l'API Central Ledger](./central-ledger-api.md) présente et décrit l'**API Central Ledger**. Le but de cette API est de permettre aux opérateurs du Hub de gérer les processus administratifs liés à : + +- La création/l’activation/la désactivation de participants dans le Hub +- L’ajout et la mise à jour des informations de point de l'endpoint des participants +- La gestion des comptes des participants, des limites et des positions +- La création de comptes Hub +- L'exécution des opérations de Fonds Entrants et Sortants +- La création/la mise à jour/la consultation des modèles de règlement +- La récupération des détails des transferts diff --git a/docs/fr/technical/api/administration/central-ledger-api.md b/docs/fr/technical/api/administration/central-ledger-api.md new file mode 100644 index 000000000..9e6300063 --- /dev/null +++ b/docs/fr/technical/api/administration/central-ledger-api.md @@ -0,0 +1,1728 @@ +--- +showToc: true +--- +# API du Central Ledger + +## Introduction + +Ce document fournit des informations détaillées sur l'API Central Ledger. L’API Central Ledger est une API Mojaloop permettant aux opérateurs du Hub de gérer les processus administratifs tels que : + +- Création, activation et désactivation de participants dans le hub +- Ajout et mise à jour des informations d’endpoints des participants +- Gestion des comptes, des limites et des positions des participants +- Création de comptes Hub +- Effectuer des opérations de dépôt (Funds In) et de retrait (Funds Out) +- Création/mise à jour/consultation des modèles de règlement (settlement) +- Récupération des détails des transferts + +Pour plus d’informations sur les concepts de participants et de modèles de règlement que l’opérateur du Hub peut gérer via l’API Central Ledger, voir la section [Concepts de base](#basic-concepts). + +
+ +## Concepts de base + +Afin de contextualiser les opérations administratives rendues possibles par l’API Central Ledger, cette section présente une brève définition de certains concepts essentiels. + +### Participant + +Le Hub lui-même ou un Prestataire de Services Financiers Numériques (DFSP) qui participe à un schéma Mojaloop. + +### Endpoint + +L’URL de callback du DFSP où le Hub envoie les callbacks de l’API. L’URL spécifiée correspond à l’endpoint configuré dans la passerelle API sortante. + +### Limite + +Actuellement, un seul type de limite est pris en charge, appelée "_Net Debit Cap (NDC)_". À l’avenir, d’autres types de limites pourraient être pris en charge. + +Le _Net Debit Cap_ représente la couverture de liquidité disponible pour un compte spécifique (le compte de Position). Il s’agit du montant total de fonds garantis que le système atteste disponibles afin de garantir qu’un participant a la capacité de régler les obligations résultant des transferts sur ce compte de Position. Ce montant est représenté par le solde d’un compte (le compte de Règlement), qui est lié au compte de Position via un modèle de règlement. L’origine des fonds dans ce compte peut provenir soit de dépôts/retraits effectués par les administrateurs du système, soit de fonds automatiquement crédités/débités par le système si le compte correspond à un modèle de règlement brut immédiat. + +Il doit également être possible pour un participant d’indiquer qu’un montant (ou une proportion) des fonds disponibles dans un compte de Règlement soit exclu du calcul du Net Debit Cap. Dans le cas où un participant est bénéficiaire net sur le long terme via le règlement, ou conserve un excédent de fonds pour faire face à des périodes où il n’est pas possible d’alimenter les comptes, il peut choisir d’exclure une partie du solde de son compte de règlement du calcul de couverture pour les transferts. + +### Compte + +Également appelé _Ledger_. Le Hub maintient plusieurs comptes internes pour suivre les mouvements de fonds (argent électronique ou réel) entre les DFSPs. + +### Position + +La Position représente le solde net de : +- transferts sur le compte ayant été compensés mais pas encore réglés, et +- transferts sur le compte où : + - le DFSP est débiteur, + - le transfert a été accepté pour traitement mais pas encore compensé par le Hub. + +La Position d’un compte donné est toujours vérifiable et à jour. + +Lorsqu’un transfert est initié, le Hub vérifie que le DFSP dispose d’une couverture de liquidité suffisante sur ce compte pour couvrir le montant du transfert. Sinon, le transfert sera rejeté. + +Nous autorisons actuellement que les obligations nées sur le compte – où le participant est bénéficiaire – réduisent la Position du participant, comme si ces fonds avaient déjà été réglés. + +### Opérations Funds In et Funds Out + +Les opérations Funds In et Funds Out servent à tracer (dans les comptes du Hub) les mouvements d’argent liés aux dépôts, retraits et règlements. + +Les opérations Funds In enregistrent soit le dépôt d’argent sur le compte bancaire de règlement d’un DFSP, soit le montant du règlement pour un DFSP receveur. + +Les opérations Funds Out enregistrent soit le retrait d’argent d’un compte bancaire de règlement d’un DFSP, soit le montant du règlement pour un DFSP qui envoie des fonds. + +### Modèle de règlement (Settlement model) + +Fait référence à la façon dont le règlement se produit dans un schéma. Le règlement est le processus par lequel des fonds sont transférés d’un DSFP à un autre, de sorte que le DFSP du payeur rembourse celui du bénéficiaire pour les fonds versés lors d’une transaction. Un modèle de règlement spécifie si les participants règlent séparément entre eux ou avec le schéma, si les transferts sont réglés un par un ou en lot, immédiatement ou avec délai, etc. + +
+ +## Détails HTTP + +Cette section fournit des informations détaillées sur l’usage du protocole HTTP au niveau applicatif dans l’API. + +### Champs d’en-tête HTTP + +Les en-têtes HTTP sont généralement décrits dans la [RFC 7230](https://tools.ietf.org/html/rfc7230). Tout en-tête spécifique à l’API Central Ledger sera standardisé à l’avenir. + +### Méthodes HTTP + +Les méthodes HTTP suivantes, telles que définies dans la [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4), sont supportées par l’API : + +- `GET` – La méthode HTTP GET est utilisée par un client pour récupérer des informations concernant un objet déjà créé sur un serveur. +- `POST` – La méthode HTTP POST est utilisée par un client pour demander la création d’un objet sur le serveur. +- `PUT` – La méthode HTTP PUT est utilisée par un client pour modifier un objet déjà existant sur le serveur (remplace la représentation de la ressource cible par le contenu de la requête). + +> **REMARQUE :** La méthode `DELETE` n’est pas prise en charge. + +### Codes de statut de réponse HTTP + +La table [Codes de statut de réponse HTTP](#http-response-status-codes) liste les codes de statut HTTP pris en charge par l’API : + +|Code de statut|Raison|Description| +|---|---|---| +|**200**|OK|Réponse standard pour une opération `GET`, `PUT`, ou `POST` réussie. La réponse contiendra une entité correspondant à la ressource demandée.| +|**201**|Created|La requête `POST` a abouti à la création d’une nouvelle ressource. La réponse ne contiendra pas d’entité décrivant ou contenant le résultat de l’action.| +|**202**|Accepted|La requête a été acceptée pour traitement, mais le traitement n’est pas encore terminé.| +|**400**|Bad Request|Le serveur n’a pas compris la requête à cause d’une syntaxe invalide.| +|**401**|Unauthorized|L’accès à la ressource nécessite une authentification.| +|**403**|Forbidden|La requête a été rejetée, et le sera également à l’avenir.| +|**404**|Not Found|La ressource demandée n’est pas disponible actuellement.| +|**405**|Method Not Allowed|Une méthode HTTP non supportée a été utilisée.| +|**406**|Not Acceptable|La ressource demandée ne peut générer que du contenu non accepté selon les en-têtes Accept de la requête.| +|**500**|Internal Server Error|Message d’erreur générique, utilisé lorsqu’une condition inattendue est rencontrée et qu’aucun message plus spécifique n’est approprié.| +|**501**|Not Implemented|Le serveur ne supporte pas le service demandé. Le client ne doit pas réessayer.| +|**503**|Service Unavailable|Le serveur est temporairement indisponible pour de nouvelles requêtes. Cela doit être un état temporaire, le client doit réessayer dans un délai raisonnable.| + +
+ +## Services API + +Cette section introduit et détaille tous les services supportés par l’API pour chaque ressource et méthode HTTP. + +### Services API de haut niveau + +De façon générale, l’API permet d’effectuer les actions suivantes : + +- **`/participants`** : Consulter, créer ou modifier les détails des participants tels que la limite (Net Debit Cap), la position, ou les endpoints configurés. +- **`/settlementModels`** : Consulter, créer ou modifier les détails liés aux modèles de règlement (granularité, délais, contrôle de liquidité etc.). +- **`/transactions`** : Consulter les détails d’une transaction particulière. + +### Services API supportés + +La table [Services API supportés](#supported-api-services) inclut une description de haut niveau des services fournis par l’API. Pour plus de détails, se référer aux sections suivantes. + +| URI | Méthode HTTP `GET`| Méthode HTTP `PUT` | Méthode HTTP `POST` | Méthode HTTP `DELETE` | +|---|---|---|---|---| +| **`/participants`** | Obtenir les infos de tous les participants | Non supporté | Créer un participant dans le Hub | Non supporté | +| `/participants/limits` | Voir les limites pour tous les participants | Non supporté | Non supporté | Non supporté | +| `/participants/{name}` | Obtenir les infos d’un participant particulier | Modifier les infos du participant (activer/désactiver) | Non supporté | Non supporté | +| `/participants/{name}/endpoints` | Voir les endpoints d’un participant | Non supporté | Ajouter/Modifier les endpoints d’un participant | Non supporté | +| `/participants/{name}/limits` | Voir les limites d’un participant | Ajuster les limites d’un participant | Non supporté | Non supporté | +| `/participants/{name}/positions` | Voir les positions d’un participant | Non supporté | Non supporté | Non supporté | +| `/participants/{name}/accounts` | Voir les comptes et soldes d’un participant | Non supporté | Créer des comptes Hub | Non supporté | +| `/participants/{name}/accounts/{id}` | Non supporté | Modifier les comptes d’un participant | Enregistrer un Funds In/Out pour le compte participant | Non supporté | +| `/participants/{name}/accounts/{id}/transfers/{transferId}` | Non supporté | Non supporté | Enregistrer un transfert comme Funds In/Out pour un compte particpant | Non supporté | +| `/participants/{name}/initialPositionAndLimits` | Non supporté | Non supporté | Ajouter limites et position initiales du participant | Non supporté | +| **`/settlementModels`** | Voir tous les modèles de règlement | Non supporté | Créer un modèle de règlement | Non supporté | +| `/settlementModels/{name}` | Voir un modèle de règlement par nom | Modifier (activer/désactiver) un modèle de règlement | Non supporté | Non supporté | +| **`/transactions/{id}`** | Récupérer les détails d’une transaction par `transferId` | Non supporté | Non supporté | Non supporté | + + +
+ +## Ressource API `/participants` + +Les services proposés par la ressource `/participants` sont principalement utilisés par l’opérateur du Hub pour consulter, créer et modifier les paramètres des participants, tels que la limite (Net Debit Cap), la position ou les endpoints configurés. + +### GET /participants + +Récupère les informations de tous les participants. + +#### Exemple de requête + +``` +curl 'http:///participants' +``` + +#### Exemple de réponse + +> **REMARQUE :** Dans l’exemple ci-dessous, `dev1-central-ledger.mojaloop.live` indique l’emplacement du service Central Ledger du Hub Mojaloop. Cet élément sera différent dans votre implémentation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "greenbankfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp", + "created": "\"2021-03-04T14:20:17.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp" + }, + "accounts": [ + { + "id": 15, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 16, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 21, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + }, + { + "name": "Hub", + "id": "dev1-central-ledger.mojaloop.live/participants/Hub", + "created": "\"2021-03-04T13:37:25.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/Hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 2, + "ledgerAccountType": "HUB_RECONCILIATION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + } +] +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [String](#string) | L'identifiant du participant sous la forme d'un nom de domaine pleinement qualifié, combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Un indicateur pour préciser si le participant est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service Web RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes du grand livre configurés pour le participant. | + +
+ +### POST /participants + +Crée un participant dans le Hub. + +#### Exemple de requête + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"name": "payerfsp", "currency": "USD"}' \ + http:///participants +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise dans laquelle le participant effectuera des transactions. | + +#### Exemple de réponse + +> **REMARQUE :** Dans l'exemple ci-dessous, `dev1-central-ledger.mojaloop.live` indique l'emplacement du service Central Ledger du Hub Mojaloop. Ce détail peut être différent dans votre implémentation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-01-12T10:56:30.000Z\"", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 30, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 31, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [String](#string) | L'identifiant du participant sous la forme d'un nom de domaine pleinement qualifié, combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Un indicateur pour préciser si le participant est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service Web RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes du grand livre configurés pour le participant. | + +
+ +### GET /participants/limits + +Récupère les informations des limites pour tous les participants. + +#### Paramètres de requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | non | [CurrencyEnum](#currencyenum) | La devise de la limite. | +| `limit` | non | [String](#string) | Type de limite. | + +#### Exemple de requête + +``` +curl 'http:///participants/limits' +``` + +#### Exemple de réponse + +> **REMARQUE :** Dans l'exemple ci-dessous, `dev1-central-ledger.mojaloop.live` indique l'emplacement du service Central Ledger du Hub Mojaloop. Ce détail peut être différent dans votre implémentation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "payerfsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + }, + { + "name": "payeefsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Modèle de données de la réponse + +Chaque limite dans la liste renvoyée est appliquée au nom du participant et à la devise spécifiés dans chaque objet. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise configurée pour le participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | La limite configurée pour le participant. | + +
+ +### GET /participants/{name} + +Récupère les informations sur un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl 'http:///participants/payerfsp' +``` + +#### Exemple de réponse + +> **REMARQUE :** Dans l'exemple ci-dessous, `dev1-central-ledger.mojaloop.live` indique l'emplacement du service Central Ledger du Hub Mojaloop. Ce détail peut être différent dans votre implémentation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [String](#string) | L'identifiant du participant sous la forme d'un nom de domaine pleinement qualifié, combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Un indicateur pour préciser si le participant est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service Web RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes du grand livre configurés pour le participant. | + +
+ +### PUT /participants/{name} + +Met à jour les détails du participant (active/désactive un participant). + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `isActive` | oui | [Boolean](boolean) | Un indicateur pour préciser si le participant est actif ou non. | + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [String](#string) | L'identifiant du participant sous la forme d'un nom de domaine pleinement qualifié, combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Un indicateur pour préciser si le participant est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service Web RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes du grand livre configurés pour le participant. | + +
+ +### GET /participants/{name}/endpoints + +Récupère les informations sur les endpoints configurés pour un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl 'http:///participants/payerfsp/endpoints' +``` + +#### Exemple de réponse +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_DELETE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_AUTHORIZATIONS", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_QUOTES", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRX_REQ_SERVICE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}/error" + }, + { + "type": "NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", + "value": "some.email@gmail.com" + } +] +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `type` | oui | [String](#string) | Type de endpoint. | +| `value` | oui | [String](#string) | Valeur du endpoint. | + +
+ +### POST /participants/{name}/endpoints + +Ajoute/met à jour des endpoints pour un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", "value": "some.email@org.com"}' + http:///participants/payerfsp/endpoints +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `type` | oui | [String](#string) | Type de endpoint. | +| `value` | oui | [String](#string) | Valeur du endpoint. | + +#### Exemple de réponse + +``` +HTTP/1.1 201 Created +Content-Type: application/json +``` + +
+ + +### GET /participants/{name}/limits + +Récupère les informations de limite pour un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Paramètres de requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | non | [CurrencyEnum](#currencyenum) | La devise de la limite. | +| `limit` | non | [String](#string) | Type de limite. | + +#### Exemple de requête + +``` +curl 'http:///participants/payerfsp/limits' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Modèle de données de la réponse + +Chaque limite dans la liste renvoyée est appliquée au nom du participant et à la devise spécifiés dans chaque objet. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise configurée pour le participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | La limite configurée pour le participant. | + +
+ +### PUT /participants/{name}/limits + +Ajuste les limites pour un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": NET_DEBIT_CAP", \ + "value": 10000, \ + "alarmPercentage": 20 + } \ + }' \ + http:///participants/payerfsp/limits +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise configurée pour le participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | La limite configurée pour le participant. | + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 20 + } +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise configurée pour le participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | La limite configurée pour le participant. | + +
+ +### GET /participants/{name}/positions + +Récupère la position d'un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Paramètres de requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | non | [CurrencyEnum](#currencyenum) | La devise de la limite. | + +#### Exemple de requête + +``` +curl 'http:///participants/payerfsp/positions' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "value": 150, + "changedDate": "2021-05-10T08:01:38.000Z" + } +] +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise configurée pour le participant. | +| `value` | oui | [Number](#number) | Valeur de la position. | +| `changedDate` | oui | [DateTime](#datetime) | Date et heure du dernier changement de la position. | + +
+ +### GET /participants/{name}/accounts + +Récupère les comptes et soldes d’un participant donné. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl 'http:///participants/payerfsp/accounts' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "value": 150, + "reservedValue": 0, + "changedDate": "2021-05-10T08:01:38.000Z" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": -165000, + "reservedValue": 0, + "changedDate": "2021-05-10T14:27:02.000Z" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": 0, + "reservedValue": 0, + "changedDate": "2021-03-30T12:23:06.000Z" + } +] +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `id` | oui | [Integer](#integer) | Identifiant du compte du grand livre. | +| `ledgerAccountType` | oui | [String](#string) | Type de compte du grand livre. | +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise du compte du grand livre. | +| `isActive` | oui | [Integer(1)](#integer) | Indique si le compte du grand livre est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `value` | oui | [Number](#number) | Solde du compte. | +| `reservedValue` | oui | [Number](#number) | Valeur réservée dans le compte. | +| `changedDate` | oui | [DateTime](#datetime) | Date et heure du dernier changement du compte du grand livre. | + +
+ +### POST /participants/{name}/accounts + +Crée des comptes dans le Hub. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"currency": "USD", "type": "HUB_MULTILATERAL_SETTLEMENT"}' \ + http:///participants/payerfsp/accounts +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise du compte du grand livre du participant. | +| `type` | oui | [String](#string) | Type de compte du grand livre. | + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "hub", + "id": "dev1-central-ledger.mojaloop.live/participants/hub", + "created": "2021-01-12T10:56:30.000Z", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": "2021-01-12T10:56:30.000Z", + "createdBy": "unknown" + } + ] +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String](#string) | Le nom du participant. | +| `id` | oui | [String](#string) | L'identifiant du participant sous la forme d'un nom de domaine pleinement qualifié, combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Un indicateur pour préciser si le participant est actif ou non. Les valeurs possibles sont `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service Web RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes du grand livre configurés pour le participant. | + +
+ +### POST /participants/{name}/accounts/{id} + +Enregistre des opérations de dépôt ou de retrait sur un compte participant. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [Integer](#integer) | Identifiant du compte. | + +#### Exemple de requête + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "transferId": "bfd38d14-893f-469d-a6ca-a312a0223949", \ + "externalReference": "660616", \ + "action": "recordFundsIn", \ + "reason": "settlement", \ + "amount": { \ + "amount": "5000", \ + "currency": "USD" \ + }, \ + "extensionList": { \ + "extension": [ \ + { \ + "key": "scheme", \ + "value": "abc" \ + } \ + ] \ + } \ + }' \ + http:///participants/payerfsp/accounts/2 +```` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `transferId` | oui | [UUID](#uuid) | Identifiant du transfert. | +| `externalReference` | oui | [String](#string) | Référence à toute donnée externe, telle qu'un identifiant de la banque de règlement. | +| `action` | oui | [Enum](#enum) | L'action effectuée sur les fonds. Les valeurs possibles sont : `recordFundsIn` et `recordFundsOutPrepareReserve`. | +| `reason` | oui | [String](#string) | Raison de l'opération de funds in ou funds out. | +| `amount` | oui | [Money](#money) | Montant de l'opération (FundsIn ou FundsOut). | +| `extensionList` | non | [ExtensionList](#extensionlist) | Détails supplémentaires. | + +#### Exemple de réponse + +```` +HTTP/1.1 202 Accepted +```` + +
+ +### PUT /participants/{name}/accounts/{id} + +Met à jour un compte de participant. Actuellement, seule la modification du champ `isActive` est prise en charge. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [Integer](#integer) | Identifiant du compte. | + +#### Exemple de requête + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp/account/2 +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `isActive` | oui | [Boolean](boolean) | Indique si le compte du participant est actif ou non. | + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +``` + +
+ +### PUT /participants/{name}/accounts/{id}/transfers/{transferId} + +Enregistre un transfert en tant qu’opération de fonds entrants ou sortants pour un compte de participant. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | +| `id` | oui | [Integer](#integer) | Identifiant du compte. | +| `transferId` | oui | [UUID](#uuid) | Identifiant du transfert. | + +#### Exemple de requête + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"action": "recordFundsOutCommit", "reason": "fix"}' \ + http:///participants/payerfsp/account/2/transfers/bfd38d14-893f-469d-a6ca-a312a0223949 +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `action` | oui | [Enum](#enum) | Action de funds out effectuée. Valeurs possibles : `recordFundsOutCommit` et `recordFundsOutAbort`. | +| `reason` | oui | [String](#string) | Raison de l'opération de FundsOut. | + +#### Exemple de réponse + +``` +HTTP/1.1 202 Accepted +``` + +
+ +### POST /participants/{name}/initialPositionAndLimits + +Ajoute des limites initiales et une position pour un participant particulier. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String(2..30)](#string) | Le nom du participant. | + +#### Exemple de requête + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": "NET_DEBIT_CAP", \ + "value": "10000" \ + }, \ + "initialPosition": 0 \ + }' \ + http:///participants/payerfsp/initialPositionAndLimits +```` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise du participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | Limite configurée pour le participant. | +| `initialPosition` | non | [Number](#number) | Position initiale. | + +#### Exemple de réponse + +``` +HTTP/1.1 201 Created +``` + +
+ +## Ressource API `/settlementModels` + +Les services fournis par la ressource `/settlementModels` sont utilisés par l’opérateur du Hub pour créer, mettre à jour et consulter des modèles de règlement. + +### GET /settlementModels + +Récupère les informations de tous les modèles de règlement. + +#### Exemple de requête + +``` +curl 'http:///settlementModels' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "settlementModelId": 1, + "name": "DEFERREDNETUSD", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true + }, + { + "settlementModelId": 4, + "name": "DEFERREDNETEUR", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "EUR", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "SETTLEMENT", + "autoPositionReset": true + } +] +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementModelId` | oui | [Integer](#integer) | Identifiant du modèle de règlement. | +| `name` | oui | [String](#string) | Nom du modèle de règlement. | +| `isActive` | oui | [Boolean](boolean) | Indique si le modèle de règlement est actif ou non. | +| `settlementGranularity` | oui | [String](#string) | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs possibles :
`GROSS` : Règlement exécuté après chaque transfert complété, c'est-à-dire, il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération de règlement, chaque participant réglant la somme nette de tous les transferts sur une période donnée. | +| `settlementInterchange` | oui | [String](#string) | Spécifie le type d’arrangement de règlement entre parties. Valeurs possibles :
`BILATERAL` : Chaque participant règle ses obligations avec les autres séparément, et le schéma n’est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie. | +| `settlementDelay` | oui | [String](#string) | Spécifie si le règlement a lieu immédiatement après qu’un transfert est terminé ou avec un délai. Valeurs possibles :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier. | +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le modèle de règlement. | +| `requireLiquidityCheck` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite une vérification de liquidité ou non. | +| `ledgerAccountTypeId` | oui | [String](#string) | Type de compte de grand livre. Valeurs possibles :
`INTERCHANGE_FEE` : Suit les frais d’interchange appliqués aux transferts.
`POSITION` : Suit les montants dus ou à recevoir pour un DFSP.
`SETTLEMENT` : Compte bancaire de règlement du DFSP reflété dans le Hub. Sert de compte de rapprochement et reflète le mouvement des fonds réels. | +| `autoPositionReset` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite la remise à zéro automatique de la position ou non. | + +
+ +### POST /settlementModels + +Crée un modèle de règlement. + +#### Exemple de requête + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "name": "DEFERREDNET", \ + "settlementGranularity": "NET", \ + "settlementInterchange": "MULTILATERAL", \ + "settlementDelay": "DEFERRED", \ + "requireLiquidityCheck": true, \ + "ledgerAccountType": "POSITION", \ + "autoPositionReset": true \ + }' \ + http:///settlementModels +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String](#string) | Nom du modèle de règlement. | +| `settlementGranularity` | oui | [String](#string) | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs possibles :
`GROSS` : Règlement exécuté après chaque transfert complété, c'est-à-dire, il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération de règlement, chaque participant réglant la somme nette de tous les transferts sur une période donnée. | +| `settlementInterchange` | oui | [String](#string) | Spécifie le type d’arrangement de règlement entre parties. Valeurs possibles :
`BILATERAL` : Chaque participant règle ses obligations avec les autres séparément, et le schéma n’est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie. | +| `settlementDelay` | oui | [String](#string) | Spécifie si le règlement a lieu immédiatement après qu’un transfert est terminé ou avec un délai. Valeurs possibles :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier. | +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le modèle de règlement. | +| `requireLiquidityCheck` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite une vérification de liquidité ou non. | +| `ledgerAccountTypeId` | oui | [String](#string) | Type de compte de grand livre. Valeurs possibles :
`INTERCHANGE_FEE` : Suit les frais d’interchange appliqués aux transferts.
`POSITION` : Suit les montants dus ou à recevoir pour un DFSP.
`SETTLEMENT` : Compte bancaire de règlement du DFSP reflété dans le Hub. Sert de compte de rapprochement et reflète le mouvement des fonds réels. | +| `settlementAccountType` | oui | [String](#string) | Un type spécial de compte de grand livre dans lequel les règlements doivent être versés. Valeurs possibles :
`SETTLEMENT` : Un compte de règlement pour la valeur principale des transferts (c’est-à-dire, le montant que le payeur souhaite verser au bénéficiaire).
`INTERCHANGE_FEE_SETTLEMENT` : Un compte de règlement pour les frais liés aux transferts. | +| `autoPositionReset` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite la remise à zéro automatique de la position ou non. | + +#### Exemple de réponse + +``` +HTTP/1.1 201 Created +``` + +
+ +### GET /settlementModels/{name} + +Récupère des informations sur un modèle de règlement particulier. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String](#string) | Le nom du modèle de règlement. | + +#### Exemple de requête + +``` +curl 'http:///settlementModels/DEFERREDNET' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementModelId` | oui | [Integer](#integer) | Identifiant du modèle de règlement. | +| `name` | oui | [String](#string) | Nom du modèle de règlement. | +| `isActive` | oui | [Boolean](boolean) | Indique si le modèle de règlement est actif ou non. | +| `settlementGranularity` | oui | [String](#string) | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs possibles :
`GROSS` : Le règlement est exécuté après chaque transfert complété, c'est-à-dire qu'il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération de règlement, chaque participant réglant la somme nette de tous les transferts sur une période donnée.| +| `settlementInterchange` | oui | [String](#string) | Spécifie le type d’arrangement de règlement entre parties. Valeurs possibles :
`BILATERAL` : Chaque participant règle séparément ses obligations avec les autres, et le schéma n'est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie.| +| `settlementDelay` | oui | [String](#string) | Spécifie si le règlement a lieu immédiatement après la fin d’un transfert ou avec un délai. Valeurs possibles :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier.| +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le modèle de règlement. | +| `requireLiquidityCheck` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite une vérification de liquidité. | +| `ledgerAccountTypeId` | oui | [String](#string) | Type de compte de grand livre. Valeurs possibles :
`INTERCHANGE_FEE` : Suit les frais d’interchange appliqués aux transferts.
`POSITION` : Suit combien un DFSP doit ou est dû.
`SETTLEMENT` : Le compte bancaire de règlement du DFSP reflété dans le Hub. Sert de compte de rapprochement et reflète le mouvement des fonds réels. | +| `autoPositionReset` | oui | [Boolean](boolean) | Indique si le modèle de règlement nécessite la remise à zéro automatique de la position. | + +
+ +### PUT /settlementModels/{name} + +Met à jour un modèle de règlement (active/désactive un modèle de règlement). + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String](#string) | Le nom du modèle de règlement. | + +#### Exemple de requête + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///settlementModels/DEFERREDNET +``` + +#### Modèle de données de la requête + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `isActive` | oui | [Boolean](#boolean) | Indique si le modèle de règlement est actif ou non. | + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementModelId` | oui | [Integer](#integer) | Identifiant du modèle de règlement. | +| `name` | oui | [String](#string) | Nom du modèle de règlement. | +| `isActive` | oui | [Boolean](boolean) | Indique si le modèle de règlement est actif ou non. | +| `settlementGranularity` | oui | [String](#string) | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs possibles :
`GROSS` : Le règlement est exécuté après chaque transfert complété, c'est-à-dire qu'il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération de règlement, chaque participant réglant la somme nette de tous les transferts sur une période donnée.| +| `settlementInterchange` | oui | [String](#string) | Spécifie le type d’arrangement de règlement entre parties. Valeurs possibles :
`BILATERAL` : Chaque participant règle séparément ses obligations avec les autres, et le schéma n'est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie.| +| `settlementDelay` | oui | [String](#string) | Spécifie si le règlement a lieu immédiatement après la fin d’un transfert ou avec un délai. Valeurs possibles :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier.| +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le modèle de règlement. | +| `requireLiquidityCheck` | oui | [Boolean](#boolean) | Indique si le modèle de règlement nécessite une vérification de liquidité. | +| `ledgerAccountTypeId` | oui | [String](#string) | Type de compte de grand livre. Valeurs possibles :
`INTERCHANGE_FEE` : Suit les frais d’interchange appliqués aux transferts.
`POSITION` : Suit combien un DFSP doit ou est dû.
`SETTLEMENT` : Le compte bancaire de règlement du DFSP reflété dans le Hub. Sert de compte de rapprochement et reflète le mouvement des fonds réels. | +| `autoPositionReset` | oui | [Boolean](#boolean) | Indique si le modèle de règlement nécessite la remise à zéro automatique de la position. | + +
+ +## Ressource API `/transactions` + +Les services proposés par la ressource `/transactions` sont utilisés par l'Opérateur du Hub pour récupérer les détails des transferts. + +### GET /transactions/{id} + +Récupère des informations sur une transaction particulière. + +#### Paramètres de chemin + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `id` | oui | [UUID](#uuid) | Identifiant du transfert. | + +#### Exemple de requête + +``` +curl 'http:///transactions/85feac2f-39b2-491b-817e-4a03203d4f14' +``` + +#### Exemple de réponse + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "transactionRequestId": "a8323bc6-c228-4df2-ae82-e5a997baf898", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoneyAbc" + }, + "name": "John Doe", + "personalInfo": { + "complexName": { + "firstName": "John", + "middleName": "William", + "lastName": "Doe" + }, + "dateOfBirth": "1966-06-16" + } + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "987654321", + "fspId": "MobileMoneyXyz" + }, + "name": "Jane Doe", + "personalInfo": { + "complexName": { + "firstName": "Mary", + "middleName": "Jane", + "lastName": "Doe" + }, + "dateOfBirth": "1975-05-15" + } + }, + "amount": { + "currency": "USD", + "amount": "50" + }, + "transactionType": { + "scenario": "DEPOSIT", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + } +} +``` + +#### Modèle de données de la réponse + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `quoteId` | | [UUID](#uuid) | Identifiant du devis (quote). | +| `transactionId` | | [UUID](#uuid) | Identifiant de la transaction. | +| `transactionRequestId` | | [String](#string) | Identifie une éventuelle demande de transaction envoyée précédemment. | +| `payee` | | [Party](#party) | Détails du bénéficiaire. | +| `payer` | | [Party](#party) | Détails du payeur. | +| `amount` | | [Money](#money) | Montant de la transaction. | +| `transactionType` | | [TransactionType](#transactiontype) | Détails sur le type de transaction. | +| `note` | | [String](#string) | Un mémo qui sera attaché à la transaction. | +| `extensionList` | | [ExtensionList](#extensionlist) | Détails additionnels. | + +
+ +## Modèles de données utilisés par l'API + +### Format + +Pour les détails sur les formats utilisés pour les types de données élémentaires de l’API, voir la section [Element Data Type Formats](../fspiop/logical-data-model#element-data-type-formats) dans la définition de l’API Mojaloop FSPIOP. + +### Formats des types de données élémentaires + +Cette section définit les types de données élémentaires utilisés par l'API. + +#### Amount + +Pour plus de détails, voir la section [Amount](../fspiop/logical-data-model#amount) dans la définition de l’API Mojaloop FSPIOP. + +#### Boolean + +Une valeur `"true"` ou `"false"`. + +#### DateTime + +Pour plus de détails, voir la section [DateTime](../fspiop/logical-data-model#datetime) dans la définition de l’API Mojaloop FSPIOP. + +#### Enum + +Pour plus de détails, voir la section [Enum](../fspiop/logical-data-model#enum) dans la définition de l’API Mojaloop FSPIOP. + +#### Integer + +Pour plus de détails, voir la section [Integer](../fspiop/logical-data-model#integer) dans la définition de l’API Mojaloop FSPIOP. + +#### Number + +Le type de données API `Number` est un nombre décimal en base 10 de précision arbitraire. + +#### String + +Pour plus de détails, voir la section [String](../fspiop/logical-data-model#string) dans la définition de l’API Mojaloop FSPIOP. + +#### UUID + +Pour plus de détails, voir la section [UUID](../fspiop/logical-data-model#uuid) dans la définition de l’API Mojaloop FSPIOP. + +
+ +## Définitions des éléments + +Cette section définit les types d’éléments utilisés par l’API. + +#### IsActive + +Modèle de données pour l’élément **IsActive**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `isActive` | oui | [Integer(1)](#integer) | Indique si un compte de grand livre ou un participant est actif. Valeurs possibles : `1` (actif) et `0` (inactif). | + +#### IsActiveBoolean + +Modèle de données pour l’élément **IsActiveBoolean**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `isActive` | oui | [Boolean](#boolean) | Indique si un compte / participant / modèle de règlement est actif ou non. | + +#### CurrencyEnum + +Pour plus de détails, voir la section [Currency](../fspiop/logical-data-model#currencycode-enum) enum dans la définition de l’API Mojaloop FSPIOP. + +#### RequireLiquidityCheck + +Modèle de données pour l'élément **RequireLiquidityCheck**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `requireLiquidityCheck` | oui | [Boolean](#boolean) | Indique si un modèle de règlement nécessite une vérification de liquidité. | + +#### Self + +Modèle de données pour l’élément **Self**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `self` | oui | [String](#string) | Nom de domaine pleinement qualifié combiné avec le `fspId` du participant. | + +#### SettlementDelay + +Modèle de données pour l’élément **SettlementDelay**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementDelay` | oui | [Enum](#enum) de String | Spécifie si le règlement a lieu immédiatement après la fin d’un transfert ou avec un délai. Valeurs autorisées :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier. | + +#### SettlementGranularity + +Modèle de données pour l’élément **SettlementGranularity**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementGranularity` | oui | [Enum](#enum) de String | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs autorisées :
`GROSS` : Le règlement est exécuté après chaque transfert complété, c'est-à-dire, il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération, chaque participant réglant la somme nette de tous les transferts sur une période donnée. | + +#### SettlementInterchange + +Modèle de données pour l’élément **SettlementInterchange**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementInterchange` | oui | [Enum](#enum) de String | Spécifie le type d’arrangement de règlement entre parties. Valeurs autorisées :
`BILATERAL` : Chaque participant règle séparément ses obligations avec les autres, et le schéma n'est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie. | + +
+ +## Types complexes + +#### Accounts + +La liste des comptes de grand livre configurés pour le participant. Pour plus de détails sur l'objet compte, voir [IndividualAccount](#individualaccount). + +#### ErrorInformation + +Pour plus de détails, voir la section [ErrorInformation](../fspiop/logical-data-model#errorinformation) dans la définition de l’API Mojaloop FSPIOP. + +#### ErrorInformationResponse + +Modèle de données pour le type complexe contenant un élément optionnel [ErrorInformation](#errorinformation) utilisé avec les réponses 4xx et 5xx. + +#### Extension + +Pour plus de détails, voir la section [Extension](../fspiop/logical-data-model#extension) dans la définition de l’API Mojaloop FSPIOP. + +#### ExtensionList + +Pour plus de détails, voir la section [ExtensionList](../fspiop/logical-data-model#extensionlist) dans la définition de l’API Mojaloop FSPIOP. + +#### IndividualAccount + +Modèle de données pour le type complexe **IndividualAccount**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `id` | oui | [Integer](#integer) | Identifiant du compte de grand livre. | +| `ledgerAccountType` | oui | [String](#string) | Type du compte de grand livre (par exemple, POSITION). | +| `currency` | oui | [CurrencyEnum](#currencyenum) | La devise du compte. | +| `isActive` | oui | [Integer(1)](#integer) | Indique si le compte de grand livre est actif ou non. Valeurs possibles : `1` et `0`. | +| `createdDate` | oui | [DateTime](#datetime) | Date et heure de création du compte. | +| `createdBy` | oui | [String](#string) | L'entité qui a créé le compte. | + +#### Limit + +Modèle de données pour le type complexe **Limit**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `type` | oui | [String](#string) | Type de limite. | +| `value` | oui | un nombre positif | Valeur de la limite. | + +#### Money + +Pour plus de détails, voir la section [Money](../fspiop/logical-data-model#mondey) dans la définition de l’API Mojaloop FSPIOP. + +#### Participant + +Modèle de données pour le type complexe **Participant**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `name` | oui | [String](#string) | Nom du participant. | +| `id` | oui | [String](#string) | Identifiant du participant sous la forme d’un nom de domaine pleinement qualifié combiné avec le `fspId` du participant. | +| `created` | oui | [DateTime](#datetime) | Date et heure de création du participant. | +| `isActive` | oui | [Integer(1)](#integer) | Indique si le participant est actif ou non. Valeurs possibles : `1` et `0`. | +| `links` | oui | [Self](#self) | Liste de liens pour un service RESTful Hypermedia-Driven. | +| `accounts` | oui | [Accounts](#accounts) | Liste des comptes de grand livre configurés pour le participant. | + +#### ParticipantFunds + +Modèle de données pour le type complexe **ParticipantFunds**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `transferId` | oui | [UUID](#uuid) | Identifiant du transfert. | +| `externalReference` | oui | [String](#string) | Référence à toute donnée externe, telle qu’un identifiant provenant de la banque de règlement. | +| `action` | oui | [Enum](#enum) | Action effectuée sur les fonds. Valeurs possibles : `recordFundsIn` et `recordFundsOutPrepareReserve`. | +| `reason` | oui | [String](#string) | Raison de l’action FundsIn ou FundsOut. | +| `amount` | oui | [Money](#money) | Montant FundsIn ou FundsOut. | +| `extensionList` | non | [ExtensionList](#extensionlist) | Détails additionnels. | + +#### ParticipantLimit + +Modèle de données pour le type complexe **ParticipantLimit**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `type` | oui | [String](#string) | Type de limite de participant (par exemple, `NET_DEBIT_CAP`). | +| `value` | oui | [Number](#number) | Valeur de la limite définie pour le participant. | +| `alarmPercentage` | oui | [Number](#number) | Une notification d'alarme est déclenchée lorsqu’un pourcentage prédéfini de la limite est atteint. La spécification d’`alarmPercentage` est optionnelle. Si elle n’est pas spécifiée, la valeur par défaut est 10 %, exprimé par `10`. | + +#### ParticipantsNameEndpointsObject + +Modèle de données pour le type complexe **ParticipantsNameEndpointsObject**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `type` | oui | [String](#string) | Type d'endpoint. | +| `value` | oui | [String](#string) | Valeur de l'endpoint. | + +#### ParticipantsNameLimitsObject + +Modèle de données pour le type complexe **ParticipantsNameLimitsObject**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le participant. | +| `limit` | oui | [ParticipantLimit](#participantlimit) | Limite configurée pour le participant. | + +#### Party + +Pour plus de détails, voir la section [Party](../fspiop/logical-data-model#party) dans la définition de l’API Mojaloop FSPIOP. + +#### PartyComplexName + +Pour plus de détails, voir la section [PartyComplexName](../fspiop/logical-data-model#partycomplexname) dans la définition de l’API Mojaloop FSPIOP. + +#### PartyIdInfo + +Pour plus de détails, voir la section [PartyIdInfo](../fspiop/logical-data-model#partyidinfo) dans la définition de l’API Mojaloop FSPIOP. + +#### PartyPersonalInfo + +Pour plus de détails, voir la section [PartyPersonalInfo](../fspiop/logical-data-model#partypersonalinfo) dans la définition de l’API Mojaloop FSPIOP. + +#### RecordFundsOut + +Modèle de données pour le type complexe **RecordFundsOut**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `action` | oui | [Enum](#enum) | Action FundsOut effectuée. Valeurs possibles : `recordFundsOutCommit` et `recordFundsOutAbort`. | +| `reason` | oui | [String](#string) | Raison de l’action FundsOut. | + +#### Refund + +Modèle de données pour le type complexe **Refund**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `originalTransactionId` | oui | [UUID](#uuid) | Référence à l’ID de transaction d’origine à rembourser. | +| `refundReason` | non | [String(1-128)](#string) | Texte libre indiquant le motif du remboursement. | + +#### SettlementModelsObject + +Modèle de données pour le type complexe **SettlementModelsObject**. + +| Nom | Obligatoire | Type | Description | +|---|---|--|--| +| `settlementModelId` | oui | [Integer](#integer) | Identifiant du modèle de règlement. | +| `name` | oui | [String](#string) | Nom du modèle de règlement. | +| `isActive` | oui | [Boolean](#boolean) | Indique si le modèle de règlement est actif ou non. | +| `settlementGranularity` | oui | [String](#string) | Spécifie si les transferts sont réglés un par un ou en lot. Valeurs possibles :
`GROSS` : Le règlement est exécuté après chaque transfert complété, c'est-à-dire qu'il y a une opération de règlement pour chaque transaction.
`NET` : Un groupe de transferts est réglé ensemble dans une seule opération, chaque participant réglant la somme nette de tous les transferts sur une période donnée.| +| `settlementInterchange` | oui | [String](#string) | Spécifie le type d’arrangement de règlement entre parties. Valeurs possibles :
`BILATERAL` : Chaque participant règle séparément ses obligations avec les autres, et le schéma n'est pas partie au règlement.
`MULTILATERAL` : Chaque participant règle avec le schéma le solde net de ses obligations, au lieu de régler séparément avec chaque partie.| +| `settlementDelay` | oui | [String](#string) | Spécifie si le règlement a lieu immédiatement après la fin d’un transfert ou avec un délai. Valeurs possibles :
`IMMEDIATE` : Le règlement a lieu immédiatement après la fin d’un transfert.
`DEFERRED` : Le règlement est géré par l’opérateur du Hub à la demande ou selon un calendrier.| +| `currency` | oui | [CurrencyEnum](#currencyenum) | Devise configurée pour le modèle de règlement. | +| `requireLiquidityCheck` | oui | [Boolean](#boolean) | Indique si le modèle de règlement nécessite une vérification de liquidité. | +| `ledgerAccountTypeId` | oui | [String](#string) | Type de compte de grand livre. Valeurs possibles :
`INTERCHANGE_FEE` : Suit les frais d’interchange appliqués aux transferts.
`POSITION` : Suit combien un DFSP doit ou est dû.
`SETTLEMENT` : Le compte bancaire de règlement du DFSP reflété dans le Hub. Sert de compte de rapprochement et reflète le mouvement des fonds réels.| +| `autoPositionReset` | oui | [Boolean](#boolean) | Indique si le modèle de règlement nécessite la remise à zéro automatique de la position. | + +#### TransactionType + +Pour plus de détails, voir la section [TransactionType](../fspiop/logical-data-model#transactiontype) dans la définition de l’API Mojaloop FSPIOP. diff --git a/docs/fr/technical/api/assets/diagrams/images/figure1-platforms-layout.svg b/docs/fr/technical/api/assets/diagrams/images/figure1-platforms-layout.svg new file mode 100644 index 000000000..8a12de358 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure1-platforms-layout.svg @@ -0,0 +1,3 @@ + + +
CA
CA
ALS
ALS
FSP-1
FSP-1
FSP-2
FSP-2
Switch
Switch
FSP-3
FSP-3
FSP-4
FSP-4
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Legend:
Solid lines indicate TLS-secured communication.
Dashed lines indicate certificate owner.
Legend:...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure11.svg b/docs/fr/technical/api/assets/diagrams/images/figure11.svg new file mode 100644 index 000000000..773d8495b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure11.svg @@ -0,0 +1,4 @@ + + + +
 1 USD 
 1 USD 
Agent Commission account
Agent Comm...
 2 USD 
 2 USD 
Fee account
Fee account
 98 USD 
 98 USD 
Payer's account
Payer's ac...
 99 USD 
 99 USD 
Payer FSP's Switch account
Payer FSP'...
 99 USD 
 99 USD 
Payer FSP Switch account
Payer FSP...
 99 USD 
 99 USD 
Payee FSP Switch account
Payee FSP...
 98 USD 
 98 USD 
1 USD
1 USD
Payee FSP's Switch account
Payee FSP'...
FSP Commision account
FSP Commis...
Fee account
Fee account
Agent Commision account
Agent Comm...
Payee's account
Payee's ac...
FSO Commission account
FSO Commis...
Payer FSP
Payer FSP
Payee FSP
Payee FSP
Switch
Switch
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure12.svg b/docs/fr/technical/api/assets/diagrams/images/figure12.svg new file mode 100644 index 000000000..c5183f904 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure12.svg @@ -0,0 +1,3 @@ + + +
Payer FSP fee
[Not supported by viewer]
Payer
Payer
 Payee FSP transaction fee 
[Not supported by viewer]
Payee FSP commission
to subsidize transaction 
[Not supported by viewer]
Internal Payee fee to Payee FSP
<font color="#ff3333">Internal Payee fee to Payee FSP</font>
Internal Payee FSP
bonus/commission
to Payee
[Not supported by viewer]
Payee
Payee
InternalPayer FSP
bonus/ commission
to Payer
[Not supported by viewer]
Switch
Switch
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure14.svg b/docs/fr/technical/api/assets/diagrams/images/figure14.svg new file mode 100644 index 000000000..070228ec6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure14.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
1 USD
1 USD
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure16.svg b/docs/fr/technical/api/assets/diagrams/images/figure16.svg new file mode 100644 index 000000000..8f8828555 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure16.svg @@ -0,0 +1,3 @@ + + +
 2 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 98 USD 
 98 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 98 USD 
 98 USD 
1 USD
1 USD
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure18.svg b/docs/fr/technical/api/assets/diagrams/images/figure18.svg new file mode 100644 index 000000000..a50ef985a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure18.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 99 USD 
 99 USD 
Payer's account
Payer's account
 97 USD 
 97 USD 
Payer FSP's Switch account
[Not supported by viewer]
 97 USD 
 97 USD 
Payer FSP Switch account
[Not supported by viewer]
 97 USD 
 97 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 3 USD 
 3 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 2 USD 
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure20.svg b/docs/fr/technical/api/assets/diagrams/images/figure20.svg new file mode 100644 index 000000000..12a57a2a1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure20.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure22.svg b/docs/fr/technical/api/assets/diagrams/images/figure22.svg new file mode 100644 index 000000000..60b81e1c7 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure22.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 98 USD 
 98 USD 
Payer FSP's Switch account
[Not supported by viewer]
 98 USD 
 98 USD 
Payer FSP Switch account
[Not supported by viewer]
 98 USD 
 98 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 2 USD 
 2 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 2 USD 
[Not supported by viewer]
Agent
Agent
Customer
Customer
$
[Not supported by viewer]
100 USD in cash from Payee (Customer) to Payer (Agent)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure24.svg b/docs/fr/technical/api/assets/diagrams/images/figure24.svg new file mode 100644 index 000000000..411df60cc --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure24.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
Agent
Agent
Customer
Customer
$
[Not supported by viewer]
101 USD in cash from Payee (Customer) to Payer (Agent)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure26.svg b/docs/fr/technical/api/assets/diagrams/images/figure26.svg new file mode 100644 index 000000000..cee48e5df --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure26.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 100 USD 
 100 USD 
Payer FSP's Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
Payer FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
Customer
Customer
Merchant
Merchant
 1 USD 
 1 USD 
Goods/Service worth
100 USD from Merchant (Payee)
 to Customer (Payer)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure28.svg b/docs/fr/technical/api/assets/diagrams/images/figure28.svg new file mode 100644 index 000000000..2083fcd31 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure28.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 102 USD 
 102 USD 
Payer FSP's Switch account
[Not supported by viewer]
 102 USD 
 102 USD 
Payer FSP Switch account
[Not supported by viewer]
 102 USD 
 102 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 3 USD 
 3 USD 
 2 USD 
 2 USD 
 2 USD 
 2 USD 
Customer
Customer
Agent
Agent
$
[Not supported by viewer]
100 USD in cash from Agent (Payee) to Customer (Payer)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure30.svg b/docs/fr/technical/api/assets/diagrams/images/figure30.svg new file mode 100644 index 000000000..f91ca847a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure30.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 97 USD 
 97 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 97 USD 
 97 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 3 USD 
 3 USD 
 2 USD 
 2 USD 
 2 USD 
 2 USD 
Customer
Customer
Agent
Agent
$
[Not supported by viewer]
97 USD in cash from Agent (Payee) to Customer (Payer)
97 USD in cash from Agent (Payee) to Customer (Payer)
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure32.svg b/docs/fr/technical/api/assets/diagrams/images/figure32.svg new file mode 100644 index 000000000..943d49ae4 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure32.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 102 USD 
 102 USD 
Payer FSP's Switch account
[Not supported by viewer]
 102 USD 
 102 USD 
Payer FSP Switch account
[Not supported by viewer]
 102 USD 
 102 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 3 USD 
 3 USD 
 2 USD 
 2 USD 
 2 USD 
 2 USD 
Customer
Customer
Agent
Agent
$
[Not supported by viewer]
100 USD in cash from Agent (Payee) to Customer (Payer)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure34.svg b/docs/fr/technical/api/assets/diagrams/images/figure34.svg new file mode 100644 index 000000000..db4f8f046 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure34.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 101 USD 
 101 USD 
Payer FSP's Switch account
[Not supported by viewer]
 101 USD 
 101 USD 
Payer FSP Switch account
[Not supported by viewer]
 101 USD 
 101 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
Customer
Customer
Merchant
Merchant
 1 USD 
 1 USD 
Goods/Service worth
100 USD from Merchant (Payee)
to Customer (Payer)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure36.svg b/docs/fr/technical/api/assets/diagrams/images/figure36.svg new file mode 100644 index 000000000..d5941799f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure36.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 101 USD 
 101 USD 
Payer FSP's Switch account
[Not supported by viewer]
 101 USD 
 101 USD 
Payer FSP Switch account
[Not supported by viewer]
 101 USD 
 101 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
Customer
Customer
 2 USD 
[Not supported by viewer]
$
[Not supported by viewer]
100 USD in cash from ATM (Payee) to Customer (Payer)
100 USD in cash from ATM (Payee) to Customer (Payer)
ATM
ATM
diff --git a/docs/fr/technical/api/assets/diagrams/images/figure38.svg b/docs/fr/technical/api/assets/diagrams/images/figure38.svg new file mode 100644 index 000000000..9e6187188 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure38.svg @@ -0,0 +1,3 @@ + + +
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
Customer
Customer
Merchant
Merchant
 1 USD 
 1 USD 
Goods/Service worth
100 USD from Merchant (Payee)
to Customer (Payer)
[Not supported by viewer]
 1 USD 
 1 USD 
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure40.svg b/docs/fr/technical/api/assets/diagrams/images/figure40.svg new file mode 100644 index 000000000..ae2cf6677 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure40.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
 1 USD 
 1 USD 
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP 
Commission account
[Not supported by viewer]
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
 1 USD 
[Not supported by viewer]
Customer
Customer
Agent
Agent
 1 USD 
[Not supported by viewer]
$
[Not supported by viewer]
101 USD in cash from Agent (Payee) to Customer (Payer)
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure46.svg b/docs/fr/technical/api/assets/diagrams/images/figure46.svg new file mode 100644 index 000000000..75093833a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure46.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
PENDING
<b>PENDING</b>
REJECTED
<b>REJECTED</b>
ACCEPTED
<b>ACCEPTED</b>
Payer FSP receives
the transaction
request from 
the Payee FSP
[Not supported by viewer]
Payer FSP sends
the transaction
request to 
the Payee
[Not supported by viewer]
Payer 
responds
[Not supported by viewer]
Payer  approved 
the transaction
[Not supported by viewer]
Payer rejected 
the transaction
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure48.svg b/docs/fr/technical/api/assets/diagrams/images/figure48.svg new file mode 100644 index 000000000..1a7fa406f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure48.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
PENDING
<b>PENDING</b>
REJECTED
<b>REJECTED</b>
ACCEPTED
<b>ACCEPTED</b>
Peer FSP 
receives the 
request 
from the FSP
[Not supported by viewer]
Peer FSP 
validates 
the quote 
request
[Not supported by viewer]
Peer FSP
tries to 
create a 
quote
[Not supported by viewer]
Peer FSP 
successfully 
create a quote
[Not supported by viewer]
Peer FSP 
failed to 
create a quote
[Not supported by viewer]
EXPIRED
<b>EXPIRED</b>
The quote 
expires and 
is no longer 
valid
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure56.svg b/docs/fr/technical/api/assets/diagrams/images/figure56.svg new file mode 100644 index 000000000..b0d58be95 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure56.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
RESERVED
<b>RESERVED</b>
ABORTED
<b>ABORTED</b>
COMMITTED
<b>COMMITTED</b>
The ledger 
receives a 
transfer 
request
[Not supported by viewer]
The ledger 
reserves 
the transfer
[Not supported by viewer]
The ledger 
receives 
results 
from the 
next ledger
[Not supported by viewer]
Next ledger 
successfully 
performed the 
transfer
[Not supported by viewer]
Next ledger 
failed to 
perform the 
transfer or the 
transfer expired
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure58.svg b/docs/fr/technical/api/assets/diagrams/images/figure58.svg new file mode 100644 index 000000000..5d8ba0c93 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure58.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
PENDING
<b>PENDING</b>
REJECTED
<b>REJECTED</b>
COMPLETED
<b>COMPLETED</b>
Payee FSP
receives the
transaction
from the
Payer FSP
[Not supported by viewer]
Payee FSP 
validates 
the
transaction
[Not supported by viewer]
Payee FSP 
tries to 
perform the 
transaction
[Not supported by viewer]
Payee FSP 
successfully 
performed the 
transaction
[Not supported by viewer]
Payee FSP failed 
to 
perform 
the transaction
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure60.svg b/docs/fr/technical/api/assets/diagrams/images/figure60.svg new file mode 100644 index 000000000..9f97ba682 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure60.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
PENDING
<b>PENDING</b>
REJECTED
<b>REJECTED</b>
ACCEPTED
<b>ACCEPTED</b>
Payee FSP 
receives the 
request 
from the 
Payer FSP
[Not supported by viewer]
Payee FSP
validates 
the bulk 
quote 
request
[Not supported by viewer]
Payee FSP 
tries to 
create a 
quote
[Not supported by viewer]
Payee FSP 
successfully 
created a quote
[Not supported by viewer]
Payee FSP 
failed to 
create a quote
[Not supported by viewer]
EXPIRED
<b>EXPIRED</b>
The quote 
expires and 
is no longer 
valid
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure62.svg b/docs/fr/technical/api/assets/diagrams/images/figure62.svg new file mode 100644 index 000000000..466446b23 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure62.svg @@ -0,0 +1,3 @@ + + +
RECEIVED
<b>RECEIVED</b>
PENDING
<b>PENDING</b>
REJECTED
<b>REJECTED</b>
ACCEPTED
<b>ACCEPTED</b>
Payee FSP 
receives 
the bulk 
transfer 
from the 
Payer FSP
[Not supported by viewer]
Payee FSP 
validates 
the bulk 
transfer
[Not supported by viewer]
Payee FSP 
finishes 
validation 
of the bulk 
transfer
[Not supported by viewer]
Payee FSP 
accepts to 
process 
the bulk 
transfer
[Not supported by viewer]
Payee FSP 
rejects to 
process the 
bulk transfer
[Not supported by viewer]
PROCESSING
<b>PROCESSING</b>
Payee FSP 
starts to 
transfer 
funds to 
the Payees
[Not supported by viewer]
COMPLETED
<b>COMPLETED</b>
Payee FSP 
completes 
transfer of 
funds to 
the Payees
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure63.svg b/docs/fr/technical/api/assets/diagrams/images/figure63.svg new file mode 100644 index 000000000..1f262897d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure63.svg @@ -0,0 +1,3 @@ + + +
High-level 
category
[Not supported by viewer]
Low-level 
category
[Not supported by viewer]
Specific error
Specific error
1 digit
1 digit
1 digit
1 digit
2 digit
2 digit
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure7.svg b/docs/fr/technical/api/assets/diagrams/images/figure7.svg new file mode 100644 index 000000000..e3b0e5548 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure7.svg @@ -0,0 +1,3 @@ + + +
Payer fee to Payer FSP
<font color="#ff3333">Payer fee to Payer FSP</font>
Payer
Payer
 Payee FSP transaction fee 
[Not supported by viewer]
Payee FSP commission
to Payer FSP
[Not supported by viewer]
Internal Payee fee to Payee FSP
<font color="#ff3333">Internal Payee fee to Payee FSP</font>
internal Payee FSP
bonus/commission
to Payee
[Not supported by viewer]
Payee
Payee
Payer FSP
bonus/commission
 to Payee
[Not supported by viewer]
Switch
Switch
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure73.svg b/docs/fr/technical/api/assets/diagrams/images/figure73.svg new file mode 100644 index 000000000..148715368 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure73.svg @@ -0,0 +1,3 @@ + + +
Switch
(Identifier = Switch)
Switch<br>(Identifier = <b>Switch</b>)
FSP
(Identifier = MobileMoney)
FSP<br>(<b>Identifier = MobileMoney</b>)
FSP
(Identifier = BankNrOne)
FSP<br>(<b>Identifier = BankNrOne</b>)
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/images/figure9.svg b/docs/fr/technical/api/assets/diagrams/images/figure9.svg new file mode 100644 index 000000000..68f6c3716 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/images/figure9.svg @@ -0,0 +1,3 @@ + + +
 1 USD 
[Not supported by viewer]
Agent Commission account
Agent Commission account
 1 USD 
 1 USD 
Fee account
Fee account
 100 USD 
 100 USD 
Payer's account
Payer's account
 99 USD 
 99 USD 
Payer FSP's Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payer FSP Switch account
[Not supported by viewer]
 99 USD 
 99 USD 
Payee FSP Switch account
[Not supported by viewer]
 100 USD 
 100 USD 
1 USD
1 USD
Payee FSP's Switch account
[Not supported by viewer]
FSP Commission account
FSP Commission account
Fee account
Fee account
Agent Commission account
Agent Commission account
Payee's account
Payee's account
FSP Commission account
FSP Commission account
Payer FSP
[Not supported by viewer]
Payee FSP
[Not supported by viewer]
Switch
[Not supported by viewer]
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure1.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure1.plantuml new file mode 100644 index 000000000..e80fedf1c --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure1.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP POST call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(Service information, ID) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **POST /service**\n(Service information, ID) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Create service object\naccording to request +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service\nobject information +FSP -[hidden]> Switch +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure1.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure1.svg new file mode 100644 index 000000000..50be4512d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure1.svg @@ -0,0 +1,77 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + + Create service object + according to request + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service + object information + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure10.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure10.plantuml new file mode 100644 index 000000000..41c039e8f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure10.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of non-disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to Payee to\nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee\nor commission for\nhandeling transaction in\nPayee FSP => fee 1 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeReceiveamount=98 USD\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeReceiveamount=98 USD\npayeeFspFee=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Show total fees to Payer +PayerFSP ->> Payer: Payee will receive 98 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure10.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure10.svg new file mode 100644 index 000000000..83d930001 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure10.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to Payee to + send 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee + or commission for + handeling transaction in + Payee FSP => fee 1 USD + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeReceiveamount=98 USD + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeReceiveamount=98 USD + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + + Show total fees to Payer + + + + Payee will receive 98 USD + if you send 100 USD + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure13.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure13.plantuml new file mode 100644 index 000000000..7ea6e0dfa --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure13.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to send\n100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or\ncommission for handeling\ntransaction in Payee FSP =>\nFSP commission 1 USD +group Optional + hnote left of PayeeFSP + Notify/Ask Payee + for approval + end note + PayeeFSP ->> Payee: If accepted, you will receive\n100 USD + PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeFspCommission=1 USD,\npayeeReceivedAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeFspCommission=1 USD\npayeeReceivedAmouint=100 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Transaction is subsidized with the\ncommission as fees are disclosed,\nshow total fees to Payer +PayerFSP ->> Payer: Sending 100 USD to Payee\nwill cost 0 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure13.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure13.svg new file mode 100644 index 000000000..63a4002d7 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure13.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to send + 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or + commission for handeling + transaction in Payee FSP => + FSP commission 1 USD + + + Optional + + Notify/Ask Payee + for approval + + + + If accepted, you will receive + 100 USD + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeFspCommission=1 USD, + payeeReceivedAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeFspCommission=1 USD + payeeReceivedAmouint=100 USD) + + + + HTTP 200 + (OK) + + + + + Transaction is subsidized with the + commission as fees are disclosed, + show total fees to Payer + + + + Sending 100 USD to Payee + will cost 0 USD in fees + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure15.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure15.plantuml new file mode 100644 index 000000000..2c33654b8 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure15.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to\ nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee\nor commission for\nhandeling transaction in\nPayee FSP => fee 1 USD +group Optional +PayeeFSP ->> Payee: If accepted, you will receive\n98 USD out of Payer's 100 USD +hnote left of PayeeFSP + Notify/Ask Payee + for approval +end note +PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=98 USD,\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=98 USD\npayeeFspFees=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Show total fees to Payer +PayerFSP ->> Payer: Payee will receive 98 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure15.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure15.svg new file mode 100644 index 000000000..94a536f15 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure15.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to\ nsend 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee + or commission for + handeling transaction in + Payee FSP => fee 1 USD + + + Optional + + + + If accepted, you will receive + 98 USD out of Payer's 100 USD + + Notify/Ask Payee + for approval + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=98 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=98 USD + payeeFspFees=1 USD) + + + + HTTP 200 + (OK) + + + + + Show total fees to Payer + + + + Payee will receive 98 USD + if you send 100 USD + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure17.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure17.plantuml new file mode 100644 index 000000000..e95153b41 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure17.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to \nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or commission\nfor handeling transaction in\nPayee FSP => FSP commission 3\nUSD (1 USD to pay for Payer's\nfee, 2 USD in excess commission) +group Optional +PayeeFSP ->> Payee: If accepted, you will receive\n100 USD out of Payer's 100 USD +hnote left of PayeeFSP + Notify/Ask Payee + for approval +end note +PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=97 USD,\npayeeReceivedAmount=100 USD,\npayeeFspCommission=3 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=97 USD,\npayeeReceiveAmount=100 USD\npayeeFspCommission=3 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer should pay 100 USD, Payer\nFSP will earn in total 3 USD in fees\n(Payer fee of 1 USD paid by\nPayeeFSP, plus 2 USD in access\ncommission) +PayerFSP ->> Payer: Payee will receive 100 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure17.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure17.svg new file mode 100644 index 000000000..aa3f4fdb4 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure17.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to + send 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or commission + for handeling transaction in + Payee FSP => FSP commission 3 + USD (1 USD to pay for Payer's + fee, 2 USD in excess commission) + + + Optional + + + + If accepted, you will receive + 100 USD out of Payer's 100 USD + + Notify/Ask Payee + for approval + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=97 USD, + payeeReceivedAmount=100 USD, + payeeFspCommission=3 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=97 USD, + payeeReceiveAmount=100 USD + payeeFspCommission=3 USD) + + + + HTTP 200 + (OK) + + + + + Payer should pay 100 USD, Payer + FSP will earn in total 3 USD in fees + (Payer fee of 1 USD paid by + PayeeFSP, plus 2 USD in access + commission) + + + + Payee will receive 100 USD + if you send 100 USD + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure19.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure19.plantuml new file mode 100644 index 000000000..33ed308f9 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure19.plantuml @@ -0,0 +1,159 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title P2P Transfer example with receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like Payee\nto receive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Commission is 1 USD in\nPayee FSP for P2P +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer FSP keeps commission\nas fee, Payer also should pay\nfee of 1 USD +PayerFSP ->> Payer: Transfering 100 USD to Payee\nwill cost you 101 USD\nincluding fees +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Receive 101 USD from Payer\naccount, 99 USD to Switch\naccount, 1 USD to fee account,\n1 USD to FSP commission account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Receive 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount and 1 USD from\ncommission account\nto Payee account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful,\nyou have paid 1 USD in fee +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure19.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure19.svg new file mode 100644 index 000000000..cb8eef462 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure19.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like Payee + to receive 100 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Commission is 1 USD in + Payee FSP for P2P + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer FSP keeps commission + as fee, Payer also should pay + fee of 1 USD + + + + Transfering 100 USD to Payee + will cost you 101 USD + including fees + + + + Perform transaction + + + + + Receive 101 USD from Payer + account, 99 USD to Switch + account, 1 USD to fee account, + 1 USD to FSP commission account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Receive 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account and 1 USD from + commission account + to Payee account + + + You have received 100 USD + from Payer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, + you have paid 1 USD in fee + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml new file mode 100644 index 000000000..0b5116c3f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam sequencearrowcolor Black + +hide footbox + +' declare title +' title HTTP POST call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(Service information, ID) +activate FSP +activate Switch +FSP <<[#Red]-- Switch : **HTTP 202** (Accepted) +Switch ->> PEERFSP: **POST /service**\n(Service information, ID) +activate PEERFSP +Switch <<[#Red]-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Create service object\naccording to request +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch --[#Red]>> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP --[#Red]>> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object information +FSP -[hidden]> Switch +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg new file mode 100644 index 000000000..49c15b416 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg @@ -0,0 +1,76 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + + Create service object + according to request + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object information + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure2.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure2.plantuml new file mode 100644 index 000000000..5a7668cd6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure2.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declare skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP GET call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /service/**//// +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **GET /service/**//// +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Lookup service\ninformation regarding\nservice with//// +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object\ninformation update +FSP -[hidden]> FSP +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure2.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure2.svg new file mode 100644 index 000000000..0b32be0cf --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure2.svg @@ -0,0 +1,79 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Lookup service + information regarding + service with + <ID> + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object + information update + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure21.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure21.plantuml new file mode 100644 index 000000000..294c13d52 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure21.plantuml @@ -0,0 +1,167 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-initiated Cash-In example with send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n(OTC)" as PayerOTC +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee + +' start flow +PayerOTC ->> Payer: I would like to Cash-in\nthis 100 USD bill +PayerOTC <<- Payer: OK, you will receive a\nnotification from your FSP\ndisplaying the fees +Payer ->> PayerFSP: I would like to send\n100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 2 USD in Payer\nFSP for Cash-in,\nPayer will receive 1\nUSD in internal commission. +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=98 USD, fees=2 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=98 USD, fees=2 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payee FSP decides to give\n2 USD in FSP commission to\nPayer so that\nCash-in is free +PayeeFSP ->> Payee: By paying 100 USD in cash\nto Payer, you will receive\n100 USD to your account +PayeeFSP <<-- Payee: OK +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=98 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=98 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <<- PayerFSP: Payee will receive 100 USD\nand has accepted the\nquote, you will receive\n1 USD in commission +deactivate PayerFSP +PayerOTC <<- Payer: You will receive 100 USD\non your account. Please give\nme the 100 USD bill +PayerOTC ->> Payer: OK, here is 100 USD +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 98 USD to Switch\naccount and 2 USD to fee account,\n1 USD from agent commission\naccount to Payer +PayerFSP ->> Switch: **POST /transfers**\n(amount=98 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 98 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=98 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 98 USD from Switch\naccount and 2 USD from\nFSP commission account\nto Payee account +PayeeFSP -> Payee: You have Cash-in 100 USD +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful, you have\nsent 100 USD and received\n1 USD in commission +deactivate PayerFSP +PayerOTC <- Payer: Thank you! +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure21.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure21.svg new file mode 100644 index 000000000..35f3955eb --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure21.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + (OTC) + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + + + + + + + + + I would like to Cash-in + this 100 USD bill + + + + OK, you will receive a + notification from your FSP + displaying the fees + + + + I would like to send + 100 USD to Payee + + + + + Fee is 2 USD in Payer + FSP for Cash-in, + Payer will receive 1 + USD in internal commission. + + + + POST /quotes + (amountType=SEND, + amount=98 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=98 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + + Payee FSP decides to give + 2 USD in FSP commission to + Payer so that + Cash-in is free + + + + By paying 100 USD in cash + to Payer, you will receive + 100 USD to your account + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=98 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=98 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=2 USD) + + + + HTTP 200 + (OK) + + + + Payee will receive 100 USD + and has accepted the + quote, you will receive + 1 USD in commission + + + + You will receive 100 USD + on your account. Please give + me the 100 USD bill + + + + OK, here is 100 USD + + + + Perform transaction + + + + + Reserve 100 USD from Payer + account, 98 USD to Switch + account and 2 USD to fee account, + 1 USD from agent commission + account to Payer + + + + POST /transfers + (amount=98 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 98 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=98 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 98 USD from Switch + account and 2 USD from + FSP commission account + to Payee account + + + You have Cash-in 100 USD + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, you have + sent 100 USD and received + 1 USD in commission + + + Thank you! + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure23.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure23.plantuml new file mode 100644 index 000000000..bb636328f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure23.plantuml @@ -0,0 +1,167 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-initiated Cash-In example with received amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n(OTC)" as PayerOTC +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee + +' start flow +PayerOTC ->> Payer: I would like to Cash-in\nso that I receive 100 USD +PayerOTC <<- Payer: OK, you will receive a\nnotification from your FSP\ndisplaying the fees +Payer ->> PayerFSP: I would like Agent (Payee) to\nreceive 100 USD +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 2 USD in Payer\nFSP for Cash-in,\nPayer will receive 1\nUSD in internal commission. +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=2 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=2 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payee FSP decides to give\n1 USD in commission to\nPayer so that\nCash-in only costs 1 USD +PayeeFSP ->> Payee: By paying 101 USD in cash\nto Payer, you will receive\n100 USD to your account +PayeeFSP <<-- Payee: OK +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <<- PayerFSP: Payee will receive 100 USD\nand fee is 1 USD, you will receive\n1 USD in commission +deactivate PayerFSP +PayerOTC <<- Payer: You will receive 100 USD on your\naccount. Please give me 101 USD +PayerOTC ->> Payer: OK, here is 101 USD +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 1 USD from Agent\ncommission to Payer account,\n100 USD from Payer account,\n99 USD to Switch account and 1\nUSD to fee account, 1 USD from\nFSP Commission to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount = 99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount = 99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount and 1 USD from\ninternal commission account\nto Payee account +PayeeFSP -> Payee: You have Cashed-in 100 USD +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful, you have\nsent 100 USD and received\n1 USD in commission +deactivate PayerFSP +PayerOTC <- Payer: Thank you! +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure23.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure23.svg new file mode 100644 index 000000000..84b41a512 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure23.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + (OTC) + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + + + + + + + + + I would like to Cash-in + so that I receive 100 USD + + + + OK, you will receive a + notification from your FSP + displaying the fees + + + + I would like Agent (Payee) to + receive 100 USD + + + + + Fee is 2 USD in Payer + FSP for Cash-in, + Payer will receive 1 + USD in internal commission. + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + + Payee FSP decides to give + 1 USD in commission to + Payer so that + Cash-in only costs 1 USD + + + + By paying 101 USD in cash + to Payer, you will receive + 100 USD to your account + + + + OK + + + + PUT /quotes/ + <ID> +   + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + Payee will receive 100 USD + and fee is 1 USD, you will receive + 1 USD in commission + + + + You will receive 100 USD on your + account. Please give me 101 USD + + + + OK, here is 101 USD + + + + Perform transaction + + + + + Reserve 1 USD from Agent + commission to Payer account, + 100 USD from Payer account, + 99 USD to Switch account and 1 + USD to fee account, 1 USD from + FSP Commission to fee account + + + + POST /transfers + (amount = 99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount = 99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account and 1 USD from + internal commission account + to Payee account + + + You have Cashed-in 100 USD + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, you have + sent 100 USD and received + 1 USD in commission + + + Thank you! + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure25.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure25.plantuml new file mode 100644 index 000000000..97b9d89ee --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure25.plantuml @@ -0,0 +1,163 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Merchant Payment example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to buy\nthis goods or service +Payee ->> PayerOTC: The goods or service cost\n100 USD before any fees,\nplease initiate the transaction +Payer ->> PayerFSP: I would like Payee to\nreceive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Interoperable fee is 0 USD in\nPayee FSP for Merchant\nPayment, but 1 USD in\ninternal Payee fee for Merchant +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=100 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Fee is 1 USD in Payer\nFSP for Merchant Payment,\ntotal fee is 1 USD +Payer <<- PayerFSP: Will you approve Merchant Payment\nof 100 USD to Payee? It will\ncost you 1 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 101 USD from Payer\naccount, 100 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 100 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 100 USD from Switch\naccount to Payee account, 1 USD\nfrom Payee to fee account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer and paid 1 USD\nin internal fee. Please give\ngoods or service to Payer. +Payee ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Payment successful, you\nhave paid 100 USD to Payee\nplus 1 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure25.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure25.svg new file mode 100644 index 000000000..54293ab7b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure25.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + Payer + (OTC) + + + + + + + + + + + + I would like to buy + this goods or service + + + + The goods or service cost + 100 USD before any fees, + please initiate the transaction + + + + I would like Payee to + receive 100 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Interoperable fee is 0 USD in + Payee FSP for Merchant + Payment, but 1 USD in + internal Payee fee for Merchant + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + + Fee is 1 USD in Payer + FSP for Merchant Payment, + total fee is 1 USD + + + + Will you approve Merchant Payment + of 100 USD to Payee? It will + cost you 1 USD in fees. + + + + Perform transaction + + + + + Reserve 101 USD from Payer + account, 100 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 100 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 100 USD from Switch + account to Payee account, 1 USD + from Payee to fee account + + + You have received 100 USD + from Payer and paid 1 USD + in internal fee. Please give + goods or service to Payer. + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Payment successful, you + have paid 100 USD to Payee + plus 1 USD in fees + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure27.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure27.plantuml new file mode 100644 index 000000000..41fcc2b28 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure27.plantuml @@ -0,0 +1,163 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Cash-Out example (receive amount) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +Payee ->> PayerOTC: Please initiate the transaction +Payer ->> PayerFSP: I would like to Cash-Out\n100 USD from Agent (Payee) +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee\nFSP to cover agent\ncommission, agent will receive\n1 USD in agent commission +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=102 USD,\nPayFspFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFspFee=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Cash-Out, total fee\nis 3 USD +Payer <<- PayerFSP: Will you approve Cash-Out\nof 100 USD? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 103 USD from Payer\naccount, 102 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=102 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 102 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=102 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 102 USD from Switch\naccount, 101 USD to Payee\n(1 USD commission), and\n1 USD to fee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer plus 1 USD in\ncommission, please give 100 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 100 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure27.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure27.svg new file mode 100644 index 000000000..45e0d08a2 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure27.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + Please initiate the transaction + + + + I would like to Cash-Out + 100 USD from Agent (Payee) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee + FSP to cover agent + commission, agent will receive + 1 USD in agent commission + + + + PUT /quotes/ + <ID> +   + (transferAmount=102 USD, + PayFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Cash-Out, total fee + is 3 USD + + + + Will you approve Cash-Out + of 100 USD? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 103 USD from Payer + account, 102 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 102 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 102 USD from Switch + account, 101 USD to Payee + (1 USD commission), and + 1 USD to fee account + + + + You have received 100 USD + from Payer plus 1 USD in + commission, please give 100 USD + in cash to Payer + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 100 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure29.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure29.plantuml new file mode 100644 index 000000000..e6886c6b9 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure29.plantuml @@ -0,0 +1,164 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Cash-Out example (send amount) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +Payee ->> PayerOTC: Please initiate the transaction +Payer ->> PayerFSP: I would like to Cash-Out from\nAgent (Payee) so that 100 USD is\nwithdrawn from my account +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 1 USD in Payer\nFSP from Cash-Out +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee FSP to\ncover agent commission, agent will\nreceive 1 USD in internal commission +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=99 USD,\nPayeeFspFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspFee=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Calculate Payee receive amount\nas not sent from Payee FSP\n(transferAmount -\npayeeFspFee=97 USD) +Payer <<- PayerFSP: Will you approve Cash-Out\nof 97 USD? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 99 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount, 2 USD to fee account and\n98 USD (including 1 USD in\ncommission) to Payee +PayeeFSP ->> Payee: You have received 97 USD\nfrom Payer plus 1 USD in\ncommission, please give 97 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 97 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 97 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure29.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure29.svg new file mode 100644 index 000000000..8e1c5bd64 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure29.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + Please initiate the transaction + + + + I would like to Cash-Out from + Agent (Payee) so that 100 USD is + withdrawn from my account + + + + + Fee is 1 USD in Payer + FSP from Cash-Out + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee FSP to + cover agent commission, agent will + receive 1 USD in internal commission + + + + PUT /quotes/ + <ID> +   + (transferAmount=99 USD, + PayeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Calculate Payee receive amount + as not sent from Payee FSP + (transferAmount - + payeeFspFee=97 USD) + + + + Will you approve Cash-Out + of 97 USD? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 100 USD from Payer + account, 99 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account, 2 USD to fee account and + 98 USD (including 1 USD in + commission) to Payee + + + + You have received 97 USD + from Payer plus 1 USD in + commission, please give 97 USD + in cash to Payer + + + + Here is your 97 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 97 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml new file mode 100644 index 000000000..4834069c2 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declare skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP GET call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /service/**//// +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **GET /service/**//// +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Lookup service\ninformation regarding\nservice with//// +Switch <<[#Red]- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<[#Red]- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object\ninformation update +FSP -[hidden]> FSP +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg new file mode 100644 index 000000000..43254c4a9 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg @@ -0,0 +1,79 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Lookup service + information regarding + service with + <ID> + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object + information update + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure3.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure3.plantuml new file mode 100644 index 000000000..04af955c2 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure3.plantuml @@ -0,0 +1,59 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP DELETE call flow + +' Actor Keys: +' participant - FSP and Account Lookup + +' declare actors +participant "\nFSP" as FSP +participant "Account\nLookup" as ALS + +' start flow +FSP ->> ALS: **DELETE /service/**//// +activate FSP +activate ALS +FSP <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Delete object\naccording to request +FSP <<- ALS: **PUT /service/**////\n(Delete object information) +FSP -->> ALS: **HTTP 200** (OK) +deactivate ALS +FSP -> FSP: Handle delete object\ninformation +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure3.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure3.svg new file mode 100644 index 000000000..abeab0e1e --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure3.svg @@ -0,0 +1,50 @@ + + + + + + + + +   + FSP + + Account + Lookup + + + + + + DELETE /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Delete object + according to request + + + + PUT /service/ + <ID> + (Delete object information) + + + + HTTP 200 + (OK) + + + + + Handle delete object + information + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure31.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure31.plantuml new file mode 100644 index 000000000..5f62c990d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure31.plantuml @@ -0,0 +1,177 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-Initiated Cash-Out example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +PayeeFSP <<- Payee: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequest**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee FSP\nto cover agent\ncommission, agent will\nreceive 1 USD in commission +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFSPFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFSPFee=2 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Cash-Out, total fees\nare 3 USD +Payer <<- PayerFSP: Will you approve Cash-out of\n100 USD to Payee? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 103 USD for Payer\naccount, 102 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=102 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 102 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=102 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 102 USD from Switch\naccount, 101 USD to Payee\n(1 USD commission), and\n1 USD to fee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer plus 1 USD in\ncommission, please give 100 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 100 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure31.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure31.svg new file mode 100644 index 000000000..ee320e69b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure31.svg @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequest + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee FSP + to cover agent + commission, agent will + receive 1 USD in commission + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFSPFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFSPFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Cash-Out, total fees + are 3 USD + + + + Will you approve Cash-out of + 100 USD to Payee? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 103 USD for Payer + account, 102 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 102 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 102 USD from Switch + account, 101 USD to Payee + (1 USD commission), and + 1 USD to fee account + + + + You have received 100 USD + from Payer plus 1 USD in + commission, please give 100 USD + in cash to Payer + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 100 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure33.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure33.plantuml new file mode 100644 index 000000000..188829960 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure33.plantuml @@ -0,0 +1,177 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Merchant-Initiated Merchant Payment example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to buy goods\nor service for 100 USD +PayeeFSP <<- Payee: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Receives status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 0 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Merchant Payment +Payer <<- PayerFSP: Will you approve Merchant Payment\nof 100 USD to Payee? It will\ncost you 1 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 101 USD from Payer\naccount, 100 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 100 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 100 USD from Switch\naccount to Payee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer. Please give goods\nor service to Payer +Payee ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP ->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou have paid 100 USD to Payee\nplus 1 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure33.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure33.svg new file mode 100644 index 000000000..67ccb5047 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure33.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + + + + I would like to buy goods + or service for 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Receives status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 0 USD + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Merchant Payment + + + + Will you approve Merchant Payment + of 100 USD to Payee? It will + cost you 1 USD in fees. + + + + Perform transaction + + + + + Reserve 101 USD from Payer + account, 100 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 100 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 100 USD from Switch + account to Payee account + + + + You have received 100 USD + from Payer. Please give goods + or service to Payer + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you have paid 100 USD to Payee + plus 1 USD in fees. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure35.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure35.plantuml new file mode 100644 index 000000000..1bbc06eb6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure35.plantuml @@ -0,0 +1,205 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title ATM-Initiated Cash-Out example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(ATM)" as PayeeATM +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payer -> PayerFSP: Pre-generate OTP for me so that\nI can use it for ATM Cash-Out +activate PayerFSP +PayerFSP -> PayerFSP: Generate OTP +Payer <<-- PayerFSP: "12345 is your OTP" +deactivate PayerFSP +PayeeATM <<- PayerOTC: I would like to\nCash-Out 100 USD +PayeeFSP <<- PayeeATM: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payer fee is 1 USD for\nATM Cash-Out +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=101 USD,\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=101 USD,\npayeeFspFee=1 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer FSP\nfor ATM Cash-Out, total fee 2 USD +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: OTP is pre-generated +Payer <<- PayerFSP: Use you pre-generated OTP to accept\ntransaction of 100 USD, 2 USD\nin fees. +PayerFSP ->> Switch: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=2 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=2 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeeATM: Total fee for Cash-Out of\n100 USD is 2 USD +PayeeATM ->> PayerOTC: Please enter you OTP\nto confirm Cash-Out of 100 USD,\nfee is 2 USD +PayeeATM <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeeATM: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n{transactionRequestID}\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n{transactionRequestID}\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP OK +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 102 USD from Payer\naccount, 101 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=101 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 101 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=101 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 101 USD from Switch\naccount, 100 USD to Payee,\n1 USD to fee account +PayeeFSP ->> PayeeATM: Dispense 100 USD in Cash +PayeeATM ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch <- Switch: Commit reserved transfer +Switch ->> PayerFSP: **PUT /transfers/** +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP <- PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transfer successful,\nyou should receive 100 USD\nin cash from ATM. You have\npaid 2 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure35.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure35.svg new file mode 100644 index 000000000..7ca43eff6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure35.svg @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (ATM) + + + + Payer + (OTC) + + + + + + + + + + + + + + + + + + Pre-generate OTP for me so that + I can use it for ATM Cash-Out + + + + + Generate OTP + + + + "12345 is your OTP" + + + + I would like to + Cash-Out 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Payer fee is 1 USD for + ATM Cash-Out + + + + PUT /quotes/ + <ID> + (transferAmount=101 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=101 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer FSP + for ATM Cash-Out, total fee 2 USD + + + + + OTP is pre-generated + + + + Use you pre-generated OTP to accept + transaction of 100 USD, 2 USD + in fees. + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=2 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=2 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total fee for Cash-Out of + 100 USD is 2 USD + + + + Please enter you OTP + to confirm Cash-Out of 100 USD, + fee is 2 USD + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP OK + + + + + Reserve 102 USD from Payer + account, 101 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=101 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 101 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=101 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 101 USD from Switch + account, 100 USD to Payee, + 1 USD to fee account + + + + Dispense 100 USD in Cash + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transfer successful, + you should receive 100 USD + in cash from ATM. You have + paid 2 USD in fees. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure37.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure37.plantuml new file mode 100644 index 000000000..04e62ac13 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure37.plantuml @@ -0,0 +1,196 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Merchant-Initiated Merchant Payment authorized on POS example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +PayeePOS <<- PayerOTC: I would like to buy goods\nor service for 100 USD +PayeeFSP <<- PayeePOS: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +activate PayerFSP +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amount=100 USD,\namountType=RECEIVE) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amount=100 USD,\namountType=RECEIVE) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: FSP Commission is 1 USD\nin Payee FSP for\nMerchant Payment +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer FSP uses the\nFSP commission as\na transaction fee +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Generate OTP, "12345" +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant of 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter you OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeePOS: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/***\n{transactionRequestID}\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +PayerFSP <<- Switch: **PUT /authorizations/***\n{transactionRequestID}\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP OK +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 99 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount, 1 USD from\ncommission account\nto Payee account +PayeeFSP ->> PayeePOS: You have received 100 USD\nfrom Payer. Please give goods\nor service to Payer. +PayeePOS ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch <- Switch: Commit reserved transfer +Switch ->> PayerFSP: **PUT /transfers/** +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP <- PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Payment successful, you\nhave paid 100 USD to Payee. +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure37.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure37.svg new file mode 100644 index 000000000..ffc7084e2 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure37.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + + + + + + + I would like to buy goods + or service for 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amount=100 USD, + amountType=RECEIVE) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amount=100 USD, + amountType=RECEIVE) + + + + HTTP 202 + (Accepted) + + + + + FSP Commission is 1 USD + in Payee FSP for + Merchant Payment + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer FSP uses the + FSP commission as + a transaction fee + + + + + Generate OTP, "12345" + + + + Use OTP "12345" to accept + transaction to Merchant of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter you OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + * + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + * + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP OK + + + + + Reserve 100 USD from Payer + account, 99 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account, 1 USD from + commission account + to Payee account + + + + You have received 100 USD + from Payer. Please give goods + or service to Payer. + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Payment successful, you + have paid 100 USD to Payee. + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure39.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure39.plantuml new file mode 100644 index 000000000..187a75c8a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure39.plantuml @@ -0,0 +1,162 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Refund example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like a Refund\nof my Agent Cash-in of 101 USD +activate PayerFSP +PayerFSP -> PayerFSP: Find original transaction, FSP\ncommission was 1 USD which\nmeans Payer FSP wants 1 USD\nin fee to reverse. +PayerFSP ->> Switch: **POST /quotes**\n(transactionScenario=REFUND\namountType=SEND,\namount=100 USD, fee=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202**\n(Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(transactionScenario=REFUND\namountType=SEND,\namount=100 USD, fee=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202**\n(Accepted) +PayeeFSP -> PayeeFSP:Find original transaction, 1 USD\nwas received in FSP commission, \ngive back in FSP commission.\nReverse Agent commission. +PayeeFSP ->> Payee:Customer wants a refund of Cash-in,\nyou will lose 1 USD in commission\nand 100 USD will be transfered to\nyour account, please pay customer\n101 USD in cash +PayeeFSP <<- Payee: OK +Switch <<- PayeeFSP: **PUT /quote/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quote/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer gets fee subsizidized by\nFSP commission. +Payer <<- PayerFSP: By refunding 100 USD to Agent, you\nshould receive 101 USD in cash +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reverse original transaction by\nreversing 100 USD from Payer\nAccount, 99 USD to Switch account,\n1 USD to commission account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfer/** +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reverse original transaction by\ntransferring 100 USD to Payee\naccount, 99 USD from Switch\naccount, 1 USD from fee account,\nand 1 USD from fee account to\ninternal commission account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer in Cash-in refund,\nplease pay customer his 101 USD +Switch <<- PayeeFSP: **POST /transfer/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **POST /transfer/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful,\nyou have paid 1 USD in fee +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure39.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure39.svg new file mode 100644 index 000000000..c10af8f4f --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure39.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like a Refund + of my Agent Cash-in of 101 USD + + + + + Find original transaction, FSP + commission was 1 USD which + means Payer FSP wants 1 USD + in fee to reverse. + + + + POST /quotes + (transactionScenario=REFUND + amountType=SEND, + amount=100 USD, fee=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (transactionScenario=REFUND + amountType=SEND, + amount=100 USD, fee=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Find original transaction, 1 USD + was received in FSP commission, + give back in FSP commission. + Reverse Agent commission. + + + + Customer wants a refund of Cash-in, + you will lose 1 USD in commission + and 100 USD will be transfered to + your account, please pay customer + 101 USD in cash + + + + OK + + + + PUT /quote/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quote/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer gets fee subsizidized by + FSP commission. + + + + By refunding 100 USD to Agent, you + should receive 101 USD in cash + + + + Perform transaction + + + + + Reverse original transaction by + reversing 100 USD from Payer + Account, 99 USD to Switch account, + 1 USD to commission account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfer/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Reverse original transaction by + transferring 100 USD to Payee + account, 99 USD from Switch + account, 1 USD from fee account, + and 1 USD from fee account to + internal commission account + + + You have received 100 USD + from Payer in Cash-in refund, + please pay customer his 101 USD + + + + POST /transfer/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + POST /transfer/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, + you have paid 1 USD in fee + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure4.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure4.plantuml new file mode 100644 index 000000000..db01171d2 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure4.plantuml @@ -0,0 +1,64 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP PATCH call flow + +' Actor Keys: +' participant - Switch and FSP + +' declare actors +participant "Switch" as Switch +participant "FSP" as FSP + +' start flow +activate Switch +activate FSP +Switch ->> FSP: **POST /service/**//// +FSP -->> Switch: **HTTP 202** (Accepted) +FSP ->> FSP: Create object, state of \ncreated object is a \nnon-fiinalized state +FSP ->> Switch: **PUT /service/** \n(Non-finalized state) +Switch -->> FSP: **HTTP 200** (OK) +deactivate FSP +Switch ->> Switch: Handle callback, send\nnotificaction to FSP regarding\nthe object's finalized state +Switch ->> FSP: **PATCH /service/**\n(Finalized state) +activate FSP +FSP -->> Switch: **HTTP 202** (Accepted) +deactivate Switch +FSP ->> FSP: Update object's state\naccording to new\ninformation +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure4.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure4.svg new file mode 100644 index 000000000..4d6eb7612 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure4.svg @@ -0,0 +1,73 @@ + + + + + + + + + + Switch + + FSP + + + + + + + POST /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + + Create object, state of + created object is a + non-fiinalized state + + + + PUT /service/ + <ID> + (Non-finalized state) + + + + HTTP 200 + (OK) + + + + + + Handle callback, send + notificaction to FSP regarding + the object's finalized state + + + + PATCH /service/ + <ID> + (Finalized state) + + + + HTTP 202 + (Accepted) + + + + + + Update object's state + according to new + information + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure41.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure41.plantuml new file mode 100644 index 000000000..ee5053cd8 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure41.plantuml @@ -0,0 +1,139 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the services provided by /participants if there is no common Account Lookup System + +' Actor Keys: +' participant - FSP(User's) and FSP +' actor - User + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "\nFSP 1" as fsp1 +participant "\nFSP 2" as fsp2 + +' start flow +user ->> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system,\nask FSP 1 +userfsp ->> fsp1: **GET /participants/MSISDN/123456789** +activate fsp1 +userfsp <<-- fsp1: **HTTP 202** (Accepted) +fsp1 -> fsp1: +123456789 is not\nwithin this system +userfsp <<- fsp1: **PUT /participants/MSISDN/123456789/error** +userfsp -->> fsp1: **HTTP 200** (OK) +deactivate fsp1 +userfsp -> userfsp: Not in FSP 1, ask FSP 2 +userfsp ->> fsp2: **GET /participants/MSISDN/123456789** +activate fsp2 +userfsp <<-- fsp2: **HTTP 202** (Accepted) +fsp2 -> fsp2: +123456789 is\nwithin this system +userfsp <<- fsp2: **PUT /participants/MSISDN/123456789/error** +userfsp -->> fsp2: **HTTP 200** (OK) +deactivate fsp2 +userfsp -> userfsp: +123456789 found\nin FSP 2 +userfsp -[hidden]>fsp2 +deactivate userfsp +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure41.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure41.svg new file mode 100644 index 000000000..cf028451c --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure41.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + User + + + + User's + FSP + +   + FSP 1 + +   + FSP 2 + + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system, + ask FSP 1 + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + +123456789 is not + within this system + + + + PUT /participants/MSISDN/123456789/error + + + + HTTP 200 + (OK) + + + + + Not in FSP 1, ask FSP 2 + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + +123456789 is + within this system + + + + PUT /participants/MSISDN/123456789/error + + + + HTTP 200 + (OK) + + + + + +123456789 found + in FSP 2 + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure42.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure42.plantuml new file mode 100644 index 000000000..05ba8f242 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure42.plantuml @@ -0,0 +1,128 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the services provided by /participants if there is no common Account Lookup System + +' Actor Keys: +' participant - FSP(User's) and Account Lookup Service +' actor - User + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "Account\nLookup" as ALS + +' start flow +user ->> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system +userfsp ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +userfsp <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to. +userfsp <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP ID) +userfsp -->> ALS: **HTTP 200** (OK) +deactivate ALS +deactivate userfsp +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure42.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure42.svg new file mode 100644 index 000000000..1f9cf748e --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure42.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + User + + + + User's + FSP + + Account + Lookup + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to. + + + + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure43.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure43.plantuml new file mode 100644 index 000000000..cc7a269f5 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure43.plantuml @@ -0,0 +1,144 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for /parties resource + +' Actor Keys: +' participant - FSP(User's), Switch, Account Lookup and FSP +' actor - Payee/Payer(User) + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "\nFSP 1" as fsp1 + +' start flow +user -> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system +userfsp ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +userfsp <<-- Switch: **HTTP 202** (Accepted) +Switch ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to. +Switch <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP 1) +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +Switch ->> fsp1: **GET /parties/MSISDN/123456789** +activate fsp1 +Switch <<-- fsp1: **HTTP 202** (Accepted) +fsp1 -> fsp1: Lookup party information\nfor +123456789 +Switch <<- fsp1: **PUT /parties/MSISDN/123456789**\n(Party information) +Switch -->> fsp1: **HTTP 200** (OK) +deactivate fsp1 +userfsp <<- Switch: **PUT /parties/MSISDN/123456789**\n(Party information) +userfsp -->> Switch: **HTTP 200** (OK) +deactivate Switch +user <- userfsp: Is "name" correct? +deactivate userfsp +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure43.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure43.svg new file mode 100644 index 000000000..0c6980acc --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure43.svg @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + User + + + + User's + FSP + + Optional + Switch + + Account + Lookup + +   + FSP 1 + + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system + + + + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to. + + + + PUT /participants/MSISDN/123456789 + (FSP 1) + + + + HTTP 200 + (OK) + + + + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party information + for +123456789 + + + + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + Is "name" correct? + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure44.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure44.plantuml new file mode 100644 index 000000000..ed8d8bd0e --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure44.plantuml @@ -0,0 +1,137 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +payeefsp <- Payee: I would like to receive\nfunds from +123456789 +activate payeefsp +payeefsp <- payeefsp: Lookup +123456789\n(process not shown her) +Switch <<- payeefsp: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepted) +payerfsp <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepted) +payeefsp -> payeefsp: Perform optional validation +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Received status) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Received status) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Wait for either quote and\ntransfer, or rejected\ntransaction request by Payer +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure44.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure44.svg new file mode 100644 index 000000000..e073588f1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure44.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + I would like to receive + funds from +123456789 + + + + + Lookup +123456789 + (process not shown her) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + Wait for either quote and + transfer, or rejected + transaction request by Payer + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure45.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure45.plantuml new file mode 100644 index 000000000..bcaad8a0d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure45.plantuml @@ -0,0 +1,131 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process in which a transaction request is rejected + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +activate payerfsp +payerfsp -> payerfsp: Transaction request and\nquoting (process not shown) +payerfsp -> payerfsp: User rejection, OTP not correct,\nor automatic rejection +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Rejected state) +activate Switch +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Rejected state) +activate payeefsp +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> Payee: Transaction failed due\nto user rejection +deactivate payeefsp +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure45.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure45.svg new file mode 100644 index 000000000..5b94d8fd5 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure45.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + Transaction request and + quoting (process not shown) + + + + + User rejection, OTP not correct, + or automatic rejection + + + + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + Transaction failed due + to user rejection + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure47.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure47.plantuml new file mode 100644 index 000000000..86deaaefd --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure47.plantuml @@ -0,0 +1,150 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for resource /quotes + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(Transaction details) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the quote and Payer name + PayeeFSP <- Payee: I confirm +end +Switch <<- PayeeFSP: ** PUT /quotes/**\n(Payee FSP fee/commission, condition) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP fee/commission, condition) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +Payer <- PayerFSP: Present fees and optionally\npayee name +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure47.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure47.svg new file mode 100644 index 000000000..e18393d9b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure47.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + Payee + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Rate Payer FSP quote + (depending on fee model) + + + + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + Here is the quote and Payer name + + + I confirm + + + + + PUT /quotes/** + <ID> + (Payee FSP fee/commission, condition) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (Payee FSP fee/commission, condition) + + + + HTTP 200 + (OK) + + + + + Rate Payer FSP quote + (depending on fee model) + + + Present fees and optionally + payee name + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure49.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure49.plantuml new file mode 100644 index 000000000..553dfc514 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure49.plantuml @@ -0,0 +1,156 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for resource /authorizations + +' Actor Keys: +' participant - FSP(Payee) and Switch +' actor - Payee/Payer(POS/ATM) + +' declare actors +'actor "<$actor>\nPayer" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS/ATM)" as Payee + +' start flow +PayeeFSP <- Payee: I would like to receive\nfunds from +123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Lookup +123456789\n(process not shown here) +Switch <<- PayeeFSP: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate PayerFSP +PayerFSP ->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +activate PayerFSP +PayerFSP -> PayerFSP: Do quote, generate OTP,\nnotify user (process\nnot shown here) +PayerFSP ->> Switch: **GET /authorizations/**\n\n(Amount including fees) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(Amount including fees) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> Payee: Show fees on POS +Payee -> Payee: Payer approves/rejects\ntransaction using OTP +PayeeFSP <<-- Payee: +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(OTP) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(OTP) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure49.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure49.svg new file mode 100644 index 000000000..3a5ae346a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure49.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + +   + Payer + FSP + +   + Optional + Switch + +   + Payee + FSP + + Payee + (POS/ATM) + + + + + + + + + + + I would like to receive + funds from +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + Do quote, generate OTP, + notify user (process + not shown here) + + + + GET /authorizations/ + <TransactionRequestID> + (Amount including fees) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (Amount including fees) + + + + HTTP 202 + (Accepted) + + + Show fees on POS + + + + + Payer approves/rejects + transaction using OTP + + + + + + + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure5.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure5.plantuml new file mode 100644 index 000000000..0b48ee49c --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure5.plantuml @@ -0,0 +1,69 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Using the customized HTTP header fields FSPIOP-Destination and FSPIOP-Source + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(**FSPIOP-Source=**FSP,\n**FSPIOP-Destination=**Peer FSP) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Route message according\nto **FSPIOP-Destination** +Switch ->> PEERFSP: **POST /service**\n(**FSPIOP-Source=**FSP,\n**FSPIOP-Destination=**Peer FSP) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Optionally validate messages signature\nusing stored certificate for\nFSP in **FSPIOP-Source** +PEERFSP -> PEERFSP: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination**\nand visa versa for routing of callback +Switch <<- PEERFSP: **PUT /service/**////\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +Switch -->> PEERFSP: **HTTP 200** (OK) +Switch -> Switch: Route message according\nto **FSPIOP-Destination** +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure5.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure5.svg new file mode 100644 index 000000000..54a0efff5 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure5.svg @@ -0,0 +1,112 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Route message according + to + FSPIOP-Destination + + + + POST /service + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Optionally validate messages signature + using stored certificate for + FSP in + FSPIOP-Source + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and visa versa for routing of callback + + + + PUT /service/ + <ID> + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + + + + Route message according + to + FSPIOP-Destination + + + + PUT /service/ + <ID> + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure50.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure50.plantuml new file mode 100644 index 000000000..29daf6dff --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure50.plantuml @@ -0,0 +1,145 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer requests resend of authorization value (OTP) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(OTC/POS) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +activate PayerFSP +PayerFSP -> PayerFSP: Transaction request and\nquoting process (not shown) +PayerFSP -> PayerFSP: Generate OTP, "12345", Payer FSP\nsets maximum retries to 2 +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter your OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: OTP not received +PayeeFSP <<- PayeePOS: OTP not received +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(resend OTP) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(resend OTP) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Resend OTP (optionally\nregenerate) as customer\ndid not receive it +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP -> PayerFSP: Resend GET /authorizations\n(not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure50.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure50.svg new file mode 100644 index 000000000..70b657a1b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure50.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + Transaction request and + quoting process (not shown) + + + + + Generate OTP, "12345", Payer FSP + sets maximum retries to 2 + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter your OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + OTP not received + + + + OTP not received + + + + PUT /authorizations/ + <TransactionRequestID> + (resend OTP) + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (resend OTP) + + + + HTTP 200 + (OK) + + + + + Resend OTP (optionally + regenerate) as customer + did not receive it + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + + Resend GET /authorizations + (not shown here) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure51.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure51.plantuml new file mode 100644 index 000000000..505e8f947 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure51.plantuml @@ -0,0 +1,160 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer enters incorrect authorization value (OTP) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(OTC/POS) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +activate PayerFSP +PayerFSP -> PayerFSP: Transaction request and\nquoting process (not shown) +PayerFSP -> PayerFSP: Generate OTP, "12345", Payer FSP\nsets maximum retries to 2 +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter your OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: Enters "12346" +PayeeFSP <<- PayeePOS: "12346" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(authenticationValue="12346") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(authenticationValue="12346") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP incorrect, decrease retriesLeft +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=1, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=1, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Incorrect OTP,\n1 retry left +PayeePOS ->> PayerOTC: Please enter your OTP to\nconfirm Merchant Payment of\n100 USD, fee is 0 USD, last retry +PayeePOS <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeePOS: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validates OTP sent by\nPayee FSP, OTP OK, perform\ntransfer (not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure51.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure51.svg new file mode 100644 index 000000000..7918e48dc --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure51.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + + + Transaction request and + quoting process (not shown) + + + + + Generate OTP, "12345", Payer FSP + sets maximum retries to 2 + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter your OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + Enters "12346" + + + + "12346" is the OTP + + + + PUT /authorizations/ + <TransactionRequestID> + (authenticationValue="12346") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (authenticationValue="12346") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP incorrect, decrease retriesLeft + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=1, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=1, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Incorrect OTP, + 1 retry left + + + + Please enter your OTP to + confirm Merchant Payment of + 100 USD, fee is 0 USD, last retry + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + <TransactionRequestID> + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validates OTP sent by + Payee FSP, OTP OK, perform + transfer (not shown here) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure52.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure52.plantuml new file mode 100644 index 000000000..a162cad3d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure52.plantuml @@ -0,0 +1,155 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the POST /transfers service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, conditions, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, conditions, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Perform transfer from Switch\naccount to Payee account,\ngenerate fulfilment +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +PayeeFSP -> Payee: Transaction notification +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure52.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure52.svg new file mode 100644 index 000000000..f66d00cc6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure52.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote + (process not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, conditions, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, conditions, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer from Switch + account to Payee account, + generate fulfilment + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + Transaction notification + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from Payer + account to Payee FSP account + + + Transaction notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure53.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure53.plantuml new file mode 100644 index 000000000..4d9e48767 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure53.plantuml @@ -0,0 +1,156 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Optional additional clearing check + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Perform transfer from\nSwitch account to\nPayee account +PayeeFSP -> Payee: Transaction notification +Switch -> Switch: Expiry time reached,\ncancel reservation +PayerFSP <<- Switch: **PUT /transfers/**/**error** +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Mark transfer for\nReconciliation as Payee\nFSP has completed and\nPayer FSP has cancelled +deactivate PayeeFSP +PayerFSP -> PayerFSP: Cancel transfer from Payer\naccount to Switch +deactivate Switch +Payer <- PayerFSP: Transaction failure notification +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure53.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure53.svg new file mode 100644 index 000000000..8eea5e412 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure53.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer from + Switch account to + Payee account + + + Transaction notification + + + + + Expiry time reached, + cancel reservation + + + + PUT /transfers/ + <ID> + / + error + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + HTTP 200 + (OK) + + + + + Mark transfer for + Reconciliation as Payee + FSP has completed and + Payer FSP has cancelled + + + + + Cancel transfer from Payer + account to Switch + + + Transaction failure notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure54.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure54.plantuml new file mode 100644 index 000000000..608a813b0 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure54.plantuml @@ -0,0 +1,159 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Optional additional clearing check where commit in Switch failed + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reserve transfer from Switch\naccount to Payee account,\ngenerate fulfilment +PayeeFSP -> PayeeFSP: Request commit notification\nfrom Switch by sending transfer\nstate as reserved +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment,\ntransferState=RESERVED) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP,\nsend commit notification\nto Payee FSP +Switch ->> PayeeFSP: **PATCH /transfers/**\n(transferState=COMMITTED,\ncompletedTimestamp) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayeeFSP -> PayeeFSP: Commit reserved transfer\nfrom Switch to Payee +PayeeFSP -> Payee: Transaction notification +deactivate PayeeFSP +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure54.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure54.svg new file mode 100644 index 000000000..3a80063b6 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure54.svg @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from Switch + account to Payee account, + generate fulfilment + + + + + Request commit notification + from Switch by sending transfer + state as reserved + + + + PUT /transfers/ + <ID> + (Fulfilment, + transferState=RESERVED) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP, + send commit notification + to Payee FSP + + + + PATCH /transfers/ + <ID> + (transferState=COMMITTED, + completedTimestamp) + + + + HTTP 200 + (OK) + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + from Switch to Payee + + + Transaction notification + + + + + Commit transfer from Payer + account to Payee FSP account + + + Transaction notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure55.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure55.plantuml new file mode 100644 index 000000000..b0b15412e --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure55.plantuml @@ -0,0 +1,158 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Commit notification where commit of transfer in Switch failed + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Switch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reserve transfer from Switch\naccount to Payee account,\ngenerate fulfilment +PayeeFSP -> PayeeFSP: Request commit notification\nfrom Switch by sending transfer\nstate as reserved +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment,\ntransferState=RESERVED) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP\nfailed, notify both FSPs +Switch ->> PayeeFSP: **PATCH /transfers/**\n(transferState=ABORTED,\ncompletedTimestamp) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +PayeeFSP -> PayeeFSP: Rollback reserved transfer\nfrom Switch to Payee +PayerFSP <<- Switch: **PUT /transfers/**/**error** +deactivate PayeeFSP +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Rollback reserved transfer from\nPayer to Switch +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure55.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure55.svg new file mode 100644 index 000000000..56263ad83 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure55.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from Switch + account to Payee account, + generate fulfilment + + + + + Request commit notification + from Switch by sending transfer + state as reserved + + + + PUT /transfers/ + <ID> + (Fulfilment, + transferState=RESERVED) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP + failed, notify both FSPs + + + + PATCH /transfers/ + <ID> + (transferState=ABORTED, + completedTimestamp) + + + + HTTP 200 + (OK) + + + + + Rollback reserved transfer + from Switch to Payee + + + + PUT /transfers/ + <ID> + / + error + + + + HTTP 200 + (OK) + + + + + Rollback reserved transfer from + Payer to Switch + + + Transaction notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure57.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure57.plantuml new file mode 100644 index 000000000..615c2acec --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure57.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example transaction process + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP + +' start flow +Payer -> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -> PayerFSP: Perform quote\n(process not shown here) +PayerFSP -> PayerFSP: Perform transfer\n(process not shown here) +PayerFSP ->> Switch: **GET /transactions/** +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /transactions/** +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Lookup transaction\ninformation +Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction detail) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction detail) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <- PayerFSP: Transaction notification\nincluding transaction\ndata(e.g. token ID) +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure57.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure57.svg new file mode 100644 index 000000000..98acfada5 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure57.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Perform quote + (process not shown here) + + + + + Perform transfer + (process not shown here) + + + + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + Lookup transaction + information + + + + PUT /transactions/ + <TransactionID> + (Transaction detail) + + + + HTTP 200 + (OK) + + + + PUT /transactions/ + <TransactionID> + (Transaction detail) + + + + HTTP 200 + (OK) + + + Transaction notification + including transaction + data(e.g. token ID) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure59.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure59.plantuml new file mode 100644 index 000000000..f90967b30 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure59.plantuml @@ -0,0 +1,147 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example bulk quote process + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP + +' start flow +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +PayerFSP -> PayerFSP: Lookup in which FSP each\nPayee is located in, divide\nPayees into FSP separate files\n(process not shown here) +Loop #OldLace + hnote left of PayerFSP #OldLace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(process not shown here) + PayerFSP ->> Switch: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch ->> PayeeFSP: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + Switch <<- PayeeFSP: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + PayerFSP <<- Switch: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + PayerFSP -> PayerFSP: Rate payer FSP bulk quote\n(depending on fee model) +end Loop +PayerFSP -> PayerFSP: Handle quote results for\nall Payee FSPs +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure59.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure59.svg new file mode 100644 index 000000000..558bc47e8 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure59.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + + + + + I would like to upload + a file of bulk transactions + + + + + Lookup in which FSP each + Payee is located in, divide + Payees into FSP separate files + (process not shown here) + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (process not shown here) + + + + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + + Rate payer FSP bulk quote + (depending on fee model) + + + + + Handle quote results for + all Payee FSPs + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure6.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure6.plantuml new file mode 100644 index 000000000..7f28f23c9 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure6.plantuml @@ -0,0 +1,77 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Example scenario where FSPIOP-Destination is unknown by FSP + +' Actor Keys: +' participant - FSP, Peer FSP, Optional Switch and Account Lookup + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /parties/msisdn/123456789**\n(**FSPIOP-Source=**FSP) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> ALS: **GET /participants/msisdn/123456789**\n(**FSPIOP-Source=**Switch,\n**FSPIOP-Destination=**Account Lookup) +activate ALS +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination**\nand vice versa for\nrouting of callback +Switch <<- ALS: **PUT /participants/msisdn/123456789**\n(**FSPIOP-Source=**Account Lookup,\n**FSPIOP-Destination=**Switch) +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +Switch -> Switch: Set **FSPIOP-Destination**\nin original messages according\nto results of **PUT /participants** +Switch ->> PEERFSP: **GET /parties/msisdn/123456789**\n(**FSPIOP-Source=**FSP, **FSPIOP-Destination=**Peer FSP) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Optionally validate message\nsignature using stored certificate\nfor FSP in **FSPIOP-Source** +PEERFSP -> PEERFSP: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination** and\nvice versa for routing of callback +Switch <<- PEERFSP: **PUT /parties/msisdn/123456789**\n(**FSPIOP-Source=**Peer FSP, **FSPIOP-Destination=**FSP) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +Switch -> Switch: Route messages according\nto **FSPIOP-Destination** +FSP <<- Switch: **PUT /parties/msisdn/123456789**\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate FSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure6.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure6.svg new file mode 100644 index 000000000..c61416d66 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure6.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + +   + FSP + + Optional + Switch + + Account + Lookup + + Peer + FSP + + + + + + + + GET /parties/msisdn/123456789 + ( + FSPIOP-Source= + FSP) + + + + HTTP 202 + (Accepted) + + + + GET /participants/msisdn/123456789 + ( + FSPIOP-Source= + Switch, + FSPIOP-Destination= + Account Lookup) + + + + HTTP 202 + (Accepted) + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and vice versa for + routing of callback + + + + PUT /participants/msisdn/123456789 + ( + FSPIOP-Source= + Account Lookup, + FSPIOP-Destination= + Switch) + + + + HTTP 200 + (OK) + + + + + Set + FSPIOP-Destination + in original messages according + to results of + PUT /participants + + + + GET /parties/msisdn/123456789 + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Optionally validate message + signature using stored certificate + for FSP in + FSPIOP-Source + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and + vice versa for routing of callback + + + + PUT /parties/msisdn/123456789 + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + + + + Route messages according + to + FSPIOP-Destination + + + + PUT /parties/msisdn/123456789 + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure61.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure61.plantuml new file mode 100644 index 000000000..5f0ab8b64 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure61.plantuml @@ -0,0 +1,153 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example bulk transfer process + +' Actor Keys: +' participant - FSP(Payer/Payee(s)) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +PayerFSP -> PayerFSP: Lookup in which FSP each\nPayee is located in, divide\nPayees into FSP separate files\n(process not shown here) +PayerFSP -> PayerFSP: Perform bulk quoting per\nPayee FSP\n(process not shown here) +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +Payer -> PayerFSP: Execute my bulk +Loop #OldLace + hnote left of PayerFSP #OldLace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account + PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + PayeeFSP -> PayeeFSP: Perform each transfer from \nPayer FSP account to Payee \naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **PUT /bulkTransfers/**\n(List of fulfilments) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + PayerFSP <<- Switch: **PUT /bulkTransfers/**\n(List of fulfilments) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure61.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure61.svg new file mode 100644 index 000000000..31fb7c70d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure61.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + Payer +   + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + I would like to upload + a file of bulk transactions + + + + + Lookup in which FSP each + Payee is located in, divide + Payees into FSP separate files + (process not shown here) + + + + + Perform bulk quoting per + Payee FSP + (process not shown here) + + + Bulk has finished processing, + present fees + + + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Perform each transfer from + Payer FSP account to Payee + account, generate fulfilments + + + Transaction notification + for each Payee + + + + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer account + to Payee account + + + Your bulk has been executed + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure64.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure64.plantuml new file mode 100644 index 000000000..589e9e159 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure64.plantuml @@ -0,0 +1,258 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer Initiated Transaction pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to\npay 100 USD\nto +123456789 +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Payee not within\nPayer FSP system +autonumber resume +PayerFSP ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +autonumber stop +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which\nFSP MSISDN\n+123456789\nbelongs to +autonumber resume +Switch <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +autonumber resume +Switch ->> PayeeFSP: **GET /parties/MSISDN/123456789** +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Lookup party\ninformation\nRegarding\nMSISDN\n+123456789 +autonumber resume +Switch <<- PayeeFSP: **Put /parties/MSISDN/123456789**\n(Party information) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /parties/MSISDN/123456789**\n(Party information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate PayerFSP +autonumber resume +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /quote**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +Payer <- PayerFSP: Present fees and\noptionally payee name +deactivate PayerFSP +autonumber resume +Payer -> PayerFSP: I approve the\ntransaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +autonumber resume +PayerFSP -> Switch: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +autonumber stop +activate Switch +PayerFSP <-- Switch: **HTTL 202** (Accepted) +autonumber resume +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber stop +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch\naccount to Payee\naccount, generate\nfulfilment +autonumber stop +PayeeFSP -> Payee: Transaction notification +autonumber resume +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +autonumber stop +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Switch account +group #OldLace Optional + hnote left of PayerFSP #OldLace + Get transaction data + end hnote + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch <<- PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch -->> PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch +end +autonumber resume +Payer <- PayerFSP: Transaction notification\nincluding optional\ntransaction data\n(e.g. token ID) +deactivate PayerFSP +autonumber stop +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure64.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure64.svg new file mode 100644 index 000000000..a5fe0d64d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure64.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + [1] + I would like to + pay 100 USD + to +123456789 + + + + + Payee not within + Payer FSP system + + + + [2] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + [3] + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which + FSP MSISDN + +123456789 + belongs to + + + + [4] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [5] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party + information + Regarding + MSISDN + +123456789 + + + + [6] + Put /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + [7] + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + + [9] + Rate Payer FSP quote + (depending on fee model) + + + + [10] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [11] + POST /quote + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + [12] + Rate Payee FSP + fee/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + [15] + PUT /quotes/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + + [16] + Rate Payer FSP quote + (depending on fee model) + + + Present fees and + optionally payee name + + + [17] + I approve the + transaction + + + + + Reserve transfer from Payer + account to Switch account + + + [18] + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + HTTL 202 + (Accepted) + + + + + [19] + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [20] + Perform transfer + from Switch + account to Payee + account, generate + fulfilment + + + Transaction notification + + + + [21] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [22] + Commit transfer from + Payer FSP to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [23] + Commit transfer from Payer + account to Switch account + + + Optional + + Get transaction data + + + + [24] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + [25] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + [26] + Lookup + transaction + information + + + + [27] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + [28] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + [29] + Transaction notification + including optional + transaction data + (e.g. token ID) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure64a.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure64a.plantuml new file mode 100644 index 000000000..673e1daca --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure64a.plantuml @@ -0,0 +1,212 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer-Initiated Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to\npay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Payee not within\nPayer FSP system +autonumber stop +PayerFSP ->> Switch: **Lookup Party Information**\n(MSISDN 123456789) +activate Switch +autonumber resume +Switch ->> ALS: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +ALS -> ALS: Lookup which\nFSP MSISDN\n+123456789\nbelongs to +autonumber stop +Switch <<- ALS: **Return Participant Information**\n(FSP ID) +deactivate ALS +autonumber resume +Switch ->> PayeeFSP: **Lookup Party Information**\n(MSISDN 123456789) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Lookup party\ninformation\nregarding\nMSISDN\n+123456789 +autonumber stop +Switch <<- PayeeFSP: **Return Party Information**\n(Party Information) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **Return Party Information**\n(Party Information) +deactivate Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction details) +activate Switch +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +Payer <- PayerFSP: Present fees and\noptionally payee name +deactivate PayerFSP +autonumber resume +Payer -> PayerFSP: I approve the\ntransaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +autonumber resume +PayerFSP -> Switch: **Preform Transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate Switch +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber stop +Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate PayeeFSP +autonumber resume +PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch\naccount to Payee\naccount, generate\nfulfilment +PayeeFSP -> Payee: Transaction notification +autonumber stop +Switch <<- PayeeFSP: **Return Transfer Information**\n(Fulfilment) +deactivate PayeeFSP +autonumber resume +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +autonumber stop +PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Switch account +group #OldLace Optional + hnote left of PayerFSP #OldLace + Get transaction data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch <<- PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction details) + deactivate PayeeFSP + PayerFSP <<- Switch: **Return Transaction Information**\n(Transaction details) + deactivate Switch +end +Payer <- PayerFSP: Transaction notification\nincluding optional\ntransaction data\n(e.g. token ID) +deactivate PayerFSP +autonumber stop +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure64a.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure64a.svg new file mode 100644 index 000000000..44df91386 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure64a.svg @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + [1] + I would like to + pay 100 USD + to +123456789 + + + + + [2] + Payee not within + Payer FSP system + + + + Lookup Party Information + (MSISDN 123456789) + + + + [3] + Lookup Participant Information + (MSISDN 123456789) + + + + + [4] + Lookup which + FSP MSISDN + +123456789 + belongs to + + + + Return Participant Information + (FSP ID) + + + + [5] + Lookup Party Information + (MSISDN 123456789) + + + + + [6] + Lookup party + information + regarding + MSISDN + +123456789 + + + + Return Party Information + (Party Information) + + + + [7] + Return Party Information + (Party Information) + + + + + [9] + Rate Payer FSP quote + (depending on fee model) + + + + [10] + Calculate Quote + (Transaction details) + + + + [11] + Calculate Quote + (Transaction details) + + + + + [12] + Rate Payee FSP + fee/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + [15] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + + [16] + Rate Payer FSP quote + (depending on fee model) + + + Present fees and + optionally payee name + + + [17] + I approve the + transaction + + + + + Reserve transfer from Payer + account to Switch account + + + [18] + Preform Transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [19] + Reserve transfer from + Payer FSP to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [20] + Perform transfer + from Switch + account to Payee + account, generate + fulfilment + + + [21] + Transaction notification + + + + Return Transfer Information + (Fulfilment) + + + + + [22] + Commit transfer from + Payer FSP to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + [23] + Commit transfer from Payer + account to Switch account + + + Optional + + Get transaction data + + + + [24] + Retrieve Transaction Information + (Transaction ID) + + + + [25] + Retrieve Transaction Information + (Transaction ID) + + + + + [26] + Lookup + transaction + information + + + + [27] + Return Transaction Information + (Transaction details) + + + + [28] + Return Transaction Information + (Transaction details) + + + [29] + Transaction notification + including optional + transaction data + (e.g. token ID) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure65.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure65.plantuml new file mode 100644 index 000000000..369c7624a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure65.plantuml @@ -0,0 +1,283 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee Initiated Transaction pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Payer not\nwithin Payee\nFSP system +autonumber stop +ALS <<- PayeeFSP: **GET /participants/MSISDN/123456789** +activate ALS +ALS -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS ->> PayeeFSP: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +ALS <<-- PayeeFSP: **HTTP 200** (OK) +deactivate ALS +deactivate PayeeFSP +autonumber resume +Switch <<- PayeeFSP: **Post /transactionRequests**\n(Payee information, transaction details) +activate PayeeFSP +activate Switch +autonumber stop +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate PayerFSP +autonumber stop +PayerFSP -->> Switch: **HTTP 202** (Accepted) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +autonumber stop +activate Switch +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +autonumber stop +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +deactivate Switch +autonumber resume +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /quotes**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + autonumber resume + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quotes/**\n(Payee FSP fee/commission,condition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP\nfee/commission,condition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on the fee model) +Payer <- PayerFSP: Will you approve the\ntransaction request\nfor 100 USD\n(plus fees)\nto Payee? +deactivate PayerFSP +Alt #OldLace Alternatives + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + autonumber resume + Payer -> PayerFSP: I reject the\ntransaction request + activate PayerFSP + PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Rejected state) + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate PayerFSP + autonumber resume + Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Rejected state) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayeeFSP -> Payee: Transaction failed\ndue to user\nrejection + deactivate PayeeFSP + autonumber stop +else + hnote over of Payer #OldLace + User approves + transaction request + end hnote + Payer -> PayerFSP: I approve the\ntransaction request + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer\nFSP to Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account + group #LightGrey Optional + hnote over PayerFSP #LightGrey + Get transaction data + end hnote + autonumber resume + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch ->> PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Looksup transaction\ninformation + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + end + autonumber resume + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure65.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure65.svg new file mode 100644 index 000000000..e606726df --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure65.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + [1] + I would like + to receive + 100 USD from + +123456789 + + + + + [2] + Payer not + within Payee + FSP system + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + [3] + Lookup which FSP MSISDN + +123456789 belongs to + + + + [4] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [5] + Post /transactionRequests + (Payee information, transaction details) + + + + HTTP 202 + (Accepted) + + + + [6] + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + [7] + Perform optional validation + + + + [8] + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + [9] + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + [10] + Rate Payer FSP quote + (depending on fee model) + + + + [11] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [12] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + PUT /quotes/ + <ID> + (Payee FSP fee/commission,condition) + + + + HTTP 200 + (OK) + + + + [15] + PUT /quotes/ + <ID> + (Payee FSP + fee/commission,condition) + + + + HTTP 200 + (OK) + + + + + [16] + Rate Payer FSP quote + (depending on the fee model) + + + [17] + Will you approve the + transaction request + for 100 USD + (plus fees) + to Payee? + + + alt + [Alternatives] + + User rejects + transaction request + + + [18] + I reject the + transaction request + + + + [19] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + [20] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + [21] + Transaction failed + due to user + rejection + + + User approves + transaction request + + + I approve the + transaction request + + + + + [22] + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [23] + Reserve transfer + from Payer + FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [24] + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + [25] + Transaction + notification + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [26] + Commit transfer + from Payer FSP + to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [27] + Commit transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction data + + + + [28] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + [29] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + [30] + Looksup transaction + information + + + + [31] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + [32] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + [33] + Transaction + notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure65a.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure65a.plantuml new file mode 100644 index 000000000..86398225a --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure65a.plantuml @@ -0,0 +1,234 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee Initiated Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Payer not\nwithin Payee\nFSP system +autonumber stop +ALS <<- PayeeFSP: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +autonumber resume +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS ->> PayeeFSP: **Returns Participant Information**\n(FSP ID) +deactivate ALS +deactivate PayeeFSP +Switch <<- PayeeFSP: **Perform Transaction Request**\n(Payee information, transaction details) +activate PayeeFSP +activate Switch +PayerFSP <<- Switch: **Perform Transaction Request**\n(Payee information,\ntransaction details) +deactivate Switch +activate PayerFSP +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Received status) +activate Switch +deactivate PayerFSP +Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Received status) +deactivate PayeeFSP +deactivate Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction detail) +activate Switch +autonumber resume +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commission,condition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP\nfee/commission,condition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on the fee model) +Payer <- PayerFSP: Will you approve\ntransaction\nrequest for\n100 USD(plusfees)\nto Payee? +deactivate PayerFSP +Alt #OldLace Alternatives + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + Payer -> PayerFSP: I reject the\ntransaction request + activate PayerFSP + PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Rejected state) + deactivate PayerFSP + activate Switch + Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Rejected state) + deactivate Switch + activate PayeeFSP + PayeeFSP -> Payee: Transaction failed\ndue to user\nrejection + deactivate PayeeFSP + autonumber stop +else + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + Payer -> PayerFSP: I approve the\ntransaction request + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer\nFSP to Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate PayeeFSP + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **Retrun Transfer Information**\n(Fulfilment) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account + group #LightGrey Optional + hnote over PayerFSP #LightGrey + Get transaction data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch ->> PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Looksup transaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction detail) + deactivate PayeeFSP + PayerFSP <<- Switch: **Return Transaction Information**\n(Transaction detail) + deactivate Switch + end + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +autonumber stop +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure65a.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure65a.svg new file mode 100644 index 000000000..cb9409cac --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure65a.svg @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + [1] + I would like + to receive + 100 USD from + +123456789 + + + + + [2] + Payer not + within Payee + FSP system + + + + Lookup Participant Information + (MSISDN 123456789) + + + + + [3] + Lookup which FSP MSISDN + +123456789 belongs to + + + + [4] + Returns Participant Information + (FSP ID) + + + + [5] + Perform Transaction Request + (Payee information, transaction details) + + + + [6] + Perform Transaction Request + (Payee information, + transaction details) + + + + + [7] + Perform optional validation + + + + [8] + Return Transaction + Request Information + (Received status) + + + + [9] + Return Transaction Request Information + (Received status) + + + + + [10] + Rate Payer FSP quote + (depending on fee model) + + + + Calculate Quote + (Transaction detail) + + + + [11] + Calculate Quote + (Transaction details) + + + + + [12] + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + Return Quote Information + (Payee FSP fee/commission,condition) + + + + [15] + Return Quote Information + (Payee FSP + fee/commission,condition) + + + + + [16] + Rate Payer FSP quote + (depending on the fee model) + + + [17] + Will you approve + transaction + request for + 100 USD(plusfees) + to Payee? + + + alt + [Alternatives] + + User rejects + transaction request + + + [18] + I reject the + transaction request + + + + [19] + Return Transaction + Request Information + (Rejected state) + + + + [20] + Return Transaction Request Information + (Rejected state) + + + [21] + Transaction failed + due to user + rejection + + + User rejects + transaction request + + + I approve the + transaction request + + + + + [22] + Reserve transfer from Payer + account to Switch account + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [23] + Reserve transfer + from Payer + FSP to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [24] + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + [25] + Transaction + notification + + + + Retrun Transfer Information + (Fulfilment) + + + + + [26] + Commit transfer + from Payer FSP + to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + [27] + Commit transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction data + + + + [28] + Retrieve Transaction Information + (Transaction ID) + + + + [29] + Retrieve Transaction Information + (Transaction ID) + + + + + [30] + Looksup transaction + information + + + + [31] + Return Transaction Information + (Transaction detail) + + + + [32] + Return Transaction Information + (Transaction detail) + + + [33] + Transaction + notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure66.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure66.plantuml new file mode 100644 index 000000000..179a4e1b1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure66.plantuml @@ -0,0 +1,346 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' Payee Initiated Transaction using OTP pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Group #Oldlace Option #1 + hnote left of Payer #Oldlace + User + initiated + OTP + end hnote + Payer -> PayerFSP: Generate\nOTP for me + activate PayerFSP + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Your OTP\nis 12345 + deactivate PayerFSP +end +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +autonumber stop +PayeeFSP <- PayeeFSP: MSISDN not within\nPayee FSP system +autonumber resume +ALS <<- PayeeFSP: **GET /participants/MSISDN/123456789** +activate ALS +autonumber stop +ALS -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +ALS <- ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS -> PayeeFSP: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +ALS <<-- PayeeFSP: **HTTP 200** (OK) +deactivate ALS +deactivate PayeeFSP +autonumber resume +Switch <<- PayeeFSP: **POST /transactionRequests**\n(Payee information, transaction details, OTP authorization) +activate PayeeFSP +activate Switch +autonumber stop +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details, OTP authorization) +activate PayerFSP +autonumber stop +PayerFSP -->> Switch: **HTTP 202** (Accepted) +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Put /transactionRequests/**\n(Received status) +autonumber stop +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **Put /transactionRequests/**\n(Received status) +autonumber stop +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /qoutes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202**\n(Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /qoutes**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202**\n(Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #Oldlace Optional + hnote left of PayeeFSP #Oldlace + Confirm + quote + end hnote + autonumber resume + PayeeFSP -> Payee: Her is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Option #2 + hnote left of Payer #Oldlace + Automatic + generated + OTP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Use OTP\nto confirm +end +PayerFSP ->> Switch: **GET /authorizations/**\n(Amount and fees) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **GET /authorizations/**\n(Amount and fees) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> Payee: Show fees\non POS +Payee -> Payee: Payer\napproves/rejects\ntransaction\nusing OTP +autonumber stop +PayeeFSP <<-- Payee: Entered OTP +autonumber resume +Switch <<- PayeeFSP: **PUT /authorizations/**\n(OTP) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /authorizations/**\n(OTP) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Alternatives + hnote left of Payer #Oldlace + OTP + validation + failed + end hnote + autonumber resume + PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Rejected state) + activate PayerFSP + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate PayerFSP + autonumber resume + Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Rejected state) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayeeFSP -> Payee: Transaction\nfailed due to\nincorrect OTP + deactivate PayeeFSP + autonumber stop +else + hnote left of Payer #Oldlace + OTP + validation + successful + end hnote + PayerFSP -[hidden]> Switch + autonumber 33 1 + activate PayerFSP + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition,\nILP packet including transaction ID) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, \nILP packet including transaction ID) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commits transfer from Payer\naccount to Payee FSP account + autonumber stop + PayerFSP -[hidden]> Switch + Group #Lightgrey Optional + hnote left of PayerFSP #Lightgrey + Get transaction + data + end hnote + autonumber resume + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch ->> PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + autonumber resume + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP ->> Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate Switch + end + autonumber resume + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure66.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure66.svg new file mode 100644 index 000000000..10475e8cf --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure66.svg @@ -0,0 +1,568 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + + + + Option #1 + + User + initiated + OTP + + + [1] + Generate + OTP for me + + + + + [2] + Generate OTP + + + [3] + Your OTP + is 12345 + + + [4] + I would like + to receive + 100 USD from + +123456789 + + + + + MSISDN not within + Payee FSP system + + + + [5] + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + [6] + Lookup which FSP MSISDN + +123456789 belongs to + + + [7] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [8] + POST /transactionRequests + (Payee information, transaction details, OTP authorization) + + + + HTTP 202 + (Accepted) + + + + [9] + POST /transactionRequests + (Payee information, + transaction details, OTP authorization) + + + + HTTP 202 + (Accepted) + + + + + [10] + Perform optional validation + + + + [11] + Put /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + [12] + Put /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + [13] + Rate Payer FSP quote + (depending on fee model) + + + + [14] + POST /qoutes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [15] + POST /qoutes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm + quote + + + [16] + Her is the + quote and + Payer name + + + I confirm + + + + [17] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + [18] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + + [19] + Rate Payer FSP quote + (depending on fee model) + + + Option #2 + + Automatic + generated + OTP + + + + + [20] + Generate OTP + + + [21] + Use OTP + to confirm + + + + [22] + GET /authorizations/ + <TransactionRequestID> + (Amount and fees) + + + + HTTP 202 + (Accepted) + + + + [23] + GET /authorizations/ + <TransactionRequestID> + (Amount and fees) + + + + HTTP 202 + (Accepted) + + + [24] + Show fees + on POS + + + + + [25] + Payer + approves/rejects + transaction + using OTP + + + + Entered OTP + + + + [26] + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + [27] + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + + [28] + Validate OTP sent by Payee FSP + + + Alternatives + + OTP + validation + failed + + + + [29] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + [30] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + [31] + Transaction + failed due to + incorrect OTP + + + OTP + validation + successful + + + + + 33 + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, + ILP packet including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + 34 + Reserve transfer + from Payer FSP + to Payee FSP + + + + POST /transfers + (Transfer ID, condition, + ILP packet including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + 35 + Lookup + transaction + information + + + 36 + Transaction + notification + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + 37 + Commit transfer + from Payer FSP + to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + 38 + Commits transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction + data + + + + 39 + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + 40 + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + 41 + Lookup + transaction + information + + + + 42 + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + 43 + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + 44 + Transaction + notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure66a.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure66a.plantuml new file mode 100644 index 000000000..8e944f64d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure66a.plantuml @@ -0,0 +1,288 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee-Initiated Transaction using OTP + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Group #Oldlace Option #1 + hnote left of Payer #Oldlace + User + initiated + OTP + end hnote + Payer -> PayerFSP: Generate\nOTP for me + activate PayerFSP + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Your OTP\nis 12345 + deactivate PayerFSP +end +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +autonumber stop +PayeeFSP <- PayeeFSP: MSISDN not within\nPayee FSP system +autonumber resume +ALS <<- PayeeFSP: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +ALS <- ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS -> PayeeFSP: **Return Participant Information**\n(FSP ID) +deactivate ALS +deactivate PayeeFSP +Switch <<- PayeeFSP: **Perform Transaction Request**\n(Payee information, transaction details, OTP authorization) +activate PayeeFSP +activate Switch +PayerFSP <<- Switch: **Perform Transaction Request**\n(Payee information,\ntransaction details, OTP authorization) +activate PayerFSP +autonumber stop +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Received status) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Received status) +deactivate Switch +deactivate PayeeFSP +autonumber stop +PayerFSP -[hidden]> Switch +activate PayerFSP +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction details) +activate Switch +autonumber resume +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #Oldlace Optional + hnote left of PayeeFSP #Oldlace + Confirm + quote + end hnote + autonumber resume + PayeeFSP -> Payee: Her is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commision, condition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Option #2 + hnote left of Payer #Oldlace + Automatic + generated + OTP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Use OTP\nto confirm +end +PayerFSP ->> Switch: **Perform Authorization**\n(Amount and fees) +activate Switch +Switch ->> PayeeFSP: **Perform Authorization**\n(Amount and fees) +activate PayeeFSP +PayeeFSP -> Payee: Show fees\non POS +Payee -> Payee: Payer\napproves/rejects\ntransaction\nusing OTP +autonumber stop +PayeeFSP <<-- Payee: Entered OTP +autonumber resume +Switch <<- PayeeFSP: **Return Authorization Result**\n(OTP) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Authorization Result**\n(OTP) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Alternatives + hnote left of Payer #Oldlace + OTP + validation + failed + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP ->> Switch: **Return Transaction Request Information**\n(Rejected state) + activate Switch + deactivate PayerFSP + Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Rejected state) + activate PayeeFSP + deactivate Switch + PayeeFSP -> Payee: Transaction\nfailed due to\nincorrect OTP + deactivate PayeeFSP + autonumber stop +else + hnote left of Payer #Oldlace + OTP + validation + successful + end hnote + PayerFSP -[hidden]> Switch + autonumber 33 1 + activate PayerFSP + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, \nILP packet including transaction ID)\n + activate PayeeFSP + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **Return Transfer Information**\n(Fulfilment) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commits transfer from Payer\naccount to Payee FSP account + Group #Lightgrey Optional + hnote left of PayerFSP #Lightgrey + Get transaction + data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch ->> PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction details) + deactivate PayeeFSP + PayerFSP ->> Switch: Return Transaction Information**\n(Transaction details) + deactivate Switch + end + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure66a.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure66a.svg new file mode 100644 index 000000000..25303cb58 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure66a.svg @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + + + + Option #1 + + User + initiated + OTP + + + [1] + Generate + OTP for me + + + + + [2] + Generate OTP + + + [3] + Your OTP + is 12345 + + + [4] + I would like + to receive + 100 USD from + +123456789 + + + + + MSISDN not within + Payee FSP system + + + + [5] + Lookup Participant Information + (MSISDN 123456789) + + + + + [6] + Lookup which FSP MSISDN + +123456789 belongs to + + + [7] + Return Participant Information + (FSP ID) + + + + [8] + Perform Transaction Request + (Payee information, transaction details, OTP authorization) + + + + [9] + Perform Transaction Request + (Payee information, + transaction details, OTP authorization) + + + + + [10] + Perform optional validation + + + + [11] + Return Transaction + Request Information + (Received status) + + + + [12] + Return Transaction Request Information + (Received status) + + + + + [13] + Rate Payer FSP quote + (depending on fee model) + + + + Calculate Quote + (Transaction details) + + + + [14] + Calculate Quote + (Transaction details) + + + + + [15] + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm + quote + + + [16] + Her is the + quote and + Payer name + + + I confirm + + + + [17] + Return Quote Information + (Payee FSP fee/commision, condition) + + + + [18] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + + [19] + Rate Payer FSP quote + (depending on fee model) + + + Option #2 + + Automatic + generated + OTP + + + + + [20] + Generate OTP + + + [21] + Use OTP + to confirm + + + + [22] + Perform Authorization + (Amount and fees) + + + + [23] + Perform Authorization + (Amount and fees) + + + [24] + Show fees + on POS + + + + + [25] + Payer + approves/rejects + transaction + using OTP + + + + Entered OTP + + + + [26] + Return Authorization Result + (OTP) + + + + [27] + Return Authorization Result + (OTP) + + + + HTTP 200 + (OK) + + + + + [28] + Validate OTP sent by Payee FSP + + + Alternatives + + OTP + validation + failed + + + + [29] + Return Transaction Request Information + (Rejected state) + + + + [30] + Return Transaction Request Information + (Rejected state) + + + [31] + Transaction + failed due to + incorrect OTP + + + OTP + validation + successful + + + + + 33 + Reserve transfer from Payer + account to Switch account + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + 34 + Reserve transfer + from Payer FSP + to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, + ILP packet including transaction ID) +   + + + + + 35 + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + 36 + Transaction + notification + + + + Return Transfer Information + (Fulfilment) + + + + + 37 + Commit transfer + from Payer FSP + to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + 38 + Commits transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction + data + + + + 39 + Retrieve Transaction Information + (Transaction ID) + + + + 40 + Retrieve Transaction Information + (Transaction ID) + + + + + 41 + Lookup + transaction + information + + + + 42 + Return Transaction Information + (Transaction details) + + + + 43 + Return Transaction Information** + (Transaction details) + + + 44 + Transaction + notification + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure67.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure67.plantuml new file mode 100644 index 000000000..0576dc323 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure67.plantuml @@ -0,0 +1,222 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Bulk Transactions pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee(s)), Switch and Account Lookup Services (ALS) +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nAccount\nLookup" as ALS +participant "\nPayee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + transaction + in bulk file + end hnote + PayerFSP -> PayerFSP: Locate Payee, if not\nwithin Payer FSP\nuse Account Lookup + PayerFSP ->> ALS: **GET /participants/****/** + activate ALS + autonumber stop + PayerFSP <<-- ALS: **HTTP 202** (Accepted) + autonumber resume + ALS -> ALS: Lookup FSP for\nrequested Type/ID + autonumber stop + PayerFSP ->> ALS: **PUT /participants/****/** + PayerFSP <<-- ALS: **HTTP 200** (OK) + deactivate ALS + autonumber resume + PayerFSP -> PayerFSP: Place transaction\nin bulk file\nper Payee FSP + autonumber stop +end Loop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) + autonumber resume + PayerFSP ->> Switch: **POST /bulkQuotes**\n(Bulk info and list\nof individual quotes) + autonumber stop + activate Switch + autonumber resume + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch ->> PayeeFSP: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + autonumber stop + Switch <<- PayeeFSP: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) +end Loop + +PayerFSP -> PayerFSP: Calculate total fee for Payer +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +deactivate PayerFSP +Payer -> PayerFSP: Execute my bulk +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account + autonumber stop + PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Perform each transaction from\nPayer FSP account to Payee\naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **PUT /bulkTransfers/**\n(List of fulfilments) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + autonumber resume + PayerFSP <<- Switch: **PUT /bulkTransfers/**\n(List of fulfilments) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee FSP account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure67.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure67.svg new file mode 100644 index 000000000..7372a33e3 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure67.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   + Optional + Switch + +   + Account + Lookup + +   + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + + + + + + [1] + I would like to upload + a file of bulk transactions + + + loop + + For each + transaction + in bulk file + + + + + [2] + Locate Payee, if not + within Payer FSP + use Account Lookup + + + + [3] + GET /participants/ + <PartyIdType> + / + <PartyId> + + + + HTTP 202 + (Accepted) + + + + + [4] + Lookup FSP for + requested Type/ID + + + + PUT /participants/ + <PartyIdType> + / + <PartyId> + + + + HTTP 200 + (OK) + + + + + [5] + Place transaction + in bulk file + per Payee FSP + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (depending on fee model) + + + + [6] + POST /bulkQuotes + (Bulk info and list + of individual quotes) + + + + [7] + HTTP 202 + (Accepted) + + + + [8] + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + + [9] + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + [10] + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + + [11] + Rate Payer FSP bulk quote + (depending on fee model) + + + + + [12] + Calculate total fee for Payer + + + [13] + Bulk has finished processing, + present fees + + + [14] + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + [15] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + [16] + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + [17] + Perform each transaction from + Payer FSP account to Payee + account, generate fulfilments + + + [18] + Transaction notification + for each Payee + + + + [19] + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + [20] + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + [21] + Commit each successful + transfer from Payer account + to Payee FSP account + + + [22] + Your bulk has been executed + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure67a.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure67a.plantuml new file mode 100644 index 000000000..9f4ba3a5d --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure67a.plantuml @@ -0,0 +1,200 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Bulk Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee(s)), Switch and Account Lookup Services (ALS) +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nAccount\nLookup" as ALS +participant "\nPayee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + transaction + in bulk file + end hnote + PayerFSP -> PayerFSP: Locate Payee, if not\nwithin Payer FSP\nuse Account Lookup + PayerFSP ->> ALS: **Lookup Participant Information**\n(Payee Party ID Type and Party ID) + activate ALS + ALS -> ALS: Lookup FSP for\nrequested Type/ID + PayerFSP ->> ALS: **Return Participant Information**\n(FSP ID) + autonumber stop + deactivate ALS + PayerFSP -> PayerFSP: Place transaction\nin bulk file\nper Payee FSP + PayerFSP -[hidden]> Switch + deactivate PayerFSP +end Loop +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) + autonumber resume + PayerFSP ->> Switch: **Calculate Bulk Quote**\n(Bulk info and list\nof individual quotes) + Switch ->> PayeeFSP: **Calculate Bulk Quote**\n(Bulk info and list of individual quotes) + activate PayeeFSP + activate Switch + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + autonumber stop + Switch <<- PayeeFSP: **Return Bulk Quote Information**\n(List of individual quote results\nand condition per transfer) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **Return Bulk Quote Information**\n(List of individual quote results\nand condition per transfer) + deactivate Switch + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) +end Loop +autonumber resume +PayerFSP -> PayerFSP: Calculate total fee for Payer +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +deactivate PayerFSP +Payer -> PayerFSP: Execute my bulk +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account +autonumber stop + PayerFSP ->> Switch: **Perform Bulk Transfer**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch +autonumber resume + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Bulk Transfer**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP +autonumber resume + PayeeFSP -> PayeeFSP: Perform each transaction from\nPayer FSP account to Payee\naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **Return Bulk Transfer Information**\n(List of fulfilments) + autonumber stop + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + autonumber resume + PayerFSP <<- Switch: **Return Bulk Transfer Information**\n(List of fulfilments) + deactivate Switch + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee FSP account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure67a.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure67a.svg new file mode 100644 index 000000000..11e7f3675 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure67a.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   + Optional + Switch + +   + Account + Lookup + +   + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + + + + + + [1] + I would like to upload + a file of bulk transactions + + + loop + + For each + transaction + in bulk file + + + + + [2] + Locate Payee, if not + within Payer FSP + use Account Lookup + + + + [3] + Lookup Participant Information + (Payee Party ID Type and Party ID) + + + + + [4] + Lookup FSP for + requested Type/ID + + + + [5] + Return Participant Information + (FSP ID) + + + + + Place transaction + in bulk file + per Payee FSP + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (depending on fee model) + + + + [6] + Calculate Bulk Quote + (Bulk info and list + of individual quotes) + + + + [7] + Calculate Bulk Quote + (Bulk info and list of individual quotes) + + + + + [8] + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + Return Bulk Quote Information + (List of individual quote results + and condition per transfer) + + + + [9] + Return Bulk Quote Information + (List of individual quote results + and condition per transfer) + + + + + [10] + Rate Payer FSP bulk quote + (depending on fee model) + + + + + [11] + Calculate total fee for Payer + + + [12] + Bulk has finished processing, + present fees + + + [13] + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + [14] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + Perform Bulk Transfer + (List of individual transfers + including ILP packet and condition) + + + + + [15] + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + Perform Bulk Transfer + (List of individual transfers + including ILP packet and condition) + + + + + [16] + Perform each transaction from + Payer FSP account to Payee + account, generate fulfilments + + + [17] + Transaction notification + for each Payee + + + + [18] + Return Bulk Transfer Information + (List of fulfilments) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + [19] + Return Bulk Transfer Information + (List of fulfilments) + + + + + [20] + Commit each successful + transfer from Payer account + to Payee FSP account + + + [21] + Your bulk has been executed + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure68.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure68.plantuml new file mode 100644 index 000000000..2acdac867 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure68.plantuml @@ -0,0 +1,64 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Error on server during processing of request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +activate server +client <<-- server: **HTTP 202** (Accepted) +autonumber stop +server -> server: Some processing error\noccurs, i.e. the request\ncan not be handled as\nrequested. +autonumber resume +client <<- server: **PUT /service/****/error** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure68.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure68.svg new file mode 100644 index 000000000..f1b5d40d1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure68.svg @@ -0,0 +1,47 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + [2] + HTTP 202 + (Accepted) + + + + + Some processing error + occurs, i.e. the request + can not be handled as + requested. + + + + [3] + PUT /service/ + <ID> + /error + + + + [4] + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure69.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure69.plantuml new file mode 100644 index 000000000..c1f3ba428 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure69.plantuml @@ -0,0 +1,81 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Handling of error callback from POST /transfers + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch + + +' declare actors +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP + +' start flow +autonumber 1 1 "[0]" +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber resume +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Some processing error occurs,\ne.g. a limit breach +autonumber resume +Switch <<- PayeeFSP: **PUT /transfers/****/error** +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Cancel transfer from\nPayer FSP to Payee FSP +autonumber resume +PayerFSP <<- Switch: **PUT /transfers/****/error**\n(Error information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Cancel transfer from Payer\naccount to Payee FSP account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure69.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure69.svg new file mode 100644 index 000000000..c8e47a23b --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure69.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + + + + + + + [1] + Reserve transfer from Payer + account to Switch account + + + + [2] + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + [3] + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details) + + + + HTTP 202 + (Accepted) + + + + + Some processing error occurs, + e.g. a limit breach + + + + [4] + PUT /transfers/ + <ID> + /error + + + + HTTP 200 + (OK) + + + + + Cancel transfer from + Payer FSP to Payee FSP + + + + [5] + PUT /transfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel transfer from Payer + account to Payee FSP account + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure70.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure70.plantuml new file mode 100644 index 000000000..42f6da819 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure70.plantuml @@ -0,0 +1,81 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Handling of error callback from API Service /bulkTransfers + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch + + +' declare actors +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP + +' start flow +autonumber 1 1 "[0]" +activate PayerFSP +PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account +PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP +autonumber resume +Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Some processing error occurs,\ne.g. a validation failure that prevents\nthe bulk transfer to be performed +autonumber resume +Switch <<- PayeeFSP: **PUT /bulkTransfers/****/error**\n(Error information) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Cancel each reserved\ntransfer from Payer\nFSP to Payee FSP +autonumber resume +PayerFSP <<- Switch: **PUT /bulkTransfers/****/error**\n(Error information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Cancel each transfer\nfrom Payer account\nto Payee FSP account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure70.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure70.svg new file mode 100644 index 000000000..bbdcd79ec --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure70.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + + + + + + + [1] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + [2] + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + [3] + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Some processing error occurs, + e.g. a validation failure that prevents + the bulk transfer to be performed + + + + [4] + PUT /bulkTransfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel each reserved + transfer from Payer + FSP to Payee FSP + + + + [5] + PUT /bulkTransfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel each transfer + from Payer account + to Payee FSP account + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure71.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure71.plantuml new file mode 100644 index 000000000..858f8bca1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure71.plantuml @@ -0,0 +1,70 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Error handling from client using resend of request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +client -> client: Timeout, resend\nservice request +client ->> server: **POST /service** +activate server +client <<-- server: **HTTP 202** (Accepted) +autonumber stop +client -> client: Timeout, resend\nservice request +autonumber resume +client ->> server: **POST /service** +autonumber stop +client <<-- server: **HTTP 202** (Accepted) +autonumber resume +client <<- server: **PUT /service/** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure71.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure71.svg new file mode 100644 index 000000000..155304af7 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure71.svg @@ -0,0 +1,66 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + + [2] + Timeout, resend + service request + + + + [3] + POST /service + + + + [4] + HTTP 202 + (Accepted) + + + + + Timeout, resend + service request + + + + [5] + POST /service + + + + HTTP 202 + (Accepted) + + + + [6] + PUT /service/ + <ID> + + + + [7] + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure72.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure72.plantuml new file mode 100644 index 000000000..6bf57abd8 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure72.plantuml @@ -0,0 +1,67 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke + +hide footbox + +' declare title +' title Error handling from client using GET request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +activate server +client <<-- server: **HTTP 202** (Accepted) +'autonumber stop +client -> client: No update received within\nreasonable time period,\ncheck status +'autonumber resume +client ->> server: **GET /service** +autonumber stop +client <<-- server: **HTTP 202** (Accepted) +autonumber resume +client <<- server: **PUT /service/** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure72.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure72.svg new file mode 100644 index 000000000..148863300 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure72.svg @@ -0,0 +1,57 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + [2] + HTTP 202 + (Accepted) + + + + + [3] + No update received within + reasonable time period, + check status + + + + [4] + GET /service + <ID> + + + + HTTP 202 + (Accepted) + + + + [5] + PUT /service/ + <ID> + + + + [6] + HTTP 200 + (OK) + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure74.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure74.plantuml new file mode 100644 index 000000000..752507fa1 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure74.plantuml @@ -0,0 +1,220 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title End-to-end flow, from provision of account holder FSP information to a successful transaction + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nMats\nHagman" as Payer +participant "\nBank\nNrOne" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nMobile\nMoney" as MM +actor "<$actor>\nHenrik\nKarlsson" as Payee + +' start flow +autonumber 1 1 "[0]" +Switch <<- MM: **POST /participants/MSISDN/123456789**\n(fspid=MobileMoney) +activate Switch +activate MM +autonumber stop +Switch -->> MM: **HTTP 202** (Accepted) +autonumber resume +Switch <<-- Switch: Save FSP information for\nMSISDN 123456789 +Switch ->> MM: **PUT /participants/MSISDN/123456789**\n(fspid=MobileMoney) +autonumber stop +Switch <<-- MM: **HTTP 200** (OK) +deactivate MM +deactivate Switch +autonumber resume +Payer -> PayerFSP: I would like MSISDN +123456789\nto receive 100 USD +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: MSISDN +123456789\nnot within BankNrOne +autonumber resume +PayerFSP ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Lookup which FSP MSISDN\n+123456789 belongs to +autonumber resume +Switch ->> MM: **GET /parties/MSISDN/123456789** +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Lookup party information\nregarding MSISDN +123456789 +autonumber resume +Switch <<- MM: **PUT /Parties/MSISDN/123456789**\n(Party Information) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +autonumber resume +PayerFSP <<- Switch: **PUT /Parties/MSISDN/123456789**\n(Party Information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate PayerFSP +autonumber resume +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE, amount=100) +activate PayerFSP +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> MM: **POST /quotes**\n(amountType=RECEIVE, amount=100) +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Internal rating for fees/commission,\n1 USD in FSP commission, generate\nand store fulfilment, generate\ncondition out of fulfilment +autonumber resume +Switch <<- MM: **PUT /quotes/**\n(transferAmount=99 USD\npayeeFspCommission=1 USD) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD\npayeeFspCommission=1 USD) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: BankNrOne keeps commission as\nfee, transaction is free for Mats +autonumber resume +Payer <- PayerFSP: Transferring 100 USD to Henrik\nKarlsson will cost 0 USD in fees +deactivate PayerFSP +Payer -> PayerFSP: I approve the transaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve 100 USD from Mats\nHagman's account,\n99 USD to Switch and\n1 USD to FSP commission +autonumber resume +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD, PayerFsp=BankNrOne\npayeeFsp=MobileMoney) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from\nBankNrOne to MobileMoney +autonumber resume +Switch ->> MM: **POST /transfers**\n(amount=99 USD, PayerFsp=BankNrOne\npayeeFsp=MobileMoney) +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Perform transfer of 100 USD to\nHenrik Karlsson's account,\n99 USD from Switch\naccount, and 1 USD from FSP\ncommission account +autonumber resume +MM -> MM: Retrieve fulfilment +MM -> Payee: You have received 100 USD\nfrom Mats Hagman +Switch <<- MM: **PUT /transfers/**\n(Fulfilment) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +Switch -> Switch: Commit transfer from\nBankNrOne to MobileMoney +autonumber resume +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit transfer from Mats\nHagman's account to\nSwitch account +autonumber resume +Payer <- PayerFSP: You have transferred 100 USD\nto Henrik Karlsson +autonumber stop +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure74.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure74.svg new file mode 100644 index 000000000..0d00d55c4 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure74.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mats + Hagman + + + +   + Bank + NrOne + +   +   + Switch + +   + Mobile + Money + + Henrik + Karlsson + + + + + + + + + + + + + + + + + [1] + POST /participants/MSISDN/123456789 + (fspid=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + + [2] + Save FSP information for + MSISDN 123456789 + + + + [3] + PUT /participants/MSISDN/123456789 + (fspid=MobileMoney) + + + + HTTP 200 + (OK) + + + [4] + I would like MSISDN +123456789 + to receive 100 USD + + + + + MSISDN +123456789 + not within BankNrOne + + + + [5] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to + + + + [6] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party information + regarding MSISDN +123456789 + + + + [7] + PUT /Parties/MSISDN/123456789 + (Party Information) + + + + HTTP 200 + (OK) + + + + [8] + PUT /Parties/MSISDN/123456789 + (Party Information) + + + + HTTP 200 + (OK) + + + + [9] + POST /quotes + (amountType=RECEIVE, amount=100) + + + + HTTP 202 + (Accepted) + + + + [10] + POST /quotes + (amountType=RECEIVE, amount=100) + + + + HTTP 202 + (Accepted) + + + + + Internal rating for fees/commission, + 1 USD in FSP commission, generate + and store fulfilment, generate + condition out of fulfilment + + + + [11] + PUT /quotes/ + <ID> + (transferAmount=99 USD + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + [12] + PUT /quotes/ + <ID> + (transferAmount=99 USD + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + BankNrOne keeps commission as + fee, transaction is free for Mats + + + [13] + Transferring 100 USD to Henrik + Karlsson will cost 0 USD in fees + + + [14] + I approve the transaction + + + + + Reserve 100 USD from Mats + Hagman's account, + 99 USD to Switch and + 1 USD to FSP commission + + + + [15] + POST /transfers + (amount=99 USD, PayerFsp=BankNrOne + payeeFsp=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from + BankNrOne to MobileMoney + + + + [16] + POST /transfers + (amount=99 USD, PayerFsp=BankNrOne + payeeFsp=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer of 100 USD to + Henrik Karlsson's account, + 99 USD from Switch + account, and 1 USD from FSP + commission account + + + + + [17] + Retrieve fulfilment + + + [18] + You have received 100 USD + from Mats Hagman + + + + [19] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + BankNrOne to MobileMoney + + + + [20] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from Mats + Hagman's account to + Switch account + + + [21] + You have transferred 100 USD + to Henrik Karlsson + + diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure8.plantuml b/docs/fr/technical/api/assets/diagrams/sequence/figure8.plantuml new file mode 100644 index 000000000..69a6186af --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure8.plantuml @@ -0,0 +1,135 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} +hide footbox + +' declare title +' title Example of non-disclosing receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to Payee to\nreceive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVED,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or\ncommission for handeling\ntransaction in Payee FSP => \nFSP commission 1 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Keep commission\nfee for Payer for\nhandling transaction in\nPayer FSP => total fee 1 USD +PayerFSP ->> Payer: Sending 100 USD to Payee\nwill cost 1 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/fr/technical/api/assets/diagrams/sequence/figure8.svg b/docs/fr/technical/api/assets/diagrams/sequence/figure8.svg new file mode 100644 index 000000000..7ffa03a23 --- /dev/null +++ b/docs/fr/technical/api/assets/diagrams/sequence/figure8.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to Payee to + receive 100 USD + + + + POST /quotes + (amountType=RECEIVED, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or + commission for handeling + transaction in Payee FSP => + FSP commission 1 USD + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + + + + HTTP 200 + (OK) + + + + + Keep commission + fee for Payer for + handling transaction in + Payer FSP => total fee 1 USD + + + + Sending 100 USD to Payee + will cost 1 USD in fees + + diff --git a/docs/fr/technical/api/assets/figure1-platforms-layout.svg b/docs/fr/technical/api/assets/figure1-platforms-layout.svg new file mode 100644 index 000000000..8a12de358 --- /dev/null +++ b/docs/fr/technical/api/assets/figure1-platforms-layout.svg @@ -0,0 +1,3 @@ + + +
CA
CA
ALS
ALS
FSP-1
FSP-1
FSP-2
FSP-2
Switch
Switch
FSP-3
FSP-3
FSP-4
FSP-4
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Issuer: CN=CA
O=CA
Subject: CN=CA
O=CA
Issuer: CN=CA...
Legend:
Solid lines indicate TLS-secured communication.
Dashed lines indicate certificate owner.
Legend:...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/fr/technical/api/assets/scheme-rules-figure-1-http-timeout.png b/docs/fr/technical/api/assets/scheme-rules-figure-1-http-timeout.png new file mode 100644 index 000000000..9d3faf74e Binary files /dev/null and b/docs/fr/technical/api/assets/scheme-rules-figure-1-http-timeout.png differ diff --git a/docs/fr/technical/api/assets/scheme-rules-figure-2-callback-timeout.png b/docs/fr/technical/api/assets/scheme-rules-figure-2-callback-timeout.png new file mode 100644 index 000000000..04f5da996 Binary files /dev/null and b/docs/fr/technical/api/assets/scheme-rules-figure-2-callback-timeout.png differ diff --git a/docs/fr/technical/api/assets/sequence-diagram-figure-1.png b/docs/fr/technical/api/assets/sequence-diagram-figure-1.png new file mode 100644 index 000000000..53215785d Binary files /dev/null and b/docs/fr/technical/api/assets/sequence-diagram-figure-1.png differ diff --git a/docs/fr/technical/api/fspiop/README.md b/docs/fr/technical/api/fspiop/README.md new file mode 100644 index 000000000..01fa41daa --- /dev/null +++ b/docs/fr/technical/api/fspiop/README.md @@ -0,0 +1,28 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# API FSPIOP + +La spécification Open API pour l’interopérabilité des FSP inclut les documents suivants : + +## Documents Logiques + +* [Modèle de Données Logique](./logical-data-model.md) +* [Modèles de Transactions Génériques](./generic-transaction-patterns.md) +* [Cas d’Utilisation](./use-cases.md) + +## Documents de Liaison REST Asynchrone + +* Définition de l’API + * [FSPIOP v1.1](./v1.1/api-definition.md) + * [FSPIOP v1.0](./v1.0/api-definition.md) +* [API Central Ledger](#central-ledger-api) +* [Règles de Liaison JSON](#json-binding-rules) +* [Règles du système](./scheme-rules.md) + +## Intégrité des Données, Confidentialité et Non-Répudiation + +* [Bonnes Pratiques PKI](./pki-best-practices.md) +* [Signature](./v1.1/signature.md) +* [Chiffrement](./v1.1/encryption.md) diff --git a/docs/fr/technical/api/fspiop/definitions.md b/docs/fr/technical/api/fspiop/definitions.md new file mode 100644 index 000000000..3ca5ba8c7 --- /dev/null +++ b/docs/fr/technical/api/fspiop/definitions.md @@ -0,0 +1,13 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# API FSPIOP + +## Versions + +|Version|Date|Description des changements| +|---|---|---| +|[1.0](./v1.0/api-definition)|2018-03-13|Version initiale| +|[1.1](./v1.1/api-definition)|2020-05-19|1. Cette version comprend une nouvelle option pour qu'un FSP du Bénéficiaire demande une notification de confirmation auprès du Switch. Le Switch doit alors envoyer la notification de confirmation en utilisant la nouvelle requête **PATCH /transfers/**_{ID}_. L’option d’utiliser la notification de confirmation remplace l’ancienne option de « Vérification de compensation additionnelle facultative ». La section décrivant cela a été remplacée par la nouvelle section « Notification de confirmation ». Comme la ressource **transfers** a été mise à jour avec la nouvelle requête **PATCH**, cette ressource est passée à la version 1.1. Dans le cadre de l’ajout de la possibilité d’utiliser une notification de confirmation, les changements suivants ont été apportés :
a. PATCH a été ajouté comme méthode HTTP autorisée dans la Section 3.2.2. b. Le déroulement de l’appel pour **PATCH** est décrit en Section 3.2.3.5.
c. Le Tableau 6 en Section 6.1.1 a été mis à jour pour inclure **PATCH** comme méthode HTTP possible.
d. La Section 6.7.1 contient la nouvelle version de la ressource **transfers**.
e. La Section 6.7.2.6 décrit le processus d’utilisation des notifications de confirmation.
f. La Section 6.7.3.3 décrit la nouvelle requête **PATCH /transfers**/_{ID}_.

2. En plus des changements mentionnés ci-dessus concernant la notification de confirmation, les modifications suivantes n’affectant pas l’API ont été effectuées :
a. La Figure 6 a été corrigée car elle contenait une erreur de copier-coller.
b. Ajout de la Section 6.1.2 pour décrire une vue complète de la version actuelle de chaque ressource.
c. Ajout d’une section pour chaque ressource permettant de consulter l’historique des versions de la ressource.
d. Corrections éditoriales mineures.

3. Les descriptions de deux champs d’en-tête HTTP dans le Tableau 1 ont été mises à jour afin d’apporter plus de précisions et de contextes.
a. La description du champ d’en-tête **FSPIOP-Destination** a été mise à jour pour indiquer qu’il doit être laissé vide si la destination n’est pas connue de l’expéditeur initial, mais dans tous les autres cas, il doit être ajouté par l’expéditeur initial d’une requête.
b. La description du champ d’en-tête **FSPIOP-URI** a été rendue plus spécifique.

4. Les exemples utilisés dans ce document ont été actualisés pour utiliser la bonne interprétation du type complexe ExtensionList tel que défini dans le Tableau 84. Ceci n’implique pas de changement en tant que tel.
a. La Liste 5 a été mise à jour en ce sens.

5. Le modèle de données a été mis à jour pour ajouter un élément optionnel ExtensionList au type complexe **PartyIdInfo** sur la base de la Demande de modification : https://github.com/mojaloop/mojaloop-specification/issues/30. Suite à cela, le modèle de données tel que spécifié dans le Tableau 103 a été mis à jour. Pour la cohérence, le modèle de données pour les appels **POST /participants/**_{Type}/{ID}_ et **POST /participants/**_{Type}/{ID}/{SubId}_ dans le Tableau 10 a été également mis à jour pour inclure l’élément ExtensionList optionnel.

6. Une nouvelle Section 6.5.2.2 est ajoutée pour décrire le processus impliqué dans le rejet d’un devis.

7. Une note a été ajoutée à la Section 6.7.4.1 pour clarifier l’utilisation de l’état ABORTED dans les retours d’appel **PUT /transfers/**_{ID}_.| +|**1.1.1**|2021-09-22|Cette version du document ajoute uniquement des informations concernant les en-têtes HTTP optionnels supportant la traçabilité dans le [Tableau 2](#table-2), voir _Support de la traçabilité distribuée pour OpenAPI Interoperability_ pour plus d’informations. Il n'y a aucun changement dans les ressources dans cette version.| \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/generic-transaction-patterns.md b/docs/fr/technical/api/fspiop/generic-transaction-patterns.md new file mode 100644 index 000000000..271ee17b8 --- /dev/null +++ b/docs/fr/technical/api/fspiop/generic-transaction-patterns.md @@ -0,0 +1,494 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# Modèles de Transactions Génériques + +## Préface + +Cette section contient des informations sur la manière d'utiliser ce document. + +### Conventions Utilisées dans Ce Document + +Les conventions suivantes sont utilisées dans ce document pour identifier les différents types d’information : + +|Type d’Information|Convention|Exemple| +|---|---|---| +|**Éléments de l’API, comme les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans le _Glossaire_|L'objectif de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateurs ne devraient généralement pas être utilisées par les déploiements d’API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ doivent être employées.| + +### Informations sur la Version du Document + +|Version|Date|Description des modifications| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| + +
+ +## Introduction + +Ce document présente les quatre modèles de transactions génériques pris en charge dans une version logique de l’API d’Interopérabilité. De plus, tous les services logiques faisant partie de l’API sont présentés dans les grandes lignes. + +### Spécification Open API pour l'Interopérabilité des FSP + +La spécification Open API pour l’interopérabilité des FSP inclut les documents suivants. + +#### Documents Logiques + +- [Modèle de Données Logique](#) + +- [Modèles de Transactions Génériques](./generic-transaction-patterns) + +- [Cas d’Utilisation](./use-cases) + +#### Documents de Liaison REST Asynchrone + +- [Définition de l’API](./api-definition) + +- [Règles de Liaison JSON](./json-binding-rules) + +- [Règles du scheme](./scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents Généraux + +- [Glossaire](./glossary) + +
+ +## Services logiques de l’API + +L’API d’Interopérabilité se compose de plusieurs ressources d’API logiques. Chaque ressource définit un ou plusieurs services utilisables par les clients pour se connecter à un serveur ayant implémenté l’API. Cette section présente ces services. + +**Note:** Les services API identifiés dans cette section peuvent ne pas s’appliquer (et donc ne pas apparaître) dans les modèles de transactions génériques identifiés dans [Modèles de Transactions Génériques](#generic-transaction-patterns). + +Par exemple, certains services servent à la fourniture d'informations, font partie des cas d'erreurs ou servent à la récupération d'informations non nécessaires dans un modèle de transaction générique. + +
+ +### Fonctionnalités Communes + +Cette section présente des fonctionnalités utilisées par plusieurs ressources ou services logiques de l'API. + +#### Adressage des parties + +Une Partie est une entité telle qu’un individu, une entreprise, une organisation ayant un compte financier dans un des FSPs. Une partie est identifiée par une combinaison d’un _Type d’ID_ et d’un _ID_, et éventuellement aussi par un _sous-type_ ou un _sous-ID_. Quelques exemples de combinaisons _Type d’ID_ et _ID_ : + +- _Type d’ID_ : **MSISDN**, _ID_ : **+123456789** + +- _Type d’ID_ : **Email**, _ID_ : **john@doe.com** + +#### Interledger + +L’API inclut une prise en charge de base du protocole Interledger (ILP) en définissant une mise en œuvre concrète du protocole « Interledger Payment Request »[1](https://interledger.org/rfcs/0011-interledger-payment-request)(ILP) dans les ressources logiques **Devis** et **Transferts**. Plus de détails sur le protocole ILP sont disponibles sur le site du projet Interledger[2](https://interledger.org), dans le livre blanc Interledger[3](https://interledger.org/interledger.pdf) et dans la spécification d’architecture Interledger[4](https://interledger.org/rfcs/0001-interledger-architecture). + +
+ +### Ressource API Participants + +Dans l’API, un _Participant_ est l’équivalent d’un FSP qui participe à un scheme d’interopérabilité. L’objectif principal de la ressource API logique **Participants** est de permettre aux FSPs de savoir dans quel autre FSP se situe une contrepartie dans une transaction financière interopérable. Il existe également des services définis pour que les FSPs puissent fournir des informations à un système commun. + +#### Requêtes + +Cette section identifie les requêtes de services de l’API logique qui peuvent être envoyées d’un client à un serveur. + +##### Recherche d’Informations sur un Participant + +La requête logique `Recherche d’Informations sur un Participant` est utilisée par un FSP pour demander à un autre système (qui peut être un autre FSP ou un système commun) des informations concernant dans quel FSP se situe une contrepartie dans une transaction financière interopérable. + +- Réponse en cas de succès : [Retour des informations sur le participant](#return-participant-information) + +- Réponse en cas d’erreur : [Erreur de retour des informations sur le participant](#return-participant-information-error) + +##### Création d’Informations sur un Participant + +La requête logique `Création d’Informations sur un Participant` est utilisée pour fournir des informations sur le FSP dans lequel se trouve une partie. + +- Réponse en cas de succès : [Retour des informations sur le participant](#return-participant-information) + +- Réponse en cas d’erreur : [Erreur de retour des informations sur le participant](#return-participant-information-error) + +##### Création d’informations groupées sur les participants + +La requête logique `Création d’informations groupées sur les participants` est utilisée pour fournir des informations sur le(s) FSP(s) dans le(s)quel(s) se trouvent une ou plusieurs parties. + +- Réponse en cas de succès : [Retour des informations groupées sur les participants](#return-bulk-participant-information) + +- Réponse en cas d’erreur : [Erreur de retour des informations groupées sur les participants](#return-bulk-participant-information-error) + +##### Suppression d’Informations sur un Participant + +La requête logique `Suppression d’Informations sur un Participant` est utilisée pour retirer des informations concernant le FSP dans lequel se trouve une partie. + +- Réponse en cas de succès : [Retour des informations sur le participant](#return-participant-information) + +- Réponse en cas d’erreur : [Erreur de retour des informations sur le participant](#return-participant-information-error) + +
+ +#### Réponses + +Cette section identifie les réponses de service logique de l’API pouvant être renvoyées à un client par un serveur. + +##### Retour des informations sur le participant + +Réponse utilisée pour retourner des informations suite aux requêtes [Recherche d’Informations sur un Participant](#lookup-participant-information), [Création d’Informations sur un Participant](#create-participant-information) et [Suppression d’Informations sur un Participant](#delete-participant-information). + +##### Retour des informations groupées sur les participants + +Réponse utilisée pour retourner les informations suite à la requête [Création d’informations groupées sur les participants](#create-bulk-participant-information). + +
+ +#### Réponses d’Erreur + +Cette section identifie les réponses d’erreur pouvant être renvoyées à un client par un serveur. + +##### Erreur de retour des informations sur le participant + +Réponse d’erreur utilisée en cas de problème lors des requêtes [Recherche d’Informations sur un Participant](#lookup-participant-information), [Création d’Informations sur un Participant](#create-participant-information) et [Suppression d’Informations sur un Participant](#delete-participant-information). + +##### Erreur de retour des informations groupées sur les participants + +Réponse d’erreur utilisée en cas de problème lors de la requête [Création d’informations groupées sur les participants](#create-bulk-participant-information). + +
+ +### Ressource API Parties + +Dans l’API, une _Partie_ est un individu, une entreprise, une organisation ou une entité similaire possédant un compte financier dans l’un des FSP. L’objectif principal de la ressource API logique **Parties** est de permettre aux FSP de récupérer des informations sur une contrepartie dans une transaction interopérable (nom, date de naissance, etc.). + +#### Requêtes + +##### Recherche d’Informations sur une Partie + +La requête logique `Recherche d’Informations sur une Partie` est utilisée par un FSP pour demander à un autre FSP des informations concernant une contrepartie dans une transaction financière interopérable. + +- Réponse en cas de succès : [Retour des informations sur la partie](#return-party-information) + +- Réponse en cas d’erreur : [Retour d'erreur sur les informations de la partie](#return-party-information-error) + +
+ +#### Réponses + +##### Retour des informations sur la partie + +Réponse utilisée pour retourner des informations suite à la requête [Recherche d’Informations sur une Partie](#lookup-party-information). + +
+ +#### Réponses d’Erreur + +##### Retour d'erreur sur les informations de la partie + +Réponse d’erreur utilisée pour retourner des informations d’erreur suite à la requête [Recherche d’Informations sur une Partie](#lookup-party-information). + +
+ +### Ressource API : demandes de transaction + +Dans l’API, une _Demande de Transaction_ est une demande d’un Bénéficiaire vers un Payeur pour transférer des fonds électroniques au Bénéficiaire, que le Payeur peut accepter ou refuser. L’objectif de la ressource logique **Demandes de transaction** est qu’un FSP du bénéficiaire envoie la demande de transfert au FSP du payeur. + +#### Requêtes + +##### Effectuer une demande de transaction + +La requête `Effectuer une demande de transaction` sert à envoyer une demande de transfert d’un FSP bénéficiaire vers un FSP payeur, c’est-à-dire à demander si le payeur accepte ou refuse la transaction. + +- Réponse en cas de succès : [Retour des informations sur la demande de transaction](#return-transaction-request-information) + +- Réponse en cas d’erreur : [Erreur de retour de la demande de transaction](#return-transaction-request-information-error) + +##### Récupérer des Informations sur une Demande de Transaction + +Cette requête est envoyée du FSP du bénéficiaire vers le FSP du payeur pour récupérer des informations sur une demande antérieure. + +- Réponse en cas de succès : [Retour des informations sur la demande de transaction](#return-transaction-request-information) + +- Réponse en cas d’erreur : [Erreur de retour de la demande de transaction](#return-transaction-request-information-error) + +
+ +#### Réponses + +##### Retour des informations sur la demande de transaction + +Réponse utilisée pour retourner des informations suite aux requêtes [Effectuer une demande de transaction](#perform-transaction-request) ou [Récupérer des Informations sur une Demande de Transaction](#retrieve-transaction-request-information). + +
+ +#### Réponses d’Erreur + +##### Erreur de retour de la demande de transaction + +Réponse d’erreur utilisée pour retourner des informations d’erreur concernant les requêtes [Effectuer une demande de transaction](#perform-transaction-request) ou [Récupérer des Informations sur une Demande de Transaction](#retrieve-transaction-request-information). + +
+ +### Ressource API Devis + +Dans l’API, un _Devis_ représente le prix pour effectuer une transaction financière interopérable entre un FSP payeur et un FSP bénéficiaire. L’objectif principal de la ressource logique **Devis** est que le FSP payeur demande au FSP bénéficiaire de calculer sa part du devis. + +#### Requêtes + +##### Calculer un devis + +La requête `Calculer un devis` est envoyée par un FSP payeur pour demander au FSP bénéficiaire de calculer sa part du devis. Le FSP bénéficiaire devrait aussi générer le paquet ILP et la condition (voir [Interledger](#interledger)) à la réception de la demande. + +- Réponse en cas de succès : [Retour des informations sur le devis](#return-quote-information) + +- Réponse en cas d’erreur : [Erreur de retour du devis](#return-quote-information-error) + +
+ +##### Récupérer des Informations sur un Devis + +Cette requête permet au FSP payeur de demander des informations sur un devis déjà émis. + +- Réponse en cas de succès : [Retour des informations sur le devis](#return-quote-information) + +- Réponse en cas d’erreur : [Erreur de retour du devis](#return-quote-information-error) + +
+ +#### Réponses + +##### Retour des informations sur le devis + +Réponse utilisée pour retourner des informations suite aux requêtes [Calculer un devis](#calculate-quote) ou [Récupérer des Informations sur un Devis](#retrieve-quote-information). + +
+ +#### Réponses d’Erreur + +##### Erreur de retour du devis + +Réponse d’erreur utilisée pour retourner des informations d’erreur concernant les requêtes [Calculer un devis](#calculate-quote) ou [Récupérer des Informations sur un Devis](#retrieve-quote-information). + +
+ +### Ressource API Autorisations + +Dans l’API, une _Autorisation_ est une approbation d’un payeur pour effectuer une transaction interopérable par saisie des identifiants applicables dans le système FSP du bénéficiaire. Exemple : un payeur effectuant une opération sur un DAB géré par un autre FSP. L’objectif principal de la ressource logique **Autorisations** est que le FSP payeur demande au FSP bénéficiaire de solliciter la saisie des identifiants au payeur. + +#### Requêtes + +##### Exécuter une Autorisation + +La requête `Exécuter une Autorisation` est envoyée par un FSP payeur au FSP bénéficiaire pour demander la saisie des identifiants permettant d’approuver la transaction interopérable. + +- Réponse en cas de succès : [Retour du résultat d'autorisation](#return-authorization-result) + +- Réponse en cas d’erreur : [Retour d'erreur d'autorisation](#return-authorization-error) + +
+ +#### Réponses + +##### Retour du résultat d'autorisation + +Réponse utilisée pour retourner des informations suite à la requête [Exécuter une Autorisation](#perform-authorization). + +
+ +#### Réponses d’Erreur + +##### Retour d'erreur d'autorisation + +Réponse d’erreur utilisée pour retourner les erreurs concernant la requête [Exécuter une Autorisation](#perform-authorization). + +
+ +### Ressource API Transferts + +Dans l’API, un _Transfert_ désigne un transfert de fonds hop-to-hop via ILP (voir [Interledger](#interledger) pour plus d’informations). + +Le transfert contient également des informations sur la transaction interopérable de bout en bout. L’objectif principal de la ressource logique **Transferts** est qu’un FSP ou le Switch demande au prochain acteur de la chaîne ILP d’effectuer le transfert. + +#### Requêtes + +##### Effectuer un Transfert + +La requête `Effectuer un Transfert` permet à un FSP ou au Switch de demander au prochain acteur de la chaîne de réserver le transfert correspondant à la transaction. + +- Réponse en cas de succès : [Retour des informations sur le transfert](#return-transfer-information) + +- Réponse en cas d’erreur : [Erreur de retour du transfert](#return-transfer-information-error) + +##### Récupérer des Informations sur un Transfert + +Permet de demander au prochain acteur des informations concernant le transfert concerné. + +- Réponse en cas de succès : [Retour des informations sur le transfert](#return-transfer-information) + +- Réponse en cas d’erreur : [Erreur de retour du transfert](#return-transfer-information-error) + +
+ +#### Réponses + +##### Retour des informations sur le transfert + +Réponse utilisée pour retourner des informations suite aux requêtes [Effectuer un Transfert](#perform-transfer) ou [Récupérer des Informations sur un Transfert](#retrieve-transfer-information). Suite à la réception de cette réponse, le FSP ou Switch doit valider l’exécution (voir [Interledger](#interledger)) et valider le transfert réservé si la validation est positive. + +
+ +#### Réponses d’Erreur + +##### Erreur de retour du transfert + +Réponse d’erreur utilisée pour retourner des erreurs liées aux requêtes [Effectuer un Transfert](#perform-transfer) ou [Récupérer des Informations sur un Transfert](#retrieve-transfer-information). + +
+ +### Ressource API Transactions + +Dans l’API, une _Transaction_ est une transaction financière interopérable de bout en bout entre le FSP du payeur et celui du bénéficiaire. L’objectif principal de la ressource logique **Transactions** est que le FSP payeur demande des informations de bout en bout au FSP bénéficiaire, par exemple pour obtenir un code ou un jeton à utiliser pour retirer un service ou un produit. + +### Requêtes + +Permet d’identifier les requêtes de services API logiques pouvant être envoyées d’un client à un serveur. + +##### Récupérer des Informations sur une Transaction + +La requête `Récupérer des Informations sur une Transaction` permet au FSP payeur de demander au FSP bénéficiaire des informations sur une transaction effectuée précédemment (en utilisant la ressource logique **Transferts**, voir [API Ressource Transferts](#api-resource-transfers)). + +- Réponse en cas de succès : [Retour des informations sur le transfert](#return-transfer-information) + +- Réponse en cas d’erreur : [Erreur de retour du transfert](#return-transfer-information-error) + +
+ +#### Réponses + +##### Retour des informations sur la transaction + +Réponse utilisée pour retourner des informations suite à la requête [Récupérer des Informations sur un Transfert](#retrieve-transfer-information). + +
+ +#### Réponses d’Erreur + +##### Erreur de retour des informations sur la transaction + +Réponse d’erreur utilisée pour retourner des erreurs liées à la requête [Récupérer des Informations sur un Transfert](#retrieve-transfer-information). + +
+ +### Ressource API : devis groupés + +Dans l’API, un _devis groupé_ désigne un ensemble de devis individuels (voir la section [Ressource API Devis](#api-resource-quotes)) pour effectuer plusieurs transactions interopérables de FSP payeur à FSP bénéficiaire. + +L’objectif principal de la ressource **Devis groupés** est que le FSP payeur demande au FSP bénéficiaire de calculer sa part du devis groupé. + +#### Requêtes + +##### Calculer un devis groupé + +La requête `Calculer un devis groupé` est utilisée par un FSP payeur pour demander au FSP bénéficiaire de calculer sa part du devis pour effectuer plusieurs transactions interopérables. + +Le FSP bénéficiaire devrait aussi générer le paquet ILP et la condition pour chaque devis. + +- Réponse en cas de succès : [Retour des informations sur le devis groupé](#return-bulk-quote-information) + +- Réponse en cas d’erreur : [Erreur de retour du devis groupé](#return-bulk-quote-information-error) + +##### Récupérer des informations sur un devis groupé + +Permet à un FSP payeur de demander à un FSP bénéficiaire des informations sur un devis groupé précédemment envoyé. + +- Réponse en cas de succès : [Retour des informations sur le devis groupé](#return-bulk-quote-information) + +- Réponse en cas d’erreur : [Erreur de retour du devis groupé](#return-bulk-quote-information-error) + +
+ +#### Réponses + +##### Retour des informations sur le devis groupé + +Réponse utilisée pour retourner des informations suite aux requêtes [Calculer un devis groupé](#calculate-bulk-quote) ou [Récupérer des informations sur un devis groupé](#retrieve-bulk-quote-information). + +
+ +#### Réponses d’Erreur + +##### Erreur de retour du devis groupé + +Réponse d’erreur utilisée pour retourner des erreurs liées aux requêtes [Calculer un devis groupé](#calculate-bulk-quote) ou [Récupérer des informations sur un devis groupé](#retrieve-bulk-quote-information). + +
+ +### Ressource API : transferts groupés + +Dans l’API, un _transfert groupé_ est un ensemble de transferts ILP hop-to-hop (voir [Interledger](#interledger)), chacun correspondant à une transaction. Les transferts contiennent aussi les détails des transactions de bout en bout. + +La ressource logique **Transferts groupés** permet à un FSP ou au Switch de demander au prochain acteur d’effectuer les transferts nécessaires. + +#### Requêtes + +##### Effectuer un transfert groupé + +Permet à un FSP ou Switch de demander au prochain acteur de réserver les transferts nécessaires à une transaction financière interopérable. + +- Réponse en cas de succès : [Retour des informations sur le transfert groupé](#return-bulk-transfer-information) + +- Réponse en cas d’erreur : [Erreur de retour du transfert groupé](#return-bulk-transfer-information-error) + +##### Récupérer des informations sur un transfert groupé + +Permet de demander des informations sur un transfert donné. + +- Réponse en cas de succès : [Retour des informations sur le transfert groupé](#return-bulk-transfer-information) + +- Réponse en cas d’erreur : [Erreur de retour du transfert groupé](#return-bulk-transfer-information-error) + +
+ +#### Réponses + +##### Retour des informations sur le transfert groupé + +Réponse pour retourner les informations suite aux requêtes [Effectuer un transfert groupé](#perform-bulk-transfer) ou [Récupérer des informations sur un transfert groupé](#retrieve-bulk-transfer-information). + +À réception, le FSP ou le Switch doit valider les fulfilments et valider les transferts réservés si la validation est réussie. + +
+ +#### Réponses d’Erreur + +##### Erreur de retour du transfert groupé + +Réponse utilisée pour retourner des erreurs concernant [Effectuer un transfert groupé](#perform-bulk-transfer) ou [Récupérer des informations sur un transfert groupé](#retrieve-bulk-transfer-information). + +
+ +## Modèles de Transactions Génériques + +Cette section expose les trois principaux modèles de transactions définis dans l’API d’Interopérabilité : + +- [Transaction initiée par le payeur](#payer-initiated-transaction) + +- [Transaction initiée par le bénéficiaire](#payee-initiated-transaction) + +- [Transaction groupée](#bulk-transaction) + +Chaque modèle décrit comment transférer des fonds d’un payeur dans un FSP à un bénéficiaire dans un autre FSP. + +Les modèles [Transaction initiée par le payeur](#payer-initiated-transaction) et [Transaction initiée par le bénéficiaire](#payee-initiated-transaction) concernent chacun un transfert unique entre un payeur et un bénéficiaire. La différence principale porte sur l’initiateur de la transaction. + +Le modèle [Transaction groupée](#bulk-transaction) est utilisé lorsqu’un seul payeur souhaite transférer des fonds à plusieurs bénéficiaires, éventuellement dans des FSP différents, en une seule opération. + +Cette section fournit également des informations sur le modèle alternatif _Transaction initiée par le bénéficiaire avec OTP_. De plus, elle couvre dans les grandes lignes tous les services logiques inclus dans l’API. + +
+ diff --git a/docs/fr/technical/api/fspiop/glossary.md b/docs/fr/technical/api/fspiop/glossary.md new file mode 100644 index 000000000..db81d13b0 --- /dev/null +++ b/docs/fr/technical/api/fspiop/glossary.md @@ -0,0 +1,285 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# Glossaire + +## Préface + +Cette section fournit des informations sur la façon d'utiliser ce document. + +### Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'informations spécifiés. + +| **Type d’Information** | **Convention** | **Exemple** | +| :--- | :--- | :--- | +| **Éléments de l'API tels que les ressources** | Gras | **/authorization** | +| **Variables** | Italique entre accolades | _{ID}_ | +| **Glossaire** | Italique à la première occurrence ; défini dans le _Glossaire_ | Le but de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un bénéficiaire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP. | +| **Documents de référence** | Italique | Les informations utilisateur ne doivent, en général, pas être utilisées par les déploiements d’API ; les mesures de sécurité détaillées dans _Signature de l'API_ et _Chiffrement de l'API_ doivent être utilisées à la place.| + +### Informations sur la version du document + +| **Version** | **Date** | **Description des modifications** | +| :--- | :--- | :--- | +| **1.0** | 2018-03-13 | Version initiale | + +
+ +## Introduction + +Ce document fournit le glossaire pour la spécification Open API pour l’interopérabilité FSP. Les termes ont été compilés à partir de trois sources : + +- ITU-T Digital Financial Services Focus Group Glossary (ITU-T)[ITU-T Digital Financial Services Focus Group Glossary (ITU-T)](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-E.pdf), +- Retours des fournisseurs de services technologiques (TSP) dans les groupes de travail Product Development Partnership (PDP), et +- Retours de l’équipe L1P IST Reference Implementation (RI). + +Les informations sont partagées conformément à la licence Creative Commons[LICENSE](https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md). + + +### Open API pour la spécification d’interopérabilité FSP + +L’Open API pour la spécification d’interopérabilité FSP comprend les documents suivants. + +#### Documents logiques + +- [Modèle de données logique](./logical-data-model) + +- [Modèles de transactions génériques](./generic-transaction-patterns) + +- [Cas d'utilisation](./use-cases) + +#### Documents de liaison REST asynchrone + +- [Définition de l'API](./api-definition) + +- [Règles de liaison JSON](./json-binding-rules) + +- [Règles du système](./scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents généraux + +- [Glossary](#) + +
+ + +## Glossaire de l’API + +| **Terme** | **Termes alternatifs et connexes** | **Définition** | **Source** | +| --- | --- | --- | --- | +| **Access Channel** | POS ("Point of Sale"), Customer Access Point, ATM, Branch, MFS Access Point | Lieux ou moyens utilisés pour initier ou recevoir un paiement. Les canaux d'accès peuvent inclure les agences bancaires, les distributeurs automatiques (ATM), terminaux POS, points d’agents, téléphones portables et ordinateurs. | ITU-T | +| **Account ID** | | Identifiant unique assigné par le FSP ayant créé le compte. | PDP | +| **Account Lookup System** | | Entité abstraite utilisée pour retrouver dans quel FSP un compte, un wallet, ou une identité est hébergé. Peut être hébergée sur son propre serveur, au sein d’un financial switch ou chez divers FSPs. | PDP | +| **Active User** | | Terme utilisé par plusieurs fournisseurs pour décrire combien de détenteurs de compte utilisent fréquemment leur service. | +| **Agent** | Agent Till, Agent Outlet | Entité autorisée par le fournisseur pour gérer diverses fonctions comme l’enrôlement client, le cash-in et le cash-out à l’aide d’un _agent till_. | ITU-T | +| **Agent Outlet** | Access Point | Emplacement physique accueillant un ou plusieurs _agent tills_, permettant de réaliser des opérations d’enrôlement, cash-in et cash-out pour des clients au nom d’un ou plusieurs fournisseurs. Le droit d’exclusivité peut dépendre de la loi nationale. Un _agent outlet_ peut exercer d’autres activités. | ITU-T | +| **Agent Till** | Registered Agent | Un _agent till_ est une ligne enregistrée délivrée par un fournisseur (carte SIM spéciale ou terminal POS), utilisée pour les opérations d’enrôlement, cash-in et cash-out. La loi nationale définit quels fournisseurs de services financiers peuvent en émettre. | ITU-T | +| **Aggregator** | Merchant Aggregator | Fournisseur spécialisé de services aux marchands, gérant généralement les transactions pour de nombreux petits commerçants. Les règles du système peuvent limiter leur champ d’action. | ITU-T | +| **Anti-Money Laundering** | AML ; aussi "Combating the Financing of Terrorism", ou CFT | Initiatives visant à détecter et arrêter l’utilisation des systèmes financiers pour dissimuler des fonds obtenus illégalement. | ITU-T | +| **API** | Application Programming Interface | Ensemble de méthodes clairement définies pour permettre l’interaction et l’échange de données entre différents programmes logiciels. |PDP | +| **Arbitration** | | Recours à un arbitre (et non au tribunal) pour résoudre des litiges. | ITU-T | +| **Authentication** | Verification, Validation | Processus permettant de s’assurer qu’une personne ou une transaction est valide pour le processus effectué (ouverture de compte, initiation de transaction, etc) | ITU-T | +| **Authorization** | | Processus utilisé lors d’un paiement tiré (« pull payment », tel un paiement par carte), dans lequel le bénéficiaire demande (par l’intermédiaire de son fournisseur) à la banque du payeur de confirmer la validité de la transaction. | ITU-T | +| **Authorized /institution entity** | | Institution non financière autorisée par la Banque d’État ou autres autorités de régulation à fournir des services financiers mobiles. | PDP | +| **Automated Clearing House** | ACH | Système électronique d’échanges d’ordres de paiement entre fournisseurs de services de paiement, via médias magnétiques ou réseaux de télécommunications, puis compensation entre participants. | ITU-T | +| **Bank** | Savings Bank, Credit Union, Payments Bank | Système financier agréé dans un pays, capable d’accepter des dépôts et d’effectuer des paiements sur les comptes des clients. | ITU-T | +| **Bank Accounts and Transaction Services** | Mobile Banking, Remote Banking, Digital Banking| Compte de transactions détenu auprès d’une banque, parfois accessible par téléphone mobile (mobile banking). | ITU-T | +| **Bank-Led Model** | Bank-Centric Model| Système où les banques sont les principaux fournisseurs de services financiers numériques à l’utilisateur final. | ITU-T | +| **Basic Phone** | | Appareil minimal requis pour l’utilisation des services financiers numériques. | PDP | +| **Bill Payment** | C2B, Utility Payments, School Payments | Réalisation d’un paiement pour un service récurrent, en personne ou à distance. | ITU-T | +| **Biometric Authentication** | | Utilisation d’une caractéristique physique d'une personne (empreinte digitale, iris...) pour l’authentifier. | ITU-T | +| **Biometric Authentication** | | Tout processus validant l’identité d’un utilisateur souhaitant accéder à un système par mesure d’une caractéristique intrinsèque. | ITU-T | +| **Blacklist** | | Registre d’entités (utilisateurs enregistrés) refusés/désactivés d’un privilège, service, accès… N’ayant pas droit d’accès/usage/prise en compte. Cette pratique permet d’identifier explicitement les utilisateurs à refuser. | PDP | +| **Blockchain** | Digital Currency, Cryptocurrency, Distributed Ledger Technology | Technologie sous-jacente à Bitcoin et autres crypto-monnaies : un registre numérique partagé, mis à jour en continu. | ITU-T | +| **Borrowing** | | Emprunter de l’argent pour un besoin à court ou long terme. | ITU-T | +| **Bulk Payments** | G2C, B2C, G2P, Social Transfers| Versements de masse gouvernement-consommateur : allocations, transferts, salaires, pensions… | ITU-T | +| **Bulk Payment Services** | | Service permettant à une agence gouvernementale ou entreprise d’effectuer des paiements à un grand nombre de bénéficiaires. | ITU-T | +| **Bulk upload service** | | Service permettant l’import de multiples transactions par session, souvent via transfert de fichier bulk pour initialiser des paiements (ex: fichier de paie). | ITU-T | +| **Bundling** | Packaging, Tying | Modèle dans lequel un fournisseur regroupe des services en un seul produit que l’utilisateur final accepte d’acheter ou d’utiliser. | ITU-T | +| **Business** | | Entité (ex : société anonyme, SARL, etc) utilisant le mobile money pour effectuer / recevoir des paiements, verser les salaires… | PDP | +| **Cash Management** | Agent Liquidity Management | Gestion des soldes de liquidité chez un agent. | ITU-T | +| **Cash-In** | CICO (Cash-In Cash-Out) | Crédit d’eMoney en échange d’argent liquide, typiquement chez un agent. | ITU-T | +| **Cash-Out** | CICO (Cash-In Cash-Out) | Remise d’argent physique en échange d’un débit sur compte eMoney, typiquement chez un agent. | ITU-T | +| **Certificate Signing Request** | CSR | Message envoyé d’un demandeur à une Autorité de Certification pour demander un certificat d’identité numérique. | | +| **Chip Card** | EMV Chip Card, Contactless Chip Card | Carte à puce comportant un microprocesseur, pouvant être sans contact ou à contact (insérée en terminal). | ITU-T | +| **Clearing** | | Processus de transmission, rapprochement et confirmation des transactions avant leur règlement. Inclut parfois le netting et la création des positions finales. | RI | +| **Clearing House** | | Emplacement ou mécanisme central où les institutions financières échangent instructions de paiement ou d’autres obligations, avant règlement selon les règles et procédures du clearinghouse. | ITU-T | +| **Client Authentication** | TLS | Certificat utilisé pour authentifier un client durant un handshake SSL ; celuici permet de vérifier que le client est bien celui revendiqué (Source: Techopedia). | | +| **Closed-Loop** | | Système de paiement utilisé par un fournisseur unique ou un groupe fermé de fournisseurs. | ITU-T | +| **Combatting Terrorist Financing** | | Initiatives visant à détecter et à empêcher l’utilisation des systèmes financiers pour transférer des fonds à des organisations ou personnes terroristes. | ITU-T | +| **Commission** | | Paiement incitatif effectué, typiquement à un agent ou autre intermédiaire agissant pour le compte d’un fournisseur DFS. Offre une incitation à l’agent. | ITU-T | +| **Commit** | | Partie d’une opération de transfert en deux phases au cours de laquelle les fonds réservés pour le transfert sont libérés au bénéficiaire ; le transfert est achevé entre les comptes du payeur d’origine et du bénéficiaire. | PDP | +| **Condition** | | Dans le protocole Interledger, verrou cryptographique utilisé lorsqu’un transfert est réservé. Prend généralement la forme d’un hachage SHA-256 d’une image secrète (preimage). Lorsqu’elle est fournie dans une demande de transfert, le transfert doit être réservé de sorte qu’il ne soit validé (commit) que si la condition est remplie (la preimage secrète est fournie). | PDP | +| **Counterparty** | Payee, Payer, Borrower, Lender | L’autre partie d’un paiement ou d’une opération de crédit. Un bénéficiaire est la contrepartie d’un payeur, et inversement. | ITU-T | +| **Coupon** | | Jeton donnant droit à une remise ou échangeable contre des biens ou services. | PDP | +| **Credit History** | Credit Bureaus, Credit Files | Ensemble d’enregistrements conservés pour un utilisateur final reflétant son utilisation du crédit, y compris emprunts et remboursements. | ITU-T | +| **Credit Risk Management** | | Outils pour gérer le risque qu’un emprunteur ou une contrepartie ne respecte pas ses obligations selon les conditions convenues. | ITU-T | +| **Credit Scoring** | | Processus créant un score numérique reflétant la solvabilité. | ITU-T | +| **Cross Border Trade Finance Services** | | Services permettant à une entreprise de vendre ou d’acheter à des entreprises ou particuliers d’autres pays ; peuvent inclure la gestion des transactions de paiement, le traitement des données et le financement. | ITU-T | +| **Cross-FX Transfer** | | Transfert impliquant plusieurs devises, incluant un calcul de change. | PDP | +| **Customer Database Management** | | Pratiques des fournisseurs pour gérer les données clients ; peuvent être prises en charge par la plateforme de paiement utilisée. | ITU-T | +| **Customer Financial Data** | Customer Financial Data | Ensemble d’informations financières du client, incluant soldes de compte, dépôts et données relatives aux transactions financières, etc. | PDP | +| **Data Controller** | Data Controller | Toute personne physique ou morale, autorité publique, agence ou autre organisme qui, seul ou conjointement avec d’autres, détermine les finalités et les moyens du traitement des données personnelles. Le responsable du traitement est également chargé de fournir une infrastructure sécurisée pour les données. | PDP | +| **Data Portability** | Data Portability | Capacité d’une personne concernée à demander une copie des données personnelles traitées dans un format utilisable et à les transmettre électroniquement à un autre système de traitement. | PDP | +| **Data Protection** | PCI-DSS | Pratiques des entreprises pour protéger les données et identifiants des utilisateurs finaux. « PCI-DSS » est une norme de l’industrie des cartes à cet effet. | ITU-T | +| **Deposit Guarantee System** | Deposit Insurance | Fonds garantissant les dépôts des titulaires de compte auprès d’un fournisseur ; souvent une fonction gouvernementale pour les comptes bancaires. | ITU-T | +| **Diffie-Hellman solution** | | Mécanisme sécurisé d’échange d’une clé symétrique partagée entre deux pairs anonymes. | | +| **Digital Financial Services** | DFS, Mobile Financial Services | Les services financiers numériques comprennent des méthodes de stockage et de transfert électroniques de fonds, d’émission et de réception de paiements, d’emprunt, d’épargne, d’assurance et d’investissement, ainsi que de gestion des finances personnelles ou d’entreprise. | ITU-T | +| **Digital Liquidity** | | État dans lequel un consommateur accepte de laisser des fonds (eMoney ou dépôts bancaires) sous forme électronique plutôt que d’effectuer un cash-out. | ITU-T | +| **Digital Payment** | Mobile Payment, Electronic Funds Transfer | Terme large incluant tout paiement exécuté électroniquement, y compris les paiements initiés par téléphone mobile ou ordinateur. | ITU-T | +| **Dispute Resolution** | | Processus défini par un fournisseur ou par les règles d’un système de paiement pour résoudre les litiges entre utilisateurs finaux et fournisseurs, ou entre un utilisateur final et sa contrepartie. | ITU-T | +| **Electronic consent** | Electronic consent | Tout son, symbole ou processus qui est :
1. Lié à une technologie
    a. Ayant des capacités électriques, numériques, magnétiques, sans fil, optiques, électromagnétiques ou similaires, y compris (sans s’y limiter) téléphone mobile, télécopie et internet, et
    b. Qui ne peut être accessible que par un code d’accès sécurisé, et


2. Logiquement associé à un accord ou une autorisation juridiquement contraignants et exécuté ou adopté par une personne avec l’intention d’être liée par cet accord ou cette autorisation.
| PDP | +| **Electronic Invoicing, ERP, Digital Accounting, Supply Chain Solutions, Services, Business Intelligence** | | Services soutenant les fonctions marchandes ou d’entreprise liées aux services DFS. | ITU-T | +| **eMoney** |eFloat, Float, Mobile Money, Electronic Money, Prepaid Cards, Electronic Funds | Enregistrement de fonds ou de valeur disponible pour un consommateur, stocké sur un dispositif de paiement (puce, carte prépayée, téléphone mobile) ou dans des systèmes informatiques comme compte non traditionnel auprès d’une entité bancaire ou non bancaire. | ITU-T | +| **eMoney Accounts and Transaction Services** | Digital Wallet, Mobile Wallet, Mobile Money Account | Compte de transaction détenu auprès d’une entité non bancaire. La valeur de ce compte est appelée eMoney. | ITU-T | +| **eMoney Issuer** | Issuer, Provider | Fournisseur (banque ou non-banque) qui dépose de l’eMoney sur un compte ouvert pour un utilisateur final. L’eMoney peut être créé lorsque le fournisseur reçoit des espèces (cash-in) ou un paiement numérique d’un autre fournisseur. | ITU-T | +| **Encryption** |Decryption | Processus d’encodage d’un message pour qu’il ne puisse être lu que par l’expéditeur et le destinataire prévu. | ITU-T | +| **End User** |Consumer, Customer, Merchant, Biller | Client d’un fournisseur de services financiers numériques : consommateur, marchand, gouvernement ou autre forme d’entreprise. | ITU-T | +| **External Account** | | Compte hébergé en dehors du FSP, régulièrement accessible via une API d’interface de fournisseur externe. | PDP | +| **FATF** | | Le Groupe d’action financière (GAFI) est une organisation intergouvernementale visant à lutter contre le blanchiment d’argent et à agir sur le financement du terrorisme. | ITU-T | +| **Feature Phone** | | Téléphone mobile sans capacités informatiques significatives. | ITU-T | +| **Fees** | | Paiements facturés par un fournisseur à son utilisateur final (frais fixes, pourcentage ou mixte). Les systèmes ou systèmes de paiement, ainsi que les processeurs, facturent également des frais à leurs clients (typiquement le fournisseur). | ITU-T | +| **Financial Inclusion** | | Fourniture durable de services financiers numériques abordables intégrant les populations défavorisées dans l’économie formelle. | ITU-T | +| **Financial Literacy** | | Compétences financières essentielles des consommateurs et entreprises (budget familial, valeur temporelle de l’argent, utilisation d’un produit DFS, etc.). | ITU-T | +| **FinTech** | | Terme désignant les entreprises fournissant logiciels, services et produits pour les services financiers numériques ; souvent associé aux technologies récentes. | ITU-T | +| **Float** | | Terme pouvant signifier différentes choses. En banque, le float est créé lorsque le compte d’une partie est débité ou crédité à un moment différent de sa contrepartie. L’eMoney, obligation d’un fournisseur non bancaire, est parfois appelé float. | ITU-T | +| **Fraud** | Fraud Management, Fraud Detection, Fraud Prevention | Usage criminel des services financiers numériques pour retirer des fonds à une personne ou entreprise, ou lui nuire autrement. | ITU-T | +| **Fraud Risk Management** | | Outils pour gérer les risques des fournisseurs et parfois des utilisateurs (marchands, gouvernements) dans la fourniture et l’utilisation des services DFS. | ITU-T | +| **FSP** | Provider, Financial Service Provider (FSP), Payment Service Provider, Digital Financial Services Provider (DFSP) | Entité fournissant un service financier numérique à un utilisateur final. Dans un système en boucle fermée, l’opérateur du système de paiement est aussi le fournisseur. Dans un système en boucle ouverte, les fournisseurs sont les banques ou non-banques participant au système. | ITU-T | +| **FSP On-boarding** | | Processus d’ajout d’un nouveau FSP à ce réseau financier. | RI | +| **Fulfillment** | | Dans le protocole Interledger, secret qui est la preimage d’un hachage SHA-256, utilisé comme condition sur un transfert. La preimage est requise dans le message de commit pour déclencher le transfert. | PDP | +| **FX** | | Change (Foreign Exchange). | PDP | +| **Government Payments Acceptance Services** | | Services permettant aux gouvernements de percevoir taxes et redevances auprès des particuliers et entreprises. | ITU-T | +| **HCE** | | Host Card Emulation. Technologie permettant de stocker en toute sécurité des données de paiement sans utiliser l’élément sécurisé du téléphone. | ITU-T | +| **Identity** | National Identity, Financial Identity, Digital Identity | Justificatif identifiant un utilisateur final. Identités nationales émises par les gouvernements ; dans certains pays, identité financière émise par les fournisseurs de services financiers. | ITU-T | +| **Immediate Funds Transfer** | Real Time | Paiement numérique reçu par le bénéficiaire presque immédiatement après initiation par le payeur. | ITU-T | +| **Insurance Products** | | Produits permettant aux utilisateurs finaux d’assurer des actifs ou des vies. | ITU-T | +| **Insuring Lives or assets** | | Payer pour protéger la valeur d’une vie ou d’un actif. | ITU-T | +| **Interchange** | Swipe Fee, Merchant Discount Fee | Structure dans certains systèmes de paiement imposant à un fournisseur de payer des frais à un autre sur certaines transactions (typiquement cartes : du marchand vers la banque émettrice). | ITU-T | +| **Interledger** | | Protocole de transfert de valeur monétaire entre plusieurs réseaux de paiement déconnectés via une chorégraphie de transferts conditionnels sur chaque réseau. | PDP | +| **International Remittance** | P2P; Remote Cross-Border Transfer of Value, Cross-Border Remittance | Émission et réception de paiements vers une personne dans un autre pays. | ITU-T | +| **Interoperability** | Interconnectivity | Lorsque les systèmes de paiement sont interopérables, ils permettent l’interaction de plateformes ou produits propriétaires distincts. Résultat : échange de transactions entre fournisseurs (participation à un système ou accords bilatéraux/multilatéraux). Questions techniques et de règles métier à résoudre. | ITU-T | +| **Interoperability Service for Transfers (IST)** | Switch | Entité recevant des transactions d’un fournisseur et les routant vers un autre. Peut être détenue ou louée par un système ou des fournisseurs individuels ; peut se connecter à un système de règlement. | ITU-T | +| **Interoperability settlement bank** | | Entité facilitant l’échange de fonds entre FSP. Banque de règlement centrale dans toute transaction inter-FSP. | PDP | +| **Investment Products** | | Produits permettant aux utilisateurs finaux d’investir hors compte d’épargne. | ITU-T | +| **Irrevocable** | | Transaction ne pouvant pas être « rappelée » par le payeur ; une fois reçue par le bénéficiaire, elle ne peut être annulée par le payeur. | ITU-T | +| **JSON** | JavaScript Object Notation | Format léger d’échange de données, lisible par humains et machines, basé sur un sous-ensemble de JavaScript (ECMA-262). | | +| **Know Your Customer** | KYC, Agent and Customer Due Diligence, Tiered KYC, Zero Tier | Processus d’identification d’un nouveau client à l’ouverture de compte, conforme à la loi. Exigences réduites possibles pour comptes à faible valeur (KYC par paliers). | ITU-T | +| **Liability** | Agent Liability, Issuer Liability, Acquirer Liability | Obligation légale d’une partie envers une autre, imposée par la loi nationale, les règles du système ou des accords entre fournisseurs. | ITU-T | +| **Liquidity** | Agent Liquidity | Disponibilité d’actifs liquides pour honorer une obligation. Banques, non-banques et agents ont besoin de liquidité. | ITU-T | +| **Loans** | Microfinance, P2P Lending, Factoring, Cash Advances, Credit, Overdraft, Facility | Moyens par lesquels les utilisateurs finaux peuvent emprunter. | ITU-T | +| **M2C** | | Marchand vers client ou consommateur (Merchant to Customer or Consumer). | PDP | +| **mCommerce** | eCommerce | Achat ou vente à distance : par téléphone ou tablette (mCommerce) ou par ordinateur (eCommerce). | ITU-T | +| **Merchant** | Payments Acceptor | Entreprise vendant biens ou services et recevant des paiements. | ITU-T | +| **Merchant Acquisition** | Onboarding | Processus d’activation d’un marchand pour la réception de paiements électroniques. | ITU-T | +| **Merchant payment - POS** | C2B, Proximity Payments | Paiement pour un bien ou service en personne ; inclut bornes et distributeurs automatiques. | ITU-T | +| **Merchant payment - Remote** |C2b, eCommerce Payment, Mobile Payment | Paiement pour un bien ou service à distance (téléphone, ordinateur, etc.). | ITU-T | +| **Merchant Payments Acceptance Services** | Acquiring Services | Service permettant à un marchand d’accepter un ou plusieurs types de paiements électroniques. « Acquiring » est typique des systèmes cartes. | ITU-T | +| **Merchant Service Provider** | Acquirer | Fournisseur (banque ou non-banque) soutenant les marchands pour recevoir des paiements clients. « Acquirer » concerne l’acceptation cartes. | ITU-T | +| **Mobile Network Operator** | MNO | Entreprise vendant services de téléphonie mobile (voix et données). | ITU-T | +| **Money Transfer Operator** | | Fournisseur DFS spécialisé dans les envois de fonds nationaux et/ou internationaux. | ITU-T | +| **MSISDN** | | Numéro identifiant de façon unique un abonnement dans un réseau mobile (norme E.164). | RI | +| **Mutual Authentication** | TLS | Authentification mutuelle : les deux parties s’authentifient simultanément (mode par défaut dans IKE, SSH ; optionnel dans TLS). | | +| **Near Field Communication** | NFC | Technologie de communication utilisée en paiement pour transmettre des données du téléphone NFC au terminal. | ITU-T | +| **Netting** | | Compensation des obligations entre participants du système de règlement, réduisant nombre et valeur des paiements nécessaires. | RI | +| **Non-Bank** | Payments Institution, Alternative Lender | Entité non bancaire fournissant des services financiers ; conditions et limites fixées par la loi nationale. | ITU-T | +| **Non-Bank-Led Model** | MNO-Led Model | Système où des non-banques sont les fournisseurs principaux de services financiers numériques aux utilisateurs finaux. | ITU-T | +| **Non-repudiation** | | Capacité à prouver l’authenticité d’une transaction (par ex. validation d’une signature numérique). | PDP | +| **Nostro Account** | | Du point de vue du payeur : fonds/comptes du FSP payeur détenus/hébergés chez le FSP bénéficiaire. | PDP | +| **Notification** | | Avis au payeur ou bénéficiaire concernant le statut d’un transfert. |PDP | +| **Off-Us Payments** | Off-Net Payments | Paiements dans un système multi-participants où le fournisseur du payeur diffère de celui du bénéficiaire. | ITU-T | +| **On-Us Payments** | On-Net Payments | Paiements où le fournisseur du payeur est le même que celui du bénéficiaire. | ITU-T | +| **Open-Loop** | | Système de paiement conçu pour la participation de multiples fournisseurs ; la loi ou les règles peuvent restreindre les classes de participants. | ITU-T | +| **Operations Risk Management** | | Outils pour gérer les risques opérationnels des fournisseurs d’un système DFS. | ITU-T | +| **Organization** | Business | Entité (entreprise, association, administration) utilisant le mobile money pour paiements et décaissements de salaires, etc. | PDP | +| **OTP** | One-Time Password | Justificatif utilisable une seule fois, généré puis validé par le même FSP pour approbation automatique ; souvent lié à un payeur précis. Généralement numérique de 4 à 6 chiffres. | PDP | +| **Over The Counter Services** | OTC, Mobile to Cash | Services d’agents lorsqu’une partie n’a pas de compte eMoney : le payeur distant peut créditer le compte agent qui verse des espèces au bénéficiaire sans compte. | ITU-T | +| **P2P** | Domestic Remittance, Remote Domestic Transfer of Value| Paiements entre personnes dans le même pays. | ITU-T | +| **Participant** | | Fournisseur membre d’un système de paiement, soumis à ses règles. | ITU-T | +| **Partner Bank** | | Institution financière soutenant le FSP et lui donnant accès à l’écosystème bancaire local. | PDP | +| **Payee** | Receiver | Bénéficiaire de fonds électroniques dans une transaction de paiement. | ITU-T | +| **Payee FSP** | | FSP du bénéficiaire. | PDP | +| **Payer** | Sender | Payeur de fonds électroniques dans une transaction de paiement. | ITU-T | +| **Payer FSP** | | FSP du payeur. | PDP | +| **Paying for Purchases** | C2B - Consumer to Business | Paiements d’un consommateur vers une entreprise ; l’entreprise est le marchand ou accepteur de paiement. | ITU-T | +| **Payment Device** | ATM (Automated Teller Machine), POS (Point of Sale), Access Point, Point of Sale Device | Notion abstraite d’un dispositif électronique (autre que celui du payeur) permettant d’accepter une transaction via un justificatif (OTP). Exemples : DAB et TPE. | PDP | +| **Payment Instruction** | Payment Instruction | Instruction d’un émetteur à son prestataire de services de paiement pour payer un montant fixe ou déterminable à un bénéficiaire, sous conditions de temps de paiement uniquement, transmise directement ou via agent/système de transfert. | PDP | +| **Payment System** | Payment Network, Money Transfer System | Ensemble des activités, processus, mécanismes, infrastructures, institutions et utilisateurs liés au paiement dans un pays ou une région. | ITU-T | +| **Payment System Operator** | Mobile Money Operator, Payment Service Provider | Entité exploitant un système ou système de paiement. | ITU-T | +| **Peer FSP** | | FSP homologue (contrepartie). | PDP | +| **PEP** | | Personne politiquement exposée (PPE) : personne ayant reçu une fonction publique importante, présentant un risque accru de corruption. | PDP | +| **Platform** | Payment Platform, Payment Platform Provider, Mobile Money Platform | Logiciel ou service utilisé par un fournisseur, un système ou un switch pour gérer les comptes utilisateurs et les transactions. | ITU-T | +| **Posting** | Clearing | Action du fournisseur d’inscrire un débit ou crédit dans le registre du compte utilisateur. | ITU-T | +| **Pre-approval** |Debit Authorization, Mandate |Le payeur autorise un bénéficiaire précis à prélever des fonds sans validation manuelle à chaque transaction (ponctuelle, période définie ou jusqu’à annulation).| PDP | +| **Prefunding** | | Processus d’ajout de fonds aux comptes Vostro/Nostro. | PDP | +| **Prepaid Cards** | | Produit eMoney à usage général où l’enregistrement des fonds est sur la carte (bande magnétique ou puce) ou un système central. | ITU-T | +| **Processing of Personal/Consumer Data** | Processing of Personal/Consumer Data | Toute opération effectuée sur des données personnelles/de consommation (collecte, enregistrement, stockage, consultation, transmission, effacement, etc.). | PDP | +| **Processor** | Gateway | Entreprise gérant en sous-traitance des fonctions pour un fournisseur DFS (transactions, données clients, risques) ; peut aussi servir systèmes ou switches. | ITU-T | +| **Promotion** | | Initiative marketing d’un FSP offrant une remise de frais sur biens ou services ; peut utiliser un coupon. | PDP | +| **Pull Payments** | | Type de paiement initié par le bénéficiaire (marchand) dont le fournisseur « tire » les fonds du compte du payeur. | ITU-T | +| **Push Payments** | | Type de paiement initié par le payeur qui instruit son fournisseur de débiter son compte et « pousser » les fonds vers le bénéficiaire. | ITU-T | +| **Quote** | | Prix pour une transaction financière hypothétique (frais, change, commission, taxes). Garanti pour une courte période, puis expire. | PDP | +| **Reconciliation** | | Processus de rapprochement de deux ensembles d’enregistrements (soldes de comptes) entre FSP pour s’assurer que les fonds sortants correspondent aux transferts effectifs. | PDP | +| **Recourse** | | Droits accordés par la loi, les règles privées ou des accords permettant certaines actions (par ex. annulation) dans certaines circonstances. | ITU-T | +| **Refund** | | Remboursement d’une somme au client retournant biens ou services. | PDP | +| **Registration** | Enrollment, Agent Registration, User Creation, User On- Boarding | Processus d’ouverture d’un compte fournisseur (consommateurs, marchands, agents, etc.). | ITU-T | +| **Regulator** | | Organisation gouvernementale habilitée par la loi à fixer et faire respecter normes et pratiques (banques centrales, régulateurs télécoms, protection des consommateurs, etc.). | ITU-T | +| **Reserve** | Prepare | Partie d’un transfert en deux phases : fonds verrouillés jusqu’à commit ou rollback (souvent avec expiration automatique). | PDP | +| **Reversal** | | Processus d’annulation d’un transfert achevé. | PDP | +| **Risk Management** | Fraud Management | Pratiques pour comprendre, détecter, prévenir et gérer les risques chez fournisseurs, systèmes, processeurs et accepteurs de paiement. | ITU-T | +| **Risk-based Approach** | | Approche réglementaire et/ou de gestion créant des obligations différentes selon le risque de la transaction ou du client. | ITU-T | +| **Roll back** | Reject | Remise des fonds électroniques réservés à leur état initial ; la transaction est annulée. | PDP | +| **Rollback** | | Annulation d’une transaction pour restaurer l’état du système (soldes), typiquement après erreur par un administrateur. | PDP | +| **Rules** | | Règles d’exploitation privées d’un système de paiement liant les participants directs. | ITU-T | +| **Saving and Investing** | | Conserver des fonds pour besoins futurs et rendement financier. | ITU-T | +| **Savings Products** | | Compte bancaire ou non bancaire aidant les utilisateurs finaux à épargner. | ITU-T | +| **Scheme** | | Ensemble de règles, pratiques et normes nécessaires au fonctionnement des services de paiement. | ITU-T | +| **Secure Element** | | Puce sécurisée dans un téléphone pouvant stocker des données de paiement. | ITU-T | +| **Security Access Code** | Security Access Code | NIP, mot de passe/OTP, reconnaissance biométrique ou autre moyen d’accès certifié au compte pour initier un transfert électronique. | PDP | +| **Security Level** | | Niveau de sécurité du système définissant l’efficacité de la protection des risques. | ITU-T | +| **Sensitive Consumer Data** | Sensitive Consumer Data | Données sensibles du consommateur : identifiants d’authentification (ID utilisateur, mot de passe, PIN mobile, PIN transaction) et données relatives à convictions, santé, origine, opinions politiques, syndicales, casier, etc. | PDP | +| **Settlement** | Real Time Gross Settlement (RTGS) | Acte qui éteint les obligations de transfert de fonds ou titres entre parties. | RI | +| **Settlement Instruction** | | Instruction donnée à un système de règlement pour effectuer le règlement d’obligations de paiement entre participants. | PDP | +| **Settlement Obligation** | | Dette due par un participant à un autre suite à une ou plusieurs instructions de règlement. | PDP | +| **Settlement System** | Net Settlement, Gross Settlement, RTGS | Système facilitant le règlement des transferts de fonds, actifs ou instruments financiers (net ou brut). | ITU-T | +| **Short Message Service** | | Service d’envoi de messages courts entre téléphones mobiles. | ITU-T | +| **SIM Card** | SIM ToolKit, Thin SIM | Carte à puce dans un téléphone mobile portant un numéro d’identification unique, stockant des données personnelles. | ITU-T | +| **Smart Phone** | | Appareil combinant téléphone mobile et ordinateur. | ITU-T | +| **Standards Body** | EMV, ISO, ITU, ANSI, GSMA | Organisation créant des normes utilisées par fournisseurs et systèmes de paiement. | ITU-T | +| **Stored Value Account** | SVA | Compte dans lequel les fonds sont conservés sous forme électronique sécurisée (compte bancaire ou eMoney). | PDP | +| **Storing Funds** | Account, Wallet, Cash-In, Deposit | Conversion d’espèces en argent électronique et conservation sécurisée (compte bancaire ou eMoney). | PDP | +| **Super-Agent** | Master Agent | Dans certains pays, agents gérés par des super-agents responsables de leurs actions vis-à-vis du fournisseur. | ITU-T | +| **Supplier Payment** | B2B - Business to Business, B2G - Business to Government | Paiement d’une entreprise à une autre pour fournitures, en personne ou à distance, national ou transfrontalier. | ITU-T | +| **Suspicious Transaction Report** | Suspicious Transaction Report | Si une institution financière note une activité suspecte, elle peut déposer un rapport auprès de l’unité de renseignement financier. | PDP | +| **Systemic Risk** | | Dans les systèmes de paiement, risque d’effondrement de l’ensemble du système financier ou du marché. | ITU-T | +| **Tax Payment** | C2G, B2G | Paiement d’un consommateur vers un gouvernement (taxes, redevances, etc.). | ITU-T | +| **Tokenization** | | Substitution d’un jeton (« numéros factices ») aux « vrais » numéros pour limiter le vol et l’usage frauduleux. | ITU-T | +| **Trading** | International Trade | Échange de capitaux, biens et services au-delà des frontières internationales. | ITU-T | +| **Transaction Accounts** | | Compte de transaction : compte auprès d’une banque ou d’un prestataire autorisé/régulé (y compris non bancaire) pour émettre et recevoir des paiements. | ITU-T | +| **Transaction Cost** | | Coût pour un fournisseur DFS de fournir un service (forfait ou par transaction). | ITU-T | +| **Transaction Request** | Payment Request | Demande envoyée par un bénéficiaire à un payeur pour transférer des fonds électroniques ; approbation manuelle habituelle, ou pré-approbation/justificatif (OTP) pour validation automatique. | PDP | +| **Transfer** | | Terme générique pour toute transaction où de la valeur passe d’un compte à un autre. | PDP | +| **Transfer Funds** | Sending or Receiving Funds | Émission et réception de paiements à une autre personne. | ITU-T | +| **Transport Layer Security** | TLS, client authentication, mutual authentication | Protocole cryptographique assurant la sécurité des communications sur un réseau informatique (point à point). | | +| **Trust Account** | Escrow, Funds Isolation, Funds Safeguarding, Custodian Account, Trust Account | Moyen de détenir des fonds au profit d’une autre partie. Les émetteurs eMoney doivent souvent isoler la valeur des comptes utilisateurs dans un compte fiduciaire bancaire. | ITU-T | +| **Trusted Execution Environment** | | Environnement d’exécution disposant de capacités et exigences de sécurité. | ITU-T | +| **Ubiquity** | | Capacité d’un payeur d’atteindre la plupart des bénéficiaires du pays, quel que soit leur fournisseur ; nécessite l’interopérabilité. | ITU-T | +| **Unbanked** | Underbanked, Underserved| Personnes sans compte de transaction ; sous-bancarisées avec compte peu utilisé ; « mal desservies » cible l’inclusion financière. | ITU-T | +| **User ID** | | Identifiant unique d’un utilisateur (MSISDN, compte bancaire, ID fournisseur, identité nationale, etc.). En transaction, l’argent est adressé à un ID utilisateur, pas directement à un ID de compte. | PDP | +| **USSD** | | Technologie d’envoi de texte entre téléphone mobile et application réseau. | ITU-T | +| **Vostro Account** | | Du point de vue du bénéficiaire : fonds/comptes du FSP payeur détenus chez le FSP bénéficiaire. | PDP | +| **Voucher** | | Instrument de valeur monétaire pour transférer des fonds à des bénéficiaires sans compte chez le FSP payeur. | ITU-T | +| **Wallet** | eWallet | Référentiel de fonds pour un compte ; relation portefeuille-compte pouvant être plusieurs-à-un. | PDP | +| **Whitelist** | | Liste d’entités autorisées pour un privilège, service ou accès (inverse de la liste noire). | PDP | +| **'x'-initiated** | | Utilisé pour la partie ayant initié une transaction (ex. cash-out initié par agent vs. par utilisateur). | PDP | + diff --git a/docs/fr/technical/api/fspiop/json-binding-rules.md b/docs/fr/technical/api/fspiop/json-binding-rules.md new file mode 100644 index 000000000..0663da833 --- /dev/null +++ b/docs/fr/technical/api/fspiop/json-binding-rules.md @@ -0,0 +1,218 @@ +--- +showToc: true +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- +# Règles de liaison JSON (JSON Binding Rules) + +## Préface + +Cette section contient des informations sur la manière d’utiliser ce document. + +### Conventions Utilisées dans ce Document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d’informations spécifiés. + +|Type d’information|Convention|Exemple| +|---|---|---| +|**Éléments de l’API, tels que ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans _Glossaire_|Le but de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une opération de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne doivent, en général, pas être utilisées par les déploiements API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ doivent être utilisées à la place.| + +### Informations sur la Version du Document + +|Version|Date|Description des modifications| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| + +## Introduction + +L’objectif de ce document est d’exprimer le modèle de données utilisé par l’API ouverte pour l’interopérabilité des Fournisseurs de Services Financiers (FSP) (ci-après appelée « l’API ») sous la forme de règles de liaison JSON Schema, ainsi que les règles de validation de leurs instances correspondantes. + +Ce document complète et développe l’information fournie dans _Open API for FSP Interoperability Specification_. Les contenus de la spécification sont listés dans [Vue d’ensemble de l’API FSPIOP](/). + +Les types utilisés dans l’API PDP relèvent principalement de trois catégories : + +- Types de données et formats de base utilisés + +- Types d’éléments + +- Types complexes + +Les différents types utilisés dans _Définition de l’API_, _Modèle de Données_ et _Spécification Open API_, ainsi que les règles de transformation JSON auxquelles leurs instances doivent se conformer, sont identifiés dans les sections suivantes. + +
+ +### Spécification Open API pour l’interopérabilité des FSP + +La spécification Open API pour l’interopérabilité des FSP inclut les documents suivants. + +#### Documents Logiques + +- [Modèle de Données Logique](./logical-data-model) + +- [Modèles Généraux de Transaction](./generic-transaction-patterns) + +- [Cas d’Utilisation](./use-cases) + +#### Documents de Liaison REST Asynchrone + +- [Définition de l’API](./api-definition) + +- [Règles de liaison JSON](#) + +- [Règles du système](./scheme-rules) + +#### Intégrité des Données, Confidentialité et Non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents Généraux + +- [Glossaire](./glossary) + +
+ +## Mots-clés et Utilisation + +Les _mots-clés_ utilisés dans les Schémas JSON et les règles sont dérivés de la _Spécification JSON Schema_[1](http://json-schema.org/documentation.html). Les types de mots-clés employés sont identifiés dans les sections [Mots-clés de validation](#validation-keywords), [Mots-clés de métadonnées](#metadata-keywords) et [Instance-et-$ref](#instance-and-$ref). Comme expliqué plus en détail plus loin, certains de ces mots-clés spécifient des paramètres de validation tandis que d’autres sont plus descriptifs, comme les métadonnées. La description suivante précise, par exemple, si un champ DOIT[2](https://www.ietf.org/rfc/rfc2119.txt) être présent dans la définition ou s’il est associé à un certain type de données. + +### Mots-clés de validation + +Cette section[3](http://json-schema.org/latest/json-schema-validation.html) fournit des descriptions des mots-clés utilisés pour la validation dans la _Définition de l’API_. Les mots-clés de validation dans un schéma imposent des exigences pour la validation réussie d’une instance. + +#### maxLength + +La valeur de ce mot-clé DOIT être un entier non négatif. Une instance chaîne est valide vis-à-vis de ce mot-clé si sa longueur est inférieure ou égale à la valeur de ce dernier. La longueur d’une instance chaîne est le nombre de ses caractères selon la RFC 7159 [RFC7159]. + +#### minLength + +La valeur de ce mot-clé DOIT être un entier non négatif. Une instance chaîne est valide pour ce mot-clé si sa longueur est supérieure ou égale à la valeur de ce dernier. Omettre ce mot-clé a le même effet que de lui assigner la valeur **0**. + +#### pattern + +La valeur de ce mot-clé DOIT être une chaîne de caractères. Cette chaîne DEVRAIT être une expression régulière valide selon la syntaxe ECMA 262. Une instance chaîne est valide si l’expression régulière correspond avec succès. Rappel : les expressions régulières ne sont pas implicitement ancrées. + +#### items + +La valeur de `items` DOIT être un schéma JSON valide ou un tableau de schémas valides. Ce mot-clé détermine comment les instances enfants sont validées pour les tableaux ; il ne valide pas directement l’instance elle-même. Si `items` est un schéma, la validation réussit si tous les éléments du tableau valident contre ce schéma. Si `items` est un tableau de schémas, la validation réussit si chaque élément valide contre le schéma à la même position. Omettre ce mot-clé a le même effet que de spécifier un schéma vide. + +#### maxItems + +La valeur de ce mot-clé DOIT être un entier non négatif. Une instance de tableau est valide contre `maxItems` si sa taille est inférieure ou égale à cette valeur. + +#### minItems + +La valeur de ce mot-clé DOIT être un entier non négatif. Une instance de tableau est valide contre `minItems` si sa taille est supérieure ou égale à cette valeur. Omettre ce mot-clé a le même effet que la valeur **0**. + +#### required + +La valeur de ce mot-clé DOIT être un tableau. Les éléments DOIVENT être des chaînes de caractères uniques. Une instance objet est valide contre ce mot-clé si chaque élément du tableau est le nom d’une propriété présente dans l’instance. Omettre ce mot-clé revient à avoir un tableau vide. + +#### properties + +La valeur de `properties` DOIT être un objet. Chaque valeur de cet objet DOIT être un schéma JSON valide. Ce mot-clé définit comment les enfants sont validés pour les objets ; il ne valide pas l’instance elle-même. La validation réussit si, pour chaque nom commun entre l’instance et le schéma, l’instance enfant valide contre le schéma correspondant. Omettre ce mot-clé revient à un objet vide. + +#### enum + +La valeur de ce mot-clé DOIT être un tableau. Il DEVRAIT inclure au moins un élément. Les éléments DEVRAIENT être uniques. Une instance valide contre ce mot-clé si sa valeur est égale à un des éléments du tableau. Les éléments peuvent être de toute valeur, y compris null. + +#### type + +La valeur de ce mot-clé DOIT être une chaîne ou un tableau. Si c’est un tableau, les éléments DOIVENT être des chaînes uniques. Les chaînes DOIVENT être un des six types primitifs (null, boolean, object, array, number, ou string), ou integer pour les entiers. Une instance valide si et seulement si elle fait partie de l’un des ensembles listés pour ce mot-clé. + +Cette spécification utilise le type string pour tous les types de base et d’éléments, mais applique des restrictions avec des expressions régulières via `patterns`. Les types complexes sont des objets et contiennent des propriétés de type élément ou objet à leur tour. Les types array servent à spécifier des listes, actuellement seulement utilisées dans des types complexes. + +### Mots-clés de métadonnées + +Cette section décrit les champs utilisés dans les définitions JSON des types. Elle précise si un champ DOIT être présent dans la définition et s’il est associé à un type de données principal. + +#### definitions + +La valeur de ce mot-clé DOIT être un objet. Chaque membre DOIT être un schéma JSON valide. Ce mot-clé ne joue pas de rôle dans la validation. Il offre un emplacement standardisé pour inclure des schémas JSON dans un schéma plus général. + +#### title et description + +La valeur des deux mots-clés DOIT être une chaîne. Ces deux mots-clés peuvent fournir à une interface utilisateur des informations sur les données produites. Un titre sera de préférence court, tandis qu’une description expliquera le but de l’instance décrite. + +### Instance et $ref + +Deux mots-clés, **Instance** et **$ref** sont utilisés dans les définitions JSON Schema ou les règles de transformation dans ce document, décrits dans [Instance](#instance) et [Références de Schéma avec $ref](#schema-references-with-$ref-keyword). `Instance` n’est pas utilisé dans la Spécification Open API ; ce terme sert à décrire des règles de validation et de transformation dans ce document. `$ref` contient une URI comme référence à d’autres types ; il est utilisé dans la Spécification. + +#### Instance + +JSON Schema interprète les documents selon un modèle de données. Une valeur JSON interprétée selon ce modèle est appelée une `instance`[4](http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2). Une instance a un des six types primitifs, et une plage de valeurs selon le type : + +- **null** : Production JSON `null`. + +- **boolean** : Valeur `true` ou `false` de la production JSON. + +- **object** : Ensemble non ordonné de propriétés associant une chaîne à une instance (production object). + +- **array** : Liste ordonnée d’instances (production array JSON). + +- **number** : Nombre décimal en précision arbitraire, base-10, production number. + +- **string** : Suite de points de code Unicode (production string JSON). + +Les espaces et le formatage sont hors du périmètre du JSON Schema. Comme un objet ne peut pas avoir deux propriétés avec la même clé, le comportement d’un document JSON essayant d’avoir deux propriétés de même nom est indéfini. + +#### Références de schéma avec le mot-clé $ref + +Le mot-clé `$ref`[5](http://json-schema.org/latest/json-schema-core.html\#rfc.section.8) sert à référencer un schéma et permet de valider des structures récursives via l’auto-référence. Un objet schéma avec une propriété `$ref` DOIT être interprété comme référence. La valeur de `$ref` DOIT être une référence URI. Concernant l’URI de base courante, elle identifie l’URI d’un schéma à utiliser. Toutes autres propriétés d’un objet `$ref` DOIVENT être ignorées. + +L’URI n’est pas un localisateur réseau, seulement un identifiant. Un schéma n’a pas besoin d’être téléchargeable à partir de l’adresse si c’est une URL réseau, et les implémentations ne DOIVENT PAS effectuer d’opération réseau quand elles rencontrent une URI réseau. Un schéma NE DOIT PAS tourner en boucle infinie sur un schéma. Par exemple, si deux schémas "#alice" et "#bob" ont une propriété "allOf" qui référence l’autre, un validateur naïf pourrait passer en boucle. Les schémas NE DOIVENT PAS utiliser de telles boucles récursives ; le comportement est indéfini. + +On l’utilise avec la syntaxe `"$ref"` et il est mappé à une définition existante. La syntaxe de la valeur `_$ref_`, `#/definitions/`, indique que le type référencé vient de la section Définitions de la Spécification Open API (typiquement, les sections sont Paths, Definitions, Responses et Parameters). Un exemple se trouve en [Liste 26](#listing-26), où les types pour les propriétés _authentication_ et _authenticationValue_ sont fournis par des références vers les types `AuthenticationType` et `AuthenticationValue`. + +### Définitions JSON et exemples + +Les définitions JSON et exemples sont fournis après la plupart des sections définissant les règles de transformation, si pertinent. Ils sont fournis au format JSON, tirés de la version JSON de la Spécification Open API. Les expressions régulières dans les exemples peuvent avoir de petites différences (parfois un ‘**\\**’ supplémentaire) par rapport à celles des règles car les exemples sont issus de la version JSON alors que les règles viennent de la spécification standard Open API (Swagger). Ils sont fournis dans la section concernée sous forme de Liste numérotée. Par exemple, [Liste 1](#listing-1) fournit la version JSON de la définition du type de données `Amount`. + +Pour chaque type de données, une description du schéma JSON extrait de la Spécification Open API et (si pertinent) un exemple pour ce type sont fournis. Après la description du schéma, viennent les règles de transformation qui s’appliquent à une instance de ce type particulier. + +
+ +## Types d’éléments et types de base + +Cette section contient les définitions et règles de transformation pour les formats de base et les types _éléments_ utilisés par l’API comme spécifié dans _API Definition_ et _API Data Model_. Ces définitions sont basiques dans le contexte de la spécification API, mais *pas* dans la spécification technique Open API. Souvent, ces types de données de base sont dérivés des types de base supportés par Open API, comme le type string. + +### Type de données Amount + +Cette section fournit la définition JSON Schema pour le type de données `Amount`. [Liste 1](#listing-1) fournit le schéma JSON pour le type `Amount`. + +- Paire clé-valeur JSON avec Nom "**title**" et Valeur "**Amount**" + +- Paire clé-valeur JSON avec Nom "**type**" et Valeur "**string**" + +- Paire clé-valeur JSON avec Nom "**pattern**" et Valeur "**^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$**" + +- Paire clé-valeur JSON avec Nom "**description**" et Valeur "**Le type de données Amount de l’API est une chaîne JSON dans un format canonique, restreint par une expression régulière pour des raisons d’interopérabilité. Ce format n’autorise pas de zéros en fin, mais permet un montant sans unité mineure de devise. Seules quatre décimales au plus dans l’unité mineure ; aucune valeur négative n’est permise. Pas plus de 18 chiffres dans l’unité majeure.**" + +##### Liste 1 + +```JSON +"Amount": { + "title": "Amount", + "type": "string", + "pattern": + "^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$", + "maxLength": 32, + "description": "Le type de données Amount de l’API est une chaîne JSON dans un format canonique, restreint par une expression régulière pour des raisons d’interopérabilité." +} +``` +**Liste 1 -- JSON Schema pour le type Amount** + +Les règles de transformation pour une instance du type Amount sont les suivantes : + +- Une instance du type `Amount` DOIT être de type string. + +- L’instance DOIT correspondre à l’expression régulière **^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$** + +- La longueur de cette instance est limitée comme ci-dessus à 23, avec 18 chiffres pour l’unité majeure et 4 pour l’unité mineure. Exemples valides : **124.45**, **5, 5.5, 4.4444, 0.5, 0, 181818181818181818** + + diff --git a/docs/fr/technical/api/fspiop/logical-data-model.md b/docs/fr/technical/api/fspiop/logical-data-model.md new file mode 100644 index 000000000..3c4654cc7 --- /dev/null +++ b/docs/fr/technical/api/fspiop/logical-data-model.md @@ -0,0 +1,273 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# Modèle de Données Logique + +## Préface + +Cette section contient des informations sur la façon d'utiliser ce document. + +### Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'informations spécifiés. + +|Type d'information|Convention|Exemple| +|---|---|---| +|**Éléments de l'API, comme les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans le _Glossaire_|Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une opération de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne devraient généralement pas être utilisées par les déploiements API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ doivent être utilisées à la place.| + +### Informations sur la version du document + +|Version|Date|Description du changement| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| + +
+ +## Introduction + +Ce document spécifie le modèle de données logique utilisé par l’API ouverte (Interface de Programmation Applicative) pour l’interopérabilité des Fournisseurs de Services Financiers (FSP) (ci-après appelée « l’API »). + +La section [Éléments de Services](#api-services-elements) répertorie les éléments utilisés par chaque service. + +La section [Modèle de Données de Support](#api-supporting-data-model) décrit le modèle de données en termes d’éléments de base, de types de données simples et de types complexes. + +### Spécification Open API pour l’Interopérabilité des FSP + +La spécification Open API pour l'interopérabilité des FSP inclut les documents suivants. + +#### Documents logiques + +- [Modèle de Données Logique](#) + +- [Modèles de Transaction Génériques](./generic-transaction-patterns) + +- [Cas d’Utilisation](./use-cases) + +#### Documents de liaison REST asynchrone + +- [Définition de l'API](./api-definition) + +- [Règles de liaison JSON](./json-binding-rules) + +- [Règles du scheme](./scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents généraux + +- [Glossaire](./glossary) + +
+ +## Éléments des services de l’API + +Cette section identifie et décrit les éléments utilisés par chaque service. + +### Ressource API : Participants + +Cette section décrit le modèle de données des services pour la ressource **Participants**. + +#### Requêtes + +Cette section décrit le modèle de données des services qui peuvent être demandés par un client à l’API pour la ressource **Participants**. +
+ +##### Recherche d’informations sur un participant + +Le Tableau 1 contient le modèle de données pour _Recherche d’informations sur un participant_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie.| + +**Tableau 1 – Modèle de données de recherche d’informations sur un participant** + +
+ +##### Création d’Informations sur un Participant + +Le Tableau 2 ci-dessous contient le modèle de données pour _Création d’Informations sur un Participant_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) |Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie. | +| **fspId** | 1 | [FspId](#fspid-element) | Identifiant du FSP auquel appartient la Partie. | +| **currency** | 0..1 | [Currency](#currency-element) | Indique que la devise fournie est prise en charge par la Partie. | + +**Tableau 2 – Modèle de données de Création d’Informations sur un Participant** + +
+ +##### Création d’informations groupées sur des participants + +Le Tableau 3 ci-dessous contient le modèle de données pour _Création d’informations groupées sur des participants_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | L’ID de la demande, déterminé par le client. Utilisé pour identifier le rappel du serveur. | +| **partyList** | 1..10000 | [PartyIdInfo](#partyidinfo) | Liste des éléments Party pour lesquels le client souhaite mettre à jour ou créer des informations FSP. | +| **currency** | 0..1 | [Currency](#currency-enum) | Indique que la devise fournie est prise en charge par chaque PartyIdInfo de la liste. | + +**Tableau 3 – Modèle de données de création d’informations groupées sur les participants** + +
+ +##### Suppression d’Informations sur un Participant + +Le Tableau 4 ci-dessous contient le modèle de données pour _Suppression d’Informations sur un Participant_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l’identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie. | + +**Tableau 4 – Modèle de données de Suppression d’Informations sur un Participant** + +
+ +#### Réponses + +Cette section décrit le modèle de données des réponses utilisées par le serveur dans l’API pour les services fournis par la ressource **Participants**. + +##### Retour des Informations sur un Participant + +Le Tableau 5 ci-dessous contient le modèle de données pour _Retour des Informations sur un Participant_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie. | +| **fspId** | 0..1 | [FspId](#fspid-element) | Identifiant du FSP auquel appartient la Partie. | + +**Tableau 5 – Modèle de données de Retour des Informations sur un Participant** + +
+ +##### Retour d’informations groupées sur des participants + +Le Tableau 6 ci-dessous contient le modèle de données pour _Retour d’informations groupées sur des participants_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | L’ID de la demande, déterminé par le client. Utilisé pour identifier le rappel du serveur. | +| **partyList** | 1..10000 | [PartyResult](#partyresult) | Liste des éléments PartyResult pour lesquels la création a été tentée (et a réussi ou a échoué). | +| **currency** | 0..1 | [Currency](#currency-element) | Indique que la devise fournie a été définie comme prise en charge par chaque PartyIdInfo ajouté avec succès. | + +**Tableau 6 – Modèle de données de retour d’informations groupées sur les participants** + +
+ +#### Réponses d’erreur + +Cette section décrit le modèle de données des réponses d'erreur utilisées par le serveur dans l’API pour les services fournis par la ressource **Participants**. + +##### Erreur de Retour d’Informations sur un Participant + +Le Tableau 7 ci-dessous contient le modèle de données pour _Erreur de Retour d’Informations sur un Participant_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Code d’erreur, description de la catégorie. | + +**Tableau 7 – Modèle de données d’Erreur de Retour d’Informations sur un Participant** + +
+ +##### Erreur de retour d’informations groupées sur des participants + +Le Tableau 8 ci-dessous contient le modèle de données pour _Erreur de retour d’informations groupées sur des participants_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | L’ID de la demande, déterminé par le client. Utilisé pour identifier le rappel du serveur. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Code d’erreur, description de la catégorie. | + +**Tableau 8 – Modèle de données d’erreur de retour d’informations groupées sur les participants** + +
+ +### Ressource API : Parties + +Cette section décrit le modèle de données des services pour la ressource **Parties**. + +#### Requêtes + +Cette section décrit le modèle de données des services qui peuvent être demandés par un client dans l’API pour la ressource **Parties**. + +##### Recherche d’informations sur une partie + +Le Tableau 9 ci-dessous contient le modèle de données pour _Recherche d’informations sur une partie_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | Un sous-identifiant ou sous-type pour la Partie. | + +**Tableau 9 – Modèle de données de recherche d’informations sur une partie** + +
+ +#### Réponses + +Cette section décrit le modèle de données des réponses utilisées par le serveur dans l’API pour les services fournis par la ressource **Parties**. + +##### Retour d’Informations sur une Partie + +Le Tableau 10 ci-dessous contient le modèle de données pour _Retour d’Informations sur une Partie_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | Un sous-identifiant ou sous-type pour la Partie. | +| **party** | 1 | [Party](#party) | Informations concernant la Partie demandée. | + +**Tableau 10 – Modèle de données de Retour d’Informations sur une Partie** + +
+ +#### Réponses d’erreur + +##### Erreur de Retour d’Informations sur une Partie + +Le Tableau 11 ci-dessous contient le modèle de données pour _Erreur de Retour d’Informations sur une Partie_. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | Le type de l'identifiant. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | Un identifiant pour la Partie. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | Un sous-identifiant ou sous-type pour la Partie. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Code d’erreur, description de la catégorie. | + +**Tableau 11 – Modèle de données d’Erreur de Retour d’Informations sur une Partie** + +
+ +### Ressource API : demandes de transaction + +_… Etc (CONTINUER pour tout le document en respectant la structure, la terminologie et en traduisant l’anglais vers le français, conserver les noms techniques JSON/tables tels quels, traduire entête, descriptions, colonnes, paragraphes, légendes, intitulés, titres, notes, et ne pas traduire la syntaxe des expressions régulières, noms de champs d’API ou extraits de code)._ + +
+ +_En raison de la longueur et le volume de la documentation, cette traduction doit continuer selon le même schéma pour toutes les autres sections détaillées, en maintenant la fidélité et la clarté pour un public technique francophone._ + diff --git a/docs/fr/technical/api/fspiop/pki-best-practices.md b/docs/fr/technical/api/fspiop/pki-best-practices.md new file mode 100644 index 000000000..fb967c948 --- /dev/null +++ b/docs/fr/technical/api/fspiop/pki-best-practices.md @@ -0,0 +1,700 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- + +# Bonnes pratiques d’infrastructure à clé publique (PKI) + +## Préface + +Cette section contient des informations sur la manière d’utiliser ce document. + +### Conventions Utilisées dans Ce Document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types spécifiques d’informations. + +| Type d’Information | Convention | Exemple | +|---|---|---| +| **Éléments de l’API, comme les ressources** | Gras | **/authorization** | +| **Variables** | Italique entre accolades | _{ID}_ | +| **Termes du glossaire** | Italique à la première occurrence ; défini dans le _Glossaire_ | Le but de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP. | +| **Documents de référence** | Italique | Les informations utilisateur ne devraient, en général, pas être utilisées par les déploiements d’API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ doivent être utilisées à la place. | + +### Informations sur la Version du Document + +| Version | Date | Description du Changement | +|---|---|---| +| **1.0** | 2018-03-13 | Version initiale | + +## Introduction + +Ce document explique les _bonnes pratiques de l’Infrastructure à Clé Publique_ (PKI)1 à appliquer dans un déploiement de l’_Open API pour l’Interopérabilité des FSP_ (ci-après cité comme « l’API »). Voir la section [Contexte PKI](#pki-background) pour plus d’informations à propos de la PKI. + +L’API doit être mise en œuvre dans un environnement composé soit : + +- de _Fournisseurs de Services Financiers_ (FSP) qui communiquent avec d’autres FSP (en configuration bilatérale), ou + +- d’un _Switch_ qui agit comme une plateforme intermédiaire entre les plateformes des FSP. Un _Système de Recherche de Comptes_ (ALS) est également disponible pour identifier dans quel FSP se trouve un titulaire de compte. + +Pour plus d’informations sur l’environnement, voir la section [Topologie du Réseau](#network-topology). [Stratégie de gestion PKI de l’Autorité de Certification](#certificate-authority-pki-management-strategy) et [Stratégie de gestion PKI de la Plateforme](#platform-pki-management-strategy) identifient les stratégies de gestion pour la CA et la plateforme. + +La communication entre plateformes s’effectue en utilisant un protocole HTTP basé sur REST (REpresentational State Transfer) (pour plus d’informations, voir _Définition de l’API_). Ce protocole ne fournit pas de moyen d’assurer l’intégrité ou la confidentialité entre plateformes, il est donc nécessaire d’ajouter des couches de sécurité supplémentaires pour protéger les informations sensibles contre la modification ou l’exposition à des parties non autorisées. + +
+ +### Spécification Open API pour l’Interopérabilité des FSP + +La spécification Open API pour l’Interopérabilité des FSP inclut les documents suivants. + +#### Documents Logiques + +- [Modèle de Données Logique](./logical-data-model) + +- [Modèles de Transactions Génériques](./generic-transaction-patterns) + +- [Cas d’Utilisation](./use-cases) + +#### Documents de Liaison REST Asynchrone + +- [Définition de l’API](./api-definition) + +- [Règles de Liaison JSON](./json-binding-rules) + +- [Règles du système](./scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes pratiques PKI](#) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents Généraux + +- [Glossaire](./glossary) + +
+ + +## Contexte PKI + +L’infrastructure à clé publique (PKI) est un ensemble de normes, procédures et logiciels permettant la mise en œuvre de l’authentification par cryptographie à clé publique. La PKI est utilisée pour demander, installer, configurer, gérer et révoquer des certificats numériques. La PKI fournit l’authentification via des certificats numériques ; ces certificats sont signés et fournis par des _Autorités de Certification_ (CA). + +La PKI utilise la cryptographie à clé publique et fonctionne avec des certificats conformes à la norme X.509. Elle offre également des fonctionnalités telles que : + +- Authentification de l’utilisateur + +- Production et distribution de certificats + +- Maintien, gestion et révocation des certificats + +La PKI est constituée de plusieurs composants qui permettent à l’infrastructure de fonctionner ; ce n’est pas un processus ou algorithme unique. Outre l’authentification, la PKI permet également de garantir l’intégrité, la non-répudiation et le chiffrement. + +Pour obtenir une clé publique, une entité doit obtenir un certificat numérique. Cette dernière doit demander ce certificat à une CA ou à une _Autorité d’Enregistrement_ (RA) - une organisation qui traite des demandes au nom d’une CA. Tous les participants doivent faire confiance à la CA pour gérer et maintenir les certificats. La CA exige que l’entité fournisse plusieurs informations (_Common Name_ (CN), _Organization_ (O), _Country_ (C), etc.) et valide leur demande avant de fournir le certificat. Ce certificat est la preuve que l’entité est bien celle qu’elle prétend être dans le monde numérique (comme un passeport dans le monde réel). + +La PKI se combine bien avec une _solution Diffie-Hellman_ (un mécanisme sécurisé pour l’échange d’une clé symétrique partagée entre deux pairs anonymes) pour fournir des échanges de clés sécurisés. Parce que Diffie-Hellman n’offre pas d’authentification, la PKI est utilisée avec des protocoles supplémentaires, tels que _Pretty Good Privacy_ (PGP) et _Transport Layer Security_ (TLS). + +### Protection en Couches + +L’API doit être utilisée avec une protection au niveau du transport et au niveau applicatif. + +#### Protection au Niveau du Transport + +Pour protéger le niveau de transport, _Transport Layer Security_2 (TLS) doit être utilisé. TLS est une technique fondamentale pour sécuriser la communication point à point. Elle s’est avérée stable et sûre lors de l’utilisation d’algorithmes robustes avec les versions les plus récentes, et son usage est largement répandu. TLS est un mécanisme sécurisé pour échanger une clé symétrique partagée entre deux pairs anonymes, avec vérification d’identité (c’est-à-dire via des certificats de confiance). Cela garantit la _confidentialité_ (personne n’a lu le contenu) et l’_intégrité_ (personne n’a modifié le contenu). Une bonne utilisation de TLS nécessite une gestion des certificats. + +#### Protection au Niveau Applicatif + +Cette couche assure l’intégrité et la confidentialité de bout en bout. L’API utilise le standard _JSON Web Signature_3 (JWS) pour l’intégrité et la _non-répudiation_ (preuve de l’intégrité et de l’origine des données), et le standard JSON Web Encryption (JWE)4 pour la confidentialité. Une version étendue de JWE est utilisée pour prendre en charge le chiffrement au niveau des champs. + +L’utilisation de ces standards nécessite la gestion de certificats ; par conséquent, les _Autorités de Certification_ (CA) et les techniques PKI associées sont nécessaires. Pour plus d’informations, voir le Contexte PKI. + +## Topologie du Réseau + +Cette section identifie les plateformes constituant l’API. + +### Disposition Point-à-Point des Plateformes + +La Figure 1 montre un exemple de disposition point-à-point des plateformes. + +![Figure1 Platforms Layout](../assets/figure1-platforms-layout.svg) + +**Figure 1 - Disposition des plateformes** + +Toute la communication entre plateformes doit être sécurisée par TLS utilisant l’_authentification client_, aussi connue sous le nom d’_authentification mutuelle_. + +### Rôles des Plateformes + +#### Autorité de Certification (CA) + +La CA réalise les fonctions suivantes : + +- Signature des _demandes de signature de certificat_ (CSR) – Les CSR sont un mécanisme sécurisé pour l’échange d’une clé symétrique partagée entre deux pairs anonymes. La CA signe différents types de certificats (par exemple, TLS, signature de contenu, chiffrement de contenu). + +- Révocation des certificats – Marquer un ou plusieurs certificats comme non valides. + +- Support des CRL – Maintenir et fournir des listes de révocation de certificats (CRL) à télécharger afin que les clients puissent voir les certificats révoqués. + +- Support du protocole OCSP – Fournir des vérifications de révocation en temps réel. + +#### Système de Recherche de Comptes (ALS) + +- Stocke les informations de base sur les titulaires de compte. + +- Répond à des questions telles que : « Où dois-je envoyer ma demande de transaction financière pour le titulaire du compte **MSISDN 0123456** ? » + +#### Fournisseur de Services Financiers (FSP) + +Détient les comptes des titulaires vers lesquels ou depuis lesquels l’argent est transféré. + +#### Switch + +- Relaie les informations de transaction vers d’autres plateformes. + +- Peut exécuter des services financiers, comme spécifié dans la _Définition de l’API_. + +## Stratégie de Gestion de la PKI de la CA + +Cette section décrit la stratégie de gestion PKI pour les Autorités de Certification. + +### Importance de la CA et Critères de Sélection + +Le rôle de la CA est important car : + +- La CA fournit une seule entité légale de confiance pour toutes les plateformes. + +- Le protocole TLS point à point dépend des certificats. + +- Les protocoles de bout en bout JWS et JWE dépendent des certificats pour la preuve de non-répudiation et de confidentialité. + +#### Raisons de Ne Pas Utiliser une CA Publique + +- Une CA publique peut révoquer le certificat intermédiaire utilisé pour signer vos certificats, interrompant ainsi toute communication entre les plateformes. + +- Une CA publique signe également des certificats qui ne font pas partie du dispositif _Open API pour l’Interopérabilité des FSP_. Parce que vous faites confiance au certificat signé, vous faites confiance à tous les certificats signés par cette CA. + +- Aucun service de l’API n’est ouvert au public ; il n’y a donc aucune raison d’utiliser une CA publique déjà approuvée par les clients publics (tels que les navigateurs web). + +#### Options pour une CA Privée + +- Construire sa propre CA depuis zéro + +- Construire une CA à l’aide d’outils existants (par exemple, _openssl_) + +- Utiliser une CA complète (par exemple, le produit open source _EJBCA_) + +### Chaîne de Certificats de Confiance + +Une CA centralisée facilite la gestion des certificats pour les plateformes impliquées. En approuvant le certificat de la même CA, chaque plateforme n’a qu’un seul certificat à approuver : le certificat racine auto-signé de la CA. + +La CA doit signer tous les types de certificats (TLS, signature et chiffrement), mais uniquement pour les participants du dispositif _Open API pour l’Interopérabilité des FSP_. + +Aucun certificat CA intermédiaire n’est nécessaire car une disposition segmentée n’est pas utilisée dans ce cadre. + +### Certificat Racine de la CA + +- La CA doit créer un certificat racine auto-signé pour signer tous les types de certificats pris en charge (TLS, signature et chiffrement). + +- La longueur minimale de la clé RSA asymétrique est de 4096 bits, et l’algorithme de signature doit être sha512WithRSAEncryption. + +- Les _contraintes de base X.509_ doivent avoir l’attribut **CA** positionné à **TRUE**. + +- La durée de validité du certificat racine doit être de dix ans. Après huit ans, un nouveau certificat racine auto-signé doit être créé par la CA ; la paire de clés RSA asymétriques doit être recréée, et non réutilisée. Ce certificat sert alors à signer les CSR des plateformes. Cependant, l’ancien certificat racine reste actif jusqu’à expiration, ce qui laisse deux ans aux plateformes pour changer de certificat racine sans perturber les communications sécurisées en cours. + +### Signature des CSR des Plateformes + +La CA doit fournir un mécanisme permettant aux plateformes de faire signer leurs CSR. Les méthodes de signature courantes sont l’e-mail et une page web. La solution et la politique choisies doivent être connues des plateformes. + +La CA signe trois types de certificats : TLS (pour la communication), JWS (pour la signature) et JWE (pour le chiffrement). Exigences communes : + +- Longueur minimale de la clé RSA asymétrique : 2048 bits, algorithme de signature : sha256WithRSAEncryption. + +- Les contraintes de base X.509 doivent avoir **CA** à **FALSE**. + +- Les DN du sujet doivent inclure au moins les attributs suivants : + + - _Nom Commun_ (CN) : doit être le nom d’hôte de la plateforme qui a créé le certificat. Un CN ne peut jamais être identique pour deux plateformes ou organisations différentes. + + - _Organisation_ (O) : le nom de l’organisation. + + - _Pays_ (C) : le pays de l’organisation. + +- L’URL permettant de télécharger les CRL doit être présente. + +- L’URL d’envoi des requêtes OCSP doit être présente. + +- La durée de validité doit être de deux ans. + +En fonction du type de certificat à signer, les usages de la clé X.509 et les usages étendus X.509 diffèrent ; voir Tableau 1. + +| Type de Certificat | Usage de Clé X.509 | Usage Étendu de Clé X.509 | +| --- | --- | --- | +| **Certificats TLS** | Signature numérique, chiffrement de clé | Authentification TLS serveur web, authentification TLS client web | +| **Certificats de Signature** | Signature numérique | | +| **Certificats de Chiffrement** | Chiffrement de clé | | + +**Tableau 1 – Types de certificats et usages de clé** + +### Révocation des Certificats + +- La CA doit être capable de révoquer les certificats d’une plateforme. Révoquer un certificat signifie qu’il n’est plus approuvé par aucune partie. Il sera marqué comme invalide par la CA et son état de révocation publié aux plateformes, soit par une liste de révocation (CRL) téléchargeable, soit via une requête HTTP en temps réel utilisant le _protocole OCSP_. + +- La CA doit permettre à la fois le téléchargement de CRL et les requêtes OCSP. + +- La CA doit mettre à jour et signer la CRL quotidiennement et fournir (chaque jour) une URL HTTP permettant aux plateformes de télécharger la CRL. Cette URL doit être stockée dans les _points de distribution CRL_ de chaque certificat signé. + +- L’URL OCSP doit être présente dans l’_Authority Information Access_ de chaque certificat signé. Une réponse OCSP doit être signée. Les valeurs de nonce dans une requête OCSP doivent être prises en charge pour éviter les attaques par rejeu. + +- La CA a le droit de révoquer les certificats, mais n’a pas l’obligation d’informer les plateformes. Les plateformes n’ont pas le droit de révoquer des certificats, mais elles ont l’obligation de vérifier régulièrement leur état de révocation. + +### Enrôlement et Renouvellement de Certificats + +La CA n’accepte pas l’enrôlement ou le renouvellement de certificats pour lesquels une paire de clés asymétriques est réutilisée. Pour plus de sécurité, la paire de clés doit être recréée à chaque enrôlement ou renouvellement via un nouveau CSR. + +## Stratégie de Gestion PKI de la Plateforme + +Cette section décrit la stratégie de gestion PKI pour les plateformes. + +### Clés, Certificats et Magasins + +Un certificat fournit l’identité de son propriétaire via une CA de confiance qui l’a signé. Cela peut être validé via la chaîne de certificats. Il permet également d’assurer l’intégrité (signature) et la confidentialité (chiffrement) des données en utilisant sa paire de clés asymétriques (_clé publique et clé privée_). La clé publique est dans le certificat signé ; la clé privée doit être protégée et maintenue confidentielle. Une solution courante consiste à stocker certificats et clés privées dans un magasin protégé. Ce magasin peut être un fichier, un répertoire ou tout autre espace offrant accès et confidentialité. + +Une seule clé privée et son certificat associé peuvent servir à toutes les tâches cryptographiques, mais pour renforcer la sécurité, chaque plateforme doit disposer des éléments suivants : + +- Une clé privée et un certificat pour la communication TLS + +- Une clé privée et un certificat pour l’intégrité de bout-en-bout avec JWS + +- Une clé privée et un certificat pour la confidentialité de bout-en-bout avec JWE + +Différentes clés et types de certificats peuvent être dans le même magasin, mais une configuration courante est la suivante : + +- Pour la communication TLS : + + - Un magasin de clés protégé (key store) pour stocker la clé privée, son certificat associé et la chaîne de certificats, utilisés lors de l’authentification serveur et client en TLS. + + - Un magasin de certificats protégé pour stocker les certificats TLS de confiance. Ces certificats seront approuvés lors de la poignée de main TLS, permettant de communiquer avec leurs détenteurs. Comme tous les participants font confiance à la même CA, il suffit d’y placer le certificat racine de la CA. + +- Pour la signature et le chiffrement : + + - Un magasin de clés protégé pour stocker les clés privées, leurs certificats associés et les chaînes de certificats utilisés pour signer et chiffrer. + + - Une clé privée et chaîne de certificats pour la signature JWS, et une autre pour le chiffrement JWE. + + - Un magasin de certificats protégé pour les certificats de signature et chiffrement de confiance d’autres plateformes. On y stocke les certificats de chaque plateforme à laquelle vous souhaitez faire confiance pour l’intégrité/confidentialité de bout à bout. + +### Création d’un CSR et Obtention de la Signature de la CA + +Pour communiquer avec les autres plateformes, vous devez créer un magasin de clés (s’il n’existe pas déjà), une paire de clés asymétriques et un certificat associé identifiant votre plateforme. Ce certificat non signé doit être signé par la CA pour être approuvé. La procédure commence par une demande de signature de certificat (CSR). + +Lors de la création de vos clés, certificats et CSR, les exigences suivantes s’appliquent : + +- Longueur minimale de la clé RSA asymétrique : 2048 bits, algorithme de signature : sha256WithRSAEncryption. + +- Les champs suivants dans le nom distingué du sujet sont obligatoires : + + - Common Name (CN) : doit être le nom d’hôte de la plateforme. Un CN ne doit pas être utilisé pour deux plateformes ou organisations différentes. + + - Organization (O) : nom de l’organisation. + + - Country (C) : pays de l’organisation. + +**Pour des exemples de création de magasin, de certificat et de CSR, voir Annexe C – Tâches PKI courantes** + +Créer votre CSR et l’envoyer à votre CA conformément à leurs instructions. + +**Remarque :** La même procédure doit être réalisée pour toutes vos clés et certificats (TLS, signature et chiffrement). + +### Importation d’un CSR Signé + +Après la signature de votre CSR, vous recevrez deux certificats dans la réponse de la CA. Le premier est votre certificat signé. Le second est le certificat racine de la CA qui a servi à la signature. Vous devez approuver ce certificat. + +D’abord, importez votre certificat signé dans votre magasin de clés (il doit remplacer l’ancien non signé ; voir les exemples pour importer un certificat signé). + +Ensuite, importez le certificat racine de la CA dans le même magasin pour compléter la chaîne entre votre certificat et la CA (voir les exemples pour importer le certificat de la CA). + +#### Certificats TLS + +Pour les certificats TLS, vous devez également importer le certificat racine de la CA dans le magasin de confiance TLS pour approuver automatiquement les autres plateformes lors de l’établissement de nouveaux canaux. Voir exemples pour l’import dans le trust store. + +La procédure ci-dessus doit être répétée pour chaque CSR signé. Rappelez-vous d’envoyer votre certificat et le certificat racine de la CA à toutes les autres plateformes avec lesquelles vous devez communiquer. + +La CA créera une période de validité de deux ans pour chaque certificat signé. Après 18 mois, générez un nouveau CSR à faire signer par la même CA. Le certificat et le certificat racine de la CA doivent de nouveau être importés dans vos magasins et envoyés aux autres plateformes. Cela accorde à chacun une fenêtre de six mois pour s’assurer que le nouveau certificat fonctionne. Après deux ans, l’ancien certificat expiré peut être supprimé. + +### Approuver les Certificats des Autres Plateformes + +De même que vos pairs doivent avoir vos certificats pour vous faire confiance, ils doivent vous envoyer les leurs pour que vous les approuviez. + +Assurez-vous de toujours recevoir au moins deux certificats de tout pair : + +- Le certificat signé du pair à approuver + +- Le certificat racine de la CA qui l’a signé + +**Remarque :** Le certificat CA d’un pair peut être différent du vôtre si la CA a créé un nouveau certificat racine avant expiration de l’ancien. + +Examinez toujours les certificats reçus (vérifiez le CN, la période de validité, etc.) et validez la chaîne (chaque certificat est bien signé par la bonne CA) avant de les importer dans votre magasin. + +Pour des exemples, voir comment visualiser un certificat. + +Importez ensuite le certificat et le certificat racine de la CA du pair dans votre magasin de confiance (voir les exemples pour importer un certificat approuvé). + +### Vérification de l’État de Révocation des Certificats + +Les certificats peuvent être révoqués par la CA. Un certificat révoqué n’est plus approuvé et doit être supprimé du magasin de confiance. Un certificat peut aussi être _en attente_ (« on hold »), c’est-à-dire en cours d’investigation, et ne doit pas être supprimé. + +Toutes les plateformes doivent effectuer régulièrement des vérifications de révocation. Deux méthodes courantes existent : utiliser une liste CRL téléchargée ou une requête HTTP en temps réel (OCSP). + +#### Liste de Révocation (CRL) + +Il s’agit d’un fichier maintenu par la CA, contenant la liste des numéros de série des certificats révoqués. Le fichier peut être téléchargé par toute plateforme à tout moment. L’URL de la CRL est incluse dans le certificat lui-même (_CRL Distribution Points_). Une CRL est signée et doit être validée. + +Une CRL doit être téléchargée chaque jour et mise en cache par la plateforme. + +Voir exemples pour la vérification via CRL. + +#### Protocole OCSP + +L’état d’un certificat peut être obtenu via une requête OCSP à un _OCSP Responder_ (souvent la CA). La requête contient le numéro de série du certificat ; la réponse renvoie l’état, signée. + +La requête doit contenir une valeur de nonce que le répondeur retournera afin que la plateforme la valide à la réception. Ceci empêche les attaques par rejeu. + +Une requête/réponse OCSP est très rapide et peut être réalisée pour chaque opération de certificat client, mais selon la charge, elle peut être mise en cache. + +L’URL OCSP est présente dans _Authority Information Access_. + +Voir exemples de vérification via une requête OCSP. + +### Renouvellement des Certificats + +Ne renouvelez pas les certificats réutilisant la même paire de clés. Pour la sécurité, la paire de clés doit être recréée à chaque fois via une nouvelle CSR. + +## Protection de la Couche de Transport + +Cette section décrit la protection de la couche de transport. + +### TLS + +TLS assure l’intégrité et la confidentialité point à point et doit être utilisé pour toute communication entre pairs. + +La configuration requiert _l’authentification serveur_ (le serveur se présente avec son certificat TLS) et _l’authentification client_ (ou mutuelle), le client présentant aussi son certificat TLS. + +#### Versions de TLS + +La version minimale requise de TLS est 1.2 ou supérieure. + +#### Suites de Chiffrement TLS + +Les suites de chiffrement suivantes doivent être utilisées : + +- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_RSA_WITH_AES_128_GCM_SHA256 + +## Protection de la Couche Applicative + +Cette section décrit la protection de la couche applicative. + +### JSON Web Signature + +Le standard _JSON Web Signature_ (JWS) est utilisé pour garantir l’intégrité et la non-répudiation de bout en bout : il assure que l’expéditeur est bien celui indiqué et que le message n’a pas été altéré. + +L’utilisation de JWS est obligatoire et les certificats doivent être utilisés. Voir _Signature API_ pour plus d’informations. + +### JSON Web Encryption + +Le standard _JSON Web Encryption_ (JWE) est utilisé pour assurer la confidentialité de bout en bout, c’est-à-dire protéger les données contre toute lecture non autorisée. + +L’utilisation de JWE est optionnelle et appliquée sur des champs spécifiques, pour répondre à des exigences réglementaires pouvant exister selon le type de données ou le pays. + +Pour plus d’informations sur l’application de JWE aux champs, voir la spécification avancée _API Encryption_. + + +## Liste des Annexes + +### Annexe A – Tailles de Clé et Algorithmes + +Le tableau 2 présente la longueur des clés et l’algorithme requis pour chaque entité. + +| Entité | Algorithme | Taille de clé/hash | +| --- | --- | --- | +| Clés asymétriques CA | RSA | 4096 bits | +| Algorithme de signature CA | RSA avec SHA2 | >= 256 bits | +| Clés asymétriques TLS | RSA | 2048 bits | +| Algorithme de signature TLS | RSA avec SHA2 | >= 256 bits | +| Clés asymétriques de signature | RSA | 2048 bits | +| Algorithme de signature | RSA avec SHA2 | >= 256 bits | +| Clés asymétriques de chiffrement | RSA | 2048 bits | +| HMAC | SHA2 - AES | >= 256 bits| +| Clés symétriques | AES | 256 bits | +| Hachage | SHA2 | >= 256 bits | + +**Tableau 2 – Tailles de clé et algorithmes** + +### Annexe B – Terminologie + +| | | +| --- | --- | +| PKI | Infrastructure à Clé Publique +| API | Interface de Programmation Applicative +| TLS | Transport Layer Security (Sécurité de la couche de transport) +| JWS | JSON Web Signature +| JWE | JSON Web Encryption +| FSP | Fournisseur de Services Financiers +| AL | Account Lookup (Recherche de comptes) +| CA | Autorité de Certification +| CSR | Certificate Signing Request (Demande de Signature de Certificat) +| CRL | Certificate Revocation List (Liste de révocation de certificats) +| OCSP | Online Certificate Status Protocol +| PEM | Privacy Enhanced Mail +| RSA | Rivest, Shamir, & Adleman +| HMA | Hashed Message Authentication Code +| AES | Advanced Encryption Standard +| SHA | Secure Hash Algorithm + +### Annexe C – Tâches PKI Courantes + +#### Annexe C.1 – Création d’un magasin, d’un certificat, et d’une CSR + +**Avec Java keytool** + +Utilisez la commande suivante pour créer une paire de clés asymétriques RSA et les informations de certificat associées à faire signer par la CA. Elle crée automatiquement un keystore JKS si le fichier indiqué n’existe pas : + +``` +keytool -genkey -dname "CN=" -alias -keyalg RSA - +keystore -keysize 2048 +``` + +**Exemple :** + +``` +keytool -genkey -dname "CN=bank-fsp" -alias tlscert -keyalg RSA -keystore +tlskeystore.jks -keysize 2048 +``` + +**Notes :** + +1. L’attribut CN indique le nom d’hôte qui s’authentifie avec ce certificat lors d’une session TLS. +2. Lorsque vous êtes invité à saisir un mot de passe, utilisez le même pour la clé et le keystore. + +Utilisez la commande suivante pour créer la CSR à signer par la CA : + +``` +keytool -certreq -alias -keystore –file .csr +``` + +**Exemple :** + +``` +keytool -certreq -alias tlscert -keystore tlskeystore.jks -file tlscert.csr +``` + +**Avec openssl** + +Pour créer une paire de clés RSA et une CSR : + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=" -out +.csr -keyout .key +``` + +**Exemple :** + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=bank-fsp" -out tlscert.csr - +keyout tlscert.key +``` + +**Note :** L’attribut CN indique le nom d’hôte utilisé pour s’identifier lors d’une session TLS. + +Remarque : la clé privée créée est non chiffrée. Utilisez la commande suivante pour le chiffrer : + +``` +openssl rsa -aes256 -in -out +``` + +**Exemple :** + +``` +openssl rsa -aes256 -in tlscert.key -out tlscert_encrypted.key +``` + +#### Annexe C.2 – Importer un certificat signé dans votre keystore + +**Avec Java keytool** + +Importez le certificat signé dans votre keystore. Il doit remplacer l’ancien certificat non signé, donc veillez à utiliser le bon alias. + +``` +keytool -importcert -alias -file -keystore +``` + +**Exemple :** + +``` +keytool -importcert -alias tlscert -file bank-fsp.pem -keystore tlskeystore.jks +``` + +**Avec openssl** + +Supprimez votre ancien CSR et remplacez-le par le nouveau certificat signé. + +#### Annexe C.3 – Importer le certificat CA dans votre keystore + +**Avec Java keytool** + +Importez le certificat CA dans votre keystore : + +``` +keytool -importcert -alias -file -keystore +``` + +**Exemple :** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlskeystore.jks +``` + +Lorsque vous êtes invité à confirmer la confiance : + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Avec openssl** + +Placez le certificat CA avec les autres fichiers de certificats. + +#### Annexe C.4 – Importer le certificat CA dans le trust store TLS + +**Avec Java keytool** + +Importez le certificat CA dans votre trust store : + +``` +keytool -importcert -alias -file -keystore +``` + +**Exemple :** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlstruststore.jks +``` + +Puis : + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` +**Avec openssl** + +Placez le certificat CA avec vos autres certificats. + +#### Annexe C.5 – Visualiser un certificat + +**Avec Java keytool** + +Listez tous les certificats du keystore dans un format lisible : + +``` +keytool -list -keystore -v +``` + +**Exemple :** + +``` +keytool -list -keystore tlskeystore.jks -v +``` + +**Avec openssl** + +Affichez le contenu lisible d’un certificat PEM : + +``` +openssl x509 -in -text -nout +``` + +**Exemple :** + +``` +openssl x509 -in rootca.pem -text -nout +``` + +#### Annexe C.6 – Importer un certificat approuvé + +**Avec Java keytool** + +Importez le certificat dans le trust store : + +``` +keytool -importcert -alias -file -keystore +``` + +**Exemple :** + +``` +keytool -importcert -alias trustedcert -file cert.pem -keystore truststore.jks +``` + +Puis : + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Avec openssl** + +Placez le certificat approuvé avec vos autres certificats. + +#### Annexe C.7 – Vérifier un certificat via une CRL + +**Avec Java** + +Vous pouvez utiliser une bibliothèque comme Bouncy Castle ou le support natif, voir : [https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006](#https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006) + +**Avec openssl** + +Exemple : [https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html](#https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html) + +#### Annexe C.8 – Vérifier un certificat via une requête OCSP + +**Avec Java** + +Exemples : [https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate](#https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate) + +**Avec openssl** + +Exemple : [https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html](#https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html) + + +1 Ce terme, ainsi que d’autres termes en italique, sont définis dans le Glossaire de la spécification Open API pour l’Interopérabilité des FSP. + +2 [https://tools.ietf.org/html/rfc5246](#https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + +3 [https://tools.ietf.org/html/rfc7515](#https://tools.ietf.org/html/rfc7515) - JSON Web Signature (JWS) + +4 [https://tools.ietf.org/html/rfc7516](#https://tools.ietf.org/html/rfc7516) - JSON Web Encryption (JWE) + +
+ +## Table des Figures + +- [Figure 1 - Disposition des plateformes](#platforms-point-to-point-layout) + +
+ +## Tableaux + +- [Tableau 1 – Types de certificats et usages de clé](#Table-1–Certificate-type-and-key-usage) + +- [Tableau 2 – Tailles de clé et algorithmes](#Table-2-Key-lengths-and-algorithms) \ No newline at end of file diff --git a/assets/diagrams/.gitkeep b/docs/fr/technical/api/fspiop/sandbox.md similarity index 100% rename from assets/diagrams/.gitkeep rename to docs/fr/technical/api/fspiop/sandbox.md diff --git a/docs/fr/technical/api/fspiop/scheme-rules.md b/docs/fr/technical/api/fspiop/scheme-rules.md new file mode 100644 index 000000000..4df799df0 --- /dev/null +++ b/docs/fr/technical/api/fspiop/scheme-rules.md @@ -0,0 +1,217 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- +# Règles du système + +## Préface + +Cette section contient des informations sur l’utilisation de ce document. + +### Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d’informations spécifiés. + +|Type d’information|Convention|Exemple| +|---|---|---| +|**Éléments de l’API, comme les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans le _Glossaire_|Le but de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne devraient généralement pas être utilisées par les déploiements API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ doivent être utilisées à la place.| + +### Informations sur la version du document + +|Version|Date|Description du changement| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| + +## Introduction + +Ce document définit les règles du système pour l’Open API d’Interopérabilité FSP (ci-après appelée l’API) dans trois catégories. + +1. Règles du système métier : + + a. Ces règles métier doivent être régies par les FSP et, éventuellement, par une autorité de régulation mettant en œuvre l’API dans le cadre d’un système. + + b. L’autorité réglementaire ou l’autorité de mise en œuvre doit identifier les valeurs valides pour ces règles du système métier dans son document de politique API. + +2. Règles du système de mise en œuvre de l’API : + + a. Ces paramètres API doivent être convenus entre les FSP et, éventuellement, le Switch. Ces paramètres doivent faire partie de la politique de mise en œuvre du système. + + b. Tous les participants doivent configurer ces paramètres API comme indiqué par les règles du système de niveau API pour la mise en œuvre avec laquelle ils travaillent. + +3. Règles du système de sécurité et non fonctionnelles : + + a. Les règles du système de sécurité et non fonctionnelles doivent être déterminées et identifiées dans la politique de mise en œuvre du système. + +
+ +### Spécification Open API pour l’Interopérabilité des FSP + +La spécification Open API pour l’interopérabilité des FSP inclut les documents suivants. + +#### Documents logiques + +- [Modèle de Données Logique](./logical-data-model) + +- [Modèles de Transaction Génériques](./generic-transaction-patterns) + +- [Cas d’Utilisation](./use-cases) + +#### Documents de liaison REST asynchrone + +- [Définition de l’API](./api-definition) + +- [Règles de Liaison JSON](./json-binding-rules) + +- [Règles du système](#) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes Pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](./v1.1/encryption) + +#### Documents généraux + +- [Glossaire](./glossary) + +
+ +## Règles du système Métier + +Cette section décrit les règles du système métier. Le modèle de données des paramètres de cette section se trouve dans la _Définition de l’API_. + +#### Type d’Authentification + +La règle du système de type d’authentification contrôle les types d’authentification OTP et QR code. Elle énumère les différents types d’authentification disponibles pour l’authentification du _Payeur_. Le système peut choisir de prendre en charge tous les types d’authentification mentionnés dans “AuthenticationTypes” dans la _Définition de l’API_ ou un sous-ensemble de ceux-ci. + +#### Identification KYC Consommateur Requise + +Le système peut imposer la vérification de l’identification KYC (Know Your Customer) du consommateur par un Agent ou un Marchand au moment de la transaction (par exemple, retrait, dépôt, paiement marchand). L’API ne peut pas contrôler cette règle du système ; cela doit donc être documenté dans la politique du système afin que cette règle soit suivie par tous les participants. Le système peut également décider des preuves d’identification KYC valides qui doivent être acceptées par tous les FSP. + +#### Devise + +Le système peut recommander de permettre des transactions dans plusieurs devises. Le système peut définir la liste des devises valides dans lesquelles les transactions peuvent être effectuées par les participants ; cependant ce n’est pas obligatoire. Un Switch peut agir en tant que routeur de transaction et ne valide pas la devise de la transaction. Si un système ne définit pas la liste des devises valides, alors le Switch joue ce rôle et le FSP participant peut accepter ou rejeter la transaction selon les devises qu’il prend en charge. Le change de devises n’est pas pris en charge ; c’est-à-dire que la devise de transaction du Payeur et du _Bénéficiaire_ doit être la même. + +#### Format d’ID FSP + +Le système peut déterminer le format de l’ID FSP. L’ID FSP doit être de type chaîne de caractères. Chaque participant recevra un ID FSP unique attribué par le système. Chaque FSP doit préfixer l’ID FSP au code marchand (identifiant unique du marchand) afin que le code marchand soit unique parmi tous les participants (c’est-à-dire dans l’ensemble du système). Le système peut également déterminer une stratégie alternative pour garantir l’unicité des identifiants FSP et des codes marchands à travers les FSP participants. + +#### Type de Transaction d’Interopérabilité + +L’API prend en charge les cas d’utilisation documentés dans _Cas d’Utilisation_. Le système peut recommander la mise en œuvre de tous les cas d’usages pris en charge ou d’un sous-ensemble d’entre eux. Le système peut aussi recommander de déployer des cas d’utilisation en plusieurs phases. Deux FSP ou plus du système peuvent décider de mettre en œuvre d’autres cas d’usage pris en charge par l’API. Un Switch peut agir en tant que routeur de transaction et ne valide pas le type de transaction ; le FSP peut accepter ou rejeter la transaction en fonction des types de transaction qu’il prend en charge. Si un FSP participant initie un type de transaction API pris en charge en raison d’une mauvaise configuration côté Payeur, alors la transaction doit être rejetée par le FSP pair si celui-ci ne prend pas en charge ce type de transaction spécifique. + +#### Géo-Localisation Requise + +L’API prend en charge la géolocalisation du Payeur et du Bénéficiaire ; cependant, cela est optionnel. Le système peut imposer la géolocalisation des transactions. Dans ce cas, tous les participants doivent transmettre la géolocalisation de leur partie respective. + +#### Paramètres d’Extension + +L’API prend en charge un ou plusieurs paramètres d’extension. Le système peut recommander que la liste des paramètres d’extension soit prise en charge. Tous les participants doivent se conformer à la règle du système et prendre en charge les paramètres d’extension obligatoires du système. + +#### Format du Code Marchand + +L’API prend en charge la transaction de paiement marchand. Généralement, un consommateur saisit ou scanne un code marchand pour initier un paiement marchand. Dans le cas d’un paiement marchand, le code marchand doit être unique dans tous les systèmes. Actuellement, le code marchand n’est pas unique comme le sont les numéros de mobile ou les adresses email. Il est donc recommandé de préfixer ou suffixer le code marchand (avec l’ID FSP) afin que celui-ci soit unique à travers les FSP. + +#### Taille maximale des paiements groupés + +L’API prend en charge le cas d’utilisation du paiement groupé. Le système peut définir le nombre maximal de transactions dans un paiement groupé. + +#### Longueur de l’OTP + +L’API prend en charge le mot de passe à usage unique (OTP) comme type d’authentification. Le système peut définir la longueur minimale et maximale de l’OTP à utiliser par tous les FSP. + +#### Délai d’expiration de l’OTP + +Le délai d’expiration d’un OTP est configuré par chaque FSP. Le système peut recommander qu’il soit uniforme pour tous les systèmes afin que les utilisateurs des différents FSP aient une expérience homogène. + +#### Types d’ID de Partie + +L’API prend en charge le système de recherche de compte. Une recherche de compte peut être effectuée sur la base de types valides d’ID de partie. Le système peut choisir les types d’ID de partie à prendre en charge à partir de **PartyIDType** dans la Définition de l’API. + +#### Types d’Identifiant Personnel + +Le système peut choisir les types d’identifiant personnel valides ou pris en charge mentionnés dans **PersonalIdentifierType** dans la Définition de l’API. + +#### Format du Code QR + +Le système doit standardiser le format du code QR dans les deux scénarios suivants : + +##### Transaction initiée par le Payeur + +Le Payeur scanne le code QR du Bénéficiaire (Marchand) pour initier une transaction initiée par le payeur. Dans ce cas, le code QR doit être standardisé pour inclure les informations du bénéficiaire, le montant de la transaction, le type de transaction, et une note éventuelle. Le système doit standardiser le format du code QR pour le bénéficiaire. + +##### Transaction initiée par le Bénéficiaire + +Le bénéficiaire scanne le code QR du Payeur pour initier une transaction initiée par le bénéficiaire. Par exemple, un marchand scanne le code QR du Payeur pour initier un paiement marchand. Dans ce cas, le code QR doit être standardisé pour localiser le payeur sans utiliser le système de recherche de compte. Le système doit standardiser le format du code QR : c’est-à-dire ID FSP, Type d’ID de Partie et ID Payeur, ou seulement Type d’ID de Partie et ID de Partie. + +## Règles du système de Mise en œuvre de l’API + +Cette section décrit les règles du système de mise en œuvre de l’API. + +#### Version de l’API + +Les informations de version de l’API doivent être incluses dans tous les appels API comme défini dans la _Définition de l'API_. Le système doit recommander que tous les FSP implémentent la même version de l’API. + +#### HTTP ou HTTPS + +L’API prend en charge HTTP et HTTPS. Le système doit recommander que la communication soit sécurisée à l’aide de TLS (voir la section [Sécurité des communications](#securite-des-communications)). + +#### Délai d’expiration HTTP + +Les FSP et le Switch doivent configurer le délai d’expiration HTTP. Si un FSP ne reçoit pas de réponse HTTP (soit **HTTP 202** soit **HTTP 200**) à une requête **POST** ou **PUT**, alors le FSP doit considérer la requête comme ayant expiré. Se référer au diagramme de la Figure 1 pour les délais d’expiration des **HTTP 202** et **HTTP 200**, indiqués en pointillés. + +###### Figure-1 + +![Figure 1 HTTP Timeout](../assets/scheme-rules-figure-1-http-timeout.png) + +**Figure 1 – Délai d’expiration HTTP** + +#### Délais d’expiration des rappels (Callback) + +Les FSP et le Switch doivent configurer les délais d’expiration des rappels (callbacks). Le délai d’expiration de rappel du FSP initiateur doit être supérieur à celui du Switch. Le système doit déterminer ce délai pour le FSP initiateur et le Switch. Se référer au diagramme de la Figure 2 pour les délais d’expiration de rappel mis en évidence en rouge. + +###### Figure-2 + +![Figure 1 Callback Timeout](../assets/scheme-rules-figure-2-callback-timeout.png) + +**Figure 2 – Délai d’expiration des rappels** + +## Règles du système de Sécurité et de Non-Fonctionnel + +Cette section décrit les règles du système concernant la sécurité, l’environnement et autres exigences réseau. + +#### Synchronisation des horloges + +Il est important de synchroniser les horloges entre les FSP et les Switch. Il est recommandé d’utiliser un ou plusieurs serveurs NTP pour la synchronisation de l’horloge. + +#### Chiffrement des Champs de Données + +Les champs de données devant être chiffrés seront déterminés par les lois nationales et locales, ainsi que par toute norme à laquelle il faut se conformer. Le chiffrement doit respecter la section _Chiffrement_. + +#### Signature numérique des messages + +Le système peut décider que tous les messages doivent être signés comme décrit dans la section _Signature_. Les messages de réponse n'ont pas à être signés. + +#### Certificats numériques + +Pour utiliser les fonctionnalités de signature et de chiffrement détaillées dans les sections _Signature_ et _Chiffrement_ d’un système, les FSP et les Switch doivent obtenir des certificats numériques tels que spécifiés par l’_AC_ (Autorité de Certification) désignée dans le système. + +#### Exigence cryptographique + +Toutes les parties doivent prendre en charge les encodages et les algorithmes de chiffrement spécifiés dans _Chiffrement_, si les fonctionnalités de chiffrement doivent être utilisées dans le système. + +#### Sécurité des communications + +Le système doit exiger que toute communication HTTP entre les parties soit sécurisée à l’aide de TLS[1](https://tools.ietf.org/html/rfc5246) version 1.2 ou ultérieure. + +1 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + +### Table des figures + +[Figure 1 – Délai d’expiration HTTP](#figure-1) + +[Figure 2 – Callback](#figure-2) \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/use-cases.md b/docs/fr/technical/api/fspiop/use-cases.md new file mode 100644 index 000000000..e379d797d --- /dev/null +++ b/docs/fr/technical/api/fspiop/use-cases.md @@ -0,0 +1,139 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Cas d’utilisation + +## Préface + +Cette section contient des informations sur la façon d'utiliser ce document. + +### Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'informations spécifiques. + +|Type d'information|Convention|Exemple| +|---|---|---| +|**Éléments de l'API, tels que les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans _Glossaire_|Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un bénéficiaire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne devraient, en général, pas être utilisées par les déploiements de l'API ; les mesures de sécurité détaillées dans _Signature API_ et _Chiffrement API_ devraient être utilisées à la place.| + +### Informations sur la version du document + +|Version|Date|Description des modifications| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| + +
+ +## Introduction + +L'objectif de ce document est de définir un ensemble de cas d'utilisation pouvant être mis en œuvre à l'aide de l’Open API pour l’interopérabilité FSP (appelée ci-après l’API). Les cas d’utilisation référencés dans ce document donnent un aperçu des flux de traitement des transactions et des règles métier de chaque étape ainsi que des conditions d’erreur pertinentes. + +Le but principal de l’API est de permettre le transfert de transactions financières entre un _Fournisseur de Services Financiers_ (FSP) et un autre. + +Il convient de noter que l’API n’est responsable que de l’échange de messages entre les FSP et un switch lorsque qu’une transaction entre FSPs est initiée par un _Utilisateur Final_ dans l’un des FSPs. Ceci peut se produire dans deux scénarios : + +- Un scénario bilatéral dans lequel les FSPs communiquent directement entre eux + +- Un scénario basé sur Switch dans lequel toutes les communications passent par un Switch + +La réconciliation, la compensation et le règlement après les transactions en temps réel sont hors du champ de l’API. De plus, la recherche de comptes est prise en charge par l’API, mais dépend de l’implémentation dans un marché local dans lequel un tiers ou un Switch fournirait ces services. Par conséquent, la nécessité de processus d’intégration efficaces et de règles du système appropriées doit être prise en compte lors de la mise en œuvre des cas d’utilisation. + +
+ +### Spécification Open API pour l’interopérabilité FSP + +La spécification Open API pour l’interopérabilité FSP comprend les documents suivants. + +#### Documents généraux + +- _Glossaire_ + +#### Documents logiques + +- _Modèle de données logique_ + +- _Schémas de transaction génériques_ + +- _Cas d’utilisation_ + +#### Documents de liaison REST asynchrone + +- _Définition API_ + +- _Règles de liaison JSON_ + +- _Règles du système_ + +#### Intégrité des données, confidentialité et non-répudiation + +- _Meilleures pratiques PKI_ + +- _Signature_ + +- _Chiffrement_ + +
+ +## Résumés des cas d’utilisation + +Les schémas de transaction génériques suivants sont présentés dans [Schémas de transaction génériques]() pour réduire la duplication des descriptions de chaque cas d’utilisation. Ces modèles résument les flux de transaction communs et les fonctions partagées des cas d'utilisation pertinents. + +- **Transaction initiée par le payeur** + - Dans une _transaction initiée par le payeur_, c’est le _Payeur_ (c’est-à-dire celui qui effectue le paiement électronique) qui initie la transaction. + + Ce modèle doit être utilisé chaque fois qu’un Payeur souhaite transférer des fonds à une autre partie dont le compte n’est pas situé dans le même FSP. + +- **Transaction initiée par le bénéficiaire** + - Dans une _transaction initiée par le bénéficiaire_, c’est le _Bénéficiaire_ (c’est-à-dire le receveur des fonds électroniques) qui initie la transaction. + + Ce modèle doit être utilisé chaque fois qu’un bénéficiaire souhaite recevoir des fonds d’une autre partie dont le compte n’est pas situé dans le même FSP. + +- **Transaction initiée par le bénéficiaire avec OTP** + - Une _transaction initiée par le bénéficiaire avec mot de passe à usage unique (OTP)_ est similaire à la transaction initiée par le bénéficiaire, mais les informations de transaction (y compris les frais et les taxes) et l'approbation du payeur sont affichées ou saisies sur un appareil du bénéficiaire. + + - Ce modèle doit être utilisé lorsque le bénéficiaire souhaite recevoir des fonds d'une autre partie dont le compte n’est pas dans le même FSP, et que les informations et l’approbation sont gérées sur l'appareil du bénéficiaire. + +- **Transactions groupées** + - Dans une _transaction groupée_, c’est le payeur (l’expéditeur de fonds) qui initie plusieurs transactions vers plusieurs bénéficiaires situés potentiellement dans différents FSPs. + + - Le modèle doit être utilisé chaque fois qu’un payeur souhaite transférer des fonds à plusieurs bénéficiaires lors de la même transaction. Les bénéficiaires peuvent être dans différents FSPs. + +Il est recommandé de lire tous les schémas de transaction génériques avant de lire les cas d'utilisation. Pour plus d’informations, voir [Schémas de transaction génériques](). + +Chaque cas d’utilisation décrit des variations et des considérations spéciales pour le schéma de transaction générique auquel il se réfère. Les cas d’utilisation sont présentés dans le [Tableau 1](#table-1) ci-dessous : + +##### Tableau 1 + +| Nom du cas d’utilisation | Description | +| --- | --- | +| P2P |Ce cas décrit le processus métier et les règles selon lesquelles un Utilisateur Final initie une transaction pour envoyer de l’argent à un autre Utilisateur Final n’appartenant pas au même FSP que le Payeur.

C’est généralement une transaction à distance où Payeur et Bénéficiaire ne sont pas au même endroit. | +| Dépôt d'espèces initié par l’agent | Ce cas décrit le processus métier et les règles où un client demande à un agent d’un autre FSP d’effectuer un dépôt sur son compte.

Il s’agit généralement d’une transaction en face à face où le client et l’agent sont au même endroit. | +| Retrait d'espèces initié par l’agent | Ce cas décrit le processus métier et les règles où un client demande qu’un agent d’un autre FSP effectue un retrait de son compte.

Il s’agit généralement d’une transaction en face à face où le client et l’agent sont au même endroit. | +| Retrait d'espèces initié par l’agent
Autorisé sur POS
| Ce cas décrit le processus métier où un client demande à un agent d’un autre FSP d’effectuer un retrait. L’agent initie la transaction via un terminal de point de vente (_POS_) et le client saisit un OTP sur le POS pour l’autoriser. Alternativement, l’agent peut utiliser le POS pour scanner un QR code généré par l’application mobile du client. | +| Retrait d'espèces initié par le client | Ce cas décrit le processus métier où un client enregistré initie un retrait d’espèces via un agent n’appartenant pas à son FSP.

C’est également typiquement une transaction en face à face. | +| Paiement marchand initié par le client

| Ce cas décrit le processus métier où un utilisateur final initie une transaction d’achat pour payer un marchand n’étant pas dans le même FSP.

C’est généralement une transaction en face à face lors d’un achat en magasin.

Une variante est le paiement en ligne où un QR code est généré et affiché sur une page web, puis scanné par le client pour compléter la transaction. | +| Paiement marchand initié par le marchand

| Ce cas décrit le processus où un commerçant initie une demande de paiement vers un client ; le client révise le montant et confirme via authentification sur son propre appareil. | +| Paiement marchand initié par le marchand
Autorisé sur POS
| Ce cas décrit le processus où un marchand initie une demande de paiement ; le client révise la demande sur le terminal du marchand et autorise le paiement par OTP ou QR code. Les informations d’authentification du client sont envoyées du FSP du bénéficiaire vers le FSP du payeur pour authentification. | +| Retrait d'espèces initié par DAB | Ce cas décrit le processus où un DAB lance une demande de retrait sur un compte client. Le client pré-génère un OTP pour le retrait et l’utilise sur le DAB pour lancer l’opération. Le FSP du payeur valide l’OTP reçu pour authentification. | +| Paiements groupés | _Paiements groupés_ est utilisé lorsqu’une organisation ou une entreprise effectue des paiements, par exemple, de l’aide ou des salaires à plusieurs bénéficiaires ayant des comptes dans différents FSPs. L’organisation peut grouper les transactions pour faciliter l’envoi et la validation avant exécution. Il est aussi possible de suivre les résultats des transactions individuelles après exécution. | +| Remboursement | Ce cas décrit le flux métier pour rembourser une transaction d’interopérabilité complétée. | + +**Tableau 1 – Résumé des cas d’utilisation** + +
+ +## Cas d’utilisation + +Cette section illustre les façons dont l’API peut être utilisée via les cas d’utilisation identifiés dans le [Tableau 1](#table-1) – _Résumé des cas d’utilisation_. + +Pour chaque cas d’utilisation, les éléments suivants sont présentés : +- Description du cas d’utilisation +- Référence au schéma générique +- Acteurs et rôles +- Ajouts au schéma de transaction générique +- Conditions d’erreur pertinentes + +(La traduction complète du document est très volumineuse. Veuillez indiquer si vous souhaitez poursuivre avec la traduction de l’intégralité du contenu ci-dessous, ou d’une partie spécifique.) diff --git a/docs/fr/technical/api/fspiop/v1.0/README.md b/docs/fr/technical/api/fspiop/v1.0/README.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/docs/fr/technical/api/fspiop/v1.0/README.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/v1.0/api-definition.md b/docs/fr/technical/api/fspiop/v1.0/api-definition.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/docs/fr/technical/api/fspiop/v1.0/api-definition.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/v1.1/api-definition.md b/docs/fr/technical/api/fspiop/v1.1/api-definition.md new file mode 100644 index 000000000..ae34f1584 --- /dev/null +++ b/docs/fr/technical/api/fspiop/v1.1/api-definition.md @@ -0,0 +1,5399 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Bill & Melinda Gates Foundation +--- + +## Préface + +Cette section contient des informations sur la manière d'utiliser ce document. + +### Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'informations spécifiés. + +|Type d'information|Convention|Exemple| +|---|---|---| +|**Éléments de l'API, tels que les ressources**|Gras|**/authorization**| +|**Variables**|Italique avec des chevrons|_{ID}_| +|**Termes du glossaire**|Italique lors de la première occurrence ; défini dans le _Glossaire_|Le but de l’API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un bénéficiaire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne devraient généralement pas être utilisées par les déploiements de l’API ; les mesures de sécurité détaillées dans _Signature API et Chiffrement API_ doivent être utilisées à la place.| + +### Informations sur la version du document + +|Version|Date|Description des modifications| +|---|---|---| +|**1.0**|2018-03-13|Version initiale| +|**1.1**|2020-05-19|1. Cette version contient une nouvelle option pour qu'un FSP Bénéficiaire demande une notification de validation (commit) du Switch. Le Switch doit ensuite envoyer la notification de validation à l'aide de la nouvelle requête **PATCH /transfers/**_{ID}_. L'option d'utiliser la notification de validation remplace l'ancienne option "Contrôle supplémentaire de compensation facultatif". La section décrivant cela a été remplacée par la nouvelle section "Commit Notification (Notification de validation)". La ressource **transfers** a été mise à jour avec la nouvelle requête **PATCH**, cette ressource est donc passée en version 1.1. Dans le cadre de l'ajout de la possibilité d'utiliser une notification de validation, les changements suivants ont été apportés :
a. PATCH a été ajouté comme méthode HTTP autorisée dans la section 3.2.2. b. Le flux d’appel pour **PATCH** est décrit dans la section 3.2.3.5.
c. Le tableau 6 en section 6.1.1 a été mis à jour pour inclure **PATCH** comme méthode HTTP possible.
d. La section 6.7.1 contient la nouvelle version de la ressource **transfers**.
e. La section 6.7.2.6 décrit le processus d’utilisation des notifications de validation
f. La section 6.7.3.3 décrit la nouvelle requête **PATCH /transfers**/_{ID}_.

2. En plus des changements mentionnés ci-dessus concernant la notification de validation, les modifications suivantes n'affectant pas l'API ont été apportées :
a. Figure 6 mise à jour car elle contenait une erreur de copier-coller.
b. Ajout de la section 6.1.2 pour fournir une vue complète de la version actuelle de chaque ressource.
c. Ajout d'une section pour chaque ressource afin de voir l’historique des versions de ressource.
d. Corrections éditoriales mineures.

3. Les descriptions de deux des champs d'en-tête HTTP du Tableau 1 ont été mises à jour pour ajouter plus de spécificité et de contexte
a. La description du champ d'en-tête **FSPIOP-Destination** a été mise à jour pour indiquer qu'il doit rester vide si la destination n'est pas connue de l'émetteur original, mais dans tous les autres cas, doit être ajouté par l'émetteur original de la requête.
b. La description du champ d'en-tête **FSPIOP-URI** a été rendue plus spécifique.

4. Les exemples utilisés dans ce document ont été mis à jour pour utiliser la bonne interprétation du type complexe ExtensionList défini dans le Tableau 84. Ceci n'implique pas de changement en soi.
a. L’exemple 5 a été mis à jour à ce sujet.

5. Le modèle de données est mis à jour pour ajouter un élément optionnel ExtensionList au type complexe **PartyIdInfo** selon la demande de changement : https://github.com/mojaloop/mojaloop-specification/issues/30. Par conséquent, le modèle de données comme spécifié dans le Tableau 103 a été mis à jour. Pour plus de cohérence, le modèle de données pour les appels **POST /participants/**_{Type}/{ID}_ et **POST /participants/**_{Type}/{ID}/{SubId}_ dans le Tableau 10 a également été mis à jour pour inclure l’élément optionnel ExtensionList.

6. Une nouvelle section 6.5.2.2 est ajoutée pour décrire le processus impliqué dans le rejet d’un devis.

7. Une note est ajoutée à la Section 6.7.4.1 pour clarifier l’utilisation de l’état ABORTED dans les callbacks **PUT /transfers/**_{ID}_.| +|**1.1.1**|2021-09-22|Cette version du document ajoute uniquement des informations sur les en-têtes HTTP optionnels relatifs à la prise en charge de la traçabilité dans [Table 2](#table-2), voir _Distributed Tracing Support for OpenAPI Interoperability_ pour plus d’informations. Aucun changement n’est apporté à aucune ressource dans cette version.| + +## Introduction + +Ce document introduit et décrit l’API ouverte (Interface de Programmation Applicative) pour l’interopérabilité des Fournisseurs de Services Financiers (FSP), appelée ci-après « l’API ». L'objectif de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une opération de paiement) situé dans un autre FSP. L'API ne précise aucun service frontal entre un Payeur ou un Bénéficiaire et son propre FSP ; tous les services définis dans l'API sont entre FSPs. Les FSPs sont connectés soit (a) directement entre eux, soit (b) par un _Switch_ placé entre les FSPs pour router les transactions financières vers le FSP approprié. + +Le transfert de fonds d'un Payeur à un Bénéficiaire doit être effectué en quasi temps réel. Dès qu'une transaction financière a été acceptée par les deux parties, elle est réputée irrévocable. Cela signifie qu'une transaction terminée ne peut pas être annulée dans l'API. Pour annuler une transaction, une nouvelle transaction de remboursement inverse doit être créée à partir du Bénéficiaire de la transaction d'origine. + +L'API est conçue pour être suffisamment générique pour prendre en charge de nombreux cas d'utilisation et l’extensibilité de ceux-ci. Cependant, elle doit contenir suffisamment de détails pour permettre une implémentation sans ambiguïté. + +La version 1.0 de l'API est conçue pour être utilisée dans un pays ou une région ; les envois internationaux nécessitant des opérations de change ne sont pas pris en charge. Cette version contient également une prise en charge de base du [protocole Interledger](#4-interledger-protocol), qui sera utilisé dans les futures versions de l’API pour gérer les transactions multi-devises et multi-intermédiaires. + +Ce document : + +- Définit une liaison REST asynchrone de l'API logique introduite dans _Modèles de transactions génériques_. +- Complète et développe les informations fournies dans [Spécification Open API pour l’Interopérabilité FSP](#open-api-for-fsp-interoperability-specification). + +### Spécification Open API pour l’Interopérabilité FSP + +La spécification Open API pour l’Interopérabilité FSP inclut les documents suivants. + +#### Documents logiques + +- [Modèle de données logique](../logical-data-model) + +- [Modèles de transaction génériques](../generic-transaction-patterns) + +- [Cas d’utilisation](../use-cases) + +#### Documents de liaison REST asynchrone + +- [Définition de l’API](../definitions) + +- [Règles de liaison JSON](../json-binding-rules) + +- [Règles du scheme](../scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Meilleures pratiques PKI](../pki-best-practices) + +- [Signature](../v1.1/signature) + +- [Chiffrement](../v1.1/encryption) + +#### Documents généraux + +- [Glossaire](../glossary) + +
+ +## Définition de l’API + +Cette section introduit la technologie utilisée par l’API, incluant : + +- [Caractéristiques générales](#general-characteristics) +- [Détails HTTP](#http-details) +- [Gestion des versions de l'API](#api-versioning) + +### Caractéristiques générales + +Cette section décrit les caractéristiques générales de l’API. + +#### Style architectural + +L’API est basée sur le style architectural REST (REpresentational State Transfer1). Il existe cependant quelques différences avec une implémentation REST typique. Ces différences incluent : + +- **API totalement asynchrone** : pour pouvoir gérer de nombreux processus longs concurrents et avoir un mécanisme unique de gestion des requêtes, tous les services API sont asynchrones. Exemples : + - Transactions financières en lots + - Une transaction financière nécessitant une interaction utilisateur + +- **Décentralisée** : les services sont décentralisés, il n’existe pas d’autorité centrale pour piloter une transaction. + +- **Orientée service** : les ressources proposées par l’API sont relativement orientées service comparées à une API REST classique. + +- **Pas entièrement sans état** : certaines informations d’état doivent être conservées à la fois côté client et côté serveur durant le processus de transaction. + +- **Le client détermine l’identifiant commun** : dans une implémentation REST typique (avec distinction claire client/serveur), c’est le serveur qui génère l’ID lors de la création de l’objet. Dans cette API, un devis ou une transaction financière réside à la fois dans le FSP du Payeur et du Bénéficiaire, car les services sont décentralisés. Il est donc nécessaire d’avoir un identifiant commun pour l’objet. Les raisons en sont doubles : + - L’ID commun est utilisé dans l’URI du callback asynchrone vers le client. Le client sait donc à quelle URI écouter pour le callback correspondant à la requête. + - Le client peut utiliser l’ID commun dans une requête HTTP **GET** directement s’il ne reçoit pas de callback depuis le serveur (voir [Détails HTTP](#http-details) pour plus d’informations). + + Pour maintenir l’unicité des IDs communs, chacun est défini comme un UUID (Identifiant Universel Unique2). Pour garantir encore plus l’unicité, il est recommandé au serveur d’associer chaque ID d’objet à l’ID FSP du client. Si un serveur reçoit tout de même un ID commun non unique lors d’une requête HTTP **POST** (voir [Détails HTTP](#http-details) pour plus de détails), la requête doit être gérée comme indiqué dans la section [Services idempotents côté serveur](#idempotent-services-in-server). + +#### Protocole de niveau applicatif + +HTTP, tel que défini dans RFC 72303, est utilisé comme protocole de niveau applicatif dans l’API. Toute communication en environnement de production doit être sécurisée en utilisant HTTPS (HTTP sur TLS4). Pour plus de détails, voir [Détails HTTP](#http-details). + +#### Syntaxe URI + +La syntaxe des URIs suit la RFC 39865 pour identifier les ressources et services proposés par l’API. Cette section introduit et précise les sujets d’implémentation propres à chaque partie de la syntaxe. + +Une URI générique a la forme présentée dans [Exemple 1](#listing-1), où la partie \[_user:password@_\]_host_\[_:port_\] correspond à la partie `Authority` décrite dans la section [Authority](#authority). +_{resource}_. + +###### Exemple 1 + +``` +scheme:[//[user:password@]host[:port]][/]path[?query][#fragment] +``` + +**Exemple 1 -- Format générique d’URI** + +##### Scheme + +Conformément à la section [Protocole de niveau applicatif](#aplication-level-protocol), le _scheme_ sera toujours soit **http**, soit **https**. + +##### Autorité + +La partie d’autorité consiste en une partie d’authentification optionnelle (`User Information`), une partie hôte obligatoire, suivie d’un port optionnel. + +###### Informations utilisateur + +Les informations utilisateur ne devraient généralement pas être utilisées par les déploiements API ; les mesures de sécurité détaillées dans *Signature API* et _Chiffrement API_ doivent être utilisées à la place. + +###### Hôte + +L’hôte correspond à l’adresse du serveur. Il peut s’agir d’une adresse IP ou d’un nom d’hôte. Elle variera (généralement) selon le déploiement. + +###### Port + +Le numéro de port est optionnel ; par défaut, le port HTTP est **80** et HTTPS **443**, mais d’autres ports peuvent être utilisés. Le port à utiliser peut différer selon le déploiement. + +##### Chemin (Path) + +Le chemin pointe vers une ressource ou un service effectif de l’API. Les ressources de l’API sont : + +- **participants** +- **parties** +- **quotes** +- **transactionRequests** +- **authorizations** +- **transfers** +- **transactions** +- **bulkQuotes** +- **bulkTransfers** + +Toutes les ressources ci-dessus sont également organisées de façon hiérarchique, séparées par un ou plusieurs slash (**'/'**). Les ressources supportent différents services selon la méthode HTTP utilisée. Toutes les ressources et services API supportés, avec URI et méthode HTTP, figurent dans [le tableau 6](#table-6). + +##### Query + +La partie query est optionnelle ; elle n’est actuellement utilisée et prise en charge que par certains services de l’API. Voir les ressources API dans la section [Services API](#api-services) pour plus de détails sur les services qui prennent en charge les chaînes de requête. Tous les autres services doivent ignorer toute chaîne de requête reçue, car des chaînes de requête pourront être ajoutées dans de futures versions mineures de l’API (voir [Méthodes HTTP](#http-methods)). + +S’il y a plusieurs paires clé-valeur dans la chaîne de requête, celles-ci doivent être séparées par l’esperluette (**'&'**). + +[L'exemple 2](#listing-2) montre un exemple d’URI issue de la ressource **/authorization**, où quatre paires clé-valeur différentes sont présentes, séparées par l’esperluette. + +###### Exemple 2 + +``` +/authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD +``` + +**Exemple 2 -- URI contenant plusieurs paires clé-valeur dans la chaîne de requête** + +##### Fragment + +Le fragment est une partie optionnelle d’une URI. Il n’est pris en charge par aucun service de l’API et doit donc être ignoré s’il est reçu. + +#### Normalisation et comparaison d’URI + +Comme précisé dans la RFC 72306, les parties [scheme](#scheme)) et [hôte](#host)) de l’URI doivent être considérées comme insensibles à la casse. Toutes les autres parties doivent être traitées en tenant compte de la casse. + +#### Jeu de caractères + +Le jeu de caractères doit toujours être supposé UTF-8, défini dans 36297. Il n’est donc pas nécessaire de l’indiquer dans les en-têtes HTTP (voir [Champs d’en-tête HTTP](#http-header-fields)). Aucun autre jeu de caractères que UTF-8 n’est pris en charge par l’API. + +#### Format d’échange de données + +L’API utilise JSON (JavaScript Object Notation), défini dans RFC 71598, comme format d’échange. JSON est ouvert, léger, lisible et indépendant de la plateforme, bien adapté pour l’échange de données entre systèmes. + +
+ +### Détails HTTP + +Cette section contient des informations détaillées concernant l’utilisation du protocole HTTP dans l’API. + +#### Champs d’en-tête HTTP + +Les en-têtes HTTP sont généralement décrits dans la RFC 72309. Les deux sections suivantes décrivent les champs d’en-tête HTTP qui doivent être attendus et mis en œuvre dans l’API. + +L’API prend en charge une taille maximale de 65536 octets (64 kilooctets) dans l’en-tête HTTP. + +#### Champs d’en-tête HTTP de requête + +[Le tableau 1](#table-1) contient les champs d’en-tête HTTP de requête qui doivent être supportés par les implémentations de l’API. Une implémentation doit également s’attendre à d’autres champs d’en-tête HTTP standards et non standards non listés ici. + +###### Tableau 1 + +|Champ|Exemples de valeurs|Cardinalité|Description| +|---|---|---|---| +|**Accept**|**application/vnd.interoperability.resource+json**|0..1
Obligatoire dans une requête client. Non utilisé dans un callback du serveur.
Le champ d’en-tête **Accept**10 indique la version de l’API que le client souhaite utiliser côté serveur. Voir [En-tête Accept HTTP](#http-accept-header) pour demander une version spécifique de l’API.| +|**Content-Length**|**3495**|0..1|Le champ **Content-Length**11 indique la taille attendue du corps de la requête. Présent seulement s’il y a un corps.
**Note** : l’API autorise une taille maximale de 5 Mo (5242880 octets).
| +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|**Content-Type**12 indique la version spécifique de l’API utilisée pour envoyer le corps de la requête. Voir [Version acceptée demandée par le client](#acceptable-version-requested-by-client) pour plus d’informations.| +|**Date**|**Tue, 15 Nov 1994 08:12:31 GMT**|1|Le champ **Date**13 indique la date à laquelle la requête a été envoyée.| +|**X-Forwarded-For**|**X-Forwarded-For: 192.168.0.4, 136.225.27.13**|1..0|Le champ **X-Forwarded-For**14 est une norme officieuse utilisée pour indiquer l’IP d’origine du client à titre informatif, une requête pouvant passer par plusieurs proxys, pare-feux, etc. Plusieurs valeurs **X-Forwarded-For** comme dans l’exemple doivent être attendues et supportées.
**Note** : Une alternative à **X-Forwarded-For** est définie dans RFC 723915. Cependant, en 2018, RFC 7239 est moins utilisé/supporté que **X-Forwarded-For**.
| +|**FSPIOP-Source**|**FSP321**|1|Le champ d’en-tête **FSPIOP-Source** est un champ non standard HTTP utilisé par l’API pour identifier l’émetteur de la requête HTTP. Il doit être placé par l’émetteur original de la requête. Nécessaire pour le routage (voir [Routage des flux d'appels avec FSPIOP-Destination et FSPIOP-Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source)) et la vérification de signature (**FSPIOP-Signature**).| +|**FSPIOP-Destination**|**FSP123**|0..1|Le champ **FSPIOP-Destination** est non standard HTTP, utilisé pour le routage (via en-tête HTTP) des requêtes/réponses vers la destination. Il doit être défini par l’émetteur initial de la requête, si la destination est connue (valable pour tous les services sauf GET /parties), afin que les entités intermédiaires n’aient pas à parser le corps pour le routage (voir [Routage](#3236-call-flow-routing-using-fspiop-destination-and-fspiop-source)). Si la destination n’est pas connue (valable pour GET /parties), ce champ doit rester vide.| +|**FSPIOP-Encryption**||0..1|Champ non standard HTTP utilisé pour le chiffrement de bout en bout de la requête.
Voir Chiffrement API.
| +|**FSPIOP-Signature**||0..1|Champ non standard, utilisé pour la signature de bout en bout de la requête.
Voir Signature API.
| +|**FSPIOP-URI**|**/parties/msisdn/123456789**|0..1|Champ non standard HTTP utilisé pour la vérification de la signature, contient l’URI du service. Obligatoire si la signature est utilisée.
Dans le contexte de l’API Mojaloop FSPIOP, la valeur FSPIOP-URI commence au **_service_** dans l’URI. Par exemple, si l’URL est http://stg-simulator.moja.live/payerfsp/participants/MSISDN/123456789, alors la valeur FSPIOP-URI est « /participants/MSISDN/123456789 ».| +|**FSPIOP-HTTP-Method**|**GET**|0..1|Champ non standard HTTP utilisé pour la vérification de la signature : doit contenir la méthode HTTP du service utilisé. Obligatoire si la signature est utilisée, voir Signature API.| + +**Tableau 1 -- Champs d’en-tête HTTP de requête obligatoires** + +[Le tableau 2](#table-2) liste les champs d’en-tête de requête HTTP dont la prise en charge par les implémentations de l’API est optionnelle. + +###### Tableau 2 + +|Champ|Exemples de valeurs|Cardinalité|Description| +|---|---|---|---| +|**traceparent**|**00-91e502e28cd723686e9940bd3f378f85-b0f903d000944947-01**|0..1|L’en-tête traceparent représente la requête entrante dans un système de traçage dans un format commun. Voir _Distributed Tracing Support for OpenAPI Interoperability_ pour plus d’information.| +|**tracestate**|**banknrone=b0f903d0009449475**|0..1|Fournit des informations de traçage spécifiques au fournisseur et prend en charge plusieurs traces distribuées. Voir _Distributed Tracing Support for OpenAPI Interoperability_ pour plus d’information.| + +**Tableau 2 -- Champs d’en-tête HTTP de requête optionnels** + +##### Champs d’en-tête HTTP de réponse + +[Le tableau 3](#table-3) contient les champs d’en-tête HTTP de réponse obligatoires. Une implémentation peut aussi recevoir d’autres en-têtes HTTP standards ou non standards non listés ici. + +###### Tableau 3 + +|Champ|Exemples de valeurs|Cardinalité|Description| +|---|---|---|---| +|**Content-Length**|**3495**|0..1|Champ **Content-Length**16 indiquant la taille attendue du corps. Envoyé uniquement si corps présent.| +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|Champ **Content-Type**17 indiquant la version de l’API utilisée pour envoyer le corps. Voir [Section 3.3.4.2](#3342-acceptable-version-requested-by-client) pour plus de détails.| + +**Tableau 3 -- Champs d’en-tête HTTP de réponse** + +#### Méthodes HTTP + +Les méthodes HTTP suivantes, telles que définies dans RFC 723118, sont supportées par l’API : + +- **GET** : utilisée par le client pour demander des informations sur un objet précédemment créé côté serveur. Comme tous les services API sont asynchrones, la réponse directe à la requête **GET** ne contient pas l’objet demandé : cet objet viendra en callback dans une requête **PUT**. + +- **PUT** : utilisée comme callback à une précédente requête **GET**, **POST** ou **DELETE** émise par le client. Le callback contient soit : + + - Informations sur l’objet précédemment créé (**POST**) ou informations demandées (**GET**) + - Accusé de réception de suppression d’un objet (**DELETE**) + - Informations d’erreur si la requête **POST** ou **GET** n’a pu être traitée côté serveur + +- **POST** : utilisée par le client pour demander la création d’un objet côté serveur. Comme l’API est asynchrone, la réponse directe ne contient pas l’objet : celui-ci viendra en callback via un **PUT**. + +- **DELETE** : utilisée pour demander la suppression d’un objet côté serveur. **DELETE** ne doit être supporté qu’au sein d’un système commun Account Lookup System (ALS) pour supprimer des informations sur une Party (détenteur de compte chez un FSP) précédemment ajoutée ; aucun autre type d’objet ne peut être supprimé. Comme tous les services sont asynchrones, la réponse à **DELETE** ne contient pas l’accusé de réception final : celui-ci viendra via un callback en **PUT**. + +- **PATCH** : utilisée pour notifier une mise à jour d’un objet existant. Comme l’API est asynchrone, la réponse à **PATCH** ne contient pas de corps : cette méthode sert de notification et ne génère pas de callback. + +
+ +#### Séquencement HTTP + +Tous les séquences et services sont asynchrones. Aucun service ne supporte le mode synchrone. + +##### Appel POST HTTP + +[La figure 1](#figure-1) montre le cas normal de création d’un objet dans un FSP pair via HTTP **POST**. Le service **_/service_** du schéma doit être remplacé par n’importe lequel des services du [Tableau 6](#table-6) supportant **POST**. + +###### Figure 1 + +![](../../assets/diagrams/sequence/figure1.svg) + +**Figure 1 — Séquence d’appel POST HTTP** + +##### Appel GET HTTP + +[La figure 2](#figure-2) montre le cas d’obtention d’informations sur un objet dans un FSP pair via HTTP **GET**. Le service **/service/**_{ID}_ doit être remplacé par n’importe quel service listé dans [Tableau 6](#table-6) prenant en charge **GET**. + +###### Figure 2 + +![](../../assets/diagrams/sequence/figure2.svg) + +**Figure 2 — Séquence d’appel GET HTTP** + +##### Appel DELETE HTTP + +[La figure 3](#figure-3) décrit l’appel d’API pour supprimer des informations FSP sur une Party via HTTP **DELETE** dans un ALS. Le service **/service/**_{ID}_ doit être remplacé par un service du [Tableau 6](#table-6) prenant en charge **DELETE**. DELETE n’est géré que par un ALS commun (c’est pourquoi l’ALS n’apparaît que côté serveur dans la figure). + +###### Figure 3 + +![](../../assets/diagrams/sequence/figure3.svg) + +**Figure 3 — Séquence d’appel DELETE HTTP** + +**Remarque :** il est également possible que les requêtes vers l’ALS passent par un Switch, ou que l’ALS et le Switch soient le même serveur. + +##### Callback PUT HTTP + +Le **PUT** HTTP est toujours utilisé comme callback sur une requête **POST**, **GET** ou **DELETE**. + +Le flux d’appel d’une requête **PUT** et de la réponse peut être observé dans les figures 1, 2 et 3 indiquées précédemment. + +##### Séquence PATCH HTTP + +[La figure 4](#figure-4) montre un exemple de séquence pour le **PATCH** HTTP, utilisé pour envoyer une notification. D’abord, un objet est créé via un **POST** depuis le Switch. L’objet est créé dans le FSP à l’état non finalisé. Le FSP demande ensuite à être notifié de l’état final par le Switch via un callback **PUT** avec l’état non finalisé. Le Switch gère le callback et envoie la notification d’état finalisé via un **PATCH**. La seule ressource supportant PATCH est /transfers. + +###### Figure 4 + +![](../../assets/diagrams/sequence/figure4.svg) + +**Figure 4 — Séquence PATCH HTTP** + +**Remarque :** les requêtes vers l’ALS peuvent aussi être routées via un Switch, voire ALS et Switch peuvent être le même serveur. + +##### Routage des flux d'appels avec FSPIOP-Destination et FSPIOP-Source + +Les en-têtes HTTP non standard **FSPIOP-Destination** et **FSPIOP-Source** servent au routage et à la vérification de signature (voir _Signature API_). [La figure 5](#figure-5) montre l’usage de ces en-têtes dans un appel **POST /service** abstrait, lorsque le FSP de destination est connu. + +###### Figure 5 + +![](../../assets/diagrams/sequence/figure5.svg) + +**Figure 5 — Usage des en-têtes HTTP personnalisés FSPIOP-Destination et FSPIOP-Source** + +Pour certains services avec un Switch, la destination n’est pas connue. Par exemple, un FSP envoie un **GET /parties** au Switch sans savoir quel autre FSP détient la Party (voir [Section 6.3.2](#632-service-details)). **FSPIOP-Destination** sera alors vide (ou défini à l’ID du Switch) émis depuis le FSP, et renseigné à sa vraie valeur par le Switch lors du routage. Voir [Figure 6](#figure-6) pour illustration. + +###### Figure 6 + +![](../../assets/diagrams/sequence/figure6.svg) + +**Figure 6 — Exemple : FSPIOP-Destination inconnu pour le FSP** + +
+ +#### Codes de statut HTTP de réponse + +L’API prend en charge les codes HTTP de réponse indiqués dans le [tableau 4](#table-4) : + +###### Tableau 4 + +|Code|Raison|Description| +|---|---|---| +|**200**|`OK`|Réponse standard pour une requête réussie. Utilisé dans l’API en réponse à un callback pour marquer la complétion d’un service asynchrone.| +|**202**|`Accepted`|La requête a été acceptée pour un traitement ultérieur côté serveur, sans garantie de succès. Utilisé comme accusé de réception d’une requête asynchrone.| +|**400**| `Bad Request`|L’application ne peut pas traiter la requête : syntaxe incorrecte ou corps dépassant la taille autorisée.| +|**401**|`Unauthorized`|La requête nécessite une authentification.| +|**403**|`Forbidden`|La requête a été refusée et sera systématiquement refusée à l’avenir.| +|**404**|`Not Found`|La ressource indiquée dans l’URI n’a pas été trouvée.| +|**405**|`Method Not Allowed`|Méthode HTTP non supportée ; voir Tableau 6 pour les méthodes autorisées par service.| +|**406**|`Not acceptable`|Le serveur ne peut générer de contenu conformément à l’en-tête Accept reçu ; cela indique qu'il ne supporte pas la version demandée.| +|**501**|`Not Implemented`|Le serveur ne supporte pas le service demandé. Le client ne doit pas retenter.| +|**503**|`Service Unavailable`|Le serveur n’est actuellement pas disponible pour de nouvelles requêtes. Cela devrait être temporaire : le client doit retenter dans un temps raisonnable.| + + **Tableau 4 — Codes de statut HTTP supportés dans l’API** + +Tout code de statut HTTP 3*xx*20 retourné côté serveur ne doit pas faire l'objet d'une nouvelle tentative et requiert une investigation manuelle. + +Une implémentation de l’API doit aussi savoir gérer d’autres erreurs non listées, en particulier si la requête passe par des proxies. + +Comme toutes les requêtes API sont asynchrones, les codes d’erreur HTTP serveur supplémentaires (5*xx*21 non définis au tableau 4) ne sont pas utilisés par l’API elle-même. Toute erreur serveur lors du traitement réel sera notifiée via un callback d’erreur au client (voir [Section 9.2](#92-error-in-server-during-processing-of-request)). + +
+ +##### Informations d’erreur en réponse HTTP + +En plus du code HTTP, toutes les réponses d’erreur HTTP (4*xx* et 5*xx*) peuvent contenir un élément **ErrorInformation**, défini dans la section [ErrorInformation](#errorinformation). Cet élément doit, si possible, permettre de fournir plus d’informations au client. + +
+ +##### Services idempotents côté serveur + +Tout service supportant **GET** doit être _idempotent_ : la même requête peut être envoyée plusieurs fois sans changer l’objet. (L’état de l’objet côté serveur peut toutefois évoluer : par exemple, l’état d’une transaction peut changer, mais le FSP envoyant **GET** ne peut changer l’état). + +Tout service supportant **POST** doit aussi être idempotent si le client réutilise le même identifiant. Le serveur ne doit pas créer un nouvel objet s’il reçoit à nouveau la même requête **POST**. Ceci facilite la gestion de la reprise après erreur côté client, mais impose des contraintes au serveur — voir l’exemple [ici](#client-missing-response-from-server---using-resend-of-request). + +##### Analyse des duplicats côté serveur lors de la réception d’un POST + +Lors de la réception d’une requête côté serveur, il doit vérifier si un objet de service portant le même identifiant existe déjà : par exemple, si le client a déjà envoyé **POST /transfers** avec le même **transferId**. Si l’objet existe déjà, le serveur vérifie si ses paramètres correspondent à ceux de la nouvelle requête. + +- Si l’objet existant a les mêmes paramètres que la nouvelle requête, on considère qu’il s’agit d’un renvoi de la part du client. + - Si le serveur n’a pas encore traité la requête précédente/créée et n’a donc pas envoyé de callback, la nouvelle requête peut être ignorée (un callback va être envoyé de toute façon). + - Si le serveur a fini de traiter l’ancienne requête et a déjà envoyé un callback, un nouveau callback doit être envoyé, comme si une requête **GET** avait été reçue. + +- Si l’ancien objet n’a pas les mêmes paramètres que la requête, un callback d’erreur expliquant qu’un objet avec le même identifiant existe déjà mais avec des paramètres différents doit être envoyé au client. + +Pour simplifier cette analyse, il est recommandé de stocker un hash de toutes les requêtes **POST** reçues côté serveur afin de les comparer facilement lors de réceptions ultérieures. + +
+ +### Gestion des versions de l’API + +La stratégie de développement de l’API est de maintenir la compatibilité ascendante entre l’API et ses ressources/services au maximum, cependant des changements doivent être attendus par les parties qui implémentent. La gestion des versions de l’API est propre à chaque ressource (par exemple : **/participants**, **/quotes**, **/transfers**). + +Il existe deux types de versions de ressource API : les versions _mineures_ (rétrocompatibles), et _majeures_ (non rétrocompatibles). + +- À chaque changement des caractéristiques de l’API impactant un service, la ressource concernée voit sa version augmentée (mineure ou majeure selon la compatibilité). +- Un changement dans un service spécifique voit sa ressource correspondante recevoir une nouvelle version. + +Le format de la version de ressource est _x.y_ où _x_ est le numéro majeur, _y_ le mineur. À chaque nouvelle version majeure, la version mineure repart à **0**. La version initiale de chaque ressource est **1.0**. + +#### Changements n’affectant pas la version de ressource API + +Certains changements n’affecteront pas la version, par exemple : modification de l’ordre des paramètres d’une requête ou d’un callback. + +#### Changement mineur de version de ressource + +Les modifications suivantes sont considérées comme rétrocompatibles. Les implémenteurs doivent concevoir client/serveur pour les accepter d’emblée sans casse fonctionnelle : + +- Ajout de paramètres d’entrée facultatifs (chaînes de requête, etc.) +- Ajout de paramètres facultatifs dans une requête ou un callback +- Ajout de codes d’erreur + +Ces changements affectent la version mineure. + +#### Changement majeur de version de ressource + +Les modifications ci-après sont considérées comme rétro-incompatibles. L’implémenteur n’a PAS à garantir la prise en charge automatique : + +- Suppression ou ajout de paramètres obligatoires +- Paramètres facultatifs devenant obligatoires +- Renommage de paramètres +- Changement de types de données +- Changement de logique métier +- Modification des URI de ressource/service + +Cette liste n’est pas exhaustive. + +#### Négociation de version entre client et serveur + +L’API prend en charge une négociation basique par HTTP content negotiation. Un client doit envoyer la version de ressource API souhaitée dans l’en-tête **Accept** (voir [En-tête Accept HTTP](#http-accept-header)). Si le serveur supporte cette version, elle est utilisée au callback ([Version acceptable…](#acceptable-version-requested-by-client)). Si le serveur ne la supporte pas, il doit répondre HTTP 40622 avec une liste des versions supportées ([Version non acceptable…](#non-acceptable-version-requested-by-client)). + +#### En-tête Accept HTTP + +Voir ci-dessous un exemple de requête HTTP simplifiée avec seulement l’en-tête **Accept**23. Il convient de l’utiliser pour un client souhaitant une version majeure précise d’une ressource. [Exemple 3](#listing-3) : « Je souhaite la version majeure 1, sinon donne la dernière ». + +###### Exemple 3 + +``` +POST /service HTTP/1.1 +Accept: application/vnd.interoperability.{resource}+json;version=1, +application/vnd.interoperability.{resource}+json + +{ + ... +} +``` + +**Exemple 3 — En-tête HTTP Accept : requête pour la version 1 ou la dernière supportée** + +Pour l’exemple de [l’exemple 3](#listing-3) : + +- **_POST /service_** doit être remplacé par n’importe quelle méthode HTTP et le service associé (voir [Tableau 6](#table-6)). +- L’en-tête **Accept** indique la version de ressource API que le client souhaite utiliser. + - Le type d’application est toujours **application/vnd.interoperability.**_{resource}_ où _{resource}_ est la vraie ressource (**participants**, **quotes**, ...). + - Le seul format d’échange de données actuellement supporté est **json**. + - Pour n’importe quelle version mineure d’une version majeure : envoyer uniquement la version majeure : **version=1** ou **version=2**. + - Pour une version mineure précise : utiliser **version=1.2** ou **version=2.8**. L’utilisation d’une version majeure.mineure spécifique est à éviter habituellement (les versions mineures étant rétrocompatibles). + +#### Version acceptable demandée par le client + +Si le serveur supporte la version API demandée via Accept, il doit utiliser cette version dans le callback. La version majeure.mineure utilisée doit toujours être indiquée dans l’en-tête **Content-Type**, même si le client n’a demandé que la majeure. Par exemple (voir [exemple 4](#listing-4)) : version 1.0 utilisée : + +###### Exemple 4 + +``` +Content-Type: application/vnd.interoperability.resource+json;version=1.0 +``` + +**Exemple 4 — Champ HTTP Content-Type** + +#### Version non acceptable demandée par le client + +Si le serveur ne supporte pas la version demandée dans **Accept**, il doit répondre HTTP 406 pour signifier l’absence de support. + +**Remarque :** il est aussi possible que cette information soit envoyée via un callback d’erreur et non directement — par exemple si la requête passe via un Switch qui supporte la version, mais que le FSP de destination non. + +En plus du HTTP 406, les versions supportées doivent figurer dans la liste des extensions de l’erreur, avec le numéro majeur comme clé et le mineur comme valeur. Voir [exemple 5](#listing-5) : « Je ne supporte pas la version demandée, mais je supporte 1.0, 2.1 et 4.2. » + +###### Exemple 5 + +```json +{ + "errorInformation": { + "errorCode": "3001", + "errorDescription": "Le client a demandé une version non supportée, voir la liste d'extensions pour les versions supportées.", + "extensionList": { + "extension": + [ + { "key": "1", "value": "0"}, + { "key": "2", "value": "1"}, + { "key": "4", "value": "2"} + ] + } + } +} +``` + +**Exemple 5 — Message d’erreur : la version demandée n’est pas supportée** + + +
+ +## Protocole Interledger + +La version actuelle de l’API introduit une prise en charge basique du protocole Interledger (ILP), à travers l’implémentation concrète du protocole Interledger Payment Request24 dans la ressource API [/quotes](#api-resource-quotes) et [**/transfers**](#api-resource-transfers). + +### Plus d’informations + +Ce document contient les informations ILP utiles à l’API. Pour davantage d’informations, consultez le site du projet Interledger25, le livre blanc Interledger26, et la spécification Interledger architecture27. + +### Introduction à Interledger + +ILP est une norme pour l’interconnexion des réseaux de paiement. De la même façon que le protocole IP constitue les bases pour la transmission et l’adressage entre réseaux de données différents, ILP définit des bases pour l’adressage des transactions financières et le transfert de valeur entre comptes sur différents réseaux de paiement. + +ILP n’est pas un scheme en soi. C’est un ensemble de standards qui, s’il est mis en œuvre par plusieurs schemes de paiement, permettra leur interopérabilité. Par conséquent, implémenter ILP implique d’adapter un scheme existant à ces standards. Cela implique notamment que les transferts se fassent en deux phases (_réserve_ et _validation_) et la définition d’une correspondance entre les comptes du scheme et le système d’adressage mondial ILP. Cela peut se faire en modifiant le scheme lui-même, ou via des entités qui fournissent une compatibilité ILP via des adaptateurs. + +Les prérequis pour un paiement ILP sont l’adresse ILP du Bénéficiaire (voir [Adressage ILP](#ilp-addressing)) et la condition (voir [Transferts conditionnels](#conditional-transfers)). Dans la version actuelle de l’API, ces deux informations doivent être renvoyées par le FSP Bénéficiaire lors d’un devis ([**/quotes**](#api-resource-quotes)). + +### Adressage ILP + +Un composant clé du standard ILP est le système d’adressage28. Il s’agit d’un système hiérarchique définissant une ou plusieurs adresses pour chaque compte d’un registre. + +[Le tableau 5](#table-5) donne des exemples d’adresses ILP dans différents scénarios. À noter : la structure est standardisée, le contenu non, sauf pour le premier segment (avant le premier point). + +###### Tableau 5 + +|Adresse ILP|Description| +|---|---| +|**g.tz.fsp1.msisdn.1234567890**|Un compte mobile money chez **FSP1** pour l’utilisateur de **MSISDN 1234567890**.| +|**g.pk.fsp2.ac03396c-4dba-4743**|Un compte mobile money chez **FSP2** identifié par un ID opaque.| +|**g.us.bank1.bob**|Un compte bancaire chez **Bank1** pour l’utilisateur **bob**.| + +**Tableau 5 — Exemples d’adresses ILP** + +Le but principal d’une adresse ILP est d’identifier un compte et de router une transaction financière vers ce compte. + +**Remarque :** Une adresse ILP ne doit pas servir à identifier une contrepartie dans l’API d’interopérabilité. Voir la section [Remboursement](#refund) pour l’adressage d’une Party dans l’API. + +Penser à une adresse ILP comme à une adresse IP : jamais vue par l’utilisateur final, mais utilisée côté système pour router une transaction et identifier un compte. Un même compte aura souvent plusieurs adresses ILP. Le système qui tient le compte peut suivre toutes ou seulement une partie si elles partagent un préfixe commun. + +### Transferts conditionnels + +ILP se base sur les _transferts conditionnels_, où tous les registres impliqués dans une transaction financière peuvent d’abord réserver des fonds du compte Payeur puis, plus tard, les déposer dans celui du Bénéficiaire. Le transfert du Payeur au Bénéficiaire dépend de la présentation d’un _accomplissement_ (fulfilment) qui respecte la condition associée à la requête d’origine. + +Pour supporter les transferts conditionnels, un registre doit permettre d’attacher une condition et une expiration à chaque transfert. Le registre doit réserver les fonds du compte Payeur, puis attendre l’un des événements suivants : + +- L’accomplissement de la condition est soumis au registre : les fonds sont crédités sur le compte du Bénéficiaire. +- L’expiration est atteinte, ou la transaction est rejetée (par le Bénéficiaire, son FSP…). Le transfert est alors annulé et les fonds remis au Payeur. + +Lorsqu’un accomplissement est soumis, le registre doit s’assurer qu’il satisfait bien la condition associée à la requête. Si oui, le transfert est validé ; sinon, il est refusé, et reste en attente jusqu’à obtention d’un accomplissement valide ou expiration. + +ILP supporte différentes conditions, mais les implémenteurs de l’API doivent utiliser le hash SHA-256 d’un pré-image de 32 octets. La condition jointe au transfert est le SHA-256, l’accomplissement étant le pré-image. Ainsi, quand la condition jointe est un SHA-256, une fois un accomplissement soumis, le registre le valide en calculant son SHA-256 et vérifiant qu’il correspond. + +Voir [Interledger Payment Request](#interledger-payment-request) pour des informations concrètes sur la génération de l’accomplissement (fulfilment) et de la condition. + +### Paquet ILP + +Le _paquet ILP_ sert à emballer des données de bout en bout pouvant être transmises service par service. Il est inclus comme champ dans les requêtes « hop by hop » et ne doit jamais être modifié par un intermédiaire. L'intégrité du paquet est liée à celle du transfert de fonds, car le déclencheur de validation (fulfilment) est généré à partir d'un hash du paquet. + +Le paquet a un format binaire strict, car il peut transiter par des systèmes à haut débit/volume, qui doivent lire l’adresse ILP et le montant depuis les headers, sans avoir à interpréter le champ **data** du paquet (voir [Exemple 6](#listing-6)). Comme ils ne doivent pas l’interpréter, ce champ reste au format octet variable dans la définition. Voir [Interledger Payment Request](#interledger-payment-request) pour le détail sur la manière de peupler ce champ dans l’API. + +Le paquet ILP relie les transferts livre à livre qui composent tout paiement ILP. Il est parsé par le destinataire du premier transfert, utilisé pour savoir vers où router le suivant et pour quel montant, lui est passé, etc., jusqu’au Bénéficiaire final qui fournit l’accomplissement, ce qui valide les transferts en chaîne, du dernier au premier. + +Le format du paquet ILP est défini en ASN.129 (Abstract Syntax Notation One), voir [Exemple 6](#listing-6). L’encodage se fait avec les règles canoniques Octet Encoding Rules. + +###### Exemple 6 + +``` +InterledgerProtocolPaymentMessage ::= SEQUENCE { + -- Montant qui doit être reçu à destination : amount UInt64, + -- Adresse ILP destinataire : account Address, + -- Information pour le destinataire (couche de transport) : data OCTET STRING (SIZE (0..32767)), + -- Extensibilité ASN.1 + extensions SEQUENCE { + ... + } +} +``` + +**Exemple 6 — Format du paquet ILP en ASN.1** + +**Remarque :** Les seuls éléments obligatoires sont le montant à transférer au Bénéficiaire et son adresse ILP. + +
+ +## Fonctionnalités courantes de l'API + +Cette section décrit les fonctionnalités communes utilisées par l'API, incluant : + +- [Devis (Quoting)](#quoting) +- [Adressage des Parties](#party-addressing) +- [Mapping de cas d’utilisation vers les types de transactions](#mapping-of-use-cases-to-transaction-types) + +### Devis (Quoting) + +Le devis est le processus qui détermine les frais et les commissions nécessaires pour effectuer une transaction financière entre deux FSP. Il est toujours initié par le FSP Payeur vers le FSP Bénéficiaire, ce qui signifie que le devis circule dans le même sens qu'une transaction financière. + +Deux modes différents pour établir un devis entre FSP sont pris en charge dans l’API : _Non-divulgation des frais_ et _Divulgation des frais_. + +- La _Non-divulgation des frais_ doit être utilisée lorsque le FSP Payeur ne souhaite pas montrer sa structure de frais au FSP Bénéficiaire, ou lorsqu’il souhaite avoir plus de contrôle sur les frais payés par le Payeur une fois le devis établi (ce dernier cas s’applique uniquement pour le _montant à recevoir_ ; voir la liste suivante). + +- La _Divulgation des frais_ peut être utilisée dans des cas où le FSP Bénéficiaire souhaite subventionner la transaction ; par exemple, lors d'un dépôt d'espèces chez un agent d’un autre FSP. + +La _Non-divulgation des frais_ doit être le mode standard de devis supporté dans la plupart des schémas. La _Divulgation des frais_ peut être utilisée dans certains schémas, par exemple lorsqu’une structure de frais dynamique est utilisée et qu’un FSP souhaite pouvoir subventionner le cas d’usage de dépôt d’espèces sur la base d’un coût dynamique. + +En outre, le Payeur peut décider si le montant doit être un _montant à recevoir_ ou _montant à envoyer_. + +- _Montant à envoyer_ doit être interprété comme le montant réel à déduire du compte du Payeur, frais inclus. + +- _Montant à recevoir_ doit être interprété comme le montant qui doit être crédité sur le compte du Bénéficiaire, indépendamment des frais de transaction interopérables. Ce montant exclut d’éventuels frais internes ajoutés par le FSP Bénéficiaire. + +Le FSP Bénéficiaire peut choisir d’envoyer ou non le montant réellement reçu par le Bénéficiaire dans la réponse au FSP Payeur. Ce montant doit inclure les éventuels frais internes appliqués par le FSP Bénéficiaire au Bénéficiaire. + +Toutes les taxes sont supposées être internes au FSP, ce qui signifie qu'elles ne sont pas transmises via l'API. Consultez [Informations fiscales](#tax-information) pour plus de détails sur la fiscalité. + +**Remarque :** Les frais dynamiques mis en œuvre via un Switch ou tout autre intermédiaire ne sont pas pris en charge dans cette version de l’API. + +#### Non-divulgation des frais + +Les paiements de frais et de commissions relatifs à une transaction interopérable lorsque les frais ne sont pas divulgués sont illustrés dans la [Figure 7](#figure-7). Les frais et commissions faisant directement partie de l’API sont identifiés en texte vert. Les éléments internes (frais, commissions, bonus internes) sont identifiés en texte rouge—et ne font pas partie de la transaction entre un FSP Payeur et un FSP Bénéficiaire, mais le montant reçu par le Bénéficiaire après déduction de frais internes peut être communiqué à titre informatif par le FSP Bénéficiaire. + +Pour un _montant à envoyer_ (voir [Montant à envoyer sans divulgation](#non-disclosing-send-amount)), des frais internes du FSP Payeur appliqués au Payeur vont affecter le montant envoyé par ce FSP (ex : pour une transaction de 100 USD avec 1 USD de frais, 99 USD sont envoyés). Pour un _montant à recevoir_ (voir [Montant à recevoir sans divulgation](#non-disclosing-receive-amount)), ces frais internes n'ont pas d'effet sur le montant envoyé. Les bonus ou commissions internes du FSP Payeur doivent être cachés, quel que soit le mode (envoi/réception). + +###### Figure 7 + +![Figure 7](../../assets/diagrams/images/figure7.svg) + +**Figure 7 -- Frais et commissions liés à l’interopérabilité lorsque les frais ne sont pas divulgués** + +Voir [Types de frais](#fee-types) pour plus d’informations sur les types de frais envoyés via l’API. + +#### Montant à recevoir sans divulgation + +[Figure 8](#figure-8) présente un exemple de montant à recevoir sans divulgation, où le Payeur souhaite que le Bénéficiaire reçoive exactement 100 USD. Dans ce cas, le FSP Payeur ne fixe pas nécessairement les frais internes avant d’avoir reçu le devis, puisque le FSP Bénéficiaire connaît déjà le montant qu’il recevra. + +Dans cet exemple, le FSP Bénéficiaire décide de verser une commission au FSP Payeur, car les fonds sont injectés dans le système du FSP Bénéficiaire et seront ultérieurement dépensés, ce qui représente un gain futur pour le FSP Bénéficiaire. Le FSP Payeur décide ensuite des frais à facturer au Payeur. Par exemple, s'il veut percevoir 1 USD de frais du Payeur (et reçoit aussi 1 USD de commission), il gagne au total 2 USD. + +###### Figure 8 + +![](../../assets/diagrams/sequence/figure8.svg) + +**Figure 8 -- Exemple de montant à recevoir sans divulgation** + +###### Figure 9 + +![Figure 9](../../assets/diagrams/images/figure9.svg) + +**Figure 9 -- Vue simplifiée du mouvement de fonds pour l’exemple précédent** + +Pour calculer l’élément **transferAmount** dans le FSP Bénéficiaire pour un devis à montant à recevoir sans divulgation, appliquer l’équation [Listing 9](#listing-9), où le _Montant de transfert_ correspond à **transferAmount** ([Tableau 24](#table-24)), le _Montant du devis_ à **amount** ([Tableau 23](#table-23)), les _frais FSP Bénéficiaire_ à **payeeFspFee** ([Tableau 24](#table-24)), et la commission FSP Bénéficiaire à **payeeFspCommission** ([Tableau 24](#table-24)). + +###### Listing 7 + +``` +Montant de transfert = Montant du devis + Frais FSP Bénéficiaire – Commission FSP Bénéficiaire +``` + +**Listing 7 -- Relation entre le montant de transfert et le montant du devis pour ce cas** + +#### Montant à envoyer sans divulgation + +[Figure 10](#figure-10) montre un exemple où le Payeur souhaite envoyer 100 USD. Ici, le FSP Payeur doit déterminer les frais, commissions ou les deux avant d’envoyer le devis, pour que le FSP Bénéficiaire connaisse le montant qui sera reçu. Le montant retiré du compte du Payeur n’est pas communiqué, ni les frais. + +Dans cet exemple, le FSP Payeur et le FSP Bénéficiaire veulent chacun 1 USD de frais, donc le Bénéficiaire recevra 98 USD. Le montant reçu peut être indiqué dans la réponse sous l’élément **payeeReceiveAmount**, mais ce n’est pas obligatoire. + +###### Figure 10 + +![](../../assets/diagrams/sequence/figure10.svg) + +**Figure 10 -- Exemple de montant à envoyer sans divulgation** + +###### Figure 11 + +[Figure 11](#figure-11) : vue simplifiée du mouvement d’argent. + +![Figure 11](../../assets/diagrams/images/figure11.svg) + +**Figure 11 -- Vue simplifiée du mouvement de fonds pour cet exemple** + +Pour calculer **transferAmount**, utiliser l’équation du [Listing 8](#listing-8) : _Montant du transfert_ = **transferAmount** ([Tableau 24](#table-24)), _Montant du devis_ = **amount**, commission = **payeeFspCommission**. + +###### Listing 8 + +``` +Montant de transfert = Montant du devis – Commission FSP Bénéficiaire +``` + +**Listing 8 -- Relation entre le montant de transfert et le montant du devis pour ce cas** + +La raison pour laquelle les frais FSP Bénéficiaire sont absents de l’équation : le Payeur veut envoyer un certain montant de son compte, le Bénéficiaire reçoit donc moins au lieu que des frais soient ajoutés au montant. + +#### Divulgation des frais + +Les paiements de frais et de commissions relatifs à une transaction interopérable lorsque les frais sont divulgués se trouvent en [Figure 12](#figure-12). Ce qui est directement lié à l’API est indiqué en vert. Les frais, bonus, et commissions internes sont en rouge : ils impactent le montant envoyé/reçu mais ne sont pas transmis dans la transaction interopérable. Le montant net reçu par le Bénéficiaire (après frais internes) peut être transmis à titre d’information. + +Quand la divulgation des frais est utilisée, la commission envoyée par le FSP Bénéficiaire doit subventionner tout ou partie du coût de la transaction pour le Payeur. Si la commission est supérieure aux frais pour le Payeur, l’excédent doit être traité comme un frais payé du Bénéficiaire au Payeur. Un exemple : [ici](#excess-fsp-commission-example). + +###### Figure 12 + +![Figure 12](../../assets/diagrams/images/figure12.svg) + +**Figure 12 -- Frais et commissions liés à l’interopérabilité lorsque les frais +sont divulgués** + +Voir [Types de frais](#fee-types) pour plus d'informations. + +#### Montant à recevoir avec divulgation + +[Figure 13](#figure-13) : le Payeur veut que le Bénéficiaire reçoive 100 USD. Le FSP Payeur doit évaluer la transaction en interne avant d’envoyer la demande de devis, car les frais sont divulgués. Exemple : le FSP Payeur veut 1 USD de frais, le FSP Bénéficiaire attribue 1 USD de commission pour subventionner, rendant la transaction gratuite pour le Payeur. + +###### Figure 13 + +![](../../assets/diagrams/sequence/figure13.svg) + +**Figure 13 -- Exemple avec montant à recevoir en divulgation** + +[Figure 14](#figure-14) : vue simplifiée. + +###### Figure 14 + +![Figure 14](../../assets/diagrams/images/figure14.svg) + +**Figure 14 -- Vue simplifiée du mouvement de fonds** + +Pour calculer **transferAmount** côté FSP Bénéficiaire pour ce type de devis, appliquer l'équation du [Listing 9](#listing-9), où _Montant transfert_ = **transferAmount**, _Montant devis_ = **amount**, frais FSP Bénéficiaire = **payeeFspFee**, commission FSP Bénéficiaire = **payeeFspCommission**. + +###### Listing 9 + +``` +Montant de transfert = Montant du devis + Frais FSP Bénéficiaire – Commission FSP Bénéficiaire +``` + +**Listing 9 -- Relation pour ce cas** + +#### Montant à envoyer avec divulgation + +[Figure 15](#figure-15) : le Payeur souhaite envoyer 100 USD au Bénéficiaire. Les frais doivent être calculés avant la demande de devis, car ils sont divulgués. Exemple : chaque FSP souhaite 1 USD de frais. + +###### Figure 15 + +![](../../assets/diagrams/sequence/figure15.svg) + +**Figure 15 -- Exemple avec montant à envoyer en divulgation** + +###### Figure 16 + +[Figure 16](#figure-16) : vue simplifiée du mouvement de fonds. + +![Figure 16](../../assets/diagrams/images/figure16.svg) + +**Figure 16 -- Vue simplifiée pour ce cas** + +Pour calculer **transferAmount** (côté FSP Bénéficiaire), l’équation du [Listing 10](#listing-10) doit être utilisée : + +###### Listing 10 + +``` +Si (Frais Payeur <= Commission FSP Bénéficiaire) + Montant de transfert = Montant du devis +Sinon + Montant de transfert = Montant du devis – (Frais Payeur – Commission FSP Bénéficiaire) +``` + +**Listing 10 -- Relation pour ce cas** + +Les frais FSP Bénéficiaire sont absents : on souhaite envoyer un montant précis, le Bénéficiaire reçoit donc moins, plutôt que d’ajouter les frais « par-dessus ». + +#### Exemple d’excédent de commission FSP + +[Figure 17](#figure-17) : excédent de commission FSP avec divulgation du montant à envoyer : le Payeur souhaite envoyer 100 USD, le FSP Payeur veut 1 USD de frais, le FSP Bénéficiaire donne 3 USD de commission. Sur les 3 USD, 1 USD couvre les frais Payeur, 2 USD reviennent au FSP Payeur. + +###### Figure 17 + +![](../../assets/diagrams/sequence/figure17.svg) + +**Figure 17 -- Exemple d’excédent de commission** + +###### Figure 18 + +[Figure 18](#figure-18) : vue simplifiée du mouvement de fonds. + +![Figure 18](../../assets/diagrams/images/figure18.svg) + +**Figure 18 -- Vue simplifiée pour ce cas** + +#### Types de frais + +Comme vu en [Figure 7](#figure-7) et [Figure 12](#figure-12), il existe deux types de frais et commissions dans l’objet Quote entre FSP : + +1. **Frais FSP Bénéficiaire** : frais de transaction que le FSP Bénéficiaire souhaite obtenir pour la gestion de la transaction. +2. **Commission FSP Bénéficiaire** : commission que le FSP Bénéficiaire veut verser au FSP Payeur (non-divulgation) ou subventionner la transaction en payant à la place du FSP Payeur (divulgation). Si excédent, il est traité comme frais payé du Bénéficiaire vers le Payeur, voir l’exemple d’excès de commission. + +
+ +#### Équations de devis + +Section contenant des formules utiles pour les devis qui n’ont pas encore été mentionnées. + +#### Relation entre montant reçu par le Bénéficiaire et montant de transfert + +Le montant que doit recevoir le Bénéficiaire, hors frais internes, bonus ou commission FSP Bénéficiaire, peut être calculé par le FSP Payeur via [Listing 11](#listing-11). _Montant de transfert_ = **transferAmount**, frais FSP Bénéficiaire = **payeeFspFee**, commission = **payeeFspCommission**. + +###### Listing 11 + +``` +Montant reçu Bénéficiaire = Montant de transfert - Frais FSP Bénéficiaire + Commission FSP Bénéficiaire +``` + +**Listing 11 -- Relation entre montant de transfert et montant reçu** + +Le montant reçu peut optionnellement être transmis lors du retour du devis sous **payeeReceiveAmount**. + +
+ +#### Informations fiscales + +Aucune information de taxe n’est transmise via l’API (toute la fiscalité est considérée comme interne). Les sections suivantes détaillent les cas les plus courants. + +##### Taxe sur la commission des agents + +Taxe sur la commission d’un agent (en tant que revenu). C’est l’agent ou son FSP qui gère la relation avec l’administration fiscale, selon le cas. Toutes les commissions agent étant internes, rien n’est transmis dans l’API. + +##### Taxe sur les frais internes FSP + +Un FSP peut être taxé sur certains frais internes reçus : ex : frais Payeur vers son FSP, ou frais Bénéficiaire vers son FSP. Cette taxe doit être gérée et collectée en interne par le FSP concerné. + +##### Taxe sur le montant (TVA, taxe de vente, ... ) + +La TVA ou les taxes de vente sont des taxes sur un montant, typiquement supportées par le consommateur lors d’un achat marchand. Le marchand collecte la taxe et reverse à l’administration. Si la TVA s’applique, elle doit être incluse dans la somme demandée au client, et le montant reçu par le FSP Bénéficiaire est taxé en conséquence. + +##### Taxe sur frais FSP + +Dans l’API, un FSP Bénéficiaire peut ajouter un frais à payer par le Payeur ou son FSP. Il doit gérer la fiscalité conformément à la pratique locale, en interne et sans transmettre de détail via l’API. + +##### Taxe sur la commission FSP + +Un FSP Bénéficiaire peut ajouter une commission, soit pour subventionner la transaction (divulgation), soit pour inciter le FSP Payeur (non-divulgation). + +###### Non-divulgation des frais + +Dans ce cas, toute commission FSP Bénéficiaire doit être considérée comme un frais reçu par le FSP Payeur. La taxe correspondante est gérée en interne comme tout frais reçu. + +###### Divulgation des frais + +Si le montant de commission est inférieur ou égal aux frais à la charge du Payeur, la commission sert à couvrir ces frais. Si elle les dépasse, l’excédent est traité comme dans la non-divulgation. + +
+ +#### Exemples pour chaque cas d’usage + +Cette section présente un ou plusieurs exemples pour chaque cas. + +#### Virement P2P + +Un virement P2P est typiquement un montant à recevoir, sans aucune divulgation de frais côté Bénéficiaire ([Figure 19](#figure-19)). Ex : le Payeur veut que le Bénéficiaire reçoive 100 USD. Le FSP Bénéficiaire offre une commission au FSP Payeur. Le FSP Payeur prend 1 USD de frais à son client : il gagne donc 2 USD (1 USD venant du client, 1 USD en commission). 99 USD sont transférés après déduction de la commission. + +###### Figure 19 + +![](../../assets/diagrams/sequence/figure19.svg) + +**Figure 19 -- Exemple virement P2P avec montant à recevoir** + +###### Vue simplifiée du mouvement de fonds + +###### Figure 20 + +Voir [Figure 20](#figure-20) pour une vue très simplifiée du mouvement. + +![Figure 20](../../assets/diagrams/images/figure20.svg) + +**Figure 20 -- Vue simplifiée virement P2P** + +##### Dépôt d’espèces initié par l’agent (Montant à envoyer) + +[Figure 21](#figure-21) : dépôt avec divulgation des frais. Le Bénéficiaire veut savoir les frais avant d’accepter l’opération. Exemple : le client souhaite déposer 100 USD chez un agent du FSP Payeur. Celui-ci prend 2 USD de frais, le FSP Bénéficiaire subventionne la transaction avec 2 USD de commission pour couvrir ces frais. 98 USD sont transférés après déduction de la commission. + +###### Figure 21 + +![](../../assets/diagrams/sequence/figure21.svg) + +**Figure 21 -- Exemple dépôt agent, montant à envoyer** + +###### Vue simplifiée + +Voir [Figure 22](#figure-22). + +###### Figure 22 + +![Figure 22](../../assets/diagrams/images/figure22.svg) + +**Figure 22 -- Vue simplifiée dépôt agent** + +##### Dépôt d’espèces initié par l’agent (Montant à recevoir) + +[Figure 23](#figure-23) : dépôt avec divulgation des frais, client souhaite recevoir exactement 100 USD. Le FSP Payeur souhaite 2 USD de frais pour la commission agent ; le FSP Bénéficiaire subventionne 1 USD en commission (50 % des frais). 99 USD transférés après déduction de la commission. + +###### Figure 23 + +![](../../assets/diagrams/sequence/figure23.svg) + +**Figure 23 -- Exemple dépôt agent, montant à recevoir** + +###### Vue simplifiée + +###### Figure 24 + +Voir [Figure 24](#figure-24). + +![Figure 24](../../assets/diagrams/images/figure24.svg) + +**Figure 24 -- Vue simplifiée dépôt agent montant à recevoir** + +##### Paiement marchand initié par le client + +Typiquement un montant à recevoir sans divulgation des frais. Ex : achat de biens/ services pour 100 USD auprès d’un marchand dans le FSP Bénéficiaire. Le FSP Bénéficiaire ne facture pas le client mais prend un frais caché d’1 USD au marchand. Le FSP Payeur prélève 1 USD au client. 100 USD sont transférés. + +###### Figure 25 + +![](../../assets/diagrams/sequence/figure25.svg) + +**Figure 25 -- Exemple paiement marchand client** + +###### Vue simplifiée + +Voir [Figure 26](#figure-26). + +###### Figure 26 + +![Figure 26](../../assets/diagrams/images/figure26.svg) + +**Figure 26 -- Vue simplifiée paiement marchand client** + +##### Retrait d’espèces initié par le client (Montant à recevoir) + +Typiquement, montant à recevoir sans divulgation des frais. Ex : le client veut retirer 100 USD en espèces. Le FSP Bénéficiaire prend 2 USD de frais (commission agent), le FSP Payeur prend 1 USD. 102 USD transférés. + +###### Figure 27 + +![](../../assets/diagrams/sequence/figure27.svg) + +**Figure 27 -- Exemple retrait client (montant à recevoir)** + +###### Vue simplifiée + +Voir [Figure 28](#figure-28). + +###### Figure 28 + +![Figure 28](../../assets/diagrams/images/figure28.svg) + +**Figure 28 -- Vue simplifiée retrait client (montant à recevoir)** + +##### Retrait d’espèces initié par le client (Montant à envoyer) + +Normalement, typiquement montant à recevoir, mais ici exemple avec montant à envoyer : voir [Figure 29](#figure-29). Le client veut retirer 100 USD de son compte. Le FSP Bénéficiaire prend 2 USD (commission agent), le FSP Payeur prend 1 USD. 99 USD transférés. + +###### Figure 29 + +![](../../assets/diagrams/sequence/figure29.svg) + +**Figure 29 -- Exemple retrait client (montant à envoyer)** + +###### Vue simplifiée + +Voir [Figure 30](#figure-30). + +###### Figure 30 + +![Figure 30](../../assets/diagrams/images/figure30.svg) + +**Figure 30 -- Vue simplifiée retrait client (montant à envoyer)** + +#### Retrait initié par agent + +Montant à recevoir, pas de divulgation des frais côté FSP Payeur. Ex : le client veut recevoir 100 USD en liquide. Frais : 2 USD côté FSP Bénéficiaire ; 1 USD côté FSP Payeur. 102 USD transférés. + +###### Figure 31 + +![](../../assets/diagrams/sequence/figure31.svg) + +**Figure 31 -- Exemple retrait agent** + +###### Vue simplifiée + +Voir [Figure 32](#figure-32). + +###### Figure 32 + +![Figure 32](../../assets/diagrams/images/figure32.svg) + +**Figure 32 -- Vue simplifiée retrait agent** + +##### Paiement marchand initié par le marchand + +Montant à recevoir, pas de divulgation des frais. Ex : achat de 100 USD, aucun frais Bénéficiaire, mais 1 USD de frais côté Payeur. 100 USD transférés. + +###### Figure 33 + +![](../../assets/diagrams/sequence/figure33.svg) + +**Figure 33 -- Exemple paiement marchand initié par marchand** + +###### Vue simplifiée + +Voir [Figure 34](#figure-34). + +###### Figure 34 + +![Figure 34](../../assets/diagrams/images/figure34.svg) + +**Figure 34 -- Vue simplifiée paiement marchand initié par marchand** + +##### Retrait initié par ATM + +Montant à recevoir, pas de divulgation. Ex : retrait de 100 USD en espèces, 1 USD de frais côté FSP Bénéficiaire (frais ATM), 1 USD côté FSP Payeur. 101 USD transférés. + +###### Figure 35 + +![](../../assets/diagrams/sequence/figure35.svg) + +**Figure 35 -- Exemple retrait ATM** + +###### Vue simplifiée + +Voir [Figure 36](#figure-36). + +###### Figure 36 + +![Figure 36](../../assets/diagrams/images/figure36.svg) + +**Figure 36 -- Vue simplifiée retrait ATM** + +##### Paiement marchand initié par le marchand autorisé sur un TPE + +Montant à recevoir, pas de divulgation des frais. Ex : achat de 100 USD, le FSP Bénéficiaire accorde 1 USD de commission, le FSP Payeur l’utilise comme frais. 100 USD transférés. + +###### Figure 37 + +![](../../assets/diagrams/sequence/figure37.svg) + +**Figure 37 -- Exemple paiement marchand sur TPE** + +###### Vue simplifiée + +Voir [Figure 38](#figure-38). + +###### Figure 38 + +![Figure 38](../../assets/diagrams/images/figure38.svg) + +**Figure 38 -- Vue simplifiée paiement marchand sur TPE** + +##### Remboursement + +[Figure 39](#figure-39) présente un exemple de remboursement du montant entier d’un dépôt d’espèces (voir exemple plus haut). + +###### Figure 39 + +![](../../assets/diagrams/sequence/figure39.svg) + +**Figure 39 -- Exemple de remboursement** + +#### 5.1.6.11.1 Vue simplifiée du mouvement de fonds + +Voir [Figure 40](#figure-40). + +###### Figure 40 + +![Figure 40](../../assets/diagrams/images/figure40.svg) + +**Figure 40 -- Vue simplifiée du remboursement** + +
+ +### Adressage des Parties + +Les deux parties d’une transaction financière (le `Payeur` et le `Bénéficiaire`) sont identifiées dans l’API par un _Type d’ID de Partie_ ([**PartyIdType**](#partyidtype-element)), un _ID de Partie_ ([**PartyIdentifier**](#partyidentifier-element)), et, éventuellement, un _Sous-ID ou Type de Partie_ ([PartySubIdOrType](#partysubidortype-element)). Certains sous-types sont prévus en standard pour des identifiants personnels ([PersonalIdentifierType](#personalidentifiertype-enum)), par ex. pour le numéro de passeport ou le permis de conduire. + +Exemples de base d’utilisation des éléments _Party ID Type_ et _Party ID_ : + +- Pour utiliser le numéro de téléphone mobile **+123456789** comme contrepartie, mettre *Party ID Type* à **MSISDN** et _Party ID_ à **+123456789**. + - Exemple de service pour obtenir le FSP : + + **GET /participants/MSISDN/+123456789** + +- Pour utiliser l'adresse email **john\@doe.com**, mettre _Party ID Type_ à **EMAIL** et _Party ID_ à **john\@doe.com**. + - Exemple : + + **GET /participants/EMAIL/john\@doe.com** + +- Pour utiliser l’IBAN **SE45 5000 0000 0583 9825 7466** : _Party ID Type_ = **IBAN**, _Party ID_ = **SE4550000000058398257466** (sans espaces). + - Exemple : + + **GET /participants/IBAN/SE4550000000058398257466** + +Exemples avancés : + +- Pour une personne dont le numéro de passeport est **12345678** : _Party ID Type_ = **PERSONAL_ID**, _Party ID_ = **12345678**, _Party Sub ID or Type_ = **PASSPORT**. + - Exemple : + + **GET /participants/PERSONAL_ID/123456789/PASSPORT** + +- Pour **employeeId1** travaillant chez **Shoe-company** : _Party ID Type_ = **BUSINESS**, _Party ID_ = **Shoe-company**, _Party Sub ID or Type_ = **employeeId1** + - Exemple : + + **GET /participants/BUSINESS/Shoe-company/employeeId1** + +**5.2.1 Caractères interdits dans Party ID et Party Sub ID or Type** + +Le _Party ID_ et _Party Sub ID or Type_ font partie de l’URI (voir [Syntaxe URI](#uri-syntax)), donc certaines restrictions existent : + +- Barre oblique (**/**) interdite (utilisée dans le [Path](#path) pour la séparation). +- Point d’interrogation (**?**) interdit (identifie la [Query](#query) dans l’URI). + +
+ +### Correspondance des cas d’usage et des types de transaction + +Cette section décrit comment mapper les cas d’usage non-bulk actuellement supportés dans l’API vers le type complexe [**TransactionType**](#transactiontype)), en utilisant les éléments [TransactionScenario](#transactionscenario)), et [TransactionInitiator](#transactioninitiator)). + +Plus de détails dans _Cas d’usage de l’API_. + +#### Virement P2P + +Pour effectuer un virement P2P : + +- [**TransactionScenario**](#transactionscenario) = **TRANSFER** +- [**TransactionInitiator**](#transactioninitiator) = **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **CONSUMER** + +#### Dépôt d’espèces initié par agent + +- [**TransactionScenario**](#transactionscenario) = **DEPOSIT** +- [**TransactionInitiator**](#transactioninitiator) = **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **AGENT** + +#### Retrait d’espèces initié par agent + +- [**TransactionScenario**](#transactionscenario) = **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) = **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **AGENT** + +#### Retrait d’espèces par agent sur TPE + +- [**TransactionScenario**](#transactionscenario) = **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) = **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **AGENT** + +#### Retrait d’espèces initié par client + +- [**TransactionScenario**](#transactionscenario) = **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) = **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **CONSUMER** + +#### Paiement marchand initié par client + +- [**TransactionScenario**](#transactionscenario) = **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) = **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **CONSUMER** + +#### Paiement marchand initié par marchand + +- [**TransactionScenario**](#transactionscenario) = **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) = **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **BUSINESS** + +#### Paiement marchand initié par marchand sur TPE + +- [**TransactionScenario**](#transactionscenario) = **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) = **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **DEVICE** + +#### Retrait initié par ATM + +- [**TransactionScenario**](#transactionscenario) = **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) = **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) = **DEVICE** + +#### Remboursement + +Pour effectuer un remboursement, configurez les éléments comme suit : + +- [**TransactionScenario**](#transactionscenario) à **REFUND** +- [**TransactionInitiator**](#transactioninitiator) à **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) dépend de l’initiateur du remboursement. + +De plus, le type complexe [Refund](#refund) doit être renseigné avec l’identifiant de la transaction d’origine à rembourser. + +
+ +## Services de l’API + +Cette section présente et détaille tous les services que l’API prend en charge pour chaque ressource et méthode HTTP. Chaque ressource et service de l’API est également mappé à une ressource et un service logique décrits dans les [Modèles génériques de transaction](../generic-transaction-patterns). + +### Services API de haut niveau + +À un niveau élevé, l’API peut être utilisée pour réaliser les actions suivantes : + +- **Recherche d’informations sur un participant** — Déterminer dans quel FSP se situe la contrepartie d’une transaction financière. + - Utilisez les services fournis par la ressource API **/participants**. + +- **Recherche d’informations sur une partie** — Obtenir des informations sur la contrepartie d’une transaction financière. + - Utilisez les services fournis par la ressource API **/parties**. + +- **Demande de transaction** — Demander à un payeur de transférer des fonds électroniques au bénéficiaire, à la demande du bénéficiaire. Le payeur peut approuver ou refuser la demande. Une approbation initiera effectivement la transaction financière. + - Utilisez les services fournis par la ressource API **/transactionRequests**. + +- **Calculer une devis** — Calculer tous les éléments d’une transaction qui influenceront le montant de la transaction, c’est-à-dire les frais et la commission du FSP. + - Utilisez les services fournis par la ressource API **/quotes** pour le devis d’une transaction individuelle (un payeur vers un bénéficiaire). + - Utilisez les services fournis par la ressource API **/bulkQuotes** pour le devis d’une transaction groupée (un payeur vers plusieurs bénéficiaires). + +- **Réaliser une autorisation** — Demander au payeur de saisir les identifiants requis lorsqu’il a initié la transaction depuis un terminal de paiement, un DAB, ou un appareil similaire dans le système FSP du bénéficiaire. + - Utilisez les services fournis par la ressource API **/authorizations**. + +- **Effectuer un transfert** — Réaliser effectivement la transaction financière en transférant les fonds électroniques du payeur au bénéficiaire, éventuellement via des registres intermédiaires. + - Utilisez les services fournis par la ressource API **/transfers** pour une transaction unique (un payeur vers un bénéficiaire). + - Utilisez les services fournis par la ressource API **/bulkTransfers** pour une transaction groupée (un payeur vers plusieurs bénéficiaires). + +- **Récupérer les informations de transaction** — Obtenir les informations relatives à la transaction financière ; par exemple, un jeton créé en cas de transaction réussie. + - Utilisez les services fournis par la ressource API **/transactions**. + +#### Services API pris en charge + +[Tableau 6](#table-6) inclut des descriptions de haut niveau des services que l’API propose. Pour plus d’informations détaillées, consultez les sections suivantes. + +###### Tableau 6 + +|URI|Méthode HTTP GET|Méthode HTTP PUT|Méthode HTTP POST|Méthode HTTP DELETE|Méthode HTTP PATCH| +|---|---|---|---|---|---| +|**/participants**|Non pris en charge|Non pris en charge|Demande à un ALS de créer les informations FSP concernant les parties fournies dans le corps ou, si l'information existe déjà, demande à l’ALS de la mettre à jour|Non pris en charge|Non pris en charge| +|**/participants/**_{ID}_|Non pris en charge|Callback pour informer un FSP pair d’une liste de parties précédemment créée.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/participants/**_{Type}_/_{ID}_ Alternative : **/participants/**_{Type}_/_{ID}_/_{SubId}_|Obtenir les informations FSP concernant une partie depuis un FSP pair ou un ALS.|Callback pour informer un FSP pair des informations FSP demandées ou créées.|Demander à un ALS de créer une information FSP concernant une partie ou, si elle existe déjà, de la mettre à jour|Demander à un ALS de supprimer les informations FSP concernant une partie.|Non pris en charge| +|**/parties/**_{Type}_/_{ID}_ Alternative : **/parties/**_{Type}_/_{ID}_/_{SubId}_|Obtenir des informations concernant une partie depuis un FSP pair.|Callback pour informer un FSP pair des informations demandées sur la partie.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/transactionRequests**|Non pris en charge|Non pris en charge|Demander à un FSP pair de solliciter l’approbation d’un payeur pour transférer des fonds à un bénéficiaire. Le payeur peut approuver ou refuser la demande.|Non pris en charge|Non pris en charge| +|**/transactionRequests/**_{ID}_|Obtenir des informations concernant une demande de transaction déjà envoyée.|Callback pour informer un FSP pair d’une demande de transaction déjà envoyée.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/quotes**|Non pris en charge|Non pris en charge|Demander à un FSP pair de créer une nouvelle devis pour réaliser une transaction.|Non pris en charge|Non pris en charge| +|**/quotes/**_{ID}_|Obtenir des informations concernant une devis déjà demandée.|Callback pour informer un FSP pair d’une devis demandée précédemment.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/authorizations/**_{ID}_|Obtenir l’autorisation pour une transaction du payeur qui interagit avec le système FSP du bénéficiaire.|Callback pour informer le FSP payeur concernant les informations d’autorisation.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/transfers**|Non pris en charge|Non pris en charge|Demander à un FSP pair d’effectuer le transfert des fonds liés à une transaction.|Non pris en charge|Non pris en charge| +|**/transfers/**_{ID}_|Obtenir des informations concernant un transfert déjà effectué.|Callback pour informer un FSP pair d’un transfert déjà effectué.|Non pris en charge|Non pris en charge|Notification d’engagement au FSP bénéficiaire| +|**/transactions/**_{ID}_|Obtenir des informations concernant une transaction déjà réalisée.|Callback pour informer un FSP pair d’une transaction déjà réalisée.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/bulkQuotes**|Non pris en charge|Non pris en charge|Demander à un FSP pair de créer une nouvelle devis pour effectuer une transaction groupée.|Non pris en charge|Non pris en charge| +|**/bulkQuotes/**_{ID}_|Obtenir des informations concernant une devis groupé déjà demandée.|Callback pour informer un FSP pair d’une devis groupé déjà demandée.|Non pris en charge|Non pris en charge|Non pris en charge| +|**/bulkTransfers**|Non pris en charge|Non pris en charge|Demander à un FSP pair de créer un transfert groupé.|Non pris en charge|Non pris en charge| +|**/bulkTransfers/**_{ID}_|Obtenir des informations concernant un transfert groupé déjà envoyé.|Callback pour informer un FSP pair d’un transfert groupé déjà envoyé.|Non pris en charge|Non pris en charge|Non pris en charge| + +**Tableau 6 – Services fournis par l’API** + +#### Versions actuelles des ressources + +[Tableau 7](#table-7) contient la version de chaque ressource décrite dans ce document. + +###### Tableau 7 + +|Ressource|Version actuelle|Dernière modification| +|---|---|---| +|/participants|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/parties|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/transactionRequests|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/quotes|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/authorizations|1.0|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/transfers|1.1|Ajout d’une possible notification de validation via PATCH /transfers/``. Le processus d’utilisation des notifications de validation est décrit à la section 6.7.2.6. Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/transactions|1.0|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/bulkQuotes|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| +|/bulkTransfers|1.1|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| + +**Tableau 7 – Versions actuelles des ressources** + +
+ +### Ressource API /participants + +Cette section définit la ressource API logique **Participants**, décrite dans les [Modèles génériques de transaction](../generic-transaction-patterns#api-resource-participants). + +Les services fournis par la ressource **/participants** servent principalement à déterminer dans quel FSP se trouve la contrepartie d’une transaction financière. Selon le schéma, ces services doivent être pris en charge, au minimum, soit par les FSP individuels soit par un service commun. + +Si un service commun (par exemple, un ALS) est pris en charge dans le schéma, les services de la ressource **/participants** peuvent aussi être utilisés par les FSP pour ajouter et supprimer des informations dans ce système. + +#### Historique des versions de la ressource + +[Tableau 8](#table-8) fournit une description de chaque version différente de la ressource **/participants**. + +###### Tableau 8 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| +|1.1|2020-05-19|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour. +Pour garantir la cohérence, le modèle de données pour les appels **POST /participants/**_{Type}/{ID}_ et **POST /participants/**_{Type}/{ID}/{SubId}_ du Tableau 10 a également été mis à jour pour inclure l’élément ExtensionList optionnel.| + +**Tableau 8 – Historique des versions pour la ressource /participants** + +#### Détails des services + +Différents modèles sont utilisés pour la recherche de compte, selon qu’un ALS existe ou non. Les sections suivantes décrivent chaque modèle à tour de rôle. + +#### Système sans service commun de recherche de comptes + +[Figure 41](#figure-41) montre comment effectuer une recherche de compte s’il n’existe pas d’ALS commun dans un schéma. Le processus consiste à demander aux autres FSP (en séquence) s’ils « possèdent » la partie avec le couple identité/type délivré jusqu’à trouver la partie. + +Si ce modèle est utilisé, tous les FSP doivent prendre en charge à la fois la partie cliente et serveur des différents services HTTP **GET** de la ressource **/participants**. Les services HTTP **POST** ou **DELETE** de la ressource **/participants** ne doivent pas être utilisés, car les FSP sont directement sollicités pour récupérer les informations (au lieu d’un ALS commun). + +###### Figure 41 + +![](../../assets/diagrams/sequence/figure41.svg) + + +**Figure 41 — Comment utiliser les services fournis par /participants s’il n’existe pas de système commun de recherche de comptes** + +#### Système de recherche de comptes commun + +[Figure 42](#figure-42) montre comment une recherche de compte peut être effectuée s’il existe un ALS commun dans un schéma. Le processus consiste à demander au service commun de recherche de comptes quel FSP détient la partie avec l’identité fournie. Le service commun est représenté comme « Account Lookup » dans les flux ; ce service peut être mis en œuvre par le Switch ou comme un service séparé, selon le marché. + +Les FSP n’ont pas besoin de prendre en charge la partie serveur des différents services HTTP **GET** sous la ressource **/participants** ; cette partie doit être assurée par l’ALS. À la place, les FSP (clients) doivent fournir des informations FSP concernant leurs comptes et titulaires de comptes (parties) à l’ALS (serveur) en utilisant les méthodes HTTP **POST** (pour créer ou mettre à jour les informations FSP, voir [POST /participants](#post-participants) et [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id)) et HTTP **DELETE** (pour supprimer les informations FSP existantes, voir [DELETE /participants/_{Type}_/_{ID}_](#delete-participantstypeid)). + +###### Figure 42 + +![](../../assets/diagrams/sequence/figure42.svg) + + +**Figure 42 — Comment utiliser les services fournis par /participants s’il existe un système commun de recherche de comptes** + +#### Requêtes + +Cette section décrit les services qu’un client peut demander sur la ressource **/participants**. + +##### GET /participants/_{Type}_/_{ID}_ + +URI alternative : **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Service logique API : [Recherche d’informations sur un participant](../generic-transaction-patterns#lookup-participant-information) + +La requête HTTP **GET /participants/**_{Type}_**/**_{ID}_ (ou **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) sert à déterminer dans quel FSP se trouve la partie demandée, définie par _{Type}_, _{ID}_ et éventuellement _{SubId}_ (par exemple, **GET** **/participants/MSISDN/123456789**, ou **GET /participants/BUSINESS/shoecompany/employee1**). Voir [Remboursement](#refund) pour plus d’informations sur l’adressage d’une partie. + +Cette requête HTTP doit prendre en charge une chaîne de requête (voir [Syntaxe URI](#uri-syntax) pour plus d’informations sur la syntaxe URI) pour filtrer par devise. Pour utiliser le filtrage par devise, la requête HTTP **GET /participants/**_{Type}_**/**_{ID}_**?currency=**_XYZ_ doit être utilisée, où _XYZ_ est la devise demandée. + +Informations de callback et de modèle de données pour **GET /participants/**_{Type}_**/**_{ID}_ (alternative **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback – [**PUT /participants/**_{Type}_/_{ID}_](#put-participants-type-id) +- Callback d’erreur – [**PUT /participants/**_{Type}_/_{ID}_**/error**](#put-participants-type-iderror) +- Modèle de données — Corps vide + +##### POST /participants + +URI alternative : N/A + +Service logique API : [Création d’informations bulk sur un participant](../generic-transaction-patterns#create-bulk-participant-information) + +La requête HTTP **POST /participants** est utilisée pour créer des informations sur le serveur concernant la liste d’identités fournie. Cette requête doit être utilisée pour la création groupée d’informations FSP pour plusieurs parties. Le paramètre de devise optionnel doit indiquer que chaque partie fournie prend en charge la devise. + +Callback et modèle de données pour **POST /participants** : + +- Callback – [**PUT /participants/**_{ID}_](#put-participants-type-id) +- Callback d’erreur – [**PUT /participants/**_{ID}_ **/error**](#put-participants-type-iderror) +- Modèle de données – Voir [Tableau 9](#table-9) + +###### Tableau 9 + +|Nom|Cardinalité|Type|Description| +|---|---|---|---| +|**requestId**|1|CorrelationId|L’identifiant de la requête, choisi par le client. Utilisé pour identifier le callback du serveur.| +|**partyList**|1..10000|PartyIdInfo|Liste des éléments PartyIdInfo pour lesquels le client souhaite créer ou mettre à jour les informations FSP.| +|**currency**|0..1|Currency|Indique que la devise fournie est prise en charge par chaque PartyIdInfo de la liste.| + +**Tableau 9 — Modèle de données POST /participants** + +##### POST /participants/_{Type}_/_{ID}_ + +URI alternative : **POST /participants/**_{Type}_/_{ID}_/_{SubId}_ + +Service logique API : [Création d’informations sur un participant](../generic-transaction-patterns#create-participant-information) + +La requête HTTP **POST /participants/**_{Type}_**/**_{ID}_ (ou **POST /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) est utilisée pour créer sur le serveur les informations concernant l’identité fournie, définie par _{Type}_, _{ID}_ et éventuellement _{SubId}_ (par exemple, **POST /participants/MSISDN/123456789** ou **POST /participants/BUSINESS/shoecompany/employee1**). Voir [Remboursement](#refund) pour plus d’informations sur l’adressage d’une partie. + +Callback et modèle de données pour **POST /participants**/_{Type}_**/**_{ID}_ (alternative **POST** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback – [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) +- Callback d’erreur — [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) +- Modèle de données – Voir [Tableau 10](#table-10) + +###### Tableau 10 + +|Nom|Cardinalité|Type|Description| +|---|---|---|---| +|**fspId**|1|FspId|Identifiant FSP auquel appartient la partie.| +|**currency**|0..1|Currency|Indique que la devise fournie est prise en charge par la partie.| +|**extensionList**|0..1|ExtensionList|Extension optionnelle, spécifique au déploiement.| + +**Tableau 10 — Modèle de données POST /participants/_{Type}_/_{ID}_ (ou POST /participants/_{Type}_/_{ID}_/_{SubId}_)** + +##### DELETE /participants/_{Type}_/_{ID}_ + +URI alternative : **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Service logique API : [Suppression d’informations sur un participant](../generic-transaction-patterns#delete-participant-information) + +La requête HTTP **DELETE /participants/**_{Type}_**/**_{ID}_ (ou **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) est utilisée pour supprimer les informations sur le serveur concernant l’identité fournie, définie par _{Type}_ et _{ID}_ (par exemple, **DELETE /participants/MSISDN/123456789**) et éventuellement _{SubId}_. Voir [Remboursement](#refund) pour plus d’informations sur l’adressage d’une partie. + +Cette requête HTTP doit prendre en charge une chaîne de requête (voir [Syntaxe URI](#uri-syntax)) pour supprimer les informations FSP concernant uniquement une devise spécifique. Pour supprimer uniquement une devise spécifique, la requête HTTP **DELETE** **/participants/**_{Type}_**/**_{ID}_**?currency**_=XYZ_ doit être utilisée, où _XYZ_ est la devise demandée. + +**Note :** L’ALS doit vérifier que c’est bien le FSP actuel de la partie qui supprime l’information FSP. + +Callback et modèle de données pour **DELETE /participants/**_{Type}_**/**_{ID}_ (alternative **GET** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback – [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) +- Callback d’erreur – [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) +- Modèle de données — Corps vide + +
+ +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur pour les services fournis par la ressource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_ + +URI alternative : **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Service logique API : [Retour d’information sur un participant](../generic-transaction-patterns#return-participant-information) + +Le callback **PUT /participants/**_{Type}_**/**_{ID}_ (ou **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) est utilisé pour informer le client d’un succès à la suite d’une recherche, création ou suppression des informations FSP liées à la partie. Si l’information FSP a été supprimée, l’élément **fspId** doit être vide ; sinon il doit contenir l’information FSP de la partie. + +Voir [Tableau 11](#table-11) pour le modèle de données. + +###### Tableau 11 + +|Nom|Cardinalité|Type|Description| +|---|---|---|---| +|**fspId**|0..1|FspId|Identifiant FSP auquel appartient la partie.| + +**Tableau 11 — Modèle de données PUT /participants/_{Type}_/_{ID}_ (ou PUT /participants/_{Type}_/_{ID}_/_{SubId}_)** + +##### PUT /participants/_{ID}_ + +URI alternative : N/A + +Service logique API : [Retour d’informations groupées sur les participants](../generic-transaction-patterns#return-bulk-participant-information) + +Le callback **PUT /participants/**_{ID}_ est utilisé pour informer le client du résultat de la création de la liste d’identités fournie. + +Voir [Tableau 12](#table-12) pour le modèle de données. + +###### Tableau 12 + +|Nom|Cardinalité|Type|Description| +|---|---|---|---| +|**partyList**|1..10000|PartyResults|Liste des éléments PartyResult qui ont été créés ou dont la création a échoué.| +|**currency**|0..1|Currency|Indique que la devise fournie a été définie comme prise en charge par chaque PartyIdInfo ajouté avec succès.| + +**Tableau 12 — Modèle de données PUT /participants/_{ID}_** + +####Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur pour la ressource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_/error + +URI alternative : **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Service logique API : [Erreur de retour d’information sur un participant](../generic-transaction-patterns#return-participant-information-error) + +Si le serveur ne parvient pas à trouver, créer ou supprimer l’association FSP pour l’identité fournie, ou si une autre erreur de traitement est survenue, le callback d’erreur **PUT /participants/**_{Type}_**/**_{ID}_**/error** (ou **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) est utilisé. Voir [Tableau 13](#table-13) pour le modèle de données. + +###### Tableau 13 + +|Nom|Cardinalité|Type|Description| +|---|---|---|---| +|**errorInformation**|1|ErrorInformation|Code d’erreur, description de la catégorie.| + +**Tableau 13 — Modèle de données PUT /participants/_{Type}_/_{ID}_/error (ou PUT /participants/_{Type}_/_{ID}_/_{SubId}_/error)** + +##### PUT /participants/_{ID}_/error + +URI alternative : N/A + +Service logique API : [Erreur de retour d’informations sur des participants groupés](../generic-transaction-patterns#return-bulk-participant-information-error) + +En cas d’erreur lors de la création des informations FSP sur le serveur, le callback d’erreur **PUT /participants/**_{ID}_**/error** est utilisé. L’_{ID}_ de l’URI doit contenir le **requestId** (voir [Tableau 9](#table-9)) qui a servi à la création de l’information du participant. Voir [Tableau 14](#table-14) pour le modèle de données. + +###### Tableau 14 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie. | + +**Tableau 14 — Modèle de données PUT /participants/_{ID}_/error** + +#### États + +Aucun état n’est défini pour la ressource **/participants** ; soit le serveur détient des informations FSP pour l’identité demandée, soit il n’en détient pas. + +
+ +### Ressource API /parties + +Cette section définit la ressource API logique **Parties**, décrite dans les [Modèles génériques de transaction](../generic-transaction-patterns#api-resource-parties). + +Les services fournis par la ressource **/parties** servent à obtenir des informations concernant une partie détenue par un FSP pair. + +#### Historique des versions de la ressource + +[Tableau 15](#table-15) présente une description de chaque version de la ressource **/parties**. + +###### Tableau 15 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| +|1.1|2020-05-19|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| + +**Tableau 15 — Historique des versions de la ressource /parties** + +#### Détails des services + +[Figure 43](#figure-43) contient un exemple de processus pour la ressource [**/parties**](../generic-transaction-patterns#api-resource-parties). D’autres déploiements sont possibles, par exemple un où le Switch et l’ALS sont sur le même serveur, ou un où le FSP de l’utilisateur interroge directement le FSP 1 pour obtenir les informations sur la partie. + +###### Figure 43 + +![](../../assets/diagrams/sequence/figure43.svg) + +**Figure 43 — Exemple de processus pour la ressource /parties** + +
+ +#### Requêtes + +Cette section décrit les services qui peuvent être demandés par un client sur la ressource **/parties** de l’API. + +##### GET /parties/_{Type}_/_{ID}_ + +URI alternative : **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Service logique API : [Recherche d’informations sur une partie](../generic-transaction-patterns#lookup-party-information) + +La requête HTTP **GET /parties/**_{Type}_**/**_{ID}_ (ou **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) est utilisée pour rechercher des informations sur la partie demandée, définie par _{Type}_, _{ID}_ et éventuellement _{SubId}_ (par exemple, **GET /parties/MSISDN/123456789** ou **GET /parties/BUSINESS/shoecompany/employee1**). Voir [Remboursement](#refund) pour plus d’informations sur l’adressage d’une partie. + +Callback et modèle de données pour **GET /parties/**_{Type}_**/**_{ID}_ (alternative **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback – [**PUT /parties/**_{Type}_**/**_{ID}_](#put-partiestypeid) +- Callback d’erreur – [**PUT /parties/**_{Type}_**/**_{ID}_**/error**](#put-partiestypeiderror) +- Modèle de données — Corps vide + +
+ +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur pour les services fournis par la ressource **/parties**. + +##### PUT /parties/_{Type}_/_{ID}_ + +URI alternative : **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Service logique API : [Retour d’informations sur une partie](../generic-transaction-patterns#return-party-information) + +Le callback **PUT /parties/**_{Type}_**/**_{ID}_ (ou **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) est utilisé pour informer le client d’un succès à la suite de la recherche d’une partie. Voir [Tableau 16](#table-16) pour le modèle de données. + +###### Tableau 16 + +|**Nom**|**Cardinalité**|**Type**|**Description**| +|---|---|---|---| +|**party**|1|Party|Informations sur la partie demandée.| + +**Tableau 16 — Modèle de données PUT /parties/_{Type}_/_{ID}_ (ou PUT /parties/_{Type}_/_{ID}_/_{SubId}_)** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur pour la ressource **/parties**. + +#### PUT /parties/_{Type}_/_{ID}_/error + +URI alternative : **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Service logique API : [Erreur de retour d’informations sur une partie](../generic-transaction-patterns#return-party-information-error) + +Si le serveur ne peut pas trouver les informations de la partie pour l’identité fournie, ou si une autre erreur de traitement est survenue, le callback d’erreur **PUT /parties/**_{Type}_**/**_{ID}_**/error** (ou **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) est utilisé. Voir [Tableau 17](#table-17) pour le modèle de données. + +###### Tableau 17 + +|**Nom**|**Cardinalité**|**Type**|**Description**| +|---|---|---|---| +|**errorInformation**|1|ErrorInformation|Code d’erreur, description de la catégorie.| + +**Tableau 17 — Modèle de données PUT /parties/_{Type}_/_{ID}_/error (ou PUT /parties/_{Type}_/_{ID}_/_{SubId}_/error)** + +#### États + +Aucun état n’est défini pour la ressource **/parties** ; soit un FSP dispose d’informations sur l’identité demandée, soit il n’en a pas. + +
+ +### Ressource API /transactionRequests + +Cette section définit la ressource API logique **Transaction Requests** (« demandes de transaction »), décrite dans les [Modèles génériques de transaction](../generic-transaction-patterns#api-resource-transaction-requests). + +Le service principal qu’offre la ressource **/transactionRequests** permet à un bénéficiaire de demander à un payeur de lui transférer des fonds électroniques. Le payeur peut approuver ou refuser la demande émise par le bénéficiaire. La décision du payeur peut être prise de manière programmatique si : + +- Le bénéficiaire est de confiance (c’est-à-dire que le payeur l’a pré-approuvé dans son FSP), ou +- Une valeur d’autorisation — c’est-à-dire un **mot de passe à usage unique** (OTP) — a été vérifiée correctement à l’aide de la ressource API **/authorizations** (voir [Section 6.6](#66-api-resource-authorizations)). + +Alternativement, le payeur peut prendre la décision manuellement. + +#### Historique des versions de la ressource + +[Tableau 18](#table-18) présente une description de chaque version de la ressource **/transactionRequests**. + +###### Tableau 18 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| +|1.1|2020-05-19|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| + +**Tableau 18 — Historique des versions de la ressource /transactionRequests** + +#### Détails des services + +[Figure 44](#figure-44) montre comment fonctionne le processus de demande de transaction à l’aide de la ressource **/transactionRequests**. L’approbation ou le refus n’est pas montré dans la figure. Un refus est un callback **PUT /transactionRequests/**_{ID}_ avec un état **REJECTED**, similaire au callback de la figure avec l’état **RECEIVED**, tel que décrit dans la [Section 6.4.2.1](#6421-payer-rejected-transaction-request). Une approbation du payeur n’est pas envoyée en tant que callback ; à la place, une devis et un transfert sont envoyés contenant une référence à la demande de transaction. + +###### Figure 44 + +![](../../assets/diagrams/sequence/figure44.svg) + +**Figure 44 — Comment utiliser le service /transactionRequests** + +##### Demande de transaction rejetée par le payeur + +[Figure 45](#figure-45) montre le processus par lequel une demande de transaction est rejetée. Les raisons possibles du refus incluent : + +- Le payeur a rejeté la demande manuellement. +- Un dépassement de limite automatique s’est produit. +- Le payeur a saisi un OTP de façon erronée plus que le nombre de fois autorisé. + +###### Figure 45 + +![](../../assets/diagrams/sequence/figure45.svg) + +**Figure 45 — Exemple de processus dans lequel une demande de transaction est rejetée** + +#### Requêtes + +Cette section décrit les services qu’un client peut demander pour la ressource **/transactionRequests**. + +##### GET /transactionRequests/_{ID}_ + +URI alternative : N/A + +Service logique API : [Récupérer les informations de demande de transaction](../generic-transaction-patterns#retrieve-transaction-request-information) + +La requête HTTP **GET /transactionRequests/**_{ID}_ est utilisée pour obtenir des informations sur une demande de transaction préalablement créée ou sollicitée. L’_{ID}_ dans l’URI doit contenir le **transactionRequestId** (voir [Tableau 15](#table-15)) qui a été utilisé lors de la création de la demande de transaction. + +Callback et modèle de données pour **GET /transactionRequests/**_{ID}_ : + +- Callback — [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Callback d’erreur — [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Modèle de données — Corps vide + +##### POST /transactionRequests + +URI alternative : N/A + +Service logique API : [Effectuer une demande de transaction](../generic-transaction-patterns#perform-transaction-request) + +La requête HTTP **POST /transactionRequests** est utilisée pour demander la création d’une demande de transaction financière sur le serveur. + +Callback et modèle de données pour **POST /transactionRequests** : + +- Callback — [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Callback d’erreur — [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Modèle de données — Voir [Tableau 19](#table-19) + +###### Tableau 19 + +|**Nom**|**Cardinalité**|**Type**|**Description**| +|---|---|---|---| +|**transactionRequestId**|1|CorrelationId|Identifiant partagé entre les FSP pour l’objet de la demande de transaction, défini par le FSP bénéficiaire. L’ID doit être réutilisé pour les renvois de la même demande de transaction. Un nouvel ID doit être généré pour chaque nouvelle demande.| +|**payee**|1|Party|Informations sur le bénéficiaire de la transaction financière proposée.| +|**payer**|1|PartyInfo|Informations sur le type de payeur, id, sous-type/id, FSP Id dans la transaction financière proposée.| +|**amount**|1|Money|Montant demandé à transférer du payeur au bénéficiaire.| +|**transactionType**|1|TransactionType|Type de transaction.| +|**note**|0..1|Note|Motif de la demande de transaction, destiné au payeur.| +|**geoCode**|0..1|GeoCode|Longitude et latitude de la partie initiatrice. Peut être utilisé pour détecter une fraude.| +|**authenticationType**|0..1|AuthenticationType|OTP ou code QR, sinon vide.| +|**expiration**|0..1|DateTime|Peut être défini pour obtenir un échec rapide si le FSP pair met trop longtemps à répondre. Il peut aussi être utile pour le consommateur, l’agent ou le commerçant de savoir que leur demande a une durée limitée.| +|**extensionList**|0..1|ExtensionList|Extension optionnelle, spécifique au déploiement.| + +**Tableau 19 — Modèle de données POST /transactionRequests** + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur pour la ressource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_ + +URI alternative : N/A + +Service logique API : **Retour d’informations de demande de transaction** + +Le callback **PUT /transactionRequests/**_{ID}_ est utilisé pour informer le client d’une demande de transaction créée ou sollicitée. L’_{ID}_ dans l’URI doit contenir le **transactionRequestId** (voir [Tableau 19](#table-19)) utilisé lors de la création de la demande, ou l’_{ID}_ utilisé dans le [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). Voir [Tableau 20](#table-20) pour le modèle de données. + +###### Tableau 20 + +|**Nom**|**Cardinalité**|**Type**|**Description**| +|---|---|---|---| +|**transactionId**|0..1|CorrelationId|Identifie la transaction liée (si une transaction a été créée).| +|**transactionRequestState**|1|TransactionRequestState|État de la demande de transaction.| +|**extensionList**|0..1|ExtensionList|Extension optionnelle, spécifique au déploiement.| + +**Tableau 20 — Modèle de données PUT /transactionRequests/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur pour la ressource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_/error + +URI alternative : N/A + +Service logique API : [Erreur de retour d’informations sur une demande de transaction](../generic-transaction-patterns#return-transaction-request-information-error) + +Si le serveur ne parvient pas à trouver ou créer une demande de transaction, ou si une autre erreur de traitement survient, le callback d’erreur **PUT /transactionRequests/**_{ID}_**/error** est utilisé. L’_{ID}_ de l’URI doit contenir le **transactionRequestId** (voir [Tableau 19](#table-19)) utilisé lors de la création de la demande, ou l’_{ID}_ utilisé dans le [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). Voir [Tableau 21](#table-21) pour le modèle de données. + +###### Tableau 21 + +|**Nom**|**Cardinalité**|**Type**|**Description**| +|---|---|---|---| +|**errorInformation**|1|ErrorInformation|Code d’erreur, description de la catégorie.| + +**Tableau 21 — Modèle de données PUT /transactionRequests/_{ID}_/error** + +#### 6.4.6 États + +Les états possibles d’une demande de transaction sont représentés dans la [Figure 46](#figure-46). + +**Note :** Un serveur n’a pas besoin de conserver les objets de demande de transaction qui ont été rejetés dans sa base de données. Cela signifie qu’un client doit s’attendre à recevoir un callback d’erreur pour une demande de transaction rejetée. + +###### Figure 46 + +![Figure 46](../../assets/diagrams/images/figure46.svg) + +**Figure 46 — États possibles d’une demande de transaction** + +
+ +### Ressource API /quotes + +Cette section définit la ressource API logique **Quotes** (« Devis »), décrite dans les [Modèles génériques de transaction](../generic-transaction-patterns#api-resource-quotes). + +Le principal service proposé par la ressource **/quotes** est le calcul des frais éventuels et des commissions FSP liés à la réalisation d’une transaction financière interopérable. Les FSP payeur et bénéficiaire doivent chacun calculer leur part du devis pour obtenir une vue globale de tous les frais et commissions applicables à la transaction. + +Une devis est irrévocable ; elle ne peut pas être modifiée après sa création. Elle peut cependant expirer (toutes les devis sont valables uniquement jusqu’à leur date d’expiration). + +**Note :** Une devis n’est pas une garantie que la transaction financière réussira. La transaction peut toujours échouer ultérieurement. Une devis garantit uniquement que les frais et commissions appliqués à la transaction spécifiée restent valables jusqu’à expiration du devis. + +Pour plus d’informations, voir la section [Devis](#quoting). + +#### Historique des versions de la ressource + +[Tableau 22](#table-22) présente une description de chaque version de la ressource **/quotes**. + +###### Tableau 22 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| +|1.1|2020-05-19|Le modèle de données a été mis à jour pour ajouter un élément ExtensionList optionnel au type complexe PartyIdInfo selon la Change Request : https://github.com/mojaloop/mojaloop-specification/issues/30. À la suite de cela, le modèle de données décrit dans le Tableau 93 a été mis à jour.| + +**Tableau 22 – Historique des versions de la ressource /quotes** + +#### Détails des services + +[Figure 47](#figure-47) présente un exemple de processus pour la ressource API **/quotes**. Cet exemple montre une transaction initiée par le payeur, mais elle peut aussi être initiée par le bénéficiaire, en utilisant la ressource API [**/transactionRequests**](#api-resource-transactionrequests). Dans ce cas, la recherche sera effectuée par le FSP du bénéficiaire. + +###### Figure 47 + +![](../../assets/diagrams/sequence/figure47.svg) + +**Figure 47 — Exemple de processus pour la ressource /quotes** + +#### Détails de l’expiration du devis + +La demande de devis du FSP payeur peut contenir une date d’expiration, si le FSP payeur souhaite indiquer à partir de quand il n’est plus utile pour le FSP bénéficiaire de renvoyer une devis. Par exemple, la transaction peut expirer ou sa devis peut expirer. + +Le FSP bénéficiaire doit définir une expiration dans le callback du devis pour indiquer à partir de quand elle n’est plus valable pour le FSP payeur. + +#### Rejet d’une devis + +Le FSP bénéficiaire peut rejeter une demande de devis émise par le FSP payeur en envoyant le callback d’erreur **PUT /quotes/**_{ID}_/**error** plutôt que le callback **PUT /quotes/**_{ID}_. +Selon le modèle générique de transaction utilisé (voir Section 8 pour plus d’informations), le FSP payeur peut rejeter une devis en utilisant l’une des méthodes suivantes : + +- Si la transaction est initiée par le payeur (voir Section 8.1), le FSP payeur ne doit pas informer le FSP bénéficiaire du rejet. La devis créée chez le FSP bénéficiaire doit avoir une date d’expiration, après laquelle elle est automatiquement supprimée. +- Si la transaction est initiée par le bénéficiaire (voir Section 8.2 et 8.3), le FSP payeur doit informer le FSP bénéficiaire du rejet par le callback **PUT /transactionRequests/**_{ID}_ avec un état « rejected ». Le processus est décrit plus en détail à la Section 6.4.2.1. + +#### Demande de paiement Interledger + +Dans le cadre de la prise en charge d’Interledger et de l’implémentation concrète de la demande de paiement Interledger (voir [Protocole Interledger](#interledger-protocol)), le FSP bénéficiaire doit : + +- Déterminer l’adresse ILP (voir [Adresses ILP](#ILP-addressing) pour plus d’informations) du bénéficiaire et le montant qu’il recevra. Notez que puisque l’élément **amount** dans le paquet ILP est défini comme un UInt64 (donc valeur entière), le montant doit être multiplié par l’exposant du devise (par exemple, l’exposant de l’USD est 2, donc le montant doit être multiplié par 102, et celui du JPY est 0, donc multiplié par 100). L’adresse ILP et le montant doivent être renseignés dans le paquet ILP (voir [ILP Packet](#ilp-packet) pour plus d’informations). + +- Renseigner l’élément **data** dans le paquet ILP par le modèle de données [Transaction](#transaction). +- Générer la fulfilment et la condition (voir [Transferts conditionnels](#conditional-transfers) pour plus de détails). Renseigner l’élément **condition** dans le [PUT /quotes/**_{ID}_](#put-quotes-id)). Le [Tableau 19](#table-19) montre le modèle de données avec la condition générée. + +La fulfilment est un secret temporaire généré pour chaque transaction financière par le FSP bénéficiaire et utilisé comme déclencheur pour valider les transferts constituant un paiement ILP. + +Le FSP bénéficiaire utilise un secret local pour générer un HMAC SHA-256 du paquet ILP. Le même secret peut être utilisé pour toutes les transactions financières, ou le FSP bénéficiaire peut stocker un secret différent par bénéficiaire ou selon une autre segmentation. + +Le choix et la cardinalité du secret local sont une décision d’implémentation, qui peut être dictée par les règles du système. Le seul prérequis est que le FSP bénéficiaire puisse déterminer à quel secret correspond un paquet ILP reçu ultérieurement dans le cadre d’un transfert entrant (voir [Ressource API Transfers](#api-resource-transfers)). + +La fulfilment et la condition sont générées conformément à l’algorithme défini dans le [Listing 12](#listing-12). Une fois que le FSP bénéficiaire a dérivé la condition, la fulfilment peut être supprimée puisqu’elle peut être régénérée plus tard. + +###### Listing 12 + +Génération du fulfilment (accomplissement) et de la condition + +**Entrées :** + +- Secret local (chaîne binaire de 32 octets) +- Paquet ILP + +**Algorithme :** + +1. Le fulfilment est obtenu en exécutant l’algorithme HMAC SHA-256 sur le paquet ILP en utilisant le secret local comme clé. + +2. La condition est obtenue en exécutant l’algorithme de hachage SHA-256 sur le fulfilment. + +**Sorties :** + +- Fulfilment (chaîne binaire de 32 octets) +- Condition (chaîne binaire de 32 octets) + +**Listing 12 -- Algorithme pour générer le fulfilment et la condition** + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client de l’API sur la ressource **/quotes**. + +##### GET /quotes/_{ID}_ + +URI alternative : N/A + +Service logique de l’API : [Récupérer les informations du devis](../generic-transaction-patterns#retrieve-quote-information) + +La requête HTTP **GET /quotes/**_{ID}_ permet d’obtenir des informations sur une devis préalablement créée ou demandée. Le _{ID}_ dans l’URI doit contenir le **quoteId** (voir [Tableau 23](#table-23)) qui a été utilisé pour la création du devis. + +Informations sur les callbacks et le modèle de données pour **GET /quotes/**_{ID}_ : + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Callback d’erreur -- [**PUT /quotes/**_{ID}_**/_error_**](#put-quotes-iderror) +- Modèle de données -- Corps vide + +##### POST /quotes + +URI alternative : N/A + +Service logique de l’API : [Calculer les informations du devis](../generic-transaction-patterns#calculate-quote-information) + +La requête HTTP **POST /quotes** est utilisée pour demander la création d’une devis pour la transaction financière fournie sur le serveur. + +Informations sur les callbacks et le modèle de données pour **POST /quotes** : + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Callback d’erreur -- [**PUT /quotes/**_{ID}_**/error**](#put-quotes-iderror) +- Modèle de données -- Voir [Tableau 23](#table-23) + +###### Tableau 23 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | CorrelationId | Identifiant commun entre les FSPs pour l’objet devis, décidé par le FSP du payeur. Cet ID doit être réutilisé pour les renvois de la même devis pour une transaction. Un nouvel ID doit être généré pour chaque nouvelle devis pour une transaction. | +| **transactionId** | 1 | CorrelationId | Identifiant commun (décidé par le FSP du payeur) entre les FSPs pour l’objet de la future transaction. La transaction réelle sera créée dans le cadre d’un processus de transfert réussi. L’ID doit être réutilisé pour les renvois de la même devis pour une transaction. Un nouvel ID doit être généré pour chaque nouvelle devis pour une transaction. | +| **transactionRequestId** | 0..1 | CorrelationId | Identifie une demande de transaction optionnelle envoyée précédemment. | +| **payee** | 1 | Party | Informations concernant le bénéficiaire de la transaction financière proposée. | +| **payer** | 1 | Party | Informations concernant le payeur de la transaction financière proposée. | +| **amountType** | 1 | AmountType |**SEND** pour montant envoyé, **RECEIVE** pour montant reçu. | +| **amount** | 1 | Money | Selon **amountType** :
Si **SEND** : Le montant que le payeur souhaite envoyer ; c’est-à-dire le montant à prélever du compte payeur, frais inclus. Le montant est mis à jour par chaque entité participant à la transaction.
Si **RECEIVE** : Le montant que le bénéficiaire doit recevoir ; c’est-à-dire le montant qui doit être envoyé au destinataire, frais exclus. Le montant n’est pas mis à jour par les entités participantes.
| +| **fees** | 0..1 | Money | Frais associés à la transaction.
  • L’élément fees doit être vide si les frais ne doivent pas être divulgués.
  • L’élément fees doit être renseigné si les frais doivent être divulgués.
  • | +| **transactionType** | 1 | TransactionType | Type de transaction pour laquelle le devis est demandée. | +| **geoCode** | 0..1 | GeoCode | Longitude et latitude de la partie initiatrice. Peut être utilisé pour détecter la fraude. | +| **note** | 0..1 | Note | Mémo à joindre à la transaction. | +| **expiration** | 0..1 | DateTime | L’expiration est optionnelle. Elle peut être fixée afin d’obtenir un échec rapide si le FSP pair met trop de temps à répondre. Elle peut également être utile pour que le consommateur, l’agent ou le commerçant sache que leur demande a une limite de temps. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 23 -- Modèle de données POST /quotes** + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/quotes**. + +#### PUT /quotes/_{ID}_ + +URI alternative : N/A + +Service logique de l’API : [Retourner les informations du devis](../generic-transaction-patterns#return-quote-information) + +Le callback **PUT /quotes/**_{ID}_ est utilisé pour informer le client d’une devis demandée ou créée. Le _{ID}_ dans l’URI doit contenir le **quoteId** (voir [Tableau 23](#table-23)) qui a été utilisé pour la création du devis, ou le _{ID}_ utilisé dans le [**GET /quotes/**_{ID}_](#get-quotesid). Voir [Tableau 24](#table-24) pour le modèle de données. + +###### Tableau 24 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferAmount** | 1 | Money | Le montant que le FSP payeur doit transférer au FSP bénéficiaire. | +| **payeeReceiveAmount** | 0..1 | Money | Le montant que le bénéficiaire doit recevoir dans la transaction de bout en bout. Optionnel si le FSP bénéficiaire ne souhaite pas divulguer de potentiels frais au bénéficiaire. | +| **payeeFspFee** | 0..1 | Money | Partie des frais de la transaction imputée au FSP bénéficiaire. | +| **payeeFspCommission** | 0..1 | Money | Commission du FSP bénéficiaire sur la transaction. | +| **expiration** | 1 | DateTime | Date et heure jusqu’à laquelle le devis est valide et peut être honorée lorsqu’elle est utilisée dans la transaction suivante. | +| **geoCode** | 0..1 | GeoCode | Longitude et latitude du bénéficiaire. Peut être utilisé pour détecter la fraude. | +| **ilpPacket** | 1 | IlpPacket | Le paquet ILP qui doit être joint au transfert par le payeur. | +| **condition** | 1 | IlpCondition | La condition qui doit être jointe au transfert par le payeur. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 24 -- Modèle de données PUT /quotes/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur +sous la ressource **/quotes**. + +##### PUT /quotes/_{ID}_/error + +URI alternative : N/A + +Service logique de l’API : [Retourner une erreur d’information de devis](../generic-transaction-patterns#return-quote-information-error) + +Si le serveur ne parvient pas à trouver ou créer une devis, ou qu’une autre erreur de traitement se produit, le callback d’erreur **PUT** **/quotes/**_{ID}_**/error** est utilisé. Le _{ID}_ dans l’URI doit contenir le **quoteId** (voir [Tableau 23](#table-23)) utilisé pour la création du devis, ou le _{ID}_ utilisé dans le [**GET /quotes/**_{ID}_](#get-quotesid). Voir [Tableau 25](#table-25) pour le modèle de données. + +###### Tableau 25 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie.| + +**Tableau 25 -- Modèle de données PUT /quotes/_{ID}_/error** + +#### États + +###### Figure 48 + +[Figure 48](#figure-48) contient la machine à états UML (Unified Modeling Language) pour les états possibles d’un objet devis. + +**Remarque :** Un serveur n’a pas besoin de conserver en base les objets devis ayant été rejetés ou expirés. Cela signifie qu’un client doit s’attendre à ce qu’un callback d’erreur puisse être retourné pour une devis expirée ou rejetée. + +![Figure 48](../../assets/diagrams/images/figure48.svg) + +**Figure 48 -- États possibles d’une devis** + +
    + +### Ressource d’API /authorizations + +Cette section définit la ressource logique d’API **Authorizations**, décrite dans [Modèles de transaction génériques](../gerneric-transaction-patterns#api-resource-authorizations). + +La ressource **/authorizations** est utilisée pour demander au payeur de saisir les identifiants applicables dans le système du FSP bénéficiaire pour approuver la transaction financière, lorsqu’il a initié la transaction depuis un POS, un DAB ou similaire, dans le système du FSP bénéficiaire et souhaite autoriser via un OTP. + +#### Historique des versions de la ressource + +[Tableau 26](#table-26) décrit les différentes versions de la ressource **/authorizations**. + +###### Tableau 26 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| + +**Tableau 26 – Historique des versions de la ressource /authorizations** + +#### Détails des services + +[Figure 49](#figure-49) présente un exemple de processus pour la ressource API **/authorizations**. Le FSP bénéficiaire envoie d’abord une [demande de transaction](#api-resource-transactionrequests)) qui est autorisée via OTP. Le FSP payeur réalise ensuite le devis (voir [Ressource API Quotes](#api-resource-quotes)) avant qu’une demande d’autorisation soit envoyée au système du FSP bénéficiaire pour que le payeur approuve via la saisie de l’OTP. Si l’OTP est correct, le processus de transfert doit être initié (voir [Ressource API Transfers](#api-resource-transfers)). + +###### Figure 49 + +![](../../assets/diagrams/sequence/figure49.svg) + + +**Figure 49 -- Exemple de processus pour la ressource /authorizations** + +#### Renvoi de la valeur d’autorisation + +Si la notification contenant la valeur d’autorisation n’atteint pas le payeur, celui-ci peut demander le renvoi de la valeur d’autorisation si le POS, le DAB ou appareil similaire propose cette option. Voir [Figure 50](#figure-50) pour un exemple où le payeur demande un renvoi de l’OTP. + +###### Figure 50 + +![](../../assets/diagrams/sequence/figure50.svg) + + +**Figure 50 -- Le payeur demande le renvoi de la valeur d’autorisation (OTP)** + +##### Tentative de saisie de la valeur d’autorisation + +Le FSP payeur doit décider du nombre de tentatives autorisées pour la saisie de la valeur d’autorisation sur le POS, DAB ou appareil similaire. Ce nombre est fixé dans la chaîne de requête **retriesLeft** (voir [Syntaxe URI](#uri-syntax) pour plus de détails) dans le service [**GET** **/authorizations/**_{ID}_](#get-authorizationsid). Si le FSP payeur envoie retriesLeft=1, cela signifie qu’il s’agit de la dernière tentative autorisée par le payeur. Voir [Figure 51](#figure-51) pour un exemple où le payeur saisit un OTP incorrect et où la valeur **retriesLeft** est alors décrémentée. + +###### Figure 51 + +![](../../assets/diagrams/sequence/figure51.svg) + + +**Figure 51 -- Le payeur saisit une valeur d’autorisation incorrecte (OTP)** + +##### Échec de l’autorisation OTP + +Si l’utilisateur échoue à saisir le bon OTP dans le nombre de tentatives autorisées, le processus décrit dans [Demande de transaction rejetée par le payeur](#payer-rejected-transaction-request) est suivi. + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client de l’API sur la ressource **/authorizations**. + +##### GET /authorizations/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Réaliser l’autorisation](../generic-transaction-patterns#perform-authorization) + +La requête HTTP **GET /authorizations/**_{ID}_ est utilisée pour demander au payeur de saisir les identifiants dans le système du FSP bénéficiaire. Le _{ID}_ dans l’URI doit contenir le **transactionRequestID** (voir [Tableau 15](#table-15)), obtenu via le service [**POST** **/transactionRequests**](#post-transactionrequests)) plus tôt dans le processus. + +Cette requête nécessite que la chaîne de requête (voir [Syntaxe URI](#uri-syntax) pour plus d’infos) contienne les paires clé-valeur suivantes : + +- **authenticationType=**_{Type}_, où _{Type}_ est une valeur valide de l’énumération [AuthenticationType](#authenticationtype). +- **retriesLeft=**_{NrOfRetries}_, où _{NrOfRetries}_ est le nombre de tentatives restantes avant le rejet de la transaction financière. _{NrOfRetries}_ doit être exprimé via le type de données [Integer](#integer)). **retriesLeft=1** signifie qu’il s’agit de la dernière tentative. +- **amount=**_{Amount}_, où _{Amount}_ est le montant de la transaction qui sera prélevé du compte du payeur. _{Amount}_ doit être de type [Amount](#amount). +- **currency=**_{Currency}_, où _{Currency}_ est la devise de la transaction. La valeur _{Currency}_ doit être conforme à l’énumération [CurrencyCode](#currencycode)). + +Exemple d’URI contenant toutes les clés requises : + +**GET /authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD** + +Informations sur les callbacks et le modèle de données pour **GET /authorization/**_{ID}_ : + +- Callback - [**PUT /authorizations/**_{ID}_](#6641-put-authorizationsid) +- Callback d’erreur - [**PUT /authorizations/**_{ID}_**/error**](#6651-put-authorizationsiderror) +- Modèle de données -- Corps vide + +#### 6.6.4 Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/authorizations**. + +#### 6.6.4.1 PUT /authorizations/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Retourner le résultat de l’autorisation](../generic-transaction-patterns#return-authorization-result) + +Le callback **PUT /authorizations/** _{ID}_ est utilisé pour informer le client du résultat d’une autorisation précédemment demandée. Le _{ID}_ dans l’URI doit contenir l’identifiant utilisé dans le [**GET /authorizations/**_{ID}_](#get-authorizationsid). **Voir** [Tableau 27](#table-27) **pour** le modèle de données. + +###### Tableau 27 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **authenticationInfo** | 0..1 | AuthenticationInfo | OTP ou code QR si renseigné, sinon vide. | +| **responseType** | 1 | AuthorizationResponse | Enum contenant le résultat : si le client a saisi la valeur d’authentification, a rejeté la transaction ou a demandé le renvoi de la valeur d’authentification. | + +**Tableau 27 – Modèle de données PUT /authorizations/{ID}** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource **/authorizations**. + +#### PUT /authorizations/_{ID}_/error + +URI alternative : N/A + +Service logique d’API : [Retourner une erreur d’autorisation](../generic-transaction-patterns#return-authorization-error) + +Si le serveur ne trouve pas la demande de transaction, ou une autre erreur de traitement survient, le callback d’erreur **PUT** **/authorizations/**_{ID}_ **/error** est utilisé. Le _{ID}_ dans l’URI doit être celui utilisé dans le [**GET /authorizations/**_{ID}_](#get-authorizationsid). **Voir** [Tableau 28](#table-28) **pour** le modèle de données. + +###### Tableau 28 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie | + +**Tableau 28 -- Modèle de données PUT /authorizations/_{ID}_/error** + +#### États + +Aucun état n’est défini pour la ressource **/authorizations**. + +
    + +### Ressource d’API /transfers + +Cette section définit la ressource logique d’API **Transfers**, décrite dans [Modèles de transaction génériques](../generic-transation-patterns#api-resource-transfers). + +Les services fournis par la ressource d’API **/transfers** servent à effectuer le(s) transfert(s) ILP hop-by-hop et à réaliser la transaction financière de bout en bout en envoyant les détails de transaction du FSP payeur au FSP bénéficiaire. Les détails de la transaction sont envoyés en tant que partie du modèle de données de transfert dans le paquet ILP. + +Le protocole Interledger suppose que la mise en place d’une transaction financière se fait via un protocole de bout en bout, mais qu’un transfert ILP est réalisé via des protocoles hop-by-hop entre FSPs connectés au même registre. Dans la version actuelle de l’API, la ressource **/quotes** établit la transaction financière. Avant de réaliser un transfert, le devis doit être effectuée pour préparer la transaction. Voir [Ressource API Quotes](#api-resource-quotes) pour plus d’informations. + +Un transfert ILP s’effectue entre deux détenteurs de comptes sur chaque côté d’un registre commun. Il s’exprime généralement par une demande d’exécution d’un transfert sur le registre et une notification au bénéficiaire que le transfert est réservé en sa faveur, incluant une condition devant être remplie pour commettre le transfert. + +Quand le FSP bénéficiaire présente le fulfilment au registre commun, le transfert est commis sur le registre. Simultanément, le FSP payeur est notifié que le transfert a été commis ainsi que du fulfilment. + +#### Historique des versions de la ressource + +Le Tableau 29 décrit les différentes versions de la ressource **/transfers**. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Version initiale | +| **1.1** | 2020-05-19 | Ajout du support des notifications de commit via la méthode HTTP **PATCH**. La nouvelle requête **PATCH /transfers/{ID}** est décrite en Section 6.7.3.3. Le processus d’utilisation des notifications de commit est décrit en Section 6.7.2.6.

    Le modèle de données est mis à jour pour inclure un élément ExtensionList optionnel au type complexe PartyIdInfo (voir Change Request : [https://github.com/mojaloop/mojaloop-specification/issues/30](https://github.com/mojaloop/mojaloop-specification/issues/30)). Suite à cela, le modèle de données du Tableau 93 a été mis à jour.| + +**Tableau 29 –- Historique des versions pour la ressource /transfers** + +#### Détails des services + +Cette section fournit des détails concernant les transferts hop-by-hop et les transactions financières de bout en bout. + +#### Processus + +[Figure 52](#figure-52) illustre le fonctionnement du processus transactionnel utilisant le service **POST /transfers**. + +###### Figure 52 + +![](../../assets/diagrams/sequence/figure52.svg) + + +**Figure 52 -- Utilisation du service POST /transfers** + +#### Irrévocabilité des transactions + +L’API est conçue pour ne supporter que les transactions financières irrévocables ; c’est-à-dire qu’une transaction ne peut pas être modifiée, annulée ou inversée après sa création. Cela vise à simplifier et réduire les coûts pour les FSPs utilisant l’API. Une grande partie du coût opérationnel des systèmes financiers est due à l’inversion des transactions. + +Dès qu’un FSP payeur envoie une transaction au FSP bénéficiaire (via **POST /transfers** incluant la transaction de bout en bout), la transaction est irrévocable côté FSP payeur. Elle peut toutefois encore être rejetée côté FSP bénéficiaire, mais le payeur ne peut plus modifier ou rejeter la transaction. Une exception à cela serait si le délai d’expiration du transfert est dépassé avant que le FSP bénéficiaire ne réponde (voir [Quote expirée](#expired-quote) et [Client recevant un transfert expiré](#client-receiving-expired-transfer) pour plus d’informations). Dès que la transaction a été acceptée par le FSP bénéficiaire, elle est irrévocable pour toutes les parties. + +#### Devis expirée + +Si un serveur reçoit une transaction utilisant une devis expirée, il doit refuser le transfert ou la transaction. + +#### Timeout et expiration + +Le FSP payeur doit toujours définir un temps d’expiration pour le transfert afin de permettre les cas d’utilisation nécessitant un traitement ou un échec rapide. Si le cas d’utilisation ne nécessite pas de réponse rapide, un délai d’expiration plus long peut être fixé. Si le FSP bénéficiaire ne répond pas avant le temps d’expiration, la transaction est annulée côté FSP payeur. Ce dernier doit cependant s’attendre à un callback du bénéficiaire. + +Les délais d’expiration courts sont souvent requis dans le commerce de détail, où un client se trouve devant un commerçant ; les deux parties doivent savoir si la transaction a réussi avant la remise d’un produit ou service. + +Dans [Figure 52](#figure-52), un délai d’expiration de 30 secondes à partir de l’heure courante a été défini dans la requête du FSP payeur, et de 20 secondes dans la requête du Switch au FSP bénéficiaire. Cette stratégie de réduction du délai à chaque maillon de la chaîne du FSP payeur au bénéficiaire doit toujours être utilisée pour permettre un délai de communication supplémentaire. + +**Remarque :** Il est possible qu’un callback de succès soit reçu par le FSP payeur après l’expiration, par exemple lors d’une congestion réseau. Le FSP payeur devrait laisser un délai supplémentaire après l’expiration avant d’annuler la transaction dans le système. Si un callback de succès arrive après annulation, la transaction doit être marquée pour rapprochement et traitée à part. + +#### Client recevant un transfert expiré + +[Figure 53](#figure-53) illustre un scénario d’erreur lié à l’expiration et au timeout. Pour une raison quelconque, le callback du FSP bénéficiaire prend plus de temps à arriver que le délai d’expiration dans le Switch. Cela conduit le Switch à annuler le transfert réservé et à envoyer un callback d’erreur au FSP payeur. Ainsi, FSP payeur et bénéficiaire ont deux visions différentes du résultat de la transaction ; celle-ci doit être marquée pour rapprochement. + +###### Figure 53 + +![](../../assets/diagrams/sequence/figure53.svg) + + +**Figure 53 -- Client recevant un transfert expiré** + +Pour limiter ce type d’erreur, les clients (FSP payeur et Switch optionnel dans la [Figure 52](#figure-52)) participant au transfert ILP doivent permettre un délai supplémentaire post expiration permettant de recevoir le callback du serveur. Le(s) client(s) doivent aussi interroger le serveur après expiration et avant la fin du délai supplémentaire en cas de perte du callback. Un rapprochement pourrait néanmoins rester nécessaire, même avec ce délai et une interrogation du serveur. + +#### Notification de commit + +Comme alternative pour éviter le scénario d’erreur décrit dans [Client recevant un transfert expiré](#client-receiving-expired-transfer), pour les cas où il est compliqué d’effectuer un remboursement, un FSP bénéficiaire peut (si le schéma le permet) réserver le transfert puis attendre la notification de commit émise par le Switch. Demander une notification de commit plutôt qu’un commit direct relève de la décision métier du FSP bénéficiaire (si le schéma l’autorise), selon le contexte de la transaction. Par exemple, un retrait cash ou un paiement commerçant est plus risqué qu’un transfert P2P du fait de la difficulté de remboursement a posteriori. +Pour demander la notification de commit depuis le Switch, le FSP bénéficiaire doit marquer l’état du transfert (voir Section 6.7.6) comme réservé (reserved) au lieu de commis (committed) dans le callback **PUT /transfers/**_{ID}_ . Selon l’état, le Switch doit alors effectuer : + +- Si le transfert est commis, le Switch n’envoie pas de notification de commit puisque le FSP bénéficiaire a déjà accepté le risque. C’est la méthode de commit par défaut décrite dans [Processus](#process). +- Si le transfert est réservé, le Switch doit envoyer une notification de commit au FSP bénéficiaire à la fin du traitement (commit ou annulation). + +La notification de commit est envoyée avec la requête **PATCH /transfers/**_{ID}_ du Switch au FSP bénéficiaire. Si ce dernier ne reçoit pas la notification dans un délai raisonnable, il doit renvoyer le callback **PUT /transfers/**_{ID}_ au Switch. Le FSP bénéficiaire doit recevoir la notification de commit du Switch avant de commettre le transfert, ou accepter le risque que le transfert ait échoué côté Switch. Il n’a pas le droit de rollbacker sans avoir reçu un état "aborted" (voir Section 6.7.6) du Switch, car il a déjà envoyé le fulfilment (déclencheur du commit). +[Figure 54](#figure-54) illustre un cas où une notification de commit est demandée. Ici, le commit a réussi côté Switch. + +###### Figure 54 + +![](../../assets/diagrams/sequence/figure54.svg) + + +**Figure 54 -- Notification de commit après succès du transfert dans le Switch** + +[Figure 55](#figure-55) montre un exemple où le commit dans le Switch a échoué (par exemple expiration du délai dans le Switch à cause d’un incident réseau). C’est le même scénario que [Figure 53](#figure-53), mais sans rapprochement à réaliser car le FSP bénéficiaire reçoit la notification de commit avant de réaliser effectivement le transfert. + +###### Figure 55 + +![](../../assets/diagrams/sequence/figure55.svg) + + +**Figure 55 -- Notification de commit après échec du commit dans le Switch** + +#### Remboursements + +Au lieu de supporter les inversions, l’API supporte les remboursements. Pour rembourser une transaction via l’API, une nouvelle transaction doit être créée par le bénéficiaire initial. Celle-ci doit annuler la transaction originale (en totalité ou partiellement) ; par exemple, si le client X a envoyé 100 USD au commerçant Y, celui-ci crée une nouvelle transaction pour reverser 100 USD à X. Il existe un type de transaction spécifique pour indiquer un remboursement ; cela permet de gérer différemment le devis. L’ID de la transaction d’origine doit être inclus dans la nouvelle transaction à des fins d’information et de rapprochement. + +#### Demande de paiement Interledger + +Dans le cadre du support d’Interledger et de la demande de paiement Interledger (voir [Protocole Interledger](#interledger-protocol)), le FSP payeur doit joindre au transfert le paquet ILP, la condition ainsi qu’une date d’expiration. La condition et le paquet ILP sont les mêmes que ceux envoyés par le FSP bénéficiaire dans le callback du devis ; voir [Demande de paiement Interledger](#interledger-payment-request) pour plus d’informations. + +Le paiement ILP de bout en bout est une chaîne d’un ou plusieurs transferts conditionnels tous dépendants de la même condition. La condition est fournie par le FSP payeur lors de l’initiation du transfert vers le prochain ledger. + +Le récepteur du transfert extrait l’adresse ILP du bénéficiaire dans le paquet ILP et effectue un autre transfert sur le ledger suivant, en joignant le même paquet ILP et condition et en fixant une expiration plus courte que celle du transfert entrant. + +Quand le FSP bénéficiaire reçoit le dernier transfert entrant pour le compte du bénéficiaire, il extrait le paquet ILP et procède ainsi : + +1. Valide que l’adresse ILP du bénéficiaire dans le paquet ILP correspond au compte bénéficiaire de destination. +2. Valide que le montant dans le paquet ILP correspond au montant du transfert et déclenche la réservation sur le registre local (moins les éventuels frais cachés au bénéficiaire, voir [Devis](#quoting)). +3. Si la réservation est un succès, le FSP bénéficiaire génère le fulfilment à l’aide du même algorithme que celui utilisé pour générer la condition envoyée dans le callback du devis (voir [Demande de paiement Interledger](#interledger-payment-request)). +4. Le fulfilment est soumis au registre du FSP bénéficiaire pour engager la réservation en faveur du bénéficiaire. Le registre valide que le hash SHA-256 du fulfilment correspond à la condition du transfert. Si oui, il valide la transaction. Sinon, il la rejette, et le FSP bénéficiaire annule la réservation préalablement effectuée. + +Le fulfilment est ensuite transmis au FSP payeur via la même chaîne de registres dans le callback du transfert. Chaque ledger engage les fonds après validation du fulfilment, et l’entité initiatrice est notifiée que ses fonds ont été libérés et reçoit le fulfilment. + +Le dernier transfert à engager est celui sur le registre du FSP payeur, où la réservation est déduite de son compte. Le FSP payeur notifie alors le payeur du succès de la transaction. + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client de l’API sur la ressource **/transfers**. + +##### GET /transfers/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Retourner le résultat de l’autorisation](../generic-transaction-patterns#return-authorization-result) + +La requête HTTP **GET /transfers/**_{ID}_ est utilisée pour obtenir des informations sur un transfert créé ou demandé précédemment. Le _{ID}_ dans l’URI doit contenir le **transferId** (voir [Tableau 23](#table-23)) utilisé lors de la création du transfert. + +Informations sur les callbacks et modèle de données pour **GET /transfers/**_{ID}_ : + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Callback d’erreur -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Modèle de données -- Corps vide + +##### POST /transfers + +URI alternative : N/A + +Service logique d’API : [Effectuer le transfert](../generic-transaction-patterns#perform-transfer) + +La requête HTTP **POST /transfers** est utilisée pour demander la création d’un transfert pour le prochain ledger, et une transaction financière pour le FSP bénéficiaire. + +Informations sur les callbacks et modèle de données pour **POST /transfers** : + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Callback d’erreur -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Modèle de données -- Voir [Tableau 30](#table-30) + +###### Tableau 30 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1| CorrelationId | Identifiant commun entre les FSPs et le Switch optionnel pour l’objet de transfert, défini par le FSP payeur. À réutiliser pour les rééditions, à régénérer pour chaque nouveau transfert. | +| **payeeFsp** | 1 | FspId | FSP bénéficiaire dans la transaction financière proposée. | +| **payerFsp** | 1 | FspId | FSP payeur dans la transaction financière proposée. | +| **amount** | 1 | Money | Montant à transférer. | +| **ilpPacket** | 1 | IlpPacket | Paquet ILP contenant le montant remis au bénéficiaire, l’adresse ILP du bénéficiaire et toutes données end-to-end. | +| **condition** | 1 | IlpCondition | Condition devant être remplie pour engager le transfert. | +| **expiration** | 1 | DateTime | L’expiration permet de générer un échec rapide si besoin. Le transfert doit être annulé si aucun fulfilment n’est délivré avant cette limite. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 30 – Modèle de données POST /transfers** + +##### PATCH /transfers/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Notification de commit](../generic-transaction-patterns#commit-notification) + +La requête HTTP **PATCH /transfers/**_{ID}_ est utilisée par un Switch pour mettre à jour l’état d’un transfert réservé si le FSP bénéficiaire a demandé une notification de commit, une fois le traitement terminé côté Switch. Le _{ID}_ doit contenir le transferId (voir Tableau 30) utilisé pour la création du transfert. Notez que cette requête ne génère pas de callback. Voir Tableau 31 pour le modèle de données. + +###### Tableau 31 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 1| DateTime | Date et heure d’achèvement de la transaction | +| **transferState** | 1 | TransferState | État du transfert | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 31 – Modèle de données PATCH /transfers/_{ID}_** + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/transfers**. + +##### PUT /transfers/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Retourner les informations du transfert](../generic-transaction-patterns#return-transfer-information) + +Le callback **PUT /transfers/**_{ID}_ est utilisé pour informer le client d’un transfert demandé ou créé. Le _{ID}_ dans l’URI doit contenir le **transferId** (voir [Tableau 30](#table-30)) utilisé à la création ou celui utilisé dans le [**GET** **/transfers/**_{ID}_](#6731-get-transfersid). **Voir** [Tableau 32](#table-32) **pour** le modèle de données. + +**Remarque** : pour les callbacks **PUT /transfers/**_{ID}_ , l’état ABORTED n’est pas une option valide pour le champ **transferState** en Tableau 32. Si un transfert doit être rejeté, l’émetteur du callback doit utiliser un callback d’erreur, c’est-à-dire callback sur l’endpoint /error. Cependant, l’état ‘ABORTED’ est valide en réponse à un appel **GET /transfers/**_{ID}_ . + +###### Tableau 32 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **fulfilment** | 0..1 | IlpFulfilment | Fulfilment (accomplissement) de la condition spécifiée avec la transaction. Obligatoire en cas de succès du transfert. | +| **completedTimestamp** | 0..1 | DateTime | Date et heure d’achèvement de la transaction | +| **transferState** | 1 | TransferState | État du transfert | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement | + +**Tableau 32 -- Modèle de données PUT /transfers/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource **/transfers**. + +##### PUT /transfers/_{ID}_/error + +URI alternative : N/A + +Service logique d’API : [Retourner une erreur d’information de transfert](../generic-transaction-patterns#return-transfer-information-error) + +Si le serveur ne trouve pas ou ne crée pas un transfert, ou qu’une autre erreur de traitement survient, le callback d’erreur **PUT** + +**/transfers/**_{ID}_**/error** est utilisé. Le _{ID}_ dans l’URI doit être le **transferId** (voir [Tableau 30](#table-30)) utilisé lors de la création du transfert, ou celui utilisé dans le [**GET /transfers/**_{ID}_](#6731-get-transfersid). Voir [Tableau 33](#table-33) pour le modèle de données. + +###### Tableau 33 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie. | + +**Tableau 33 -- Modèle de données PUT /transfers/_{ID}_/error** + +**6.7.6 États** + +###### Figure 56 + +Les états possibles d’un transfert sont représentés dans [Figure 56](#figure-56). + +![Figure 56](../../assets/diagrams/images/figure56.svg) + +**Figure 56 -- États possibles d’un transfert** + +
    + + +### Ressource d’API /transactions + +Cette section définit la ressource logique d’API **Transactions**, décrite dans [Modèles de transaction génériques](../generic-transaction-patterns#api-resource-transactions). + +Les services fournis par la ressource **/transactions** permettent d’obtenir des informations sur la transaction financière de bout en bout exécutée ; par exemple, obtenir les détails d’un éventuel code/ticket généré lors de la transaction. + +La transaction financière réelle est exécutée via la ressource d’API [**/transfers**](#67-api-resource-transfers), qui inclut la transaction de bout en bout entre le FSP payeur et le FSP bénéficiaire. + +#### Historique des versions de la ressource + +[Tableau 34](#table-34) décrit les différentes versions de la ressource **/transactions**. + +###### Tableau 34 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Version initiale| + +**Tableau 34 – Historique des versions de la ressource /transactions** + +#### Détails des services + +[Figure 57](#figure-57) montre un exemple du processus de transaction. La transaction réelle sera exécutée lors du processus de transfert. Le service **GET /transactions/**_{TransactionID}_ peut ensuite être utilisé pour obtenir plus d’informations sur la transaction financière exécutée lors du transfert. + +###### Figure 57 + +![](../../assets/diagrams/sequence/figure57.svg) + + +**Figure 57 -- Exemple de processus de transaction** + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client sur la ressource **/transactions**. + +##### GET /transactions/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Récupérer les informations sur la transaction](../generic-transaction-patterns#retrieve-transaction-information) + +La requête HTTP **GET /transactions/**_{ID}_ est utilisée pour obtenir des informations sur une transaction financière précédemment créée. Le _{ID}_ doit correspondre au **transactionId** utilisé lors de la création du devis (voir [Tableau 23](#table-23)), car la transaction est créée dans le cadre d’un autre processus (le transfert, voir [API Resource Transfers](#api-resource-transfers)). + +Informations sur les callbacks et modèles de données pour **GET /transactions/**_{ID}_ : + +- Callback -- [**PUT /transactions/**_{ID}_](#put-transactionsid) +- Callback d’erreur -- [**PUT /transactions/**_{ID}_**/error**](#put-transactionsiderror) +- Modèle de données -- Corps vide + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/transactions**. + +##### PUT /transactions/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Retourner les informations de la transaction](../generic-transaction-patterns#return-transaction-information) + +Le callback **PUT /transactions/**_{ID}_ est utilisé pour informer le client d’une transaction demandée. Le _{ID}_ doit être celui utilisé dans le [**GET /transactions/**_{ID}_](#get-transactionsid). Voir [Tableau 35](#table-35) pour le modèle de données. + +###### Tableau 35 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Date et heure d’achèvement de la transaction. | +| **transactionState** | 1 | TransactionState | État de la transaction. | +| **code** | 0..1 | Code | Information de code/jeton de rédemption optionnelle fournie au payeur après finalisation de la transaction. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 35 -- Modèle de données PUT /transactions/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource **/transactions**. + +##### PUT /transactions/_{ID}_/error + +URI alternative : N/A + +Service logique d’API : [Retourner une erreur concernant la transaction](../generic-transaction-patterns#retrieve-transaction-information-error) + +Si le serveur ne parvient pas à trouver ou créer une transaction, ou en cas d’erreur de traitement, le callback d’erreur **PUT** **/transactions/**_{ID}_**/error** est utilisé. Le _{ID}_ doit être celui utilisé dans le [**GET /transactions/**_{ID}_](#get-transactionsid). Voir [Tableau 36](#table-36) pour le modèle de données. + +###### Tableau 36 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie. | + +**Tableau 36 -- Modèle de données PUT /transactions/_{ID}_/error** + +#### États + +###### Figure 58 + +Les états possibles d'une transaction sont illustrés à la [Figure 58](#figure-58). + +**Remarque :** À des fins de rapprochement, un serveur doit conserver dans sa base de données, pendant une période définie par le système, les objets transactionnels ayant été rejetés. Cela signifie qu’un client peut s’attendre à recevoir un callback approprié concernant une transaction (si celle-ci a bien été reçue par le serveur) lorsqu’il demande des informations à son sujet. + +![Figure 58](../../assets/diagrams/images/figure58.svg) + +**Figure 58 -- États possibles d'une transaction** + +
    + +### Ressource API /bulkQuotes + +Cette section définit la ressource logique d'API **Bulk Quotes** (Devis en lot), comme décrit dans [Modèles de transactions génériques](../generic-transaction-patterns#api-resource-bulk-quotes). + +Les services fournis par la ressource API **/bulkQuotes** sont utilisés pour demander la création d’un devis en lot, c’est-à-dire un devis pour plus d’une transaction financière. Pour plus d’informations concernant un devis unique pour une transaction, voir la ressource API [/quotes](#api-resource-quotes). + +Un objet de devis en lot créé contient un devis pour chaque transaction individuelle du lot au sein d’un FSP Pair. Un devis en lot est irrévocable ; il ne peut pas être modifié après sa création. Toutefois, il peut expirer (tous les devis en lot ne sont valables que jusqu’à leur expiration). + +**Remarque :** Un devis en lot n’est pas une garantie de réussite de la transaction financière. La transaction en lot peut toujours échouer ultérieurement dans le processus. Un devis en lot garantit seulement que les frais et commissions FSP applicables à l'opération spécifiée restent valables tant que le devis n’est pas expiré. + +#### Historique des versions de la ressource + +Le Tableau 37 présente une description de chaque version différente de la ressource **/bulkQuotes**. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Version initiale | +| **1.1** | 2020-05-19 | Le modèle de données a été mis à jour pour ajouter un élément optionnel ExtensionList au type complexe PartyIdInfo suite à la demande de changement : https://github.com/mojaloop/mojaloop-specification/issues/30. Par la suite, le modèle de données tel que spécifié dans le Tableau 93 a été mis à jour.| + +**Tableau 37 –- Historique des versions pour la ressource /bulkQuotes** + +#### Détails du service + +La [Figure 59](#figure-59) illustre le fonctionnement du processus de devis en lot, utilisant le service **POST /bulkQuotes**. À la réception d’un lot de transactions de la part du Payeur, le FSP du Payeur doit : + +1. Rechercher à quel FSP appartient chaque Bénéficiaire ; par exemple, en utilisant la ressource API [/participants](#api-resource-participants). + +2. Diviser le lot selon le FSP du Bénéficiaire. Le service **POST /bulkQuotes** est alors utilisé pour chaque FSP de Bénéficiaire pour obtenir les devis en lot de chacun. Chaque résultat de devis contiendra le paquet ILP et la condition (voir [Paquet ILP](#ilp-packet) et [Transferts conditionnels](#conditional-transfers)) nécessaires pour effectuer chaque transfert dans le transfert en lot (voir la ressource API [/bulkTransfers](#api-resource-bulktransfers)), qui réalisera effectivement la transaction financière du Payeur vers chaque Bénéficiaire. + +###### Figure 59 + +![](../../assets/diagrams/sequence/figure59.svg) + +**Figure 59 -- Exemple de processus de devis en lot** + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client sur la ressource API **/bulkQuotes**. + +##### GET /bulkQuotes/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Récupérer les informations du devis en lot](../generic-transaction-patterns#retrieve-bulk-quote-information) + +La requête HTTP **GET /bulkQuotes/**_{ID}_ est utilisée pour obtenir des informations concernant un devis en lot préalablement créé ou demandé. + +Le _{ID}_ de l’URI doit contenir le **bulkQuoteId** (voir [Tableau 38](#table-38)) utilisé pour la création du devis en lot. + +Informations sur les callbacks et le modèle de données pour **GET /bulkQuotes/**_{ID}_ : + +- Callback -- [PUT /bulkQuotes/**_{ID}_](#put-bulkquotesid) +- Callback d’erreur -- [PUT /bulkQuotes/**_{ID}_**/error**](#put-bulkquotesiderror) +- Modèle de données -- Corps vide + +##### POST /bulkQuotes + +URI alternative : N/A + +Service logique d’API : **Calculer un devis en lot** + +La requête HTTP **POST /bulkQuotes** est utilisée pour demander la création d’un devis en lot pour les transactions financières fournies sur le serveur. + +Informations sur les callbacks et le modèle de données pour **POST /bulkQuotes** : + +- Callback -- [**PUT /bulkQuotes/**_{ID}_](#6941-put-bulkquotesid) +- Callback d’erreur -- [**PUT /bulkQuotes/**_{ID}_**/error**](#6951-put-bulkquotesiderror) +- Modèle de données -- Voir [Tableau 38](#table-38) + +###### Tableau 38 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | CorrelationId | Identifiant commun entre les FSPs pour l'objet devis en lot, décidé par le FSP du Payeur. L’ID doit être réutilisé pour les renvois du même devis en lot. Un nouvel ID doit être généré pour chaque nouveau devis en lot. | +| **payer** | 1 | Party | Informations sur le Payeur dans la transaction financière proposée. | +| **geoCode** | 0..1 | GeoCode | Longitude et latitude de la Partie initiatrice. Peut être utilisé pour détecter une fraude. | +| **expiration** | 0..1 | DateTime | L’expiration est optionnelle et permet au FSP du Bénéficiaire de savoir quand un devis n’a plus besoin d’être renvoyé. | +| **individualQuotes** | 1..1000 | IndividualQuote | Liste des éléments de devis individuels. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 38 -- Modèle de données POST /bulkQuotes** + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Retourner les informations du devis en lot](../generic-transaction-patterns#return-bulk-quote-information) + +Le callback **PUT /bulkQuotes/**_{ID}_ est utilisé pour informer le client d’un devis en lot demandé ou créé. Le _{ID}_ de l’URI doit contenir le **bulkQuoteId** (voir [Tableau 38](#table-38)) utilisé pour la création du devis en lot, ou le _{ID}_ qui a été utilisé dans le [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). Voir [Tableau 39](#table-39) pour le modèle de données. + +###### Tableau 39 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **individualQuoteResults** | 0..1000 | IndividualQuoteResult | Frais pour chaque transaction individuelle, si certains sont facturés par transaction. | +| **expiration** | 1 | DateTime | Date et heure jusqu'à laquelle le devis est valable et peut être honoré dans une demande de transaction ultérieure. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 39 -- Modèle de données PUT /bulkQuotes/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_/error + +URI alternative : N/A + +Service logique d’API : [Retourner une erreur concernant le devis en lot](../generic-transaction-patterns#retrieve-bulk-quote-information-error) + +Si le serveur ne parvient pas à trouver ou créer un devis en lot, ou en cas d’erreur de traitement, le callback d’erreur **PUT** **/bulkQuotes/**_{ID}_**/error** est utilisé. Le _{ID}_ de l’URI doit contenir le **bulkQuoteId** (voir [Tableau 38](#table-38)) utilisé pour la création du devis, ou le _{ID}_ utilisé dans le [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). Voir [Tableau 40](#table-40) pour le modèle de données. + +###### Tableau 40 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie. | + +**Tableau 40 -- Modèle de données PUT /bulkQuotes/_{ID}_/error** + +#### États + +###### Figure 60 + +Les états possibles d’un devis en lot sont illustrés à la [Figure 60](#figure-60). + +**Remarque :** Un serveur n’a pas besoin de conserver dans sa base de données les objets de devis en lot qui ont été rejetés ou expirés. Cela signifie qu’un client doit s’attendre à recevoir un callback d’erreur pour un devis en lot rejeté ou expiré. + +![Figure 60](../../assets/diagrams/images/figure60.svg) + +**Figure 60 -- États possibles d’un devis en lot** + +
    + +### Ressource API /bulkTransfers + +Cette section définit la ressource logique d'API **Bulk Transfers** (Transferts en lot), comme décrit dans [Modèles de transactions génériques](../generic-transaction-patterns#api-resource-bulk-transfers). + +Les services fournis par la ressource API **/bulkTransfers** sont utilisés pour demander la création d’un transfert en lot ou pour obtenir des informations sur un transfert en lot précédemment demandé. Pour plus d'informations sur un transfert individuel, voir la ressource API [/transfers](#api-resource-transfers). Avant qu’un transfert en lot ne puisse être demandé, un devis en lot doit être réalisé. Voir la ressource API [/bulkQuotes](#api-resource-bulkquotes) pour plus d’informations. + +Un transfert en lot est irrévocable ; il ne peut pas être modifié, annulé ou inversé après avoir été envoyé par le FSP du Payeur. + +#### Historique des versions de la ressource + +Le Tableau 41 présente une description de chaque version différente de la ressource **/bulkTransfers**. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Version initiale | +| **1.1** | 2020-05-19 | Le modèle de données a été mis à jour pour ajouter un élément optionnel ExtensionList au type complexe PartyIdInfo suite à la demande de changement : https://github.com/mojaloop/mojaloop-specification/issues/30. Par la suite, le modèle de données tel que spécifié dans le Tableau 93 a été mis à jour.| + +**Tableau 41 –- Historique des versions pour la ressource /bulkTransfers** + +#### Détails du service + +La [Figure 61](#figure-61) illustre le fonctionnement du processus de transfert en lot utilisant le service **POST /bulkTransfers**. Lors de la réception des transactions groupées du Payeur, le FSP du Payeur doit effectuer les étapes suivantes : + +1. Rechercher à quel FSP appartient chaque Bénéficiaire ; par exemple, en utilisant la ressource API **/participants**, [Section 6.2](#62-api-resource-participants). +2. Effectuer le processus de devis en lot en utilisant la ressource API **/bulkQuotes**, [Section 6.9](#69-api-resource-bulkquotes). Le callback du devis en lot doit contenir les paquets ILP requis et les conditions nécessaires à l’exécution de chaque transfert. +3. Effectuer le processus de transfert en lot comme dans la [Figure 61](#figure-61) en utilisant **POST /bulkTransfers**. Ceci réalise chaque transfert “hop-to-hop” et la transaction financière de bout en bout. Pour plus d’informations sur les transferts “hop-to-hop” versus les transactions financières de bout en bout, voir [Section 6.7](#67-api-resource-transfers). + +###### Figure 61 + +![](../../assets/diagrams/sequence/figure61.svg) + +**Figure 61 -- Exemple de processus de transfert en lot** + +#### Requêtes + +Cette section décrit les services pouvant être demandés par un client sur la ressource **/bulkTransfers**. + +##### GET /bulkTransfers/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Récupérer les informations du transfert en lot](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +La requête HTTP **GET /bulkTransfers/**_{ID}_ est utilisée pour obtenir des informations concernant un transfert en lot préalablement créé ou demandé. Le _{ID}_ de l’URI doit contenir le **bulkTransferId** (voir [Tableau 42](#table-42)) utilisé pour la création du transfert. + +Informations sur les callbacks et le modèle de données pour **GET /bulkTransfers/**_{ID}_ : + +- Callback -- [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Callback d’erreur -- [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Modèle de données -- Corps vide + +##### POST /bulkTransfers + +URI alternative : N/A + +Service logique d’API : [Exécuter un transfert en lot](../generic-transaction-patterns#perform-bulk-transfer) + +La requête HTTP **POST /bulkTransfers** est utilisée pour demander la création d’un transfert en lot sur le serveur. + +- Callback - [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Callback d’erreur - [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Modèle de données -- Voir [Tableau 42](#table-42) + +###### Tableau 42 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | CorrelationId | Identifiant commun entre les FSPs et éventuellement le Switch pour l'objet transfert en lot, décidé par le FSP du Payeur. L’ID doit être réutilisé pour les renvois du même transfert en lot. Un nouvel ID doit être généré pour chaque nouveau transfert en lot. | +| **bulkQuoteId** | 1 | CorrelationId | ID du devis en lot associé | +| **payeeFsp** | 1 | FspId | Identifiant du FSP du Bénéficiaire. | +| **payerFsp** | 1 | FspId | Identifiant du FSP du Payeur. | +| **individualTransfers** | 1..1000 | IndividualTransfer | Liste des éléments IndividualTransfer. | +| **expiration** | 1 | DateTime | Date d’expiration des transferts. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 42 -- Modèle de données POST /bulkTransfers** + +#### Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_ + +URI alternative : N/A + +Service logique d’API : [Récupérer les informations du transfert en lot](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +Le callback **PUT /bulkTransfers/**_{ID}_ est utilisé pour informer le client d’un transfert en lot demandé ou créé. Le _{ID}_ de l’URI doit contenir le **bulkTransferId** (voir [Tableau 42](#table-42)) utilisé pour la création du transfert ([POST /bulkTransfers](#post-bulktransfers)), ou le _{ID}_ utilisé dans le [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). Voir [Tableau 43](#table-43) pour le modèle de données. + +###### Tableau 43 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Date et heure de la finalisation de la transaction de lot. | +| **individualTransferResults** | 0..1000 | **Erreur ! Source de référence introuvable.** | Liste des éléments **Erreur ! Source de référence introuvable.** | +| **bulkTransferState** | 1 | BulkTransferState | État du transfert en lot. | +| **extensionList** | 0..1 | ExtensionList | Extension optionnelle, spécifique au déploiement. | + +**Tableau 43 -- Modèle de données PUT /bulkTransfers/_{ID}_** + +#### Callbacks d’erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_/error + +URI alternative : N/A + +Service logique d’API : [Retourner une erreur concernant le transfert en lot](../generic-transaction-patterns#retrieve-bulk-transfer-information-error) + +Si le serveur ne parvient pas à trouver ou créer un transfert en lot, ou en cas d’erreur de traitement, le callback d’erreur **PUT /bulkTransfers/**_{ID}_**/error** est utilisé. Le _{ID}_ de l’URI doit contenir le **bulkTransferId** (voir [Tableau 42](#table-42)) utilisé pour la création du transfert ([POST /bulkTransfers](#post-bulktransfers)), ou le _{ID}_ utilisé dans le [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). Voir [Tableau 44](#table-44) pour le modèle de données. + +###### Tableau 44 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Code d’erreur, description de la catégorie. | + +**Tableau 44 -- Modèle de données PUT /bulkTransfers/_{ID}_/error** + +#### États + +###### Figure 62 + +Les états possibles d’un transfert en lot sont illustrés à la [Figure 62](#figure-62). + +**Remarque :** À des fins de rapprochement, un serveur doit conserver dans sa base de données les objets de transfert en lot ayant été rejetés durant une période définie par le marché. Cela signifie qu’un client peut s’attendre à recevoir un callback approprié concernant un transfert en lot (si celui-ci a bien été reçu par le serveur) lorsqu’il demande des informations à son sujet. + +![Figure 62](../../assets/diagrams/images/figure62.svg) + +**Figure 62 -- États possibles d’un transfert en lot** + +
    + +## Modèles de données de support de l’API + +Cette section fournit des informations sur des modèles de données complémentaires utilisés par l’API. + +### Introduction sur le format + +Cette section introduit les formats utilisés pour les types de données des éléments employés par l’API. + +Tous les types de données d’élément ont à la fois une longueur minimale et maximale. Ces longueurs sont indiquées de l’une des façons suivantes : + +- Une longueur minimale et maximale +- Une longueur exacte +- Une expression régulière limitant l’élément de façon à n’autoriser qu’une ou plusieurs longueurs spécifiques. + +#### Longueur minimale et maximale + +Lorsqu’une longueur minimale et maximale est utilisée, cela sera indiqué après le type de données entre parenthèses : d’abord la valeur minimale (incluse), suivie de deux points consécutifs, puis la valeur maximale (incluse). + +Exemples : + +- `String(1..32)` – Une chaîne de caractères d’au moins un caractère et au maximum 32 caractères. +- `Integer(3..10)` - Un entier d’au moins 3 chiffres et au maximum 10 chiffres. + +#### Longueur exacte + +Lorsqu’une longueur exacte est utilisée, cela sera indiqué après le type de données entre parenthèses contenant une seule valeur exacte. Les autres longueurs ne sont pas permises. + +Exemples : + +- `String(3)` – Une chaîne de caractères d’exactement trois caractères. +- `Integer(4)` – Un entier d’exactement quatre chiffres. + +#### Expressions régulières + +Certains types de données d’élément sont limités par des expressions régulières. Les expressions régulières dans ce document utilisent la norme de syntaxe et les classes de caractères établies par le langage de programmation Perl[30](https://perldoc.perl.org/perlre.html#Regular-Expressions). + +### Formats des types de données d’éléments + +Cette section définit les types de données d’éléments utilisés par l’API. + + + +#### String + +Le type de données API `String` est une chaîne JSON normale[31](https://tools.ietf.org/html/rfc7159#section-7), limitée par un nombre maximum et minimum de caractères. + +##### Exemple de format I + +`String(1..32)` – Une chaîne de caractères d’au moins *1* caractère et au maximum *32* caractères. + +Un exemple de `String(1..32)` apparaît ci-dessous : + +- _Cette chaîne fait 28 caractères_ + +##### Exemple de format II + +`String(1..128)` – Une chaîne de caractères d’au moins *1* caractère et au maximum *128* caractères. + +Un exemple de `String(32..128)` apparaît ci-dessous : + +- _Cette chaîne est plus longue que 32 caractères, mais inférieure à 128_ + +
    + +#### Enum + +Le type de données API `Enum` est une liste restreinte de valeurs JSON [String](#string)) autorisées ; une énumération de valeurs. D’autres valeurs que celles définies dans la liste ne sont pas autorisées. + +##### Exemple de format + +`Enum of String(1..32)` – Une chaîne de caractères d’au moins un caractère et au maximum 32 caractères restreinte par la liste des valeurs autorisées. La description de l’élément contient un lien vers l’énumération. + +
    + +#### UndefinedEnum + +Le type de données d’API **UndefinedEnum** est une chaîne JSON constituée de 1 à 32 caractères en majuscule, incluant le caractère de soulignement (\*\*_**\*\*). + +##### Expression régulière + +L’expression régulière limitant le type **UndefinedEnum** apparaît dans [Liste 13](#listing-13). + +###### Liste 13 + +``` +^[A-Z_]{1,32}$ +``` + +**Liste 13 -- Expression régulière pour le type de données UndefinedEnum** + +
    + +#### Name + +Le type de données API `Name` est une chaîne JSON, restreinte par une expression régulière pour éviter les caractères généralement non utilisés dans un nom. + +##### Expression régulière + +L’expression régulière limitant le type `Name` apparaît dans la [Liste 14](#listing-14) ci-dessous. La contrainte n’autorise pas une chaîne constituée uniquement d’espaces, tous les caractères Unicode32 sont autorisés, ainsi que le point (**.**), l’apostrophe (**'**), le tiret (**-**), la virgule (**,**) et l’espace ( ). Le nombre maximal de caractères pour **Name** est 128. + +**Remarque :** Dans certains langages de programmation, le support Unicode doit être explicitement activé. Par exemple, si Java est utilisé, il faut activer le flag `UNICODE_CHARACTER_CLASS` pour permettre les caractères Unicode. + +###### Liste 14 + +``` +^(?!\s*$)[\w .,'-]{1,128}$ +``` + +**Liste 14 -- Expression régulière pour le type de données Name** + +
    + +#### Integer + +Le type de données API `Integer` est une chaîne JSON composée uniquement de chiffres. Les nombres négatifs et les zéros initiaux ne sont pas autorisés. Le type de données est toujours limité par un nombre de chiffres. + +##### 7.2.5.1 Expression régulière + +L’expression régulière restreignant le type `Integer` apparaît à la [Liste 15](#listing-15). + +###### Liste 15 + +``` +^[1-9]\d*$ +``` + +**Liste 15 -- Expression régulière pour le type de données Integer** + + +##### Exemple de format + +`Integer(1..6)` – Un `Integer` d’au moins un chiffre et de six chiffres au maximum. + +Un exemple de `Integer(1..6)` apparaît ci-dessous : + +- _123456_ + +
    + +#### OtpValue + +Le type de données API `OtpValue` est une chaîne JSON de trois à dix caractères composée uniquement de chiffres. Les nombres négatifs ne sont pas autorisés. Un ou plusieurs zéros initiaux sont autorisés. + +##### Expression régulière + +L’expression régulière limitant le type `OtpValue` apparaît dans la [Liste 16](#listing-16). + +###### Liste 16 + +``` +^\d{3,10}$ +``` + +**Liste 16 -- Expression régulière pour le type de données OtpValue** + +
    + +#### BopCode + +Le type de données API `BopCode` est une chaîne JSON de trois caractères, composée uniquement de chiffres. Les nombres négatifs ne sont pas autorisés. Un zéro initial n’est pas permis. + +##### Expression régulière + +L’expression régulière limitant le type `BopCode` apparaît à la [Liste 17](#listing-17). + +###### Liste 17 + +``` +^[1-9]\d{2}$ +``` + +**Liste 17 -- Expression régulière pour le type de données BopCode** + +
    + +#### ErrorCode + +Le type de données API `ErrorCode` est une chaîne JSON de quatre caractères, composée uniquement de chiffres. Les nombres négatifs ne sont pas autorisés. Un zéro initial n’est pas permis. + +##### Expression régulière + +L’expression régulière limitant le type `ErrorCode` apparaît à la [Liste 18](#listing-18). + +###### Liste 18 + +``` +^[1-9]\d{3}$ +``` + +**Liste 18 -- Expression régulière pour le type de données ErrorCode** + +
    + +#### TokenCode + +Le type de données API `TokenCode` est une chaîne JSON comprise entre quatre et 32 caractères. Elle peut être composée de chiffres, de lettres majuscules (**A** à **Z**), de lettres minuscules (**a** à **z**), ou d’une combinaison des trois. + +##### 7.2.9.1 Expression régulière + +L’expression régulière limitant le type `TokenCode` apparaît à la [Liste 19](#listing-19). + +###### Liste 19 + +``` +^[0-9a-zA-Z]{4,32}$ +``` + +**Liste 19 -- Expression régulière pour le type de données TokenCode** + +
    + +#### MerchantClassificationCode + +Le type de données API `MerchantClassificationCode` est une chaîne JSON composée de un à quatre chiffres. + +##### 7.2.10.1 Expression régulière + +L’expression régulière limitant le type `MerchantClassificationCode` apparaît à la [Liste 20](#listing-20). + +###### Liste 20 + +``` +^[\d]{1,4}$ +``` + +**Liste 20 -- Expression régulière pour le type de données MerchantClassificationCode** + +
    + +#### Latitude + +Le type de données API `Latitude` est une chaîne JSON au format lexical restreinte par une expression régulière pour des raisons d’interopérabilité. + +##### 7.2.11.1 Expression régulière + +L’expression régulière limitant le type `Latitude` apparaît à la [Liste 21](#listing-21). + +###### Liste 21 + +``` +^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Liste 21 -- Expression régulière pour le type de données Latitude** + +
    + +#### Longitude + +Le type de données API `Longitude` est une chaîne JSON au format lexical restreinte par une expression régulière pour des raisons d’interopérabilité. + +##### 7.2.12.1 Expression régulière + +L’expression régulière limitant le type `Longitude` apparaît à la [Liste 22](#listing-22). + +###### Liste 22 + +``` +^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Liste 22 -- Expression régulière pour le type de données Longitude** + +
    + +#### Amount + +Le type de données API `Amount` est une chaîne JSON au format canonique restreinte par une expression régulière pour des raisons d’interopérabilité. + +##### Expression régulière + +L’expression régulière limitant le type `Amount` apparaît à la [Liste 23](#listing-23). Ce motif n’autorise aucune décimale finale à zéro, mais autorise un montant sans unité monétaire mineure. Il permet également uniquement quatre chiffres dans l’unité monétaire mineure ; une valeur négative n’est pas acceptée. L’utilisation de plus de 18 chiffres dans l’unité monétaire majeure n’est pas acceptée. + +###### Liste 23 + +``` +^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$ +``` + +**Liste 23 -- Expression régulière pour le type de données Amount** + +##### Exemples de valeurs + +Consultez le [Tableau 45](#table-45) pour les résultats de validation pour quelques exemples de valeurs **Amount** à l’aide de l’[expression régulière](#regular-expression-6). + +###### Tableau 45 + +| **Valeur** | **Résultat de validation** | +| --- | --- | +| **5** | Acceptée | +| **5.0** | Rejetée | +| **5.** | Rejetée | +| **5.00** | Rejetée | +| **5.5** | Acceptée | +| **5.50** | Rejetée | +| **5.5555** | Acceptée | +| **5.55555** | Rejetée | +| **555555555555555555** | Acceptée | +| **5555555555555555555** | Rejetée | +| **-5.5** | Rejetée | +| **0.5** | Acceptée | +| **.5** | Rejetée | +| **00.5** | Rejetée | +| **0** | Acceptée | + +**Tableau 45 -- Exemples de résultats pour différentes valeurs du type Amount** + +
    + +#### DateTime + +Le type de données API `DateTime` est une chaîne JSON au format lexical qui est restreinte par une expression régulière pour des raisons d’interopérabilité. + +##### 7.2.14.1 Expression Régulière + +L’expression régulière limitant le type `DateTime` apparaît à la [Liste 24](#listing-24). Le format est conforme à l’ISO 8601, exprimé en une date, une heure et un fuseau horaire combinés. Une version plus lisible du format est : + +_aaaa_**-**_MM_**-**_jj_**T**_HH_**:**_mm_**:**_ss_**.**_SSS_[**-**_HH_**:**_MM_] + +###### Liste 24 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468\][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ +``` + +**Liste 24 -- Expression régulière pour le type de données DateTime** + +##### Exemples + +Deux exemples du type `DateTime` apparaissent ci-dessous : + +**2016-05-24T08:38:08.699-04:00** + +**2016-05-24T08:38:08.699Z** (où **Z** indique le fuseau horaire Zulu, identique à UTC). + +
    + +#### Date + +Le type de données API `Date` est une chaîne JSON au format lexical restreinte par une expression régulière pour garantir l’interopérabilité. + +##### Expression Régulière + +L’expression régulière restreignant le type **Date** apparaît à la [Liste 25](#listing-25). Ce format, tel que spécifié dans la norme ISO 8601, contient uniquement une date. Une version plus lisible est _aaaa_**-**_MM_**-**_jj_. + +###### Liste 25 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ +``` + +**Liste 25 -- Expression régulière pour le type de données Date** + +##### Exemples + +Deux exemples de type `Date` apparaissent ci-dessous : + +- _1982-05-23_ + +- _1987-08-05_ + +
    + +#### UUID + +Le type de données API `UUID` (Identifiant Unique Universel) est une chaîne JSON au format canonique, conforme à la RFC 4122, restreinte par une expression régulière pour garantir l’interopérabilité. Un UUID fait toujours 36 caractères de long, soit 32 caractères hexadécimaux et quatre tirets (« - »). + +##### 7.2.16.1 Expression Régulière + +L’expression régulière restreignant le type `UUID` figure à la [Liste 26](#listing-26). + +###### Liste 26 + +``` +^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ +``` + +**Liste 26 -- Expression régulière pour le type de données UUID** + +##### Exemple + +Un exemple de type `UUID` : + +- _a8323bc6-c228-4df2-ae82-e5a997baf898_ + +
    + +#### BinaryString + +Le type de données API `BinaryString` est une chaîne JSON. La chaîne est un encodage base64url d’une séquence d’octets bruts, où un caractère de bourrage (‘**=**’) est ajouté à la fin des données si besoin afin de garantir que la chaîne est un multiple de quatre caractères. La contrainte de longueur indique le nombre de caractères autorisés. + +##### Expression Régulière + +L’expression régulière limitant le type `BinaryString` apparaît à la [Liste 27](#listing-27). + +###### Liste 27 + +``` +^[A-Za-z0-9-_]+[=]{0,2}$ +``` + +**Liste 27 -- Expression régulière pour le type de données BinaryString** + +##### Exemple de format + +`BinaryString(32)` – 32 octets de données encodés en base64url. + +Un exemple de `BinaryString(32..256)` figure ci-dessous. Notez qu’un caractère de bourrage `'='` a été ajouté pour garantir que la chaîne soit un multiple de quatre caractères. + +- _QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE=_ + +
    + +#### BinaryString32 + +Le type de données API `BinaryString32` est une version à taille fixe du type de données API `BinaryString` défini [plus haut](#binarystring), où les données sont toujours de 32 octets. **BinaryString32** ne doit pas utiliser de caractère de bourrage puisque la taille des données sous-jacentes est fixe. + +##### Expression Régulière + +L’expression régulière limitant le type `BinaryString32` apparaît à la [Liste 28](#listing-28). + +###### Liste 28 + +``` +^[A-Za-z0-9-_]{43}$ +``` + +**Liste 28 -- Expression régulière pour le type de données BinaryString32** + +##### Exemple de format + +`BinaryString(32)` – 32 octets de données encodés en base64url. + +Un exemple de `BinaryString32` figure ci-dessous. Il s’agit des mêmes données binaires que dans l’exemple du [format d’exemple](#example-format-4) du type `BinaryString`, mais comme la taille sous-jacente est fixe, le caractère de bourrage `'='` est exclu. + +``` +QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE +``` + +
    + +### Définitions des éléments + +Cette section définit les types d’éléments utilisés par l’API. + +#### Élément AmountType + +[Le tableau 46](#table-46) ci-dessous présente le modèle de données pour l’élément `AmountType`. + +###### Tableau 46 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **AmountType** | 1 | [Enum](#enum) de [String(1..32)](#string) | Cet élément contient le type de montant. Voir l’énumération [AmountType](#amounttype-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 46 – Élément AmountType** + +
    + +#### Élément AuthenticationType + +[Le tableau 47](#table-47) ci-dessous présente le modèle de données pour l’élément `AuthenticationType`. + +###### Tableau 47 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **Authentication** | 1 | [Enum](#enum) de [String(1..32)](#string) | Cet élément contient le type d’authentification. Voir l’énumération [AuthenticationType](#authenticationtype-enum) pour les valeurs possibles. | + +**Tableau 47 – Élément AuthenticationType** + +
    + +#### Élément AuthenticationValue + +[Le tableau 48](#table-48) ci-dessous présente le modèle de données pour l’élément `AuthenticationValue`. + +###### Tableau 48 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **AuthenticationValue** | 1 | Dépend de [AuthenticationType](#authenticationtype-element).

    Si `OTP` : le type est [Integer(1..6)](#integer). Par exemple : **123456**

    OtpValue
    Si `QRCODE` : le type est [String(1..64)](#string) | Cet élément contient la valeur d’authentification. Le format dépend du type d’authentification utilisé dans le type complexe [AuthenticationInfo](#authenticationinfo). | + +**Tableau 48 – Élément AuthenticationValue** + +
    + +#### Élément AuthorizationResponse + +[Le tableau 49](#table-49) ci-dessous présente le modèle de données pour l’élément `AuthorizationResponse`. + +###### Tableau 49 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **AuthorizationResponse** | 1 | [Enum](#enum) de [String(1..32)](#string) | Cet élément contient la réponse d’autorisation. Voir l’énumération [AuthorizationResponse](#authorizationresponse-enum) pour les valeurs possibles. | + +**Tableau 49 – Élément AuthorizationResponse** + +
    + +#### Élément BalanceOfPayments + +[Le tableau 50](#table-50) ci-dessous présente le modèle de données pour l’élément `BalanceOfPayment`. + +###### Tableau 50 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **BalanceOfPayments** | 1 | [BopCode](#bopcode) | Les valeurs et significations possibles sont définies dans [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/) | + +**Tableau 50 – Élément BalanceOfPayments** + +
    + +#### Élément BulkTransferState + +[Le tableau 51](#table-51) ci-dessous présente le modèle de données pour l’élément `BulkTransferState`. + +###### Tableau 51 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **BulkTransferState** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [BulkTransferState](#bulktransferstate-enum) pour connaître les valeurs autorisées.| + +**Tableau 51 – Élément BulkTransferState** + +
    + +#### Élément Code + +[Le tableau 52](#table-52) ci-dessous présente le modèle de données pour l’élément `Code`. + +###### Tableau 52 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **Code** | 1 | [TokenCode](#tokencode) | Tout code/jeton retourné par l’IFP bénéficiaire. | + +**Tableau 52 – Élément Code** + +
    + +#### Élément CorrelationId + +[Le tableau 53](#table-53) ci-dessous présente le modèle de données pour l’élément `CorrelationId`. + +###### Tableau 53 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **CorrelationId** | 1 |[UUID](#uuid) | Identifiant permettant de corréler tous les messages d’une même séquence. | + + +**Tableau 53 – Élément CorrelationId** + +
    + +#### Élément Currency + +[Le tableau 54](#table-54) ci-dessous présente le modèle de données pour l’élément `Currency`. + +###### Tableau 54 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **Currency** | 1 | [Enum](#enum) de [String(3)](#string) | Voir l’énumération [Currency](#currencycode-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 54 – Élément Currency** + +
    + +#### Élément DateOfBirth + +[Le tableau 55](#table-55) ci-dessous présente le modèle de données pour l’élément `DateOfBirth`. + +###### Tableau 55 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **DateOfBirth** | 1 | Exemples

    Deux exemples du type [DateTime](#datetime) figurent ci-dessous :

    2016-05-24T08:38:08.699-04:00

    2016-05-24T08:38:08.699Z (où Z indique le fuseau Zulu, équivalent à UTC).

    Date

    | Date de naissance du participant.| + +**Tableau 55 – Élément DateOfBirth** + +
    + +#### Élément ErrorCode + +[Le tableau 56](#table-56) ci-dessous présente le modèle de données pour l’élément `ErrorCode`. + +###### Tableau 56 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **ErrorCode** | 1 | [ErrorCode](#errorcode) | Code d’erreur à quatre chiffres, voir la section sur les [Codes d’erreur](#error-codes) pour plus d’informations. | + +**Tableau 56 – Élément ErrorCode** + +
    + +#### Élément ErrorDescription + +[Le tableau 57](#table-57) ci-dessous présente le modèle de données pour l’élément `ErrorDescription`. + +###### Tableau 57 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **ErrorDescription** | 1 | [String(1..128)](#string) | Description de l’erreur. | + +**Tableau 57 – Élément ErrorDescription** + +
    + +#### Élément ExtensionKey + +[Le tableau 58](#table-58) ci-dessous présente le modèle de données pour l’élément `ExtensionKey`. + +###### Tableau 58 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **ExtensionKey** | 1 | [String(1..32)](#string) | La clé de l’extension. | + +**Tableau 58 – Élément ExtensionKey** + +
    + +#### Élément ExtensionValue + +[Le tableau 59](#table-59) ci-dessous présente le modèle de données pour l’élément `ExtensionValue`. + +###### Tableau 59 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **ExtensionValue** | 1 | [String(1..128)](#string) | La valeur de l’extension. | + +**Tableau 59 – Élément ExtensionValue** + +
    + +#### Élément FirstName + +[Le tableau 60](#table-60) ci-dessous présente le modèle de données pour l’élément `FirstName`. + +###### Tableau 60 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **FirstName** | 1 | [Name](#name) | Prénom du participant | + +**Tableau 60 – Élément FirstName** + +
    + +#### Élément FspId + +[Le tableau 61](#table-61) ci-dessous présente le modèle de données pour l’élément `FspId`. + +###### Tableau 61 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **FspId** | 1 | [String(1..32)](#string)| Identifiant de l’IFP (Institution Financière de Paiement). | + +**Tableau 61 – Élément FspId** + +
    + +#### Élément IlpCondition + +[Le tableau 62](#table-62) ci-dessous présente le modèle de données pour l’élément `IlpCondition`. + +###### Tableau 62 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **IlpCondition** | 1 | [BinaryString32](#binarystring32) | Condition qui doit être jointe au transfert par le Payeur. | + +**Tableau 62 – Élément IlpCondition** + +
    + +#### Élément IlpFulfilment + +[Le tableau 63](#table-63) ci-dessous présente le modèle de données pour l’élément `IlpFulfilment`. + +###### Tableau 63 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **IlpFulfilment** | 1 | [BinaryString32](#binarystring32) | Exécution qui doit être jointe au transfert par le Bénéficiaire. | + +**Tableau 63 – Élément IlpFulfilment** + +
    + +#### Élément IlpPacket + +[Le tableau 64](#table-64) ci-dessous présente le modèle de données pour l’élément `IlpPacket`. + +###### Tableau 64 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **IlpPacket** | 1 | Exemple

    Un exemple de type [UUID](#uuid) :

    a8323bc6-c228-4df2-ae82-e5a997baf898

    [BinaryString(1..32768)](#binarystring)

    | Informations pour le destinataire (informations de niveau transport). | + +**Tableau 64 – Élément IlpPacket** + +
    + +#### Élément LastName + +[Le tableau 65](#table-65) ci-dessous présente le modèle de données pour l’élément `LastName`. + +###### Tableau 65 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **LastName** | 1 | [Name](#name) | Nom de famille du participant (définition ISO 20022). | + +**Tableau 65 – Élément LastName** + +
    + +#### Élément MerchantClassificationCode + +[Le tableau 66](#table-66) ci-dessous présente le modèle de données pour l’élément `MerchantClassificationCode`. + +###### Tableau 66 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **MerchantClassificationCode** | 1 | [MerchantClassificationCode](#merchantclassificationcode) | Un ensemble limité de numéros prédéfinis. Cette liste identifie des types de marchands populaires comme frais d’école, bars et restaurants, épiceries, etc. | + +**Tableau 66 – Élément MerchantClassificationCode** + +
    + +#### Élément MiddleName + +[Le tableau 67](#table-67) ci-dessous présente le modèle de données pour l’élément `MiddleName`. + +###### Tableau 67 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **MiddleName** | 1 | [Name](#name) | Deuxième prénom du participant (définition ISO 20022). | + +**Tableau 67 – Élément MiddleName** + +
    + +#### Élément Note + +[Le tableau 68](#table-68) ci-dessous présente le modèle de données pour l’élément `Note`. + +###### Tableau 68 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **Note** | 1 | [String(1..128)](#string) | Mémo ou libellé affecté à la transaction. | + +**Tableau 68 – Élément Note** + +
    + +#### Élément PartyIdentifier + +[Le tableau 69](#table-69) ci-dessous présente le modèle de données pour l’élément `PartyIdentifier`. + +###### Tableau 69 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **PartyIdentifier** | 1 | [String(1..128)](#string) | Identifiant du participant.| + +**Tableau 69 – Élément PartyIdentifier** + +
    + +#### Élément PartyIdType + +[Le tableau 70](#table-70) ci-dessous présente le modèle de données pour l’élément `PartyIdType`. + +###### Tableau 70 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **PartyIdType** | 1 | Enum de [String(1..32)](#string) | Voir l’énumération [PartyIdType](#partyidtype-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 70 – Élément PartyIdType** + +
    + +#### Élément PartyName + +[Le tableau 71](#table-71) ci-dessous présente le modèle de données pour l’élément `PartyName`. + +###### Tableau 71 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **PartyName** | 1 | `Name` | Nom du participant. Peut être un vrai nom ou un surnom. | + +**Tableau 71 – Élément PartyName** + +
    + +#### Élément PartySubIdOrType + +[Le tableau 72](#table-72) ci-dessous présente le modèle de données pour l’élément `PartySubIdOrType`. + +###### Tableau 72 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **PartySubIdOrType** | 1 | [String(1..128)](#string) | Un sous-identifiant d’un [PartyIdentifier](#partyidentifier-element) ou un sous-type du [PartyIdType](#partyidtype-element), souvent un `PersonalIdentifierType`. | + +**Tableau 72 – Élément PartySubIdOrType** + +
    + +#### Élément RefundReason + +[Le tableau 73](#table-73) ci-dessous présente le modèle de données pour l’élément `RefundReason`. + +###### Tableau 73 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **RefundReason** | 1 | [String(1..128)](#string) | Raison du remboursement. | + +**Tableau 73 – Élément RefundReason** + +
    + +#### Élément TransactionInitiator + +[Le tableau 74](#table-74) ci-dessous présente le modèle de données pour l’élément `TransactionInitiator`. + +###### Tableau 74 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiator** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransactionInitiator](#transactioninitiator-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 74 – Élément TransactionInitiator** + +
    + +#### Élément TransactionInitiatorType + +[Le tableau 75](#table-75) ci-dessous présente le modèle de données pour l’élément `TransactionInitiatorType`. + +###### Tableau 75 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiatorType** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransactionInitiatorType](#transactioninitiatortype-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 75 – Élément TransactionInitiatorType** + +
    + +#### Élément TransactionRequestState + +[Le tableau 76](#table-76) ci-dessous présente le modèle de données pour l’élément `TransactionRequestState`. + +###### Tableau 76 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionRequestState** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransactionRequestState](#transactionrequeststate-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 76 – Élément TransactionRequestState** + +
    + +#### Élément TransactionScenario + +[Le tableau 77](#table-77) ci-dessous présente le modèle de données pour l’élément `TransactionScenario`. + +###### Tableau 77 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionScenario** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransactionScenario](#transactionscenario-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 77 – Élément TransactionScenario** + +
    + +#### Élément TransactionState + +[Le tableau 78](#table-78) ci-dessous présente le modèle de données pour l’élément `TransactionState`. + +###### Tableau 78 + +|Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransactionState](#transactionstate-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 78 – Élément TransactionState** + +
    + + +#### Élément TransactionSubScenario + +[Le tableau 79](#table-79) ci-dessous présente le modèle de données pour l’élément `TransactionSubScenario`. + +###### Tableau 79 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionSubScenario** | 1 | [UndefinedEnum](#undefinedenum) | Sous-scénario possible, défini localement au sein du système.| + +**Tableau 79 – Élément TransactionSubScenario** + +
    + +#### Élément TransferState + +[Le tableau 80](#table-80) ci-dessous présente le modèle de données pour l’élément `TransferState`. + +###### Tableau 80 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) de [String(1..32)](#string) | Voir l’énumération [TransferState](#transferstate-enum) pour plus d’informations sur les valeurs autorisées. | + +**Tableau 80 – Élément TransferState** + +
    + +### Types Complexes + +Cette section décrit les types complexes utilisés par l’API. + +#### AuthenticationInfo + +[Le tableau 81](#table-81) présente le modèle de données pour le type complexe `AuthenticationInfo`. + +###### Tableau 81 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **authentication** | 1 | `AuthenticationType` | Type d’authentification. | +| **authenticationValue** | 1 | `AuthenticationValue` | Valeur d’authentification. | + +**Tableau 81 -- Type complexe AuthenticationInfo** + +
    + +#### ErrorInformation + +[Le tableau 82](#table-82) présente le modèle de données pour le type complexe `ErrorInformation`. + +###### Tableau 82 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **errorCode** | 1 | `Errorcode` | Numéro d’erreur spécifique. | +| **errorDescription** | 1 | `ErrorDescription` | Chaîne décrivant l’erreur. | +| **extensionList** | 1 | `ExtensionList` | Liste facultative d’extensions, spécifique au déploiement. | + +**Tableau 82 -- Type complexe ErrorInformation** + +
    + +#### Extension + +[Le tableau 83](#table-83) présente le modèle de données pour le type complexe `Extension`. + +###### Tableau 83 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **key** | 1 | `ExtensionKey` | Clé d’extension. | +| **value** | 1 | `ExtensionValue` | Valeur de l’extension. | + +**Tableau 83 -- Type complexe Extension** + +
    + +#### ExtensionList + +[Le tableau 84](#table-84) présente le modèle de données pour le type complexe `ExtensionList`. + +###### Tableau 84 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **extension** | 1..16 | `Extension` | Nombre d’éléments Extension. | + +**Tableau 84 -- Type complexe ExtensionList** + +
    + +#### IndividualQuote + +[Le tableau 85](#table-85) présente le modèle de données pour le type complexe `IndividualQuote`. + +###### Tableau 85 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifie le message du devis. | +| **transactionId** | 1 | `CorrelationId` | Identifie le message de transaction. | +| **payee** | 1 | `Party` | Informations concernant le bénéficiaire dans la transaction financière proposée. | +| **amountType** | 1 | `AmountType` | **SEND** pour le montant envoyé, **RECEIVE** pour le montant à recevoir. | +| **amount** | 1 | `Money` | Selon **amountType** :
    Si **SEND** : montant que le payeur souhaite envoyer, c’est-à-dire le montant à débiter y compris les frais. Le montant est mis à jour par chaque entité participante.
    Si **RECEIVE** : montant à recevoir par le bénéficiaire (hors frais). Le montant n’est pas mis à jour par les entités participantes. | +| **fees** | 0..1 | `Money` | Frais de la transaction.
    • Doit être vide si les frais ne doivent pas être divulgués.
    • Doit être renseigné si les frais sont à divulguer.
    | +| **transactionType** | 1 | `TransactionType` | Type de transaction pour laquelle le devis est demandé. | +| **note** | 0..1 | Note | Mémo joint à la transaction. | +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 85 -- Type complexe IndividualQuote** + +
    + +#### IndividualQuoteResult + +[Le tableau 86](#table-86) présente le modèle de données pour le type complexe `IndividualQuoteResult`. + +###### Tableau 86 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifie le message du devis. | +| **payee** | 0..1 | `Party` | Informations sur le bénéficiaire dans la transaction financière proposée. | +| **transferAmount** | 0..1 | `Money` | Montant que le FSP du Payeur doit transférer au FSP du Bénéficiaire. | +| **payeeReceiveAmount** | 0..1 | `Money` | Montant que le Bénéficiaire devra recevoir au final. Facultatif si le FSP du Bénéficiaire ne souhaite pas divulguer de frais optionnels. | +| **payeeFspFee** | 0..1 | `Money` | Part des frais de transaction du FSP du Bénéficiaire. | +| **payeeFspCommission** | 0..1 | `Money` | Commission de transaction du FSP du Bénéficiaire. | +| **ilpPacket** | 0..1 | `IlpPacket` | Paquet ILP à joindre au transfert par le Payeur. | +| **condition** | 0..1 | `IlpCondition` | Condition à joindre au transfert par le Payeur. | +| **errorInformation** | 0..1 | `ErrorInformation` | Code d’erreur, description de la catégorie.
    **Remarque :** Les paramètres payee, transferAmount, payeeReceiveAmount, payeeFspFee, payeeFspCommission, ilpPacket et condition ne doivent pas être définis si errorInformation est renseigné.
    | +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 86 -- Type complexe IndividualQuoteResult** + +
    + +#### IndividualTransfer + +[Le tableau 87](#table-87) présente le modèle de données pour le type complexe `IndividualTransfer`. + +###### Tableau 87 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifie les messages liés à la même séquence **/transfers**. | +| **transferAmount** | 1 | `Money` | Montant de la transaction à envoyer. | +| **ilpPacket** | 1 | `IlpPacket` | Paquet ILP contenant le montant destiné au bénéficiaire, l’adresse ILP du bénéficiaire et toutes données end-to-end. | +| **condition** | 1 | `IlpCondition` | Condition qui doit être remplie pour engager le transfert. | +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 87 -- Type complexe IndividualTransfer** + +
    + +#### IndividualTransferResult + +[Le tableau 88](#table-88) présente le modèle de données pour le type complexe `IndividualTransferResult`. + +###### Tableau 88 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifie les messages liés à la même séquence /transfers. | +| **fulfilment** | 0..1 | `IlpFulfilment` | Fulfilment (preuve) de la condition définie avec la transaction.
    **Remarque :** Soit **fulfilment**, soit **errorInformation** doit être renseigné, jamais les deux. | +| **errorInformation** | 0..1 | `ErrorInformation` | Si le transfert est REJECTED, les informations d’erreur peuvent être fournies.
    **Remarque :** Soit **fulfilment**, soit **errorInformation** doit être renseigné, jamais les deux.| +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 88 -- Type complexe IndividualTransferResult** + +
    + +#### GeoCode + +[Le tableau 89](#table-89) présente le modèle de données pour le type complexe `GeoCode`. + +###### Tableau 89 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **latitude** | 1 | `Latitude` | Latitude de la Partie. | +| **longitude** | 1 | `Longitude` | Longitude de la Partie. | + +**Tableau 89 -- Type complexe GeoCode** + +
    + +#### Money + +[Le tableau 90](#table-90) présente le modèle de données pour le type complexe `Money`. + +###### Tableau 90 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **currency** | 1 | `Currency` | Devise du montant. | +| **amount** | 1 | `Amount` | Montant d’argent. | + +**Tableau 90 -- Type complexe Money** + +
    + +#### Party + +[Le tableau 91](#table-91) présente le modèle de données pour le type complexe `Party`. + +###### Tableau 91 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdInfo** | 1 | `PartyIdInfo` | Type d’id de la Partie, id, sous-id ou type, et FSP Id. | +| **merchantClassificationCode** | 0..1 | `MerchantClassificationCode` | Utilisé pour la partie Bénéficiaire marchande. | +| **name** | 0..1 | `PartyName` | Nom affiché de la Partie, peut être un nom réel ou un pseudo. | +| **personalInfo** | 0..1 | `PartyPersonalInfo` | Informations personnelles pour vérifier l’identité de la Partie (nom, prénom, date de naissance, etc.). | + +**Tableau 91 -- Type complexe Party** + +
    + +#### PartyComplexName + +[Le tableau 92](#table-92) présente le modèle de données pour le type complexe `PartyComplexName`. + +###### Tableau 92 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **firstName** | 0..1 | `FirstName` | Prénom de la Partie. | +| **middleName** | 0..1 | `MiddleName` | Deuxième prénom de la Partie. | +| **lastName** | 0..1 | `LastName` | Nom de famille de la Partie. | + +**Tableau 92 -- Type complexe PartyComplexName** + +
    + +#### PartyIdInfo + +[Le tableau 93](#table-93) présente le modèle de données pour le type complexe `PartyIdInfo`. + +###### Tableau 93 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdType** | 1 | `PartyIdType` | Type d’identifiant. | +| **partyIdentifier** | 1 | `PartyIdentifier` | Identifiant de la Partie. | +| **partySubIdOrType** | 0..1 | `PartySubIdOrType` | Sous-identifiant ou sous-type pour la Partie. | +| **fspId** | 0..1 | `FspId` | Identifiant FSP (si connu). | +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 93 -- Type complexe PartyIdInfo** + +
    + +#### PartyPersonalInfo + +[Le tableau 94](#table-94) présente le modèle de données pour le type complexe `PartyPersonalInfo`. + +###### Tableau 94 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **complexName** | 0..1 | `PartyComplexName` | Prénom, deuxième prénom et nom de famille de la Partie. | +| **dateOfBirth** | 0..1 | `DateOfBirth` | Date de naissance de la Partie. | + +**Tableau 94 -- Type complexe PartyPersonalInfo** + +
    + +#### PartyResult + +[Le tableau 95](#table-95) présente le modèle de données pour le type complexe `PartyResult`. + +###### Tableau 95 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyId** | 1 | `PartyIdInfo` | Type d’id de la Partie, id, sous-id ou type, et FSP Id. | +| **errorInformation** | 0..1 | `ErrorInformation` | Si la Partie n’a pas pu être ajoutée, une information d’erreur doit être fournie. Sinon, ce paramètre doit être vide pour indiquer le succès. | + +**Tableau 95 -- Type complexe PartyResult** + +
    + +#### Refund + +[Le tableau 96](#table-96) présente le modèle de données pour le type complexe `Refund`. + +###### Tableau 96 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **originalTransactionId** | 1 | `CorrelationId` | Référence à l’ID de la transaction d’origine à rembourser. | +| **refundReason** | 0..1 | `RefundReason` | Texte libre précisant la raison du remboursement. | + +**Tableau 96 -- Type complexe Refund** + +
    + +#### Transaction + +[Le tableau 97](#table-97) présente le modèle de données pour le type complexe Transaction. Le type Transaction sert à véhiculer des données de bout en bout entre le FSP Payeur et le FSP Bénéficiaire dans le paquet ILP, voir [IlpPacket](#ilp-packet). Les champs **transactionId** et **quoteId** sont décidés par le FSP Payeur lors du [POST /quotes](#post-quotes), voir [Tableau 23](#table-23). + +###### Tableau 97 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transactionId** | 1 | `CorrelationId` | ID de la transaction, défini par le FSP Payeur lors de la création du devis. | +| **quoteId** | 1 | `CorrelationId` | ID du devis, défini par le FSP Payeur lors de la création du devis. | +| **payee** | 1 | `Party` | Informations sur le bénéficiaire dans la transaction proposée. | +| **payer** | 1 | `Party` | Informations sur le payeur dans la transaction proposée. | +| **amount** | 1 | `Money` | Montant de la transaction à envoyer. | +| **transactionType** | 1 | `TransactionType` | Type de la transaction. | +| **note** | 0..1 | `Note` | Mémo associé à la transaction, destiné au bénéficiaire. | +| **extensionList** | 0..1 | `ExtensionList` | Extension facultative, spécifique au déploiement. | + +**Tableau 97 -- Type complexe Transaction** + +
    + +#### TransactionType + +[Le tableau 98](#table-98) présente le modèle de données pour le type complexe `TransactionType`. + +###### Tableau 98 + +| **Nom** | **Cardinalité** | **Format** | **Description** | +| --- | --- | --- | --- | +| **scenario** | 1 | `TransactionScenario` | Dépôt, retrait, remboursement, ... | +| **subScenario** | 0..1 | `TransactionSubScenario` | Sous-scénario éventuel, défini localement. | +| **initiator** | 1 | `TransactionInitiator` | Initiateur de la transaction : Payeur ou Bénéficiaire. | +| **initiatorType** | 1 | `TransactionInitiatorType` | Consommateur, agent, entreprise, ... | +| **refundInfo** | 0..1 | `Refund` | Informations supplémentaires particulières pour les remboursements. À renseigner uniquement si le scénario est REFUND. | +| **balanceOfPayments** | 0..1 | `BalanceOfPayments` | Code Balance des Paiements. | + +**Tableau 98 -- Type complexe TransactionType** + +
    + +### Énumérations + +Cette section présente les énumérations utilisées par l’API. + +#### AmountType enum + +[Le tableau 99](#table-99) présente les valeurs autorisées pour l’énumération `AmountType`. + +###### Tableau 99 + +| **Nom** | **Description** | +| --- | --- | +| **SEND** | Montant que le payeur souhaite envoyer ; c’est-à-dire le montant à débiter, frais inclus. | +| **RECEIVE** | Montant que le payeur souhaite que le bénéficiaire reçoive, c’est-à-dire montant crédité hors frais. | + +**Tableau 99 -- Énumération AmountType** + +
    + +#### AuthenticationType enum + +[Le tableau 100](#table-100) présente les valeurs autorisées pour l’énumération `AuthenticationType`. + +###### Tableau 100 + +| **Nom** | **Description** | +| --- | --- | +| **OTP** | Mot de passe à usage unique généré par le FSP du payeur. | +| **QRCODE** | Code QR utilisé comme mot de passe à usage unique. | + +**Tableau 100 -- Énumération AuthenticationType** + +
    + +#### AuthorizationResponse enum + +[Le tableau 101](#table-101) présente les valeurs autorisées pour l’énumération `AuthorizationResponse`. + +###### Tableau 101 + +| **Nom** | **Description** | +| --- | --- | +| **ENTERED** | Le consommateur a saisi la valeur d’authentification. | +| **REJECTED** | Le consommateur a rejeté la transaction. | +| **RESEND** | Le consommateur demande de renvoyer la valeur d’authentification. | + +**Tableau 101 -- Énumération AuthorizationResponse** + +
    + +#### BulkTransferState enum + +[Le tableau 102](#table-102) présente les valeurs autorisées pour l’énumération `BulkTransferState`. + +###### Tableau 102 + +| **Nom** | **Description** | +| --- | --- | +| **RECEIVED** | Le FSP bénéficiaire a reçu le transfert en lot du FSP payeur. | +| **PENDING** | Le FSP bénéficiaire a validé le transfert en lot. | +| **ACCEPTED** | Le FSP bénéficiaire a accepté le transfert en lot pour traitement. | +| **PROCESSING** | Le FSP bénéficiaire a commencé à transférer les fonds aux bénéficiaires. | +| **COMPLETED** | Le FSP bénéficiaire a terminé le transfert des fonds aux bénéficiaires. | +| **REJECTED** | Le FSP bénéficiaire a rejeté le traitement du transfert en lot. | + +**Tableau 102 -- Énumération BulkTransferState** + +
    + +#### Code devise (CurrencyCode) enum + +Les codes de devise définis par la norme ISO 421736 sous forme de codes alphabétiques à trois lettres sont utilisés comme représentation standard des devises. Les codes ISO 4217 ne sont pas listés ici, les implémenteurs sont invités à se référer directement à la norme ISO 4217. + +
    + +#### PartyIdType enum + +[Le tableau 103](#Table-103) présente les valeurs autorisées pour l’énumération `PartyIdType`. + +###### Tableau 103 + +| **Nom** | **Description** | +| --- | --- | +| **MSISDN** | Un MSISDN (numéro international de téléphone mobile) est utilisé pour référencer une Partie. Il doit être au format E.164 ITU-T, éventuellement précédé d’un "+". | +| **EMAIL** | Une adresse email est utilisée pour référencer une Partie. Format selon RFC 3696. | +| **PERSONAL_ID** | Un identifiant personnel (numéro de passeport, d'acte de naissance, d’enregistrement national, etc.) Pour le type voir [PartySubIdOrType](#partysubidortype-element). | +| **BUSINESS** | Une entreprise spécifique (ex : société, organisation) est utilisée pour référencer un participant. Format libre. Pour cibler un identifiant spécifique (utilisateur, facture, etc.) utiliser [PartySubIdOrType](#partysubidortype-element). | +| **DEVICE** | Un identifiant de dispositif spécifique (ex : TPE ou DAB) est utilisé pour une Partie. Pour une référence sous une entreprise, utiliser [PartySubIdOrType](#partysubidortype-element). | +| **ACCOUNT_ID** | Un numéro de compte bancaire ou identifiant FSP doit être utilisé pour référencer un participant. Format libre variant selon le pays et le FSP. | +| **IBAN** | Un numéro IBAN est utilisé pour référencer un participant. Jusqu’à 34 caractères alphanumériques sans espaces. | +| **ALIAS** | Un alias est utilisé pour référencer un participant (ex : username/pseudo). Un sous-compte peut aussi être ciblé via [PartySubIdOrType](#partysubidortype-element). | + +**Tableau 103 -- Énumération PartyIdType** + +
    + +#### PersonalIdentifierType enum + +[Le tableau 104](#table-104) présente les valeurs autorisées pour l’énumération `PersonalIdentifierType`. + +###### Tableau 104 + +| **Nom** | **Description** | +| --- | --- | +| **PASSPORT** | Numéro de passeport. | +| **NATIONAL_REGISTRATION** | Numéro d’enregistrement national. | +| **DRIVING_LICENSE** | Permis de conduire. | +| **ALIEN_REGISTRATION** | Numéro d’enregistrement d’étranger. | +| **NATIONAL_ID_CARD** | Numéro de carte d’identité nationale. | +| **EMPLOYER_ID** | Numéro d’identification fiscale (employeur). | +| **TAX_ID_NUMBER** | Numéro d’identification fiscale. | +| **SENIOR_CITIZENS_CARD** | Numéro de carte senior. | +| **MARRIAGE_CERTIFICATE** | Numéro d’acte de mariage. | +| **HEALTH_CARD** | Numéro de carte de santé. | +| **VOTERS_ID** | Numéro de carte d’électeur. | +| **UNITED_NATIONS** | Numéro ONU. | +| **OTHER_ID** | Tout autre type d’identifiant. | + +**Tableau 104 -- Énumération PersonalIdentifierType** + +
    + +#### TransactionInitiator + +[Le tableau 105](#table-105) décrit les valeurs autorisées pour l’énumération `TransactionInitiator`. + +###### Tableau 105 + +| **Nom** | **Description** | +| --- | --- | +| **PAYER** | Le payeur initie la transaction. Le compte source lui appartient ou lui est associé d’une manière ou d’une autre. | +| **PAYEE** | Le bénéficiaire initie la transaction en envoyant une demande de transaction. Le payeur doit approuver (automatiquement ou manuellement). | + +**Tableau 105 -- Énumération TransactionInitiator** + +
    + +#### TransactionInitiatorType + +[Le tableau 106](#table-106) présente les valeurs autorisées pour l’énumération `TransactionInitiatorType`. + +###### Tableau 106 + +| **Nom** | **Description** | +| --- | --- | +| **CONSUMER** | Le consommateur est l’initiateur de la transaction. | +| **AGENT** | L’agent est l’initiateur de la transaction. | +| **BUSINESS** | L’entreprise est l’initiatrice de la transaction. | +| **DEVICE** | L’équipement est l’initiateur de la transaction. | + +**Tableau 106 -- Énumération TransactionInitiatorType** + +
    + +#### TransactionRequestState + +[Le tableau 107](#table-107) présente les valeurs autorisées pour l’énumération `TransactionRequestState`. + +###### Tableau 107 + +| **Nom** | **Description** | +| --- | --- | +| **RECEIVED** | Le FSP du payeur a reçu la transaction du FSP du bénéficiaire. | +| **PENDING** | Le FSP du payeur a transmis la demande de transaction au payeur. | +| **ACCEPTED** | Le payeur a approuvé la transaction. | +| **REJECTED** | Le payeur a rejeté la transaction. | + +**Tableau 107 -- Énumération TransactionRequestState** + +
    + +#### TransactionScenario + +[Le tableau 108](#table-108) présente les valeurs autorisées pour l’énumération `TransactionScenario`. + +###### Tableau 108 + +| **Nom** | **Description** | +| --- | --- | +| **DEPOSIT** | Pour effectuer un dépôt (cash-in) : transfert de fonds électroniques vers le consommateur, remise d’espèces au commerçant. | +| **WITHDRAWAL** | Pour effectuer un retrait (cash-out) : transfert de fonds électroniques au commerçant, remise d’espèces au client. | +| **TRANSFER** | Pour un transfert de personne à personne (P2P). | +| **PAYMENT** | Pour effectuer le paiement d’un consommateur à un commerçant ou une organisation, ou un paiement B2B. Peut concerner un achat en ligne, un paiement sur place, une facture, un don, etc. | +| **REFUND** | Pour effectuer un remboursement. | + +**Tableau 108 -- Énumération TransactionScenario** + +
    + +#### TransactionState + +[Le tableau 109](#table-109) présente les valeurs autorisées pour l’énumération `TransactionState`. + +###### Tableau 109 + +| **Nom** | **Description** | +| --- | --- | +| **RECEIVED** | Le FSP du bénéficiaire a reçu la transaction du FSP du payeur. | +| **PENDING** | Le FSP du bénéficiaire a validé la transaction. | +| **COMPLETED** | Le FSP du bénéficiaire a exécuté la transaction avec succès. | +| **REJECTED** | Le FSP du bénéficiaire a échoué à réaliser la transaction. | + +**Tableau 109 -- Énumération TransactionState** + +
    + +#### TransferState + +[Le tableau 110](#table-110) présente les valeurs autorisées pour l’énumération `TransferState`. + +###### Tableau 110 + +| **Nom** | **Description** | +| --- | --- | +| **RECEIVED** | Le ledger suivant a reçu le transfert. | +| **RESERVED** | Le ledger suivant a réservé le transfert. | +| **COMMITTED** | Le ledger suivant a validé le transfert. | +| **ABORTED** | Le ledger suivant a annulé le transfert à cause d’un rejet ou d’un échec. | + +**Tableau 110 -- Énumération TransferState** + +
    + +### Codes d’erreur + +###### Figure 63 + +Chaque code d’erreur de l’API est un nombre à quatre chiffres, par exemple **1234**, où le premier chiffre (**1** ici) indique la catégorie d’erreur principale, le deuxième (**2**) la sous-catégorie, et les deux derniers (**34**) l’erreur spécifique. [Figure 63](#figure-63) montre la structure d’un code d’erreur. Les sections suivantes détaillent les codes d’erreur définis pour chaque catégorie. + +![Figure 63](../../assets/diagrams/images/figure63.svg) + +**Figure 63 -- Structure des codes d’erreur** + +Chaque combinaison de catégories principale et secondaire possède une erreur générique (_x_**0**_xx_), utilisable s’il n’existe pas d’erreur plus spécifique, ou si le serveur ne souhaite pas communiquer plus d’information. + +Toutes les erreurs spécifiques inférieures à _xx_**40** (c’est-à-dire de _xx_**00** à _xx_**39**) sont réservées à un usage ultérieur de l’API. Celles à partir de _xx_**40** peuvent servir pour des besoins propres à un schéma. Si un client reçoit une erreur inconnue propre à un schéma, elle devra être traitée comme une erreur générique de la catégorie (_xx_**00**). + +#### Erreurs de communication -- 1_xxx_ + +Toutes les erreurs de communication ou réseau n’étant pas couvertes par un code HTTP doivent utiliser le code d’erreur principal **1** (codes **1**_xxx_). Comme tous les services de l’API sont asynchrones, ces erreurs sont généralement émises par le Switch au client FSP si le FSP pair est injoignable ou si aucun callback n’est reçu dans le délai convenu. + +Sous-catégories pour les erreurs de communication : + +- **Erreur de communication générique** -- **10**_xx_ + +Voir [Tableau 111](#table-111) pour la liste des erreurs de ce type. + +###### Tableau 111 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **1000** | Erreur de communication | Erreur de communication générique. | X | X | X | X | X | X | X | X | X | +| **1001** | Erreur de communication destination | La destination de la requête n’a pas pu être jointe (échec de réponse intermédiaire). | X | X | X | X | X | X | X | X | X | + +**Tableau 111 -- Erreurs de communication -- 1_xxx_** + +#### Erreurs serveur -- 2_xxx_ + +Toutes les erreurs survenues côté serveur où ce dernier n’a pas pu satisfaire une requête apparemment valide du client utilisent la catégorie **2** (codes **2**_xxx_). Ces erreurs signifient que le serveur est conscient d’avoir rencontré une erreur ou d’être incapable de traiter la demande. + +Sous-catégories pour les erreurs serveur : + +- **Erreur serveur générique** -- **20**_xx_ + +Voir [Tableau 112](#Table-112) pour les erreurs serveur définies. + +###### Tableau 112 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **2000** | Erreur serveur générique | Erreur serveur générique pour ne pas divulguer d’informations privées. | X | X | X | X | X | X | X | X | X | +| **2001** | Erreur serveur interne | Exception inattendue générique (bug ou cas non géré). | X | X | X | X | X | X | X | X | X | +| **2002** | Non implémenté | Service demandé non supporté par le serveur. | X | X | X | X | X | X | X | X | X | +| **2003** | Service indisponible | Service demandé indisponible (maintenance, panne temporaire, etc.). | X | X | X | X | X | X | X | X | X | +| **2004** | Timeout serveur | Le serveur n’a pas reçu de callback dans le délai imparti (timeout). | X | X | X | X | X | X | X | X | X | +| **2005** | Serveur surchargé | Le serveur refuse les requêtes pour surcharge. Réessayez plus tard. | X | X | X | X | X | X | X | X | X | + +**Tableau 112 -- Erreurs serveur -- 2_xxx_** + +#### Erreurs côté Client -- 3_xxx_ + +Toutes les erreurs possibles se produisant sur le serveur, où ce dernier signale que le client a envoyé un ou plusieurs paramètres erronés, doivent utiliser le code d’erreur principal **3** (codes d’erreur **3**_xxx_). Ces codes d’erreur indiquent que le serveur n’a pas pu effectuer le service selon la demande du client. Le serveur doit fournir une explication sur la raison pour laquelle le service n’a pas pu être exécuté. + +Catégories de bas niveau définies sous les erreurs client : + +- **Erreur Générique du Client** -- **30**_xx_ + + - Voir [Tableau 113](#table-113) pour la liste des erreurs génériques côté client définies dans l’API. + +- **Erreur de Validation** -- **31**_xx_ + + - Voir [Tableau 114](#table-114) pour la liste des erreurs de validation dans l’API. + +- **Erreur d’Identifiant** -- **32**_xx_ + + - Voir [Tableau 115](#table-115) pour la liste des erreurs d’identification dans l’API. + +- **Erreur d’Expiration** -- **33**_xx_ + + - Voir [Tableau 116](#table-116) pour la liste des erreurs d’expiration dans l’API. + +###### Tableau 113 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3000** | Erreur générique côté client | Erreur générique côté client, utilisée pour ne pas divulguer d’informations sensibles. | X | X | X | X | X | X | X | X | X | +| **3001** | Version demandée non acceptable | Le client a demandé une version du protocole qui n’est pas supportée par le serveur. | X | X | X | X | X | X | X | X | X | +| **3002** | URI inconnue | L’URI fournie est inconnue du serveur. | X | X | X | X | X | X | X | X | X | +| **3003** | Erreur d’ajout d’information de Partie | Une erreur s’est produite lors de l’ajout ou de la mise à jour des informations concernant une Partie. | X | X | X | X | X | X | X | X | X | + +**Tableau 113 -- Erreurs génériques côté client -- 30_xx_** + +###### Tableau 114 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3100** | Erreur de validation générique | Erreur de validation générique utilisée pour ne pas divulguer d’informations sensibles. | X | X | X | X | X | X | X | X | X | +| **3101** | Syntaxe mal formée | Le format du paramètre n’est pas valide. Par exemple, montant fixé à **5.ABC**. Le champ de description d’erreur devrait préciser quel élément est erroné. | X | X | X | X | X | X | X | X | X | +| **3102** | Élément obligatoire manquant | Élément obligatoire absent dans le modèle de données. | X | X | X | X | X | X | X | X | X | +| **3103** | Trop d’éléments | Le nombre d’éléments dans un tableau dépasse le nombre maximum autorisé. | X | X | X | X | X | X | X | X | X | +| **3104** | Charge utile trop volumineuse | La taille de la charge utile dépasse la taille maximale autorisée. | X | X | X | X | X | X | X | X | X | +| **3105** | Signature invalide | Certains paramètres du message ont été modifiés, rendant la signature invalide. Cela peut indiquer que le message a été modifié de manière malveillante. | X | X | X | X | X | X | X | X | X | +| **3106** | Requête modifiée | Une précédente requête avec le même ID a déjà été traitée, mais avec des paramètres différents. ||| X | X | X | X | X | X | X | +| **3107** | Paramètre d’extension obligatoire manquant | Un paramètre d’extension obligatoire pour le schéma est absent. ||| X | X | X | X | X | X | X | + +**Tableau 114 -- Erreurs de validation -- 31_xx_** + +###### Tableau 115 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3200** | Identifiant générique non trouvé | Erreur générique d’identifiant fournie par le client. | X | X | X | X | X | X | X | X | X | +| **3201** | Erreur FSP Destinataire | Le FSP destinataire n’existe pas ou est introuvable. | X | X | X | X | X | X | X | X | X | +| **3202** | Identifiant FSP Payeur introuvable | Identifiant FSP Payeur fourni introuvable. |||||| X ||| X | +| **3203** | Identifiant FSP Bénéficiaire introuvable | Identifiant FSP Bénéficiaire fourni introuvable. |||||| X ||| X | +| **3204** | Partie non trouvée | Partie avec l’identifiant, le type d’identifiant et le sous-id ou type optionnel fournis non trouvée. | X | X | X | X |||||| +| **3205** | Identifiant de devis introuvable | Devis fourni introuvable sur le serveur. |||| X || X |||| +| **3206** | ID de demande de transaction introuvable | Demande de Transaction fournie introuvable sur le serveur. ||| X ||| X |||| +| **3207** | ID de transaction introuvable | ID de transaction fourni introuvable sur le serveur. ||||||| X ||| +| **3208** | ID de transfert introuvable | ID de transfert fourni introuvable sur le serveur. |||||| X |||| +| **3209** | ID de devis groupé introuvable | ID de devis groupé fourni introuvable sur le serveur. |||||||| X | X | +| **3210** | ID de transfert groupé introuvable | ID de transfert groupé fourni introuvable sur le serveur. ||||||||| X | + +**Tableau 115 -- Erreurs d’identifiant -- 32_xx_** + +###### Tableau 116 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3300** | Erreur générique d’expiration | Erreur d’objet expiré générique, à utiliser pour ne pas divulguer d’informations sensibles. | X | X | X | X | X | X | X | X | X | +| **3301** | Demande de transaction expirée | Le client a demandé d’utiliser une demande de transaction qui a déjà expiré. |||| X |||||| +| **3302** | Devis expiré | Le client a demandé d’utiliser un devis qui a déjà expiré. ||||| X | X ||| X | +| **3303** | Transfert expiré | Le client a demandé d’utiliser un transfert qui a déjà expiré. | X | X | X | X | X | X | X | X | X | + +**Tableau 116 -- Erreurs d’expiration -- 33_xx_** + +#### Erreurs côté Payeur -- 4_xxx_ + +Toutes les erreurs se produisant sur le serveur dont la cause est liée au Payeur ou à son FSP doivent utiliser le code d’erreur principal **4** (codes **4**_xxx_). Ces codes d’erreur indiquent qu’il n’y a pas eu d’erreur sur le serveur ni dans la requête du client, mais que la requête a échoué pour une raison liée au Payeur ou à son FSP. Le serveur doit fournir une explication sur la raison pour laquelle le service n’a pas pu être exécuté. + +Catégories de bas niveau définies pour les erreurs côté Payeur : + +- **Erreur Générique Payeur** -- **40**_xx_ +- **Erreur de Rejet Payeur** -- **41**_xx_ +- **Erreur de Limite Payeur** -- **42**_xx_ +- **Erreur de Permission Payeur** -- **43**_xx_ +- **Erreur Payeur Bloqué** -- **44**_xx_ + +Voir [Tableau 117](#table-117) pour les erreurs Payeur définies dans l’API. + +###### Tableau 117 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **4000** | Erreur générique Payeur | Erreur générique liée au Payeur ou à son FSP. Utilisée pour protéger les informations pouvant être sensibles. ||| X | X | X | X | X | X | X | +| **4001** | FSP Payeur liquidité insuffisante | Le FSP Payeur n’a pas assez de liquidité pour effectuer le transfert. |||||| X |||| +| **4100** | Rejet générique Payeur | Le Payeur ou le FSP Payeur a rejeté la requête. ||| X | X | X | X | X | X | X | +| **4101** | Payeur a rejeté la demande de transaction | Le Payeur a rejeté la demande de transaction du Bénéficiaire. ||| X ||||||| +| **4102** | FSP Payeur type de transaction non supporté | Le FSP Payeur ne supporte pas ou a rejeté le type de transaction demandé. ||| X ||||||| +| **4103** | Payeur devise non supportée | Le Payeur n’a pas de compte supportant la devise demandée. ||| X ||||||| +| **4200** | Erreur de limite Payeur | Erreur de limite générique, par exemple nombre de paiements journalier/mensuel dépassé ou montant de la transaction supérieur au maximum autorisé. ||| X | X || X || X | X | +| **4300** | Erreur de permission Payeur | Erreur de permission générique, le Payeur ou son FSP n’a pas les droits pour réaliser le service. ||| X | X | X | X | X | X | X | +| **4400** | Erreur Payeur bloqué générique | Erreur Payeur bloqué générique ; le Payeur est bloqué ou a échoué les contrôles réglementaires. ||| X | X | X | X | X | X | X | + +**Tableau 117 -- Erreurs côté Payeur -- 4_xxx_** + +#### Erreurs côté Bénéficiaire -- 5_xxx_ + +Toutes les erreurs se produisant sur le serveur pour lesquelles le Bénéficiaire ou son FSP est la cause de l’erreur utilisent le code d’erreur principal **5** (codes **5**_xxx_). Ces codes d’erreur indiquent qu’il n’y a pas eu d’erreur sur le serveur ni dans la requête du client, mais que la requête a échoué pour une raison liée au Bénéficiaire ou à son FSP. Le serveur doit fournir une explication sur la raison pour laquelle le service n’a pas pu être exécuté. + +Catégories de bas niveau pour les erreurs Bénéficiaire : + +- **Erreur Générique Bénéficiaire** -- **50**_xx_ +- **Erreur de Rejet Bénéficiaire** -- **51**_xx_ +- **Erreur de Limite Bénéficiaire** -- **52**_xx_ +- **Erreur de Permission Bénéficiaire** -- **53**_xx_ +- **Erreur Bénéficiaire Bloqué** -- **54**_xx_ + +Voir [Tableau 118](#table-118) pour toutes les erreurs Bénéficiaire définies dans l’API. + +###### Tableau 118 + +| **Code d’erreur** | **Nom** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **5000** | Erreur générique Bénéficiaire | Erreur générique due au Payeur ou à son FSP, à utiliser pour ne pas divulguer d’informations sensibles. ||| X | X | X | X | X | X | X | +| **5001** | FSP Bénéficiaire liquidité insuffisante | FSP Bénéficiaire n’a pas assez de liquidité pour effectuer le transfert. |||||| X |||| +| **5100** | Rejet générique Bénéficiaire | Le Bénéficiaire ou son FSP a rejeté la requête. ||| X | X | X | X | X | X | X | +| **5101** | Bénéficiaire a rejeté le devis | Le Bénéficiaire ne souhaite pas poursuivre la transaction après réception du devis. |||| X |||| X || +| **5102** | FSP Bénéficiaire type de transaction non supporté | FSP Bénéficiaire ne supporte pas ou a rejeté le type de transaction demandé. |||| X ||||| X | +| **5103** | FSP Bénéficiaire a rejeté le devis | Le FSP Bénéficiaire ne souhaite pas poursuivre la transaction après réception du devis. |||| X |||| X || +| **5104** | Bénéficiaire a rejeté la transaction | Le Bénéficiaire a rejeté la transaction financière. |||||| X ||| X | +| **5105** | FSP Bénéficiaire a rejeté la transaction | Le FSP Bénéficiaire a rejeté la transaction financière. |||||| X ||| X | +| **5106** | Devise non supportée par le Bénéficiaire | Le Bénéficiaire ne possède pas de compte prenant en charge la devise demandée. |||| X || X || X | X | +| **5200** | Erreur de limite Bénéficiaire | Erreur de limite générique, par exemple Bénéficiaire recevant plus de paiements par jour/mois que permis, ou recevant un paiement dépassant le montant maximum par transaction. ||| X | X || X || X | X | +| **5300** | Erreur de permission Bénéficiaire | Erreur de permission générique, le Bénéficiaire ou son FSP n’a pas les droits pour réaliser le service. ||| X | X | X | X | X | X | X | +| **5400** | Erreur Bénéficiaire bloqué générique | Erreur générique Bénéficiaire bloqué, le Bénéficiaire est bloqué ou a échoué les contrôles réglementaires. ||| X | X | X | X | X | X | X | + +**Tableau 118 -- Erreurs côté Bénéficiaire -- 5_xxx_** + + +## Liaison avec les schémas génériques des transactions + +Cette section décrit comment les schémas logiques de transaction présentés dans [Schémas de Transactions Génériques](../generic-transaction-patterns) sont utilisés dans la liaison REST asynchrone de l’API. De nombreuses informations sont présentées sous forme de diagrammes de séquence. Pour plus d’informations sur les étapes de ces diagrammes, voir [Schémas de Transactions Génériques](../generic-transaction-patterns). + +### Transaction Initiée par le Payeur + +Le schéma `Transaction Initiée par le Payeur` est introduit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payer-initiated-transaction). À un niveau général, ce schéma doit être utilisé chaque fois qu’un Payeur souhaite transférer des fonds à une autre Partie qui ne se trouve pas dans le même FSP que le Payeur. [Figure 64](#figure-64) présente le diagramme de séquence pour une `Transaction Initiée par le Payeur` utilisant la liaison REST asynchrone de la version logique. Le processus de chaque numéro dans le diagramme de séquence est décrit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payer-initiated-transaction). + +###### Figure 64 + +![](../../assets/diagrams/sequence/figure64.svg) + +**Figure 64 -- Schéma Transaction Initiée par le Payeur utilisant l’API REST asynchrone** + +### Transaction Initiée par le Bénéficiaire + +Le schéma `Transaction Initiée par le Bénéficiaire` est introduit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payer-initiated-transaction). À un niveau général, le schéma doit être utilisé lorsqu’un Bénéficiaire souhaite demander au Payeur de transférer des fonds vers le Bénéficiaire. Le Payeur et le Bénéficiaire sont supposés dans des FSP différents, et l’approbation de la transaction est réalisée dans le FSP Payeur. Si l’entrée et l’approbation de la transaction ont lieu sur un appareil du Bénéficiaire, utilisez plutôt le schéma connexe Transaction Initiée par le Bénéficiaire avec OTP](#payee-initiated-transaction-using-otp). [Figure 65](#figure-65) présente le diagramme de séquence pour une `Transaction Initiée par le Bénéficiaire` utilisant la liaison REST asynchrone de la version logique. Le processus pour chaque numéro du diagramme est décrit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payee-initiated-transaction). + +###### Figure 65 + +![](../../assets/diagrams/sequence/figure65.svg) + +**Figure 65 -- Schéma Transaction Initiée par le Bénéficiaire utilisant l’API REST asynchrone** + +### Transaction Bénéficiaire Initiée avec OTP + +Le schéma `Transaction Initiée par le Bénéficiaire avec OTP` est introduit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payee-initiated-transaction-using-otp). À un niveau général, ce schéma ressemble à [Transaction Initiée par le Bénéficiaire](#payee-initiated-transaction) ; cependant, dans ce schéma les informations de transaction et l’approbation du Payeur sont affichées et saisies sur un appareil du Bénéficiaire. Comme pour les autres schémas, le Payeur et le Bénéficiaire sont dans des FSP différents. [Figure 66](#figure-66) montre le diagramme pour une `Transaction Initiée par le Bénéficiaire avec OTP` utilisant la liaison REST asynchrone de la version logique. Le processus de chaque étape du diagramme est décrit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#payee-initiated-transaction-using-otp). + +###### Figure 66 + +![](../../assets/diagrams/sequence/figure66.svg) + +**Figure 66 -- Schéma Transaction Initiée par le Bénéficiaire avec OTP via REST asynchrone** + +### Transactions Groupées + +Le schéma `Transactions Groupées` est introduit dans [Schémas de Transactions Génériques](../generic-transaction-patterns#bulk-transactions). Ce schéma est utilisé lorsque le Payeur souhaite transférer des fonds à plusieurs Bénéficiaires au sein d’une seule transaction. Les Bénéficiaires peuvent être dans différents FSP. [Figure 67](#figure-67) montre le diagramme de séquence pour des `Transactions Groupées` utilisant la liaison REST asynchrone de la version logique. L’explication de chaque étape du diagramme est disponible dans [Schémas de Transactions Génériques](../generic-transaction-patterns#bulk-transactions). + +###### Figure 67 + +![](../../assets/diagrams/sequence/figure67.svg) + +**Figure 67 -- Schéma Transactions groupées via REST asynchrone** + +
    + +## Gestion des erreurs de l’API + +Cette section décrit comment gérer les réponses ou callbacks absents ainsi que les erreurs à traiter côté serveur lors du traitement d’une requête. + +### Requête Erronée + +Si un serveur reçoit une requête de service erronée qui peut être traitée immédiatement (par exemple, syntaxe mal formée ou ressource non trouvée), un code d’erreur HTTP approprié côté client (commençant par **4_xx_**) doit être retourné au client dans la réponse. Les codes d’erreur HTTP définis pour l’API sont listés dans le [Tableau 4](#table-4). La réponse HTTP peut aussi contenir un élément [**ErrorInformation**](#errorinformation) afin de donner plus de détails sur l’erreur (voir [Informations d’erreur dans la réponse HTTP](#error-information-in-http-response)). + +
    + +### Erreur serveur lors du traitement d’une requête + +[Figure 68](#figure-68) montre un exemple sur la gestion d’une erreur survenue lors du traitement serveur. + +###### Figure 68 + +![](../../assets/diagrams/sequence/figure68.svg) + +**Figure 68 -- Erreur côté serveur lors du traitement d’une requête** + +#### Étapes internes du traitement + +La liste suivante décrit les étapes de la séquence (voir [Figure 68](#figure-68)). + +1. Le client souhaite que le serveur crée un nouvel objet de service et utilise donc une requête **POST**. + +2. Le serveur reçoit la requête. Il envoie immédiatement une réponse **accepted** au client, puis tente de créer l’objet selon la demande. Une erreur de traitement survient et la demande ne peut être satisfaite. Le serveur envoie alors le callback **_PUT_ /**_{resource}_**/**_{ID}_**/error** incluant un code d’erreur ([Codes d’erreur](#error-codes)) et une description pour notifier le client. + +3. Le client reçoit le callback d’erreur et répond immédiatement avec **OK**. Il gère ensuite l’erreur. + +4. Le serveur reçoit la réponse **OK** et le processus est terminé. + +
    + +### Gestion côté client d’un callback d’erreur + +Les sections suivantes expliquent comment un client doit traiter les callbacks d’erreur reçus d’un serveur. + +#### Ressource API /participants + +L’erreur typique du service **/participants** est que la Partie demandée n’a pas été trouvée. Le client peut soit essayer un autre serveur, soit informer l’utilisateur final que la Partie recherchée est introuvable. + +#### Ressource API /parties + +L’erreur typique du service **/parties** est que la Partie demandée n’a pas été trouvée. Le client peut soit essayer un autre serveur, soit informer l’utilisateur final que les informations recherchées sont indisponibles. + +#### Ressource API /quotes + +L’erreur typique du service **/quotes** est qu’un devis n’a pas pu être calculé pour la transaction demandée. Le client doit notifier l’utilisateur final que la transaction n’a pas pu être réalisée. + +#### Ressource API /transactionRequests + +L’erreur typique du service **/transactionRequests** est que le Payeur a rejeté la transaction ou qu’une validation automatique a échoué. Le client doit informer le Bénéficiaire que la demande de transaction a échoué. + +#### Ressource API /authorizations + +L’erreur typique du service **/authorizations** est que la demande de transaction n’a pas été trouvée. Le client doit informer le Payeur que la demande a été annulée. + +#### Ressource API /transfers + +L’erreur typique du service **/transfers** est qu’un échec a eu lieu lors du transfert hop-to-hop ou lors de la transaction financière de bout en bout. Par exemple : dépassement de limite ou Bénéficiaire introuvable. Dans tous les cas d’erreur, le client (FSP Payeur) doit annuler la réservation pour la transaction financière réalisée avant la demande d’exécution sur le serveur (FSP Bénéficiaire). Voir [Figure 69](#figure-69) pour un exemple avec un Switch financier entre les FSP. + +###### Figure 69 + +![](../../assets/diagrams/sequence/figure69.svg) + +**Figure 69 -- Gestion du callback d’erreur suite à POST /transfers** + +##### Étapes internes du traitement + +La liste suivante détaille les étapes de la séquence (voir [Figure 69](#figure-69)). + +1. La réservation du transfert est faite depuis le compte du Payeur vers un compte Switch combiné ou un compte FSP Bénéficiaire. Lorsque la réservation est réussie, la demande [POST /transfers](#post-transfers) est utilisée sur le Switch. Le transfert devient alors irrévocable côté FSP Payeur. Le FSP Payeur attend la réponse **accepted** du Switch. + +2. Le Switch reçoit la demande [POST /transfers](#post-transfers), envoie de suite une réponse **accepted** au FSP Payeur, puis effectue toutes les validations internes nécessaires. Si tout est valide, une réservation est effectuée du FSP Payeur vers le FSP Bénéficiaire. Une fois cette réservation réussie, [POST /transfers](#post-transfers) est utilisé côté FSP Bénéficiaire. Le transfert est alors irrévocable du côté Switch. Le Switch attend une réponse **accepted** du FSP Bénéficiaire. + +3. Le FSP Bénéficiaire reçoit le [POST /transfers](#post-transfers) et envoie immédiatement une réponse **accepted** au Switch. Il effectue ses propres validations. On suppose ici qu’une validation échoue (par exemple, pour dépassement de limite). Le callback d’erreur [PUT /transfers/_{ID}_/error](#put-transfers-id-error) est utilisé vers le Switch pour informer le FSP Payeur de l’erreur. Le FSP Bénéficiaire attend alors la réponse **OK** du Switch pour conclure le processus. + +4. Le Switch reçoit le callback d’erreur [PUT /transfers/_{ID}_/error](#put-transfers-id-error) et répond immédiatement avec **OK**. Il annule le transfert réservé suite à la réception du callback d’erreur. Le Switch utilise alors le callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) vers le FSP Payeur avec les mêmes paramètres, et attend une réponse **OK** pour terminer la procédure. + +5. Le FSP Payeur reçoit le callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) et répond immédiatement avec **OK**. Il annule sa propre réservation de transfert suite à la réception du callback d’erreur. + +#### Ressource API /transactions + +L’erreur normale du service **/transactions** est que la transaction n’a pas été trouvée dans le FSP Pair. + +#### Ressource API /bulkQuotes + +L’erreur typique du service **/bulkQuotes** est qu’un devis n’a pas pu être calculé pour la transaction demandée. Le client doit notifier l’utilisateur final que la transaction demandée a échoué. + +#### Ressource API /bulkTransfers + +L’erreur classique du service **/bulkTransfers** est que la transaction groupée n’a pas été acceptée, par exemple suite à une erreur de validation. Dans tous les cas d’erreur, le client (FSP Payeur) doit annuler la réservation des transactions financières effectuées avant la demande côté FSP Bénéficiaire. Voir [Figure 70](#figure-70) pour un exemple avec Switch financier entre les FSP. + +###### Figure 70 + +![](../../assets/diagrams/sequence/figure70.svg) + +**Figure 70 -- Gestion du callback d’erreur pour le service API /bulkTransfers** + +##### Étapes internes du traitement + +La liste suivante décrit les étapes de la séquence (voir [Figure 70](#figure-70)). + +1. Chaque transfert individuel du transfert groupé est réservé depuis le compte du Payeur vers un compte Switch combiné ou un compte FSP Bénéficiaire. Une fois toutes les réservations individuelles réussies, [POST /bulkTransfers](#post-bulktransfers) est utilisé sur le Switch. Le transfert groupé devient alors irrévocable côté FSP Payeur. Ce dernier attend une réponse **accepted** du Switch. + +2. Le Switch reçoit [POST /bulkTransfers](#post-bulktransfers) et répond immédiatement **accepted** au FSP Payeur. Il réalise toutes les validations nécessaires. Si celles-ci passent, chaque transfert individuel est réservé du FSP Payeur au FSP Bénéficiaire. Une fois les réservations validées, [POST /bulkTransfers](#post-bulktransfers) est utilisé vers le FSP Bénéficiaire. Le transfert groupé devient irrévocable côté Switch, qui attend alors la réponse **accepted** du FSP Bénéficiaire. + +3. Le FSP Bénéficiaire reçoit [POST /bulkTransfers](#post-bulktransfers), répond de suite **accepted** au Switch, puis effectue ses validations sur le transfert groupé. Supposons qu’une validation empêche tout le transfert groupé. Le callback d’erreur [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) est utilisé vers le Switch pour informer le FSP Payeur. Le FSP Bénéficiaire attend ensuite la réponse **OK** du Switch. + +4. Le Switch reçoit le callback d’erreur [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) et répond immédiatement par **OK**. Il annule toutes les réservations de transferts précédentes, puis utilise à son tour le callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) vers le FSP Payeur avec les paramètres identiques, et attend la réponse **OK** pour conclure. + +5. Le FSP Payeur reçoit le callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error), répond par **OK** et annule toutes les réservations précédentes suite à la réception du callback d’erreur. + +
    + +### Absence de réponse du serveur côté Client - Réenvoi de la requête + +[Figure 71](#figure-71) présente un exemple (UML) où un client (FSP ou Switch) gère une absence de réponse d’un serveur (Switch ou FSP Pair) suite à une requête de service, via le renvoi de la même requête de service. + +###### Figure 71 + +![](../../assets/diagrams/sequence/figure71.svg) + +**Figure 71 -- Gestion d’erreur côté client via réenvoi de la requête** + +#### Étapes internes du traitement + +Voici la description détaillée de chaque étape (voir [Figure 71](#figure-71)). + +1. Le client sollicite la création d’un nouvel objet de service coté serveur. La requête HTTP est perdue. + +2. Le client constate qu’aucune réponse n’a été reçue dans un délai imparti, et renvoie la requête de service. + +3. Le serveur reçoit la nouvelle requête, envoie immédiatement une réponse **accepted** au client, puis procède à la création de l’objet selon la demande initiale. + +4. La réponse HTTP **accepted** du serveur se perd en retour, le client constate à nouveau une absence de réponse dans le délai, et renvoie la requête de service. + +5. Le serveur reçoit la nouvelle requête, envoie à nouveau une réponse **accepted** au client, et constate qu’il s’agit d’un doublon (cf. étape 3). Nul besoin de créer un nouvel objet ; un callback est alors envoyé pour notifier le client de l’objet déjà créé à l’étape 3. + +6. Le client reçoit le callback concernant l’objet créé, envoie une réponse HTTP **OK** au serveur pour conclure le processus. + +7. Le serveur reçoit la réponse **OK** du client, le processus est terminé. + +
    + +### Absence de réponse du client côté Serveur + +Un serveur utilisant l’API n’est pas responsable de s’assurer qu’un callback a bien été livré au client. Toutefois, il est recommandé de réessayer en cas de non-réception d'une réponse **OK** du client. + +#### Absence de callback côté client - Utilisation de GET + +[Figure 72](#figure-72) est un diagramme de séquence UML illustrant la manière dont un client (Switch ou FSP Pair) peut gérer une absence de callback de la part d’un client (FSP ou Switch) dans un délai raisonnable. + +###### Figure 72 + +![](../../assets/diagrams/sequence/figure72.svg) + +**Figure 72 -- Gestion d’erreur côté client via requête GET** + +#### Étapes internes du traitement + +La liste suivante détaille les étapes de la séquence (voir [Figure 71](#figure-71)). + +1. Le client souhaite que le serveur crée un nouvel objet de service ; une requête de service est envoyée. + +2. Le serveur reçoit la requête de service, répond immédiatement **accepted** au client, puis crée l’objet conformément à la demande. La création est longue (ex : transfert groupé volumineux). + +3. Le serveur constate l’absence de callback côté client dans un délai raisonnable. Le client utilise alors une requête **GET** avec l’ID fourni initialement. + +4. Le serveur reçoit la requête **GET**, répond **accepted** pour signifier que la demande sera traitée. + +5. Le client reçoit la réponse **accepted** et attend le callback, qui arrive plus tard ; le client envoie alors **OK** en retour et le processus est terminé. + +6. Le serveur envoie le callback contenant l’information demandée, puis reçoit le **OK** qui termine le processus. + +
    + +## Exemple bout-en-bout + +Cette section contient un exemple complet où un titulaire de compte est provisionné, puis un transfert P2P depuis un Payeur sur un FSP vers un Bénéficiaire sur un autre FSP est effectué. L’exemple inclut les requêtes et réponses HTTP, les en-têtes HTTP, et les modèles de données JSON, mais exclut la sécurité JWS ([_Signature_](./signature.md)) et le chiffrement JWE ([_Encryption_](./encryption.md)). + +### Configuration de l’exemple + +Description de l’environnement de l’exemple. + +#### Nœuds + +###### Figure 73 + +Les nœuds de l’exemple bout-en-bout sont simplifiés à deux FSP : une banque (identifiant **BankNrOne**), un opérateur mobile money (**MobileMoney**), et un Switch (identifiant **Switch**). Le Switch joue aussi le rôle de ALS (Account Lookup System, ou Système de Recherche de Compte) ([voir Figure 73](#figure-73)). + +![Figure 73](../../assets/diagrams/images/figure73.svg) + +**Figure 73 -- Nœuds de l’exemple bout-en-bout** + +#### Titulaires de comptes + +Les titulaires de compte dans l’exemple sont : + +- Un titulaire de compte chez **BankNrOne** nommé Mats Hagman. Il dispose d’un compte IBAN **SE4550000000058398257466** en USD. + +- Un titulaire de compte chez **MobileMoney** nommé Henrik Karlsson. Il dispose d’un compte mobile identifié par **123456789** (numéro), en USD. + +#### Scénario + +Le scénario : Mats Hagman (**BankNrOne**) souhaite transférer 100 USD à Henrik Karlsson (**MobileMoney**). Avant que Henrik ne soit trouvable, son FSP **MobileMoney** doit fournir au Switch l’information d’affectation de FSP. Le déroulé complet se trouve en [Autres Informations](#other-notes). + +#### Autres Informations + +Les messages JSON sont formatés avec couleurs, indentation et retours à la ligne pour la lisibilité. + +Il est supposé que chaque FSP dispose d’un compte Switch pré-approvisionné dans son propre établissement. + +### Déroulé de l’exemple + +[Figure 74](#figure-74) illustre l’ensemble du processus, du provisioning des informations FSP jusqu’à la transaction. + +###### Figure 74 + +![](../../assets/diagrams/sequence/figure74.svg) + +**Figure 74 -- Déroulé complet : de la fourniture d’information FSP compte au succès de la transaction** + +### Provisionnement du Titulaire de Compte + +Avant que le bénéficiaire Henrik Karlsson ne soit trouvable via le FSP **BankNrOne**, il doit être provisionné dans l’ALS (le Switch) par son FSP (**MobileMoney**). Cela s’effectue via [**POST /participants**](#6232-post-participants) (version bulk) ou [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) (version simple). Comme il n'y a ici qu'un bénéficiaire, la version simple est utilisée par **MobileMoney**. Le provisioning peut avoir lieu à tout moment, lors de la création du compte ou lors de la connexion initiale au Switch. + +#### FSP MobileMoney provisionne Henrik Karlsson : Étape 1 du déroulé + +[Listing 29](#listing-29) montre la demande HTTP où **MobileMoney** provisionne les infos FSP pour Henrik Karlsson, identifié par **MSISDN** et **123456789** (voir [Adressage de Parties](#party-addressing)). L’élément JSON **fspId** est mis à l’identifiant du FSP et **currency** à la devise du compte (USD). + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis, +et [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) pour plus d’infos. Pour le routage avec **FSPIOP-Destination** et **FSPIOP-Source**, voir [Routage du flux d’appel](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Pour la négociation de version, voir [Négociation de version entre client et serveur](#version-negotiation-between-client-and-server). + +###### Listing 29 + +``` +POST /participants/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.participants+json;version=1 +Content-Length: 50 +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +Date: Tue, 14 Nov 2017 08:12:31 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 29 -- Provision d’informations FSP pour le titulaire Henrik Karlsson** + +[Listing 30](#listing-30) présente la réponse HTTP synchrone où le Switch accuse réception immédiate (après vérif de headers, etc.). + +Voir [Tableau 3](#table-3) pour les en-têtes de réponse requis. + +###### Listing 30 + +``` +HTTP/1.1 202 Accepted +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 30 -- Réponse synchrone à la requête de provision** + +
    + +#### Traitement du provisionnement par le Switch : Étape 2 + +Une fois la demande reçue ([Listing 29](#listing-29)) et la réponse envoyée ([Listing 30](#listing-30)), le Switch vérifie le corps de la demande. Par exemple, il s’assure que **fspId** correspond à **FSPIOP-Source**, que la devise est autorisée, etc. + +Après validation, l’information que le compte identifié par **MSISDN** et **123456789** est chez le FSP **MobileMoney** est enregistrée en base Switch. + +
    + +#### Switch envoie le callback de succès : Étape 3 + +Le Switch doit ensuite notifier le FSP **MobileMoney** du succès du provisioning, via [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id). [Listing 31](#listing-31) illustre cette requête HTTP. + +Voir [Tableau 1](#table-1) pour les en-têtes requis. Dans le callback, **Accept** ne doit pas être utilisé (appel de service précédent). Les headers **FSPIOP-Destination** et **FSPIOP-Source** sont inversés par rapport à la demande d’origine. + +###### Listing 31 + +``` +PUT /participants/MSISDN/123456789 HTTP/1.1 +Content-Length: 50 +Content-Type: +Date: Tue, 14 Nov 2017 08:12:32 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 31 -- Callback pour le provisioning demandé précédemment** + +[Listing 32](#listing-32) montre la réponse HTTP synchrone où le FSP **MobileMoney** accuse réception immédiate (après vérification des headers…) pour conclure le process après réception du callback. + +Voir [Tableau 3](#table-3) pour les en-têtes requis. + +###### Listing 32 + +``` +HTTP/1.1 200 OK +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 32 -- Réponse synchrone au callback** + +
    + +### Transfert P2P + +Comme le bénéficiaire visé, Henrik Karlsson, est désormais connu du Switch (qui fait aussi office d’ALS), comme détaillé dans la section [Provision Account Holder](#provision-account-holder), Mats Hagman peut maintenant initier et approuver le cas d'utilisation Transfert P2P de sa banque vers Henrik Karlsson. + +#### Initiation du cas d’utilisation : Étape 4 du flux de bout en bout + +Mats Hagman sait que Henrik Karlsson possède le numéro de téléphone **123456789**, il saisit donc ce numéro sur son appareil comme bénéficiaire et 100 USD comme montant. La communication réelle entre l’appareil de Mats et sa banque **BankNrOne** est hors du périmètre de cette API. + +
    + +#### Demande d'information sur la partie auprès du Switch : Étape 5 du flux de bout en bout + +À l’étape 5 du flux de bout en bout, **BankNrOne** reçoit la demande de Mats Hagman visant à transférer 100 USD au numéro de téléphone 123456789. **BankNrOne** effectue une recherche interne pour savoir si le compte 123456789 existe dans la banque, mais ne le trouve pas. **BankNrOne** utilise alors le service [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) du Switch pour voir si ce dernier a des informations sur le compte. + +[Exemple 33](#listing-33) illustre la requête HTTP où le PSP **BankNrOne** demande au Switch des informations sur la partie correspondant au compte identifié par **MSISDN** et **123456789**. + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête, ainsi que [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) pour plus d'informations sur ce service. **Plus** d’informations sur le routage des requêtes via **FSPIOP-Destination** et **FSPIOP-Source** sont disponibles dans [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Dans cette requête, le FSP **BankNrOne** ne connaît pas le FSP du bénéficiaire. Par conséquent, l’en-tête **FSPIOP-Destination** n’est pas présent. Les informations sur la négociation de version de l’API se trouvent dans [Négociation de version entre client et serveur](#version-negotiation-between-client-and-server). + +###### Exemple 33 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:37 GMT +FSPIOP-Source: BankNrOne +``` + +**Exemple 33 — Obtenir les informations d’une partie pour le compte identifié par MSISDN et 123456789 depuis BankNrOne** + +[Exemple 34](#listing-34) montre la réponse HTTP synchrone où le Switch accuse réception immédiatement (après vérification basique des en-têtes requis, par exemple) de la requête HTTP illustrée dans [Exemple 33](#listing-33). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse HTTP. + +###### Exemple 34 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Exemple 34 — Réponse synchrone à la demande d’information sur une partie** + +#### Demande d'information sur la partie auprès du FSP : Étape 6 du flux de bout en bout + +Quand le Switch a reçu la requête HTTP [Exemple 33](#listing-33) et envoyé la réponse synchrone [Exemple 34](#listing-34), il peut vérifier dans sa base de données s’il dispose d’informations sur le FSP auquel appartient le titulaire du compte identifié par **MSISDN** et **123456789**. Comme cette information a été provisionnée selon la section [Provision Account Holder](#provision-account-holder), le Switch sait que le compte est chez le FSP **MobileMoney**. Le Switch envoie donc la requête HTTP illustrée dans [Exemple 35](#listing-35). + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis, et [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) pour plus d’informations sur ce service. **Plus** d’informations sur le routage via **FSPIOP-Destination** et **FSPIOP-Source** se trouvent dans [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Dans cette requête, le Switch ajoute l’entête **FSPIOP-Destination** car il connaît le FSP destination. Les informations sur la négociation de version API sont dans [Négociation de version entre client et serveur](#version-negotiation-between-client-and-server). + + + +###### Exemple 35 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:38 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +``` + +**Exemple 35 — Demande d’information de partie pour le compte identifié par MSISDN et 123456789, envoyée par le Switch** + +[Exemple 36](#listing-36) montre la réponse HTTP synchrone dans laquelle le FSP **MobileMoney** accuse réception immédiatement (après vérification basique des en-têtes requis, par exemple) de la requête HTTP illustrée dans [Exemple 35](#listing-35). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse HTTP. + +###### Exemple 36 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Exemple 36 — Réponse synchrone à la demande d’information sur une partie** + +
    + +#### Recherche de l’information sur la partie dans le FSP MobileMoney : Étape 7 du flux de bout en bout + +Quand le FSP **MobileMoney** a reçu la requête HTTP [Exemple 35](#listing-35) et envoyé la réponse synchrone [Exemple 36](#listing-36), il peut chercher dans sa base de données des informations supplémentaires sur le compte identifié par **MSISDN** et **123456789**. Comme le compte existe et appartient à Henrik Karlsson, le FSP **MobileMoney** envoie le callback illustré dans [Exemple 37](#listing-37). **MobileMoney** ne souhaite pas partager certains détails, par exemple la date de naissance, avec l’autre FSP (**BankNrOne**), donc certains éléments facultatifs ne sont pas envoyés. + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête, +et [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id) pour plus d’informations sur le callback. **Dans** le callback, l’entête **Accept** ne doit pas être envoyé. Les en-têtes HTTP **FSPIOP-Destination** et **FSPIOP-Source** sont inversés par rapport à la requête HTTP [Exemple 35](#listing-35), comme expliqué dans [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Exemple 37 + +```` +PUT /parties/MSISDN/123456789 HTTP/1.1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Content-Length: 347 +Date: Tue, 15 Nov 2017 10:13:39 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + } +} +```` + +**Exemple 37 — Callback en réponse à la demande d’information sur la partie** + +[Exemple 38](#listing-38) présente la réponse HTTP synchrone du Switch qui confirme immédiatement (après vérification des en-têtes requis, par exemple) la fin du processus, après réception du callback [Exemple 37](#listing-37). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis en réponse. + +###### Exemple 38 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Exemple 38 — Réponse synchrone au callback d’information sur une partie** + +
    + +#### Relais du callback au FSP BankNrOne : Étape 8 du flux de bout en bout + +Quand le Switch a reçu le callback [Exemple 37](#listing-37) et envoyé la réponse synchrone [Exemple 38](#listing-38), il doit relayer exactement le même callback que dans [Exemple 37](#listing-37) au FSP **BankNrOne**, qui doit alors répondre de façon synchrone avec la même réponse que dans [Exemple 38](#listing-38). + +La requête et la réponse HTTP ne sont pas répétées ici, car identiques à la dernière section, mais envoyées cette fois du Switch vers **BankNrOne** (requête HTTP [Exemple 37](#listing-37)) et de **BankNrOne** vers le Switch (réponse HTTP [Exemple 38](#listing-38)). + +
    + +#### Envoi d’une demande de devis par le FSP BankNrOne : Étape 9 du flux de bout en bout + +Après avoir reçu les informations de partie via le callback [PUT /parties/_{Type}_/_{ID}_](#put-parties-type-id), le FSP **BankNrOne** sait désormais que le compte identifié par **MSISDN** et **123456789** existe et qu’il est chez le FSP **MobileMoney**. Il connaît aussi le nom du titulaire. Selon l’implémentation, le nom du bénéficiaire visé (Henrik Karlsson) pourrait être affiché à Mats Hagman dès cette étape, avant l’envoi du devis. Dans cet exemple, une demande de devis est envoyée avant d’afficher le nom ou d’éventuels frais. + +Le FSP **BankNrOne** envoie la requête HTTP présentée dans [Exemple 39](#listing-39) pour demander un devis. **BankNrOne** ne souhaite pas divulguer ses frais (voir [Quoting](#quoting) pour plus d’infos), il n’inclut donc pas l’élément **fees** dans la demande. L’élément **amountType** est positionné sur RECEIVE car Mats veut qu’Henrik reçoive 100 USD. Le **transactionType** est défini selon la [Correspondance des cas d’usage avec les types de transaction](#mapping-of-use-cases-to-transaction-types). Les infos sur Mats sont envoyées dans l’élément **payer**. **BankNrOne** a aussi généré deux UUID pour l’ID du devis (7c23e80c-d078-4077-8263-2c047876fcf6) et l’ID de la transaction (85feac2f-39b2-491b-817e-4a03203d4f14). Ces identifiants doivent être uniques, voir [Style architectural](#architectural-style). + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête, et [Section 6.5.3.2](#6532-post-quotes) concernant le service [POST /quotes](#6532-post-quotes). **Plus** d’informations sur le routage via **FSPIOP-Destination** et **FSPIOP-Source** se trouvent dans [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Des informations sur la négociation de version API se trouvent dans [Négociation de version entre client et serveur](#version-negotiation-between-client-and-server). + +###### Exemple 39 + +```` +POST /quotes HTTP/1.1 +Accept: application/vnd.interoperability.quotes+json;version=1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 975 +Date: Tue, 15 Nov 2017 10:13:40 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amountType": "RECEIVE", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats", + "expiration": "2017-11-15T22:17:28.985-01:00" +} +```` + +**Exemple 39 — Demande de devis pour une transaction de 100 USD** + +[Exemple 40](#listing-40) montre la réponse HTTP synchrone dans laquelle le Switch accuse réception immédiatement (après vérification des en-têtes, par exemple) de la requête HTTP illustrée dans [Exemple 39](#listing-39). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse. + +###### Exemple 40 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Exemple 40 — Réponse synchrone à la demande de devis** + +#### Transmission de la demande de devis par le Switch : Étape 10 du flux de bout en bout + +Après réception de la demande de devis, [Exemple 39](#listing-39), et l’envoi de la réponse synchrone [Exemple 40](#listing-40), le Switch doit relayer la même demande que dans [Exemple 39](#listing-39) au FSP **MobileMoney**, lequel doit alors répondre de manière synchrone avec la même réponse que dans [Exemple 40](#listing-40). + +La requête et la réponse HTTP ne sont pas répétées ici, car identiques à la dernière section, mais cette fois du Switch vers **MobileMoney** (requête HTTP [Exemple 39](#listing-39)) puis de **MobileMoney** vers le Switch (réponse HTTP [Exemple 40](#listing-40)). + +
    + +#### Détermination des frais et de la commission FSP dans MobileMoney : Étape 11 du flux de bout en bout + +Quand le FSP **MobileMoney** a reçu la requête HTTP [Exemple 39](#listing-40) et envoyé la réponse synchrone [Exemple 40](#listing-40), il doit valider la requête puis calculer les frais applicables et/ou la commission FSP pour effectuer la transaction demandée via le devis. + +Dans cet exemple, le FSP **MobileMoney** décide de prendre 1 USD de commission car il va recevoir de l’argent, ce qui peut engendrer de futurs revenus (frais ultérieurs). Comme le bénéficiaire (Henrik Karlsson) doit recevoir 100 USD et que la commission FSP est de 1 USD, le FSP **BankNrOne** n’aura à transférer que 99 USD au FSP **MobileMoney** (voir [Non Disclosing Receive Amount](#non-disclosing-receive-amount) pour l’équation). Les 99 USD sont renseignés dans l’élément transferAmount du callback, c’est donc le montant à transférer plus tard entre FSPs. + +Pour envoyer le callback, le FSP **MobileMoney** doit alors créer un paquet ILP (voir [ILP Packet](#ilp-packet) pour plus d’infos) encodé en base64url, car l'élément **ilpPacket** du callback [PUT /quotes/_{ID}_](#put-quotes-id) est défini comme [BinaryString](#binarystring). La manière de remplir ce paquet ILP est expliquée dans [Interledger Payment Request](#interledger-payment-request). L’adresse ILP d’Henrik dans le FSP **MobileMoney** est fixée à **g.se.mobilemoney.msisdn.123456789** (voir [ILP Addressing](#ilp-addressing)). Comme le montant du transfert est de 99 USD et que l’exposant du devise USD est 2, le montant renseigné dans le paquet ILP est 9900 (99 \* 10^2 = 9900). L’autre élément du paquet ILP est **data**. Comme expliqué dans [Interledger Payment Request](#interledger-payment-request), cet élément doit contenir le modèle de données Transaction (voir [Transaction](#transaction)). Avec les informations de la demande de devis, la Transaction dans cet exemple est illustrée dans [Exemple 41](#listing-41). Après encodage base64url du paquet ILP complet avec **amount**, **account** et le **data**, cela donne l’élément **ilpPacket** du callback [PUT /quotes/_{ID}_](#put-quotes-id). + +Une fois le paquet ILP créé, la réalisation (fulfilment) et la condition sont générées selon l’algorithme défini dans [Exemple 12](#listing-12). En utilisant un secret d’exemple généré (voir [Exemple 42](#listing-42)), la réalisation devient celle de [Exemple 43](#listing-43) après execution de HMAC SHA-256 sur le paquet ILP avec ce secret comme clé (le tout en base64url). Le FSP **MobileMoney** doit stocker la réalisation en base de données pour ne pas avoir à la régénérer plus tard. La condition correspond au hash SHA-256 de la réalisation (voir [Exemple 44](#listing-44), base64url). + +Le callback complet envoyé en réponse à la demande de devis est présenté dans [Exemple 45](#listing-45). + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête, et [PUT /quotes/_{ID}_](#put-quotes-id) pour plus d’infos sur le callback. **L’ID** dans l’URI doit être celui spécifié comme quote ID dans la demande de devis, ici 7c23e80c-d078-4077-8263-2c047876fcf6. Dans le callback, l’entête **Accept** ne doit pas être envoyé. Les en-têtes HTTP **FSPIOP-Destination** et **FSPIOP-Source** sont inversés par rapport à la demande [Exemple 39](#listing-39), conformément à [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 41 + +``` +{ + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amount": { + "amount": "99", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats" +} +``` + +**Liste 41 -- Objet JSON Transaction** + +###### Listing 42 + +``` +JdtBrN2tskq9fuFr6Kg6kdy8RANoZv6BqR9nSk3rUbY +``` + +**Liste 42 -- Secret généré, encodé en base64url** + +###### Listing 43 + +``` +mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s +``` + +**Liste 43 -- Fulfilment calculé à partir du paquet ILP et du secret, encodé en base64url** + +###### Listing 44 + +``` +fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG\_fqGnR7Xs +``` + +**Liste 44 -- Condition calculée à partir du fulfilment, encodée en base64url** + +###### Listing 45 + +``` +PUT /quotes/7c23e80c-d078-4077-8263-2c047876fcf6 HTTP/1.1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 1802 +Date: Tue, 15 Nov 2017 10:13:41 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "transferAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2017-11-15T14:17:09.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", + "condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Liste 45 -- Callback du devis** + +**Remarque :** L’élément **ilpPacket** dans la [Liste 45](#listing-45) devrait être sur une seule ligne dans une vraie implémentation ; il est affiché ici avec des sauts de ligne pour montrer toute la valeur. + +[La Liste 46](#listing-46) montre la réponse HTTP synchrone où le Switch accuse immédiatement réception (après vérification basique des en-têtes requis, par exemple) du callback de la [Liste 45](#listing-45). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse HTTP. + +###### Listing 46 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Liste 46 -- Réponse synchrone au callback de devis** + +#### Transmission du callback au FSP BankNrOne : Étape 12 du flux de bout en bout + +Lorsque le Switch a reçu le callback de devis dans la [Liste 45](#listing-45) et a envoyé la réponse synchrone dans la [Liste 46](#listing-46), il doit relayer exactement le même callback que dans la [Liste 45](#listing-45) au FSP **BankNrOne**. Le FSP **BankNrOne** doit alors répondre de manière synchrone avec la même réponse que dans la [Liste 46](#listing-46). + +La requête et la réponse HTTP ne sont pas répétées ici, car elles sont identiques à la section précédente, mais cette fois-ci envoyées du Switch vers **BankNrOne** (requête HTTP de la [Liste 45](#listing-45)) puis de **BankNrOne** vers le Switch (réponse HTTP de la [Liste 46](#listing-46)). + +
    + +#### Détermination des frais dans le FSP BankNrOne : Étape 13 du flux de bout en bout + +Lorsque le FSP **BankNrOne** a reçu le callback du devis dans la [Liste 45](#listing-45) et qu’il a envoyé la réponse synchrone de la [Liste 46](#listing-46), il peut alors déterminer les frais pour le payeur Mats Hagman. Dans cet exemple, les frais pour le payeur sont fixés à 0 USD, mais la commission du FSP reçue du FSP **MobileMoney** reste un revenu pour le FSP **BankNrOne**. Cela signifie que pour que le bénéficiaire Henrik Karlsson reçoive 100 USD, le payeur Mats Hagman doit transférer 100 USD de son compte. 99 USD seront alors transférés entre les FSPs **BankNrOne** et **MobileMoney**. + +Le FSP **BankNrOne** notifie alors Mats Hagman que la transaction de transfert de 100 USD à Henrik Karlsson coûtera 0 USD de frais. La façon dont Mats Hagman est notifié est hors du champ de cette API. + +
    + +#### Acceptation de la transaction par le payeur : Étape 14 du flux de bout en bout + +Dans cet exemple, Mats Hagman accepte d’effectuer la transaction. La manière dont l’acceptation est envoyée est hors du périmètre de cette API. + +#### Envoi de la demande de transfert depuis FSP BankNrOne : Étape 15 du flux de bout en bout + +Une fois que Mats Hagman a accepté la transaction, le FSP **BankNrOne** réserve les mouvements internes nécessaires pour effectuer la transaction. Cela signifie que 100 USD seront réservés du compte de Mats Hagman, où 1 USD sera un revenu pour le FSP et 99 USD seront transférés au compte Switch préfinancé. Après le succès des réservations, le FSP **BankNrOne** envoie un [POST /transfers](#post-transfers) au Switch comme dans la [Liste 47](#listing-47). Les mêmes éléments **ilpPacket** et **condition** sont envoyés comme reçus dans le callback de devis et le champ **amount** correspond au **transferAmount** reçu, voir [Liste 45](#listing-45). + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête et [Post Transfers](#post-transfers) pour plus d’informations sur le service [POST /transfers](#post-transfers). Davantage d'informations concernant le routage des requêtes via **FSPIOP-Destination** et **FSPIOP-Source** peuvent être trouvées dans [Routage des flux d'appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). L’information sur la négociation de version API se trouve dans [Négociation de version entre client et serveur](#version-negotiation-between-client-and-server). + +###### Listing 47 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:17:01.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Liste 47 -- Requête de transfert de BankNrOne à MobileMoney** + +**Remarque :** L’élément **ilpPacket** dans la [Liste 47](#listing-47) devrait être sur une seule ligne dans une vraie implémentation ; il est affiché ici avec des sauts de ligne pour montrer toute la valeur. + +[La Liste 48](#listing-48) montre la réponse HTTP synchrone où le Switch accuse réception immédiatement (après une vérification élémentaire des en-têtes requis par exemple) de la requête HTTP dans la [Liste 47](#listing-47). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse. + +###### Listing 48 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Liste 48 -- Réponse synchrone à la demande de transfert** + +
    + +#### Envoi de la demande de transfert depuis le Switch : Étape 16 du flux de bout en bout + +Lorsque le Switch a reçu la demande de transfert dans la [Liste 47](#listing-47) et envoyé la réponse synchrone dans la [Liste 48](#listing-48), il doit réserver le transfert du compte de **BankNrOne** vers le compte de **MobileMoney** au sein du Switch. Après succès de la réservation, le Switch relaie quasiment la même requête que dans la [Liste 47](#listing-47) au FSP **MobileMoney**, à l’exception de l’élément **expiration** qui doit être réduit, comme expliqué dans [Timeout and Expiry](#timeout-and-expiry). La [Liste 49](#listing-49) montre la requête HTTP avec l’**expiration** réduite de 30 secondes par rapport à la [Liste 47](#listing-47). Le FSP **MobileMoney** doit alors répondre de façon synchrone avec la même réponse qu’en [Liste 48](#listing-48). + +###### Listing 49 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:16:31.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny08MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJlayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Liste 49 -- Requête de transfert de BankNrOne à MobileMoney avec expiration réduite** + +**Remarque :** L’élément **ilpPacket** dans la [Liste 49](#listing-49) devrait être sur une seule ligne dans une vraie implémentation ; il est affiché ici avec des sauts de ligne pour montrer toute la valeur. + +
    + +#### Réalisation du transfert dans FSP MobileMoney : Étape 17 du flux de bout en bout + +Lorsque le FSP **MobileMoney** a reçu la requête de transfert dans la [Liste 47](#listing-47), il doit effectuer le transfert comme décrit dans la précédente demande de devis, ce qui signifie que 100 USD doivent être transférés sur le compte de Henrik Karlsson, dont 99 USD depuis le compte Switch préfinancé et 1 USD depuis un compte commission FSP. + +Comme preuve de réalisation de la transaction, le FSP **MobileMoney** récupère alors le fulfilment stocké [(Liste 43](#listing-43)) depuis la base de données (enregistré lors de la [Détermination des frais et de la commission FSP dans MobileMoney](#determine-fees-and-fsp-commission-in-fsp-mobilemoney-step-11-in-end-to-end-flow)) et le place dans l’élément **fulfilment** du callback [PUT /transfers/_{ID}_](#put-transfersid). Le champ **transferState** est positionné à COMMITTED et **completedTimestamp** à la date de réalisation de la transaction ; voir [Liste 50](#listing-50) pour la requête complète. + +En même temps, une notification est envoyée au bénéficiaire Henrik Karlsson pour l’informer qu’il a reçu 100 USD de Mats Hagman. + +La manière dont est envoyée la notification est hors du périmètre de cette API. + +Voir [Tableau 1](#table-1) pour les en-têtes HTTP requis dans une requête, et [PUT /transfers/_{ID}_](#put-transfersid) pour plus d’infos sur le callback. **L’ID** dans l’URI doit être celui présent dans la demande de transfert, qui est dans l’exemple 11436b17-c690-4a30-8505-42a2c4eafb9d. Dans le callback, l’en-tête **Accept** ne doit pas être envoyé. Les en-têtes HTTP **FSPIOP-Destination** et **FSPIOP-Source** sont maintenant inversés par rapport à la requête HTTP en [Liste 47](#listing-47), comme détaillé dans [Routage des flux d’appels avec FSPIOP Destination et FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 50 + +``` +PUT /transfers/11436b17-c690-4a30-8505-42a2c4eafb9d HTTP/1.1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 166 +Date: Tue, 15 Nov 2017 10:14:02 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "completedTimestamp": "2017-11-16T04:15:35.513+01:00", + "transferState": "COMMITTED" +} +``` + +**Liste 50 -- Callback pour la demande de transfert** + +[La Liste 51](#listing-51) montre la réponse HTTP synchrone dans laquelle le Switch accuse immédiatement réception (après vérification basique des en-têtes requis par exemple) après avoir reçu le callback de la [Liste 50](#listing-50). + +Voir [Tableau 3](#table-3) pour les en-têtes HTTP requis dans une réponse HTTP. + +###### Listing 51 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Liste 51 -- Réponse synchrone au callback de transfert** + +
    + +#### Réception de la notification de transaction par le bénéficiaire : Étape 18 du flux de bout en bout + +Le bénéficiaire Henrik Karlsson reçoit la notification de transaction et est ainsi informé du succès de la transaction. + +
    + +#### Réalisation du transfert dans le Switch : Étape 19 du flux de bout en bout + +Lorsque le Switch a reçu le callback de la [Liste 50](#listing-50) et envoyé la réponse synchrone de la [Liste 51](#listing-51), il doit valider le fulfilment, effectuer le transfert réservé antérieurement et relayer exactement le même callback que dans la [Liste 50](#listing-50) au FSP **BankNrOne**. **BankNrOne** doit alors répondre de façon synchrone avec la même réponse que dans la [Liste 51](#listing-51). + +La validation du fulfilment se fait en calculant le hash SHA-256 du fulfilment et en s’assurant que le hash est égal à la condition reçue lors de la demande de transfert. + +La requête et la réponse HTTP ne sont pas répétées ici car elles sont identiques à la section précédente, mais cette fois envoyées du Switch vers **BankNrOne** (requête HTTP de la [Liste 50](#listing-51)) puis de **BankNrOne** vers le Switch (réponse HTTP de la [Liste 51](#listing-51)). + +
    + +#### Réalisation du transfert dans FSP BankNrOne : Étape 20 du flux de bout en bout + +Quand le FSP **BankNrOne** a reçu le callback de la [Liste 50](#listing-50) et envoyé la réponse synchrone de la [Liste 51](#listing-51), il doit valider le fulfilment (voir [Section 10.4.16](#10416-perform-transfer-in-switch----step-19-in-end-to-end-flow)), puis effectuer le transfert réservé précédemment. + +Une fois le transfert réservé effectué, le payeur Mats Hagman doit être notifié du succès de la transaction. La façon dont la notification est envoyée est hors du champ de cette API. + +#### Réception de la notification de transaction par le payeur : Étape 21 du flux de bout en bout + +Le payeur Mats Hagman reçoit la notification de transaction et est ainsi informé du succès de la transaction. + + + + + +1 [http://www.ics.uci.edu/\~fielding/pubs/dissertation/rest\_arch\_style.htm](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) -- Transfert de Représentation d’État (REST) + +2 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- Espace de noms UUID (Identifiant Unique Universel) + +3 [https://tools.ietf.org/html/rfc7230](https://tools.ietf.org/html/rfc7230) -- Hypertext Transfer Protocol (HTTP/1.1): Syntaxe des messages et routage + +4 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) -- Le protocole TLS (Transport Layer Security) – Version 1.2 + +5 [https://tools.ietf.org/html/rfc3986](https://tools.ietf.org/html/rfc3986) -- Uniform Resource Identifier (URI) : Syntaxe générique + +6 [https://tools.ietf.org/html/rfc7230\#section-2.7.3](https://tools.ietf.org/html/rfc7230#section-2.7.3) -- HTTP/1.1 : Normalisation et comparaison des URI http et https + +7 [https://tools.ietf.org/html/rfc3629](https://tools.ietf.org/html/rfc3629) -- UTF-8, un format de transformation d’ISO 10646 + +8 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) -- Format d’échange de données JSON + +9 [https://tools.ietf.org/html/rfc7230\#section-3.2](https://tools.ietf.org/html/rfc7230#section-3.2) -- HTTP/1.1 : Champs d’en-tête + +10 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- HTTP/1.1 : Accept + +11 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- HTTP/1.1 : Content-Length + +12 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- HTTP/1.1 : Content-Type + +13 [https://tools.ietf.org/html/rfc7231\#section-7.1.1.2](https://tools.ietf.org/html/rfc7231#section-7.1.1.2) -- HTTP/1.1 : Date + +14 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) -- X-Forwarded-For + +15 [https://tools.ietf.org/html/rfc7239](https://tools.ietf.org/html/rfc7239) -- Extension HTTP Forwarded + +16 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- HTTP/1.1 : Content-Length + +17 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- HTTP/1.1 : Content-Type + +18 [https://tools.ietf.org/html/rfc7231\#section-4](https://tools.ietf.org/html/rfc7231#section-4) -- HTTP/1.1 : Méthodes de requête + +19 [https://tools.ietf.org/html/rfc7231\#section-6](https://tools.ietf.org/html/rfc7231#section-6) -- HTTP/1.1 : Codes d’état de réponse + +20 [https://tools.ietf.org/html/rfc7231\#section-6.4](https://tools.ietf.org/html/rfc7231#section-6.4) -- HTTP/1.1 : Redirection 3xx + +21 [https://tools.ietf.org/html/rfc7231\#section-6.6](https://tools.ietf.org/html/rfc7231#section-6.6) -- HTTP/1.1 : Erreur serveur 5xx + +22 [https://tools.ietf.org/html/rfc7231\#section-6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6) -- HTTP/1.1 : 406 Non Acceptable + +23 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- HTTP/1.1 : Accept + +24 [https://interledger.org/rfcs/0011-interledger-payment-request/](https://interledger.org/rfcs/0011-interledger-payment-request/) -- Demande de paiement Interledger (IPR) + +25 [https://interledger.org/](https://interledger.org/) -- Interledger + +26 [https://interledger.org/interledger.pdf](https://interledger.org/interledger.pdf) -- Un protocole pour les paiements Interledger + +27 [https://interledger.org/rfcs/0001-interledger-architecture/](https://interledger.org/rfcs/0001-interledger-architecture/) -- Architecture Interledger + +28 [https://interledger.org/rfcs/0015-ilp-addresses/](https://interledger.org/rfcs/0015-ilp-addresses/) -- Adresses ILP + +29 [https://www.itu.int/rec/dologin\_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items) -- Règles d’encodage ASN.1 : Spécification des Octet Encoding Rules (OER) + +30 [https://perldoc.perl.org/perlre.html\#Regular-Expressions](https://perldoc.perl.org/perlre.html#Regular-Expressions) -- perlre - Expressions régulières Perl + +31 [https://tools.ietf.org/html/rfc7159\#section-7](https://tools.ietf.org/html/rfc7159#section-7) -- JSON : Chaînes + +32 [http://www.unicode.org/](http://www.unicode.org/) -- Le consortium Unicode + +33 [https://www.iso.org/iso-8601-date-and-time-format.html](https://www.iso.org/iso-8601-date-and-time-format.html) -- Format de date et d’heure - ISO 8601 + +34 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- Espace de noms UUID (Identifiant Unique Universel) + +35 [https://tools.ietf.org/html/rfc4648\#section-5](https://tools.ietf.org/html/rfc4648#section-5) -- Encodages Base16, Base32 et Base64 - Base64 compatible URL et nom de fichier + +36 [https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html) -- Codes de devises - ISO 4217 + +37 [https://www.itu.int/rec/T-REC-E.164/en](https://www.itu.int/rec/T-REC-E.164/en) -- E.164 : Plan international de numérotation téléphonique publique + +38 [https://tools.ietf.org/html/rfc3696](https://tools.ietf.org/html/rfc3696) -- Techniques d’application pour la vérification et la transformation des noms + +39 [https://tools.ietf.org/html/rfc7231\#section-6.5](https://tools.ietf.org/html/rfc7231#section-6.5) -- HTTP/1.1 : Erreur client 4xx \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/v1.1/encryption.md b/docs/fr/technical/api/fspiop/v1.1/encryption.md new file mode 100644 index 000000000..b3d288f79 --- /dev/null +++ b/docs/fr/technical/api/fspiop/v1.1/encryption.md @@ -0,0 +1,308 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Bill & Melinda Gates Foundation +--- +# Chiffrement + +## Préface + +Cette section contient des informations sur la façon d'utiliser ce document. + +### Conventions Utilisées dans ce Document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types spécifiés d'information : + +| **Type d'Information** | **Convention** | **Exemple** | +| :--- | :--- | :--- | +| **Éléments de l'API, tels que ressources** | Gras | **/authorization** | +| **Variables** | Italique entre accolades | _{ID}_ | +| **Termes du glossaire** | Italique à la première occurrence ; défini dans le _Glossaire_ | Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité fournissant un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP. | +| **Documents de référence** | Italique | Les informations utilisateur ne devraient, en général, pas être utilisées par les déploiements de l’API ; les mesures de sécurité détaillées dans _Signature de l'API_ et _Chiffrement de l'API_ devraient être utilisées à la place. | + +### Informations sur les versions du document + +| **Version** | **Date** | **Description des modifications** | +| :--- | :--- | :--- | +|**1.1**|2020-05-19|Cette version contient les modifications suivantes : 1. Les éléments ExtensionList de la Section 4 ont été mis à jour sur la base du problème [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), afin de corriger le modèle de données de l'objet extensionList.| +| **1.0** | 2018-03-13 | Version initiale | + +
    + +## Introduction + +Ce document détaille les méthodes de sécurité à mettre en œuvre pour l'Open API (Interface de Programmation Applicative) pour l'interopérabilité des FSP (Fournisseurs de Services Financiers) (ci-après citée « l’API ») afin de garantir la confidentialité des messages API entre un client API et le serveur API. + +En sécurité de l'information, la _confidentialité_ signifie que l'information n'est pas rendue disponible ou divulguée à des personnes, entités ou processus non autorisés (extrait de l’ISO27000[The ISO 27000 Directory](http://www.27000.org)). Pour l’API, la confidentialité signifie que certains champs sensibles du contenu d’un message API ne peuvent être consultés ou identifiés de manière non autorisée ou non détectée par les intermédiaires impliqués dans la communication API. Autrement dit, si certains champs d’un message API sont chiffrés par le client API, alors seul le destinataire prévu de l’API peut déchiffrer ces champs. + +Le chiffrement JSON Web Encryption (JWE, défini dans la RFC 7516[JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516)) doit être appliqué à l'API pour assurer la confidentialité de bout en bout des messages. Lorsqu'un client API envoie une requête HTTP (telle qu'une requête API ou un message de rappel) à un contrepartie, le client API peut déterminer s'il existe des champs sensibles dans le message API à protéger selon la réglementation ou le système local. S'il y a un champ à protéger, le client API utilise JWE pour chiffrer la valeur de ce champ. Par la suite, le texte chiffré de ce champ sera transmis à la contrepartie. + +Pour prendre en charge le chiffrement de plusieurs champs d’un message API, le JWE est étendu dans ce document pour s’adapter aux exigences de l’API. + +
    + +### Spécification Open API pour l'interopérabilité FSP + +La Spécification Open API pour l’Interopérabilité FSP comprend les documents suivants. + +#### Documents logiques + +- [Modèle de Données Logique](./logical-data-model) + +- [Modèles de Transactions Génériques](./generic-transaction-patterns) + +- [Cas d'Utilisation](./use-cases) + +#### Documents de liaison REST asynchrones + +- [Définition de l'API](./api-definition) + +- [Règles de Liaison JSON](../json-binding-rules) + +- [Règles du système](./scheme-rules) + +#### Intégrité des données, Confidentialité et Non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Chiffrement](#) + +#### Documents généraux + +- [Glossaire](./glossary) + +
    + +## Définition du chiffrement de l'API + +Cette section présente la technologie utilisée par le chiffrement de l'API, notamment : + +- Le format d'échange de données pour les champs chiffrés d’un message API. +- Le mécanisme de chiffrement et de déchiffrement des champs. + +### Modèle de données pour le chiffrement + +L’API utilise l’en-tête HTTP personnalisé **FSPIOP-Encryption** pour représenter les champs chiffrés d’un message API ; sa valeur est une sérialisation d’objet JSON. Le modèle de données de ce paramètre est décrit dans la [Table 1](#table-1), [Table 2](#table-2) et [Table 3](#table-3). + +**Note** : Si **FSPIOP-Encryption** est présent dans un message API, il doit également être protégé par la signature de l’API. Cela signifie que **FSPIOP-Encryption** doit être inclus dans le JWS Protected Header de la signature. + +###### Tableau 1 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedFields** | 1 | EncryptedFields | Informations sur les champs chiffrés d’un message API | +**Tableau 1 -- Modèle de données du champ d’en-tête HTTP FSPIOP-Encryption** + +###### Tableau 2 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedField** | 1..* | EncryptedField | Informations sur un champ chiffré d’un message API | +**Tableau 2 -- Modèle de données du type complexe EncryptedFields** + +###### Tableau 3 + +| **Nom** | **Cardinalité** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +|**fieldName** | 1 | String(1..512) | Cet élément identifie le champ à chiffrer dans le contenu d’un message API.
    Comme la charge utile (payload) de l’API est une chaîne de sérialisation d’objet JSON, le nom du champ doit permettre d’identifier le chemin exact de l’élément dans l’objet JSON. Un point (‘**.**’) est utilisé pour séparer les éléments dans un chemin d’élément. Par exemple, **payer.personalInfo.dateOfBirth** est une valeur valide pour cet élément pour la requête API **POST /quotes**.
    | +| **encryptedKey** | 1 | String(1..512) | Valeur de la clé de chiffrement de contenu chiffrée (CEK). Sa valeur est encodée en BASE64URL (Clé Chiffrée JWE).
    S'il y a plusieurs champs à chiffrer dans le message API, il est recommandé d'utiliser la même clé chiffrée JWE pour simplifier la mise en œuvre ; cependant, c'est une décision propre à chaque FSP selon leur implémentation.
    | +|**protectedHeader** | 1 | String(1..1024) | Cet élément identifie les paramètres d’en-tête appliqués à JWE pour chiffrer le champ spécifié. Sa valeur est encodée en BASE64URL(UTF8(JWE Protected Header)).
    Par exemple, si le JWE Protected Header appliqué au chiffrement est ```{"alg":"RSA-OAEP-256","enc":"A256GCM"}```, alors la valeur est ```eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ```.
    | +| **initializationVector** | 1 | String(1..128) | Valeur du vecteur d'initialisation utilisé lors du chiffrement du texte clair. Sa valeur est encodée en BASE64URL (vecteur d'initialisation JWE). | +| **authenticationTag** | 1 | String(1..128) | Valeur de l’étiquette d’authentification résultant du chiffrement authentifié du texte en clair avec des Données Authentifiées Additionnelles. Sa valeur est encodée en BASE64URL (Tag d’authentification JWE) | +**Tableau 3 -- Modèle de données du type complexe EncryptedField** + +### Chiffrement des champs d’un message API + +Cette section décrit le processus de chiffrement des champs de message. L’ordre des étapes n'est pas significatif dans les cas où il n'y a pas de dépendances entre les entrées et sorties des étapes. + +1. Déterminer l'algorithme utilisé pour déterminer la valeur de la CEK (c'est l'algorithme enregistré dans le paramètre d'en-tête **alg** du JWE résultant). Parce que la CEK doit être chiffrée avec la clé publique du destinataire de l’API, l’algorithme disponible pour protéger la CEK dans l’API ne peut être que **RSA-OAEP-256**. +2. S'il y a plusieurs champs à chiffrer dans le message API, exécuter les étapes 3-15 pour chaque champ. +3. Générer une CEK aléatoire. Le FSP peut générer la valeur en utilisant sa propre application ou l’implémentation JWE employée. +4. Chiffrer la CEK avec l’algorithme déterminé par le paramètre d’en-tête JWE **alg**. +5. Calculer la valeur encodée en BASE64URL(JWE Encrypted Key). +6. Générer un vecteur d'initialisation JWE aléatoire de la taille correcte pour l’algorithme de chiffrement de contenu (si requis par l’algorithme) ; sinon, que le vecteur soit une séquence d’octets vide. +7. Calculer la valeur encodée du vecteur d'initialisation BASE64URL(JWE Initialization Vector). +8. Si un paramètre **zip** a été inclus, compresser le texte clair en utilisant l’algorithme de compression spécifié et que *M* soit la séquence d’octets représentant le texte clair compressé ; sinon, que _M_ soit la séquence d’octets représentant le texte clair. +9. Créer l'objet JSON ou les objets contenant le jeu désiré de paramètres d’en-tête, qui constituent ensemble le JWE Protected Header. Outre le paramètre **alg**, le paramètre **enc** doit être inclus dans le protected header JWE. Les valeurs disponibles pour le paramètre **enc** dans l’API ne peuvent être que : **A128GC**_M_, **A192GC**_M_, **A256GC**_M_. **A256GC**_M_ est recommandé. +10. Calculer la valeur encodée du protected header BASE64URL(UTF8(JWE Protected Header)). +11. Prendre pour paramètre de Données Authentifiées Additionnelles la valeur ASCII(Encoded Protected Header). +12. Chiffrer *M* en utilisant la CEK, le vecteur d'initialisation JWE et la Donnée Authentifiée Additionnelle selon l’algorithme de chiffrement de contenu spécifié pour créer la valeur du texte chiffré JWE et le Tag d’authentification JWE (qui est la sortie du chiffrement). +13. Calculer la valeur chiffrée encodée en BASE64URL (JWE Cipher Text). +14. Calculer la valeur du tag d’authentification encodée en BASE64URL (JWE Authentication Tag). +15. Calculer l'élément **encryptedField** (voir la Table 3) pour le paramètre d'en-tête HTTP **FSPIOP-Encryption**. +16. Calculer la valeur du paramètre d’en-tête HTTP **FSPIOP-Encryption** comme décrit dans la documentation [FSPIOP API](/fspiop). La valeur de ce **FSPIOP-Encryption** est une chaîne de sérialisation d’objet JSON. + +**Note** : Si JWE est utilisé pour chiffrer certains champs de la charge utile, alors le client API doit : + +1. Chiffrer les champs désirés. + +2. Remplacer la valeur de ces champs par le texte chiffré encodé dans la charge utile. + +3. Signer la charge utile. + +### Déchiffrement des champs d’un message API + +Si le paramètre d’en-tête HTTP **FSPIOP-Encryption** (qui est aussi protégé par la signature de l’API) est présent, alors le destinataire du message API doit déchiffrer les champs chiffrés du message API après que la signature de l’API ait été validée avec succès. Le processus de déchiffrement est l’inverse du chiffrement. L’ordre des étapes n’est pas significatif dans les cas où il n’y a pas de dépendance entre les entrées et sorties des étapes. S’il y a plusieurs champs chiffrés, alors tous les champs doivent être déchiffrés avec succès ; sinon cela indique que le message API est invalide. + +1. Analyser le paramètre d’en-tête HTTP **FSPIOP-Encryption** pour obtenir les informations sur les champs chiffrés, y compris le nom du champ, le protected header JWE, la clé chiffrée JWE, le vecteur d’initialisation JWE et le tag d’authentification JWE pour chaque champ. S’il y a plusieurs champs à déchiffrer, exécuter les étapes 2-9 pour chaque champ. +2. Obtenir le texte chiffré du champ chiffré en analysant la charge utile avec le chemin de champ spécifié. La valeur du champ spécifié est déjà encodée en BASE64URL. +3. Vérifier que la séquence d'octets résultant du décodage du protected header JWE encodé est une représentation UTF-8 valide d'un objet JSON conforme au format d’échange JSON (cf. RFC 7159[The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)) ; le protected header JWE doit être cet objet JSON. +4. Vérifier que les paramètres dans le protected header JWE comprennent et peuvent traiter tous les champs requis pour prendre en charge la spécification JWE ; par exemple, l’algorithme utilisé. +5. Déterminer si l’algorithme spécifié par le paramètre **alg** du header correspond à l’algorithme de la clé publique / privée du destinataire de l’API. +6. Déchiffrer la clé chiffrée JWE avec la clé privée du destinataire API pour obtenir la CEK JWE. +7. Prendre pour paramètre de Données Authentifiées Additionnelles la valeur ASCII (Encoded Protected Header). +8. Déchiffrer le texte chiffré JWE en utilisant la CEK, le vecteur d'initialisation JWE, la Donnée Authentifiée Additionnelle et le Tag d’authentification JWE avec l’algorithme de chiffrement spécifié, pour retourner le texte déchiffré tout en validant le tag d’authentification conformément à l’algorithme. Si le tag d’authentification JWE est incorrect, rejeter l’entrée sans procéder au déchiffrement. +9. Si un paramètre **zip** a été inclus, le destinataire de l’API doit décompresser le texte déchiffré en utilisant l'algorithme de compression spécifié. + +## Exemples de chiffrement/déchiffrement d’API + +Cette section utilise un processus typique de devis pour expliquer comment le chiffrement et le déchiffrement de l’API sont réalisés avec JWE. Puisque l’algorithme de clé publique / privée du destinataire de l’API ne peut être que RSA, la clé RSA utilisée pour cet exemple est représentée ci-dessous au format JSON Web Key (JWK, défini dans la RFC 7517[JSON Web Key(JWK)](https://tools.ietf.org/html/rfc7517)) (avec retours à la ligne pour l’affichage uniquement) : + +```json +{ + "kty": "RSA", + "n": "oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E- + BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9Le + wND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH- + PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5tw + XTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC- + FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm- + L5StowjzGy-_bq6Gw", + "e": "AQAB", + "d": "kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4- + WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93D + t62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3 + kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOz + lpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K- + VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ", + "p": "1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ- + SWxkbk- + moEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lffNn03IXqWF5M + DFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0", + "q": + "wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBmUDdaD + YVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aXIWxKwd4gvxF + ImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc", + "dp": "ZK- + YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo-uz- + KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgq + rXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE", + "dq": + "Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCjywcMlY + Yg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDBUfCAiJVeESOj + JDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis", + "qi": "VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8- + ZW1FxU7AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E + 3eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY" +} +``` + +### Exemple de chiffrement + +Le texte de message suivant est un exemple d’une requête POST /quotes sans chiffrement envoyée par le FSP Payeur à un FSP Bénéficiaire. + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +``` + +```json +{ + "payee": { + "partyIdInfo": { "partyIdType": "MSISDN", "partyIdentifier": "15295558888", + "fspId": "5678" } }, + "amountType": "RECEIVE", + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", "initiatorType": "CONSUMER" }, + "note": "Ceci est un exemple de requête POST /quotes", + "amount": { "amount": "150","currency": "USD" }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1"}, + { "value": "value2", "key": "key2"}, + { "value": "value3", "key": "key3" } + ] + }, + "geoCode": { "latitude": "57.323889", "longitude": "125.520001" + }, + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "complexName": { "firstName": "Bill", "middleName": "Ben", "LastName": "Lee" + }, "dateOfBirth": "1986-02-14" }, + "partyIdInfo": { "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": "16135551212", + "fspId": "1234" + }, "name": "Bill Lee" + }, "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc" +} +``` + +Dans ce cas, le FSP Payeur souhaite chiffrer deux champs du message API : **payer** et **payee.partyIdInfo.partyIdentifier**. + +#### Chiffrer les champs requis + +Comme il y a deux champs à chiffrer, le FSP Payeur doit les chiffrer l’un après l’autre. + +##### Chiffrer "payer" + +Le FSP Payeur exécute les étapes suivantes pour chiffrer le champ **payer** dans le message API **POST /quotes**. + +1. Déterminer l’algorithme utilisé pour déterminer la CEK. Dans ce cas, supposons qu’il s’agit de **RSA-OAEP-256**. +2. Générer une CEK aléatoire de 256 bits. Dans ce cas, sa valeur est (notation tableau JSON) : + +``` +191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167 +``` + +3. Chiffrer la CEK avec la clé publique du FSP Bénéficiaire indiquée au format JSON Web Key dans [Exemples de chiffrement/déchiffrement d’API](#api-encryptiondecryption-examples). Dans ce cas, la valeur chiffrée est : + +``` +22 210 45 47 ... (les valeurs restent identiques, inchangées pour la traduction) +``` + +4. Calculer la valeur de la clé chiffrée en BASE64URL(JWE Encrypted Key). La valeur sera : + +``` +FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g-BJb2yfj... +``` + +... *(Le reste des exemples, tableaux, et représentations JSON sont laissés tels quels car ce sont des valeurs techniques universelles.)* + +### Exemple de déchiffrement + +Dans cet exemple, le FSP Bénéficiaire reçoit le message API POST /quotes du FSP Payeur. Le message est décrit dans le [Modèle de données pour le chiffrement](#encryption-data-model). Si le FSP Bénéficiaire détecte que le paramètre d'en-tête HTTP **FSPIOP-Encryption** est présent dans le message, il sait alors que certains champs ont été chiffrés par le FSP Payeur. Le FSP Bénéficiaire effectue alors les étapes suivantes pour déchiffrer les champs chiffrés. + +#### Analyser FSPIOP-Encryption + +Le FSP Bénéficiaire vérifie que la valeur de **FSPIOP-Encryption** est une représentation encodée UTF-8 d’un objet JSON valide selon la RFC 7159. Le FSP analyse alors le paramètre d’en-tête HTTP **FSPIOP-Encryption** pour obtenir les informations sur les champs chiffrés : nom du champ, Protected Header JWE, Clé chiffrée JWE, Vecteur d'initialisation JWE, et Tag d’authentification JWE pour chaque champ. + +#### Déchiffrer les champs chiffrés + +Dans ce cas, le FSP Bénéficiaire extrait deux champs **payer** et **payee.partyIdInfo.partyIdentifier** de l’en-tête HTTP **FSPIOP-Encryption**, puis les déchiffre l’un après l’autre. + +##### Déchiffrer payer + +Le FSP Payeur exécute les étapes suivantes pour déchiffrer le champ **payer** dans le message API **POST /quotes**. + +1. Obtenir le Protected Header JWE encodé BASE64URL depuis **FSPIOP-Encryption** pour le champ **payer**. Sa valeur est : + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +... *(Les étapes détaillées sont conservées, simplement traduites ; les valeurs techniques ne changent pas.)* + +
    + +## Table des tableaux +- [Tableau 1 -- Modèle de données du champ d’en-tête HTTP FSPIOP-Encryption](#table-1) +- [Tableau 2 -- Modèle de données du type complexe EncryptedFields](#table-2) +- [Tableau 3 -- Modèle de données du type complexe EncryptedField](#table-3) \ No newline at end of file diff --git a/docs/fr/technical/api/fspiop/v1.1/signature.md b/docs/fr/technical/api/fspiop/v1.1/signature.md new file mode 100644 index 000000000..65af90eba --- /dev/null +++ b/docs/fr/technical/api/fspiop/v1.1/signature.md @@ -0,0 +1,425 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, et la Fondation Bill & Melinda Gates +--- +# Signature + +## Préface + +Cette section contient des informations sur la manière d'utiliser ce document. + +### Conventions utilisées dans ce document + +Ce document utilise les conventions de notation pour BASE64URL(OCTETS), UTF8(CHAÎNE), ASCII(CHAÎNE), et || définies dans la RFC 7515[1](https://tools.ietf.org/html/rfc7515#section-1.1). + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'information spécifiés. + +|Type d'information|Convention|Exemple| +|---|---|---| +|**Éléments de l'API, tels que les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre accolades|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence; définis dans le _Glossaire_|Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (entité fournissant un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire des fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne doivent généralement pas être utilisées par les implémentations de l'API ; les mesures de sécurité détaillées dans _Signature de l'API_ et _Chiffrement de l'API_ doivent être utilisées à la place.| + +### Informations sur les versions du document + +|Version|Date|Description des changements| +|---|---|---| +|**1.1**|2020-05-19|Cette version contient les changements suivants : 1. Les sections 3.1, 3.2 et 3.3 ont été mises à jour selon « Solution Proposal 12 - Clarify usage of FSPIOP-Destination ». 2. Les éléments ExtensionList dans la section 4 ont été mis à jour en fonction du problème [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), pour corriger le modèle de données de l'objet extensionList.| +|**1.0**|2018-03-13|Version initiale| + +
    + +## Introduction + +Ce document détaille les méthodes de sécurité à implémenter pour l'Open API pour l'interopérabilité des FSP (ci-après dénommée l'API) afin de garantir l’_intégrité_ et la _non-répudiation_ entre le client API et le serveur API. + +En sécurité de l'information, l’_intégrité des données_ signifie maintenir et assurer l'exactitude et la complétude des données sur tout leur cycle de vie. Pour l'API, l'intégrité des données signifie qu'un message API ne peut être modifié de manière non autorisée ou non détectée par les parties impliquées dans la communication API. + +Dans les termes juridiques, la _non-répudiation_ signifie qu'une personne s'engage à remplir ses obligations contractuelles. Cela signifie aussi qu'une des parties à une transaction ne peut pas nier avoir reçu la transaction, pas plus que l'autre partie ne peut nier l’avoir envoyée. Pour l'API, la non-répudiation signifie qu’un client API ne peut pas nier avoir envoyé un message API à une contrepartie. JSON Web Signature (JWS), telle que définie dans la RFC 7515[2](https://tools.ietf.org/html/rfc7515), doit être appliquée à l'API pour garantir l'intégrité et la non-répudiation du message, soit pour des champs composants d'une charge utile API, soit pour la totalité de celle-ci. À chaque fois qu'un client API envoie un message API à une contrepartie, le client API doit signer le message à l'aide de sa clé privée. Après que la contrepartie a reçu le message API, elle doit valider la signature avec la clé publique du client API. Seul le message HTTP request d'une API doit être signé ; toute réponse API HTTP NE DOIT PAS être signée. + +**Note :** La clé publique correspondante doit soit être partagée à l'avance avec la contrepartie, soit être récupérée par la contrepartie (par exemple via l'autorité de certification du système local). + +Comme les frais d'intermédiaire ne sont pas supportés dans la version courante de l'API, les intermédiaires impliqués dans le transit du message API ne peuvent pas modifier la charge utile du message API. Ainsi, la signature au niveau de la charge utile complète est utilisée pour protéger l'intégrité de l'ensemble du message API de bout en bout. Peu importe le nombre d'intermédiaires, la charge utile originale ne peut pas être modifiée. Le destinataire final du message API doit valider la signature générée par le client API original en se basant sur la charge utile reçue. + +**Note :** La nécessité pour les intermédiaires d’effectuer la validation de la signature en transit dépend de l’implémentation interne de chaque intermédiaire ou du système local. + +**Note :** Dans une future version de l'API, les frais d’intermédiaire pourraient être pris en charge ; la signature au niveau du champ pourrait alors aussi être prise en charge. Cependant, ces deux fonctionnalités sont hors du périmètre de cette version de l'API. + +
    + +### Spécification Open API pour l'interopérabilité des FSP + +La spécification Open API pour l'interopérabilité des FSP inclut les documents suivants. + +#### Documents logiques + +- [Modèle de données logique](./logical-data-model) + +- [Modèles de transactions génériques](./generic-transaction-patterns) + +- [Cas d'utilisation](./use-cases) + +#### Documents de liaison REST asynchrone + +- [Définition de l'API](./definitions) + +- [Règles de liaison JSON](./json-binding-rules) + +- [Règles du système](./scheme-rules) + +#### Intégrité des données, confidentialité et non-répudiation + +- [Bonnes pratiques PKI](./pki-best-practices) + +- [Signature](#) + +- [Chiffrement](./v1.1/encryption) + +#### Documents généraux + +- [Glossaire](../glossary) + +
    + +## Définition de la signature API + +Cette section présente la technologie utilisée par la signature API, y compris le format d'échange de données pour la signature d'un message API et le mécanisme utilisé pour générer et vérifier une signature. + +### Modèle de données de la signature + +L'API utilise un paramètre d'en-tête HTTP personnalisé **FSPIOP-Signature** pour représenter la signature produite par le client API initiateur pour le message API. Le modèle de données de ce paramètre est décrit dans le [Tableau 1](#table-1). + +**Note :** Actuellement, l'API ne prend pas en charge les intermédiaires dans un message API ; seul l'initiateur du message peut signer un message. Si cela est requis à l'avenir, un nouveau paramètre d'en-tête HTTP personnalisé sera défini, mais cela est hors périmètre pour cette version de l'API. + +###### Tableau 1 + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| protectedHeader | 1 | Chaîne(1..32768) |
    Cet élément indique les paramètres d'en-tête HTTP protégés par la signature. Sa valeur doit être BASE64URL(UTF8(JWS Protected Header)).

    Selon la spécification JWS, le paramètre d'en-tête **alg** doit être présent pour identifier l'algorithme cryptographique utilisé pour sécuriser le JWS.

    Un paramètre personnalisé **FSPIOP-URI** représentant le chemin d'URI et les paramètres de requête du message de requête HTTP de l'API doit être présent.

    Un paramètre personnalisé **FSPIOP-HTTP-Method** contenant la méthode HTTP utilisée dans le message HTTP doit être présent.

    Un paramètre personnalisé **FSPIOP-Source** indiquant le système qui a envoyé la requête API doit être présent.

    Le paramètre d'en-tête HTTP personnalisé **FSPIOP-Destination** est obligatoire dans protectedHeader si le FSP de destination est connu par l'initiateur du message. Sinon, cet en-tête ne doit pas être protégé car il peut être modifié par les systèmes intermédiaires. Voir Définition de l'API pour plus d'informations sur les services pour lesquels l'en-tête FSPIOP-Destination est optionnel.
    | +| signature | 1 | Chaîne(1..512) | Cet élément représente la signature. Sa valeur fait partie de la sérialisation JWS : BASE64URL(JWS Signature). | +**Tableau 1 – Modèle de données du champ d'en-tête HTTP FSPIOP-Signature** + +### Génération d'une signature + +Pour créer la signature d'un message API, on effectue les étapes suivantes. L’ordre des étapes n’est pas significatif lorsque les entrées et sorties ne dépendent pas les unes des autres. + +1. Créer le contenu à utiliser comme JWS Payload. Puisque la signature est actuellement au niveau de la charge utile complète, le corps complet HTTP du message API est le JWS Payload. + +2. Calculer la valeur encodée du payload : BASE64URL(JWS Payload). + +3. Créer l'objet ou les objets JSON contenant les paramètres désirés pour le JWS Protected Header. + + A. Le paramètre **alg** du JWS Protected Header doit être présent. Dans l’API, les algorithmes disponibles pour la signature sont **RS256, RS384, RS512**. Une clé d’une taille de 2048 bits ou supérieure doit être utilisée avec ces algorithmes. + + B. Les autres paramètres enregistrés dans l’IANA JSON _Web Signature and Encryption Header Parameters_[3](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) sont optionnels. + + C. Le paramètre personnalisé **FSPIOP-URI** doit être inclus dans le JWS Protected Header pour protéger le chemin d'URI et les paramètres de requête des API. + + D. Le paramètre personnalisé **FSPIOP-HTTP-Method** doit être inclus dans le JWS Protected Header pour protéger la méthode HTTP de la requête. + + E. Le paramètre **FSPIOP-Source** doit être présent, sa valeur provenant du paramètre d'en-tête HTTP correspondant **FSPIOP-Source**. + + F. Le paramètre **FSPIOP-Destination** doit être présent si le FSP de destination est connu par l'initiateur du message, et sa valeur doit être la même que le paramètre d'en-tête HTTP **FSPIOP-Destination**. + + G. Il est recommandé d'inclure d'autres paramètres d’en-tête HTTP des APIs dans le JWS Protected Header, mais ils sont optionnels. + +4. Calculer la valeur encodée de l'en-tête : BASE64URL(UTF8(JWS Protected Header)). + +5. Calculer la signature JWS selon la spécification JWS en utilisant la sortie des étapes 2 et 4. + +6. Calculer la valeur encodée de la signature : BASE64URL(JWS Signature). + +7. Calculer la valeur pour le paramètre d'en-tête HTTP **FSPIOP-Signature** tel que décrit dans la section [Modèle de données de la signature](#signature-data-model). La valeur de ce **FSPIOP-Signature** est une chaîne de sérialisation d’objet JSON. + +**Note :** Si JSON Web Encryption (JWE) est utilisé pour chiffrer certains champs de la charge utile (voir « Chiffrement »), alors le client API doit tout d’abord chiffrer les champs concernés, remplacer leur texte en clair par le texte chiffré encodé dans la charge utile, puis enfin signer la charge utile. + +### Validation de la signature + +Lors de la validation de la signature d'une requête API, on effectue les étapes suivantes. L’ordre des étapes n’est pas significatif lorsque les entrées et sorties ne dépendent pas les unes des autres. Si l’une des étapes échoue, alors la signature ne peut pas être validée. + +1. Analyser le paramètre d’en-tête HTTP **FSPIOP-Signature** pour obtenir les composants **protectedHeader** et **signature**. + +2. Utiliser BASE64URL pour décoder la représentation encodée du JWS Protected Header. Vérifier que la séquence d’octets résultante est une représentation UTF-8 d’un objet JSON complètement valide conforme au format JSON Data Interchange, défini dans la RFC 7159[4](https://tools.ietf.org/html/rfc7159). + +3. Vérifier les paramètres du JWS Protected Header. + + a) Le paramètre **alg** doit être présent et sa valeur doit être l'une de **RS256, RS384, RS512**. + + b) Les autres paramètres enregistrés dans l’IANA JSON _Web Signature and Encryption Header Parameters_ sont optionnels. + + c) Le paramètre **FSPIOP-URI** doit être présent et sa valeur doit correspondre exactement à l'URL cible de la requête. + + d) Le paramètre **FSPIOP-HTTP-Method** doit être présent et sa valeur doit être la même que la méthode d'opération de la requête. + + e) Le paramètre **FSPIOP-Source** doit être présent, et sa valeur doit être la même que celle du paramètre d’en-tête HTTP **FSPIOP-Source**. + + f) Si le paramètre **FSPIOP-Destination** est présent dans le JWS Protected Header, alors sa valeur doit être la même que celle du paramètre d’en-tête HTTP **FSPIOP-Destination**. + + g) S'il y a d'autres paramètres d'en-tête HTTP présents dans le JWS Protected Header, leurs valeurs doivent être validées avec les valeurs d’en-tête HTTP correspondantes. + +4. Calculer la valeur encodée du payload : BASE64URL(JWS Payload). Actuellement, il s'agit du corps HTTP complet du message API. + +5. Valider la signature JWS contre JWS Signing Input ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)) de la manière définie par l’algorithme utilisé, qui doit correspondre à la valeur du paramètre d’en-tête **alg**. + +6. Consigner le résultat de la validation. + +
    + +## Exemples de signatures API + +Cette section utilise un processus de devis typique pour expliquer comment la signature API est implémentée via JWS. Les FSP de l’API peuvent vérifier que leur implémentation interne pour la signature API est correcte à l’aide du scénario suivant. + +Le cas de cette section utilise RS256 comme algorithme de signature. La clé RSA utilisée dans cet exemple de signature est représentée en format JSON Web Key (JWK), défini dans la RFC 7517[5](https://tools.ietf.org/html/rfc7517), ci-dessous (avec retours à la ligne et indentation pour la présentation uniquement) : + +```json +{ + "kty": "RSA", + "n": "ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", + "e": "AQAB", + "d": "Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ", + "p": "4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdiYrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPGBY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc", + "q": "uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxaewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc", + "dp": "BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3QCLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0", + "dq": "h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-kyNlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU", + "qi": "IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2oy26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLUW0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U" +} +``` + +### Génération d'une signature exemple + +Le texte de message ci-dessous est un exemple de `POST /quotes` sans signature, envoyé par le FSP Payeur vers un destinataire (retours à la ligne et indentation à des fins de présentation uniquement). + +```json +POST /quotes HTTP/1.1 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Source:1234 +FSPIOP-Destination:5678 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +{ + "amount": { "amount": "150", "currency": "USD" },"transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER","subScenario": "P2P Transfer across MM systems","initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc","quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50","expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer","partyIdentifier": "16135551212" } + }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } + }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { + "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +#### Calcul de l'entrée de la signature + +Conformément à la spécification JWS, l'entrée de la signature est BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload). + +En supposant que les paramètres d'en-tête HTTP **Date** et **FSPIOP-Destination** soient protégés par la signature, et que l'algorithme RS256 soit utilisé pour signer le message, le JWS Protected Header est le suivant (indentation pour la présentation uniquement) : + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +L'encodage de ce JWS Protected Header en BASE64URL(UTF8(JWS Protected Header)) donne : + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +Dans ce cas, le JWS Payload est le corps HTTP décrit dans la section [Génération d'une signature](#generating-a-signature). En codant ce JWS Payload en BASE64URL(JWS Payload), on obtient : + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +#### Production de la signature + +Utiliser la clé privée RSA fournie, le JWS Protected Header et le JWS Payload pour générer la signature, puis encoder la signature en BASE64URL(JWS Signature) donne : + +``` +dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-uve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGw-QkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg +``` + +#### Reproduction de la requête API avec signature + +Comme décrit dans la section [Modèle de données de la signature](#signature-data-model), la signature API est représentée par un en-tête HTTP personnalisé **FSPIOP-Signature** ; donc la requête API avec la signature dans ce cas ressemble à : + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Signature: {"signature": "dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEBuve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGwQkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg", "protectedHeader": "eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9" +} +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +### Validation de la signature + +Après que le FSP Bénéficiaire ait reçu le message API `POST /quotes` du FSP Payeur, le FSP Bénéficiaire doit valider la signature signée par le FSP Payeur. + +#### Analyse de FSPIOP-Signature + +1. Analysez le paramètre d’en-tête HTTP **FSPIOP-Signature** pour obtenir les composants **protectedHeader** et **signature**. Dans ce cas, la valeur de **protectedHeader** est : + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjo +iL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYX +kgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +2. Utilisez BASE64URL pour décoder la représentation encodée du JWS Protected Header. Vérifiez que la séquence d’octets résultante est une représentation UTF-8 d’un objet JSON conforme au format RFC7159. Dans ce cas, l'objet JSON décodé est : + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +3. Vérifier que le paramètre **alg** est valide pour l’API. Il doit faire partie de **RS256, RS384, RS512**. Dans ce cas, la valeur **alg** est **RS256**, ce qui est valide. + +4. Vérifier que la valeur du paramètre **FSPIOP-URI** est la même que l’URL d’entrée de ce message API. + +5. Vérifier que la valeur du paramètre **FSPIOP-HTTP-Method** est la même que la méthode HTTP de ce message API. + +6. Vérifier que la valeur de l'en-tête HTTP **FSPIOP-Source** est la même que celle indiquée dans ce JWS Protected Header. + +7. Vérifier que la valeur de l’en-tête HTTP **FSPIOP-Destination** est la même que celle indiquée dans ce JWS Protected Header. + +8. Vérifier les autres paramètres d’en-tête HTTP protégés. Ici, le paramètre **Date** est protégé par le JWS Protected Header. Si les paramètres **Date** dans l’en-tête HTTP et le JWS Protected Header sont égaux, alors la validation est réussie. Les deux paramètres **Date** dans l’exemple doivent avoir la valeur : + +``` +"Tue, 23 May 2017 21:12:31 GMT" +``` + +La validation est réussie. + +#### Vérification de la signature JWS + +1. Dans ce cas, le JWS Payload est le corps complet du message HTTP de l'API, donc (indentation incluse pour la présentation) : + +```json +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", + "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} + ``` + +2. Calculez la valeur encodée du payload : BASE64URL(JWS Payload). Obtenez la valeur encodée suivante : + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +3. Validez la signature JWS par rapport à JWS Signing Input (le JWS Protected Header, JWS Payload) avec l'algorithme **RS256** (spécifié dans le JWS Protected Header), et la clé publique. Notez si la validation a réussi ou non. + +
    + +## Références + +1 [https://tools.ietf.org/html/rfc7515#section-1.1](https://tools.ietf.org/html/rfc7515#section-1.1) – JSON Web Signature (JWS) - Conventions de notation + +2 [https://tools.ietf.org/html/rfc7515](https://tools.ietf.org/html/rfc7515) – JSON Web Signature (JWS) + +3 [https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) – Paramètres d’en-tête JSON Web Signature et Encryption + +4 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) – Format d'échange de données JavaScript Object Notation (JSON) + +5 [https://tools.ietf.org/html/rfc7517](https://tools.ietf.org/html/rfc7517) – JSON Web Key (JWK) diff --git a/docs/fr/technical/api/license.md b/docs/fr/technical/api/license.md new file mode 100644 index 000000000..4bf2f2526 --- /dev/null +++ b/docs/fr/technical/api/license.md @@ -0,0 +1,27 @@ +# LICENSE + +This API specification is made available by **Ericsson**, **Huawei**, **Mahindra-Comviva**, **Telepin**, and the **Bill & Melinda Gates Foundation** under a **Creative Commons Attribution-NoDerivatives 4.0 International** License. In order to help maintain the integrity of the text of this document that reflects the underlying charitable goals of this project, we are circulating under a CC-BY license that prohibits the creation of derivative works based on this document. We ask that you do not create or distribute derivatives of this documentation. + +The Bill & Melinda Gates Foundation believes that an economy that includes everyone, benefits everyone. In support of this goal, we asked leading mobile wallet technology providers Ericsson, Huawei, Mahindra-Comviva and Telepin to work together to create a set of APIs for interoperability within the digital financial services infrastructure. Together with consultants from **Interledger** and **Modusbox**, the group worked to produce the APIs documented below. + +The underlying charitable goal for the API is to spur innovation and access to digital products and services that serve the financially underserved with a focus on interoperability, and strengthening and accelerating the availability of solutions that reflect the design principles of **L1P** as documented on www.leveloneproject.org. The contributors commit to making the relevant background technology which is provided to the API project necessary to implement the API in furtherance of the charitable goals available on a royalty-free basis. + +[**Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0)**](https://creativecommons.org/licenses/by-nd/4.0/) + +#### You are free to: +Share — copy and redistribute the material in any medium or format for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms. +_____________________ + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + +NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + +No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +________________________________ + +#### Notices: + +You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. \ No newline at end of file diff --git a/docs/fr/technical/api/settlement/README.md b/docs/fr/technical/api/settlement/README.md new file mode 100644 index 000000000..4fe520c99 --- /dev/null +++ b/docs/fr/technical/api/settlement/README.md @@ -0,0 +1,8 @@ +--- +showToc: false +--- +# Settlement API + + + + diff --git a/docs/fr/technical/api/thirdparty/README.md b/docs/fr/technical/api/thirdparty/README.md new file mode 100644 index 000000000..45819a160 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/README.md @@ -0,0 +1,41 @@ +# API Tierce Partie + +L’API Tierce Partie est une API destinée aux acteurs qui ne détiennent pas de fonds afin de leur permettre d’interagir via un hub Mojaloop centralisé. +Plus précisément, cette API permet aux Prestataires de Services d’Initiation de Paiement (PISP) d’agir en tant que mandataire lors de l’initiation +des paiements, tout en assurant une authentification forte des utilisateurs. + +## Termes + +Les termes suivants sont fréquemment utilisés dans la documentation de l’API Tierce Partie : + +| **Terme** | **Termes alternatifs et associés** | **Définition** | **Source** | +| --- | --- | --- | --- | +| **Prestataire de Services d’Initiation de Paiement** | PISP, Initiateur de Paiement Tiers (3PPI) | Entités réglementées telles que des banques de détail ou des tiers, permettant aux clients d'effectuer des paiements sans accéder à des comptes bancaires ou à des cartes | [DSP2 (Directive sur les Services de Paiement 2)](https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX%3A32015L2366) | +| **FSP** | Fournisseur, Prestataire de Services Financiers (FSP), Prestataire de Services de Paiement, Prestataire de Services Financiers Numériques (DFSP) | L’entité qui fournit un service financier numérique à un utilisateur final (consommateur, entreprise ou gouvernement). Dans un système de paiement en boucle fermée, l’Opérateur du Système de Paiement remplit également ce rôle. Dans un système en boucle ouverte, les fournisseurs sont des banques ou des établissements non bancaires participant à ce système. | [UIT-T](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-F.pdf) | +| **Utilisateur** | Utilisateur final | Un utilisateur final partagé entre un PISP et un DFSP. Utilisé principalement pour désigner un être humain, mais peut également représenter une machine ou une entreprise par exemple. | +| **Consentement** | Lien de compte | Représentation d’un accord entre le DFSP, le PISP et l’Utilisateur | | +| **Service d’authentification** | | Service opéré par le Hub Mojaloop, responsable de la vérification et conservation des consentements, ainsi que de la vérification des signatures des demandes de transaction | | + +## Définition de l’API + +L’API Tierce Partie est définie à travers les fichiers OpenAPI 3.0 suivants : + +- [API Tierce Partie – PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +- [API Tierce Partie – DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml) + +L’implémentation de ces API dépendra du rôle du participant. Les PISP doivent implémenter l’interface [API Tierce Partie – PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +pour initier et gérer les opérations de Liaison de Compte et initier des Demandes de Transaction Tierce Partie. + +Les DFSP qui souhaitent prendre en charge les opérations de liaison de compte, et être en mesure de répondre aux demandes de transaction tierce partie et de les vérifier doivent +implémenter l’[API Tierce Partie – DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml). + +## Modèles de transaction + +Les interactions et exemples de collaboration entre un DFSP et un PISP via l’API Tierce Partie sont disponibles dans les documents suivants sur les modèles de transaction : + +1. [Liaison](./transaction-patterns-linking.md) décrit comment un lien de compte et un justificatif peuvent être établis entre un DFSP et un PISP. +2. [Transfert](./transaction-patterns-transfer.md) décrit comment un PISP peut initier un paiement depuis un compte DFSP à l’aide du lien de compte. + +## Modèles de données + +Le [document sur les modèles de données](./data-models.md) décrit en détail les modèles de données utilisés dans l’API Tierce Partie. diff --git a/docs/fr/technical/api/thirdparty/_sync_docs.sh b/docs/fr/technical/api/thirdparty/_sync_docs.sh new file mode 100644 index 000000000..fd92ad483 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/_sync_docs.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +## +# Synchronises the definition docs from their disparate locations into one place. +# +# The API Spec for the Third Party API is managed by the api-snippets project +## + +set -eu + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +GIT_URL="https://github.com/mojaloop/api-snippets.git" +BRANCH='master' +CLONE_DIR='/tmp/api-snippets' + +rm -rf ${CLONE_DIR} + +git clone -b ${BRANCH} ${GIT_URL} ${CLONE_DIR} + +# API definition, grab from mojaloop/pisp-project +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-dfsp-api.yaml ${DIR}/thirdparty-dfsp-v1.0.yaml +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-pisp-api.yaml ${DIR}/thirdparty-pisp-v1.0.yaml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml new file mode 100644 index 000000000..e3dfde0df --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml @@ -0,0 +1,49 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Pré-liaison + +box "Appareil mobile" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +autonumber 1 "PRE-#" +activate App +App -> PISP ++: Quels DFSP peuvent être liés ? + + +PISP -> Switch ++: ""GET /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: pispa""\n""FSPIOP-Destination: switch"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> PISP ++: ""PUT /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: switch""\n""FSPIOP-Destination: pispa""\n\ + ""{""\n\ + "" "serviceProviders": ["" \n\ + "" "dfspa", "dfspb""" \n\ + "" ]"" \n\ + ""}"" +PISP --> Switch: ""200 OK"" + +PISP --> App --: Nous avons dfspa et dfspb\n + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg new file mode 100644 index 000000000..80ba29f8a --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg @@ -0,0 +1,72 @@ + + Liaison PISP : Pré-liaison + + + Liaison PISP : Pré-liaison + + Appareil mobile + + PISP + + Mojaloop + + + + + + + + + App + + PISP + + Switch + + + + + + + PRE-1 + Quels DFSP peuvent être liés ? + + + PRE-2 + GET /services/THIRD_PARTY_DFSP + FSPIOP-Source: pispa + FSPIOP-Destination: switch + + + PRE-3 + 202 Accepted + + + PRE-4 + PUT /services/THIRD_PARTY_DFSP + FSPIOP-Source: switch + FSPIOP-Destination: pispa +   + { +    + "serviceProviders": [ +   +    + "dfspa", "dfspb + " +    + ] +   +   + } + + + PRE-5 + 200 OK + + + PRE-6 + Nous avons dfspa et dfspb +   + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml new file mode 100644 index 000000000..070d31ad8 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml @@ -0,0 +1,85 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title Liaison PISP : Découverte + +box "Appareil mobile" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +... + +note over App, DFSP + L'utilisateur est invité dans l'application PISP à saisir l'identifiant unique qu'il utilise auprès de son DFSP, et le type d'identifiant. Il peut s'agir d'un alias de compte, d'un MSISDN, d'une adresse e-mail, etc. +end note + +... + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> Switch ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over App, DFSP + Le PISP peut maintenant présenter à l'utilisateur une liste de comptes possibles pour l'appariement. +end note + +... + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg new file mode 100644 index 000000000..0829997f5 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg @@ -0,0 +1,151 @@ + + Liaison PISP : Découverte + + + Liaison PISP : Découverte + + Appareil mobile + + PISP + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + App + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + + L'utilisateur est invité dans l'application PISP à saisir l'identifiant unique qu'il utilise auprès de son DFSP, et le type d'identifiant. Il peut s'agir d'un alias de compte, d'un MSISDN, d'une adresse e-mail, etc. + + + DISC-1 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-2 + 202 Accepted + + + DISC-3 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-4 + 202 Accepted + + + DISC-5 + PUT /accounts/username1234 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + [ +    + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, +    + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } +    + ] + + + DISC-6 + 200 OK + + + DISC-7 + PUT /accounts/username1234 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + [ +    + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, +    + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } +    + ] + + + DISC-8 + 200 OK + + + Le PISP peut maintenant présenter à l'utilisateur une liste de comptes possibles pour l'appariement. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml new file mode 100644 index 000000000..f65cfbe40 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml @@ -0,0 +1,119 @@ +@startuml + + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Demande de consentement (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + L'utilisateur a initié une liaison de compte en choisissant le DFSP approprié depuis un écran de l'application PISP. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Vérification de la validité du consentRequest + + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" + +note over PISP, DFSP + Ici, le DFSP envoie un OTP directement à l'utilisateur (par ex. par SMS). +end note + +deactivate DFSP + +Switch -> PISP: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +""{""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + À ce stade, le PISP sait que le canal d'authentification OTP est utilisé et que l'application PISP doit inviter l'utilisateur à saisir l'OTP. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg new file mode 100644 index 000000000..bdf84bebf --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg @@ -0,0 +1,203 @@ + + Liaison PISP : Demande de consentement (OTP) + + + Liaison PISP : Demande de consentement (OTP) + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + L'utilisateur a initié une liaison de compte en choisissant le DFSP approprié depuis un écran de l'application PISP. + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + REQ-5 + Vérification de la validité du consentRequest + + + REQ-6 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa + { +    + authChannels: [ "OTP" ], +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-7 + 200 OK + + + Ici, le DFSP envoie un OTP directement à l'utilisateur (par ex. par SMS). + + + REQ-8 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa + { +    + authChannels: [ "OTP" ], +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-9 + 200 OK + + + À ce stade, le PISP sait que le canal d'authentification OTP est utilisé et que l'application PISP doit inviter l'utilisateur à saisir l'OTP. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml new file mode 100644 index 000000000..8c6b158e3 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml @@ -0,0 +1,118 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title Liaison PISP : Demande de consentement (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + L'utilisateur a initié une liaison de compte en choisissant le DFSP approprié depuis un écran de l'application PISP. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" + +DFSP -> DFSP: Vérification de la validité du consentRequest +DFSP -> DFSP: Dans ce cas, le DFSP choisit le canal Web \n et ajoute l'URI de rappel du PISP à une liste autorisée +deactivate Switch + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + À ce stade, le PISP sait que le canal d'authentification Web est utilisé et que l'application PISP doit rediriger l'utilisateur vers l'""authUri"" fourni. +end note + + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg new file mode 100644 index 000000000..f31db2486 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg @@ -0,0 +1,219 @@ + + Liaison PISP : Demande de consentement (Web) + + + Liaison PISP : Demande de consentement (Web) + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + + L'utilisateur a initié une liaison de compte en choisissant le DFSP approprié depuis un écran de l'application PISP. + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa +    + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa +    + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + REQ-5 + Vérification de la validité du consentRequest + + + + + REQ-6 + Dans ce cas, le DFSP choisit le canal Web + et ajoute l'URI de rappel du PISP à une liste autorisée + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web" ], +    + callbackUri: "pisp-app://callback... + " +    + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" +    + } + + + REQ-8 + 200 OK + + + REQ-9 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web" ], +    + callbackUri: "pisp-app://callback... + " +    + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" +    + } + + + REQ-10 + 200 OK + + + À ce stade, le PISP sait que le canal d'authentification Web est utilisé et que l'application PISP doit rediriger l'utilisateur vers l' + authUri + fourni. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml new file mode 100644 index 000000000..e49b425f8 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml @@ -0,0 +1,62 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Authentification (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +... + +note over PISP, DFSP + Ici, l'utilisateur saisit l'OTP qui lui a été envoyé directement par le DFSP dans l'application PISP. Il est utilisé comme secret pour prouver au DFSP que l'utilisateur fait confiance au PISP. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Vérification que l'OTP est correct. + +note over PISP, DFSP + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. + + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg new file mode 100644 index 000000000..d95990687 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg @@ -0,0 +1,82 @@ + + Liaison PISP : Authentification (OTP) + + + Liaison PISP : Authentification (OTP) + + Mojaloop + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + Ici, l'utilisateur saisit l'OTP qui lui a été envoyé directement par le DFSP dans l'application PISP. Il est utilisé comme secret pour prouver au DFSP que l'utilisateur fait confiance au PISP. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + Vérification que l'OTP est correct. + + + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. +   + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml new file mode 100644 index 000000000..ba9cd1f5c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml @@ -0,0 +1,45 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Authentification (enregistrement FIDO tiers) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "3P-FIDO-AUTH-#" + +... + +note over PISP, DFSP + Ici, l'utilisateur suit le processus d'authentification Web auprès de son DFSP. + Il en résulte une redirection vers le PISP avec un paramètre d'URL particulier indiquant au PISP d'attendre une notification concernant un identifiant. +end note + +... + +autonumber 1 "AUTH-#" + +note over PISP, DFSP + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. + + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg new file mode 100644 index 000000000..c46dc8c1c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg @@ -0,0 +1,39 @@ + + Liaison PISP : Authentification (enregistrement FIDO tiers) + + + Liaison PISP : Authentification (enregistrement FIDO tiers) + + Mojaloop + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + Ici, l'utilisateur suit le processus d'authentification Web auprès de son DFSP. + Il en résulte une redirection vers le PISP avec un paramètre d'URL particulier indiquant au PISP d'attendre une notification concernant un identifiant. + + + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. +   + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml new file mode 100644 index 000000000..6676205c6 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml @@ -0,0 +1,65 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Authentification (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "WEB-AUTH-#" + +... + +note over PISP, DFSP + Ici, l'utilisateur suit le processus d'authentification Web auprès de son DFSP. + Il en résulte une redirection vers le PISP avec un paramètre d'URL particulier contenant un secret fourni par le DFSP. +end note + +... + +autonumber 1 "AUTH-#" + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Vérification que le jeton d'authentification est correct. + +note over PISP, DFSP + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. + + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg new file mode 100644 index 000000000..6d5843e38 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg @@ -0,0 +1,83 @@ + + Liaison PISP : Authentification (Web) + + + Liaison PISP : Authentification (Web) + + Mojaloop + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + Ici, l'utilisateur suit le processus d'authentification Web auprès de son DFSP. + Il en résulte une redirection vers le PISP avec un paramètre d'URL particulier contenant un secret fourni par le DFSP. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<SECRET>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<SECRET>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + Vérification que le jeton d'authentification est correct. + + + À ce stade, le DFSP considère que l'utilisateur est son client et que l'utilisateur fait confiance au PISP. Le DFSP peut donc poursuivre en accordant le consentement. +   + Note : le DFSP ne « répond » jamais directement à la demande de consentement. Il créera plutôt une ressource Consent lors de la phase d'octroi. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml new file mode 100644 index 000000000..8fd48380d --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml @@ -0,0 +1,64 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title Liaison PISP : Octroi du consentement + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +DFSP -> Switch ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" +Switch --> DFSP: ""202 Accepted"" +deactivate DFSP + +Switch -> PISP ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" + +PISP --> Switch: ""202 Accepted"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg new file mode 100644 index 000000000..a805ff7e0 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg @@ -0,0 +1,82 @@ + + Liaison PISP : Octroi du consentement + + + + Mojaloop + Liaison PISP : Octroi du consentement + + + + + + + PISP + + Switch + + DFSP + + + GRANT-1 + POST /consents + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { +      + consentId: "22222222-0000-0000-0000-000000000000", +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + { accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + ], +      + } + + + GRANT-2 + 202 Accepted + + + GRANT-3 + POST /consents + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { +      + consentId: "22222222-0000-0000-0000-000000000000", +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + { accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + ], +      + } + + + GRANT-4 + 202 Accepted + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml new file mode 100644 index 000000000..e8ed4fc39 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml @@ -0,0 +1,219 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title Liaison PISP : Enregistrement des identifiants (vérification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 0 "CRED-#" + +... + +note over PISP, DFSP + Le PISP utilise le flux d'enregistrement FIDO pour générer une nouvelle paire de clés et signer le défi, l'utilisateur effectuant une « action de déverrouillage » sur son appareil mobile. + + Le PISP utilise PublicKeyCredential comme fidoPayload pour l'identifiant, interprétable par le Auth Service et le DFSP. + Voir https://webauthn.guide/#authentication pour plus d'informations sur cet objet +end note + +... + +PISP -> Switch ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + + +Switch -> DFSP ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: ""202 Accepted"" + + +rnote over DFSP + 1. Le DFSP vérifie le défi signé par rapport au défi dérivé des portées + + Si le DFSP choisit d'utiliser le Auth-Service hébergé par le hub : + 1. Enregistre le consentement auprès du Auth Service ""POST /consents"" + 2. Si le DFSP reçoit un `PUT /consents/{id}` et que le rappel contient + ""Consent.credential.status"" égal à ""VERIFIED"", pour chaque portée du + Consent, le DFSP crée un ""CredentialScope"" ; sinon, s'il reçoit + un rappel `PUT /consents/{id}/error`, il sait que le Consent est + invalide et peut propager l'erreur au PISP + +end note + + +DFSP -> Switch: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000"""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000"""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" + +Switch --> DFSP: "202 Accepted" + + +Switch -> Auth: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {...}"" + +Auth --> Switch: "202 Accepted" + + +rnote over Auth + Le Auth Service vérifie la signature par rapport au défi +end note + +rnote over Auth + Le service d'authentification est désormais la source faisant autorité pour l'objet Consent. + + Il doit enregistrer le consentId auprès de l'ALS + - `Consent` — pour autoriser les appels `GET /consent/{ID}`, etc. Pointera vers le fspId du Auth Service responsable du Consent +end note + +Auth -> ALS: ""POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSPIOP-Source: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +ALS --> Auth: ""202 Accepted"" + +rnote over ALS #LightGray + L'ALS enregistre une nouvelle entrée dans l'oracle Consents +end note + +ALS -> Auth: ""PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSPIOP-Source: account-lookup-service""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +Auth --> ALS: ""200 OK"" + +rnote over Auth #LightGray + Le service d'authentification informe maintenant le DFSP que l'identifiant est valide +end note + + +Auth -> Switch: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000"""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "VERIFIED",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> Auth: "200 OK" + +Switch -> DFSP: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: "200 OK" + +rnote over DFSP + Le DFSP considère maintenant que le Consent enregistré par le PISP est valide. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg new file mode 100644 index 000000000..5bcc9b383 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg @@ -0,0 +1,348 @@ + + Liaison PISP : Enregistrement des identifiants (vérification) + + + + Mojaloop + Liaison PISP : Enregistrement des identifiants (vérification) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Thirdparty-API-Adapter + + Account Lookup Service + + Auth Service + + DFSP + + + Le PISP utilise le flux d'enregistrement FIDO pour générer une nouvelle paire de clés et signer le défi, l'utilisateur effectuant une « action de déverrouillage » sur son appareil mobile. +   + Le PISP utilise PublicKeyCredential comme fidoPayload pour l'identifiant, interprétable par le Auth Service et le DFSP. + Voir https://webauthn.guide/#authentication pour plus d'informations sur cet objet + + + CRED-0 + PUT /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSPIOP-Destination: dfspa + { +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "PENDING", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-1 + 202 Accepted + + + CRED-2 + PUT /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSPIOP-Destination: dfspa + {...} + + + CRED-3 + 202 Accepted + + 1. Le DFSP vérifie le défi signé par rapport au défi dérivé des portées +   + Si le DFSP choisit d'utiliser le Auth-Service hébergé par le hub : + 1. Enregistre le consentement auprès du Auth Service + POST /consents + 2. Si le DFSP reçoit un `PUT /consents/{id}` et que le rappel contient +     + Consent.credential.status + égal à + VERIFIED + , pour chaque portée du + Consent, le DFSP crée un + CredentialScope + ; sinon, s'il reçoit + un rappel `PUT /consents/{id}/error`, il sait que le Consent est + invalide et peut propager l'erreur au PISP +   + + + CRED-4 + POST /consents +   + FSIOP-Source: dfspa + FSPIOP-Destination: central-auth + { +      + consentId: "22222222-0000-0000-0000-000000000000 + " +      + consentRequestId: "11111111-0000-0000-0000-000000000000 + " +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + }, +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "PENDING", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-5 + "202 Accepted" + + + CRED-6 + POST /consents +   + FSIOP-Source: dfspa + FSPIOP-Destination: central-auth + {...} + + + CRED-7 + "202 Accepted" + + Le Auth Service vérifie la signature par rapport au défi + + Le service d'authentification est désormais la source faisant autorité pour l'objet Consent. +   + Il doit enregistrer le consentId auprès de l'ALS + - `Consent` — pour autoriser les appels `GET /consent/{ID}`, etc. Pointera vers le fspId du Auth Service responsable du Consent + + + CRED-8 + POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000 +   + FSPIOP-Source: central-auth + { + fspId: "central-auth", + } + + + CRED-9 + 202 Accepted + + L'ALS enregistre une nouvelle entrée dans l'oracle Consents + + + CRED-10 + PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000 +   + FSPIOP-Source: account-lookup-service + FSPIOP-Destination: central-auth + { + fspId: "central-auth", + } + + + CRED-11 + 200 OK + + Le service d'authentification informe maintenant le DFSP que l'identifiant est valide + + + CRED-12 + PUT /consents/22222222-0000-0000-0000-000000000000 +   + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { +      + consentRequestId: "11111111-0000-0000-0000-000000000000 + " +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "accounts.transfer", "accounts.getBalance" ], +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "accounts.transfer", "accounts.getBalance" ], +      + }, +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "VERIFIED", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-13 + "200 OK" + + + CRED-14 + PUT /consents/22222222-0000-0000-0000-000000000000 +   + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + {...} + + + CRED-15 + "200 OK" + + Le DFSP considère maintenant que le Consent enregistré par le PISP est valide. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml new file mode 100644 index 000000000..96c1f8451 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml @@ -0,0 +1,96 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title Liaison PISP : Enregistrement des identifiants (vérification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch + participant "Account Lookup Service" as ALS +end box + +participant "DFSP" as DFSP + +autonumber 16 "CRED-#" + +... + + +rnote over DFSP + Le DFSP considère maintenant que le Consent enregistré par le PISP est valide, + et poursuit l'enregistrement auprès de l'ALS : + - `THIRD_PARTY_LINK` (facultatif — pour le routage des fonds vers un lien tiers) +end note + +loop pour chaque portée dans ""Consents.scopes"" + +DFSP -> ALS: ""POST /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +ALS --> DFSP: ""202 Accepted"" + +rnote over ALS #LightGray + L'ALS enregistre une nouvelle entrée dans l'oracle THIRD_PARTY_LINK +end note + +ALS -> DFSP: ""PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSPIOP-Source: account-lookup-service""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +DFSP --> ALS: ""200 OK"" +end + + +rnote over DFSP + Les identifiants étant vérifiés et enregistrés auprès du Auth Service, + le DFSP peut mettre à jour le PISP avec le statut final +end note + +DFSP -> Switch: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +DFSP --> Switch: ""200 OK"" + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +PISP --> Switch: ""200 OK"" + + +note over PISP, DFSP + Nous disposons maintenant d'un nouvel identifiant que le PISP peut utiliser pour initier des transactions, d'un identifiant enregistré, et cet identifiant est stocké dans le service d'authentification +end note + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg new file mode 100644 index 000000000..a96a285a9 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg @@ -0,0 +1,115 @@ + + Liaison PISP : Enregistrement des identifiants (vérification) + + + + Mojaloop + Liaison PISP : Enregistrement des identifiants (vérification) + + + + + + + + + + + + + + + PISP + + Switch + + Account Lookup Service + + DFSP + + Le DFSP considère maintenant que le Consent enregistré par le PISP est valide, + et poursuit l'enregistrement auprès de l'ALS : + - `THIRD_PARTY_LINK` (facultatif — pour le routage des fonds vers un lien tiers) + + + loop + [pour chaque portée dans + Consents.scopes + ] + + + CRED-16 + POST /participants/THIRD_PARTY_LINK/dfsp.username.5678 +   + FSIOP-Source: dfspa + { + fspId: "dfspa", + } + + + CRED-17 + 202 Accepted + + L'ALS enregistre une nouvelle entrée dans l'oracle THIRD_PARTY_LINK + + + CRED-18 + PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678 +   + FSPIOP-Source: account-lookup-service + FSPIOP-Destination: dfspa + { + fspId: "dfspa", + } + + + CRED-19 + 200 OK + + Les identifiants étant vérifiés et enregistrés auprès du Auth Service, + le DFSP peut mettre à jour le PISP avec le statut final + + + CRED-20 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSPIOP-Destination: pispa + Content-Type: application/merge-patch+json + { +      + credential: { +      +      + status: "VERIFIED", //this is new! +      + } + } + + + CRED-21 + 200 OK + + + CRED-22 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSPIOP-Destination: pispa + Content-Type: application/merge-patch+json + { +      + credential: { +      +      + status: "VERIFIED", //this is new! +      + } + } + + + CRED-23 + 200 OK + + + Nous disposons maintenant d'un nouvel identifiant que le PISP peut utiliser pour initier des transactions, d'un identifiant enregistré, et cet identifiant est stocké dans le service d'authentification + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml new file mode 100644 index 000000000..2e7db7fca --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title Liaison PISP : Dissociation + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-A-#" + +activate PISP + +... + +note over PISP, DFSP + Dans ce scénario, il n'y a pas de service d'authentification hébergé par le hub. Le DFSP est l'autorité sur l'objet ""Consent"". +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Marquer l'objet ""Consent"" comme « REVOKED » + +DFSP -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg new file mode 100644 index 000000000..591be29b6 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg @@ -0,0 +1,102 @@ + + Liaison PISP : Dissociation + + + + Mojaloop + Liaison PISP : Dissociation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + Dans ce scénario, il n'y a pas de service d'authentification hébergé par le hub. Le DFSP est l'autorité sur l'objet + Consent + . + + + UNLINK-A-1 + DELETE /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSIOP-Destination: dfspa + + + UNLINK-A-2 + 202 Accepted + + + UNLINK-A-3 + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + UNLINK-A-4 + 202 Accepted + + + + + UNLINK-A-5 + Marquer l'objet + Consent + comme « REVOKED » + + + UNLINK-A-6 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-A-7 + 200 OK + + + UNLINK-A-8 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + } + + + UNLINK-A-9 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml new file mode 100644 index 000000000..319f377ec --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml @@ -0,0 +1,105 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title Liaison PISP : Dissociation + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-B-#" + +activate PISP + +... + +note over PISP, DFSP + Dans ce scénario, il n'y a pas de service d'authentification hébergé par le hub. Le DFSP est l'autorité sur l'objet ""Consent"". +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> ALS: ""GET /participants/CONSENT/22222222-0000-0000-0000-000000000000"" +ALS --> Switch: ""200 OK""\n\ +"" { "fspId": "central-auth" }"" + +rnote over Switch #LightGray + Le hub a déterminé que « central-auth » est responsable du ""Consent"" 22222222-0000-0000-0000-000000000000 +end note + +Switch -> Auth ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +Auth --> Switch: ""202 Accepted"" +deactivate Switch + +Auth -> Auth: Marquer l'objet ""Consent"" comme « REVOKED » + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +rnote over Auth #LightGray + Le Auth Service doit également informer le DFSP du statut mis à jour +end note + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> DFSP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSPIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +DFSP --> Switch: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg new file mode 100644 index 000000000..46bcf01be --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg @@ -0,0 +1,164 @@ + + Liaison PISP : Dissociation + + + + Mojaloop + Liaison PISP : Dissociation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + Account Lookup Service + + Auth Service + + DFSP + + + Dans ce scénario, il n'y a pas de service d'authentification hébergé par le hub. Le DFSP est l'autorité sur l'objet + Consent + . + + + UNLINK-B-1 + DELETE /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSIOP-Destination: dfspa + + + UNLINK-B-2 + 202 Accepted + + + UNLINK-B-3 + GET /participants/CONSENT/22222222-0000-0000-0000-000000000000 + + + UNLINK-B-4 + 200 OK + { "fspId": "central-auth" } + + Le hub a déterminé que « central-auth » est responsable du + Consent + 22222222-0000-0000-0000-000000000000 + + + UNLINK-B-5 + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + UNLINK-B-6 + 202 Accepted + + + + + UNLINK-B-7 + Marquer l'objet + Consent + comme « REVOKED » + + + UNLINK-B-8 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-9 + 200 OK + + + UNLINK-B-10 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-11 + 200 OK + + Le Auth Service doit également informer le DFSP du statut mis à jour + + + UNLINK-B-12 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-13 + 200 OK + + + UNLINK-B-14 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-15 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml new file mode 100644 index 000000000..d6a89f192 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml @@ -0,0 +1,79 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : cas d'erreur de découverte + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Recherche d'un utilisateur pour **username1234** +DFSP -> DFSP: Aucun utilisateur trouvé + +DFSP -> Switch ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over Switch + Le PISP peut maintenant afficher un message d'erreur et l'utilisateur peut réessayer avec un autre nom d'utilisateur ou un autre DFSP. +end note + +... + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg new file mode 100644 index 000000000..748c4020d --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg @@ -0,0 +1,130 @@ + + Liaison PISP : cas d'erreur de découverte + + + Liaison PISP : cas d'erreur de découverte + + PISP + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + DISC-1 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-2 + 202 Accepted + + + DISC-3 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-4 + 202 Accepted + + + + + DISC-5 + Recherche d'un utilisateur pour + username1234 + + + + + DISC-6 + Aucun utilisateur trouvé + + + DISC-7 + PUT /accounts/username1234/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6205", +    + errorDescription: "No accounts found" +    + } +    + } + + + DISC-8 + 200 OK + + + DISC-9 + PUT /accounts/username1234/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6205", +    + errorDescription: "No accounts found" +    + } +    + } + + + DISC-10 + 200 OK + + + Le PISP peut maintenant afficher un message d'erreur et l'utilisateur peut réessayer avec un autre nom d'utilisateur ou un autre DFSP. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml new file mode 100644 index 000000000..ab12c0ff9 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml @@ -0,0 +1,162 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title **Liaison PISP : cas d'erreur consentRequest** + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +== Portées demandées non prises en charge == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: Le PISP a demandé des autorisations \npour accountId dfsp.username.91011 qui \n n'appartient pas à username1234 + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +== URI de rappel non fiable == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { **accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: Le callbackUri utilise le schéma http \nau lieu de https. Rejet du consentRequest + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg new file mode 100644 index 000000000..5069b7f1c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg @@ -0,0 +1,299 @@ + + **Liaison PISP : cas d'erreur consentRequest** + + + Liaison PISP : cas d'erreur consentRequest + + Mojaloop + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + Portées demandées non prises en charge + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.91011", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.91011", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + DFSP-1 + Le PISP a demandé des autorisations + pour accountId dfsp.username.91011 qui + n'appartient pas à username1234 + + + REQ-5 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6101", +    + errorDescription: "Unsupported scopes were requested" +    + } +    + } + + + REQ-6 + 200 OK + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6101", +    + errorDescription: "Unsupported scopes were requested" +    + } +    + } + + + REQ-8 + 200 OK + + + + + URI de rappel non fiable + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { **accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "http://phishing.com + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "http://phishing.com + " +    + } + + + REQ-4 + 202 Accepted + + + + + DFSP-1 + Le callbackUri utilise le schéma http + au lieu de https. Rejet du consentRequest + + + REQ-5 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6204", +    + errorDescription: "Bad callbackUri" +    + } +    + } + + + REQ-6 + 200 OK + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6204", +    + errorDescription: "Bad callbackUri" +    + } +    + } + + + REQ-8 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml new file mode 100644 index 000000000..dd1e8bbe6 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml @@ -0,0 +1,85 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Liaison PISP : Authentification — authToken invalide + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +... + +note over PISP, DFSP + L'utilisateur saisit un OTP incorrect pour l'authentification. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: L'OTP est incorrect. + +note over PISP, DFSP + Nous renvoyons une erreur indiquant que l'OTP est incorrect afin que le PISP puisse informer l'utilisateur. +end note + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg new file mode 100644 index 000000000..ed2ec290a --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg @@ -0,0 +1,132 @@ + + Liaison PISP : Authentification — authToken invalide + + + Liaison PISP : Authentification — authToken invalide + + Mojaloop + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + L'utilisateur saisit un OTP incorrect pour l'authentification. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + L'OTP est incorrect. + + + Nous renvoyons une erreur indiquant que l'OTP est incorrect afin que le PISP puisse informer l'utilisateur. + + + AUTH-6 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6203", +    + errorDescription: "Invalid authentication token" +    + } +    + } + + + AUTH-7 + 200 OK + + + AUTH-8 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6203", +    + errorDescription: "Invalid authentication token" +    + } +    + } + + + AUTH-9 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml new file mode 100644 index 000000000..ce6a98f9d --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +!pragma teoz true + +title Liaison PISP : Erreur de récupération des portées lors de l'octroi du consentement + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +== Cas d'échec == + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Vérification que l'OTP est correct. + +DFSP -> DFSP: Impossible de récupérer les portées stockées + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg new file mode 100644 index 000000000..9c0d41083 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg @@ -0,0 +1,127 @@ + + Liaison PISP : Erreur de récupération des portées lors de l'octroi du consentement + + + + Mojaloop + Liaison PISP : Erreur de récupération des portées lors de l'octroi du consentement + + + + + + + + + + + PISP + + Thirdparty-API-Adapter + + Account Lookup Service + + Auth Service + + DFSP + + + + + Cas d'échec + + + GRANT-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + GRANT-2 + 202 Accepted + + + GRANT-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + GRANT-4 + 202 Accepted + + + + + GRANT-5 + Vérification que l'OTP est correct. + + + + + GRANT-6 + Impossible de récupérer les portées stockées + + + GRANT-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "7207", +    + errorDescription: "FSP failed retrieve scopes for consent request" +    + } +    + } + + + GRANT-8 + 200 OK + + + GRANT-9 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "7207", +    + errorDescription: "FSP failed retrieve scopes for consent request" +    + } +    + } + + + GRANT-10 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml new file mode 100644 index 000000000..e08c14139 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.1 Découverte + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP B" + participant "DFSP B\n(Bénéficiaire)" as D3 +end box + + +== Découverte (recherche) == +rnote right of D1 #LightGray +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +end note +D1 -> S: ""GET /parties/MSISDN/+4412345678"" +S --> D1: ""202 Accepted"" + +... Flux de recherche ALS non représenté ici ... + +rnote over S #LightGray +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspb"" +end note +S -> D3: ""GET /parties/MSISDN/+4412345678"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /parties/MSISDN/+4412345678""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: pispa"" +{ + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + party: { + partyIdInfo: { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + fspId: 'dfspb", + }, + name: "Bhavesh S.", + } +} +end note +D3 -> S: ""PUT /parties/MSISDN/+4412345678"" +S --> D3: ""200 OK"" +S -> D1: ""PUT /parties/MSISDN/+4412345678"" +D1 --> S: ""200 OK"" + +... Le PISP confirme la partie bénéficiaire avec son utilisateur ... + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg new file mode 100644 index 000000000..70f9cb931 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg @@ -0,0 +1,89 @@ + + Transfert : 1.1 Découverte + + + Transfert : 1.1 Découverte + + PISP + + Mojaloop + + DFSP B + + + + + + + + + + + + + + + + + Serveur PISP + + Switch + + DFSP B + (Bénéficiaire) + + + + + Découverte (recherche) + + GET /parties/MSISDN/+4412345678 + FSPIOP-Source: pispa + + + GET /parties/MSISDN/+4412345678 + + + 202 Accepted + Flux de recherche ALS non représenté ici + + GET /parties/MSISDN/+4412345678 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspb + + + GET /parties/MSISDN/+4412345678 + + + 202 Accepted + + PUT /parties/MSISDN/+4412345678 + FSPIOP-Source: dfspb + FSPIOP-Destination: pispa + { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + party: { + partyIdInfo: { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + fspId: 'dfspb", + }, + name: "Bhavesh S.", + } + } + + + PUT /parties/MSISDN/+4412345678 + + + 200 OK + + + PUT /parties/MSISDN/+4412345678 + + + 200 OK + Le PISP confirme la partie bénéficiaire avec son utilisateur + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml new file mode 100644 index 000000000..95cc3600c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml @@ -0,0 +1,86 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.1 Accord + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + + +== Phase d'accord == +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" +D2 -> D2: Recherche du consentement pour ce ""payeur"", vérification de l'existence et que le consentement \nest accordé avec des identifiants valides +D2 -> D2: Stockage d'une référence au ""consentId"" avec le ""transactionRequestId"" +D2 -> D2: Génération d'un transactionId unique pour cette demande de transaction :\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg new file mode 100644 index 000000000..a9c5a2a1e --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg @@ -0,0 +1,114 @@ + + Transfert : 1.2.1 Accord + + + Transfert : 1.2.1 Accord + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + + + Phase d'accord + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + + + Recherche du consentement pour ce + payeur + , vérification de l'existence et que le consentement + est accordé avec des identifiants valides + + + + + Stockage d'une référence au + consentId + avec le + transactionRequestId + + + + + Génération d'un transactionId unique pour cette demande de transaction : + 11111111-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "RECEIVED" + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml new file mode 100644 index 000000000..e87398bbb --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml @@ -0,0 +1,150 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.2 Autorisation + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Bénéficiaire)" as D3 +end box + +rnote left of D2 #LightGray +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +rnote left of D2 #LightGray +**""PUT /quotes/22222222-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "transferAmount": { + "amount": "100", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeFspFee": { + "amount": "1", + "currency": "USD" + }, + "expiration": "2020-06-15T12:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note left of D2 + Le DFSP A dispose du devis, il peut maintenant demander + l'autorisation au PISP +end note + +D2 -> D2: Génération d'un UUID pour la demande d'autorisation :\n""33333333-0000-0000-0000-000000000000"" +D2 -> D2: Dérivation du défi à partir de \n""PUT /quotes/{ID}"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/authorizations""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "challenge": """", + "transferAmount": {"amount": "100", "currency": "USD"}, + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + "fees": {"amount": "1", "currency": "USD"}, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T12:00:00.000", +} +end note +D2 -> S: ""POST /thirdpartyRequests/authorizations"" +S --> D2: ""202 Accepted"" +S -> D1: ""POST /thirdpartyRequests/authorizations"" +D1 --> S: ""202 Accepted"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg new file mode 100644 index 000000000..26820b6b7 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg @@ -0,0 +1,174 @@ + + Transfert : 1.2.2 Autorisation + + + Transfert : 1.2.2 Autorisation + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + DFSP B + (Bénéficiaire) + + POST /quotes + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" + } + + + POST /quotes + + + 202 Accepted + + + POST /quotes + + + 202 Accepted + + PUT /quotes/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "transferAmount": { + "amount": "100", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeFspFee": { + "amount": "1", + "currency": "USD" + }, + "expiration": "2020-06-15T12:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + 200 OK + + + Le DFSP A dispose du devis, il peut maintenant demander + l'autorisation au PISP + + + + + Génération d'un UUID pour la demande d'autorisation : + 33333333-0000-0000-0000-000000000000 + + + + + Dérivation du défi à partir de + PUT /quotes/{ID} + + POST /thirdpartyRequests/authorizations + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "transferAmount": {"amount": "100", "currency": "USD"}, + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + "fees": {"amount": "1", "currency": "USD"}, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T12:00:00.000", + } + + + POST /thirdpartyRequests/authorizations + + + 202 Accepted + + + POST /thirdpartyRequests/authorizations + + + 202 Accepted + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml new file mode 100644 index 000000000..86cb06364 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml @@ -0,0 +1,76 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.3 Autorisation refusée + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +== Phase d'accord == +note right of D1 + Le PISP recherche le ""transactionRequestId"" et + vérifie le devis avec l'utilisateur, + + + L'utilisateur refuse les conditions de la demande de transaction +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "REJECTED" +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Recherche du ""transactionRequestId"" pour cet ""authorizationId"" + +note over D2 + L'utilisateur a refusé la demande de transaction. +end note + +rnote over D2 #LightGray +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "REJECTED", + "transactionId": "11111111-0000-0000-0000-000000000000", +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + Le PISP peut informer l'utilisateur que la transaction n'a pas eu lieu +end note + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg new file mode 100644 index 000000000..c8f4d8412 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg @@ -0,0 +1,93 @@ + + Transfert : 1.2.3 Autorisation refusée + + + Transfert : 1.2.3 Autorisation refusée + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + + + Phase d'accord + + + Le PISP recherche le + transactionRequestId + et + vérifie le devis avec l'utilisateur, +   +   + L'utilisateur refuse les conditions de la demande de transaction + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "REJECTED" + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + pour cet + authorizationId + + + L'utilisateur a refusé la demande de transaction. + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "REJECTED", + "transactionId": "11111111-0000-0000-0000-000000000000", + } + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + Le PISP peut informer l'utilisateur que la transaction n'a pas eu lieu + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml new file mode 100644 index 000000000..bfd850a0d --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml @@ -0,0 +1,74 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.3 Autorisation signée FIDO + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +== Phase d'accord == +note right of D1 + Le PISP recherche le ""transactionRequestId"" et + vérifie les conditions avec l'utilisateur. + + Si l'utilisateur accepte les conditions, le PISP + utilise l'API FIDO sur l'appareil de l'utilisateur pour signer + la chaîne **""challenge""** +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Recherche du ""transactionRequestId"" pour cet ""authorizationId"" +D2 -> D2: Recherche du ""consentId"" pour ce ""transactionRequestId"" + +note over D2 + Le DFSP dispose du défi signé. + Il doit maintenant demander au Auth-Service de vérifier + le défi signé. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg new file mode 100644 index 000000000..96a961f1f --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg @@ -0,0 +1,94 @@ + + Transfert : 1.2.3 Autorisation signée FIDO + + + Transfert : 1.2.3 Autorisation signée FIDO + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + + + Phase d'accord + + + Le PISP recherche le + transactionRequestId + et + vérifie les conditions avec l'utilisateur. +   + Si l'utilisateur accepte les conditions, le PISP + utilise l'API FIDO sur l'appareil de l'utilisateur pour signer + la chaîne + challenge + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + pour cet + authorizationId + + + + + Recherche du + consentId + pour ce + transactionRequestId + + + Le DFSP dispose du défi signé. + Il doit maintenant demander au Auth-Service de vérifier + le défi signé. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml new file mode 100644 index 000000000..5cbc94985 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml @@ -0,0 +1,63 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.3 Autorisation signée (générique) + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +== Phase d'accord == +note right of D1 + Le PISP recherche le ""transactionRequestId"" et + vérifie le devis avec l'utilisateur. + + Si l'utilisateur accepte les conditions, le PISP utilise + la clé privée du Credential pour signer le défi +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Recherche du ""transactionRequestId"" pour cet ""authorizationId"" +D2 -> D2: Recherche du ""consentId"" pour ce ""transactionRequestId"" + +note over D2 + Le DFSP dispose du défi signé. + Il doit maintenant demander au Auth-Service de vérifier + le défi signé. +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg new file mode 100644 index 000000000..2f103fd83 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg @@ -0,0 +1,82 @@ + + Transfert : 1.2.3 Autorisation signée (générique) + + + Transfert : 1.2.3 Autorisation signée (générique) + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + + + Phase d'accord + + + Le PISP recherche le + transactionRequestId + et + vérifie le devis avec l'utilisateur. +   + Si l'utilisateur accepte les conditions, le PISP utilise + la clé privée du Credential pour signer le défi + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + pour cet + authorizationId + + + + + Recherche du + consentId + pour ce + transactionRequestId + + + Le DFSP dispose du défi signé. + Il doit maintenant demander au Auth-Service de vérifier + le défi signé. + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml new file mode 100644 index 000000000..bbcda015e --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 1.2.4 Vérifier l'autorisation + + +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + + +D2 -> D2: Génération d'un nouveau ""verificationRequestId"", et association \n avec le ""thirdpartyTransactionRequestId"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Recherche de ce consentement à partir du consentId +AUTHS -> AUTHS: Vérification que accountAddress correspond au Consent +AUTHS -> AUTHS: Vérification que les octets signés correspondent à la \nclé publique stockée pour le consentement + +rnote right of AUTHS #LightGray +**""PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "authenticationResponse": "VERIFIED" +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note over D2 + Le DFSPA sait maintenant que l'utilisateur a signé cette transaction + et peut procéder à l'initiation du transfert +end note + + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg new file mode 100644 index 000000000..6bcf6278a --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg @@ -0,0 +1,106 @@ + + Transfert : 1.2.4 Vérifier l'autorisation + + + Transfert : 1.2.4 Vérifier l'autorisation + + Mojaloop + + DFSP A + + + + + Switch + + Auth-Service + + DFSP A + (Payeur) + + + + + Génération d'un nouveau + verificationRequestId + , et association + avec le + thirdpartyTransactionRequestId + + POST /thirdpartyRequests/verifications + FSPIOP-Source: dfspa + FSPIOP-Destination: central-auth + { + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + + + Recherche de ce consentement à partir du consentId + + + + + Vérification que accountAddress correspond au Consent + + + + + Vérification que les octets signés correspondent à la + clé publique stockée pour le consentement + + PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + "authenticationResponse": "VERIFIED" + } + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000 + + + 200 OK + + + Le DFSPA sait maintenant que l'utilisateur a signé cette transaction + et peut procéder à l'initiation du transfert + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml new file mode 100644 index 000000000..1f0000881 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml @@ -0,0 +1,178 @@ +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +hide footbox + +title Transfert : 1.3 Transfert final + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Bénéficiaire)" as D3 +end box +actor "<$actor>\nBénéficiaire" as CB + + + +== Phase de transfert == + +... Le DFSP A initie un transfert P2P Mojaloop classique ... + +D2 -> D2: Génération d'un nouveau ""transferId"", et association \n avec le ""transactionRequestId"" + +rnote over D2 #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /transfers/55555555-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "fulfilment": "...", + "completedTimestamp": "2020-06-15T12:01:00.000", + "transferState": "COMMITTED" +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +D3 -> CB: Vous avez reçu des fonds ! +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + + +D2 -> D2: Recherche du ""transactionRequestId"" à partir du ""transferId"" + +rnote over D2 #LightGray +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", + "transactionState": "COMMITTED" +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + Le PISP peut maintenant informer l'utilisateur que les + fonds ont été envoyés +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg new file mode 100644 index 000000000..5f26680e0 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg @@ -0,0 +1,161 @@ + + Transfert : 1.3 Transfert final + + + Transfert : 1.3 Transfert final + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + DFSP B + (Bénéficiaire) + + Bénéficiaire + + + + + + + Phase de transfert + Le DFSP A initie un transfert P2P Mojaloop classique + + + + + Génération d'un nouveau + transferId + , et association + avec le + transactionRequestId + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + PUT /transfers/55555555-0000-0000-0000-000000000000 + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "fulfilment": "...", + "completedTimestamp": "2020-06-15T12:01:00.000", + "transferState": "COMMITTED" + } + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + 200 OK + + + Vous avez reçu des fonds ! + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + à partir du + transferId + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "ACCEPTED", + "transactionState": "COMMITTED" + } + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + Le PISP peut maintenant informer l'utilisateur que les + fonds ont été envoyés + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml new file mode 100644 index 000000000..ffab1aed2 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml @@ -0,0 +1,90 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3.2.1 Demande de transaction tiers invalide + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + + +== Phase d'accord == +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: Le DFSP détecte un problème avec cette demande de transaction. + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6104", + "errorDescription": "Thirdparty request rejection", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg new file mode 100644 index 000000000..f0baefaf3 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg @@ -0,0 +1,101 @@ + + Transfert : 3.2.1 Demande de transaction tiers invalide + + + Transfert : 3.2.1 Demande de transaction tiers invalide + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + + + Phase d'accord + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + + + Le DFSP détecte un problème avec cette demande de transaction. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6104", + "errorDescription": "Thirdparty request rejection", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml new file mode 100644 index 000000000..66255721c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml @@ -0,0 +1,140 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3.3.1 Demande de devis invalide + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Bénéficiaire)" as D3 +end box + +... Le PISP a initié une demande de transaction tiers avec ""POST /thirdpartyRequests/transactions""... + +D2 -> D2: Génération d'un transactionId unique pour cette demande de transaction :\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +rnote left of D2 #LightGray +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +D3 -> D3: Le devis échoue pour une raison quelconque. + +rnote left of D3 #LightGray +**""PUT /quotes/22222222-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Échec du devis, le DFSP doit informer le PISP +end note + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream Failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg new file mode 100644 index 000000000..263cd491c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg @@ -0,0 +1,177 @@ + + Transfert : 3.3.1 Demande de devis invalide + + + Transfert : 3.3.1 Demande de devis invalide + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + DFSP B + (Bénéficiaire) + Le PISP a initié une demande de transaction tiers avec + POST /thirdpartyRequests/transactions + + + + + Génération d'un transactionId unique pour cette demande de transaction : + 11111111-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + POST /quotes + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" + } + + + POST /quotes + + + 202 Accepted + + + POST /quotes + + + 202 Accepted + + + + + Le devis échoue pour une raison quelconque. + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } + } + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + 200 OK + + + Échec du devis, le DFSP doit informer le PISP + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream Failure", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml new file mode 100644 index 000000000..b9913144c --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml @@ -0,0 +1,122 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3.3.2 Demande de transfert invalide + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Bénéficiaire)" as D3 +end box + +... Le PISP a initié une demande de transaction tiers avec ""POST /thirdpartyRequests/transactions""... + +... Le DFSP A a reçu le devis et a demandé au PISP de vérifier... + +... Le DFSP A a reçu ""PUT /thirdpartyRequests/verifications depuis Auth-Service""... + +... Le DFSP A initie un transfert P2P Mojaloop classique ... + +D2 -> D2: Génération d'un nouveau ""transferId"", et association \n avec le ""transactionRequestId"" + +rnote over D2 #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /transfers/55555555-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Échec du transfert, le DFSP doit informer le PISP +end note + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg new file mode 100644 index 000000000..8a98f4629 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg @@ -0,0 +1,172 @@ + + Transfert : 3.3.2 Demande de transfert invalide + + + Transfert : 3.3.2 Demande de transfert invalide + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + DFSP B + (Bénéficiaire) + Le PISP a initié une demande de transaction tiers avec + POST /thirdpartyRequests/transactions + Le DFSP A a reçu le devis et a demandé au PISP de vérifier + Le DFSP A a reçu + PUT /thirdpartyRequests/verifications depuis Auth-Service + Le DFSP A initie un transfert P2P Mojaloop classique + + + + + Génération d'un nouveau + transferId + , et association + avec le + transactionRequestId + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } + } + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + 200 OK + + + Échec du transfert, le DFSP doit informer le PISP + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream failure", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml new file mode 100644 index 000000000..6d11169f3 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml @@ -0,0 +1,95 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3.4.1 Défi signé invalide — Auth-Service auto-hébergé + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + +... Le PISP a initié une demande de transaction tiers avec ""POST /thirdpartyRequests/transactions""... + +... Le DFSP A a reçu le devis et a demandé au PISP de vérifier... + +note right of D1 + Le PISP recherche le ""transactionRequestId"" et + vérifie le devis avec l'utilisateur, + et utilise l'API FIDO pour signer + la chaîne **""challenge""** +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Recherche du ""transactionRequestId"" pour cet ""authorizationId"" +D2 -> D2: Recherche du ""consentId"" pour ce ""transactionRequestId"" +D2 -> D2: Recherche de la ""publicKey"" pour ce ConsentId. Vérification de la signature du défi signé + +note over D2 + Le défi signé est invalide. La demande de transaction a échoué. +end note + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg new file mode 100644 index 000000000..8ffa39b79 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg @@ -0,0 +1,133 @@ + + Transfert : 3.4.1 Défi signé invalide — Auth-Service auto-hébergé + + + Transfert : 3.4.1 Défi signé invalide — Auth-Service auto-hébergé + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + Le PISP a initié une demande de transaction tiers avec + POST /thirdpartyRequests/transactions + Le DFSP A a reçu le devis et a demandé au PISP de vérifier + + + Le PISP recherche le + transactionRequestId + et + vérifie le devis avec l'utilisateur, + et utilise l'API FIDO pour signer + la chaîne + challenge + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + pour cet + authorizationId + + + + + Recherche du + consentId + pour ce + transactionRequestId + + + + + Recherche de la + publicKey + pour ce ConsentId. Vérification de la signature du défi signé + + + Le défi signé est invalide. La demande de transaction a échoué. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml new file mode 100644 index 000000000..634c1c0de --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml @@ -0,0 +1,149 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3.4.2 Défi signé invalide — Auth-Service hébergé par le hub + + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + + +... Le PISP a initié une demande de transaction tiers avec ""POST /thirdpartyRequests/transactions""... + +... Le DFSP A a reçu le devis et a demandé au PISP de vérifier... + +note right of D1 + Le PISP recherche le ""transactionRequestId"" et + vérifie le devis avec l'utilisateur, + et utilise l'API FIDO pour signer + la chaîne **""challenge""** +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations""** +**"" /33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Recherche du ""transactionRequestId"" pour cet ""authorizationId"" +D2 -> D2: Recherche du ""consentId"" pour ce ""transactionRequestId"" + + +D2 -> D2: Génération d'un nouveau ""verificationRequestId"", et association \n avec le ""thirdpartyTransactionRequestId"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Recherche de ce consentement à partir du consentId +AUTHS -> AUTHS: Vérification que accountAddress correspond au Consent +AUTHS -> AUTHS: Vérification que les octets signés correspondent à la \nclé publique stockée pour le consentement + +rnote right of AUTHS #LightGray +**""PUT /thirdpartyRequests/verifications""** +**"" /44444444-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note over D2 + Le défi signé est invalide. La demande de transaction a échoué. +end note + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg new file mode 100644 index 000000000..abcc60bc0 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg @@ -0,0 +1,221 @@ + + Transfert : 3.4.2 Défi signé invalide — Auth-Service hébergé par le hub + + + Transfert : 3.4.2 Défi signé invalide — Auth-Service hébergé par le hub + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + + + + + + + + + + + + Serveur PISP + + Switch + + Auth-Service + + DFSP A + (Payeur) + Le PISP a initié une demande de transaction tiers avec + POST /thirdpartyRequests/transactions + Le DFSP A a reçu le devis et a demandé au PISP de vérifier + + + Le PISP recherche le + transactionRequestId + et + vérifie le devis avec l'utilisateur, + et utilise l'API FIDO pour signer + la chaîne + challenge + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Recherche du + transactionRequestId + pour cet + authorizationId + + + + + Recherche du + consentId + pour ce + transactionRequestId + + + + + Génération d'un nouveau + verificationRequestId + , et association + avec le + thirdpartyTransactionRequestId + + POST /thirdpartyRequests/verifications + FSPIOP-Source: dfspa + FSPIOP-Destination: central-auth + { + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + + + Recherche de ce consentement à partir du consentId + + + + + Vérification que accountAddress correspond au Consent + + + + + Vérification que les octets signés correspondent à la + clé publique stockée pour le consentement + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + + + 200 OK + + + Le défi signé est invalide. La demande de transaction a échoué. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml new file mode 100644 index 000000000..1c4813fe9 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml @@ -0,0 +1,77 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfert : 3. Expiration de la demande de transaction tiers + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + + +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + + +... Le DFSP ne répond pas pour une raison quelconque... + + +D1 -> D1: Expiration de la demande de transaction tiers atteinte + +note over D1 + Le PISP informe son utilisateur que la transaction a échoué. + +end note + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg new file mode 100644 index 000000000..f9b6ef19b --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg @@ -0,0 +1,81 @@ + + Transfert : 3. Expiration de la demande de transaction tiers + + + Transfert : 3. Expiration de la demande de transaction tiers + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + Le DFSP ne répond pas pour une raison quelconque + + + + + Expiration de la demande de transaction tiers atteinte + + + Le PISP informe son utilisateur que la transaction a échoué. +   + + diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml new file mode 100644 index 000000000..042816135 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml @@ -0,0 +1,67 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP — Obtenir la demande de transaction (GetTransactionRequest) + +box "PISP" +participant "Serveur PISP" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payeur)" as D2 +end box + +autonumber 1 "GTR-#" + +note over S + En supposant une demande de transaction tiers précédemment créée avec l'id : ""00000000-0000-0000-0000-000000000000"" + +end note + + + +rnote right of D1 #LightGray +**""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +end note + +D1 -> S: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D1: ""202 Accepted"" + +S -> D2: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: Le DFSP recherche la demande de transaction tiers déjà créée +D2 -> D2: Le DFSP vérifie que le FSPIOP-Source (pisp)\nest le même que l'émetteur d'origine du \n""POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg new file mode 100644 index 000000000..78f19c739 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg @@ -0,0 +1,85 @@ + + PISP — Obtenir la demande de transaction (GetTransactionRequest) + + + PISP — Obtenir la demande de transaction (GetTransactionRequest) + + PISP + + Mojaloop + + DFSP A + + + + + Serveur PISP + + Switch + + DFSP A + (Payeur) + + + En supposant une demande de transaction tiers précédemment créée avec l'id : + 00000000-0000-0000-0000-000000000000 +   + + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + + + GTR-1 + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-2 + 202 Accepted + + + GTR-3 + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-4 + 202 Accepted + + + + + GTR-5 + Le DFSP recherche la demande de transaction tiers déjà créée + + + + + GTR-6 + Le DFSP vérifie que le FSPIOP-Source (pisp) + est le même que l'émetteur d'origine du + POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "ACCEPTED", + } + + + GTR-7 + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-8 + 200 OK + + + GTR-9 + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-10 + 200 OK + + diff --git a/docs/fr/technical/api/thirdparty/data-models.md b/docs/fr/technical/api/thirdparty/data-models.md new file mode 100644 index 000000000..0ac85d4a4 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/data-models.md @@ -0,0 +1,253 @@ +# Modèles de données + +API Tierce Partie + +### Table des Matières + +1. [Préface](#Preface) + 1.1 [Conventions Utilisées dans ce Document](#ConventionsUsedinThisDocument) + 1.2 [Informations sur la Version du Document](#DocumentVersionInformation) + 1.3 [Références](#References) +2. [Introduction](#Introduction) + 2.1 [Spécification de l’API Tierce Partie](#ThirdPartyAPISpecification) +3. [Éléments de l’API Tierce Partie](#ThirdPartyAPIElements) + 3.1 [Ressources](#Resources) + 3.2 [Modèles de données](#DataModels) + 3.3 [Codes d’erreur](#ErrorCodes) +# 1. Préface +Cette section contient des informations sur l'utilisation de ce document. + +## 1.1 Conventions Utilisées dans ce Document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d’informations spécifiés. + +|Type d’Information|Convention|Exemple| +|---|---|---| +|**Éléments de l’API, tels que les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre chevrons|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans _Glossaire_|Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un bénéficiaire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne doivent généralement pas être utilisées par les déploiements de l’API ; les mesures de sécurité détaillées dans _Signature API et Chiffrement API_ doivent être utilisées à la place.| + +## 1.2 Informations sur la Version du Document + +| Version | Date | Description des Changements | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Version initiale + +## 1.3 Références + +Les références suivantes sont utilisées dans cette spécification : + +| Référence | Description | Version | Lien | +| --- | --- | --- | --- | +| Ref. 1 | Open API pour l’interopérabilité de FSP | `1.1` | [Définition API v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +Ce document spécifie le modèle de données utilisé par l’API Tierce Partie Mojaloop ("l’API"). + +## 2.1 Spécification de l’API Tierce Partie + +La spécification de l’API Tierce Partie Mojaloop comprend les documents suivants : + +- [Modèles de données](./data-models.md) +- [Modèles de transaction - Liaison](./transaction-patterns-linking.md) +- [Modèles de transaction - Transfert](./transaction-patterns-transfer.md) +- [Définition Open API Tierce Partie - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Définition Open API Tierce Partie - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Éléments de l’API Tierce Partie + +Cette section décrit le contenu de l’API qui sera utilisé par les PISP et DFSP. + +Le contenu de l’API se divise en deux sections : + +1. [Modèles de transaction - Liaison](./transaction-patterns-linking.md) décrit le processus de liaison des comptes clients et fournit un mécanisme d'autorisation générale pour permettre aux PISP d’effectuer des opérations sur ces comptes +2. [Modèles de transaction - Transfert](./transaction-patterns-transfer.md) décrit le transfert de fonds à l’instigation d’un PISP. + +L’API est utilisée par les différents types de participants suivants : + 1. PISP + 2. DFSP offrant à leurs clients des services leur permettant d'accéder à leur compte via un ou plusieurs PISP + 3. Auth-Services + 4. Le switch Mojaloop + +Chaque ressource dans la définition de l’API est accompagnée d’une définition du (des) type(s) de participant pouvant y accéder. + +## 3.1 Ressources + +L’API contient les ressources suivantes : + +### 3.1.1 **/accounts** + +La ressource **/accounts** est utilisée pour demander des informations à un DFSP concernant les comptes qu'il détient pour un identifiant donné. L'identifiant est une valeur fournie par l'utilisateur qu’il utilise pour accéder à son compte chez le DFSP, tel qu’un numéro de téléphone, une adresse e-mail ou tout autre identifiant précédemment fourni par le DFSP. + +Le DFSP retourne un ensemble d'informations sur les comptes qu'il est prêt à divulguer au PISP. +Le PISP peut ensuite afficher les noms des comptes à l'utilisateur et permettre à l’utilisateur de sélectionner les comptes qu’il souhaite lier via le PISP. + +La ressource **/accounts** prend en charge les endpoints décrits ci-dessous. + +#### 3.1.1.1 Requêtes + +Cette section décrit les services qu’un PISP peut demander sur la ressource /accounts. + +##### 3.1.1.1.1 **GET /accounts/**_{ID}_ + +Utilisé par : PISP + +La requête HTTP **GET /accounts/**_{ID}_ est utilisée pour rechercher des informations sur les comptes de l’utilisateur demandé, défini par un identifiant *{ID}*, où *{ID}* est un identifiant qu’un utilisateur utilise pour accéder à son compte chez le DFSP, tel qu’un numéro de téléphone, une adresse e-mail ou tout autre identifiant précédemment fourni par le DFSP. + +Informations sur le callback et le modèle de données pour **GET /accounts/**_{ID}_ : +- Callback - **PUT /accounts/**_{ID}_ +- Callback d’erreur - **PUT /accounts/**_{ID}_**/error** +- Modèle de données – corps vide + +#### 3.1.1.2 Callbacks + +Les réponses pour la ressource **/accounts** sont les suivantes : + +##### 3.1.1.2.1 **PUT /accounts/**_{ID}_ + +Utilisé par : DFSP + +La réponse **PUT /accounts/**_{ID}_ est utilisée pour informer le demandeur du résultat d'une demande d’informations de comptes. L’identifiant ID donné dans l’appel correspond à la valeur donnée dans la demande d’origine (voir la section 3.1.1.1.1 ci-dessus.) + +Le contenu des données du message est donné ci-dessous. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| accountList | 1 | AccountList | Informations sur les comptes que le DFSP associe à l’identifiant envoyé par le PISP. | + +##### 3.1.1.2.2 **PUT /accounts/**_{ID}_**/error** + +Utilisé par : DFSP + +La réponse **PUT /accounts/**_{ID}_**/error** est utilisée pour informer le demandeur qu’une demande de liste de comptes a généré une erreur. L’identifiant ID donné dans l’appel correspond aux valeurs données dans la demande d’origine (voir la section 3.1.1.1.1 ci-dessus.) + +Le contenu de données du message est donné ci-dessous. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Informations décrivant l’erreur et le code erreur. | + +### 3.1.2 **/consentRequests** + +La ressource **/consentRequests** est utilisée par un PISP pour initier le processus de liaison avec un compte DFSP au nom d’un utilisateur. Le PISP contacte le DFSP et envoie une liste des autorisations qu’il souhaite obtenir et les comptes pour lesquels il souhaite l'autorisation. + +#### 3.1.2.1 Requêtes + +Cette section décrit les services pouvant être demandés par un client sur la ressource API **/consentRequests**. + +##### 3.1.2.1.1 **GET /consentRequests/**_{ID}_ + +Utilisé par : PISP + +La requête HTTP **GET /consentRequests/**_{ID}_ est utilisée pour obtenir des informations sur un consentement précédemment demandé. Le *{ID}* dans l’URI doit contenir le consentRequestId qui a été attribué à la demande par le PISP lors de la création de la demande. + +Informations de callback et modèle de données pour **GET /consentRequests/**_{ID}_ : +- Callback – **PUT /consentRequests/**_{ID}_ +- Callback d’erreur – **PUT /consentRequests/**_{ID}_**/error** +- Modèle de données – corps vide + +##### 3.1.2.1.2 **POST /consentRequests** + +Utilisé par : PISP + +La requête HTTP **POST /consentRequests** est utilisée pour demander à un DFSP d’accorder l’accès à un ou plusieurs comptes appartenant à un client du DFSP pour le PISP qui envoie la demande. + +Callback et modèle de données pour **POST /consentRequests** : +- Callback : **PUT /consentRequests/**_{ID}_ +- Callback d’erreur : **PUT /consentRequests/**_{ID}_**/error** +- Modèle de données – voir ci-dessous + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| consentRequestId | 1 | CorrelationId | ID commun entre le PISP et le DFSP payeur pour l’objet de demande de consentement. L’ID doit être réutilisé pour les renvois de la même demande. Un nouvel ID doit être généré pour chaque nouvelle demande. | +| userId | 1 | String(1..128) | L'identifiant utilisé dans **GET /accounts/**_{ID}_. Utilisé par le DFSP pour mettre en corrélation une recherche de compte avec une `consentRequest` | +| scopes | 1..256 | Scope | Une ou plusieurs demandes d’accès à un compte particulier. Dans chaque cas, l’adresse du compte et les types d’accès requis sont donnés. | +| authChannels | 1..256 | ConsentRequestChannelType | Une collection des types d’authentification que le DFSP peut utiliser pour vérifier que son client a effectivement demandé l’accès pour le PISP aux comptes demandés. | +| callbackUri | 1 | Uri | L’URI de redirection où l’utilisateur sera redirigé après vérification via le canal d’autorisation WEB. Ce champ est obligatoire car le PISP ne sait pas à l’avance quel AuthChannel le DSFP utilisera pour authentifier son utilisateur. | + +#### 3.1.2.2 Callbacks + +Cette section décrit les callbacks utilisés par le serveur sous la ressource /consentRequests. + +##### 3.1.2.2.1 **PUT /consentRequests/**_{ID}_ + +Utilisé par : DFSP + +Un DFSP utilise ce callback pour (1) informer le PISP que la demande de consentement a été acceptée, et +(2) communiquer au PISP le `authChannel` qu’il doit utiliser pour authentifier son utilisateur. + +Lorsque le PISP demande une série d’autorisations à un DFSP pour le compte d’un client du DFSP, il se peut que tous les droits ne soient pas accordés par le DFSP. Inversement, le processus d’autorisation hors bande peut aboutir à l’octroi de privilèges supplémentaires au PISP par le possesseur du compte. La ressource **PUT /consentRequests/**_{ID}_ retourne l’état courant des droits relatifs à une demande d’autorisation en particulier. Le modèle de données pour cet appel est le suivant : + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| scopes | 1..256 | Scope | Une ou plusieurs demandes d’accès à un compte particulier. Dans chaque cas, l’adresse et les types d’accès demandés sont renseignés. | +| authChannels | 1 | ConsentRequestChannelType | Une liste d’un élément, que le DFSP utilise pour informer le PISP du canal d’autorisation choisi. | +| callbackUri | 0..1 | Uri | L’URI de rappel où l’utilisateur sera redirigé après la vérification via le canal WEB. | +| authUri | 0..1 | Uri | L’URI que le PISP doit appeler pour terminer la procédure s’il faut la compléter. | + + +##### 3.1.2.2.2 **PATCH /consentRequests/**_{ID}_ + +Utilisé par : PISP + +Après que l’utilisateur a complété une autorisation hors bande avec le DFSP, le PISP recevra +un jeton qu’il pourra utiliser pour prouver au DFSP que l’utilisateur fait confiance à ce PISP. + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| authToken | 1 | BinaryString |Le jeton donné au PISP par le DFSP dans le cadre du processus d’authentification hors bande | + +#### 3.1.2.3 Callbacks d’Erreur + +Cette section décrit les callbacks d’erreur utilisés par le serveur sous la ressource +**/consentRequests**. + +##### 3.1.2.3.1 **PUT /consentRequests/**_{ID}_**/error** + +Utilisé par : DFSP + +Si le serveur ne peut pas compléter la demande de consentement, ou si une erreur de traitement hors bande ou une autre erreur se produit, le callback d’erreur **PUT /consentRequests/**_{ID}_**/error** est utilisé. Le *{ID}* dans l’URI doit contenir *{ID}* utilisé dans la requête **GET /consentRequests/**_{ID}_ +ou la requête **POST /consentRequests**. Le modèle de données pour cette ressource est : + +| Nom | Cardinalité | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Informations décrivant l’erreur et le code erreur. | + +## 3.3 Codes d’erreur + +Les codes d’erreur de l’API tierce partie sont définis dans la [Section 7.6](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#76-error-codes) de la Réf. 1 ci-dessus. + +En outre, l’API tierce partie ajoute les codes d’erreur suivants, préfixés par `6` : + +- Erreur générale tierce partie — **60**_xx_ + +| **Code d’erreur** | **Nom** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6000** | Erreur tierce partie | Erreur générique. | X | X | X | X | X | X | X | X | +| **6001** | Erreur de demande tierce partie | Échec de la demande tierce partie. | X | X | X | X | X | X | X | X | +| **6003** | Échec aval | La demande aval a échoué. | X | X | X | X | X | X | X | X | + +- Erreur de permission — **61**_xx_ + +| **Code d’erreur** | **Nom** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6100** | Rejet d’authentification | Rejet d’authentification générique | | X | | | | X | | | +| **6101** | Étendues non prises en charge | Le PISP a demandé des étendues que le DFSP n’autorise ou ne prend pas en charge | | X | X | | | | | | +| **6102** | Consentement non accordé | L’utilisateur n’a pas accordé son consentement au PISP | | X | X | | | | | | +| **6103** | Consentement non valide | L’objet Consent n’est pas valide ou a été révoqué | | X | X | | | X | X | X | +| **6104** | Rejet de demande tierce partie | La demande a été rejetée | X | X | X | X | X | X | X | X | + +- Erreur de validation — **62**_xx_ + +| **Code d’erreur** | **Nom** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6200** | Justificatif de consentement invalide | La signature du justificatif soumis par le PISP est invalide | | | X | | | | | | +| **6201** | Signature de transaction invalide | La signature de la réponse de vérification ne correspond pas au justificatif | | | | | | X | | X | +| **6203** | Jeton d’authentification invalide | Le DFSP reçoit un jeton d’authentification invalide du PISP | | X | | | | | | | +| **6204** | callbackUri invalide | Le callbackUri est jugé invalide ou non fiable | | X | | | | | | | +| **6205** | Aucun compte trouvé | Aucun compte n’a été trouvé pour l’identifiant donné | X | | | | | | | | + diff --git a/docs/fr/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml b/docs/fr/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml new file mode 100644 index 000000000..327d244dd --- /dev/null +++ b/docs/fr/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml @@ -0,0 +1,2625 @@ +openapi: 3.0.2 +info: + title: Mojaloop Third Party API (DFSP) + version: '1.0' + description: | + A Mojaloop API for DFSPs supporting Third Party functions. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) to perform actions on behalf of a DFSP's user should implement this API. + PISPs should implement the accompanying API - Mojaloop Third Party API (PISP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: 'The object sent in a `PUT /accounts/{ID}` request.' + properties: + accountList: + description: Information about the accounts that the DFSP associates with the identifier sent by the PISP + type: array + items: + title: Account + type: object + description: Data model for the complex type Account. + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + required: + - accountNickname + - id + - currency + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: The object sent in a `POST /consentRequests` request. + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: Scope + Account Identifier mapping for a Consent. + properties: + address: + title: AccountAddress + type: string + description: | + An address which can be used to identify the account. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + description: | + The permissions allowed on a given account by a DFSP as defined in + a consent object + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user’s account + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consentRequest. + - "WEB" - The Web auth channel. + - "OTP" - The OTP auth channel. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: 'The object sent in a `PATCH /consentRequests/{ID}` request.' + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consents: + parameters: + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for resends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatus + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatus + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: | + The type of the Credential. + - "FIDO" - A FIDO public/private keypair + - "GENERIC" - A Generic public/private keypair + status: + title: CredentialStatus + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/credential/properties/payload' + required: + - credentialType + - status + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + type: string + enum: + - VERIFIED + description: 'The Credential is valid, and ready to be used by the PISP.' + payload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + - payload + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: POST /thirdpartyRequests/authorizations request object. + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer’s account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer’s account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/signedPayloadType' + fidoSignedPayload: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/fidoSignedPayload' + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/1/properties/signedPayloadType' + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: The object sent in the POST /thirdpartyRequests/transactions request. + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + $ref: '#/paths/~1accounts~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/accountList/items/properties/currency' + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdPartyRequests/transactions/{ID} request.' + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: 'The object sent in the PATCH /thirdpartyRequests/transactions/{ID} callback.' + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/verifications: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - thirdpartyRequests + - sampled + operationId: PostThirdpartyRequestsVerifications + summary: PostThirdpartyRequestsVerifications + description: | + The HTTP request `POST /thirdpartyRequests/verifications` is used by the DFSP to verify a third party authorization. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The thirdparty authorization details to verify + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsVerificationsPostRequestFIDO + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + An object sent in a `PUT /thirdpartyRequests/authorization/{ID}` request. + based mostly on: https://webauthn.guide/#authentication + AuthenticatorAssertionResponse + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - fidoSignedPayload + - title: ThirdpartyRequestsVerificationsPostRequestGeneric + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - genericSignedPayload + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyRequestsVerificationsById + summary: GetThirdpartyRequestsVerificationsById + description: | + The HTTP request `/thirdpartyRequests/verifications/{ID}` is used to get + information regarding a previously created or requested authorization. The *{ID}* + in the URI should contain the verification request ID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsById + summary: PutThirdpartyRequestsVerificationsById + description: | + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}` is used by the Auth-Service to inform + the DFSP of a successful result in validating the verification of a Thirdparty Transaction Request. + + If the validation fails, The Auth-Service MUST use `PUT /thirdpartyRequests/verifications/{ID}/error` + instead. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The result of validating the Thirdparty Transaction Request + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsVerificationsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdpartyRequests/verifications/{ID} request.' + properties: + authenticationResponse: + type: string + enum: + - VERIFIED + description: The verification passed + required: + - authenticationResponse + example: + authenticationResponse: VERIFIED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsByIdAndError + summary: PutThirdpartyRequestsVerificationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}/error` is used by the Auth-Service to inform + the DFSP of a failure in validating or looking up the verification of a Thirdparty Transaction Request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' diff --git a/docs/fr/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml b/docs/fr/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml new file mode 100644 index 000000000..cb9f52f27 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml @@ -0,0 +1,2830 @@ +openapi: 3.0.1 +info: + title: Mojaloop Third Party API (PISP) + version: '1.0' + description: | + A Mojaloop API for Payment Initiation Service Providers (PISPs) to perform Third Party functions on DFSPs' User's accounts. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) should implement the accompanying API - Mojaloop Third Party API (DFSP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: 'The object sent in a `PUT /accounts/{ID}` request.' + properties: + accountList: + description: Information about the accounts that the DFSP associates with the identifier sent by the PISP + type: array + items: + title: Account + type: object + description: Data model for the complex type Account. + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + required: + - accountNickname + - id + - currency + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: The object sent in a `POST /consentRequests` request. + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: Scope + Account Identifier mapping for a Consent. + properties: + address: + title: AccountAddress + type: string + description: | + An address which can be used to identify the account. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + description: | + The permissions allowed on a given account by a DFSP as defined in + a consent object + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user’s account + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consentRequest. + - "WEB" - The Web auth channel. + - "OTP" - The OTP auth channel. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: 'The object sent in a `PATCH /consentRequests/{ID}` request.' + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consents: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for resends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatus + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatus + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: | + The type of the Credential. + - "FIDO" - A FIDO public/private keypair + - "GENERIC" - A Generic public/private keypair + status: + title: CredentialStatus + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/credential/properties/payload' + required: + - credentialType + - status + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + type: string + enum: + - VERIFIED + description: 'The Credential is valid, and ready to be used by the PISP.' + payload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + - payload + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: POST /thirdpartyRequests/authorizations request object. + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer’s account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer’s account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + An object sent in a `PUT /thirdpartyRequests/authorization/{ID}` request. + based mostly on: https://webauthn.guide/#authentication + AuthenticatorAssertionResponse + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: The object sent in the POST /thirdpartyRequests/transactions request. + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/merchantClassificationCode' + name: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/name' + personalInfo: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/personalInfo' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + $ref: '#/paths/~1accounts~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/accountList/items/properties/currency' + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdPartyRequests/transactions/{ID} request.' + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: 'The object sent in the PATCH /thirdpartyRequests/transactions/{ID} callback.' + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}': + parameters: + - name: Type + in: path + required: true + schema: + type: string + description: 'The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`.' + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesByTypeAndID + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesByTypeAndID2 + parameters: + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + title: PartiesTypeIDPutResponse + type: object + description: 'The object sent in the PUT /parties/{Type}/{ID} callback.' + properties: + party: + title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. An ExtensionList element has been added to this reqeust in version v1.1 + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + description: |- + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. + - EMAIL - An email is used as reference to a participant. The format of the email should be according to the informational [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. + partyIdentifier: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partyIdentifier' + partySubIdOrType: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partySubIdOrType' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + required: + - party + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubI}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - name: SubId + in: path + required: true + schema: + type: string + description: 'A sub-identifier of the party identifier, or a sub-type of the party identifier''s type. For example, `PASSPORT`, `DRIVING_LICENSE`.' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesSubIdByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesSubIdByTypeAndIDPut + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubId}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesSubIdErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D~1%7BSubId%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}': + parameters: + - name: ServiceType + in: path + required: true + schema: + type: string + description: 'The type of the service identifier. For example, `THIRD_PARTY_DFSP`' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetServicesByServiceType + summary: GetServicesByServiceType + description: | + The HTTP request `GET /services/{ServiceType}` is used to retrieve the list of participants + that support a specified service. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - services + - sampled + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /services/{ServiceType}` is used to return list of participants + that support a specified service. + operationId: PutServicesByServiceType + summary: PutServicesByServiceType + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ServicesServiceTypePutResponse + type: object + description: 'The object sent in a `PUT /services/{ServiceType}` request.' + properties: + providers: + type: array + minLength: 0 + maxLength: 256 + items: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + required: + - providers + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}/error': + parameters: + - $ref: '#/paths/~1services~1%7BServiceType%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /services/{ServiceType}/error` is used to return error information + operationId: PutServicesByServiceTypeAndError + summary: PutServicesByServiceTypeAndError + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' diff --git a/docs/fr/technical/api/thirdparty/transaction-patterns-linking.md b/docs/fr/technical/api/thirdparty/transaction-patterns-linking.md new file mode 100644 index 000000000..8ad073ae8 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/transaction-patterns-linking.md @@ -0,0 +1,312 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Modèles de transaction - Liaison + +API Tiers de Mojaloop + +### Table des Matières + +1. [Préface](#Preface) + 1.1 [Conventions utilisées dans ce document](#ConventionsUsedinThisDocument) + 1.2 [Informations sur la version du document](#DocumentVersionInformation) + 1.3 [Références](#References) +2. [Introduction](#Introduction) + 2.1 [Spécification de l'API Tiers](#ThirdPartyAPISpecification) +3. [Liaison](#Linking) + 3.1 [Pré-liaison](#Pre-linking) + 3.2 [Découverte](#Discovery) + 3.3 [Demande de consentement](#Requestconsent) + 3.4 [Authentification](#Authentication) + 3.5 [Octroi du consentement](#Grantconsent) + 3.6 [Enregistrement du justificatif](#Credentialregistration) +4. [Déliaison](#Unlinking) + 4.1 [Déliaison sans service d'authentification hébergé par le Switch](#UnlinkingwithoutaSwitchHostedAuthService) + 4.2 [Déliaison avec service d'authentification hébergé par le Switch](#UnlinkingwithaSwitchHostedAuthService) +5. [Scénarios d'Erreur](#ErrorScenarios) + 5.1 [Découverte](#Discovery-1) + 5.2 [Erreurs sur les demandes de consentement](#BadconsentRequests) + 5.3 [Authentification](#Authentication-1) + 5.4 [Octroi du consentement](#Grantconsent-1) + +# 1. Préface + +Cette section contient des informations sur la façon d'utiliser ce document. + +## 1.1. Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les informations spécifiées. + +|Type d'information|Convention|Exemple| +|---|---|---| +|**Éléments de l'API, tels que les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre chevrons|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans _Glossaire_|Le but de l'API est de permettre des transactions financières interopérables entre un _Payeur_ (une personne qui paie dans une transaction) localisé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (une personne qui reçoit des fonds) localisé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations sur l'utilisateur ne doivent généralement pas être utilisées par les déploiements de l'API ; les mesures de sécurité détaillées dans _Signature API et Chiffrement API_ doivent être utilisées à la place.| + +## 1.2. Informations sur la version du document + +| Version | Date | Description des modifications | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Version initiale + +## 1.3. Références + +Les références suivantes sont utilisées dans cette spécification : + +| Référence | Description | Version | Lien | +| --- | --- | --- | --- | +| Réf. 1 | API Ouvert pour l'Interopérabilité FSP | `1.1` | [Définition de l'API v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +Ce document présente les modèles de transaction supportés par l’API Tiers relatifs à l’établissement d’une relation entre un Utilisateur, un DFSP et un PISP. + +Le style architectural et la conception de cette API sont basés sur la [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) de la Réf. 1 ci-dessus. + +## 2.1 Spécification de l'API Tiers + +La spécification de l'API Tiers Mojaloop inclut les documents suivants : + +- [Modèles de données](./data-models.md) +- [Modèles de transactions - Liaison](./transaction-patterns-linking.md) +- [Modèles de transactions - Transfert](./transaction-patterns-transfer.md) +- [Définition de l'API ouverte tierce partie – DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Définition de l'API ouverte tierce partie – PISP](./thirdparty-pisp-v1.0.yaml) + + +# 3. Liaison + +L'objectif du processus de liaison est d'expliquer comment les utilisateurs établissent la confiance entre les trois parties intéressées : + +1. Utilisateur +2. DFSP où l'utilisateur détient un compte +3. PISP sur lequel l'utilisateur veut compter pour initier les paiements + +La liaison est divisée en plusieurs phases distinctes : + +1. **Pré-liaison** + Dans cette phase, un PISP demande quels DFSP sont disponibles pour être liés. +2. **Demande de consentement** + Dans cette phase, un PISP tente d’établir la confiance entre les 3 parties. +3. **Authentification** + Dans cette phase, l'utilisateur prouve son identité à son DFSP. +4. **Octroi du consentement** + Dans cette phase, un PISP prouve au DFSP que l'utilisateur et le PISP ont établi la confiance, et ainsi, le DFSP confirme que la confiance mutuelle existe entre les 3 parties. +5. **Enregistrement du justificatif** + Dans cette phase, un utilisateur crée le justificatif qu'il utilisera pour consentir à des transferts futurs du DFSP initiés par le PISP. + +## 3.1 Pré-liaison + +Dans cette phase, un serveur PISP doit connaître les DFSP disponibles pour être liés. Ceci est *peu probable* d’être fait à la demande (par exemple, quand un utilisateur clique sur "lier" dans l’application mobile du PISP), et plus probablement réalisé périodiquement et mis en cache par le serveur PISP. La raison est que de nouveaux DFSP ne rejoignent généralement pas le réseau Mojaloop très fréquemment, donc appeler ceci plusieurs fois dans la même journée donnerait probablement les mêmes résultats. Nous recommandons que le PISP fasse cette requête une fois par jour pour maintenir la liste des DFSPs à jour. + +L'objectif final de cette phase est que le serveur PISP dispose d'une liste finale de DFSPs disponibles ainsi que de toutes les métadonnées utiles nécessaires pour débuter le processus de liaison. + +Le PISP peut afficher cette liste de DFSPs à l'utilisateur, et l'utilisateur peut sélectionner le DFSP avec lequel il détient un compte à lier. + +![Pré-liaison](./assets/diagrams/linking/0-pre-linking.svg) + +## 3.2 Découverte + +Dans cette phase, on demande à l'utilisateur de sélectionner le type et la valeur de l'identifiant qu'il utilise avec le DFSP avec lequel il souhaite se lier. Cela peut être un nom d'utilisateur, un MSISDN (numéro de téléphone), ou une adresse e-mail. + +Le résultat de cette phase est une liste de comptes potentiels disponibles pour la liaison. L'utilisateur choisira ensuite un ou plusieurs de ces comptes sources et le PISP les fournira au DFSP lors de la demande de consentement. + +Le DFSP PEUT renvoyer un « accountNickname » au PISP dans la liste des comptes. Cette liste sera affichée à l'utilisateur dans l’application PISP pour qu’il sélectionne quels comptes il souhaite lier. Un DFSP pourrait masquer une partie du surnom selon ses exigences pour afficher les informations sur le compte sans authentifier l’utilisateur. + +**REMARQUE :** Lors de l’utilisation du canal d’authentification Web, il est possible que les choix faits (c’est à dire, les comptes à lier) soient remplacés par l'utilisateur dans une vue web. L’utilisateur peut donc décider, pendant la phase d’Authentification, de lier un compte différent de celui d’origine. Cela est parfaitement acceptable et doit être attendu de temps à autre. + +![Découverte](./assets/diagrams/linking/1-discovery.svg) + +## 3.3 Demande de consentement + +Dans cette phase, un PISP demande à un DFSP spécifique de démarrer le processus d’établissement du consentement entre trois parties : + +1. Le PISP +2. Le DFSP spécifié +3. Un utilisateur présumé client du DFSP ci-dessus + +La demande de consentement du PISP doit inclure plusieurs éléments importants : + +- Les canaux d’authentification acceptables pour l’utilisateur +- Les étendues nécessaires dans le cadre du consentement (ici, presque toujours, seulement la possibilité de voir le solde d’un compte spécifique et d’envoyer des fonds depuis un compte). + +Certaines informations dépendent du canal d’authentification utilisé (Web ou OTP). Si le canal Web est utilisé, les informations supplémentaires suivantes sont requises : + +- Un URI de rappel vers lequel l’utilisateur peut être redirigé avec toute information supplémentaire. + +Le résultat de cette phase dépend du canal d’authentification utilisé : + +### 3.3.1 Web + +Dans le canal d’authentification Web, le résultat est que le PISP reçoit une URL spécifique où cet utilisateur devrait être redirigé. Cette URL doit être un endroit où l’utilisateur peut prouver son identité (par exemple, via une connexion classique). + +![Demande de consentement](./assets/diagrams/linking/2-request-consent-web.svg) + +### 3.3.2 OTP / SMS + +Dans le canal d’authentification OTP, le DFSP envoie un message OTP « hors bande » à son utilisateur (par exemple, par SMS ou e-mail). Le PISP demande à l'utilisateur ce code OTP, et l'inclut dans le champ « authToken » lors du rappel **PATCH /consentRequests/**_{ID}_. + +![Demande de consentement](./assets/diagrams/linking/2-request-consent-otp.svg) + +## 3.4 Authentification + +Dans la phase d’authentification, il est attendu de l’utilisateur qu’il prouve son identité auprès du DFSP. Une fois cela fait, le DFSP fournira à l’utilisateur un certain type de secret (par exemple, un OTP ou un token d’accès). Ce secret sera alors transmis au PISP afin que celui-ci puisse démontrer une chaîne de confiance : + +- Le DFSP fait confiance à l'utilisateur +- Le DFSP donne un secret à l'utilisateur +- L'utilisateur fait confiance au PISP +- L'utilisateur transmet le secret reçu du DFSP au PISP +- Le PISP donne le secret au DFSP +- Le DFSP vérifie que le secret est correct + +Cette chaîne aboutit à la conclusion suivante : le DFSP peut faire confiance au PISP pour agir pour le compte de l’utilisateur, et une confiance mutuelle existe entre les trois parties. + +Le processus d’établissement de cette chaîne de confiance dépend du canal d’authentification utilisé : + +### 3.4.1 Web + +Dans le canal Web, le PISP utilise le champ `authUri` renvoyé lors du rappel **PUT /consentRequests/**_{ID}_ pour rediriger l’utilisateur vers le site web du DFSP où il pourra prouver son identité (probablement via un identifiant et mot de passe classique). + +**Remarque:** Notez qu’à ce stade, l’utilisateur peut modifier ses choix de comptes à lier. Le résultat sera visible plus tard lors de la phase d'octroi du consentement, dans laquelle le DFSP fournira les bonnes valeurs au PISP dans le champ `scopes`. + +![Authentification (Web)](./assets/diagrams/linking/3-authentication-web.svg) + +### 3.4.2 OTP + +Lors de l’utilisation du canal OTP, le DFSP enverra à l’utilisateur un mot de passe à usage unique via un canal préétabli (comme un SMS). Le PISP doit alors demander à l’utilisateur ce mot de passe à usage unique et le renvoyer au DFSP via l’appel API **PATCH /consentRequests/**_{ID}_. + +![Authentification (OTP)](./assets/diagrams/linking/3-authentication-otp.svg) + +## 3.5 Octroi du consentement + +Maintenant que la confiance mutuelle a été établie entre les trois parties, le DFSP est capable de créer un enregistrement de ce fait en créant une nouvelle ressource Consent. Cette ressource enregistrera toutes les informations pertinentes sur la relation entre les trois parties, et contiendra éventuellement des informations supplémentaires sur la manière dont l’utilisateur pourra prouver son consentement pour chaque transfert futur. + +Cette phase consiste exclusivement à ce que le DFSP demande à ce qu’un nouveau consentement soit créé. + +![Octroi du consentement](./assets/diagrams/linking/4-grant-consent.svg) + +## 3.6 Enregistrement du justificatif + +Une fois la ressource de consentement créée, le PISP tentera d’établir avec le DFSP le justificatif qui devra être utilisé pour vérifier que l'utilisateur donne son consentement pour chaque transfert futur. + +Cela se fera en stockant un justificatif FIDO (par exemple, une clé publique) sur le service Auth à l'intérieur de la ressource de consentement. Lors des futurs transferts, il sera demandé que ces transferts soient signés numériquement par le credential FIDO (ici la clé privée) pour être considérés comme valides. + +Cet enregistrement du justificatif est composé de trois phases : (1) dériver le challenge, (2) enregistrer le justificatif, et (3) finaliser le consentement. + +### 3.6.1 Dérivation du challenge + +Le PISP doit dériver le challenge qui sera utilisé comme entrée dans l’étape d'enregistrement de clé FIDO. Ce challenge ne doit pas pouvoir être deviné à l’avance par le PISP. + +1. _Soit `consentId` la valeur de `body.consentId` dans la requête **POST /consents**_ +2. _Soit `scopes` la valeur de `body.scopes` dans la requête **POST /consents**_ + +3. Le PISP doit construire l'objet JSON `rawChallenge` +``` +{ + "consentId": , + "scopes": +} +``` + +4. Ensuite, le PISP doit convertir cet objet JSON en une chaîne au format Canonical JSON RFC-8785 ([RFC-8785 Canonical JSON format](https://tools.ietf.org/html/rfc8785)) + +5. Enfin, le PISP doit calculer un hash SHA-256 de la chaîne JSON canonique, c'est-à-dire : `SHA256(CJSON(rawChallenge))` + +La sortie de cet algorithme, `challenge`, sera utilisée comme défi lors du [flux d'enregistrement FIDO](https://webauthn.guide/#registration) + +### 3.6.2 Enregistrement du justificatif + +Une fois le challenge dérivé, le PISP générera un nouveau justificatif sur le dispositif, signera numériquement le challenge, et fournira des informations supplémentaires sur le justificatif dans la ressource Consent : + +1. L’objet `PublicKeyCredential` — qui contient l’ID de la clé et une [AuthenticatorAttestationResponse](https://w3c.github.io/webauthn/#iface-authenticatorattestationresponse) contenant la clé publique +2. Un champ `credentialType` à la valeur `FIDO` +3. Un champ `status` avec la valeur `PENDING` + +> **Remarque :** Objets Credential génériques +> Bien que nous soyons concentrés d’abord sur FIDO, il est possible que certains PISP souhaitent offrir des services aux utilisateurs via d’autres canaux, par ex. USSD ou SMS. L’API prend donc aussi en charge un type `GENERIC`, par exemple : +>``` +> CredentialTypeGeneric { +> credentialType: 'GENERIC' +> status: 'PENDING', +> payload: { +> publicKey: base64(...), +> signature: base64(...), +> } +> } +>``` + +Le DFSP reçoit l’appel **PUT /consents/**_{ID}_ du PISP, et valide éventuellement l'objet Credential inclus dans la requête. Le DFSP demande ensuite au service Auth de créer l’objet `Consent` et de valider le justificatif. + +Si le DFSP reçoit un rappel **PUT /consents/**_{ID}_ du service Auth, avec un `credential.status` à `VERIFIED`, il sait que le justificatif est valide selon le service Auth. + +Sinon, s’il reçoit un rappel **PUT /consents/**_{ID}_**/error**, il sait que quelque chose a mal tourné lors de l’enregistrement du consentement et du justificatif associé, et peut informer le PISP en conséquence. + +Le service Auth est ensuite responsable d'appeler **POST /participants/CONSENTS/**_{ID}_. +Cet appel associera le `consentId` au `participantId` du service Auth et permettra de retrouver plus tard le service Auth correspondant. + +![Enregistrement du justificatif : Enregistrement](./assets/diagrams/linking/5a-credential-registration.svg) + +### 3.6.3 Finalisation du consentement + +Une fois que le DFSP est sûr que le justificatif est valide, il appelle **POST /participants/THIRD_PARTY_LINK/**_{ID}_ pour chaque compte dans la liste `Consent.scopes`. Cette entrée représente le lien entre le compte du PISP et celui du DFSP, que le PISP pourra utiliser pour spécifier la _source des fonds_ lors de la demande de transaction. + +Enfin, le DFSP appelle **PUT /consent/**_{ID}_ avec l'objet Consent finalisé reçu du service Auth. + +![Enregistrement du justificatif : Finalisation](./assets/diagrams/linking/5b-finalize_consent.svg) + + +# 4. Déliaison + +À un moment donné, il est possible qu’un utilisateur, un PISP ou un DFSP décide que la relation de confiance précédemment établie ne doit plus exister. Par exemple, un scénario courant peut être la perte du téléphone par un utilisateur, qui utilise l’interface du DFSP pour supprimer le lien entre le dispositif perdu, le PISP et le DFSP. + +Pour rendre cela possible, il suffit de fournir un moyen à un membre du réseau de supprimer la ressource de consentement et de notifier les autres parties de cette suppression. + +Nous devons gérer 2 scénarios avec une requête **DELETE /consents/**_{ID}_ : +1. Un service Auth hébergé par le DFSP, où aucun détail du consentement n’est stocké dans le Switch ; +2. Un service Auth hébergé par le Switch, où ce service est considéré comme la source faisant autorité pour l’objet `Consent`. + +## 4.1 Déliaison sans service d'authentification hébergé par le Switch + +Dans ce cas, le Switch transmet la requête **DELETE /consents/22222222-0000-0000-0000-000000000000** au DFSP dans l’en-tête `FSPIOP-Destination`. + +![Déliaison — DFSP hébergé](./assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg) + +Dans le cas où la déliaison est demandée depuis le côté DFSP, celui-ci peut simplement appeler **PATCH /consents/22222222-0000-0000-0000-000000000000** pour informer le PISP d’une mise à jour sur l’objet `Consent`. + +## 4.2 Déliaison avec service d'authentification hébergé par le Switch + +Dans cette instance, le PISP adresse toujours son appel **DELETE /consents/22222222-0000-0000-0000-000000000000** au DFSP via l’en-tête `FSPIOP-Destination`. + +En interne, le Switch recherchera la source faisant autorité de l’objet `Consent` via l’appel ALS, **GET /participants/CONSENT/**_{ID}_. S’il est déterminé qu’un service Auth hébergé par le Switch « possède » ce consentement, l’appel HTTP **DELETE /consents/**_{ID}_ sera redirigé vers le service Auth. + +![Déliaison — Switch hébergé](./assets/diagrams/linking/6b-unlinking-hub-hosted.svg) + +# 5.Scénarios d’erreur + +## 5.1 Découverte + +Quand le DFSP ne trouve pas d'utilisateur pour l'identifiant dans **GET /accounts/**_{ID}_, +le DFSP répond avec le code d’erreur `6205` via **PUT /accounts/**_{ID}_**/error**. + +![Erreur — Comptes](./assets/diagrams/linking/error_scenarios/1-discovery-error.svg) + +## 5.2 Erreurs sur les demandes de consentement + +Lorsque le DFSP reçoit la requête **POST /consentRequests** du PISP, les erreurs suivantes peuvent survenir : + +1. Le DFSP ne prend pas en charge les étendues (scopes) spécifiées : `6101`. Par exemple, le `userId` spécifié ne correspond pas aux comptes mentionnés, ou le champ `scope.actions` contient des permissions que ce DFSP ne prend pas en charge. +2. Le PISP a envoyé un mauvais callbackUri : `6204`. Par exemple, le schéma de callbackUri pourrait être http, ce que le DFSP pourrait choisir de ne pas accepter. +3. Tout autre contrôle ou validation côté DFSP échoue : `6104`. Par exemple, le compte de l’utilisateur pourrait être inactif ou suspendu. + +Dans ce cas, le DFSP doit informer le PISP de l’échec en envoyant un rappel **PUT /consentRequests/**_{ID}_**/error** au PISP. + +![Erreur — consentRequests](./assets/diagrams/linking/error_scenarios/2-request-consent-error.svg) + +## 5.3 Authentification + +Lorsqu'un PISP envoie un **PATCH /consentRequests/**_{ID}_ au DFSP, il est possible que le `authToken` soit expiré ou invalide : + +![Authentification — OTP invalide](./assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg) diff --git a/docs/fr/technical/api/thirdparty/transaction-patterns-transfer.md b/docs/fr/technical/api/thirdparty/transaction-patterns-transfer.md new file mode 100644 index 000000000..16470b084 --- /dev/null +++ b/docs/fr/technical/api/thirdparty/transaction-patterns-transfer.md @@ -0,0 +1,361 @@ +# Modèles de transaction - Transfert + +API Tiers de Mojaloop + +### Table des matières + +1. [Préface](#Preface) + 1.1 [Conventions utilisées dans ce document](#ConventionsUsedinThisDocument) + 1.2 [Informations sur la version du document](#DocumentVersionInformation) + 1.3 [Références](#References) +2. [Introduction](#Introduction) + 2.1 [Spécification de l'API Tiers](#ThirdPartyAPISpecification) +3. [Transferts](#Transfers) + 3.1 [Découverte](#Discovery) + 3.2 [Accord](#Agreement) + 3.3 [Transfert](#Transfer) +4. [Demande de statut de TransactionRequest](#RequestTransactionRequestStatus) +5. [Conditions d’erreur](#ErrorConditions) + 5.1 [Recherche de Bénéficiaire Incorrecte](#badpayeelookup) + 5.2 [Mauvaise demande de transaction tierce](#badtptr) + 5.3 [Échec API FSPIOP aval](#downstreamapifailure) + 5.4 [Challenge signé invalide](#invalidsignedchallenge) + 5.5 [Expiration de la demande de transaction tierce](#thirdpartytransactionrequesttimeout) +6. [Annexe](#Appendix) + 6.1 [Dérivation du challenge](#DerivingtheChallenge) + +# 1. Préface + +Cette section contient des informations sur l'utilisation de ce document. + +## 1.1. Conventions utilisées dans ce document + +Les conventions suivantes sont utilisées dans ce document pour identifier les types d'informations spécifiés. + +|Type d’information|Convention|Exemple| +|---|---|---| +|**Éléments de l’API, comme les ressources**|Gras|**/authorization**| +|**Variables**|Italique entre chevrons|_{ID}_| +|**Termes du glossaire**|Italique à la première occurrence ; défini dans le _Glossaire_|Le but de l'API est de permettre les transactions financières interopérables entre un _Payeur_ (un payeur de fonds électroniques dans une transaction de paiement) situé dans un _FSP_ (une entité qui fournit un service financier numérique à un utilisateur final) et un _Bénéficiaire_ (un destinataire de fonds électroniques dans une transaction de paiement) situé dans un autre FSP.| +|**Documents de référence**|Italique|Les informations utilisateur ne devraient, en général, pas être utilisées par les déploiements d'API ; les mesures de sécurité détaillées dans _Signature API et Chiffrement API_ devraient être utilisées à la place.| + +## 1.2. Informations sur la version du document + +| Version | Date | Description des modifications | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Version initiale + +## 1.3. Références + +Les références suivantes sont utilisées dans cette spécification : + +| Référence | Description | Version | Lien | +| --- | --- | --- | --- | +| Réf. 1 | Open API pour l'interopérabilité FSP | `1.1` | [Définition d’API v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +Ce document présente les modèles de transaction pris en charge par l'API Tiers en lien +avec l'initiation d'une demande de transaction (Transaction Request) provenant d’un PISP. + +La conception de l’API et le style architectural de cette API sont basés sur la [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) de la Réf. 1 ci-dessus. + +## 2.1 Spécification de l'API Tiers + +La spécification de l’API Tiers Mojaloop inclut les documents suivants: + +- [Modèles de données](./data-models.md) +- [Modèles de transaction - Liaison](./transaction-patterns-linking.md) +- [Modèles de transaction - Transfert](./transaction-patterns-transfer.md) +- [Définition de l'API ouverte tierce partie – DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Définition de l'API ouverte tierce partie – PISP](./thirdparty-pisp-v1.0.yaml) + + +# 3. Transferts + +Les transferts sont divisés en sections séparées : +1. **Découverte** : Le PISP recherche le bénéficiaire auquel envoyer des fonds + +2. **Accord** : Le PISP confirme le bénéficiaire, et recherche les conditions de la transaction. Si l'Utilisateur accepte les conditions de la transaction, il signe la transaction avec le justificatif établi lors du flux d’API de liaison + +3. **Transfert** : Le DFSP du payeur initie la transaction et informe le PISP du résultat de celle-ci. + +## 3.1 Découverte + +Dans cette phase, un utilisateur saisit l'identifiant de l'utilisateur à qui il souhaite envoyer des fonds. Le PISP exécute un appel **GET /parties/**_{Type}/{ID}_** (ou **GET /parties/**_{Type}/{ID}/{SubId}_) et attend un callback du switch Mojaloop. [Section 6.3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#63-api-resource-parties) +de la Réf. 1 décrit la ressource **/parties** en détail. + +Si la demande **GET /parties/**_{Type}/{ID}_ réussit, le PISP recevra un callback **PUT /parties** du switch Mojaloop. Le PISP confirme alors le bénéficiaire avec son utilisateur. + +Si le PISP reçoit un callback **PUT /parties/**_{Type}/{ID}_**/error** (ou **PUT /parties/**_{Type}/{ID}/{SubId}_**/error**), il doit afficher l’erreur pertinente à l'utilisateur. + + +![Discovery](./assets/diagrams/transfer/1-1-discovery.svg) + +## 3.2 Accord + +### 3.2.1 Demande de transaction tierce + +Après avoir confirmé les détails du bénéficiaire avec son utilisateur, le PISP demande à l'utilisateur de saisir le `montant` à envoyer au bénéficiaire, et s’il souhaite que le bénéficiaire _reçoive_ ce montant, ou qu'il souhaite _envoyer_ ce montant (champ `amountType`). + +Si l'utilisateur a associé plus d'un compte avec l'application PISP, le PISP peut lui demander de choisir un compte source pour le virement. Une fois la source de fonds confirmée, le PISP peut déterminer : +1. le `FSPIOP-Destination` comme le DFSP avec lequel le compte de l'utilisateur est associé +2. Le champ `payer` du corps de la requête **POST /thirdpartyRequests/transactions**. `partyIdType` est `THIRD_PARTY_LINK`, `fspId` est le fspId du DFSP qui a émis la liaison, et `partyIdentifier` est l’`accountId` spécifié dans le corps **POST /consents#scopes**. + +> Voir [Octroi du consentement](./transaction-patterns-linking.md#Grantconsent) pour plus d’informations. + +Le PISP génère ensuite un `transactionRequestId` aléatoire de type UUID (voir [RFC 4122 UUID](https://tools.ietf.org/html/rfc4122)). + +![1-2-1-agreement](./assets/diagrams/transfer/1-2-1-agreement.svg) + +Lors de la réception de l'appel **POST /thirdpartyRequests/transactions** du PISP, le DFSP effectue certaines validations telles que : +1. Déterminer que l'identifiant `payer` existe, et a bien été émis par ce DFSP au PISP spécifié dans `FSPIOP-Source`. +2. Confirmer que le `Consentement` identifié par `payer` existe et est valide. +3. Confirmer que le compte de l'utilisateur est actif et a suffisamment de fonds pour effectuer la transaction. +4. Toute autre validation que le DFSP souhaite effectuer. + +Si cette validation réussit, le DFSP génère un `transactionId` unique pour la demande, et appelle **PUT /thirdpartyRequests/transactions/**_{ID}_ avec ce `transactionId` et l’état `transactionRequestState` à `RECEIVED`. + +Cet appel informe le PISP que la demande de transaction tierce a été acceptée, et l'informe du `transactionId` final à suivre ultérieurement. + +Si la validation échoue, le DFSP doit envoyer un appel **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** au PISP, contenant un message d’erreur expliquant l’échec. Voir [Codes erreurs](./data-models.md#errorcodes) pour plus d’informations. + +### 3.2.2 Demande d’autorisation tierce + +Le DFSP payeur (c’est-à-dire, l’institution envoyant des fonds à la demande du PISP) peut alors émettre une demande de devis (**POST /quotes**) au DFSP bénéficiaire (l’institution recevant les fonds). Après réception du callback **PUT /quotes/**_{ID}_ du DFSP bénéficiaire, le DFSP payeur doit confirmer les détails de la transaction auprès du PISP. + +Il utilise l’appel d’API **POST /thirdpartyRequests/authorizations**. Le corps de la requête contient les champs suivants : + +- `transactionRequestId` – l'identifiant original de **POST /thirdpartyRequests/transactions**. Utilisé par le PISP pour corréler une demande d’autorisation à une demande de transaction tierce. +- `authorizationRequestId` – un UUID aléatoire généré par le DFSP pour identifier cette demande d’autorisation tierce +- `challenge` – le challenge est une `BinaryString` qui sera signé par la clé privée sur l'appareil de l'utilisateur. Bien qu'il puisse s'agir d'une chaîne aléatoire, il est recommandé qu’elle soit dérivée à partir de quelque chose de _significatif_ pour les acteurs de la transaction, qui ne puisse être prédit à l’avance par le PISP. Voir [Section 4.1](#DerivingtheChallenge) pour un exemple de dérivation du challenge. +- `transactionType` – le champ `transactionType` de la demande initiale **POST /thirdpartyRequests/transactions** + +![1-2-2-authorization](./assets/diagrams/transfer/1-2-2-authorization.svg) + +### 3.2.3 Autorisation signée + +Une fois la requête **POST /thirdpartyRequests/authorizations** reçue du DFSP Payeur, le PISP présente les conditions de la transaction à l'utilisateur, et lui demande s'il souhaite la poursuivre. + +Les résultats de la demande d'autorisation sont retournés au DFSP via **PUT /thirdpartyRequests/authorizations/**_{ID}_, où +_{ID}_ est le `authorizationRequestId`. + +Si l’utilisateur rejette la transaction, la charge utile envoyée dans **PUT /thirdpartyRequests/authorizations/**_{ID}_ est : + +```json +{ + "responseType": "REJECTED" +} +``` + +![1-2-3-rejected-authorization](./assets/diagrams/transfer/1-2-3-rejected-authorization.svg) + +Si l’utilisateur accepte la transaction, la charge utile dépend du `credentialType` du `Consent.credential` : + +1. Si `FIDO`, le PISP demande à l’utilisateur de compléter le flux [FIDO Assertion](https://webauthn.guide/#authentication) pour signer le challenge. + Le `signedPayload.fidoSignedPayload` est le `FIDOPublicKeyCredentialAssertion` renvoyé suite au processus FIDO. Voir [3.2.3.1 Signature du challenge FIDO](#SigningTheChallengeFIDO) + +2. Si `GENERIC`, la clé privée créée lors du [processus d’enregistrement du credential](../linking/README.md#162-registering-the-credential) + est utilisée pour signer le challenge. Voir [3.2.3.2 Signature du challenge avec un credential GENERIC](#SigningTheChallengeGeneric) + +#### 3.2.3.1 Signature du challenge FIDO + +Pour un `credentialType` FIDO, le PISP demande à l’utilisateur de compléter le flux [FIDO Assertion](https://webauthn.guide/#authentication) pour signer le challenge. Le champ `signedPayload.value` est le [`PublicKeyCredential`](https://w3c.github.io/webauthn/#publickeycredential) renvoyé du processus FIDO Assertion, où les `ArrayBuffer` sont encodés en chaînes base64 utf-8. Le `PublicKeyCredential` est la réponse aussi bien pour l’attestation que pour l’assertion FIDO, nous définissons l’interface suivante : `FIDOPublicKeyCredentialAssertion` : + + +```json +FIDOPublicKeyCredentialAssertion { + "id": "string", + "rawId": "string - base64 encodé utf-8", + "response": { + "authenticatorData": "string - base64 encodé utf-8", + "clientDataJSON": "string - base64 encodé utf-8", + "signature": "string - base64 encodé utf-8", + "userHandle": "string - base64 encodé utf-8" + }, + "type": "public-key" +} +``` + +Le payload final du **PUT /thirdpartyRequests/authorizations/**_{ID}_ sera ainsi : + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": FIDOPublicKeyCredentialAssertion + } +} +``` + +![1-2-3-signed-authorization-fido](./assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg) + +#### 3.2.3.2 Signature du challenge avec un credential GENERIC + +Pour un credential `GENERIC`, le PISP effectue les étapes suivantes : + +1. Étant donné les entrées : + - `challenge` (`authorizationRequest.challenge`) sous forme de chaîne base64 encodée utf-8 + - `privatekey` (stockée par le PISP lors de la création du credential), chaîne base64 encodée utf-8 + - SHA256() est une fonction de hachage à sens unique, voir [RFC6234](https://datatracker.ietf.org/doc/html/rfc6234) + - sign(data, key) est une fonction de signature prenant des données et une clé privée pour produire une signature +2. _Soit `challengeHash` le résultat de la fonction SHA256() appliquée au `challenge`_ +3. _Soit `signature` le résultat de la fonction sign() appliquée à `challengeHash` et `privateKey`_ + +La réponse du PISP au DFSP utilise alors cette _signature_ comme champ `signedPayload.genericSignedPayload` : + + +Le payload final du **PUT /thirdpartyRequests/authorizations/**_{ID}_ est alors : + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "signature encodée utf-8 base64" + } +} +``` + +![1-2-3-signed-authorization-generic](./assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg) + +### 3.2.4 Validation de l’autorisation + +> __Note :__ Si le DFSP utilise un service d’autorisation auto-hébergé, cette étape peut être sautée. + +Le DFSP doit maintenant vérifier que le challenge a bien été signé, et par la clé privée correspondant à la clé publique attachée à l'objet `Consent`. + +Le DFSP utilise l'appel d’API **POST /thirdpartyRequests/verifications**, dont le corps est composé de : + +- `verificationRequestId` – Un UUID créé par le DFSP pour identifier cette vérification. +- `challenge` – Le même challenge envoyé au PISP dans [3.2.2 Demande d’autorisation tierce](#ThirdpartyAuthorizationRequest) +- `consentId` – L’identifiant du Consent qui contient la clé publique credential à utiliser pour vérifier cette transaction. +- `signedPayloadType` – Le type de SignedPayload, selon le type d’identifiant enregistré par le PISP +- `fidoValue` ou `genericValue` – Le champ correspondant du corps de la requête **PUT /thirdpartyRequests/authorizations** du PISP. +Le DFSP doit rechercher le `consentId` d’après les détails du `payer` de la `ThirdpartyTransactionRequest`. + +![1-2-4-verify-authorization](./assets/diagrams/transfer/1-2-4-verify-authorization.svg) + +## 3.3 Transfert + +Après validation du challenge signé, le DFSP peut lancer une transaction Mojaloop standard via l’API FSPIOP. + +Après avoir reçu l’appel **PUT /transfers/**_{ID}_ du switch, le DFSP recherche le ThirdpartyTransactionRequestId du transfert donné puis envoie un appel **PATCH /thirdpartyRequests/transactions/**_{ID}_ au PISP. + +Une fois ce callback reçu, le PISP sait que le transfert est réussi et peut en informer son utilisateur. + +![1-3-transfer](./assets/diagrams/transfer/1-3-transfer.svg) + +# 4. Demander le statut de la TransactionRequest + +Un PISP peut effectuer un **GET /thirdpartyRequests/transactions/**_{ID}_ pour obtenir le statut d’une demande de transaction. + +![PISPTransferSimpleAPI](./assets/diagrams/transfer/get_transaction_request.svg) + +1. Le PISP effectue un **GET /thirdpartyRequests/transactions/**_{ID}_ +1. Le switch valide la demande et répond par `202 Accepted` +1. Le switch recherche l’endpoint pour `dfspa` pour la transférer à DFSP A +1. DFSPA valide la demande et répond avec `202 Accepted` +1. Le DFSP recherche la demande de transaction via son `transactionRequestId` + - Si elle est introuvable, il appelle **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** vers le switch, avec un message d’erreur pertinent + +1. Le DFSP vérifie que l'entête `FSPIOP-Source` correspond à celui d’origine du **POST /thirdpartyRequests/transactions** + - Sinon il appelle **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** vers le switch, avec un message d'erreur pertinent + +1. Le DFSP appelle **PUT /thirdpartyRequests/transactions/**_{ID}_ avec le corps suivant : + ``` + { + transactionRequestState: TransactionRequestState + } + ``` + + Où `transactionId` est l’identifiant de transaction généré par le DFSP, et `TransactionRequestState` est `RECEIVED`, `PENDING`, `ACCEPTED`, `REJECTED`, comme défini dans [7.5.10 TransactionRequestState](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7510-transactionrequeststate) de la Définition d’API + + +1. Le switch valide la demande et répond avec `200 OK` +1. Le switch recherche l’endpoint pour `pispa` et transmet au PISP +1. Le PISP valide la demande et répond avec `200 OK` + +# 5. Conditions d’erreur + +Après que le PISP a initié la demande de transaction tierce via **POST /thirdpartyRequests/transactions**, le DFSP doit envoyer soit un **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** soit un callback **PATCH /thirdpartyRequests/transactions/**_{ID}_ pour informer le PISP du statut final. + +- **PATCH /thirdpartyRequests/transactions/**_{ID}_ est utilisé pour informer le PISP du statut final. Il peut s’agir soit d’un rejet par l’utilisateur, soit d’une approbation ayant abouti à un transfert réussi. +- **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** informe le PISP en cas d’échec de la demande. +- Si le PISP ne reçoit aucun de ces callbacks avant l’expiration `expiration` spécifiée dans la requête **POST /thirdpartyRequests/transactions**, il peut considérer la demande comme échouée et en informer son utilisateur. + + +## 5.1 Recherche de bénéficiaire infructueuse + +Quand le PISP effectue une recherche de bénéficiaire (**GET /parties/**_{Type}/{ID}_), il peut recevoir le callback **PUT /parties/**_{Type}/{ID}_**/error**. + +Voir [6.3.4 Parties Error Callbacks](https://docs.mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#634-error-callbacks) de la Définition d’API FSPIOP pour plus d’informations sur ce callback d’erreur. + +Dans ce cas, le PISP peut vouloir afficher un message d’erreur à l’utilisateur, en l’invitant à essayer avec un autre identifiant ou plus tard. + +## 5.2 Mauvaise demande de transaction tierce + +Quand le DFSP reçoit le **POST /thirdpartyRequests/transactions** du PISP, les erreurs suivantes peuvent se produire : +1. Le `payer.partyIdType` ou `payer.partyIdentifier` est invalide ou pas lié à un consentement valide connu du DFSP +2. Le compte utilisateur identifié par `payer.partyIdentifier` n'a pas assez de fonds +3. La devise précisée dans `amount.currency` n’est pas prise en charge par le compte de l’utilisateur +4. `payee.partyIdInfo.fspId` n’est pas défini — il s’agit d’une propriété optionnelle, mais le fspId bénéficiaire sera requis pour adresser correctement la demande de devis +5. Tout autre contrôle ou vérification côté DFSP échoue + +Dans ce cas, le DFSP doit informer le PISP de l’échec en envoyant un callback **PUT /thirdpartyRequests/transactions/**_{ID}_**/error**. + +![3-2-1-bad-tx-request](./assets/diagrams/transfer/3-2-1-bad-tx-request.svg) + +Le PISP peut alors informer son utilisateur de l’échec, et proposer de relancer une demande s’il le souhaite. + +## 5.3 Échec API FSPIOP aval + +Le DFSP peut ne pas vouloir, ou ne pas être en mesure, d’exposer des détails sur les échecs API FSPIOP aval au PISP. + +Par exemple, avant d’émettre un **POST /thirdpartyRequests/authorizations** au PISP, si le **POST /quotes** avec le FSP bénéficiaire échoue, le DFSP envoie un callback **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** au PISP. + +![3-3-1-bad-quote-request](./assets/diagrams/transfer/3-3-1-bad-quote-request.svg) + +Un autre exemple : si la requête **POST /transfers** échoue : + +![3-3-2-bad-transfer-request](./assets/diagrams/transfer/3-3-2-bad-transfer-request.svg) + + +## 5.4 Challenge signé invalide + +Après réception d’un **POST /thirdpartyRequests/authorizations** du DFSP, le PISP demande à l'utilisateur de signer le `challenge` via le justificatif enregistré lors du flux de liaison de comptes. + +Le challenge signé est retourné au DFSP via **PUT /thirdpartyRequest/authorizations/**_{ID}_. + +Le DFSP : +1. Valide lui-même le challenge signé +2. Ou interroge le Auth-Service via **thirdpartyRequests/verifications** pour vérifier la signature contre la clé publique enregistrée dans le Consent. + +Si le challenge signé est invalide, le DFSP appelle alors **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** vers le PISP. + +### Cas 1 : DFSP se charge de vérifier le challenge + +![3-4-1-bad-signed-challenge-self-hosted](./assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg) + +### Cas 2 : DFSP utilise le Auth-Service hébergé par le hub pour vérifier le challenge signé contre le credential enregistré. + +![3-4-2-bad-signed-challenge-auth-service](./assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg) + +## 5.5 Expiration de la demande de transaction tierce + +Si le PISP ne reçoit aucun des callbacks ci-dessus avant la date d’expiration `expiration` définie dans **POST /thirdpartyRequests/transactions**, il peut considérer la demande comme échouée et en informer immédiatement l'utilisateur. + + +![3-6-tpr-timeout](./assets/diagrams/transfer/3-6-tpr-timeout.svg) + +# 6. Annexe + +## 6.1 Dérivation du challenge + +1. _Soit `quote` la valeur du corps de la réponse de l’appel **PUT /quotes/**_{ID}_ +2. _La fonction `CJSON()` est l’implémentation du JSON Canonical vers une chaîne, conforme à [RFC-8785 - Canonical JSON format](https://tools.ietf.org/html/rfc8785)_ +3. _La fonction `SHA256()` est la fonction de hachage SHA-256, conforme à [RFC-6234](https://tools.ietf.org/html/rfc6234)_ +4. Le DFSP doit générer la valeur `jsonString` en appliquant `CJSON(quote)` +5. Le `challenge` est la valeur de `SHA256(jsonString)` \ No newline at end of file diff --git a/docs/fr/technical/api/thirdparty/transaction-patterns.md b/docs/fr/technical/api/thirdparty/transaction-patterns.md new file mode 100644 index 000000000..52936602a --- /dev/null +++ b/docs/fr/technical/api/thirdparty/transaction-patterns.md @@ -0,0 +1,6 @@ +## Modèles de Transactions + +Les interactions et exemples illustrant comment un DFSP et un PISP interagissent via l’API Tierce Partie se trouvent dans les documents suivants sur les modèles de transaction : + +1. [Liaison](./transaction-patterns-linking.md) décrit comment un lien de compte et un justificatif peuvent être établis entre un DFSP et un PISP +2. [Transfert](./transaction-patterns-transfer.md) décrit comment un PISP peut initier un paiement à partir du compte d’un DFSP en utilisant le lien de compte \ No newline at end of file diff --git a/docs/fr/technical/business-operations-framework/Microfrontend-JAMStack.md b/docs/fr/technical/business-operations-framework/Microfrontend-JAMStack.md new file mode 100644 index 000000000..9d30416e2 --- /dev/null +++ b/docs/fr/technical/business-operations-framework/Microfrontend-JAMStack.md @@ -0,0 +1,266 @@ +# Micro-frontend - conception JAMStack +## Vue d'ensemble +L'objectif de la conception micro-frontend - JAMStack est de créer un framework qui : + +- facilite la collaboration de la communauté (en permettant le développement indépendant de composants) +- rend les extensions ou personnalisations faciles +- permet aux membres de la communauté de contribuer en retour à l'OSS sans forker l'ensemble du code source + +### Micro-frontends +Le framework utilise des micro-frontends comme moyen de découpler les parties de l'UI pour permettre des bases de code maintenables, des équipes autonomes, des publications indépendantes et des mises à niveau progressives de parties de l'UI. + +### JAMStack +L'implémentation [JAMStack](https://jamstack.org/) réduit le rôle du serveur web à la distribution de fichiers de balisage statiques, en maintenant la fonctionnalité dans JavaScript (qui s'exécute dans le navigateur client) et dans l'API backend. +:::warning JAMStack signifie : + **J** - JavaScript + **A** - APIs + **M** - Static markup (balisage statique) + ::: +Cette implémentation de stack est considérée comme une bonne pratique car elle : +- est beaucoup plus simple à sécuriser +- offre une bonne expérience client grâce à des temps de réponse web rapides +- est peu coûteuse à héberger + +De plus, les éléments suivants ont également été conçus et font normalement partie d'une implémentation JAMStack : +- déploiement sur un réseau de distribution de contenu (CDN) +- déploiements atomiques +- utilise des micro-frontends chargés dynamiquement, de sorte que la mise à jour vers la dernière version est automatique + +## Pile technologique + +1. **React** +Le framework est basé sur la bibliothèque React. +C'est la bibliothèque Single Page Application (SPA) la plus populaire en usage, et de plus ce choix nous permet de capitaliser sur d'autres efforts communautaires facilitant une conversion facile vers cette bibliothèque. +Elle peut être améliorée en utilisant des bibliothèques de conteneurs d'état (Redux, Flux, MobX), mais il n'y a aucune restriction sur une utilisation spécifique. +Les micro-frontends sont livrés avec des stores Redux préconfigurés et isolés. + +2. **Webpack 5** +Webpack 5 est actuellement le seul bundler JavaScript qui supporte la séparation de build à distance. Cela se fait en utilisant le Module Federation Plugin. +Il permet une composition au moment de l'exécution pour offrir une expérience utilisateur fluide et entièrement transparente, résultant en une Single Page Application traditionnelle. +Il y a des avantages supplémentaires par rapport aux autres technologies, résultant tous en une empreinte réduite et une meilleure expérience globale pour les utilisateurs. +Webpack 5 implémentera l'intégration host/child micro-frontends au moment de l'exécution. + +3. **CI/CD et déploiements atomiques** (par exemple, Github Actions) +Chaque implémentation du Business Operations Framework devra implémenter sa propre solution de déploiement atomique. +Le projet Business Operations standard utilisera Github Actions pour exécuter le pipeline d'intégration continue, exécuter les tests pertinents, construire le micro-frontend individuel et déployer les fichiers statiques résultants sur un CDN et/ou créer une image Docker. +Chaque micro-frontend est publié en complète autonomie : l'application composée peut utiliser les versions mises à jour de chaque micro-frontend individuel automatiquement, sans nécessiter de coordination supplémentaire. + +4. **Fonctionnement sur un CDN** +Les micro-frontends peuvent fonctionner sur un CDN. Les builds individuels sont composés uniquement de fichiers statiques (HTML, CSS, JavaScript) et peuvent être déployés dans différents emplacements / différentes URLs. +Tant qu'ils sont disponibles via une connexion sécurisée (HTTPS), les micro-frontends peuvent être servis depuis n'importe quel emplacement et également depuis différents CDN. + +5. **Fonctionnement dans Kubernetes** +Les micro-frontends peuvent fonctionner dans un environnement Kubernetes. Deux approches peuvent être adoptées ici : + - Les micro-frontends individuels et l'application shell sont conteneurisés (par exemple avec Docker) puis hébergés dans Kubernetes. +L'hôte et les applications enfants peuvent être déployés sur le même cluster ou sur des clusters différents tant qu'ils sont accessibles publiquement. + - Déployer un CDN privé dans le cluster Kubernetes et héberger les fichiers de balisage statiques sur le CDN. +Divers CDN compatibles avec Kubernetes sont disponibles. + +## Construction Webpack + +L'hôte et les applications enfants incluent des scripts pour construire les artefacts de distribution. La construction peut être effectuée sur la machine hôte du développeur, dans le CI et dans Docker. + +## Chargement des micro-frontends + +L'hôte est responsable du chargement des applications enfants au moment de l'exécution. Il recueille des informations sur les enfants disponibles au moment de l'exécution, soit depuis une API soit depuis un registre. + +L'hôte inclut un moteur interne responsable du chargement uniquement des enfants nécessaires lorsqu'ils doivent être affichés. + +Les micro-frontends individuels ne seront pas chargés lorsque ce n'est pas nécessaire (par exemple, lorsqu'une page spécifique n'est pas accédée par l'utilisateur). + +**Diagramme de séquence de haut niveau illustrant comment les microservices sont chargés** +![Diagramme de séquence de haut niveau illustrant comment les microservices sont chargés](../../../.vuepress/public/microfrontendloading.png) + +### Référentiel de micro-frontends +Afin de fournir une autorité centralisée responsable du contrôle des micro-frontends individuels répondant aux exigences nécessaires, il est suggéré de construire une solution qui fonctionne comme un registre. + +Le registre servirait les objectifs suivants : + +1. permettre à la communauté d'enregistrer les micro-frontends et de spécifier certains détails +2. exposer une API utilisée par l'hôte pour récupérer des informations sur les micro-frontends disponibles +3. fournir des informations sur les versions des micro-frontends disponibles + +Le registre n'existe pas encore, et il n'est pas judicieux de le créer pour le moment. + +## Déploiements + +Le diagramme de vue d'ensemble suivant montre le déploiement des micro-frontends sur un CDN. +::: tip REMARQUE +Le déploiement de l'API de contexte délimité n'est pas couvert dans ce diagramme. +::: +![Diagramme de vue d'ensemble montrant le déploiement](../../../.vuepress/public/BizOps-Framework-Micro-frontend-deploy.png) + +Les micro-frontends utilisent des déploiements atomiques et aucun build complet n'est jamais requis. + +Chaque micro-frontend individuel se déploie indépendamment des autres. + +### Intégration Continue / Livraison Continue (CI/CD) + +Chaque micro-frontend a sa propre configuration CI/CD ; il n'est pas nécessaire de partager la même configuration ou d'utiliser le même outil CI. + +Le CI/CD peut être configuré pour supporter plusieurs environnements, par exemple DEV, QA, PROD. + +Voici un exemple de fichier montrant un flux de travail git action. + +```yml +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Use NodeJS ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache node modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: '**/node_modules' + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - run: yarn install --frozen-lockfile + - run: yarn lint + - run: yarn test + - run: yarn build +# - name: Slack Notification +# uses: rtCamp/action-slack-notify@v2.0.2 +# env: +# SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} +``` + +### CDN + +L'application SPA résultante est servie par un CDN ou plusieurs CDN. Les micro-frontends individuels peuvent résider dans différents CDN. + +### Kubernetes + +L'application SPA résultante peut fonctionner et être servie dans un ou plusieurs environnements Kubernetes. + +### Application hôte + +L'application hôte est livrée avec une configuration préconfigurée prête à l'emploi. Elle ne nécessite aucune configuration particulière différente d'un SPA traditionnel, autre que la configuration du Module Federation de Webpack 5. +Elle agira comme l'orchestrateur, chargeant les micro-frontends distants et leur fournissant des fonctionnalités à l'échelle de l'application, par exemple l'authentification, le RBAC, le routage côté client. + +Il n'y a pratiquement aucune limite à la façon dont l'hôte peut croître et être étendu. +Il est cependant suggéré de centraliser toutes les communications hôte-enfant et les composants partagés dans une bibliothèque externe afin que l'hôte et les enfants aient la même connaissance et que l'intégration ne se brise pas. + +### Versionnement des micro-frontends +​L'approche suggérée est de construire un registre où les applications individuelles sont enregistrées. Le registre permettrait de définir une configuration sur chaque application et de suivre toutes les versions disponibles. +​ +Le registre exposerait ensuite une API consommée par l'hôte, fournissant des informations sur les micro-frontends disponibles, les versions et les emplacements des artefacts. +​ +Le registre serait administré par un opérateur de confiance via une interface utilisateur ; il serait de la responsabilité de l'opérateur de confiance de décider quelle version de chaque application individuelle serait rendue publique et disponible pour l'hôte à charger. +Il permettrait également de tester facilement des versions et de les annuler si nécessaire, tout cela sans avoir besoin de reconstruire et de redéployer les applications. +​ +::: tip REMARQUE +Les artefacts de build JS créés par Webpack n'incluent pas la version dans le nom du fichier. Il pourrait être nécessaire de mettre à jour le build afin de différencier les versions. Une approche plus simple qui ne nécessite pas de mettre à jour la configuration de build serait d'héberger les versions sur différentes URLs. +::: +​ +### Mise à niveau de l'hôte +​L'hôte est assez bien isolé et la seule chose nécessaire pour faire un versionnement correct est d'utiliser la commande intégrée `yarn version`. Elle créera un nouveau tag git et incrémentera la version de `package.json` selon la façon dont la commande est utilisée (CLI interactif). +​ +### Mise à niveau des remotes +​Les remotes sont isolés et la seule chose nécessaire pour faire un versionnement correct est d'utiliser la commande intégrée `yarn version`. Elle créera un nouveau tag git et incrémentera la version de `package.json` selon la façon dont la commande est utilisée (CLI interactif). + +### Composition Menu / Application +​L'hôte est configuré pour construire dynamiquement la structure _Menu_ et _Pages_ (avec react-router). Actuellement, le(s) composant(s) _Menu_ est importé de la bibliothèque `@modusbox/react-components`. +​ +Il n'est pas strictement nécessaire d'utiliser de tels composants et l'hôte / les remotes pourraient utiliser des composants personnalisés, à condition qu'ils permettent la composition dynamique et supportent le routage. +​​ +## Motivation des micro-frontends en détail + +​La construction d'interfaces utilisateur évolutives et distribuées est complexe ; la complexité logique, la configuration des tests, les coûts de build et de déploiement augmentent avec le temps. ​Les décisions architecturales prises dans la phase initiale peuvent générer une complexité inutile et fortement affecter les coûts de développement dans les étapes ultérieures.​ De plus, un seul projet ne s'adapte pas bien aux équipes distribuées travaillant en collaboration sur la même base de code.​ Passer à une configuration micro-frontend peut résoudre tous les problèmes ci-dessus ; elle s'adapte bien, les déploiements atomiques ne nécessitent pas de build complet, et les équipes indépendantes peuvent utiliser différentes bases de code.​​ + +### Ce qui définit un micro-frontend + +​Les règles principales qui peuvent définir une configuration micro-frontend peuvent être résumées comme suit :​ + +**Responsabilité unique** +Frontières définies et fermées +Orchestration centralisée​ +Responsabilité unique +​Chaque application micro-frontend ne devrait fournir que des fonctionnalités métier spécifiques. Une application micro-frontend n'a pas besoin de connaître d'autres aspects de l'activité et peut évoluer indépendamment.​ + +**Frontières définies et fermées** +​Chaque micro-frontend devrait être isolé, posséder ses propres données, et la communication directe entre micro-frontends ne devrait pas être possible.​ + +**Orchestration centralisée** +​Chaque micro-frontend devrait être chargé, géré et contrôlé par un hôte. Les fonctionnalités à l'échelle de l'application sont fournies par l'hôte (authentification, routage, etc.).​​ + +### Types de configurations de micro-frontends + +​Il existe plusieurs façons d'implémenter des micro-frontends, pour en citer quelques-unes :​ +- Composition par Iframe +- Composition à l'exécution +- Composition par fédération de modules (framework unique)​ + +**Composition par Iframe** +​La composition par Iframe est probablement la façon la plus ancienne et la plus facile d'implémenter des micro-frontends, grâce à l'ancien support HTML pour les iframes et l'isolation de contexte native qu'elle offre. La communication entre l'hôte et les micro-frontends est généralement difficile à réaliser et ne s'adapte pas bien au web moderne.​ + +**Composition à l'exécution** +​La composition à l'exécution est l'idée de charger dynamiquement des scripts JS situés sur des URLs http/https et de composer le résultat localement. ​Bien qu'elle vous permette théoriquement d'utiliser des technologies indépendantes pour chaque micro-frontend, elle est également très difficile à maintenir en raison des différences entre les frameworks utilisés dans les micro-frontends.​​ + +**Composition SPA** +​La fédération de modules est une technologie implémentée dans Webpack 5 qui vous permet de charger dynamiquement des modules distants au moment de l'exécution. Combinée avec un framework d'application unique (par exemple React), elle permet aux applications construites d'être divisées en plusieurs micro-frontends sans sacrifier les avantages qu'un SPA offre. Elle présente également l'avantage de tailles de build plus petites.​​ + +### La configuration choisie + +Nous avons choisi d'utiliser la composition SPA avec Webpack 5 et React. Il vaut la peine de mentionner qu'afin de construire un SPA avec plusieurs micro-frontends, un contrat spécifique et rigoureux entre l'hôte et les frontends doit être implémenté et respecté.​ Dorénavant nous ferons référence aux micro-frontends dans la forme technique utilisée par Webpack 5 : les remotes. ​Le contrat est défini par les règles suivantes :​ + +- L'hôte récupère la liste des remotes dynamiquement et de manière asynchrone +- L'hôte est responsable du chargement des remotes +- L'hôte partage un certain contexte avec les remotes (routage, authentification) +- Les remotes ont des noms uniques +- Les remotes sont déployés sur différentes URLs +- Les remotes n'utilisent pas de règles CSS globales +- Les remotes s'exportent eux-mêmes comme défini par les règles de fédération de modules +- Les remotes partagent la même version de React (et de certaines bibliothèques)​ + +Lorsque ces règles sont respectées, il n'y a pratiquement aucune limite à la façon dont le SPA peut croître.​ La plupart des dépendances de base utilisées dans chaque frontend sont fournies par l'hôte. Cela facilite leur mise à niveau. ​Chaque application est construite indépendamment des autres ; le pipeline CI/CD reste rapide, les déploiements atomiques ne nécessitent pas de configurations complexes et chaque remote est publié à son propre rythme sans avoir besoin de modifier l'hôte de quelque façon que ce soit.​ + +### Exemple en direct hébergé sur un CDN + +Consultez l'exemple en direct suivant : [https://microfrontend-shell-boilerplate.vercel.app/](https://microfrontend-shell-boilerplate.vercel.app/) + +## Dépôts Git + +Voici une liste de dépôts Git qui font partie de cette implémentation : + + - [Micro frontend-shell-boilerplate](https://github.com/mojaloop/microfrontend-shell-boilerplate) + - [Micro frontend-boilerplate](https://github.com/mojaloop/microfrontend-boilerplate) + - [Micro frontend-utils](https://github.com/modusintegration/microfrontend-utils) +Bibliothèque partagée avec l'application shell et le micro-frontend. + - [Reporting-Hub BizOps Role Assignment Micro-frontend](https://github.com/mojaloop/reporting-hub-bop-role-ui) + - [Reporting-Hub BizOps Transaction Tracing Micro-frontend](https://github.com/mojaloop/reporting-hub-bop-trx-ui) + diff --git a/docs/fr/technical/business-operations-framework/README.md b/docs/fr/technical/business-operations-framework/README.md new file mode 100644 index 000000000..2355d04df --- /dev/null +++ b/docs/fr/technical/business-operations-framework/README.md @@ -0,0 +1,58 @@ +# Introduction + +Rejoignez la collaboration pour construire un ensemble de processus métier fondamentaux permettant un **"démarrage rapide"**, faciles à personnaliser, à contribuer en open source et conformes aux meilleures pratiques. + +Le Business Operations Framework vise à aider les opérateurs de Hub à construire et déployer des portails de processus métier qui soutiennent leurs processus métier tels que définis dans la [documentation métier Mojaloop](https://docs.mojaloop.io/mojaloop-business-docs/). Le Business Operations Framework soutient la collaboration communautaire dans la création d'une expérience utilisateur (UX) pour un opérateur de Hub Mojaloop qui comprend des API robustes, suit les meilleures pratiques et est sécurisé par conception. L'objectif est de soutenir davantage l'adoption et d'améliorer la valeur prête à l'emploi de la solution Mojaloop. + +L'interface utilisateur (UI) résultante n'est pas destinée à être exhaustive, mais à démontrer une expérience web exemplaire qui est facile à étendre et à personnaliser. Il est donc important que le contrôle d'accès basé sur les rôles (RBAC), l'interfaçage avec les systèmes standard de gestion des identités et des accès (IAM), le contrôle de sécurité au niveau API, les micro-frontends et les flux de travail de validation maker-checker soient pris en charge. L'architecture UX suit un bundle pré-compilé avec un modèle API de support pouvant être déployé sur un réseau de distribution de contenu (CDN). + +Ce document fournit une conception plus détaillée, incluant les aspects de sécurité, les technologies utilisées et les modèles d'architecture. + +Le framework : +1. Implémente une intégration/implémentation RBAC et IAM conforme aux meilleures pratiques. +2. Comprend un plan de déploiement pour intégrer la solution RBAC et IAM dans Mojaloop. +3. Comprend un plan de déploiement pour le portail UI afin qu'il puisse être déployé dans un réseau CDN. +4. Utilise des micro-frontends construits à partir de différents dépôts pour découpler les efforts communautaires et faciliter les extensions et personnalisations. +5. Fournit une piste d'audit de toutes les activités effectuées. + +Trois niveaux ou degrés de contrôle sont nécessaires lors de la configuration d'une sécurité conforme aux meilleures pratiques : +1. Accès quotidien aux interfaces utilisateur IAM où les utilisateurs sont créés, suspendus et leurs rôles assignés. +2. Mappages des rôles aux permissions, qui peuvent être modifiés via une demande de changement de configuration. +3. Restrictions sur l'accès à l'API en fonction des permissions disponibles pour un sujet (un utilisateur ou un client API) à travers leurs rôles. + +## Effort communautaire – liste des tâches à faire +La première livraison de ce framework comprend une tranche verticale mince pour démontrer l'implémentation fonctionnelle de bout en bout du framework. Bien que cette fonction livrée en premier serve un objectif important, ce n'est pas l'objectif final de ce projet. L'objectif est de fournir un framework auquel d'autres efforts communautaires pourront contribuer. Voici la liste actuelle des tâches d'API de support de processus backend/micro-frontends qui sont destinés à être ajoutés à ce framework par les efforts d'implémentation de la communauté Mojaloop : + +|Catégorie|Description|Effort communautaire contributeur| +| --- | --- | --- | +|**Configuration de la plateforme**|Processus pour configurer la plateforme afin qu'elle applique le schéma et les règles du système.| - | +|**Gestion de la plateforme**|Contrôles de gestion opérationnelle technique pour la plateforme.| Actuellement réalisé avec Kibana Application Performance Monitoring (APM) et Elasticsearch. Aucun plan actuel de migration vers le framework. | +|**Gestion de la liquidité**|Support de processus pour la gestion de la liquidité.|Financial Portal V2 - pas encore intégré au framework.| +|**Gestion du cycle de vie des participants
    (vue Hub)**|Gérer l'intégration et les transitions d'état des participants.|Financial Portal V2 - pas encore intégré au framework.| +|**Gestion du cycle de vie des participants
    (vue DFSP)**|Permettre aux DFSP de gérer leur statut et leur interaction avec le Hub.| - | +|**Gestion du règlement**|Interface de gestion pour le règlement.|Rapports de réconciliation DFSP - les rapports Myanmar MFI Digitization (MMD) sont en cours d'intégration dans le framework (accessibles via une API).
    Règlement net différé multilatéral - Financial Portal V2 pas encore disponible dans le framework.| +|**Gestion des transferts et transactions**| Vue des opérations métier de toutes les transactions au niveau du hub. | Financial Portal V2 - en cours de conversion dans le framework avec des améliorations. Activation du traçage d'un transfert de bout en bout. | +|**Gestion des accords (devis)**| - | - | +|**Gestion de la recherche et découverte de compte**| - | - | +|**Gestion des paiements initiés par des tiers**| - | - | +|**Gestion des frais (interchange et facturation)**| - | - | +|**Rapports et analytique**| - | - | + +## Architecture de référence +Le groupe de travail sur l'architecture de référence a - à travers un processus collaboratif - conçu l'architecture de la version future/suivante de Mojaloop. Le Business Operations Framework est conçu pour fonctionner sur la version actuelle de Mojaloop (core v1.0). Le Business Operations Framework doit cependant être compatible avec l'architecture de référence et, dans la mesure du possible, faciliter le passage vers la conception de l'architecture de référence. + +Les éléments suivants du projet Business Operations Framework contribuent directement à la construction d'une architecture de référence : +1. **Contexte délimité de sécurité** +L'implémentation RBAC de ce groupe de travail a utilisé certaines idées de conception et séparations définies dans le contexte délimité de sécurité de l'architecture de référence. Elle n'a pas implémenté les interfaces nécessaires pour être considérée comme une implémentation de contexte délimité de sécurité. +2. **Contexte délimité de reporting** +Une partie du contexte délimité de reporting est construite dans ce groupe de travail. + +La division du frontend en micro-frontends pouvant être construits, testés et publiés indépendamment ; donnant aux équipes qui créent des solutions dans chaque contexte délimité la capacité de construire indépendamment des fonctionnalités API et l'UI correspondante. Les personnalisations et extensions de chaque contexte délimité sont également facilement supportées avec cette conception. + +Voici une vue d'ensemble de la façon dont les API opérationnelles, les API d'expérience et les micro-frontends peuvent être combinés dans les parties qui forment le Business Operations Framework. + +![Diagramme de vue d'ensemble de l'architecture compatible avec l'architecture de référence](../../../.vuepress/public/BizOps-Framework-BizOps-Framework.png) + + +## IaC 4.xx +La prochaine version du projet "Infrastructure as Code" prévoit d'utiliser un ensemble d'outils différent de ceux actuellement utilisés dans la communauté Mojaloop ; c'est-à-dire que WSO2 avec son Identity Server en tant que Key Manager (IS-KM) et les implémentations HAproxy seront remplacés par Keycloak et les outils Ambassador - Envoy. Cette conception est compatible avec la prochaine version IaC. diff --git a/docs/fr/technical/business-operations-framework/ReportDeveloperGuide.md b/docs/fr/technical/business-operations-framework/ReportDeveloperGuide.md new file mode 100644 index 000000000..fe4fbb91a --- /dev/null +++ b/docs/fr/technical/business-operations-framework/ReportDeveloperGuide.md @@ -0,0 +1,319 @@ +# Guide du développeur de rapports +Ceci est un guide du développeur pour la construction et le déploiement de rapports pour le service REST de reporting qui fait partie du déploiement au niveau du Hub. + +## Architecture +![Diagramme d'architecture du service de reporting](../../../.vuepress/public/RestReportingArchitecture.drawio.png) +[Voici](https://github.com/mojaloop/reporting) le dépôt de l'opérateur du service de reporting. +L'opérateur du service de reporting a été conçu pour être accessible soit par un opérateur de hub, soit par un opérateur DFSP. +L'accès au rapport est contrôlé via l'intégration RBAC qui fait partie du business operations framework. Ory Oathkeeper protège l'endpoint API de reporting, et Keto est vérifié par l'opérateur du service de reporting pour une autorisation de rapport plus précise. +Les données du rapport sont interrogées depuis la base de données SQL de reporting qui est actuellement une synchronisation unidirectionnelle de la base de données du central ledger. +Chaque rapport est installé sur le système en tant que ressource personnalisée Kubernetes qui est un fichier .yaml d'un format particulier appliqué au cluster Kubernetes. [Voici](https://github.com/mojaloop/reporting-k8s-templates) le dépôt des templates de rapports open source. La définition de ressource personnalisée pour un rapport est définie [ici](https://github.com/mojaloop/reporting-k8s-templates/blob/master/crds/reporting-crd.yaml), qui décrit le format de la ressource personnalisée. + +## RBAC +L'accès aux rapports est contrôlé via le RBAC lorsque le service est déployé via la configuration IaC standard. +Cela signifie que pour accéder à un rapport, un utilisateur devra avoir l'autorisation correcte assignée. Cela est réalisé grâce à l'assignation de rôles à l'utilisateur et à l'assignation de l'accès aux participants. + +La première vérification d'autorisation est effectuée par Ory Oathkeeper qui dispose d'une règle qui lie la permission +``` +reportingApi +``` +à l'accès à l'endpoint API du service de reporting. + +La vérification d'autorisation suivante est effectuée par l'opérateur du service de reporting. La permission d'accéder au rapport particulier est vérifiée. La permission qui est vérifiée est définie dans la ressource personnalisée. Cette permission est optionnelle et utilisera sinon le nom (metadata) du rapport tel que défini dans la ressource personnalisée. +### Exiger la permission DFSP +Si le rapport est destiné à un participant ou DFSP particulier, il est important d'utiliser le paramètre 'dfspId'. Ce paramètre vérifie d'abord l'autorisation du participant avant d'exécuter et de produire le rapport. +C.-à-d. +``` yaml + params: + - name: dfspId + required: true +``` +### Exécuter le rapport +Vous devrez d'abord vous connecter. La façon la plus simple de le faire est de se connecter au Financial Portal. Cela crée les tokens de cookies d'autorisation et d'authentification que le rapport utilise ensuite. +Voici un exemple d'accès au rapport directement après la connexion. +``` +https://bofportal.YourEnvironment.YourDomain.com/proxy/reports/MyReportPath?ReportParamter=25 +``` + +### Formats de sortie du rapport +Le rapport prend en charge plusieurs formats de sortie. Pour basculer entre ceux-ci, utilisez le paramètre format dans la requête Rest. +1. Fichier Excel +``` +&format=xlsx +``` +2. Valeurs séparées par des virgules +``` +&format=csv +``` +3. Format classe JSON +``` +&format=json +``` +4. Format navigateur HTML (c'est le format de sortie par défaut) +``` +&format=html +``` + +## Ressource personnalisée Kubernetes +Tous les aspects d'un rapport sont contrôlés via le fichier de ressource personnalisée mojaloopreport. La définition de ce fichier est la suivante. + +### Définition de ressource personnalisée +``` yml +kind: CustomResourceDefinition +apiVersion: apiextensions.k8s.io/v1 +metadata: + name: mojaloopreports.mojaloop.io +spec: + group: mojaloop.io + scope: Namespaced + names: + plural: mojaloopreports + singular: mojaloopreport + shortNames: + - mlreport + kind: MojaloopReport + listKind: MojaloopReportList + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: MojaloopReport is the Schema for MojaloopReport API + type: object + properties: + apiVersion: + description: >- + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the + latest internal value, and may reject unrecognized values. More + info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: >- + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the + client submits requests to. Cannot be updated. In CamelCase. + More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MojaloopReport.spec describes the desired state of my resource + type: object + required: + - endpoint + - queries + - template + properties: + permission: + description: Permission to be needed to access this report. This is optional. If unspecified, the name of the resource will be considered as permission. + type: string + endpoint: + description: Reporting endpoint + type: object + required: + - path + properties: + path: + description: Report URL path + type: string + params: + description: Report query params + type: array + items: + description: Query param + type: object + required: + - name + properties: + name: + description: Query param name + type: string + required: + description: Make query param required + type: boolean + default: + description: Default query param value + type: string + queries: + description: The list of queries used in ejs reporting template + type: array + items: + description: permission ID. + type: object + required: + - name + - query + properties: + name: + description: Variable name that the query result will be assigned to + type: string + query: + description: SQL query + type: string + template: + description: ejs reporting template + type: string + + status: + description: The status of this MojaloopReport resource, set by the operator. + type: object + properties: + state: + description: The state of the report. + type: string + additionalPrinterColumns: + - name: endpoint + type: string + description: Reporting endpoint + jsonPath: .spec.endpoint.path + conversion: + strategy: None +``` +Des exemples de rapports conformes à cette ressource personnalisée peuvent être trouvés [ici](https://github.com/mojaloop/reporting-k8s-templates/tree/master/templates). +Veuillez noter que ces fichiers Yaml contiennent également des **directives helm** dans ces fichiers, indiquées par les doubles accolades. +``` +{{ some helm directive / function }} +``` +Si vous avez l'intention d'appliquer manuellement ces fichiers à Kubernetes, celles-ci devront être supprimées ou remplacées. + +### Kubectl +Vous pouvez utiliser la commande suivante pour appliquer une ressource personnalisée de rapport à une instance Kubernetes. + ``` + kubectl apply -f resources/examples/participant_list.yaml + ``` + +Examinons quelques détails de la ressource personnalisée. + +### Contrôler la façon dont le rapport est appelé +La première partie de spec: du rapport définit comment le rapport est appelé. +C.-à-d. +``` yaml +spec: + permission: report-dfsp-settlement-detail + endpoint: + path: /dfspSettlementDetail + params: + - name: settlementId + required: true + - name: fspid + required: true +``` +- **permission** c'est ici que le tag de permission RBAC pour ce rapport est défini +- **path** c'est le chemin de l'endpoint pour ce rapport +- **params** ici les paramètres du rapport sont définis et il est précisé s'ils sont des paramètres requis ou non. + +### Contrôler la source des données du rapport +``` yaml +queries: + - name: dfspInfo + query: | + SELECT participantId, name FROM participant WHERE name = :fspid AND name != 'Hub' + - name: report + query: | + SELECT + pCPayer.participantId as payerFspid, +``` +Dans la section queries, n'importe quel nombre de requêtes peut être défini, qui sont exécutées contre la base de données de reporting et chargées dans des classes json nommées. +Les paramètres d'entrée peuvent être utilisés dans les requêtes en utilisant un deux-points devant le nom du paramètre. Par exemple : +``` +:paramname +``` +### Contrôler l'apparence des rapports +La partie template du fichier de ressource personnalisée contient un script EJS utilisé pour produire le rapport. +Ces scripts ressemblent à du HTML avec du style, mais contiennent du code dans des blocs de script +``` ejs +<% ejs script %> +``` +Les scripts EJS sont assez polyvalents et peuvent être utilisés pour modifier un texte de nom, ou définir des fonctions de formatage, ou des boucles qui itèrent à travers les données. + +## Construire votre environnement de développement +*(Installation de ce service localement pour faciliter le développement.)* +Actuellement, la seule façon de valider la conception du rapport est d'appliquer le rapport au cluster Kubernetes sur lequel le service de reporting s'exécute. Le service de reporting validera initialement le rapport, puis activera l'endpoint. Le rapport peut être exécuté et vérifié pour voir s'il répond à ses exigences. + +Ce document fournit des instructions pour déployer ce service localement, afin qu'un développeur puisse tester ses conceptions avant d'installer le rapport dans un environnement. +Étant donné que le service de reporting suit le modèle d'opérateur K8S, nous devons déployer un mini cluster Kubernetes sur notre machine et déployer le service de reporting avec certains services dépendants. + +### Prérequis +- Assurez-vous d'avoir les logiciels suivants installés + - git + - docker + - minikube + - kubectl + - helm + - mysql-client + +### Installer K8S +- Démarrez le cluster K8S minikube avec la commande suivante + ``` + minikube start --driver=docker --kubernetes-version=v1.21.5 + ``` + +### Cloner le dépôt +- Télécharger le dépôt + ``` + git clone https://github.com/mojaloop/reporting.git + cd reporting + ``` + +### Déployer le chart helm +- Installer le chart helm en utilisant les commandes suivantes + ``` + helm dep up ./resources/test-integration/ + helm install test1 ./resources/test-integration/ --set reporting-legacy-api.image.tag=v11.0.0 + ``` +- Attendre que tous les services soient opérationnels + Vous pouvez surveiller l'état des pods ou utiliser les commandes suivantes pour attendre que les services soient prêts + ``` + kubectl -n default rollout status deployment test1-reporting-legacy-api + kubectl -n default rollout status statefulset mysql + ``` + +### Restaurer la sauvegarde de la base de données mysql +- Transférer le port du service mysql + ``` + kubectl port-forward -n default service/mysql 3306:3306 + ``` +- Insérer des données d'exemple dans la base de données. Vous pouvez modifier le nom de la base de données et le nom du fichier dans la commande suivante selon vos besoins. + ``` + mysql -h127.0.0.1 -P3306 -uuser -ppassword default < ./resources/examples/participants_db_dump.sql + ``` + +### Charger le template de rapport +- Ajouter la ressource personnalisée en utilisant la commande suivante + ``` + kubectl apply -f resources/examples/participant_list.yaml + ``` + +### Obtenir le rapport +- Transférer le port du service de reporting + ``` + kubectl port-forward -n default service/test1-reporting-legacy-api 8080:80 + ``` +- Obtenir le rapport en ouvrant l'URL suivante dans le navigateur + ``` + http://localhost/participant-list + ``` + +### Nettoyage +- Nettoyage + ``` + kubectl delete -f resources/examples/participant_list.yaml + helm uninstall test1 + minikube stop + ``` + +## Déploiement dans un environnement de production +Il existe plusieurs façons de déployer une ressource personnalisée de rapport dans un environnement. La méthode qui a été choisie et intégrée à l'offre IaC implique l'utilisation d'un chart helm. (Cela s'aligne bien avec les autres composants Mojaloop.) + +L'IaC permet à la fois un déploiement public et privé de rapports. Le processus est identique, à l'exception que le dépôt est privé et réside dans le contrôle de source de l'organisation. +À un niveau élevé, le processus se déroule comme suit : +1. Créer une branche et valider les modifications dans le dépôt depuis lequel le rapport est déployé. +2. Créer une pull request et fusionner les modifications dans la branche master du dépôt. +3. Créer une nouvelle version dans le dépôt. (Selon la configuration, cela déclenche généralement un mécanisme CICD qui construit et publie le package helm.) +4. Mettre à jour l'IaC pour déployer la nouvelle version helm pour les rapports. +5. Exécuter le pipeline approprié pour effectuer le déploiement. + diff --git a/docs/fr/technical/business-operations-framework/ReportingBC.md b/docs/fr/technical/business-operations-framework/ReportingBC.md new file mode 100644 index 000000000..946876745 --- /dev/null +++ b/docs/fr/technical/business-operations-framework/ReportingBC.md @@ -0,0 +1,498 @@ +# Implémentation du contexte délimité de reporting +L'un des objectifs de ce projet de groupe de travail est de fournir la capacité de tracer un transfert de bout en bout. Afin de répondre à cet objectif, une partie du contexte délimité de reporting (BC) doit être construite en accord avec l'architecture de référence. + +## Vue d'ensemble de la conception +Voici la conception architecturale globale. +![Diagramme de vue d'ensemble de l'architecture du contexte délimité de reporting](../../../.vuepress/public/Reporting-&-Auditing-Overview.png) + +Dans Mojaloop, tous les services principaux envoient déjà des événements à Kafka sur un topic (appelé 'topic-event'). + +Il existe deux bases de données de reporting fondamentales : +1. **Base de données de reporting** +La base de données de reporting est une base de données relationnelle qui suit l'état le plus récent des objets Mojaloop et les rend disponibles via une interface de requête efficace. \ +\ +Dans l'implémentation de cet effort de groupe de travail, un réplica dédié de la base de données du central ledger sera utilisé pour le reporting. Cela ne correspond pas tout à fait au modèle architectural, car une base de données appartenant au contexte délimité de reporting ne devrait pas avoir de dépendances externes. Une base de données réplica du central ledger dépend du schéma du central ledger et a donc une dépendance externe. +::: warning Dette technique +Cela devrait être reconnu comme une **dette technique** qui doit être remboursée à mesure que davantage de l'architecture de référence est construite. +::: +Deux approches peuvent être adoptées lors du remboursement de cette dette technique : + - Changer l'appel de réplica en une fonction de **synchronisation de données unidirectionnelle**, ce qui découplerait les schémas des deux bases de données. + - Reconstruire une nouvelle **base de données relationnelle** conçue, mise à jour en fonction des topics Kafka souscrits. + +La meilleure approche dépendra de l'état de la version actuelle de Mojaloop au moment où cette dette sera remboursée. \ +\ +2. **Magasin de données d'événements** +Le magasin de données d'événements est une capture des détails des événements pouvant fournir une vue de reporting plus détaillée de ce qui s'est passé. + +**Limitations de l'effort du magasin d'événements dans ce groupe de travail** +Cette conception sera implémentée sur la version actuelle de Mojaloop. + +Actuellement, seules les données nécessaires pour fournir un traçage de bout en bout d'un transfert seront collectées et rendues disponibles via l'API de reporting. Des extensions à cette offre peuvent facilement être ajoutées en étendant le processeur d'événements pour traiter de nouveaux messages de cas d'utilisation et les stocker dans MongoDB, puis en configurant la requête de ressource GraphQL générique pour interroger les nouveaux magasins de données de manière appropriée. + +## Alignement avec l'architecture de référence +Bien que le contexte délimité se réfère au reporting et à l'audit, ce projet ne commence qu'à aborder la partie reporting de cette définition. La conception actuelle est indépendante des autres contextes délimités, ce qui est en accord avec l'architecture de référence. +(Il n'y a pas de séparation complète car la conception actuelle utilise une base de données réplica comme base de données de reporting. La dette technique et les prochaines étapes pour résoudre cela sont décrites ci-dessus.) + +Il est important de considérer comment ce contexte délimité changera à mesure que davantage de la conception de l'architecture de référence est implémentée. + +Les contextes délimités - lors de l'implémentation de l'architecture de référence - cesseront de stocker des données dans les bases de données du central ledger. + +Trois approches peuvent être adoptées pour accommoder ce changement. La façon dont l'architecture de référence est construite déterminera la meilleure approche : +1. Modifier la fonctionnalité de synchronisation pour accommoder le nouveau magasin de données du contexte délimité. +2. Étendre le processeur de messages d'événements pour capturer les informations requises dans la base de données de reporting. +3. Appeler les nouvelles API de contexte délimité définies, pour récupérer les données requises. + +## Cas d'utilisation pour soutenir le traçage d'un transfert + +Afin de tracer efficacement un transfert de bout en bout, quatre cas d'utilisation ont été définis. + +### Cas d'utilisation 1 : Vue du tableau de bord + +**En tant que** spécialiste des opérations métier d'un opérateur de Hub, +**je veux** un résumé de tableau de bord de haut niveau des transferts passant par le hub, dérivé d'une plage de date-heure, +**afin de** surveiller de manière proactive l'état de santé de l'écosystème. + +:::::: col-wrapper +| Données retournées | +| --- | +| Nombre de transferts | +| Montant total des transferts par devise | +| Nombre de transferts par code d'erreur | +| Nombre de transferts par DFSP payeur | +| Nombre de transferts par DFSP bénéficiaire | +| Montant des transferts par devise par DFSP payeur | +| Montant des transferts par devise par DFSP bénéficiaire | +::::::::: + +### Cas d'utilisation 2 : Vue de la liste des transferts + +**En tant que** spécialiste des opérations métier d'un opérateur de Hub, +**je veux** voir une liste de transferts pouvant être filtrée sur un ou plusieurs des critères suivants : +- Toujours requis (doit être fourni dans chaque appel) + - Plage de date-heure + +- Filtres optionnels + - Un DFSP bénéficiaire spécifique + - Un type d'ID bénéficiaire spécifique + - Un bénéficiaire spécifique + - Un DFSP payeur spécifique + - Un type d'ID payeur spécifique + - Un payeur spécifique + - État du transfert + - Devise + +- Filtres souhaitables (pas une exigence stricte, mais devraient être fournis si la conception le permet) + - Un code d'erreur spécifique + - Fenêtre de règlement + - ID de lot de règlement : L'identifiant unique du lot de règlement dans lequel le transfert a été réglé. Si le transfert n'a pas encore été réglé, il est vide. + - Chaîne de recherche sur les messages + +**afin de** surveiller de manière proactive l'état de santé de l'écosystème en ayant une vue plus détaillée des données de transfert passant par le hub. + +:::::: col-wrapper +| Données retournées | | +| --- | --- | +| ID de transfert | L'identifiant unique du transfert | +| État du transfert | Indique si le transfert a réussi, est en attente ou si une erreur s'est produite | +| Type de transfert | (Par exemple : P2P) | +| Devise | La devise du transfert | +| Montant | Le montant du transfert | +| DFSP payeur | | +| Type d'ID payeur | | +| Payeur | | +| DFSP bénéficiaire | | +| Type d'ID bénéficiaire | | +| Bénéficiaire | | +| ID de lot de règlement | L'identifiant unique du lot de règlement dans lequel le transfert a été réglé.
    Si le transfert n'a pas encore été réglé, il est vide. | +| Date de soumission | La date et l'heure auxquelles le transfert a été initié. | +::::::::: + +### Cas d'utilisation 3 : Vue du détail du transfert + +**En tant que** spécialiste des opérations métier d'un opérateur de Hub, +**je veux** tracer un transfert spécifique depuis son ID de transfert, +**afin de** pouvoir identifier : + +- La chronologie et l'état actuel du transfert +- Toute information d'erreur associée à ce transfert +- Les informations de devis associées et la chronologie pour ce transfert +- Le statut du processus de règlement associé et les identifiants + +:::::: col-wrapper +| Données retournées | | +| --- | --- | +| ID de transfert | L'identifiant unique du transfert | +| État du transfert | Indique si le transfert a réussi, est en attente ou si une erreur s'est produite | +| Type de transfert | (Par exemple : P2P) | +| Devise | La devise du transfert | +| Montant | Le montant du transfert | +| ID de lot de règlement | L'identifiant unique du lot de règlement dans lequel le transfert a été réglé.
    Si le transfert n'a pas encore été réglé, il est vide. | +| Payeur | | +| Détails du payeur | L'identifiant unique du payeur (généralement un MSISDN, c'est-à-dire un numéro de mobile) | +| DFSP payeur | | +| DFSP bénéficiaire | | +| Bénéficiaire | | +| Détails du bénéficiaire | L'identifiant unique du bénéficiaire (généralement un MSISDN, c'est-à-dire un numéro de mobile) | +| État du transfert | Indique si le transfert a réussi, est en attente ou si une erreur s'est produite | +| Date de soumission | La date et l'heure auxquelles le transfert a été initié | +::::::::: + +### Cas d'utilisation 4 : Vue des messages du transfert + +**En tant que** spécialiste des opérations métier d'un opérateur de Hub, +**je veux** voir les messages détaillés depuis son ID de transfert, +**afin de** pouvoir enquêter sur tout problème inattendu associé à ce transfert. + +:::::: col-wrapper +| Données retournées | | +| --- | --- | +| ID de transfert du schéma | | +| TransferID | | +| QuoteID | | +| ID de transfert domestique | | +| Informations sur le payeur et le bénéficiaire | Type d'ID, Valeur d'ID, Nom d'affichage, Prénom, Deuxième prénom,
    Nom, Date de naissance, Code de classification du marchand,
    ID FSP, Liste d'extensions | +| Réponse de recherche de partie | | +| Demande de devis | | +| Réponse de devis | | +| Préparation du transfert | | +| Exécution du transfert | | +| Message(s) d'erreur | | +::::::::: + +## Flux de travail métier +Voici un flux de travail métier qui décrit comment les cas d'utilisation sont appelés. +![Flux de travail métier](../../../.vuepress/public/BusinessFlowView.png) + +## Outils choisis +### Magasin de données d'événements : MongoDB +La base de données MongoDB a été choisie parce que : + - MongoDB est actuellement utilisé et déployé dans Mojaloop, et est un outil open-source accepté qui dispose optionnellement d'entreprises standard pouvant fournir un support d'entreprise si nécessaire. + - MongoDB répondra à nos exigences pour ce projet. + - D'autres outils ont été considérés mais se sont avérés ne pas répondre à toutes les exigences d'un outil OSS dans Mojaloop. + +### API : GraphQL +En plus de l'API de reporting existante, une API GraphQL sera également déployée. Cette nouvelle API aura la fonctionnalité supplémentaire de pouvoir accéder à la base de données de reporting des événements comme données supplémentaires ou données de requête autonomes. + +L'implémentation de l'API GraphQL a été ajoutée pour ces raisons : + - Une implémentation de modélisation RBAC plus naturelle + - Plus facile de mélanger des données provenant de différentes sources en une seule ressource + - L'implémentation de la solution de reporting existante a abouti à des instructions SQL très complexes nécessitant des connaissances spécialisées pour être construites et maintenues. La division des données en une ressource plus naturelle et une instruction SQL subséquente simplifie à la fois l'instruction SQL et l'utilisation de cette ressource. + - Dans l'équipe, nous avions un expert GraphQL qui connaissait la meilleure bibliothèque et les meilleurs outils à utiliser. + - Une implémentation générique a été construite afin qu'aucune connaissance spéciale de GraphQL ne soit requise pour étendre la fonctionnalité. + +**Avantages supplémentaires de l'utilisation de GraphQL** + - Ressources/permissions RBAC associées réutilisables entre les rapports + - Les requêtes complexes sont plus simples à construire car les ressources sont modélisées + - Mélange de sources de données dans une seule requête (par exemple MySQL avec MongoDB) + - Pas besoin de récupérations imbriquées + - Pas besoin de récupérations multiples + - Pas besoin de version d'API. L'API supporte naturellement la compatibilité ascendante entre les versions. + - API auto-documentée + +**Introduction d'une nouvelle technologie** +L'introduction d'une nouvelle technologie dans la communauté comporte certains risques et une exigence d'apprendre et de maintenir une nouvelle technologie. Une tentative de réduire l'impact de ceci a été faite en implémentant l'API selon une approche générique ou de template, minimisant les exigences de connaissance GraphQL pour l'implémentation. Un exemple de requête GraphQL a également été fourni. + +L'implémentation GraphQL actuelle est conviviale pour les développeurs. + +**Implémentation REST de reporting** +Il existe une implémentation d'API REST de reporting qui a été donnée à la communauté Mojaloop. Il est possible de déployer cette fonctionnalité parallèlement à l'implémentation de l'API GraphQL si cela devient nécessaire. + +### API GraphQL - implémentation de ressource générique expliquée +Au cœur de l'implémentation de ce contexte délimité se trouve une implémentation générique qui relie un magasin de données de reporting et une requête à une ressource de données GraphQL ayant sa propre autorisation RBAC. C'est-à-dire qu'une nouvelle ressource personnalisée peut être ajoutée à cette API en effectuant les opérations suivantes : + +1. Définir le type de magasin de données +2. Définir la requête +3. Définir les noms et champs de ressource GraphQL +4. Définir la permission utilisateur liée à cette ressource + +### Exemples de requêtes GraphQL + +**Interroger les transferts filtrés sur un DFSP payeur spécifique** +```GraphQL +query GetTransfers { + transfers(filter: { + payer: "payerfsp" + }) { + transferId + createdAt + payee { + name + } + } +} +``` + +**Interroger un résumé des transferts** +```GraphQL +query TransferSumary2021Q1 { + transferSummary( + filter: { + currency: "USD" + startDate: "2021-01-01" + endDate: "2021-03-31" + }) { + count + payer + } +} +``` + + +## Construction du magasin de données d'événements +L'objectif du magasin de données d'événements est de fournir un stockage persistant des événements d'intérêt qui sont facilement et efficacement trouvés et interrogés pour le reporting. + +Pour réaliser cela avec un minimum de changements structurels par rapport au message original, il a été décidé de traiter le message en catégories et de stocker ces catégories en tant que métadonnées supplémentaires dans le message, qui peuvent être interrogées ultérieurement. Les messages qui ne correspondent pas à ces catégories ne sont pas stockés et sont donc filtrés. + +Voici un exemple des métadonnées ajoutées au message JSON : + +```json{7-12} +{ + "event": { + "id" : {}, + "content" : {}, + "type" : {}, + "metadata" : {} + }, + "metadata" : { + "reporting" : { + "transactionId" : "...", + "quoteId": "...", + "eventType" : "Quote" + } + } +} +``` +Où `"eventType"` peut être l'un des suivants : +:::::: col-wrapper +::: col-third +::: + +::: col-third +| eventType | +| ------- | +|Quote | +|Transfer | +|Settlement | +::: +::::::::: + +Le processeur de flux d'événements s'abonnera au topic Kafka `'topic-event'`. Cette file de messages contient tous les messages d'événements. Un degré significatif de filtrage est donc nécessaire. + +:::tip REMARQUE +Le code qui implémente cette fonctionnalité a été structuré de manière à ce que ces filtres puissent être facilement modifiés ou étendus. +Les messages souscrits et classifiés sont représentés dans des fichiers 'const' afin qu'ils puissent facilement être ajoutés ou modifiés sans connaissance détaillée du code. +::: + +### Stocker uniquement les messages 'audit' + +Seuls les messages Kafka de type `'audit'` seront considérés pour la sauvegarde, c'est-à-dire uniquement si : +:::::: col-wrapper +::: col-third +::: +::: col-third +| metadata.event.type | +| ---- | +| audit | +::: +::::::::: + +## Messages 'Transfer' qui sont stockés +**ml-api-adapter** + +:::::: col-wrapper +| metadata.trace.service | +| ---- | +| ml_transfer_prepare | +| ml_transfer_fulfil | +| ml_transfer_abort | +| ml_transfer_getById | +| ml_notification_event | +::::::::: + +## Messages 'Quote' qui sont stockés +**quoting-service** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| qs_quote_handleQuoteRequest | +| qs_quote_forwardQuoteRequest | +| qs_quote_forwardQuoteRequestResend | +| qs_quote_handleQuoteUpdate | +| qs_quote_forwardQuoteUpdate | +| qs_quote_forwardQuoteUpdateResend | +| qs_quote_handleQuoteError | +| qs_quote_forwardQuoteGet | +| qs_quote_sendErrorCallback | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| qs_bulkquote_forwardBulkQuoteRequest | +| qs_quote_forwardBulkQuoteUpdate | +| qs_quote_forwardBulkQuoteGet | +| qs_quote_forwardBulkQuoteError | +| qs_bulkQuote_sendErrorCallback | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| QuotesErrorByIDPut | +| QuotesByIdGet | +| QuotesByIdPut | +| QuotesPost | +| BulkQuotesErrorByIdPut | +| BulkQuotesByIdGet | +| BulkQuotesByIdPut | +| BulkQuotesPost | +::: +::::::::: + +## Messages 'Settlement' qui sont stockés +**central-settlement** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| cs_process_transfer_settlement_window | +| cs_close_settlement_window | +| ... | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| getSettlementWindowsByParams | +| getSettlementWindowById | +| updateSettlementById | +| getSettlementById | +| createSettlement | +| closeSettlementWindow | +| ... | +::: +::::::::: + +## Messages qui restent actuellement non classifiés et sont filtrés +**account-lookup-service (pas dans PI - inclus comme référence)** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| ParticipantsErrorByIDPut | +| ParticipantsByIDPut | +| ParticipantsErrorByTypeAndIDPut | +| ParticipantsErrorBySubIdTypeAndIDPut | +| ParticipantsSubIdByTypeAndIDGet | +| ParticipantsSubIdByTypeAndIDPut | +| ParticipantsSubIdByTypeAndIDPost | +| ParticipantsSubIdByTypeAndIDDelete | +| ParticipantsByTypeAndIDGet | +| ParticipantsByTypeAndIDPut | +| ParticipantsByIDAndTypePost | +| ParticipantsByTypeAndIDDelete | +| ParticipantsPost | +| PartiesByTypeAndIDGet | +| PartiesByTypeAndIDPut | +| PartiesErrorByTypeAndIDPut | +| PartiesBySubIdTypeAndIDGet | +| PartiesSubIdByTypeAndIDPut | +| PartiesErrorBySubIdTypeAndIDPut | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| OraclesGet | +| OraclesPost | +| OraclesByIdPut | +| OraclesByIdDelete | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| postParticipants | +| getPartiesByTypeAndID | +| ... | +::: +::::::::: + +**transaction-requests-service (pas dans PI - inclus comme référence)** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ----- | +| TransactionRequestsErrorByID | +| TransactionRequestsByID | +| TransactionRequestsByIDPut | +| TransactionRequests | +| AuthorizationsIDResponse | +| AuthorizationsIDPutResponse | +| AuthorizationsErrorByID | +::: + +::: col-third +| metadata.trace.service | +| ----- | +| forwardAuthorizationMessage | +| forwardAuthorizationError | +| ... | +::: +::::::::: + +### Outils utiles + +#### Explorateur Kafka +Le logiciel ['kowl'](https://github.com/cloudhut/kowl) de cloudhut est un outil utile pour explorer tous les messages Kafka dans un cluster Mojaloop. Nous pouvons le déployer dans le même namespace que les services de base Mojaloop. + +Le fichier de valeurs personnalisées pour le déploiement OSS peut être trouvé dans ce [dépôt](https://github.com/mojaloop/deploy-config/tree/deploy/PI15.2/mojaloop/kowl-kafka-ui). +(Il s'agit d'un dépôt privé, vous pourriez avoir besoin d'une permission pour accéder à ce lien.) + +**Étapes d'installation** +``` +helm repo add cloudhut https://raw.githubusercontent.com/cloudhut/charts/master/archives +helm repo update +helm install kowl cloudhut/kowl -f values-moja2-kowl-values.yaml +``` +**Interface web** +Ouvrez l'URL configurée dans la section `ingress` du fichier `values`. + +**Personnalisation supplémentaire** +Pour des informations sur la façon d'ajouter des personnalisations supplémentaires, consultez la [configuration de référence](https://github.com/cloudhut/kowl/blob/master/docs/config/kowl.yaml) fournie par cloudhut. + +#### Chemin doré TTK +Les cas de test du chemin doré TTK ont été conçus pour explorer tous les résultats de test possibles lors de l'envoi de transferts. C'est donc un outil important qui peut être utilisé pour tester que la fonctionnalité couvre toutes les éventualités. C'est-à-dire que nous pouvons utiliser le TTK intégré pour exécuter différents cas de test tels que le chemin heureux P2P, les scénarios négatifs, les cas d'utilisation liés au règlement, etc. + +## Service de traitement des événements + +Le service de traitement des événements est responsable de l'abonnement aux topics Kafka et du filtrage des événements par type d'événement. Le type d'événement se décompose ensuite en plusieurs parties selon le service à partir duquel les événements ont été produits. Les événements filtrés seront ensuite traités en fonction du contexte de la structure de l'événement, et des métadonnées de reporting seront créées. + +Exemple : + +```json +{ + "event": { + "id" : {}, + "content" : {}, + "type" : {}, + "metadata" : {} + }, + "metadata" : { + "reporting" : { + "transactionId" : "...", + "quoteId": "...", + "eventType" : "Quote" + } + } +} +``` + +| eventType | Origine de l'événement | +| ------- | ------- | +|Quote | quoting-service | +|Transfer | ml-api-adapter | +|Settlement | central-settlement | + +Le service de traitement des événements s'abonne au flux d'événements Kafka pour construire un magasin lié aux événements de transfert qui peut être interrogé via l'API opérationnelle. Cela est en accord avec l'architecture de référence. diff --git a/docs/fr/technical/business-operations-framework/SecurityBC.md b/docs/fr/technical/business-operations-framework/SecurityBC.md new file mode 100644 index 000000000..608e20ead --- /dev/null +++ b/docs/fr/technical/business-operations-framework/SecurityBC.md @@ -0,0 +1,811 @@ +# Implémentation de l'API opérationnelle RBAC + +## Introduction à l'implémentation de l'API opérationnelle RBAC + +Les objectifs de cette implémentation sont de fournir une solution RBAC pour soutenir les opérations du hub et les fonctions associées. Ce guide présente la conception à haut niveau et explique la logique ayant mené à cette conception. + +La conception de la sécurité : +1. implémente le contrôle d'accès basé sur les rôles (RBAC) à la version actuelle de Mojaloop, +1. est compatible lorsque possible avec l'architecture de référence et donc avec les futures versions de Mojaloop, +1. est compatible avec les futurs déploiements Infrastructure-as-Code (IaC), +1. fournit une journalisation des activités qui peut être utilisée lors d'un audit. + +## Détails de l'implémentation RBAC +1. Les utilisateurs se voient endosser un ou plusieurs rôles. Un utilisateur peut endosser plusieurs rôles plusieurs rôles, sous réserve de règles définies. +1. Les rôles se voient attribuer des permissions. +1. Le Proxy d'Identité et d'Accès (Ory Oathkeeper) applique l'accès aux endpoints en fonction des permissions. +1. L'API backend peut, en option, vérifier les permissions via l'API Keto. +1. Des ensembles de permissions mutuellement exclusives peuvent être définis dans le système pour faire respecter la séparation des tâches. + +## Application du principe Maker-Checker +Deux approches peuvent être utilisées pour appliquer un flux de validation maker-checker. +1. Appliquer via les rôles et les permissions mutuellement exclusives, à travers les politiques de sécurité. C.-à-d. les makers ne peuvent pas aussi être checkers. +1. Appliquer dans la couche application via des règles de sécurité. C.-à-d. les makers ne peuvent pas non plus être checkers dans le même processus de validation. Cela est souvent mis en œuvre dans la couche application lors de l'attribution des makers/checkers comme défini dans un flux de processus, et en imposant qu'un checker ne puisse pas être la même personne que le maker dans le processus de validation. Le code qui applique cela existera dans chaque contexte borné. + +::: tip Responsabilité RBAC +Pour prendre en charge cette fonctionnalité, le système RBAC doit fournir : +1. l'identifiant utilisateur à ce contexte borné, +1. un moyen de vérifier l'autorisation si nécessaire. +::: + +### Fourniture de l'identifiant utilisateur +La configuration actuelle fournit l'identifiant de l'utilisateur dans l'en-tête des appels API. +Ory Oathkeeper est configuré pour utiliser un "mutateur" d'en-tête. Ce mutateur transformera la requête, permettant de passer les informations d'identification à l'application en amont via les en-têtes. Par exemple, les backends d'API recevront l'en-tête suivant dans les requêtes HTTP : +``` +X-User: wso2-uuid +``` + +Il est à noter que les "id_token" JWT sont également facilement supportés en modifiant la configuration du mutateur Ory Oathkeeper. Le mutateur "id_token" prend les informations d'authentification (par exemple le subject) et les transforme en un JSON Web Token signé, et plus spécifiquement en un ID Token OpenID Connect. Les backends d'API peuvent vérifier ce token en allant chercher la clé publique depuis l'endpoint /.well-known/jwks.json fourni par l'API Ory Oathkeeper. + +### Vérification de l'autorisation +Toutes les informations d'autorisation sont stockées dans Ory Keto. Ory Keto dispose d'une API standard qui peut être appelée pour vérifier une autorisation. +C'est-à-dire : *« Ce jeton d'identifiant utilisateur a-t-il cette permission ? »* + +## Outils / standards choisis +Voici une liste d'outils standards sélectionnés pour implémenter ce design. +1. **Ory Oathkeeper** +Sera utilisé comme Proxy d'Identité et d'Accès (IAP) qui vérifiera l'authentification et l'autorisation avant de donner accès aux endpoints fonctionnels, c'est-à-dire qu'il sera utilisé pour appliquer le contrôle d'accès. +2. **Ory Keto** +Vérifiera l'autorisation via les correspondances sujet-rôle et rôle-permission. Utilise une structure flexible d'objet, de relation et de sujet, initié chez Google, pouvant modéliser divers schémas d'autorisation, y compris le contrôle d'accès basé sur les rôles (RBAC). +3. **Ory Kratos** +Sera Utilisé pour créer et gérer l'objet d'autorisation (cookie). +4. **OpenID Connect** +C'est le standard retenu pour interagir avec un système de gestion d'identité. Ce standard est largement adopté et compatible avec tous les outils utilisés actuellement dans la communauté Mojaloop, à savoir, WSO2 Identity Server (IS), Keycloak et Ory Kratos. + +## Vue d'ensemble de l'architecture +Voici une vue d'ensemble de haut niveau de l'implémentation de l'API opérationnelle RBAC sur la version actuelle de Mojaloop. + +![Diagramme d'architecture générale de l'implémentation du contexte de sécurité](../../../.vuepress/public/BizOps-Framework-IaC-3.xx-&-Mojaloop-13.xx.png) + +Voici un tableau des services et de leur rôle respectif. +| Service | Gère | Rôle | +| --- | --- | --- | +|**WSO2 IS KM**|Utilisateurs| 1. Redirection de la connexion utilisateur et UI qui crée le cookie
    2. Flux d'autorisation standard OpenID Connect (OIDC) | +|**Ory Keto**|1. Mappage rôles-utilisateurs
    2. Mappage participants-utilisateurs| 1. Vérification d'autorisation RBAC via Ory Oathkeeper
    2. Vérification d'autorisation RBAC via appel API opérationnelle| +|**Ory Oathkeeper**|Permissions liées à l'accès API | Passerelle API pour les APIs opérationnelles, avec contrôles d'authentification et d'autorisation| +|**Ory Kratos**|Aucune|Cookie d'authentification| +|**API opérationnelle du contexte borné**|Permissions liées aux appels API opérationnels|Fonctions API opérationnelles| +|**Shim**| Aucune | Redirection pour configurer OIDC| +|**Rôle Opérateur**| Aucune | Met à jour Keto pour refléter les changements de mapping rôle-permission réalisés dans le fichier ressource des rôles| +|**Fichier de ressources rôle Kubernetes**| Rôles et assignations de rôles-permissions| Modifications contrôlées par implémentation de contrôle de version (par exemple GitHub ou GitLab).| +|**API des Rôles**|Aucune|1. Contrôle API rôle-utilisateur
    (liste des utilisateurs, liste des rôles, liste des rôles attribués aux utilisateurs, ajouter un rôle à un utilisateur, enlever un rôle à un utilisateur)
    2. Contrôle API participant-utilisateur
    (liste des utilisateurs, liste des participants, liste des participants attribués à un utilisateur, ajout/suppression de participant à un utilisateur)| + +## Alignement avec l'architecture de référence +Comparons cette implémentation RBAC à celle définie dans l'architecture de référence, appelée "bounded context sécurité". Cette conception diffère de l'architecture de référence par sa fonction, son but et son approche, mais elle en adopte certaines idées quand cela est approprié. Le but de cette RBAC est d'ajouter une couche de sécurité aux APIs opérationnelles des contextes bornés. L'architecture de référence du "Security Bounded Context"/"contexte de sécurité de référence" a été conçue pour prendre en compte les exigences de performance des fonctions transactionnelles critiques de Mojaloop. +Voici les principales différences : +1. Les fonctions d'autorisation sont centralisées dans cette RBAC. L'architecture de référence prévoit une autorisation distribuée, mise en œuvre indépendamment dans chaque contexte borné. Ce niveau de complexité supplémentaire est inutile dans le cas des APIs opérationnelles. +1. L'architecture de référence demande des interfaces vers d'autres contextes bornés pour initier l'autorisation distribuée. Elles n'ont pas été construites car aucun composant n'existe pour les consommer. +1. L'architecture de référence exige que le contexte de sécurité génère ses propres tokens de sécurité. Cette RBAC utilise ceux générés par l'IAM. +1. L'architecture de référence exige que les permissions soient distribuées via les JWT à chaque contexte borné. Cela pourrait être paramétré dans l'outillage actuel, mais ne l'a pas été car certains expert considèrent cette distribution comme une vulnérabilité, et ce n'était pas nécessaire pour cette implémentation RBAC. + +Certains principes du contexte de sécurité de référence ont été repris : +1. Chaque contexte borné possède son propre jeu de permissions ou privilèges. +1. L'implémentation RBAC centralise toutes les associations privilèges/utilisateurs. +1. Les permissions de rôles utilisateurs sont structurées pour être facilement distribuable dans un cluster Kubernetes. + +## Alignement avec IaC 4.xxx +Voici un schéma illustrant à quoi ressemblerait l'architecture si l'API opérationnelle RBAC était implémentée dans la future version IaC (IaC 4.xxx) utilisant Keycloak et Ambassador / Envoy entre autres évolutions. + +![Diagramme d'architecture générale de l'implémentation du contexte de sécurité](../../../.vuepress/public/BizOps-Framework-IaC-4.xx-&-Mojaloop-13.xx.png) + +## Caractérisation des performances de l'implémentation RBAC +Une caractérisation des performances du POC RBAC a été réalisée pour évaluer la surcharge de la couche de sécurité RBAC. +::: tip En résumé : +Le RBAC ajoute une surcharge de 10ms à chaque vérification d'autorisation API. +Si un appel API requiert une vérification d'autorisation supplémentaire via API, la surcharge est alors de 20ms. + +Dans nos tests, cela se traduit typiquement par : +1. moins de 5% pour des vérifications d'autorisation simples (Ory Oathkeeper & Ory Keto) +1. moins de 10% pour des vérifications doubles (Ory Oathkeeper & Ory Keto + un appel Keto additionnel) +::: + +**Configuration des tests de caractérisation** +Sur la même infrastructure de test, des appels chronométrés identiques ont été effectués sur la même API backend et via RBAC. +Voici les résultats des appels aux APIs Role avec et sans RBAC et aux APIs POST Transfers avec et sans RBAC. L'API Role a une seule vérification d'autorisation réalisée via Ory Oathkeeper qui appelle Ory Keto. L'API Transfer (GraphQL) ajoute une vérification RBAC additionnelle. + +**Statistiques des requêtes** + +|Méthode| Nom| # Requêtes| # Échecs| Moyenne (ms)| Min (ms)| Max (ms)| Taille Moyenne| Taille moyenne (octets) RPS| Echecs/s| +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +|GET| Role API| 321| 0| 248| 221| 499| 604| 9.0| 0.0| +|GET| Role API RBAC| 320| 0| 262| 232| 418| 604| 8.9| 0.0| +|POST| Transfers API| 318| 0| 229| 184| 373| 4873| 8.9| 0.0| +|POST| Transfers API RBAC| 314| 0| 240| 194| 406| 4873| 8.8| 0.0| +| | **Agrégé**| **1273**| **0**| **245**| **184**| **499**| **2723**| **35.5**| **0.0**| + +**Statistiques des Temps de Réponse** + +|Méthode| Nom| 50%ile (ms)| 60%ile (ms)| 70%ile (ms)| 80%ile (ms)| 90%ile (ms)| 95%ile (ms)| 99%ile (ms)| 100%ile (ms)| +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +|GET| Role API| 240| 240| 240| 250| 270| 290| 400| 500| +|GET| Role API RBAC| 250| 260| 260| 270| 290| 320| 410| 420| +|POST| Transfers API| 220| 220| 240| 250| 290| 330| 360| 370| +|POST| Transfers API RBAC| 230| 240| 250| 280| 310| 330| 400| 410| +| |**Agrégé**| **240**| **250**| **250**| **260**| **290**| **320**| **400**| **500**| + +## Connexion à l'interface utilisateur (UI) +Ce diagramme de séquence illustre les événements lors d'une tentative d'accès à une API backend depuis un navigateur : +- Si le navigateur est déjà connecté, la requête est transférée. +- Sinon, un classique flux autorisation OIDC standard démarre avec une redirection. + +![Diagramme de séquence illustrant la connexion d'un navigateur](../../../.vuepress/public/frontend.png) + +## Consultation des données via le micro-frontend API opérationnelle du contexte borné +Le diagramme suivant détaille les interactions lorsque : +- le bearer token est valide ou non, +- l'autorisation réussit ou échoue. + +Le micro-frontend est représenté comme un client. + +![Diagramme de séquence illustrant une vérification d'autorisation sur un appel client API](../../../.vuepress/public/client.png) + +Dans certains cas, il peut être nécessaire d'effectuer une vérification d'autorisation plus détaillée côté API opérationnelle. Le diagramme suivant décrit comment cela est implémenté. + +À noter que toutes les APIs opérationnelles ne requièrent pas ce niveau d'autorisation, et qu'Ory Oathkeeper peut ou non être nécessaire dans ces cas. + +![Diagramme de séquence illustrant une vérification d'autorisation sur un appel client API](../../../.vuepress/public/clientgraphql.png) + +## Application de la Séparation des Tâches +Cette implémentation RBAC permet de faire respecter la séparation des tâches via des ensembles de permissions mutuellement exclusives. Cela renforce la sécurité mais peut accroitre la complexité pour l'administrateur de la sécurité des utilisateurs finaux du système. Appliquer des permissions mutuellement exclusives permet d'en réduire et gérer la complexité. + +Un exemple pourrait être un utilisateur qui peut accéder au Portail Finance et réaliser des opérations sensibles (ajout/retrait de fonds). Cet utilisateur ne devrait plus avoir accès. + +### Modélisation de l'exclusion +Cette implémentation modélise ce besoin comme un ensemble d'exclusions permission-permission appliqué globalement. Ces exclusions sont définies comme deux ensembles de permissions qui sont mutuellement exclusifs—ce qui est intuitif et facile à maintenir. + +*Justification* +Cette exclusion auraient pu être modélisées de trois façons: +1. Exclusions de type permission - permission +1. Exclusions de type rôle-utilisateur - rôle-utilisateur +1. Exclusions de type rôle-utilisateur - permission + +Cette fonctionnalité ayant été ajoutée pour prendre en charge la ségrégation/séparation des tâches, la méthode la plus propre pour répondre à cela consiste à définir une exclusion par paire de permission, au niveau global. Avec toutles les autres options, il est possible que l'exclusion soit contournée par la création d'un rôle inclusif supplémentaire. + +### Rôles synthétiques versus multiples rôles utilisateur +Cette implémentation RBAC n'utilise pas de rôles synthétiques, mais utilise plutôt l'affectation de multiples rôles fonctionnels à chaque utilisateur. + +*Justification* +Deux méthodes sont possibles pour modéliser RBAC avec des permissions mutuellement exclusices: +1. Construire dynamiquement un rôle synthétique pour chaque utilisateur, à partir des règles définies sur leurs rôles actuels, leurs permissions et exclusions. +1. Définir des rôles associés aux fonctions utilisateurs; chaque utilisateur devra donc se voir attribuer plusieurs rôles. Les permissions des rôles ont moinds de chances de changer. + +La seconde méthode est privilégiée car elle est beaucoup plus simple à comprendre, maintenir et assurer le support de cette méthode. Identifier la cause d'une perte de droits dans un rôle synthétique suite à l'application de plusieurs rôles et de règles nécessite une compréhension détaillée du processus de calcul et d'implémentation. Cette complexité est évitée en optant pour la deuxième solution. + +### Affectation de multiples rôles utilisateur et vérification dynamique des exclusions +Permettre à l'administrateur d'attribuer plusieurs rôles par utilisateur est pratique, flexible et réduit le nombre de rôles dans l'organisation. Cela signifie également rend possible la violation de permissions mutuellement exclusives lors de telles affectations. Les contrôles doivent donc être dynamiques. + +Ils s'effectuent à plusieurs endroits : +1. Lors de l'attribution d'un rôle à un utilisateur +1. Lors de l'application d'une nouvelle définition ressource rôle-permission, ou d'une nouvelle politique de sécurité impliquant des changements massif dans la structure des rôles et permissions. +::: warning Extension future : +S'il est possible qu'une violation existe, alors chaque consultation de permission devrait également vérifier les violations d'exclusions. Pour l'instant cela n'est pas prévu, on considère que les points précédents sont bien appliqués pour éviter le problème. +Ce contrôle additionnel est recommandé pour de futures évolutions, afin que nulle contournement par porte dérobée de la séparation des tâches ne puisse être réalisée. +::: + +::: tip Remarque : +La gestion de changement et les tests sur des environnements inférieurs ne détectent pas forcément ces violations. Il faut que le contrôle des accès utilisateurs soit strictement identique entre environnements de test/développement pour pouvoir tester efficacement ces violations, ce qui est rarement le cas. +::: + +**Relation Keto: introduction** +Introduction d'une relation reliant deux permissions qui ne peuvent pas coexister. +``` +“Définition de ressource personnalisée d’exclusion de permission :X excludes permission:Y#allowed” +``` + +**Définition Custom Resource Exclusion de Permission** +Des ressources customisées d'exclusion de permission sont consommées par le contrôleur de rôles-permissions, qui les transmet à Keto. Chaque ressource contient deux ensembles de permissions, et avoir une permission d'un ensemble exclut celles de l'autre. Cela permet d'exprimer de nombreux scénarios flexibles, y compris le scénario le plus simple d'exclusion bi-directionnelle reste simple à exprimer. + +**Vérification API d'un changement opérateur rôle-permission** +Le contrôleur ressource rôle-permission met à disposition une API permettant de pré-vérifier qu'une mise à jour sera acceptable. Cette API prend la modification proposée, et renvoie si un conflit d'exclusions serait introduit. Elle est exploitable par l'UI Administrateur et les outils CI/CD. + +**Application effective du changement opérateur rôle-permission** +Lorsqu'une ressource est modifiée, l'opérateur verrouille temporairement la modification des attributions de rôles, effectue la même vérification, et si la modification ne passe pas, elle est rejetée et la situation actuelle conservée ; le problème est remonté dans l'API Kubernetes pour instrumentation/alerte. + +**Vérification de conflit à l'attribution d'un rôle utilisateur** +Lorsqu'un utilisateur reçoit un nouveau rôle, le système vérifie que cela ne provoque pas de conflit d'exclusions. Si c'est le cas, l'opération est rejetée avec une erreur. + +## Attribution des rôles et de la participation aux utilisateurs +Cette fonctionnalité est implémentée dans le service API des Rôles. Le diagramme ci-dessous décrit comment les rôles et les accès participants de l'utilisateur sont interrogés et modifiés via cette API. +![Diagramme de séquence illustrant l'attribution des rôles et participation utilisateur](../../../.vuepress/public/userroles.png) + +### API des Rôles +Le tableau suivant fait la synthèse des ressources de l'API des Rôles. + +|Catégorie|Méthode|Endpoint| Description|Codes d'erreur| +| --- | --- | --- | --- | --- | +|**HEALTH**| | | | | +| | GET | /health | Retourne l'état actuel de l'API | 400, 401, 403, 404, 405, 406, 501, 503 | +| | GET | /metrics | Retourne les métriques de l'API | 400, 401, 403, 404, 405, 406, 501, 503| +|**PARTICIPANTS**| | | | | +| | GET | /participants | Retourne la liste des IDs de participants | 400, 401, 403, 404, 405, 406, 501, 503| +|**RÔLES**| | | | | +| | GET | /roles | Retourne la liste des IDs de rôles |400, 401, 403, 404, 405, 406, 501, 503 | +|**UTILISATEURS**| | | | | +| | GET | /users | Retourne la liste des IDs utilisateurs | 400, 401, 403, 404, 405, 406, 501, 503| +| | GET | /users/{ID} | Retourne les infos d'un utilisateur spécifique|400, 401, 403, 404, 405, 406, 501, 503 | +| | GET | /users/{ID}/participants | Liste les participants attribués à un utilisateur |400, 401, 403, 404, 405, 406, 501, 503| +| | PATCH | /users/{ID}/participants | Assigne un participant à un utilisateur | 400, 401, 403, 404, 405, 406, 501, 503| +| | GET | /users/{ID}/roles | Liste des rôles attribués à un utilisateur|400, 401, 403, 404, 405, 406, 501, 503 | +| | PATCH | /users/{ID}/roles | Assigne un rôle à un utilisateur|400, 401, 403, 404, 405, 406, 501, 503 | + +La spécification détaillée de l'API est disponible [ici](https://docs.mojaloop.io/role-assignment-service/). +Le dépôt GitHub du service est disponible [ici](https://github.com/mojaloop/role-assignment-service). + +## Attribution des permissions aux rôles & ensembles mutuellement exclusifs +L'attribution des permissions aux rôles est stockée dans un fichier `.yml` appelé fichier ressource de rôle (`roleresource.yml`). +Les accès et les modifications sur ces fichiers sont gérés via une solution de gestion de versions hébergée (ex. : GitHub, GitLab). Cela assure un historique complet et des points de contrôle automatiques et manuels configurables. +Ces fichiers sont définis comme des définitions de ressources personnalisées (CRD) Kubernetes, auxquels un opérateur rôle-permission s'abonne. Les changements déclenchent la mise à jour d'Ory Keto. Un même rôle peut être représenté par plusieurs fichiers au besoin. + +Il existe deux types de fichiers de ressource : un pour les attributions rôle-permission, l'autre pour les permissions mutuellement exclusives. + +Exemple d'un fichier rôle-permission : +```yml +apiVersion: "mojaloop.io/v1" +kind: MojaloopRole +metadata: + name: nom-arbitraire-ici +spec: + # doit correspondre à ce qui est utilisé dans Keto, quelle que soit la valeur + role: IdentifiantRole + permissions: + - permission_01 + - permission_02 + - permission_03 + - permission_04 +``` +Le diagramme de séquence suivant illustre comment Ory Keto est mis à jour. + +![Diagramme de séquence illustrant l'attribution des rôles et participation utilisateur](../../../.vuepress/public/rolepermissions.png) + +## Détail d'implémentation Ory Keto +Dans cette conception, Ory Keto est l'outil qui détermine si un jeton de connexion possède la bonne autorisation pour accéder à une partie du système, c'est-à-dire qu'il est utilisé pour faire respecter le RBAC. Trois volets sont gérés : +1. L'attribution des rôles aux utilisateurs. +Cette fonctionnalité sera maintenue et mise à jour depuis le module API des Rôles, qui appellera et mettra à jour Keto en conséquence. +2. L'attribution des accès participants à un utilisateur. +Cela concerne les rapports d'accès DFSP qui ne doivent être délivrés que pour les participants configurés. +Cette fonctionnalité sera également maintenue via le module API des Rôles, qui appellera et mettra à jour Keto en conséquence. +3. L'attribution des permissions/privilèges aux rôles. +Contrôlée via les modifications du fichier `roleresource.yml` sur GitHub. L'opérateur rôle-permission surveille ces fichiers et met à jour Keto. + +### Ajouter des rôles et des accès aux participants dans Keto +La liste des utilisateurs (personnes et comptes de service) vient du serveur d'identités WSO2 ; celle des participants, d'une API existante. Un identifiant permanent et durable doit être utilisé pour les appels Keto. + +Les rôles sont hardcodés, chacun avec un identifiant court, lisible et inscriptible, ainsi qu'un nom. L'interface devrait afficher l'identifiant et le nom, car l'identifiant sera nécessaire pour l'opérateur rôle-permission. + +Deux espaces de nom Keto sont utilisés : role et participant. Les tuples Keto sont : +``` +role:ROLEID#member@USERID et participant:PARTICIPANTID#member@USERID +``` +(selon la notation [Keto/Zanzibar](https://www.ory.sh/keto/docs/concepts/relation-tuples)) + +La réutilisation de "member" pour la relation ne pose pas problème, chaque relation étant spécifique à l'espace de nom. Un autre terme peut être utilisé si préféré. + +Pour récupérer les rôles/participants d'un utilisateur : utiliser [l'API de requête de tuples de relation](https://www.ory.sh/keto/docs/reference/rest-api#query-relation-tuples), en passant namespace, relation et subject. La réponse inclura les tuples et un next-page-token si besoin. + +Pour ajouter/supprimer un rôle ou participant pour un utilisateur : utiliser [create](https://www.ory.sh/keto/docs/reference/rest-api#create-a-relation-tuple) et [delete](https://www.ory.sh/keto/docs/reference/rest-api#delete-a-relation-tuple) ; chaque appel traite un seul tuple. Si l'appel échoue, mais que l'échec n'est pas une erreur HTTP 4xx, il devrait être retenté quelques fois. + +Exemple d'appel Keto pour ajouter un rôle à un utilisateur : +::: tip Exemple : Attribuer un rôle à un utilisateur via Ory Keto +PATCH /relation-tuples HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: + +```json +[ + { + "action": "insert", + "relation_tuple": { + "namespace": "role", + "object": "RoleIdentifier", + "relation": "member", + "subject": "userIdentifier" + } + } +] +``` +Succès = HTTP 204 sans contenu. + +::: tip REMARQUE +Le champ `"relation"` utilise `"member"`. +On utilise `PATCH` plutôt que `PUT` car `PATCH` fonctionne comme une création et/ou suppression en lot. +::: + +### Attribution des permissions/privilèges à un rôle dans Keto +Ceci se fait via un opérateur Kubernetes dédié à une définition de ressource personnalisée [(CRD)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/_print/). L'opérateur pourrait être implémenté dans presque n'importe quel langage. L'expertise existante de ModusBox en opérateurs repose principalement sur `kopf`, un framework Python, mais il existe aussi des options en Go et Node (et d'autres). + +L'opérateur doit garder en mémoire l'ensemble des ressources qu'il gère, regroupées par rôle. [L'indexation de Kopf](https://kopf.readthedocs.io/en/latest/indexing/) est idéale pour ceci. + +Lorsqu'une ressource de rôle change, la liste des permissions de ce rôle, sur l'ensemble des ressources de rôle, doit être compilée, et un changement envoyé via l'API Patch [Multiple Relation Tuples](https://www.ory.sh/keto/docs/reference/rest-api#patch-multiple-relation-tuples) en utilisant les actions `insert` et `delete`. Il est nécessaire de prendre en compte toutes les ressources de rôle, car un même rôle peut être réparti sur plusieurs ressources, et plusieurs peuvent inclure la même permission ; supprimer une ressource de rôle qui associe le Rôle X à la Permission P ne signifie pas nécessairement que le tuple Keto pour cette association rôle-permission doit être supprimé, car une autre ressource de rôle peut toujours associer le Rôle X à la Permission P. + +Les tuples Keto auront la forme suivante : +``` +permission:PERMISSIONID#granted@role:ROLEID#member +``` + +Opérations détaillées lors du changement de ressource : +1. Récupérer les permissions actuellement accordées au rôle via [l'API de requête de tuples de relation](https://www.ory.sh/keto/docs/reference/rest-api/#query-relation-tuples). +2. À partir de l'index stocké des rôles vers les permissions, calculer la différence à partir de la liste récupérée. +3. Exécuter le patch à partir de la différence. +4. En cas de problème, lever une exception pour que le problème soit journalisé et qu'une resynchronisation soit tentée ultérieurement. + +Exemple d'appel Keto pour assigner une permission à un rôle : +::: tip Exemple : Attribuer une permission/privilège à un rôle +PATCH /relation-tuples HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: + +```json +[ + { + "action": "insert", + "relation_tuple": { + "namespace": "permission", + "object": "permissionIdentifier", + "relation": "granted", + "subject": "role:x#member" + } + } +] +``` +Succès = HTTP 204 sans contenu. + +::: tip REMARQUE +Le champ `"relation"` utilise `"granted"`. +On utilise `PATCH` plutôt que `PUT` car `PATCH` fonctionne comme une création et/ou suppression en lot. +::: + +### Ajout de permissions mutuellement exclusives dans Keto +Les ensembles de permissions mutuellement exclusives sont aussi modélisés dans Keto via la relation "excludes". +La relation qui relie deux permissions qui ne doivent pas coexister s'écrit : +``` +“permission:X excludes permission:Y#allowed” +``` + +::: tip REMARQUE +On utilise `"excludes"` pour désigner les exclusions de permissions. +::: + +### Appel standard à l'API Keto pour vérifier l'autorisation +La vérification de l'autorisation d'un utilisateur pour un privilège ou une permission est gérée par la passerelle API, et si nécessaire, peut être vérifiée par chaque contexte borné. + +Exemple de requête Keto pour vérifier si un utilisateur détient une permission : +::: tip Exemple : Vérification d'une autorisation dans Ory Keto +POST /check HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: +```json +{ + "namespace": "permission", + "object": "PermissionIdentifier", + "relation": "granted", + "subject": "UserIdentifier" +} +``` +Réponse : +```json +{ +"allowed": true/false +} +``` +::: tip Remarque : +Les permissions mutuellement exclues n'ont pas besoin d'être vérifiées explicitement par un appel Keto, car le système est maintenu de manière à ce que les attributions rôle-permission ne puissent être définies que si les ensembles de permissions mutuellement exclusives ne sont pas violés. +::: + +## Ory Oathkeeper – détail d'implémentation +### Configuration de Ory Oathkeeper pour BizOps + +[ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/next/) contrôle l'autorisation des requêtes HTTP entrantes. Il peut agir comme point d'application de la politique (PEP) dans une architecture cloud, c'est-à-dire un reverse proxy devant l'API ou le serveur web en amont qui rejette les requêtes non autorisées et transmet les requêtes autorisées au serveur. Si un autre API Gateway est utilisé (Kong, Nginx, Envoy, AWS API Gateway…), Ory Oathkeeper peut également s'y intégrer et servir de point de décision de politique (PDP). + +Le chart Helm Ory Oathkeeper est décrit [ici](https://k8s.ory.sh/helm/oathkeeper.html) et défini [là](https://github.com/ory/k8s/tree/master/helm/charts/oathkeeper). Le référentiel Helm est documenté [ici](https://k8s.ory.sh/helm/). La configuration de référence est [là](https://www.ory.sh/oathkeeper/docs/reference/configuration). Toutes les valeurs peuvent être surchargées par des variables d'environnement. + +Le chart Helm Ory Oathkeeper déploie deux composants clés dans Kubernetes : Ory Oathkeeper lui-même, et Ory Oathkeeper Maester. Ory Oathkeeper est sans état et piloté par la configuration ; il se recharge de manière transparente sans interruption de service à chaque changement de configuration. Ory Oathkeeper Maester est un contrôleur pour la CRD Rule et compose les objets Rule dans Kubernetes en un fichier de règles unique et complet chargé par Ory Oathkeeper. Par défaut, il s'agit d'un ConfigMap monté par Ory Oathkeeper, mais il peut aussi être configuré en sidecar avec un montage partagé. + +Ory Oathkeeper expose deux ports sous forme de deux services : un service API et un service Proxy. À long terme, nous utiliserons le service API, qui sera interrogé par la passerelle API de nouvelle génération via l'[API Access Control Decision](https://www.ory.sh/oathkeeper/docs/reference/api/#access-control-decision-api) fournie par Ory Oathkeeper ; pour l'instant, nous utiliserons le service Proxy, exposé via Ingress. Les URL externes des services protégés par Ory Oathkeeper pointeront vers l'ingress du Proxy Ory Oathkeeper, qui fera ensuite le proxy vers les services internes à ces URL et appliquera les règles de contrôle d'accès. + +Ory Oathkeeper sera configuré pour générer et signer un JSON Web Token (JWT) contenant des revendications que les services internes peuvent vérifier en pointant vers le jeu de clés JSON Web (JWKS) publié par Ory Oathkeeper (voir [listes-cryptographic-keys](https://www.ory.sh/oathkeeper/docs/reference/api/#lists-cryptographic-keys)). Si un service fait cela, il opère alors dans un régime de confiance zéro de base, car il ne sera pas possible d'appeler ce service sauf avec un jeton généré par Ory Oathkeeper, et Ory Oathkeeper ne générera un jeton que si les règles d'accès pour l'URL donnée autorisent l'accès. + +### Débogage +Les réponses/logs d'Oathkeeper sont généralement informatifs. Vérifiez les logs lors d'une requête problématique. Oathkeeper log aussi des health checks, etc. + +Quelques actions de débogage utiles dans différentes circonstances : + +- Rendre une correspondance beaucoup plus permissive (en remplaçant la partie entière commençant par `<.*>` et en conservant le suffixe unique minimum actuel). + +- Vérifier minutieusement que chaque URL interne est bien l'URL interne appropriée en vérifiant qu'elle est accessible dans le cluster avec curl. + +- Examiner les logs du fournisseur d'identité (IdP). + +- S'assurer que les domaines et les ports pour l'introspection et l'endpoint de jeton externe sont identiques. Keycloak notamment n'apprécie pas qu'ils ne le soient pas. + +- Pointer la règle Ory Oathkeeper vers [https://httpbin.org/](https://httpbin.org/), généralement le préfixe de chemin `/anything` qui renverra tout ce qu'il reçoit, ce qui facilite la visualisation de ce que le service verra. + +### Éléments nécessaires en plus d'un chart Helm + +Les éléments suivants seront nécessaires en plus du chart Helm : + +- un secret JWKS, +- des valeurs Helm annotées. + +#### Secret JWKS + +Un secret doit être créé avec la clé `mutator.id_token.jwks.json` et la valeur d'un JWKS adapté à Ory Oathkeeper. Un JWKS initial peut être généré comme décrit dans [Configure and Deploy | ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/configure-deploy#cryptographic-keys). Il contiendra les clés publiques et privées. + +##### Utilisation du secret JWKS + +Pour faire tourner le secret, appliquer la procédure suivante : + +0. Noter l'heure. +1. Ajouter une paire de clés publique et privée au début du tableau dans le JWKS (s'assurer que toutes les JWK publiques ont un `kid` unique spécifié) dans le secret. Toutes les clés autres que les nouvelles clés et les premières clés publique et privée précédentes peuvent être supprimées, car Ory Oathkeeper signe toujours avec la première clé. +2. Attendre que toutes les requêtes qu'Ory Oathkeeper aurait pu recevoir et autoriser aient eu leur JWT traité par le service backend. Le délai principal ici est le temps de propagation de la mise à jour du secret, comprenant le délai du gestionnaire de secrets vers le secret mis à jour et le délai du secret vers le volume mis à jour, ce qui est probablement d'une minute ou deux au maximum ; attendre aussi longtemps après l'heure notée à l'étape 0. +3. Si l'ancien secret doit être supprimé (ce n'est nécessaire que si une violation est suspectée, sinon l'étape 1 suffit pour la rotation périodique des clés), retirez-le maintenant. + +#### Valeurs Helm annotées + +Plusieurs endroits devront être modifiés pour utiliser les URL ou autres valeurs spécifiques au reste du déploiement. Ces endroits sont décrits dans les commentaires de l'exemple ci-dessous, ainsi que d'autres commentaires. + +La configuration du Proxy ingress n'est pas encore décidée à ce stade, car elle devra changer lorsque la solution sera ajoutée à l'IaC 3.xxx ; cette zone de la configuration n'est donc pas encore spécifiée. Cela laisse l'ingress hors configuration par défaut. Modifier `ingress.proxy.enabled` à `true` activera le proxy ingress. Voir les pages liées au début pour les options disponibles pour la configuration ingress intégrée. + +Si le TLS doit être terminé au niveau d'Ory Oathkeeper, voir les sections `tls` dans la [documentation de configuration](https://www.ory.sh/oathkeeper/docs/reference/configuration), et combinez cela avec des secrets et les valeurs `deployment.extraVolumes` et `deployment.extraVolumeMounts`. +Prometheus est accessible sur `:9000/metrics` par défaut, s'il est utilisé. + +```yaml + +oathkeeper: + config: + log: + level: trace + access_rules: + matching_strategy: regexp + authenticators: + cookie_session: + enabled: true + config: + check_session_url: http://kratos-public/sessions/whoami + preserve_path: true + extra_from: "@this" + subject_from: "identity.id" + only: + - ory_kratos_session + oauth2_introspection: + enabled: true + config: + introspection_url: https://whatever/the/wso2/url/is/oauth2/introspect + introspection_request_headers: + authorization: "Basic SOME WORKING AUTH HERE" + cache: + enabled: false + ttl: "60s" + authorizers: + remote_json: + enabled: true + config: + remote: http://internal-keto-url-here/check + mutators: + id_token: + enabled: true + config: + issuer_url: http://whatever-oathkeeper-internal-is-api:4456/ + errors: + fallback: + - json + handlers: + json: + enabled: true + config: + verbose: true + redirect: + enabled: true + config: + to: https://whatever-external-main-url-is/ + when: + error: + - unauthorized + - forbidden + request: + header: + accept: + - text/html +secret: + manage: false + name: oathkeeper-jwks +deployment: + extraEnv: + - name: MUTATORS_ID_TOKEN_CONFIG_JWKS_URL + value: file:///etc/secrets/mutator.id_token.jwks.json +``` + +### Règles + +Des ressources Rule devront être créées dans Kubernetes pour chaque correspondance backend (expression régulière d'URL plus méthode(s) HTTP) protégée par une permission. L'exemple ci-dessous fournit des indications. + +À mesure que la flexibilité pour définir des services tiers et des contextes bornés augmente, ceux-ci peuvent définir leurs propres règles (peut-être derrière un indicateur de valeurs Helm), qui expriment quelles permissions devraient être requises pour quelles URL. + +Le plus gros problème potentiel ici est que chaque correspondance DOIT être unique. Si une requête correspond à plusieurs, Ory Oathkeeper se plaindra. Une fois qu'un modèle général est choisi qui produit des regex uniques, cela n'arrivera pas sauf en cas d'erreur utilisateur. + +```yaml +apiVersion: oathkeeper.ory.sh/v1alpha1 +kind: Rule +metadata: + name: nom-unique +spec: + version: v0.36.0-beta.4 + upstream: + # définissez l'URL vers laquelle cette requête doit être transférée + url: http://url-interne-backend/ + match: + # cela pourrait devoir être http même si l'externe est https, cela dépend de la façon dont l'ingress gère les choses + # ma recommandation est d'avoir un préfixe donné, puis le matcher « tout le reste dans le nom de domaine » + # pour qu'il n'ait pas besoin d'être changé quand la configuration est déplacée entre différents domaines principaux + # puis ce qui est nécessaire pour le chemin spécifique (cela est défini pour correspondre à tous les sous-chemins) + # les regex vont entre des chevrons + url: https://example.<[^/]*>/<.*> + methods: + # quelle(s) que soit/ent la/les méthode(s) auxquelles cette règle s'applique + - GET + authenticators: + - handler: oauth2_introspection + # commentez ce deuxième handler pour ne pas permettre l'accès par cookie navigateur + - handler: cookie_session + authorizer: + handler: remote_json + config: + # celles-ci seront généralement identiques pour toutes les règles, + # sauf que « object » sera changé en l'ID de permission pertinent pour cette URL + payload: | + { + "namespace": "permission", + "object": "IDENTIFIANT_PERMISSION_ICI", + "relation": "granted", + "subject_id": "{{ print .Subject }}" + } + mutators: + # changez cela en un tableau vide si le id_token n'est pas nécessaire, si vous le souhaitez + - handler: id_token +``` + +### Oathkeeper avec Kratos comme authentificateur cookie +(voir doc Ory [ici](https://www.ory.sh/oathkeeper/docs/next/pipeline/authn)) +```yaml +authenticators: + cookie_session: + enabled: true + config: + check_session_url: http://kratos-public/sessions/whoami + preserve_path: true + extra_from: "@this" + subject_from: "identity.id" + only: + - ory_kratos_session +``` + +### Oathkeeper avec WSO2 ISKM pour introspection token +(voir doc Ory [ici](https://www.ory.sh/oathkeeper/docs/next/pipeline/authn)) +```yaml +oauth2_introspection: + enabled: true + config: + introspection_url: https://whatever/the/wso2/url/is/oauth2/introspect + introspection_request_headers: + authorization: "Basic SOME WORKING AUTH HERE" + cache: + enabled: false + ttl: "60s" +``` + +### Oathkeeper avec Keto comme authorizer +(voir doc Ory [ici](https://www.ory.sh/oathkeeper/docs/next/pipeline/authz)) +```yaml +authorizers: + remote_json: + enabled: true + config: + remote: http://internal-keto-url-here/check +``` + +## Ory Kratos – détail d'implémentation + +Ory Kratos est la partie de la suite Ory qui gère tous les flux d'authentification. +Il est hautement configurable et peut se connecter à une variété et à de multiples systèmes et flux d'authentification. La [documentation Kratos](https://www.ory.sh/kratos/docs/next/) explique bien l'étendue de la configuration. C'est-à-dire qu'il est probable qu'elle réponde à vos besoins. +Dans ce projet de flux de travail, seuls les flux de connexion et de déconnexion utilisateur sont requis et mis en œuvre. +Il est utile de savoir que Kratos peut aussi fournir des flux pour : +- **Connexion et inscription en libre-service** : permettre aux utilisateurs finaux de créer et de se connecter à des comptes (que nous appelons des identités) en utilisant des combinaisons nom d'utilisateur/e-mail et mot de passe, une connexion sociale (« Se connecter avec Google, GitHub »), des flux sans mot de passe, et d'autres. +- **Authentification multifacteur (MFA/2FA)** : prend en charge des protocoles tels que TOTP (RFC 6238 et IETF RFC 4226 — mieux connu sous le nom de Google Authenticator) +- **Vérification de compte** : vérifier qu'une adresse e-mail, un numéro de téléphone ou une adresse physique appartiennent bien à cette identité. +- **Récupération de compte** : récupérer l'accès en utilisant des flux « Mot de passe oublié », des codes de sécurité (en cas de perte de dispositif MFA), etc. +- **Gestion du profil et du compte** : mettre à jour les mots de passe, les détails personnels, les adresses e-mail, les profils sociaux liés en utilisant des flux sécurisés. +- **APIs d'administration** : importer, mettre à jour, supprimer des identités. +… ce qui peut devenir important dans les futures versions des conceptions de déploiement IaC. + +### Détails du déploiement +Le chart Helm Kratos est décrit sur [ORY Kratos Helm Chart | k8s](https://k8s.ory.sh/helm/kratos.html) et défini sur [k8s/helm/charts/kratos](https://github.com/ory/k8s/tree/master/helm/charts/kratos). Contrairement à Ory Oathkeeper, il n'a pas de Maester associé gérant un CRD. Il nécessite toutefois une base de données (MySQL, PostgreSQL, CockroachDB, ou quelques autres). Le dépôt Helm est le même que pour Ory Oathkeeper, et documenté sur [ORY Helm Charts | k8s](https://k8s.ory.sh/helm/). Une référence de configuration est disponible sur [Configuration | Ory Kratos](https://www.ory.sh/kratos/docs/reference/configuration), mais notez que le chart Helm fonctionne légèrement différemment. + +En plus d'une base de données, l'autre différence majeure pour Kratos est qu'il nécessite une interface utilisateur, sous la forme d'une petite application web qui gère le rendu de l'étape actuelle de ce qui se passe avec Kratos dans le navigateur et effectue également la communication backend nécessaire pour que cela se produise en toute sécurité. Dans notre cas, l'interface utilisateur que nous utiliserons est très simple et n'est jamais réellement visible — tout ce qu'elle fera est de rediriger immédiatement vers le seul fournisseur d'identité OIDC (IdP) que nous aurons configuré et de recevoir le callback associé. Cette application d'interface utilisateur a déjà été créée et open-sourcée dans le dépôt modusbox, et publie des images docker publiques dans le registre docker GitHub. L'interface utilisateur peut être trouvée sur [GitHub - modusbox/kratos-ui-oidcer : une interface utilisateur Kratos pour rediriger immédiatement vers un seul fournisseur OIDC configuré](https://github.com/modusbox/kratos-ui-oidcer), et est une application Rust très minimale avec une excellente couverture de tests et une image docker minuscule (environ 5 mégaoctets, [https://github.com/modusbox/kratos-ui-oidcer/pkgs/container/oidcer](https://github.com/modusbox/kratos-ui-oidcer/pkgs/container/oidcer)). Elle est désignée comme « Shim » dans la documentation de conception ci-dessus. + +Pour faciliter l'hébergement, Kratos et l'interface utilisateur doivent être montés sur des chemins séparés sur le même domaine que l'interface utilisateur principale. Alternativement, il est possible de les configurer sur un domaine différent et de configurer Kratos pour utiliser des cookies inter-domaines. Ce document est rédigé sous l'hypothèse que la stratégie de même domaine est choisie. + +### Connexion à l'UI principale +Un client doit être créé dans l'IdP qui prend en charge les autorisations de code OIDC. Ce client doit être configuré pour rediriger soit vers n'importe quelle URL sous l'interface utilisateur principale si elle prend en charge les caractères génériques, soit vers l'URL spécifique du chemin `/kratos/self-service/methods/oidc/callback/idp` (notez que le dernier segment, `idp`, est l'ID du fournisseur dans la configuration, les deux doivent donc être modifiés ensemble). Ce client sera utilisé dans la configuration des valeurs du chart Helm. + +Afin de se connecter avec succès à Kratos, l'interface utilisateur principale doit se comporter comme suit : + +1. Effectuer une requête incluant les cookies vers `/kratos/sessions/whoami` (documenté dans la [documentation de l'API HTTP Ory Kratos](https://www.ory.sh/kratos/docs/reference/api/#operation/toSession)), qui retourne un 200 et un objet contenant les métadonnées utilisateur si l'utilisateur est connecté, ou un 401 s'il ne l'est pas. +2. Si l'utilisateur n'est pas connecté, rediriger immédiatement ou fournir un lien vers `/kratos/self-service/registration/browser`. Note : l'inscription dans l'URL n'est pas une faute de frappe. Cela fait référence à l'inscription avec Kratos, ce que les utilisateurs IdP ne seront pas initialement. Si l'utilisateur existe déjà, Kratos suivra automatiquement le flux de connexion à la place. +3. Pour se déconnecter, liez l'utilisateur à `/kratos/self-service/browser/flows/logout`. + +### Valeurs Helm annotées +Cette configuration suppose que le nom du déploiement Helm est `kratos`, que le service Kratos est exposé sous `/kratos/` sur le même domaine que l'interface utilisateur principale, et que l'interface utilisateur Kratos est exposée sous `/auth/` sur le même domaine que l'interface utilisateur principale. + +Le chart Helm prend en charge la création d'ingress, mais cela n'est pas couvert dans la documentation. + +```yaml +deployment: + extraVolumes: + - name: extra-config + configMap: + name: kratos-extra-config + extraVolumeMounts: + - name: extra-config + mountPath: /etc/config2 + readOnly: true +kratos: + identitySchemas: + "identity.schema.json": | + { + "$id": "http://A_REMPLACER_PAR_UN_DOMAINE_SIGNIFICATIF/schema/user", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Un utilisateur", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "email": { + "title": "E-Mail", + "type": "string", + "format": "email" + }, + "subject": { + "title": "Subject", + "type": "string" + }, + "name": { + "title": "Nom", + "type": "string" + } + } + } + } + } + config: + identity: + default_schema_url: file:///etc/config/identity.schema.json + courier: + smtp: + connection_uri: smtp://unused/ + dsn: LA_CONNEXION_BASE_DE_DONNEES_ICI + hashers: + argon2: + parallelism: 1 + iterations: 3 + memory: 17000 + salt_length: 16 + key_length: 32 + log: + level: trace + selfservice: + flows: + registration: + ui_url: /auth/ + after: + oidc: + hooks: + - hook: session + logout: + after: + default_browser_return_url: https://idp.logout.url.here/logout/path?redirect_uri=https%3A%2F%2Fsomewhere.example.com%2F + methods: + oidc: + enabled: true + config: + providers: + - id: idp + provider: generic + client_id: A_DEFINIR + client_secret: A_DEFINIR + mapper_url: file:///etc/config2/oidc.jsonnet + issuer_url: https://url.idp.oidc/ + scope: + - openid + password: + enabled: false + default_browser_return_url: "https://somewhere.example.com/" + serve: + public: + base_url: "https://somewhere.example.com/kratos" + autoMigrate: true +``` + +### ConfigMap JSonnet +Dans les valeurs Helm de Kratos, cela fait référence à une ConfigMap `kratos-extra-config` qui contient du JSonnet (un langage de configuration) expliquant comment transformer les revendications de l'IdP en ce que Kratos stocke sur la personne. Elle doit contenir le fichier JSonnet suivant : + +```javascript +local claims = std.extVar('claims'); + +{ + identity: { + traits: { + email: claims.email, + name: claims.name, + subject: claims.sub + }, + }, +} +``` + +Les revendications d'e-mail et de sujet n'auront probablement jamais besoin de changer, mais avec certains IdP, le nom pourrait être fourni différemment, auquel cas cette partie du JSonnet devra être mise à jour. Les clés à l'intérieur de `traits` sont fondamentalement arbitraires (bien que `subject` ait certaines dépendances ailleurs qui devraient être mises à jour), tant qu'elles sont également mises à jour dans le schéma dans la configuration, mais les valeurs sont limitées à la liste des revendications probables à l'intérieur d'un jeton d'identification OIDC, et sont décrites dans la documentation de Kratos. Cela ne se présentera probablement pas. + +### Déploiement & Service de l'UI + +Le service devra également être exposé à un chemin approprié, la configuration suppose `/auth/`, sur le même domaine que l'interface utilisateur principale : + + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: kratos-ui + labels: + app: kratos-ui +spec: + ports: + - name: http + port: 80 + targetPort: http + selector: + app: kratos-ui + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kratos-ui + labels: + app: kratos-ui +spec: + replicas: 1 + selector: + matchLabels: + app: kratos-ui + template: + metadata: + labels: + app: kratos-ui + spec: + containers: + - name: kratos-ui + image: ghcr.io/modusbox/oidcer:latest + env: + - name: ROCKET_PORT + value: "80" + - name: ROCKET_REGISTRATION_ENDPOINT + value: http://kratos-public/self-service/registration/flows + ports: + - name: http + containerPort: 80 + readinessProbe: + httpGet: + path: /healthz + port: 80 +``` + +### Liens de référence Ory +- **Sessions de connexion** : [docs ici](https://www.ory.sh/kratos/docs/guides/login-session) +- **Cookies de session** : [docs ici](https://www.ory.sh/kratos/docs/guides/configuring-cookies) +- **CORS avec Kratos** : [docs ici](https://www.ory.sh/kratos/docs/guides/setting-up-cors) +- **Intégration Kratos - Oathkeeper (OIDC)** : [docs ici](https://www.ory.sh/kratos/docs/guides/zero-trust-iap-proxy-identity-access-proxy) +- **Intégration Kratos - WSO2 OIDC** : [docs ici](https://www.ory.sh/kratos/docs/guides/sign-in-with-github-google-facebook-linkedin) + diff --git a/docs/fr/technical/business-operations-framework/SettlementBC.md b/docs/fr/technical/business-operations-framework/SettlementBC.md new file mode 100644 index 000000000..f1241d517 --- /dev/null +++ b/docs/fr/technical/business-operations-framework/SettlementBC.md @@ -0,0 +1,197 @@ +# Mise en œuvre opérationnelle du règlement + +## Introduction + +L'objectif de cette conception est de fournir une solution reliant les fonctions des processus métier aux opérations essentielles de règlement sur le switch. + +Cette conception est un exemple d’implémentation d’un règlement Mojaloop pour un cas d’utilisation spécifique et n’est pas destinée à être exhaustive ni à couvrir tous les scénarios. Ce guide présente la conception à haut niveau et explique la logique adoptée pour un cas d’utilisation choisi. +Bien qu’une version de cette conception soit construite et opérationnelle, tout ce qui est décrit dans ce document n’a pas forcément été réalisé. +Il s’agit d’un exemple de conception d’implémentation du règlement. L’intérêt de cette conception et de ce document est donc : +- d'être utilisé comme démonstration ; +- de servir de version initiale pour aider à ‘démarrer rapidement’ ; +- d’être une base à améliorer avant adoption ; +- de servir de point de départ pour approfondir des concepts abordés ici qui pourraient être traités dans un autre design. + +## Opérations principales de règlement + +Il s’agit des fonctionnalités de règlement actuellement fournies par le composant central de Mojaloop, [Central-Settlement](https://github.com/mojaloop/central-settlement). Des informations détaillées sont disponibles dans la [Documentation technique Mojaloop](https://github.com/mojaloop/documentation/tree/master/legacy/mojaloop-technical-overview/central-settlements). + +Les opérations de règlement de base offrent les capacités suivantes : + +- Créer un rapport de matrice de règlement à partir d’une liste de fenêtres de règlement (Settlement-Windows) +- Traiter les accusés de réception de règlement pour un rapport de matrice de règlement existant +- Gérer les fenêtres de règlement (création, fermeture, etc) +- Interroger les rapports de matrice de règlement, les fenêtres de règlement, etc. + +La définition OpenAPI est disponible dans le [dépôt Mojaloop-Specification](https://github.com/mojaloop/mojaloop-specification/tree/master/settlement-api). + +## Architecture de haut niveau + +![Architecture de haut niveau du règlement](../../../.vuepress/public/BizOps-Framework-Settlements.png) + +### Couche d’expérience (Experience layer) + +La couche d'expérience du règlement est une API sans état qui expose les données à consommer par le public concerné. Sa fonction principale actuelle est d'ajouter les informations utilisateurs récupérées dans l’API, informations injectées dans les en-têtes de requête par le proxy ORY Oathkeeper. Cette fonction devrait s’élargir au fil du développement du produit. + +### Couche de processus (Process layer) + +Les API de processus permettent de combiner des données et d’orchestrer plusieurs APIs système pour un objectif métier donné. L’API central-settlement et central-ledger du Mojaloop sont consommées par cette API de processus. + +L’API “Settlement Process” doit respecter les [standards de nommage Mojaloop](https://docs.google.com/document/d/1AZbX0UjraytFty0IWOHpyR6z35bh0-MCFG1vGKId_5M/edit?usp=sharing), et donc porter le nom suivant : `settlement-process-svc`. + +## Processus métier de règlement à haut niveau + +C’est un processus qui s’appuie sur les opérations de règlement de base pour orchestrer les capacités suivantes : + +1. **Clôture d’une fenêtre de règlement** +La fenêtre de règlement courante peut être clôturée manuellement du moment où des transferts lui sont associés. L’opérateur du hub sélectionne la fenêtre ouverte et choisit ensuite de la clôturer. +1. **Initiation du règlement** +L’initiation du règlement sert à l’opérateur du hub pour créer un lot de règlement qui pilote le processus de règlement. +Pour initier le processus, l’opérateur choisit : + - un ensemble de fenêtres de règlement ; + - et éventuellement une devise de règlement ou un modèle de règlement (si une devise est sélectionnée, elle définit le modèle applicable). +Les grands livres de position des participants en crédit net sont ajustés lors de l’initiation. +**Note :** Il est important de créer l’objet de lot de règlement selon la manière dont le règlement doit être finalisé. +1. Un **rapport d’initiation de règlement** est généré, servant à communiquer à la banque de règlement les besoins du règlement. +1. **Finalisation du règlement et rééquilibrage du compte de règlement** +Ce processus intervient après l’exécution des changements de règlement par la banque. À cette étape : + - le processus est terminé et un rapport de finalisation a été reçu de la banque ; + - les grands livres de position des participants débiteurs nets sont ajustés ; + - les grands livres de règlement sont ajustés pour tous les participants afin de correspondre au montant transféré ; + - les grands livres de règlement sont comparés aux soldes réels des comptes et ajustés pour s’aligner. + +### Fonction de rééquilibrage — non optimale +Il est à noter que la fonction de rééquilibrage définie ci-dessus n’est pas l’approche recommandée ou optimale. +Elle a été choisie pour répondre à des exigences réglementaires et aux limites des mécanismes disponibles pour réaliser le règlement entre participants, c’est-à-dire conçue pour fonctionner avec les solutions financières existantes. Le rééquilibrage présente plusieurs inconvénients et devrait être évité si possible. +Ces inconvénients sont : +1. Un rééquilibrage hors séquence donne des résultats incorrects, ce qui nécessite un processus métier et une gestion dédiée. +1. La réconciliation du compte Mojaloop Settlement et de celui à la banque est difficile et complexe, car le rééquilibrage ne reflète pas directement l’activité du compte en banque : les montants des transferts dépendent du moment où le rééquilibrage est effectué et de la génération des rapports et relevés. + +**Solutions recommandées** +Il existe de nombreuses autres approches suivant les meilleures pratiques. Merci de consulter un expert de la communauté Mojaloop pour les explorer. Si vos contraintes sont similaires et qu’il est impossible de créer un nouveau mécanisme, un ajustement mineur peut améliorer cette solution. +Remplacer le rééquilibrage par l’import d’un extrait de compte bancaire d’opérations supprimerait les problèmes de timing et de rapprochement mentionnés plus haut. + +## Schéma de séquence détaillé +![Processus de règlement détaillé](../../../.vuepress/public/settlementProcessAPI.svg) + +Certains processus du schéma méritent d’être détaillés. + +### Détermination du modèle de règlement + +Il faut d’abord déterminer les devises impliquées puis la liste appropriée de modèles de règlement. Un règlement est créé pour chaque modèle retenu. + +### Validation des données de finalisation du règlement + +Les données présentées au cours de la finalisation du règlement exigent de nombreuses validations. +Certaines contrôlent l’intégrité des données : un échec stoppe le processus. D’autres, non bloquantes, génèrent des avertissements pour l’opérateur. +La poursuite du processus n’est possible que lorsque l’opérateur a accepté les avertissements, leurs effets et a choisi les options d’application du processus. +C’est pourquoi la validation des données est une étape nécessaire, à consulter lors de toute acceptation ou poursuite du processus. + +### Cas d’utilisation pour la finalisation du règlement +**Scénarios de validation** + +| Description de la validation | Comportement attendu | +|------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| +| L’ID de règlement sélectionné ne correspond pas à celui du rapport | Finalisation annulée avec erreur | +| La somme des transferts dans le rapport est non nulle | Finalisation annulée avec erreur | +| Le montant du transfert ne correspond pas au montant net de règlement | Finalisation annulée avec erreur | +| Solde non modifié à hauteur du montant du transfert | Continuer --> Ajuster le solde du compte de règlement | +| Le solde fourni dans le rapport n’est pas positif | Continuer --> Solde de règlement à zéro ; NCD=0 ; désactivation du compte POSITION participant | +| Comptes du règlement absents du rapport | Finalisation annulée avec erreur | +| Comptes du rapport absents du règlement | Finalisation annulée avec erreur | +| Les identifiants participant ne correspondent pas (ID, nom, compte) | Finalisation annulée avec erreur | +| Le type de compte doit être POSITION | Finalisation annulée avec erreur | +| Nouveau solde invalide pour la devise | Finalisation annulée avec erreur | +| Montant du transfert invalide pour la devise | Finalisation annulée avec erreur | +| L’ID du compte n’existe pas dans le switch | Finalisation annulée avec erreur | +| Tentative de finaliser un règlement annulé | Finalisation annulée avec erreur | +| Erreur lors de l’ajustement d’un participant | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreur lors du passage à l’état PS_TRANSFERS_RECORDED | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreur lors du passage à l’état PS_TRANSFERS_RESERVED | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreur lors du passage à l’état PS_TRANSFERS_COMMITTED | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreurs lors du règlement des comptes | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreur lors de la mise à jour du NDC | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Erreur lors du traitement des fonds entrants/sortants | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Solde inchangé après traitement des fonds entrants/sortants | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Solde final incorrect après traitement des fonds entrants/sortants | Continuer avec les autres ; notifier l’utilisateur de l’erreur | +| Échec de l’enregistrement de l’état du compte participant au règlement | Continuer avec les autres ; notifier l’utilisateur de l’erreur | + +### Informations d’audit dans la version Mojaloop actuelle + +L’opération réalisée est enregistrée dans le champ “settlement reason”, donc consultable dans les rapports d’audit. +De plus, l’utilisateur et les références sont capturés dans les listes d’extension — consultables elles aussi dans les rapports d’audit. + +### RBAC + +Pour exploiter au mieux le contrôle RBAC, les quatre processus ci-dessus seront implémentés comme combinaisons distinctes d'endpoint API et méthode HTTP. Cela autorise des permissions dédiées à chaque processus. + +## Prise en charge du multi-devises + +L’exécution des règlements multi-devises dépend de deux facteurs : +1. Comment les modèles de règlement sont conçus ? + Les modèles peuvent être liés à une devise ou non, et s’appliquer à toutes les devises. +1. Comment les règlements sont initiés ? + L’initiation du règlement peut se faire avec ou sans devise ou modèle spécifié. + +Comme il est difficile de séparer un règlement une fois initié, il est préférable de décider à l’avance du mode d’application du règlement et de concevoir le système en conséquence. + +--- +**REMARQUE** +Si vous exécutez un modèle net différé multilatéral à devise unique et utilisez des devises test pour vos tests réguliers, il est préférable de créer les règlements des devises de test séparément du devise réelle. Idéalement, il ne faut pas avoir à sélectionner la devise ou un modèle lors de l’initiation du règlement. +Cela s’obtient en créant des modèles séparés : un pour chaque monnaie test, un pour la monnaie réelle. +Par défaut, l’initiation sur transactions multi-devises génère des règlements séparés. (La fonction de détermination des modèles les trouvera tous.) +___ + +## Cas d’erreur +### Initiation du règlement + +**Schéma de séquence détaillé de l’initiation** + +![Processus d’initiation du règlement avec erreurs](../../../.vuepress/public/settlementProcessInitiationErrors.svg) + +**Codes d’erreur à l’initiation du règlement** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|-----------------------------------------------------------------------|------------|------------------|---------------------------------------------| +| ID de règlement introuvable | 3100 | 400 | Erreur validation requête | +| Devise non valide | 3100 | 400 | Erreur validation requête | +| Modèle de règlement introuvable | 3100 | 400 | Erreur validation requête | +| Impossible de créer le règlement | 2000 | 500 | Erreur interne serveur | +| Impossible de mettre à jour l’état du règlement | 2000 | 500 | Erreur interne serveur | +| Erreur technique lors des communications avec les services Mojaloop | 1000 | 500 | Erreur technique | + +### Finalisation du règlement + +**Schéma de séquence détaillé de la finalisation** + +![Processus d’initiation du règlement avec erreurs](../../../.vuepress/public/settlementProcessFinaliseErrors.svg) + +**Codes erreurs de validation à la finalisation** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|-----------------------------------------------------------------------|------------|------------------|---------------------------------------------| +| ID de règlement introuvable | 3100 | 400 | Erreur validation requête | +| IDs de participants introuvables | 3000 | 400 | Erreur validation requête | +| IDs de compte participants introuvables | 3000 | 400 | Erreur validation requête | +| Erreur technique lors des communications avec les services Mojaloop | 1000 | 500 | Erreur technique | +| ID de règlement sélectionné ne correspondant pas au rapport | 3100 | 500 | Erreur validation processus | +| IDs participants du rapport ne correspondent pas au règlement | 3000 | 500 | Erreur validation processus | +| Comptes du rapport ne correspondent pas au règlement | 3000 | 500 | Erreur validation processus | +| Somme des transferts non nulle dans le rapport | 3100 | 500 | Erreur validation processus | +| Montant transfert ≠ montant net de règlement | 3100 | 500 | Erreur validation processus | +| Nouveau solde non valide pour la devise | 3100 | 500 | Erreur validation processus | +| Montant de transfert non valide pour la devise | 3100 | 500 | Erreur validation processus | +| Règlement à l’état ABORTED ou invalide | 3100 | 500 | Erreur validation processus | +| Montant de transfert non valide pour la devise | 3100 | 500 | Erreur validation processus | + +**Codes d’erreur de confirmation à la finalisation** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|-----------------------------------------------------------------------|------------|------------------|---------------------------------------------| +| ID de finalisation introuvable | 3100 | 400 | Erreur validation requête | +| ID de règlement introuvable | 3100 | 400 | Erreur validation requête | +| Erreur technique lors des communications avec les services Mojaloop | 1000 | 500 | Erreur technique | +| Erreur traitement des fonds entrants/sortants | 2001 | 500 | Erreur interne serveur | +| Impossible de mettre à jour l’état du règlement | 2001 | 500 | Erreur interne serveur | +| Soldes non concordants après règlement | 2001 | 500 | Erreur interne serveur | +| Soldes non concordants après rééquilibrage | 2001 | 500 | Erreur interne serveur | diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml new file mode 100644 index 000000000..7131dc2e4 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml @@ -0,0 +1,171 @@ +/' + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + '/ + + +@startuml fx-fulfil-request +title 2.1.0. Le FXP envoie une demande d’exécution réussie (fulfil success) de conversion FX + +autonumber + +actor "DFSP1\nPayeur" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d’événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "topic-transfer-fulfil" as TOPIC_FULFIL +control "Gestionnaire d’événements Fulfil" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Gestionnaire du modèle\nde règlement" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire Position" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group FXP1 envoie une demande d’exécution réussie de conversion FX + FXP1 <-> FXP1: Récupérer la chaîne d’exécution (fulfilment) générée lors du\nprocessus de devis FX ou la régénérer à partir du\n**secret local** et du **paquet ILP** + note right of FXP1 #yellow + En-têtes - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Charge utile - transferMessage: + { + "conversionState": "" + "fulfilment": , + "completedTimestamp": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + FXP1 ->> MLAPI: PUT - /fxTransfers/ + activate MLAPI + MLAPI -> MLAPI: Validation de schéma\n + break Échec de la validation de schéma + MLAPI -->> FXP1: Réponse HTTP - 400 (Bad Request) + end + MLAPI -> MLAPI: Valider la requête entrante \n(p. ex. le transfert n’a pas expiré, completedTimestamp n’est pas dans le futur)\nCodes d’erreur : 2001, 3100 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: fx_commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Router et publier l’événement Fulfil pour le bénéficiaire\nCode d’erreur : 2001 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Vérifier que l’événement est répliqué selon la configuration (ACKS=all)\nCode d’erreur : 2001 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> FXP1: Réponse HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation du gestionnaire Fulfil (succès) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg 2.1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produire un message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire un message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consommer le message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Consommation du gestionnaire de modèle de règlement (succès)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation du gestionnaire Position (succès)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire un message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'fx_commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoi de notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'fx_commit' + ||| + ref over FXP1, TOPIC_NOTIFICATIONS: Envoi de notification au participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg new file mode 100644 index 000000000..52607783b --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg @@ -0,0 +1,322 @@ + + 2.1.0. Le FXP envoie une demande d’exécution réussie (fulfil success) de conversion FX + + + 2.1.0. Le FXP envoie une demande d’exécution réussie (fulfil success) de conversion FX + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + FXP1 + FXP + + + FXP1 + FXP + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d’événements de notification ML API + + + Gestionnaire d’événements de notification ML API + + + API du service central + + + API du service central + + + + + topic-transfer-fulfil + + + topic-transfer-fulfil + Gestionnaire d’événements Fulfil + + + Gestionnaire d’événements Fulfil + + + + + topic- + settlement-model + + + topic- + settlement-model + Gestionnaire du modèle + de règlement + + + Gestionnaire du modèle + de règlement + + + + + topic- + transfer-position + + + topic- + transfer-position + Gestionnaire Position + + + Gestionnaire Position + + + + + topic- + notification + + + topic- + notification + + + + + + + + + FXP1 envoie une demande d’exécution réussie de conversion FX + + + + + + 1 + Récupérer la chaîne d’exécution (fulfilment) générée lors du + processus de devis FX ou la régénérer à partir du + secret local + et du + paquet ILP + + + En-têtes - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Charge utile - transferMessage: + { + "conversionState": "<transferState>" + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /fxTransfers/<ID> + + + + + 3 + Validation de schéma +   + + + break + [Échec de la validation de schéma] + + + + 4 + Réponse HTTP - 400 (Bad Request) + + + + + 5 + Valider la requête entrante + (p. ex. le transfert n’a pas expiré, completedTimestamp n’est pas dans le futur) + Codes d’erreur : + 2001, 3100 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: fx_commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 6 + Router et publier l’événement Fulfil pour le bénéficiaire + Code d’erreur : + 2001 + + + + + + 7 + Vérifier que l’événement est répliqué selon la configuration (ACKS=all) + Code d’erreur : + 2001 + + + 8 + Répondre que les accusés de réplication ont été reçus + + + + 9 + Réponse HTTP - 200 (OK) + + + 10 + Consommer le message + + + ref + Consommation du gestionnaire Fulfil (succès) { + 2.1.1 + } +   + + + 11 + Produire un message + + + 12 + Produire un message + + + 13 + Consommer le message + + + ref + Consommation du gestionnaire de modèle de règlement (succès) +   + + + 14 + Consommer le message + + + ref + Consommation du gestionnaire Position (succès) +   + + + 15 + Produire un message + + + 16 + Consommer le message + + + opt + [action == 'fx_commit'] + + + ref + Envoi de notification au participant (payeur) +   + + + 17 + Envoyer la notification de rappel (callback) + + + 18 + Consommer le message + + + opt + [action == 'fx_commit'] + + + ref + Envoi de notification au participant (FXP) +   + + + 19 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml new file mode 100644 index 000000000..69836a480 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml @@ -0,0 +1,183 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml PayerFSP-fx-conversion-prepare-request + +!$payerCurrency = "" +!$payeeCurrency = "" +!$dfsp1Id = "" +!$fxpID = "" +!$payerMSISDN = "" +!$payeeMSISDN = "" +!$payeeReceiveAmount = "" +!$payerSendAmount = "" +!$payeeFee = "" +!$targetAmount = "" +!$fxpChargesSource = "" +!$fxpChargesTarget = "" +!$fxpSourceAmount = "" +!$fxpTargetAmount = "" +!$conversionRequestId = "" +!$conversionId = "" +!$homeTransactionId = "" +!$quoteId = "" +!$transactionId = "" +!$quotePayerExpiration = "" +!$quotePayeeExpiration = "" +!$commitRequestId = "" +!$determiningTransferId = "" +!$transferId = "" +!$fxCondition = "" +!$condition = "" + +title 1.1.0. DFSP1 envoie une demande de préparation de conversion FX à FXP1 + +autonumber + +actor "DFSP1\nPayeur" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d’événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Gestionnaire d’événements Prepare" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d’événements Position" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +activate NOTIFY_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +group DFSP1 envoie une demande de conversion FX à FXP1 + note right of DFSP1 #yellow + En-têtes - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Charge utile : + { + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$dfsp1Id", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "condition": "$fxCondition" + } + end note + DFSP1 ->> MLAPI: POST - /fxTransfers + activate MLAPI + MLAPI -->> DFSP1: Réponse HTTP - 202 (Accepted) + alt Erreur de validation du schéma + MLAPI-->>DFSP1: Réponse HTTP - 400 (Bad Request) + end + note right of MLAPI #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: prepare, + action: fx_prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_TRANSFER_PREPARE: Router et publier l’événement FX Prepare pour le payeur + activate TOPIC_TRANSFER_PREPARE + TOPIC_TRANSFER_PREPARE <-> TOPIC_TRANSFER_PREPARE: Vérifier que l’événement est répliqué selon la configuration (ACKS=all)\nCode d’erreur : 2003 + TOPIC_TRANSFER_PREPARE --> MLAPI: Les accusés de réplication ont été reçus + deactivate TOPIC_TRANSFER_PREPARE + alt Erreur lors de la publication de l’événement + MLAPI-->>DFSP1: Réponse HTTP - 500 (Internal Server Error)\n**Code d’erreur :** 2003 + end + deactivate MLAPI + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION : Consommation du gestionnaire Prepare\n + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produire un message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER : Consommation du gestionnaire Position\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire un message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + ref over FXP1, TOPIC_NOTIFICATIONS : Envoi de notification au participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Envoyer la notification de rappel (callback) + ||| +end +deactivate POS_HANDLER +deactivate PREP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg new file mode 100644 index 000000000..38d3e04ea --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg @@ -0,0 +1,246 @@ + + 1.1.0. DFSP1 envoie une demande de préparation de conversion FX à FXP1 + + + 1.1.0. DFSP1 envoie une demande de préparation de conversion FX à FXP1 + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + FXP1 + FXP + + + FXP1 + FXP + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d’événements de notification ML API + + + Gestionnaire d’événements de notification ML API + + + API du service central + + + API du service central + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Gestionnaire d’événements Prepare + + + Gestionnaire d’événements Prepare + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d’événements Position + + + Gestionnaire d’événements Position + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP1 envoie une demande de conversion FX à FXP1 + + + En-têtes - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Charge utile : + { + "commitRequestId": "<UUID>", + "determiningTransferId": "<UUID>", + "initiatingFsp": "<DFSP1>", + "counterPartyFsp": "<fxpId>", + "amountType": "SEND", + "sourceAmount": { + "currency": "<ISO currency code>", + "amount": "<number>" + }, + "targetAmount": { + "currency": "<ISO currency code>", + "amount": "<number>" + }, + "condition": "<ILP condition>" + } + + + + 1 + POST - /fxTransfers + + + + 2 + Réponse HTTP - 202 (Accepted) + + + alt + [Erreur de validation du schéma] + + + + 3 + Réponse HTTP - 400 (Bad Request) + + + Message : + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <UUID>, + type: prepare, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Router et publier l’événement FX Prepare pour le payeur + + + + + + 5 + Vérifier que l’événement est répliqué selon la configuration (ACKS=all) + Code d’erreur : + 2003 + + + 6 + Les accusés de réplication ont été reçus + + + alt + [Erreur lors de la publication de l’événement] + + + + 7 + Réponse HTTP - 500 (Internal Server Error) + Code d’erreur : + 2003 + + + 8 + Consommer le message + + + ref + Consommation du gestionnaire Prepare +   + + + 9 + Produire un message + + + 10 + Consommer le message + + + ref + Consommation du gestionnaire Position +   + + + 11 + Produire un message + + + 12 + Consommer le message + + + ref + Envoi de notification au participant (FXP) +   + + + 13 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml new file mode 100644 index 000000000..67f65c239 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml @@ -0,0 +1,269 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml prepare-handler-consume +title 1.1.1.a. Consommation du gestionnaire Prepare FX (message unique) + +autonumber + +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Gestionnaire d’événements Prepare" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "DAO Position" as POS_DAO +entity "DAO Participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +activate PREP_HANDLER +group Consommation du gestionnaire Prepare + note left of PREP_HANDLER #lightgrey + L’événement est automatiquement répliqué + vers le topic des événements (topic-events) + end note + + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consommer le message d’événement Prepare + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Filtrer l’événement + PREP_HANDLER <-> PREP_HANDLER: Filtrer l’événement - Règles : type == 'prepare' && action == 'fx_prepare'\nCodes d’erreur : 2001 + end + end + + group Valider le transfert Prepare + PREP_HANDLER <-> PREP_HANDLER: Validation de schéma du message entrant + PREP_HANDLER <-> PREP_HANDLER: Vérifier la signature du message (à confirmer dans une exigence ultérieure) + note right of PREP_HANDLER #lightgrey + Les étapes de validation ci-dessus sont déjà traitées par + le ML-Adapter pour l’implémentation open source. + Elles pourront devoir être ajoutées ultérieurement pour des adaptateurs personnalisés. + end note + + group Contrôle des doublons + ||| + PREP_HANDLER -> DB: Demander le contrôle des doublons + ref over PREP_HANDLER, DB: Demande de contrôle des doublons\n + DB --> PREP_HANDLER: Retour { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE + group Traiter la duplication + alt hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of PREP_HANDLER #lightgrey + Valider le transfert Prepare (échec) - Requête modifiée + end note + else hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + PREP_HANDLER -> DB: stateRecord = await getFxTransferById(commitRequestId) + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + DB --> PREP_HANDLER: Retour stateRecord + deactivate DB + alt [COMMITTED, ABORTED].includes(stateRecord.transferStateEnumeration) + ||| + + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Produire un message [functionality = TRANSFER, action = PREPAPE_DUPLICATE] + else + note right of PREP_HANDLER #lightgrey + Ignorer - renvoi en cours + end note + end + end + end + end + else hasDuplicateId == FALSE + group Valider la requête Prepare + group Valider le payeur + PREP_HANDLER -> PREP_HANDLER: Valider que l’en-tête FSPIOP-Source correspond à initiatingFsp + PREP_HANDLER -> PREP_HANDLER: Valider l’échelle et la précision de payload.sourceAmount et payload.targetAmount + PREP_HANDLER -> PARTICIPANT_DAO: Demander les détails du participant payeur (s’il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Retour des détails du participant s’ils existent + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Retour des détails du participant s’ils existent + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider que le participant payeur est actif + PREP_HANDLER <-> PREP_HANDLER: Valider le compte de position du participant payeur pour la devise source [existe, actif] + end + group Valider le bénéficiaire + PREP_HANDLER -> PARTICIPANT_DAO: Demander les détails du participant bénéficiaire (s’il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Retour des détails du participant s’ils existent + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Retour des détails du participant s’ils existent + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider que le participant bénéficiaire est actif + PREP_HANDLER <-> PREP_HANDLER: Valider le compte de position du participant bénéficiaire pour la devise cible [existe, actif] + end + group Valider la condition et l’expiration + PREP_HANDLER <-> PREP_HANDLER: Valider la condition cryptographique + PREP_HANDLER <-> PREP_HANDLER: Valider l’expiration [payload.expiration est une date ISO valide et non passée] + end + group Valider des FSP distincts (si ENABLE_ON_US_TRANSFER == false) + PREP_HANDLER <-> PREP_HANDLER: Valider que les FSP payeur et bénéficiaire sont différents + end + alt Valider le transfert Prepare (succès) + group Persister l’état du transfert (avec transferState='RECEIVED-PREPARE') + PREP_HANDLER -> DB: Demander la persistance du transfert\nCodes d’erreur : 2003 + activate DB + hnote over DB #lightyellow + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + end note + DB --> PREP_HANDLER: Retour succès + deactivate DB + end + else Valider le transfert Prepare (échec) + group Persister l’état du transfert (avec transferState='INVALID') (introduction d’un nouveau statut INVALID pour marquer ces entrées) + PREP_HANDLER -> DB: Demander la persistance du transfert\n(lorsque la validation payeur/bénéficiaire/condition crypto échoue)\nCodes d’erreur : 2003 + activate DB + hnote over DB #lightyellow + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + fxTransferError + end note + DB --> PREP_HANDLER: Retour succès + deactivate DB + end + end + end + end + end + + alt Valider le transfert Prepare (succès) + group Hydrater le message Prepare du transfert + PREP_HANDLER -> PARTICIPANT_DAO: Obtenir participant et devise pour le transfert FX (avec 'payload.determiningTransferId') + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander participant et devise + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Retour participant et devise + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Retour participant et devise + deactivate PARTICIPANT_DAO + + end + note right of PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: fx_prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Router et publier l’événement Position pour le payeur\nCodes d’erreur : 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Valider le transfert Prepare (échec) + note right of PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: fx_prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publier l’événement de notification (échec) pour le payeur\nCodes d’erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate PREP_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg new file mode 100644 index 000000000..69422eae7 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg @@ -0,0 +1,467 @@ + + 1.1.1.a. Consommation du gestionnaire Prepare FX (message unique) + + + 1.1.1.a. Consommation du gestionnaire Prepare FX (message unique) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Gestionnaire d’événements Prepare + + + Gestionnaire d’événements Prepare + + + + + topic-transfer-position + + + topic-transfer-position + + + Notification-Topic + + + Notification-Topic + DAO Position + + + DAO Position + + + DAO Participant + + + DAO Participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + Consommation du gestionnaire Prepare + + + L’événement est automatiquement répliqué + vers le topic des événements (topic-events) + + + 1 + Consommer le message d’événement Prepare + + + break + + + Filtrer l’événement + + + + + + 2 + Filtrer l’événement - Règles : type == 'prepare' && action == 'fx_prepare' + Codes d’erreur : + 2001 + + + Valider le transfert Prepare + + + + + + 3 + Validation de schéma du message entrant + + + + + + 4 + Vérifier la signature du message (à confirmer dans une exigence ultérieure) + + + Les étapes de validation ci-dessus sont déjà traitées par + le ML-Adapter pour l’implémentation open source. + Elles pourront devoir être ajoutées ultérieurement pour des adaptateurs personnalisés. + + + Contrôle des doublons + + + 5 + Demander le contrôle des doublons + + + ref + Demande de contrôle des doublons +   + + + 6 + Retour { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE] + + + Traiter la duplication + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Valider le transfert Prepare (échec) - Requête modifiée + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + 7 + stateRecord = await getFxTransferById(commitRequestId) + + fxTransferStateChange + + + 8 + Retour stateRecord + + + alt + [[COMMITTED, ABORTED].includes(stateRecord.transferStateEnumeration)] + + + 9 + Produire un message [functionality = TRANSFER, action = PREPAPE_DUPLICATE] + + + + Ignorer - renvoi en cours + + [hasDuplicateId == FALSE] + + + Valider la requête Prepare + + + Valider le payeur + + + + + 10 + Valider que l’en-tête FSPIOP-Source correspond à initiatingFsp + + + + + 11 + Valider l’échelle et la précision de payload.sourceAmount et payload.targetAmount + + + 12 + Demander les détails du participant payeur (s’il existe) + + + 13 + Demander les détails du participant + + participant + participantCurrency + + + 14 + Retour des détails du participant s’ils existent + + + 15 + Retour des détails du participant s’ils existent + + + + + + 16 + Valider que le participant payeur est actif + + + + + + 17 + Valider le compte de position du participant payeur pour la devise source [existe, actif] + + + Valider le bénéficiaire + + + 18 + Demander les détails du participant bénéficiaire (s’il existe) + + + 19 + Demander les détails du participant + + participant + participantCurrency + + + 20 + Retour des détails du participant s’ils existent + + + 21 + Retour des détails du participant s’ils existent + + + + + + 22 + Valider que le participant bénéficiaire est actif + + + + + + 23 + Valider le compte de position du participant bénéficiaire pour la devise cible [existe, actif] + + + Valider la condition et l’expiration + + + + + + 24 + Valider la condition cryptographique + + + + + + 25 + Valider l’expiration [payload.expiration est une date ISO valide et non passée] + + + Valider des FSP distincts (si ENABLE_ON_US_TRANSFER == false) + + + + + + 26 + Valider que les FSP payeur et bénéficiaire sont différents + + + alt + [Valider le transfert Prepare (succès)] + + + Persister l’état du transfert (avec transferState='RECEIVED-PREPARE') + + + 27 + Demander la persistance du transfert + Codes d’erreur : + 2003 + + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + + + 28 + Retour succès + + [Valider le transfert Prepare (échec)] + + + Persister l’état du transfert (avec transferState='INVALID') (introduction d’un nouveau statut INVALID pour marquer ces entrées) + + + 29 + Demander la persistance du transfert + (lorsque la validation payeur/bénéficiaire/condition crypto échoue) + Codes d’erreur : + 2003 + + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + fxTransferError + + + 30 + Retour succès + + + alt + [Valider le transfert Prepare (succès)] + + + Hydrater le message Prepare du transfert + + + 31 + Obtenir participant et devise pour le transfert FX (avec 'payload.determiningTransferId') + + + 32 + Demander participant et devise + + participant + participantCurrency + + + 33 + Retour participant et devise + + + 34 + Retour participant et devise + + + Message : + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <hydratedTransferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 35 + Router et publier l’événement Position pour le payeur + Codes d’erreur : + 2003 + + [Valider le transfert Prepare (échec)] + + + Message : + { + id: <transferMessage.commitRequestId> + from: <ledgerName>, + to: <transferMessage.initiatingFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <codes possibles : [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<voir la section 35.1.3 pour la description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 36 + Publier l’événement de notification (échec) pour le payeur + Codes d’erreur : + 2003 + + diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml new file mode 100644 index 000000000..93905870d --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml @@ -0,0 +1,309 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml position-handler-consume +title 1.1.2.a. Consommation du gestionnaire Position (message unique) + +autonumber + +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d’événements Position" as POS_HANDLER +entity "DAO Position" as POS_DAO +entity "DAO Règlement" as SETTLEMENT_DAO +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "DAO Participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant SETTLEMENT_DAO + participant DB +end box + +activate POS_HANDLER +group Consommation du gestionnaire Position + note left of POS_HANDLER #lightgrey + L’événement est automatiquement répliqué + vers le topic des événements (topic-events) + end note + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d’événement Position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + break + group Valider l’événement + POS_HANDLER <-> POS_HANDLER: Valider l’événement - Règle : type == 'position' && action == 'fx_prepare' + POS_HANDLER -> POS_HANDLER: Valider que 'payload.commitRequestId' ou 'message.value.content.uriParams.id' n’est pas vide\n**Code d’erreur :** 2003 + end + end + + alt Calculer et valider la position la plus récente (succès) + group Calculer la position et persister le changement + POS_HANDLER -> SETTLEMENT_DAO: Demander les modèles de règlement actifs + activate SETTLEMENT_DAO + SETTLEMENT_DAO -> DB: Récupérer les modèles de règlement actifs + activate DB + hnote over DB #lightyellow + settlementModel + end note + DB --> SETTLEMENT_DAO: Retour des modèles de règlement actifs + deactivate DB + SETTLEMENT_DAO --> POS_HANDLER: Retour des modèles de règlement actifs + deactivate SETTLEMENT_DAO + POS_HANDLER -> POS_HANDLER: Sélectionner la devise correspondante ou le modèle de règlement par défaut pour le type de compte grand livre POSITION\n**Code d’erreur :** 6000 + + POS_HANDLER -> PARTICIPANT_DAO: Demander le compte de position du participant payeur par nom et devise + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer le compte de position du participant payeur par nom et devise + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Retour du compte de position du participant payeur par nom et devise + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Retour du compte de position du participant payeur par nom et devise + deactivate PARTICIPANT_DAO + + POS_HANDLER -> DB: Récupérer l’état du transfert en base via 'commitRequestId' + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + DB --> POS_HANDLER: Récupérer l’état du transfert en base + deactivate DB + DB --> POS_HANDLER: Retour de l’état du transfert + + POS_HANDLER -> PARTICIPANT_DAO: Demander les plafonds de position pour le participant payeur + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les plafonds de position pour le participant payeur + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Retour des plafonds de position + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Retour des plafonds de position + deactivate PARTICIPANT_DAO + + alt Valider l’état du transfert (transferState='RECEIVED_PREPARE') + POS_HANDLER <-> POS_HANDLER: Mettre à jour l’état du transfert vers RESERVED + POS_HANDLER <-> POS_HANDLER: Calculer la position la plus récente pour la préparation + POS_HANDLER <-> POS_HANDLER: Valider la position la plus récente calculée (lpos) par rapport au plafond de débit net (netcap) - Règle : lpos < netcap + + POS_HANDLER -> POS_DAO: Demander la position du participant payeur pour la devise du transfert et la devise de règlement + activate POS_DAO + POS_DAO -> DB: Récupérer la position du participant payeur pour la devise du transfert et la devise de règlement + hnote over DB #lightyellow + participantPosiiton + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Retour de la position du participant payeur pour la devise du transfert et la devise de règlement + deactivate POS_DAO + + POS_HANDLER <-> POS_HANDLER: Mettre à jour la position du participant (augmenter la position réservée du montant du transfert) + POS_HANDLER -> DB: Persister la position du participant payeur en base + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB -> POS_HANDLER: Retour succès + deactivate DB + + POS_HANDLER -> PARTICIPANT_DAO: Demander la limite du participant payeur par devise + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer la limite du participant payeur par devise + activate DB + hnote over DB #lightyellow + participant + participantCurrency + participantLimit + end note + DB --> PARTICIPANT_DAO: Retour de la limite du participant payeur par devise + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Retour de la limite du participant payeur par devise + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculer la position disponible la plus récente selon la limite et la couverture de liquidité du payeur + + alt Valider les plafonds de position (succès) + POS_HANDLER <-> POS_HANDLER: Mettre à jour l’état du transfert vers RESERVED + POS_HANDLER -> DB: Mettre à jour la position du participant + activate DB + hnote over DB #lightyellow + participantPosition + end note + deactivate DB + + POS_HANDLER -> DB: Persister le changement d’état du transfert (RESERVED) en base + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + + POS_HANDLER -> DB: Insérer l’enregistrement de changement de position du participant + activate DB + hnote over DB #lightyellow + participantPositionChange + end note + deactivate DB + else Valider les plafonds de position (échec) + POS_HANDLER -> DB: Persister le changement d’état du transfert (ABORTED_REJECTED) en base, **Codes d’erreur :** 4001, 4200 + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + end + else transferState !='RECEIVED_PREPARE' + POS_HANDLER <-> POS_HANDLER: Mettre à jour l’état du transfert vers ABORTED_REJECTED + POS_HANDLER -> DB: Persister l’état de transfert abandonné + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + end + + alt L’état du transfert est RESERVED + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l’événement de notification vers le FXP + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": , + "errorDescription": "", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l’événement de notification (échec) pour le payeur. **Code d’erreur :** 2001 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + + end + else Calculer et valider la position la plus récente (échec) + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": , + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l’événement de notification (échec) pour le payeur **Codes d’erreur :** 4001, 4200 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg new file mode 100644 index 000000000..9ef1053a0 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg @@ -0,0 +1,478 @@ + + 1.1.2.a. Consommation du gestionnaire Position (message unique) + + + 1.1.2.a. Consommation du gestionnaire Position (message unique) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d’événements Position + + + Gestionnaire d’événements Position + + + + + Notification-Topic + + + Notification-Topic + DAO Position + + + DAO Position + + + DAO Participant + + + DAO Participant + + + DAO Règlement + + + DAO Règlement + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + + + + + + + + Consommation du gestionnaire Position + + + L’événement est automatiquement répliqué + vers le topic des événements (topic-events) + + + 1 + Consommer le message d’événement Position pour le payeur + + + break + + + Valider l’événement + + + + + + 2 + Valider l’événement - Règle : type == 'position' && action == 'fx_prepare' + + + + + 3 + Valider que 'payload.commitRequestId' ou 'message.value.content.uriParams.id' n’est pas vide + Code d’erreur : + 2003 + + + alt + [Calculer et valider la position la plus récente (succès)] + + + Calculer la position et persister le changement + + + 4 + Demander les modèles de règlement actifs + + + 5 + Récupérer les modèles de règlement actifs + + settlementModel + + + 6 + Retour des modèles de règlement actifs + + + 7 + Retour des modèles de règlement actifs + + + + + 8 + Sélectionner la devise correspondante ou le modèle de règlement par défaut pour le type de compte grand livre POSITION + Code d’erreur : + 6000 + + + 9 + Demander le compte de position du participant payeur par nom et devise + + + 10 + Récupérer le compte de position du participant payeur par nom et devise + + participant + participantCurrency + + + 11 + Retour du compte de position du participant payeur par nom et devise + + + 12 + Retour du compte de position du participant payeur par nom et devise + + + 13 + Récupérer l’état du transfert en base via 'commitRequestId' + + fxTransferStateChange + + + 14 + Récupérer l’état du transfert en base + + + 15 + Retour de l’état du transfert + + + 16 + Demander les plafonds de position pour le participant payeur + + + 17 + Demander les plafonds de position pour le participant payeur + + participant + participantLimit + + + 18 + Retour des plafonds de position + + + 19 + Retour des plafonds de position + + + alt + [Valider l’état du transfert (transferState='RECEIVED_PREPARE')] + + + + + + 20 + Mettre à jour l’état du transfert vers RESERVED + + + + + + 21 + Calculer la position la plus récente pour la préparation + + + + + + 22 + Valider la position la plus récente calculée (lpos) par rapport au plafond de débit net (netcap) - Règle : lpos < netcap + + + 23 + Demander la position du participant payeur pour la devise du transfert et la devise de règlement + + + 24 + Récupérer la position du participant payeur pour la devise du transfert et la devise de règlement + + participantPosiiton + + + 25 + Retour de la position du participant payeur pour la devise du transfert et la devise de règlement + + + + + + 26 + Mettre à jour la position du participant (augmenter la position réservée du montant du transfert) + + + 27 + Persister la position du participant payeur en base + + participantPosition + + + 28 + Retour succès + + + 29 + Demander la limite du participant payeur par devise + + + 30 + Récupérer la limite du participant payeur par devise + + participant + participantCurrency + participantLimit + + + 31 + Retour de la limite du participant payeur par devise + + + 32 + Retour de la limite du participant payeur par devise + + + + + + 33 + Calculer la position disponible la plus récente selon la limite et la couverture de liquidité du payeur + + + alt + [Valider les plafonds de position (succès)] + + + + + + 34 + Mettre à jour l’état du transfert vers RESERVED + + + 35 + Mettre à jour la position du participant + + participantPosition + + + 36 + Persister le changement d’état du transfert (RESERVED) en base + + fxTransferStateChange + + + 37 + Insérer l’enregistrement de changement de position du participant + + participantPositionChange + + [Valider les plafonds de position (échec)] + + + 38 + Persister le changement d’état du transfert (ABORTED_REJECTED) en base, + Codes d’erreur : + 4001, 4200 + + fxTransferStateChange + + [transferState !='RECEIVED_PREPARE'] + + + + + + 39 + Mettre à jour l’état du transfert vers ABORTED_REJECTED + + + 40 + Persister l’état de transfert abandonné + + fxTransferStateChange + + + alt + [L’état du transfert est RESERVED] + + + Message : + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 41 + Publier l’événement de notification vers le FXP + + + + Message : + { + id: <transferMessage.commitRequestId> + from: <switch>, + to: <transferMessage.initiatingFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <code d’erreur>, + "errorDescription": "<description de l’erreur>", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 42 + Publier l’événement de notification (échec) pour le payeur. + Code d’erreur : + 2001 + + [Calculer et valider la position la plus récente (échec)] + + + Message : + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <code d’erreur>, + "errorDescription": "<description de l’erreur>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 43 + Publier l’événement de notification (échec) pour le payeur + Codes d’erreur : + 4001, 4200 + + diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml new file mode 100644 index 000000000..f27425202 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml @@ -0,0 +1,164 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- +******'/ + +@startuml fx-conversion-abort-request + +title 2.2.0.a. FXP1 envoie un appel PUT sur le l'endpoint /error pour une demande de conversion FX + +autonumber + +actor "DFSP1\nPayeur" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d’événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "transfer-fulfil-topic" as TOPIC_FULFIL +control "Gestionnaire d’événements Fulfil" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d’événements Position" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group FXP1 signale une erreur pour la demande de conversion FX + FXP1 <-> FXP1: Lors du traitement d’une requête entrante\nPOST /fxTransfers, une erreur de\ntraitement s’est produite et un rappel d’erreur (Error callback) est effectué + note right of FXP1 #yellow + En-têtes - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Charge utile - errorMessage: + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + FXP1 ->> MLAPI: PUT - /fxTransfers//error + activate MLAPI + MLAPI -> MLAPI: Validation de schéma + alt Échec de la validation de schéma + MLAPI -> FXP1: Réponse HTTP - 400 (Bad Request) + end + MLAPI -> MLAPI: Valider le message entrant (p. ex. le code d’erreur est valide)\n**Codes d’erreur :** 3100 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: fx_abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Router et publier l’événement Abort/Reject pour le FXP\nCode d’erreur : 2001 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Vérifier que l’événement est répliqué selon la configuration (ACKS=all)\nCode d’erreur : 2001 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> FXP1: Réponse HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation du gestionnaire Fulfil (Reject/Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire un message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation du gestionnaire Position (Abort)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire un message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'fx_abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoi de notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'fx_abort' + ||| + ref over FXP1, TOPIC_NOTIFICATIONS: Envoi de notification au participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg new file mode 100644 index 000000000..3fe170cbb --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg @@ -0,0 +1,280 @@ + + 2.2.0.a. FXP1 envoie un appel PUT sur le l'endpoint /error pour une demande de conversion FX + + + 2.2.0.a. FXP1 envoie un appel PUT sur le l'endpoint /error pour une demande de conversion FX + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + FXP1 + FXP + + + FXP1 + FXP + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d’événements de notification ML API + + + Gestionnaire d’événements de notification ML API + + + API du service central + + + API du service central + + + + + transfer-fulfil-topic + + + transfer-fulfil-topic + Gestionnaire d’événements Fulfil + + + Gestionnaire d’événements Fulfil + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d’événements Position + + + Gestionnaire d’événements Position + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + FXP1 signale une erreur pour la demande de conversion FX + + + + + + 1 + Lors du traitement d’une requête entrante + POST /fxTransfers, une erreur de + traitement s’est produite et un rappel d’erreur (Error callback) est effectué + + + En-têtes - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Charge utile - errorMessage: + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /fxTransfers/<ID>/error + + + + + 3 + Validation de schéma + + + alt + [Échec de la validation de schéma] + + + 4 + Réponse HTTP - 400 (Bad Request) + + + + + 5 + Valider le message entrant (p. ex. le code d’erreur est valide) + Codes d’erreur : + 3100 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: fx_abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 6 + Router et publier l’événement Abort/Reject pour le FXP + Code d’erreur : + 2001 + + + + + + 7 + Vérifier que l’événement est répliqué selon la configuration (ACKS=all) + Code d’erreur : + 2001 + + + 8 + Répondre que les accusés de réplication ont été reçus + + + + 9 + Réponse HTTP - 200 (OK) + + + 10 + Consommer le message + + + ref + Consommation du gestionnaire Fulfil (Reject/Abort) +   + + + 11 + Produire un message + + + 12 + Consommer le message + + + ref + Consommation du gestionnaire Position (Abort) +   + + + 13 + Produire un message + + + 14 + Consommer le message + + + opt + [action == 'fx_abort'] + + + ref + Envoi de notification au participant (payeur) +   + + + 15 + Envoyer la notification de rappel (callback) + + + 16 + Consommer le message + + + opt + [action == 'fx_abort'] + + + ref + Envoi de notification au participant (FXP) +   + + + 17 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml new file mode 100644 index 000000000..4587b3471 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml @@ -0,0 +1,99 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Mojaloop Foundation for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + + * Steven Oderayi + -------------- + ******'/ + +@startuml send-notification-to-participant-single-message-v2_0 +title 1.1.4.a. Envoi de notification au participant (Payeur / Bénéficiaire / FXP) (message unique) v2.0 + +autonumber + +actor "DFSP payeur\nParticipant" as PAYER_DFSP +actor "DFSP bénéficiaire / FXP\nParticipant" as PAYEE_DFSP_OR_FXP +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "DAO Participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Fournisseur de services financiers (payeur)" #lightGray + participant PAYER_DFSP +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant PARTICIPANT_DAO + participant DB +end box + +box "Fournisseur de services financiers (bénéficiaire ou FXP)" #lightGray + participant PAYEE_DFSP_OR_FXP +end box + +activate NOTIFY_HANDLER +group Envoi de notification aux participants + note left of NOTIFY_HANDLER #lightgray + L'événement est automatiquement répliqué + vers le topic des événements (topic-events) + end note + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer l'événement de notification + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + note right of NOTIFY_HANDLER #lightgray + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + end note + NOTIFY_HANDLER -> CSAPI: Demander les détails de l'endpoint pour le participant - GET - /participants/{{fsp}}/endpoints\nCode d'erreur : 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Récupérer les détails de l'endpoint pour le participant\nCode d'erreur : 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer les détails de l'endpoint pour le participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Détails de l'endpoint récupérés pour le participant + deactivate DB + PARTICIPANT_DAO --> CSAPI: Retour des détails de l'endpoint pour le participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Retour des détails de l'endpoint pour le participant\nCodes d'erreur : 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification avec le résultat prepare/fulfil ou l'erreur vers\nle DFSP payeur sur l'endpoint indiqué - PUT \nCode d'erreur : 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt event.action === 'reserve' + alt event.status === 'success' + NOTIFY_HANDLER -> PAYEE_DFSP_OR_FXP: Notification du résultat d'exécution réussi (engagé) vers le DFSP bénéficiaire / FXP sur l'endpoint indiqué - PATCH \nCode d'erreur : 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP_OR_FXP: HTTP 200 OK + end + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg new file mode 100644 index 000000000..7d3963eb7 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg @@ -0,0 +1,157 @@ + + 1.1.4.a. Envoi de notification au participant (Payeur / Bénéficiaire / FXP) (message unique) v2.0 + + + 1.1.4.a. Envoi de notification au participant (Payeur / Bénéficiaire / FXP) (message unique) v2.0 + + Fournisseur de services financiers (payeur) + + Service adaptateur ML API + + Service central + + Fournisseur de services financiers (bénéficiaire ou FXP) + + + + + + + + + + + + + + + + DFSP payeur + Participant + + + DFSP payeur + Participant + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + + + Notification-Topic + + + Notification-Topic + API du service central + + + API du service central + + + DAO Participant + + + DAO Participant + + + Stockage central + + + Stockage central + + + DFSP bénéficiaire / FXP + Participant + + + DFSP bénéficiaire / FXP + Participant + + + + + + + + + + Envoi de notification aux participants + + + L'événement est automatiquement répliqué + vers le topic des événements (topic-events) + + + 1 + Consommer l'événement de notification + + + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + + + 2 + Demander les détails de l'endpoint pour le participant - GET - /participants/{{fsp}}/endpoints + Code d'erreur : + 2003 + + + 3 + Récupérer les détails de l'endpoint pour le participant + Code d'erreur : + 2003 + + + 4 + Récupérer les détails de l'endpoint pour le participant + + participantEndpoint + + + 5 + Détails de l'endpoint récupérés pour le participant + + + 6 + Retour des détails de l'endpoint pour le participant + + + 7 + Retour des détails de l'endpoint pour le participant + Codes d'erreur : + 3202, 3203 + + + 8 + Notification avec le résultat prepare/fulfil ou l'erreur vers + le DFSP payeur sur l'endpoint indiqué - PUT + Code d'erreur : + 1001 + + + 9 + HTTP 200 OK + + + alt + [event.action === 'reserve'] + + + alt + [event.status === 'success'] + + + 10 + Notification du résultat d'exécution réussi (engagé) vers le DFSP bénéficiaire / FXP sur l'endpoint indiqué - PATCH + Code d'erreur : + 1001 + + + 11 + HTTP 200 OK + + diff --git a/docs/fr/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md b/docs/fr/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md new file mode 100644 index 000000000..0ace66041 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md @@ -0,0 +1,13 @@ +# Demande de préparation de transfert FX + +Diagramme de conception de séquence pour le processus de demande de préparation de transfert FX. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Prepare FX (1.1.1.a)](1.1.1.a-fx-prepare-handler-consume.md) +* [Consommation par le gestionnaire Position FX (1.1.2.a)](1.1.2.a-fx-position-handler-consume.md) +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v2.0.md) + +## Diagramme de séquence + +![seq-fx-prepare-1.1.0.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md b/docs/fr/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md new file mode 100644 index 000000000..f0d365a9d --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire Prepare FX + +Diagramme de conception de séquence pour le processus de consommation par le gestionnaire Prepare FX. + +## Diagramme de séquence + +![seq-fx-prepare-1.1.1.a.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md b/docs/fr/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md new file mode 100644 index 000000000..c52c30b2f --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire Position FX + +Diagramme de conception de séquence pour le processus de consommation par le gestionnaire Position FX. + +## Diagramme de séquence + +![seq-fx-prepare-1.1.2.a.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md b/docs/fr/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md new file mode 100644 index 000000000..c85fb3c4f --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md @@ -0,0 +1,7 @@ +# Envoi de notification au participant v2.0 + +Diagramme de conception de séquence pour la demande d’envoi de notification au participant. + +## Diagramme de séquence + +![seq-prepare-1.1.4.a-v2.0.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md b/docs/fr/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md new file mode 100644 index 000000000..ccb34fed7 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md @@ -0,0 +1,13 @@ +# Demande d’exécution de transfert réussie (fulfil) + +Diagramme de conception de séquence pour la demande d’exécution de transfert en succès. + +## Références dans le diagramme de séquence + + +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v2.0.md) + +## Diagramme de séquence + +![seq-fx-fulfil-2.1.0.svg](../assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md b/docs/fr/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md new file mode 100644 index 000000000..92bbd1630 --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md @@ -0,0 +1,7 @@ +# Le FXP envoie une demande d’abandon d’exécution (fulfil abort) pour un transfert FX + +Diagramme de conception de séquence pour le processus de rejet d’exécution de transfert FX (fulfil reject). + +## Diagramme de séquence + +![seq-fx-reject-2.2.0.a.svg](../assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg) diff --git a/docs/fr/technical/central-fx-transfers/transfers/README.md b/docs/fr/technical/central-fx-transfers/transfers/README.md new file mode 100644 index 000000000..42067553b --- /dev/null +++ b/docs/fr/technical/central-fx-transfers/transfers/README.md @@ -0,0 +1,8 @@ +# Opérations Mojaloop de transfert FX + +Processus opérationnels au cœur de l’activation des transferts FX : + +- Processus de préparation FX (Prepare) +- Processus d’exécution FX (Fulfil) +- Processus FX de notifications +- Processus de rejet / abandon FX (Reject/Abort) diff --git a/docs/fr/technical/faqs.md b/docs/fr/technical/faqs.md new file mode 100644 index 000000000..41926c5e6 --- /dev/null +++ b/docs/fr/technical/faqs.md @@ -0,0 +1,156 @@ +# Foire Aux Questions + +Ce document contient certaines des questions techniques fréquemment posées par la communauté. + +## 1. Qu'est-ce qui est supporté ? + +Actuellement, les composants du Central Ledger sont pris en charge par l'équipe. Les composants DFSP sont obsolètes, ce qui rend l'installation de l'environnement de bout en bout et la configuration complète difficile. + +### 2. Pouvons-nous nous connecter directement à Pathfinder dans un environnement de développement ? + +Pour les environnements locaux et de test, nous recommandons d'utiliser plutôt le service 'mock-pathfinder'. Pathfinder est un service payant à l'utilisation. + +Accédez au dépôt https://github.com/mojaloop/mock-pathfinder pour télécharger et installer mock-pathfinder. Exécutez la commande `npm install` dans le dossier mock-pathfinder pour installer les dépendances, puis mettez à jour `Database_URI` dans `mock-pathfinder/src/lib/config.js`. + +### 3. Dois-je enregistrer un DFSP via l'URL http://central-directory/commands/register ou dois-je mettre à jour la configuration dans default.json ? + +Vous devez vous enregistrer en utilisant l'API fournie, en utilisant Postman ou curl. Le client utilise le code LevelOne. Il est nécessaire d'implémenter la version actuelle de Mojaloop avec les scripts Postman actuels. + +### 4. Le pod pi3-kafka-0 est toujours en état CrashLoopBackOff ? + +- Plus d'informations concernant la question : + + Lorsque j'ai essayé d'obtenir les logs du conteneur centralledger-handler-admin-transfer, j'obtiens l'erreur suivante : + `Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing` + Et le statut du pod pi3-kafka-0 reste sur CrashLoopBackOff. + J'utilise un VPS sous Ubuntu 16.04 avec 12 Go de RAM, 2 vCores, 2,4 GHz, 50 Go d'espace disque chez OVH pour le déploiement. + +L'augmentation de la RAM à 24 Go et du CPU à 4 a résolu les problèmes. Il semble que ce soit un timeout de Zookeeper dû à l'épuisement des ressources disponibles, ce qui entraîne l'arrêt des services. + +### 5. Pourquoi ai-je une erreur lorsque je tente de créer un nouveau DFSP via Admin ? + +Assurez-vous d'utiliser les scripts Postman les plus récents disponibles sur le dépôt https://github.com/mojaloop/mock-pathfinder. + +### 6. Puis-je répartir les composants Mojaloop sur différentes machines physiques et VM ? + +Vous devriez pouvoir configurer Mojaloop sur différentes VM ou machines physiques. La répartition dépend entièrement de vos besoins et sera spécifique à votre implémentation. Nous utilisons Kubernetes pour l'orchestration des conteneurs. Cela permet de planifier les déploiements via le runtime Kubernetes sur des machines spécifiques si nécessaire, et de demander des ressources spécifiques si besoin. Les Helm charts du dépôt Helm peuvent servir de ligne directrice sur la meilleure manière d'allouer et de regrouper les composants dans votre déploiement. Naturellement, vous devrez mettre à jour les configurations pour compléter votre implémentation personnalisée. + +### 7. Peut-on s’attendre à ce que tous les endpoints définis dans la documentation API soient implémentés dans Mojaloop ? + +L'API de la spécification Mojaloop pour les transferts et l'implémentation Mojaloop Open Source Switch sont des flux indépendants, bien que l'implémentation repose évidemment sur la spécification. En fonction des cas d'utilisation prioritaires, les endpoints nécessaires sont implémentés. Si certains endpoints ne sont pas prioritaires, il se peut qu'ils ne soient pas disponibles. Cependant, l'objectif est de prendre en charge tous les endpoints spécifiés, même si cela prendra du temps. Nous avons quelques-uns de ces endpoints dans le dépôt ‘postman’ de l’organisation Github mojaloop. + +### 8. Mojaloop stocke-t-il les informations de quote/statut du FSP initiateur de paiement ? + +Pour le moment, l’implémentation Switch open source Mojaloop ne stocke *pas* les informations liées aux Quotes. C’est au payeur et au bénéficiaire impliqués dans le processus de stocker les informations pertinentes. + +### 9. Mojaloop gère-t-il la validation des workflows ? + +Pas pour le moment, mais cela pourrait arriver à l’avenir. Concernant la corrélation des requêtes associées à un transfert spécifique, vous pouvez consulter l’endpoint ‘transaction’ dans la spécification pour plus d’informations. De plus, il y a un travail en cours concernant la spécification afin de rendre cette corrélation plus simple et directe, c’est-à-dire pour faire correspondre les requêtes de quote et de transfert relevant d’une seule transaction. + +### 10. Comment enregistrer un nouveau participant dans Mojaloop ? + +Il n'y a pas de méthode POST sur la ressource /parties, comme spécifié dans la section 6.1.1 de la définition de l’API. Veuillez vous référer à la section 6.2.2.3 : `POST /participants//` dans la définition de l’API. + +"_La requête HTTP `POST /participants//` (ou `POST /participants///`) est utilisée pour créer des informations sur le serveur concernant l'identité fournie, définie par ``, ``, et éventuellement `` (par exemple : POST_ + _/participants/MSISDN/123456789 ou POST /participants/BUSINESS/shoecompany/employee1). Voir Section 5.1.6.11 pour plus d’informations sur l’adressage d’un Participant._" + +### 11. Le participant représente-t-il un compte client dans une banque ? + +Pour plus d'informations, consultez ce document (section 3..2) : https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +"_Dans l’API, un Participant est identique à un FSP qui participe à un schéma d’interopérabilité. L'objectif principal de la ressource logique Participants API est de permettre aux FSPs de savoir dans quel autre FSP se trouve une contrepartie impliquée dans une transaction financière interopérable. Il existe également des services permettant aux FSPs de fournir des informations à un système commun._" + +En résumé, un participant est tout FSP participant au schéma (généralement pas un client). Pour la recherche de comptes, un service d’annuaire tel que *Pathfinder* peut être utilisé, qui fournit la recherche utilisateur et le mapping. Si un tel service n'est pas fourni, une alternative est proposée dans la spécification, où le Switch héberge un Account Lookup Service (ALS) auquel les participants doivent enregistrer les parties. J'ai déjà abordé ce point. À noter que le Switch ne stocke pas les détails, uniquement la correspondance entre un ID et un FSP, puis les appels pour résoudre le participant sont envoyés à ce FSP. + +https://github.com/mojaloop/mojaloop-specification CORE RELATED (Mojaloop): + +Ce dépôt contient l’ensemble des documents de spécification de l’API ouverte pour l'interopérabilité FSP - mojaloop/mojaloop-specification. + +### 12. Comment enregistrer un bénéficiaire _de confiance_ pour un payeur, afin d’éviter l’OTP ? + +Pour éviter l’OTP, la demande initiale sur /transactionRequests du bénéficiaire peut être approuvée de manière programmatique (ou manuelle) sans recourir à l’endpoint /authorizations (qui est utilisé pour l’approbation OTP). En effet, c’est au FSP de gérer cela, le Switch ne le fait pas. Ceci est brièvement évoqué dans la section 6.4 de la spécification. + +### 13. 404 lors de l’accès ou du chargement du fichier kubernetes-dashboard.yaml ? + +Depuis le dépôt officiel Github Kubernetes dans le README.md, le lien le plus récent à utiliser est : "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Vérifiez toujours les liens tiers avant de les utiliser. Les applications open source évoluent constamment. + +### 14. Lors de l'installation de nginx-ingress pour le load-balancing et l’accès externe - Erreur : no available release name found ? + +Merci de consulter la documentation traitant d’un problème similaire. En résumé - il s'agit très probablement d'un problème RBAC. Consultez la documentation pour mettre en place Tiller avec RBAC. https://docs.helm.sh/using_helm/#role-based-access-control détaille ce point. Voir l’issue enregistrée : helm/helm#3839. + +### 15. Erreur "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" lors du lancement de `npm start`. + +Une solution a été trouvée ici : https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Ubuntu 14 ici, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. Pour commencer, je souhaite compiler la dernière version stable (semble être 0.9.2) de librdkafka dans /opt/librdkafka. curl https://codeload.github.com/ede... + +Voici les étapes pour recompiler librdkafka : + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout `` + +cd librdkafka && ./configure && make && make install && ldconfig + +Après cela, je peux importer sans spécifier LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +La bibliothèque Apache Kafka C/C++. Contribuez au développement de edenhill/librdkafka sur GitHub. + +### 16. Peut-on utiliser mojaloop comme logiciel open source de portefeuille mobile ou mojaloop ne fait que l’interopérabilité ? + +Nous pouvons utiliser mojaloop pour l’interopérabilité afin de prendre en charge les portefeuilles mobiles et autres transferts d'argent. Ce n’est pas un logiciel pour un DFSP (il existe d’autres projets open source pour cela, comme Finserv etc.). Mojaloop est principalement destiné à un Hub/Switch et à une API que le DFSP doit implémenter. Mais ce n’est pas fait pour gérer des portefeuilles mobiles en tant que tel. + +### 17. Décrivez les entreprises qui aident à déployer & supporter mojaloop ? + +Mojaloop est un logiciel et une spécification open source. + +### 18. Pouvez-vous dire quelque chose sur mojaloop & la sécurité ? + +La spécification est assez standard et dispose de bonnes normes de sécurité. Mais celles-ci doivent être mises en œuvre par les adopteurs et les déployeurs. En plus de cela, les mesures de sécurité doivent être complétées par d’autres mesures de sécurité opérationnelle et de déploiement. De plus, les prochains mois seront axés sur la sécurité dans la communauté open source. + +### 19. Quels sont les avantages d'utiliser mojaloop comme plateforme d’interopérabilité ? + +Avantages : Actuellement, par exemple, un utilisateur Airtel mobile money peut seulement transférer vers un autre utilisateur Airtel mobile money. Avec ce système, il/elle peut transférer vers tout fournisseur de services financiers, tel qu'un autre fournisseur de mobile money ou tout autre compte bancaire ou commerçant connecté au Hub, quelle que soit leur implémentation. Ils doivent simplement être connectés au même Switch. De plus, il est conçu pour fonctionner sur des téléphones basiques afin que tout le monde puisse l’utiliser. + +### 20. Quels sont les principaux défis pour les entreprises utilisant mojaloop ? + +Pour l’instant, les principaux défis concernent les attentes. Les attentes des adopteurs de mojaloop et ce qu'est réellement mojaloop. Beaucoup d’adopteurs ont une compréhension différente de ce qu’est mojaloop et de ses capacités. S'ils ont la bonne compréhension, de nombreux défis actuels sont atténués. +Oui, le journal d’audit (forensic logging) est également une mesure de sécurité à des fins d’audit, qui garantit qu’il existe des traces vérifiables des actions et que toute action notable est enregistrée et sécurisée après un chiffrement à plusieurs niveaux. + +### 21. Le forensic logging/l’audit dans mojaloop est-il lié à la sécurisation de la plateforme d’interopérabilité ? + +Cela garantit également que tous les services exécutent toujours le code qu'ils sont censés exécuter, et que tout comportement anormal/indésirable est arrêté dès le démarrage. Pour le reporting et les auditeurs, cela permet de suivre les actions via un audit-log. + +### 22. Comment les fournisseurs de services financiers se connectent-ils à mojaloop ? + +Il existe un schéma architectural qui donne une bonne vue de l’intégration entre les différentes entités. https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +### 23. Existe-t-il un convertisseur/connecteur open source ISO8583-OpenAPI ? + +Je ne pense pas qu’il existe actuellement une intégration générique ISO8583 `<-> Mojaloop. Nous travaillons sur certaines intégrations « canal de paiement traditionnel » vers Mojaloop (POS et GAB) que nous espérons présenter lors de la prochaine conférence. Celles-ci pourraient constituer la base d'une intégration ISO8583 à ajouter à la pile OSS, mais gardez à l'esprit que ces intégrations seront très spécifiques à l'usage. + +### 24. Comment connaître les endpoints à configurer dans Postman pour tester le déploiement ? + +Sur le dashboard Kubernetes, sélectionnez le bon NAMESPACE. Allez dans les Ingresses. Selon la façon dont vous avez déployé les Helm charts, cherchez 'moja-centralledger-service'. Cliquez sur éditer et trouvez la balise ``. Cela contiendra le endpoint pour ce service. + +### 25. Pourquoi n’y a-t-il pas de possibilité d’annulation (reversal) sur Mojaloop ? + +*L’irrévocabilité* est un principe fondamental du programme Level One et ne pas autoriser d’annulations (reversals) est essentiel pour cela. Voici la section de la définition API qui en parle : + +_*6.7.1.2 Irrévocabilité des transactions*_ +_L’API est conçue pour prendre en charge uniquement des transactions financières irrévocables ; cela signifie qu’une transaction financière ne peut pas être modifiée, annulée ou inversée après sa création. Cela vise à simplifier et à réduire les coûts pour les FSP utilisant l’API. Une grande partie des coûts d’exploitation des systèmes financiers classiques est due aux annulations de transactions._ +_Dès qu’un FSP payeur envoie une transaction financière à un FSP bénéficiaire (c’est-à-dire via POST /transfers avec la transaction de bout en bout), la transaction est irrévocable du point de vue du FSP payeur. La transaction peut encore être rejetée par le FSP bénéficiaire, mais le FSP payeur ne peut plus la rejeter ou la modifier. Une exception à cela serait si l’expiration du transfert survient avant la réponse du FSP bénéficiaire (voir les sections 6.7.1.3 et 6.7.1.5 pour plus d’informations). Une fois la transaction acceptée par le FSP bénéficiaire, elle est irrévocable pour toutes les parties._ + +Cependant, *les remboursements* sont un cas d’utilisation supporté par l’API. + +### 26. Erreur lors de l'installation de microk8s : "MountVolume.SetUp failed" ? + +Cela semblerait être un problème d’espace, bien que plus de 100GiB de stockage EBS aient été alloués. +Le problème s’est résolu de lui-même après 45 minutes. L’implémentation initiale du projet mojaloop peut prendre du temps à se stabiliser. + +### 27. Pourquoi ai-je cette erreur lors de la création d’un participant : "Hub reconciliation account for the specified currency does not exist" ? + +Vous devez créer les comptes Hub correspondants (HUB_MULTILATERAL_SETTLEMENT et HUB_RECONCILIATION) pour la devise spécifiée avant de configurer les participants. +Dans cette collection Postman, vous pouvez trouver les requêtes nécessaires dans le dossier "Hub Account" : https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Trouvez aussi les environnements associés dans le dépôt Postman : https://github.com/mojaloop/postman diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png new file mode 100644 index 000000000..818a34706 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png new file mode 100644 index 000000000..21d61c305 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png new file mode 100644 index 000000000..175ca5e37 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png new file mode 100644 index 000000000..edfac583f Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png new file mode 100644 index 000000000..ccb1b42a2 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md new file mode 100644 index 000000000..4baced0aa --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md @@ -0,0 +1,70 @@ +# BC de Recherche et Découverte de Comptes + +Le BC de Recherche et Découverte de Comptes est responsable de la localisation et de l’association des participants et des parties avec les transactions initiées par une partie ou un participant. + +## Termes + +Les termes suivants sont utilisés dans ce BC, aussi appelé domaine. + +| Terme | Description | +|---|---| +| **Participant** | Fournisseur de Services Financiers (FSP) | +| **Party (Partie)** | Client du FSP | + +## Vue Fonctionnelle + +![Cas d’Utilisation - Vue Fonctionnelle](./assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png) +>Diagramme fonctionnel du BC : Vue d’ensemble de la Recherche et Découverte de Comptes + +## Cas d’Utilisation + +#### Association Partie/Participant + +#### Description + +Lorsqu’un Participant DFSP demande à associer un identifiant de Partie donné à un Participant (lui-même). + +***Remarque :*** *Les vérifications et validations KYC (« Know Your Customer » – Connaître votre client) ne sont pas couvertes ici et relèvent de processus extérieurs aux appels d’API Mojaloop. Ces vérifications doivent être couvertes par le Schéma pour garantir la validité des demandes d’association (ou de dissociation).* + +#### Diagramme de Flux + +![Cas d’Utilisation - Association Partie/Participant](./assets/aldPartyParticipantAssoc_20220919.png) +>Diagramme de flux UC : Association Partie/Participant + +### Dissociation Partie/Participant + +#### Description + +Dans ce cas, un Participant DFSP demande à supprimer l’association existante entre un identifiant de Partie et un Participant (lui-même). + +#### Diagramme de Flux + +![Cas d’Utilisation - Dissociation Partie/Participant](./assets/aldPartyParticipantDisassoc_20220919.png) +>Diagramme de flux UC : Dissociation Partie/Participant + +### Obtenir un Participant + +#### Description + +Lorsqu’un Participant DFSP demande des informations d’association de Participant sur la base d’un identifiant de Partie, ce cas d’utilisation est utilisé par le Switch pour valider la demande et fournir les données d’association demandées au DFSP requérant. + +#### Diagramme de Flux + +![Cas d’Utilisation - Obtenir un Participant](./assets/aldGetParticipant_20210825.png) +>Diagramme de flux UC : Obtenir un Participant + +### Obtenir une Partie + +#### Description + +Lorsqu’un Participant DFSP interroge un autre Participant DFSP pour obtenir les détails d’une Partie gérée par ce dernier, ce cas d’utilisation permet de valider la demande et de fournir les données de la Partie demandées au DFSP requérant. + +#### Diagramme de Flux + +![Cas d’Utilisation - Obtenir une Partie](./assets/aldGetParty_20210825.png) +>Diagramme de flux UC : Obtenir une Partie + + + + +[^1]: Interfaces Communes : [Liste d’interfaces communes Mojaloop](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png b/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png new file mode 100644 index 000000000..4da5a26b9 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md b/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md new file mode 100644 index 000000000..aeff47837 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md @@ -0,0 +1,121 @@ +# BC Comptes et Soldes + +Le BC Comptes et Soldes agit comme le « grand livre central » du système. Il interagit principalement avec le BC Règlements, le BC Cycle de Vie des Participants et les BCs Transferts. Il s’agit d’un sous-système dirigé, ce qui signifie qu’il constitue une dépendance pour les BCs qui l’utilisent comme « registre financier » pour la comptabilité. + +**Remarque :** + +Le BC Comptes et Soldes contient une quantité limitée de logique afin de garantir que **(a)** les bonnes relations sont créées et maintenues entre les entités lorsqu’un BC externe crée, met à jour, consulte ou ferme des comptes et **(b)** que les limites de comptes appropriées sont appliquées (c’est-à-dire définies et non dépassées) lorsqu’un BC externe tente de créer des écritures comptables, et **(c)** qu’on évite les doublons d’écritures grâce à l’utilisation d’*identifiants uniques universels (UUID)* pour les identifiants d’écritures uniques. + +## Termes + +Termes ayant une signification spécifique et communément acceptée dans le contexte délimité où ils sont utilisés. + +| Terme | Description | +|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Compte** | Désigne un compte du Grand Livre, un enregistrement dans un système comptable qui enregistre les écritures au débit ou au crédit représentant une opération financière. | +| **Écriture** | Enregistrements comptables de crédit/débit sur un Compte. | +| **Solde** | Montant disponible dans un compte, une fois pris en compte les débits et crédits. | + +## Vue fonctionnelle – Comptes et Soldes + +![Aperçu fonctionnel – Comptes et Soldes](./assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png) +>Diagramme fonctionnel BC : Vue d’ensemble des Comptes & Soldes + +## Cas d’utilisation + +### Création de Compte + +#### Description + +Le flux défini par ce cas d’utilisation permet au Switch de créer de nouveaux comptes participants/de transfert/de règlement dans le Grand Livre du Système. (La création de comptes Participants intervient à la fois depuis le BC Cycle de Vie des Participants et le BC Règlements. Des exemples issus des deux sont fournis dans les diagrammes de flux ci-dessous.) + +De plus, ce flux permet de spécifier des limites de crédit/débit pour les Écritures, et garantit que le Compte est unique dans le Grand Livre du Système. + +#### Diagramme de flux + +Création de compte depuis le [BC Cycle de Vie des Participants](../participantLifecycleManagement/index.md) + + + +![Cas d’utilisation – BC PLCM](../participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png) +![Cas d’utilisation – Approbation de création Compte Participant (P2)](../participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png) +>Diagramme de flux UC : Ajout de comptes participants + +Création de compte depuis le [BC Règlements](../settlements/index.md) + +![Cas d’utilisation – BC Règlements](../settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png) +>Diagramme de flux UC : Initialisation via configuration d’un modèle de règlement + +### Fermeture de Compte + +#### Description + +Fermer un compte participant dans le Grand Livre du Système et empêcher l’impact de nouvelles écritures comptables sur celui-ci.
    (À déterminer : possible vidage automatique des soldes CR de collatéral vers un autre compte automatiquement ?) + +### Consultation de Compte + +#### Description + +Consulter le statut et le solde d’un compte participant. + +#### Diagramme de flux + +Demande des limites de liquidité CR/DR depuis le [BC Cycle de Vie des Participants](../participantLifecycleManagement/index.md) + + + +![Cas d’utilisation – BC PLCM](../participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png) +>Diagramme de flux UC : Demande de couverture de liquidité + +### Consultation des écritures + +#### Description + +Consulter les écritures comptables (débit/crédit) d’un Compte. + +### Insertion d’une écriture + +#### Description + +Saisir une écriture comptable de participant dans le Grand Livre en spécifiant les comptes débiteurs et créditeurs (Il existe trois façons d’effectuer ces saisies ; voir les diagrammes de flux ci-dessous pour chacune.) +Répondre avec le nouveau solde du compte. + +#### Diagramme de flux + +Insertion d’une écriture depuis le [BC Transferts](../transfers/index.md) + +![Cas d’utilisation – BC Transferts](../transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png) +>Diagramme de flux UC : Effectuer un transfert (mode universel) + +Insertion d’une écriture depuis le [BC Règlements](../settlements/index.md) en utilisant le modèle `Règlement Net Différé (DNS)` + +![Cas d’utilisation – BC Règlements](../settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png) +>Diagramme de flux UC : Règlement Net Différé – 19/10/2021 + +Insertion d’une écriture depuis le [BC Règlements](../settlements/index.md) en utilisant le modèle `Règlement Brut Immédiat (IGS)` + +![Cas d’utilisation – BC Règlements](../settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png) +>Diagramme de flux UC : Règlement Brut Immédiat + +## Modèle Canonique + +- Compte + - accountId + - ledgerAccountType + - ledgerAccountState + - debitLimit + - creditLimit + - debitBalance + - creditBalance +- Écriture + - journalEntryId + - debitAccountId + - creditAccountId + - journalEntryType + - transferAmount + - transferTimestamp + + + + +[^1]: Interfaces Communes : [Liste d’interfaces communes Mojaloop](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png new file mode 100644 index 000000000..8e5c8c2d9 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png new file mode 100644 index 000000000..c2392091e Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png new file mode 100644 index 000000000..67bb2b3b0 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png new file mode 100644 index 000000000..6ec6a7dd0 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/auditing/index.md b/docs/fr/technical/reference-architecture/boundedContexts/auditing/index.md new file mode 100644 index 000000000..eb706b14c --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/auditing/index.md @@ -0,0 +1,67 @@ +# BC Auditing + +Le BC Auditing est responsable du maintien d’un enregistrement immuable de toutes les transactions qui ont lieu sur le Switch. Son architecture est composée de cinq principaux composants : + +* Service centralisé de journalisation médico-légale +* Services +* Stockage immuable +* Système de Gestion des Clés (KMS) +* Module Fournisseur Cryptographique (CPM)[^1] + +Les utilisateurs autorisés peuvent interroger le BC Auditing via une API d’Opérations exposée à cet effet, afin d’obtenir des détails sur les événements auditables. + +## Termes + +Termes ayant une signification spécifique et communément admise dans le Contexte Borné où ils sont utilisés. + +| Terme | Description | +|---|---| +| **KMS** | Système de Gestion des Clés (Key Management System) – Fournit des services de chiffrement/déchiffrement et d’Autorité de Certification (CA) à l’environnement du Switch (émission, signature et vérification via le BC Sécurité). | +| **CPM** | Module Fournisseur Cryptographique – Gère les techniques et méthodologies cryptographiques employées par le Switch, afin de garantir des services de chiffrement et de déchiffrement de bout en bout pour toutes les données stockées ou transmises. | + +## Vue Fonctionnelle + +![Cas d’Utilisation – Vue Fonctionnelle du Système d’Audit](./assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png) +> Diagramme Fonctionnel du BC : Vue d’ensemble du Système d’Audit + +## Cas d’Utilisation + +### Démarrage du BC Auditing + +#### Description + +Le cas d’utilisation « Démarrage du BC Auditing » est déclenché lors du démarrage (à intervalles réguliers ou sur évènement) et récupère l’ensemble des clés publiques utilisées par les différents BCs Participants du Switch depuis le BC Sécurité fournissant les services de gestion des clés (KMS) pour tous les BCs Participants du Switch. + +#### Diagramme de déroulement + +![Cas d’Utilisation – Démarrage du BC Auditing](./assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png) +> Diagramme de Workflow du Cas d’Utilisation : Démarrage du BC Auditing + +### Audit Sync/RPC + +#### Description + +Le cas d’utilisation « Audit Sync/RPC » est activé lors d’un événement digne d’audit déclenché pendant une transaction notée par un BC participant. Le BC participant notifie alors le BC Auditing via un appel RPC synchronisé. L’entrée d’audit est signée localement par le BC émetteur. Dès réception, le BC Auditing effectue une série de procédures comprenant une procédure avec le KMS via le BC Sécurité, puis persiste l’enregistrement dans un stockage à ajout seul (Append-only Store). + +#### Diagramme de déroulement + +![Cas d’Utilisation – Audit Sync/RPC](./assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png) +> Diagramme de Workflow du Cas d’Utilisation : Audit Sync/RPC + +### Audit Basé sur les Événements + +#### Description + +Le cas d’utilisation « Audit Basé sur les Événements » est déclenché lorsqu’un BC participant dispose d’une capacité d’audit locale, détecte un événement digne d’audit, crée un événement d’audit signé localement, qu’il publie puis envoie (individuellement ou en lot (Event-batch)) au BC Auditing. L’événement est validé via une procédure avec le BC Sécurité, puis stocké dans le dépôt à ajout seul (Append-Only Store). + +#### Diagramme de déroulement + +![Cas d’Utilisation – Audit Basé sur les Événements](./assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png) +> Diagramme de Workflow du Cas d’Utilisation : Audit Basé sur les Événements + + +## Notes + +[^1]: « Cryptographique » fait référence à l’ensemble des techniques et méthodologies algorithmiques employées par les systèmes pour empêcher des systèmes ou des personnes non autorisées d’accéder, d’identifier ou d’utiliser des données stockées. Pour en savoir plus, veuillez consulter l’article Wikipédia dédié : [Cryptographie, Wikipedia – l’encyclopédie libre](https://fr.wikipedia.org/wiki/Cryptographie) + +[^2]: Interfaces communes : [Liste des Interfaces Communes Mojaloop](../../refarch/commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/commonInterfaces/index.md b/docs/fr/technical/reference-architecture/boundedContexts/commonInterfaces/index.md new file mode 100644 index 000000000..12dbf7f44 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/commonInterfaces/index.md @@ -0,0 +1,151 @@ +# Liste des Interfaces Communes + +La Liste des Interfaces Communes recense l’ensemble des interfaces communes utilisées actuellement dans l’Architecture de Référence Mojaloop 2.0. Les interfaces communes sont partagées par plusieurs Bounded Contexts, d’où leur nom. + +Chaque interface commune listée comprend les informations suivantes : le nom de l'événement source ou de l'endpoint, le style de communication, le Bounded Context éditeur/fournisseur, une description de la fonction de l'interface, ainsi qu'une liste de contrôle des Bounded Contexts qui l'utilisent. + +## Interfaces Communes + +| Nom de l'événement OU endpoint | Style de communication | BC éditeur/fournisseur | Description | BC API Interop FSP | BC Admin/Opérations | BC Gestion du Cycle de Vie du Participant | BC Transferts | BC Comptes & Soldes | BC Règlements | BC Recherche de Comptes | BC Accords / Devis | Paiements Initiés par une Tierce Partie | BC Notifications & Alertes | BC Planification | BC Audit | BC Sécurité - authZ | BC Sécurité - authN | BC Sécurité - auditing | BC Sécurité - logging | BC Sécurité - crypto | +|------------------------------------------------------|---------------|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|---------------------|------------------------------------|---------------|---------------------|---------------|------------------------|--------------------|-------------------------|----------------------------|-------------------|---------|-------------------|-------------------|--------------------|--------------------|-------------------| +| TransferCommittedFulfiled | Événement | BC Transferts | Événement indiquant le résultat final de l’étape Transfer Committed d’un transfert traitée par le BC Transferts | x | | x | | | | | | | | | | | | | | | +| LiquidityThresholdExceeded | gRPC | BC Transferts | Événement déclenché lorsqu’un seuil de liquidité d’un participant donné est dépassé et qu’une action doit être prise | | | X | | | | | | | | | | | | | | | +| TransferPrepared | Événement | BC Transferts | Événement Transfer Prepared indiquant le résultat final de l’étape Transfer Prepare d’un transfert traitée par le BC Transferts | x | | | | | | | | | | | | | | | | | +| TransferQueryResponse | Événement | BC Transferts | Événement contenant la réponse suite à un événement TransferQueryReceived | x | | | | | | | | | | | | | | | | | +| TransferRejectRequestProcessed | Événement | BC Transferts | Événement confirmant qu’une demande de rejet de transfert a été traitée par le BC Transferts | x | | | | | | | | | | | | | | | | | +| TransferPrepareRequestTimedout | Événement | BC Transferts | Événement de délai dépassé lorsqu’un transfert était encore en cours de préparation | x | | | | | | | | | | | | | | | | | +| TransferFulfilComitRequestTimedout | Événement | BC Transferts | Événement de délai dépassé lorsqu’un transfert était en état préparé final (c.-à-d. en attente d’un accomplissement ou d’un rejet à recevoir) | x | | | | | | | | | | | | | | | | | +| TransferPrepareDuplicateCheckFailed | Événement | BC Transferts | Événement représentant un échec de vérification de doublon suite au traitement de l’événement TransferPrepareAccountAllocated | x | | | | | | | | | | | | | | | | | +| TransferPrepareLiquidityCheckFailed | Événement | BC Transferts | Événement représentant un échec de vérification de liquidité suite au traitement de l’événement TransferPrepareAccountAllocated | x | | | | | | | | | | | | | | | | | +| TransferPrepareInvalidPayerCheckFailed | Événement | BC Transferts | Événement représentant un échec de vérification du participant Payeur suite au traitement d’un événement TransferPrepareAccountAllocated | x | | | | | | | | | | | | | | | | | +| TransferPrepareInvalidPayeeCheckFailed | Événement | BC Transferts | Événement représentant un échec de vérification du participant Bénéficiaire suite au traitement d’un événement TransferPrepareAccountAllocated | x | | | | | | | | | | | | | | | | | +| TransferPrepareAccountsAllocated | Événement | BC Règlements | Événement de demande Transfer Prepare enrichi des comptes applicables pour la validation/allocation de liquidité pour chaque participant | | | | x | | | | | | | | | | | | | | +| /random-number-gen | Événement | BC Sécurité - crypto | Générateur de nombres aléatoires. Permet de générer (1) un id (2) un secret (3) un challenge FIDO | x | x | | | | | | | | | | | x | x | | | x | +| /hash-gen | HTTP/Rest | BC Sécurité - crypto | Génération de hash. Peut être utilisé pour hacher des nombres aléatoires et des informations utilisateur. Le hash est utilisé pour l’authentification de base et la vérification de signature.| x | x | | | | | | | | | | | x | x | | | x | +| /signature-gen | HTTP/Rest | BC Sécurité - crypto | Génération de signature. Utilisée pour signer les enregistrements d’audit afin d’assurer l’immutabilité | | | | | | | | | | | | x | x | x | x | x | | +| /signature-ver | HTTP/Rest | BC Sécurité - crypto | Vérification de signature. Utilisée pour l’authentification et l’autorisation FIDO. Cela est également utilisé pour valider l’enregistrement d’audit lors de la récupération | x | x | | | | | | | | | | x | x | x | x | x | | +| /encrypt | HTTP/Rest | BC Sécurité - crypto | Chiffrement générique | | | | | | | | | | | | x | | | x | x | x | +| /decrypt | HTTP/Rest | BC Sécurité - crypto | Déchiffrement générique | | | | | | | | | | | | x | | | x | x | x | +| /pin-translation | HTTP/Rest | BC Sécurité - crypto | Traduction de bloc PIN bancaire d’une zone de chiffrement à une autre. Peut être utilisé pour des transactions interbancaires ATM ou POS | | | | | | | | | | | | | | | | | x | +| /fido-register | HTTP/Rest | BC Sécurité - crypto | Fonction crypto composite. Stocke la clé publique ECC de l’authentificateur avec les informations utilisateur | x | x | | | | | | | | | | | | | | | | +| /fido-authenticate | HTTP/Rest | BC Sécurité - crypto | Authentifier la signature FIDO | x | x | | | | | | | | | | | | | | | | +| /fido-authorize | HTTP/Rest | BC Sécurité - crypto | Autoriser une transaction FIDO après un geste (bouton pressé, empreinte digitale, etc.) | x | x | | | | | | | | | | | | | | | | +| /kms-key-definition | HTTP/Rest | BC Sécurité - crypto | Définition de clé cryptographique (usage de clé, durée, label) | | | | | | | | | | | | | | | | | x | +| /kms-aes-key-gen | HTTP/Rest | BC Sécurité - crypto | Génération de clé cryptographique pour chiffrement symétrique | | | | | | | | | | | | | | | | | x | +| /kms-ecc-key-gen | HTTP/Rest | BC Sécurité - crypto | Génération de clé cryptographique pour la génération de paire de clés à courbe elliptique | | | | | | | | | | | | | | | | | x | +| /crypto-adapter-set | HTTP/Rest | BC Sécurité - crypto | Définir le fournisseur / adaptateur cryptographique (AWS, Azure, HSM on-prem, librairies logicielles locales...) | | | | | | | | | | | | | | | | | x | +| /iam-token-verifty | HTTP/Rest | BC Sécurité - crypto | Vérification basique de token d’authentification. Appel composite à l’adaptateur IAM | x | x | | x | | | | | | | | | | | | | x | +| /kms-pem-gen | HTTP/Rest | BC Sécurité - crypto | Clés PKI pour l’authentification client et les fonctions CLI | x | x | | | | | | | | | | | | | | | x | +| /ssl-terminate | HTTP/Rest | BC Sécurité - crypto | Terminaison SSL | | | | | | | | | | | | | | | | | x | +| /kms-load-key | HTTP/Rest | BC Sécurité - crypto | Charger des clés cryptographiques dans le magasin de clés | | | | | | | | | | | | | | | | | x | +| /app-authorize | HTTP/Rest | BC Sécurité - authZ | Appelle AuthZ BC pour vérifier le token d’autorisation. Appelle également IAM pour vérifier les rôles | x | x | | | | | | | | | | | x | | | | x | +| /app-fido-authorize | HTTP/Rest | BC Sécurité - authZ | Appelle Crypto BC pour autoriser la transaction | x | x | | | | | | | | | | | | | | | x | +| /app-pem-auth | HTTP/Rest | BC Sécurité - authZ | Utilise les clés PKI privée et publique pour authentifier les appels API. Utilise le profil IAM utilisateur (informations utilisateur + rôle) pour autoriser | | | | | | | | | | | | | | x | | | x | +| /app-basic-auth | HTTP/Rest | BC Sécurité - authN | Appelle AuthZ BC pour vérifier l’id et le secret. Retourne un token d’autorisation | x | x | | | | | | | | | | | | x | | | x | +| CreateScheduleReminder | gRPC | BC Planification | Crée un rappel planifié avec les informations nécessaires pour créer un événement ou un callback API une fois le rappel écoulé | | | | x | | | | | | | | | | | | | | +| DeleteScheduleReminder | gRPC | BC Planification | Événement indiquant qu’un délai a expiré pour un rappel planifié | | | | x | | | | | | | | | | | | | | +| POST /config/schemas/ | HTTP/Rest | BC Configuration Plateforme | (upsert) Publier les versions initiales ou nouvelles d’un schéma d’objet de gestion de configuration BC au démarrage – inclut le numéro de version | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/schemas/ | HTTP/Rest | BC Configuration Plateforme | Récupérer le schéma et les configurations actuelles de tous les bounded contexts | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/schemas/:boundedContextId | HTTP/Rest | BC Configuration Plateforme | Récupérer le schéma et les configurations actuelles d’un bounded context spécifique | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| ConfigurationValuesChanged | Événement | BC Configuration Plateforme | Événement envoyé lors de modifications sur une configuration – devrait inclure au moins l’ID du bounded context, éventuellement les noms de clés avec les valeurs modifiées | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| POST /config/schemas/:boundedContextId | HTTP/Rest | BC Configuration Plateforme | Publier les versions initiales ou nouvelles d’un schéma d’objet de gestion de configuration BC au démarrage – inclut le numéro de version | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| POST /config/secrets/ | HTTP/Rest | BC Configuration Plateforme | (upsert) Publier la liste des secrets attendus (clés) dont un bounded context a besoin pour fonctionner – envoyé au démarrage – inclut le numéro de version | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/ | HTTP/Rest | BC Configuration Plateforme | Récupérer la liste des clés secrètes dont chaque BC a besoin pour fonctionner – pour tous les bounded contexts | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/:boundedContextId | HTTP/Rest | BC Configuration Plateforme | Récupérer la liste des clés secrètes dont chaque BC a besoin pour fonctionner – pour un bounded context spécifique | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/:boundedContextId/values | HTTP/Rest | BC Configuration Plateforme | Appel réalisable uniquement par le bounded context propriétaire (vérification de signature) — retourne les secrets ainsi que les clés pour ce bounded context | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| SecretsValuesChanged | Événement | BC Configuration Plateforme | Événement envoyé lors de modifications sur un secret – devrait inclure au moins l’ID du bounded context, éventuellement les noms de clés avec les secrets modifiés | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| UpdateParticipantAccountThreshold | gRPC | BC Gestion du Cycle de Vie du Participant | Met à jour les seuils des comptes spécifiés | | | | | X | | | | | | | | | | | | | +| GetParticipantsTransfersData | gRPC | BC Gestion du Cycle de Vie du Participant | Service de requête pour obtenir les informations Participant à des fins de Transfert (c.-à-d. validations, etc.) | | | | x | | | | | | | | | | | | | | +| GetParticipantCallbackInfo | gRPC | BC Gestion du Cycle de Vie du Participant | API pour interroger les informations Participant pour les Callbacks. Exemple : le BC API Interop FSP utilise ceci pour interroger les informations nécessaires afin de produire un événement NotifyRequested | x | | | | | | | | | | | | | | | | | +| GetParticipantQuoteData | gRPC | BC Gestion du Cycle de Vie du Participant | Service de requête pour obtenir les informations Participant à des fins de Devis (c.-à-d. validations, etc.) | | | | | x | | | | | | | | | | | | | +| CreateParticipant | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de création d’un nouveau participant avec une charge utile unique définissant TOUS les détails pertinents du Participant | | X | | | | | | | | | | | | | | | | +| GetPendingParticipants | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les participants dans l’état « PEND-APPROVAL », c’est-à-dire les Participants qui n’ont pas encore été approuvés ou rejetés | | X | | | | | | | | | | | | | | | | +| ApproveParticipant | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Participant en état d’approbation en attente | | X | | | | | | | | | | | | | | | | +| CreateParticipantAccountsWithLimits | gRPC | BC Gestion du Cycle de Vie du Participant | Notifie que le participant a été créé et que les comptes avec limites seront ensuite créés également | | | | | X | | | | | | | | | | | | | +| ParticipantCreated | Événement | BC Gestion du Cycle de Vie du Participant | Notifie que le participant a été créé, comptes et limites inclus | | | X | | | | | | | | | | | | | | | +| ManageFunds | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Appel pour retirer ou déposer des fonds | | X | | | | | | | | | | | | | | | | +| GetPendingManageFunds | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère toutes les demandes de gestion de fonds qui doivent être approuvées | | X | | | | | | | | | | | | | | | | +| ApproveManageFunds | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Demande de dépôt ou de retrait | | X | | | | | | | | | | | | | | | | +| ManageFundsCreditDebitPairInstruction | gRPC | BC Gestion du Cycle de Vie du Participant | Met à jour la comptabilité avec les écritures de crédit et de débit pertinentes | | | | | X | | | | | | | | | | | | | +| ReserveLiquidityCover | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de réserve d’un montant de couverture de liquidité, soit une valeur soit un % | | X | | | | | | | | | | | | | | | | +| GetPendingLiquidityCoverReservations | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère toutes les demandes de couverture de liquidité en attente d’approbation | | X | | | | | | | | | | | | | | | | +| ApproveLiquidityCoverReservation | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Réservation de couverture de liquidité | | X | | | | | | | | | | | | | | | | +| UpdateParticipantState | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de changement d’état pour un participant donné | | X | | | | | | | | | | | | | | | | +| GetPendingStateUpdates | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les participants avec des demandes de changement d’état en attente d’approbation | | X | | | | | | | | | | | | | | | | +| ApproveParticipantStateUpdate | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Changement d’état de participant | | X | | | | | | | | | | | | | | | | +| ParticipantStateUpdated | gRPC | BC Gestion du Cycle de Vie du Participant | Notifie les BC du changement d’état d’un participant | | | X | X | | | X | | | | | X | X | X | X | X | | +| ParticipantLiquidityThresholdExceeded | Événement | BC Gestion du Cycle de Vie du Participant | Une notification devrait être envoyée indiquant qu’un seuil de liquidité d’un participant donné est dépassé | | | | | | | | | | X | | | | | | | | +| AddParticipantAccount | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de création de compte pour un participant donné | | X | | | | | | | | | | | | | | | | +| GetPendingParticipantsAccounts | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les participants et comptes qui nécessitent une approbation pour être créés | | X | | | | | | | | | | | | | | | | +| ApproveParticipantAccount | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Demande de création de compte participant | | X | | | | | | | | | | | | | | | | +| CreateParticipantAccountWithLimits | gRPC | BC Gestion du Cycle de Vie du Participant | Crée les comptes pertinents dans le BC Comptes & Soldes | | | | | X | | | | | | | | | | | | | +| ParticipantAccountAdded | Événement | BC Gestion du Cycle de Vie du Participant | Événement pour notifier qu’un compte participant a été créé | | | X | | | | | | | | | | | | | | | +| UpdateAccountStatus | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande d’activation ou de désactivation du compte participant en fonction des informations transmises | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithStatusUpdates | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les comptes en attente d’approbation pour un changement de statut | | X | | | | | | | | | | | | | | | | +| ApproveAccountStatusUpdate | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Changement de statut de compte participant | | X | | | | | | | | | | | | | | | | +| Enabled/DisabledParticipantAccount | gRPC | BC Gestion du Cycle de Vie du Participant | Active ou désactive le compte en fonction des informations transmises | | | | | X | | | | | | | | | | | | | +| ParticipantAccountEnabled | Événement | BC Gestion du Cycle de Vie du Participant | Notifie qu’un compte participant a été activé | | | X | | | | | | | | | | | | | | | +| ParticipantAccountDisabled | Événement | BC Gestion du Cycle de Vie du Participant | Notifie qu’un compte participant a été désactivé | | | X | | | | | | | | | | | | | | | +| UpdateAccountLimit | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de modification des limites d’un compte participant donné | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithLimitUpdates | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les comptes avec des mises à jour de limites en attente | | X | | | | | | | | | | | | | | | | +| ApproveAccountLimitUpdate | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Demande de mise à jour de limite de compte | | X | | | | | | | | | | | | | | | | +| UpdateParticipantAccountLimit | gRPC | BC Gestion du Cycle de Vie du Participant | Met à jour les limites d’un compte participant donné | | | | | X | | | | | | | | | | | | | +| ParticipantAccountLimitUpdated | Événement | BC Gestion du Cycle de Vie du Participant | Événement pour notifier que la limite du compte participant a été créée | | | X | | | | | | | | | | | | | | | +| UpdateAccountThreshold | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de modification du seuil d’un compte participant donné | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithThresholdUpdates | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère tous les comptes avec des mises à jour de seuil en attente | | X | | | | | | | | | | | | | | | | +| ApproveAccountThresholdUpdate | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Mise à jour de seuil de compte participant | | X | | | | | | | | | | | | | | | | +| ParticipantAccountThresholdUpdated | Événement | BC Gestion du Cycle de Vie du Participant | Événement pour notifier que le seuil du compte a été mis à jour | | | X | | | | | | | | | | | | | | | +| UpdateEndpoints | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de mise à jour des endpoints d’un participant donné | | X | | | | | | | | | | | | | | | | +| GetPendingEndpointUpdates | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère toutes les demandes de mise à jour d’endpoint de participant en attente d’approbation | | X | | | | | | | | | | | | | | | | +| ApproveEndpointsUpdate | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Approuve OU Rejette – Mise à jour d’endpoint de participant | | X | | | | | | | | | | | | | | | | +| ParticipantEndpointsUpdated | Événement | BC Gestion du Cycle de Vie du Participant | Événement pour notifier que les endpoints du Participant ont été mis à jour | | | X | X | X | X | X | X | X | | | | | | | | | +| GetParticipantInfo | gRPC | BC Gestion du Cycle de Vie du Participant | Récupère toutes les informations relatives à un participant donné | X | | | | | | X | X | X | | | | | | | | | +| GetParticipantInfo | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Récupère toutes les informations relatives à un participant donné | | X | | | | | | | | | | | | | | | | +| GetLiquidityCoverCurrentState | HTTP/Rest | BC Gestion du Cycle de Vie du Participant | Demande de récupération de l’état actuel de la couverture de liquidité | | X | | | | | | | | | | | | | | | | +| NotifyReport | Événement | BC Notifications & Alertes | Événement de rapport de notification contenant un rapport de la notification, indiquant si elle a réussi (avec une réponse applicable de la destination) ou échoué avec une erreur/raison applicable | | | | x | | | | | | | | | | | | | | +| /log-read-build-log | HTTP/Rest | BC Logging | Consommateur de logs. Fournit un endpoint pour que les applications écrivent dans le topic de log. Construction de logs | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /read-log | HTTP/Rest | BC Logging | Lire les logs. Appelle éventuellement Crypto BC pour déchiffrer et/ou vérifier une signature | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| NotifyRequested | Événement | BC API Interop FSP | Événement de demande de notification contenant la requête de transfert FSPIOP ou le callback qui sera envoyé à un participant spécifique | | | | x | | | | | | | | | | | | | | +| TransferPrepareRequested | Événement | BC API Interop FSP | Événement de demande de préparation de transfert | | | x | | | | | | | | | | | | | | | +| TransferPrepareCallbackReport | Événement | BC API Interop FSP | Rapport de callback Transfer Prepare pour le participant Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommittedRequested | Événement | BC API Interop FSP | Événement de demande de complétion indiquant qu’un « commit » a été traité par le participant Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommittedCallbackReport | Événement | BC API Interop FSP | Rapport de callback Transfer Fulfil pour le participant Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferQueryReceived | Événement | BC API Interop FSP | Événement contenant les informations pour une requête de transfert | | | | x | | | | | | | | | | | | | | +| TransferQueryResponseCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse à une requête de transfert | | | | x | | | | | | | | | | | | | | +| TransferRejectRequested | Événement | BC API Interop FSP | Événement de rejet de transfert émis par le participant bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferRejectRequestProcessedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse de rejet de transfert vers un participant Payeur | | | | x | | | | | | | | | | | | | | +| TransferPrepareRequestTimedoutCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse de délai dépassé de transfert vers un participant Payeur | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommitRequestTimedoutCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse de délai dépassé de transfert vers des participants Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferPrepareDuplicateCheckFailedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse d’échec de vérification de doublon de préparation de transfert vers des participants Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferPrepareLiquidityCheckFailedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse d’échec de vérification de liquidité de préparation de transfert vers des participants Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferPrepareInvalidPayerCheckFailedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse d’échec de vérification du participant Payeur de transfert vers des participants Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| TransferPrepareInvalidPayeeCheckFailedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un callback de réponse d’échec de vérification du participant Bénéficiaire de transfert vers des participants Payeur/Bénéficiaire | | | | x | | | | | | | | | | | | | | +| QuoteRequestReceived | Événement | BC API Interop FSP | Événement contenant une demande de devis d'un participant Payeur | | | | | | | | x | | | | | | | | | | +| QuoteReceivedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour une demande de devis vers un participant Bénéficiaire | | | | | | | | x | | | | | | | | | | +| QuoteResponseReceived | Événement | BC API Interop FSP | Événement contenant une réponse à une demande de devis d’un participant Bénéficiaire | | | | | | | | x | | | | | | | | | | +| QuoteAcceptedCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour une réponse de devis vers un participant Payeur | | | | | | | | x | | | | | | | | | | +| InvalidQuoteRequestCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour une demande de devis invalide vers un participant Payeur | | | | | | | | x | | | | | | | | | | +| InvalidFSPInQuoteRequestCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour un FSP invalide dans une demande de devis vers un participant Payeur | | | | | | | | x | | | | | | | | | | +| RuleViolatedInQuoteRequestCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour une règle violée dans une demande de devis vers un participant Payeur | | | | | | | | x | | | | | | | | | | +| RuleViolatedInQuoteResponseCallbackReport | Événement | BC API Interop FSP | Événement contenant un rapport de réponse de callback pour une règle violée dans une réponse de devis vers un participant Payeur | | | | | | | | x | | | | | | | | | | +| /app-fido-register | HTTP/Rest | BC API Interop FSP | Appelle Crypto BC pour enregistrer un utilisateur | x | x | | | | | | | | | | | | | | | x | +| /audit-log-write | Événement | BC Audit | Écrit des entrées d’audit dans le topic Kafka d’audit. Le consommateur appelle Crypto BC pour chiffrer et/ou signer les enregistrements de log | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /audit-read-build-audit-log | HTTP/Rest | BC Audit | Consommateur d’audit. Fournit un endpoint pour que les applications écrivent dans le topic d’audit. Construction des logs | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /read-audit-log | HTTP/Rest | BC Audit | Lire les logs d’audit. Appelle Crypto BC pour déchiffrer et/ou vérifier la signature | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| QuoteRequestAccepted | Événement | BC Accords/Devis | Événement pour une demande de devis en cours de traitement par le BC Transferts | x | | | | | | | | | | | | | | | | | +| QuoteResponseAccepted | Événement | BC Accords/Devis | Événement pour une réponse de devis en cours de traitement par le BC Transferts | x | | | | | | | | | | | | | | | | | +| InvalidQuoteRequest | Événement | BC Accords/Devis | Événement représentant un échec de validation de devis suite au traitement d’un événement QuoteRequestReceived | x | | | | | | | | | | | | | | | | | +| InvalidFSPInQuoteRequest | Événement | BC Accords/Devis | Événement représentant un échec de FSP invalide dans une demande de devis suite au traitement d’un événement QuoteRequestReceived | x | | | | | | | | | | | | | | | | | +| RuleViolatedInQuoteRequest | Événement | BC Accords/Devis | Événement représentant un échec de règle violée dans une demande de devis suite au traitement d’un événement QuoteRequestReceived | x | | | | | | | | | | | | | | | | | +| RuleViolatedInQuoteResponse | Événement | BC Accords/Devis | Événement représentant un échec de règle violée dans une réponse de devis suite au traitement d’un événement QuoteRequestReceived | x | | | | | | | | | | | | | | | | | +| /app-register | HTTP/Rest | BC Admin/Opérations | Appelle Crypto BC pour obtenir un id et un secret | x | x | | | | | | | | | | | | x | | | x | +| GetLiquidityCoverHistory | HTTP/Rest | BC Admin/Opérations | Demande l’historique de position de compte | | X | | | | | | | | | | | | | | | | +| GetReservations | HTTP/Rest | BC Admin/Opérations | Demande les réservations | | X | | | | | | | | | | | | | | | | +| GetCurrentLiquidityPosition | gRPC | BC Comptes & Soldes | Récupère la position de liquidité actuelle pour la validation de la mise à jour de la réservation de couverture de liquidité | | | X | | | | | | | | | | | | | | | +| RecordLiquidityReservationEntries | gRPC | BC Comptes & Soldes | Enregistre les écritures pertinentes pour les réservations de couverture de liquidité | | | X | | | | | | | | | | | | | | | +| RequestAccountsPositions | gRPC | BC Comptes & Soldes | Récupère les positions de compte pour un participant donné | | | X | | | | | | | | | | | | | | | +| RequestAccountPositionHistory | gRPC | BC Comptes & Soldes | Demande l’historique de position de compte pour un participant donné | | | X | | | | | | | | | | | | | | | +| RequestReservationAccounts | gRPC | BC Comptes & Soldes | Récupère les comptes liés aux réservations | | | X | | | | | | | | | | | | | | | +| ProcessTransferPrepare | gRPC | BC Comptes & Soldes | Traite une demande Transfer Prepare (débite liquidité payeur, crédite la position via réserve de fonds) | | | | x | | | | | | | | | | | | | | +| ProcessTransferFulfil | gRPC | BC Comptes & Soldes | Traite une demande Transfer Fulfil (débite la réserve payeur, crédite la liquidité du bénéficiaire) | | | | x | | | | | | | | | | | | | | +| /log-write | Événement | | Écrit des entrées de log dans Kafka. Consommateur peut faire appel à Crypto BC pour chiffrer et/ou signer les logs | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | diff --git a/docs/fr/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md b/docs/fr/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md new file mode 100644 index 000000000..ebcdd1f16 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md @@ -0,0 +1,19 @@ +# Termes et conventions communs utilisés + +L’équipe de l’Architecture de Référence a utilisé des termes et conventions communs tout au long de la conception et la documentation du modèle d’Architecture de Référence Mojaloop 2.0.

    Veuillez utiliser cette liste pour vous familiariser avec des termes qui pourraient vous sembler inconnus ou oubliés. La liste contient également des références à des articles et documents tiers disponibles dans la section “Pour aller plus loin” de ce document. + +| **Convention/Terme** | **Description** | +| :------------------- | :-------------- | +| **Acteurs** | Participant humain ou système externe à un Cas d’Utilisation. Tous les Cas d’Utilisation sont initiés par des Acteurs. | +| **BC** | Bounded Context : Un Contexte Borné est un composant du Design-Driven Development et contient généralement un ou plusieurs sous-domaines. Les Contextes Bornés sont des entités de l’Espace Solution (Solution Space), et contiennent une solution unique applicable à un ou plusieurs sous-domaines.

    (*Pour plus d’informations, voir : [Vue d’ensemble de l’Architecture inspirée du DDD](../../introduction/#ddd-inspired-architecture-overview) dans l’aperçu de l’Espace Solution, ou notre section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents)*)| +| **UC** | Cas d’Utilisation: Liste d’actions ou d’étapes décrivant les interactions entre un Acteur (humain ou système externe) et un système pour atteindre un objectif particulier. Un exemple dans Mojaloop serait : “Effectuer un transfert avec confirmation du bénéficiaire”.

    (*Pour plus d’informations, voir l’article Wikipédia “Use Case” cité dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **Sync** | Communications synchrones, unidirectionnelles ou bidirectionnelles, faisant partie du processus initial. Représentées par une ligne pleine dans les schémas UC. Utilisées généralement pour les Messages devant impérativement figurer dans le workflow d’un UC pour assurer son exécution correcte. Exemple : une messagerie synchrone du BC Transferts vers le BC Gestion du Cycle de Vie des Participants pour obtenir des données Participant non présentes en cache lors d’une demande de transfert. | +| **Async** | Communications asynchrones, unidirectionnelles ou bidirectionnelles, ne faisant pas partie du processus initial. Signalées par une ligne pointillée dans les schémas UC. Utilisées principalement pour les Événements qui signalent qu’une action a eu lieu : c’est immuable et ne changera pas, comme les rapports de rappel (callback). | +| **POST** | Utilisé pour créer de nouvelles ressources. Plus précisément, pour créer des ressources subordonnées à une autre (ex. ressource “parent”). En d'autres termes (IOW), lors de la création d'une nouvelle ressource, on fait un POST sur le parent, le service l’associe au parent, lui attribue un identifiant (URI de la nouvelle ressource), etc. En cas de succès, le système renvoie un en-tête Location avec le lien de la ressource créée (HTTP 201).

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **GET** | Utilisé pour lire (ou récupérer) la représentation d’une ressource. En cas de succès “normal”, GET retourne une représentation XML ou JSON et le code de réponse HTTP 200 (OK). En cas d’erreur, renvoie généralement un 404 (NOT FOUND) ou un 400 (BAD REQUEST).

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **PUT** | Utilisé pour mettre à jour une ressource connue, en effectuant un PUT sur l'URI d'une ressource connue avec le corps de requête contenant la représentation nouvellement mise à jour de la ressource d'origine. Dans certains cas, PUT peut également servir à créer de nouvelles ressources, mais en raison de la complexité, ce n'est pas recommandé (il faut utiliser POST à la place).

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **200 (OK)** | Code HTTP indiquant “Succès”. La requête a abouti. L’information retournée avec le code de statut dépend généralement de la méthode employée dans la requête : pour POST, la réponse décrit le résultat ; pour GET, la ressource demandée ; pour PUT, une réponse similaire à POST.

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **201 (Created)** | Code HTTP indiquant “Créé” ou “traitée”. La ressource demandée a été créée, consultable via l’URI renvoyée dans la réponse. Si la ressource ne peut être créée immédiatement, le serveur retourne un 202 (Accepted).

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **202 (Accepted)** | Code HTTP indiquant que la requête a été acceptée pour traitement, mais n’est pas terminée. Elle peut ou non être traitée selon l’état du système. L’opération étant asynchrone, il n’y a pas non plus de mécanisme pour renvoyer le code de statut quelle que soit l’issue de l’opération. La réponse 202 est délibérément non-engageante pour permettre à une requête d’être traitée sans exiger que l’agent reste connecté jusqu’à ce qu’elle le soit. La réponse doit donner un état du système, éventuellement un lien vers une plateforme de suivi ou une estimation du moment d’exécution.

    (*Pour plus d’informations, voir la référence “Restful API Tutor” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **OHS** | Open Host Service : Documentation des méthodes à utiliser pour intégrer des systèmes aval à une plateforme amont existante sans nécessiter de modifications. Apporte généralement le support de multiples types de clients, sans se focaliser sur aucun : c’est au système aval de comprendre la documentation publiée par l’amont. OHS et PL sont couramment associés par les plateformes amont.

    Actuellement utilisé dans les entités suivantes : API externe FSPIOP, API externe ISO, Notifications & Alertes BC, API externe PISP ML, API externe PISP ISO, Scheduling BC, Transfers & Transactions BC, Quoting BC, Accounts & Balances BC, Settlements BC, Gestion du Cycle de Vie du Participant, Account Lookup & Discovery BC.

    (*Pour plus d’informations, voir la référence “Strategic Domain-Driven Design” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*)| +| **PL** | Published Language : Proche parent de l’Open Host Service et souvent utilisé conjointement. PL utilise un langage documenté, par exemple XML, pour les opérations d’entrée/sortie de base pour lesquelles il est utilisé. Aucun environnement ou bibliothèque spécifique n’est requis, tant que le langage publié est respecté. Le Published Language n’est pas exclusif aux web services : on peut par exemple déposer un fichier dans un dossier, déclenchant ainsi une opération qui le stocke à un emplacement spécifié par l'application.

    Actuellement utilisé dans les entités suivantes : API externe FSPIOP ; API externe ISO.

    (*Pour plus d’informations, voir la référence “Strategic Domain-Driven Design” dans la section [Pour aller plus loin : Articles et Documents de Référence](../../furtherReading/#reference-articles-and-documents) de ce document*))| diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg new file mode 100644 index 000000000..887629575 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg new file mode 100644 index 000000000..e48567cd4 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg new file mode 100644 index 000000000..a2568a5ac Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg new file mode 100644 index 000000000..061048844 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg new file mode 100644 index 000000000..4bc8cc587 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg new file mode 100644 index 000000000..55fcff12a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg new file mode 100644 index 000000000..4914c1d68 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg new file mode 100644 index 000000000..b5c5b3316 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg new file mode 100644 index 000000000..cfb317673 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg new file mode 100644 index 000000000..5b67c0f66 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg new file mode 100644 index 000000000..d581b8c66 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg new file mode 100644 index 000000000..a9c4f9a77 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg new file mode 100644 index 000000000..3b467d937 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg new file mode 100644 index 000000000..29c57e3e6 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg new file mode 100644 index 000000000..26163264b Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg new file mode 100644 index 000000000..4183a0928 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg new file mode 100644 index 000000000..b53949758 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg new file mode 100644 index 000000000..13a4f7c4a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg new file mode 100644 index 000000000..245172f56 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg new file mode 100644 index 000000000..27f9b5405 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg new file mode 100644 index 000000000..ef3cfc3dc Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg new file mode 100644 index 000000000..a7a8cdabd Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg new file mode 100644 index 000000000..f08f8c2fc Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg new file mode 100644 index 000000000..f21f280b7 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg new file mode 100644 index 000000000..118dbdb1f Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg new file mode 100644 index 000000000..1f88fa39b Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/index.md b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/index.md new file mode 100644 index 000000000..3d6fedcf3 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/fspInteropApi/index.md @@ -0,0 +1,377 @@ +# BC de l'API d'Interopérabilité FSP + +Le Contexte Borné de l'API d'Interopérabilité FSP (FSP Interoperability API Bounded Context) permet l'accès aux opérations internes et aux ressources que l'écosystème Mojaloop met à la disposition d'un Participant donné. Ce Contexte Borné est responsable de fournir à un Participant des interfaces lui permettant d'exécuter des actions sur Mojaloop. Il est également responsable de la communication vers le Participant concernant différentes notifications et messages système que ce dernier doit recevoir. + +## Vue Fonctionnelle + +L'API FSP IOP interagit avec de nombreux autres contextes bornés, une vue simplifiée est donc présentée ici. Pour une lecture approfondie sur les événements, connexions que l'API FSP IOP fournit ou consomme, veuillez consulter les Interfaces Communes Mojaloop [^1]. Les contextes bornés intégrés avec l'API FSP IOP sont : + +- Contexte borné de Recherche et Découverte de Compte [^14] +- Contexte borné des Notifications et Alertes [^27] +- Contexte borné de Gestion du Cycle de Vie du Participant [^26] +- Contexte borné de Devis/Accords [^19] +- Contexte borné des Transferts [^22] +- Contexte borné de Règlement [^21] + +![Cas d'Usage - Vue Fonctionnelle de l'API d'Interopérabilité FSP](./assets/0-0-functional-overview.jpg) + +> Vue Fonctionnelle de l'API d'Interopérabilité FSP + +## Termes + +Termes ayant une signification spécifique et reconnue dans le contexte borné où ils sont utilisés. + +| Terme | Description | +| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **(D)FSP** | Fournisseur de Services Financiers (Digitaux) | +| **Participant** | Fournisseur de Services Financiers (FSP) enregistré dans l'écosystème Mojaloop, pouvant ainsi effectuer des transactions avec d'autres Participants | +| **FSP IOP API** | Interface API d'Interopérabilité des FSP, qui donne accès aux fonctions de l'écosystème Mojaloop | +| **Payer** | Le payeur des fonds électroniques dans une transaction de paiement | +| **Payer FSP** | Fournisseur de Services Financiers du payeur | +| **Payee** | Le destinataire des fonds électroniques dans une transaction de paiement | +| **Payee FSP** | Fournisseur de Services Financiers du bénéficiaire | + +## Cas d'Utilisation + +### Remarque + +Les définitions des cas d'utilisation stipulées dans la Spécification Open API pour FSP Interoperability [^2] n'ont pas été modifiées. L'Architecture de Référence a été conçue pour ne changer que l'orchestration interne des services Mojaloop et des Contextes Bornés. + +### BC Notifications - Envoi de Notification + +#### Description + +Les notifications concernent TOUS les cas d'utilisation ci-dessous en réponse à des demandes reçues sous différentes formes. Pendant que l'API FSP IOP traite une demande, elle peut devoir envoyer une requête au DFSP demandeur ou à d'autres DFSP concernés. L'API FSP IOP interrogera alors le Contexte Borné de Gestion du Cycle de Vie du Participant [^26] pour obtenir l'URI de rappel (callback) du participant destinataire. L'API FSP IOP enverra ensuite la notification au Contexte Borné Notifications et Alertes [^27]. + +#### Schéma de Flux + +![Cas d'Usage - BC Notifications - Envoi de Notification](./assets/0-0-0-notifications.jpg) + +> + +## BC Recherche et Découverte de Compte + +### Association d'une Partie/Participant + +#### Description + +Associer un ou plusieurs Participants et/ou parties à la requête POST Participant [^5] (POST /participants/{Type}/{ID}). L'API FSP IOP envoie la requête au BC de Recherche et Découverte de Compte [^14] qui la traite et répond par un évènement de succès. L'API FSP IOP envoie ensuite une réponse de notification PUT Participant [^15] (PUT /participants/{Type}/{ID}). + +#### Schéma de Flux + +![Cas d'Usage - BC Recherche et Découverte de Compte - Association d'une Partie/Participant](./assets/0-1-party-participant-associate.jpg) + +> + +### Dissociation d'une Partie/Participant + +#### Description + +Dissocier un ou plusieurs Participants ou parties à l'aide de la requête DELETE Participant [^6] (DELETE /participants/{Type}/{ID}). L'API FSP IOP envoie la requête au BC de Recherche et Découverte de Compte [^14] pour dissocier la partie. Le succès est renvoyé à l'API FSP IOP qui notifie l'appelant avec une réponse de notification PUT Participant [^15] (PUT /participants/{Type}/{ID}). + +#### Schéma de Flux + +![Cas d'Usage - BC Recherche et Découverte de Compte - Dissociation d'une Partie/Participant](./assets/0-2-party-participant-disassociate.jpg) + +> + +### Obtenir un Participant + +#### Description + +Récupérer les informations d'un participant grâce à la requête GET Participant [^7] (GET /participants/{Type}/{ID}) qui envoie l'ID et la structure. L'API FSP IOP envoie la requête au BC de Recherche et Découverte de Compte [^14] pour vérifier si le participant existe. L'API FSP IOP répond alors au demandeur avec une réponse PUT Participant [^15] (PUT /participants/{Type}/{ID}). + +#### Schéma de Flux + +![Cas d'Usage - BC Recherche et Découverte de Compte - Obtenir un Participant](./assets/0-3-get-participant.jpg) + +> + +### Obtenir une Partie + +#### Description + +Récupérer les informations d'une partie via l'ID avec la requête GET Party [^8] (GET /parties/{Type}/{ID}). L'API FSP IOP envoie une requête au BC de Recherche et Découverte de Compte [^14] pour déterminer le FSP cible pour le transfert de la requête GET. Le FSP cible répond avec une requête PUT parties. L'information est ensuite envoyée au BC pour être mise en cache avant que la réponse PUT Party [^17] (PUT /parties/{Type}/{ID}) ne soit renvoyée à l'émetteur de la requête GET. + +#### Schéma de Flux + +![Cas d'Usage - BC Recherche et Découverte de Compte - Obtenir une Partie](./assets/0-4-get-party.jpg) + +> + +## BC Devis (Quoting) + +### Calculer un Devis - Parcours Nominal + +#### Description + +Lorsqu'un devis est envoyé via un POST Quote [^3] (POST /quotes), l'API FSP IOP transmet la demande au BC Quoting/Agreement [^19] pour validation. L'API FSP IOP transmet ensuite le POST Quote au FSP bénéficiaire, qui répond à son tour avec une réponse PUT Quote [^18] (PUT /quotes/{ID}) avec les informations mises à jour. L'API FSP IOP envoie le devis accepté au BC Quoting/Agreement [^19] pour l'enregistrement, puis envoie la requête PUT quote au FSP payeur et considère le devis réussi. + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Calculer un Devis - Parcours Nominal](./assets/1-1-calculate-quote-happy-path.jpg) + +> + +### Obtenir un Devis - Parcours Nominal + +#### Description + +Permet à un FSP de récupérer les détails d'un devis existant. La requête GET Quote [^4] (GET /quotes/{ID}) est envoyée à l'API FSP IOP qui interroge le BC Quoting/Agreement [^19] pour les devis existants. Une fois le devis récupéré, les informations sont renvoyées au FSP demandeur via une réponse PUT Quote [^18] (PUT /quotes/{ID}). + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Obtenir un Devis - Parcours Nominal](./assets/1-2-get-quote-happy-path.jpg) + +> + +### Calculer un Devis - Demande de Devis Invalide + +#### Description + +Lorsqu'une requête POST Quote [^3] (POST /quotes) est reçue, l'API FSP IOP l'envoie au BC Quoting/Agreement [^19] pour traitement. Si le devis échoue à la validation, le BC Quoting/Agreement retourne une erreur, notifiée au FSP demandeur via PUT Quote Error [^20] (PUT /quotes/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Calculer un Devis - Demande de Devis Invalide](./assets/1-3-calculate-quote-invalid-quote-request.jpg) + +> + +### Calculer un Devis - Participants FSP Invalides + +#### Description + +Si une requête POST Quote [^3] (POST /quotes) est envoyée et que le BC Quoting/Agreement [^19] ne peut valider les deux FSP, une réponse d'erreur est envoyée à l'API FSP IOP qui la notifie au FSP demandeur via PUT Quote Error [^20] (PUT /quotes/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Calculer un Devis - Participants FSP Invalides](./assets/1-4-calculate-quote-invalid-fsps.jpg) + +> + +### Calculer un Devis - Règles de Schéma Invalides détectées dans la Requête + +#### Description + +Quand le FSP Payeur envoie une requête POST Quote [^3] (POST /quotes), l'API FSP IOP l'envoie au BC Quoting/Agreement [^19]. Si le devis n'est pas conforme aux règles du système, une erreur est renvoyée à l'API FSP IOP qui la notifie au FSP Payeur via PUT Quote Error [^20] (PUT /quotes/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Calculer un Devis - Règles de Schéma Invalides détectées dans la Requête](./assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg) + +> + +### Calculer un Devis - Règles de Schéma Invalides détectées dans la Réponse + +#### Description + +Lorsque le FSP Payeur envoie une requête POST Quote [^3] (POST /quotes), l'API FSP IOP l'envoie au BC Quoting/Agreement [^19]. Si la réponse du FSP bénéficiaire (PUT Quote [^18]) échoue aux validations de schéma, une erreur est envoyée à l'API FSP IOP, qui notifie les deux FSP via PUT Quote Error [^20] (PUT /quotes/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - BC Devis - Calculer un Devis - Règles de Schéma Invalides détectées dans la Réponse](./assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg) + +> BC Devis - Calculer un Devis - Règles de Schéma Invalides détectées dans la Réponse + +## BC des Transferts + +### Réaliser un Transfert (Mode Universel) + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci envoie ensuite un évènement au BC des Règlements [^21]. L'API FSP IOP attend un évènement du BC des Transferts [^22] signalant que le transfert a été préparé, pour envoyer une requête POST au FSP Bénéficiaire. Celui-ci répond avec une requête PUT Transfers [^23] (PUT /transfers/{ID}) (transferState = committed) à l'API FSP IOP qui finalise l'exécution du transfert. Le PUT transfer est ensuite envoyé au FSP Payer. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert (Mode Universel)](./assets/2-1-perform-transfer-universal-mode.jpg) + +> + +### Réaliser un Transfert avec Confirmation du Bénéficiaire + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci envoie un évènement au BC des Règlements [^21]. L'API FSP IOP attend l'évènement du BC des Transferts [^22], puis émet un POST vers le FSP Bénéficiaire. Celui-ci répond avec un PUT Transfers [^23] (PUT /transfers/{ID}) (transferState = reserved). Le PUT transfer est ensuite envoyé au FSP Payer. Le FSP Bénéficiaire reçoit alors un PATCH Transfers [^24] (PATCH /transfers/{ID}) pour notifier le changement d'état. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert avec Confirmation du Bénéficiaire](./assets/2-2-perform-transfer-payee-confirmation.jpg) + +> + +### Requête Get Transfer + +#### Description + +Obtention des infos sur un transfert selon l'ID utilisé dans GET Transfer [^11] (GET /transfers/{ID}), puis réception du PUT Transfers [^23] (PUT /transfers/{ID}) pour obtenir les informations pertinentes. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Requête Get Transfer](./assets/2-3-query-get-transfer.jpg) + +> + +### Réaliser un Transfert - Post Doublon (Nouvel Envoi) + +#### Description + +Une requête POST Transfers [^9] (POST /transfers) a déjà été traitée, un rapport de statut est retourné au FSP Payeur via PUT Transfers [^23] (PUT /transfers/{ID}). + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - Post Doublon (Nouvel Envoi)](./assets/2-4-perform-transfer-duplicate-post.jpg) + +> BC Transferts - Réaliser un Transfert - Post Doublon (Nouvel Envoi) + +### Réaliser un Transfert - Post Doublon (Ignoré) + +#### Description + +Une requête POST Transfers [^9] (POST /transfers) a déjà été traitée mais aucune réponse n'est nécessaire ou attendue. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - Post Doublon (Ignoré)](./assets/2-5-perform-transfer-duplicate-post-ignor.jpg) + +> + +### Réaliser un Transfert - DFSP Bénéficiaire Rejette le Transfert + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci prépare le transfert puis envoie la requête POST au FSP Bénéficiaire. Celui-ci rejette le transfert via une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error). L'API FSP IOP notifie alors le BC des Transferts [^22] que le transfert est rejeté et envoie une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error) au FSP Payeur. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - DFSP Bénéficiaire Rejette le Transfert](./assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg) + +> + +### Réaliser un Transfert - Timeout (Préparation) + +#### Description + +Une requête POST Transfers [^9] (POST /transfers) est rejetée car le transfert expire [^13] lors de la préparation des fonds. L'API FSP IOP envoie une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error) au FSP Payeur pour signaler l'erreur. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - Timeout (Préparation)](./assets/2-7-perform-transfer-timeout-prepare.jpg) + +> + +### Réaliser un Transfert - Timeout (Pré-Engagé) + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP, qui envoie un évènement au BC des Règlements [^21]. L'API FSP IOP attend un évènement du BC des Transferts [^22] indiquant la préparation du transfert avant de le transmettre au FSP Bénéficiaire. Celui-ci répond avec PUT Transfers [^23] (PUT /transfers/{ID}) (transferState = committed). Si le transfert expire [^13] pendant/avant l'engagement des fonds, les deux FSP sont alors notifiés de l'échec via PUT Transfer Error [^25] (PUT /transfers/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - Timeout (Pré-Engagé)](./assets/2-8-perform-transfer-timeout-pre-committed.jpg) + +> + +### Réaliser un Transfert - Timeout (Post-Engagé) + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci envoie un évènement au BC des Règlements [^21]. L'API FSP IOP attend la préparation depuis le BC des Transferts [^22], puis transmet le POST au FSP Bénéficiaire qui répond par PUT Transfers [^23] (disant que le transfert est engagé – transferState = committed). Après validation, le transfert expire ; le transfert est alors considéré rejeté. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Réaliser un Transfert - Timeout (Post-Engagé)](./assets/2-9-perform-transfer-timeout-post-commit.jpg) + +> + +### Réaliser un Transfert - Post Doublon (Aucun correspondant) + +#### Description + +Une requête POST Transfers [^9] (POST /transfers) déjà traitée ; un rapport d'état est retourné au FSP Payeur via une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error). + +#### Schéma de Flux + +![Cas d'Usage - Ex. À REMPLACER](./assets/2-10-perform-transfer-duplicate-none-matching.jpg) + +> + +### Réaliser un Transfert - Liquidité Insuffisante du FSP Payeur + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci émet un évènement au BC des Règlements [^21]. Après avoir reçu l'indication de préparation depuis le BC des Transferts [^22], un échec de contrôle de liquidité est détecté pour le FSP Payeur. L'API FSP IOP envoie alors une requête PUT Transfer Error [^25] au FSP Payeur. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Liquidité Insuffisante du FSP Payeur](./assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg) + +> + +### Réaliser un Transfert - Préparation Rejetée + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Celle-ci prépare le transfert puis envoie le POST au FSP Bénéficiaire. Celui-ci décline le transfert avec une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error). L'API FSP IOP notifie alors le BC Transferts [^22] que le transfert a été rejeté et envoie une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error) au FSP Payeur. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Préparation Rejetée](./assets/2-12-perform-transfer-prepare-rejected.jpg) + +> + +### Réaliser un Transfert - Échec de Validation à la Préparation (Participant Payeur Invalide) + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Le BC Transferts [^22] signale à l'API FSP IOP que le FSP Payeur est invalide. Selon le motif pour lequel le FSP Payer est invalide, l'API FSP IOP enverra une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error) au FSP Payeur. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Échec de Validation à la Préparation (Participant Payeur Invalide)](./assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg) + +> + +### Réaliser un Transfert - Échec de Validation à la Préparation (Participant Bénéficiaire Invalide) + +#### Description + +Le FSP Payeur envoie une requête POST Transfers [^9] (POST /transfers) à l'API FSP IOP. Le BC Transferts [^22] signale à l'API FSP IOP que le FSP Bénéficiaire est invalide. L'API FSP IOP enverra une requête PUT Transfer Error [^25] (PUT /transfers/{ID}/error) au FSP Payeur pour l'informer de l'échec. + +#### Schéma de Flux + +![Cas d'Usage - BC Transferts - Échec de Validation à la Préparation (Participant Bénéficiaire Invalide)](./assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg) + +> + +## Notes + +### Validation de la structure sur les événements internes + +De nombreux cas d'utilisation stipulent que la structure et la sémantique de la requête doivent être validées lors de la réception d'un événement provenant d'un contexte borné interne. Cela ne se produit pas à chaque requête, mais est une exigence à respecter lors de la construction de l'architecture de référence. Cela signifie qu'en interne, tous les événements et ressources disponibles doivent être standardisés et vérifiés. + +[^1]: [Liste des Interfaces Communes Mojaloop](../../commonInterfaces.md) +[^2]: [Documentation Open API pour la Spécification d'Interopérabilité FSP](https://docs.mojaloop.io/mojaloop-specification/) +[^3]: [Post Quote - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6532-post-quotes) +[^4]: [Get Quote - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6531-get-quotesid) +[^5]: [Post Participant - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6233-post-participantstypeid) +[^6]: [Delete Participant - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6234-delete-participantstypeid) +[^7]: [Get Participant - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6231-get-participantstypeid) +[^8]: [Get Parties - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6331-get-partiestypeid) +[^9]: [Post Transfers - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6732-post-transfers) +[^10]: [Commit Notification - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6726-commit-notification) +[^11]: [Get Transfers - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6731-get-transfersid) +[^12]: [Transaction Irrevocability - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.#6722-transaction-irrevocability) +[^13]: [Transfers Timeout and Expiry - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6724-timeout-and-expiry) +[^14]: [Contexte borné de Recherche et Découverte de Compte](../accountLookupAndDiscovery/index.md) +[^15]: [Put Participant - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6242-put-participantsid) +[^17]: [Put Party- Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6341-put-partiestypeid) +[^18]: [Put Quote - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6541-put-quotesid) +[^19]: [Contexte borné Devis/Accord](../quotingAgreement/index.md) +[^20]: [Put Quote Error - Définition](https://docs.mojmojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6551-put-quotesiderror) +[^21]: [Contexte borné Règlements](../settlements/index.md) +[^22]: [Contexte borné Transferts](../transfers/index.md) +[^23]: [Put Transfers - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6741-put-transfersid) +[^24]: [Patch Transfers - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6733-patch-transfersid) +[^25]: [Put Transfers Error - Définition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6751-put-transfersiderror) +[^26]: [Contexte borné Gestion du Cycle de Vie du Participant](../participantLifecycleManagement/index.md) +[^27]: [Contexte borné Notifications et Alertes](../notificationsAndAlerts/index.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/index.md b/docs/fr/technical/reference-architecture/boundedContexts/index.md new file mode 100644 index 000000000..f2adb3565 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/index.md @@ -0,0 +1,23 @@ +# Contexte Borné + +Dans cette section, nous examinons en détail chacun des Contextes Bornés identifiés, en indiquant leur objectif (description), les sous-domaines couverts, les cas d’utilisation que chaque Contexte Borné traite, ainsi que des remarques de conclusion le cas échéant. + + \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png b/docs/fr/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png new file mode 100644 index 000000000..577e56490 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/logging/index.md b/docs/fr/technical/reference-architecture/boundedContexts/logging/index.md new file mode 100644 index 000000000..b51a7e4e1 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/logging/index.md @@ -0,0 +1,20 @@ +# BC Journalisation (Logging) + +Le Contexte Borné Logging (Logging BC) est utilisé pour stocker des informations techniques afin de faciliter le débogage, la recherche de pannes et la résolution des problèmes. Les journaux (logs) sont récupérés depuis n'importe quel autre Contexte Borné [^1] et stockés afin de pouvoir être interrogés ou utilisés pour des rapports. Les informations de journalisation sont considérées comme des « données techniques » ; toute éventuelle perte de ces informations ne devrait avoir pour conséquence que la perte de capacité technique à comprendre le comportement du système. Toutes les activités système sont journalisées et conservées, afin de permettre au Contexte Borné d’Audit [^2] d’effectuer des requêtes sur ces données de log. + +Les Contextes Bornés doivent publier les événements dans un format défini et en utilisant le mécanisme disponible fourni par le BC Journalisation. La structure inclut implicitement une couche d’abstraction appliquée à l’événement reçu par le BC Journalisation, qui est alors utilisée pour persister les données de log. + +## Cas d’Utilisation + +### Journalisation Basée sur les Événements + +#### Diagramme de flux + +![Cas d’Utilisation – Journalisation Basée sur les Événements](./assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png) +>Diagramme de Workflow UC : Journalisation basée sur les événements + + +## Notes + +[^1] : [Liste des Interfaces Communes Mojaloop](../../refarch/commonInterfaces.md) +[^2] : [Contexte Borné d'Audit (Auditing BC)](../auditing/index.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png new file mode 100644 index 000000000..607842c5a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png new file mode 100644 index 000000000..754ec79dc Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png new file mode 100644 index 000000000..b858925b7 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png new file mode 100644 index 000000000..b188e7f71 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md new file mode 100644 index 000000000..fc1fbeb59 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md @@ -0,0 +1,62 @@ +# BC Notifications et Alertes + +Le BC Notifications et Alertes agit comme le moteur de notification de la plateforme Mojaloop. Il fournit des capacités complémentaires pour les callbacks FSPIOP fiables en veillant à ce que des rapports de livraison soient disponibles, à des fins d’actions de compensation et d’audit. De même, ces capacités peuvent être utilisées pour envoyer des alertes de manière fiable à des sous-systèmes internes ou à des consommateurs externes. + +La fiabilité est assurée par plusieurs mécanismes : + +- Chaque commande de Notification contient : + - toutes les informations nécessaires (en-têtes, payload, transport, etc.) requises par le BC pour effectuer la livraison + - une configuration de nouvelle tentative et de livraison précisant comment le BC Notifications doit gérer les échecs de livraison +- Les rapports de Notification ou d’Alerte sont conservés et peuvent être interrogés. + +## Termes + +Termes ayant une signification spécifique et communément admise dans le Contexte Borné où ils sont utilisés. + +| Terme | Description | +|---|---| +| **Notification** | Notification sortante envoyée par le BC Notifications et Alertes, généralement vers une destination externe, contenant des en-têtes contextuels et des payloads. Un exemple en est les callbacks FSPIOP dans le cadre de la spécification d’API Mojaloop. | +| **Alerte** | Similaire à une notification, mais une alerte sert généralement à informer des sous-systèmes internes (c.-à-d. d’autres BC) ou un opérateur de hub d’un « événement canonique » observé. Un exemple serait qu'un FSP a dépassé sa liquidité disponible. | +| **Rapport de Livraison** | Rapport produit par le BC Notifications et Alertes contenant des informations de livraison relatives à une Notification ou une Alerte spécifique, telles que le statut de livraison, la réponse reçue par la destination, le nombre de tentatives, ainsi que les informations sur les échecs. Ce rapport peut être généré sous la forme d’un événement du domaine, et/ou une réponse synchrone à une requête API. | +| **Événement Canonique** | Désigne tout événement de domaine produit par un Contexte Borné. | + +## Cas d'Utilisation + +### Envoi de notifications asynchrones avec rapport de livraison + +#### Diagramme de flux + +![Cas d’utilisation - Envoi de notifications asynchrones avec rapport de livraison](./assets/sendAsyncNotificationWithDeliveryReport.png) + +### Envoi de notifications synchrones avec rapport de livraison + +#### Diagramme de flux + +![Cas d’utilisation - Envoi de notifications synchrones avec rapport de livraison](./assets/sendSyncNotificationWithDeliveryReport.png) + + + +### Enregistrement d’alerte + +#### Description + +Les opérateurs du hub ou les sous-systèmes pourront appeler l’API d’enregistrement d’alerte pour s’abonner à des alertes de notification spécifiques. L’opération AlertRegister inclura : + +- Message/Événement de domaine à surveiller +- Informations d'endpoint / de transport pour la livraison de la notification +- Modèle pour l’alerte de notification qui sera utilisé pour générer la notification réelle + +#### Diagramme de flux + +![Cas d’utilisation - Envoi de notifications synchrones avec rapport de livraison](./assets/alertRegistration.png) + +### Notifications d’alerte + +#### Diagramme de flux + +![Cas d’utilisation - Envoi de notifications synchrones avec rapport de livraison](./assets/alertNotification.png) + + + diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png new file mode 100644 index 000000000..c16848a1b Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..adbfe0d98 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..ec745aaa8 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..b4abeaf4f Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..177241a98 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png new file mode 100644 index 000000000..eea3ac385 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png new file mode 100644 index 000000000..bc50ae969 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..109050536 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..bd4f49e56 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png new file mode 100644 index 000000000..3bcd8009c Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png new file mode 100644 index 000000000..d3b2129d3 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png new file mode 100644 index 000000000..a833e5ae6 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..4d429dc37 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..fcde920b2 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..26d13ab31 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..b9e206363 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..54033e161 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..be01060f0 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md new file mode 100644 index 000000000..9213093b5 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md @@ -0,0 +1,192 @@ +# BC Gestion du Cycle de Vie des Participants + +Le Contexte Borné Gestion du Cycle de Vie des Participants (Participant Lifecycle Management) traite de tout ce qui concerne la gestion d’un Participant dans l’environnement Mojaloop. Lorsqu’on définit ce Contexte Borné, certains concepts clés doivent être identifiés clairement. + +#### Processus Maker-Checker +Le processus Maker-Checker établit une vérification à 6 yeux, garantissant qu'aucune action d'écriture n'a lieu sans être validée par une personne disposant des autorisations adéquates. Ces autorisations sont définies par le Contexte Borné Gestion du Cycle de Vie des Participants, mais elles restent configurables et attribuables selon les règles du système. Il est recommandé que les utilisateurs/rôles titulaires des droits de "Maker" ne reçoivent pas ceux de "Checker", et que les droits de "Checker" soient attribués à des personnes différentes. Il reste possible d'attribuer les deux responsabilités au même utilisateur/rôle, mais cela annule alors la sécurité prévue par la séparation des rôles qui est au cœur du processus maker-checker. + +#### États du Participant +La gestion des états du participant permet aux opérateurs administrateurs de contrôler les permissions d’un participant donné selon son état. Lors de la phase de configuration de la plateforme, le Contexte Borné attend que les états soient définis et configurés avec des rôles et/ou permissions. Un état peut ensuite être attribué à un participant via le processus de gestion du statut du participant. + +## Termes + +Termes ayant une signification précise et communément acceptée dans le Contexte Borné où ils sont utilisés. + +| Terme | Description | +| ------------- | ------------ | +| **Participant** | Fournisseur de Services Financiers (FSP) qui s’inscrit sur l’écosystème Mojaloop et peut ainsi effectuer des transactions avec d’autres Participants. | +| **Maker** | Représentant responsable de la création de structures de données via l’envoi de requêtes. | +| **Checker** | Représentant responsable de l’approbation et de l’acceptation des données ayant été demandées pour création. | + +## Vue Fonctionnelle + +Veuillez consulter la page des interfaces communes pour comprendre comment ces interactions ont lieu. [^1] + +![Cas d’Utilisation - Exemple À REMPLACER](./assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png) +>Diagramme de workflow BC : Vue Fonctionnelle + +## Cas d’Utilisation + +### Création de Participant (Inscription en une seule étape) + +#### Description + +Ce flux permet au BC d’employer un processus afin de créer un Participant dans l’écosystème Mojaloop — cela nécessite généralement toutes les informations relatives au participant ainsi qu’aux comptes initiaux nécessaires. + +#### Diagramme de flux + +![Cas d’Utilisation - Création de Participant Initiale](./assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Création de Participant - Approbation](./assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png) +>Workflow UC : Création de Participant + +### Gestion des Fonds + +#### Description + +Ce flux permet au BC de mettre en œuvre un processus pour permettre les retraits ou dépôts de fonds sur le(s) compte(s) du Participant. + +#### Diagramme de flux + +![Cas d’Utilisation - Gestion des Fonds - Initial](./assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Gestion des Fonds - Approbation](./assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png) +>Workflow UC : Gestion des Fonds + +### Mise à Jour des Points de Terminaison + +#### Description + +Ce flux permet au BC de mettre à jour l’endpoint (adresse réseau) d’un participant donné. Une fois la demande approuvée, l’endpoint sera contacté (chemin keep-alive) pour garantir la connectivité. + +#### Diagramme de flux + +![Cas d’Utilisation - Mise à jour de l’Endpoint - Initial](./assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Mise à jour de l’Endpoint - Approbation](./assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png) +>Workflow UC : Mise à jour des Endpoints + +### Mise à Jour du Statut du Participant + +#### Description + +Ce flux permet au BC de mettre en place un processus par lequel on change le statut d’un participant pour lui appliquer de nouveaux rôles ou règles de schéma. + +#### Diagramme de flux + +![Cas d’Utilisation - Mise à Jour du Statut - Initial](./assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Mise à Jour du Statut - Approbation](./assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png) +>Workflow UC : Mise à jour du statut du Participant + +### Consultation d’un Participant + +#### Description + +Ce flux permet au BC de mettre en œuvre un processus pour obtenir des informations concernant un participant donné. + +#### Diagramme de flux + +![Cas d’Utilisation - Consultation de Participant](./assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png) +>Workflow UC : Consultation de Participant + +### Ajout de Comptes Participant + +#### Description + +Ce flux permet au BC de contrôler divers aspects des comptes d’un Participant, notamment : création, activation/désactivation, mise à jour des plafonds et seuils d’alerte d’un compte. + +- Ajouter un Compte Participant +- Mettre à Jour le Statut d’un Compte Participant (Activation/Désactivation) +- Mettre à Jour les Limites de Liquidité et Seuils d’Alerte + +#### Diagramme de flux + + + +![Cas d’Utilisation - Ajout de Compte Participant - Initial](./assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Ajout de Compte Participant - Approbation](./assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png) +>Workflow UC : Ajout de Comptes Participants + +### Réserve de Couverture de Liquidité + +#### Description + +Ce flux permet au BC de réserver une couverture de liquidité pour un Participant et de notifier le BC Comptes et Soldes de la mise à jour. + +#### Diagramme de flux + +![Cas d’Utilisation - Réserve de Couverture de Liquidité - Initial](./assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png) +![Cas d’Utilisation - Réserve de Couverture de Liquidité - Approbation](./assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png) +>Workflow UC : Réserve de Couverture de Liquidité + +### Dépassement du Seuil de Liquidité + +#### Description + +Ce flux permet au BC de notifier le participant lorsqu’un seuil de liquidité prédéfini est atteint et qu’une action peut être requise. + +#### Diagramme de flux + +![Cas d’Utilisation - Dépassement de Seuil de Liquidité](./assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png) +>Workflow UC : Dépassement du Seuil de Liquidité + +### Dépassement de la Limite de Liquidité + +#### Description + +Ce flux permet au BC de notifier le participant lorsqu’il atteint la limite de liquidité prédéfinie pour un compte. + +#### Diagramme de flux + +![Cas d’Utilisation - Dépassement de Limite de Liquidité](./assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png) +>Workflow UC : Dépassement de la Limite de Liquidité + +### Réinitialisation des Seuils et Limites de Liquidité + +#### Description + +Ce flux permet au BC de réinitialiser les vérifications de notification de limite ou seuil de liquidité lorsque des transferts réussis ont été exécutés et que la position du compte du participant est devenue positive. + +#### Diagramme de flux + +![Cas d’Utilisation - Réinitialisation des Seuils/Limites de Liquidité](./assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png) +>Workflow UC : Réinitialisation des Seuils et Limites de Liquidité + +### Requête de Couverture de Liquidité + +#### Description + +Ce flux permet au BC d’interroger la liquidité courante d’un compte participant, ainsi que d’effectuer d’autres opérations de lecture associées à la liquidité du participant. + +#### Diagramme de flux + + + +![Cas d’Utilisation - Requête de Couverture de Liquidité](./assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png) +>Workflow UC : Requêtes de Couverture de Liquidité + +## Modèle Canonique + +- Participant + - id + - participantAlias + - endpointURL + - state + - Accounts[] + - accountID + - ledgerAccountType + - accountCurrency + - isActive + - warningThreshold + - limit + - type + - value + +## Commentaires de Conclusion + +**Comptes Participants :** Les Participants ne peuvent avoir qu’un seul compte par devise autorisée. +**Cas d'Utilisation - Update Position :** A été remplacé par le cas d’utilisation Gestion des Fonds. +**Opérations Maker/Checker :** Le nombre de tentatives de reprise (retry) n’a aucun effet. + + + +## Notes + +[^1]: Interfaces communes : [Liste des interfaces communes Mojaloop](../../boundedContexts/commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png b/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png new file mode 100644 index 000000000..fd9ae7373 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/index.md b/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/index.md new file mode 100644 index 000000000..1fa059c56 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/platformMonitoring/index.md @@ -0,0 +1,23 @@ +# {name} BC + +{overview} + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|---|---| +| Term1 | Description1 | + +## Use Cases + +### Perform Transfer (universal mode) + +![Use Case - Example REPLACE ME](./assets/useCaseExample.png) +> example image - replace + + +## Notes + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png new file mode 100644 index 000000000..ce5c78a4d Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png new file mode 100644 index 000000000..80bbd8d7a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png new file mode 100644 index 000000000..5cb2262e8 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png new file mode 100644 index 000000000..b98cbc26e Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png new file mode 100644 index 000000000..a023e3df6 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png new file mode 100644 index 000000000..72ac92834 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png new file mode 100644 index 000000000..5c67aa42b Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png new file mode 100644 index 000000000..f4386a449 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/index.md b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/index.md new file mode 100644 index 000000000..04490ddcb --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/quotingAgreement/index.md @@ -0,0 +1,120 @@ +# BC Devis/Accords + +Le Contexte Borné de Devis et Accords fournit aux Participants des devis pour effectuer des transferts, et enregistre les réponses d’acceptation ou de rejet des participants. + +## Termes + +Les termes suivants sont utilisés dans ce BC, également appelé domaine. + +| Terme | Description | +|---|---| +| **(D)FSP** | Fournisseur de Services Financiers (Digital) | +| **Participant** | Fournisseur de Services Financiers | + +## Vue Fonctionnelle + +![Cas d’Utilisation - Vue Fonctionnelle](./assets/qtaFunctionalOverview_20210825.png) + +## Cas d’Utilisation + +### Calculer le Devis - Parcours Nominal + +#### Description + +Ce processus collecte une série de données pertinentes sur le Participant, y compris les indicateurs de statut, calcule le coût du transfert (y compris les frais), et le fournit au(x) Participant(s). Il est également capable d’enregistrer les demandes & réponses des Participants (par exemple, acceptation ou rejet du devis). + +#### Diagramme de flux + +![Cas d’Utilisation - Calcul du Devis - Parcours Nominal](./assets/qtaCalculateQuoteHappyPath_20210825.png) + +### Obtenir un Devis - Parcours Nominal + +#### Description + +Processus pour obtenir et délivrer les détails d’un devis existant au(x) Participant(s) sur demande. + +#### Diagramme de flux + +![Cas d’Utilisation - Exemple À REMPLACER](./assets/qtaGetQuoteHappyPath.png) + +### Calculer le Devis - Demande de Devis Invalide + +#### Description + +Processus permettant au système d’invalider des demandes de devis en surveillant et répondant à des événements de demande invalides, FSP invalides, ou demandes dupliquées. + +#### Diagramme de flux + +![Cas d’Utilisation - Calcul du Devis - Demande de Devis Invalide](./assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png) + +### Calculer le Devis - FSP Invalides + +#### Description + +Processus permettant au système d’invalider des demandes de devis FSP lorsque les détails du FSP ne correspondent pas au devis d’origine pour un ou les deux Participants. + +#### Diagramme de flux + +![Cas d’Utilisation - Calcul du Devis - FSP Invalides](./assets/qtaCalculateQuoteInvalidFSPs_20210825.png) + +### Calculer le Devis - Règles du Schéma Invalides Détectées dans la Demande + +#### Description + +Processus permettant au système d’invalider une demande de devis lorsqu’une ou plusieurs règles du schéma (Scheme Rules) sont violées par un ou plusieurs participants, par exemple lorsque la limite de période du devis est atteinte. + +#### Diagramme de flux + +![Cas d’Utilisation - Calcul du Devis - Règles du Schéma Invalides dans la Demande](./assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png) + +### Calculer le Devis - Règles du Schéma Invalides Détectées dans la Réponse + +#### Description + +Processus permettant au système d’invalider les réponses de devis dans le cas où des règles du schéma (Scheme Rules) sont violées par un ou plusieurs participants, par exemple lorsque des conditions invalides sont détectées. + +#### Diagramme de flux + +![Cas d’Utilisation - Calcul du Devis - Règles du Schéma Invalides dans la Réponse](./assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png) + +## Modèle Canonique de Devis + +Le modèle canonique stocke les informations suivantes des devis dans le BC Cotations & Accords : + +- Identifiant du devis +- Identifiant de la transaction +- Participants + - payerId + - payeeId +- Payer + - Participant + - participantId + - roleType (ex. payer) + - Montant demandé (montant initial) + - value (nombre) + - currency (code de devise ISO) + - Montant à envoyer (incluant frais, etc.) + - value (nombre) + - currency (code de devise ISO) +- Payee(s) (un ou plusieurs : tous doivent être ajoutés au « Montant à envoyer ») + - '#' + - Participant + - participantId + - roleType (identifier pourquoi ce « payee » reçoit ce montant, ex : frais, destinataire, etc.) + - motif (reason) + - Montant à recevoir + - value (nombre) + - currency (code de devise ISO) +- Extensions + +## Commentaires finaux + +- Aucune anomalie majeure dans le BC ou la conception de l’Architecture de Référence. +- Besoin de mieux comprendre/clarifier le pattern « GET » via « POST » : + - Un événement « GET » doit-il être un simple « GET » Restful, ou le système doit-il prendre en charge le « GET » à partir de posts dupliqués ? + - Devons-nous prendre en charge des requêtes « GET » incluant des détails FSP à une date ultérieure ? + + + + +[^1]: Interfaces Communes : [Liste des interfaces communes Mojaloop](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png new file mode 100644 index 000000000..db2b6246a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png new file mode 100644 index 000000000..723f9b87e Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png new file mode 100644 index 000000000..5223a2137 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png new file mode 100644 index 000000000..13a7d81ae Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png new file mode 100644 index 000000000..98d2ece29 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/reporting/index.md b/docs/fr/technical/reference-architecture/boundedContexts/reporting/index.md new file mode 100644 index 000000000..ad4426a5e --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/reporting/index.md @@ -0,0 +1,101 @@ +# BC Reporting + +## Vue d'ensemble + +### Stratégie & Règles + +La stratégie de reporting pour cette architecture de référence est de décrire les mécanismes génériques par lesquels les données des BC clients peuvent être persistées et tenues à jour dans un Magasin de données de reporting, de sorte que les utilisateurs et les systèmes puissent ensuite consommer ces données directement du Magasin de données de reporting, ou via tout outil de reporting et/ou de tableau de bord connecté à ce Magasin de données de reporting. + +- Ce Magasin de données de reporting doit être accessible en écriture uniquement du point de vue du switch, et en lecture seule par les composants externes. +- Les modèles de données du Magasin de données de reporting peuvent différer des modèles de données opérationnels internes utilisés par le switch ; si pertinent, pour des raisons de performance ou autres, plusieurs modèles pour les mêmes données peuvent être rendus disponibles dans le Magasin de données de reporting – à l'instar de plusieurs projections ou vues. +- Un Composant de Reporting du BC Client, fourni par le switch, traduira les événements internes et les modèles de données internes vers les modèles du magasin de données externe – ce composant peut être remplacé, ou il peut même en exister plusieurs pour un même BC client. +- Un tel composant doit exister dans le BC Reporting pour tout BC Client dont les données sont rendues disponibles dans le Magasin de données de reporting. +- Tout envoi ou récupération directe de données depuis le BC Client source, ou ses magasins de données internes, vers le Magasin de données de reporting constitue une violation du principe de découplage et affectera négativement la maintenabilité du système en raison de son couplage fort. + +### Stratégies de reporting : + +- Basé sur les événements – Méthode privilégiée – Sur le BC Reporting, un composant (gestionnaire d'événements) écoute les événements pertinents depuis son BC associé et transforme ces événements en entrées dans le magasin de données de reporting – il peut y avoir plusieurs de ces composants par BC client, toutefois chacun doit être le seul responsable de l'écriture d'un sous-ensemble des données de reporting. +- Push – Le BC client appelle l'API du Composant de Reporting correspondant afin d'envoyer les données ; cette API transforme et persiste les données dans le magasin de données de reporting ([^1] avec le BC source, c'est-à-dire, il doit y avoir une API par BC source). +- Pull – Sur le BC Reporting, un Composant de Reporting pour BC client (piloté par minuterie) appelle une API sur le BC source pour récupérer ses données, qui sont ensuite persistées dans le magasin de données de reporting ([^1] avec le BC source). + +**Pour les BC critiques en performance, il faut toujours privilégier la stratégie de reporting pilotée par les événements.** + +### Règles minimales à respecter : + +- Seul le Magasin de données de reporting doit être utilisé pour le reporting et les tableaux de bord. Les systèmes externes ne sont pas autorisés à accéder directement aux magasins de données internes des Bounded Contexts. L'accès opérationnel pour les systèmes externes sera disponible via les API opérationnelles ou API d'interopérabilité. +- Les données sources internes des BC clients ne peuvent pas être « transmises » directement au Magasin de données de reporting : il doit y avoir une traduction entre la structure de données source et la structure de données de reporting, même s'il n'y a pas de différence de structure. L'objectif est d'éviter toute dépendance du côté reporting à la structure de données source. + +### À faire + +- Décider quels rapports initiaux et tableaux de bord doivent être inclus dans la fonctionnalité de reporting de base. +- Choisir des outils open source de reporting et de tableau de bord pour fournir cette fonctionnalité de base. +- Reporting de conformité/assurance – définir certains de ces rapports de base (KYC, AML) +- Discuter de la « Surveillance des processus (et SLA) » et décider si cela peut être fait au-dessus de la couche de reporting (la définition des chiffres critiques, SLI & SLO, se fait par la configuration de la plateforme) +- Ajouter un lien vers l'API opérationnelle BC dans la section des règles ci-dessus. + +## Termes + +Termes ayant une signification spécifique et communément acceptée dans le Contexte Borné dans lequel ils sont utilisés. + +| Terme | Description | +|-------------------------------|-------------| +| **BC Client** | Contexte Borné source (ou propriétaire) des données persistées dans le Magasin de données de reporting | +| **Magasin de données de reporting** | Data store(s) externe(s) (il peut y en avoir plusieurs) où les données de reporting produites par les Composants de Reporting des BC Clients sont stockées et tenues à jour | +| **Composant de Reporting du BC Client** | Ce composant, qui peut prendre la forme d'un service, est responsable de la traduction du modèle interne vers le(s) modèle(s) externe(s) stocké(s) dans le Magasin de données de reporting | +| **Outil de reporting ou de tableau de bord** | Outils externes qui utilisent les données du Magasin de données de reporting comme source pour produire des rapports, des tableaux de bord ou toute autre tâche liée au reporting | + +## Vue Fonctionnelle + +![Diagramme d'ensemble fonctionnel du reporting](./assets/ML2RA_Rpts_functionalOverview_Apr22-b.png) +> Diagramme des fonctions BC : Vue fonctionnelle + +## Cas d'Utilisation + +### Reporting par événements (méthode privilégiée) + +#### Description + +Stratégie pour alimenter le Magasin de données de reporting en ayant un Composant de Reporting du BC Client à l'écoute des événements internes et persistant les données de reporting correspondantes. + +#### Diagramme de flux + +![Diagramme UC reporting événementiel](./assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png) +> Diagramme du workflow UC : Reporting par événements (méthode privilégiée) + +### Reporting par extraction (pull) + +#### Description + +Stratégie pour alimenter le Magasin de données de reporting en faisant en sorte que le Composant de Reporting du BC Client aille chercher les données auprès de l'API du BC Client. + +#### Diagramme de flux + +![Diagramme UC reporting par extraction](./assets/ML2RA_Rpts_pullReporting_Apr22-b.png) +> Diagramme du workflow UC : Reporting par extraction (pull) + +### Reporting par envoi (push) + +#### Description + +Stratégie pour alimenter le Magasin de données de reporting en ayant le BC client qui envoie à l'API du Composant de Reporting du BC Client les données à rapporter, puis ce composant traduit et persiste ces données. + +#### Diagramme de flux + +![Diagramme UC reporting par envoi](./assets/ML2RA_Rpts_pushReporting_Apr22-b.png) +> Diagramme du workflow UC : Reporting par envoi (push) + +### Consultation des rapports et tableaux de bord par l'utilisateur + +#### Description + +Exemple de la manière dont un utilisateur peut consommer des rapports et des tableaux de bord. + +#### Diagramme de flux + +![Diagramme de consommation de rapports / dashboard utilisateur](./assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png) +> Diagramme du workflow UC : Consommation utilisateur – reporting & dashboard + + +## Notes + +[^1] : Interfaces communes : [Liste des interfaces communes Mojaloop](../../refarch/commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png new file mode 100644 index 000000000..6db98ef15 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png new file mode 100644 index 000000000..43a900f75 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png new file mode 100644 index 000000000..00de4e46d Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png new file mode 100644 index 000000000..fd9ae7373 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/scheduling/index.md b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/index.md new file mode 100644 index 000000000..25552c68f --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/scheduling/index.md @@ -0,0 +1,131 @@ +# BC Scheduling + +De nombreux processus et événements dans les différents BCs de la plateforme Mojaloop Switch nécessitent une fonctionnalité permettant de déclencher des actions à des moments précis ou selon un calendrier défini. Afin de prendre en charge ce besoin de manière centralisée et d’éviter d’implémenter cette fonctionnalité dans chaque BC, un seul BC dédié à la planification sera introduit et mis en œuvre sur la plateforme Switch. + +Pour planifier un processus ou un événement, un BC Client soumet une demande au Scheduling BC pour créer un rappel destiné à être déclenché à un horaire précis ou selon une récurrence. Le Scheduling BC maintient un registre de tous les rappels reçus et, lorsque le moment fixé arrive, il envoie une notification du rappel au BC Client concerné. + +De plus, le Scheduling BC fournira également des services au Switch pour permettre aux BC Clients et aux administrateurs du Switch de gérer les rappels. + +## Termes + +Le(s) terme(s) suivant(s) sont utilisés dans ce BC : + +| Terme | Description | +|---|---| +| **BC Client** | Tout autre BC utilisant les services du Scheduling BC | + +## Cas d’Utilisation + + +L’état des cas d’utilisation (UC) pour le Scheduling BC est le suivant : + +| UCs Disponibles | | | UCs Prévus | | +| --- | :-- | --- | --- | :-- | +| **Cas d'utilisation** | **Description** | | **Cas d'utilisation** | **Description** | +| **Créer un rappel** | Le BC Client demande la création d’un rappel | | **Requête de rappel du client** | Le BC Client interroge ses propres rappels | +| **Supprimer un rappel** | Le BC Client demande la suppression d’un rappel | | **Requête de rappel de l’administrateur** | L’administrateur de la plateforme interroge tous les rappels | +| **Déclenchement du rappel** | Le Scheduling BC exécute le déclenchement du rappel lorsque le moment est venu | | | +| **Mettre à jour un rappel** | *Non fourni. Solution recommandée : supprimer et créer un nouveau Rappel* | | | | | + + +### Créer un rappel + +#### Description +Ce flux permet au Switch de traiter les demandes autorisées des BC Clients pour créer des rappels. + +#### Diagramme de flux + +![Créer un rappel](./assets/schedulingCreateReminder_20211021.png) +> +### Déclenchement du rappel + +#### Description +Ce flux permet au Switch de traiter les rappels envoyés du Scheduling BC à un BC Client pour exécuter une tâche, ou simplement comme rappel. + +#### Diagramme de flux + +![Déclenchement du rappel](./assets/schedulingReminderTriggered_20211021.png) +> +### Suppression d’un rappel (récurrent) + +#### Description +Ce flux permet au Switch de gérer les messages des BC Clients autorisés au Scheduling BC pour supprimer un Rappel. Si le Scheduling BC ne parvient pas à traiter l’instruction, il envoie un message d’alerte au Notifications BC. + +#### Diagramme de flux + +![Suppression d’un rappel récurrent](./assets/schedulingDeleteRecurringReminder_20211021.png) +> + + +## Notes + +#### Créer un Rappel – Données requises + +La demande de Création de Rappel doit inclure les données suivantes : + +| Donnée | Description | +| --- | ---- | +| **Identifiant** | nom/id | +| **Définition Cron** | récurrent ?, intervalle de temps ? | +| **Transport de Déclenchement** | Callback HTTP/Événement ; URL de Callback ou Sujet d'Événement | +| **Payload Spécial** | opaque pour le Scheduling BC | +| **Conditions de récupération** | nouvelle tentative, replanification, abandon, abandon | +| **Alertes** | notification, journalisation en cas d’exception | +| **Actions** | registre des processus BC automatisables/planifiables | + +#### BC Scheduling – Exigences + +Le Scheduling BC doit répondre aux exigences suivantes : + +* Les rappels ne doivent être déclenchés qu’une seule fois + +* Le BC doit conserver l’historique des Rappels déclenchés + +* Le BC doit garder l’historique des actions de Création/Lecture/Suppression + + * Les mises à jour seront facilitées via les actions Suppression/Création, comme indiqué dans la liste des UCs disponibles + +* Lots de tâches (Job batches) + +* Offrir plusieurs options d’interface (gRPC, REST, HTTP, etc.) + +* Les rappels doivent être déclenchés avec un callback HTTP, pas un appel gRPC, ou vers un sujet spécifique + +* Il ne doit pas avoir la capacité de traiter de la logique externe au Scheduling BC lui-même + +* Utiliser exclusivement les horodatages UTC basés sur Linux pour éviter les problèmes de synchronisation + +***Remarque :*** *Il est supposé que le système sous-jacent maintiendra une heure parfaite.* + +#### BC Scheduling – Exigences en suspens + +Les exigences d’accès pour le Scheduling BC restent à définir. + +#### BC Scheduling – Exceptions + +* Instructions malformées + * Date/heure invalide, y compris des heures dans le passé + * BC ou commande invalide +* Échec d’exécution (identifié via le callback) +* Autorité insuffisante du BC Client pour réaliser l’opération CRD +* Échec du traitement/exécution du Rappel + +#### Questions + +Certaines questions sont apparues lors des sessions d’architecture de référence. Jugées utiles pour le plus grand nombre, elles sont incluses ci-dessous : + +* Après que la tâche planifiée a été initiée, le Scheduling BC reste-t-il responsable du suivi de sa progression ? + + * Réponse : Non. Lorsque le rappel est dû, il est communiqué au BC Client selon la méthode prévue, et la responsabilité du rappel est alors transférée au BC Client. + +* Est-ce le BC Client ou la personne qui a planifié le Rappel qui est noté comme « Utilisateur » par le Scheduling BC ? En d’autres termes, quel ID est inscrit dans la piste d’audit (audit trail) ? + + * Réponse : Cela doit être déterminé par le BC Client, selon l’action qu’il entreprend à la réception du rappel. \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png new file mode 100644 index 000000000..8c67da4bb Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png new file mode 100644 index 000000000..3bf4c83db Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png new file mode 100644 index 000000000..f268daee4 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png new file mode 100644 index 000000000..b67ea6e1a Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png new file mode 100644 index 000000000..798b8681b Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png new file mode 100644 index 000000000..807c85f63 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/security/index.md b/docs/fr/technical/reference-architecture/boundedContexts/security/index.md new file mode 100644 index 000000000..2f6a27bb2 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/security/index.md @@ -0,0 +1,93 @@ +# BC Security + +## Vue d'ensemble + +Le protocole est basé sur le modèle requête-réponse, utilisant le protocole Hypertext Transfer Protocol Secure (HTTPS). Tous les services utilisent les méthodes HTTP POST et GET. Les corps des requêtes et des réponses sont encodés en texte au format JSON. + +## Termes + +Termes ayant une signification spécifique et communément acceptée dans le Contexte Borné Sécurité. + +| Module | Description | +|---|---| +| **Fournisseurs Crypto** | Adaptateur qui fournit les services cryptographiques et les services de gestion de clés (KMS) | +| **IAM** | Gestion des Identités et des Accès (Identity and Access Management). Adaptateur qui fournit les services de gestion des utilisateurs, menus, profils, rôles et permissions. | +| **AuthN** | Module d’authentification. Nécessite un identifiant utilisateur et un mot de passe, et retourne un jeton JWT. | +| **AuthZ** | Module d’autorisation. Nécessite un JWT et un certificat (clé publique). Vérifie les ROLES du JWT et la signature. | +| **JWT** | JSON Web Token. Renvoyé après une authentification utilisateur réussie. Contient les détails de l’utilisateur, les ROLES et la signature. | +| **KMS** | Système de Gestion de Clés (Key Management System). Gère le cycle de vie des clés cryptographiques (définition, création et retrait). Fait partie du sous-système Crypto. | + +## Cas d’Utilisation + +### Connexion Utilisateur / Opérateur du BC (AuthN) + +#### Description + +La fonction de connexion requiert que l’identifiant utilisateur et une clé secrète soient transmis dans le corps HTTP. La réponse contient un jeton JWT signé. La signature est générée par le sous-système Crypto. La connexion est réalisée par les services d’authentification ou l’IAM. + +#### Diagramme de flux + +![Cas d’Utilisation - Connexion Utilisateur / Opérateur du BC (AuthN)](./assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png) +> Diagramme de workflow UC : Connexion Utilisateur / Opérateur du BC (AuthN) + +### Modèle d’Autorisation du BC (AuthZ) + +#### Description + +IAM fournit l'association des utilisateurs/groupes, rôles et privilèges. Chaque BC dispose également d’une liste de rôles correspondants. Lorsqu’une fonction API ou un microservice est appelé, la signature du JWT est vérifiée à l’aide de la clé publique et le rôle fourni dans le JWT est comparé au rôle associé au BC. Si la vérification de la signature et celle du rôle sont réussies, la fonction API ou le microservice est exécuté. + +#### Diagramme de flux + +![Cas d’Utilisation - Modèle d’Autorisation du BC (AuthZ)](./assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png) +> Diagramme de workflow UC : Modèle d’Autorisation du BC (AuthZ) + +### Bootstrap du BC + +#### Description + +Au démarrage ("bootstrap"), le BC envoie la liste des privilèges possibles. Cette opération est effectuée une fois à chaque déploiement d’une nouvelle version. + +#### Diagramme de flux + +![Cas d’Utilisation - Bootstrap du BC](./assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png) +> Diagramme de workflow UC : Bootstrap du BC + +### Démarrage du BC + +#### Description + +Au lancement, le BC demande les clés publiques de l’émetteur d’authentification auprès des sous-systèmes Crypto / KMS du BC Sécurité ainsi que la liste des rôles/privilèges auprès du sous-système IAM du BC Sécurité. Une fonction locale de vérification de signature d'une bibliothèque cryptographique vérifie la signature JWT et les rôles dans le JWT sont comparés à la liste locale de rôles obtenue du service central d’autorisation. + +##### Diagramme de flux + +![Cas d’Utilisation - Démarrage du BC](./assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png) +> Diagramme de workflow UC : Démarrage du BC + +### Association Rôle / Privilège + +#### Description + +Les rôles sont associés à un certain nombre de privilèges. + +#### Diagramme de flux + +![Cas d’Utilisation - Association Rôle / Privilège](./assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png) +> Diagramme de workflow UC : Association Rôle / Privilège + +### Exemple de Requête / Appel + +#### Description + +L’autorisation du client doit être réalisée à l’aide d’un jeton d’accès (access token). Un client doit d’abord demander au service d’autorisation de générer un jeton d’accès pour l’utilisateur qui souhaite accéder à l’interface. Cet utilisateur est authentifié dans le service d’autorisation. Le jeton d’accès généré est ensuite utilisé pour l’autorisation sur l’interface. +Pour utiliser le jeton d’accès, le client doit définir l’en-tête HTTP Authorization à la valeur Bearer [jeton_d_acces] sur chaque requête adressée à l’interface. + +#### Diagramme de flux + +![Cas d’Utilisation - Exemple de Requête API/ Appel](./assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png) +> Diagramme de workflow UC : Exemple de Requête API / Appel + + + \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png new file mode 100644 index 000000000..9b04df7c1 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png new file mode 100644 index 000000000..8c8b1977f Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png new file mode 100644 index 000000000..911db5bfe Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png new file mode 100644 index 000000000..5016294ea Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png new file mode 100644 index 000000000..8c27bfe78 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png new file mode 100644 index 000000000..054b6a2f2 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png new file mode 100644 index 000000000..153e4c753 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/settlements/index.md b/docs/fr/technical/reference-architecture/boundedContexts/settlements/index.md new file mode 100644 index 000000000..e1aa9c76f --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/settlements/index.md @@ -0,0 +1,87 @@ +# BC Settlements + +Le BC Settlements est essentiel pour le règlement des transferts des Participants, en utilisant soit la méthode de Règlement Net Différé (DNS), soit celle de Règlement Brut Immédiat (IGS). Il est responsable de la création des fenêtres de règlement, de l'identification et du déploiement de la méthode de règlement requise (DNS/IGS), du règlement, de la clôture et de la mise à jour des lots, ainsi que de l'enregistrement de tous les dépôts et retraits sur les comptes appropriés dans le BC Accounts & Balances. + +## Termes + +Les termes suivants sont utilisés dans ce BC, aussi appelé domaine. + +| Terme | Description | +| ------------- | ------------ | +| **DNS** | Règlement Net Différé (Deferred Net Settlement) | +| **IGS/RTGS** | Règlement Brut Immédiat/Règlement Brut en Temps Réel (Immediate Gross Settlement/Real-Time Gross Settlement) | +| **Opérateur** | Personne ou système émettant des instructions/demandes | +| **Participant** | FSP/PISP ou client FSP | +| **Compte** | Compte de grand livre (Cr/Dr) | + +## Vue Fonctionnelle + +![Cas d'Utilisation - Vue Fonctionnelle](./assets/settleFunctionalOverview_20210826.png) +> + +## Cas d'Utilisation + +### Règlement Net Différé (DNS) + +#### Description +Méthode permettant de différer les paiements afin de procéder au règlement sur plusieurs lots selon un calendrier prédéfini. Ceci est utile pour les environnements impliquant plusieurs Participants à une transaction nécessitant une approche de règlement du solde dû. + +#### Diagramme de flux + +![Cas d'Utilisation - Règlement Net Différé (DNS)](./assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png) +>Diagramme du parcours UC : Règlement Net Différé - 19/10/2021 + +### Règlement Brut Immédiat (IGS) + +#### Description +Méthode permettant le règlement immédiat des lots. Ceci est utile pour les environnements PME où des cycles de paiement rapides sont souvent souhaités afin de maximiser leur liquidité. IGS est également connu sous le nom de Règlement Brut en Temps Réel (RTGS). + +#### Diagramme de flux + +![Cas d'Utilisation - Règlement Brut Immédiat (IGS)](./assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png) +>Diagramme du parcours UC : Règlement Brut Immédiat + +### Abort Settlement + +#### Description +Méthode permettant au Settlements BC d'abandonner un règlement si nécessaire, en inversant les comptes de règlement des Participants, en mettant à jour le statut du règlement pour les fenêtres de règlement et en mettant à jour l'état du règlement. + +#### Diagramme de flux + +![Cas d'Utilisation - Abort Settlement](./assets/settleAbortSettle_20210827.png) +> + +### Création/Mise à jour du Settlement Model (DNS/IGS) + +#### Description +Méthode permettant au Settlements BC de créer ou mettre à jour la méthode de règlement pour un lot de règlement, en fonction du type de compte du Participant. Utile dans les cas où des Settlement Methods mixtes sont nécessaires. + +#### Diagramme de flux + +![Cas d'Utilisation - Création/Mise à jour du Settlement Model (DNS/IGS)](./assets/settleCreateUpdateModel_20210827.png) +> + +### Bootstrap (Startup) du Settlement Model via Configuration + +#### Description +Méthode configurant la Settlement Method (DNS/IGS) sur la base de la configuration de démarrage du système. Utile dans les cas où tous les Settlement Models sont identiques, par exemple, tous en DNS ou tous en IGS. + +#### Diagramme de flux + +![Cas d'Utilisation - Bootstrap (Startup) du Settlement Model via Configuration](./assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png) +>Diagramme de workflow UC : Bootstrap (Startup) du Settlement Model via Configuration + +### Création de comptes liés au règlement pour les nouveaux Participants + +#### Description +Le système crée des comptes de règlement pour les nouveaux Participants afin de permettre la gestion des transferts de fonds par le Switch. Cela permet au Switch d'assurer la gestion de bout en bout de tous les transferts, quel que soit le mode de règlement utilisé. + +#### Diagramme de flux + +![Cas d'Utilisation - Création de comptes liés au règlement pour les nouveaux Participants](./assets/settleCreateSettleAccountsNewPart_20210827.png) +> + + + + +[^1]: Common Interfaces : [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png new file mode 100644 index 000000000..94ef957ff Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png new file mode 100644 index 000000000..f45af2d12 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png new file mode 100644 index 000000000..f40d264f8 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png new file mode 100644 index 000000000..6aa565e7d Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png new file mode 100644 index 000000000..5e3b6a184 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png new file mode 100644 index 000000000..90da29fc6 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png new file mode 100644 index 000000000..dad5d2724 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png new file mode 100644 index 000000000..1cd3f6cfa Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png new file mode 100644 index 000000000..841a8b8c7 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png new file mode 100644 index 000000000..de4844fc8 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png new file mode 100644 index 000000000..7ab02a922 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png new file mode 100644 index 000000000..fcb9eb8ca Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png new file mode 100644 index 000000000..fc5c3934c Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png new file mode 100644 index 000000000..48601bc8c Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png new file mode 100644 index 000000000..c426cf207 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png new file mode 100644 index 000000000..4900cf6d5 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png new file mode 100644 index 000000000..817f487b9 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png new file mode 100644 index 000000000..8d26fbfad Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png new file mode 100644 index 000000000..5890e84aa Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png new file mode 100644 index 000000000..de4c47de3 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md new file mode 100644 index 000000000..c654c93df --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md @@ -0,0 +1,262 @@ +# BC Third Party API + +Le Third Party API BC a été implémenté dans le cadre de l’architecture de référence Mojaloop 2.0 afin de permettre aux opérateurs PISP tiers (généralement des applications) d’interagir avec la plateforme. Veuillez noter que, sauf indication contraire, toutes les références aux BC concernent les différents composants ou Bounded Contexts (BCs) de Mojaloop. + +## Termes + +Les termes communs suivants sont utilisés dans ce BC : + +| Terme | Description | +| ---------- | ------------ | +| **PISP** | PISP (Payment Initiation Service Provider) (par exemple PayPal, ApplePay, GooglePay, etc.) | +| **DFSP** | DFSP (Digital Financial Service Provider) (par exemple Banque, Opérateur de Mobile Money) | +| **Utilisateur** | Client DFSP/PISP (selon indication) | + +## Cas d’Utilisation + +**Remarque :** Nos cas d’usage couvrent deux scénarios spécifiques : + +| Scénarios | Description | +| ----------- | -------------------------- | +| [Liaison](#linking-scenarios) | Activités de maintenance PISP | +| [Transfert](#transfer-scenarios) | Activités d’initiation de transfert PISP | + +## Scénarios de Liaison + +### Obtention par le PISP des DFSP pris en charge + +#### Description + +Ce flux permet au Switch de traiter les demandes autorisées d’utilisateurs PISP pour obtenir une liste de DFSP Account Holders pris en charge par le système. + +#### Schéma de Flux + +![Cas d’Utilisation - Obtention par le PISP des DFSP pris en charge](./assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png) +>Schéma de workflow UC : Obtention par le PISP des DFSP pris en charge + +### Obtention par le PISP de la liste des comptes pour un DFSP + Identifiant + +#### Description + +Ce flux permet au Switch de traiter les cas où des utilisateurs PISP autorisés souhaitent rechercher les détails de leurs comptes de titulaire DFSP à l’aide de leur DFSP Account Holder Identifier. Généralement, l’Identifier est intégré dans une application ou un processus émanant du PISP. + +#### Schéma de Flux + +![Cas d’Utilisation - Obtention par le PISP de la liste des comptes pour un DFSP + Identifiant](./assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png) +>Schéma de workflow UC : Obtention par le PISP de la liste des comptes pour un DFSP + Identifiant + +### PISP Consent Request + +#### Description + +Ce flux permet au Switch de gérer les cas où un utilisateur PISP autorisé notifie son DFSP Account Holder de son intention de lier un ou plusieurs de ses comptes à un PISP via une Consent Request. Cette demande est satisfaite via un processus d’émission de consentement hors bande, suite à la réception d’une réponse à une demande de confirmation d’autorisation. Ce processus établit une relation de confiance entre le PISP User, le PISP, et le DFSP Account Holder. Le Switch met à jour les détails des comptes participants en conséquence. + +#### Schéma de Flux + +![Cas d’Utilisation - PISP Consent Request](./assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png) +>Schéma de workflow UC : PISP Consent Request + +### DFSP Issue Consent + +#### Description + +Ce flux permet au Switch de gérer les cas où un DFSP Account Holder répond à une Consent Request reçue d’un PISP User autorisé et authentifié. Le DFSP Account Holder émet une demande au PISP via le Switch pour que le PISP User crée un Credential sur son appareil. Une fois le Credential reçu et vérifié par le DFSP Account Holder émetteur, le Switch et les enregistrements de compte DFSP Account Holder sont mis à jour avec le PISP User Credential et les Accounts liés, et le PISP User est notifié que son/ses DFSP Account Holder Account/s a/ont été lié(s) avec succès à son PISP profile. + +***Remarque :*** *L’Issue Consent est en réponse à une Consent Request faite par un PISP User autorisé pour lier un ou plusieurs de ses DFSP Account Holder Accounts à son PISP profile et suit le flux décrit dans la section [PISP Consent Request](#pisp-consent-request) ci-dessus.* + +#### Schéma de Flux + +![Cas d’Utilisation - DFSP Issue Consent](./assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png) +>Schéma de workflow UC : DFSP Issue Consent + +### Unlink Accounts : Hub Hosted Auth + +#### Description + +Ce flux permet au Switch de gérer une demande autorisée de PISP/DFSP Account Holder pour révoquer le consentement pour qu’un DFSP Account Holder Account soit lié à son PISP Profile. Le Switch traite en mettant à jour le Account Lookup Service du système pour dissocier l’association PISP Participant/DFSP Account, notifiant le DFSP Account Holder (qui retire l’entrée ALS Participant et le Link de son système), et le PISP Host qui envoie une notification de réalisation au User. + +#### Schéma de Flux + +![Cas d’Utilisation - Unlink Accounts - Hub Hosted Auth](./assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png) +>Schéma de workflow UC : Unlink Accounts - Hub Hosted Auth + +### Link Accounts - Account Discovery Failure + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé initie une demande pour lier un DFSP Account à son PISP Profile en utilisant une paire DFSP/Identifier invalide non reconnue par le DFSP. Le DFSP envoie un message au Switch avec une erreur, qui notifie le PISP approprié, et le User reçoit un message pour essayer une autre paire DFSP/Identifier. + +#### Schéma de Flux + +![Cas d’Utilisation - Link Accounts - Account Discovery Failure](./assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png) +>Schéma de workflow UC : Link Accounts - Account Discovery Failure + +### Link Accounts - DFSP Rejects Consent Request + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé demande qu'un ou plusieurs accounts soient liés à son PISP Profile par le DFSP Account Holder. Lorsque le DFSP Account Holder refuse le consentement pour la liaison pour une raison quelconque, par exemple : un account sélectionné ne prend pas en charge la liaison, il enverra un message au Switch avec une condition d’erreur. Le Switch notifie le PISP approprié, et le PISP User reçoit un message, in-app ou autrement, pour réessayer sa demande car la demande de liaison de compte précédente a échoué. + +#### Schéma de Flux + +![Cas d’Utilisation - Link Accounts - DFSP Rejects Consent Request](./assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png) +>Schéma de workflow UC : Link Accounts - DFSP Rejects Consent Request + +### Credential Registration Error + +#### Description + +Ce flux permet au Switch de gérer les cas où un DFSP Account Holder fournit à un PISP une demande pour qu'un (PISP) User crée un credential embarqué sur appareil pour confirmer une Consent Request, où le credential, qui lorsqu'il est envoyé au DFSP inclut soit un signed challenge invalide soit des signed metadata rejetées. Dans cette instance le DFSP envoie un message de la condition d'erreur au Switch, qui envoie un message au PISP approprié qui notifie le (PISP) User que le Consent credential a été rejeté. + +#### Schéma de Flux + +![Cas d’Utilisation - Credential Registration Error](./assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png) +>Schéma de workflow UC : Credential Registration Error + +### Unlink Accounts - Consent Not Found + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé est demandé de confirmer une consent request émise via soit le PISP soit le DFSP Account Holder pour unlink son DFSP Account de son PISP Profile. Le Switch réfère la consent request response au Consent Oracle pour confirmation du Consent Owner ID. Dans les instances où l’Oracle est incapable de confirmer l’ID du Consent Owner, la demande échoue. Le PISP User est alerté via le DFSP Account Holder ou le PISP profile holder, que le DFSP Account qu’il a cherché à unlink de son PISP profile n’a pas été trouvé. + +#### Schéma de Flux + +![Cas d’Utilisation - Unlink Accounts - Consent Not Found](./assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png) +>Schéma de workflow UC : Unlink Accounts - Consent Not Found + +### DFSP Rejects OTP/Auth Token from PISP + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé demande qu’un ou plusieurs de ses DFSP Account Holder Accounts soient liés à son PISP Profile. La demande est dirigée par le Switch vers le DFSP Account Holder qui émet un OTP/Web Login Flow au PISP User pour des fins de vérification qui est retourné via le PISP au Switch, et ensuite au DFSP Account Holder pour consent. Dans les instances où le token de réponse est altéré ou expiré, le DFSP Account Holder émet un message de condition d’erreur au Switch et le PISP User est notifié que la demande de liaison de DFSP Account a échoué. + +#### Schéma de Flux + +![Cas d’Utilisation - DFSP Rejects OTP/Auth Token from PISP](./assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png) +>Schéma de workflow UC : DFSP Rejects OTP/Auth Token from PISP + +### Unlink Accounts - Downstream Failure + +#### Description + +Ce flux permet au Switch de gérer les cas où la confirmation de consentement de unlink de DFSP Account d’un PISP User autorisé échoue à l’étape d’Authentication/Authorisation du Switch pour une raison quelconque, exemple : une erreur downstream FSPIOP API. L’erreur est messagée par le Switch au DFSP Account Holder qui examinera l’erreur et déterminera comment répondre. Lorsqu’une erreur s’est produite, le PISP User est notifié par le Switch via le PISP que sa demande pour unlink son DFSP Account a échoué. + +#### Schéma de Flux + +![Cas d’Utilisation - Unlink Accounts - Downstream Failure](./assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png) +>Schéma de workflow UC : Unlink Accounts - Downstream Failure + +## Scénarios de Transfert + +***Remarque :*** *Pour alléger la description du flux, le lecteur doit noter que le BC API Tiers Partie et le BC Paiements Initiés par Tiers travaillent de concert pour maintenir le Participant Information – l’interaction n’est pas toujours précisée ici, mais se fait ainsi : lorsque le Third Party API BC met à jour le Transaction state, et où le Participant Information n’est pas en cache, le BC Paiements Initiés par Tiers sollicitera le Participant Information manquant du BC Gestion du Cycle de Vie des Participants et le livrera au Third Party API BC pour inclusion dans le Transaction information présenté aux systèmes DFSP/PISP.* + +### Third Party Initiated Transaction Request + +#### Description + +Ce flux permet au Switch d’autoriser les PISP Users/Apps autorisés à émettre une demande à un DFSP pour exécuter une transaction au nom d’un Account Holder, typiquement le PISP User/App, en faveur d’un third-party recipient ou recipients. La transaction est vétérinée via une DFSP confirmation request à l’Account Holder, et conclue sur réception réussie de confirmation. Le Switch, selon les instructions DFSP, gère la transaction et met à jour tous les accounts en conséquence. + +Quelques applications suggérées de Third Party Payment Initiation UC incluent : + + - Paiements pair à pair (ex. : GPay en Inde) + - Paiements en ligne pour une expérience utilisateur finale fluide (UX) (ex. : PayPal) + - Logiciels de liquidation de paie + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Initiated Transaction Request](./assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png) +>Schéma de workflow UC : Third Party Initiated Transaction Request + +### PISP Bulk Transaction Request + +#### Description + +Ce flux permet au Switch de traiter les cas où des PISP Users/Apps autorisés émettent une demande à un DFSP pour exécuter un nombre de bulk transactions au nom d’un Account Holder, typiquement le PISP User/App, en faveur d’un groupe de third-party recipients. La transaction est vétérinée via une DFSP confirmation request envoyée à l’Account Holder, et conclue sur réception réussie de confirmation. Le Switch, selon les instructions DFSP, gère la transaction et met à jour tous les accounts en conséquence. + +#### Schéma de Flux + +![Cas d’Utilisation - Exemple À REMPLACER](./assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png) +>Schéma de workflow UC : PISP Bulk Transaction Request + +### Pay To A PISP - PISP As A Payee + +#### Description + +Ce flux permet au Switch d’autoriser les DFSP Users autorisés à initier et exécuter des paiements en faveur de PISPs en tant que Payees via le Switch. Le flux prend en charge les paiements vers un ou plusieurs PISP en tant que Bénéficiaire (Payee). + +#### Schéma de Flux + +![Cas d’Utilisation - Pay To A PISP - PISP As A Payee](./assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png) +>Schéma de workflow UC : Pay To A PISP - PISP As A Payee + +### Échec de la recherche de participant + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé initie une transaction avec un identifiant de Participant invalide. L’erreur est détectée à l’étape Get Parties de la préparation de la transaction et la demande est automatiquement terminée, avec notification envoyée au User initiateur de la demande indiquant l’échec et la raison. + +#### Schéma de Flux + +![Cas d’Utilisation - Échec de la recherche de participant](./assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png) +>Schéma de workflow UC : Échec de la recherche de participant + +### Third Party Transaction Request Failure - Invalid Transaction Request + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User autorisé initie une Third Party Transaction Request, confirme correctement les détails du Payee, mais où le DFSP du bénéficiaire ne trouve pas d’accord (Agreement) valide pour la transaction. Le Switch rejette la demande et envoie une notification au User initiateur de la demande indiquant l’échec et les actions de suivi suggérées. + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Transaction Request Failure - Invalid Transaction Request](./assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png) +>Schéma de workflow UC : Third Party Transaction Request Failure - Invalid Transaction Request + +### Third Party Transaction Request Failure - Downstream FSPIOP Failure + +#### Description + +Ce flux permet au Switch de gérer les cas où une demande de transaction tierce confirmée échoue côté DFSP lors du processus de devis. Le Switch est informé de la défaillance et transmet la notification au PISP User via son PISP App/Process. + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Transaction Request Failure - Downstream FSPIOP Failure](./assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png) +>Schéma de workflow UC : Third Party Transaction Request Failure - Downstream FSPIOP Failure + +### Third Party Transaction Request Failure - Authorization Was Invalid + +#### Description + +Ce flux permet au Switch de gérer les cas où un parcours de transaction tierce est initié, puis autorisé par un PISP User sur demande du DFSP Account Holder, et où la réponse au challenge DFSP comporte une signature invalide. Le Switch vérifie et notifie le titulaire DFSP qui annule la transaction et informe l’utilisateur PISP via le Switch et son détenteur du profil PISP. + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Transaction Request Failure - Authorization Was Invalid](./assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png) +>Schéma de workflow UC : Third Party Transaction Request Failure - Authorization Was Invalid + +### Third Party Transaction Request Rejected by user + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User initie et confirme une transaction via son PISP, mais décline de la finaliser à réception de l’acceptation du devis et du challenge de signature du DFSP Account Holder. Après refus, le PISP prévient le DFSP via le Switch, qui annule la transaction et envoie la confirmation d’annulation au PISP initiateur. + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Transaction Request Rejected By User](./assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png) +>Schéma de workflow UC : Third Party Transaction Request Rejected By User + +### Third Party Transaction Request Failed - DFSP timeout + +#### Description + +Ce flux permet au Switch de gérer les cas où un PISP User initie et confirme une transaction via son PISP, mais ne répond pas dans le délai requis à la demande d’acceptation de devis et de challenge de signature DFSP. Passé le délai, le PISP signale le défaut au DFSP via le Switch et le DFSP annule la transaction et notifie l’utilisateur de l’échec de la demande. + +#### Schéma de Flux + +![Cas d’Utilisation - Third Party Transaction Request Failed - DFSP Timeout](./assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png) +>Schéma de workflow UC : Third Party Transaction Request Failed - DFSP Timeout + + + \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png new file mode 100644 index 000000000..363b750a4 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png new file mode 100644 index 000000000..4a8c4de05 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png new file mode 100644 index 000000000..ec6365184 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png new file mode 100644 index 000000000..1487e20c6 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png new file mode 100644 index 000000000..8f9d61adb Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png new file mode 100644 index 000000000..a85064494 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png new file mode 100644 index 000000000..10256bae5 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png new file mode 100644 index 000000000..1a9ffefbb Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png new file mode 100644 index 000000000..2f11f3088 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png new file mode 100644 index 000000000..7d17ba4cf Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png new file mode 100644 index 000000000..a8e55e640 Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png new file mode 100644 index 000000000..0bfbd6a1f Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png new file mode 100644 index 000000000..88d4cc4ce Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png new file mode 100644 index 000000000..9ff7d8fda Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png new file mode 100644 index 000000000..4239eb31e Binary files /dev/null and b/docs/fr/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png differ diff --git a/docs/fr/technical/reference-architecture/boundedContexts/transfers/index.md b/docs/fr/technical/reference-architecture/boundedContexts/transfers/index.md new file mode 100644 index 000000000..6a2400106 --- /dev/null +++ b/docs/fr/technical/reference-architecture/boundedContexts/transfers/index.md @@ -0,0 +1,261 @@ +# BC Transferts + +Le BC Transferts est responsable de l'orchestration des demandes de transfert. Il fonctionne en concert avec plusieurs autres BCs, notamment Settlements, Scheduling, Participant Lifecycle Management, Accounts & Balances, ainsi que le FSPIOP. + +## Termes + +Les termes suivants sont utilisés dans ce BC, également appelé domaine. + +| Terme | Description | +|---|---| +| **Comptes** | Désigne les comptes utilisés dans toutes les activités de transfert. Ils servent à enregistrer les positions créditrices et débitrices, soit de manière temporaire dans le cas des comptes alloués spécifiquement pour les transferts, soit de façon permanente dans le cas des mises à jour finales sur les comptes des participants. | +| **Participant/Acteur** | Désigne généralement les parties DFSP Payer/Payee utilisant Mojaloop. | +| **IGS** | Méthode de règlement des transferts - Règlement Brut Immédiat (Immediate Gross Settlement). Ce processus est typiquement utilisé dans les environnements à haut volume comme le commerce de détail, et s’applique aux comptes individuels ou partagés. Dans le cas de comptes partagés, le système met à jour les soldes des Participants en modifiant la valeur proportionnelle des fonds détenus par chaque Participant sur le total disponible du compte. | +| **DNS** | Méthode de règlement des transferts - Règlement Net Différé (Deferred Net Settlement). Ce processus est fréquemment utilisé dans les environnements où un groupe de Participants réalise un transfert nécessitant un règlement global entre eux. Par exemple, lorsque des matières premières sont vendues par le Participant A au Participant B pour être transformées en produits finis, puis revendues par le Participant B au Participant A. Le switch calcule alors la valeur proportionnelle due à chaque Participant de la transaction, et effectue le règlement à la clôture de la fenêtre de règlement. | + +## Vue Fonctionnelle - Transferts - Bulk + +![Vue Fonctionnelle - Transferts - Bulk](./assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png) +>Diagramme de flux UC : Vue Fonctionnelle - Transferts - Bulk + +## Cas d’Utilisation + +### Effectuer un Transfert (mode universel) + +#### Description + +Le flux de ce cas d'utilisation (UC) permet au BC d’effectuer un transfert en utilisant une méthode qui exclut l’intervention de l’Actor. + +#### Diagramme de flux + +![Effectuer un Transfert (Mode Universel)](./assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert (Mode Universel) + +### Effectuer un Transfert avec Confirmation du Payee + +#### Description + +Le flux de ce cas d’utilisation permet au BC d’effectuer un transfert via une méthode incluant l’intervention de l’Actor. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert avec Confirmation du Payee](./assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png) +>Diagramme de flux UC : Effectuer un Transfert avec Confirmation du Payee + +### Requête (GET) Transfert + +#### Description + +Le flux de ce cas d’utilisation permet au BC de fournir un mécanisme permettant à un Participant d’interroger l’état d’un transfert. + +#### Diagramme de flux + +![Cas d’utilisation - Requête (GET) Transfert](./assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png) +>Diagramme de flux UC : Requête (GET) Transfert + +### Effectuer un Transfert – Duplicate POST (Réémission) + +#### Description + +Le flux de ce cas d’utilisation permet au BC de traiter une demande de transfert dupliquée. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert – Duplicate POST (Réémission)](./assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert – Duplicate POST (Réémission) + +### Effectuer un Transfert – Duplicate POST (Ignorer) + +#### Description + +Le flux de ce cas d’utilisation permet au BC d’ignorer une demande de transfert dupliquée. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert – Duplicate POST (Ignorer)](./assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert – Duplicate POST (Ignorer) + +## Variantes des cas d’utilisation (hors scénario nominal) + +### Effectuer un Transfert - PayeeFSP Rejette le Transfert + +#### Description + +Le flux de ce cas d’utilisation permet au BC de terminer une demande de transfert rejetée par le Payee. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - PayeeFSP Rejette le Transfert](./assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - PayeeFSP Rejette le Transfert + +### Effectuer un Transfert - Timeout (Prepare) + +#### Description + +Ce flux permet au BC de terminer une demande de préparation de transfert lorsque le seuil de délai d’attente est dépassé. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Timeout (Prepare)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Timeout (Prepare) + +### Effectuer un Transfert - Timeout (Pre-Committed) + +#### Description + +Ce flux permet au BC de terminer une demande de transfert pré-engagée (pre-committed) dépassant le délai. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Timeout (Pre-Committed)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png) +>Diagramme de flux UC : Effectuer un Transfert - Timeout (Pre-Committed) + +### Effectuer un Transfert - Timeout (Post-Committed) + +#### Description + +Ce flux permet au BC de terminer une demande de transfert post-engagée (post-committed) dont le délai est dépassé. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Timeout (Post-Committed)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Timeout (Post-Committed) + +### Effectuer un Transfert - Duplicate POST (Aucune Correspondance) + +#### Description + +Ce flux permet au BC de terminer une demande de transfert dupliquée ne correspondant à aucune transaction existante, lorsqu’un timeout survient. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Duplicate POST (Aucune Correspondance)](./assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Duplicate POST (Aucune Correspondance) + +### Effectuer un Transfert - Liquidité Insuffisante du Payer FSP + +#### Description + +Ce flux permet au BC de décliner une demande de transfert échouée car le Payer ne dispose pas d’assez de liquidités pour couvrir la transaction. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Liquidité Insuffisante du Payer FSP](./assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Liquidité Insuffisante du Payer FSP + +### Effectuer un Transfert - Échec de Validation lors de la Préparation (Payer Participant invalide) + +#### Description + +Ce flux permet au BC de mettre fin à une demande de préparation de transfert qui échoue lors de la validation, du fait d’un Payer Participant invalide ou inexistant. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Échec de Validation lors de la Préparation (Payer Participant invalide)](./assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Échec de Validation lors de la Préparation (Payer Participant invalide) + +### Effectuer un Transfert - Échec de Validation lors de la Préparation (Payee Participant invalide) + +#### Description + +Ce flux permet au BC de terminer une demande de préparation qui échoue car le Payee Participant n'est pas valide ou inexistant. + +#### Diagramme de flux + +![Cas d’utilisation - Effectuer un Transfert - Échec de Validation lors de la Préparation (Payee Participant invalide)](./assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png) +>Diagramme de flux UC : Effectuer un Transfert - Échec de Validation lors de la Préparation (Payee Participant invalide) + +### Requête (GET) Transfert - Échec de Validation (Payer Participant invalide) + +#### Description + +Ce flux permet au BC de terminer une requête d’état de transfert lorsque la validation échoue en raison d’un Payer Participant invalide ou inexistant. + + + +### Requête (GET) Transfert - Échec de Validation (Payee Participant invalide) + +#### Description + +Ce flux permet au BC de terminer une requête d’état de transfert lorsque la validation échoue à cause d’un Payee Participant invalide ou inexistant. + + + +### Requête (GET) Transfert - Échec de Validation (Identifiant de Transfert Introuvable) + +#### Description + +Ce flux permet au BC de terminer une requête d’état de transfert lorsque la validation échoue en raison d’un identifiant de transfert introuvable. + + + +## Modèle Canonique + +Mojaloop utilise deux modèles canoniques pour gérer les transferts de fonds : un pour les transferts simples (hors bulk) et un pour les transferts groupés (bulk). + +### Modèle Canonique Standard + +* Transfert + * transferId + * transferType + * quoteld (optionnel) + * settlementModelId + * Participants + * Payer + * participantId + * Comptes + * Debit + * accountId + * accountType + * devise (currency) + * Credit + * accountId + * accountType + * devise (currency) + * Payee + * participantId + * Comptes + * Debit + * accountId + * accountType + * devise (currency) + * Credit + * accountId + * accountType + * devise (currency) + * Montant (montant à transférer) + * value (nombre) + * devise (code de devise ISO) + * expiration (dateTime ISO) + * ilpPacket + * Extensions + +### Modèle Canonique Bulk + +* Transferts + * bulkId + * bulkQuoteId + * Transferts[] + * Transfert* (voir ci-dessus) + +## Commentaires Finaux + +* Le Payer FSP ne doit pas être autorisé à forcer unilatéralement le timeout d’un transfert (peu importe son délai d’expiration), mais doit respecter les décisions de timeout du Switch. +* La validation des conditions cryptographiques et accomplissements (fulfillments) serait gérée par le BC Transferts car il s’agit d’une composante fondamentale du « processus de transfert » (c’est-à-dire : cette fonction n’est pas spécifique au langage FSPIOP). +* Le BC Transferts appliquera le même modèle de validation que le Quoting & Party BC pour valider les Participants, pour déterminer la capacité d’un compte à effectuer une transaction, ou si un Participant est activé en mode exclusif. +* Le BC Transferts est l’unique « source de vérité » pour tous les transferts, il est donc responsable de la persistance de l’état des transferts. +* Désactiver des Participants déjà dans un état « préparé » ne doit pas empêcher le traitement des transferts en cours. Néanmoins, toute nouvelle instruction de transfert reçue par le BC Transferts via des événements TransferPrepareAccountAllocated doit être refusée. + + + + +[^1]: Interfaces communes : [Liste des interfaces communes Mojaloop](../../commonInterfaces.md) diff --git a/docs/fr/technical/reference-architecture/furtherReading/README.md b/docs/fr/technical/reference-architecture/furtherReading/README.md new file mode 100644 index 000000000..4cf188159 --- /dev/null +++ b/docs/fr/technical/reference-architecture/furtherReading/README.md @@ -0,0 +1,55 @@ +# Pour aller plus loin + +## Ressources de l’équipe + +Lors des sessions de travail sur la planification de l’Architecture de Référence, l’équipe a utilisé différentes ressources pour construire et conserver un historique des discussions et construire les modèles de cas d’utilisation nécessaires afin de prendre en charge l’ensemble des exigences possibles des parties prenantes pour la nouvelle architecture. + +N’hésitez pas à consulter les ressources de l’équipe via les liens fournis. + +**P.S.** Une ressource que vous pourriez trouver particulièrement utile est Miro, où nous conservons un enregistrement de l’ensemble des cas d’utilisation de Bounded Context utilisés par le système. + +***Note :** Veuillez garder à l’esprit que le document d’Architecture de Référence est un document vivant et, en conséquence, il est mis à jour de temps en temps pour diverses raisons. Cela signifie que les ressources que nous avons partagées avec vous sont toujours utilisées et changeront occasionnellement.* + +| Ressource | Objectif | Lien/URL | +| --- | --- | --- | +| Miro | Création de diagrammes de flux de cas d’utilisation | [Miro - architecture de référence Mojaloop](https://miro.com/app/board/o9J_lJyA1TA=/) | +| Google Docs | Notes de travail de session pour l’équipe, fournissant des détails sur l’Architecture de Référence à inclure dans la proposition et la documentation d’introduction. | [Mojaloop 2.0 Reference Architecture Work Sessions](https://docs.google.com/document/d/1Nm6B_tSR1mOM0LEzxZ9uQnGwXkruBeYB2slgYK1Kflo/edit#heading=h.vymmtvqaio5b) | +| Google Sheets | Registre des interfaces courantes utilisées dans l’architecture du Switch, ainsi que divers autres éléments. | [Mojaloop 2.0 Reference Architecture](https://docs.google.com/spreadsheets/d/1ITmAesHjRZICC0EUNV8vUVV8VDnKLjbSKu_dzhEa5Fw/edit#gid=1810993431) + +## Articles et documents de référence + +Les ressources ci-dessous ont été sourcées pour offrir un éclairage supplémentaire sur les modèles d’architecture ayant été mis en œuvre. + +| Ressource | Détails | +| --- | --- | +|[*Domain-Driven Design*, de Wikipédia, l’encyclopédie libre](https://en.wikipedia.org/wiki/Domain-driven_design) | Éditeur : Wikipédia, l’encyclopédie libre ; Auteur : Communauté ; Date : non spécifiée ; ±7 min de lecture | +| [*Domain, Subdomain, Bounded Context, Problem/Solution Space in DDD: Clearly Defined*](https://medium.com/nick-tune-tech-strategy-blog/domains-subdomain-problem-solution-space-in-ddd-clearly-defined-e0b49c7b586c) | Éditeur : Medium.com ; Auteur : Nick Tune ; Date : 11/07/2020 ; ±7 min de lecture | +| [*Strategic Domain-Driven Design*](https://microservices.io/patterns/decomposition/decompose-by-subdomain.html) | Éditeur : Vaadin.com ; Auteur : Petter Holmstrom | +| [*Pattern: Decompose by Subdomain Context*](https://microservices.io/patterns/decomposition/decompose-by-subdomain.html) | Éditeur : Microservices Architecture ; Auteur : Chris Richardson | +| [*Rest API Tutor*](https://www.restapitutorial.com/) | Éditeur : Auto-publié ; Auteur : Todd Fredrich ; Licence : [Creative Commons Attribution ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) | +| [*Use Case*, de Wikipédia, l’encyclopédie libre](https://en.wikipedia.org/wiki/Use_case) | En bref, et pour reprendre le résumé introductif de l’article Wikipédia, un cas d’utilisation est une liste d’actions ou d’étapes, généralement définissant les interactions entre un rôle (connu dans le Unified Modeling Language (UML) sous le nom d’acteur) et un système afin d’atteindre un objectif. L’acteur peut être un humain ou un autre système externe. En ingénierie système, les cas d’utilisation sont utilisés à un niveau plus élevé que dans l’ingénierie logicielle, représentant souvent des missions ou des objectifs des parties prenantes. Les exigences détaillées peuvent ensuite être capturées dans le Systems Modeling Language (SysML) ou sous forme d’énoncés contractuels. | + +## Réunions d’itération de projet + +Les ressources ci-dessous sont des inclusions aux Réunions Techniques de Mojaloop par l’équipe d’Architecture de Référence à partir du début de l’année 2021. Les ressources incluent des notes, des diapositives et des enregistrements vidéo. + +| Itération de projet (PI) | Période | Description | Lien/URL | +| --- | --- | --- | --- | +| PI-13 | Janvier 2021 | Performance, évolutivité et mise à jour de l’architecture de Mojaloop | [PI-13 Diapositives et Enregistrement](https://community.mojaloop.io/t/mojaloop-performance-scalability-and-architecture-update/240) | +| PI-14 | Avril 2021 | Ouverture et Architecture de Référence Mojaloop et TigerBeetle | [Enregistrement PI-14 (YouTube)](https://www.youtube.com/watch?v=UHxULJXIzj8) | +| PI-15 | Juillet 2021 | architecture de référence v1.0 | [Ressources PI-15](https://mojaloopcommunitymeeting.us2.pathable.com/meetings/virtual/ookcbEc6aDZgwyo2n) / [Vidéothèque PI-15 (YouTube)](https://www.youtube.com/playlist?list=PLSamWCIlxVXujHm4CWfyl6uLzcXJE1Zi_) | +| PI-16 | Octobre 2021 | architecture de référence et mise à jour V2 | [Agenda PI-16](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/pi_16_october_2021) / [Vidéothèque PI-16](https://mojaloop.io/video/pi-16-mojaloop-community-meeting-technical-sessions-october-2021/) | +| PI-17 | Janvier 2022 | architecture de référence : Documentation et mises à jour v.Next | [Présentation Architecture de Référence PI-17 (YouTube)](https://youtu.be/kqbEVbglBEM) | + + \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/gettingStarted/README.md b/docs/fr/technical/reference-architecture/gettingStarted/README.md new file mode 100644 index 000000000..687ff3899 --- /dev/null +++ b/docs/fr/technical/reference-architecture/gettingStarted/README.md @@ -0,0 +1,6 @@ +# Getting Started + +To help get you started with the Mojaloop Reference Architecture, select which of the options below best suits your needs: + +1. [Sub-menu](./subMenu/) +2. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) diff --git a/docs/fr/technical/reference-architecture/gettingStarted/subMenu/README.md b/docs/fr/technical/reference-architecture/gettingStarted/subMenu/README.md new file mode 100644 index 000000000..ffdfdf924 --- /dev/null +++ b/docs/fr/technical/reference-architecture/gettingStarted/subMenu/README.md @@ -0,0 +1,11 @@ +# Sub Menu + +Some text. + +## Sub title 1 + +Some more text. + +## Sub title 2 + +Some more text. diff --git a/docs/fr/technical/reference-architecture/glossary/README.md b/docs/fr/technical/reference-architecture/glossary/README.md new file mode 100644 index 000000000..ebf7390bd --- /dev/null +++ b/docs/fr/technical/reference-architecture/glossary/README.md @@ -0,0 +1,14 @@ +# TBD Placeholder + + \ No newline at end of file diff --git a/docs/fr/technical/reference-architecture/howToImplement/README.md b/docs/fr/technical/reference-architecture/howToImplement/README.md new file mode 100644 index 000000000..cd51378ea --- /dev/null +++ b/docs/fr/technical/reference-architecture/howToImplement/README.md @@ -0,0 +1,2 @@ +# TBD Placeholder for vNext Implementation architecture + diff --git a/docs/fr/technical/reference-architecture/index.md b/docs/fr/technical/reference-architecture/index.md new file mode 100644 index 000000000..98f223627 --- /dev/null +++ b/docs/fr/technical/reference-architecture/index.md @@ -0,0 +1,17 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: This is the official Reference Architecture documentation for the Mojaloop project. + + +actionText: Introduction → +actionLink: /introduction/ + +features: +- title: What it is + details: In a software system, a Reference Architecture is a set of software design documents, that capture the essence of the product and provide guidance to its technical evolution. The Reference Architecture is the architectural vision of the perfect design. +- title: Objectives + details: Identify abstractions, interfaces and standardization opportunities; Solutions and patterns to common problems; Enforces technical design principles; Provides guidance to the implementation architectures; Foster's innovation and contribution, by defining what can be done and how +- title: Benefits + details: Foundation for a Technical Roadmap; Guidance to decision-making regarding technology choices and implementation strategies; Alignment between technical vision and product vision +--- diff --git a/docs/fr/technical/reference-architecture/introduction/assets/process.png b/docs/fr/technical/reference-architecture/introduction/assets/process.png new file mode 100644 index 000000000..55e8cf7ed Binary files /dev/null and b/docs/fr/technical/reference-architecture/introduction/assets/process.png differ diff --git a/docs/fr/technical/reference-architecture/introduction/index.md b/docs/fr/technical/reference-architecture/introduction/index.md new file mode 100644 index 000000000..d173b0b0b --- /dev/null +++ b/docs/fr/technical/reference-architecture/introduction/index.md @@ -0,0 +1,109 @@ +# Introduction + +## Qu'est-ce qu'une Architecture de Référence ? + +Dans un système logiciel, l’Architecture de Référence est un ensemble de documents de conception logicielle qui saisissent l’essence du produit et fournissent des indications pour son évolution technique. + +Ce concept peut être simplifié ainsi : + +_**L’Architecture de Référence représente la vision architecturale du design parfait.**_ + +Dans des conditions normales, ce design parfait n’est jamais réellement atteint, en partie car il n’y a ni suffisamment de temps, ni de ressources pour le mettre pleinement en œuvre, en partie car cette conception évolue et s’améliore plus vite qu’elle ne peut être réalisée. +Il est donc dans la nature d’une Architecture de Référence d’être un document vivant, continuellement mis à jour et enrichi. + +## Quels sont les objectifs de l’Architecture de Référence ? + +Les objectifs principaux de l’Architecture de Référence sont : + +* Identifier les abstractions, interfaces et opportunités de standardisation +* Proposer des solutions et des modèles à des problèmes courants +* Aider à l’application des principes de conception technique +* Fournir des orientations pour les architectures d’implémentation +* Favoriser l’innovation et la contribution, en définissant ce qui peut être fait et comment + +## Quels sont les bénéfices d’une Architecture de Référence ? + +Le premier bénéfice est qu’elle constitue la fondation idéale pour une Feuille de Route Technique. En ayant la vision future à l’esprit, on peut facilement créer une feuille de route technique par étapes, garantissant que les ressources et l’attention sont concentrées sur la valeur à long terme. + +Un autre avantage important concerne les orientations qu’elle donne pour la prise de décision en matière de choix technologiques et de stratégies d’implémentation. +Avec l’Architecture de Référence en tête, toute décision de développement peut être qualifiée de tactique ou de stratégique : + +* Tactique – ce qui est nécessaire immédiatement et qui peut faire l’objet d’exceptions à l’Architecture de Référence en raison d’un besoin urgent à forte valeur. Ces exceptions doivent être documentées en tant que dette technique pouvant être traitée ultérieurement. +* Stratégique – ce qui a vocation à durer et devrait être mis en œuvre conformément à l’Architecture de Référence, afin de s’en rapprocher. + +Enfin, et ce n’est pas moins important, elle assure l’alignement entre la vision technique et la vision produit, essentielle (voir ci-dessous concernant le processus et les modes de fonctionnement). + +## Processus de création et de maintien de l’Architecture de Référence + +Lors de la création de la version initiale de l’Architecture de Référence, l’équipe a suivi les étapes suivantes : + +1. Cartographie de l’Espace Problème – Documenter les différents domaines et sous-domaines de problèmes, ainsi que leur classification selon leur importance. +2. Cartographie du Contexte de l’Espace Solution – Regrouper les problèmes similaires selon leur objectif et contexte. +3. Cartographie individuelle des cas d’utilisation – Discuter et documenter les cas d’utilisation en détail, en tenant compte de l’ensemble de la solution. + +## Comment garder une Architecture de Référence à jour ? + +Le schéma ci-dessous illustre où se situe une architecture de référence par rapport aux autres processus de la plateforme Mojaloop ; ce qu’elle doit intégrer et comprendre, non seulement la vision et les principes, mais aussi les exigences, l’expérience passée et même favoriser l’innovation technique. + +![Effectuer un transfert (mode universel)](./assets/process.png) +> Introduction (Mojaloop 2.0 Reference Architecture): Comment garder l’Architecture de Référence à jour + + +## Principes guidant cette architecture + +La conception de l’Architecture de Référence Mojaloop 2.0 s’appuie sur les principes du Domain-Driven Design[^1], et s’inspire également des principes de SOLID[^2] pour la programmation orientée objet, notamment le principe de responsabilité unique (SRP). + +Pour expliquer comment l’architecture est interprétée par Mojaloop, nous incluons un bref aperçu de l’architecture du Domain-Driven Design. + +### Vue d’ensemble de l’architecture inspirée par le DDD + +L’implémentation de l’architecture inspirée du DDD pour Mojaloop inclut les concepts suivants : + +* **Espace Problème** — Typiquement, l’architecture DDD reconnaît les besoins métiers comme appartenant à des domaines distincts. Par exemple, un système eCommerce est vu comme un **_Domaine_**. Mais un système eCommerce possède plusieurs composants : gestion des stocks, panier d’achat, commande, etc. Chaque composant est classé en tant que **_Sous-domaine_**, qui apporte de la valeur au domaine, ici le système eCommerce. Mojaloop utilise un seul domaine : c’est un switch. + + L’Espace Problème est l’un des deux conteneurs où sont regroupés tous les problèmes métier identifiés (améliorations/services) à résoudre. Selon la complexité du problème métier (amélioration) ou la multiplicité des problèmes à résoudre, il est possible de faire évoluer la structure initiale des sous-domaines. Chaque problème est alors assigné à son propre sous-domaine. Il convient cependant de s’assurer de la nécessité de chaque sous-domaine, et de se concentrer uniquement sur ceux qui apportent de la valeur, afin d’éviter une multiplication inutile et confuse de sous-domaines dans l’Espace Problème. + + Ce cloisonnement des améliorations/services dans des sous-domaines séparés permet à différentes équipes de travailler sur des parties gérables du système, ce qui est plus efficace et moins risqué que de construire un système monolithique. Un avantage significatif de cette méthode est que le processus de développement tout entier peut ainsi être centré sur l’amélioration continue et la création de valeur pour la plateforme, plutôt que sur l’ajout de fonctions isolées. + + Typiquement, l’Espace Problème comprend trois grands types de conteneurs qui déterminent comment ou par quoi un problème peut être résolu, auxquels un quatrième a été ajouté pour les exigences non fonctionnelles (NFRs) : + + * Cœur — solutions nécessitant un développement interne pour leur mise en œuvre. + * Soutien (Supporting) — solutions pouvant être implémentées grâce à des produits du marché prêts à l’emploi : par exemple, connexion sécurisée. + * Générique — solutions pouvant s’appuyer sur des produits du marché, mais nécessitant du développement supplémentaire : par exemple, reporting ou authentification. + * Exigences Non Fonctionnelles (NFRs) — solutions nécessaires pour répondre à des besoins communs, sans apporter de valeur directe au produit. + +* **Espace Solution** — Le second grand pilier de l’architecture DDD est « l’Espace Solution ». Contrairement à l’Espace Problème, il ne s’intéresse pas à quoi résoudre, mais à comment résoudre un problème (amélioration/service), et comment les différentes solutions s’articulent entre elles. L’Espace Solution inclut donc nécessairement davantage d’informations et de détails techniques sur la manière de résoudre les problèmes. + + * L’Espace Solution introduit un certain nombre d’éléments pour faciliter et harmoniser les efforts de résolution des problèmes. + + * Les Contextes Délimités (« Bounded Contexts ») servent à regrouper des ensembles cohérents de solutions partageant leur propre langage. + + Bien souvent, la correspondance entre les Contextes Délimités et les Sous-domaines n’est pas univoque. Les Sous-domaines appartiennent à l’Espace Problème et les Contextes Délimités à l’Espace Solution ; il se peut donc qu’un Sous-domaine soit adressé par plusieurs Contextes Délimités, ou qu’un Contexte Délimité couvre plusieurs Sous-domaines. + + En général — et c’est vrai dans l’environnement Mojaloop — les solutions sont conçues et mises en œuvre sans connaître les dépendances d’infrastructure spécifiques ou le fonctionnement interne des autres Contextes Délimités. Cette approche favorise notamment la sécurité, en s’assurant que chaque Contexte Délimité ne connaît que son propre environnement et ses interfaces. Les échanges entre Contextes Délimités s’effectuent exclusivement via des API et des messages sécurisés. Des exemples de Contextes Délimités (CD) dans Mojaloop incluent : Comptes & Soldes, Virements & Transactions, etc. + +* **_Langage Ubiquitaire_** — c’est une approche encourageant l’utilisation d’un langage explicite et compris de tous, lors de la description des problèmes et solutions, de l’utilisateur final au développeur. Deux objectifs principaux au langage ubiquitaire : + + 1. S’assurer que les termes uniques sont identifiés et compris dans un même sens par toutes les parties au sein de leur Contexte Délimité. Par exemple, le terme « Compte » : il peut signifier un profil de compte pour l’un, et un compte du système comptable pour un autre. Il ne s’agit pas ici de chercher un langage universel pour tout le projet ou l’organisation, ce qui serait illusoire : il s’agit de s’assurer que chaque Contexte Délimité possède son jeu de termes parfaitement définis et partagés. + 2. Faire en sorte que ces termes soient utilisés partout : de l’interface utilisateur à la documentation, dans tous les supports du projet, et même dans le code. L’usage ubiquitaire des mêmes termes garantit la compréhension commune des problèmes et solutions décrits et résolus. + +* **_Préoccupations Transversales_**[^3] — Ce sont des aspects de la solution logicielle nécessitant une résolution dans plusieurs Contextes Délimités (ou fonctions/modules), tels que l’audit, la sécurité, l’authentification, ou la gestion de la configuration de la plateforme (métier et technique). Dans notre approche, ces préoccupations transversales sont séparées des Contextes Délimités. La plupart ont une nature distribuée, avec des composants centraux et des bibliothèques clientes. Elles sont représentées dans cette documentation comme l’équivalent des Contextes Délimités. + +### Principes SOLID + +En complément de l’architecture DDD, l’approche architecturale de Mojaloop s’inspire aussi des principes SOLID : + +* Responsabilité unique et interfaces internes permettant d’implémenter des domaines additionnels, comme ISO, sans modifier l’architecture principale +* Les entités logicielles doivent être étendues mais jamais modifiées. La règle : ne jamais modifier le cœur, toujours étendre via des modules ou nœuds additionnels +* Les fonctions utilisant des références à des classes de base doivent pouvoir utiliser des objets issus des classes dérivées sans le savoir +* Plusieurs interfaces client spécifiques valent mieux qu’une seule interface fourre-tout +* Bâtir les dépendances sur les abstractions, jamais sur les implémentations concrètes + + +### Notes + +[^1]: Pour aller plus loin : [Domain-driven design sur Wikipedia, l’encyclopédie libre](https://en.wikipedia.org/wiki/Domain-driven_design) + +[^2]: Pour aller plus loin : [SOLID sur Wikipedia, l’encyclopédie libre](https://en.wikipedia.org/wiki/SOLID) + +[^3]: Pour aller plus loin : [Préoccupation transversale](https://en.wikipedia.org/wiki/Cross-cutting_concern#:~:text=Cross%2Dcutting%20concerns%20are%20parts,oriented%20programming%20or%20procedural%20programming.) – Éditeur : Wikipedia, l’encyclopédie libre diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png new file mode 100644 index 000000000..6402dc462 Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png new file mode 100644 index 000000000..17b11b5ab Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png new file mode 100644 index 000000000..523373d7a Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png new file mode 100644 index 000000000..4034289ad Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png new file mode 100644 index 000000000..8ad905989 Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png new file mode 100644 index 000000000..5d2299425 Binary files /dev/null and b/docs/fr/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png differ diff --git a/docs/fr/technical/reference-architecture/refarch/index.md b/docs/fr/technical/reference-architecture/refarch/index.md new file mode 100644 index 000000000..3914d453f --- /dev/null +++ b/docs/fr/technical/reference-architecture/refarch/index.md @@ -0,0 +1,113 @@ +# Aperçu de l’Architecture de Référence Mojaloop + +## Espace Problème (_Identification des problèmes et cartographie_) + +Comme indiqué dans l’aperçu de l’architecture DDD, l’Espace Problème contient un certain nombre de conteneurs orientés solution identifiés par l’équipe d’architectes système, qui servent à catégoriser les sous-domaines où des problèmes (améliorations) ont été détectés. + +### Problèmes Cœur + +#### Description + +Un certain nombre de problèmes Cœur (améliorations) ont été identifiés par (Business/Développeurs/Business & Développeurs). Afin de mettre en œuvre ces améliorations, des équipes de développement « internes » seront chargées de développer les solutions requises. Généralement, les sous-domaines ainsi identifiés générèrent une valeur significative pour le système Mojaloop ; il est donc essentiel de s’assurer que les services qu’ils fournissent ne soient pas compromis. Les exemples de sous-domaines Cœur incluent : la gestion du cycle de vie des participants, le règlement et la planification. + +#### Carte à Haut Niveau + +![Core Problems](./assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png) +> Architecture de Référence (Mojaloop): Problèmes Cœur + +### Problèmes Génériques + +#### Description + +Un certain nombre de problèmes Génériques (améliorations) ont été identifiés par (Business/Développeurs/Business & Développeurs). Afin de les mettre en œuvre, des solutions du marché seront adoptées sans nécessiter de personnalisation supplémentaire. Une intégration avec Mojaloop sera cependant nécessaire. Les exemples de sous-domaines de problèmes génériques comprennent l’authentification, le FRMS et la surveillance de la plateforme. + +#### Carte à Haut Niveau + +![Generic Problems](./assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png) +> Architecture de Référence (Mojaloop): Problèmes Génériques + +### Problèmes de Support + +#### Description + +Un certain nombre de problèmes de Support (améliorations) ont été identifiés par (Business/Développeurs/Business & Développeurs). Pour les mettre en œuvre, des solutions du marché seront également adoptées, mais une personnalisation additionnelle sera demandée pour intégrer pleinement ces solutions au système Mojaloop et répondre aux problèmes identifiés. Exemples de sous-domaines Support : gestion des politiques d’accès, reporting et autorisation (vérification du contenu des politiques d’accès). + +#### Carte à Haut Niveau + +![Supporting Problems](./assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png) +> Architecture de Référence (Mojaloop): Problèmes de Support + +### Exigences Non Fonctionnelles + +#### Description + +Plusieurs exigences non fonctionnelles ont été identifiées par (Business/Développeurs/Business & Développeurs). Bien qu’elles n’ajoutent pas de valeur directe à Mojaloop, elles sont nécessaires pour répondre à certains problèmes (améliorations) métier. Par exemple, la sécurité n’occupe pas son propre sous-domaine : tous les sous-domaines du système devront inclure des éléments de code liés à la sécurité pour répondre à cette exigence, ou bien un service centralisé de gestion de la sécurité sera mis en place, permettant de gérer et de construire des profils de sécurité pour chaque sous-domaine, qui seront téléchargés lors de la jonction au Domaine ou à l’initialisation, et/ou poussés lors de mises à jour par le service central. + +#### Carte à Haut Niveau + +![Non-Functional Requirements](./assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png) +> Architecture de Référence (Mojaloop): Exigences Non Fonctionnelles + +### Nouveaux Problèmes et Non Classifiés (hors-domaine) + +#### Description + +Un certain nombre de nouveaux problèmes et problèmes non classifiés (hors-domaine) ont été identifiés à la fois par les équipes métiers et techniques. Dès que le métier et les architectes du système ont identifié la solution requise, ceux-ci seront classés dans l’un des conteneurs de problème et traités selon le processus associé. + +#### Carte à Haut Niveau + +![New & Unclassified Problems](./assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png) +> Architecture de Référence (Mojaloop): Nouveaux Problèmes et Problèmes Non Classifiés + +## Espace Solution (_Description haut niveau et cartographie du contexte_) + +#### Description + +L’Espace Solution défini par l’architecture DDD se concentre sur la manière dont les problèmes métier (améliorations) identifiés dans l’espace problème seront résolus. Par conséquent, il comprend nécessairement plus d’informations et de détails techniques que l’Espace Problème. Il inclut des éléments comme le langage ubiquitaire, les contextes délimités (« Bounded Contexts ») et les préoccupations transversales (« Cross-Cutting Concerns »). + +#### Carte à Haut Niveau + +![Solution Space](./assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png) +> Architecture de Référence (Mojaloop): Espace Solution + +### Langage Ubiquitaire + +#### Description + +Un défi auquel la plupart des équipes sont confrontées est de maintenir une compréhension claire des termes qui peuvent ne pas être uniques à un domaine particulier. Un exemple classique de terme non unique est « compte » : ce terme pourrait désigner un ensemble de comptes financiers, le profil d’une entité ou un identifiant de connexion. + +Comme indiqué dans l’introduction, le langage ubiquitaire sert à éliminer la confusion et la mauvaise communication entre les équipes métiers et techniques qui travaillent à la résolution d’un (groupe de) problème(s) métier. Bien qu’il soit possible que chaque Domaine/Sous-domaine contienne des termes non uniques, il est essentiel, dans chaque contexte particulier — pour l’architecture DDD, c’est-à-dire un contexte limité (« Bounded Context ») — que tous les termes y soient uniques, compris de tous les participants, et appliqués correctement. + +Pour plus d’informations et une description de chacun des termes uniques utilisés dans le domaine Mojaloop, veuillez consulter le [Glossaire](../glossary/README.md) annexé à ce document. + +### Contextes Délimités (« Bounded Contexts ») + +Les contextes délimités suivants ont été identifiés et mis en œuvre dans Mojaloop : + +> Il s'agit d'une description de haut niveau de chacun des contextes délimités qui ont été identifiés et inclus dans l’Architecture de Référence Mojaloop. Une vue détaillée figure dans la section [Contexte Délimité](../boundedContexts/index.md) de ce document. + +| Contexte Délimité | Objectif | Contexte Délimité | Objectif | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Règlements (Settlements) | Exécute les règlements
    Configure les modèles de règlement
    Calcule les règlements | Gestion du Cycle de Vie du Participant | Onboarding des participants
    Gestion du cycle de vie
    Self-service participant
    Interface self-service participant | +| Recherche & Découverte de Compte | Noyau Oracle interne
    Recherche/découverte de compte
    Traitement en masse
    Gestion des identifiants en double
    Connexions inter-schéma (y compris règlements) | Comptes & Soldes | Système d’enregistrement des activités financières et des soldes du participant DFSP | +| Transferts & Transactions | Traitement des transferts
    Vérification de la liquidité pour chaque transfert
    Transactions en masse
    Multi-devises, incluant les transactions multi-hop | Accord (Devis) | Accord/devis (cœur)
    Transactions de masse
    Multi-devises, incluant multi-hop
    Enforcement des règles schéma dans chaque Contexte Délimité | +| Planification | Planification des événements d’API selon le temps (cœur) | Notifications & Alertes | État de notification - priorisation & SLA (cœur)
    Gestion des triggers & alertes (cœur)
    Livraison notifications - priorité et SLA (générique) | +| API Interop des FSP | API externe ISO (masse ; API, callbacks déclenchés (transferts uniquement, manquant dans l’AS-IS actuel) | Paiements Initiés par Tiers | Liaison de compte PISP
    Gestion du consentement
    Initiation de paiement par un tiers (cœur) | +| API tiers | | API externe Mojaloop PISP
    API externe ISO PISP | | + +### Préoccupations Transversales (« Cross cutting concerns ») + +Les préoccupations transversales suivantes ont été identifiées dans Mojaloop : + +| Préoccupation Transversale (BC) | Objectif | +| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AuthZ & AuthN et Gestion des Identités BC | Gérer tous les aspects de l'authentification utilisateur/système (AuthN) et de l'autorisation (AuthZ). Les solutions prévues s’intègreront dans les catégories Générique et de Support. | +| Cryptographie BC | Gérer tous les services cryptographiques, notamment la gestion des clés, des certificats et des systèmes de stockage. Les solutions prévues relèvent de la catégorie Générique. | +| Reporting et Audit BC | Gérer tous les services d’audit et de reporting, notamment les rapports de conformité et d’assurance, journalisation d’événements judiciaires et KMS, accès et gestion des logs forensiques, monitoring des process et SLA, audit système. (Chaque Contexte contiendra des capacités d’audit. Le module Reporting & Auditing centralisera les logs de tous les contextes.) Solutions réparties dans les trois catégories problème. | +| Configuration Plateforme (Business) BC | Gérer le processus de gestion des règles/schémas (NB : leur enforcement reste dans chaque contexte), la gestion des schémas imposés, la gestion des applications, la sécurité, la gestion des identités et des accès (incluant la gestion des utilisateurs et des équipes), l’API bizops pour la gestion des consentements de liaison et la gestion des politiques d’accès. Concerné par tous les types de problèmes. | +| Gestion Technique de la Plateforme BC | Gérer la surveillance et la gestion de la plateforme. Solutions prévues dans la catégorie Générique. | + + + \ No newline at end of file diff --git a/docs/fr/technical/technical/account-lookup-service/README.md b/docs/fr/technical/technical/account-lookup-service/README.md new file mode 100644 index 000000000..7f58601b7 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/README.md @@ -0,0 +1,132 @@ +--- +version: 1.1 +sidebarTitle: Aperçu +--- + +# Service de recherche de compte - Account Lookup Service + +L'**Account Lookup Service** (**ALS**) ou **Service de recherche de compte** — *(voir la section `6.2.1.2`)* de la [spécification Mojaloop {{ $page.frontmatter.version }}](/api) — mets en œuvre les cas d’usage suivants : + +* Recherche de participant (*Participant Look-up*) +* Recherche de entité (*Party Look-up*) +* Gestion des informations du registre des participants + * Ajout d’informations au registre des participants + * Suppression d’informations du registre des participants + +Cas d’usage implémentés en sus pour l’exploitation du Hub : +* Opérations d’administration + * Gestion des informations de routage des endpoints Oracle + * Gestion des informations du routage des endpoints du *Switch* + +## 1. Considérations de conception + +### 1.1. Account Lookup Service (ALS) + +La conception de l’ALS fournit un composant générique central faisant partie du cœur Mojaloop. Il sert à fournir le routage et l’alignement sur la spécification de l’API Mojaloop. Il prend en charge plusieurs registres de recherche (*Oracles*). Cet ALS fournira une API d'administration pour configurer le routage/la configuration de chaque Oracle, de manière similaire à l'API du Central-Service pour la configuration des points de terminaison de routage DFSP par le Notification Handler (composant ML-API-Adapter). L’ALS est, à toutes fin utiles, un *switch* doté d'un stockage persistant des règles et de la configuration de routage. + +#### 1.1.1. Hypothèses + +* La conception de l'ALS ne prend en charge pour l'instant qu’un seul *switch*. +* La prise en charge de plusieurs *switch* utilisera le même mécanisme de résolution DNS que celui prévu pour les paiements transfrontaliers / réseaux (*Cross Border*). + +#### 1.1.2. Routage + +La configuration de routage repose sur les éléments suivants : + +* **PartyIdType** — voir la section `7.5.6` de la spécification Mojaloop +* **Currency** — voir la section `7.5.5` de la spécification Mojaloop. Code devise selon [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) sous forme de chaîne alphabétique de trois lettres. Ce champ est optionnel ; toutefois, l'indicateur `isDefault` doit être défini à `true` si la devise n'est pas fournie. +* **isDefault** — indicateur précisant qu'un Oracle donné est le fournisseur par défaut pour un **PartyIdType** spécifique. Plusieurs Oracles peuvent être définis comme « par défaut », mais il ne peut y avoir qu'un seul Oracle par défaut par **PartyIdType** donné. L’Oracle par défaut, pour un **PartyIdType** donné n’est séléctionné que si la requête initiale n’inclut pas de filtre de devise. + + +### 1.2. Oracle ALS + +L’Oracle ALS, peut être mis en œuvre comme **Service** ou **Adaptateur** (sémantique selon le cas — médiation = adaptateur, service = implémentation), fournit un registre de recherche avec des fonctionnalités similaires à celles des ressources `/participants` de l'API Mojaloop. Elle s'appuie cependant de manière souple sur la spécification ML API : son interface met en œuvre un modèle synchrone, ce qui réduit les exigences de corrélation et de persistance du modèle de *callback* asynchrone implémenté directement par la spécification ML API. Cela fournira à tous les services/adaptateurs Oracle ALS une interface standardisée, médiatisée par l'ALS. +Ce composant (ou les systèmes en back-end) assure aussi la persistance et la mise par défaut des détails des participants. + +## 2. Conception de la recherche de participants + +### 2.1. Vue d’ensemble de l’architecture +![Flux architectural Account-Lookup pour les participants](./assets/diagrams/architecture/arch-flow-account-lookup-participants.svg) + +_Note : le cas « recherche de participant » s’applique de la même façon à un cas d'usage initié par le bénéficiaire (Payee Initiated), par exemple les `transactionRequests`. La différence est que le bénéficiaire est l’initiateur dans le schéma ci-dessus._ + +### 2.2. Diagrammes de séquence + +#### 2.2.1. GET — Participants + +- [Diagramme de séquence GET — Participants](als-get-participants.md) + +#### 2.2.2. POST Participants + +- [Diagramme de séquence POST Participants](als-post-participants.md) + +#### 2.2.3. POST Participants (batch) + +- [Diagramme de séquence POST Participants (batch)](als-post-participants-batch.md) + +#### 2.2.4. DEL Participants + +- [Diagramme de séquence DEL Participants](als-del-participants.md) + +## 3. Conception de la recherche d'entités + +### 3.1. Vue d’ensemble de l’architecture +![Flux architectural Account-Lookup pour les parties](./assets/diagrams/architecture/arch-flow-account-lookup-parties.svg) + +### 3.2. Diagramme de séquence + +#### 3.2.1. GET — Parties + +- [Diagramme de séquence GET — Parties](als-get-parties.md) + +## 4. Conception de l’administration ALS + +### 4.1. Vue d’ensemble de l’architecture +![Flux architectural Account-Lookup — admin GET Oracles](./assets/diagrams/architecture/arch-flow-account-lookup-admin.svg) + +### 4.2. Diagrammes de séquence + +#### 4.2.1 GET Oracles + +- [Diagramme de séquence GET Oracles](als-admin-get-oracles.md) + +#### 4.2.2 POST Oracle + +- [Diagramme de séquence POST Oracle](als-admin-post-oracles.md) + +#### 4.2.3 PUT Oracle + +- [Diagramme de séquence PUT Oracle](als-admin-put-oracles.md) + +#### 4.2.4 DELETE Oracle + +- [Diagramme de séquence DELETE Oracle](als-admin-del-oracles.md) + +#### 4.2.5 DELETE cache d'endpoint + +- [Diagramme de séquence DELETE cache d'endpoint](als-del-endpoint.md) + +## 5. Conception de la base de données + +### 5.1. Schéma de base de données ALS + +#### Notes + +- `partyIdType` — valeurs initialement injectées selon la section _`7.5.6`_ de la [spécification Mojaloop {{ $page.frontmatter.version }}](../../api/README.md). +- `currency` — voir la section `7.5.5` de la spécification Mojaloop ; code selon [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). Optionnel ; et doit fournir une configuration « par défaut » si aucune devise n'est fournie, OU fournir une valeur par défaut si la devise est fournie mais que seule la configuration de point de terminaison « par défaut » existe. +- `endPointType` — identifiant du type d'endpoint (ex. `URL`) offrant la flexibilité nécessaire pour la prise en charge de futurs protocoles de transport. +- `migration*` — tables de métadonnées utilisées par le moteur du framework Knex. +- Un `centralSwitchEndpoint` doit être associé à l’`OracleEndpoint` par l’API de l'admin lors de l’insertion d’un nouvel enregistrement `OracleEndpoint`. S’il n’est pas fourni dans la requête API, il doit être défini par défaut. + +![MCD de l'Account Lookup Service](./assets/entities/AccountLookupService-schema.png) + +* [MCD Account Lookup Service (DBeaver)](./assets/entities/AccountLookupDB-schema-DBeaver.erd) +* [Export Account Lookup Service MySQL Workbench ](./assets/entities/AccountLookup-ddl-MySQLWorkbench.sql) + +## 6. Conception de l’Oracle ALS + +La conception et l'implémentation de l'Oracle sont spécifiques aux exigences de chaque Oracle. + +### 6.1. Spécification d’API + +Voir l'**API Oracle API** dans la section [Spécifications d’API](../../api/README.md#als-oracle-api). diff --git a/docs/fr/technical/technical/account-lookup-service/als-admin-del-oracles.md b/docs/fr/technical/technical/account-lookup-service/als-admin-del-oracles.md new file mode 100644 index 000000000..23275a7b9 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-admin-del-oracles.md @@ -0,0 +1,7 @@ +# DELETE Oracles + +Conception de la suppression d’un oracle (administration ALS). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-admin-get-oracles.md b/docs/fr/technical/technical/account-lookup-service/als-admin-get-oracles.md new file mode 100644 index 000000000..eb1b29ca5 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-admin-get-oracles.md @@ -0,0 +1,7 @@ +# GET Oracles + +Conception de la récupération des oracles (administration ALS). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-admin-post-oracles.md b/docs/fr/technical/technical/account-lookup-service/als-admin-post-oracles.md new file mode 100644 index 000000000..ed49381d4 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-admin-post-oracles.md @@ -0,0 +1,7 @@ +# POST Oracles + +Conception de la création d’un oracle (administration ALS). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-admin-put-oracles.md b/docs/fr/technical/technical/account-lookup-service/als-admin-put-oracles.md new file mode 100644 index 000000000..cf9724628 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-admin-put-oracles.md @@ -0,0 +1,7 @@ +# PUT Oracles + +Conception de la mise à jour d’un oracle (administration ALS). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-del-endpoint.md b/docs/fr/technical/technical/account-lookup-service/als-del-endpoint.md new file mode 100644 index 000000000..51337b0f6 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-del-endpoint.md @@ -0,0 +1,7 @@ +# DELETE cache de l'endpoint + +Conception de la suppression du cache de l'endpoint (administration ALS). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-del-participants.md b/docs/fr/technical/technical/account-lookup-service/als-del-participants.md new file mode 100644 index 000000000..f6c88ab3d --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-del-participants.md @@ -0,0 +1,11 @@ +# DEL Participants + +Conception de la suppression d’un participant par un DFSP. + +## Notes + +- Voir la section 6.2.2.4 — l’ALS doit vérifier que c’est bien le FSP actuel de la partie qui supprime l’information. C’est pris en compte dans la conception en s’assurant que la partie appartient au FSP qui demande la suppression. Les autres validations hors périmètre du *Switch* relèvent du schéma. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-get-participants.md b/docs/fr/technical/technical/account-lookup-service/als-get-participants.md new file mode 100644 index 000000000..796c0d698 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-get-participants.md @@ -0,0 +1,12 @@ +--- +sidebarTitle: GET — Participants +title: GET — Participants +--- + +# GET — Participants + +Conception de la récupération d’un participant par un DFSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-get-parties.md b/docs/fr/technical/technical/account-lookup-service/als-get-parties.md new file mode 100644 index 000000000..7cc5fec5d --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-get-parties.md @@ -0,0 +1,12 @@ +--- +sidebarTitle: GET — Parties +title: GET — Parties +--- + +# GET — Parties + +Conception de la récupération d’informations de partie (*Party*) par un DFSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-post-participants-batch.md b/docs/fr/technical/technical/account-lookup-service/als-post-participants-batch.md new file mode 100644 index 000000000..00c9d51cc --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-post-participants-batch.md @@ -0,0 +1,14 @@ +# Diagramme de séquence — POST Participants (batch) + +Conception de la création de participants par un DFSP via une requête groupée. + +## Notes + +- L’opération ne prend en charge que les requêtes où : + - tous les FSP des participants correspondent au `FSPIOP-Source` + - tous les participants partagent la même devise, conformément à l’appel `POST /participants` de l’[API FSPIOP Mojaloop](/api/fspiop/v1.1/api-definition.html#post-participants) +- Un second `POST` avec le même TYPE et une devise optionnelle correspondante est traité comme une **mise à jour** : l’enregistrement existant doit être **entièrement remplacé**. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg) diff --git a/docs/fr/technical/technical/account-lookup-service/als-post-participants.md b/docs/fr/technical/technical/account-lookup-service/als-post-participants.md new file mode 100644 index 000000000..671859421 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/als-post-participants.md @@ -0,0 +1,7 @@ +# POST Participant + +Conception de la création d’un participant par un DFSP via une requête. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg) diff --git a/assets/images/uml/.gitkeep b/docs/fr/technical/technical/account-lookup-service/assets/.gitkeep similarity index 100% rename from assets/images/uml/.gitkeep rename to docs/fr/technical/technical/account-lookup-service/assets/.gitkeep diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg new file mode 100644 index 000000000..d46ffa284 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service Admin
    (ALS)
    Account Lookup Service Adm...
    HUB
    Backend



    HUB...
    Account Lookup Admin
    Account Lookup Admin
    HUB Operator
    HUB Operator
    A1. Request Oracle Endpoints 
    GET /oracles
    A1. Requ...
    A1.3. Return List of Oracles
    A1.3. Re...
    ALS
    DB
    ALS...
    Key
    Key
    A1.2. Lookup All Oracle Registry Service End-points 
    API
    Internal Use-Only
    API...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg rename to docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg rename to docs/fr/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml new file mode 100644 index 000000000..55f213445 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' titre +title 7.3.4 Supprimer un endpoint d'oracle + +autonumber + + +' Clés des acteurs : +' boundary - API / interfaces, etc. +' control - Gestionnaire d’administration ALS +' database - persistance base de données + +' acteurs +entity "OPÉRATEUR DU HUB" as OPERATOR +boundary "API d’administration Account Lookup Service" as ALSADM +control "Gestionnaire DELETE Oracle" as ORC_HANDLER +database "Stockage ALS" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' flux + +activate OPERATOR +group Supprimer un endpoint d'oracle + OPERATOR -> ALSADM: Requête pour supprimer un endpoint d'oracle —\nDELETE /oracles/{ID} + activate ALSADM + + ALSADM -> ORC_HANDLER: Supprimer l'endpoint d'oracle + + activate ORC_HANDLER + ORC_HANDLER -> DB: Mettre à jour l'endpoint Oracle existant par ID + hnote over DB #lightyellow + Mettre isActive = false + end note + alt Suppression de l'endpoint Oracle existant (succès) + activate DB + DB -> ORC_HANDLER: Retour succès + deactivate DB + + ORC_HANDLER -> ALSADM: Retourner une réponse de succès + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Retour Statut HTTP : 204 + + deactivate ALSADM + deactivate OPERATOR + end + alt Suppression de l'endpoint Oracle existant (échec) + DB -> ORC_HANDLER: Lever une erreur (introuvable) + ORC_HANDLER -> ALSADM: Lever une erreur + note left of ALSADM #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Retour Statut HTTP : 502 + end +end + +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg new file mode 100644 index 000000000..3820f9d29 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg @@ -0,0 +1,111 @@ + + 7.3.4 Supprimer un endpoint d'oracle + + + 7.3.4 Supprimer un endpoint d'oracle + + Account Lookup Service + + + + + + + + + + + + OPÉRATEUR DU HUB + + + OPÉRATEUR DU HUB + + + API d’administration Account Lookup Service + + + API d’administration Account Lookup Service + + + Gestionnaire DELETE Oracle + + + Gestionnaire DELETE Oracle + + + Stockage ALS + + + Stockage ALS + + + + + + + + + Supprimer un endpoint d'oracle + + + 1 + Requête pour supprimer un endpoint d'oracle — + DELETE /oracles/{ID} + + + 2 + Supprimer l'endpoint d'oracle + + + 3 + Mettre à jour l'endpoint Oracle existant par ID + + Mettre isActive = false + + + alt + [Suppression de l'endpoint Oracle existant (succès)] + + + 4 + Retour succès + + + 5 + Retourner une réponse de succès + + + 6 + Retour + Statut HTTP : + 204 + + + alt + [Suppression de l'endpoint Oracle existant (échec)] + + + 7 + Lever une erreur (introuvable) + + + 8 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 9 + Retour + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml new file mode 100644 index 000000000..3427abbc2 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' titre +title 7.3.1 Obtenir tous les endpoints d'oracle + +autonumber + + +' Clés des acteurs : +' boundary - API / interfaces, etc. +' control - Gestionnaire d’administration ALS +' database - persistance base de données + +' acteurs +entity "OPÉRATEUR DU HUB" as OPERATOR +boundary "API d’administration Account Lookup Service" as ALSADM +control "Gestionnaire d’obtention des oracles" as ORC_HANDLER +database "Stockage ALS" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' flux + +activate OPERATOR +group Obtenir les endpoints d'oracle + OPERATOR -> ALSADM: Requête GET pour tous les endpoints d'oracle —\nGET /oracles?currency=USD&type=MSISDN + activate ALSADM + + ALSADM -> ORC_HANDLER: Obtenir les endpoints d'oracle + activate ORC_HANDLER + ORC_HANDLER -> DB: Lire les endpoints d'oracle + activate DB + + alt Obtenir les endpoints d’oracle (succès) + DB --> ORC_HANDLER: Retourner les endpoints d’oracle + deactivate DB + + deactivate DB + ORC_HANDLER -> ALSADM: Retourner les endpoints d’oracle + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message : + { + [ + { + "oracleId": , + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + ] + } + end note + ALSADM --> OPERATOR: Retour Statut HTTP : 200 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Obtenir les endpoints d’oracle (échec) + DB --> ORC_HANDLER: Lever une erreur + deactivate DB + ORC_HANDLER -> ALSADM: Lever une erreur + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Retour Statut HTTP : 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg new file mode 100644 index 000000000..cfb421a77 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg @@ -0,0 +1,126 @@ + + 7.3.1 Obtenir tous les endpoints d'oracle + + + 7.3.1 Obtenir tous les endpoints d'oracle + + Account Lookup Service + + + + + + + + + + + + OPÉRATEUR DU HUB + + + OPÉRATEUR DU HUB + + + API d’administration Account Lookup Service + + + API d’administration Account Lookup Service + + + Gestionnaire d’obtention des oracles + + + Gestionnaire d’obtention des oracles + + + Stockage ALS + + + Stockage ALS + + + + + + + + + Obtenir les endpoints d'oracle + + + 1 + Requête GET pour tous les endpoints d'oracle — + GET /oracles?currency=USD&type=MSISDN + + + 2 + Obtenir les endpoints d'oracle + + + 3 + Lire les endpoints d'oracle + + + alt + [Obtenir les endpoints d’oracle (succès)] + + + 4 + Retourner les endpoints d’oracle + + + 5 + Retourner les endpoints d’oracle + + + Message : + { + [ + { + "oracleId": <string>, + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + ] + } + + + 6 + Retour + Statut HTTP : + 200 + + + alt + [Obtenir les endpoints d’oracle (échec)] + + + 7 + Lever une erreur + + + 8 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 9 + Retour + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml new file mode 100644 index 000000000..a8a1578c1 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml @@ -0,0 +1,112 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' titre +title 7.3.2 Créer des endpoints d’oracle + +autonumber + + +' Clés des acteurs : +' boundary - API / interfaces, etc. +' control - Gestionnaire d’administration ALS +' database - persistance base de données + +' acteurs +entity "OPÉRATEUR DU HUB" as OPERATOR +boundary "API d’administration Account Lookup Service" as ALSADM +control "Gestionnaire POST Oracle" as ORC_HANDLER +database "Stockage ALS" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' flux + +activate OPERATOR +group Créer un l'endpoint d’oracle + OPERATOR -> ALSADM: Requête pour créer un l'endpoint d’oracle —\nPOST /oracles + note left of ALSADM #yellow + Message : + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Créer un l'endpoint d’oracle + + activate ORC_HANDLER + ORC_HANDLER -> ORC_HANDLER: Construire l’objet de données de l'endpoint Oracle + ORC_HANDLER -> DB: Insérer l’objet de données de l'endpoint Oracle + activate DB + + alt Création d’une entrée Oracle (succès) + DB --> ORC_HANDLER: Retourner une réponse de succès + deactivate DB + + ORC_HANDLER -> ALSADM: Retourner une réponse de succès + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Retour Statut HTTP : 201 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Création d’une entrée Oracle (échec) + DB --> ORC_HANDLER: Lever une erreur + deactivate DB + ORC_HANDLER -> ALSADM: Lever une erreur + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Retour Statut HTTP : 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg new file mode 100644 index 000000000..f3f1bf085 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg @@ -0,0 +1,127 @@ + + 7.3.2 Créer des endpoints d’oracle + + + 7.3.2 Créer des endpoints d’oracle + + Account Lookup Service + + + + + + + + + + + + OPÉRATEUR DU HUB + + + OPÉRATEUR DU HUB + + + API d’administration Account Lookup Service + + + API d’administration Account Lookup Service + + + Gestionnaire POST Oracle + + + Gestionnaire POST Oracle + + + Stockage ALS + + + Stockage ALS + + + + + + + + + Créer un l'endpoint d’oracle + + + 1 + Requête pour créer un l'endpoint d’oracle — + POST /oracles + + + Message : + { + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + + + 2 + Créer un l'endpoint d’oracle + + + + + 3 + Construire l’objet de données de l'endpoint Oracle + + + 4 + Insérer l’objet de données de l'endpoint Oracle + + + alt + [Création d’une entrée Oracle (succès)] + + + 5 + Retourner une réponse de succès + + + 6 + Retourner une réponse de succès + + + 7 + Retour + Statut HTTP : + 201 + + + alt + [Création d’une entrée Oracle (échec)] + + + 8 + Lever une erreur + + + 9 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 10 + Retour + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml new file mode 100644 index 000000000..2672d4bdb --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml @@ -0,0 +1,131 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' titre +title 7.3.3 Mettre à jour un l'endpoint d’oracle + +autonumber + + +' Clés des acteurs : +' boundary - API / interfaces, etc. +' control - Gestionnaire d’administration ALS +' database - persistance base de données + +' acteurs +entity "OPÉRATEUR DU HUB" as OPERATOR +boundary "API d’administration Account Lookup Service" as ALSADM +control "Gestionnaire PUT Oracle" as ORC_HANDLER +database "Stockage ALS" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' flux + +activate OPERATOR +group Mettre à jour un l'endpoint d’oracle + OPERATOR -> ALSADM: Requête pour mettre à jour un l'endpoint d’oracle —\nPUT /oracles/{ID} + note left of ALSADM #yellow + Message : + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Mettre à jour le l'endpoint d’oracle + + activate ORC_HANDLER + ORC_HANDLER -> DB: Trouver le l'endpoint Oracle existant + alt Trouver le l'endpoint Oracle existant (succès) + activate DB + DB -> ORC_HANDLER: Retourner le résultat de l'endpoint Oracle + deactivate DB + ORC_HANDLER -> ORC_HANDLER: Mettre à jour l’objet de données Oracle retourné + ORC_HANDLER -> DB: Mettre à jour l’objet de données Oracle + activate DB + alt Mise à jour d’une entrée Oracle (succès) + DB --> ORC_HANDLER: Retourner une réponse de succès + deactivate DB + + ORC_HANDLER -> ALSADM: Retourner une réponse de succès + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Retour Statut HTTP : 204 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Mise à jour d’une entrée Oracle (échec) + DB --> ORC_HANDLER: Lever une erreur + deactivate DB + ORC_HANDLER -> ALSADM: Lever une erreur + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Retour Statut HTTP : 502 + + deactivate ALSADM + deactivate OPERATOR + + + end + end + alt Trouver le l'endpoint Oracle existant (échec) + DB -> ORC_HANDLER: Retourne un objet vide + ORC_HANDLER -> ALSADM: Lever une erreur + note left of ALSADM #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Retour Statut HTTP : 502 + end +end + +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg new file mode 100644 index 000000000..ff4496610 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg @@ -0,0 +1,170 @@ + + 7.3.3 Mettre à jour un l'endpoint d’oracle + + + 7.3.3 Mettre à jour un l'endpoint d’oracle + + Account Lookup Service + + + + + + + + + + + + + + + OPÉRATEUR DU HUB + + + OPÉRATEUR DU HUB + + + API d’administration Account Lookup Service + + + API d’administration Account Lookup Service + + + Gestionnaire PUT Oracle + + + Gestionnaire PUT Oracle + + + Stockage ALS + + + Stockage ALS + + + + + + + + + + Mettre à jour un l'endpoint d’oracle + + + 1 + Requête pour mettre à jour un l'endpoint d’oracle — + PUT /oracles/{ID} + + + Message : + { + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + + + 2 + Mettre à jour le l'endpoint d’oracle + + + 3 + Trouver le l'endpoint Oracle existant + + + alt + [Trouver le l'endpoint Oracle existant (succès)] + + + 4 + Retourner le résultat de l'endpoint Oracle + + + + + 5 + Mettre à jour l’objet de données Oracle retourné + + + 6 + Mettre à jour l’objet de données Oracle + + + alt + [Mise à jour d’une entrée Oracle (succès)] + + + 7 + Retourner une réponse de succès + + + 8 + Retourner une réponse de succès + + + 9 + Retour + Statut HTTP : + 204 + + + alt + [Mise à jour d’une entrée Oracle (échec)] + + + 10 + Lever une erreur + + + 11 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 12 + Retour + Statut HTTP : + 502 + + + alt + [Trouver le l'endpoint Oracle existant (échec)] + + + 13 + Retourne un objet vide + + + 14 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 15 + Retour + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml new file mode 100644 index 000000000..c7587e3d3 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml @@ -0,0 +1,104 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' titre +title 7.3.0 Suppression du cache des endpoints + +autonumber + + +' Clés des acteurs : +' boundary - API / interfaces, etc. +' control - Gestionnaire d’API ALS +' database - persistance base de données + +' acteurs +entity "OPÉRATEUR DU HUB" as OPERATOR +boundary "API Account Lookup Service" as ALSAPI +control "Gestionnaire de suppression du cache" as DEL_HANDLER +database "Cache" as Cache + +box "Account Lookup Service" #LightYellow +participant ALSAPI +participant DEL_HANDLER +participant Cache +end box + +' flux + +activate OPERATOR +group Suppression du cache des endpoints + OPERATOR -> ALSAPI: Requête DELETE sur le cache des endpoints — DELETE /endpointcache + activate ALSAPI + activate ALSAPI + + ALSAPI -> DEL_HANDLER: Supprimer le cache + activate DEL_HANDLER + DEL_HANDLER -> Cache: Arrêter le cache + activate Cache + + + alt Statut d’arrêt du cache (succès) + Cache --> DEL_HANDLER: Retourner le statut + deactivate Cache + + DEL_HANDLER -> Cache: Initialiser le cache + activate Cache + Cache -> DEL_HANDLER: Retourner le statut + deactivate Cache + DEL_HANDLER -> ALSAPI: Retourner le statut + deactivate DEL_HANDLER + ALSAPI --> OPERATOR: Retour Statut HTTP : 202 + + deactivate ALSAPI + deactivate OPERATOR + end + + alt Validation du statut (échec du service) + Cache --> DEL_HANDLER: Lever une erreur + deactivate Cache + DEL_HANDLER -> ALSAPI: Lever une erreur + deactivate DEL_HANDLER + note left of ALSAPI #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSAPI --> OPERATOR: Retour Statut HTTP : 502 + + deactivate ALSAPI + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg new file mode 100644 index 000000000..4522a7775 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg @@ -0,0 +1,120 @@ + + 7.3.0 Suppression du cache des endpoints + + + 7.3.0 Suppression du cache des endpoints + + Account Lookup Service + + + + + + + + + + + + + + OPÉRATEUR DU HUB + + + OPÉRATEUR DU HUB + + + API Account Lookup Service + + + API Account Lookup Service + + + Gestionnaire de suppression du cache + + + Gestionnaire de suppression du cache + + + Cache + + + Cache + + + + + + + + + + + Suppression du cache des endpoints + + + 1 + Requête DELETE sur le cache des endpoints — DELETE /endpointcache + + + 2 + Supprimer le cache + + + 3 + Arrêter le cache + + + alt + [Statut d’arrêt du cache (succès)] + + + 4 + Retourner le statut + + + 5 + Initialiser le cache + + + 6 + Retourner le statut + + + 7 + Retourner le statut + + + 8 + Retour + Statut HTTP : + 202 + + + alt + [Validation du statut (échec du service)] + + + 9 + Lever une erreur + + + 10 + Lever une erreur + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 11 + Retour + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml new file mode 100644 index 000000000..0a2660601 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' déclaration du titre +title 7.1.2. Supprimer les détails du participant + +autonumber +' Légendes des Acteurs : +' boundary - APIs/Interfaces, etc. +' entity - Objets d'accès à la base de données +' database - Stockage en base de données + +' Déclaration des acteurs +actor "PSF Payeur" as PAYER_FSP +actor "PSF Bénéficiaire" as PAYEE_FSP +boundary "Service de Recherche de Compte\n(ALS)" as ALS_API +control "Gestionnaire des Participants\nALS" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +entity "ALS Participant Endpoint\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "Base de Données ALS" as ALS_DB +boundary "API du Service Oracle" as ORACLE_API +boundary "API du Service Central" as CENTRALSERVICE_API + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYER_FSP +end box + +box "Service de Recherche de Compte" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Services Centraux" #LightGreen +participant CENTRALSERVICE_API +end box + +box "Service/Adaptateur Oracle ALS" #LightBlue +participant ORACLE_API +end box + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYEE_FSP +end box + +' DÉBUT DU FLUX + +group Obtenir les détails du participant + PAYER_FSP ->> ALS_API: Demande de suppression des détails du participant\nDEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 202\nCode erreur : 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Valider la requête par rapport + à la Spécification d'Interface Mojaloop. + Code erreur : 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Demande de suppression des détails du participant + + alt correspondance de l'oracleEndpoint trouvée et informations sur les parties récupérées + activate ALS_PARTICIPANT_HANDLER + '********************* Récupérer la configuration de routage Oracle - DÉBUT ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la configuration de routage Oracle\nCode erreur : 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Séquence d'obtention de la configuration de routage Oracle]] + ||| + end ref + '********************* Récupérer la configuration de routage Oracle - FIN ************************ + ||| + '********************* Récupérer la configuration de routage Switch - DÉBUT ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la configuration de routage Switch\nCode erreur : 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Séquence d'obtention de la configuration de routage Switch]] +' ||| +' end ref + '********************* Récupérer la configuration de routage Switch - FIN ************************ + + ||| + + '********************* Valider le participant FSPIOP-Source - DÉBUT ************************ + group Valider le participant FSPIOP-Source + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Demande d'informations sur le participant FSPIOP-Source\nCode erreur : 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Retourner les informations du participant FSPIOP-Source + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Retourner les informations du participant FSPIOP-Source + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider le participant FSPIOP-Source\nCode erreur : 320x + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider que PARTICIPANT.fspId == FSPIOP-Source\nCode erreur : 3100 + end group + '********************* Valider le participant - FIN ************************ + + ||| + + '********************* Demande d'informations sur le participant Oracle - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Obtenir les informations du participant pour le PSF Payeur\nCode erreur : 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Séquence de demande d'informations sur le participant à Oracle]] + ||| + end ref + + '********************* Demande d'informations sur le participant Oracle - FIN ************************ + + ||| + + '********************* Valider la propriété du participant - DÉBUT ************************ + ' Voir section 6.2.2.4 - Remarque : L'ALS doit vérifier que c'est le PSF actuel de la Partie qui supprime les informations du PSF. Est-ce suffisant ? + group Valider la propriété du participant + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider que PARTICIPANT.fspId correspond à l'information du participant récupérée d'Oracle.\nCode erreur : 3100 + end group + '********************* Valider le participant - FIN ************************ + + ||| + + '********************* Supprimer les informations du participant Oracle - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Demande de suppression des détails FSP du participant DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode erreur : 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Demande de suppression des détails FSP du participant DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 200 \nCode erreur : 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Retour du résultat + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Retour du résultat + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Supprimer les informations du participant Oracle - FIN ************************ + ||| + + '********************* Obtenir les informations d’endpoint du participant PayerFSP - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint de rappel du participant PayerFSP\nCode erreur : 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint de rappel du participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Associer les endpoints de rappel du participant PayerFSP pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Obtenir les informations d’endpoint du participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Retour du résultat de la demande de suppression + ALS_API ->> PAYER_FSP: Rappel indiquant le succès :\nPUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + else Échec de la validation ou Oracle n'a pas pu traiter la demande de suppression + + '********************* Obtenir les informations d’endpoint du participant PayerFSP - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint de rappel du participant PayerFSP\nCode erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint de rappel du participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Associer les endpoints de rappel du participant PayerFSP pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Obtenir les informations d’endpoint du participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l’erreur\nCode erreur : 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Rappel : PUT - /participants/{TYPE}/{ID}/error + + else Liste vide de switchEndpoint renvoyée + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Gérer l’erreur\nCode erreur : 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Cadre de gestion des erreurs + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg new file mode 100644 index 000000000..8488d07d7 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg @@ -0,0 +1,353 @@ + + 7.1.2. Supprimer les détails du participant + + + 7.1.2. Supprimer les détails du participant + + Fournisseur de Services Financiers + + Service de Recherche de Compte + + Services Centraux + + Service/Adaptateur Oracle ALS + + Fournisseur de Services Financiers + + + + + + + + + + + + + + + + + + + + + + + + + + PSF Payeur + + + PSF Payeur + + + Service de Recherche de Compte + (ALS) + + + Service de Recherche de Compte + (ALS) + + + Gestionnaire des Participants + ALS + + + Gestionnaire des Participants + ALS + + + ALS Participant Endpoint + Oracle DAO + + + ALS Participant Endpoint + Oracle DAO + + + Base de Données ALS + + + Base de Données ALS + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + ALS Parties + FSP DAO + + + ALS Parties + FSP DAO + + + API du Service Central + + + API du Service Central + + + API du Service Oracle + + + API du Service Oracle + + + PSF Bénéficiaire + + + PSF Bénéficiaire + + + + + + + + + + + + + + + Obtenir les détails du participant + + + + 1 + Demande de suppression des détails du participant + DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code réponse&nbsp;: + 202 + Code erreur&nbsp;: + 200x, 300x, 310x, 320x + + + Valider la requête par rapport + à la Spécification d'Interface Mojaloop. + Code erreur&nbsp;: + 300x, 310x + + + 2 + Demande de suppression des détails du participant + + + alt + [correspondance de l'oracleEndpoint trouvée et informations sur les parties récupérées] + + + + 3 + Obtenir la configuration de routage Oracle + Code erreur&nbsp;: + 200x, 310x, 320x + + + ref + GET Participants - + Séquence d'obtention de la configuration de routage Oracle + + + + + + Valider le participant FSPIOP-Source + + + 4 + Demande d'informations sur le participant FSPIOP-Source + Code erreur&nbsp;: + 200x + + + 5 + GET - /participants/{FSPIOP-Source} + Code erreur&nbsp;: + 200x, 310x, 320x + + + 6 + Retourner les informations du participant FSPIOP-Source + + + 7 + Retourner les informations du participant FSPIOP-Source + + + + + 8 + Valider le participant FSPIOP-Source + Code erreur&nbsp;: + 320x + + + + + 9 + Valider que PARTICIPANT.fspId == FSPIOP-Source + Code erreur&nbsp;: + 3100 + + + + 10 + Obtenir les informations du participant pour le PSF Payeur + Code erreur&nbsp;: + 200x, 310x, 320x + + + ref + GET Participants - + Séquence de demande d'informations sur le participant à Oracle + + + + + + Valider la propriété du participant + + + + + 11 + Valider que PARTICIPANT.fspId correspond à l'information du participant récupérée d'Oracle. + Code erreur&nbsp;: + 3100 + + + 12 + Demande de suppression des détails FSP du participant DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code erreur&nbsp;: + 200x, 310x, 320x + + + 13 + Demande de suppression des détails FSP du participant DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code réponse&nbsp;: + 200 +   + Code erreur&nbsp;: + 200x, 310x, 320x + + + 14 + Retour du résultat + + + 15 + Retour du résultat + + + 16 + Récupérer l’endpoint de rappel du participant PayerFSP + Code erreur&nbsp;: + 200x + + + 17 + Récupérer l’endpoint de rappel du participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code erreur&nbsp;: + 200x, 310x, 320x + + + 18 + Liste des endpoints de rappel du participant PayerFSP + + + 19 + Liste des endpoints de rappel du participant PayerFSP + + + + + 20 + Associer les endpoints de rappel du participant PayerFSP pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 21 + Retour du résultat de la demande de suppression + + + + 22 + Rappel indiquant le succès&nbsp;: + PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + [Échec de la validation ou Oracle n'a pas pu traiter la demande de suppression] + + + 23 + Récupérer l’endpoint de rappel du participant PayerFSP + Code erreur&nbsp;: + 200x, 310x, 320x + + + 24 + Récupérer l’endpoint de rappel du participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse&nbsp;: + 200 + Code erreur&nbsp;: + 200x, 310x, 320x + + + 25 + Liste des endpoints de rappel du participant PayerFSP + + + 26 + Liste des endpoints de rappel du participant PayerFSP + + + + + 27 + Associer les endpoints de rappel du participant PayerFSP pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 28 + Gérer l’erreur + Code erreur&nbsp;: + 200x, 310x, 320x + + + + 29 + Rappel&nbsp;: PUT - /participants/{TYPE}/{ID}/error + + [Liste vide de switchEndpoint renvoyée] + + + + + 30 + Gérer l’erreur + Code erreur&nbsp;: + 200x + + Cadre de gestion des erreurs + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml new file mode 100644 index 000000000..13e9e6f0c --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml @@ -0,0 +1,180 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' déclaration du titre +title 7.1.0. Obtenir les Détails du Participant + +autonumber +' Légende des acteurs : +' boundary - APIs/Interfaces, etc. +' entity - Objets d'Accès à la Base de Données +' database - Base de Données Persistante + +' déclaration des acteurs +actor "FSP Payeur" as PAYER_FSP +boundary "Service Account Lookup\n(ALS)" as ALS_API +control "Gestionnaire de Participant\nALS" as ALS_PARTICIPANT_HANDLER +entity "DAO Config Type\nEndpoint ALS" as ALS_TYPE_ENDPOINT_CONFIG_DAO +entity "DAO Endpoint CentralService\nALS" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "DAO Oracle Participant\nALS" as ALS_PARTICIPANT_ORACLE_DAO +entity "DAO Oracle Endpoint Participant\nALS" as ALS_PARTICIPANT_ORACLE_DAO +database "Base de Données ALS" as ALS_DB +boundary "API Service Oracle" as ORACLE_API +boundary "API Service Central" as CENTRALSERVICE_API + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYER_FSP +end box + +box "Service Account Lookup" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_TYPE_ENDPOINT_CONFIG_DAO +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +end box + +box "Services Centraux" #LightGreen +participant CENTRALSERVICE_API +end box + +box "Service/Adaptateur Oracle ALS" #LightBlue +participant ORACLE_API +end box + +' DÉBUT DU FLUX + +group Obtenir les détails FSP du Participant + + + PAYER_FSP ->> ALS_API: Requête pour obtenir les détails FSP du Participant\nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 202 \nCode erreur : 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Valider la requête selon + la Spécification d'Interface Mojaloop. + Code erreur : 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Requête pour obtenir les détails FSP du Participant + + alt une correspondance oracleEndpoint trouvée + group #lightskyblue MISE EN OEUVRE : Séquence Config Routage Oracle [CACHÉE] + activate ALS_PARTICIPANT_HANDLER + ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Récupérer la configuration de routage Oracle basée sur\n{TYPE} et {CURRENCY} si fournie\nCode erreur : 200x + activate ALS_TYPE_ENDPOINT_CONFIG_DAO + ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Récupérer oracleEndpoint\nCode erreur : 200x + activate ALS_DB + hnote over ALS_DB #lightyellow + oracleEndpoint + endpointType + partyIdType + currency (optionnel) + end note + ALS_DB --> ALS_TYPE_ENDPOINT_CONFIG_DAO: Retourner le résultat oracleEndpoint + deactivate ALS_DB + ALS_TYPE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des **oracleEndpoint** pour le Participant + deactivate ALS_TYPE_ENDPOINT_CONFIG_DAO + opt #lightskyblue oracleEndpoint EST NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Code erreur : 3200 + end + end group + + group #lightskyblue MISE EN OEUVRE : Séquence de Requête d'Informations Participant Oracle + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Requête pour obtenir les détails FSP du Participant\nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode erreur : 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Requête pour obtenir les détails FSP du Participant\nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 200 \nCode erreur : 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Retourner la liste des informations du Participant + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Retourner la liste des informations du Participant + deactivate ALS_PARTICIPANT_ORACLE_DAO + end group + +' group #lightskyblue MISE EN OEUVRE : Séquence Config Routage Switch [CACHÉE] +' note right of ALS_PARTICIPANT_HANDLER #lightgray +' **RÉFÉRENCE** : Séquence Config Routage Oracle : oracleEndpoint +' end note +' alt #lightskyblue oracleEndpoint N'EST PAS NULL +' ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Récupérer la configuration de routage Switch\nCode erreur : 200x +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Récupérer switchEndpoint\nCode erreur : 200x +' activate ALS_DB +' hnote over ALS_DB #lightyellow +' switchEndpoint +' endpointType +' end note +' ALS_DB -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Retourner switchEndpoint +' deactivate ALS_DB +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_PARTICIPANT_HANDLER: Retourner **switchEndpoint** +' else +' ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Code erreur : 2000 +' end alt +' end group + + '********************* Obtenir l'End-point Callback du Participant PayerFSP - DÉBUT ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l'End-point Callback du Participant PayerFSP\nCode erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l'End-point Callback du Participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200 \nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des End-points Callback du PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des End-points Callback du PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Correspondance des End-points pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + '********************* Obtenir l'End-point Callback du Participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Retourner la liste des informations du Participant + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + else oracleEndpoint EST NULL OU erreur survenue + + '********************* Obtenir l'End-point Callback du Participant - DÉBUT ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l'End-point Callback du Participant\nCode erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l'End-point Callback du Participant\nGET - /participants/{FSPIOP-Source}/endpoints. \nCode réponse : 200 \nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des End-points Callback du Participant + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des End-points Callback du Participant + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Correspondance des End-points pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + '********************* Obtenir l'End-point Callback du Participant - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l'erreur\nCode erreur : 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{TYPE}/{ID}/error + else switchEndpoint EST NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Gérer l'erreur\nCode erreur : 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Cadre de gestion des erreurs + end note + end alt + deactivate ALS_API + + deactivate ALS_PARTICIPANT_HANDLER + +end +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg new file mode 100644 index 000000000..eb558f5d6 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg @@ -0,0 +1,308 @@ + + 7.1.0. Obtenir les Détails du Participant + + + 7.1.0. Obtenir les Détails du Participant + + Fournisseur de Services Financiers + + Service Account Lookup + + Services Centraux + + Service/Adaptateur Oracle ALS + + + + + + + + + + + + + + + + + + + + + + + + + FSP Payeur + + + FSP Payeur + + + Service Account Lookup + (ALS) + + + Service Account Lookup + (ALS) + + + Gestionnaire de Participant + ALS + + + Gestionnaire de Participant + ALS + + + DAO Config Type + Endpoint ALS + + + DAO Config Type + Endpoint ALS + + + DAO Oracle Participant + ALS + + + DAO Oracle Participant + ALS + + + Base de Données ALS + + + Base de Données ALS + + + DAO Endpoint CentralService + ALS + + + DAO Endpoint CentralService + ALS + + + API Service Central + + + API Service Central + + + API Service Oracle + + + API Service Oracle + + + + + + + + + + + + + + + Obtenir les détails FSP du Participant + + + + 1 + Requête pour obtenir les détails FSP du Participant + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code réponse : + 202 +   + Code erreur : + 200x, 300x, 310x, 320x + + + Valider la requête selon + la Spécification d'Interface Mojaloop. + Code erreur : + 300x, 310x + + + 2 + Requête pour obtenir les détails FSP du Participant + + + alt + [une correspondance oracleEndpoint trouvée] + + + MISE EN OEUVRE : Séquence Config Routage Oracle + [CACHÉE] + + + 3 + Récupérer la configuration de routage Oracle basée sur + {TYPE} et {CURRENCY} si fournie + Code erreur : + 200x + + + 4 + Récupérer oracleEndpoint + Code erreur : + 200x + + oracleEndpoint + endpointType + partyIdType + currency (optionnel) + + + 5 + Retourner le résultat oracleEndpoint + + + 6 + Liste des + oracleEndpoint + pour le Participant + + + opt + [oracleEndpoint EST NULL] + + + + + 7 + Code erreur : + 3200 + + + MISE EN OEUVRE : Séquence de Requête d'Informations Participant Oracle + + + 8 + Requête pour obtenir les détails FSP du Participant + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code erreur : + 200x, 310x, 320x + + + 9 + Requête pour obtenir les détails FSP du Participant + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Code réponse : + 200 +   + Code erreur : + 200x, 310x, 320x + + + 10 + Retourner la liste des informations du Participant + + + 11 + Retourner la liste des informations du Participant + + + 12 + Récupérer l'End-point Callback du Participant PayerFSP + Code erreur : + 200x, 310x, 320x + + + 13 + Récupérer l'End-point Callback du Participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse : + 200 +   + Code erreur : + 200x, 310x, 320x + + + 14 + Liste des End-points Callback du PayerFSP + + + 15 + Liste des End-points Callback du PayerFSP + + + + + 16 + Correspondance des End-points pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 17 + Retourner la liste des informations du Participant + + + + 18 + Callback : PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + [oracleEndpoint EST NULL OU erreur survenue] + + + 19 + Récupérer l'End-point Callback du Participant + Code erreur : + 200x, 310x, 320x + + + 20 + Récupérer l'End-point Callback du Participant + GET - /participants/{FSPIOP-Source}/endpoints. + Code réponse : + 200 +   + Code erreur : + 200x, 310x, 320x + + + 21 + Liste des End-points Callback du Participant + + + 22 + Liste des End-points Callback du Participant + + + + + 23 + Correspondance des End-points pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 24 + Gérer l'erreur + Code erreur : + 200x, 310x, 320x + + + + 25 + Callback : PUT - /participants/{TYPE}/{ID}/error + + [switchEndpoint EST NULL] + + + + + 26 + Gérer l'erreur + Code erreur : + 200x + + Cadre de gestion des erreurs + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml new file mode 100644 index 000000000..1aa55f1cf --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml @@ -0,0 +1,215 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' déclaration du titre +title 7.2.0. Obtenir les Détails d'une Partie + +autonumber +' Clés des Acteurs : +' boundary - APIs/Interfaces, etc +' entity - Objets d'Accès à la Base de Données +' database - Stockage Persitant des Bases de Données + +' déclaration des acteurs +actor "Payer FSP" as PAYER_FSP +actor "Payee FSP" as PAYEE_FSP +boundary "Service de Recherche de\nCompte (ALS)" as ALS_API +control "Gestionnaire de\nParticipant ALS" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +database "Base de Données ALS" as ALS_DB +boundary "API Service Oracle" as ORACLE_API +boundary "API Service Central" as CENTRALSERVICE_API + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYER_FSP +end box + +box "Service de Recherche de Compte" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Services Centraux" #LightGreen +participant CENTRALSERVICE_API +end box + +box "Service/Adaptateur Oracle ALS" #LightBlue +participant ORACLE_API +end box + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYEE_FSP +end box + +' DÉBUT DU FLUX + +group Obtenir les Détails d'une Partie + PAYER_FSP ->> ALS_API: Requête pour obtenir les détails FSP des parties\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 202\nCode erreur : 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Valider la requête selon + la Spécification d'Interface Mojaloop. + Code erreur : 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Requête pour obtenir les détails FSP des parties + + alt correspondance oracleEndpoint trouvée & informations sur les parties récupérées + activate ALS_PARTICIPANT_HANDLER + '********************* Récupération Infos de Routage Oracle - DÉBUT ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la configuration de routage Oracle\nCode erreur : 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + OBTENIR Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + '********************* Récupération Infos de Routage Oracle - FIN ************************ + ||| + '********************* Récupération Infos de Routage Switch - DÉBUT ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir configuration de routage du Switch\nCode erreur : 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' OBTENIR Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref + '********************* Récupération Infos de Routage Switch - FIN ************************ + ||| + group Valider le Participant FSPIOP-Source + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Requête d'information participant FSPIOP-Source\nCode erreur : 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Retourner les informations du participant FSPIOP-Source + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Retourner les informations du participant FSPIOP-Source + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider le participant FSPIOP-Source\nCode erreur : 320x + end group + ||| + + '********************* Requête Infos Participant Oracle - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Obtenir les informations du Participant pour PayeeFSP\nCode erreur : 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + OBTENIR Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Request Participant Information from Oracle Sequence]] + ||| + end ref + + '********************* Requête Infos Participant Oracle - FIN ************************ + ||| + '********************* Requête Infos Parties - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTIES_FSP_DAO: Requêter les informations des Parties depuis FSP.\nCode erreur : 200x + + activate ALS_PARTIES_FSP_DAO + ALS_PARTIES_FSP_DAO ->> PAYEE_FSP: Rappel des Parties vers la Destination:\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nCode réponse : 202\nCode erreur : 200x, 310x, 320x + deactivate ALS_PARTIES_FSP_DAO + activate PAYEE_FSP + + PAYEE_FSP ->> ALS_API: Rappel avec les informations du Participant:\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY}\nCode erreur : 200x, 300x, 310x, 320x + deactivate PAYEE_FSP + + ALS_API -> ALS_API: Valider la requête selon\nla Spécification d'Interface Mojaloop\nCode erreur : 300x, 310x + ALS_API -> ALS_PARTICIPANT_HANDLER: Traiter les informations de rappel du Participant pour PUT + + '********************* Requête Infos Parties - FIN ************************ + + '********************* Récupérer l'information d'End-point du Participant PayerFSP - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l'End-point de rappel du Participant PayerFSP\nCode erreur : 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l'End-point de rappel du Participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des end-points de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des end-points de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Associer les End-points de rappel du Participant PayerFSP pour\nFSPIOP_CALLBACK_URL_PARTIES_PUT + + '********************* Récupérer l'information d'End-point du Participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Retourner les informations du Participant à PayerFSP + ALS_API ->> PAYER_FSP: Callback avec infos Parties :\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + else Liste d'end-points vide renvoyée pour la config (PayeeFSP ou Oracle) ou erreur pour PayerFSP + + '********************* Récupérer l'information d'End-point du Participant PayerFSP - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l'End-point de rappel du Participant PayerFSP\nCode erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l'End-point de rappel du Participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des end-points de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des end-points de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Associer les end-points de rappel du Participant PayerFSP pour\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Récupérer l'information d'End-point du Participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l'erreur\nCode erreur : 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{TYPE}/{ID}/error + else Liste d'end-points vide renvoyée pour la config PayerFSP ou erreur pour PayeeFSP + + '********************* Récupérer l'information d'End-point du Participant PayeeFSP - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l'End-point de rappel du Participant PayeeFSP\nCode erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l'End-point de rappel du Participant PayeeFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200\nCode erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des end-points de rappel du participant PayeeFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des end-points de rappel du participant PayeeFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Associer les end-points de rappel du participant PayeeFSP pour\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Récupérer l'information d'End-point du Participant PayerFSP - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l'erreur\nCode erreur : 200x, 310x, 320x + ALS_API ->> PAYEE_FSP: Callback : PUT - /participants/{TYPE}/{ID}/error + else Liste de résultats switchEndpoint vide renvoyée + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Gérer l'erreur\nCode erreur : 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Cadre de Gestion des Erreurs + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg new file mode 100644 index 000000000..a7a7aaf57 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg @@ -0,0 +1,385 @@ + + 7.2.0. Obtenir les Détails d'une Partie + + + 7.2.0. Obtenir les Détails d'une Partie + + Fournisseur de Services Financiers + + Service de Recherche de Compte + + Services Centraux + + Service/Adaptateur Oracle ALS + + Fournisseur de Services Financiers + + + + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Service de Recherche de + Compte (ALS) + + + Service de Recherche de + Compte (ALS) + + + Gestionnaire de + Participant ALS + + + Gestionnaire de + Participant ALS + + + Base de Données ALS + + + Base de Données ALS + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + ALS Parties + FSP DAO + + + ALS Parties + FSP DAO + + + API Service Central + + + API Service Central + + + API Service Oracle + + + API Service Oracle + + + Payee FSP + + + Payee FSP + + + + + + + + + + + + + + + + + Obtenir les Détails d'une Partie + + + + 1 + Requête pour obtenir les détails FSP des parties + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + Code réponse : + 202 + Code erreur : + 200x, 300x, 310x, 320x + + + Valider la requête selon + la Spécification d'Interface Mojaloop. + Code erreur : + 300x, 310x + + + 2 + Requête pour obtenir les détails FSP des parties + + + alt + [correspondance oracleEndpoint trouvée & informations sur les parties récupérées] + + + + 3 + Obtenir la configuration de routage Oracle + Code erreur : + 200x, 310x, 320x + + + ref + OBTENIR Participants - + Get Oracle Routing Config Sequence + + + + + + Valider le Participant FSPIOP-Source + + + 4 + Requête d'information participant FSPIOP-Source + Code erreur : + 200x + + + 5 + GET - /participants/{FSPIOP-Source} + Code erreur : + 200x, 310x, 320x + + + 6 + Retourner les informations du participant FSPIOP-Source + + + 7 + Retourner les informations du participant FSPIOP-Source + + + + + 8 + Valider le participant FSPIOP-Source + Code erreur : + 320x + + + + 9 + Obtenir les informations du Participant pour PayeeFSP + Code erreur : + 200x, 310x, 320x + + + ref + OBTENIR Participants - + Request Participant Information from Oracle Sequence + + + + + + 10 + Requêter les informations des Parties depuis FSP. + Code erreur : + 200x + + + + 11 + Rappel des Parties vers la Destination: + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + Code réponse : + 202 + Code erreur : + 200x, 310x, 320x + + + + 12 + Rappel avec les informations du Participant: + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + Code erreur : + 200x, 300x, 310x, 320x + + + + + 13 + Valider la requête selon + la Spécification d'Interface Mojaloop + Code erreur : + 300x, 310x + + + 14 + Traiter les informations de rappel du Participant pour PUT + + + 15 + Récupérer l'End-point de rappel du Participant PayerFSP + Code erreur : + 200x + + + 16 + Récupérer l'End-point de rappel du Participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code erreur : + 200x, 310x, 320x + + + 17 + Liste des end-points de rappel du participant PayerFSP + + + 18 + Liste des end-points de rappel du participant PayerFSP + + + + + 19 + Associer les End-points de rappel du Participant PayerFSP pour + FSPIOP_CALLBACK_URL_PARTIES_PUT + + + 20 + Retourner les informations du Participant à PayerFSP + + + + 21 + Callback avec infos Parties : + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + [Liste d'end-points vide renvoyée pour la config (PayeeFSP ou Oracle) ou erreur pour PayerFSP] + + + 22 + Récupérer l'End-point de rappel du Participant PayerFSP + Code erreur : + 200x, 310x, 320x + + + 23 + Récupérer l'End-point de rappel du Participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse : + 200 + Code erreur : + 200x, 310x, 320x + + + 24 + Liste des end-points de rappel du participant PayerFSP + + + 25 + Liste des end-points de rappel du participant PayerFSP + + + + + 26 + Associer les end-points de rappel du Participant PayerFSP pour + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + 27 + Gérer l'erreur + Code erreur : + 200x, 310x, 320x + + + + 28 + Callback : PUT - /participants/{TYPE}/{ID}/error + + [Liste d'end-points vide renvoyée pour la config PayerFSP ou erreur pour PayeeFSP] + + + 29 + Récupérer l'End-point de rappel du Participant PayeeFSP + Code erreur : + 200x, 310x, 320x + + + 30 + Récupérer l'End-point de rappel du Participant PayeeFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse : + 200 + Code erreur : + 200x, 310x, 320x + + + 31 + Liste des end-points de rappel du participant PayeeFSP + + + 32 + Liste des end-points de rappel du participant PayeeFSP + + + + + 33 + Associer les end-points de rappel du participant PayeeFSP pour + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + 34 + Gérer l'erreur + Code erreur : + 200x, 310x, 320x + + + + 35 + Callback : PUT - /participants/{TYPE}/{ID}/error + + [Liste de résultats switchEndpoint vide renvoyée] + + + + + 36 + Gérer l'erreur + Code erreur : + 200x + + Cadre de Gestion des Erreurs + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml new file mode 100644 index 000000000..034740749 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' déclaration du titre +title 7.1.3 Poster les détails du Participant par Type et ID + +autonumber +' Clés des acteurs : +' boundary - API / Interfaces, etc. +' entity - Objets d’accès à la base de données +' database - Stockage persistant en base de données + +' déclaration des acteurs +actor "PSF Payeur" as PAYER_FSP +boundary "Service de découverte de compte\n(ALS)" as ALS_API +control "Gestionnaire de participant ALS" as ALS_PARTICIPANT_HANDLER +entity "DAO des points d'accès Service Central ALS" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "DAO des participants Service Central ALS" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "DAO Oracle des participants ALS" as ALS_PARTICIPANT_ORACLE_DAO +database "Base de données ALS" as ALS_DB +boundary "API du service Oracle" as ORACLE_API +boundary "API Service Central" as CENTRALSERVICE_API + +box "Prestataire de services financiers" #LightGrey +participant PAYER_FSP +end box + +box "Service de découverte de compte" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Services centraux" #LightGreen +participant CENTRALSERVICE_API +end box + +box "Service/Adaptateur Oracle ALS" #LightBlue +participant ORACLE_API +end box + +' DÉBUT DU FLUX + +group Publication des détails PSF du Participant + note right of PAYER_FSP #yellow + Entêtes - postParticipantsByTypeIDHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Charge utile - postParticipantsByTypeIDMessage: + { + "fspId": "chaîne" + } + end note + PAYER_FSP ->> ALS_API: Requête pour ajouter les détails PSF du participant\nPOST - /participants/{Type}/{ID}\nCode de réponse : 202 \nCode d’erreur : 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Valider la requête suivant + la Spécification d’interface Mojaloop. + Code d’erreur : 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Traiter la création des détails PSF du participant + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Vérifier que PARTICIPANT.fspId == FSPIOP-Source\nCode d’erreur : 3100 + + '********************* Trier dans les groupes de participants selon {TYPE} - FIN ************************ + + alt Validation réussie + + + '********************* Récupérer les infos de routage Oracle - DÉBUT ************************ + + '********************* Récupérer les infos de routage Oracle - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la configuration de routage Oracle selon Type (et optionnellement Devise)\nCode d’erreur : 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + OBTENIR Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Sequence de récupération de la configuration de routage Oracle]] + ||| + end ref + + '********************* Récupérer les infos de routage Oracle - FIN ************************ + + ||| + +' '********************* Récupérer les infos de routage Oracle - FIN ************************ +' +' '********************* Récupérer la config de routage Switch - DÉBUT ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la configuration de routage Switch\nCode d’erreur : 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' OBTENIR Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Sequence de récupération de la configuration de routage Switch]] +' ||| +' end ref +' +' '********************* Récupérer la config de routage Switch - FIN ************************ +' ||| + + '********************* Validation du participant - DÉBUT ************************ + group Validation du PSF du participant + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Requête d’informations sur le participant (PARTICIPANT.fspId) pour {Type}\nCode d’erreur : 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nCode de réponse : 200 \nCode d’erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Retourner les informations du participant + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Retourner les informations du participant + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider le participant\nCode d’erreur : 320x + end group + '********************* Validation du participant - FIN ************************ + + '********************* Création des informations du participant - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Créer les détails PSF du participant\nPOST - /participants\nCode d’erreur : 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Créer les détails PSF du participant\nPOST - /participants\nCode de réponse : 204 \nCode d’erreur : 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Retourner le résultat de la requête de création du participant + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Retourner le résultat de la création du participant + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Création des informations du participant - FIN ************************ + + '********************* Obtenir les informations d’end-point du PSF Payeur - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint Callback Participant du PSF Payeur (FSPIOP-Source)\nCode d’erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint Callback Participant du PSF Payeur\nGET - /participants/{FSPIOP-Source}/endpoints\nCode de réponse : 200 \nCode d’erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints Callback Participant du PSF Payeur + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints Callback Participant du PSF Payeur + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Faire correspondre les endpoints Callback du PSF Payeur pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Obtenir les informations d’end-point du PSF Payeur - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Retourner la liste d’informations de participant à partir du ParticipantResult + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{Type}/{ID} + + else Validation échouée + '********************* Obtenir les informations d’end-point du PSF Payeur - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint Callback Participant du PSF Payeur (FSPIOP-Source)\nCode d’erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint Callback Participant du PSF Payeur\nGET - /participants/{FSPIOP-Source}/endpoints\nCode de réponse : 200 \nCode d’erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints Callback Participant du PSF Payeur + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints Callback Participant du PSF Payeur + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Faire correspondre les endpoints Callback Participant pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Obtenir les informations d’end-point du PSF Payeur - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l’erreur\nCode d’erreur : 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{Type}/{ID}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg new file mode 100644 index 000000000..9eae33320 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg @@ -0,0 +1,316 @@ + + 7.1.3 Poster les détails du Participant par Type et ID + + + 7.1.3 Poster les détails du Participant par Type et ID + + Prestataire de services financiers + + Service de découverte de compte + + Services centraux + + Service/Adaptateur Oracle ALS + + + + + + + + + + + + + + + + + + + + + + + PSF Payeur + + + PSF Payeur + + + Service de découverte de compte + (ALS) + + + Service de découverte de compte + (ALS) + + + Gestionnaire de participant ALS + + + Gestionnaire de participant ALS + + + DAO Oracle des participants ALS + + + DAO Oracle des participants ALS + + + Base de données ALS + + + Base de données ALS + + + DAO des points d'accès Service Central ALS + + + DAO des points d'accès Service Central ALS + + + DAO des participants Service Central ALS + + + DAO des participants Service Central ALS + + + API Service Central + + + API Service Central + + + API du service Oracle + + + API du service Oracle + + + + + + + + + + + + + + + Publication des détails PSF du Participant + + + Entêtes - postParticipantsByTypeIDHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Charge utile - postParticipantsByTypeIDMessage: + { + "fspId": "chaîne" + } + + + + 1 + Requête pour ajouter les détails PSF du participant + POST - /participants/{Type}/{ID} + Code de réponse : + 202 +   + Code d’erreur : + 200x, 300x, 310x, 320x + + + Valider la requête suivant + la Spécification d’interface Mojaloop. + Code d’erreur : + 300x, 310x + + + 2 + Traiter la création des détails PSF du participant + + + + + 3 + Vérifier que PARTICIPANT.fspId == FSPIOP-Source + Code d’erreur : + 3100 + + + alt + [Validation réussie] + + + + 4 + Obtenir la configuration de routage Oracle selon Type (et optionnellement Devise) + Code d’erreur : + 300x, 310x + + + ref + OBTENIR Participants - + Sequence de récupération de la configuration de routage Oracle + + + + + + Validation du PSF du participant + + + 5 + Requête d’informations sur le participant (PARTICIPANT.fspId) pour {Type} + Code d’erreur : + 200x + + + 6 + GET - /participants/{PARTICIPANT.fspId} + Code de réponse : + 200 +   + Code d’erreur : + 200x, 310x, 320x + + + 7 + Retourner les informations du participant + + + 8 + Retourner les informations du participant + + + + + 9 + Valider le participant + Code d’erreur : + 320x + + + 10 + Créer les détails PSF du participant + POST - /participants + Code d’erreur : + 200x, 310x, 320x + + + 11 + Créer les détails PSF du participant + POST - /participants + Code de réponse : + 204 +   + Code d’erreur : + 200x, 310x, 320x + + + 12 + Retourner le résultat de la requête de création du participant + + + 13 + Retourner le résultat de la création du participant + + + 14 + Récupérer l’endpoint Callback Participant du PSF Payeur (FSPIOP-Source) + Code d’erreur : + 200x, 310x, 320x + + + 15 + Récupérer l’endpoint Callback Participant du PSF Payeur + GET - /participants/{FSPIOP-Source}/endpoints + Code de réponse : + 200 +   + Code d’erreur : + 200x, 310x, 320x + + + 16 + Liste des endpoints Callback Participant du PSF Payeur + + + 17 + Liste des endpoints Callback Participant du PSF Payeur + + + + + 18 + Faire correspondre les endpoints Callback du PSF Payeur pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 19 + Retourner la liste d’informations de participant à partir du ParticipantResult + + + + 20 + Callback : PUT - /participants/{Type}/{ID} + + [Validation échouée] + + + 21 + Récupérer l’endpoint Callback Participant du PSF Payeur (FSPIOP-Source) + Code d’erreur : + 200x, 310x, 320x + + + 22 + Récupérer l’endpoint Callback Participant du PSF Payeur + GET - /participants/{FSPIOP-Source}/endpoints + Code de réponse : + 200 +   + Code d’erreur : + 200x, 310x, 320x + + + 23 + Liste des endpoints Callback Participant du PSF Payeur + + + 24 + Liste des endpoints Callback Participant du PSF Payeur + + + + + 25 + Faire correspondre les endpoints Callback Participant pour + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 26 + Gérer l’erreur + Code d’erreur : + 200x, 310x, 320x + + + + 27 + Callback : PUT - /participants/{Type}/{ID}/error + + diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml new file mode 100644 index 000000000..51e195fc4 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml @@ -0,0 +1,238 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' déclaration du titre +title 7.1.1. Détail : Publication des participants (Batch) + +autonumber +' Clés des acteurs : +' boundary - APIs/Interfaces, etc. +' entity - Objets d'accès à la base de données +' database - Stockage persistant en base + +' déclaration des acteurs +actor "FSP Payeur" as PAYER_FSP +boundary "Service de Recherche\nde Compte (ALS)" as ALS_API +control "Gestionnaire de Participant\nALS" as ALS_PARTICIPANT_HANDLER +entity "DAO Endpoint ALS CentralService" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "DAO Participant ALS CentralService" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "DAO Oracle Participant ALS" as ALS_PARTICIPANT_ORACLE_DAO +database "Base de Données ALS" as ALS_DB +boundary "API Service Oracle" as ORACLE_API +boundary "API Service Central" as CENTRALSERVICE_API + +box "Fournisseur de Services Financiers" #LightGrey +participant PAYER_FSP +end box + +box "Service de Recherche de Compte" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Services Centraux" #LightGreen +participant CENTRALSERVICE_API +end box + +box "Service/Adaptateur Oracle ALS" #LightBlue +participant ORACLE_API +end box + +' DÉBUT DU FLUX + +group Publication des détails FSP du Participant + note right of PAYER_FSP #yellow + En-têtes - postParticipantsHeaders : { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Corps - postParticipantsMessage: + { + "requestId": "string", + "partyList": [ + { + "partyIdType": "string", + "partyIdentifier": "string", + "partySubIdOrType": "string", + "fspId": "string" + } + ], + "currency": "string" + } + end note + PAYER_FSP ->> ALS_API: Requête pour ajouter les détails FSP du participant\nPOST - /participants\nCode réponse : 202 \nCodes erreur : 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Valide la requête selon + les spécifications d'interface Mojaloop. + Codes d’erreur : 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Traite la création des détails FSP du participant + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + '********************* Trier dans des groupes de Participants selon {TYPE} - DÉBUT ************************ + loop pour chaque Participant dans ParticipantList + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider que PARTICIPANT.fspId == FSPIOP-Source\nCode erreur : 3100 + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Grouper la liste des Participants dans une Carte (ParticipantMap) selon {TYPE} + + end loop + + '********************* Trier dans des groupes de Participants selon {TYPE} - FIN ************************ + + alt Validation réussie et la ParticipantMap a été créée avec succès + + loop pour chaque clé de ParticipantMap -> TypeKey + + '********************* Récupérer les infos de routage Oracle - DÉBUT ************************ + + '********************* Récupérer les infos de routage Oracle - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la config de routage Oracle selon TypeKey (et la devise si présente)\nCodes erreur : 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Séquence : Obtenir la config de routage Oracle]] + ||| + end ref + + '********************* Récupérer les infos de routage Oracle - FIN ************************ + + ||| + +' '********************* Fin récupération infos routage Oracle - FIN ************************ +' +' '********************* Début récupération infos routage Switch - DÉBUT ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Obtenir la config de routage Switch\nCodes erreur : 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Séquence : Obtenir la config de routage Switch]] +' ||| +' end ref +' +' '********************* Fin récupération infos routage Switch - FIN ************************ +' ||| + + '********************* Valider le Participant - DÉBUT ************************ + group Validation du FSP du Participant + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Demander les informations sur le participant (PARTICIPANT.fspId) pour {TypeKey}\nCode erreur : 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nCode réponse : 200 \nCodes erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Retourner les informations du participant + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Retourner les informations du participant + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Valider le participant\nCode erreur : 320x + end group + '********************* Valider le Participant - FIN ************************ + + '********************* Créer l’Information de Participant - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Créer les détails FSP du participant\nPOST - /participants\nCodes erreur : 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Créer les détails FSP du participant\nPOST - /participants\nCode réponse : 204 \nCodes erreur : 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Retourner le résultat de la requête de création du Participant + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Retourner le résultat de la création du participant + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Créer l’Information de Participant - FIN ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Stocker les résultats dans ParticipantResultMap[TypeKey] + + end loop + + loop pour chaque clé dans ParticipantResultMap -> TypeKey + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Combiner les résultats de ParticipantResultMap[TypeKey] dans ParticipantResult + end loop + + '********************* Obtenir les infos de l'endpoint Participant FSP payeur - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint de rappel du participant PayerFSP (FSPIOP-Source)\nCodes erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint de rappel du participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200 \nCodes erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Trouver les endpoints de rappel de Participant PayerFSP pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + '********************* Obtenir les infos de l'endpoint Participant FSP payeur - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Retourner la liste des informations du participant depuis ParticipantResult + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{requestId} + + else Échec de validation ou la ParticipantMap n’a pas pu être créée + '********************* Obtenir les infos de l'endpoint Participant FSP payeur - DÉBUT ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Récupérer l’endpoint de rappel du participant PayerFSP (FSPIOP-Source)\nCodes erreur : 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Récupérer l’endpoint de rappel du participant PayerFSP\nGET - /participants/{FSPIOP-Source}/endpoints\nCode réponse : 200 \nCodes erreur : 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Liste des endpoints de rappel du participant PayerFSP + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: Liste des endpoints de rappel du participant PayerFSP + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Trouver les endpoints de rappel du participant pour\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + '********************* Obtenir les infos de l'endpoint Participant FSP payeur - FIN ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Gérer l’erreur\nCodes erreur : 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback : PUT - /participants/{requestId}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg new file mode 100644 index 000000000..9ca6001b8 --- /dev/null +++ b/docs/fr/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg @@ -0,0 +1,360 @@ + + 7.1.1. Détail : Publication des participants (Batch) + + + 7.1.1. Détail : Publication des participants (Batch) + + Fournisseur de Services Financiers + + Service de Recherche de Compte + + Services Centraux + + Service/Adaptateur Oracle ALS + + + + + + + + + + + + + + + + + + + + + + + + + + FSP Payeur + + + FSP Payeur + + + Service de Recherche + de Compte (ALS) + + + Service de Recherche + de Compte (ALS) + + + Gestionnaire de Participant + ALS + + + Gestionnaire de Participant + ALS + + + DAO Oracle Participant ALS + + + DAO Oracle Participant ALS + + + Base de Données ALS + + + Base de Données ALS + + + DAO Endpoint ALS CentralService + + + DAO Endpoint ALS CentralService + + + DAO Participant ALS CentralService + + + DAO Participant ALS CentralService + + + API Service Central + + + API Service Central + + + API Service Oracle + + + API Service Oracle + + + + + + + + + + + + + + + Publication des détails FSP du Participant + + + En-têtes - postParticipantsHeaders : { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Corps - postParticipantsMessage: + { + "requestId": "string", + "partyList": [ + { + "partyIdType": "string", + "partyIdentifier": "string", + "partySubIdOrType": "string", + "fspId": "string" + } + ], + "currency": "string" + } + + + + 1 + Requête pour ajouter les détails FSP du participant + POST - /participants + Code réponse : + 202 +   + Codes erreur : + 200x, 300x, 310x, 320x + + + Valide la requête selon + les spécifications d'interface Mojaloop. + Codes d’erreur : + 300x, 310x + + + 2 + Traite la création des détails FSP du participant + + + loop + [pour chaque Participant dans ParticipantList] + + + + + 3 + Valider que PARTICIPANT.fspId == FSPIOP-Source + Code erreur : + 3100 + + + + + 4 + Grouper la liste des Participants dans une Carte (ParticipantMap) selon {TYPE} + + + alt + [Validation réussie et la ParticipantMap a été créée avec succès] + + + loop + [pour chaque clé de ParticipantMap -> TypeKey] + + + + 5 + Obtenir la config de routage Oracle selon TypeKey (et la devise si présente) + Codes erreur : + 300x, 310x + + + ref + GET Participants - + Séquence : Obtenir la config de routage Oracle + + + + + + Validation du FSP du Participant + + + 6 + Demander les informations sur le participant (PARTICIPANT.fspId) pour {TypeKey} + Code erreur : + 200x + + + 7 + GET - /participants/{PARTICIPANT.fspId} + Code réponse : + 200 +   + Codes erreur : + 200x, 310x, 320x + + + 8 + Retourner les informations du participant + + + 9 + Retourner les informations du participant + + + + + 10 + Valider le participant + Code erreur : + 320x + + + 11 + Créer les détails FSP du participant + POST - /participants + Codes erreur : + 200x, 310x, 320x + + + 12 + Créer les détails FSP du participant + POST - /participants + Code réponse : + 204 +   + Codes erreur : + 200x, 310x, 320x + + + 13 + Retourner le résultat de la requête de création du Participant + + + 14 + Retourner le résultat de la création du participant + + + + + 15 + Stocker les résultats dans ParticipantResultMap[TypeKey] + + + loop + [pour chaque clé dans ParticipantResultMap -> TypeKey] + + + + + 16 + Combiner les résultats de ParticipantResultMap[TypeKey] dans ParticipantResult + + + 17 + Récupérer l’endpoint de rappel du participant PayerFSP (FSPIOP-Source) + Codes erreur : + 200x, 310x, 320x + + + 18 + Récupérer l’endpoint de rappel du participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse : + 200 +   + Codes erreur : + 200x, 310x, 320x + + + 19 + Liste des endpoints de rappel du participant PayerFSP + + + 20 + Liste des endpoints de rappel du participant PayerFSP + + + + + 21 + Trouver les endpoints de rappel de Participant PayerFSP pour + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + + 22 + Retourner la liste des informations du participant depuis ParticipantResult + + + + 23 + Callback : PUT - /participants/{requestId} + + [Échec de validation ou la ParticipantMap n’a pas pu être créée] + + + 24 + Récupérer l’endpoint de rappel du participant PayerFSP (FSPIOP-Source) + Codes erreur : + 200x, 310x, 320x + + + 25 + Récupérer l’endpoint de rappel du participant PayerFSP + GET - /participants/{FSPIOP-Source}/endpoints + Code réponse : + 200 +   + Codes erreur : + 200x, 310x, 320x + + + 26 + Liste des endpoints de rappel du participant PayerFSP + + + 27 + Liste des endpoints de rappel du participant PayerFSP + + + + + 28 + Trouver les endpoints de rappel du participant pour + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + + 29 + Gérer l’erreur + Codes erreur : + 200x, 310x, 320x + + + + 30 + Callback : PUT - /participants/{requestId}/error + + diff --git a/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql b/docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql rename to docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql diff --git a/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd b/docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd rename to docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd diff --git a/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupService-schema.png b/docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupService-schema.png rename to docs/fr/technical/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png diff --git a/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg b/docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg similarity index 100% rename from mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg rename to docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg diff --git a/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg b/docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg similarity index 100% rename from mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg rename to docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg diff --git a/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg b/docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg similarity index 100% rename from mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg rename to docs/fr/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg diff --git a/mojaloop-technical-overview/assets/diagrams/architecture/central_ledger_block_diagram.png b/docs/fr/technical/technical/assets/diagrams/architecture/central_ledger_block_diagram.png similarity index 100% rename from mojaloop-technical-overview/assets/diagrams/architecture/central_ledger_block_diagram.png rename to docs/fr/technical/technical/assets/diagrams/architecture/central_ledger_block_diagram.png diff --git a/docs/fr/technical/technical/central-bulk-transfers/README.md b/docs/fr/technical/technical/central-bulk-transfers/README.md new file mode 100644 index 000000000..40add943a --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/README.md @@ -0,0 +1,298 @@ +# Conception des transferts groupés + +Le scénario des transferts groupés est décrit dans le document *API Definition* pour la ressource `/bulkTransfers`. Pour plus de détails (voir la section 6.10), conformément à la [spécification Mojaloop](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf). + +1. [Introduction](introduction) +2. [Principes de conception](design-considerations) +3. [Étapes impliquées dans l’architecture de haut niveau](steps-involved-in-the-high-level-architecture) +4. [Notes](notes) + 1. [Points de discussion](discussion-items) + 2. [Nouvelles tables proposées](proposed-new-tables) + 3. [États des transferts groupés](bulk-transfers-states) + 4. [Notes complémentaires](additional-notes) +5. [Sujets de feuille de route](roadmap-topics) + +## 1. Introduction + +Le processus de transferts groupés est traité à la section 6.10 du document *API Definition* 1.0, illustré par la figure 60 dont un extrait figure ci-dessous. +![Figure 60](./assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png) + +Les éléments clés implicites dans la spécification en version 1.0 sont les suivants : + +- La réserve de fonds est effectuée pour chaque transfert individuel du FSP payeur vers le FSP bénéficiaire +- Si un seul transfert individuel échoue pendant la phase *prepare*, l’ensemble du lot doit être rejeté. + +## 2. Principes de conception + +D’après la figure 60 de la spécification, voici quelques implications importantes. + +1. Le DFSP payeur effectue les recherches d’utilisateur pour chaque partie du paiement groupé séparément +2. Le DFSP payeur effectue une devis groupé par DFSP bénéficiaire +3. Il incombe au DFSP payeur de préparer les transferts groupés selon les FSP bénéficiaires et d’envoyer une demande de transfert groupé à un seul FSP bénéficiaire +4. Ce processus semble fonctionner selon un principe « tout ou rien » : si un transfert individuel ne peut pas être réservé, tout le lot doit être rejeté, car on ne peut l’envoyer tel quel au bénéficiaire s’il contient un transfert sans réserve de fonds. +5. Dans cette logique, la proposition actuelle est d’habiliter le *Switch* (une mise à jour de la spécification est nécessaire) à envoyer la requête `POST /bulkTransfers` avec la liste des transferts individuels pour lesquels les fonds ont pu être réservés sur le *Switch* +6. Il en résulte que le *Switch* agrège les engagements et les échecs côté FSP bénéficiaire et envoie un seul appel `PUT /bulkTransfers/{ID}` au FSP payeur avec la liste complète, y compris les transferts ayant échoué sur le *Switch* ou chez le FSP bénéficiaire +7. Exemple : 1000 transferts dans un lot ; le *Switch* réserve les fonds pour 900 d’entre eux — la requête *prepare* vers le DFSP bénéficiaire ne contient que ces 900. Si le FSP bénéficiaire renvoie un *Bulk Fulfil* avec 800 engagements et 100 abandons, le *Switch* traite chaque transfert et envoie le *callback* `PUT /bulkTransfers/{ID}` au FSP payeur pour les 1000 transferts : 800 *committed*, 200 *aborted* +8. Des impacts sur la signature, le chiffrement, la PKI et d’autres aspects de sécurité devront être traités +9. L’ordonnancement des transferts individuels doit également être pris en compte par le schéma. Dans les marchés émergents, l’objectif de mise en œuvre est de maximiser le nombre de transactions : un schéma bien conçu peut réordonner les transferts par montants croissants avant traitement. Il peut toutefois s’agir d’une décision propre au schéma. +10. Une règle de schéma recommandée : les FSP bénéficiaires ne devraient pas pouvoir réordonner les transferts d’un lot pour éviter un biais en faveur des parties bénéficiaires +11. Les règlements impliquant des paiements publics de très gros montants via transferts groupés doivent être examinés pour permettre le traitement sans règles de liquidité trop strictes + +## 3. Étapes impliquées dans l’architecture de haut niveau + +Étapes principales pour les transferts groupés. + +![Diagramme d’architecture](./assets/diagrams/architecture/bulk-transfer-arch-flows.svg) + +1. [1.0, 1.1, 1.2] Une entrée `POST /bulkTransfers` sur le *bulk-api-adapter* est stockée dans un objet ; une notification avec référence au message est publiée sur le topic Kafka `bulk-prepare` ; une réponse **202** est renvoyée au FSP payeur +2. [1.3] Le *Bulk Prepare handler* consomme la requête et enregistre l’état RECEIVED + + a. Il valide le lot et passe à PENDING si la validation réussit + + b. Règle supplémentaire proposée : rejeter un lot si des identifiants de transfert dupliqués apparaissent dans le lot + + c. [1.4] Si la validation échoue, passage de `bulkTransferState` à PENDING_INVALID (état interne) et message vers le topic de traitement groupé + i. Le *Bulk processing Handler* met `bulkTransferState` à REJECTED et notifie le payeur + +3. [1.4] [suite de 2.a] Le *Bulk Prepare handler* décompose le lot en transferts individuels et les envoie sur le topic *prepare* + + a. Chaque transfert reçoit notamment la même date d’expiration que le transfert groupé (et les autres champs nécessaires) + +4. [1.5, 1.6, 1.7] Les *Prepare handler* et *Position handler* sont adaptés pour traiter les transferts d’un lot (indicateurs `type`, `action`, `status`, etc.) + + a. La réserve de fonds est gérée par les gestionnaires concernés ; le lot est agrégé dans le *Bulk Processing Handler* + +5. [1.8] Le *Position Handler* publie des messages vers le topic de traitement groupé pour chaque transfert du lot +6. [1.9] Pour chaque message consommé, le *Bulk processing Handler* vérifie s’il s’agit du dernier transfert de la phase en cours +7. [1.10, 1.11, 1.12] S’il s’agit du dernier transfert, agréger l’état de tous les transferts individuels et + + a. S’ils sont tous en état réservé → envoyer `POST /bulkTransfers` au bénéficiaire (message vers le topic *notifications*, consommé par le *notification handler*) + + b. Une fois la requête *prepare* envoyée au bénéficiaire, passer le statut à ACCEPTED + +8. En cas de *Prepare* réussi — à réception du `PUT` *bulkFulfil* du FSP bénéficiaire, publication sur le topic *bulk fulfil* avec référence au message *Fulfil* stocké dans le *object store* +9. Consommation par le *bulkFulfilHandler*, passage à PROCESSING +10. Le *bulk-fulfil-handler* décompose le lot et envoie chaque transfert aux *Fulfil* et *Position Handlers* refactorisés pour valider ou abandonner selon le `PUT /bulkTransfers/{ID}` du bénéficiaire et pour engager ou libérer les fonds sur le *Switch* +11. Le *bulk-processing-handler* agrège les résultats et fixe l’état `bulkTransfer` à COMPLETED ou REJECTED + + a. Si le bénéficiaire envoie COMMITTED pour au moins un transfert individuel, proposition : état de lot COMPLETED + + b. En revanche, pour l’étape 8 ou si le bénéficiaire envoie REJECTED comme `bulkTransferState`, l’état final sur le *Switch* doit être REJECTED + +12. Notifications au payeur et au bénéficiaire (proche des transferts unitaires, avec écart par rapport à la spec 1.0). Le FSP payeur reçoit la liste exhaustive des transferts individuels (identique à celle de la requête *prepare*). Le FSP bénéficiaire ne reçoit que le sous-ensemble qui lui a été adressé dans la requête *Bulk prepare* (transferts réservés sur le *Switch*). + +## 4. Détails d’implémentation + +### 4.1 États des transferts groupés + +États d’un transfert groupé selon la spécification d’API Mojaloop : + +1. RECEIVED +2. PENDING +3. ACCEPTED +4. PROCESSING +5. COMPLETED +6. REJECTED +7. État interne — PENDING_PREPARE (mappé sur PENDING) +8. État interne — PENDING_INVALID (mappé sur PENDING) +9. État interne — PENDING_FULFIL (mappé sur PROCESSING) +10. État interne — EXPIRING (mappé sur PROCESSING) +11. État interne — EXPIRED (mappé sur COMPLETED) +12. État interne — INVALID (mappé sur REJECTED) +13. Des micro-états supplémentaires peuvent être ajoutés pour usage interne sur le *Switch* + +### 4.2 Nouvelles tables proposées + +Tables proposées pour la conception des transferts groupés : + +- bulkTransfer +- bulkTransferStateChange +- bulkTransferError +- bulkTransferDuplicateCheck +- bulkTransferFulfilment +- bulkTransferFulfilmentDuplicateCheck +- bulkTransferAssociation +- bulkTransferExtension +- bulkTransferState +- bulkProcessingState + +### 4.3 Combinaisons internes type — action — statut + +#### 1. Transfert groupé validé au schéma [ml-api-adapter → bulk-prepare-handler] + + 1. type: bulk-prepare + 2. action: bulk-prepare + 3. Status: success + 4. Résultat : bulkTransferState=RECEIVED, bulkProcessingState=RECEIVED + +#### 2. Doublon [bulk-prepare-handler → notification handler] + + 1. type: notification + 2. action: bulk-prepare-duplicate + 3. Status: success + 4. Résultat : bulkTransferState=N/A, bulkProcessingState=N/A + +#### 3. Échec de validation *Bulk Prepare* [bulk-prepare-handler → notification-handler] + + 1. type: notification + 2. action: bulk-abort + 3. Status: error + +#### 4. *Bulk Prepare* valide (décomposé en transferts individuels) [bulk-prepare-handler → prepare-handler] + + 1. type: prepare + 2. action: bulk-prepare + 3. Status: success + +#### 5. Doublon d’un transfert individuel du lot [prepare-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: prepare-duplicate + 3. Status: success + 4. Action attendue : ajouter un message d’erreur indiquant un doublon + 5. Résultat : bulkTransferState=PENDING_PREPARE/ACCEPTED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=RECEIVED_DUPLICATE + +#### 6. Transfert *Prepare* individuel, doublon valide dans le *prepare handler* [prepare-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: prepare-duplicate + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_PREPARE/ACCEPTED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=RECEIVED_DUPLICATE + +#### 7. *Prepare* individuel valide, membre d’un lot [prepare-handler → position-handler] + + 1. type: position + 2. action: bulk-prepare + 3. Status: success + +#### 8. *Prepare* individuel du lot, validation échouée dans le *prepare handler* [prepare-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_PREPARE/ACCEPTED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=RECEIVED_INVALID + +#### 9. *Prepare* individuel valide, membre d’un lot [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: success + 4. Résultat : bulkTransferState=PENDING_PREPARE/ACCEPTED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=ACCEPTED + +#### 10. *Prepare* individuel du lot, validation échouée dans le *position handler* [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_PREPARE/ACCEPTED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=RECEIVED_INVALID + +#### 11. *Fulfil* individuel valide (engagement), membre d’un lot [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-commit + 3. Status: success + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=COMPLETED + +#### 12. Message *Fulfil* de lot validé [ml-api-adapter → bulk-fulfil-handler] + + 1. type: bulk-fulfil + 2. action: bulk-commit + 3. Status: success + +#### 13. Transfert individuel valide du lot, *timeout* dans le *position handler* [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-reserved + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=FULFIL_INVALID + +#### 14. *Fulfil* individuel valide (rejet), membre d’un lot [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: reject + 3. Status: success + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=REJECTED + +#### 15. Doublon *Fulfil* invalide pour un transfert du lot [fulfil-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: fulfil-duplicate + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=FULFIL_DUPLICATE + +#### 16. Doublon *Fulfil* valide pour un transfert du lot [fulfil-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: fulfil-duplicate + 3. Status: success + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=FULFIL_DUPLICATE + +#### 17. Message *Fulfil* valide pour un transfert du lot [fulfil-handler → position-handler] + + 1. type: position + 2. action: bulk-commit + 3. Status: success + +#### 18. *Fulfil* individuel du lot, validation échouée dans le *fulfil handler* [fulfil-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-commit + 3. Status: error + 4. Résultat : bulkTransferState=PENDING_FULFIL/COMPLETED (selon qu’il s’agisse du dernier ou non), bulkProcessingState=FULFIL_INVALID + +#### 19. Demande *Fulfil* valide pour un transfert du lot [bulk-fulfil-handler → fulfil-handler] + + 1. type: bulk-fulfil + 2. action: bulk-commit + 3. Status: success + +#### 20. Transferts groupés : validation échouée au niveau *bulk-fulfil-handler* [bulk-fulfil-handler → notification-handler] + + 1. type: notification + 2. action: bulk-abort + 3. Status: error + +#### 21. Notifications de transfert groupé vers les FSP [bulk-processing-handler → notification-handler] + + 1. type: notification + 2. action: bulk-prepare / bulk-commit + 3. Status: success + +#### 22. Notification de *timeout* [timeout-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-received + 3. Status: error + 4. Résultat : bulkTransferState=COMPLETED (pour le dernier), bulkProcessingState=EXPIRED + +#### 23. Notification de *timeout* [timeout-handler → position-handler] + + 1. type: position + 2. action: bulk-timeout-reserved + 3. Status: error + +#### 24. Notification de *timeout* après ajustement de position [position-handler → bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-reserved + 3. Status: error + 4. Résultat : bulkTransferState=COMPLETED (pour le dernier), bulkProcessingState=EXPIRED + +### 4.4 Notes complémentaires + +1. Documenter `GET /bulkTransfers` pour préciser les différences de réponses entre FSP payeur et FSP bénéficiaire +2. Un service dédié a été utilisé : *bulk-api-adapter* pour les endpoints des transferts groupés (y compris la persistance évoquée ci-dessus). + +## 5. Sujets de feuille de route + +1. Réévaluer le besoin de prendre en charge plusieurs FSP bénéficiaires dans un lot et les modifications nécessaires à apporter à la spécification. +2. Traiter par ordre de priorité les problèmes et enseignements documentés issus du PoC. +3. Étudier une ressource type *Bulk make* (`/bulkMake` ?) où le *Switch* accepte un lot complet et enchaîne les trois phases — recherche, devis et transferts +4. *Throttling* des transferts individuels dans un lot ? +5. Ordre de traitement dans un lot — sur le *Switch* et chez les FSP. Recommandation : règle imposant aux FSP de respecter l’ordre du lot sans traitement préférentiel ; sur le *Switch*, rester neutre sur l’ordre, bonne pratique : tri par montants croissants +6. Règlements avec transferts groupés et paiements publics de très montants : assouplir les règles de liquidité si nécessaire +7. Implémenter `GET /bulkTransfers` +8. Notifications / journaux pour tous les cas négatifs de lot +9. Couverture complète par tests unitaires +10. Tests d’intégration du *golden path* de transfert groupé réussi +11. Tests de régression, scénarios négatifs inclus diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql rename to docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd b/docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd rename to docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema.png b/docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema.png similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema.png rename to docs/fr/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema.png diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml new file mode 100644 index 000000000..5bdd8119f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml @@ -0,0 +1,217 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULK_API +control "Bulk API Notification \nHandler" as NOTIFY_HANDLER +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +boundary "Central Service API" as CSAPI +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +control "Bulk Prepare\nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Handler" as PREP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULK_API + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant CSAPI + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_PREP_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +activate BULK_PROC_HANDLER +group DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - bulkTransferMessage: + { + bulkTransferId: , + bulkQuoteId: , + payeeFsp: , + payerFsp: , + individualTransfers: [ + { + transferId: , + transferAmount: + { + currency: , + amount: + }, + ilpPacket: , + condition: , + extensionList: { extension: [ + { key: , value: } + ] } + } + ], + extensionList: { extension: [ + { key: , value: } + ] }, + expiration: + } + end note + DFSP1 ->> BULK_API: POST - /bulkTransfers + activate BULK_API + BULK_API -> BULK_API: Validate incoming message\nError codes: 3000-3002, 3100-3107 + loop + BULK_API -> OBJECT_STORE: Persist individual transfers in the bulk to\nobject store: **MLOS.individualTransfers** + activate OBJECT_STORE + OBJECT_STORE --> BULK_API: Return messageId reference to the stored object(s) + deactivate OBJECT_STORE + end + note right of BULK_API #yellow + Message: + { + id: + to: , + from: , + type: "application/json" + content: { + headers: , + payload: { + bulkTransferId: , + bulkQuoteId": , + payerFsp: , + payeeFsp: , + expiration: , + hash: + } + }, + metadata: { + event: { + id: , + type: "bulk-prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_API -> TOPIC_BULK_PREPARE: Route & Publish Bulk Prepare event \nfor Payer\nError code: 2003 + activate TOPIC_BULK_PREPARE + TOPIC_BULK_PREPARE <-> TOPIC_BULK_PREPARE: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 + TOPIC_BULK_PREPARE --> BULK_API: Respond replication acknowledgements \nhave been received + deactivate TOPIC_BULK_PREPARE + BULK_API -->> DFSP1: Respond HTTP - 202 (Accepted) + deactivate BULK_API + ||| + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume message + ref over TOPIC_BULK_PREPARE, BULK_PREP_HANDLER, TOPIC_TRANSFER_PREPARE: Bulk Prepare Handler Consume \n + alt Success + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Produce (stream) single transfer message\nfor each individual transfer [loop] + else Failure + BULK_PREP_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk + end + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION: Prepare Handler Consume\n + alt Success + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + else Failure + PREP_HANDLER --> TOPIC_BULK_PROCESSING: Produce message + end + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER, TOPIC_BULK_PROCESSING: Position Handler Consume\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + ||| + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + ref over TOPIC_BULK_PROCESSING, BULK_PROC_HANDLER, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume\n + BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** + deactivate OBJECT_STORE + BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Prepare notification + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification(s) payload + deactivate OBJECT_STORE + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send Bulk Prepare notification to Payee + ||| +end +deactivate POS_HANDLER +deactivate BULK_PREP_HANDLER +deactivate PREP_HANDLER +deactivate BULK_PROC_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg new file mode 100644 index 000000000..9c52a416a --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg @@ -0,0 +1,405 @@ + + 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + Financial Service Providers + + Bulk API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification + Handler + + + Bulk API Notification + Handler + + + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + Central Service API + + + Central Service API + + + + + topic- + bulk-prepare + + + topic- + bulk-prepare + Bulk Prepare + Handler + + + Bulk Prepare + Handler + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + Prepare Handler + + + Prepare Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position Handler + + + Position Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + notifications + + + topic- + notifications + + + + + + + + + + + + + DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + Headers - transferHeaders: { + Content-Length: <int>, + Content-Type: <string>, + Date: <date>, + FSPIOP-Source: <string>, + FSPIOP-Destination: <string>, + FSPIOP-Encryption: <string>, + FSPIOP-Signature: <string>, + FSPIOP-URI: <uri>, + FSPIOP-HTTP-Method: <string> + } +   + Payload - bulkTransferMessage: + { + bulkTransferId: <uuid>, + bulkQuoteId: <uuid>, + payeeFsp: <string>, + payerFsp: <string>, + individualTransfers: [ + { + transferId: <uuid>, + transferAmount: + { + currency: <string>, + amount: <string> + }, + ilpPacket: <string>, + condition: <string>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + ], + extensionList: { extension: [ + { key: <string>, value: <string> } + ] }, + expiration: <string> + } + + + + 1 + POST - /bulkTransfers + + + + + 2 + Validate incoming message + Error codes: + 3000-3002, 3100-3107 + + + loop + + + 3 + Persist individual transfers in the bulk to + object store: + MLOS.individualTransfers + + + 4 + Return messageId reference to the stored object(s) + + + Message: + { + id: <messageId> + to: <payeeFspName>, + from: <payerFspName>, + type: "application/json" + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkQuoteId": <uuid>, + payerFsp: <string>, + payeeFsp: <string>, + expiration: <timestamp>, + hash: <string> + } + }, + metadata: { + event: { + id: <uuid>, + type: "bulk-prepare", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 5 + Route & Publish Bulk Prepare event + for Payer + Error code: + 2003 + + + + + + 6 + Ensure event is replicated + as configured (ACKS=all) + Error code: + 2003 + + + 7 + Respond replication acknowledgements + have been received + + + + 8 + Respond HTTP - 202 (Accepted) + + + 9 + Consume message + + + ref + Bulk Prepare Handler Consume +   + + + alt + [Success] + + + 10 + Produce (stream) single transfer message + for each individual transfer [loop] + + [Failure] + + + 11 + Produce single message for the entire bulk + + + 12 + Consume message + + + ref + Prepare Handler Consume +   + + + alt + [Success] + + + 13 + Produce message + + [Failure] + + + 14 + Produce message + + + 15 + Consume message + + + ref + Position Handler Consume +   + + + 16 + Produce message + + + 17 + Consume message + + + ref + Bulk Processing Handler Consume +   + + + 18 + Persist bulk message by destination to the + object store: + MLOS.bulkTransferResults + + + 19 + Return the reference to the stored + notification object(s): + messageId + + + 20 + Send Bulk Prepare notification + + + 21 + Consume message + + + 22 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 23 + Return notification(s) payload + + + ref + Send notification to Participant (Payee) +   + + + 24 + Send Bulk Prepare notification to Payee + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml new file mode 100644 index 000000000..a9c53292f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml @@ -0,0 +1,320 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.1. Bulk Prepare Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +control "Bulk Prepare \nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +collections "topic-event" as TOPIC_EVENTS +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +entity "Bulk DAO" as BULK_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant BULK_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate BULK_PREP_HANDLER +group Bulk Prepare Handler Consume + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume Bulk Prepare message + activate TOPIC_BULK_PREPARE + deactivate TOPIC_BULK_PREPARE + group Validate Bulk Prepare Transfer + group Duplicate Check + note right of BULK_PREP_HANDLER #cyan + The Specification doesn't touch on the duplicate handling + of bulk transfers, so the current design mostly follows the + strategy used for individual transfers, except in two places: + + 1. For duplicate requests where hash matches, the current design + includes only the status of the bulk & timestamp (if completed), + but not the individual transfers (for which a GET should be used). + + 2. For duplicate requests where hash matches, but are not in a + finalized state, only the state of the bulkTransfer is sent. + end note + ||| + BULK_PREP_HANDLER -> DB: Request Duplicate Check + ref over BULK_PREP_HANDLER, DB: Request Duplicate Check (using message.content.payload)\n + DB --> BULK_PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break Return TRUE & Log ('Not implemented') + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of BULK_PREP_HANDLER #yellow + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: + } + ] + } + }, + uriParams: { + id: + } + } + }, + metadata: { + correlationId: , + event: { + id: , + type: "notification", + action: "bulk-prepare", + createdAt: , + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 3106 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else hasDuplicateId == FALSE + group Validate Bulk Transfer Prepare Request + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: FSPIOP Source matches Payer + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Check expiration + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Payer and Payee FSP's are different + group Validate Payer + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payee\nError codes: 3203 + end + end + ||| + alt Validate Bulk Transfer Prepare Request (success) + group Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + else Validate Bulk Transfer Prepare Request (failure) + group Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist transfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + bulkTransferError + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + end + end + end + alt Validate Bulk Prepare Transfer (success) + loop for each individual transfer in the bulk + BULK_PREP_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransfers.messageId** + activate OBJECT_STORE + note right of OBJECT_STORE #lightgrey + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + transfer to make their format similar to a single transfer + end note + OBJECT_STORE --> BULK_PREP_HANDLER: Stream bulk's individual transfers + deactivate OBJECT_STORE + + group Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Route & Publish Prepare event to the Payee for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + end + else Validate Bulk Prepare Transfer (failure) + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-abort", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + group Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + end +end +deactivate BULK_PREP_HANDLER +@enduml + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg new file mode 100644 index 000000000..ac272e017 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg @@ -0,0 +1,518 @@ + + 1.1.1. Bulk Prepare Handler Consume + + + 1.1.1. Bulk Prepare Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + + + topic- + bulk-prepare + + + topic- + bulk-prepare + Bulk Prepare + Handler + + + Bulk Prepare + Handler + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + + + topic-event + + + topic-event + + + topic- + notification + + + topic- + notification + + + topic-bulk- + processing + + + topic-bulk- + processing + Bulk DAO + + + Bulk DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + Bulk Prepare Handler Consume + + + 1 + Consume Bulk Prepare message + + + Validate Bulk Prepare Transfer + + + Duplicate Check + + + The Specification doesn't touch on the duplicate handling + of bulk transfers, so the current design mostly follows the + strategy used for individual transfers, except in two places: +   + 1. For duplicate requests where hash matches, the current design + includes only the status of the bulk & timestamp (if completed), + but not the individual transfers (for which a GET should be used). +   + 2. For duplicate requests where hash matches, but are not in a + finalized state, only the state of the bulkTransfer is sent. + + + 2 + Request Duplicate Check + + + ref + Request Duplicate Check (using message.content.payload) +   + + + 3 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + [Return TRUE & Log ('Not implemented')] + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + { + id: <messageId>, + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: <FSPIOPError> + } + ] + } + }, + uriParams: { + id: <bulkTransferId> + } + } + }, + metadata: { + correlationId: <uuid>, + event: { + id: <uuid>, + type: "notification", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: <uuid> + } + } + } + + + 4 + Publish Notification (failure) event for Payer + Error codes: + 3106 + + [hasDuplicateId == FALSE] + + + Validate Bulk Transfer Prepare Request + + + + + + 5 + FSPIOP Source matches Payer + + + + + + 6 + Check expiration + + + + + + 7 + Payer and Payee FSP's are different + + + Validate Payer + + + 8 + Request to retrieve Payer Participant details (if it exists) + + + 9 + Request Participant details + + participant + participantCurrency + + + 10 + Return Participant details if it exists + + + 11 + Return Participant details if it exists + + + + + + 12 + Validate Payer + Error codes: + 3202 + + + Validate Payee + + + 13 + Request to retrieve Payee Participant details (if it exists) + + + 14 + Request Participant details + + participant + participantCurrency + + + 15 + Return Participant details if it exists + + + 16 + Return Participant details if it exists + + + + + + 17 + Validate Payee + Error codes: + 3203 + + + alt + [Validate Bulk Transfer Prepare Request (success)] + + + Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + + + 18 + Request to persist bulk transfer + Error codes: + 2003 + + + 19 + Persist bulkTransfer + + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + + + 20 + Return state + + [Validate Bulk Transfer Prepare Request (failure)] + + + Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 21 + Request to persist bulk transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + + 22 + Persist transfer + + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + bulkTransferError + + + 23 + Return state + + + alt + [Validate Bulk Prepare Transfer (success)] + + + loop + [for each individual transfer in the bulk] + + + 24 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransfers.messageId + + + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + transfer to make their format similar to a single transfer + + + 25 + Stream bulk's individual transfers + + + Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + + + 26 + Request to persist bulk transfer association + Error codes: + 2003 + + + 27 + Insert bulkTransferAssociation + + bulkTransferAssociation + bulkTransferStateChange + + + 28 + Return state + + + Message: + { + id: <messageId> + from: <payerFspName>, + to: <payeeFspName>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "prepare", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + + + 29 + Route & Publish Prepare event to the Payee for the Individual Transfer + Error codes: + 2003 + + [Validate Bulk Prepare Transfer (failure)] + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <bulkTransferMessage.payerFsp>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 7.6 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-abort", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 30 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + + Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + + + 31 + Request to persist bulk transfer association + Error codes: + 2003 + + + 32 + Insert bulkTransferAssociation + + bulkTransferAssociation + bulkTransferStateChange + + + 33 + Return state + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg new file mode 100644 index 000000000..210388650 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg @@ -0,0 +1,484 @@ + + 1.2.1. Prepare Handler Consume individual transfers from Bulk + + + 1.2.1. Prepare Handler Consume individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + Prepare Handler + + + Prepare Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Prepare Handler Consume + + + 1 + Consume Prepare event message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'prepare' && action == 'bulk-prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate Prepare Transfer + + + + + + 4 + Schema validation of the incoming message + + + + + + 5 + Verify the message's signature (to be confirmed in future requirement) + + + Validate Duplicate Check + + + 6 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 7 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + In the context of a bulk (when compared to regular transfers), duplicate + individual transfers are now considered and reported with Modified Request, + because they could have already been handled for another bulk. + + + break + + + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request - Individual transfer prepare duplicate", + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + } + }, + uriParams: { id: <transferId> } + }, + metadata: { + correlationId: <uuid>, + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: <timestamp>, + state: { + code: "3106", + status: "error", + description: "Modified request - Individual transfer prepare duplicate" + }, + id: <uuid>, + responseTo: <uuid> + } + } + + + 8 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + break + + + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + } + }, + uriParams: { id: <transferId> } + }, + metadata: { + correlationId: <uuid>, + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: <timestamp>, + state: { + code: "3106", + status: "error", + description: "Modified request" + }, + id: <uuid>, + responseTo: <uuid> + } + } + + + 9 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + [hasDuplicateId == FALSE] + + + The validation of Payer, Payee can be skipped for individual transfers in Bulk + as they should've/would've been validated already in the bulk prepare part. + However, leaving it here for now, as in the future, this can be leveraged + when bulk transfers to multiple Payees are supported by the Specification. + + + Validate Payer + + + 10 + Request to retrieve Payer Participant details (if it exists) + + + 11 + Request Participant details + + participant + participantCurrency + + + 12 + Return Participant details if it exists + + + 13 + Return Participant details if it exists + + + + + + 14 + Validate Payer + Error codes: + 3202 + + + Validate Payee + + + 15 + Request to retrieve Payee Participant details (if it exists) + + + 16 + Request Participant details + + participant + participantCurrency + + + 17 + Return Participant details if it exists + + + 18 + Return Participant details if it exists + + + + + + 19 + Validate Payee + Error codes: + 3203 + + + alt + [Validate Prepare Transfer (success)] + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + 20 + Request to persist transfer + Error codes: + 2003 + + + 21 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + + + 22 + Return success + + [Validate Prepare Transfer (failure)] + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 23 + Request to persist transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + + 24 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + + + 25 + Return success + + + alt + [Validate Prepare Transfer (success)] + + + Message: + { + id: <messageId> + from: <payerFspName>, + to: <payeeFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "position", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + + + 26 + Route & Publish Position event for Payer + Error codes: + 2003 + + [Validate Prepare Transfer (failure)] + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 35.1.3 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "prepare", + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Prepare failure event to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg new file mode 100644 index 000000000..ee9d9ac7c --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg @@ -0,0 +1,187 @@ + + 1.3.0. Position Handler Consume individual transfers from Bulk + + + 1.3.0. Position Handler Consume individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Handler + + + Position Handler + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + + + + + + + Position Handler Consume + + + alt + [Consume Prepare message for Payer] + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'position' && action == 'bulk-prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Prepare Position Handler Consume +   + + + 4 + Produce message + + [Consume Fulfil message for Payee] + + + 5 + Consume Position event message for Payee + + + break + + + Validate Event + + + + + + 6 + Validate event - Rule: type == 'position' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 7 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Fulfil Position Handler Consume +   + + + 8 + Produce message + + [Consume Abort message] + + + 9 + Consume Position event message + + + break + + + Validate Event + + + + + + 10 + Validate event - Rule: type == 'position' && action == 'timeout-reserved' + Error codes: + 2001 + + + Persist Event Information + + + 11 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Abort Position Handler Consume +   + + + 12 + Produce message + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg new file mode 100644 index 000000000..bbf658e1c --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg @@ -0,0 +1,522 @@ + + 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + + + 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position + Management + Facade + + + Position + Management + Facade + + + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + Prepare Position Handler Consume + + + 1 + Request transfers to be processed + + + + + 2 + Check 1st transfer to select the Participant and Currency + + + DB TRANSACTION + + + + + 3 + Loop through batch and build list of transferIds and calculate sumTransfersInBatch, + checking all in Batch are for the correct Paricipant and Currency + Error code: + 2001, 3100 + + + 4 + Retrieve current state of all transfers in array from DB with select whereIn + (FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + + transferStateChange + transferParticipant + + + 5 + Return current state of all selected transfers from DB + + + + + + 6 + Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + Error code: + 2001 + against failing transfers + Batch is not rejected as a whole. + + + List of transfers used during processing + reservedTransfers + is list of transfers to be processed in the batch + abortedTransfers + is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + processedTransfers + is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation +   + Scalar intermidate values used in the algorithm + transferAmount + = payload.amount.amount + sumTransfersInBatch + = SUM amount against each Transfer in batch + currentPosition + = participantPosition.value + reservedPosition + = participantPosition.{original}reservedValue + effectivePosition + = currentPosition + reservedPosition + heldPosition + = effectivePosition + sumTransfersInBatch + availablePosition + = participantLimit(NetDebitCap) - effectivePosition + sumReserved + = SUM of transfers that have met rule criteria and processed + + + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + + + 7 + Select effectivePosition FOR UPDATE from DB for Payer + + participantPosition + + + 8 + Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + + + + + 9 + Increment reservedValue to heldPosition + (reservedValue = reservedPosition + sumTransfersInBatch) + + + 10 + Persist reservedValue + + UPDATE + participantPosition + SET reservedValue += sumTransfersInBatch + + + 11 + Request position limits for Payer Participant + + FROM + participantLimit + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + + + 12 + Return position limits + + + + + + 13 + availablePosition + = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) + + + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + + + + + + 14 + Validate availablePosition for each tranfser (see algorithm below) + Error code: + 4001 + + + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far + (NEED TO UPDATE IN CODE) + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + (NEED TO UPDATE IN CODE) + // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + + + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + + + + + 15 + Assess any limit thresholds on the final position + adding to alarm list if triggered + + + 16 + Persist latest position + value + and + reservedValue + to DB for Payer + + UPDATE + participantPosition + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + + + 17 + Bulk persist transferStateChange for all processedTransfers + + batch INSERT + transferStateChange + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch +   + + + + + 18 + Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + + + 19 + Bulk persist the participant position change for all processedTransfers + + batch INSERT + participantPositionChange +              + + + 20 + Return a map of transferIds and their transferStateChanges + + + alt + [Calculate & Validate Latest Position Prepare (success)] + + + + + 21 + Notifications for Position Validation Success + Reference: Position Validation Success case (Prepare) + + [Calculate & Validate Latest Position Prepare (failure)] + + + Validation failure! + + + Persist Transfer State (with transferState='ABORTED' on position check fail) + + + 22 + Request to persist transfer + Error code: + 2003 + + + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 23 + Persist transfer state + + transferStateChange + + + 24 + Return success + + + + + 25 + Notifications for failures + Reference: Failure in Position Validation (Prepare) + + + Reference: Failure in Position Validation (Prepare) + + + alt + [If action == 'bulk-prepare'] + + + Message: + { + id: "<messageId>" + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 26 + Publish Position failure event (in Prepare) to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + [If action == 'prepare'] + + + Message: + { + id: "<messageId>" + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "position", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Notification (failure) event for Payer + Error code: + 2003 + + + Reference: Position Validation Success case (Prepare) + + + alt + [If action == 'bulk-prepare'] + + + Message: + { + id: "<messageId>" + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 28 + Publish Position Success event (in Prepare) to Bulk Processing Topic + Error codes: + 2003 + + [If action == 'prepare'] + + + Message: + { + id: "<messageId>" + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "abort", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Publish Notification event + Error code: + 2003 + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml new file mode 100644 index 000000000..19b2a9574 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml @@ -0,0 +1,347 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 1.4.0. Bulk Processing Handler Consume + +autonumber + +/'***** + Diagram notes + -------------- + RECEIVED/RECEIVED + from: prepare-handler , action: prepare-duplicate/success, result: PENDING_PREPARE/ACCEPTED & RECEIVED_DUPLICATE + from: prepare-handler , action: prepare-duplicate/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_DUPLICATE + from: prepare-handler , action: prepare/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_INVALID + from: position-handler, action: prepare/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_INVALID + from: position-handler, action: prepare/success , result: PENDING_PREPARE/ACCEPTED & ACCEPTED + from: timeout-handler , action: timeout-received/error , result: unchanged/COMPLETED & EXPIRED + -------------- + ACCEPTED/ACCEPTED + from: position-handler, action: timeout-reserved/error , result: unchanged/COMPLETED & EXPIRED + -------------- + PROCESSING/ACCEPTED + from: fulfil-handler , action: fulfil-duplicate/success , result: PENDING_FULFIL/COMPLETED & FULFIL_DUPLICATE + from: fulfil-handler , action: fulfil-duplicate/error , result: PENDING_FULFIL/COMPLETED & FULFIL_DUPLICATE + from: position-handler, action: commit/success , result: PENDING_FULFIL/COMPLETED & COMPLETED + from: position-handler, action: reject/success , result: PENDING_FULFIL/COMPLETED & REJECTED + from: position-handler, action: abort/error , result: PENDING_FULFIL/COMPLETED & FULFIL_INVALID + from: fulfil-handler , action: commit/error , result: PENDING_FULFIL/COMPLETED & FULFIL_INVALID + from: position-handler, action: timeout-reserved/error , result: unchanged/COMPLETED & EXPIRED + -------------- + COMPLETED/EXPIRED + -------------- + ******'/ + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-event" as TOPIC_EVENTS +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +collections "topic-notification" as TOPIC_NOTIFICATION +entity "Bulk DAO" as BULK_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_EVENTS + participant OBJECT_STORE + participant TOPIC_NOTIFICATION + participant BULK_DAO + participant DB +end box + +' start flow +activate BULK_PROC_HANDLER +group Bulk Processing Handler Consume + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + + break + group Validate Event + BULK_PROC_HANDLER <-> BULK_PROC_HANDLER: Validate event - Rule:\ntype == 'bulk-processing' && action IN\n['prepare-duplicate', 'bulk-prepare',\n'bulk-timeout-received', 'fulfil-duplicate',\n'bulk-commit', 'bulk-timeout-reserved']\nError codes: 2001 + end + end + + group Persist Event Information + ||| + BULK_PROC_HANDLER -> TOPIC_EVENTS: Publish event information + ref over BULK_PROC_HANDLER, TOPIC_EVENTS: Event Handler Consume\n + ||| + end + + group Process Message + BULK_PROC_HANDLER -> BULK_DAO: Retrieve current state of Bulk Transfer + activate BULK_DAO + BULK_DAO -> DB: Retrieve current state of Bulk Transfer + activate DB + hnote over DB #lightyellow + bulkTransfer + bulkTransferStateChange + end note + BULK_DAO <-- DB: Return **bulkTransferInfo** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **bulkTransferInfo** + deactivate BULK_DAO + + group Validate Bulk Transfer State + note right of BULK_PROC_HANDLER #lightgrey + **Initialize variables**: + let criteriaState + let incompleteBulkState + let completedBulkState + let bulkTransferState + let processingState + let errorCode, errorMessage + let produceNotification = false + end note + alt bulkTransferInfo.bulkTransferState IN ['RECEIVED', 'PENDING_PREPARE'] + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'RECEIVED' + incompleteBulkState = 'PENDING_PREPARE' + completedBulkState = 'ACCEPTED' + end note + alt action == 'prepare-duplicate' AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'RECEIVED_DUPLICATE' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else action == 'bulk-prepare' AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'RECEIVED_INVALID' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else action == 'bulk-prepare' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'ACCEPTED' + end note + else action IN ['bulk-timeout-received', 'bulk-timeout-reserved'] + note right of BULK_PROC_HANDLER #lightgrey + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['ACCEPTED'] + alt action == 'bulk-timeout-reserved' + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'ACCEPTED' + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['PROCESSING', 'PENDING_FULFIL', 'EXPIRING'] + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'PROCESSING' + incompleteBulkState = 'PENDING_FULFIL' + completedBulkState = 'COMPLETED' + end note + alt action == 'fulfil-duplicate' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'FULFIL_DUPLICATE' + end note + else action == 'bulk-commit' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'COMPLETED' + end note + else action == 'reject' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'REJECTED' + end note + else action IN ['commit', 'abort'] AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'FULFIL_INVALID' + end note + else action == 'bulk-timeout-reserved' + note right of BULK_PROC_HANDLER #lightgrey + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['ABORTING'] + alt action == 'bulk-abort' + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'ABORTING' + processingState = 'FULFIL_INVALID' + completedBulkState = 'REJECTED' + incompleteBulkState = 'ABORTING' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else all other ['PENDING_INVALID', 'COMPLETED', 'REJECTED', 'INVALID'] + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + end + + BULK_PROC_HANDLER -> BULK_DAO: Persist individual transfer processing state + activate BULK_DAO + BULK_DAO -> DB: Persist individual transfer processing state\n-- store errorCode/errorMessage when\nstate.status == 'error' + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end note + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return success + deactivate BULK_DAO + + BULK_PROC_HANDLER -> BULK_DAO: Check previously defined completion criteria + activate BULK_DAO + BULK_DAO -> DB: Select EXISTS (LIMIT 1) in criteriaState + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end note + BULK_DAO <-- DB: Return **existingIndividualTransfer** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **existingIndividualTransfer** + deactivate BULK_DAO + + alt individual transfer exists + note right of BULK_PROC_HANDLER #lightgrey + bulkTransferState = incompleteBulkState + end note + else no transfer in criteriaState exists + note right of BULK_PROC_HANDLER #lightgrey + bulkTransferState = completedBulkState + produceNotification = true + end note + end + + BULK_PROC_HANDLER -> BULK_DAO: Persist bulkTransferState from previous step + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransferState + activate DB + deactivate DB + hnote over DB #lightyellow + bulkTransferStateChange + end note + BULK_PROC_HANDLER <-- BULK_DAO: Return success + deactivate BULK_DAO + + + alt produceNotification == true + BULK_PROC_HANDLER -> BULK_DAO: Request to retrieve all bulk transfer and individual transfer results + activate BULK_DAO + BULK_DAO -> DB: Get bulkTransferResult + activate DB + hnote over DB #lightyellow + bulkTransfer + bulkTransferStateChange + bulkTransferAssociation + end note + BULK_DAO <-- DB: Return **bulkTransferResult** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **bulkTransferResult** + deactivate BULK_DAO + + group Send Bulk Notification(s) + note right of BULK_PROC_HANDLER #lightgrey + Depending on the action decide where to + send notification: payer, payee OR both + end note + + BULK_PROC_HANDLER -> OBJECT_STORE: Generate & Persist bulk message to object store:\n**MLOS.bulkTransferResults** by destination + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return reference to the stored object(s)\n**MLOS.bulkTransferResults.messageId** + deactivate OBJECT_STORE + note right of BULK_PROC_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + bulkTransferId: , + bulkTransferState: + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "bulk-[prepare | commit | abort | processing]", + createdAt: , + state: { + status: state.status, + code: state.code + } + } + } + } + end note + + BULK_PROC_HANDLER -> TOPIC_NOTIFICATION: Publish Notification event for Payer/Payee\nError codes: 2003 + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + end + else produceNotification == false + note right of BULK_PROC_HANDLER #lightgrey + Do nothing (awaitAllTransfers) + end note + end + end +end +deactivate BULK_PROC_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg new file mode 100644 index 000000000..9d756ff45 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg @@ -0,0 +1,468 @@ + + 1.4.0. Bulk Processing Handler Consume + + + 1.4.0. Bulk Processing Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-bulk- + processing + + + topic-bulk- + processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic-event + + + topic-event + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + + + topic-notification + + + topic-notification + Bulk DAO + + + Bulk DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + Bulk Processing Handler Consume + + + 1 + Consume message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: + type == 'bulk-processing' && action IN + ['prepare-duplicate', 'bulk-prepare', + 'bulk-timeout-received', 'fulfil-duplicate', + 'bulk-commit', 'bulk-timeout-reserved'] + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Process Message + + + 4 + Retrieve current state of Bulk Transfer + + + 5 + Retrieve current state of Bulk Transfer + + bulkTransfer + bulkTransferStateChange + + + 6 + Return + bulkTransferInfo + + + 7 + Return + bulkTransferInfo + + + Validate Bulk Transfer State + + + Initialize variables + : + let criteriaState + let incompleteBulkState + let completedBulkState + let bulkTransferState + let processingState + let errorCode, errorMessage + let produceNotification = false + + + alt + [bulkTransferInfo.bulkTransferState IN ['RECEIVED', 'PENDING_PREPARE']] + + + criteriaState = 'RECEIVED' + incompleteBulkState = 'PENDING_PREPARE' + completedBulkState = 'ACCEPTED' + + + alt + [action == 'prepare-duplicate' AND state.status == 'error'] + + + processingState = 'RECEIVED_DUPLICATE' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [action == 'bulk-prepare' AND state.status == 'error'] + + + processingState = 'RECEIVED_INVALID' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [action == 'bulk-prepare' AND state.status == 'success'] + + + processingState = 'ACCEPTED' + + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['ACCEPTED']] + + + alt + [action == 'bulk-timeout-reserved'] + + + criteriaState = 'ACCEPTED' + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['PROCESSING', 'PENDING_FULFIL', 'EXPIRING']] + + + criteriaState = 'PROCESSING' + incompleteBulkState = 'PENDING_FULFIL' + completedBulkState = 'COMPLETED' + + + alt + [action == 'fulfil-duplicate'] + + + processingState = 'FULFIL_DUPLICATE' + + [action == 'bulk-commit' AND state.status == 'success'] + + + processingState = 'COMPLETED' + + [action == 'reject' AND state.status == 'success'] + + + processingState = 'REJECTED' + + [action IN ['commit', 'abort'] AND state.status == 'error'] + + + processingState = 'FULFIL_INVALID' + + [action == 'bulk-timeout-reserved'] + + + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['ABORTING']] + + + alt + [action == 'bulk-abort'] + + + criteriaState = 'ABORTING' + processingState = 'FULFIL_INVALID' + completedBulkState = 'REJECTED' + incompleteBulkState = 'ABORTING' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [all other ['PENDING_INVALID', 'COMPLETED', 'REJECTED', 'INVALID']] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + 8 + Persist individual transfer processing state + + + 9 + Persist individual transfer processing state + -- store errorCode/errorMessage when + state.status == 'error' + + bulkTransferAssociation + + + 10 + Return success + + + 11 + Check previously defined completion criteria + + + 12 + Select EXISTS (LIMIT 1) in criteriaState + + bulkTransferAssociation + + + 13 + Return + existingIndividualTransfer + + + 14 + Return + existingIndividualTransfer + + + alt + [individual transfer exists] + + + bulkTransferState = incompleteBulkState + + [no transfer in criteriaState exists] + + + bulkTransferState = completedBulkState + produceNotification = true + + + 15 + Persist bulkTransferState from previous step + + + 16 + Persist bulkTransferState + + bulkTransferStateChange + + + 17 + Return success + + + alt + [produceNotification == true] + + + 18 + Request to retrieve all bulk transfer and individual transfer results + + + 19 + Get bulkTransferResult + + bulkTransfer + bulkTransferStateChange + bulkTransferAssociation + + + 20 + Return + bulkTransferResult + + + 21 + Return + bulkTransferResult + + + Send Bulk Notification(s) + + + Depending on the action decide where to + send notification: payer, payee OR both + + + 22 + Generate & Persist bulk message to object store: + MLOS.bulkTransferResults + by destination + + + 23 + Return reference to the stored object(s) + MLOS.bulkTransferResults.messageId + + + Message: + { + id: <messageId> + from: <source>, + to: <destination>, + type: "application/json" + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkTransferState: <string> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "bulk-[prepare | commit | abort | processing]", + createdAt: <timestamp>, + state: { + status: state.status, + code: state.code + } + } + } + } + + + 24 + Publish Notification event for Payer/Payee + Error codes: + 2003 + + [produceNotification == false] + + + Do nothing (awaitAllTransfers) + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml new file mode 100644 index 000000000..476d76354 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml @@ -0,0 +1,225 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API \nNotification Handler" as NOTIFY_HANDLER +collections "mongo-\nobject-store" as OBJECT_STORE +boundary "Central Service API" as CSAPI +collections "topic-\nbulk-fulfil" as TOPIC_BULK_FULFIL +control "Bulk Fulfil\nHandler" as BULK_FULFIL_HANDLER +collections "topic-\nfulfil" as TOPIC_FULFIL +control "Fulfil \nHandler" as FULF_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position \nHandler" as POS_HANDLER +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant CSAPI + participant TOPIC_BULK_FULFIL + participant BULK_FULFIL_HANDLER + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_FULFIL_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +activate BULK_PROC_HANDLER +group DFSP2 sends a Bulk Fulfil Success Transfer request to DFSP1 + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - bulkTransferMessage: + { + bulkTransferState: , + completedTimestamp: , + individualTransferResults: + [ + { + transferId: , + fulfilment: , + extensionList: { extension: [ + { key: , value: } + ] } + } + ], + extensionList: { extension: [ + { key: , value: } + ] } + } + end note + DFSP2 ->> MLAPI: PUT - /bulkTransfers/ + activate MLAPI + MLAPI -> OBJECT_STORE: Persist incoming bulk message to\nobject store: **MLOS.individualTransferFulfils** + activate OBJECT_STORE + OBJECT_STORE --> MLAPI: Return messageId reference to the stored object(s) + deactivate OBJECT_STORE + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + bulkTransferId: , + bulkTransferState: "COMPLETED", + completedTimestamp: , + extensionList: { extension: [ + { key: , value: } + ] }, + count: , + hash: + } + }, + metadata: { + event: { + id: , + type: "bulk-fulfil", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_BULK_FULFIL: Route & Publish Bulk Fulfil event for Payee\nError code: 2003 + activate TOPIC_BULK_FULFIL + TOPIC_BULK_FULFIL <-> TOPIC_BULK_FULFIL: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 + TOPIC_BULK_FULFIL --> MLAPI: Respond replication acknowledgements \nhave been received + deactivate TOPIC_BULK_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_BULK_FULFIL <- BULK_FULFIL_HANDLER: Consume message + BULK_FULFIL_HANDLER -> OBJECT_STORE: Retrieve individual transfers by key:\n**MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULFIL_HANDLER: Stream bulk's individual transfers + deactivate OBJECT_STORE + ref over TOPIC_BULK_FULFIL, TOPIC_FULFIL: Bulk Prepare Handler Consume \n + alt Success + BULK_FULFIL_HANDLER -> TOPIC_FULFIL: Produce (stream) single transfer message\nfor each individual transfer [loop] + else Failure + BULK_FULFIL_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk + end + ||| + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success)\n + alt Success + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + else Failure + FULF_HANDLER --> TOPIC_BULK_PROCESSING: Produce message + end + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_BULK_PROCESSING: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + ||| + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + ref over TOPIC_BULK_PROCESSING, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume (Success)\n + BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** + deactivate OBJECT_STORE + BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Commit notification + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification payload + deactivate OBJECT_STORE + opt action == 'bulk-commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification payload + deactivate OBJECT_STORE + opt action == 'bulk-commit' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +activate BULK_FULFIL_HANDLER +deactivate FULF_HANDLER +deactivate BULK_PROC_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg new file mode 100644 index 000000000..223109602 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg @@ -0,0 +1,429 @@ + + 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + + + 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API + Notification Handler + + + ML API + Notification Handler + + + + + mongo- + object-store + + + mongo- + object-store + Central Service API + + + Central Service API + + + + + topic- + bulk-fulfil + + + topic- + bulk-fulfil + Bulk Fulfil + Handler + + + Bulk Fulfil + Handler + + + + + topic- + fulfil + + + topic- + fulfil + Fulfil + Handler + + + Fulfil + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position + Handler + + + Position + Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + notification + + + topic- + notification + + + + + + + + + + + + + + + DFSP2 sends a Bulk Fulfil Success Transfer request to DFSP1 + + + Headers - transferHeaders: { + Content-Length: <int>, + Content-Type: <string>, + Date: <date>, + FSPIOP-Source: <string>, + FSPIOP-Destination: <string>, + FSPIOP-Encryption: <string>, + FSPIOP-Signature: <string>, + FSPIOP-URI: <uri>, + FSPIOP-HTTP-Method: <string> + } +   + Payload - bulkTransferMessage: + { + bulkTransferState: <bulkTransferState>, + completedTimestamp: <completedTimeStamp>, + individualTransferResults: + [ + { + transferId: <uuid>, + fulfilment: <ilpCondition>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + ], + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + + + + 1 + PUT - /bulkTransfers/<ID> + + + 2 + Persist incoming bulk message to + object store: + MLOS.individualTransferFulfils + + + 3 + Return messageId reference to the stored object(s) + + + Message: + { + id: <messageId>, + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkTransferState: "COMPLETED", + completedTimestamp: <timestamp>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] }, + count: <int>, + hash: <string> + } + }, + metadata: { + event: { + id: <uuid>, + type: "bulk-fulfil", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Bulk Fulfil event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated + as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements + have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + 9 + Retrieve individual transfers by key: + MLOS.individualTransferFulfils.messageId + + + 10 + Stream bulk's individual transfers + + + ref + Bulk Prepare Handler Consume +   + + + alt + [Success] + + + 11 + Produce (stream) single transfer message + for each individual transfer [loop] + + [Failure] + + + 12 + Produce single message for the entire bulk + + + 13 + Consume message + + + ref + Fulfil Handler Consume (Success) +   + + + alt + [Success] + + + 14 + Produce message + + [Failure] + + + 15 + Produce message + + + 16 + Consume message + + + ref + Position Handler Consume (Success) +   + + + 17 + Produce message + + + 18 + Consume message + + + ref + Bulk Processing Handler Consume (Success) +   + + + 19 + Persist bulk message by destination to the + object store: + MLOS.bulkTransferResults + + + 20 + Return the reference to the stored + notification object(s): + messageId + + + 21 + Send Bulk Commit notification + + + 22 + Consume message + + + 23 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 24 + Return notification payload + + + opt + [action == 'bulk-commit'] + + + ref + Send notification to Participant (Payer) +   + + + 25 + Send callback notification + + + 26 + Consume message + + + 27 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 28 + Return notification payload + + + opt + [action == 'bulk-commit'] + + + ref + Send notification to Participant (Payee) +   + + + 29 + Send callback notification + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml new file mode 100644 index 000000000..2da07f279 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml @@ -0,0 +1,324 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 2.1.1. Bulk Fulfil Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "mongo-\nobject-store" as OBJECT_STORE +collections "topic-bulk-\nfulfil" as TOPIC_BULK_FULFIL +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +control "Bulk Fulfil\nHandler" as BULK_FULF_HANDLER +collections "topic-transfer-\nfulfil" as TOPIC_TRANSFER_FULFIL +collections "topic-event" as TOPIC_EVENTS +collections "topic-notification" as TOPIC_NOTIFICATION +entity "Bulk DAO" as BULK_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant TOPIC_BULK_FULFIL + participant BULK_FULF_HANDLER + participant TOPIC_TRANSFER_FULFIL + participant TOPIC_BULK_PROCESSING + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATION + participant BULK_DAO + participant DB +end box + +' start flow +activate BULK_FULF_HANDLER +group Bulk Fulfil Handler Consume + TOPIC_BULK_FULFIL <- BULK_FULF_HANDLER: Consume message + activate TOPIC_BULK_FULFIL + deactivate TOPIC_BULK_FULFIL + + break + group Validate Event + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Validate event - Rule:\ntype == 'bulk-fulfil' && action == 'bulk-commit'\nError codes: 2001 + end + end + + group Persist Event Information + ||| + BULK_FULF_HANDLER -> TOPIC_EVENTS: Publish event information + ref over BULK_FULF_HANDLER, TOPIC_EVENTS: Event Handler Consume \n + ||| + end + + group Validate FSPIOP-Signature + ||| + ref over BULK_FULF_HANDLER, TOPIC_NOTIFICATION: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 3105/3106\n + ||| + end + + group Validate Bulk Fulfil Transfer + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Schema validation of the incoming message + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Verify the message's signature\n(to be confirmed in future requirement) + note right of BULK_FULF_HANDLER #lightgrey + The above validation steps are already handled by the + Bulk-API-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + end note + + group Validate Duplicate Check + ||| + BULK_FULF_HANDLER -> DB: Request Duplicate Check + ref over BULK_FULF_HANDLER, DB: Request Duplicate Check\n + DB --> BULK_FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + BULK_FULF_HANDLER -> BULK_DAO: Request to retrieve Bulk Transfer state & completedTimestamp\nError code: 2003 + activate BULK_DAO + BULK_DAO -> DB: Query database + hnote over DB #lightyellow + bulkTransfer + bulkTransferFulfilment + bulkTransferStateChange + end note + activate DB + BULK_DAO <-- DB: Return resultset + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return **bulkTransferStateId** & **completedTimestamp** (not null when completed) + deactivate BULK_DAO + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + bulkTransferState: , + completedTimestamp: + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "bulk-fulfil-duplicate", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_NOTIFICATION: Publish Notification event for Payee + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of BULK_FULF_HANDLER #yellow + { + id: , + from: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: + } + ] + } + }, + uriParams: { + id: + } + } + }, + metadata: { + correlationId: , + event: { + id: , + type: "notification", + action: "bulk-commit", + createdAt: , + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_NOTIFICATION: Publish Notification (failure) event for Payer\nError codes: 3106 + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + else hasDuplicateId == FALSE + alt Validate Bulk Transfer Fulfil (success) + group Persist Bulk Transfer State (with bulktransferState='PROCESSING') + BULK_FULF_HANDLER -> BULK_DAO: Request to persist bulk transfer fulfil\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransferFulfilment + hnote over DB #lightyellow + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + end note + activate DB + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return success + deactivate BULK_DAO + end + else Validate Bulk Transfer Fulfil (failure) + group Persist Bulk Transfer State (with bulkTransferState='ABORTING') + BULK_FULF_HANDLER -> BULK_DAO: Request to persist bulk\ntransfer fulfil failure\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist transfer + hnote over DB #lightyellow + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + bulkTransferError + end note + activate DB + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return success + deactivate BULK_DAO + end + end + end + end + alt Validate Bulk Transfer Fulfil (success) + loop for every individual transfer in the bulk fulfil list + BULK_FULF_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Return stored bulk transfer containing individual transfers + deactivate OBJECT_STORE + + BULK_FULF_HANDLER --> OBJECT_STORE: Update bulk transfer association record to bulk transfer processing state 'PROCESSING' + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Bulk transfer association record commited + deactivate OBJECT_STORE + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "fulfil", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_TRANSFER_FULFIL: Route & Publish fulfil bulk commit events to the Payer for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_FULFIL + deactivate TOPIC_TRANSFER_FULFIL + end + else Validate Bulk Transfer Fulfil (failure) + loop for every individual transfer in the bulk fulfil list + BULK_FULF_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Stream bulk's individual transfer fulfils + deactivate OBJECT_STORE + + BULK_FULF_HANDLER --> OBJECT_STORE: Update bulk transfer association record to bulk transfer processing state 'ABORTING' + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Bulk transfer association record commited + deactivate OBJECT_STORE + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: "errorInformation": { + "errorCode": + "errorDescription": "", + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "fulfil", + action: "bulk-abort", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_TRANSFER_FULFIL: Route & Publish fulfil bulk abort events to the Payer for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_FULFIL + deactivate TOPIC_TRANSFER_FULFIL + end +end +deactivate BULK_FULF_HANDLER +@enduml + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg new file mode 100644 index 000000000..7ab28f05f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg @@ -0,0 +1,496 @@ + + 2.1.1. Bulk Fulfil Handler Consume + + + 2.1.1. Bulk Fulfil Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mongo- + object-store + + + mongo- + object-store + + + topic-bulk- + fulfil + + + topic-bulk- + fulfil + Bulk Fulfil + Handler + + + Bulk Fulfil + Handler + + + + + topic-transfer- + fulfil + + + topic-transfer- + fulfil + + + topic-bulk- + processing + + + topic-bulk- + processing + + + topic-event + + + topic-event + + + topic-notification + + + topic-notification + Bulk DAO + + + Bulk DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + 1 + Consume message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: + type == 'bulk-fulfil' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 3105/3106 +   + + + Validate Bulk Fulfil Transfer + + + + + + 4 + Schema validation of the incoming message + + + + + + 5 + Verify the message's signature + (to be confirmed in future requirement) + + + The above validation steps are already handled by the + Bulk-API-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + + + Validate Duplicate Check + + + 6 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 7 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + 8 + Request to retrieve Bulk Transfer state & completedTimestamp + Error code: + 2003 + + + 9 + Query database + + bulkTransfer + bulkTransferFulfilment + bulkTransferStateChange + + + 10 + Return resultset + + + 11 + Return + bulkTransferStateId + & + completedTimestamp + (not null when completed) + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <payeeFspName>, + type: application/json + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferState: <string>, + completedTimestamp: <optional> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "bulk-fulfil-duplicate", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 12 + Publish Notification event for Payee + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + { + id: <messageId>, + from: <ledgerName", + to: <payeeFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: <FSPIOPError> + } + ] + } + }, + uriParams: { + id: <bulkTransferId> + } + } + }, + metadata: { + correlationId: <uuid>, + event: { + id: <uuid>, + type: "notification", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: <uuid> + } + } + } + + + 13 + Publish Notification (failure) event for Payer + Error codes: + 3106 + + [hasDuplicateId == FALSE] + + + alt + [Validate Bulk Transfer Fulfil (success)] + + + Persist Bulk Transfer State (with bulktransferState='PROCESSING') + + + 14 + Request to persist bulk transfer fulfil + Error codes: + 2003 + + + 15 + Persist bulkTransferFulfilment + + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + + + 16 + Return success + + [Validate Bulk Transfer Fulfil (failure)] + + + Persist Bulk Transfer State (with bulkTransferState='ABORTING') + + + 17 + Request to persist bulk + transfer fulfil failure + Error codes: + 2003 + + + 18 + Persist transfer + + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + bulkTransferError + + + 19 + Return success + + + alt + [Validate Bulk Transfer Fulfil (success)] + + + loop + [for every individual transfer in the bulk fulfil list] + + + 20 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransferFulfils.messageId + + + 21 + Return stored bulk transfer containing individual transfers + + + 22 + Update bulk transfer association record to bulk transfer processing state 'PROCESSING' + + + 23 + Bulk transfer association record commited + + + Message: + { + id: <messageId> + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "fulfil", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish fulfil bulk commit events to the Payer for the Individual Transfer + Error codes: + 2003 + + [Validate Bulk Transfer Fulfil (failure)] + + + loop + [for every individual transfer in the bulk fulfil list] + + + 25 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransferFulfils.messageId + + + 26 + Stream bulk's individual transfer fulfils + + + 27 + Update bulk transfer association record to bulk transfer processing state 'ABORTING' + + + 28 + Bulk transfer association record commited + + + Message: + { + id: <messageId> + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: "errorInformation": { + "errorCode": <possible codes: [3100]> + "errorDescription": "<description>", + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "fulfil", + action: "bulk-abort", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Route & Publish fulfil bulk abort events to the Payer for the Individual Transfer + Error codes: + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg new file mode 100644 index 000000000..6dccfb80f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg @@ -0,0 +1,401 @@ + + 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + + + 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Handler + + + Fulfil Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + bulk-processing + + + topic- + bulk-processing + + + topic- + notification + + + topic- + notification + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Success) + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 3105/3106 +   + + + Validate Duplicate Check + + + 4 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 5 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + getTransfer callback +   + + + 7 + Produce message + + + + Ignore - resend in progress + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == FALSE] + + + Validate and persist Transfer Fulfilment + + + 8 + Request information for the validate checks + Error code: + 2003 + + + 9 + Fetch from database + + transfer + + + 10 +   + + + 11 + Return transfer + + + + + 12 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + + + 13 + Validate expirationDate + Error code: + 3303 + + + opt + [Transfer.ilpCondition validate successful] + + + Request current Settlement Window + + + 14 + Request to retrieve current/latest transfer settlement window + Error code: + 2003 + + + 15 + Fetch settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Return settlementWindowId to be appended during transferFulfilment insert + TODO + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + state are updated to the next settlement window + + + Persist fulfilment + + + 18 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 19 + Persist to database + + transferFulfilment + transferExtension + + + 20 + Return success + + + alt + [Transfer.ilpCondition validate successful] + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + 21 + Request to persist transfer state + Error code: + 2003 + + + 22 + Persist transfer state + + transferStateChange + + + 23 + Return success + + + Message: + { + id: <messageId>, + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "position", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish Position event for Payee + + [Validate Fulfil Transfer not successful] + + + break + + + + + 25 + Route & Publish Notification event for Payee + Reference: Failure in validation + + + Reference: Failure in validation + + + Message: + { + id: <messageId>, + from: <ledgerName>, + to: <payeeFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 26 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg new file mode 100644 index 000000000..6cb06df4e --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg @@ -0,0 +1,949 @@ + + 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + + + 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + fulfil + + + topic- + fulfil + Fulfil Handler + + + Fulfil Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + bulk-processing + + + topic- + bulk-processing + + + topic- + notification + + + topic- + notification + Transfer DAO + + + Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Failure) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type IN ['fulfil','bulk-fulfil'] && ( action IN ['reject','abort'] ) + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 2001 + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + Generate transferFulfilmentId uuid + + + 5 + Request to retrieve transfer fulfilment hashes by transferId + Error code: + 2003 + + + 6 + Request Transfer fulfilment + duplicate message hashes + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Return existing hashes + + + 8 + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + Loop the list of returned hashes & compare + each entry with the calculated message hash + + + alt + [Hash matched] + + + 10 + Request to retrieve Transfer Fulfilment & Transfer state + Error code: + 2003 + + + 11 + Request to retrieve + transferFulfilment & transferState + + transferFulfilment + transferStateChange + + + 12 + Return transferFulfilment & + transferState + + + 13 + Return Transfer Fulfilment & Transfer state + + + alt + [transferFulfilment.isValid == 0] + + + break + + + alt + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 14 + Publish Notification event for Payee - Modified Request + Error codes: + 3106 + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 15 + Publish Notification event for Payee - Modified Request + 3106 to Bulk Processing Topic + Error codes: + 3106 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + alt + [If type == 'fulfil'] + + + ref + Send notification to Participant (Payee) +   + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 16 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [transferState NOT 'RESERVED'] + + + break + + + + + + 17 + Reference: Failure in validation + Error code: + 2001 + + + + break + + + alt + [If type == 'fulfil'] + + + + + + 18 + Allow previous request to complete + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 19 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [Hash not matched] + + + 20 + Request to persist transfer hash + Error codes: + 2003 + + + 21 + Persist hash + + transferFulfilmentDuplicateCheck + + + 22 + Return success + + + alt + [action=='reject' call made on PUT /transfers/{ID}] + + + 23 + Request information for the validate checks + Error code: + 2003 + + + 24 + Fetch from database + + transfer + + + 25 +   + + + 26 + Return transfer + + + alt + [Fulfilment present in the PUT /transfers/{ID} message] + + + + + 27 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + Persist fulfilment + + + 28 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 29 + Persist to database + + transferFulfilment + transferExtension + + + 30 + Return success + + [Fulfilment NOT present in the PUT /transfers/{ID} message] + + + + + 31 + Validate that transfer fulfilment message to Abort is valid + Error code: + 2001 + + + Persist extensions + + + 32 + Persist extensionList elements + Error code: + 2003 + + + 33 + Persist to database + + transferExtension + + + 34 + Return success + + + alt + [Transfer.ilpCondition validate successful OR generic validation successful] + + + Persist Transfer State (with transferState='RECEIVED_REJECT') + + + 35 + Request to persist transfer state + Error code: + 2003 + + + 36 + Persist transfer state + + transferStateChange + + + 37 + Return success + + + + + 38 + Route & Publish Position event for Payer + Reference: Publish Position Reject event for Payer + + [Validate Fulfil Transfer not successful or Generic validation failed] + + + break + + + + + 39 + Publish event for Payee + Reference: Failure in validation + + [action=='abort' Error callback] + + + alt + [Validation successful] + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + 40 + Request to persist transfer state & Error + Error code: + 2003 + + + 41 + Persist transfer state & Error + + transferStateChange + transferError + transferExtension + + + 42 + Return success + + + + + 43 + Error callback validated + Reference: Produce message for validated error callback + + [Validate Transfer Error Message not successful] + + + break + + + + + 44 + Notifications for failures + Reference: Validate Transfer Error Message not successful + + [Consume Batch Messages] + + + To be delivered by future story + + + Reference: Validate Transfer Error Message not successful + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 45 + Publish Processing event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 46 + Route & Publish Notification event for Payee + + + Reference: Produce message for validated error callback + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 47 + Route & Publish Position event for Payer + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 48 + Route & Publish Position event for Payer + + + Reference: Failure in validation + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 49 + Publish processing event to the Bulk Processing Topic + Error codes: + 2003 + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 50 + Route & Publish Notification event for Payee + + + Reference: Publish Position Reject event for Payer + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 51 + Route & Publish Position event for Payer + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 52 + Route & Publish Position event for Payer + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg new file mode 100644 index 000000000..750ea14e1 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg @@ -0,0 +1,238 @@ + + 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + + + 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notifications + + + topic- + notifications + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Position Facade + + + Position Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + + Fulfil Position Handler Consume + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state (transferState is 'RECEIVED-FULFIL') + Error code: + 2001 + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + 6 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION + + + 7 + Select participantPosition.value FOR UPDATE from DB for Payee + + participantPosition + + + 8 + Return participantPosition.value from DB for Payee + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persist latestPosition to DB for Payee + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persist transfer state and participant position change + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Return success + + + alt + [If type == 'bulk-position'] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: bulk-commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publish Transfer event to Bulk Processing Topic + Error codes: + 2003 + + [If type == 'position'] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 14 + Publish Transfer event + Error code: + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml rename to docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg new file mode 100644 index 000000000..038eaff5f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg @@ -0,0 +1,613 @@ + + 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + + + 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + Abort Position Handler Consume + + + opt + [type IN ['position','bulk-position'] && action == 'timeout-reserved'] + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state + (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 6 + transferStateId + = 'EXPIRED_RESERVED' + + + 7 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION IMPLEMENTATION + + + 8 + Select participantPosition.value FOR UPDATE for payerCurrencyId + + participantPosition + + + 9 + Return participantPosition + + + + + + 10 + latestPosition + = participantPosition - payload.amount.amount + + + 11 + Persist latestPosition to DB for Payer + + UPDATE + participantPosition + SET value = latestPosition + + + 12 + Persist participant position change and state change + + INSERT + transferStateChange +   + VALUES (transferStateId) +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 13 + Return success + + + alt + [If type == 'bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Publish Transfer event to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + [If type == 'position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 15 + Publish Notification event + Error code: + 2003 + + + opt + [type IN ['position','bulk-position'] && (action IN ['reject', 'abort'])] + + + 16 + Request current state of transfer from DB + Error code: + 2003 + + + 17 + Retrieve current state of transfer from DB + + transferStateChange + + + 18 + Return current state of transfer from DB + + + 19 + Return current state of transfer from DB + + + + + + 20 + Validate current state + (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 21 + transferStateId + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + 22 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 23 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 24 + Return success + + + alt + [If action == 'reject'] + + + alt + [If type == 'position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + + 25 + Publish Notification event + Error code: + 2003 + + [If type == 'bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + + 26 + Publish Notification event + Error code: + 2003 + + [action == 'abort'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <payload.errorInformation.errorCode || 5000> + description: <payload.errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Notification event + Error code: + 2003 + + + opt + [type IN ['position','bulk-position'] && action == 'fail' (Unable to currently trigger this scenario)] + + + 28 + Request current state of transfer from DB + Error code: + 2003 + + + 29 + Retrieve current state of transfer from DB + + transferStateChange + + + 30 + Return current state of transfer from DB + + + 31 + Return current state of transfer from DB + + + + + + 32 + Validate current state (transferStateChange.transferStateId == 'FAILED') + + + Persist Position change and Transfer state + + + + + 33 + transferStateId + = 'FAILED' + + + 34 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 35 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 36 + Return success + + + alt + [If type =='position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 37 + Publish Notification event + Error code: + 2003 + + [If type =='bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 38 + Publish Notification event + Error code: + 2003 + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml new file mode 100644 index 000000000..3f29d4657 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml @@ -0,0 +1,230 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 3.1.0. Transfer Timeout (incl. Bulk Transfer) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API\nAdapter" as MLAPI +control "ML API Notification\nEvent Handler" as NOTIFY_HANDLER +control "Transfer Timeout\nHandler" as EXP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event\nHandler" as POS_HANDLER +control "Bulk Processing\nHandler" as BULK_PROCESSING_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-event" as TOPIC_EVENT +collections "topic-\nbulk-processing" as BULK_PROCESSING_TOPIC + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant EXP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant BULK_PROCESSING_HANDLER + participant BULK_PROCESSING_TOPIC +end box + +' start flow +activate NOTIFY_HANDLER +activate EXP_HANDLER +activate POS_HANDLER +activate BULK_PROCESSING_HANDLER +group Transfer Expiry + ||| + ref over EXP_HANDLER, TOPIC_EVENT : Timeout Handler Consume\n + alt transferStateId == 'RECEIVED_PREPARE' + alt Regular Transfer + EXP_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Individual Transfer from a Bulk + EXP_HANDLER -> BULK_PROCESSING_TOPIC: Produce message + end + else transferStateId == 'RESERVED' + EXP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS : Position Hander Consume (Timeout)\n + alt Regular Transfer + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Individual Transfer from a Bulk + POS_HANDLER -> BULK_PROCESSING_TOPIC: Produce message + end + end + opt action IN ['bulk-timeout-received', 'bulk-timeout-reserved'] + ||| + BULK_PROCESSING_TOPIC <- BULK_PROCESSING_HANDLER: Consume message + ref over TOPIC_NOTIFICATIONS, BULK_PROCESSING_TOPIC : Bulk Processing Consume\n + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + ||| + opt action IN ['timeout-received', 'timeout-reserved', 'bulk-timeout-received', 'bulk-timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP1, TOPIC_NOTIFICATIONS : Send notification to Participant (Payer)\n + alt Timeout before any processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + else Timeout in middle of processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": , + "fulfilment": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + end + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + opt action IN ['timeout-reserved', 'bulk-timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP2, TOPIC_NOTIFICATIONS : Send notification to Participant (Payee)\n + alt Timeout before any processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + else Timeout in middle of processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": , + "fulfilment": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + end + NOTIFY_HANDLER -> DFSP2: Send callback notification + end +end +deactivate BULK_PROCESSING_HANDLER +deactivate POS_HANDLER +deactivate EXP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg new file mode 100644 index 000000000..e9424fc66 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg @@ -0,0 +1,349 @@ + + 3.1.0. Transfer Timeout (incl. Bulk Transfer) + + + 3.1.0. Transfer Timeout (incl. Bulk Transfer) + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API + Adapter + + + ML API + Adapter + + + ML API Notification + Event Handler + + + ML API Notification + Event Handler + + + Transfer Timeout + Handler + + + Transfer Timeout + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + Position Event + Handler + + + Position Event + Handler + + + + + topic- + notification + + + topic- + notification + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + + + + + + + Transfer Expiry + + + ref + Timeout Handler Consume +   + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + alt + [Regular Transfer] + + + 1 + Produce message + + [Individual Transfer from a Bulk] + + + 2 + Produce message + + [transferStateId == 'RESERVED'] + + + 3 + Produce message + + + 4 + Consume message + + + ref + Position Hander Consume (Timeout) +   + + + alt + [Regular Transfer] + + + 5 + Produce message + + [Individual Transfer from a Bulk] + + + 6 + Produce message + + + opt + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + 7 + Consume message + + + ref + Bulk Processing Consume +   + + + 8 + Produce message + + + opt + [action IN ['timeout-received', 'timeout-reserved', 'bulk-timeout-received', 'bulk-timeout-reserved']] + + + 9 + Consume message + + + ref + Send notification to Participant (Payer) +   + + + alt + [Timeout before any processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + [Timeout in middle of processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": <ID>, + "fulfilment": <fulfilment> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + + 10 + Send callback notification + + + opt + [action IN ['timeout-reserved', 'bulk-timeout-reserved']] + + + 11 + Consume message + + + ref + Send notification to Participant (Payee) +   + + + alt + [Timeout before any processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + [Timeout in middle of processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": <ID>, + "fulfilment": <fulfilment> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + + 12 + Send callback notification + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml new file mode 100644 index 000000000..1c9343431 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml @@ -0,0 +1,420 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Transfer Timeout\nHandler" as TIMEOUT_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as NOTIFICATIONS_TOPIC +collections "topic-event" as EVENT_TOPIC +collections "topic-\nbulk-processing" as BULK_PROCESSING_TOPIC +entity "Segment DAO" as SEGMENT_DAO +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant NOTIFICATIONS_TOPIC + participant EVENT_TOPIC + participant BULK_PROCESSING_TOPIC + participant POS_DAO + participant SEGMENT_DAO + participant DB +end box + +' start flow + +group Timeout Handler Consume + activate TIMEOUT_HANDLER + group Persist Event Information + TIMEOUT_HANDLER -> EVENT_TOPIC: Publish event information + ref over TIMEOUT_HANDLER, EVENT_TOPIC : Event Handler Consume\n + end + + group Get previous checkpoint of last record processed (Lower limit for inclusion) + TIMEOUT_HANDLER -> SEGMENT_DAO: Get last segment as @intervalMin + activate SEGMENT_DAO + SEGMENT_DAO -> DB: Get last segment as @intervalMin + hnote over DB #lightyellow + SELECT value INTO @intervalMin + FROM **segment** + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + end note + activate DB + DB --> SEGMENT_DAO: Return @intervalMin + deactivate DB + SEGMENT_DAO --> TIMEOUT_HANDLER: Return @intervalMin + deactivate SEGMENT_DAO + opt @intervalMin IS NULL => segment record NOT FOUND + TIMEOUT_HANDLER->TIMEOUT_HANDLER: Set @intervalMin = 0 + end + end + + group Do Cleanup + TIMEOUT_HANDLER -> POS_DAO: Clean up transferTimeout from finalised transfers + activate POS_DAO + POS_DAO -> DB: Clean up transferTimeout from finalised transfers + hnote over DB #lightyellow + DELETE tt + FROM **transferTimeout** AS tt + JOIN (SELECT tsc.transferId, MAX(tsc.transferStateChangeId) maxTransferStateChangeId + FROM **transferTimeout** tt1 + JOIN **transferStateChange** tsc + ON tsc.transferId = tt1.transferId + GROUP BY transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_FULFIL', 'COMMITTED', 'FAILED' + , 'EXPIRED', 'REJECTED', 'EXPIRED_PREPARED', 'EXPIRED_RESERVED', 'ABORTED') + end note + activate DB + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return success + deactivate POS_DAO + end + + group Determine IntervalMax (Upper limit for inclusion) + TIMEOUT_HANDLER -> POS_DAO: Get last transferStateChangeId as @intervalMax + activate POS_DAO + POS_DAO -> DB: Get last transferStateChangeId as @intervalMax + hnote over DB #lightyellow + SELECT MAX(transferStateChangeId) INTO @intervalMax + FROM **transferStateChange** + end note + activate DB + DB --> POS_DAO: Return @intervalMax + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return @intervalMax + deactivate POS_DAO + end + + + group Prepare data and return the list for expiration + TIMEOUT_HANDLER -> POS_DAO: Prepare data and get transfers to be expired + activate POS_DAO + group DB TRANSACTION + POS_DAO <-> POS_DAO: **transactionTimestamp** = now() + POS_DAO -> DB: Insert all new transfers still in processing state + hnote over DB #lightyellow + INSERT INTO **transferTimeout**(transferId, expirationDate) + SELECT t.transferId, t.expirationDate + FROM **transfer** t + JOIN (SELECT transferId, MAX(transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** + WHERE transferStateChangeId > @intervalMin + AND transferStateChangeId <= @intervalMax + GROUP BY transferId) ts + ON ts.transferId = t.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_PREPARE', 'RESERVED') + end note + activate DB + deactivate DB + + POS_DAO -> DB: Insert transfer state ABORTED for\nexpired RECEIVED_PREPARE transfers + hnote over DB #lightyellow + INSERT INTO **transferStateChange** + SELECT tt.transferId, 'EXPIRED_PREPARED' AS transferStateId, 'Aborted by Timeout Handler' AS reason + FROM **transferTimeout** tt + JOIN ( -- Following subquery is reused 3 times and may be optimized if needed + SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RECEIVED_PREPARE' + end note + activate DB + deactivate DB + + POS_DAO -> DB: Insert transfer state EXPIRED for\nexpired RESERVED transfers + hnote over DB #lightyellow + INSERT INTO **transferStateChange** + SELECT tt.transferId, 'RESERVED_TIMEOUT' AS transferStateId, 'Expired by Timeout Handler' AS reason + FROM **transferTimeout** tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RESERVED' + end note + activate DB + deactivate DB + + POS_DAO -> DB: Update segment table to be used for the next run + hnote over DB #lightyellow + IF @intervalMin = 0 + INSERT + INTO **segment**(segmentType, enumeration, tableName, value) + VALUES ('timeout', 0, 'transferStateChange', @intervalMax) + ELSE + UPDATE **segment** + SET value = @intervalMax + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + end note + activate DB + deactivate DB + end + + POS_DAO -> DB: Get list of transfers to be expired with current state + hnote over DB #lightyellow + SELECT tt.*, tsc.transferStateId, tp1.participantCurrencyId payerParticipantId, + tp2.participantCurrencyId payeeParticipantId, bta.bulkTransferId + FROM **transferTimeout** tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + JOIN **transferParticipant** tp1 + ON tp1.transferId = tt.transferId + AND tp1.transferParticipantRoleTypeId = {PAYER_DFSP} + AND tp1.ledgerEntryTypeId = {PRINCIPLE_VALUE} + JOIN **transferParticipant** tp2 + ON tp2.transferId = tt.transferId + AND tp2.transferParticipantRoleTypeId = {PAYEE_DFSP} + AND tp2.ledgerEntryTypeId = {PRINCIPLE_VALUE} + LEFT JOIN **bulkTransferAssociation** bta + ON bta.transferId = tt.transferId + WHERE tt.expirationDate < {transactionTimestamp} + end note + activate DB + POS_DAO <-- DB: Return **transferTimeoutList** + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return **transferTimeoutList** + deactivate POS_DAO + end + + loop for each transfer in the list + ||| + alt transferTimeoutList.bulkTransferId == NULL (Regular Transfer) + alt transferStateId == 'RECEIVED_PREPARE' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: notification, + action: timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> NOTIFICATIONS_TOPIC: Publish Notification event + activate NOTIFICATIONS_TOPIC + deactivate NOTIFICATIONS_TOPIC + else transferStateId == 'RESERVED' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + else Individual Transfer from a Bulk + alt transferStateId == 'RECEIVED_PREPARE' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + transferId: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: bulk-processing, + action: bulk-timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> BULK_PROCESSING_TOPIC: Publish to Bulk Processing topic + activate BULK_PROCESSING_TOPIC + deactivate BULK_PROCESSING_TOPIC + else transferStateId == 'RESERVED' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + transferId: , + from: , + to: , + type: application/json, + content: { + headers: ,, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: bulk-timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + + deactivate TIMEOUT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg new file mode 100644 index 000000000..5d241117d --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg @@ -0,0 +1,596 @@ + + 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + + + 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Transfer Timeout + Handler + + + Transfer Timeout + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + notification + + + topic- + notification + + + topic-event + + + topic-event + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Segment DAO + + + Segment DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + Timeout Handler Consume + + + Persist Event Information + + + 1 + Publish event information + + + ref + Event Handler Consume +   + + + Get previous checkpoint of last record processed (Lower limit for inclusion) + + + 2 + Get last segment as @intervalMin + + + 3 + Get last segment as @intervalMin + + SELECT value INTO @intervalMin + FROM + segment + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + + + 4 + Return @intervalMin + + + 5 + Return @intervalMin + + + opt + [@intervalMin IS NULL => segment record NOT FOUND] + + + + + 6 + Set @intervalMin = 0 + + + Do Cleanup + + + 7 + Clean up transferTimeout from finalised transfers + + + 8 + Clean up transferTimeout from finalised transfers + + DELETE tt + FROM + transferTimeout + AS tt + JOIN (SELECT tsc.transferId, MAX(tsc.transferStateChangeId) maxTransferStateChangeId + FROM + transferTimeout + tt1 + JOIN + transferStateChange + tsc + ON tsc.transferId = tt1.transferId + GROUP BY transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_FULFIL', 'COMMITTED', 'FAILED' + , 'EXPIRED', 'REJECTED', 'EXPIRED_PREPARED', 'EXPIRED_RESERVED', 'ABORTED') + + + 9 + Return success + + + Determine IntervalMax (Upper limit for inclusion) + + + 10 + Get last transferStateChangeId as @intervalMax + + + 11 + Get last transferStateChangeId as @intervalMax + + SELECT MAX(transferStateChangeId) INTO @intervalMax + FROM + transferStateChange + + + 12 + Return @intervalMax + + + 13 + Return @intervalMax + + + Prepare data and return the list for expiration + + + 14 + Prepare data and get transfers to be expired + + + DB TRANSACTION + + + + + + 15 + transactionTimestamp + = now() + + + 16 + Insert all new transfers still in processing state + + INSERT INTO + transferTimeout + (transferId, expirationDate) + SELECT t.transferId, t.expirationDate + FROM + transfer + t + JOIN (SELECT transferId, MAX(transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + WHERE transferStateChangeId > @intervalMin + AND transferStateChangeId <= @intervalMax + GROUP BY transferId) ts + ON ts.transferId = t.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_PREPARE', 'RESERVED') + + + 17 + Insert transfer state ABORTED for + expired RECEIVED_PREPARE transfers + + INSERT INTO + transferStateChange + SELECT tt.transferId, 'EXPIRED_PREPARED' AS transferStateId, 'Aborted by Timeout Handler' AS reason + FROM + transferTimeout + tt + JOIN ( + -- Following subquery is reused 3 times and may be optimized if needed + SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RECEIVED_PREPARE' + + + 18 + Insert transfer state EXPIRED for + expired RESERVED transfers + + INSERT INTO + transferStateChange + SELECT tt.transferId, 'RESERVED_TIMEOUT' AS transferStateId, 'Expired by Timeout Handler' AS reason + FROM + transferTimeout + tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RESERVED' + + + 19 + Update segment table to be used for the next run + + IF @intervalMin = 0 + INSERT + INTO + segment + (segmentType, enumeration, tableName, value) + VALUES ('timeout', 0, 'transferStateChange', @intervalMax) + ELSE + UPDATE + segment + SET value = @intervalMax + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + + + 20 + Get list of transfers to be expired with current state + + SELECT tt.*, tsc.transferStateId, tp1.participantCurrencyId payerParticipantId, + tp2.participantCurrencyId payeeParticipantId, bta.bulkTransferId + FROM + transferTimeout + tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + JOIN + transferParticipant + tp1 + ON tp1.transferId = tt.transferId + AND tp1.transferParticipantRoleTypeId = {PAYER_DFSP} + AND tp1.ledgerEntryTypeId = {PRINCIPLE_VALUE} + JOIN + transferParticipant + tp2 + ON tp2.transferId = tt.transferId + AND tp2.transferParticipantRoleTypeId = {PAYEE_DFSP} + AND tp2.ledgerEntryTypeId = {PRINCIPLE_VALUE} + LEFT JOIN + bulkTransferAssociation + bta + ON bta.transferId = tt.transferId + WHERE tt.expirationDate < {transactionTimestamp} + + + 21 + Return + transferTimeoutList + + + 22 + Return + transferTimeoutList + + + loop + [for each transfer in the list] + + + alt + [transferTimeoutList.bulkTransferId == NULL (Regular Transfer)] + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: notification, + action: timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 23 + Publish Notification event + + [transferStateId == 'RESERVED'] + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 24 + Route & Publish Position event + + [Individual Transfer from a Bulk] + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + Message: + { +      + id + : <transferTimeoutList.bulkTransferId>, +      + transferId + : <transferTimeoutList.transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: <bulkTransferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: bulk-processing, + action: bulk-timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 25 + Publish to Bulk Processing topic + + [transferStateId == 'RESERVED'] + + + Message: + { +      + id + : <transferTimeoutList.bulkTransferId>, +      + transferId + : <transferTimeoutList.transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: <bulkTransferHeaders>,, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: bulk-timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 26 + Route & Publish Position event + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml new file mode 100644 index 000000000..e02a15142 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml @@ -0,0 +1,233 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declare title +title 4.1.0. Bulk Transfer Abort + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULKAPI +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Bulk-Fulfil-Topic" as TOPIC_BULK_FULFIL +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Bulk Fulfil Event Handler" as BULK_FULFIL_HANDLER +control "Fulfil Event Handler" as FULFIL_HANDLER +collections "topic-transfer-position" as TOPIC_POSITION +control "Position Event Handler" as POS_HANDLER +collections "topic-bulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing Event Handler" as BULK_PROCESSING_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +database "Central Services DB" as DB + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_BULK_FULFIL + participant TOPIC_FULFIL + participant BULK_FULFIL_HANDLER + participant FULFIL_HANDLER + participant TOPIC_POSITION + participant TOPIC_EVENTS + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROCESSING_HANDLER + participant TOPIC_NOTIFICATIONS + participant OBJECT_STORE + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_FULFIL_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate BULK_PROCESSING_HANDLER +activate POS_HANDLER + +group DFSP2 sends a Fulfil Abort Transfer request + note right of DFSP2 #lightblue + **Note**: In the payload for PUT /bulkTransfers//error + only the **errorInformation** field is **required** + end note + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + Payload - errorMessage: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> BULKAPI: **PUT - /bulkTransfers//error** + activate BULKAPI + + BULKAPI -> OBJECT_STORE: Persist request payload with messageId in cache + activate OBJECT_STORE + note right of BULKAPI #yellow + Message: { + messageId: , + bulkTransferId: , + payload: + } + end note + hnote over OBJECT_STORE #lightyellow + individualTransferFulfils + end hnote + BULKAPI <- OBJECT_STORE: Response of save operation + deactivate OBJECT_STORE + note right of BULKAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULKAPI -> TOPIC_BULK_FULFIL: Produce bulk-fulfil message + BULKAPI -->> DFSP2: Respond HTTP - 200 (OK) + TOPIC_BULK_FULFIL <- BULK_FULFIL_HANDLER: Consume bulk-fulfil message + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Perform duplicate check + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Validate request + loop n times, n = number of individual transfers + note right of BULK_FULFIL_HANDLER + Message: { + transferId: , + bulkTransferId< , + bulkTransferAssociationRecord: { + transferId: , + bulkTransferId: , + bulkProcessingStateId: , + errorCode: , + errorDescription: + } + } + end note + BULK_FULFIL_HANDLER -> DB: Update bulkTransferAssociation table + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end hnote + deactivate DB + BULK_FULFIL_HANDLER -> TOPIC_FULFIL: Produce fulfil message with action bulk-abort for each individual transfer + end + ||| + loop n times, n = number of individual transfers + TOPIC_FULFIL <- FULFIL_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_EVENTS: Fulfil Handler Consume (bulk-abort)\n + FULFIL_HANDLER -> TOPIC_POSITION: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_POSITION, BULK_PROCESSING_HANDLER: Position Handler Consume (bulk-abort)\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_BULK_PROCESSING <- BULK_PROCESSING_HANDLER: Consume individual transfer message + ref over TOPIC_BULK_PROCESSING, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume (bulk-abort)\n + end + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payer) + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payee) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payer) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payee) + opt action == 'bulk-abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Notification Handler (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + opt action == 'bulk-abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Notification Handler (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +activate POS_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate NOTIFY_HANDLER +@enduml + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg new file mode 100644 index 000000000..51eae9583 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg @@ -0,0 +1,397 @@ + + 4.1.0. Bulk Transfer Abort + + + 4.1.0. Bulk Transfer Abort + + Financial Service Providers + + Bulk API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification Event Handler + + + Bulk API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Bulk-Fulfil-Topic + + + Bulk-Fulfil-Topic + + + Fulfil-Topic + + + Fulfil-Topic + Bulk Fulfil Event Handler + + + Bulk Fulfil Event Handler + + + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + Position Event Handler + + + Position Event Handler + + + + + topic-bulk-processing + + + topic-bulk-processing + Bulk Processing Event Handler + + + Bulk Processing Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + Central Services DB + + + Central Services DB + + + + + + + + + + + + + + DFSP2 sends a Fulfil Abort Transfer request + + + Note + : In the payload for PUT /bulkTransfers/<ID>/error + only the + errorInformation + field is + required + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } + Payload - errorMessage: + { + "errorInformation": { + "errorCode": <string>, + "errorDescription": <string>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 1 + PUT - /bulkTransfers/<ID>/error + + + 2 + Persist request payload with messageId in cache + + + Message: { + messageId: <string>, + bulkTransferId: <string>, + payload: <object> + } + + individualTransferFulfils + + + 3 + Response of save operation + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Produce bulk-fulfil message + + + + 5 + Respond HTTP - 200 (OK) + + + 6 + Consume bulk-fulfil message + + + + + 7 + Perform duplicate check + + + + + 8 + Validate request + + + loop + [n times, n = number of individual transfers] + + + Message: { + transferId: <string>, + bulkTransferId< <string>, + bulkTransferAssociationRecord: { + transferId: <string>, + bulkTransferId: <string>, + bulkProcessingStateId: <string>, + errorCode: <string>, + errorDescription: <string> + } + } + + + 9 + Update bulkTransferAssociation table + + bulkTransferAssociation + + + 10 + Produce fulfil message with action bulk-abort for each individual transfer + + + loop + [n times, n = number of individual transfers] + + + 11 + Consume message + + + ref + Fulfil Handler Consume (bulk-abort) +   + + + 12 + Produce message + + + loop + [n times, n = number of individual transfers] + + + 13 + Consume message + + + ref + Position Handler Consume (bulk-abort) +   + + + 14 + Produce message + + + loop + [n times, n = number of individual transfers] + + + 15 + Consume individual transfer message + + + ref + Bulk Processing Handler Consume (bulk-abort) +   + + + 16 + Produce message (Payer) + + + 17 + Produce message (Payee) + + + 18 + Consume message (Payer) + + + 19 + Consume message (Payee) + + + opt + [action == 'bulk-abort'] + + + ref + Notification Handler (Payer) +   + + + 20 + Send callback notification + + + opt + [action == 'bulk-abort'] + + + ref + Notification Handler (Payee) +   + + + 21 + Send callback notification + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml new file mode 100644 index 000000000..e219f2465 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml @@ -0,0 +1,209 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declate title +title 5.1.0. Request Bulk Transfer Status + +autonumber + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Bulk API Adapter" as BULKAPI +collections "Topic-Transfer-Get" as TOPIC_GET +control "GET Event Handler" as GET_HANDLER +entity "Bulk Transfer DAO" as BULK_TRANSFER_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box +box "Central Ledger" #LightYellow + participant TOPIC_GET + participant GET_HANDLER + participant BULK_TRANSFER_DAO + participant DB +end box + +' start flow +group Request Bulk transfer status + activate DFSP + DFSP -> BULKAPI: Request bulk transfer status - GET - /bulkTransfers/{ID} + activate BULKAPI + ||| + BULKAPI -> TOPIC_GET: Publish event information + deactivate BULKAPI + activate TOPIC_GET + ||| + deactivate GET_HANDLER + + DFSP <-- BULKAPI: Respond HTTP - 200 (OK) + deactivate DFSP + deactivate BULKAPI + GET_HANDLER -> TOPIC_GET: Consume message + ||| + ref over TOPIC_GET, GET_HANDLER : GET Handler Consume\n + ||| + deactivate TOPIC_GET + + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer participants + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer participants + activate DB + hnote over DB #lightYellow + bulkTransfer + participant + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer participants + deactivate BULK_TRANSFER_DAO + alt Is request not from bulk transfer Payer or Payee FSP? + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer status + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer status + + activate DB + hnote over DB #lightyellow + bulkTransferStateChange + bulkTransferState + bulkTransferError + bulkTransferExtension + transferStateChange + transferState + transferFulfilment + transferError + transferExtension + ilpPacket + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer status + deactivate BULK_TRANSFER_DAO + + alt Is there a bulk transfer with the given ID recorded in the system? + alt Bulk Transfer state is **"PROCESSING"** + note left of GET_HANDLER #yellow + { + "bulkTransferState": "PROCESSING" + } + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> DFSP: Send callback - PUT /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + end + ||| + alt Request is from Payee FSP? + GET_HANDLER <-> GET_HANDLER: Exclude transfers with **transferStateId** not in \n [ **COMMITTED**, **ABORTED_REJECTED**, **EXPIRED_RESERVED** ] + activate GET_HANDLER + end + + note left of GET_HANDLER #yellow + { + "bulkTransferState": "", + "individualTransferResults": [ + { + "transferId": "", + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "errorInformation": , + "extensionList": { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + ], + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "extensionList": + { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + end note + note left of GET_HANDLER #lightGray + NOTE: If transfer is REJECTED, error information may be provided. + Either fulfilment or errorInformation should be set, not both. + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + note right of NOTIFY_HANDLER #lightgray + Log ERROR event + end note + else A bulk transfer with the given ID is not present in the System or this is an invalid request + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + + deactivate GET_HANDLER + deactivate NOTIFY_HANDLER +deactivate DFSP +end +@enduml diff --git a/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg new file mode 100644 index 000000000..9b520a21c --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg @@ -0,0 +1,295 @@ + + 5.1.0. Request Bulk Transfer Status + + + 5.1.0. Request Bulk Transfer Status + + Financial Service Provider + + Bulk API Adapter Service + + Central Ledger + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification Event Handler + + + Bulk API Notification Event Handler + + + + + Topic-Transfer-Get + + + Topic-Transfer-Get + GET Event Handler + + + GET Event Handler + + + Bulk Transfer DAO + + + Bulk Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + Request Bulk transfer status + + + 1 + Request bulk transfer status - GET - /bulkTransfers/{ID} + + + 2 + Publish event information + + + 3 + Respond HTTP - 200 (OK) + + + 4 + Consume message + + + ref + GET Handler Consume +   + + + 5 + Request bulk transfer participants + + + 6 + Fetch bulk transfer participants + + bulkTransfer + participant + + + 7 + Return query result + + + 8 + Return bulk transfer participants + + + alt + [Is request not from bulk transfer Payer or Payee FSP?] + + + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + + + 9 + Publish notification event (404) + + + 10 + callback PUT on /bulkTransfers/{ID}/error + + + 11 + Request bulk transfer status + + + 12 + Fetch bulk transfer status + + bulkTransferStateChange + bulkTransferState + bulkTransferError + bulkTransferExtension + transferStateChange + transferState + transferFulfilment + transferError + transferExtension + ilpPacket + + + 13 + Return query result + + + 14 + Return bulk transfer status + + + alt + [Is there a bulk transfer with the given ID recorded in the system?] + + + alt + [Bulk Transfer state is + "PROCESSING" + ] + + + { + "bulkTransferState": "PROCESSING" + } + + + 15 + Publish notification event + + + 16 + Send callback - PUT /bulkTransfers/{ID} + + + alt + [Request is from Payee FSP?] + + + + + + 17 + Exclude transfers with + transferStateId + not in + [ + COMMITTED + , + ABORTED_REJECTED + , + EXPIRED_RESERVED + ] + + + { + "bulkTransferState": "<BulkTransferState>", + "individualTransferResults": [ + { + "transferId": "<TransferId>", + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "errorInformation": <ErrorInformationObject>, + "extensionList": { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + ], + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "extensionList": + { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + + + NOTE: If transfer is REJECTED, error information may be provided. + Either fulfilment or errorInformation should be set, not both. + + + 18 + Publish notification event + + + 19 + callback PUT on /bulkTransfers/{ID} + + + Log ERROR event + + [A bulk transfer with the given ID is not present in the System or this is an invalid request] + + + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + + + 20 + Publish notification event (404) + + + 21 + callback PUT on /bulkTransfers/{ID}/error + + diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md new file mode 100644 index 000000000..293a9986a --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Requête de transfert en lot — Préparation [Vue d’ensemble] [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus de préparation d’une requête de transfert. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire de lot — Préparation (1.1.1)](1.1.1-bulk-prepare-handler-consume.md) +* [Consommation par le gestionnaire de préparation (1.2.1)](1.2.1-prepare-handler-consume-for-bulk.md) +* [Consommation par le gestionnaire de position (1.3.0)](1.3.0-position-handler-consume-overview.md) +* [Consommation par le gestionnaire de traitement de lot (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-bulk-1.1.0-bulk-prepare-overview.svg](../assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md new file mode 100644 index 000000000..1a53098a5 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire de lot — Préparation + +Diagramme de séquence pour le processus de consommation par le gestionnaire de lot — Préparation. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-bulk-1.1.1-bulk-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md new file mode 100644 index 000000000..938851c9d --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire de préparation [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus de consommation par le gestionnaire de préparation. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-bulk-1.2.1-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md new file mode 100644 index 000000000..60b49276b --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md @@ -0,0 +1,14 @@ +# Consommation par le gestionnaire de position [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Consommation par le gestionnaire de position — Préparation (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Consommation par le gestionnaire de position — Exécution (2.3.1)](2.3.1-fulfil-position-handler-consume.md) +* [Consommation par le gestionnaire de position — Abandon (2.3.2)](2.3.2-position-consume-abort.md) + +## Diagramme de séquence + +![seq-bulk-1.3.0-position-overview.svg](../assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..6a4e3942e --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — Préparation [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position — Préparation. + +## Diagramme de séquence + +![seq-bulk-1.3.1-position-prepare.svg](../assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md new file mode 100644 index 000000000..f59432345 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de traitement de lot + +Diagramme de séquence pour le processus de consommation par le gestionnaire de traitement de lot. + +## Diagramme de séquence + +![seq-bulk-1.4.1-bulk-processing-handler.svg](../assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md new file mode 100644 index 000000000..cd3a3ddd8 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Requête de transfert en lot — Exécution [Vue d’ensemble] + +Diagramme de séquence pour la requête de transfert en lot — Exécution. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire de lot — Exécution (succès) (2.1.1)](2.1.1-bulk-fulfil-handler-consume.md) +* [Consommation par le gestionnaire d’exécution (succès) (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) +* [Consommation par le gestionnaire de position (succès) (2.3.1)](2.3.1-fulfil-position-handler-consume.md) +* [Consommation par le gestionnaire de traitement de lot (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-bulk-2.1.0-bulk-fulfil-overview.svg](../assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md new file mode 100644 index 000000000..cb41f68ce --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Consommation par le gestionnaire de lot — Exécution + +Diagramme de séquence pour le processus de consommation par le gestionnaire de lot — Exécution. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Validation de signature (seq-signature-validation)](../../central-event-processor/signature-validation.md) +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-bulk-2.1.1-bulk-fulfil-handler.svg](../assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md new file mode 100644 index 000000000..50a762599 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md @@ -0,0 +1,11 @@ +# Le bénéficiaire envoie une requête de transfert en lot — Exécution — Le lot est décomposé en transferts individuels + +Diagramme de séquence pour le transfert en lot — Exécution dans le cadre de l’option de validation (commit). + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-bulk-2.2.1-fulfil-handler-commit.svg](../assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md new file mode 100644 index 000000000..4277ece55 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md @@ -0,0 +1,13 @@ +# Le bénéficiaire envoie une requête de transfert en lot — Exécution — Le lot est décomposé en transferts individuels + +Diagramme de séquence pour le processus de rejet / abandon par le gestionnaire d’exécution. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Validation de signature (seq-signature-validation)](../../central-event-processor/signature-validation.md) +* [Envoi de notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-bulk-2.2.2-fulfil-handler-abort.svg](../assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md new file mode 100644 index 000000000..5e6b38493 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire de position — Exécution [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position — Exécution. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-bulk-2.3.1-position-fulfil.svg](../assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md new file mode 100644 index 000000000..94d784779 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — Abandon à l’exécution au niveau du transfert individuel + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position — Abandon. + +## Diagramme de séquence + +![seq-bulk-2.3.2-position-abort.svg](../assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md new file mode 100644 index 000000000..a4c8a9568 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Expiration du transfert [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus d’expiration du transfert. + +## Diagramme de séquence + +![seq-bulk-3.1.0-timeout-overview.svg](../assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md new file mode 100644 index 000000000..7ff0fa17f --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md @@ -0,0 +1,7 @@ +# Gestionnaire d’expiration + +Diagramme de séquence pour le processus du gestionnaire d’expiration. + +## Diagramme de séquence + +![seq-bulk-3.1.1-timeout-handler.svg](../assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md new file mode 100644 index 000000000..67e1b2480 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Abandon du transfert en lot — Vue d’ensemble [inclut les transferts individuels dans un lot] + +Diagramme de séquence pour le processus d’abandon du transfert en lot. + +## Diagramme de séquence + +![seq-bulk-4.1.0-abort-overview.svg](../assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md new file mode 100644 index 000000000..bc053e11c --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Récupération du transfert en lot — Vue d’ensemble + +Diagramme de séquence pour le processus de récupération du transfert en lot. + +## Diagramme de séquence + +![seq-bulk-5.1.0-get-overview.svg](../assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg) diff --git a/docs/fr/technical/technical/central-bulk-transfers/transfers/README.md b/docs/fr/technical/technical/central-bulk-transfers/transfers/README.md new file mode 100644 index 000000000..315828c50 --- /dev/null +++ b/docs/fr/technical/technical/central-bulk-transfers/transfers/README.md @@ -0,0 +1,11 @@ +# Opérations de transferts groupés Mojaloop + +Processus opérationnels au cœur du traitement des transferts groupés : + +- Processus *Bulk Prepare* au niveau du transfert groupé +- Processus *Prepare* au niveau d’un transfert unitaire +- Processus *Bulk Fulfil* au niveau du transfert groupé +- Processus *Fulfil* au niveau d’un transfert unitaire +- Processus de notifications au niveau du transfert groupé +- Processus de rejet / abandon +- Traitement groupé au niveau unitaire pour agréger les *bulks* diff --git a/docs/fr/technical/technical/central-event-processor/README.md b/docs/fr/technical/technical/central-event-processor/README.md new file mode 100644 index 000000000..7a1ac3567 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/README.md @@ -0,0 +1,13 @@ +# Service Central Event Processor + +Le service **Central Event Processor** (**CEP**) permet de surveiller un ensemble de règles métier ou de motifs prédéfinis ou configurés. + +Dans l’itération actuelle, les règles portent sur trois critères : + + 1. Dépassement d’un seuil sur la limite du plafond de débit net (qui peut être fixée lors de l’embarquement), + 2. Ajustement de la limite — plafond de débit net, + 3. Ajustement de position suite à un règlement. + +Le CEP peut ensuite être couplé à un service de notification pour envoyer des notifications ou des alertes. Ici, il s’intègre à **email-notifier** pour envoyer des alertes selon les critères susmentionnés. + +![Architecture du Central Event Processor](./assets/diagrams/architecture/CEPArchTechOverview.svg) diff --git a/mojaloop-technical-overview/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg b/docs/fr/technical/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg similarity index 100% rename from mojaloop-technical-overview/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg rename to docs/fr/technical/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml new file mode 100644 index 000000000..2610f98ca --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml @@ -0,0 +1,95 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 9.1.0. Gestionnaire d'événements (espace réservé) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Gestionnaire d'événements\n(espace réservé)" as EVENT_HANDLER + +box "Gestionnaire d'événements (espace réservé)" #LightGray + participant EVENT_HANDLER +end box + +collections "Topic Événements" as TOPIC_EVENTS + +' start flow +activate EVENT_HANDLER + +group Gestionnaire d'événements (espace réservé) + EVENT_HANDLER -> TOPIC_EVENTS : Consommer le message d'événement \n Code d'erreur : 2001 + note right of EVENT_HANDLER #yellow + Message : + { + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: INFO, + action: AUDIT, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + note right of EVENT_HANDLER #LightGray + Le « type » serait une énumération (ENUM) avec les valeurs : + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + Les valeurs possibles pour « action » seraient + [AUDIT, EXCEPTION] + Les messages d'événement peuvent être traités en fonction des valeurs + de ces deux variables (lorsque l'espace réservé est étendu). + end note + EVENT_HANDLER -> EVENT_HANDLER : Auto-commit \n Code d'erreur : 2001 + note right of EVENT_HANDLER #lightBlue + Pour l'instant, les événements ne sont publiés que dans le cadre + de l'espace réservé. Ce comportement pourra évoluer pour ajouter + les fonctionnalités pertinentes. + end note + activate TOPIC_EVENTS + deactivate TOPIC_EVENTS +end +deactivate EVENT_HANDLER + +@enduml diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg new file mode 100644 index 000000000..fc69e9721 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg @@ -0,0 +1,86 @@ + + 9.1.0. Gestionnaire d'événements (espace réservé) + + + 9.1.0. Gestionnaire d'événements (espace réservé) + + Gestionnaire d'événements (espace réservé) + + + + + + Gestionnaire d'événements + (espace réservé) + + + Gestionnaire d'événements + (espace réservé) + + + + + Topic Événements + + + Topic Événements + + + + + Gestionnaire d'événements (espace réservé) + + + 1 + Consommer le message d'événement +   + Code d'erreur : + 2001 + + + Message : + { + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: INFO, + action: AUDIT, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + Le « type » serait une énumération (ENUM) avec les valeurs : + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + Les valeurs possibles pour « action » seraient + [AUDIT, EXCEPTION] + Les messages d'événement peuvent être traités en fonction des valeurs + de ces deux variables (lorsque l'espace réservé est étendu). + + + + + 2 + Auto-commit +   + Code d'erreur : + 2001 + + + Pour l'instant, les événements ne sont publiés que dans le cadre + de l'espace réservé. Ce comportement pourra évoluer pour ajouter + les fonctionnalités pertinentes. + + diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml new file mode 100644 index 000000000..ab43deeb4 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml @@ -0,0 +1,111 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Henk Kodde + -------------- + ******'/ + +@startuml +' declate title +title 5.1.1. Gestionnaire de notifications pour les rejets + +autonumber + +' Actor Keys: + +' declare actors + +actor "DFSP1\nPayeur" as DFSP1 +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Topic Événements" as TOPIC_EVENT +collections "Topic Notifications" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS +end box + +' start flow + +group Notification du DFSP en cas de rejet + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> TOPIC_NOTIFICATIONS : Consommer le message d'événement de notification \n Code d'erreur : 2001 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + group Persister les informations d'événement + NOTIFY_HANDLER -> TOPIC_EVENT : Publier les informations d'événement \n Code d'erreur : 3201 + activate TOPIC_EVENT + ref over TOPIC_EVENT : Gestionnaire d'événements + deactivate TOPIC_EVENT + end + + alt consommer un message unique + group Valider l'événement + NOTIFY_HANDLER <-> NOTIFY_HANDLER : Valider l'événement — Règle : type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + end + NOTIFY_HANDLER -> CSAPI : Demander les détails de callback du participant \n Code d'erreur : 3201 + ref over NOTIFY_HANDLER, CSAPI : Obtenir les détails de callback du participant + NOTIFY_HANDLER <-- CSAPI : Retourner les détails de callback du participant + note left of NOTIFY_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + payload: + }, + } + end note + NOTIFY_HANDLER --> DFSP1 : Envoyer la notification de callback \n Code d'erreur : 1000, 1001, 3002 + else Règle de validation type != 'notification' / Erreur + note right of NOTIFY_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + NOTIFY_HANDLER -> TOPIC_EVENT : Messages invalides récupérés depuis le topic Notifications \n Code d'erreur : 3201 + activate TOPIC_EVENT + deactivate TOPIC_EVENT + ref over TOPIC_EVENT: Gestionnaire d'événements + note right of NOTIFY_HANDLER #lightblue + Journaliser les messages d'ERREUR + Mettre à jour le journal d'événements lors de la notification d'ERREUR + end note +' deactivate TOPIC_NOTIFICATIONS + end +end +@enduml diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg new file mode 100644 index 000000000..6f6d0e300 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg @@ -0,0 +1,160 @@ + + 5.1.1. Gestionnaire de notifications pour les rejets + + + 5.1.1. Gestionnaire de notifications pour les rejets + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Topic Événements + + + Topic Événements + + + Topic Notifications + + + Topic Notifications + + + + + + + Notification du DFSP en cas de rejet + + + 1 + Consommer le message d'événement de notification +   + Code d'erreur : + 2001 + + + Persister les informations d'événement + + + 2 + Publier les informations d'événement +   + Code d'erreur : + 3201 + + + ref + Gestionnaire d'événements + + + alt + [consommer un message unique] + + + Valider l'événement + + + + + + 3 + Valider l'événement — Règle : type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + + + 4 + Demander les détails de callback du participant +   + Code d'erreur : + 3201 + + + ref + Obtenir les détails de callback du participant + + + 5 + Retourner les détails de callback du participant + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + payload: <transferMessage> + }, + } + + + 6 + Envoyer la notification de callback +   + Code d'erreur : + 1000, 1001, 3002 + + [Règle de validation type != 'notification' / Erreur] + + + Message : + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 7 + Messages invalides récupérés depuis le topic Notifications +   + Code d'erreur : + 3201 + + + ref + Gestionnaire d'événements + + + Journaliser les messages d'ERREUR + Mettre à jour le journal d'événements lors de la notification d'ERREUR + + diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml new file mode 100644 index 000000000..c3d8294e1 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml @@ -0,0 +1,35 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + * Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title Validation de la signature + +Alice -> Bob : Demande d'authentification +Bob --> Alice : Réponse d'authentification + +Alice -> Bob : Autre demande d'authentification +Alice <-- Bob : Autre réponse d'authentification +@enduml diff --git a/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg new file mode 100644 index 000000000..8d3785474 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg @@ -0,0 +1,29 @@ + + Validation de la signature + + + Validation de la signature + + + + Alice + + Alice + + Bob + + Bob + + + Demande d'authentification + + + Réponse d'authentification + + + Autre demande d'authentification + + + Autre réponse d'authentification + + diff --git a/docs/fr/technical/technical/central-event-processor/event-handler-placeholder.md b/docs/fr/technical/technical/central-event-processor/event-handler-placeholder.md new file mode 100644 index 000000000..e8eef32fa --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/event-handler-placeholder.md @@ -0,0 +1,7 @@ +# Gestionnaire d’événements — Provisoire + +Diagramme de conception de séquence pour le processus du gestionnaire d’événements. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-event-9.1.0.svg) diff --git a/docs/fr/technical/technical/central-event-processor/notification-handler-for-rejections.md b/docs/fr/technical/technical/central-event-processor/notification-handler-for-rejections.md new file mode 100644 index 000000000..40fc3fde8 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/notification-handler-for-rejections.md @@ -0,0 +1,12 @@ +# Gestionnaire de notifications pour les rejets + +Diagramme de conception de séquence pour le processus du gestionnaire de notifications en cas de rejet. + +## Références au sein du diagramme de conception de séquence + +* [Consommation du gestionnaire d’événements (9.1.0)](event-handler-placeholder.md) +* [Récupérer les détails de callback du participant (3.1.0)](../central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-notification-reject-5.1.1.svg) diff --git a/docs/fr/technical/technical/central-event-processor/signature-validation.md b/docs/fr/technical/technical/central-event-processor/signature-validation.md new file mode 100644 index 000000000..dd42df493 --- /dev/null +++ b/docs/fr/technical/technical/central-event-processor/signature-validation.md @@ -0,0 +1,7 @@ +# Validation de la signature + +Diagramme de conception de séquence pour le processus de validation de la signature. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-signature-validation.svg) diff --git a/mojaloop-technical-overview/account-lookup-service/assets/.gitkeep b/docs/fr/technical/technical/central-ledger/.gitkeep similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/.gitkeep rename to docs/fr/technical/technical/central-ledger/.gitkeep diff --git a/docs/fr/technical/technical/central-ledger/README.md b/docs/fr/technical/technical/central-ledger/README.md new file mode 100644 index 000000000..ea41e13b5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/README.md @@ -0,0 +1,53 @@ +# Services du registre central (*Central Ledger*) + +Le registre central est une série de services qui assurent la compensation et le règlement des transferts entre DFSP, notamment : + +* L’intermédiation des messages en temps réel pour la compensation des fonds +* Le maintien des positions nettes pour un règlement net différé +* La propagation des frais au niveau du schéma de paiement et des frais hors transfert + +## 1. Conception du processus du registre central + +### 1.1 Vue d’ensemble de l’architecture + +![Architecture du registre central](./assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg) + +## 2. Architecture de bout en bout des transferts + +### 2.1 Architecture de bout en bout des transferts (v1.1) + +![Architecture des transferts pour l’API d’interopérabilité Mojaloop FSP v1.1](./assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg) + +### 2.2 Architecture de bout en bout des transferts (v1.0) + +![Architecture des transferts pour l’API d’interopérabilité Mojaloop FSP v1.0](./assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg) + +## 3. Conception de la base de données + +### Remarque + +Les tables en *gris* sont propres au processus de transfert. Les tables en *bleu* et *vert* sont utilisées à titre de référence pendant le processus de transfert. + +Résumé des tables liées au transfert : + +- `transfer` — données du transfert ; +- `transferDuplicateCheck` — identification des requêtes dupliquées lors du processus de demandes de transfert ; +- `transferError` — erreurs rencontrées pendant le transfert ; +- `transferErrorDuplicateCheck` — détection des doublons pour les processus d’erreur ; +- `transferExtensions` — données d’extension du transfert ; +- `transferFulfilment` — transferts ayant terminé la phase *prepare* ; +- `transferFulfilmentDuplicateCheck` — identification des requêtes dupliquées pour les demandes d’acquittement de transfert ; +- `transferParticipant` — informations de participant liées au transfert ; +- `transferStateChange` — suivi des changements d’état de chaque transfert individuel, constituant une piste d’audit pour chaque demande de transfert spécifique ; +- `transferTimeout` — transferts ayant subi une expiration (*timeout*) ; +- `ilpPacket` — paquet ILP du transfert ; + +Les autres tables du MCD ci-dessous sont soit des tables de consultation (*lookup*, en bleu), soit spécifiques au règlement (en rouge), et figurent comme dépendances directes ou indirectes pour montrer la relation entre entités « transfert » et tables associées. + +La définition du schéma de base de données du **registre central** : [schéma SQL du registre central](./assets/database/central-ledger-ddl-MySQLWorkbench.sql). + +![Schéma de base du registre central](./assets/database/central-ledger-schema.png) + +## 4. Spécification d’API + +Voir **Central Ledger API** dans la section [Spécifications d’API](../../api/README.md#central-ledger-api). diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md new file mode 100644 index 000000000..07858367d --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md @@ -0,0 +1,265 @@ +# GET — Vérification d’état (Health Check) + +Discussion de conception pour la nouvelle implémentation de la vérification d’état. + + +## Objectifs + +L’objectif de cette conception est d’implémenter une nouvelle vérification d’état pour les services du switch Mojaloop permettant un niveau de détail accru. + +Elle prévoit notamment : +- Des codes HTTP explicites (inutile d’inspecter le corps de la réponse pour savoir s’il n’y a pas de problème) +- ~Rétrocompatibilité avec les vérifications d’état existantes~ — Ce n’est plus une exigence. Voir [cette discussion](https://github.com/mojaloop/project/issues/796#issuecomment-498350828). +- Des informations sur la version de l’API et la durée de fonctionnement du service +- Des informations sur les connexions aux sous-services (Kafka, sidecar de journalisation et MySQL) + +## Format de la requête +`/health` + +Utilise la vérification d’état nouvellement implémentée. Comme évoqué [ici](https://github.com/mojaloop/project/issues/796#issuecomment-498350828), comme il n’y aura pas de surcharge de connexion supplémentaire (par ex. requête vers une base de données) dans l’implémentation de la vérification d’état, il n’est pas nécessaire de compliquer les choses avec une version « simple » et une version « détaillée ». + +Codes de réponse : +- `200` — Succès. L’API est en ligne et connectée aux services nécessaires. +- `502` — Passerelle invalide (*Bad Gateway*). L’API est en ligne mais ne peut pas se connecter à un service nécessaire (par ex. `kafka`). +- `503` — Service indisponible. Cette réponse n’est pas implémentée dans cette conception, mais sera la réponse par défaut si l’API n’est pas en ligne. + +## Format de la réponse + +| Nom | Type | Description | Exemple | +| --- | --- | --- | --- | +| `status` | `statusEnum` | État du service. Valeurs possibles : `OK` et `DOWN`. _Voir `statusEnum` ci-dessous_. | `"OK"` | +| `uptime` | `number` | Durée de vie du service en secondes. | `123456` | +| `started` | `string` (date-heure au format ISO) | Date et heure de démarrage du service (UTC) | `"2019-05-31T05:09:25.409Z"` | +| `versionNumber` | `string` (semver) | Version courante du service. | `"5.2.5"` | +| `services` | `Array` | Liste des services dont dépend ce service et statut de connexion | _voir ci-dessous_ | + +### serviceHealth + +| Nom | Type | Description | Exemple | +| --- | --- | --- | --- | +| `name` | `subServiceEnum` | Nom du sous-service. _Voir `subServiceEnum` ci-dessous_. | `"broker"` | +| `status` | `enum` | État du service. Valeurs possibles : `OK` et `DOWN` | `"OK"` | + +### subServiceEnum + +L’énumération `subServiceEnum` décrit le nom du sous-service : + +Options : +- `datastore` → Base de données de ce service (typiquement MySQL). +- `broker` → Courtier de messages de ce service (typiquement Kafka). +- `sidecar` → Sous-service sidecar de journalisation auquel ce service est rattaché. +- `cache` → Sous-service de mise en cache auquel ce service est rattaché. + + +### statusEnum + +L’énumération d’état représente l’état du système ou d’un sous-service. + +Elle comporte deux options : +- `OK` → Le service ou sous-service est sain. +- `DOWN` → Le service ou sous-service est dégradé ou indisponible. + +Lorsqu’un service est `OK` : l’API est considérée comme saine, et tous les sous-services le sont également. + +Si __un quelconque__ sous-service est `DOWN`, l’ensemble de la vérification d’état échoue et l’API est considérée comme `DOWN`. + +## Définition de l’état des sous-services + +Il ne suffit pas de « pinger » un sous-service pour savoir s’il est sain ; il faut aller plus loin. Ces critères évolueront selon le sous-service. + +### `datastore` + +Pour `datastore`, un état `OK` signifie : +- Une connexion active à la base de données +- La base n’est pas vide (contient plus d’une table) + + +### `broker` + +Pour `broker`, un état `OK` signifie : +- Une connexion active au courtier Kafka +- Les rubriques (*topics*) nécessaires existent. Cela dépend du service sur lequel s’exécute la vérification d’état. + +Par exemple, pour que le service `central-ledger` soit considéré comme sain, les rubriques suivantes doivent être présentes : +``` +topic-admin-transfer +topic-transfer-prepare +topic-transfer-position +topic-transfer-fulfil +``` + +### `sidecar` + +Pour `sidecar`, un état `OK` signifie : +- Une connexion active au sidecar + + +### `cache` + +Pour `cache`, un état `OK` signifie : +- Une connexion active au cache + + +## Définition Swagger + +>_Remarque : ces éléments seront ajoutés aux définitions Swagger existantes des services suivants :_ +> - `ml-api-adapter` +> - `central-ledger` +> - `central-settlement` +> - `central-event-processor` +> - `email-notifier` + +```json +{ + /// . . . + "/health": { + "get": { + "operationId": "getHealth", + "tags": [ + "health" + ], + "responses": { + "default": { + "schema": { + "$ref": "#/definitions/health" + }, + "description": "Succès" + } + } + } + }, + // . . . + "definitions": { + "health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + }, + "uptime": { + "description": "Durée de vie du service en secondes.", + "type": "number", + }, + "started": { + "description": "Date et heure de démarrage du service (UTC)", + "type": "string", + "format": "date-time" + }, + "versionNumber": { + "description": "Version courante du service.", + "type": "string", + "example": "5.2.3", + }, + "services": { + "description": "Liste des services dont dépend ce service et statut de connexion", + "type": "array", + "items": { + "$ref": "#/definitions/serviceHealth" + } + }, + }, + }, + "serviceHealth": { + "type": "object", + "properties": { + "name": { + "description": "Nom du sous-service.", + "type": "string", + "enum": [ + "datastore", + "broker", + "sidecar", + "cache" + ] + }, + "status": { + "description": "Statut de connexion avec le service.", + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + } + } + } + } +} +``` + + +### Exemples de requêtes et de réponses : + +__Vérification d’état héritée réussie :__ + +```bash +GET /health HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK" +} +``` + + +__Nouvelle vérification d’état réussie :__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "OK", + } + ] +} +``` + +__Vérification d’état en échec, mais API en ligne :__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +502 BAD GATEWAY +{ + "status": "DOWN", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "DOWN", + } + ] +} +``` + +__Vérification d’état en échec :__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +503 SERVICE UNAVAILABLE +``` + + +## Diagramme de séquence + +Diagramme de séquence pour l’endpoint GET /health (vérification d’état). + +![seq-get-health-1.0.0.svg](../assets/diagrams/sequence/seq-get-health-1.0.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md new file mode 100644 index 000000000..1ebe092be --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md @@ -0,0 +1,7 @@ +# GET — Détails des limites de participant pour tous les participants + +Diagramme de séquence de conception pour le processus GET des détails de limite de participant pour tous les participants. + +## Diagramme de séquence + +![seq-get-all-participant-limit-1.0.0.svg](../assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md new file mode 100644 index 000000000..bffddb460 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md @@ -0,0 +1,7 @@ +# Création de la position initiale et des limites d’un participant + +Diagramme de séquence de conception pour le processus POST (création) de la position initiale et de la limite d’un participant. + +## Diagramme de séquence + +![seq-participant-position-limits-1.0.0.svg](../assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md new file mode 100644 index 000000000..69eb2bf42 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md @@ -0,0 +1,7 @@ +# Demander les détails de position et de limite d’un participant + +Diagramme de séquence pour le processus de demande des détails de position et de limite d’un participant. + +## Diagramme de séquence + +![seq-get-participant-position-limit-1.1.0.svg](../assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md new file mode 100644 index 000000000..e2a521a05 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md @@ -0,0 +1,7 @@ +# Ajuster la limite d’un participant pour une devise donnée + +Diagramme de séquence pour le processus POST (gestion) des détails de limite d’un participant. + +## Diagramme de séquence + +![seq-manage-participant-limit-1.1.0.svg](../assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md new file mode 100644 index 000000000..f0785e1a6 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md @@ -0,0 +1,7 @@ +# Demander le statut d’un transfert + +Diagramme de séquence pour le processus GET du statut de transfert. + +## Diagramme de séquence + +![seq-get-transfer-1.1.5-phase2.svg](../assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md b/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md new file mode 100644 index 000000000..21b054c8c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Obtenir les détails de rappel (*callback*) d’un participant + +Diagramme de séquence pour le processus GET des détails de rappel d’un participant. + +## Diagramme de séquence + +![seq-callback-3.1.0.svg](../assets/diagrams/sequence/seq-callback-3.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md b/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md new file mode 100644 index 000000000..676db84f8 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Ajouter les détails de rappel (*callback*) d’un participant + +Diagramme de séquence pour le processus POST (ajout) des détails de rappel d’un participant. + +## Diagramme de séquence + +![seq-callback-add-3.1.0.svg](../assets/diagrams/sequence/seq-callback-add-3.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md b/docs/fr/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md new file mode 100644 index 000000000..451499e88 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md @@ -0,0 +1,7 @@ +# Obtenir les détails de position d’un participant + +Diagramme de séquence pour le processus GET des détails de position d’un participant. + +## Diagramme de séquence + +![seq-participants-positions-query-4.1.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md b/docs/fr/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md new file mode 100644 index 000000000..fb221a42f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md @@ -0,0 +1,7 @@ +# Obtenir les détails de position pour tous les participants + +Diagramme de séquence pour le processus d’obtention des positions de tous les participants. + +## Diagramme de séquence + +![seq-participants-positions-query-all-4.2.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/admin-operations/README.md b/docs/fr/technical/technical/central-ledger/admin-operations/README.md new file mode 100644 index 000000000..1601cb59e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/admin-operations/README.md @@ -0,0 +1,3 @@ +# Opérations Mojaloop HUB/Switch + +Processus opérationnels généralement initiés par un opérateur du HUB/Switch. diff --git a/docs/fr/technical/technical/central-ledger/assets/database/README.md b/docs/fr/technical/technical/central-ledger/assets/database/README.md new file mode 100644 index 000000000..d931c6fc0 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/database/README.md @@ -0,0 +1,20 @@ +# Comment modifier le fichier central-ledger-schema-DBeaver.erd + +Guide de base pour consulter ou mettre à jour le fichier `central-ledger-schema-DBeaver.erd`. + +## Prérequis + +* Installer DBeaver Community (gestionnaire de bases de données) +* La base MySQL du registre central Mojaloop doit être démarrée et accessible depuis DBeaver +* Un éditeur de texte + +## Étapes + +* Créer une connexion à la base MySQL dans DBeaver (onglet *Database Navigator*). +* Sous l’onglet *Projects*, clic droit puis créer un nouveau diagramme ER. +* Nommer le diagramme et sélectionner la base `central-ledger` dans l’assistant. + +* Copier le fichier `central-ledger-schema-DBeaver.erd` du module de documentation vers `DBeaverData/workspace/General/Diagrams` à l’emplacement de stockage DBeaver. +* Ouvrir avec un éditeur le fichier `.erd` nouvellement créé, rechercher `data-source id` et copier sa valeur (ex. `mysql5-171ea991174-1218b6e1bf273693`). +* Ouvrir `central-ledger-schema-DBeaver.erd` du dossier des diagrammes ER et remplacer la valeur `data-source id` par celle copiée. +* Le fichier `central-ledger-schema-DBeaver.erd` doit alors afficher les tables comme sur `central-ledger-schema.png`. diff --git a/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql rename to docs/fr/technical/technical/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql diff --git a/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd b/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd new file mode 100644 index 000000000..303fa1534 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema.png b/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema.png new file mode 100644 index 000000000..62b4a1a1e Binary files /dev/null and b/docs/fr/technical/technical/central-ledger/assets/database/central-ledger-schema.png differ diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg rename to docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End.svg rename to docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg new file mode 100644 index 000000000..02658b83d --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (optional) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg new file mode 100644 index 000000000..e9a1460c8 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (if transfer reserved) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml new file mode 100644 index 000000000..d406585bb --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml @@ -0,0 +1,160 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 3.1.0 Détails de rappel (callback) du participant + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "ML-API-ADAPTER" as MLAPI +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB +box "Service adaptateur ML API" #LightBlue +participant MLAPI +end box + +box "Services centraux" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate MLAPI +group Obtenir les détails de rappel (callback) + MLAPI -> CSAPI: Demande d'obtenir les détails de rappel — GET - /participants/{name}/endpoints?type={typeValue} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Récupérer les détails de rappel du participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer le participant \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer le participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Participant récupéré + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer le participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: vérifier si le paramètre « type » est envoyé + alt Paramètre « type » envoyé (oui) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les détails de rappel du participant et du type \nCode d'erreur : 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer les détails de rappel du participant et du type + note right of PARTICIPANT_DAO #lightgrey + Condition : + isActive = 1 + [endpointTypeId = ] + end note + + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB --> PARTICIPANT_DAO: Détails de rappel récupérés pour le participant et le type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les détails de rappel du participant et du type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + { + endpoints: {type: , value: } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les détails de rappel du participant + deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Renvoyer les détails de rappel du participant + else Paramètre « type » envoyé (non) + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les détails de rappel du participant \nCode d'erreur : 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer les détails de rappel du participant + note right of PARTICIPANT_DAO #lightgrey + Condition : + isActive = 1 + end note + + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB --> PARTICIPANT_DAO: Détails de rappel récupérés pour le participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les détails de rappel du participant + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + { + endpoints: [ + {type: , value: }, + {type: , value: } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les détails de rappel du participant + ' deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Renvoyer les détails de rappel du participant + end + + + else Valider le participant (échec) / erreur + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Échec de validation / erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Renvoyer Code d'erreur : 3000, 3200 + + end + deactivate CSAPI + deactivate MLAPI +end + +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg new file mode 100644 index 000000000..5784732ce --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg @@ -0,0 +1,228 @@ + + 3.1.0 Détails de rappel (callback) du participant + + + 3.1.0 Détails de rappel (callback) du participant + + Service adaptateur ML API + + Services centraux + + + + + + + + + + + + + + + + + + + ML-API-ADAPTER + + + ML-API-ADAPTER + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + Obtenir les détails de rappel (callback) + + + 1 + Demande d'obtenir les détails de rappel — GET - /participants/{name}/endpoints?type={typeValue} + + + 2 + Récupérer les détails de rappel du participant + + + 3 + Récupérer le participant + Code d'erreur : + 3200 + + + 4 + Récupérer le participant + + participant + + + 5 + Participant récupéré + + + 6 + Renvoyer le participant + + + + + 7 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + + + 8 + vérifier si le paramètre « type » est envoyé + + + alt + [Paramètre « type » envoyé (oui)] + + + 9 + Récupérer les détails de rappel du participant et du type + Code d'erreur : + 3000 + + + 10 + Récupérer les détails de rappel du participant et du type + + + Condition : + isActive = 1 + [endpointTypeId = <type>] + + participantEndpoint + + + 11 + Détails de rappel récupérés pour le participant et le type + + + 12 + Renvoyer les détails de rappel du participant et du type + + + Message : + { + endpoints: {type: <type>, value: <value>} + } + + + 13 + Renvoyer les détails de rappel du participant + + + 14 + Renvoyer les détails de rappel du participant + + [Paramètre « type » envoyé (non)] + + + 15 + Récupérer les détails de rappel du participant + Code d'erreur : + 3000 + + + 16 + Récupérer les détails de rappel du participant + + + Condition : + isActive = 1 + + participantEndpoint + + + 17 + Détails de rappel récupérés pour le participant + + + 18 + Renvoyer les détails de rappel du participant + + + Message : + { + endpoints: [ + {type: <type>, value: <value>}, + {type: <type>, value: <value>} + ] + } + + + 19 + Renvoyer les détails de rappel du participant + + + 20 + Renvoyer les détails de rappel du participant + + [Valider le participant (échec) / erreur] + + + Échec de validation / erreur ! + + + Message : + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 21 + Renvoyer + Code d'erreur : + 3000, 3200 + + + 22 + Renvoyer + Code d'erreur : + 3000, 3200 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml new file mode 100644 index 000000000..13e9377f4 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml @@ -0,0 +1,149 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + + +@startuml +' declate title +title 3.1.0 Ajout des détails de rappel du participant + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Services centraux" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Ajouter les détails de rappel (callback) + OPERATOR -> CSAPI: Demande d'ajouter les détails de rappel — POST - /paticipants/{name}/endpoints + note right of OPERATOR #yellow + Message : + { + payload: { + endpoint: { + type: , + value: + } + } + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Ajouter les détails de rappel du participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer le participant \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer le participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Participant récupéré + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer le participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Ajouter les détails de rappel du participant \nCode d'erreur : 2003/Msg : Service unavailable \nCode d'erreur : 2001/Msg : Internal Server Error + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Persister l'endpoint participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + deactivate DB + note right of PARTICIPANT_DAO #lightgrey + Si (endpoint existe && isActive = 1) + oldEndpoint.isActive = 0 + insérer endpoint + Sinon + insérer endpoint + Fin + + end note + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer le statut + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Valider le statut + alt Valider le statut (succès) + PARTICIPANT_HANDLER -->CSAPI: Renvoyer le code statut 201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer le code statut 201 + else Valider le statut (échec) / erreur + note right of PARTICIPANT_HANDLER #red: Erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur + + end + + else Valider le participant (échec) + note right of PARTICIPANT_HANDLER #red: Échec de validation ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3200 + + end + deactivate CSAPI + deactivate OPERATOR +end +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg new file mode 100644 index 000000000..440440e03 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg @@ -0,0 +1,215 @@ + + 3.1.0 Ajout des détails de rappel du participant + + + 3.1.0 Ajout des détails de rappel du participant + + Services centraux + + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + Ajouter les détails de rappel (callback) + + + 1 + Demande d'ajouter les détails de rappel — POST - /paticipants/{name}/endpoints + + + Message : + { + payload: { + endpoint: { + type: <typeValue>, + value: <endpointValue> + } + } + } + + + 2 + Ajouter les détails de rappel du participant + + + 3 + Récupérer le participant + Code d'erreur : + 3200 + + + 4 + Récupérer le participant + + participant + + + 5 + Participant récupéré + + + 6 + Renvoyer le participant + + + + + 7 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + 8 + Ajouter les détails de rappel du participant + Code d'erreur : + 2003/ + Msg : + Service unavailable +   + Code d'erreur : + 2001/ + Msg : + Internal Server Error + + + 9 + Persister l'endpoint participant + + participantEndpoint + + + Si (endpoint existe && isActive = 1) + oldEndpoint.isActive = 0 + insérer endpoint + Sinon + insérer endpoint + Fin +      + + + 10 + Renvoyer le statut + + + + + 11 + Valider le statut + + + alt + [Valider le statut (succès)] + + + 12 + Renvoyer le code statut 201 + + + 13 + Renvoyer le code statut 201 + + [Valider le statut (échec) / erreur] + + + Erreur ! + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 14 + Renvoyer + Code d'erreur + + + 15 + Renvoyer + Code d'erreur + + [Valider le participant (échec)] + + + Échec de validation ! + + + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + + + 16 + Renvoyer + Code d'erreur : + 3200 + + + 17 + Renvoyer + Code d'erreur : + 3200 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml new file mode 100644 index 000000000..a24c0b1ce --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml @@ -0,0 +1,207 @@ +/' + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Valentin Genev + -------------- + '/ + + +@startuml +' declate title +title 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert v1.1 + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "topic-fulfil" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Gestionnaire de modèle\nde règlement" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire de position" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Services centraux" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group DFSP2 envoie une demande de notification après validation du transfert dans le Switch + DFSP2 <-> DFSP2: Récupérer la chaîne d'exécution générée lors du\nprocessus de devis ou la régénérer avec\n**Local secret** et **ILP Packet** comme entrées + alt Renvoyer la demande de notification de réservation + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "fulfilment": , + "transferState": "RESERVED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + else Renvoyer la demande de validation + + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "fulfilment": , + "completedTimestamp": , + "transferState": "COMMITTED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + end + DFSP2 ->> MLAPI: PUT - /transfers/ + activate MLAPI + MLAPI -> MLAPI: Valider le jeton entrant et l'initiateur correspondant au bénéficiaire\nCodes d'erreur : 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reserve || commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement d'exécution pour le bénéficiaire\nCode d'erreur : 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué tel que configuré (ACKS=all)\nCode d'erreur : 2003 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation par le gestionnaire d'exécution (succès) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg 2.1.1-v1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produire le message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consommer le message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Consommation par le gestionnaire de modèle de règlement (succès)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation par le gestionnaire de position (succès)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'reserve' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg new file mode 100644 index 000000000..c6e4ec61f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg @@ -0,0 +1,340 @@ + + 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert v1.1 + + + 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert v1.1 + + Fournisseurs de services financiers + + Service adaptateur ML API + + Services centraux + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + topic-fulfil + + + topic-fulfil + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic- + settlement-model + + + topic- + settlement-model + Gestionnaire de modèle + de règlement + + + Gestionnaire de modèle + de règlement + + + + + topic- + transfer-position + + + topic- + transfer-position + Gestionnaire de position + + + Gestionnaire de position + + + + + topic- + notification + + + topic- + notification + + + + + + + + + DFSP2 envoie une demande de notification après validation du transfert dans le Switch + + + + + + 1 + Récupérer la chaîne d'exécution générée lors du + processus de devis ou la régénérer avec + Local secret + et + ILP Packet + comme entrées + + + alt + [Renvoyer la demande de notification de réservation] + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "fulfilment": <IlpFulfilment>, + "transferState": "RESERVED" + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + [Renvoyer la demande de validation] + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "COMMITTED" + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + Codes d'erreur : + 3000-3002, 3100-3107 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reserve || commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Acheminer et publier l'événement d'exécution pour le bénéficiaire + Code d'erreur : + 2003 + + + + + + 5 + S'assurer que l'événement est répliqué tel que configuré (ACKS=all) + Code d'erreur : + 2003 + + + 6 + Répondre que les accusés de réplication ont été reçus + + + + 7 + Répondre HTTP — 200 (OK) + + + 8 + Consommer le message + + + ref + Consommation par le gestionnaire d'exécution (succès) { + 2.1.1-v1.1 + } +   + + + 9 + Produire le message + + + 10 + Produire le message + + + 11 + Consommer le message + + + ref + Consommation par le gestionnaire de modèle de règlement (succès) +   + + + 12 + Consommer le message + + + ref + Consommation par le gestionnaire de position (succès) +   + + + 13 + Produire le message + + + 14 + Consommer le message + + + opt + [action == 'commit'] + + + ref + Envoyer une notification au participant (payeur) +   + + + 15 + Envoyer la notification de rappel (callback) + + + 16 + Consommer le message + + + opt + [action == 'reserve'] + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 17 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml new file mode 100644 index 000000000..d54d1e58f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml @@ -0,0 +1,174 @@ +/' + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + '/ + + +@startuml +' declate title +title 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "topic-fulfil" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Gestionnaire de modèle\nde règlement" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire de position" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Services centraux" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group DFSP2 envoie une demande d'exécution réussie du transfert + DFSP2 <-> DFSP2: Récupérer la chaîne d'exécution générée lors du\nprocessus de devis ou la régénérer avec\n**Local secret** et **ILP Packet** comme entrées + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "fulfilment": , + "completedTimestamp": , + "transferState": "COMMITTED", + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers/ + activate MLAPI + MLAPI -> MLAPI: Valider le jeton entrant et l'initiateur correspondant au bénéficiaire\nCodes d'erreur : 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement d'exécution pour le bénéficiaire\nCode d'erreur : 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué tel que configuré (ACKS=all)\nCode d'erreur : 2003 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation par le gestionnaire d'exécution (succès) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg 2.1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produire le message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consommer le message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Consommation par le gestionnaire de modèle de règlement (succès)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation par le gestionnaire de position (succès)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'commit' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg new file mode 100644 index 000000000..6b011bbe5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg @@ -0,0 +1,305 @@ + + 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert + + + 2.1.0. DFSP2 envoie une demande d'exécution réussie du transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Services centraux + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + topic-fulfil + + + topic-fulfil + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic- + settlement-model + + + topic- + settlement-model + Gestionnaire de modèle + de règlement + + + Gestionnaire de modèle + de règlement + + + + + topic- + transfer-position + + + topic- + transfer-position + Gestionnaire de position + + + Gestionnaire de position + + + + + topic- + notification + + + topic- + notification + + + + + + + + + DFSP2 envoie une demande d'exécution réussie du transfert + + + + + + 1 + Récupérer la chaîne d'exécution générée lors du + processus de devis ou la régénérer avec + Local secret + et + ILP Packet + comme entrées + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "COMMITTED", + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + Codes d'erreur : + 3000-3002, 3100-3107 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Acheminer et publier l'événement d'exécution pour le bénéficiaire + Code d'erreur : + 2003 + + + + + + 5 + S'assurer que l'événement est répliqué tel que configuré (ACKS=all) + Code d'erreur : + 2003 + + + 6 + Répondre que les accusés de réplication ont été reçus + + + + 7 + Répondre HTTP — 200 (OK) + + + 8 + Consommer le message + + + ref + Consommation par le gestionnaire d'exécution (succès) { + 2.1.1 + } +   + + + 9 + Produire le message + + + 10 + Produire le message + + + 11 + Consommer le message + + + ref + Consommation par le gestionnaire de modèle de règlement (succès) +   + + + 12 + Consommer le message + + + ref + Consommation par le gestionnaire de position (succès) +   + + + 13 + Produire le message + + + 14 + Consommer le message + + + opt + [action == 'commit'] + + + ref + Envoyer une notification au participant (payeur) +   + + + 15 + Envoyer la notification de rappel (callback) + + + 16 + Consommer le message + + + opt + [action == 'commit'] + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 17 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml new file mode 100644 index 000000000..fb43d387c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml @@ -0,0 +1,273 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.1. Consommation par le gestionnaire d'exécution (succès) v1.1 +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-fulfil" as TOPIC_FULFIL +control "Gestionnaire d'événements\nd'exécution" as FULF_HANDLER +collections "topic-event" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +entity "DAO de position" as POS_DAO +database "Stockage central" as DB +box "Service central" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_SETMODEL + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Consommation par le gestionnaire d'exécution (succès) + alt Consommer un message unique + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message d'événement d'exécution pour le payeur + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Valider l'événement + FULF_HANDLER <-> FULF_HANDLER: Valider l'événement — règle : type == 'fulfil' && action IN ['commit', 'reserve']\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + FULF_HANDLER -> TOPIC_EVENT: Publier les informations d'événement + ref over FULF_HANDLER, TOPIC_EVENT: Consommation du gestionnaire d'événements\n + ||| + end + + group Valider le contrôle de doublon + ||| + FULF_HANDLER -> DB: Demande de contrôle de doublon + ref over FULF_HANDLER, DB: Contrôle de doublon de requête\n + DB --> FULF_HANDLER: Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Rappel (callback) getTransfer\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else + note right of FULF_HANDLER #lightgrey + Ignorer — renvoi en cours + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validation préparation transfert (échec) — requête modifiée + end note + else hasDuplicateId == FALSE + group Valider et persister l'exécution du transfert + FULF_HANDLER -> POS_DAO: Demander les informations pour les contrôles de validation\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer depuis la base de données + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Renvoyer le transfert + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nCode d'erreur : 2001 + FULF_HANDLER -> FULF_HANDLER: Valider expirationDate\nCode d'erreur : 3303 + + opt Validation de Transfer.ilpCondition réussie + group Demander la fenêtre de règlement actuelle + FULF_HANDLER -> POS_DAO: Demande de récupérer la fenêtre de règlement actuelle/la plus récente\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Renvoyer settlementWindowId à ajouter lors de l'insertion transferFulfilment\n**TODO**: Lors de la conception du règlement, s'assurer que les transferts en état 'RECEIVED-FULFIL'\nsont mis à jour vers la prochaine fenêtre de règlement + deactivate POS_DAO + end + end + + group Persister l'exécution + FULF_HANDLER -> POS_DAO: Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid)\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Renvoyer le succès + deactivate POS_DAO + end + + alt Validation de Transfer.ilpCondition réussie + group Persister l'état du transfert (transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Demande de persister le transfert state\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: , + responseTo: , + type: setmodel, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_SETMODEL: Acheminer et publier l'événement de modèle de règlement + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le bénéficiaire + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validation d'exécution du transfert infructueuse + group Persister l'état du transfert (transferState='ABORTED') + FULF_HANDLER -> POS_DAO: Demande de persister le transfert state\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + else Consommer des messages groupés + note left of FULF_HANDLER #lightblue + À livrer dans une future itération + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg new file mode 100644 index 000000000..76be01bf9 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg @@ -0,0 +1,439 @@ + + 2.1.1. Consommation par le gestionnaire d'exécution (succès) v1.1 + + + 2.1.1. Consommation par le gestionnaire d'exécution (succès) v1.1 + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + topic-fulfil + Gestionnaire d'événements + d'exécution + + + Gestionnaire d'événements + d'exécution + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + + + topic- + settlement-model + + + topic- + settlement-model + + + topic- + notification + + + topic- + notification + DAO de position + + + DAO de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + Consommation par le gestionnaire d'exécution (succès) + + + alt + [Consommer un message unique] + + + 1 + Consommer le message d'événement d'exécution pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'fulfil' && action IN ['commit', 'reserve'] + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Valider le contrôle de doublon + + + 4 + Demande de contrôle de doublon + + + ref + Contrôle de doublon de requête +   + + + 5 + Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + Rappel (callback) getTransfer +   + + + 7 + Produire le message + + + + Ignorer — renvoi en cours + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validation préparation transfert (échec) — requête modifiée + + [hasDuplicateId == FALSE] + + + Valider et persister l'exécution du transfert + + + 8 + Demander les informations pour les contrôles de validation + Code d'erreur : + 2003 + + + 9 + Récupérer depuis la base de données + + transfer + + + 10 +   + + + 11 + Renvoyer le transfert + + + + + 12 + Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Code d'erreur : + 2001 + + + + + 13 + Valider expirationDate + Code d'erreur : + 3303 + + + opt + [Validation de Transfer.ilpCondition réussie] + + + Demander la fenêtre de règlement actuelle + + + 14 + Demande de récupérer la fenêtre de règlement actuelle/la plus récente + Code d'erreur : + 2003 + + + 15 + Récupérer settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Renvoyer settlementWindowId à ajouter lors de l'insertion transferFulfilment + TODO + : Lors de la conception du règlement, s'assurer que les transferts en état 'RECEIVED-FULFIL' + sont mis à jour vers la prochaine fenêtre de règlement + + + Persister l'exécution + + + 18 + Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid) + Code d'erreur : + 2003 + + + 19 + Persister en base de données + + transferFulfilment + transferExtension + + + 20 + Renvoyer le succès + + + alt + [Validation de Transfer.ilpCondition réussie] + + + Persister l'état du transfert (transferState='RECEIVED-FULFIL') + + + 21 + Demande de persister le transfert state + Code d'erreur : + 2003 + + + 22 + Persister l'état du transfert + + transferStateChange + + + 23 + Renvoyer le succès + + + Message : + { + id: <id>, + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: setmodel, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Acheminer et publier l'événement de modèle de règlement + + + Message : + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: commit || reserve, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 25 + Acheminer et publier l'événement de position pour le bénéficiaire + + [Validation d'exécution du transfert infructueuse] + + + Persister l'état du transfert (transferState='ABORTED') + + + 26 + Demande de persister le transfert state + Code d'erreur : + 2003 + + + 27 + Persister l'état du transfert + + transferStateChange + + + 28 + Renvoyer le succès + + + Message : + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 29 + Acheminer et publier l'événement de position pour le payeur + + [Consommer des messages groupés] + + + À livrer dans une future itération + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml new file mode 100644 index 000000000..bdb471f8e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml @@ -0,0 +1,272 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.1. Consommation par le gestionnaire d'exécution (succès) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-fulfil" as TOPIC_FULFIL +control "Gestionnaire d'événements\nd'exécution" as FULF_HANDLER +collections "topic-event" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +entity "DAO de position" as POS_DAO +database "Stockage central" as DB +box "Service central" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_SETMODEL + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Consommation par le gestionnaire d'exécution (succès) + alt Consommer un message unique + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message d'événement d'exécution pour le payeur + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Valider l'événement + FULF_HANDLER <-> FULF_HANDLER: Valider l'événement — règle : type == 'fulfil' && action == 'commit'\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + FULF_HANDLER -> TOPIC_EVENT: Publier les informations d'événement + ref over FULF_HANDLER, TOPIC_EVENT: Consommation du gestionnaire d'événements\n + ||| + end + + group Valider le contrôle de doublon + ||| + FULF_HANDLER -> DB: Demande de contrôle de doublon + ref over FULF_HANDLER, DB: Contrôle de doublon de requête\n + DB --> FULF_HANDLER: Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Rappel (callback) getTransfer\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else + note right of FULF_HANDLER #lightgrey + Ignorer — renvoi en cours + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validation préparation transfert (échec) — requête modifiée + end note + else hasDuplicateId == FALSE + group Valider et persister l'exécution du transfert + FULF_HANDLER -> POS_DAO: Demander les informations pour les contrôles de validation\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer depuis la base de données + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Renvoyer le transfert + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nCode d'erreur : 2001 + FULF_HANDLER -> FULF_HANDLER: Valider expirationDate\nCode d'erreur : 3303 + + opt Validation de Transfer.ilpCondition réussie + group Demander la fenêtre de règlement actuelle + FULF_HANDLER -> POS_DAO: Demande de récupérer la fenêtre de règlement actuelle/la plus récente\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Renvoyer settlementWindowId à ajouter lors de l'insertion transferFulfilment\n**TODO**: Lors de la conception du règlement, s'assurer que les transferts en état 'RECEIVED-FULFIL'\nsont mis à jour vers la prochaine fenêtre de règlement + deactivate POS_DAO + end + end + + group Persister l'exécution + FULF_HANDLER -> POS_DAO: Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid)\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Renvoyer le succès + deactivate POS_DAO + end + + alt Validation de Transfer.ilpCondition réussie + group Persister l'état du transfert (transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Demande de persister le transfert state\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: , + responseTo: , + type: setmodel, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_SETMODEL: Acheminer et publier l'événement de modèle de règlement + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le bénéficiaire + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validation d'exécution du transfert infructueuse + group Persister l'état du transfert (transferState='ABORTED') + FULF_HANDLER -> POS_DAO: Demande de persister le transfert state\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + else Consommer des messages groupés + note left of FULF_HANDLER #lightblue + À livrer dans une future itération + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg new file mode 100644 index 000000000..4cdbdeacb --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg @@ -0,0 +1,439 @@ + + 2.1.1. Consommation par le gestionnaire d'exécution (succès) + + + 2.1.1. Consommation par le gestionnaire d'exécution (succès) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + topic-fulfil + Gestionnaire d'événements + d'exécution + + + Gestionnaire d'événements + d'exécution + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + + + topic- + settlement-model + + + topic- + settlement-model + + + topic- + notification + + + topic- + notification + DAO de position + + + DAO de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + Consommation par le gestionnaire d'exécution (succès) + + + alt + [Consommer un message unique] + + + 1 + Consommer le message d'événement d'exécution pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'fulfil' && action == 'commit' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Valider le contrôle de doublon + + + 4 + Demande de contrôle de doublon + + + ref + Contrôle de doublon de requête +   + + + 5 + Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + Rappel (callback) getTransfer +   + + + 7 + Produire le message + + + + Ignorer — renvoi en cours + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validation préparation transfert (échec) — requête modifiée + + [hasDuplicateId == FALSE] + + + Valider et persister l'exécution du transfert + + + 8 + Demander les informations pour les contrôles de validation + Code d'erreur : + 2003 + + + 9 + Récupérer depuis la base de données + + transfer + + + 10 +   + + + 11 + Renvoyer le transfert + + + + + 12 + Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Code d'erreur : + 2001 + + + + + 13 + Valider expirationDate + Code d'erreur : + 3303 + + + opt + [Validation de Transfer.ilpCondition réussie] + + + Demander la fenêtre de règlement actuelle + + + 14 + Demande de récupérer la fenêtre de règlement actuelle/la plus récente + Code d'erreur : + 2003 + + + 15 + Récupérer settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Renvoyer settlementWindowId à ajouter lors de l'insertion transferFulfilment + TODO + : Lors de la conception du règlement, s'assurer que les transferts en état 'RECEIVED-FULFIL' + sont mis à jour vers la prochaine fenêtre de règlement + + + Persister l'exécution + + + 18 + Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid) + Code d'erreur : + 2003 + + + 19 + Persister en base de données + + transferFulfilment + transferExtension + + + 20 + Renvoyer le succès + + + alt + [Validation de Transfer.ilpCondition réussie] + + + Persister l'état du transfert (transferState='RECEIVED-FULFIL') + + + 21 + Demande de persister le transfert state + Code d'erreur : + 2003 + + + 22 + Persister l'état du transfert + + transferStateChange + + + 23 + Renvoyer le succès + + + Message : + { + id: <id>, + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: setmodel, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Acheminer et publier l'événement de modèle de règlement + + + Message : + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 25 + Acheminer et publier l'événement de position pour le bénéficiaire + + [Validation d'exécution du transfert infructueuse] + + + Persister l'état du transfert (transferState='ABORTED') + + + 26 + Demande de persister le transfert state + Code d'erreur : + 2003 + + + 27 + Persister l'état du transfert + + transferStateChange + + + 28 + Renvoyer le succès + + + Message : + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 29 + Acheminer et publier l'événement de position pour le payeur + + [Consommer des messages groupés] + + + À livrer dans une future itération + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml new file mode 100644 index 000000000..6aed2fce0 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml @@ -0,0 +1,111 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.0.0 Détails des limites de tous les participants + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "Façade participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Services centraux" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Obtenir les limites de tous les participants + OPERATOR -> CSAPI: Demande d'obtenir les limites — GET - /participants/limits?type={typeValue}¤cy={currencyType} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Récupérer les limites de tous les participants + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les limites pour tous les participants avec devise et type \nCode d'erreur : 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer les limites pour currencyId et type (si fourni) + note right of PARTICIPANT_DAO #lightgrey + Condition : + participantCurrency.participantCurrencyId = participant.participantCurrencyId + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + [ + participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimit.participantCurrencyId = + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participant + participantCurrency + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Limites participant récupérées pour currencyId et type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les limites de tous les participants + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + [ + { + name: + currency: , + limit: {type: , value: } + }, + { + name: + currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les limites de tous les participants \nCode d'erreur : 3000 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer les limites de tous les participants \nCode d'erreur : 3000 + + deactivate CSAPI + deactivate OPERATOR +end + +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg new file mode 100644 index 000000000..2b49dada4 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg @@ -0,0 +1,127 @@ + + 1.0.0 Détails des limites de tous les participants + + + 1.0.0 Détails des limites de tous les participants + + Services centraux + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + Façade participant + + + Façade participant + + + Stockage central + + + Stockage central + + + + + + + + + + Obtenir les limites de tous les participants + + + 1 + Demande d'obtenir les limites — GET - /participants/limits?type={typeValue}&currency={currencyType} + + + 2 + Récupérer les limites de tous les participants + + + 3 + Récupérer les limites pour tous les participants avec devise et type + Code d'erreur : + 3000 + + + 4 + Récupérer les limites pour currencyId et type (si fourni) + + + Condition : + participantCurrency.participantCurrencyId = participant.participantCurrencyId + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + [ + participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimit.participantCurrencyId = <currencyId> + participantLimitType.name = <type> + ] + + participant + participantCurrency + participantLimit + participantLimitType + + + 5 + Limites participant récupérées pour currencyId et type + + + 6 + Renvoyer les limites de tous les participants + + + Message : + [ + { + name: <fsp> + currency: <currencyId>, + limit: {type: <type>, value: <value>} + }, + { + name: <fsp> + currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 7 + Renvoyer les limites de tous les participants + Code d'erreur : + 3000 + + + 8 + Renvoyer les limites de tous les participants + Code d'erreur : + 3000 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml new file mode 100644 index 000000000..889043f11 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml @@ -0,0 +1,203 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Lewis Daly + -------------- + ******'/ + + +@startuml +' declare title +title 1.0.0 Vérification d'état (Health Check) + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire de métadonnées" as METADATA_HANDLER +entity "API du service central" as CSAPI +database "Stockage central" as DB +collections "Stockage Kafka" as KAFKA +collections "Sidecar de journalisation" as SIDECAR + +box "Services centraux" #LightYellow +participant CSAPI +participant METADATA_HANDLER +participant DB +participant KAFKA +participant SIDECAR +end box + +' start flow + +activate OPERATOR +group Vérification d'état détaillée + OPERATOR -> CSAPI: Demande getHealth — GET /health?detailed=true + activate CSAPI + + CSAPI -> METADATA_HANDLER: Récupérer l'état de santé de tous les sous-services + activate METADATA_HANDLER + + METADATA_HANDLER -> METADATA_HANDLER: Récupérer les métadonnées du service + note right of METADATA_HANDLER #yellow + - versionNumber + - uptime + - heure de démarrage du service + end note + + + METADATA_HANDLER -> DB: Vérifier l'état de la connexion + activate DB + DB --> METADATA_HANDLER: Rapporter l'état de la connexion + deactivate DB + + + METADATA_HANDLER -> KAFKA: Vérifier l'état de la connexion + activate KAFKA + KAFKA --> METADATA_HANDLER: Rapporter l'état de la connexion + deactivate KAFKA + + + METADATA_HANDLER -> SIDECAR: Vérifier l'état de la connexion + activate SIDECAR + SIDECAR --> METADATA_HANDLER: Rapporter l'état de la connexion + deactivate SIDECAR + + alt Valider l'état (succès) + METADATA_HANDLER --> CSAPI: Renvoyer la réponse d'état + deactivate METADATA_HANDLER + note right of OPERATOR #yellow + **Exemple de message :** + ""200 Succès"" + { + "status": "UP", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "UP", + "latency": 10 + } + ] + } + end note + + CSAPI --> OPERATOR: Renvoyer Statut HTTP : 200 + + deactivate CSAPI + deactivate OPERATOR + end + + alt Valider l'état (échec de service) + METADATA_HANDLER --> CSAPI: Renvoyer la réponse d'état + deactivate METADATA_HANDLER + note right of OPERATOR #yellow + **Exemple de message :** + ""502 Passerelle invalide"" + { + "status": "DOWN", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "DOWN", + "latency": 1111111 + } + ] + } + end note + + CSAPI --> OPERATOR: Renvoyer Statut HTTP : 502 + + deactivate CSAPI + deactivate OPERATOR + + + end + + +' group Obtenir les limites de tous les participants +' OPERATOR -> CSAPI: Demande d'obtenir les limites — GET - /participants/limits?type={typeValue}¤cy={currencyType} +' activate CSAPI +' CSAPI -> PARTICIPANT_HANDLER: Récupérer les limites de tous les participants +' activate PARTICIPANT_HANDLER +' PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les limites pour tous les participants avec devise et type \nCode d'erreur : 3000 +' activate PARTICIPANT_DAO +' PARTICIPANT_DAO ->DB: Récupérer les limites pour currencyId et type (si fourni) +' note right of PARTICIPANT_DAO #lightgrey +' Condition : +' participantCurrency.participantCurrencyId = participant.participantCurrencyId +' participantLimit.isActive = 1 +' participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId +' [ +' participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId +' participantLimit.participantCurrencyId = +' participantLimitType.name = +' ] +' end note + +' activate DB +' hnote over DB #lightyellow +' participant +' participantCurrency +' participantLimit +' participantLimitType +' end note +' DB --> PARTICIPANT_DAO: Limites participant récupérées pour currencyId et type +' deactivate DB +' PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les limites de tous les participants +' deactivate PARTICIPANT_DAO +' note right of PARTICIPANT_HANDLER #yellow +' Message : +' [ +' { +' name: +' currency: , +' limit: {type: , value: } +' }, +' { +' name: +' currency: , +' limit: {type: , value: } +' } +' ] +' end note +' PARTICIPANT_HANDLER -->CSAPI: Renvoyer les limites de tous les participants \nCode d'erreur : 3000 +' deactivate PARTICIPANT_HANDLER +' CSAPI -->OPERATOR: Renvoyer les limites de tous les participants \nCode d'erreur : 3000 + +' deactivate CSAPI +' deactivate OPERATOR +end + +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg new file mode 100644 index 000000000..71d3756f4 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg @@ -0,0 +1,174 @@ + + 1.0.0 Vérification d'état (Health Check) + + + 1.0.0 Vérification d'état (Health Check) + + Services centraux + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire de métadonnées + + + Gestionnaire de métadonnées + + + Stockage central + + + Stockage central + + + + + Stockage Kafka + + + Stockage Kafka + + + Sidecar de journalisation + + + Sidecar de journalisation + + + + + + + + + Vérification d'état détaillée + + + 1 + Demande getHealth — GET /health?detailed=true + + + 2 + Récupérer l'état de santé de tous les sous-services + + + + + 3 + Récupérer les métadonnées du service + + + - versionNumber + - uptime + - heure de démarrage du service + + + 4 + Vérifier l'état de la connexion + + + 5 + Rapporter l'état de la connexion + + + 6 + Vérifier l'état de la connexion + + + 7 + Rapporter l'état de la connexion + + + 8 + Vérifier l'état de la connexion + + + 9 + Rapporter l'état de la connexion + + + alt + [Valider l'état (succès)] + + + 10 + Renvoyer la réponse d'état + + + Exemple de message : + 200 Succès + { + "status": "UP", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "UP", + "latency": 10 + } + ] + } + + + 11 + Renvoyer + Statut HTTP : + 200 + + + alt + [Valider l'état (échec de service)] + + + 12 + Renvoyer la réponse d'état + + + Exemple de message : + 502 Passerelle invalide + { + "status": "DOWN", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "DOWN", + "latency": 1111111 + } + ] + } + + + 13 + Renvoyer + Statut HTTP : + 502 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml new file mode 100644 index 000000000..96edebfbf --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml @@ -0,0 +1,206 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.1.0 Détails de position et de limite d'un participant + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "Façade participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Services centraux" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Obtenir les limites du participant + OPERATOR -> CSAPI: Demande d'obtenir les limites — GET - /participants/{name}/limits?type={typeValue}¤cy={currencyValue} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Récupérer les limites du participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: vérifier si le paramètre « currency » est envoyé + alt Paramètre « currency » envoyé (oui) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer l'id participant/devise \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer l'id participant/devise + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Participant récupéré + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer l'id participant/devise + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les limites participant pour devise et type \nCode d'erreur : 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer la limite participant pour currencyId et type (si fourni) + note right of PARTICIPANT_DAO #lightgrey + Condition : + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Limites participant récupérées pour currencyId et type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les limites participant pour currencyId et type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + [ + { currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les limites participant + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer les limites participant + + + else Valider le participant (échec) / erreur + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Échec de validation / erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3000, 3200 + end + + else Paramètre « currency » envoyé (non) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer le participant \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer le participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Participant récupéré + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer le participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les limites participant pour toutes les devises et le type \nCode d'erreur : 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer la limite participant pour toutes les devises et type (si fourni) + note right of PARTICIPANT_DAO #lightgrey + Condition : + participantCurrency.participantId = + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + participantLimit.isActive = 1 + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participantCurrency + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Limites participant récupérées pour toutes les devises et type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les limites participant pour toutes les devises et type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + [ + { currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les limites participant + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer les limites participant + + + else Valider le participant (échec) / erreur + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Échec de validation / erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3000, 3200 + end + end + + + deactivate CSAPI + deactivate OPERATOR +end + +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg new file mode 100644 index 000000000..b9563948d --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg @@ -0,0 +1,306 @@ + + 1.1.0 Détails de position et de limite d'un participant + + + 1.1.0 Détails de position et de limite d'un participant + + Services centraux + + + + + + + + + + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + Façade participant + + + Façade participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + Obtenir les limites du participant + + + 1 + Demande d'obtenir les limites — GET - /participants/{name}/limits?type={typeValue}&currency={currencyValue} + + + 2 + Récupérer les limites du participant + + + + + 3 + vérifier si le paramètre « currency » est envoyé + + + alt + [Paramètre « currency » envoyé (oui)] + + + 4 + Récupérer l'id participant/devise + Code d'erreur : + 3200 + + + 5 + Récupérer l'id participant/devise + + participant + participantCurrency + + + 6 + Participant récupéré + + + 7 + Renvoyer l'id participant/devise + + + + + 8 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + 9 + Récupérer les limites participant pour devise et type + Code d'erreur : + 3000 + + + 10 + Récupérer la limite participant pour currencyId et type (si fourni) + + + Condition : + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = <currencyId> + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = <type> + ] + + participantLimit + participantLimitType + + + 11 + Limites participant récupérées pour currencyId et type + + + 12 + Renvoyer les limites participant pour currencyId et type + + + Message : + [ + { currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 13 + Renvoyer les limites participant + + + 14 + Renvoyer les limites participant + + [Valider le participant (échec) / erreur] + + + Échec de validation / erreur ! + + + Message : + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 15 + Renvoyer + Code d'erreur : + 3000, 3200 + + + 16 + Renvoyer + Code d'erreur : + 3000, 3200 + + [Paramètre « currency » envoyé (non)] + + + 17 + Récupérer le participant + Code d'erreur : + 3200 + + + 18 + Récupérer le participant + + participant + + + 19 + Participant récupéré + + + 20 + Renvoyer le participant + + + + + 21 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + 22 + Récupérer les limites participant pour toutes les devises et le type + Code d'erreur : + 3000 + + + 23 + Récupérer la limite participant pour toutes les devises et type (si fourni) + + + Condition : + participantCurrency.participantId = <participantId> + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + participantLimit.isActive = 1 + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = <type> + ] + + participantCurrency + participantLimit + participantLimitType + + + 24 + Limites participant récupérées pour toutes les devises et type + + + 25 + Renvoyer les limites participant pour toutes les devises et type + + + Message : + [ + { currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 26 + Renvoyer les limites participant + + + 27 + Renvoyer les limites participant + + [Valider le participant (échec) / erreur] + + + Échec de validation / erreur ! + + + Message : + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 28 + Renvoyer + Code d'erreur : + 3000, 3200 + + + 29 + Renvoyer + Code d'erreur : + 3000, 3200 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml new file mode 100644 index 000000000..c9581bc3e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml @@ -0,0 +1,167 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.1.5. Demande de statut de transfert (getTransferStatusById) — version phase 2 + +autonumber + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Rubrique d'événements" as TOPIC_EVENTS +entity "DAO transfert" as TRANSFER_DAO +database "Stockage central" as DB + +box "Fournisseur de services financiers" #lightGray + participant DFSP +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_EVENTS + participant TRANSFER_DAO + participant DB +end box + +' start flow +group Demander le statut du transfert + activate DFSP + DFSP -> NOTIFY_HANDLER: URL de demande de statut de transfert (callback) — GET - /transfers/{ID} +'alt invalid tansferId +' activate NOTIFY_HANDLER +' NOTIFY_HANDLER -> NOTIFY_HANDLER: Validate TransferId +' break +' note right of NOTIFY_HANDLER #yellow +' { +' "errorInformation": { +' "errorCode": , +' "errorDescription": "Charge utile ou état invalide" +' } +' } +' end note +' DFSP <-- NOTIFY_HANDLER: Respond HTTP - 4xx (Bad Request) +' end +'else valid transfer + ||| + group Persister les informations d'événement +' hnote over NOTIFY_HANDLER #Pink +' Do we need to write the event to the Event-Topic? +' Not transaction related. +' end hnote + NOTIFY_HANDLER -> CSAPI: Demander les informations de transfert — GET - /transfers/{ID} + activate CSAPI + + activate TOPIC_EVENTS + CSAPI -> TOPIC_EVENTS: Publier les informations d'événement + ||| + ref over TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + CSAPI <-- TOPIC_EVENTS: Renvoyer le succès + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Renvoyer le succès + deactivate CSAPI + end + DFSP <-- NOTIFY_HANDLER: Répondre HTTP — 200 (OK) +'end + NOTIFY_HANDLER -> CSAPI: Demander les détails du transfert — GET - /transfers/{ID}\nCode d'erreur : 2003 + activate CSAPI + CSAPI -> TRANSFER_DAO: Demander le statut du transfert\nCode d'erreur : 2003 + activate TRANSFER_DAO + TRANSFER_DAO -> DB: Récupérer le statut du transfert + activate DB + hnote over DB #lightyellow + SELECT transferId, transferStateId + FROM **transferStateChange** + WHERE transferId = {ID} + ORDER BY transferStateChangeId desc limit 1 + end note + deactivate DB + CSAPI <-- TRANSFER_DAO: Renvoyer le statut du transfert + deactivate TRANSFER_DAO + NOTIFY_HANDLER <-- CSAPI: Renvoyer le statut du transfert\nCodes d'erreur : 3202, 3203 + deactivate CSAPI + + alt Un transfert avec l'ID donné est-il enregistré dans le système ? + alt Oui ET transferState vaut COMMITTED\nCela signifie qu'un transfert réussi avec l'ID donné est enregistré + note left of NOTIFY_HANDLER #yellow + { + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "transferState": "COMMITTED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "Description plus détaillée" + } + ] + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT sur /transfers/{ID} + else transferState dans [RECEIVED, RESERVED, ABORTED] + note left of NOTIFY_HANDLER #yellow + { + "transferState": "RECEIVED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "Description plus détaillée" + } + ] + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT sur /transfers/{ID} + end + note right of NOTIFY_HANDLER #lightgray + Journaliser l'événement ERROR + end note + else Aucun transfert avec l'ID donné dans le système, ou requête invalide + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": , + "errorDescription": "Description d'erreur client" + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT sur /transfers/{ID}/error + end + deactivate NOTIFY_HANDLER +deactivate DFSP +end +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg new file mode 100644 index 000000000..185856495 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg @@ -0,0 +1,208 @@ + + 1.1.5. Demande de statut de transfert (getTransferStatusById) — version phase 2 + + + 1.1.5. Demande de statut de transfert (getTransferStatusById) — version phase 2 + + Fournisseur de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Rubrique d'événements + + + Rubrique d'événements + DAO transfert + + + DAO transfert + + + Stockage central + + + Stockage central + + + + + + + + + + + Demander le statut du transfert + + + 1 + URL de demande de statut de transfert (callback) — GET - /transfers/{ID} + + + Persister les informations d'événement + + + 2 + Demander les informations de transfert — GET - /transfers/{ID} + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + 4 + Renvoyer le succès + + + 5 + Renvoyer le succès + + + 6 + Répondre HTTP — 200 (OK) + + + 7 + Demander les détails du transfert — GET - /transfers/{ID} + Code d'erreur : + 2003 + + + 8 + Demander le statut du transfert + Code d'erreur : + 2003 + + + 9 + Récupérer le statut du transfert + + SELECT transferId, transferStateId + FROM + transferStateChange + WHERE transferId = {ID} + ORDER BY transferStateChangeId desc limit 1 + + + 10 + Renvoyer le statut du transfert + + + 11 + Renvoyer le statut du transfert + Codes d'erreur : + 3202, 3203 + + + alt + [Un transfert avec l'ID donné est-il enregistré dans le système ?] + + + alt + [Oui ET transferState vaut COMMITTED + Cela signifie qu'un transfert réussi avec l'ID donné est enregistré] + + + { + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "transferState": "COMMITTED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "Description plus détaillée" + } + ] + } + } + + + 12 + callback PUT sur /transfers/{ID} + + [transferState dans [RECEIVED, RESERVED, ABORTED]] + + + { + "transferState": "RECEIVED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "Description plus détaillée" + } + ] + } + } + + + 13 + callback PUT sur /transfers/{ID} + + + Journaliser l'événement ERROR + + [Aucun transfert avec l'ID donné dans le système, ou requête invalide] + + + { + "errorInformation": { + "errorCode": <integer>, + "errorDescription": "Description d'erreur client" + } + } + + + 14 + callback PUT sur /transfers/{ID}/error + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml new file mode 100644 index 000000000..0bba91899 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml @@ -0,0 +1,174 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declare title +title 1.1.0 Gestion des limites participant + +autonumber + +' declare actors +actor "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Services centraux" #LightYellow +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Gérer le plafond de débit net + OPERATOR -> CSAPI: Demande d'ajuster la limite d'un participant pour une devise — POST - /participants/{name}/limits + note right of OPERATOR #yellow + Message : + { + payload: { + currency: , + limit: { + type: , + value: + } + } + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Ajuster la limite du participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer participant/devise \nCode d'erreur : 3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer participant/devise + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Participant/devise récupéré + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer participant/devise + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: (for ParticipantCurrency) Récupérer ParticipantLimit \nCode d'erreur : 3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer ParticipantLimit + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: ParticipantLimit récupéré + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer ParticipantLimit + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Valider ParticipantLimit + alt Valider participantLimit (succès) + group IMPLÉMENTATION TRANSACTION BD — verrou sur la table ParticipantLimit avec UPDATE + note right of PARTICIPANT_DAO #lightgrey + Si (enregistrement existe && isActive = 1) + oldIsActive.isActive = 0 + insérer l'enregistrement + Else + insérer l'enregistrement + End + + end note + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: (for ParticipantLimit) Insérer un nouveau ParticipantLimit \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + + PARTICIPANT_DAO -> DB: Insérer ParticipantLimit + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: ParticipantLimit inséré + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer ParticipantLimit + + + deactivate PARTICIPANT_DAO + ' Libérer le verrou sur la table ParticipantLimit + end + + else Valider participantLimit (échec) + note right of PARTICIPANT_HANDLER #red: Échec de validation ! + + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "ParticipantLimit introuvable", + } + } + end note + end + PARTICIPANT_HANDLER --> CSAPI: Renvoyer les nouvelles valeurs de limite et statut 200 + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "currency": "EUR", + "limit": { + "participantLimitId": , + "participantLimitTypeId": , + "type": , + "value": , + "isActive": 1 + } + } + end note + CSAPI --> OPERATOR: Renvoyer les nouvelles valeurs de limite et statut 200 + + else Valider le participant (échec) + note right of PARTICIPANT_HANDLER #red: Échec de validation ! + + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + end note + + end + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3200 + + deactivate PARTICIPANT_HANDLER + deactivate CSAPI + deactivate OPERATOR +end +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg new file mode 100644 index 000000000..a07422ba3 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg @@ -0,0 +1,243 @@ + + 1.1.0 Gestion des limites participant + + + 1.1.0 Gestion des limites participant + + Services centraux + + + + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + Gérer le plafond de débit net + + + 1 + Demande d'ajuster la limite d'un participant pour une devise — POST - /participants/{name}/limits + + + Message : + { + payload: { + currency: <string>, + limit: { + type: <string>, + value: <Id> + } + } + } + + + 2 + Ajuster la limite du participant + + + 3 + Récupérer participant/devise + Code d'erreur : + 3200 + + + 4 + Récupérer participant/devise + + participant + participantCurrency + + + 5 + Participant/devise récupéré + + + 6 + Renvoyer participant/devise + + + + + 7 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + 8 + (for ParticipantCurrency) Récupérer ParticipantLimit + Code d'erreur : + 3200 + + + 9 + Récupérer ParticipantLimit + + participantLimit + + + 10 + ParticipantLimit récupéré + + + 11 + Renvoyer ParticipantLimit + + + + + 12 + Valider ParticipantLimit + + + alt + [Valider participantLimit (succès)] + + + IMPLÉMENTATION TRANSACTION BD — verrou sur la table ParticipantLimit avec UPDATE + + + Si (enregistrement existe && isActive = 1) + oldIsActive.isActive = 0 + insérer l'enregistrement + Else + insérer l'enregistrement + End +   + + + 13 + (for ParticipantLimit) Insérer un nouveau ParticipantLimit + Code d'erreur : + 3200 + + + 14 + Insérer ParticipantLimit + + participantLimit + + + 15 + ParticipantLimit inséré + + + 16 + Renvoyer ParticipantLimit + + [Valider participantLimit (échec)] + + + Échec de validation ! + + + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "ParticipantLimit introuvable", + } + } + + + 17 + Renvoyer les nouvelles valeurs de limite et statut 200 + + + Message : + { + "currency": "EUR", + "limit": { + "participantLimitId": <number>, + "participantLimitTypeId": <number>, + "type": <string>, + "value": <string>, + "isActive": 1 + } + } + + + 18 + Renvoyer les nouvelles valeurs de limite et statut 200 + + [Valider le participant (échec)] + + + Échec de validation ! + + + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + + + 19 + Renvoyer + Code d'erreur : + 3200 + + + 20 + Renvoyer + Code d'erreur : + 3200 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml new file mode 100644 index 000000000..9a452e493 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml @@ -0,0 +1,187 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.0.0 Créer la position initiale et les limites d'un participant + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "Façade participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Services centraux" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Créer la position initiale et les limites + OPERATOR -> CSAPI: Demande de créer la position initiale et les limites — POST - /paticipants/{name}/initialPositionAndLimits + note right of OPERATOR #yellow + Message : + { + currency: , + limit: { + type: , + value: + }, + initialPosition: + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Créer la position initiale et les limites pour le participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer l'identifiant participant / devise \nCode d'erreur : 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer l'identifiant participant/devise + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Identifiant participant/devise récupéré + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer l'identifiant participant/devise + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer la limite pour participantCurrencyId + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer la limite pour participantCurrencyId + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: Limite participant récupérée + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer la limite participant + deactivate PARTICIPANT_DAO + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer la position pour participantCurrencyId + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer la position pour participantCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> PARTICIPANT_DAO: Position participant récupérée + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer la position participant + deactivate PARTICIPANT_DAO + + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Vérifier si position ou limite existe + + alt position ou limite inexistante (succès) + + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: créer la position initiale et les limites pour le participant \nCode d'erreur : 2003/Msg : Service unavailable \nCode d'erreur : 2001/Msg : Internal Server Error + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Persister les limites/position du participant + activate DB + hnote over DB #lightyellow + participantPosition + participantLimit + end note + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Renvoyer le statut + deactivate PARTICIPANT_DAO + alt Détails enregistrés avec succès + PARTICIPANT_HANDLER -->CSAPI: Renvoyer le code statut 201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer le code statut 201 + else Détails non enregistrés / erreur + note right of PARTICIPANT_HANDLER #red: Erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur + + end + + else position ou limite existante (échec) + note right of PARTICIPANT_HANDLER #red: Erreur ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Limite participant ou position initiale déjà définie", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3200 + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3200 + + end + + else Valider le participant (échec) + note right of PARTICIPANT_HANDLER #red: Échec de validation ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3200 + + end + deactivate CSAPI + deactivate OPERATOR +end +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg new file mode 100644 index 000000000..4d0ddc2eb --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg @@ -0,0 +1,283 @@ + + 1.0.0 Créer la position initiale et les limites d'un participant + + + 1.0.0 Créer la position initiale et les limites d'un participant + + Services centraux + + + + + + + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + Façade participant + + + Façade participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + Créer la position initiale et les limites + + + 1 + Demande de créer la position initiale et les limites — POST - /paticipants/{name}/initialPositionAndLimits + + + Message : + { + currency: <currencyId>, + limit: { + type: <limitType>, + value: <limitValue> + }, + initialPosition: <positionValue> + } + + + 2 + Créer la position initiale et les limites pour le participant + + + 3 + Récupérer l'identifiant participant / devise + Code d'erreur : + 3200 + + + 4 + Récupérer l'identifiant participant/devise + + participant + participantCurrency + + + 5 + Identifiant participant/devise récupéré + + + 6 + Renvoyer l'identifiant participant/devise + + + + + 7 + Valider le DFSP + + + alt + [Valider le participant (succès)] + + + 8 + Récupérer la limite pour participantCurrencyId + + + 9 + Récupérer la limite pour participantCurrencyId + + participantLimit + + + 10 + Limite participant récupérée + + + 11 + Renvoyer la limite participant + + + 12 + Récupérer la position pour participantCurrencyId + + + 13 + Récupérer la position pour participantCurrencyId + + participantPosition + + + 14 + Position participant récupérée + + + 15 + Renvoyer la position participant + + + + + 16 + Vérifier si position ou limite existe + + + alt + [position ou limite inexistante (succès)] + + + 17 + créer la position initiale et les limites pour le participant + Code d'erreur : + 2003/ + Msg : + Service unavailable +   + Code d'erreur : + 2001/ + Msg : + Internal Server Error + + + 18 + Persister les limites/position du participant + + participantPosition + participantLimit + + + 19 + Renvoyer le statut + + + alt + [Détails enregistrés avec succès] + + + 20 + Renvoyer le code statut 201 + + + 21 + Renvoyer le code statut 201 + + [Détails non enregistrés / erreur] + + + Erreur ! + + + Message : + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 22 + Renvoyer + Code d'erreur + + + 23 + Renvoyer + Code d'erreur + + [position ou limite existante (échec)] + + + Erreur ! + + + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Limite participant ou position initiale déjà définie", + } + } + + + 24 + Renvoyer + Code d'erreur : + 3200 + + + 25 + Renvoyer + Code d'erreur : + 3200 + + [Valider le participant (échec)] + + + Échec de validation ! + + + Message : + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Identifiant FSP introuvable", + } + } + + + 26 + Renvoyer + Code d'erreur : + 3200 + + + 27 + Renvoyer + Code d'erreur : + 3200 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml new file mode 100644 index 000000000..12919190b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml @@ -0,0 +1,164 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 4.1.0 Détails de position d'un participant + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "Opérateur HUB" as OPERATOR +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "DAO participant" as PARTICIPANT_DAO +entity "Façade de position" as POSITION_DAO +database "Stockage central" as DB +box "Opérateur HUB" #LightBlue +participant OPERATOR +end box + +box "Service central" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant POSITION_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Obtenir les détails de position + OPERATOR -> CSAPI: Demande d'obtenir les positions — GET — /participants/{name}/positions?currency={currencyId} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Récupérer les positions du participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer le participant \nCode d'erreur : 2003,3201 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer le participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Participant récupéré + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer le participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Valider le DFSP \nCode d'erreur : 3201 + alt Valider le participant (succès) + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Paramètre currency fourni ? + + alt Paramètre currency fourni + + PARTICIPANT_HANDLER ->POSITION_DAO: Récupérer la position du participant pour un identifiant de devise\nCode d'erreur : 2003 + activate POSITION_DAO + POSITION_DAO ->DB: Récupérer la position du participant pour un identifiant de devise + activate DB + hnote over DB #lightyellow + participantCurrency + participantPosition + end note + DB --> POSITION_DAO: Position du participant récupérée pour un identifiant de devise + deactivate DB + POSITION_DAO -->PARTICIPANT_HANDLER: Renvoyer les positions du participant + deactivate POSITION_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + { + { + currency: , + value: , + updatedTime: + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer la position du participant pour un identifiant de devise + CSAPI -->OPERATOR: Renvoyer la position du participant pour un identifiant de devise + else Paramètre currency non fourni + PARTICIPANT_HANDLER ->POSITION_DAO: Récupérer les positions du participant pour toutes les devises\nCode d'erreur : 2003 + activate POSITION_DAO + POSITION_DAO ->DB: Récupérer les positions du participant pour toutes les devises + activate DB + hnote over DB #lightyellow + participantCurrency + participantPosition + end note + DB --> POSITION_DAO: Positions du participant récupérées pour toutes les devises + deactivate DB + POSITION_DAO -->PARTICIPANT_HANDLER: Renvoyer les positions du participant pour toutes les devises + deactivate POSITION_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + { + [ + { + currency: , + value: , + updatedTime: + }, + { + currency: , + value: , + updatedTime: + } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les positions du participant pour toutes les devises + CSAPI -->OPERATOR: Renvoyer les positions du participant pour toutes les devises + end + else Valider le participant (échec) + note right of PARTICIPANT_HANDLER #red: Échec de validation ! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message : + { + "errorInformation": { + "errorCode": 3201, + "errorDescription": "Identifiant FSP introuvable", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer Code d'erreur : 3201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Renvoyer Code d'erreur : 3201 + end + +end + +deactivate CSAPI +deactivate OPERATOR + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg new file mode 100644 index 000000000..71c8a7af8 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg @@ -0,0 +1,240 @@ + + 4.1.0 Détails de position d'un participant + + + 4.1.0 Détails de position d'un participant + + Opérateur HUB + + Service central + + + + + + + + + + + + + + + + + + + Opérateur HUB + + + Opérateur HUB + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + DAO participant + + + DAO participant + + + Façade de position + + + Façade de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + Obtenir les détails de position + + + 1 + Demande d'obtenir les positions — GET — /participants/{name}/positions?currency={currencyId} + + + 2 + Récupérer les positions du participant + + + 3 + Récupérer le participant + Code d'erreur : + 2003,3201 + + + 4 + Récupérer le participant + + participant + + + 5 + Participant récupéré + + + 6 + Renvoyer le participant + + + + + 7 + Valider le DFSP + Code d'erreur : + 3201 + + + alt + [Valider le participant (succès)] + + + + + 8 + Paramètre currency fourni ? + + + alt + [Paramètre currency fourni] + + + 9 + Récupérer la position du participant pour un identifiant de devise + Code d'erreur : + 2003 + + + 10 + Récupérer la position du participant pour un identifiant de devise + + participantCurrency + participantPosition + + + 11 + Position du participant récupérée pour un identifiant de devise + + + 12 + Renvoyer les positions du participant + + + Message : + { + { + currency: <currencyId>, + value: <positionValue>, + updatedTime: <timeStamp1> + } + } + + + 13 + Renvoyer la position du participant pour un identifiant de devise + + + 14 + Renvoyer la position du participant pour un identifiant de devise + + [Paramètre currency non fourni] + + + 15 + Récupérer les positions du participant pour toutes les devises + Code d'erreur : + 2003 + + + 16 + Récupérer les positions du participant pour toutes les devises + + participantCurrency + participantPosition + + + 17 + Positions du participant récupérées pour toutes les devises + + + 18 + Renvoyer les positions du participant pour toutes les devises + + + Message : + { + [ + { + currency: <currencyId1>, + value: <positionValue1>, + updatedTime: <timeStamp1> + }, + { + currency: <currencyId2>, + value: <positionValue2>, + updatedTime: <timeStamp2> + } + ] + } + + + 19 + Renvoyer les positions du participant pour toutes les devises + + + 20 + Renvoyer les positions du participant pour toutes les devises + + [Valider le participant (échec)] + + + Échec de validation ! + + + Message : + { + "errorInformation": { + "errorCode": 3201, + "errorDescription": "Identifiant FSP introuvable", + } + } + + + 21 + Renvoyer + Code d'erreur : + 3201 + + + 22 + Renvoyer + Code d'erreur : + 3201 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml new file mode 100644 index 000000000..e7edebc4d --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml @@ -0,0 +1,139 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 4.2.0 Positions de tous les participants + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "ML-API-ADAPTER" as MLAPI +boundary "API du service central" as CSAPI +control "Gestionnaire des participants" as PARTICIPANT_HANDLER +entity "API du service central" as CSAPI +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB +box "Service adaptateur ML API" #LightBlue + participant MLAPI +end box + +box "Service central" #LightYellow + participant CSAPI + participant PARTICIPANT_HANDLER + participant PARTICIPANT_DAO + participant DB +end box + +' start flow + +activate MLAPI +group Obtenir les détails de position +MLAPI -> CSAPI: Demande pour obtenir les positions — GET — /participants/positions + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Récupérer les positions de tous les participants + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Récupérer les positions de tous les participants actifs \nCodes erreur : 2003,3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Récupérer les positions pour :\n tous les participants actifs\n avec toutes les devises actives par participant + activate DB + hnote over DB #lightyellow + participant + participantPosition + participantCurrency + end note + DB --> PARTICIPANT_DAO: Positions récupérées pour les participants + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Renvoyer les positions pour les participants + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message : + { + snapshotAt: , + positions: + [ + { + participantId: , + participantPositions: + [ + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + }, + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + } + ] + }, + { + participantId: , + participantPositions: + [ + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + }, + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + } + ] + } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Renvoyer les positions pour les participants + deactivate PARTICIPANT_HANDLER +CSAPI -->MLAPI: Renvoyer les positions pour les participants + +end + deactivate CSAPI +deactivate MLAPI + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg new file mode 100644 index 000000000..6aa61d95e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg @@ -0,0 +1,153 @@ + + 4.2.0 Positions de tous les participants + + + 4.2.0 Positions de tous les participants + + Service adaptateur ML API + + Service central + + + + + + + + + + + + ML-API-ADAPTER + + + ML-API-ADAPTER + + + API du service central + + + API du service central + + + Gestionnaire des participants + + + Gestionnaire des participants + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + Obtenir les détails de position + + + 1 + Demande pour obtenir les positions — GET — /participants/positions + + + 2 + Récupérer les positions de tous les participants + + + 3 + Récupérer les positions de tous les participants actifs + Codes erreur : + 2003,3200 + + + 4 + Récupérer les positions pour : + tous les participants actifs + avec toutes les devises actives par participant + + participant + participantPosition + participantCurrency + + + 5 + Positions récupérées pour les participants + + + 6 + Renvoyer les positions pour les participants + + + Message : + { + snapshotAt: <timestamp0>, + positions: + [ + { + participantId: <dfsp1>, + participantPositions: + [ + { + currentPosition: { + currency: <currency1>, + value: <amount1>, + reservedValue: <amount2>, + lastUpdated: <timeStamp1> + } + }, + { + currentPosition: { + currency: <currency2>, + value: <amount3>, + reservedValue: <amount4>, + lastUpdated: <timeStamp2> + } + } + ] + }, + { + participantId: <dfsp2>, + participantPositions: + [ + { + currentPosition: { + currency: <currency1>, + value: <amount1>, + reservedValue: <amount2>, + lastUpdated: <timeStamp1> + } + }, + { + currentPosition: { + currency: <currency2>, + value: <amount3>, + reservedValue: <amount4>, + lastUpdated: <timeStamp2> + } + } + ] + } + ] + } + + + 7 + Renvoyer les positions pour les participants + + + 8 + Renvoyer les positions pour les participants + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml new file mode 100644 index 000000000..965a74d33 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Consommation par le gestionnaire de position (message unique) v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire de position" as POS_HANDLER +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Consommation du gestionnaire de position + alt Consommer le message de préparation pour le payeur + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' && action == 'prepare'\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (préparation)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else Consommer le message d'exécution pour le bénéficiaire + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position pour le bénéficiaire + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' && action IN ['commit', 'reserve']\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (exécution)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else Consommer le message d'abandon + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' &&\naction IN ['timeout-reserved', 'reject', 'fail']\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (abandon)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg new file mode 100644 index 000000000..8977d6010 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg @@ -0,0 +1,188 @@ + + 1.3.0. Consommation par le gestionnaire de position (message unique) v1.1 + + + 1.3.0. Consommation par le gestionnaire de position (message unique) v1.1 + + Service central + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire de position + + + Gestionnaire de position + + + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + + + + + + + Consommation du gestionnaire de position + + + alt + [Consommer le message de préparation pour le payeur] + + + 1 + Consommer le message d'événement de position pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'position' && action == 'prepare' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (préparation) +   + + + 4 + Produire le message + + [Consommer le message d'exécution pour le bénéficiaire] + + + 5 + Consommer le message d'événement de position pour le bénéficiaire + + + break + + + Valider l'événement + + + + + + 6 + Valider l'événement — règle : type == 'position' && action IN ['commit', 'reserve'] + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 7 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (exécution) +   + + + 8 + Produire le message + + [Consommer le message d'abandon] + + + 9 + Consommer le message d'événement de position + + + break + + + Valider l'événement + + + + + + 10 + Valider l'événement — règle : type == 'position' && + action IN ['timeout-reserved', 'reject', 'fail'] + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 11 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (abandon) +   + + + 12 + Produire le message + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml new file mode 100644 index 000000000..a893dcb08 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml @@ -0,0 +1,115 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Consommation par le gestionnaire de position (message unique) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire de position" as POS_HANDLER +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Consommation du gestionnaire de position + alt Consommer le message de préparation pour le payeur + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' && action == 'prepare'\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (préparation)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else Consommer le message d'exécution pour le bénéficiaire + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position pour le bénéficiaire + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' && action == 'commit'\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (exécution)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else Consommer le message d'abandon + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' &&\naction IN ['timeout-reserved', 'reject', 'fail']\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + ||| + ref over POS_HANDLER: Consommation par le gestionnaire de position (abandon)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg new file mode 100644 index 000000000..b2ff14f38 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg @@ -0,0 +1,188 @@ + + 1.3.0. Consommation par le gestionnaire de position (message unique) + + + 1.3.0. Consommation par le gestionnaire de position (message unique) + + Service central + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire de position + + + Gestionnaire de position + + + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + + + + + + + Consommation du gestionnaire de position + + + alt + [Consommer le message de préparation pour le payeur] + + + 1 + Consommer le message d'événement de position pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'position' && action == 'prepare' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (préparation) +   + + + 4 + Produire le message + + [Consommer le message d'exécution pour le bénéficiaire] + + + 5 + Consommer le message d'événement de position pour le bénéficiaire + + + break + + + Valider l'événement + + + + + + 6 + Valider l'événement — règle : type == 'position' && action == 'commit' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 7 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (exécution) +   + + + 8 + Produire le message + + [Consommer le message d'abandon] + + + 9 + Consommer le message d'événement de position + + + break + + + Valider l'événement + + + + + + 10 + Valider l'événement — règle : type == 'position' && + action IN ['timeout-reserved', 'reject', 'fail'] + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 11 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + ref + Consommation par le gestionnaire de position (abandon) +   + + + 12 + Produire le message + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml new file mode 100644 index 000000000..64c2efcb5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml @@ -0,0 +1,283 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.1. Consommation par le gestionnaire de position (préparation) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Gestionnaire de position" as POS_HANDLER + +entity "Façade de gestion\nde position" as POS_MGMT +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +entity "DAO de position" as POS_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_MGMT + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation par le gestionnaire de position (préparation) + POS_HANDLER -> POS_MGMT: Demander le traitement des transferts + activate POS_MGMT + POS_MGMT -> POS_MGMT: Vérifier le 1er transfert pour sélectionner le participant et la devise + group TRANSACTION BD + ' Transaction BD : C'est ici que débuterait la 1re transaction BD dans le futur modèle à 2 transactions BD pour la mise à l'échelle horizontale + POS_MGMT -> POS_MGMT: Parcourir le lot et construire la liste des transferIds et calculer sumTransfersInBatch,\nen vérifiant que tous les éléments du lot concernent le bon participant et la bonne devise\nCode d'erreur : 2001, 3100 + POS_MGMT -> DB: Récupérer l'état actuel de tous les transferts du tableau depuis la BD avec select whereIn\n(Info : le modèle à 2 transactions BD doit ajouter une mini-étape d'état ici (RECEIVED_PREPARE => RECEIVED_PREPARE_PROCESSING) pour ne pas toucher aux transferts si le traitement a commencé) + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_MGMT: Renvoyer l'état actuel de tous les transferts sélectionnés depuis la BD + deactivate DB + POS_MGMT <-> POS_MGMT: Valider l'état actuel (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nCode d'erreur : 2001 pour les transferts en échec\nLe lot n'est pas rejeté dans son ensemble. + + note right of POS_MGMT #lightgray + Liste des transferts utilisés lors du traitement + **reservedTransfers** est la liste des transferts à traiter dans le lot + **abortedTransfers** est la liste des transferts dans un état incorrect avant le traitement. Actuellement, transferStateChange est défini à ABORTED — cela ne doit être fait que si l'état final n'est pas déjà atteint (idempotence) + **processedTransfers** est la liste des transferts ayant traversé l'algorithme de gestion des positions. Les transferts réussis et échoués apparaissent ici car l'ordre et la "position courante" de chacun sont nécessaires pour la réconciliation + + Valeurs scalaires intermédiaires utilisées dans l'algorithme + **transferAmount** = payload.amount.amount + **sumTransfersInBatch** = SOMME des montants de chaque transfert du lot + **currentPosition** = participantPosition.value + **reservedPosition** = participantPosition.{original}reservedValue + **effectivePosition** = currentPosition + reservedPosition + **heldPosition** = effectivePosition + sumTransfersInBatch + **availablePosition** = //si le délai du modèle de règlement est IMMÉDIAT :// settlementBalance + participantLimit(NetDebitCap) - effectivePosition, //sinon :// participantLimit(NetDebitCap) - effectivePosition + **sumReserved** = SOMME des transferts ayant satisfait les critères de règle et traités + end note + note over POS_MGMT,DB + Réserver la somme des transferts valides du lot par rapport à la position du participant dans la devise de ce lot + et calculer la position disponible pour le participant + end note + POS_MGMT -> DB: Sélectionner effectivePosition FOR UPDATE depuis la BD pour le payeur + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_MGMT: Renvoyer effectivePosition (currentPosition et reservedPosition) depuis la BD pour le payeur + deactivate DB + POS_MGMT -> POS_MGMT: Incrémenter reservedValue vers heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) + POS_MGMT -> DB: Persister reservedValue + activate DB + hnote over DB #lightyellow + UPDATE **participantPosition** + SET reservedValue += sumTransfersInBatch + end note + deactivate DB + ' Transaction BD : C'est ici que se terminerait la 1re transaction BD dans le futur modèle à 2 transactions BD pour la mise à l'échelle horizontale + + + POS_MGMT -> DB: Demander les limites de position du participant payeur + activate DB + hnote over DB #lightyellow + FROM **participantLimit** + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + end note + DB --> POS_MGMT: Renvoyer les limites de position + deactivate DB + POS_MGMT <-> POS_MGMT: **availablePosition** = //si le délai du modèle de règlement est IMMÉDIAT ://\n settlementBalance + participantLimit(NetDebitCap) - effectivePosition\n //sinon ://\n participantLimit(NetDebitCap) - effectivePosition\n(équivalent à = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + note over POS_MGMT,DB + Pour chaque transfert du lot, valider la disponibilité de la position pour couvrir le montant du transfert + conformément à l'algorithme de position documenté ci-dessous + end note + POS_MGMT <-> POS_MGMT: Valider availablePosition pour chaque transfert (voir algorithme ci-dessous)\nCode d'erreur : 4001 + note right of POS_MGMT #lightgray + 01: sumReserved = 0 // Enregistrer la somme des transferts autorisés à progresser vers RESERVED + 02: sumProcessed = 0 // Enregistrer la somme des transferts déjà traités dans ce lot + 03: processedTransfers = {} // La liste des transferts traités — pour stocker les informations supplémentaires liées à la décision. En particulier la position "courante" + 04: pour chaque transfert dans reservedTransfers + 05: sumProcessed += transfer.amount // le total traité jusqu'ici **(À METTRE À JOUR DANS LE CODE)** + 06: si availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: sinon + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Plafond de débit net dépassé par cette demande, veuillez réessayer ultérieurement" + 13: fin si + 14: runningPosition = currentPosition + sumReserved // la valeur initiale de la position du participant plus la valeur totale acceptée dans le lot jusqu'ici + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(À METTRE À JOUR DANS LE CODE)** // la réduction progressive de la valeur réservée totale au début du lot. + 16: Ajouter le transfert à la liste processedTransfer en enregistrant l'état et les positions courantes { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: fin pour + end note + note over POS_MGMT,DB + Une fois le résultat de tous les transferts connu, mettre à jour la position du participant et retirer le montant réservé associé au lot + (S'il existe des seuils d'alarme, les traiter en renvoyant les limites dont le seuil a été franchi) + Effectuer une insertion groupée des transferStateChanges liés au traitement, en utilisant le résultat pour compléter participantPositionChange et l'insérer en lot afin de persister la position courante + end note + POS_MGMT->POS_MGMT: Évaluer les seuils de limite sur la position finale\nen les ajoutant à la liste d'alarmes si déclenchés + + ' Transaction BD : C'est ici que débuterait la 2e transaction BD dans le futur modèle à 2 transactions BD pour la mise à l'échelle horizontale + POS_MGMT->DB: Persister la dernière **valeur** et **reservedValue** en BD pour le payeur + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + end note + activate DB + deactivate DB + + POS_MGMT -> DB: Persister en lot les transferStateChange pour tous les processedTransfers + hnote over DB #lightyellow + batch INSERT **transferStateChange** + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch + + end note + activate DB + deactivate DB + + POS_MGMT->POS_MGMT: Remplir batchParticipantPositionChange à partir du transferStateChange résultant et de la liste processedTransfer précédente + + note right of POS_MGMT #lightgray + En pratique : + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + end note + POS_MGMT -> DB: Persister en lot le changement de position du participant pour tous les processedTransfers + hnote over DB #lightyellow + batch INSERT **participantPositionChange** + end note + activate DB + deactivate DB + ' Transaction BD : C'est ici que se terminerait la 2e transaction BD dans le futur modèle à 2 transactions BD pour la mise à l'échelle horizontale + end + POS_MGMT --> POS_HANDLER: Renvoyer une map des transferIds et leurs transferStateChanges + deactivate POS_MGMT + alt Calcul et validation dernière position préparation (succès) + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else Calcul et validation dernière position préparation (échec) + note right of POS_HANDLER #red: Échec de validation ! + + group Persister l'état du transfert (transferState='ABORTED' si contrôle de position échoué) + POS_HANDLER -> POS_DAO: Demande de persister le transfert\nCode d'erreur : 2003 + activate POS_DAO + note right of POS_HANDLER #lightgray + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + end note + POS_DAO -> DB: Persister l'état du transfert + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification (échec) pour le payeur\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg new file mode 100644 index 000000000..a58d35f6c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg @@ -0,0 +1,408 @@ + + 1.3.1. Consommation par le gestionnaire de position (préparation) + + + 1.3.1. Consommation par le gestionnaire de position (préparation) + + Service central + + + + + + + + + + + + + + + + + + + + + + + Gestionnaire de position + + + Gestionnaire de position + + + + + Rubrique de notification + + + Rubrique de notification + Façade de gestion + de position + + + Façade de gestion + de position + + + DAO de position + + + DAO de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + Consommation par le gestionnaire de position (préparation) + + + 1 + Demander le traitement des transferts + + + + + 2 + Vérifier le 1er transfert pour sélectionner le participant et la devise + + + TRANSACTION BD + + + + + 3 + Parcourir le lot et construire la liste des transferIds et calculer sumTransfersInBatch, + en vérifiant que tous les éléments du lot concernent le bon participant et la bonne devise + Code d'erreur : + 2001, 3100 + + + 4 + Récupérer l'état actuel de tous les transferts du tableau depuis la BD avec select whereIn + (Info : le modèle à 2 transactions BD doit ajouter une mini-étape d'état ici (RECEIVED_PREPARE => RECEIVED_PREPARE_PROCESSING) pour ne pas toucher aux transferts si le traitement a commencé) + + transferStateChange + transferParticipant + + + 5 + Renvoyer l'état actuel de tous les transferts sélectionnés depuis la BD + + + + + + 6 + Valider l'état actuel (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + Code d'erreur : + 2001 + pour les transferts en échec + Le lot n'est pas rejeté dans son ensemble. + + + Liste des transferts utilisés lors du traitement + reservedTransfers + est la liste des transferts à traiter dans le lot + abortedTransfers + est la liste des transferts dans un état incorrect avant le traitement. Actuellement, transferStateChange est défini à ABORTED — cela ne doit être fait que si l'état final n'est pas déjà atteint (idempotence) + processedTransfers + est la liste des transferts ayant traversé l'algorithme de gestion des positions. Les transferts réussis et échoués apparaissent ici car l'ordre et la "position courante" de chacun sont nécessaires pour la réconciliation +   + Valeurs scalaires intermédiaires utilisées dans l'algorithme + transferAmount + = payload.amount.amount + sumTransfersInBatch + = SOMME des montants de chaque transfert du lot + currentPosition + = participantPosition.value + reservedPosition + = participantPosition.{original}reservedValue + effectivePosition + = currentPosition + reservedPosition + heldPosition + = effectivePosition + sumTransfersInBatch + availablePosition + = + si le délai du modèle de règlement est IMMÉDIAT : + settlementBalance + participantLimit(NetDebitCap) - effectivePosition, + sinon : + participantLimit(NetDebitCap) - effectivePosition + sumReserved + = SOMME des transferts ayant satisfait les critères de règle et traités + + + Réserver la somme des transferts valides du lot par rapport à la position du participant dans la devise de ce lot + et calculer la position disponible pour le participant + + + 7 + Sélectionner effectivePosition FOR UPDATE depuis la BD pour le payeur + + participantPosition + + + 8 + Renvoyer effectivePosition (currentPosition et reservedPosition) depuis la BD pour le payeur + + + + + 9 + Incrémenter reservedValue vers heldPosition + (reservedValue = reservedPosition + sumTransfersInBatch) + + + 10 + Persister reservedValue + + UPDATE + participantPosition + SET reservedValue += sumTransfersInBatch + + + 11 + Demander les limites de position du participant payeur + + FROM + participantLimit + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + + + 12 + Renvoyer les limites de position + + + + + + 13 + availablePosition + = + si le délai du modèle de règlement est IMMÉDIAT : + settlementBalance + participantLimit(NetDebitCap) - effectivePosition +   + sinon : + participantLimit(NetDebitCap) - effectivePosition + (équivalent à = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + + + Pour chaque transfert du lot, valider la disponibilité de la position pour couvrir le montant du transfert + conformément à l'algorithme de position documenté ci-dessous + + + + + + 14 + Valider availablePosition pour chaque transfert (voir algorithme ci-dessous) + Code d'erreur : + 4001 + + + 01: sumReserved = 0 // Enregistrer la somme des transferts autorisés à progresser vers RESERVED + 02: sumProcessed = 0 // Enregistrer la somme des transferts déjà traités dans ce lot + 03: processedTransfers = {} // La liste des transferts traités — pour stocker les informations supplémentaires liées à la décision. En particulier la position "courante" + 04: pour chaque transfert dans reservedTransfers + 05: sumProcessed += transfer.amount // le total traité jusqu'ici + (À METTRE À JOUR DANS LE CODE) + 06: si availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: sinon + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Plafond de débit net dépassé par cette demande, veuillez réessayer ultérieurement" + 13: fin si + 14: runningPosition = currentPosition + sumReserved // la valeur initiale de la position du participant plus la valeur totale acceptée dans le lot jusqu'ici + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + (À METTRE À JOUR DANS LE CODE) + // la réduction progressive de la valeur réservée totale au début du lot. + 16: Ajouter le transfert à la liste processedTransfer en enregistrant l'état et les positions courantes { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: fin pour + + + Une fois le résultat de tous les transferts connu, mettre à jour la position du participant et retirer le montant réservé associé au lot + (S'il existe des seuils d'alarme, les traiter en renvoyant les limites dont le seuil a été franchi) + Effectuer une insertion groupée des transferStateChanges liés au traitement, en utilisant le résultat pour compléter participantPositionChange et l'insérer en lot afin de persister la position courante + + + + + 15 + Évaluer les seuils de limite sur la position finale + en les ajoutant à la liste d'alarmes si déclenchés + + + 16 + Persister la dernière + valeur + et + reservedValue + en BD pour le payeur + + UPDATE + participantPosition + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + + + 17 + Persister en lot les transferStateChange pour tous les processedTransfers + + batch INSERT + transferStateChange + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch +   + + + + + 18 + Remplir batchParticipantPositionChange à partir du transferStateChange résultant et de la liste processedTransfer précédente + + + En pratique : + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + + + 19 + Persister en lot le changement de position du participant pour tous les processedTransfers + + batch INSERT + participantPositionChange + + + 20 + Renvoyer une map des transferIds et leurs transferStateChanges + + + alt + [Calcul et validation dernière position préparation (succès)] + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 21 + Publier l'événement de notification + Code d'erreur : + 2003 + + [Calcul et validation dernière position préparation (échec)] + + + Échec de validation ! + + + Persister l'état du transfert (transferState='ABORTED' si contrôle de position échoué) + + + 22 + Demande de persister le transfert + Code d'erreur : + 2003 + + + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 23 + Persister l'état du transfert + + transferStateChange + + + 24 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 25 + Publier l'événement de notification (échec) pour le payeur + Code d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml new file mode 100644 index 000000000..2ce4dd167 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml @@ -0,0 +1,141 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.2. Consommation par le gestionnaire de position (exécution) v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Gestionnaire de position" as POS_HANDLER +collections "Notifications-Topic" as TOPIC_NOTIFICATIONS +entity "Façade de position" as POS_FACADE +entity "DAO de position" as POS_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation par le gestionnaire de position (exécution) + POS_HANDLER -> POS_DAO: Demander l'état actuel du transfert depuis la BD \nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer l'état actuel du transfert depuis la BD + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Renvoyer l'état actuel du transfert depuis la BD + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer l'état actuel du transfert depuis la BD + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Valider l'état actuel (transferState est 'RECEIVED-FULFIL')\nCode d'erreur : 2001 + group Persister le changement de position et l'état du transfert (transferState='COMMITTED' si contrôle de position réussi) + POS_HANDLER -> POS_FACADE: Demande de persister la dernière position et l'état en BD\nCode d'erreur : 2003 + group TRANSACTION BD + activate POS_FACADE + POS_FACADE -> DB: Sélectionner participantPosition.value FOR UPDATE en BD pour le bénéficiaire + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Renvoyer participantPosition.value depuis la BD pour le bénéficiaire + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persister latestPosition en BD pour le bénéficiaire + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persister l'état du transfert et le changement de position du participant + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Renvoyer le succès + deactivate POS_FACADE + end + + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de transfert\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg new file mode 100644 index 000000000..0a6b23c4e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg @@ -0,0 +1,186 @@ + + 1.3.2. Consommation par le gestionnaire de position (exécution) v1.1 + + + 1.3.2. Consommation par le gestionnaire de position (exécution) v1.1 + + Service central + + + + + + + + + + + + + + + + + Gestionnaire de position + + + Gestionnaire de position + + + + + Notifications-Topic + + + Notifications-Topic + DAO de position + + + DAO de position + + + Façade de position + + + Façade de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + Consommation par le gestionnaire de position (exécution) + + + 1 + Demander l'état actuel du transfert depuis la BD + Code d'erreur : + 2003 + + + 2 + Récupérer l'état actuel du transfert depuis la BD + + transferStateChange + transferParticipant + + + 3 + Renvoyer l'état actuel du transfert depuis la BD + + + 4 + Renvoyer l'état actuel du transfert depuis la BD + + + + + + 5 + Valider l'état actuel (transferState est 'RECEIVED-FULFIL') + Code d'erreur : + 2001 + + + Persister le changement de position et l'état du transfert (transferState='COMMITTED' si contrôle de position réussi) + + + 6 + Demande de persister la dernière position et l'état en BD + Code d'erreur : + 2003 + + + TRANSACTION BD + + + 7 + Sélectionner participantPosition.value FOR UPDATE en BD pour le bénéficiaire + + participantPosition + + + 8 + Renvoyer participantPosition.value depuis la BD pour le bénéficiaire + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persister latestPosition en BD pour le bénéficiaire + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persister l'état du transfert et le changement de position du participant + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: commit || reserve, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publier l'événement de transfert + Code d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml new file mode 100644 index 000000000..a627ab88c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml @@ -0,0 +1,140 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.2. Consommation par le gestionnaire de position (exécution) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Gestionnaire de position" as POS_HANDLER +collections "Notifications-Topic" as TOPIC_NOTIFICATIONS +entity "Façade de position" as POS_FACADE +entity "DAO de position" as POS_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation par le gestionnaire de position (exécution) + POS_HANDLER -> POS_DAO: Demander l'état actuel du transfert depuis la BD \nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer l'état actuel du transfert depuis la BD + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Renvoyer l'état actuel du transfert depuis la BD + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer l'état actuel du transfert depuis la BD + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Valider l'état actuel (transferState est 'RECEIVED-FULFIL')\nCode d'erreur : 2001 + group Persister le changement de position et l'état du transfert (transferState='COMMITTED' si contrôle de position réussi) + POS_HANDLER -> POS_FACADE: Demande de persister la dernière position et l'état en BD\nCode d'erreur : 2003 + group TRANSACTION BD + activate POS_FACADE + POS_FACADE -> DB: Sélectionner participantPosition.value FOR UPDATE en BD pour le bénéficiaire + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Renvoyer participantPosition.value depuis la BD pour le bénéficiaire + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persister latestPosition en BD pour le bénéficiaire + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persister l'état du transfert et le changement de position du participant + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Renvoyer le succès + deactivate POS_FACADE + end + + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de transfert\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg new file mode 100644 index 000000000..6ff1b866a --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg @@ -0,0 +1,186 @@ + + 1.3.2. Consommation par le gestionnaire de position (exécution) + + + 1.3.2. Consommation par le gestionnaire de position (exécution) + + Service central + + + + + + + + + + + + + + + + + Gestionnaire de position + + + Gestionnaire de position + + + + + Notifications-Topic + + + Notifications-Topic + DAO de position + + + DAO de position + + + Façade de position + + + Façade de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + Consommation par le gestionnaire de position (exécution) + + + 1 + Demander l'état actuel du transfert depuis la BD + Code d'erreur : + 2003 + + + 2 + Récupérer l'état actuel du transfert depuis la BD + + transferStateChange + transferParticipant + + + 3 + Renvoyer l'état actuel du transfert depuis la BD + + + 4 + Renvoyer l'état actuel du transfert depuis la BD + + + + + + 5 + Valider l'état actuel (transferState est 'RECEIVED-FULFIL') + Code d'erreur : + 2001 + + + Persister le changement de position et l'état du transfert (transferState='COMMITTED' si contrôle de position réussi) + + + 6 + Demande de persister la dernière position et l'état en BD + Code d'erreur : + 2003 + + + TRANSACTION BD + + + 7 + Sélectionner participantPosition.value FOR UPDATE en BD pour le bénéficiaire + + participantPosition + + + 8 + Renvoyer participantPosition.value depuis la BD pour le bénéficiaire + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persister latestPosition en BD pour le bénéficiaire + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persister l'état du transfert et le changement de position du participant + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publier l'événement de transfert + Code d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml new file mode 100644 index 000000000..3bf61a258 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml @@ -0,0 +1,306 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + ------------- + ******'/ + +@startuml +' declate title +title 1.3.3. Consommation par le gestionnaire de position (abandon) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Gestionnaire de position" as POS_HANDLER +entity "DAO de position" as POS_DAO +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +database "Stockage central" as DB + +box "Service central" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation par le gestionnaire de position (abandon) + opt type == 'position' && action == 'timeout-reserved' + POS_HANDLER -> POS_DAO: Demander l'état actuel du transfert depuis la BD\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer l'état actuel du transfert depuis la BD + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Renvoyer l'état actuel du transfert depuis la BD + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer l'état actuel du transfert depuis la BD + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Valider l'état actuel (transferStateChange.transferStateId == 'RESERVED_TIMEOUT')\nCode d'erreur : 2001 + + group Persister le changement de position et l'état du transfert + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'EXPIRED_RESERVED' + POS_HANDLER -> POS_DAO: Demande de persister la dernière position et l'état en BD\nCode d'erreur : 2003 + group IMPLÉMENTATION TRANSACTION BD + activate POS_DAO + POS_DAO -> DB: Sélectionner participantPosition.value FOR UPDATE pour payerCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_DAO: Renvoyer participantPosition + deactivate DB + POS_DAO <-> POS_DAO: **latestPosition** = participantPosition - payload.amount.amount + POS_DAO->DB: Persister latestPosition en BD pour le payeur + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_DAO -> DB: Persister le changement de position du participant et le changement d'état + hnote over DB #lightyellow + INSERT **transferStateChange** + VALUES (transferStateId) + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + end + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + note right of POS_HANDLER #yellow + Message : { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfert expiré", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + opt type == 'position' && (action IN ['reject', 'abort']) + POS_HANDLER -> POS_DAO: Demander l'état actuel du transfert depuis la BD\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer l'état actuel du transfert depuis la BD + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Renvoyer l'état actuel du transfert depuis la BD + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer l'état actuel du transfert depuis la BD + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Valider l'état actuel (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR'])\nCode d'erreur : 2001 + + group Persister le changement de position et l'état du transfert + POS_HANDLER -> POS_HANDLER: **transferStateId** = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + POS_HANDLER -> POS_DAO: Demande de persister la dernière position et l'état en BD\nCode d'erreur : 2003 + group Voir IMPLÉMENTATION TRANSACTION BD ci-dessus + activate POS_DAO + POS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + alt action == 'reject' + note right of POS_HANDLER #yellow + Message : { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + else action == 'abort' + note right of POS_HANDLER #yellow + Message : { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + end + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + + ' TODO: Nous ne voyons pas comment ce scénario pourrait être déclenché + opt type == 'position' && action == 'fail' (Impossible de déclencher ce scénario actuellement) + POS_HANDLER -> POS_DAO: Demander l'état actuel du transfert depuis la BD\nCode d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Récupérer l'état actuel du transfert depuis la BD + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Renvoyer l'état actuel du transfert depuis la BD + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer l'état actuel du transfert depuis la BD + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Valider l'état actuel (transferStateChange.transferStateId == 'FAILED') + + group Persister le changement de position et l'état du transfert + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'FAILED' + POS_HANDLER -> POS_DAO: Demande de persister la dernière position et l'état en BD\nCode d'erreur : 2003 + group Voir IMPLÉMENTATION TRANSACTION BD ci-dessus + activate POS_DAO + POS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + note right of POS_HANDLER #yellow + Message : { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfert échoué", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification\nCode d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg new file mode 100644 index 000000000..39a5759aa --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg @@ -0,0 +1,457 @@ + + 1.3.3. Consommation par le gestionnaire de position (abandon) + + + 1.3.3. Consommation par le gestionnaire de position (abandon) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gestionnaire de position + + + Gestionnaire de position + + + + + Rubrique de notification + + + Rubrique de notification + DAO de position + + + DAO de position + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + + + + Consommation par le gestionnaire de position (abandon) + + + opt + [type == 'position' && action == 'timeout-reserved'] + + + 1 + Demander l'état actuel du transfert depuis la BD + Code d'erreur : + 2003 + + + 2 + Récupérer l'état actuel du transfert depuis la BD + + transferStateChange + transferParticipant + + + 3 + Renvoyer l'état actuel du transfert depuis la BD + + + 4 + Renvoyer l'état actuel du transfert depuis la BD + + + + + + 5 + Valider l'état actuel (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + Code d'erreur : + 2001 + + + Persister le changement de position et l'état du transfert + + + + + 6 + transferStateId + = 'EXPIRED_RESERVED' + + + 7 + Demande de persister la dernière position et l'état en BD + Code d'erreur : + 2003 + + + IMPLÉMENTATION TRANSACTION BD + + + 8 + Sélectionner participantPosition.value FOR UPDATE pour payerCurrencyId + + participantPosition + + + 9 + Renvoyer participantPosition + + + + + + 10 + latestPosition + = participantPosition - payload.amount.amount + + + 11 + Persister latestPosition en BD pour le payeur + + UPDATE + participantPosition + SET value = latestPosition + + + 12 + Persister le changement de position du participant et le changement d'état + + INSERT + transferStateChange +   + VALUES (transferStateId) +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 13 + Renvoyer le succès + + + Message : { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfert expiré", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Publier l'événement de notification + Code d'erreur : + 2003 + + + opt + [type == 'position' && (action IN ['reject', 'abort'])] + + + 15 + Demander l'état actuel du transfert depuis la BD + Code d'erreur : + 2003 + + + 16 + Récupérer l'état actuel du transfert depuis la BD + + transferStateChange + + + 17 + Renvoyer l'état actuel du transfert depuis la BD + + + 18 + Renvoyer l'état actuel du transfert depuis la BD + + + + + + 19 + Valider l'état actuel (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + Code d'erreur : + 2001 + + + Persister le changement de position et l'état du transfert + + + + + 20 + transferStateId + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + 21 + Demande de persister la dernière position et l'état en BD + Code d'erreur : + 2003 + + + Voir + IMPLÉMENTATION TRANSACTION BD + ci-dessus + + + 22 + Persister en base de données + + participantPosition + transferStateChange + participantPositionChange + + + 23 + Renvoyer le succès + + + alt + [action == 'reject'] + + + Message : { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + [action == 'abort'] + + + Message : { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <payload.errorInformation.errorCode || 5000> + description: <payload.errorInformation.errorDescription> + } + } + } + } + + + 24 + Publier l'événement de notification + Code d'erreur : + 2003 + + + opt + [type == 'position' && action == 'fail' (Impossible de déclencher ce scénario actuellement)] + + + 25 + Demander l'état actuel du transfert depuis la BD + Code d'erreur : + 2003 + + + 26 + Récupérer l'état actuel du transfert depuis la BD + + transferStateChange + + + 27 + Renvoyer l'état actuel du transfert depuis la BD + + + 28 + Renvoyer l'état actuel du transfert depuis la BD + + + + + + 29 + Valider l'état actuel (transferStateChange.transferStateId == 'FAILED') + + + Persister le changement de position et l'état du transfert + + + + + 30 + transferStateId + = 'FAILED' + + + 31 + Demande de persister la dernière position et l'état en BD + Code d'erreur : + 2003 + + + Voir + IMPLÉMENTATION TRANSACTION BD + ci-dessus + + + 32 + Persister en base de données + + participantPosition + transferStateChange + participantPositionChange + + + 33 + Renvoyer le succès + + + Message : { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfert échoué", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 34 + Publier l'événement de notification + Code d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml new file mode 100644 index 000000000..d927d3cbc --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml @@ -0,0 +1,163 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.0. DFSP1 envoie une demande de préparation de transfert à DFSP2 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Gestionnaire d'événements de préparation" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +group DFSP1 envoie une demande de préparation de transfert à DFSP2 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "transferId": , + "payeeFsp": dfsp2, + "payerFsp": dfsp1, + "amount": { + "currency": "AED", + "amount": "string" + }, + "ilpPacket": "string", + "condition": "string", + "expiration": "string", + "extensionList": { + "extension": [ + { + "key": "string", + "value": "string" + } + ] + } + } + end note + DFSP1 ->> MLAPI: POST - /transfers + activate MLAPI + MLAPI -> MLAPI: Valider le jeton entrant et l'initiateur correspondant au payeur\nCodes d'erreur : 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: prepare, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_TRANSFER_PREPARE: Acheminer et publier l'événement de préparation pour le payeur\nCode d'erreur : 2003 + activate TOPIC_TRANSFER_PREPARE + TOPIC_TRANSFER_PREPARE <-> TOPIC_TRANSFER_PREPARE: S'assurer que l'événement est répliqué tel que configuré (ACKS=all)\nCode d'erreur : 2003 + TOPIC_TRANSFER_PREPARE --> MLAPI: Répondre que les accusés de réplication ont été reçus + deactivate TOPIC_TRANSFER_PREPARE + MLAPI -->> DFSP1: Répondre HTTP — 202 (Accepté) + deactivate MLAPI + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION : Consommation par le gestionnaire de préparation\n + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER : Consommation par le gestionnaire de position\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + ref over DFSP2, TOPIC_NOTIFICATIONS : Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + ||| +end +deactivate POS_HANDLER +deactivate PREP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg new file mode 100644 index 000000000..79f042f1f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg @@ -0,0 +1,238 @@ + + 1.1.0. DFSP1 envoie une demande de préparation de transfert à DFSP2 + + + 1.1.0. DFSP1 envoie une demande de préparation de transfert à DFSP2 + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Gestionnaire d'événements de préparation + + + Gestionnaire d'événements de préparation + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Rubrique de notification + + + Rubrique de notification + + + + + + + + DFSP1 envoie une demande de préparation de transfert à DFSP2 + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "transferId": <uuid>, + "payeeFsp": dfsp2, + "payerFsp": dfsp1, + "amount": { + "currency": "AED", + "amount": "string" + }, + "ilpPacket": "string", + "condition": "string", + "expiration": "string", + "extensionList": { + "extension": [ + { + "key": "string", + "value": "string" + } + ] + } + } + + + + 1 + POST - /transfers + + + + + 2 + Valider le jeton entrant et l'initiateur correspondant au payeur + Codes d'erreur : + 3000-3002, 3100-3107 + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: prepare, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 3 + Acheminer et publier l'événement de préparation pour le payeur + Code d'erreur : + 2003 + + + + + + 4 + S'assurer que l'événement est répliqué tel que configuré (ACKS=all) + Code d'erreur : + 2003 + + + 5 + Répondre que les accusés de réplication ont été reçus + + + + 6 + Répondre HTTP — 202 (Accepté) + + + 7 + Consommer le message + + + ref + Consommation par le gestionnaire de préparation +   + + + 8 + Produire le message + + + 9 + Consommer le message + + + ref + Consommation par le gestionnaire de position +   + + + 10 + Produire le message + + + 11 + Consommer le message + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 12 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml new file mode 100644 index 000000000..57d986c3c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml @@ -0,0 +1,257 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + * Georgi Georgiev + * Rajiv Mothilal + * Samuel Kummary + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.1.a. Consommation par le gestionnaire de préparation (message unique) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Gestionnaire d'événements de préparation" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +entity "DAO de position" as POS_DAO +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Consommation du gestionnaire de préparation + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consommer le message d'événement de préparation + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Valider l'événement + PREP_HANDLER <-> PREP_HANDLER: Valider l'événement — règle : type == 'prepare' && action == 'prepare'\nCodes d'erreur : 2001 + end + end + + group Persister les informations d'événement + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over PREP_HANDLER, TOPIC_EVENTS: Consommation du gestionnaire d'événements\n + ||| + end + + group Valider la préparation du transfert + PREP_HANDLER <-> PREP_HANDLER: Validation du schéma du message entrant + PREP_HANDLER <-> PREP_HANDLER: Vérifier la signature du message (à confirmer dans une future exigence) + note right of PREP_HANDLER #lightgrey + Les étapes de validation ci-dessus sont déjà gérées par + l'adaptateur ML pour l'implémentation open source. + Elles pourront être ajoutées à l'avenir pour les adaptateurs personnalisés. + end note + + group Valider le contrôle de doublon + ||| + PREP_HANDLER -> DB: Demande de contrôle de doublon + ref over PREP_HANDLER, DB: Contrôle de doublon de requête\n + DB --> PREP_HANDLER: Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + PREP_HANDLER -> PREP_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over PREP_HANDLER, TOPIC_NOTIFICATIONS: Rappel (callback) getTransfer\n + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else + note right of PREP_HANDLER #lightgrey + Ignorer — renvoi en cours + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of PREP_HANDLER #lightgrey + Validation préparation transfert (échec) — requête modifiée + end note + else hasDuplicateId == FALSE + group Valider le payeur + PREP_HANDLER -> PARTICIPANT_DAO: Demande de récupérer les détails participant payeur (s'il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Renvoyer les détails du participant s'il existe + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Renvoyer les détails du participant s'il existe + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider le payeur\nCodes d'erreur : 3202 + end + group Valider le bénéficiaire + PREP_HANDLER -> PARTICIPANT_DAO: Demande de récupérer les détails participant bénéficiaire (s'il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Renvoyer les détails du participant s'il existe + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Renvoyer les détails du participant s'il existe + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider le bénéficiaire\nCodes d'erreur : 3203 + end + + alt Validation préparation transfert (succès) + group Persister l'état du transfert (transferState='RECEIVED-PREPARE') + PREP_HANDLER -> POS_DAO: Demande de persister le transfert\nCodes d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister le transfert + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + else Validation préparation transfert (échec) + group Persister l'état du transfert (transferState='INVALID') (Introduction d'un nouveau statut INVALID pour marquer ces entrées) + PREP_HANDLER -> POS_DAO: Demande de persister le transfert\n(lorsque la validation Bénéficiaire/Payeur/crypto-condition échoue)\nCodes d'erreur : 2003 + activate POS_DAO + POS_DAO -> DB: Persister le transfert + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + end + end + end + + alt Validation préparation transfert (succès) + note right of PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur\nCodes d'erreur : 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validation préparation transfert (échec) + note right of PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification (échec) pour le payeur\nCodes d'erreur : 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate PREP_HANDLER +@enduml + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg new file mode 100644 index 000000000..e7ecf78af --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg @@ -0,0 +1,405 @@ + + 1.1.1.a. Consommation par le gestionnaire de préparation (message unique) + + + 1.1.1.a. Consommation par le gestionnaire de préparation (message unique) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Gestionnaire d'événements de préparation + + + Gestionnaire d'événements de préparation + + + + + topic-transfer-position + + + topic-transfer-position + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + DAO de position + + + DAO de position + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + Consommation du gestionnaire de préparation + + + 1 + Consommer le message d'événement de préparation + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'prepare' && action == 'prepare' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Valider la préparation du transfert + + + + + + 4 + Validation du schéma du message entrant + + + + + + 5 + Vérifier la signature du message (à confirmer dans une future exigence) + + + Les étapes de validation ci-dessus sont déjà gérées par + l'adaptateur ML pour l'implémentation open source. + Elles pourront être ajoutées à l'avenir pour les adaptateurs personnalisés. + + + Valider le contrôle de doublon + + + 6 + Demande de contrôle de doublon + + + ref + Contrôle de doublon de requête +   + + + 7 + Renvoyer { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 8 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + Rappel (callback) getTransfer +   + + + 9 + Produire le message + + + + Ignorer — renvoi en cours + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validation préparation transfert (échec) — requête modifiée + + [hasDuplicateId == FALSE] + + + Valider le payeur + + + 10 + Demande de récupérer les détails participant payeur (s'il existe) + + + 11 + Demander les détails du participant + + participant + participantCurrency + + + 12 + Renvoyer les détails du participant s'il existe + + + 13 + Renvoyer les détails du participant s'il existe + + + + + + 14 + Valider le payeur + Codes d'erreur : + 3202 + + + Valider le bénéficiaire + + + 15 + Demande de récupérer les détails participant bénéficiaire (s'il existe) + + + 16 + Demander les détails du participant + + participant + participantCurrency + + + 17 + Renvoyer les détails du participant s'il existe + + + 18 + Renvoyer les détails du participant s'il existe + + + + + + 19 + Valider le bénéficiaire + Codes d'erreur : + 3203 + + + alt + [Validation préparation transfert (succès)] + + + Persister l'état du transfert (transferState='RECEIVED-PREPARE') + + + 20 + Demande de persister le transfert + Codes d'erreur : + 2003 + + + 21 + Persister le transfert + + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + + + 22 + Renvoyer le succès + + [Validation préparation transfert (échec)] + + + Persister l'état du transfert (transferState='INVALID') (Introduction d'un nouveau statut INVALID pour marquer ces entrées) + + + 23 + Demande de persister le transfert + (lorsque la validation Bénéficiaire/Payeur/crypto-condition échoue) + Codes d'erreur : + 2003 + + + 24 + Persister le transfert + + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + + + 25 + Renvoyer le succès + + + alt + [Validation préparation transfert (succès)] + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 26 + Acheminer et publier l'événement de position pour le payeur + Codes d'erreur : + 2003 + + [Validation préparation transfert (échec)] + + + Message : + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 35.1.3 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publier l'événement de notification (échec) pour le payeur + Codes d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml new file mode 100644 index 000000000..89993b910 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml @@ -0,0 +1,186 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.1.b. Consommation par le gestionnaire de préparation (messages groupés) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Gestionnaire d'événements de préparation" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +entity "DAO de position" as POS_DAO +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Consommation du gestionnaire de préparation + note over TOPIC_TRANSFER_PREPARE #LightSalmon + Ce flux n'a pas été implémenté + end note + + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consommer le lot de messages d'événement de préparation pour le payeur + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + group Persister les informations d'événement + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over PREP_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + + group Récupérer les informations groupées du payeur + PREP_HANDLER -> PARTICIPANT_DAO: Demande de récupérer le lot de détails participant payeur (s'il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Renvoyer les détails du participant s'il existe + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Renvoyer les détails du participant s'il existe + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider le payeur + PREP_HANDLER -> PREP_HANDLER: stocker le résultat dans la variable : $LIST_PARTICIPANTS_DETAILS_PAYER + end + + group Récupérer les informations groupées du bénéficiaire + PREP_HANDLER -> PARTICIPANT_DAO: Demande de récupérer le lot de détails participant bénéficiaire (s'il existe) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les détails du participant + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Renvoyer les détails du participant s'il existe + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Renvoyer les détails du participant s'il existe + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Valider le bénéficiaire + PREP_HANDLER -> PREP_HANDLER: stocker le résultat dans la variable : $LIST_PARTICIPANTS_DETAILS_PAYEE + end + + group Récupérer le lot de transferts + PREP_HANDLER -> POS_DAO: Demande de récupérer le lot de transferts (s'il existe) + activate POS_DAO + POS_DAO -> DB: Demander le lot de transferts + hnote over DB #lightyellow + transfer + end note + activate DB + POS_DAO <-- DB: Renvoyer le lot de transferts (s'il existe) + deactivate DB + POS_DAO --> PREP_HANDLER: Renvoyer le lot de transferts (s'il existe) + deactivate POS_DAO + PREP_HANDLER -> PREP_HANDLER: stocker le résultat dans la variable : $LIST_TRANSFERS + end + + loop for each message in batch + + group Valider la préparation du transfert + group Valider le payeur + PREP_HANDLER <-> PREP_HANDLER: Valider le payeur par rapport à la variable en mémoire $LIST_PARTICIPANTS_DETAILS_PAYER + end + group Valider le bénéficiaire + PREP_HANDLER <-> PREP_HANDLER: Valider le bénéficiaire par rapport à la variable en mémoire $LIST_PARTICIPANTS_DETAILS_PAYEE + end + group Contrôle de doublon + PREP_HANDLER <-> PREP_HANDLER: Valider le contrôle de doublon par rapport à la variable en mémoire $LIST_TRANSFERS + end + PREP_HANDLER <-> PREP_HANDLER: Valider le montant + PREP_HANDLER <-> PREP_HANDLER: Valider la crypto-condition + PREP_HANDLER <-> PREP_HANDLER: Valider la signature du message (à confirmer dans une future exigence) + end + + group Persister l'état du transfert (transferState='RECEIVED' si validation réussie) + PREP_HANDLER -> POS_DAO: Demande de persister le transfert + activate POS_DAO + POS_DAO -> DB: Persister le transfert + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end +deactivate PREP_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg new file mode 100644 index 000000000..201e26b07 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg @@ -0,0 +1,320 @@ + + 1.1.1.b. Consommation par le gestionnaire de préparation (messages groupés) + + + 1.1.1.b. Consommation par le gestionnaire de préparation (messages groupés) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Gestionnaire d'événements de préparation + + + Gestionnaire d'événements de préparation + + + + + topic-transfer-position + + + topic-transfer-position + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + DAO de position + + + DAO de position + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + Consommation du gestionnaire de préparation + + + Ce flux n'a pas été implémenté + + + 1 + Consommer le lot de messages d'événement de préparation pour le payeur + + + Persister les informations d'événement + + + 2 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Récupérer les informations groupées du payeur + + + 3 + Demande de récupérer le lot de détails participant payeur (s'il existe) + + + 4 + Demander les détails du participant + + participant + + + 5 + Renvoyer les détails du participant s'il existe + + + 6 + Renvoyer les détails du participant s'il existe + + + + + + 7 + Valider le payeur + + + + + 8 + stocker le résultat dans la variable : $LIST_PARTICIPANTS_DETAILS_PAYER + + + Récupérer les informations groupées du bénéficiaire + + + 9 + Demande de récupérer le lot de détails participant bénéficiaire (s'il existe) + + + 10 + Demander les détails du participant + + participant + + + 11 + Renvoyer les détails du participant s'il existe + + + 12 + Renvoyer les détails du participant s'il existe + + + + + + 13 + Valider le bénéficiaire + + + + + 14 + stocker le résultat dans la variable : $LIST_PARTICIPANTS_DETAILS_PAYEE + + + Récupérer le lot de transferts + + + 15 + Demande de récupérer le lot de transferts (s'il existe) + + + 16 + Demander le lot de transferts + + transfer + + + 17 + Renvoyer le lot de transferts (s'il existe) + + + 18 + Renvoyer le lot de transferts (s'il existe) + + + + + 19 + stocker le résultat dans la variable : $LIST_TRANSFERS + + + loop + [for each message in batch] + + + Valider la préparation du transfert + + + Valider le payeur + + + + + + 20 + Valider le payeur par rapport à la variable en mémoire $LIST_PARTICIPANTS_DETAILS_PAYER + + + Valider le bénéficiaire + + + + + + 21 + Valider le bénéficiaire par rapport à la variable en mémoire $LIST_PARTICIPANTS_DETAILS_PAYEE + + + Contrôle de doublon + + + + + + 22 + Valider le contrôle de doublon par rapport à la variable en mémoire $LIST_TRANSFERS + + + + + + 23 + Valider le montant + + + + + + 24 + Valider la crypto-condition + + + + + + 25 + Valider la signature du message (à confirmer dans une future exigence) + + + Persister l'état du transfert (transferState='RECEIVED' si validation réussie) + + + 26 + Demande de persister le transfert + + + 27 + Persister le transfert + + transferStateChange + + + 28 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Acheminer et publier l'événement de position pour le payeur + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml new file mode 100644 index 000000000..5e072ba8b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml @@ -0,0 +1,249 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.2.a. Consommation par le gestionnaire de position (message unique) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +entity "DAO de position" as POS_DAO +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation du gestionnaire de position + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message d'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + break + group Valider l'événement + POS_HANDLER <-> POS_HANDLER: Valider l'événement — règle : type == 'position' && action == 'prepare' + end + end + + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + + alt Calculer et valider la dernière position (succès) + group Calculer la position et persister le changement + POS_HANDLER -> POS_DAO: Demander la dernière position en BD pour le payeur + activate POS_DAO + POS_DAO -> DB: Récupérer la dernière position en BD pour le payeur + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> POS_DAO: Récupérer la dernière position en BD pour le payeur + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer la dernière position + deactivate POS_DAO + + POS_HANDLER -> PARTICIPANT_DAO: Demander les limites de position du participant payeur + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les limites de position du participant payeur + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Renvoyer les limites de position + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Renvoyer les limites de position + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculer la dernière position (lpos) pour préparation + POS_HANDLER <-> POS_HANDLER: Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + + POS_HANDLER -> POS_DAO: Demande de persister la dernière position pour le payeur + activate POS_DAO + POS_DAO -> DB: Persister la dernière position en BD pour le payeur + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + group Persister l'état du transfert (transferState='RESERVED' si contrôle de position réussi) + POS_HANDLER -> POS_DAO: Demande de persister le transfert + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification pour le bénéficiaire + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else Calcul et validation de la dernière position (échec) + group Calculer la position et persister le changement + POS_HANDLER -> POS_DAO: Demander la dernière position en BD pour le payeur + activate POS_DAO + POS_DAO -> DB: Récupérer la dernière position en BD pour le payeur + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> POS_DAO: Récupérer la dernière position en BD pour le payeur + deactivate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer la dernière position + deactivate POS_DAO + + POS_HANDLER -> PARTICIPANT_DAO: Demander les limites de position du participant payeur + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Demander les limites de position du participant payeur + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Renvoyer les limites de position + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Renvoyer les limites de position + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculer la dernière position (lpos) pour préparation + POS_HANDLER <-> POS_HANDLER: Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + note right of POS_HANDLER #red: Échec de validation ! + end + + group Persister l'état du transfert (transferState='ABORTED' si contrôle de position réussi) + POS_HANDLER -> POS_DAO: Demande de persister le transfert + activate POS_DAO + POS_DAO -> DB: Persister l'état du transfert + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publier l'événement de notification (échec) pour le payeur + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg new file mode 100644 index 000000000..57ea46ee8 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg @@ -0,0 +1,366 @@ + + 1.1.2.a. Consommation par le gestionnaire de position (message unique) + + + 1.1.2.a. Consommation par le gestionnaire de position (message unique) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + DAO de position + + + DAO de position + + + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + + + + Consommation du gestionnaire de position + + + 1 + Consommer le message d'événement de position pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'position' && action == 'prepare' + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + alt + [Calculer et valider la dernière position (succès)] + + + Calculer la position et persister le changement + + + 4 + Demander la dernière position en BD pour le payeur + + + 5 + Récupérer la dernière position en BD pour le payeur + + transferPosition + + + 6 + Récupérer la dernière position en BD pour le payeur + + + 7 + Renvoyer la dernière position + + + 8 + Demander les limites de position du participant payeur + + + 9 + Demander les limites de position du participant payeur + + participant + participantLimit + + + 10 + Renvoyer les limites de position + + + 11 + Renvoyer les limites de position + + + + + + 12 + Calculer la dernière position (lpos) pour préparation + + + + + + 13 + Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + + + 14 + Demande de persister la dernière position pour le payeur + + + 15 + Persister la dernière position en BD pour le payeur + + transferPosition + + + 16 + Renvoyer le succès + + + Persister l'état du transfert (transferState='RESERVED' si contrôle de position réussi) + + + 17 + Demande de persister le transfert + + + 18 + Persister l'état du transfert + + transferStateChange + + + 19 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 20 + Publier l'événement de notification pour le bénéficiaire + + [Calcul et validation de la dernière position (échec)] + + + Calculer la position et persister le changement + + + 21 + Demander la dernière position en BD pour le payeur + + + 22 + Récupérer la dernière position en BD pour le payeur + + transferPosition + + + 23 + Récupérer la dernière position en BD pour le payeur + + + 24 + Renvoyer la dernière position + + + 25 + Demander les limites de position du participant payeur + + + 26 + Demander les limites de position du participant payeur + + participant + participantLimit + + + 27 + Renvoyer les limites de position + + + 28 + Renvoyer les limites de position + + + + + + 29 + Calculer la dernière position (lpos) pour préparation + + + + + + 30 + Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + + + Échec de validation ! + + + Persister l'état du transfert (transferState='ABORTED' si contrôle de position réussi) + + + 31 + Demande de persister le transfert + + + 32 + Persister l'état du transfert + + transferStateChange + + + 33 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 34 + Publier l'événement de notification (échec) pour le payeur + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml new file mode 100644 index 000000000..53c509099 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml @@ -0,0 +1,148 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.2.b. Consommation par le gestionnaire de position (messages groupés) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +collections "Transfer-Topic" as TOPIC_TRANSFERS +entity "DAO de position" as POS_DAO +entity "Event-Topic" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +entity "DAO transfert" as TRANS_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_TRANSFERS + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant TRANS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Consommation du gestionnaire de position + note over TOPIC_TRANSFER_POSITION #LightSalmon + Ce flux n'a pas été implémenté + end note + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le lot de messages d'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + group Persister les informations d'événement + ||| + POS_HANDLER -> TOPIC_EVENTS: Publier les informations d'événement + ref over POS_HANDLER, TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + end + + loop for each message in batch + group Calculer la position et persister le changement + POS_HANDLER -> POS_DAO: Demander la dernière position en BD pour le payeur + activate POS_DAO + POS_DAO -> DB: Récupérer la dernière position en BD pour le payeur + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer la dernière position + deactivate POS_DAO + + POS_HANDLER <-> POS_HANDLER: Calculer la dernière position (lpos) en incrémentant le transfert pour préparation + POS_HANDLER <-> POS_HANDLER: Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + + POS_HANDLER -> POS_DAO: Demande de persister la dernière position pour le payeur + activate POS_DAO + POS_DAO -> DB: Persister la dernière position en BD pour le payeur + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate POS_DAO + end + group Persister l'état du transfert (transferState='RESERVED' si contrôle de position réussi) + POS_HANDLER -> TRANS_DAO: Demande de persister le lot de transferts + activate TRANS_DAO + TRANS_DAO -> DB: Persister le lot de transferts + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + TRANS_DAO --> POS_HANDLER: Renvoyer le succès + deactivate TRANS_DAO + end + note right of POS_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_TRANSFERS: Publier l'événement de transfert + activate TOPIC_TRANSFERS + deactivate TOPIC_TRANSFERS + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg new file mode 100644 index 000000000..2add8e6d3 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg @@ -0,0 +1,206 @@ + + 1.1.2.b. Consommation par le gestionnaire de position (messages groupés) + + + 1.1.2.b. Consommation par le gestionnaire de position (messages groupés) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Transfer-Topic + + + Transfer-Topic + Event-Topic + + + Event-Topic + + + + + Rubrique de notification + + + Rubrique de notification + DAO de position + + + DAO de position + + + DAO transfert + + + DAO transfert + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + Consommation du gestionnaire de position + + + Ce flux n'a pas été implémenté + + + 1 + Consommer le lot de messages d'événement de position pour le payeur + + + Persister les informations d'événement + + + 2 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + loop + [for each message in batch] + + + Calculer la position et persister le changement + + + 3 + Demander la dernière position en BD pour le payeur + + + 4 + Récupérer la dernière position en BD pour le payeur + + transferPosition + + + 5 + Renvoyer la dernière position + + + + + + 6 + Calculer la dernière position (lpos) en incrémentant le transfert pour préparation + + + + + + 7 + Valider la dernière position calculée par rapport au plafond de débit net (netcap) — règle : lpos < netcap + + + 8 + Demande de persister la dernière position pour le payeur + + + 9 + Persister la dernière position en BD pour le payeur + + transferPosition + + + 10 + Renvoyer le succès + + + Persister l'état du transfert (transferState='RESERVED' si contrôle de position réussi) + + + 11 + Demande de persister le lot de transferts + + + 12 + Persister le lot de transferts + + transferStateChange + + + 13 + Renvoyer le succès + + + Message : + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 14 + Publier l'événement de transfert + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml new file mode 100644 index 000000000..a72597371 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml @@ -0,0 +1,123 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Shashikant Hirugade + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) v1.1 + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP\nParticipant" as PAYEE_DFSP +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +collections "Rubrique d'événements" as TOPIC_EVENTS +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee)" #lightGray + participant PAYEE_DFSP +end box + +' start flow +activate NOTIFY_HANDLER +group Envoyer une notification aux participants + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer l'événement de notification + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + group Persister les informations d'événement + NOTIFY_HANDLER -> CSAPI: Demande de persister les informations d'événement — POST — /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publier les informations d'événement + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + TOPIC_EVENTS --> CSAPI: Renvoyer le succès + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Renvoyer le succès + deactivate CSAPI + end + note right of NOTIFY_HANDLER #lightgray + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + end note + NOTIFY_HANDLER -> CSAPI: Demander les détails de l'endpoint du participant - GET - /participants/{{fsp}}/endpoints\nCode d'erreur : 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Récupérer les détails de l'endpoint du participant\nCode d'erreur : 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer les détails de l'endpoint du participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Détails de l'endpoint du participant récupérés + deactivate DB + PARTICIPANT_DAO --> CSAPI: Renvoyer les détails de l'endpoint du participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Renvoyer les détails de l'endpoint du participant\nCodes d'erreur : 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification avec résultat/erreur de préparation/exécution \nau DFSP payeur sur l'endpoint spécifié - PUT \nCode d'erreur : 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt event.action === 'reserve' + alt event.status === 'success' + NOTIFY_HANDLER -> PAYEE_DFSP: Notification avec résultat d'exécution réussi (validé) au DFSP bénéficiaire sur l'endpoint spécifié - PATCH \nCode d'erreur : 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP: HTTP 200 OK + end + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg new file mode 100644 index 000000000..cf736c085 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg @@ -0,0 +1,189 @@ + + 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) v1.1 + + + 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) v1.1 + + Financial Service Provider (Payer) + + Service adaptateur ML API + + Service central + + Financial Service Provider (Payee) + + + + + + + + + + + + + + + + + + + + Payer DFSP + Participant + + + Payer DFSP + Participant + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + + + Rubrique de notification + + + Rubrique de notification + API du service central + + + API du service central + + + + + Rubrique d'événements + + + Rubrique d'événements + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + Payee DFSP + Participant + + + Payee DFSP + Participant + + + + + + + + + + + + Envoyer une notification aux participants + + + 1 + Consommer l'événement de notification + + + Persister les informations d'événement + + + 2 + Demande de persister les informations d'événement — POST — /events + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + 4 + Renvoyer le succès + + + 5 + Renvoyer le succès + + + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + + + 6 + Demander les détails de l'endpoint du participant - GET - /participants/{{fsp}}/endpoints + Code d'erreur : + 2003 + + + 7 + Récupérer les détails de l'endpoint du participant + Code d'erreur : + 2003 + + + 8 + Récupérer les détails de l'endpoint du participant + + participantEndpoint + + + 9 + Détails de l'endpoint du participant récupérés + + + 10 + Renvoyer les détails de l'endpoint du participant + + + 11 + Renvoyer les détails de l'endpoint du participant + Codes d'erreur : + 3202, 3203 + + + 12 + Notification avec résultat/erreur de préparation/exécution + au DFSP payeur sur l'endpoint spécifié - PUT + Code d'erreur : + 1001 + + + 13 + HTTP 200 OK + + + alt + [event.action === 'reserve'] + + + alt + [event.status === 'success'] + + + 14 + Notification avec résultat d'exécution réussi (validé) au DFSP bénéficiaire sur l'endpoint spécifié - PATCH + Code d'erreur : + 1001 + + + 15 + HTTP 200 OK + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml new file mode 100644 index 000000000..270bef69f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml @@ -0,0 +1,120 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP\nParticipant" as PAYEE_DFSP +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +collections "Rubrique d'événements" as TOPIC_EVENTS +entity "DAO participant" as PARTICIPANT_DAO +database "Stockage central" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee)" #lightGray + participant PAYEE_DFSP +end box + +' start flow +activate NOTIFY_HANDLER +group Envoyer une notification aux participants + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer l'événement de notification + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + group Persister les informations d'événement + NOTIFY_HANDLER -> CSAPI: Demande de persister les informations d'événement — POST — /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publier les informations d'événement + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + TOPIC_EVENTS --> CSAPI: Renvoyer le succès + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Renvoyer le succès + deactivate CSAPI + end + note right of NOTIFY_HANDLER #lightgray + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + end note + NOTIFY_HANDLER -> CSAPI: Demander les détails de l'endpoint du participant - GET - /participants/{{fsp}}/endpoints\nCode d'erreur : 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Récupérer les détails de l'endpoint du participant\nCode d'erreur : 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Récupérer les détails de l'endpoint du participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Détails de l'endpoint du participant récupérés + deactivate DB + PARTICIPANT_DAO --> CSAPI: Renvoyer les détails de l'endpoint du participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Renvoyer les détails de l'endpoint du participant\nCodes d'erreur : 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification avec résultat/erreur de préparation/exécution \nau DFSP payeur sur l'endpoint spécifié - PUT \nCode d'erreur : 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE === true + NOTIFY_HANDLER -> PAYEE_DFSP: Notification avec résultat d'exécution (validé/annulé/rejeté) au DFSP bénéficiaire sur l'endpoint spécifié - PUT \nCode d'erreur : 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP: HTTP 200 OK + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg new file mode 100644 index 000000000..a44f1ce49 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg @@ -0,0 +1,184 @@ + + 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) + + + 1.1.4.a. Envoyer une notification au participant (payeur/bénéficiaire) (message unique) + + Financial Service Provider (Payer) + + Service adaptateur ML API + + Service central + + Financial Service Provider (Payee) + + + + + + + + + + + + + + + + + + + Payer DFSP + Participant + + + Payer DFSP + Participant + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + + + Rubrique de notification + + + Rubrique de notification + API du service central + + + API du service central + + + + + Rubrique d'événements + + + Rubrique d'événements + DAO participant + + + DAO participant + + + Stockage central + + + Stockage central + + + Payee DFSP + Participant + + + Payee DFSP + Participant + + + + + + + + + + + + Envoyer une notification aux participants + + + 1 + Consommer l'événement de notification + + + Persister les informations d'événement + + + 2 + Demande de persister les informations d'événement — POST — /events + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + 4 + Renvoyer le succès + + + 5 + Renvoyer le succès + + + Les détails de l'endpoint sont mis en cache ; à l'expiration du cache, + les détails sont récupérés à nouveau + + + 6 + Demander les détails de l'endpoint du participant - GET - /participants/{{fsp}}/endpoints + Code d'erreur : + 2003 + + + 7 + Récupérer les détails de l'endpoint du participant + Code d'erreur : + 2003 + + + 8 + Récupérer les détails de l'endpoint du participant + + participantEndpoint + + + 9 + Détails de l'endpoint du participant récupérés + + + 10 + Renvoyer les détails de l'endpoint du participant + + + 11 + Renvoyer les détails de l'endpoint du participant + Codes d'erreur : + 3202, 3203 + + + 12 + Notification avec résultat/erreur de préparation/exécution + au DFSP payeur sur l'endpoint spécifié - PUT + Code d'erreur : + 1001 + + + 13 + HTTP 200 OK + + + alt + [Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE === true] + + + 14 + Notification avec résultat d'exécution (validé/annulé/rejeté) au DFSP bénéficiaire sur l'endpoint spécifié - PUT + Code d'erreur : + 1001 + + + 15 + HTTP 200 OK + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml new file mode 100644 index 000000000..95000764e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml @@ -0,0 +1,108 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.b. Envoyer une notification au participant (payeur/bénéficiaire) (messages groupés) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +collections "Rubrique d'événements" as TOPIC_EVENTS +entity "Notification DAO" as NOTIFY_DAO +database "Stockage central" as DB + +box "Fournisseur de services financiers" #lightGray + participant DFSP +end box + +box "Service adaptateur ML API" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow +participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant EVENT_DAO + participant NOTIFY_DAO + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +group Envoyer une notification au participant + note over DFSP #LightSalmon + Ce flux n'a pas été implémenté + end note + + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: **Consommer le lot de messages d'événement de notifications pour le participant** + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + loop for each message in batch + group Persister les informations d'événement + NOTIFY_HANDLER -> CSAPI: Demande de persister les informations d'événement — POST — /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publier les informations d'événement + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Consommation du gestionnaire d'événements\n + ||| + TOPIC_EVENTS --> CSAPI: Renvoyer le succès + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Renvoyer le succès + deactivate CSAPI + end + NOTIFY_HANDLER -> CSAPI: Demander les détails de notifications du participant - GET - /notifications/DFPS(n) + activate CSAPI + CSAPI -> NOTIFY_DAO: Récupérer les détails de notifications du participant + activate NOTIFY_DAO + NOTIFY_DAO -> DB: Récupérer les détails de notifications du participant + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> NOTIFY_DAO: Détails de notifications récupérés pour le participant + 'deactivate DB + NOTIFY_DAO --> CSAPI: Renvoyer les détails de notifications du participant + deactivate NOTIFY_DAO + CSAPI --> NOTIFY_HANDLER: Renvoyer les détails de notifications du participant + deactivate CSAPI + NOTIFY_HANDLER --> DFSP: Rappel avec résultat de préparation au participant sur l'URL spécifiée - PUT - />/transfers + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg new file mode 100644 index 000000000..8cf2cc590 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg @@ -0,0 +1,154 @@ + + 1.1.4.b. Envoyer une notification au participant (payeur/bénéficiaire) (messages groupés) + + + 1.1.4.b. Envoyer une notification au participant (payeur/bénéficiaire) (messages groupés) + + Fournisseur de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + + + Rubrique de notification + + + Rubrique de notification + API du service central + + + API du service central + + + + + Rubrique d'événements + + + Rubrique d'événements + + EVENT_DAO + + EVENT_DAO + Notification DAO + + + Notification DAO + + + Stockage central + + + Stockage central + + + + + + + + + + + + Envoyer une notification au participant + + + Ce flux n'a pas été implémenté + + + 1 + Consommer le lot de messages d'événement de notifications pour le participant + + + loop + [for each message in batch] + + + Persister les informations d'événement + + + 2 + Demande de persister les informations d'événement — POST — /events + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + 4 + Renvoyer le succès + + + 5 + Renvoyer le succès + + + 6 + Demander les détails de notifications du participant - GET - /notifications/DFPS(n) + + + 7 + Récupérer les détails de notifications du participant + + + 8 + Récupérer les détails de notifications du participant + + transferPosition + + + 9 + Détails de notifications récupérés pour le participant + + + 10 + Renvoyer les détails de notifications du participant + + + 11 + Renvoyer les détails de notifications du participant + + + 12 + Rappel avec résultat de préparation au participant sur l'URL spécifiée - PUT - /<dfsp-host>>/transfers + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml new file mode 100644 index 000000000..db6b0d279 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml @@ -0,0 +1,143 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER + +' collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +' control "Gestionnaire d'événements de position" as POS_HANDLER +' collections "Rubrique d'événements" as TOPIC_EVENTS +' collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +group DFSP2 envoie un rappel d'erreur pour rejeter un transfert avec errorCode et description + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: **PUT - /transfers//error** + + activate MLAPI + MLAPI -> MLAPI: Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement d'exécution pour le bénéficiaire + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réception de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + FULF_HANDLER -> FULF_HANDLER: Consigner le message d'erreur + note right of FULF_HANDLER: (correspondant à un message d'exécution avec transferState='ABORTED')\nl'action REJECT n'est pas autorisée dans le gestionnaire d'exécution +end +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg new file mode 100644 index 000000000..636915761 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg @@ -0,0 +1,178 @@ + + 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + + + 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + + + + + DFSP2 envoie un rappel d'erreur pour rejeter un transfert avec errorCode et description + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <errorDescription>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 1 + PUT - /transfers/<ID>/error + + + + + 2 + Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 3 + Acheminer et publier l'événement d'exécution pour le bénéficiaire + + + + + + 4 + S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + + + 5 + Répondre que les accusés de réception de réplication ont été reçus + + + + 6 + Répondre HTTP — 200 (OK) + + + 7 + Consommer le message + + + + + 8 + Consigner le message d'erreur + + + (correspondant à un message d'exécution avec transferState='ABORTED') + l'action REJECT n'est pas autorisée dans le gestionnaire d'exécution + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml new file mode 100644 index 000000000..bbc999e44 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml @@ -0,0 +1,166 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +' declate title +title 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 envoie une demande d'exécution réussie du transfert + DFSP2 <-> DFSP2: Lors du traitement d'une demande\nPOST /transfers entrante, une erreur de traitement\ns'est produite et un rappel d'erreur est effectué + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage : + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers//error + activate MLAPI + MLAPI -> MLAPI: Valider l'initiateur entrant correspondant au bénéficiaire\nCodes d'erreur : 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement abandon pour le bénéficiaire\nCode d'erreur : 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué selon la configuration (ACKS=all)\nCode d'erreur : 2003 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réception de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation gestionnaire d'exécution (abandon)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation gestionnaire de position (abandon)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg new file mode 100644 index 000000000..3a798085b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg @@ -0,0 +1,265 @@ + + 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + + + 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Rubrique de notification + + + Rubrique de notification + + + + + + + + DFSP2 envoie une demande d'exécution réussie du transfert + + + + + + 1 + Lors du traitement d'une demande + POST /transfers entrante, une erreur de traitement + s'est produite et un rappel d'erreur est effectué + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - errorMessage : + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /transfers/<ID>/error + + + + + 3 + Valider l'initiateur entrant correspondant au bénéficiaire + Codes d'erreur : + 3000-3002, 3100-3107 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Acheminer et publier l'événement abandon pour le bénéficiaire + Code d'erreur : + 2003 + + + + + + 5 + S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + Code d'erreur : + 2003 + + + 6 + Répondre que les accusés de réception de réplication ont été reçus + + + + 7 + Répondre HTTP — 200 (OK) + + + 8 + Consommer le message + + + ref + Consommation gestionnaire d'exécution (abandon) +   + + + 9 + Produire le message + + + 10 + Consommer le message + + + ref + Consommation gestionnaire de position (abandon) +   + + + 11 + Produire le message + + + 12 + Consommer le message + + + opt + [action == 'abort'] + + + ref + Envoyer une notification au participant (payeur) +   + + + 13 + Envoyer la notification de rappel (callback) + + + 14 + Consommer le message + + + opt + [action == 'abort'] + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 15 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml new file mode 100644 index 000000000..d1c8394f3 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml @@ -0,0 +1,166 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +' declate title +title 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 envoie une demande d'exécution réussie du transfert + DFSP2 <-> DFSP2: Lors du traitement d'une demande\nPOST /transfers entrante, une erreur de traitement\ns'est produite et un rappel d'erreur est effectué + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage : + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers//error + activate MLAPI + MLAPI -> MLAPI: Valider l'initiateur entrant correspondant au bénéficiaire\nCodes d'erreur : 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement abandon/rejet pour le bénéficiaire\nCode d'erreur : 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué selon la configuration (ACKS=all)\nCode d'erreur : 2003 + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réception de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Consommation gestionnaire d'exécution (rejet/interruption)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation gestionnaire de position (abandon)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg new file mode 100644 index 000000000..5d00b6b41 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg @@ -0,0 +1,265 @@ + + 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + + + 2.2.0.a. DFSP2 envoie un PUT sur l'endpoint /error pour une demande de transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic-transfer-position + + + topic-transfer-position + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Rubrique de notification + + + Rubrique de notification + + + + + + + + DFSP2 envoie une demande d'exécution réussie du transfert + + + + + + 1 + Lors du traitement d'une demande + POST /transfers entrante, une erreur de traitement + s'est produite et un rappel d'erreur est effectué + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - errorMessage : + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /transfers/<ID>/error + + + + + 3 + Valider l'initiateur entrant correspondant au bénéficiaire + Codes d'erreur : + 3000-3002, 3100-3107 + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Acheminer et publier l'événement abandon/rejet pour le bénéficiaire + Code d'erreur : + 2003 + + + + + + 5 + S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + Code d'erreur : + 2003 + + + 6 + Répondre que les accusés de réception de réplication ont été reçus + + + + 7 + Répondre HTTP — 200 (OK) + + + 8 + Consommer le message + + + ref + Consommation gestionnaire d'exécution (rejet/interruption) +   + + + 9 + Produire le message + + + 10 + Consommer le message + + + ref + Consommation gestionnaire de position (abandon) +   + + + 11 + Produire le message + + + 12 + Consommer le message + + + opt + [action == 'abort'] + + + ref + Envoyer une notification au participant (payeur) +   + + + 13 + Envoyer la notification de rappel (callback) + + + 14 + Consommer le message + + + opt + [action == 'abort'] + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 15 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml new file mode 100644 index 000000000..6a394b1af --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml @@ -0,0 +1,170 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur ML API" as MLAPI +control "Gestionnaire d'événements de notification ML API" as NOTIFY_HANDLER +boundary "API du service central" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire d'événements de position" as POS_HANDLER +collections "Rubrique d'événements" as TOPIC_EVENTS +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 envoie une demande de rejet d'exécution du transfert + DFSP2 <-> DFSP2: Récupérer la chaîne d'exécution générée lors du\nprocessus de devis ou la régénérer avec\n**Local secret** et **ILP Packet** comme entrées + note right of DFSP2 #lightblue + **Remarque** : Dans le corps de la requête PUT /transfers/, + seul le champ **transferState** est **obligatoire** + end note + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage : + { + "fulfilment": , + "completedTimestamp": , + "transferState": "ABORTED", + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + note right of DFSP2 #lightgray + **Remarque** : Le motif de rejet du bénéficiaire doit être saisi + dans l'extensionList du corps de la requête. + end note + DFSP2 ->> MLAPI: **PUT - /transfers/** + + activate MLAPI + MLAPI -> MLAPI: Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + note right of MLAPI #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Acheminer et publier l'événement d'exécution pour le bénéficiaire + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + TOPIC_FULFIL --> MLAPI: Répondre que les accusés de réception de réplication ont été reçus + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Répondre HTTP — 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message + ref over TOPIC_FULFIL, TOPIC_EVENTS: Consommation gestionnaire d'exécution (rejet/interruption)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation gestionnaire de position (rejet)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'reject' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| +end +activate POS_HANDLER +activate FULF_HANDLER +activate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg new file mode 100644 index 000000000..b49db9c57 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg @@ -0,0 +1,262 @@ + + 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + + + 2.2.0. DFSP2 envoie une demande de rejet d'exécution du transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur ML API + + + Adaptateur ML API + + + Gestionnaire d'événements de notification ML API + + + Gestionnaire d'événements de notification ML API + + + API du service central + + + API du service central + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic-transfer-position + + + topic-transfer-position + + + Rubrique d'événements + + + Rubrique d'événements + Gestionnaire d'événements de position + + + Gestionnaire d'événements de position + + + + + Rubrique de notification + + + Rubrique de notification + + + + + + + + DFSP2 envoie une demande de rejet d'exécution du transfert + + + + + + 1 + Récupérer la chaîne d'exécution générée lors du + processus de devis ou la régénérer avec + Local secret + et + ILP Packet + comme entrées + + + Remarque + : Dans le corps de la requête PUT /transfers/<ID>, + seul le champ + transferState + est + obligatoire + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage : + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "ABORTED", + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + Remarque + : Le motif de rejet du bénéficiaire doit être saisi + dans l'extensionList du corps de la requête. + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Valider le jeton entrant et l'initiateur correspondant au bénéficiaire + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Acheminer et publier l'événement d'exécution pour le bénéficiaire + + + + + + 5 + S'assurer que l'événement est répliqué selon la configuration (ACKS=all) + + + 6 + Répondre que les accusés de réception de réplication ont été reçus + + + + 7 + Répondre HTTP — 200 (OK) + + + 8 + Consommer le message + + + ref + Consommation gestionnaire d'exécution (rejet/interruption) +   + + + 9 + Produire le message + + + 10 + Consommer le message + + + ref + Consommation gestionnaire de position (rejet) +   + + + 11 + Produire le message + + + 12 + Consommer le message + + + opt + [action == 'reject'] + + + ref + Envoyer une notification au participant (payeur) +   + + + 13 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml new file mode 100644 index 000000000..b64738137 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml @@ -0,0 +1,225 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Consommation par le gestionnaire d'exécution (interruption/rejet) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "Rubrique d'événements" as TOPIC_EVENT +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "DAO transfert" as TRANS_DAO +database "Stockage central" as DB +box "Service central" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Consommation du gestionnaire d'exécution (échec) + alt Consommer un message unique + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message d'événement d'exécution pour le payeur + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Valider l'événement + FULF_HANDLER <-> FULF_HANDLER: Valider l'événement — règle : type == 'fulfil' && ( action IN ['reject','abort'] )\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + FULF_HANDLER -> TOPIC_EVENT: Publier les informations d'événement + ref over FULF_HANDLER, TOPIC_EVENT: Consommation du gestionnaire d'événements + end + group Valider la signature FSPIOP + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Valider message.content.headers.**FSPIOP-Signature**\nCodes d'erreur : 2001 + end + group Valider le contrôle de doublon d'exécution du transfert + FULF_HANDLER -> FULF_HANDLER: Générer l'uuid transferFulfilmentId + FULF_HANDLER -> TRANS_DAO: Demande de récupérer les hachages d'exécution par transferId\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Demander les hachages de messages d'exécution en doublon + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Renvoyer les hachages existants + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer la ou les empreintes des messages d'exécution + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Parcourir la liste des hachages renvoyés et comparer chaque entrée au hachage du message calculé + alt Hachage correspondant + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Demande de récupérer l'exécution du transfert et l'état\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Demande de récupérer l'exécution du transfert et l'état + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Renvoyer l'exécution du transfert et l'état + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer l'exécution du transfert et l'état + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + FULF_HANDLER <-> FULF_HANDLER: Gestion des erreurs : 3105 + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Code d'erreur : 2001 + end + else + break + FULF_HANDLER <-> FULF_HANDLER: Laisser la requête précédente se terminer + end + end + else Hachage non correspondant + FULF_HANDLER -> TRANS_DAO: Demande de persister le hachage du transfert\nCodes d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister le hachage + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate TRANS_DAO + end + end + alt Appel action=='reject' effectué sur PUT /transfers/{ID} + FULF_HANDLER -> FULF_HANDLER: Consigner le message d'erreur + note right of FULF_HANDLER: l'action REJECT n'est pas autorisée dans le gestionnaire d'exécution + else action=='abort' Rappel d'erreur + alt Validation réussie + group Persister l'état du transfert (transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Demande de persister le transfert state and Error\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister l'état du transfert et les informations d'erreur + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer le succès + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Message d'erreur de transfert invalide + break + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Acheminer et publier l'événement de notification pour le bénéficiaire + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + end + else Consommer des messages groupés + note left of FULF_HANDLER #lightblue + À livrer dans une future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg new file mode 100644 index 000000000..172aedf6c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg @@ -0,0 +1,386 @@ + + 2.2.1. Consommation par le gestionnaire d'exécution (interruption/rejet) + + + 2.2.1. Consommation par le gestionnaire d'exécution (interruption/rejet) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic-transfer-position + + + topic-transfer-position + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + DAO transfert + + + DAO transfert + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + Consommation du gestionnaire d'exécution (échec) + + + alt + [Consommer un message unique] + + + 1 + Consommer le message d'événement d'exécution pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'fulfil' && ( action IN ['reject','abort'] ) + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements + + + Valider la signature FSPIOP + + + ref + Valider message.content.headers. + FSPIOP-Signature + Codes d'erreur : + 2001 + + + Valider le contrôle de doublon d'exécution du transfert + + + + + 4 + Générer l'uuid transferFulfilmentId + + + 5 + Demande de récupérer les hachages d'exécution par transferId + Code d'erreur : + 2003 + + + 6 + Demander les hachages de messages d'exécution en doublon + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Renvoyer les hachages existants + + + 8 + Renvoyer la ou les empreintes des messages d'exécution + + + + + 9 + Parcourir la liste des hachages renvoyés et comparer chaque entrée au hachage du message calculé + + + alt + [Hachage correspondant] + + + 10 + Demande de récupérer l'exécution du transfert et l'état + Code d'erreur : + 2003 + + + 11 + Demande de récupérer l'exécution du transfert et l'état + + transferFulfilment + transferStateChange + + + 12 + Renvoyer l'exécution du transfert et l'état + + + 13 + Renvoyer l'exécution du transfert et l'état + + + alt + [transferFulfilment.isValid == 0] + + + break + + + + + + 14 + Gestion des erreurs : + 3105 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + [transferState NOT 'RESERVED'] + + + break + + + + + + 15 + Code d'erreur : + 2001 + + + + break + + + + + + 16 + Laisser la requête précédente se terminer + + [Hachage non correspondant] + + + 17 + Demande de persister le hachage du transfert + Codes d'erreur : + 2003 + + + 18 + Persister le hachage + + transferFulfilmentDuplicateCheck + + + 19 + Renvoyer le succès + + + alt + [Appel action=='reject' effectué sur PUT /transfers/{ID}] + + + + + 20 + Consigner le message d'erreur + + + l'action REJECT n'est pas autorisée dans le gestionnaire d'exécution + + [action=='abort' Rappel d'erreur] + + + alt + [Validation réussie] + + + Persister l'état du transfert (transferState='RECEIVED_ERROR') + + + 21 + Demande de persister le transfert state and Error + Code d'erreur : + 2003 + + + 22 + Persister l'état du transfert et les informations d'erreur + + transferStateChange + transferError + transferExtension + + + 23 + Renvoyer le succès + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Acheminer et publier l'événement de position pour le payeur + + [Message d'erreur de transfert invalide] + + + break + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 25 + Acheminer et publier l'événement de notification pour le bénéficiaire + + [Consommer des messages groupés] + + + À livrer dans une future story + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml new file mode 100644 index 000000000..a91534c8c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml @@ -0,0 +1,343 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Consommation par le gestionnaire d'exécution (rejet/interruption) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Gestionnaire d'événements d'exécution" as FULF_HANDLER +collections "Rubrique d'événements" as TOPIC_EVENT +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Rubrique de notification" as TOPIC_NOTIFICATIONS +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "DAO transfert" as TRANS_DAO +database "Stockage central" as DB +box "Service central" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Consommation du gestionnaire d'exécution (échec) + alt Consommer un message unique + TOPIC_FULFIL <- FULF_HANDLER: Consommer le message d'événement d'exécution pour le payeur + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Valider l'événement + FULF_HANDLER <-> FULF_HANDLER: Valider l'événement — règle : type == 'fulfil' && ( action IN ['reject','abort'] )\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + FULF_HANDLER -> TOPIC_EVENT: Publier les informations d'événement + ref over FULF_HANDLER, TOPIC_EVENT: Consommation du gestionnaire d'événements + end + group Valider la signature FSPIOP + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Valider message.content.headers.**FSPIOP-Signature**\nCodes d'erreur : 2001 + end + group Valider le contrôle de doublon d'exécution du transfert + FULF_HANDLER -> FULF_HANDLER: Générer l'uuid transferFulfilmentId + FULF_HANDLER -> TRANS_DAO: Demande de récupérer les hachages d'exécution par transferId\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Demander les hachages de messages d'exécution en doublon + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Renvoyer les hachages existants + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer la ou les empreintes des messages d'exécution + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Parcourir la liste des hachages renvoyés et comparer chaque entrée au hachage du message calculé + alt Hachage correspondant + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Demande de récupérer l'exécution du transfert et l'état\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Demande de récupérer l'exécution du transfert et l'état + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Renvoyer l'exécution du transfert et l'état + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer l'exécution du transfert et l'état + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + FULF_HANDLER <-> FULF_HANDLER: Gestion des erreurs : 3105 + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Envoyer une notification au participant (bénéficiaire)\n + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Code d'erreur : 2001 + end + else + break + FULF_HANDLER <-> FULF_HANDLER: Laisser la requête précédente se terminer + end + end + else Hachage non correspondant + FULF_HANDLER -> TRANS_DAO: Demande de persister le hachage du transfert\nCodes d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister le hachage + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer le succès + deactivate TRANS_DAO + end + end + alt Appel action=='reject' effectué sur PUT /transfers/{ID} + FULF_HANDLER -> TRANS_DAO: Demander les informations pour les contrôles de validation\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Récupérer depuis la base de données + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> TRANS_DAO + deactivate DB + FULF_HANDLER <-- TRANS_DAO: Renvoyer le transfert + deactivate TRANS_DAO + + alt Exécution présente dans le message PUT /transfers/{ID} + FULF_HANDLER ->FULF_HANDLER: Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nCode d'erreur : 2001 + + group Persister l'exécution + FULF_HANDLER -> TRANS_DAO: Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid)\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Renvoyer le succès + deactivate TRANS_DAO + end + else Exécution NON présente dans le message PUT /transfers/{ID} + FULF_HANDLER ->FULF_HANDLER: Valider que le message d'exécution du transfert vers Abort est valide\nCode d'erreur : 2001 + group Persister les extensions + FULF_HANDLER -> TRANS_DAO: Persister les éléments extensionList\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister en base de données + activate DB + deactivate DB + hnote over DB #lightyellow + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Renvoyer le succès + deactivate TRANS_DAO + end + end + + alt Validation de Transfer.ilpCondition réussie OU validation générique réussie + group Persister l'état du transfert (transferState='RECEIVED_REJECT') + FULF_HANDLER -> TRANS_DAO: Demande de persister le transfert state\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister l'état du transfert + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer le succès + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validation d'exécution infructueuse ou échec générique + break + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Acheminer et publier l'événement de notification pour le bénéficiaire + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + else action=='abort' Rappel d'erreur + alt Validation réussie + group Persister l'état du transfert (transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Demande de persister le transfert state and Error\nCode d'erreur : 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persister l'état du transfert et les informations d'erreur + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Renvoyer le succès + end + + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position pour le payeur + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Message d'erreur de transfert invalide + break + note right of FULF_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Acheminer et publier l'événement de notification pour le bénéficiaire + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + end + else Consommer des messages groupés + note left of FULF_HANDLER #lightblue + À livrer dans une future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg new file mode 100644 index 000000000..b31740cd2 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg @@ -0,0 +1,572 @@ + + 2.2.1. Consommation par le gestionnaire d'exécution (rejet/interruption) + + + 2.2.1. Consommation par le gestionnaire d'exécution (rejet/interruption) + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Gestionnaire d'événements d'exécution + + + Gestionnaire d'événements d'exécution + + + + + topic-transfer-position + + + topic-transfer-position + + + Rubrique d'événements + + + Rubrique d'événements + + + Rubrique de notification + + + Rubrique de notification + DAO transfert + + + DAO transfert + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + + + + + + + + + + + Consommation du gestionnaire d'exécution (échec) + + + alt + [Consommer un message unique] + + + 1 + Consommer le message d'événement d'exécution pour le payeur + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'fulfil' && ( action IN ['reject','abort'] ) + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements + + + Valider la signature FSPIOP + + + ref + Valider message.content.headers. + FSPIOP-Signature + Codes d'erreur : + 2001 + + + Valider le contrôle de doublon d'exécution du transfert + + + + + 4 + Générer l'uuid transferFulfilmentId + + + 5 + Demande de récupérer les hachages d'exécution par transferId + Code d'erreur : + 2003 + + + 6 + Demander les hachages de messages d'exécution en doublon + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Renvoyer les hachages existants + + + 8 + Renvoyer la ou les empreintes des messages d'exécution + + + + + 9 + Parcourir la liste des hachages renvoyés et comparer chaque entrée au hachage du message calculé + + + alt + [Hachage correspondant] + + + 10 + Demande de récupérer l'exécution du transfert et l'état + Code d'erreur : + 2003 + + + 11 + Demande de récupérer l'exécution du transfert et l'état + + transferFulfilment + transferStateChange + + + 12 + Renvoyer l'exécution du transfert et l'état + + + 13 + Renvoyer l'exécution du transfert et l'état + + + alt + [transferFulfilment.isValid == 0] + + + break + + + + + + 14 + Gestion des erreurs : + 3105 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + [transferState NOT 'RESERVED'] + + + break + + + + + + 15 + Code d'erreur : + 2001 + + + + break + + + + + + 16 + Laisser la requête précédente se terminer + + [Hachage non correspondant] + + + 17 + Demande de persister le hachage du transfert + Codes d'erreur : + 2003 + + + 18 + Persister le hachage + + transferFulfilmentDuplicateCheck + + + 19 + Renvoyer le succès + + + alt + [Appel action=='reject' effectué sur PUT /transfers/{ID}] + + + 20 + Demander les informations pour les contrôles de validation + Code d'erreur : + 2003 + + + 21 + Récupérer depuis la base de données + + transfer + + + 22 +   + + + 23 + Renvoyer le transfert + + + alt + [Exécution présente dans le message PUT /transfers/{ID}] + + + + + 24 + Valider que Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Code d'erreur : + 2001 + + + Persister l'exécution + + + 25 + Persister l'exécution avec le résultat du contrôle ci-dessus (transferFulfilment.isValid) + Code d'erreur : + 2003 + + + 26 + Persister en base de données + + transferFulfilment + transferExtension + + + 27 + Renvoyer le succès + + [Exécution NON présente dans le message PUT /transfers/{ID}] + + + + + 28 + Valider que le message d'exécution du transfert vers Abort est valide + Code d'erreur : + 2001 + + + Persister les extensions + + + 29 + Persister les éléments extensionList + Code d'erreur : + 2003 + + + 30 + Persister en base de données + + transferExtension + + + 31 + Renvoyer le succès + + + alt + [Validation de Transfer.ilpCondition réussie OU validation générique réussie] + + + Persister l'état du transfert (transferState='RECEIVED_REJECT') + + + 32 + Demande de persister le transfert state + Code d'erreur : + 2003 + + + 33 + Persister l'état du transfert + + transferStateChange + + + 34 + Renvoyer le succès + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 35 + Acheminer et publier l'événement de position pour le payeur + + [Validation d'exécution infructueuse ou échec générique] + + + break + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 36 + Acheminer et publier l'événement de notification pour le bénéficiaire + + [action=='abort' Rappel d'erreur] + + + alt + [Validation réussie] + + + Persister l'état du transfert (transferState='RECEIVED_ERROR') + + + 37 + Demande de persister le transfert state and Error + Code d'erreur : + 2003 + + + 38 + Persister l'état du transfert et les informations d'erreur + + transferStateChange + transferError + transferExtension + + + 39 + Renvoyer le succès + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 40 + Acheminer et publier l'événement de position pour le payeur + + [Message d'erreur de transfert invalide] + + + break + + + Message : + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 41 + Acheminer et publier l'événement de notification pour le bénéficiaire + + [Consommer des messages groupés] + + + À livrer dans une future story + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml new file mode 100644 index 000000000..e9f1b0fa8 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml @@ -0,0 +1,114 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 9.1.1. Contrôle de doublon de requête (incl. transferts, devis, transferts groupés, devis groupés) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-source" as TOPIC_SOURCE +control "Gestionnaire de\ntraitement" as HANDLER +collections "topic-event" as TOPIC_EVENTS +collections "topic-notifcation" as TOPIC_NOTIFICATION +entity "DAO requête" as DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_SOURCE + participant HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATION + participant DAO + participant DB +end box + +' start flow +activate HANDLER + +group Contrôle de doublon de requête + TOPIC_SOURCE <- HANDLER: Consommer le message + activate TOPIC_SOURCE + deactivate TOPIC_SOURCE + + HANDLER -> HANDLER: Générer le hachage : **generatedHash** + group Contrôle UUID (compareById) + HANDLER -> DAO: Interroger le hachage via getDuplicateDataFuncOverride(id)\nCode d'erreur : 2003 + activate DAO + note right of DAO #lightgrey + Le mot-clé //request// est à remplacer par + **transfer**, **transferFulfilment**, + **bulkTransfer** ou autre selon + la surcharge + end note + DAO -> DB: getDuplicateDataFuncOverride + hnote over DB #lightyellow + //request//DuplicateCheck + end note + activate DB + DB --> DAO: Renvoyer **duplicateHashRecord** + deactivate DB + DAO --> HANDLER: Renvoyer **hasDuplicateId** + deactivate DAO + end + + alt hasDuplicateId == TRUE + group Contrôle de hachage (compareByHash) + note right of HANDLER #lightgrey + generatedHash == duplicateHashRecord.hash + end note + HANDLER -> HANDLER: Renvoyer **hasDuplicateHash** + end + else hasDuplicateId == FALSE + group Enregistrer le hachage du message + HANDLER -> DAO: Persister le hachage via saveHashFuncOverride(id, generatedHash)\nCode d'erreur : 2003 + activate DAO + DAO -> DB: Persister **generatedHash** + activate DB + deactivate DB + hnote over DB #lightyellow + //request//DuplicateCheck + end note + DAO --> HANDLER: Renvoyer le succès + deactivate DAO + end + end + + note right of HANDLER #yellow + return { + hasDuplicateId: Boolean, + hasDuplicateHash: Boolean + } + end note +end + +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg new file mode 100644 index 000000000..5f63aee21 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg @@ -0,0 +1,168 @@ + + 9.1.1. Contrôle de doublon de requête (incl. transferts, devis, transferts groupés, devis groupés) + + + 9.1.1. Contrôle de doublon de requête (incl. transferts, devis, transferts groupés, devis groupés) + + Service central + + + + + + + + + + + + + + + + + + + + topic-source + + + topic-source + Gestionnaire de + traitement + + + Gestionnaire de + traitement + + + + + topic-event + + + topic-event + + + topic-notifcation + + + topic-notifcation + DAO requête + + + DAO requête + + + Stockage central + + + Stockage central + + + + + + + + + + + Contrôle de doublon de requête + + + 1 + Consommer le message + + + + + 2 + Générer le hachage : + generatedHash + + + Contrôle UUID (compareById) + + + 3 + Interroger le hachage via getDuplicateDataFuncOverride(id) + Code d'erreur : + 2003 + + + Le mot-clé + request + est à remplacer par + transfer + , + transferFulfilment + , + bulkTransfer + ou autre selon + la surcharge + + + 4 + getDuplicateDataFuncOverride + + request + DuplicateCheck + + + 5 + Renvoyer + duplicateHashRecord + + + 6 + Renvoyer + hasDuplicateId + + + alt + [hasDuplicateId == TRUE] + + + Contrôle de hachage (compareByHash) + + + generatedHash == duplicateHashRecord.hash + + + + + 7 + Renvoyer + hasDuplicateHash + + [hasDuplicateId == FALSE] + + + Enregistrer le hachage du message + + + 8 + Persister le hachage via saveHashFuncOverride(id, generatedHash) + Code d'erreur : + 2003 + + + 9 + Persister + generatedHash + + request + DuplicateCheck + + + 10 + Renvoyer le succès + + + return { + hasDuplicateId: Boolean, + hasDuplicateHash: Boolean + } + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml new file mode 100644 index 000000000..566b44fb4 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml @@ -0,0 +1,122 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.2. Consommation par le gestionnaire de modèle de règlement +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Gestionnaire de modèle\nde règlement" as SETMODEL_HANDLER +collections "topic-event" as TOPIC_EVENT +entity "DAO de règlement" as SET_DAO +database "Stockage central" as DB + +box "Service central" #LightYellow + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_EVENT + participant SET_DAO + participant DB +end box + +' start flow +activate SETMODEL_HANDLER +group Consommation du gestionnaire de modèle de règlement + alt Consommer un message unique + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consommer le message d'événement de modèle de règlement + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + break + group Valider l'événement + SETMODEL_HANDLER <-> SETMODEL_HANDLER: Valider l'événement — règle : type == 'setmodel' && action == 'commit'\nCodes d'erreur : 2001 + end + end + group Persister les informations d'événement + ||| + SETMODEL_HANDLER -> TOPIC_EVENT: Publier les informations d'événement + ref over SETMODEL_HANDLER, TOPIC_EVENT: Consommation du gestionnaire d'événements\n + ||| + end + + SETMODEL_HANDLER -> SET_DAO: Attribuer le(s) état(s) de transferParticipant\nCode d'erreur : 2003 + activate SET_DAO + group TRANSACTION BD + SET_DAO -> DB: Récupérer les entrées transferParticipant + activate DB + hnote over DB #lightyellow + transferParticipant + end note + DB --> SET_DAO: Renvoyer **transferParticipantRecords** + deactivate DB + + loop for each transferParticipant + note right of SET_DAO #lightgrey + La mise en cache des modèles de règlement est à considérer + end note + SET_DAO -> DB: Obtenir le modèle de règlement par devise et écriture de grand livre + activate DB + hnote over DB #lightyellow + settlementModel + end note + DB --> SET_DAO: Renvoyer **settlementModel** + deactivate DB + + opt settlementModel.delay == 'IMMEDIATE' && settlementModel.granularity == 'GROSS' + SET_DAO -> DB: Définir les états : CLOSED->PENDING_SETTLEMENT->SETTLED + activate DB + hnote over DB #lightyellow + transferParticipantStateChange + transferParticipant + end note + deactivate DB + else + SET_DAO -> DB: Définir l'état : OPEN + activate DB + hnote over DB #lightyellow + transferParticipantStateChange + transferParticipant + end note + deactivate DB + end + + end + end + SETMODEL_HANDLER <-- SET_DAO: Renvoyer le succès + deactivate SET_DAO + else Consommer des messages groupés + note left of SETMODEL_HANDLER #lightblue + À livrer dans une future story + end note + end +end +deactivate SETMODEL_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg new file mode 100644 index 000000000..a3792684f --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg @@ -0,0 +1,174 @@ + + 2.1.2. Consommation par le gestionnaire de modèle de règlement + + + 2.1.2. Consommation par le gestionnaire de modèle de règlement + + Service central + + + + + + + + + + + + + + + + + + + + + + + topic- + settlement-model + + + topic- + settlement-model + Gestionnaire de modèle + de règlement + + + Gestionnaire de modèle + de règlement + + + + + topic-event + + + topic-event + DAO de règlement + + + DAO de règlement + + + Stockage central + + + Stockage central + + + + + + + + + + + + Consommation du gestionnaire de modèle de règlement + + + alt + [Consommer un message unique] + + + 1 + Consommer le message d'événement de modèle de règlement + + + break + + + Valider l'événement + + + + + + 2 + Valider l'événement — règle : type == 'setmodel' && action == 'commit' + Codes d'erreur : + 2001 + + + Persister les informations d'événement + + + 3 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + 4 + Attribuer le(s) état(s) de transferParticipant + Code d'erreur : + 2003 + + + TRANSACTION BD + + + 5 + Récupérer les entrées transferParticipant + + transferParticipant + + + 6 + Renvoyer + transferParticipantRecords + + + loop + [for each transferParticipant] + + + La mise en cache des modèles de règlement est à considérer + + + 7 + Obtenir le modèle de règlement par devise et écriture de grand livre + + settlementModel + + + 8 + Renvoyer + settlementModel + + + opt + [settlementModel.delay == 'IMMEDIATE' && settlementModel.granularity == 'GROSS'] + + + 9 + Définir les états : CLOSED->PENDING_SETTLEMENT->SETTLED + + transferParticipantStateChange + transferParticipant + + + + 10 + Définir l'état : OPEN + + transferParticipantStateChange + transferParticipant + + + 11 + Renvoyer le succès + + [Consommer des messages groupés] + + + À livrer dans une future story + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml new file mode 100644 index 000000000..ec0b99d55 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml @@ -0,0 +1,107 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.3.0. Temporisation du transfert + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayeur" as DFSP1 +actor "DFSP2\nBénéficiaire" as DFSP2 +boundary "Adaptateur\nML API" as MLAPI +control "Gestionnaire de\nnotification" as NOTIFY_HANDLER +control "Gestionnaire de\ntemporisation (préparation)" as TIMEOUT_PREP_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +control "Gestionnaire de\ntemporisation" as TIMEOUT_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Gestionnaire\nde position" as POS_HANDLER +collections "topic-notification" as TOPIC_NOTIFICATIONS + +box "Fournisseurs de services financiers" #lightgray + participant DFSP1 + participant DFSP2 +end box + +box "Service adaptateur ML API" #lightblue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Service central" #lightyellow + participant TIMEOUT_PREP_HANDLER + participant TOPIC_TRANSFER_TIMEOUT + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate TIMEOUT_PREP_HANDLER +activate NOTIFY_HANDLER +activate TIMEOUT_HANDLER +activate POS_HANDLER +group Expiration du transfert + ||| + ref over TIMEOUT_PREP_HANDLER, TOPIC_TRANSFER_TIMEOUT: Consommation du gestionnaire de temporisation\n + TIMEOUT_PREP_HANDLER -> TOPIC_TRANSFER_TIMEOUT: Produire le message + ||| + TOPIC_TRANSFER_TIMEOUT <- TIMEOUT_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_TIMEOUT, TIMEOUT_HANDLER: Consommation du gestionnaire de temporisation\n + alt transferStateId == 'RECEIVED_PREPARE' + TIMEOUT_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + else transferStateId == 'RESERVED' + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Produire le message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consommer le message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Consommation gestionnaire de position (temporisation)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produire le message + end + opt action IN ['timeout-received', 'timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + ref over DFSP1, TOPIC_NOTIFICATIONS : Envoyer une notification au participant (payeur)\n + NOTIFY_HANDLER -> DFSP1: Envoyer la notification de rappel (callback) + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consommer le message + opt action == 'timeout-reserved' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS : Envoyer une notification au participant (bénéficiaire)\n + NOTIFY_HANDLER -> DFSP2: Envoyer la notification de rappel (callback) + end +end +deactivate POS_HANDLER +deactivate TIMEOUT_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg new file mode 100644 index 000000000..cd123a985 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg @@ -0,0 +1,195 @@ + + 2.3.0. Temporisation du transfert + + + 2.3.0. Temporisation du transfert + + Fournisseurs de services financiers + + Service adaptateur ML API + + Service central + + + + + + + + + + + + + + + + + + + DFSP1 + Payeur + + + DFSP1 + Payeur + + + DFSP2 + Bénéficiaire + + + DFSP2 + Bénéficiaire + + + Adaptateur + ML API + + + Adaptateur + ML API + + + Gestionnaire de + notification + + + Gestionnaire de + notification + + + Gestionnaire de + temporisation (préparation) + + + Gestionnaire de + temporisation (préparation) + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + Gestionnaire de + temporisation + + + Gestionnaire de + temporisation + + + + + topic- + transfer-position + + + topic- + transfer-position + Gestionnaire + de position + + + Gestionnaire + de position + + + + + topic-notification + + + topic-notification + + + + + + + Expiration du transfert + + + ref + Consommation du gestionnaire de temporisation +   + + + 1 + Produire le message + + + 2 + Consommer le message + + + ref + Consommation du gestionnaire de temporisation +   + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + 3 + Produire le message + + [transferStateId == 'RESERVED'] + + + 4 + Produire le message + + + 5 + Consommer le message + + + ref + Consommation gestionnaire de position (temporisation) +   + + + 6 + Produire le message + + + opt + [action IN ['timeout-received', 'timeout-reserved']] + + + 7 + Consommer le message + + + ref + Envoyer une notification au participant (payeur) +   + + + 8 + Envoyer la notification de rappel (callback) + + + 9 + Consommer le message + + + opt + [action == 'timeout-reserved'] + + + ref + Envoyer une notification au participant (bénéficiaire) +   + + + 10 + Envoyer la notification de rappel (callback) + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml new file mode 100644 index 000000000..dcb7dff4b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml @@ -0,0 +1,132 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 2.3.1. Gestionnaire de temporisation (préparation) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Gestionnaire de\ntemporisation (préparation)" as TIMEOUT_PREP_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +collections "topic-event" as EVENT_TOPIC +entity "Timeout DAO" as TIMEOUT_DAO +database "Stockage central" as DB + +box "Service central" #lightyellow + participant TIMEOUT_PREP_HANDLER + participant TOPIC_TRANSFER_TIMEOUT + participant EVENT_TOPIC + participant TIMEOUT_DAO + participant DB +end box + +' start flow + +group Gestionnaire de temporisation (préparation) + activate TIMEOUT_PREP_HANDLER + group Persister les informations d'événement + TIMEOUT_PREP_HANDLER -> EVENT_TOPIC: Publier les informations d'événement + ref over TIMEOUT_PREP_HANDLER, EVENT_TOPIC : Consommation du gestionnaire d'événements\n + end + + group Nettoyage + TIMEOUT_PREP_HANDLER -> TIMEOUT_DAO: Nettoyer les transferts exécutés\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Supprimer les enregistrements des transferts exécutés + activate DB + deactivate DB + hnote over DB #lightyellow + DELETE et + FROM **expiringTransfer** et + JOIN **transferFulfilment** tf + ON tf.transferId = et.transferId + end note + TIMEOUT_DAO --> TIMEOUT_PREP_HANDLER: Renvoyer le succès + deactivate TIMEOUT_DAO + end + + group Lister les expirés + TIMEOUT_PREP_HANDLER -> TIMEOUT_DAO: Récupérer les transferts expirés\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Sélection via index + activate DB + hnote over DB #lightyellow + SELECT * + FROM **expiringTransfer** + WHERE expirationDate < currentTimestamp + end note + TIMEOUT_DAO <-- DB: Renvoyer les transferts expirés + deactivate DB + TIMEOUT_DAO --> TIMEOUT_PREP_HANDLER: Renvoyer **expiredTransfersList** + deactivate TIMEOUT_DAO + end + + + + loop for each transfer in the list + ||| + note right of TIMEOUT_PREP_HANDLER #yellow + Message : + { + id: + from: , + to: , + type: application/json + content: { + headers: null, + payload: + }, + metadata: { + event: { + id: , + responseTo: null, + type: transfer, + action: timeout, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + TIMEOUT_PREP_HANDLER -> TOPIC_TRANSFER_TIMEOUT: Publier l'événement de temporisation\nCode d'erreur : 2003 + activate TOPIC_TRANSFER_TIMEOUT + deactivate TOPIC_TRANSFER_TIMEOUT + end + + deactivate TIMEOUT_PREP_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg new file mode 100644 index 000000000..54989abf6 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg @@ -0,0 +1,169 @@ + + 2.3.1. Gestionnaire de temporisation (préparation) + + + 2.3.1. Gestionnaire de temporisation (préparation) + + Service central + + + + + + + + + + + + + + + + + Gestionnaire de + temporisation (préparation) + + + Gestionnaire de + temporisation (préparation) + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + + + topic-event + + + topic-event + Timeout DAO + + + Timeout DAO + + + Stockage central + + + Stockage central + + + + + + + + + + + Gestionnaire de temporisation (préparation) + + + Persister les informations d'événement + + + 1 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Nettoyage + + + 2 + Nettoyer les transferts exécutés + Code d'erreur : + 2003 + + + 3 + Supprimer les enregistrements des transferts exécutés + + DELETE et + FROM + expiringTransfer + et + JOIN + transferFulfilment + tf + ON tf.transferId = et.transferId + + + 4 + Renvoyer le succès + + + Lister les expirés + + + 5 + Récupérer les transferts expirés + Code d'erreur : + 2003 + + + 6 + Sélection via index + + SELECT * + FROM + expiringTransfer + WHERE expirationDate < currentTimestamp + + + 7 + Renvoyer les transferts expirés + + + 8 + Renvoyer + expiredTransfersList + + + loop + [for each transfer in the list] + + + Message : + { + id: <uuid> + from: <switch>, + to: <payerFsp>, + type: application/json + content: { + headers: null, + payload: <transfer> + }, + metadata: { + event: { + id: <uuid>, + responseTo: null, + type: transfer, + action: timeout, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 9 + Publier l'événement de temporisation + Code d'erreur : + 2003 + + diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml new file mode 100644 index 000000000..5657be9f5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml @@ -0,0 +1,227 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + - Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title 2.3.2. Gestionnaire de temporisation + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Gestionnaire de temporisation du transfert" as TIMEOUT_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as NOTIFICATIONS_TOPIC +collections "topic-event" as EVENT_TOPIC +entity "Timeout DAO" as TIMEOUT_DAO +database "Stockage central" as DB + +box "Service central" #lightyellow + participant TOPIC_TRANSFER_TIMEOUT + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant NOTIFICATIONS_TOPIC + participant EVENT_TOPIC + participant TIMEOUT_DAO + participant DB +end box + +' start flow + +group Consommation du gestionnaire de temporisation + activate TIMEOUT_HANDLER + TOPIC_TRANSFER_TIMEOUT <- TIMEOUT_HANDLER: Consommer le message + activate TOPIC_TRANSFER_TIMEOUT + deactivate TOPIC_TRANSFER_TIMEOUT + + group Persister les informations d'événement + TIMEOUT_HANDLER -> EVENT_TOPIC: Publier les informations d'événement + ref over TIMEOUT_HANDLER, EVENT_TOPIC: Consommation du gestionnaire d'événements\n + end + + group Obtenir les infos du transfert + TIMEOUT_HANDLER -> TIMEOUT_DAO: Acquérir les informations du transfert\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Obtenir les données et l'état du transfert + activate DB + hnote over DB #lightyellow + transfer + transferParticipant + participantCurrency + participant + transferStateChange + end note + TIMEOUT_DAO <-- DB: Renvoyer **transferInfo** + deactivate DB + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Renvoyer **transferInfo** + deactivate TIMEOUT_DAO + end + + alt transferInfo.transferStateId == 'RECEIVED_PREPARE' + TIMEOUT_HANDLER -> TIMEOUT_DAO: Définir l'état EXPIRED_PREPARED\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Insérer le changement d'état + activate DB + deactivate DB + hnote over DB #lightyellow + transferStateChange + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Renvoyer le succès + deactivate TIMEOUT_DAO + + note right of TIMEOUT_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfert expiré", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: notification, + action: timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> NOTIFICATIONS_TOPIC: Publier l'événement de notification + activate NOTIFICATIONS_TOPIC + deactivate NOTIFICATIONS_TOPIC + else transferInfo.transferStateId == 'RESERVED' + TIMEOUT_HANDLER -> TIMEOUT_DAO: Définir l'état RESERVED_TIMEOUT\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Insérer le changement d'état + activate DB + deactivate DB + hnote over DB #lightyellow + transferStateChange + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Renvoyer le succès + deactivate TIMEOUT_DAO + + note right of TIMEOUT_HANDLER #yellow + Message : + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfert expiré", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Acheminer et publier l'événement de position\nCode d'erreur : 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else + note right of TIMEOUT_HANDLER #lightgrey + Tout autre état est ignoré + end note + end + + group Nettoyage + TIMEOUT_HANDLER -> TIMEOUT_DAO: Nettoyer le transfert expirant traité\nCode d'erreur : 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Supprimer l'enregistrement + activate DB + deactivate DB + hnote over DB #lightyellow + expiringTransfer + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Renvoyer le succès + deactivate TIMEOUT_DAO + end + + deactivate TIMEOUT_HANDLER +end +@enduml diff --git a/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg new file mode 100644 index 000000000..5e88aa1f1 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg @@ -0,0 +1,302 @@ + + 2.3.2. Gestionnaire de temporisation + + + 2.3.2. Gestionnaire de temporisation + + Service central + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + Gestionnaire de temporisation du transfert + + + Gestionnaire de temporisation du transfert + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + notification + + + topic- + notification + + + topic-event + + + topic-event + Timeout DAO + + + Timeout DAO + + + Stockage central + + + Stockage central + + + + + + + + + + + + + + + + + Consommation du gestionnaire de temporisation + + + 1 + Consommer le message + + + Persister les informations d'événement + + + 2 + Publier les informations d'événement + + + ref + Consommation du gestionnaire d'événements +   + + + Obtenir les infos du transfert + + + 3 + Acquérir les informations du transfert + Code d'erreur : + 2003 + + + 4 + Obtenir les données et l'état du transfert + + transfer + transferParticipant + participantCurrency + participant + transferStateChange + + + 5 + Renvoyer + transferInfo + + + 6 + Renvoyer + transferInfo + + + alt + [transferInfo.transferStateId == 'RECEIVED_PREPARE'] + + + 7 + Définir l'état EXPIRED_PREPARED + Code d'erreur : + 2003 + + + 8 + Insérer le changement d'état + + transferStateChange + + + 9 + Renvoyer le succès + + + Message : + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { +          + headers: + { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfert expiré", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: notification, + action: timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 10 + Publier l'événement de notification + + [transferInfo.transferStateId == 'RESERVED'] + + + 11 + Définir l'état RESERVED_TIMEOUT + Code d'erreur : + 2003 + + + 12 + Insérer le changement d'état + + transferStateChange + + + 13 + Renvoyer le succès + + + Message : + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { +          + headers: + { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfert expiré", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Acheminer et publier l'événement de position + Code d'erreur : + 2003 + + + + Tout autre état est ignoré + + + Nettoyage + + + 15 + Nettoyer le transfert expirant traité + Code d'erreur : + 2003 + + + 16 + Supprimer l'enregistrement + + expiringTransfer + + + 17 + Renvoyer le succès + + diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md new file mode 100644 index 000000000..2ce9d2fa6 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md @@ -0,0 +1,16 @@ +# Demande de transfert Prepare + +Diagramme de séquence de conception pour le processus de demande de transfert Prepare. + +## Références figurant dans le diagramme de séquence + +* [Gestionnaire Prepare — Consommation (1.1.1.a)](1.1.1.a-prepare-handler-consume.md) +* **Non implémenté** [Gestionnaire Prepare — Consommation (1.1.1.b)](1.1.1.b-prepare-handler-consume.md) +* [Gestionnaire Position — Consommation (1.1.2.a)](1.1.2.a-position-handler-consume.md) +* **Non implémenté** [Gestionnaire Position — Consommation (1.1.2.b)](1.1.2.b-position-handler-consume.md) +* [Envoi de la notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) +* **Non implémenté** [Envoi de la notification au participant (1.1.4.b)](1.1.4.b-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-prepare-1.1.0.svg](../assets/diagrams/sequence/seq-prepare-1.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md new file mode 100644 index 000000000..62173469c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire Prepare + +Diagramme de séquence pour le processus de consommation par le gestionnaire Prepare. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.1.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.a.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md new file mode 100644 index 000000000..fc20d8753 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire Prepare + +Diagramme de séquence pour le processus de consommation par le gestionnaire Prepare. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.1.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.b.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md new file mode 100644 index 000000000..4eb87289b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire Position + +Diagramme de séquence pour le processus de consommation par le gestionnaire Position. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.2.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.a.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md new file mode 100644 index 000000000..4a4bc74ad --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire Position + +Diagramme de séquence pour le processus de consommation par le gestionnaire Position. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.2.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.b.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md new file mode 100644 index 000000000..95633f16c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md @@ -0,0 +1,11 @@ +# Envoi d’une notification au participant (v1.1) + +Diagramme de séquence pour la demande d’envoi d’une notification au participant. + +## Références dans le diagramme de séquence + +* [9.1.0 — Consommation par le gestionnaire d’événements](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.4.a-v1.1.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md new file mode 100644 index 000000000..e910703c5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Envoi d’une notification au participant + +Diagramme de conception de séquence pour la demande d’envoi d’une notification au participant. + +## Références au sein du diagramme de séquence + +* [9.1.0 — Consommation par le gestionnaire d’événements](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.4.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md new file mode 100644 index 000000000..0ed21798c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Envoi d’une notification au participant + +Diagramme de conception de séquence pour la demande d’envoi d’une notification au participant. + +## Références au sein du diagramme de séquence + +* [9.1.0 — Consommation par le gestionnaire d’événements](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-prepare-1.1.4.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.b.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md new file mode 100644 index 000000000..2fdfb9a72 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md @@ -0,0 +1,14 @@ +# Consommation par le gestionnaire Position (v1.1) + +Diagramme de séquence pour le processus de consommation par le gestionnaire Position. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Consommation par le gestionnaire de position — Prepare (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Consommation par le gestionnaire de position — Fulfil (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Consommation par le gestionnaire de position — abandon (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Diagramme de séquence + +![seq-position-1.3.0-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md new file mode 100644 index 000000000..d31a37e52 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md @@ -0,0 +1,14 @@ +# Consommation par le gestionnaire Position + +Diagramme de séquence de conception pour le processus de consommation par le gestionnaire Position. + +## Références figurant dans le diagramme de séquence + +* [Gestionnaire Event — Consommation (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Gestionnaire Position — Consommation Prepare (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Gestionnaire Position — Consommation Fulfil (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Gestionnaire Position — Consommation Abort (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Diagramme de séquence + +![seq-position-1.3.0.svg](../assets/diagrams/sequence/seq-position-1.3.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..042288d52 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — Prepare + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position (Prepare). + +## Diagramme de séquence + +![seq-position-1.3.1-prepare.svg](../assets/diagrams/sequence/seq-position-1.3.1-prepare.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md new file mode 100644 index 000000000..04414d455 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — Fulfil (v1.1) + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position (Fulfil). + +## Diagramme de séquence + +![seq-position-1.3.2-fulfil-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md new file mode 100644 index 000000000..27a72cbaf --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — Fulfil + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position (Fulfil). + +## Diagramme de séquence + +![seq-position-1.3.2-fulfil.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md new file mode 100644 index 000000000..3aa42d19d --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire de position — abandon + +Diagramme de séquence pour le processus de consommation par le gestionnaire de position (abandon). + +## Diagramme de séquence + +![seq-position-1.3.3-abort.svg](../assets/diagrams/sequence/seq-position-1.3.3-abort.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md new file mode 100644 index 000000000..ccac99839 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md @@ -0,0 +1,13 @@ +# Demande de transfert Fulfil — succès (v1.1) + +Diagramme de séquence pour la demande de transfert Fulfil en cas de succès. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Fulfil (succès) (2.1.1)](2.1.1-fulfil-handler-consume-v1.1.md) +* [Consommation par le gestionnaire de position — Fulfil (succès) (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Diagramme de séquence + +![seq-fulfil-2.1.0-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md b/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md new file mode 100644 index 000000000..49d5ddaa6 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md @@ -0,0 +1,13 @@ +# Demande de transfert Fulfil — succès + +Diagramme de séquence pour la demande de transfert Fulfil en cas de succès. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Fulfil (succès) (2.1.1)](2.1.1-fulfil-handler-consume.md) +* [Consommation par le gestionnaire de position — Fulfil (succès) (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-fulfil-2.1.0.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md new file mode 100644 index 000000000..9aaa4433b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md @@ -0,0 +1,13 @@ +# Consommation par le gestionnaire Fulfil (succès) (v1.1) + +Diagramme de séquence pour le processus de consommation par le gestionnaire Fulfil. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Validation de signature (seq-signature-validation)](../../central-event-processor/signature-validation.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Diagramme de séquence + +![seq-fulfil-2.1.1-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md new file mode 100644 index 000000000..47ab7a04e --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Consommation par le gestionnaire Fulfil (succès) + +Diagramme de séquence pour le processus de consommation par le gestionnaire Fulfil. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Validation de signature (seq-signature-validation)](../../central-event-processor/signature-validation.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-fulfil-2.1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md new file mode 100644 index 000000000..2a4cf8631 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md @@ -0,0 +1,7 @@ +# Le bénéficiaire envoie une demande d’abandon Fulfil pour le transfert (v1.1) + +Diagramme de séquence pour le processus de rejet Fulfil d’un transfert pour la version 1.1 de l’API. + +## Diagramme de séquence + +![seq-reject-2.2.0-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md new file mode 100644 index 000000000..05a23dd9c --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md @@ -0,0 +1,13 @@ +# [Obsolète] Le bénéficiaire envoie une demande de rejet Fulfil pour le transfert + +Diagramme de séquence pour le processus de rejet Fulfil d’un transfert. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Fulfil (rejet / abandon) (2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Consommation par le gestionnaire de position — rejet (1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Diagramme de séquence + +![seq-reject-2.2.0.svg](../assets/diagrams/sequence/seq-reject-2.2.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md new file mode 100644 index 000000000..dc45167e5 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md @@ -0,0 +1,13 @@ +# Le bénéficiaire envoie un appel PUT sur l'endpoint /error pour une demande de transfert (v1.1) + +Diagramme de séquence pour le processus de rejet Fulfil d’un transfert pour la version 1.1 de l’API. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Fulfil (abandon) (2.2.1)](2.2.1-fulfil-reject-handler-v1.1.md) +* [Consommation par le gestionnaire de position — rejet (1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Diagramme de séquence + +![seq-reject-2.2.0.a-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md new file mode 100644 index 000000000..51c9306eb --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md @@ -0,0 +1,13 @@ +# Le bénéficiaire envoie un appel PUT sur l'endpoint /error pour une demande de transfert + +Diagramme de séquence pour le processus de rejet Fulfil d’un transfert. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire Fulfil (rejet / abandon) (2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Consommation par le gestionnaire de position — rejet (1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-reject-2.2.0.a.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md new file mode 100644 index 000000000..d17edd438 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md @@ -0,0 +1,7 @@ +# Consommation par le gestionnaire Fulfil (rejet / abandon) (v1.1) + +Diagramme de séquence pour le processus de rejet ou d’abandon par le gestionnaire Fulfil pour la version 1.1 de l’API. + +## Diagramme de séquence + +![seq-reject-2.2.1-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md b/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md new file mode 100644 index 000000000..936cd852b --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md @@ -0,0 +1,13 @@ +# Consommation par le gestionnaire Fulfil (rejet / abandon) + +Diagramme de séquence pour le processus de rejet ou d’abandon par le gestionnaire Fulfil. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Validation de signature (seq-signature-validation)](../../central-event-processor/signature-validation.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-reject-2.2.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md b/docs/fr/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md new file mode 100644 index 000000000..52343b445 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md @@ -0,0 +1,13 @@ +# Expiration du transfert (timeout) + +Diagramme de séquence pour le processus d’expiration d’un transfert. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’expiration (2.3.1)](2.3.1-timeout-handler-consume.md) +* [Consommation par le gestionnaire de position — expiration (1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Envoi d’une notification au participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Diagramme de séquence + +![seq-timeout-2.3.0.svg](../assets/diagrams/sequence/seq-timeout-2.3.0.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md b/docs/fr/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md new file mode 100644 index 000000000..c0bf756c1 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md @@ -0,0 +1,11 @@ +# Consommation par le gestionnaire d’expiration (timeout) + +Diagramme de séquence pour le processus de consommation par le gestionnaire d’expiration. + +## Références dans le diagramme de séquence + +* [Consommation par le gestionnaire d’événements (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Diagramme de séquence + +![seq-timeout-2.3.1.svg](../assets/diagrams/sequence/seq-timeout-2.3.1.svg) diff --git a/docs/fr/technical/technical/central-ledger/transfers/README.md b/docs/fr/technical/technical/central-ledger/transfers/README.md new file mode 100644 index 000000000..521647442 --- /dev/null +++ b/docs/fr/technical/technical/central-ledger/transfers/README.md @@ -0,0 +1,8 @@ +# Opérations de transfert Mojaloop + +Processus opérationnels au cœur du processus opérationnel de transfert : + +- Processus Prepare +- Processus Fulfil +- Processus Notifications +- Processus Reject/Abort diff --git a/docs/fr/technical/technical/deployment-guide/README.md b/docs/fr/technical/technical/deployment-guide/README.md new file mode 100644 index 000000000..9df3891f3 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/README.md @@ -0,0 +1,494 @@ +# Déploiement Mojaloop + +Ce document s’adresse à un public disposant de solides connaissances techniques et souhaitant mettre en place un environnement pour le développement, les tests et la contribution au projet Mojaloop. + +## Déploiement et configuration + +- [Déploiement Mojaloop](#déploiement-mojaloop) + - [Déploiement et configuration](#déploiement-et-configuration) + - [1. Prérequis](#_1-prérequis) + - [2. Recommandations de déploiement](#_2-recommandations-de-déploiement) + - [3. Kubernetes](#_3-kubernetes) + - [3.1. Ingress controller Kubernetes](#_3-1-contrôleur-dentrée-kubernetes-ingress) + - [3.2. Interfaces d’administration Kubernetes](#_3-2-interfaces-dadministration-kubernetes) + - [4. Helm](#_4-helm) + - [4.1. Configuration Helm](#_4-1-configuration-helm) + - [5. Mojaloop](#_5-mojaloop) + - [5.1. Déploiement Helm du backend (prérequis)](#_5-1-déploiement-helm-du-backend-prérequis) + - [5.2. Déploiement Helm Mojaloop](#_5-2-déploiement-helm-mojaloop) + - [5.3. Vérification des règles Ingress](#_5-3-vérification-des-règles-ingress) + - [5.4. Tester Mojaloop](#_5-4-tester-mojaloop) + - [5.5. Tester Mojaloop avec Postman](#_5-5-tester-mojaloop-avec-postman) + - [6. Services superposés / 3PPI](#_6-services-superposés--3ppi) + - [6.1 Configurer un déploiement pour la prise en charge de l’API tierce](#_61-configurer-un-déploiement-pour-la-prise-en-charge-de-lapi-tierce) + - [6.2 Valider et tester l’API tierce](#_62-valider-et-tester-lapi-tierce) + - [6.2.1 Déployer les simulateurs](#_621-déployer-les-simulateurs) + - [6.2.2 Provisionner l’environnement](#_622-provisionner-lenvironnement) + - [6.2.3 Exécuter la collection de tests de l’API tierce](#_623-exécuter-la-collection-de-tests-de-lapi-tierce) + + + +### 1. Prérequis + +Choisissez avec soin les versions des logiciels : une incompatibilité peut provoquer des erreurs ou des problèmes de compatibilité. + +Liste des outils prérequis pour le déploiement de Mojaloop : + +- **Kubernetes** — Système open source pour automatiser le déploiement, la mise à l’échelle et la gestion d’applications conteneurisées. En savoir plus sur [Kubernetes](https://kubernetes.io). + + - **Versions recommandées** + + | Version de publication du chart Helm Mojaloop | Version Kubernetes recommandée | + | ---------------------------------------------------------------- | ------------------------------ | + | [v16.0.0](https://github.com/mojaloop/helm/releases/tag/v16.0.0) | v1.29 | + | [v15.0.0](https://github.com/mojaloop/helm/releases/tag/v15.0.0) | v1.24 - v1.25 | + | [v14.1.1](https://github.com/mojaloop/helm/releases/tag/v14.1.1) | v1.20 - v1.24 | + | [v14.0.0](https://github.com/mojaloop/helm/releases/tag/v14.0.0) | v1.20 - v1.21 | + | [v13.x](https://github.com/mojaloop/helm/releases/tag/v13.1.1) | v1.13 - v1.21 | + | [v12.x](https://github.com/mojaloop/helm/releases/tag/v12.0.0) | v1.13 - v1.20 | + | [v11.x](https://github.com/mojaloop/helm/releases/tag/v11.0.0) | v1.13 - v1.17 | + | [v10.x](https://github.com/mojaloop/helm/releases/tag/v10.4.0) | v1.13 - v1.15 | + + > NOTES : + > + > - Les liens ci-dessus pointent vers la dernière version majeure (ex. v13.x → v13.1.1). + > - Consulter [https://github.com/mojaloop/helm/releases](https://github.com/mojaloop/helm/releases) pour les versions intermédiaires. + > - La colonne « Version Kubernetes recommandée » indique les versions de Kubernetes testées et validées avec la version correspondante du chart Helm Mojaloop. + + - **kubectl** — Interface en ligne de commande Kubernetes ; requise pour l’administration. En savoir plus sur [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) : + - [Installer kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) + +- **Helm** — Gestionnaire de paquets pour Kubernetes. En savoir plus sur [Helm](https://helm.sh) + + **Versions recommandées** + + - [Helm v3](https://helm.sh/docs/intro/install) + + > NOTES : + > + > - Consulter le guide [Migration de Helm v2 vers v3](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-migration.html) pour migrer de Helm v2.x vers v3.x. + +### 2. Recommandations de déploiement + +Ceci présente des recommandations sur les ressources d’environnement et ainsi qu'une vue sur l’architecture d’infrastructure. + +**Besoins en ressources :** + +- Plan de contrôle c.-à-d. (nœuds maîtres) + + [https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components](https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components) + + - 3x nœuds maîtres pour la mise à l'échelle future et la haute disponibilité (HA) + +- Plan ETCd : + + [https://etcd.io/docs/latest/op-guide/hardware/](https://etcd.io/docs/latest/op-guide/hardware/) + + - 3x nœuds ETCd pour la HA (haute disponibilité) + +- Plan de calcul c.-à-d. (nœuds workers) : + + À confirmer une fois les tests de charge terminés. Cependant, le configuration générale recommandée actuellement est : + + - 3x nœuds workers, chacun disposant : + - 4 vCPU, 16 Go de RAM et 40 Go de stockage + + **Remarque :** cela dépend aussi de votre infrastructure sous-jacente et cela **N’INCLUT PAS** les besoins en volumes persistants / stockage. + +![Recommandations de déploiement Mojaloop — Architecture d’infrastructure](./assets/diagrams/deployment/KubeInfrastructureArch.svg) + +### 3. Kubernetes + +Si vous installez Kubernetes vous-même, nous recommandons l’une des distributions suivantes, en installant la version correspondante souhaitée, telle qu'indiquée à la section [1. Prérequis](#_1-prérequis) : + +- [k3s](https://docs.k3s.io/installation) — Distribution Kubernetes légère et flexible, utilisable pour presque tout, du local à la production. +- [Minikube](https://minikube.sigs.k8s.io/docs/start) — Distribution Kubernetes mono-nœud, simple et indépendant de la plateforme, adaptée au local ou au développement. +- [Microk8s](https://microk8s.io/docs/install-alternatives) — Distribution Kubernetes simple, adaptée au local ou au développement. +- [Docker Desktop](https://docs.docker.com/desktop/kubernetes/) — Distribution Kubernetes simple, adaptée au local ou au développement (installez la version qui inclut votre version Kubernetes cible en consultant les [notes de version Docker Desktop](https://docs.docker.com/desktop/release-notes)). + +Nous ne prescrivons pas une distribution Kubernetes précise ; mais plutôt toute distribution executant certifiée [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/certification/software-conformance) ou solution managée (ex. Azure, AWS, GCP) convient pour tester les nouvelles versions Mojaloop. + +Si vous débutez avec Kubernetes, il est fortement conseillé de vous familiariser avec les concepts. [Concepts Kubernetes](https://kubernetes.io/docs/concepts/overview/) est un bon point de départ et fournira un aperçu général. + +Vérifiez que **kubectl** est installé. Les instructions complètes se trouvent [ici](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + +#### 3.1. Ingress Controller Kubernetes + +Installez l'Ingress controller de votre choix pour l’équilibrage de charge et l’accès externe. + +Pour installer le contrôleur Nginx-Ingress utilisé dans ce guide, voir : . + +Liste d’autres contrôleurs Ingress : . + +Installez une version **prise en charge** de l'`Ingress Controller` compatible avec votre version cible de `Kubernetes`. + +> **DÉPANNAGE DU DÉPLOIEMENT — Mis à jour en mars 2023** +> +> - Si vous utilisez Mojaloop `v13.x` - `v14.0.x`, voir [Dépannage du déploiement — 1.1. Prise en charge du contrôleur Nginx-Ingress pour les versions Helm Mojaloop v13.x - v14.0.x et Kubernetes v1.20 - v1.21](./deployment-troubleshooting.md#11-nginx-ingress-controller-support-for-mojaloop-helm-release-v13x---v140xx-support-for-kubernetes-v120---v121). +> +> - Si vous utilisez Mojaloop `v12.x`, voir [Dépannage du déploiement — 1.2. Prise en charge du contrôleur Nginx-Ingress pour la version Helm Mojaloop v12.x](./deployment-troubleshooting.md#12-nginx-ingress-controller-support-for-mojaloop-helm-release-v12x). +> +> - Si vous utilisez Mojaloop `v10.x`, voir [Dépannage du déploiement — 1.4. La version Helm Mojaloop v10.x ou antérieure ne prend pas en charge Kubernetes v1.16 ou supérieur](./deployment-troubleshooting.md#14-mojaloop-helm-release-v10x-or-less-does-not-support-kubernetes-v116-or-greater). +> + +#### 3.2. Interfaces d’administration Kubernetes (facultatif) + +1. Tableaux de bord Kubernetes + + Interface web officielle d’administration Kubernetes. + + Instructions d’installation : [Web UI (Dashboard) — installation](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/) (inutile si **microk8s** est installé). + + **IMPORTANT :** (inutile si **microk8s** est installé) Configurez les rôles RBAC et un compte de service associé ; exemple pour un utilisateur de test uniquement : [Créer un utilisateur d’exemple](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md). + + Si vous avez installé microk8s, **activez le tableau de bord microk8s** : + + ```bash + microk8s.enable dashboard + ``` + + Plus d’informations : [Extension : dashboard](https://microk8s.io/docs/addon-dashboard). + + **Pensez** à préfixer toutes les commandes **kubectl** par **microk8s** si vous avez choisi de ne pas créer d'alias. + +2. k8sLens + + Alternative graphique de bureau (desktop) à kubectl, simple à installer et à configurer. + + Plus d’informations : . + +### 4. Helm + +Consultez [Charts Helm Mojaloop](../repositories/helm.md) pour comprendre les relations entre les charts Helm Mojaloop déployés. + +Installation de la dernière version de Helm : . + +Si vous utilisez Helm v2, consultez le document suivant : [Déploiement avec Helm v2 (obsolète)](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-deployment.html). + +Si vous souhaitez migrer un déploiement Helm v2 existant vers v3, consultez le [Guide de migration Helm v2 vers v3](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-migration.html). + +#### 4.1. Configuration Helm + +1. Ajoutez le dépôt mojaloop à la configuration Helm : + + ```bash + helm repo add mojaloop https://mojaloop.io/helm/repo/ + ``` + + Si le dépôt existe déjà, remplacez `add` par `apply` dans la commande ci-dessus. + +2. Mettez à jour les dépôts Helm : + + ```bash + helm repo update + ``` + +### 5. Mojaloop + +#### 5.1. Prérequis - Déploiement Helm du backend + +Mojaloop dépend de plusieurs dépendances backends externes. + +Nous recommandons de déployer ces dépendances dans un déploiement nommé distinct. + +Le chart backend d’exemple est fourni à titre d'exemple et ne doit servir qu’à des fins de preuve de concept, de développement et de test. + +Plus de détails [ici](https://github.com/mojaloop/helm/blob/master/README.md#deploying-backend-dependencies). + +1. Déployer le backend + + ```bash + helm --namespace demo install backend mojaloop/example-mojaloop-backend --create-namespace + ``` + + + +#### 5.2. Déploiement Helm Mojaloop + +1. Installer Mojaloop : + + 1.1. Installer la dernière version : + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace + ``` + + Ou si vous avez besoin d'une configuration personnalisée : + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace -f {custom-values.yaml} + ``` + + Plus de détails [ici](https://github.com/mojaloop/helm/blob/master/README.md#deploying-mojaloop-helm-charts). + + _Remarque : Téléchargez et adaptez le fichier [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml). Assurez vous également d'utiliser le `values.yaml` correspondant à la bonne version (ex. `https://github.com/mojaloop/helm/blob/v/mojaloop/values.yaml`) via les [releases Helm](https://github.com/mojaloop/helm/releases). Pour vérifier la version installée : `helm --namespace demo list`. Sous la colonne **CHART**, vous devriez voir quelque chose comme `mojaloop-**{version}**` où `{version}` correspond à la version déployée._ + + ```bash + $ helm -n demo list + NAME NAMESPACE REVISION UPDATED STATUS CHART + moja demo 1 2021-06-11 15:06:04.533094 +0200 SAST deployed mojaloop-{version} + ``` + + _Remarque : L’option `--create-namespace` n’est nécessaire que si l’espace de noms `demo` n’existe pas. Vous pouvez aussi le créer avec : `kubectl create namespace demo`._ + + 1.2. Installation d’une version précise : + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace --version {version} + ``` + + 1.3. Liste des versions Mojaloop : + + ```bash + $ helm search repo mojaloop/mojaloop -l + NAME CHART VERSION APP VERSION DESCRIPTION + mojaloop/mojaloop {version} {list of app-versions} Mojaloop Helm chart for Kubernetes + ... ... ... ... + ``` + +#### 5.3. Vérification des règles Ingress + +1. Mettez à jour `/etc/hosts` pour un déploiement local : + + _Remarque : Uniquement pour les déploiements locaux ; inutile si le DNS ou les règles Ingress sont définis dans un [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) personnalisé._ + + ```bash + vi /etc/hosts + ``` + + _Sous Windows, le fichier doit être modifié dans dans le Bloc-notes en l'ouvrant obligatoirement avec des droits administrateur. Emplacement : `C:\Windows\System32\drivers\etc\hosts`._ + + Ajoutez les lignes suivantes (ou combinez-les) à la configuration hôte. + + Configuration requise pour les versions du chart Helm >= 6.2.2 pour les services API Mojaloop : + + ```bash + # Mojaloop Demo + 127.0.0.1 ml-api-adapter.local central-ledger.local account-lookup-service.local account-lookup-service-admin.local quoting-service.local central-settlement-service.local transaction-request-service.local central-settlement.local bulk-api-adapter.local moja-simulator.local sim-payerfsp.local sim-payeefsp.local sim-testfsp1.local sim-testfsp2.local sim-testfsp3.local sim-testfsp4.local mojaloop-simulators.local finance-portal.local operator-settlement.local settlement-management.local testing-toolkit.local testing-toolkit-specapi.local + ``` + +2. Testez la santé du système dans le navigateur après installation. Cela ne fonctionne que si un déploiement de chart Helm est actif et en cours d'exécution. + + _Remarque : Les exemples ci-dessous concernent un déploiement local. Les entrées doivent correspondre au DNS ou aux règles Ingress du [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) ou à toute configuration Ingress personnalisée._ + + Test de santé **ml-api-adapter** : + + Test de santé **central-ledger** : + + + +#### 5.4. Tester Mojaloop + +Le [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) sert à tester les déploiements ; il est intégré à Helm via son interface CLI pour tester facilement tout déploiement Mojaloop. + +1. Valider Mojaloop avec Helm + + ```bash + helm -n demo test moja + ``` + + Ou avec les journaux affichés dans la console : + + ```bash + helm -n demo test moja --logs + ``` + + Cela exécute automatiquement les [cas de test](https://github.com/mojaloop/testing-toolkit-test-cases) suivants via le CLI du [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) : + + - [Collection de provisionnement du Hub et des simulateurs TTK](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning). + + Journaux de la collection de provisionnement : + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-setup + ``` + + - [Collection de tests Golden Path TTK](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path). + + Journaux de la collection Golden Path : + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-validation + ``` + + Exemple de résumé final dans les journaux de la collection Golden Path : + + ```bash + Test Suite:GP Tests + Environment:Development + ┌───────────────────────────────────────────────────┐ + │ SUMMARY │ + ├───────────────────┬───────────────────────────────┤ + │ Total assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Failed assertions │ 0 │ + ├───────────────────┼───────────────────────────────┤ + │ Total requests │ 297 │ + ├───────────────────┼───────────────────────────────┤ + │ Total test cases │ 61 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed percentage │ 100.00% │ + ├───────────────────┼───────────────────────────────┤ + │ Started time │ Fri, 11 Jun 2021 15:45:53 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Completed time │ Fri, 11 Jun 2021 15:47:25 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Runtime duration │ 91934 ms │ + └───────────────────┴───────────────────────────────┘ + TTK-Assertion-Report-multi-2021-06-11T15:47:25.656Z.html was generated + ``` + +2. Accéder à l’interface du Mojaloop Testing Toolkit + + Ouvrez dans le navigateur : . + + Vous pouvez charger et exécuter manuellement les collections du Testing Toolkit via l'interface graphique, ce qui permet d'inspecter visuellement les requêtes, réponses et assertions en détail. C'est une excellente façon d'en apprendre davantage sur Mojaloop. + + Voir la [documentation du Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md). + + + +#### 5.5. Tester Mojaloop avec Postman + +[Postman](https://www.postman.com/downloads) peut remplacer le [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md). Voir le [Guide des tests automatisés](../contributors-guide/tools-and-technologies/automated-testing.md). + +Les [collections Postman Mojaloop](https://github.com/mojaloop/postman) sont similaires aux [cas de test du Mojaloop Testing Toolkit](https://github.com/mojaloop/testing-toolkit-test-cases) comme suit : + +| Collection Postman | Mojaloop Testing Toolkit | Description | +|---------|----------|---------| +| [Collection Postman MojaloopHub_Setup](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) et [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) | [Collection de provisionnement du Hub et des simulateurs TTK](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning) | Configuration du Hub et provisionnement des simulateurs | +| [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) | [Collection de tests Golden Path TTK](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path) | Tests Golden Path | + +Prérequis : + +- Le fichier d'environnement Postman suivant doit être importé ou adapté selon les besoins lors de l'exécution des collections Postman listées ci-dessus : [Mojaloop-Local-MojaSims.postman_environment.json](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local-MojaSims.postman_environment.json). +- Assurez-vous de téléchargez la **dernière version patch** depuis les [releases du dépôt Postman Mojaloop](https://github.com/mojaloop/postman/releases). Par exemple, si vous installez Mojaloop v12.0.**X**, assurez-vous d’avoir la dernière version patch des collections v12.0.**Y**. + +### 6. Overlay Services/3PPI + +À partir de la [R.C. v13.1.0](https://github.com/mojaloop/helm/tree/release/v13.1.0) de Mojaloop, l'API tierce est désormais prise en charge et sera incluse dans la version officielle Mojaloop v13.1.0, +ce qui permet aux initiateurs de paiement tiers (3PPI) de demander la liaison de compte auprès d’un DFSP et d’initier +des paiements pour le compte des utilisateurs. + +> En savoir plus sur les 3PPI : +> - [API tierce](https://github.com/mojaloop/mojaloop-specification/tree/master/thirdparty-api) Mojaloop +> - Cas d’usage tiers : +> - [Liaison de compte tiers](https://sandbox.mojaloop.io/usecases/3ppi-account-linking.html) +> - [Paiements initiés par un tiers](https://sandbox.mojaloop.io/usecases/3ppi-transfer.html) + + +#### 6.1 Configurer un déploiement pour la prise en charge de l’API tierce + +La prise en charge de l’API tierce est **désactivée** par défaut sur le déploiement Mojaloop. Vous pouvez l’activer en modifiant votre fichier `values.yaml` +avec les paramètres suivants : + +```yaml +... +account-lookup-service: + account-lookup-service: + config: + featureEnableExtendedPartyIdType: true # permet à l’ALS de prendre en charge le PartyIdType THIRD_PARTY_LINK plus récent + + account-lookup-service-admin: + config: + featureEnableExtendedPartyIdType: true # permet à l’ALS de prendre en charge le PartyIdType THIRD_PARTY_LINK plus récent + +... + +thirdparty: + enabled: true +... +``` + +De plus, l’API tierce a plusieurs dépendances à déployer manuellement pour que les services thirdparty +fonctionnent. [mojaloop/helm/thirdparty](https://github.com/mojaloop/helm/tree/master/thirdparty) décrit ces +dépendances et fournit des exemples de fichiers de configuration k8s qui se chargent de les installer automatiquement. + +```bash +# installer redis et mysql pour auth-service +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-auth-svc/example_dependencies.yaml +# installer mysql pour le consent oracle +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-consent-oracle/example_dependencies.yaml + +# appliquer les modifications ci-dessus à values.yaml, puis mettre à jour l’installation mojaloop pour déployer les services thirdparty : +helm upgrade --install --namespace demo moja mojaloop/mojaloop -f values.yaml +``` + +Une fois la mise à jour Helm terminée, vous pouvez vérifiez que les services tiers sont actifs et en cours d'éxecutions : + +```bash +kubectl get po | grep tp-api +# tp-api-svc-b9bf78564-4g59d 1/1 Running 0 7m17s + +kubectl get po | grep auth-svc +# auth-svc-b75c954d4-9vq7w 1/1 Running 0 8m5s + +kubectl get po | grep consent-oracle +# consent-oracle-849cb69769-vq4rk 1/1 Running 0 8m31s + + +# vérifier aussi que l’ingress est correctement exposé +curl -H "Host: tp-api-svc.local" /health +# {"status":"OK","uptime":3545.77290063,"startTime":"2021-11-04T05:41:32.861Z","versionNumber":"11.21.0","services":[]} + +curl -H "Host: auth-service.local" /health + +# {"status":"OK","uptime":3682.48869561,"startTime":"2021-11-04T05:43:19.056Z","versionNumber":"11.10.1","services":[]} + +curl -H "Host: consent-oracle.local" /health +# {"status":"OK","uptime":3721.520096665,"startTime":"2021-11-04T05:43:48.382Z","versionNumber":"0.0.8","services":[]} +``` + +> Vous pouvez aussi ajouter les entrées suivantes à votre fichier `/etc/hosts` pour faciliter l’accès aux services thirdparty +> +> ```bash +> tp-api-svc.local auth-service.local consent-oracle.local +> ``` + +#### 6.2 Valider et tester l’API tierce + +Une fois les services tiers déployés, déployez des simulateurs capables de reproduire +les scénarios de l'API tierce. + +##### 6.2.1 Déployer les simulateurs + +Modifiez à nouveau votre fichier `values.yaml`, cette fois sous l’entrée `mojaloop-simulator` : + +```yaml +... + +mojaloop-simulator: + simulators: + ... + pisp: + config: + thirdpartysdk: + enabled: true + dfspa: + config: + thirdpartysdk: + enabled: true + dfspb: {} +... +``` + +Cette configuration crée trois nouveaux jeux de simulateurs mojaloop : + +1. `pisp` — un PISP +2. `dfspa` — un DFSP prenant en charge l’API tierce +3. `dfspb` — un simulateur DFSP classique sans API tierce, pouvant recevoir des paiements + +##### 6.2.2 Provisionner l’environnement + +Une fois les simulateurs déployés et opérationnels, il est temps de configurer le Hub Mojaloop et les simulateurs afin de pouvoir tester l'API tierce. + +Utilisez la [collection de provisionnement tiers](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-provisioning-collection) +du dépôt mojaloop/testing-toolkit-test-cases pour provisionner l’environnement tiers et les simulateurs +définis à l’étape précédente. + +##### 6.2.3 Exécuter la collection de tests de l’API tierce + +Une fois le provisionnement terminé, exécutez la [collection de tests tiers](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-test-collection) +pour vérifier que les services tiers sont correctement déployés et configurés. diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg b/docs/fr/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg new file mode 100644 index 000000000..26b8dcd92 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg @@ -0,0 +1,2 @@ + + diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd b/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd new file mode 100644 index 000000000..a5b07e79d --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd @@ -0,0 +1,30 @@ +graph TD + step1["Étape 1 : Bibliothèques de base
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing"] + step2["Étape 2 : Dépendances de premier niveau
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib"] + step3["Étape 3 : Dépendances de second niveau
    event-sdk"] + step4["Étape 4 : Groupe à dépendances circulaires
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components"] + step5["Étape 5 : Couche base de données
    central-services-db"] + step6["Étape 6 : Bibliothèques plateforme
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib"] + step7["Étape 7 : Services principaux
    central-ledger
    central-settlement"] + step8["Étape 8 : Services API
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service"] + step9["Étape 9 : Autres services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator"] + note1["Remarque : les dépôts de l’étape 4
    ont des dépendances circulaires.
    Mettez-les à jour comme un ensemble."] + %% Flèches de la séquence de mise à jour + step1 --> step2 + step2 --> step3 + step3 --> step4 + step4 --> step5 + %% Dépendances pouvant être mises à jour en parallèle + step5 --> step7 + step6 --> step8 + %% Bibliothèques plateforme : traitement particulier + step4 --> step6 + %% Les services finaux dépendent de toutes les mises à jour précédentes + step7 --> step9 + step8 --> step9 + %% Lien vers la note + step4 --- note1 + %% Styles + classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; + classDef note fill:#ffffcc,stroke:#333,stroke-width:1px; + class note1 note; diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg b/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg new file mode 100644 index 000000000..6d55a9b6c --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg @@ -0,0 +1 @@ +

    Step 1: Base Libraries
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing

    Step 2: First-level Dependencies
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib

    Step 3: Second-level Dependencies
    event-sdk

    Step 4: Circular Dependency Group
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components

    Step 5: Database Layer
    central-services-db

    Step 6: Platform Libraries
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib

    Step 7: Core Services
    central-ledger
    central-settlement

    Step 8: API Services
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service

    Step 9: Remaining Services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator

    Note: The Step 4 repositories
    have circular dependencies.
    Update them as a unit.

    \ No newline at end of file diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg b/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg new file mode 100644 index 000000000..a5e597d9c --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Target Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Target Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Sync & Data Migration

    (Transform data to new Schema)
    Sync & Data M...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment
    +
    Backed Dependencies
    (MySQL, Kafka, etc)

    (Old Release)
    Mojaloop Current...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg b/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg new file mode 100644 index 000000000..894431623 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Shared Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Shared Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment

    (Old Release)
    Mojaloop Current...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png new file mode 100644 index 000000000..736a5190c Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml new file mode 100644 index 000000000..088f3c16d --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml @@ -0,0 +1,107 @@ +@startuml dependency-vulnerability-management-process +!theme cerulean + +skinparam ActivityBackgroundColor #f0f0f0 +skinparam ActivityBorderColor #333333 +skinparam ArrowColor #333333 +skinparam backgroundColor white +skinparam ActivityFontColor black +skinparam ActivityFontSize 14 +skinparam noteFontColor black +skinparam ArrowFontColor black +skinparam PartitionFontColor #000000 +skinparam PartitionFontStyle bold +skinparam PartitionBorderColor #333333 +skinparam PartitionBackgroundColor #f8f8f8 + +title Processus de gestion des vulnérabilités des dépendances + +start + +partition "Outils de détection des vulnérabilités" { + :Identifier la vulnérabilité; + fork + :Alertes GitHub Dependabot; + fork again + :npm run audit:check; + note right: audit-ci.jsonc avec liste d’autorisation + fork again + :Analyse d’image Grype; + note right: .grype.yaml avec section d’ignorance + end fork +} + +partition "Processus de tri" { + :Trier la vulnérabilité; + :Évaluer le niveau de gravité; + fork + :Critique : 1 à 3 jours; + note right #FF6666: Action immédiate + fork again + :Élevé : 30 jours; + note right #FFCC66: Priorité élevée + fork again + :Moyen : 60 jours; + note right #FFFF66: Priorité moyenne + fork again + :Faible : 90 jours; + note right #99FF99: Priorité faible + end fork + :Agir selon la gravité\net les échéances de correction; +} + +partition "Processus de mise à jour" { + :Choisir un seul module à mettre à jour; + :Mettre à jour package.json; + :Exécuter les tests; + if (Tests OK ?) then (Oui) + :Créer une pull request; + else (Non) + if (Correction impossible ?) then (Oui) + fork + :Mettre à jour audit-ci.jsonc; + note right #F9E0FF: Pour les problèmes npm + fork again + :Mettre à jour .grype.yaml; + note right #F9E0FF: Pour les conteneurs + end fork + :Créer une pull request; + else (Non) + :Ajuster la mise à jour; + note right #F9E0FF + Envisager des solutions de repli + Contacter le mainteneur du paquet + end note + :Réexécuter les tests; + endif + endif + :Revue de code; + if (Résultat de la revue) then (Approuvé) + :Fusionner la PR; + else (Modifications demandées) + :Mettre à jour la PR; + endif +} + +partition "CI/CD" { + :Pipeline CI/CD; + :Contrôles de sécurité; + fork + :Contrôle audit-ci; + fork again + :Analyse Grype; + end fork + if (Contrôles OK ?) then (Oui) + :Publication / release; + else (Non) + :Corriger les problèmes de sécurité; + endif +} + +if (Autres vulnérabilités ?) then (Oui) + :Revenir au choix du module; +else (Non) + stop +endif + +@enduml diff --git a/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg new file mode 100644 index 000000000..a58b4cfa9 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg @@ -0,0 +1,305 @@ + + Processus de gestion des vulnérabilités des dépendances + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Processus de gestion des vulnérabilités des dépendances + + + + Outils de détection des vulnérabilités + + Identifier la vulnérabilité + + + Alertes GitHub Dependabot + + + audit-ci.jsonc avec liste d’autorisation + + npm run audit:check + + + .grype.yaml avec section d’ignorance + + Analyse d’image Grype + + + + Processus de tri + + Trier la vulnérabilité + + Évaluer le niveau de gravité + + + + Action immédiate + + Critique : 1 à 3 jours + + + Priorité élevée + + Élevé : 30 jours + + + Priorité moyenne + + Moyen : 60 jours + + + Priorité faible + + Faible : 90 jours + + + Agir selon la gravité + et les échéances de correction + + + Processus de mise à jour + + Choisir un seul module à mettre à jour + + Mettre à jour package.json + + Exécuter les tests + + Tests OK ? + Oui + Non + + Créer une pull request + + Correction impossible ? + Oui + Non + + + + Pour les problèmes npm + + Mettre à jour audit-ci.jsonc + + + Pour les conteneurs + + Mettre à jour .grype.yaml + + + Créer une pull request + + + Envisager des solutions de repli + Contacter le mainteneur du paquet + + Ajuster la mise à jour + + Réexécuter les tests + + + + Revue de code + + Résultat de la revue + Approuvé + Modifications demandées + + Fusionner la PR + + Mettre à jour la PR + + + + CI/CD + + Pipeline CI/CD + + Contrôles de sécurité + + + Contrôle audit-ci + + Analyse Grype + + + Contrôles OK ? + Oui + Non + + Publication / release + + Corriger les problèmes de sécurité + + + Revenir au choix du module + + Oui + Autres vulnérabilités ? + Non + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png new file mode 100644 index 000000000..551ea6515 Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png new file mode 100644 index 000000000..4c14b2661 Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png new file mode 100644 index 000000000..a77a907b2 Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png new file mode 100644 index 000000000..d9d3a289b Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png new file mode 100644 index 000000000..3a35c25b3 Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png differ diff --git a/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png new file mode 100644 index 000000000..2c313578f Binary files /dev/null and b/docs/fr/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png differ diff --git a/docs/fr/technical/technical/deployment-guide/deployment-troubleshooting.md b/docs/fr/technical/technical/deployment-guide/deployment-troubleshooting.md new file mode 100644 index 000000000..b723f899e --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/deployment-troubleshooting.md @@ -0,0 +1,158 @@ +# Dépannage du déploiement + +## 1. Problèmes connus + +Consultez les notes de version des **charts Helm Mojaloop** pour plus d'informations sur les problèmes connus : [https://github.com/mojaloop/helm/releases](https://github.com/mojaloop/helm/releases). + +### 1.1. Prise en charge du contrôleur Nginx-Ingress pour les versions Helm Mojaloop v13.x - v14.0.x et Kubernetes v1.20 - v1.21 + +Si vous utilisez Mojaloop `v13.x` - `v14.0.x` et souhaitez installer le contrôleur `Nginx-Ingress`, il est recommandé d’installer `Nginx-Ingress Controller v0.47.0` avec `Kubernetes v1.20 - v1.21`, en raison de ruptures de compatibilité introduits dans `Kubernetes v1.22`. + +Avec Helm : + +```bash +helm install ingress-nginx ingress-nginx --version="3.33.0" --repo https://kubernetes.github.io/ingress-nginx +``` + +### 1.2. Prise en charge du contrôleur Nginx-Ingress pour la version Helm Mojaloop v12.x + +Si vous installez Mojaloop v12.x avec un contrôleur Nginx-Ingress plus récent que `v0.22.0`, assurez-vous de créez une [configuration values Mojaloop v12.0.0](https://github.com/mojaloop/helm/blob/v12.0.0/mojaloop/values.yaml) personnalisée avec les modifications suivantes **avant l’installation** : + +```YAML +## **RECHERCHEZ CETTE LIGNE DANS LE FICHIER DE CONFIGURATION mojaloop/values.yaml** +mojaloop-simulator: + ingress: + ## contrôleur nginx ingress >= v0.22.0 <-- **COMMENTEZ LES TROIS LIGNES CI-DESSOUS :** + # annotations: <-- COMMENTÉ + # nginx.ingress.kubernetes.io/rewrite-target: '/$2' <-- COMMENTÉ + # ingressPathRewriteRegex: (/|$)(.*) <-- COMMENTÉ + ## contrôleur nginx ingress < v0.22.0 <-- **DÉCOMMENTEZ LES TROIS LIGNES CI-DESSOUS :** + annotations: + nginx.ingress.kubernetes.io/rewrite-target: '/' + ingressPathRewriteRegex: "/" +``` + +**Remarque :** inutile si vous installez Mojaloop v13.x ou plus récent. + +### 1.3. Prise en charge de Kubernetes sur Docker Desktop pour Mojaloop v13.x - v14.0.x + +Si vous installez Mojaloop `v13.x` - `v14.0.x` sous Windows ou macOS, il est recommandé d’installer [Docker Desktop v4.2.0](https://docs.docker.com/desktop/release-notes/#420), livré avec Kubernetes v1.21.5, qui satisfait les éxigences de Mojaloop `v13.x` - `v14.0.x` conformément aux recommandations du guide de déploiement [guide de déploiement (1. Prérequis)](README.md#_1-prérequis). + +### 1.4. La version Helm Mojaloop v10.x ou antérieure ne prend pas en charge Kubernetes v1.16 ou supérieur + +#### 1.4.1 Description + +_Remarque : applicable uniquement aux publications Helm Mojaloop v10.x ou antérieures._ + +Lors de l’installation des charts Helm Mojaloop, l’erreur suivante peut apparaître : + +```log +Error: validation failed: [unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta2", unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta2", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta1"] +``` + +#### 1.4.2 Cause + +À partir de Kubernetes 1.16, des ruptures de compatibilités ont été introduits (pour en savoir [« Deprecations and Removals » dans les notes de version Kubernetes](https://kubernetes.io/docs/setup/release/notes/#deprecations-and-removals)). Les versions d’API Kubernetes `apps/v1beta1` et `apps/v1beta2` ne sont plus prises en charge et ont été remplacées par `apps/v1`. + +Les version Helm Mojaloop v10 ou antérieurs font référence à des identifiants encore des API dépréciées ; l’installation de v10- sur Kubernetes supérieur à 1.15 nécessite une modification manuelle. + +Voir le ticket [mojaloop/helm#219](https://github.com/mojaloop/helm/issues/219). + +#### 1.4.3 Correctifs + +Assurez-vous de déployez les charts Helm Mojaloop v10.x ou antérieurs sur Kubernetes v1.15. + +## 2. Problèmes de déploiement + +### 2.1. Erreur `ERR_NAME_NOT_RESOLVED` + +#### 2.1.1 Description + +Cette erreur s'affiche lors d'une tentative d'accès à un endpoint (ex. central-ledger.local) via le service Kubernetes directement dans un navigateur : `ERR_NAME_NOT_RESOLVED` + +#### 2.1.2 Correctifs + +1. Vérifiez que Mojaloop a été correctement déployé (en contrôlant que les charts Helm sont bien installés) en exécutant : + + ```bash + helm list + ``` + + Si les charts n’apparaissent pas, voir la section [Guide de déploiement — 5.1. Déploiement Helm Mojaloop](./README.md#_5-1-déploiement-helm-mojaloop). + +2. Vérifiez que tous les pods/conteneurs Mojaloop ont démarré correctement et sont disponibles dans le tableau de bord Kubernetes. + +3. Remarque: le déploiement de Mojaloop via Helm peut prendre quelques minutes au premier démarrage selon les ressources disponibles et les spécifications du système. Attendez-vous à ce que cela prenne entr 2 et 10 minutes. + +### 2.3. MicroK8s — problèmes de connectivité + +#### 2.3.1 Description + +Mes pods n'atteignent pas Internet ni les autres pods (alors que ma machine hôte MicroK8s y arrive). + +Exemple : les journaux Central-Ledger indiquent une erreur de transport du broker, par exemple : + +```log +2019-11-05T12:28:10.470Z - info: Server running at: +2019-11-05T12:28:10.474Z - info: Handler Setup - Registering {"type":"prepare","enabled":true}! +2019-11-05T12:28:10.476Z - info: CreateHandler::connect - creating Consumer for topics: [topic-transfer-prepare] +2019-11-05T12:28:10.515Z - info: CreateHandler::connect - successfully connected to topics: [topic-transfer-prepare] +2019-11-05T12:30:20.960Z - error: Consumer::onError()[topics='topic-transfer-prepare'] - Error: Local: Broker transport failure) +``` + +#### 2.3.2 Correctifs + +Assurez-vous que les paquets en provenance et à destination de l'interface réseau des pods peuvent être acheminés vers et depuis l'interface par défaut de l'hôte via l'outil iptables. Ces modifications peuvent être rendues persistantes en installant le paquet iptables-persistent : + +```bash +sudo iptables -P FORWARD ACCEPT +sudo apt-get install iptables-persistent +``` + +Ou, avec ufw : + +```bash +sudo ufw default allow routed +``` + +La commande d’inspection MicroK8s permet de vérifier la configuration du pare-feu : + +```bash +microk8s.inspect +``` + +## 3. Problèmes d’Ingress + +### 3.1. Les règles Ingress ne parviennent pas à résoudre vers le bon chemin selon les annotations spécifiées dans les fichiers de configuration values.yaml, avec les contrôleurs Nginx Ingress v0.22 ou ultérieurs. + +#### 3.1.1 Description + +_Remarque : applicable uniquement aux publications Helm Mojaloop v12.x ou antérieures._ + +Les règles Ingress ne mènent pas au bon chemin selon les annotations du fichier [values.yaml](https://github.com/mojaloop/helm/blob/v12.0.0/mojaloop/values.yaml) avec les contrôleurs Nginx Ingress v0.22 ou ultérieurs. + +Cela est dû aux changements introduits dans les contrôleurs Nginx Ingress v0.22 ou ultérieurs, conformément au lien suivant : https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### 3.1.2 Correctifs + +Effectuez la modification suivante sur les annotations Ingress (de → vers) dans les fichiers values.yaml : + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/$1' +``` + +### 3.2. Les règles Ingress ne parviennent pas à résoudre vers le bon chemin selon les annotations spécifiées dans les fichiers de configuration values.yaml, avec les contrôleurs Nginx Ingress antérieurs à v0.22. + +#### 3.2.1 Description + +Les règles Ingress ne mènent pas au bon chemin selon les annotations du fichier [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) avec les contrôleurs Nginx Ingress **plus anciens** que v0.22. + +Cela est dû aux changements introduits dans les contrôleurs Nginx Ingress v0.22 ou ultérieurs, conformément au lien suivant : https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### 3.2.2 Correctifs + +Effectuez la modification suivante sur **toutes** les annotations Ingress (de → vers) dans chaque fichier values.yaml : + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/$1'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/' +``` diff --git a/docs/fr/technical/technical/deployment-guide/mojaloop-repository-update-guide.md b/docs/fr/technical/technical/deployment-guide/mojaloop-repository-update-guide.md new file mode 100644 index 000000000..dc12c8814 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/mojaloop-repository-update-guide.md @@ -0,0 +1,176 @@ +# Séquence de mise à jour des dépôts NodeJS Mojaloop + +Ce document indique l’ordre dans lequel les dépôts NodeJS Mojaloop doivent être mis à jour lors de la publication de nouvelles fonctionnalités et/ou de la maintenance de Mojaloop. Il est important de respecter cet ordre pour s'assurer que chaque service d'une publication Mojaloop utilise la bonne dépendance du dépôt Mojaloop. Ce document est à jour pour Mojaloop RC v17 ; il doit être mis à jour au fil de l'évolution de Mojaloop (ajout des nouveaux composants et retrait des composants supprimés). + +## Table des matières + +- [Ordre de mise à jour des dépôts Mojaloop](#ordre-de-mise-à-jour-des-dépôts-mojaloop) + - [Table des matières](#table-des-matières) + - [Catégories de dépôts](#catégories-de-dépôts) + - [Processus de mise à jour](#processus-de-mise-à-jour) + - [Exigences de test](#exigences-de-test) + - [Séquence des dépôts Mojaloop](#séquence-des-dépôts-mojaloop) + +## Catégories de dépôts + +Catégories des dépôts NodeJS Mojaloop : + +1. **Bibliothèques Central Services** + - `central-services-shared` + - `central-services-error-handling` + - `central-services-database` + - `central-services-stream` + - `central-services-metrics` + - `central-services-error` + - `central-services-logger` + - `sdk-standard-components` + +2. **Services principaux** + - `account-lookup-service` + - `quoting-service` + - `central-ledger` + - `central-settlement` + - `central-bulk-transfers` + - `transaction-requests-service` + - `ml-api-adapter` + +3. **Composants événementiels** + - `central-event-processor` + - `event-framework` + - `event-stream-processor` + - `elastic-apm-node` + - `elastic-apm-node-opentracing` + - `email-notifier` + - `event-sidecar` + +4. **Adaptateurs, SDK et API** + - `sdk-scheme-adapter` + - `event-sdk` + - `thirdparty-sdk` + - `bulk-api-adapter` + - `thirdparty-api-svc` + - `als-consent-oracle` + - `als-oracle-pathfinder` + +5. **Tests** + - `ml-testing-toolkit` + - `ml-testing-toolkit-client-lib` + - `ml-testing-toolkit-ui` + - `ml-testing-toolkit-shared-lib` + - `mojaloop-simulator` + - `simulator` + +6. **Autres bibliothèques** + - `api-snippets` + - `auth-service` + - `ml-number` + - `object-store-lib` + - `inter-scheme-proxy-cache-lib` + - `database-lib` + +## Processus de mise à jour + +1. **Identifier les dépendances** + - Utilisez `npm audit` pour repérer les vulnérabilités + - Examinez les fichiers `package.json` pour les dépendances obsolètes + - Vérifiez les changements majeurs lors des mises à jour majeures + +2. **Élaborer un plan de mise à jour** + - Listez tous les dépôts à mettre à jour + - Identifiez les changements majeurs potentiels + - Définissez la stratégie de test pour chaque composant + +3. **Exécuter les mises à jour** + - Commencez par les bibliothèques de base + - Mettez à jour un dépôt à la fois + - Lancez les tests après chaque mise à jour + - Documentez les problèmes ou contournements + +4. **Tests d’intégration** + - Testez les composants mis à jour ensemble + - Vérifiez le fonctionnement bout en bout + - Contrôlez l’impact sur les performances (feuille de route, après v17) + +## Exigences de test + +Pour chaque dépôt, suivez les instructions de test du README et exécuter : + +1. **Tests unitaires** + - Exécutez la suite de tests existante + - Ajoutez des tests pour les fonctionnalités modifiées + - Vérifiez la couverture de tests + +2. **Tests d’intégration** + - Testez avec les services dépendants + - Vérifiez la compatibilité des API + - Contrôlez la gestion des événements + +3. **Tests de bout en bout** + - Passez par le testing toolkit Mojaloop + - Vérifiez les flux de transaction + - Testez les scénarios d’erreur + + +## Séquence des dépôts Mojaloop + +Le tableau suivant détaille les dépôts Mojaloop et leurs dépendances. Ces informations sont essentielles pour comprendre le bon ordre de mise à jour lors du traitement de changements de dépendances ou de vulnérabilités. + +| Ordre | Dépôt | Dépendances | +|---|---|---| +| 1 | api-snippets | | +| 2 | ml-number | | +| 3 | database-lib | | +| 4 | central-services-logger | | +| 5 | central-services-metrics | | +| 6 | central-services-error-handling | | +| 7 | ml-testing-toolkit-shared-lib | | +| 8 | logging-bc-public-types-lib | | +| 9 | platform-shared-lib-messaging-types-lib | | +| 10 | elastic-apm-node | | +| 11 | elastic-apm-node-opentracing | | +| 12 | object-store-libp | central-services-logger | +| 13 | central-services-stream | | +| 14 | central-services-health | central-services-error-handling, central-services-logger | +| 15 | event-sdk | central-services-stream, central-services-logger, central-services-stream | +| 16 | inter-scheme-proxy-cache-lib | central-services-logger, central-services-shared, inter-scheme-proxy-cache-lib, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 17 | ml-schema-transformer-lib | central-services-error-handling, central-services-logger, central-services-shared, sdk-standard-components, ml-schema-transformer-lib | +| 18 | sdk-standard-components | | +| 19 | central-services-shared | | +| 20 | platform-shared-lib-nodejs-kafka-client-lib | | +| 21 | logging-bc-client-lib | | +| 22 | **account-lookup-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, database-lib, event-sdk, inter-scheme-proxy-cache-lib, sdk-standard-components, sdk-standard-components, central-services-logger, central-services-shared, central-services-stream | +| 23 | **als-consent-oracle** | api-snippets, central-services-health, central-services-shared, sdk-standard-components, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 24 | **als-oracle-pathfinder** | central-services-logger, central-services-shared | +| 25 | **auth-service** | api-snippets, central-services-health, central-services-shared, event-sdk, sdk-standard-components, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 26 | **bulk-api-adapter** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, object-store-lib | +| 27 | **central-event-processor** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk | +| 28 | **central-ledger** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, database-lib, event-sdk, inter-scheme-proxy-cache-lib, ml-number, object-store-lib | +| 29 | **central-settlement** | central-ledger, central-services-database, central-services-error-handling, central-services-health, central-services-logger, central-services-shared, central-services-stream, event-sdk, ml-number | +| 30 | **email-notifier** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk | +| 31 | **event-sidecar** | central-services-logger, central-services-metrics, central-services-stream, event-sdk | +| 32 | **event-stream-processor** | central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, elastic-apm-node, elastic-apm-node-opentracing, event-sdk | +| 33 | **mojaloop-simulator** | central-services-logger | +| 34 | **ml-api-adapter** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, sdk-standard-components, database-lib, inter-scheme-proxy-cache-lib | +| 35 | **ml-testing-toolkit** | central-services-logger, central-services-metrics, ml-schema-transformer-lib, ml-testing-toolkit-shared-lib, sdk-standard-components | +| 36 | **ml-testing-toolkit-client-lib** | central-services-logger, ml-testing-toolkit-shared-lib, sdk-standard-components | +| 37 | **ml-testing-toolkit-ui** | ml-testing-toolkit-shared-lib | +| 38 | **quoting-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, inter-scheme-proxy-cache-lib, ml-number, sdk-standard-components | +| 39 | **simulator** (hérité, oracle ALS) | central-services-error-handling, central-services-logger, central-services-metrics, central-services-shared, event-sdk, sdk-standard-components | +| 40 | **sdk-scheme-adapter** | api-snippets, central-services-error-handling, central-services-logger, central-services-metrics, central-services-shared, event-sdk, sdk-standard-components | +| 41 | **thirdparty-api-svc** | api-snippets, central-services-shared, central-services-stream, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 42 | **thirdparty-sdk** | api-snippets, central-services-error-handling, central-services-metrics, central-services-shared, sdk-scheme-adapter, sdk-standard-components | +| 43 | **transaction-requests-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, event-sdk, ml-testing-toolkit-shared-lib | + +### Visualisation de la séquence de mise à jour + +Le diagramme suivant illustre la séquence de mise à jour recommandée pour les dépôts Mojaloop, compte tenu des dépendances et des relations : + +![Séquence de mise à jour des dépôts](./assets/diagrams/repositoryUpdate/repository-update-sequence.svg) + +Ce diagramme donne une représentation visuelle de la séquence de mise à jour et montre : + +1. Le regroupement logique des dépôts +2. Les dépendances entre les différents groupes +3. Les cas particuliers comme les dépendances circulaires +4. Les possibilités de mises à jour en parallèle +5. Les différents types de dépendances à prendre en compte diff --git a/docs/fr/technical/technical/deployment-guide/nodejs-dependency-update-guide.md b/docs/fr/technical/technical/deployment-guide/nodejs-dependency-update-guide.md new file mode 100644 index 000000000..db0dbc993 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/nodejs-dependency-update-guide.md @@ -0,0 +1,42 @@ +Le diagramme suivant illustre la séquence de mise à jour recommandée pour les dépôts Mojaloop, en tenant compte de leurs dépendances et relations : + +```mermaid +graph TD + step1["Étape 1 : Bibliothèques de base
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing"] + step2["Étape 2 : Dépendances de premier niveau
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib"] + step3["Étape 3 : Dépendances de second niveau
    event-sdk"] + step4["Étape 4 : Groupe à dépendances circulaires
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components"] + step5["Étape 5 : Couche base de données
    central-services-db"] + step6["Étape 6 : Bibliothèques plateforme
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib"] + step7["Étape 7 : Services principaux
    central-ledger
    central-settlement"] + step8["Étape 8 : Services API
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service"] + step9["Étape 9 : Autres services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator"] + note1["Remarque : les dépôts de l’étape 4
    ont des dépendances circulaires.
    Mettez-les à jour comme un ensemble."] + %% Clear update sequence arrows + step1 --> step2 + step2 --> step3 + step3 --> step4 + step4 --> step5 + %% Handle dependencies that can be updated in parallel + step5 --> step7 + step6 --> step8 + %% Platform libraries need special handling + step4 --> step6 + %% Final services depend on all previous updates + step7 --> step9 + step8 --> step9 + %% Connect notes + step4 --- note1 + %% Styling + classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; + classDef note fill:#ffffcc,stroke:#333,stroke-width:1px; + class note1 note; +``` + +Ce diagramme donne une représentation visuelle de la séquence de mise à jour et montre : + +1. Le regroupement logique des dépôts +2. Les dépendances entre groupes +3. Les cas particuliers comme les dépendances circulaires +4. Les possibilités de mises à jour en parallèle +5. Les différents types de dépendances à prendre en compte diff --git a/docs/fr/technical/technical/deployment-guide/upgrade-strategy-guide.md b/docs/fr/technical/technical/deployment-guide/upgrade-strategy-guide.md new file mode 100644 index 000000000..5c5106b28 --- /dev/null +++ b/docs/fr/technical/technical/deployment-guide/upgrade-strategy-guide.md @@ -0,0 +1,187 @@ +# Guide des stratégies de mise à niveau + +Ce document fournit des instructions pour mettre à niveau des installations Mojaloop existantes. Il part du principe que Mojaloop est déjà installé avec Helm, mais ces stratégies s’appliquent de façon générale. + +## Table des matières + +- [Guide des stratégies de mise à niveau](#guide-des-stratégies-de-mise-à-niveau) + - [Table des matières](#table-des-matières) + - [Mises à niveau Helm](#mises-à-niveau-helm) + - [Versions sans rupture de compatibilité](#versions-sans-rupture-de-compatibilité) + - [Versions avec rupture de compatibilité](#versions-avec-rupture-de-compatibilité) + - [Mojaloop installé sans dépendances backend](#mojaloop-installé-sans-dépendances-backend) + - [1. La version cible n’introduit pas de changements incompatibles sur le stockage de données](#1-la-version-cible-nintroduit-pas-de-changements-cassants-sur-le-stockage-de-données) + - [Exemple de déploiement de type canary](#exemple-de-déploiement-de-type-canary) + - [2. La version cible introduit des changements incompatibles sur le stockage de données](#2-la-version-cible-introduit-des-changements-cassants-sur-le-stockage-de-données) + - [Mojaloop installé avec dépendances backend](#mojaloop-installé-avec-dépendances-backend) + - [Exemple de déploiement blue-green](#exemple-de-déploiement-blue-green) + - [Commandes de mise à niveau](#commandes-de-mise-à-niveau) + - [Mise à niveau vers v17.0.0](#mise-à-niveau-vers-v1700) + - [Tester le scénario de mise à niveau de v16.0.0 vers v17.0.0](#tester-le-scénario-de-mise-à-niveau-de-v1600-vers-v1700) + +## Mises à niveau Helm + +Cette section présente les stratégies envisageables pour appliquer des mises à niveau à un déploiement Helm Mojaloop existant utilisant les [charts Helm Mojaloop](https://github.com/mojaloop/helm). + +La portée des changements incompatibel décrits ci-dessous concerne le déploiement Helm de l’opérateur du switch sans impact direct (c’est-à-dire sans changement fonctionnel tel qu’une nouvelle version de la spécification API Mojaloop) sur les participants (par ex. fournisseurs de services financiers). De tels changements fonctionnels peuvent figurer dans une publication Helm, mais sortent du cadre de cette section. + +Recommandations : + +1. Toute mise à niveau doit être testée et validée dans un environnement préproduction (test ou QA). +2. Consultez toujours les notes de version : car elles peuvent contenir des problèmes connus ou des indications utiles applicables lors d'une montée de version. +3. La commande [migrate:list](https://knexjs.org/#Migrations) permet de lister les changements de données en attente dans les dépôts suivants : + - + - + +### Versions sans rupture de compatibilité + +Les changements non cassants n’exigent aucune action supplémentaire ou particulière (sauf indication contraire dans les notes de version), si ce n'est l’exécution d’une commande de [mise à niveau Helm](https://helm.sh/docs/helm/helm_upgrade) standard. + +Notez les drapeaux (flags) de paramètres optionnels suivants, utiles lors d'une mise à niveau : + +``` + -i, --install si aucune release de ce nom n’existe, exécuter une installation + --reuse-values lors d’une mise à niveau, réutiliser les valeurs de la dernière release et fusionner les surcharges de la ligne de commande via --set et -f. Si « --reset-values » est spécifié, cette option est ignorée + --version string contrainte de version du chart à utiliser (étiquette précise ex. 1.1.1 ou plage valide ex. ^2.0.0). Si omis, la dernière version est utilisée +``` + +Exemple d’utilisation : + +```bash +helm --namespace ${NAMESPACE} ${RELEASE_NAME} upgrade --install mojaloop/mojaloop --reuse-values --version ${RELEASE_VERSION} +``` + +Un retour en arrière est possible avec la commande [Helm rollback](https://helm.sh/docs/helm/helm_rollback/) si besoin. + +### Versions avec rupture de compatibilité + +Plusieurs stratégies existent selon la topologie de déploiement : + +1. Mojaloop installé **sans** dépendances backend (Kafka, MySQL, MongoDB, etc.), celles-ci étant gérées séparément — **option recommandée**, offrant le plus de souplesse lors des mises à niveau, surtout en présence de changements majeurs. + +2. Mojaloop installé **avec** dépendances backend couplées à l’installation Helm. + + > *REMARQUE : Ce mode sera déprécié à partir de Mojaloop v15.0.0 (y compris v15) ; un exemple de déploiement backend reste fourni pour les tests et la QA. Voir la section [5. BREAKING CHANGES](https://github.com/mojaloop/helm/blob/master/.changelog/release-v15.0.0.md#5-breaking-changes) des [notes de version v15.0.0](https://github.com/mojaloop/helm/blob/master/.changelog/release-v15.0.0.md).* + + +#### Mojaloop installé sans dépendances backend + +Topologie préférée : elle offre le plus de souplesse. En séparant les dépendances backend, vous pouvez déployer la version cible de Mojaloop comme **nouveau** déploiement. + +Ce nouveau déploiement peut soit réutiliser les dépendances backend existantes, soit en exiger de nouvelles selon les cas : + +##### 1. La version cible n’introduit pas de changements majeurs sur le stockage de données + +Dans ce cas, on peut adopter une stratégie de type **canary** en pointant le nouveau déploiement vers les dépendances backend existantes. Par défaut, les schémas de données sont mis à niveau via les scripts de `migration` (voir [Central-ledger](https://github.com/mojaloop/central-ledger/tree/master/migrations), [Account-lookup-service](https://github.com/mojaloop/account-lookup-service/tree/master/migrations)). On peut aussi désactiver les migrations (ex. [central-ledger](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml#L147), configuration analogue pour account-lookup-service) et préparer un script SQL manuel (voir [migrate:list](https://knexjs.org/#Migrations) pour la liste des changements en attente). + +Le déploiement Mojaloop actuel ne devrait pas être perturbé. + +Les dépendances backend étant partagées entre l’ancien et le nouveau déploiement, il est possible de router un sous-ensemble d’utilisateurs vers la cible afin de valider avec un impact limité et de permettre un retour rapide vers l’ancien déploiement. + +###### Exemple de déploiement de type canary + +![Stratégie de mise à niveau Helm canary](./assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg) + +1. Adaptez le [values.yaml du chart Mojaloop](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) pour la version cible : + 1. Pointez la configuration backend vers les dépendances backend déjà déployées (partagées). + 2. Si besoin, évitez que les règles Ingress écrasent la configuration du déploiement courant. +2. Déployez la version cible Mojaloop (Bleu). + 1. Surveillez les journaux des conteneurs `run-migration` pour d’éventuelles erreurs : + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=centralledger-service -c run-migration` + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=account-lookup-service-admin -c run-migration` +3. Exécutez des tests de cohérence sur l’environnement **Vert** actuel (vérifiez l'impact des changements sur le stockage de données, et prévoyez un rollback ou une bascule partielle pour les DFSP, etc.). +4. Exécutez des tests de cohérence sur l’environnement cible **Bleu**. +5. Basculez la passerelle API (ou les règles Ingress) du **Vert** actuel vers le **Bleu** cible. + +##### 2. La version cible introduit des changements majeurs sur le stockage de données + +Dans ce scénario (Mojaloop installé sans dépendances backend), on peut utiliser une **mise à niveau Helm sur place** des dépendances backend. +Une fenêtre de maintenance doit être planifiée pour arrêter les transactions « en direct » sur le déploiement courant afin de garantir la cohérence des données et une bascule sûre. Cela provoque une interruption, atténuable en planifiant la fenêtre aux heures les moins chargées. + +Il est **très important** de sauvegarder la base de données au cas où un retour à la version précédente serait nécessaire. + +1. Planifier la fenêtre de maintenance. +2. Sauvegarder les bases de données. +3. Adapter le [values.yaml du chart Mojaloop](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) pour la version cible. +4. Désinstaller les services Mojaloop. +5. Mettre à niveau les dépendances backend avec : +```bash +helm upgrade ${RELEASE_NAME} mojaloop/example-mojaloop-backend --namespace ${NAMESPACE} --version ${RELEASE_VERSION} +``` +6. Installer les services Mojaloop : +```bash +helm install ${RELEASE_NAME} mojaloop/mojaloop --namespace ${NAMESPACE} --version ${RELEASE_VERSION} -f {$VALUES_FILE} +``` +7. Exécuter les tests de cohérence. +8. En cas de retour en arrière (la sauvegarde de la base doit avoir été faite avant la montée de version) : + 1. Utilisez `helm rollback` pour revenir à la version précédente des dépendances backend. + 2. Restaurez la base à partir de la sauvegarde (pour un état cohérent du stockage). + 3. Réinstallez la version précédente des services Mojaloop. + +#### Mojaloop installé avec dépendances backend (version 15 ou antérieure) + +Dans ce scénario, on peut adopter une stratégie **blue-green** : en déployant la version cible Mojaloop séparément (avec l'avantage supplémentaire d'aligner votre déploiement vers la topologie de déploiement recommandée). + +Une **migration manuelle** des données des anciens magasins vers les nouveaux backends cibles sera nécessaire. Il faudra aussi maintenir les magasins ancien et nouveau synchronisés tant que des transactions en direct transitent encore par l’ancien déploiement. Planifiez une fenêtre de maintenance pour arrêter le trafic « live », garantir la cohérence et basculer en toute sécurité — avec interruption possible, à limiter en choisissant une plage horaire creuse. + +##### Exemple de déploiement blue-green + +![Stratégie de mise à niveau Helm blue-green](./assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg) + +1. Adaptez le [values.yaml du chart Mojaloop](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) pour la version cible : + 1. Pointez la configuration backend vers les nouvelles dépendances backend cibles. + 2. Si besoin, évitez que les règles Ingress écrasent la configuration du déploiement courant. +2. Déployez la version cible Mojaloop (Bleu). +3. Mettez en place un processus de migration pour synchroniser et transformer les données du backend **Vert** vers le **Bleu**. +4. Planifiez la fenêtre de bascule. +5. Réalisez la bascule pendant la fenêtre : + 1. Passez les backends **Verts** en lecture seule lorsque c’est possible. + 2. Videz les connexions restantes sur le Vert. + 3. Vérifiez que la migration est entièrement synchronisée de Vert vers Bleu. + 4. Exécutez les tests de cohérence sur l’environnement cible Bleu. + 5. Basculez la passerelle API (ou les règles Ingress) du Vert actuel vers le Bleu cible. + + +## Commandes de mise à niveau + +Ce document fournit des commandes pour mettre à niveau des installations Mojaloop existantes. Il suppose Mojaloop installé via Helm. + +### Mise à niveau vers v17.0.0 + +1. Mettre à niveau les dépendances backend : +```bash +helm upgrade backend mojaloop/example-mojaloop-backend --namespace ${NAMESPACE} --version v17.0.0 -f ${VALUES_FILE} +``` +2. Installez les services Mojaloop : +```bash +helm install moja mojaloop/mojaloop --namespace ${NAMESPACE} --version v17.0.0 -f ${VALUES_FILE} +``` + +#### Tester le scénario de mise à niveau de v16.0.0 vers v17.0.0 + +1. Installez les dépendances backend v16.0.0 avec persistance activée (il faut créer les bases manuellement : les scripts initDb ne s’exécuteront pas) : +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/example-mojaloop-backend --version 16.0.0 -f ${VALUES_FILE} +``` +2. Installez les services Mojaloop v16.0.0 et lancer les tests pour peupler les bases : +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/mojaloop --version 16.0.0 -f ${VALUES_FILE} +``` +3. Désinstallez les services Mojaloop : +```bash +helm delete ${RELEASE} --namespace ${NAMESPACE} +``` +4. Mettre à niveau les dépendances backend vers v17.0.0 (met à niveau les versions MySQL/Kafka/MongoDB) : +```bash +helm --namespace ${NAMESPACE} upgrade ${RELEASE} mojaloop/example-mojaloop-backend --version 17.0.0 -f ${VALUES_FILE} +``` +5. Installez les services Mojaloop v17.0.0 (exécute les migrations Knex pour mettre à jour les schémas) : +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/mojaloop --version 17.0.0 -f ${VALUES_FILE} +``` +6. Lancer les tests Golden Path : +```bash +helm test ${RELEASE} --namespace=${NAMESPACE} --logs +``` + + diff --git a/docs/fr/technical/technical/event-framework/README.md b/docs/fr/technical/technical/event-framework/README.md new file mode 100644 index 000000000..469565ddd --- /dev/null +++ b/docs/fr/technical/technical/event-framework/README.md @@ -0,0 +1,233 @@ +# Infrastructure d’événements (Event Framework) + +L’**infrastructure d’événements** (*Event Framework*) vise à fournir une architecture unifiée et standard pour capturer tous les événements Mojaloop. + +_Avertissement : solution expérimentale mise en œuvre comme preuve de concept (PoC). La conception peut évoluer selon l’avancement de la mise en œuvre du PoC et les enseignements tirés._ + + +## 1. Exigences + +- Les événements seront produits via une bibliothèque commune standard qui publiera vers un composant *sidecar* sur un protocole léger et hautement performant (p. ex. gRPC). +- Le module *sidecar* publie sur un topic Kafka unique, consommable par plusieurs gestionnaires selon les besoins. +- Le partitionnement Kafka repose sur le type d’événement (p. ex. *log*, *audit*, *trace*, *errors*). +- Chaque composant Mojaloop disposera de son propre *sidecar* étroitement couplé. +- Les messages utiliseront le *Trace-Id* comme clé Kafka, afin de garantir que tous les messages d’une même trace (transaction) soient stockés dans la même partition et dans l’ordre. + + +## 2. Architecture + +### 2.1 Vue d’ensemble + +![Architecture du cadre d’événements](./assets/diagrams/architecture/architecture-event-framework.svg) + +### 2.2 *Pods* de microservices + +![Architecture des *pods* microservices](./assets/diagrams/architecture/architecture-event-sidecar.svg) + +### 2.3 Flux d’événements + +![Architecture de traçage des événements](./assets/diagrams/architecture/architecture-event-trace.svg) + + +## 3. Modèle d’enveloppe d’événement + +### 3.1 Exemple JSON + +```JSON +{ + "from": "noresponsepayeefsp", + "to": "payerfsp", + "id": "aa398930-f210-4dcd-8af0-7c769cea1660", + "content": { + "headers": { + "content-type": "application/vnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "noresponsepayeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": "data:application/vnd.interoperability.transfers+json;version=1.0;base64,ewogICJmdWxmaWxtZW50IjogIlVObEo5OGhaVFlfZHN3MGNBcXc0aV9VTjN2NHV0dDdDWkZCNHlmTGJWRkEiLAogICJjb21wbGV0ZWRUaW1lc3RhbXAiOiAiMjAxOS0wNS0yOVQyMzoxODozMi44NTZaIiwKICAidHJhbnNmZXJTdGF0ZSI6ICJDT01NSVRURUQiCn0" + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7-3978-408e-ae2e-a13012c47739", + "parentSpanId": "4e3ce424-d611-417b-a7b3-44ba9bbc5840", + "spanId": "efeb5c22-689b-4d04-ac5a-2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } +} +``` + +### 3.2 Définition du schéma + +### 3.2.1 Définition d’objet : EventMessage + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| id | string | O | Identifiant lié au message associé. | | +| from | string | N | Si absent côté destination, la notification a été générée par le nœud connecté (serveur). | | +| to | string | O | Obligatoire côté émetteur, optionnel côté destination. L’émetteur peut omettre la valeur de domaine. | | +| pp | string | N | Optionnel côté émetteur lorsqu’il représente l’identité de session. Obligatoire côté destination si l’identité de l’émetteur diffère de la propriété `from`. | | +| metadata | object `` | N | L’émetteur devrait éviter d’utiliser cette propriété pour transporter des informations liées au contenu — uniquement des données contextuelles à la communication. Il est conseillé de définir un nouveau type de contenu si davantage d’informations de contenu doivent être incluses dans le message. | | +| type | string | O | Déclaration `MIME` du type de contenu du message. | | +| content | object \ | O | Représentation du contenu. | | + +##### 3.2.1.1 Définition d’objet : MessageMetadata + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| event | object `` | O | Informations d’événement. | | +| trace | object `` | O | Informations de trace. | | + +##### 3.2.1.2 Définition d’objet : EventMetadata + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| id | string | O | UUIDv4 généré pour l’événement. | 3920382d-f78c-4023-adf9-0d7a4a2a3a2f | +| type | enum `` | O | Type d’événement. | [`log`, `audit`, `error` `trace`] | +| action | enum `` | O | Type d’action. | [ `start`, `end` ] | +| createdAt | timestamp | O | Horodatage ISO. | 2019-05-29T23:18:32.935Z | +| responseTo | string | N | UUIDv4 de l’événement parent. | 2019-05-29T23:18:32.935Z | +| state | object `` | O | Objet d’état. | | + +##### 3.2.1.3 Définition d’objet : EventStateMetadata + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| status | enum `` | O | Statut de traitement. | success | +| code | number | N | Code d’erreur selon la spécification Mojaloop. | 2000 | +| description | string | N | Libellé du statut ; souvent utilisé pour les erreurs. | Erreur serveur générique pour ne pas divulguer d’informations sensibles. | + +##### 3.2.1.4 Définition d’objet : EventTraceMetaData + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| service | string | O | Nom du service produisant la trace. | central-ledger-prepare-handler | +| traceId | 32HEXDIGLC | O | Identifiant de transaction de bout en bout. | 664314d5b207d3ba722c6c0fdcd44c61 | +| spanId | 16HEXDIGLC | O | Identifiant de tronçon de traitement pour un composant ou une fonction. | 81fa25e8d66d2e88 | +| parentSpanId | 16HEXDIGLC | N | Identifiant du span parent. | e457b5a2e4d86bd1 | +| sampled | number | N | Indique si le message doit entrer dans la trace (`1`). Sinon, l’échantillonnage est laissé au consommateur. | 1 | +| flags | number | N | Inclusion dans le flux de trace (*Debug* `1` — surcharge la valeur `sampled`). | 0 | +| startTimestamp | datetime | N | ISO 8601 `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. Si absent, horodatage courant. Début du *span*.| 2015-08-29T11:22:09.815479Z | +| finishTimestamp | datetime | N | ISO 8601 au même format. Si absent, horodatage courant. Fin du *span*. | 2015-08-29T11:22:09.815479Z | +| tags | object `` | O | Métadonnées associées à la trace. | success | + +_Note : HEXDIGLC = chiffre / « a » … « f » (hex minuscule). Référence : [spécification W3C *trace-context*](https://www.w3.org/TR/trace-context/#field-value)._ + +##### 3.2.1.5 Définition d’objet : EventTraceMetaDataTags + +| Nom | Type | Obligatoire (O/N) | Description | Exemple | +| --- | --- | --- | --- | --- | +| transactionId | string | N | Identifiant de transaction (transfert, devis, etc.). | 659ee338-c8f8-4c06-8aff-944e6c5cd694 | +| transactionType | string | N | Type représenté par `transactionId` (transfert, devis, etc.). | transfer | +| parentEventType | string | N | Type d’événement du span parent. | bulk-prepare | +| parentEventAction | string | N | Action d’événement du span parent. | prepare | +| tracestate | string | N | Présent si la variable d’environnement EventSDK `EVENT_SDK_TRACESTATE_HEADER_ENABLED` vaut `true` ou si le contexte parent contient l’en-tête ou le tag `tracestate`. Valeur conforme W3C. [Détails](#411-wc3-http-headers). | `congo=t61rcWkgMzE,rojo=00f067aa0ba902b7` | +| `` | string | N | Paire clé-valeur arbitraire pour métadonnées de trace supplémentaires. | n/a | + +##### 3.2.1.6 Enum : EventStatusType + +| Enum | Description | +| --- | --- | +| success | Événement traité avec succès | +| fail | Événement traité avec échec ou erreur | + +##### 3.2.1.7 Enum : EventType + +| Enum | Description | +| --- | --- | +| log | Entrée de journal générale. | +| audit | Événement à signer et persister dans le magasin d’audit. | +| trace | Événement avec contexte de trace pour le magasin de traçage. | + +##### 3.2.1.8 Enum : LogEventAction + +| Enum | Description | +| --- | --- | +| info | Entrée de journal niveau `info`. | +| debug | Entrée de journal niveau `debug`. | +| error | Entrée de journal niveau `error`. | +| verbose | Entrée de journal niveau `verbose`. | +| warning | Entrée de journal niveau `warning`. | +| performance | Entrée de journal niveau `performance`. | + +##### 3.2.1.9 Enum : AuditEventAction + +| Enum | Description | +| --- | --- | +| default | Action d’audit standard. | +| start | Début d’un processus. | +| finish | Fin d’un processus. | +| ingress | Activité d’entrée. | +| egress | Activité de sortie. | + +##### 3.2.1.10 Enum : TraceEventAction + +| Enum | Description | +| --- | --- | +| span | Action représentant un *span* de trace. | + + +## 4. Conception du traçage + +### 4.1 Transports HTTP + +En-têtes HTTP proposés pour le traçage. + +Mojaloop n’a pas encore arbitré entre ces standards ni validé un support combiné. + +#### 4.1.1 En-têtes W3C + +Référence : https://w3c.github.io/trace-context/ + +| En-tête | Description | Exemple | +| --- | --- | --- | +| traceparent | Chaîne délimitée par des tirets : \-\-\-\ | 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00 | +| tracestate | Format fabricant, délimité par des virgules : \=\<état encodé base64\>| congo=t61rcWkgMzE,rojo=00f067aa0ba902b7 | + +Note : certains traceurs historiques envoyaient X-B3-Sampled comme `true`/`false` plutôt que `1`/`0`. Une implémentation tolérante peut les accepter. + +Note : [Event-SDK](https://github.com/mojaloop/event-sdk) depuis v9.4.1 permet d’ajouter des tags clé-valeur dans `tracestate` ; depuis v9.5.2, `tracestate` est encodé en base64. Pour un comportement homogène, aligner les versions du SDK sur tous les services. + +#### 4.1.2 En-têtes B3 + +Référence : https://github.com/apache/incubator-zipkin-b3-propagation + +| En-tête | Description | Exemple | +| --- | --- | --- | +| X-B3-TraceId | 32 ou 16 caractères hex minuscules. | Ex. X-B3-TraceId: 463ac35c9f6413ad48485a3953bb6124. Requis sauf si seul l’état d’échantillonnage est propagé. | +| X-B3-SpanId | 16 caractères hex minuscules. | Ex. X-B3-SpanId: a2fb4a1d1a96d312. Requis sauf propagation de l’échantillonnage seul. | +| X-B3-ParentSpanId | Présent sur un span enfant, absent sur la racine. 16 caractères hex. | Ex. X-B3-ParentSpanId: 0020000000000001 | +| X-B3-Sampled | Acceptation `1`, refus `0`. Absent = décision différée au récepteur. | Ex. X-B3-Sampled: 1 | +| X-B3-Flags | *Debug* = `1` (implique acceptation ; ne pas envoyer aussi X-B3-Sampled). | | + +### 4.2 Transport Kafka + +Voir la section *Modèle d’enveloppe d’événement* : format du message Kafka. + +Le contexte de trace peut aussi être placé dans les en-têtes Kafka (v0.11+), ce qui exclut les versions antérieures. + +### 4.3 Limites connues + +- Le traçage des transferts reste limité à chaque tronçon (*Prepare* / *Fulfil*) : la spécification API Mojaloop ne prend pas en charge les informations de trace. Le *Switch* peut les inclure dans les *callbacks*, mais les FSP ne sont pas tenus de répondre avec des en-têtes de trace réciproques. diff --git a/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg new file mode 100644 index 000000000..413c9746b --- /dev/null +++ b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg @@ -0,0 +1,3 @@ + + +
    Central-Ledger
    (API)
    Central-Ledger<br>(API)<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    (Handler #)
    Central-Ledger<br>(Handler #)<br>

    <div style="text-align: left ; font-size: 8px"><br></div>
    ML-API-Adapter
    (API)
    ML-API-Adapter<br>(API)<br>
    Central-Settlements
    (API)
    Central-Settlements<br>(API)<br>
    ML-API-Adapter
    (Handler)
    ML-API-Adapter<br>(Handler)<br>
    Quoting-Service
    (API)
    Quoting-Service<br>(API)<br>
    Account-Lookup-Service
    (API)
    Account-Lookup-Service<br>(API)<br>

    <div style="text-align: left"><br></div>
    Types de messages :
    - Traçage
    - Audit
    - Journaux
    [Not supported by viewer]
    <div style="text-align: center"></div>
    Kafka
    (flux d'événements)
    topic-events
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    EFK
    (Elasticsearch, Fluentd, 
    Kibana & APM)
    [Not supported by viewer]
    Journalisation judiciaire
    (Évolution — extrait du sidecar vers un service pour audits par lots)
    [Not supported by viewer]
    Central-KMS
    Central-KMS
    Audits
    Audits
    Keys
    Keys
    Partitionné par identifiant de trace (Trace-Id)
    [Not supported by viewer]
    Processeur de flux d'événements
    (médiation, traduction)
    [Not supported by viewer]
    OpenTracing
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    journal, trace, audit
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]
    journal, trace, audit
    [Not supported by viewer]
    Approvisionnement des clés
    [Not supported by viewer]
    Approvisionnement des clés
    [Not supported by viewer]
    Types de messages :
    - Traçage
    - Audit
    - Journaux
    [Not supported by viewer]
    Types de messages :
    - Audits
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg new file mode 100644 index 000000000..3d2660cc7 --- /dev/null +++ b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg @@ -0,0 +1,3 @@ + + +

    <div style="text-align: left"><br></div>
    Pod n°2
    Pod n°2
    Service n°2
    Service n°2<br>
    Pod n°1
    Pod n°1
    <div style="text-align: center"></div>
    Kafka
    (flux d'événements)
    topic-events
    [Not supported by viewer]
    Cluster Kubernetes
    [Not supported by viewer]
    Cadre d'événements
    Sidecar
    Cadre d'événements<br>Sidecar<br>
    Serveur gRPC
    Serveur gRPC
    Client gRPC
    Client gRPC
    Client
    Kafka
    [Not supported by viewer]
    Partitionné par Trace-Id
    [Not supported by viewer]
    Service n°1
    Service n°1<br>
    Cadre d'événements
    Sidecar
    Cadre d'événements<br>Sidecar<br>
    Serveur gRPC
    Serveur gRPC
    Client gRPC
    Client gRPC
    Client
    Kafka
    [Not supported by viewer]
    @mojaloop/
    event-sdk
    @mojaloop/<br>event-sdk
    Sidecar du cadre d'événements fourni dans le chart Helm de chaque composant
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg new file mode 100644 index 000000000..eadf3708a --- /dev/null +++ b/docs/fr/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg @@ -0,0 +1,3 @@ + + +
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Service
    consommateur 
    Service…
    Span parent
    Span parent
    Trace
    Trace
    Début
    Début
    Fin
    Fin
    Span enfant
    Span enfant
    Début
    Début
    Fin
    Fin
    Span enfant
    Span enfant
    Début
    Début
    Fin
    Fin
    Contexte de trace
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tracestate
    Contexte de trace…
    Service
    producteur 
    Service…
    Étiquettes : [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination : payeeFsp, tracestate : mojaloop=f32c19568004ce8b ]
    Étiquettes : [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination : payeeFsp, tracestate : mojaloop=f32c19568004ce...
    Span enfant
    Span enfant
    Début
    Début
    Fin
    Fin
    Transport des messages
    - HTTP
    - Kafka

    Transport des messages…
    Erreur
    Erreur
    Kafka
    (topic d'événements)
    Kafka…
    Sidecar d'événements
    Sidecar d'événements
    Sidecar d'événements
    Sidecar d'événements
    Enregistrer la trace
    Record...
    Service A
    Service A
    Service B
    Service B
    Message de trace
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tags
    - tracestate
    - contenu / erreur
    Trace Message...
    Enregistrer la trace
    Record...
    Enregistrer la trace
    Record...
    Enregistrer la trace
    Record...
    Enregistrer l'erreur
    Record...
    Audit
    Audit
    Enregistrer
    l'audit
    Record...
    Journal
    Journal
    Enregistrer le journal
    Record...
    Enregistrer
    l'audit
    Record...
    Enregistrer
    l'audit
    Record...
    Enregistrer
    l'audit
    Record...
    Enregistrer
    l'audit
    Record...
    \ No newline at end of file diff --git a/docs/fr/technical/technical/event-stream-processor/README.md b/docs/fr/technical/technical/event-stream-processor/README.md new file mode 100644 index 000000000..7890c0fe6 --- /dev/null +++ b/docs/fr/technical/technical/event-stream-processor/README.md @@ -0,0 +1,21 @@ +# Service Event Stream Processor + +L’**Event Stream Processor** consomme les messages d’événements du topic `topic-events` en réponse aux messages publiés par le service [event-sidecar](https://github.com/mojaloop/event-sidecar). Pour plus d’informations sur l’architecture globale, consulter l’[infrastructure d’événements (Event Framework)](../event-framework/README.md). + +Le service achemine les journaux (y compris les audits) et les traces vers la pile EFK avec le plugin APM activé. Selon le type de message d’événement, les messages sont acheminés vers différents index dans Elasticsearch. + +## 1. Prérequis + +Le service enregistre tous les événements dans une instance Elasticsearch avec le plugin APM activé. Un exemple *docker-compose* pour la stack Elastic est disponible [ici](https://github.com/mojaloop/event-stream-processor/blob/master/test/util/scripts/docker-efk/docker-compose.yml). Les journaux et audits utilisent un modèle d’index personnalisé ; les traces vont dans l’index par défaut `apm-*`. + +Veuillez vous assurer d’avoir créé le modèle `mojatemplate` tel que décrit dans la documentation du service [event-stream-processor](https://github.com/mojaloop/event-stream-processor#111-create-template). + +## 2. Vue d’ensemble de l’architecture + +### 2.1. Vue d’ensemble du flux + +![Vue d’ensemble du flux Event Stream Processor](./assets/diagrams/architecture/event-stream-processor-overview.svg) + +### 2.2 Diagramme de séquence du traitement des traces + +![](./assets/diagrams/sequence/process-flow.svg) diff --git a/mojaloop-technical-overview/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg b/docs/fr/technical/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg similarity index 100% rename from mojaloop-technical-overview/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg rename to docs/fr/technical/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg diff --git a/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml b/docs/fr/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml similarity index 100% rename from mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml rename to docs/fr/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml diff --git a/docs/fr/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg b/docs/fr/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg new file mode 100644 index 000000000..a85cf2bb6 --- /dev/null +++ b/docs/fr/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg @@ -0,0 +1,577 @@ + + Event Streaming Processor flow + + + Event Streaming Processor flow + + Central Services + + Event Stream Processor + + Cache + + Elasticsearch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Notification topic + + + Notification topic + Topic Observable + + + Topic Observable + + + Tracing Observable + + + Tracing Observable + + + Caching Observable + + + Caching Observable + + + Check For Last Span Observable + + + Check For Last Span Observable + + + Create Trace Observable + + + Create Trace Observable + + + Send Trace Handler + + + Send Trace Handler + + + Send Span Handler + + + Send Span Handler + + + Cache Handler + + + Cache Handler + + + Cache Storage + + + Cache Storage + + + APM + + + APM + + + Elasticsearch API + + + Elasticsearch API + + + + + + + + + + + + New Event Message Received + + + 1 + Consume Event Message + + + Message: + { + "from": "payeefsp", + "to": "payerfsp", + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "content": { + "headers": { + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "payeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": <payload> + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": "44ba9bbc5840", + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } + } + + + 2 + Send message for log purposes to custom index + + + + + 3 + Verify its tracing event Message + + + 4 + Send Message to Tracing Observable + + + Cache Span + + + 5 + Send Span Context, + metadata.State and Content + from Message + + + { + spanContext: { + service: "central-ledger-prepare-handler", + traceId: "bbd7b2c7bbd7b2c7", + parentSpanId: "44ba9bbc5840", + spanId: "2aa9cd0a7e87", + startTimestamp: "2015-08-29T11:22:09.815479Z", + finishTimestamp: "2015-08-29T11:22:09.815479Z", + tags: { + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + transctionType: "transfer", + parentEventType: "bulk-prepare", + parentEventAction: "prepare" + }, + state: metadata.state, + content + } + + + 6 + Get cachedTrace by traceId + + + alt + [the span should not be cached] + + + 7 + currentSpan + + + 8 + store to APM + + + + + 9 + Complete + + + + + + + 10 + Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + + + alt + [!cachedTrace] + + + + + 11 + Create new cachedTrace + + + { + spans: {}, + masterSpan: null, + lastSpan: null + } + + + alt + [!parentSpan] + + + + + + 12 + Generate MasterSpanId + + + + + + 13 + Make received span child of masterSpan + merge({ parentSpanId: MasterSpanId }, { ...spanContext }) + + + + + + 14 + Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, + { ...spanContext }, + { spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + + + + + + 15 + Add masterSpan to cachedTrace + + + + 16 + Add span to cachedTrace + + + { + spans: { + 2aa9cd0a7e87: { + state, + content + spanContext: { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": + MasterSpanId + , + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + }, +    + MasterSpanId: + { + state, + content, + MasterSpanContext + } + }, + masterSpan: + MasterSpanContext + , + lastSpan: null + } + + + 17 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 18 + unsubscribe from Scheduler + + + 19 + record cachedTrace + + + + + + 20 + Reschedule scheduler for handling stale traces + + + 21 + Send traceId to check if last span has been received + and cached + + + Check for last span + + + 22 + Get cachedTrace by traceId + + + + + 23 + Sort spans by startTimestamp + + + loop + [for currentSpan of SortedSpans] + + + alt + [parentSpan] + + + + + 24 + isError = (errorCode in parentSpan + OR parentSpan status === failed + OR status === failed) + + + + + 25 + apply masterSpan and error tags from parent to current span in cachedTrace + + + alt + [!isLastSpan] + + + 26 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 27 + unsubscribe from Scheduler + + + 28 + record cachedTrace + + + + + + 29 + Reschedule scheduler for handling stale traces + + + + + + 30 + Validate transactionType, TransactionAction, service and isError + to match Config.START_CRITERIA && !parentSpandId + + + + + 31 + cachedTrace.lastSpan = currentSpan.spanContext + + + 32 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 33 + unsubscribe from Scheduler + + + 34 + record cachedTrace + + + + + + 35 + Reschedule scheduler for handling stale traces + + + 36 + Send traceId + + + Recreate Trace from Cached Trace + + + 37 + get cachedTrace by TraceId + + + alt + [cachedTrace.lastSpan AND cachedTrace.masterSpan] + + + + + 38 + currentSpan = lastSpan + + + + + 39 + resultTrace = [lastSpan] + + + loop + [for i = 0; i < cachedTrace.spans.length; i++] + + + + + 40 + get parentSpan of currentSpan + + + alt + [parentSpan] + + + + + 41 + insert parent span in resultTrace in front + + + + + + 42 + break loop + + + alt + [cachedTrace.masterSpan === currentSpan.spanId] + + + + + 43 + masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + + + 44 + send resultTrace + + + send Trace + + + loop + [trace elements] + + + 45 + send each span + + + 46 + send span to APM + + + + + 47 + unsubscribe scheduler for traceId + + + 48 + drop cachedTrace + + diff --git a/docs/fr/technical/technical/fraud-services/README.md b/docs/fr/technical/technical/fraud-services/README.md new file mode 100644 index 000000000..e286cf1ad --- /dev/null +++ b/docs/fr/technical/technical/fraud-services/README.md @@ -0,0 +1,5 @@ +# Services anti-fraude + +Présentation des mesures de surveillance et de prévention envisagées pour limiter et décourager les activités frauduleuses au sein d’un schéma Mojaloop. + +Les artefacts pertinents mis à disposition du public sont regroupés dans la section [documents associés](./related-documents/documentation.md). diff --git a/docs/fr/technical/technical/fraud-services/related-documents/documentation.md b/docs/fr/technical/technical/fraud-services/related-documents/documentation.md new file mode 100644 index 000000000..eea9c8f0e --- /dev/null +++ b/docs/fr/technical/technical/fraud-services/related-documents/documentation.md @@ -0,0 +1,7 @@ +# Services anti-fraude + +Artefacts de référence publique liés aux mesures de prévention et de limitation de la fraude au sein de l’écosystème. + +## Liste des artefacts actuels + +#### [Document de synthèse fraude — écosystème Mojaloop](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/April%202019%20PI-6_OSS_community%20session/Mojaloop-Fraud-20190410.pdf) diff --git a/docs/fr/technical/technical/ml-testing-toolkit/README.md b/docs/fr/technical/technical/ml-testing-toolkit/README.md new file mode 100644 index 000000000..f69129c1b --- /dev/null +++ b/docs/fr/technical/technical/ml-testing-toolkit/README.md @@ -0,0 +1,14 @@ +# Mojaloop Testing Toolkit + +Le **Mojaloop Testing Toolkit** a été conçu pour aider les schémas Mojaloop à monter en charge en simplifiant l’intégration des DFSP. Les schémas peuvent y publier des règles et des tests ; les DFSP s’en servent pour l’auto-test (voire l’auto-certification). Cela garantit que les DFSP sont pleinement prêts à se connecter au schéma et permet un embarquement rapide et fluide pour les Hubs Mojaloop, augmentant ainsi leur capacité à monter en charge. + +L’outil visait d’abord les FSP / participants rejoignant un schéma Mojaloop. Aujourd’hui, cet ensemble d’outils peut potentiellement être utilisé par les DFSP et les **Hubs Mojaloop** pour vérifier l’intégration entre ces deux entités. Conçu délibérément comme outil de test d’intégration standard entre un **fournisseur de services financiers numériques (DFSP)** et le **switch Mojaloop** (Hub), il facilite les tests. + +Pour le contexte du *Self Testing Toolkit*, voir [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md). Il est recommandé de consulter le [diagramme d’architecture](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md#7-architecture), qui présente les différents composants et leurs flux associés. + +## Guides d’utilisation + +* Interface web : [guide d’utilisation](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide.md) +* Ligne de commande : [guide CLI](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide-CLI.md) + +**Si vous avez votre propre implémentation DFSP, vous pouvez pointer le *peer endpoint* vers le Mojaloop Testing Toolkit sur le port 5000 et tenter d’envoyer les requêtes depuis votre implémentation au lieu d’utiliser *mojaloop-simulator*.** diff --git a/docs/fr/technical/technical/overview/README.md b/docs/fr/technical/technical/overview/README.md new file mode 100644 index 000000000..8d2ba821d --- /dev/null +++ b/docs/fr/technical/technical/overview/README.md @@ -0,0 +1,24 @@ +# Hub Mojaloop + +Plusieurs composants constituent l’écosystème Mojaloop. Le Hub Mojaloop est le conteneur principal et la référence que nous utilisons pour décrire les composants centraux de Mojaloop. + +Le diagramme de composants suivant illustre la décomposition des services Mojaloop et leur architecture en microservices : + +![Vue d’ensemble actuelle de l’architecture Mojaloop](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg) + +_Note : la gradation de couleur indique la relation entre le stockage de données, la messagerie en flux et les interconnexions d'adaptateurs.. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ + +Ils se composent de : + +* Les **adaptateurs d’API Mojaloop** (**ML-API-Adapter**) fournissent l’ensemble standard d’interfaces qu’un DFSP peut mettre en œuvre pour se connecter au système pour les transferts. Un DFSP qui souhaite se raccorder peut s’appuyer sur notre code d’exemple ou implémenter les interfaces standard dans son propre logiciel. L’objectif est de rendre la connexion au réseau interopérable aussi directe et accessible que possible pour un DFSP. +* Les **Central Services** (**CS**) fournissent l'ensemble des composants nécessaires pour transférer des fonds d'un DFSP à un autre via les adaptateurs d'API Mojaloop. C’est analogue à la façon dont les fonds transitent par une banque centrale ou une chambre de compensation dans les pays développés. Les Central Services contiennent la logique centrale du registre (Central Ledger) pour déplacer les fonds, et seront également étendus pour assurer la gestion de la fraude et l'application des règles du schéma. +* Le **Account Lookup Service** (**ALS**) fournit un mécanisme permettant de résoudre les informations de routage des FSP via l'API Participant ou d'orchestrer une requête Party à partir d'une recherche interne de Participant. La recherche interne de Participant est assurée par plusieurs adaptateurs ou services Oracle standard. Un exemple d’adaptateur ou de service Oracle consiste à rechercher les informations de Participant dans Pathfinder ou un registre marchand. Ces adaptateurs ou services Oracle peuvent être ajoutés facilement selon les exigences du schéma. +* Le **Quoting Service** (**QA**) : le devis est le processus qui détermine les éventuels frais et commissions nécessaires pour réaliser une opération financière entre deux FSP. Il est toujours initié par le FSP payeur vers le FSP bénéficiaire ; le flux du devis suit donc le même sens qu’une opération financière. +* Le **simulateur** (**SIM**) émule plusieurs fonctions DFSP comme suit : + * des endpoints Oracle pour les opérations CRUD sur les Participants Oracle avec cache en mémoire ; + * des endpoints Participant pour les Oracles avec prise en charge des `partyIdTypes` paramétrables ; + * des endpoints Parties pour les FSP payeur et bénéficiaire avec réponses de rappel associées ; + * des endpoints de transfert pour les FSP payeur et bénéficiaire avec réponses de rappel associées ; et + * des API d’interrogation pour vérifier les transactions (requêtes, réponses, rappels, etc.) afin de soutenir les tests et la vérification (assurance qualité). + +De part et d’autre du Hub Mojaloop, du code open source d’exemple illustre comment un DFSP peut envoyer et recevoir des paiements, ainsi que le client qu’un DFSP existant pourrait héberger pour se connecter au réseau. diff --git a/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg new file mode 100644 index 000000000..df9396cae --- /dev/null +++ b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg new file mode 100644 index 000000000..763c5697e --- /dev/null +++ b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Settlement Windows)
    Central-Settlements...
    Central-Settlements
    (Handler - Transfer Settlements)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    diff --git a/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg new file mode 100644 index 000000000..06680fbae --- /dev/null +++ b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg new file mode 100644 index 000000000..6e753c75d --- /dev/null +++ b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg @@ -0,0 +1,4 @@ + + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Infra management
    (IaC, Miniloop)
    Infra management...
    Mojaloop API Adapter
    (FSPIOP API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (FSPIOP API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (Functional
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Accelerators
    Software Accelerators
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (micro-frontends)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (3PPI - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (3PPI Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Business Operations Framework for 
    (Reporting
    )
    (Operations)
    (Monitoring)
    (self-service portals)
    Business Operations Frame...
    IAM, RBAC
    (Administration APIs; Ory - Keto, Kratos, Oathkeeper)
    IAM, RBAC...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg similarity index 100% rename from mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg rename to docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg diff --git a/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg similarity index 100% rename from mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg rename to docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg diff --git a/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg similarity index 100% rename from mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg rename to docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg diff --git a/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg similarity index 100% rename from mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg rename to docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg diff --git a/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg b/docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg similarity index 100% rename from mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg rename to docs/fr/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg diff --git a/docs/fr/technical/technical/overview/components-PI11.md b/docs/fr/technical/technical/overview/components-PI11.md new file mode 100644 index 000000000..36631f461 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI11.md @@ -0,0 +1,7 @@ +# Composants actuels du Hub Mojaloop — PI11 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI11 : + +![Vue d’ensemble de l’architecture Mojaloop PI11](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI12.md b/docs/fr/technical/technical/overview/components-PI12.md new file mode 100644 index 000000000..6b7c4c7b6 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI12.md @@ -0,0 +1,7 @@ +# Composants actuels du Hub Mojaloop — PI12 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI12 : + +![Vue d’ensemble de l’architecture Mojaloop PI12](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI14.md b/docs/fr/technical/technical/overview/components-PI14.md new file mode 100644 index 000000000..65c360580 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI14.md @@ -0,0 +1,7 @@ +# Composants actuels du Hub Mojaloop — PI14 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI14 : + +![Vue d’ensemble de l’architecture Mojaloop PI14](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI18.md b/docs/fr/technical/technical/overview/components-PI18.md new file mode 100644 index 000000000..2994a62b7 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI18.md @@ -0,0 +1,7 @@ +# Composants actuels du Hub Mojaloop — PI18 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI18 : + +![Vue d’ensemble de l’architecture Mojaloop PI18](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI3.md b/docs/fr/technical/technical/overview/components-PI3.md new file mode 100644 index 000000000..d9e31aa4d --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI3.md @@ -0,0 +1,12 @@ +--- +sidebarTitle: Vue d'ensemble PI3 +title: Vue d'ensemble PI3 +--- + +# Composants hérités du Hub Mojaloop — PI3 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI3 : + +![Vue d’ensemble de l’architecture Mojaloop PI3](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI5.md b/docs/fr/technical/technical/overview/components-PI5.md new file mode 100644 index 000000000..8153d99b0 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI5.md @@ -0,0 +1,7 @@ +# Composants hérités du Hub Mojaloop — PI5 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI5 : + +![Vue d’ensemble de l’architecture Mojaloop PI5](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI6.md b/docs/fr/technical/technical/overview/components-PI6.md new file mode 100644 index 000000000..b26d72117 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI6.md @@ -0,0 +1,7 @@ +# Composants hérités du Hub Mojaloop — PI6 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI6 : + +![Vue d’ensemble de l’architecture Mojaloop PI6](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI7.md b/docs/fr/technical/technical/overview/components-PI7.md new file mode 100644 index 000000000..406de5983 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI7.md @@ -0,0 +1,7 @@ +# Composants hérités du Hub Mojaloop — PI7 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI7 : + +![Vue d’ensemble de l’architecture Mojaloop PI7](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/overview/components-PI8.md b/docs/fr/technical/technical/overview/components-PI8.md new file mode 100644 index 000000000..8cde7bc06 --- /dev/null +++ b/docs/fr/technical/technical/overview/components-PI8.md @@ -0,0 +1,7 @@ +# Composants hérités du Hub Mojaloop — PI8 + +Le schéma de composants suivant présente la décomposition des services Mojaloop et leur architecture microservices pour PI8 : + +![Vue d’ensemble de l’architecture Mojaloop PI8](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) + +_Note : le code couleur indique les relations entre le stockage de données, la messagerie en flux et les interconnexions d’adaptateurs. Par exemple, les `Central-Services` utilisent `MySQL` comme base de données et s’appuient sur `Kafka` pour la messagerie._ diff --git a/docs/fr/technical/technical/quoting-service/README.md b/docs/fr/technical/technical/quoting-service/README.md new file mode 100644 index 000000000..6b1d17fba --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/README.md @@ -0,0 +1,25 @@ +--- +version: 1.1 +sidebarTitle: Service de devis +title: Service de devis +--- + +# Vue d’ensemble du service de devis + +Le **Quoting Service** (**QS**) — *(voir la section `5.1`) conformément à la [spécification Mojaloop {{ $page.frontmatter.version }}](/api)* — met en œuvre la phase de devis des différents cas d’usage. + +_Note : outre les devis individuelles, le service de devis prend aussi en charge les devis groupés (*bulk quotes*)._ + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-quotes-1.0.0.svg) + +## Devis individuelles + +- [GET — Devis par ID](qs-get-quotes.md) +- [POST — Devis](qs-post-quotes.md) + +## Devis groupées (*bulk*) + +- [GET — Devis par ID](qs-get-bulk-quotes.md) +- [POST — Devis](qs-post-bulk-quotes.md) diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml new file mode 100644 index 000000000..94f64d19c --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Obtenir les informations d’une devis groupé +participant "FSP payeur" as PayerFSP +participant "Switch\n[Service de devis]" as Switch +participant "FSP bénéficiaire" as PayeeFSP + +autonumber +note right of PayerFSP: Le FSP payeur demande le détail d’une devis groupé\nau FSP bénéficiaire via le Switch +PayerFSP -\ Switch: GET /bulkQuotes/{ID} +note right of Switch #aaa + Valider la requête selon la + spécification d’interface Mojaloop + **Codes d’erreur : 300x, 310x** + **Codes HTTP d’erreur : 4xx** +end note +Switch -> Switch: Validation de schéma +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Récupérer l'endpoint « bulk quotes » du FSP bénéficiaire +alt endpoint « bulk quotes » du FSP bénéficiaire trouvé + note right of Switch: Le Switch transmet la requête au FSP bénéficiaire (mode pass-through) + Switch -\ PayeeFSP: GET /bulkQuotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Le FSP bénéficiaire récupère le devis groupé + alt le FSP bénéficiaire récupère le devis avec succès + note left of PayeeFSP: Le FSP bénéficiaire répond à la demande de devis + PayeeFSP -\ Switch: PUT /quotes/{ID} + note right of Switch #aaa + Valider la requête selon la + spécification d’interface Mojaloop + **Codes d’erreur : 300x, 310x** + **Codes HTTP d’erreur : 4xx** + end note + Switch --/ PayeeFSP: 200 Ok + alt réponse valide + Switch -> Switch: Récupérer l'endpoint « bulk quotes » du FSP payeur + alt endpoint de callback « bulk quotes » trouvé + note left of Switch: Le Switch transmet la réponse de devis groupé au FSP payeur + Switch -\ PayerFSP: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 Ok + else endpoint de callback « bulk quotes » introuvable + note right of Switch: Le Switch renvoie une erreur au FSP bénéficiaire + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else réponse invalide + note right of Switch: Le Switch renvoie une erreur au FSP bénéficiaire + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Dans ce scénario, le FSP payeur\npeut ne pas recevoir de réponse + end + + else bulkQuote introuvable + note left of PayeeFSP: Le FSP bénéficiaire renvoie une erreur au Switch\n **Code d’erreur : 3205** + PayeeFSP -\ Switch: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Le Switch renvoie une erreur au FSP payeur\n **Code d’erreur : 3205** + Switch -\ PayerFSP: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else endpoint « bulk quotes » du FSP bénéficiaire introuvable + note left of Switch + Le Switch renvoie une erreur au FSP payeur + **Code d’erreur : 3201** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg new file mode 100644 index 000000000..06c6f503f --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg @@ -0,0 +1,197 @@ + + Obtenir les informations d’une devis groupé + + + Obtenir les informations d’une devis groupé + + + + + + + + + FSP payeur + + FSP payeur + + Switch + [Service de devis] + + Switch + [Service de devis] + + FSP bénéficiaire + + FSP bénéficiaire + + + Le FSP payeur demande le détail d’une devis groupé + au FSP bénéficiaire via le Switch + + + 1 + GET /bulkQuotes/{ID} + + + Valider la requête selon la + spécification d’interface Mojaloop + Codes d’erreur : 300x, 310x + Codes HTTP d’erreur : 4xx + + + + + 2 + Validation de schéma + + + 3 + 202 Accepted + + + + + 4 + Récupérer l'endpoint « bulk quotes » du FSP bénéficiaire + + + alt + [endpoint « bulk quotes » du FSP bénéficiaire trouvé] + + + Le Switch transmet la requête au FSP bénéficiaire (mode pass-through) + + + 5 + GET /bulkQuotes/{ID} + + + 6 + 202 Accepted + + + + + 7 + Le FSP bénéficiaire récupère le devis groupé + + + alt + [le FSP bénéficiaire récupère le devis avec succès] + + + Le FSP bénéficiaire répond à la demande de devis + + + 8 + PUT /quotes/{ID} + + + Valider la requête selon la + spécification d’interface Mojaloop + Codes d’erreur : 300x, 310x + Codes HTTP d’erreur : 4xx + + + 9 + 200 Ok + + + alt + [réponse valide] + + + + + 10 + Récupérer l'endpoint « bulk quotes » du FSP payeur + + + alt + [endpoint de callback « bulk quotes » trouvé] + + + Le Switch transmet la réponse de devis groupé au FSP payeur + + + 11 + PUT /bulkQuotes/{ID} + + + 12 + 200 Ok + + [endpoint de callback « bulk quotes » introuvable] + + + Le Switch renvoie une erreur au FSP bénéficiaire + + + 13 + PUT /bulkQuotes/{ID}/error + + + 14 + 200 Ok + + [réponse invalide] + + + Le Switch renvoie une erreur au FSP bénéficiaire + + + 15 + PUT /bulkQuotes/{ID}/error + + + 16 + 200 Ok + + + Dans ce scénario, le FSP payeur + peut ne pas recevoir de réponse + + [bulkQuote introuvable] + + + Le FSP bénéficiaire renvoie une erreur au Switch +   + Code d’erreur : 3205 + + + 17 + PUT /bulkQuotes/{ID}/error + + + 18 + 200 OK + + + Le Switch renvoie une erreur au FSP payeur +   + Code d’erreur : 3205 + + + 19 + PUT /bulkQuotes/{ID}/error + + + 20 + 200 OK + + [endpoint « bulk quotes » du FSP bénéficiaire introuvable] + + + Le Switch renvoie une erreur au FSP payeur + Code d’erreur : 3201 + + + 21 + PUT /bulkQuotes/{ID}/error + + + 22 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml new file mode 100644 index 000000000..59ff8aec0 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml @@ -0,0 +1,86 @@ +@startuml +Title Obtenir les informations d’une devis +participant "FSP payeur" as PayerFSP +participant "Switch\n[Service de\ndevis]" as Switch +database "Référentiel central" as DB +participant "FSP bénéficiaire" as PayeeFSP +autonumber +note right of PayerFSP: Le FSP payeur demande le détail d’une devis\nau FSP bénéficiaire via le Switch +PayerFSP -\ Switch: GET /quotes/{ID} +note right of Switch #aaa + Valider la requête selon la + spécification d’interface Mojaloop + **Codes d’erreur : 300x, 310x** + **Codes HTTP d’erreur : 4xx** +end note +Switch -> Switch: Validation de schéma +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Récupérer le l'endpoint « quotes » du FSP bénéficiaire +alt l'endpoint « quotes » du FSP bénéficiaire trouvé + note right of Switch: Le Switch transmet la requête au FSP bénéficiaire (mode pass-through)\n + Switch -\ PayeeFSP: GET /quotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Le FSP bénéficiaire récupère le devis + alt le FSP bénéficiaire récupère le devis avec succès + note left of PayeeFSP: Le FSP bénéficiaire répond à la demande de devis + PayeeFSP -\ Switch: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 Ok + Switch -> Switch: Valider la réponse (schéma, en-têtes (**Code d’erreur : 3100**)) + alt réponse valide + alt SimpleRoutingMode est FALSE + Switch -> Switch: Valider la réponse (contrôle de doublon, scénario renvoi (**Code d’erreur : 3106**)) + alt validation réussie + Switch -\ DB: Persister la réponse de devis + activate DB + hnote over DB + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + end hnote + Switch \-- DB: Réponse de devis enregistrée + deactivate DB + end + end + alt SimpleRoutingMode est TRUE + Switch -> Switch: Récupérer l'endpoint « quotes » du FSP payeur + else SimpleRoutingMode est FALSE + Switch -> Switch: Récupérer l'endpoint « quote party » (PAYER) + end + alt endpoint de callback « quotes » trouvé + note left of Switch: Le Switch transmet la réponse au FSP payeur\n + Switch -\ PayerFSP: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 Ok + else endpoint de callback « quotes » introuvable + note right of Switch: Le Switch renvoie une erreur au FSP bénéficiaire + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else réponse invalide + note right of Switch: Le Switch renvoie une erreur au FSP bénéficiaire + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Dans ce scénario, le FSP payeur\npeut ne pas recevoir de réponse + end + + else devis introuvable + note left of PayeeFSP: Le FSP bénéficiaire renvoie une erreur au Switch\n **Code d’erreur : 3205** + PayeeFSP -\ Switch: PUT /quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode est FALSE + Switch -> Switch: Persister les données d’erreur + end + note left of Switch: Le Switch renvoie une erreur au FSP payeur\n **Code d’erreur : 3205** + Switch -\ PayerFSP: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else endpoint « quotes » du FSP bénéficiaire introuvable + note left of Switch + Le Switch renvoie une erreur au FSP payeur + **Code d’erreur : 3201** + end note + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg new file mode 100644 index 000000000..c0f0d590f --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg @@ -0,0 +1,268 @@ + + Obtenir les informations d’une devis + + + Obtenir les informations d’une devis + + + + + + + + + + + + + + + FSP payeur + + FSP payeur + + Switch + [Service de + devis] + + Switch + [Service de + devis] + Référentiel central + + + Référentiel central + + + + FSP bénéficiaire + + FSP bénéficiaire + + + + Le FSP payeur demande le détail d’une devis + au FSP bénéficiaire via le Switch + + + 1 + GET /quotes/{ID} + + + Valider la requête selon la + spécification d’interface Mojaloop + Codes d’erreur : 300x, 310x + Codes HTTP d’erreur : 4xx + + + + + 2 + Validation de schéma + + + 3 + 202 Accepted + + + + + 4 + Récupérer le l'endpoint « quotes » du FSP bénéficiaire + + + alt + [l'endpoint « quotes » du FSP bénéficiaire trouvé] + + + Le Switch transmet la requête au FSP bénéficiaire (mode pass-through) + <Règles côté payeur> + + + 5 + GET /quotes/{ID} + + + 6 + 202 Accepted + + + + + 7 + Le FSP bénéficiaire récupère le devis + + + alt + [le FSP bénéficiaire récupère le devis avec succès] + + + Le FSP bénéficiaire répond à la demande de devis + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Valider la réponse (schéma, en-têtes ( + Code d’erreur : 3100 + )) + + + alt + [réponse valide] + + + alt + [SimpleRoutingMode est FALSE] + + + + + 11 + Valider la réponse (contrôle de doublon, scénario renvoi ( + Code d’erreur : 3106 + )) + + + alt + [validation réussie] + + + 12 + Persister la réponse de devis + + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + + + 13 + Réponse de devis enregistrée + + + alt + [SimpleRoutingMode est TRUE] + + + + + 14 + Récupérer l'endpoint « quotes » du FSP payeur + + [SimpleRoutingMode est FALSE] + + + + + 15 + Récupérer l'endpoint « quote party » (PAYER) + + + alt + [endpoint de callback « quotes » trouvé] + + + Le Switch transmet la réponse au FSP payeur + <Règle bénéficiaire — requête complète> + + + 16 + PUT /quotes/{ID} + + + 17 + 200 Ok + + [endpoint de callback « quotes » introuvable] + + + Le Switch renvoie une erreur au FSP bénéficiaire + + + 18 + PUT /quotes/{ID}/error + + + 19 + 200 Ok + + [réponse invalide] + + + Le Switch renvoie une erreur au FSP bénéficiaire + + + 20 + PUT /quotes/{ID}/error + + + 21 + 200 Ok + + + Dans ce scénario, le FSP payeur + peut ne pas recevoir de réponse + + [devis introuvable] + + + Le FSP bénéficiaire renvoie une erreur au Switch +   + Code d’erreur : 3205 + + + 22 + PUT /quotes/{ID}/error + + + 23 + 200 OK + + + alt + [SimpleRoutingMode est FALSE] + + + + + 24 + Persister les données d’erreur + + + Le Switch renvoie une erreur au FSP payeur +   + Code d’erreur : 3205 + + + 25 + PUT /quotes/{ID}/error + + + 26 + 200 OK + + [endpoint « quotes » du FSP bénéficiaire introuvable] + + + Le Switch renvoie une erreur au FSP payeur + Code d’erreur : 3201 + + + 27 + PUT /quotes/{ID}/error + + + 28 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml new file mode 100644 index 000000000..6103ceed4 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml @@ -0,0 +1,99 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Demander la création d’une devis groupé +participant "FSP payeur" as PayerFSP +participant "Switch\n[Service de devis]" as Switch +participant "FSP bénéficiaire" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Le FSP payeur envoie une demande de devis groupé\nau FSP bénéficiaire via le Switch +PayerFSP -\ Switch: POST /bulkQuotes +note right of Switch #aaa + Valider la requête selon la + spécification d’interface Mojaloop + **Codes d’erreur : 300x, 310x** + **Codes HTTP d’erreur : 4xx** +end note +Switch -> Switch: Validation de schéma +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Validation de la demande de devis groupé (moteur de règles, etc.) +||| +Switch -> Switch: Contrôle de doublon +||| +alt la requête est un doublon mais pas un renvoi +||| + note left of Switch + Le Switch renvoie une erreur au FSP payeur + **Code d’erreur : 3106** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK +||| +else la requête est un doublon et un renvoi + Switch -> Switch: Le Switch gère le scénario de renvoi +end +||| +Switch -> Switch: Utiliser l'en-tête fspiop-destination pour obtenir\nl'endpoint « bulk quotes » du DFSP bénéficiaire +alt endpoint « bulk quotes » du bénéficiaire trouvé + note right of Switch: Le Switch transmet la demande de devis groupé au FSP bénéficiaire + Switch -\ PayeeFSP: POST /bulkQuotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Le FSP bénéficiaire calcule les devis individuelles\net répond avec un résultat de devis groupé + alt traitement bulkQuotes réussi côté bénéficiaire + note over PayeeFSP, Switch: Le FSP bénéficiaire envoie la réponse au FSP payeur via le Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Valider la réponse de devis groupé + Switch -> Switch: Contrôle de doublon + alt la réponse est un doublon mais pas un renvoi + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt la réponse est un doublon et un renvoi + Switch -> Switch: Le Switch gère le scénario de renvoi + end + + note left of Switch: Le Switch transmet la réponse au FSP payeur + PayerFSP /- Switch: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 OK + else le bénéficiaire rejette le devis groupé ou rencontre une erreur + note left of PayeeFSP: Le FSP bénéficiaire envoie un callback d’erreur au FSP payeur via le Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Le Switch transmet le callback d’erreur au FSP payeur + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else endpoint « quotes » du FSP bénéficiaire introuvable + note left of Switch: Le Switch envoie un callback d'erreur au FSP payeur \n **Code d'erreur : 3201** + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg new file mode 100644 index 000000000..754ebe3f7 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg @@ -0,0 +1,217 @@ + + Demander la création d’une devis groupé + + + Demander la création d’une devis groupé + + + + + + + + + + FSP payeur + + FSP payeur + + Switch + [Service de devis] + + Switch + [Service de devis] + + FSP bénéficiaire + + FSP bénéficiaire + + + Le FSP payeur envoie une demande de devis groupé + au FSP bénéficiaire via le Switch + + + 1 + POST /bulkQuotes + + + Valider la requête selon la + spécification d’interface Mojaloop + Codes d’erreur : 300x, 310x + Codes HTTP d’erreur : 4xx + + + + + 2 + Validation de schéma + + + 3 + 202 Accepted + + + + + 4 + Validation de la demande de devis groupé (moteur de règles, etc.) + + + + + 5 + Contrôle de doublon + + + alt + [la requête est un doublon mais pas un renvoi] + + + Le Switch renvoie une erreur au FSP payeur + Code d’erreur : 3106 + + + 6 + PUT /bulkQuotes/{ID}/error + + + 7 + 200 OK + + [la requête est un doublon et un renvoi] + + + + + 8 + Le Switch gère le scénario de renvoi + + + + + 9 + Utiliser l'en-tête fspiop-destination pour obtenir + l'endpoint « bulk quotes » du DFSP bénéficiaire + + + alt + [endpoint « bulk quotes » du bénéficiaire trouvé] + + + Le Switch transmet la demande de devis groupé au FSP bénéficiaire + + + 10 + POST /bulkQuotes + + + 11 + 202 OK + + + + + 12 + Le FSP bénéficiaire calcule les devis individuelles + et répond avec un résultat de devis groupé + + + alt + [traitement bulkQuotes réussi côté bénéficiaire] + + + Le FSP bénéficiaire envoie la réponse au FSP payeur via le Switch + + + 13 + PUT /bulkQuotes/{ID} + + + 14 + 200 OK + + + + + 15 + Valider la réponse de devis groupé + + + + + 16 + Contrôle de doublon + + + alt + [la réponse est un doublon mais pas un renvoi] + + + 17 + PUT /bulkQuotes/{ID}/error + + + 18 + 200 OK + + + alt + [la réponse est un doublon et un renvoi] + + + + + 19 + Le Switch gère le scénario de renvoi + + + Le Switch transmet la réponse au FSP payeur + + + 20 + PUT /bulkQuotes/{ID} + + + 21 + 200 OK + + [le bénéficiaire rejette le devis groupé ou rencontre une erreur] + + + Le FSP bénéficiaire envoie un callback d’erreur au FSP payeur via le Switch + + + 22 + PUT /bulkQuotes/{ID}/error + + + 23 + 200 OK + + + Le Switch transmet le callback d’erreur au FSP payeur + + + 24 + PUT /bulkQuotes/{ID}/error + + + 25 + 200 OK + + [endpoint « quotes » du FSP bénéficiaire introuvable] + + + Le Switch envoie un callback d'erreur au FSP payeur +   + Code d'erreur : 3201 + + + 26 + PUT /bulkQuotes/{ID}/error + + + 27 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml new file mode 100644 index 000000000..4109869e3 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml @@ -0,0 +1,117 @@ +@startuml +Title Demander la création d’une devis +participant "FSP payeur" as PayerFSP +participant "Switch\n[Service de\ndevis]" as Switch +database "Référentiel central" as DB +participant "FSP bénéficiaire" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Le FSP payeur envoie une demande de devis\nau FSP bénéficiaire via le Switch +PayerFSP -\ Switch: POST /quotes +note right of Switch #aaa + Valider la requête selon la + spécification d’interface Mojaloop + **Codes d’erreur : 300x, 310x** + **Codes HTTP d’erreur : 4xx** +end note +Switch -> Switch: Validation de schéma +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Validation de la demande de devis (moteur de règles, etc.) +||| +alt SimpleRoutingMode === FALSE + Switch -> Switch: Contrôle de doublon + ||| + alt la requête est un doublon mais pas un renvoi + ||| + note left of Switch + Le Switch renvoie une erreur au FSP payeur + **Code d’erreur : 3106** + end note + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + ||| + else la requête est un doublon et un renvoi + Switch -> Switch: Le Switch gère le scénario de renvoi + end + ||| + Switch -\ DB: Persister la demande de devis + activate DB + hnote over DB + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + end hnote + Switch \-- DB: Demande de devis enregistrée + deactivate DB +end +||| +alt SimpleRoutingMode === TRUE + Switch -> Switch: Utiliser l'en-tête fspiop-destination pour obtenir l'endpoint « quotes » du FSP bénéficiaire +else SimpleRoutingMode === FALSE + Switch -> Switch: Récupérer l'endpoint du FSP bénéficiaire via les informations « quote party » +end +||| +alt endpoint « quotes » du bénéficiaire trouvé + note right of Switch: Le Switch transmet la demande au FSP bénéficiaire + Switch -\ PayeeFSP: POST /quotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Le FSP bénéficiaire persiste et calcule le devis + alt traitement du devis réussi côté bénéficiaire + note left of PayeeFSP: Le FSP bénéficiaire envoie la réponse au FSP payeur via le Switch + Switch /- PayeeFSP: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Valider la réponse de devis + alt SimpleRoutingMode === FALSE + Switch -> Switch: Contrôle de doublon + alt la réponse est un doublon mais pas un renvoi + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt la réponse est un doublon et un renvoi + Switch -> Switch: Le Switch gère le scénario de renvoi + end + Switch -\ DB: Persister la réponse de devis + activate DB + hnote over DB + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + end hnote + Switch \-- DB: Réponse de devis enregistrée + deactivate DB + end + note left of Switch: Le Switch transmet la réponse au FSP payeur + PayerFSP /- Switch: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 OK + else le bénéficiaire rejette ou rencontre une erreur + note left of PayeeFSP: Le FSP bénéficiaire envoie un callback d’erreur au FSP payeur via le Switch + Switch /- PayeeFSP: PUT /quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode === FALSE + Switch -\ DB: Enregistrer l’erreur de devis + activate DB + hnote over DB + quoteError + end hnote + Switch \-- DB: Erreur de devis enregistrée + deactivate DB + end + note left of Switch: Le Switch transmet le callback d’erreur au FSP payeur + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else endpoint « quotes » du FSP bénéficiaire introuvable + note left of Switch: Le Switch envoie un callback d'erreur au FSP payeur \n **Code d'erreur : 3201** + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg new file mode 100644 index 000000000..713672f96 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg @@ -0,0 +1,297 @@ + + Demander la création d’une devis + + + Demander la création d’une devis + + + + + + + + + + + + + + + + + + FSP payeur + + FSP payeur + + Switch + [Service de + devis] + + Switch + [Service de + devis] + Référentiel central + + + Référentiel central + + + + FSP bénéficiaire + + FSP bénéficiaire + + + + + + Le FSP payeur envoie une demande de devis + au FSP bénéficiaire via le Switch + + + 1 + POST /quotes + + + Valider la requête selon la + spécification d’interface Mojaloop + Codes d’erreur : 300x, 310x + Codes HTTP d’erreur : 4xx + + + + + 2 + Validation de schéma + + + 3 + 202 Accepted + + + + + 4 + Validation de la demande de devis (moteur de règles, etc.) + + + alt + [SimpleRoutingMode === FALSE] + + + + + 5 + Contrôle de doublon + + + alt + [la requête est un doublon mais pas un renvoi] + + + Le Switch renvoie une erreur au FSP payeur + Code d’erreur : 3106 + + + 6 + PUT /quotes/{ID}/error + + + 7 + 200 OK + + [la requête est un doublon et un renvoi] + + + + + 8 + Le Switch gère le scénario de renvoi + + + 9 + Persister la demande de devis + + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + + + 10 + Demande de devis enregistrée + + + alt + [SimpleRoutingMode === TRUE] + + + + + 11 + Utiliser l'en-tête fspiop-destination pour obtenir l'endpoint « quotes » du FSP bénéficiaire + + [SimpleRoutingMode === FALSE] + + + + + 12 + Récupérer l'endpoint du FSP bénéficiaire via les informations « quote party » + + + alt + [endpoint « quotes » du bénéficiaire trouvé] + + + Le Switch transmet la demande au FSP bénéficiaire + + + 13 + POST /quotes + + + 14 + 202 OK + + + + + 15 + Le FSP bénéficiaire persiste et calcule le devis + + + alt + [traitement du devis réussi côté bénéficiaire] + + + Le FSP bénéficiaire envoie la réponse au FSP payeur via le Switch + + + 16 + PUT /quotes/{ID} + + + 17 + 200 OK + + + + + 18 + Valider la réponse de devis + + + alt + [SimpleRoutingMode === FALSE] + + + + + 19 + Contrôle de doublon + + + alt + [la réponse est un doublon mais pas un renvoi] + + + 20 + PUT /quotes/{ID}/error + + + 21 + 200 OK + + + alt + [la réponse est un doublon et un renvoi] + + + + + 22 + Le Switch gère le scénario de renvoi + + + 23 + Persister la réponse de devis + + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + + + 24 + Réponse de devis enregistrée + + + Le Switch transmet la réponse au FSP payeur + + + 25 + PUT /quotes/{ID} + + + 26 + 200 OK + + [le bénéficiaire rejette ou rencontre une erreur] + + + Le FSP bénéficiaire envoie un callback d’erreur au FSP payeur via le Switch + + + 27 + PUT /quotes/{ID}/error + + + 28 + 200 OK + + + alt + [SimpleRoutingMode === FALSE] + + + 29 + Enregistrer l’erreur de devis + + quoteError + + + 30 + Erreur de devis enregistrée + + + Le Switch transmet le callback d’erreur au FSP payeur + + + 31 + PUT /quotes/{ID}/error + + + 32 + 200 OK + + [endpoint « quotes » du FSP bénéficiaire introuvable] + + + Le Switch envoie un callback d'erreur au FSP payeur +   + Code d'erreur : 3201 + + + 33 + PUT /quotes/{ID}/error + + + 34 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml new file mode 100644 index 000000000..6f638d9d0 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml @@ -0,0 +1,68 @@ +@startuml +Title Séquences du service de devis +participant "DFSP payeur" +participant "Switch\nService de\ndevis" as Switch +participant "DFSP bénéficiaire" + +autonumber +note over "DFSP payeur", Switch: Le DFSP payeur demande une devis au DFSP bénéficiaire +"DFSP payeur" -\ Switch: POST /quotes +Switch --/ "DFSP payeur": 202 Accepted +Switch -> Switch: Valider la demande de devis + +alt devis valide + + Switch -> Switch: Persister les données de devis + note over Switch, "DFSP bénéficiaire": Le Switch transmet la demande au DFSP bénéficiaire\n + Switch -\ "DFSP bénéficiaire": POST /quotes + "DFSP bénéficiaire" --/ Switch: 202 Accepted + "DFSP bénéficiaire" -> "DFSP bénéficiaire": Calculer frais et commissions + + alt le DFSP bénéficiaire calcule le devis avec succès + + note over "DFSP bénéficiaire", Switch: Le DFSP bénéficiaire répond à la demande de devis + "DFSP bénéficiaire" -\ Switch: PUT /quotes/{ID} + Switch --/ "DFSP bénéficiaire": 200 Ok + + Switch -> Switch: Valider la réponse de devis + + alt réponse valide + + Switch -> Switch: Persister les données de réponse + + note over Switch, "DFSP payeur": Le Switch transmet la réponse au DFSP payeur\n + + Switch -\ "DFSP payeur": PUT /quotes/{ID} + "DFSP payeur" --/ Switch: 200 Ok + + note over "DFSP payeur" #3498db: Le DFSP payeur poursuit\nle transfert si le devis\nest acceptable… + else réponse invalide + + note over Switch, "DFSP bénéficiaire": Le Switch renvoie une erreur au DFSP bénéficiaire + + Switch -\ "DFSP bénéficiaire": PUT /quotes/{ID}/error + "DFSP bénéficiaire" --/ Switch : 200 Ok + + note over Switch, "DFSP bénéficiaire" #ec7063: Dans ce scénario, le DFSP payeur\npeut ne pas recevoir de réponse + + end + else échec du calcul ou rejet par le DFSP bénéficiaire + + note over "DFSP bénéficiaire", Switch: Le DFSP bénéficiaire renvoie une erreur au Switch + + "DFSP bénéficiaire" -\ Switch: PUT /quotes/{ID}/error + Switch --/ "DFSP bénéficiaire": 200 OK + Switch -> Switch: Persister les données d’erreur + + note over "DFSP payeur", Switch: Le Switch renvoie une erreur au DFSP payeur + + Switch -\ "DFSP payeur": PUT /quotes/{ID}/error + "DFSP payeur" --/ Switch: 200 OK + + end +else devis invalide + note over "DFSP payeur", Switch: Le Switch renvoie une erreur au DFSP payeur + Switch -\ "DFSP payeur": PUT /quotes/{ID}/error + "DFSP payeur" --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg new file mode 100644 index 000000000..8ca46236e --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg @@ -0,0 +1,182 @@ + + Séquences du service de devis + + + Séquences du service de devis + + + + + + + + DFSP payeur + + DFSP payeur + + Switch + Service de + devis + + Switch + Service de + devis + + DFSP bénéficiaire + + DFSP bénéficiaire + + + Le DFSP payeur demande une devis au DFSP bénéficiaire + + + 1 + POST /quotes + + + 2 + 202 Accepted + + + + + 3 + Valider la demande de devis + + + alt + [devis valide] + + + + + 4 + Persister les données de devis + + + Le Switch transmet la demande au DFSP bénéficiaire + <Règles côté payeur> + + + 5 + POST /quotes + + + 6 + 202 Accepted + + + + + 7 + Calculer frais et commissions + + + alt + [le DFSP bénéficiaire calcule le devis avec succès] + + + Le DFSP bénéficiaire répond à la demande de devis + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Valider la réponse de devis + + + alt + [réponse valide] + + + + + 11 + Persister les données de réponse + + + Le Switch transmet la réponse au DFSP payeur + <Règle bénéficiaire — requête complète> + + + 12 + PUT /quotes/{ID} + + + 13 + 200 Ok + + + Le DFSP payeur poursuit + le transfert si le devis + est acceptable… + + [réponse invalide] + + + Le Switch renvoie une erreur au DFSP bénéficiaire + + + 14 + PUT /quotes/{ID}/error + + + 15 + 200 Ok + + + Dans ce scénario, le DFSP payeur + peut ne pas recevoir de réponse + + [échec du calcul ou rejet par le DFSP bénéficiaire] + + + Le DFSP bénéficiaire renvoie une erreur au Switch + + + 16 + PUT /quotes/{ID}/error + + + 17 + 200 OK + + + + + 18 + Persister les données d’erreur + + + Le Switch renvoie une erreur au DFSP payeur + + + 19 + PUT /quotes/{ID}/error + + + 20 + 200 OK + + [devis invalide] + + + Le Switch renvoie une erreur au DFSP payeur + + + 21 + PUT /quotes/{ID}/error + + + 22 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml new file mode 100644 index 000000000..4b8f2626d --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml @@ -0,0 +1,67 @@ +@startuml +Title Séquences du service de devis +participant "FSP payeur" +participant "Switch\nService de\ndevis" as Switch +participant "FSP bénéficiaire" + +autonumber +note over "FSP payeur", Switch: Le FSP payeur demande une devis au FSP bénéficiaire +"FSP payeur" -\ Switch: POST /quotes +Switch --/ "FSP payeur": 202 Accepted +Switch -> Switch: Valider la demande de devis + +alt devis valide + + Switch -> Switch: Persister les données de devis + note over Switch, "FSP bénéficiaire": Le Switch transmet la demande au FSP bénéficiaire\n + Switch -\ "FSP bénéficiaire": POST /quotes + "FSP bénéficiaire" --/ Switch: 202 Accepted + "FSP bénéficiaire" -> "FSP bénéficiaire": Calculer frais et commissions + + alt le FSP bénéficiaire calcule le devis avec succès + + note over "FSP bénéficiaire", Switch: Le FSP bénéficiaire répond à la demande de devis + "FSP bénéficiaire" -\ Switch: PUT /quotes/{ID} + Switch --/ "FSP bénéficiaire": 200 Ok + + Switch -> Switch: Valider la réponse de devis + + alt réponse valide + Switch -> Switch: Persister les données de réponse + + note over Switch, "FSP payeur": Le Switch transmet la réponse au FSP payeur\n + + Switch -\ "FSP payeur": PUT /quotes/{ID} + "FSP payeur" --/ Switch: 200 Ok + + note over "FSP payeur" #3498db: Le FSP payeur poursuit\nle transfert si le devis\nest acceptable… + else réponse invalide + + note over Switch, "FSP bénéficiaire": Le Switch renvoie une erreur au FSP bénéficiaire + + Switch -\ "FSP bénéficiaire": PUT /quotes/{ID}/error + "FSP bénéficiaire" --/ Switch : 200 Ok + + note over Switch, "FSP bénéficiaire" #ec7063: Dans ce scénario, le FSP payeur\npeut ne pas recevoir de réponse + + end + else échec du calcul ou rejet par le FSP bénéficiaire + + note over "FSP bénéficiaire", Switch: Le FSP bénéficiaire renvoie une erreur au Switch + + "FSP bénéficiaire" -\ Switch: PUT /quotes/{ID}/error + Switch --/ "FSP bénéficiaire": 200 OK + Switch -> Switch: Persister les données d’erreur + + note over "FSP payeur", Switch: Le Switch renvoie une erreur au FSP payeur + + Switch -\ "FSP payeur": PUT /quotes/{ID}/error + "FSP payeur" --/ Switch: 200 OK + + end +else devis invalide + note over "FSP payeur", Switch: Le Switch renvoie une erreur au FSP payeur + Switch -\ "FSP payeur": PUT /quotes/{ID}/error + "FSP payeur" --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg new file mode 100644 index 000000000..4421fdae3 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg @@ -0,0 +1,182 @@ + + Séquences du service de devis + + + Séquences du service de devis + + + + + + + + FSP payeur + + FSP payeur + + Switch + Service de + devis + + Switch + Service de + devis + + FSP bénéficiaire + + FSP bénéficiaire + + + Le FSP payeur demande une devis au FSP bénéficiaire + + + 1 + POST /quotes + + + 2 + 202 Accepted + + + + + 3 + Valider la demande de devis + + + alt + [devis valide] + + + + + 4 + Persister les données de devis + + + Le Switch transmet la demande au FSP bénéficiaire + <Règles côté payeur> + + + 5 + POST /quotes + + + 6 + 202 Accepted + + + + + 7 + Calculer frais et commissions + + + alt + [le FSP bénéficiaire calcule le devis avec succès] + + + Le FSP bénéficiaire répond à la demande de devis + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Valider la réponse de devis + + + alt + [réponse valide] + + + + + 11 + Persister les données de réponse + + + Le Switch transmet la réponse au FSP payeur + <Règle bénéficiaire — requête complète> + + + 12 + PUT /quotes/{ID} + + + 13 + 200 Ok + + + Le FSP payeur poursuit + le transfert si le devis + est acceptable… + + [réponse invalide] + + + Le Switch renvoie une erreur au FSP bénéficiaire + + + 14 + PUT /quotes/{ID}/error + + + 15 + 200 Ok + + + Dans ce scénario, le FSP payeur + peut ne pas recevoir de réponse + + [échec du calcul ou rejet par le FSP bénéficiaire] + + + Le FSP bénéficiaire renvoie une erreur au Switch + + + 16 + PUT /quotes/{ID}/error + + + 17 + 200 OK + + + + + 18 + Persister les données d’erreur + + + Le Switch renvoie une erreur au FSP payeur + + + 19 + PUT /quotes/{ID}/error + + + 20 + 200 OK + + [devis invalide] + + + Le Switch renvoie une erreur au FSP payeur + + + 21 + PUT /quotes/{ID}/error + + + 22 + 200 OK + + diff --git a/docs/fr/technical/technical/quoting-service/qs-get-bulk-quotes.md b/docs/fr/technical/technical/quoting-service/qs-get-bulk-quotes.md new file mode 100644 index 000000000..709260d72 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/qs-get-bulk-quotes.md @@ -0,0 +1,7 @@ +# GET — Devis par ID + +Conception de la récupération d’un devis groupé par un FSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg) diff --git a/docs/fr/technical/technical/quoting-service/qs-get-quotes.md b/docs/fr/technical/technical/quoting-service/qs-get-quotes.md new file mode 100644 index 000000000..79d952d54 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/qs-get-quotes.md @@ -0,0 +1,7 @@ +# GET — Devis par ID + +Spécification de l’endpoint de récupération d’un devis par un FSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-get-quotes-1.1.0.svg) diff --git a/docs/fr/technical/technical/quoting-service/qs-post-bulk-quotes.md b/docs/fr/technical/technical/quoting-service/qs-post-bulk-quotes.md new file mode 100644 index 000000000..d1f127c9e --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/qs-post-bulk-quotes.md @@ -0,0 +1,7 @@ +# POST — Devis + +Conception d’une demande de devis groupée par un FSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg) diff --git a/docs/fr/technical/technical/quoting-service/qs-post-quotes.md b/docs/fr/technical/technical/quoting-service/qs-post-quotes.md new file mode 100644 index 000000000..8fa6b7466 --- /dev/null +++ b/docs/fr/technical/technical/quoting-service/qs-post-quotes.md @@ -0,0 +1,7 @@ +# POST — Devis + +Conception d’une demande de devis par un FSP. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-post-quotes-1.2.0.svg) diff --git a/docs/fr/technical/technical/releases.md b/docs/fr/technical/technical/releases.md new file mode 100644 index 000000000..2a03b472f --- /dev/null +++ b/docs/fr/technical/technical/releases.md @@ -0,0 +1,199 @@ +--- +sidebarTitle: Versions Mojaloop +title: Versions Mojaloop +--- + +# Processus de publication Mojaloop + +Le processus de publication de Mojaloop suit une approche menée par la communauté, en particulier par les workstreams techniques, en collaboration et consultation avec le Conseil Produit et l’Autorité de Conception (DA). + +La DA définit les politiques, lignes directrices et critères techniques pour les releases (tels que les métriques de qualité), tandis que le Produit définit les exigences fonctionnelles et celles liées au produit, lorsque cela s'applique. Cela est mis en œuvre par le(s) workstream(s) concerné(s). + +## 1. Processus de publication Mojaloop +![YM8f9iPhGU1jAfr-dQUk4e34QMGPG1ZWnbmC4ERGpsqp70GJH2he2Nje4poq_dii642B82j-Cj-2-HuYTkEF4poIBg8rJSfWYagBVOMyt6PQs5_P2YRE9magU_jE](https://github.com/mojaloop/design-authority-project/assets/10507686/075e528c-d4b2-4100-a2b9-6d06d77155d0) + +Événement communautaire (planification au niveau PI), workstreams, fonctionnalités, qualité de la release, tests, checklist, release candidate, exemple d’epic, publication + +Le processus de release Mojaloop suit une : +- démarche menée par la communauté +- menée précisément par les workstreams techniques +- en collaboration et consultation avec le Conseil Produit +- et l’Autorité de Conception (DA) + +Critères, directives : +La DA définit les politiques, lignes directrices et critères techniques pour les releases tandis que le Produit spécifie les exigences fonctionnelles et produit. +Exemple de notes de version et critères de la v17.0.0, [v17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +Les tests continuent après la sortie de la release : des tâches planifiées (cron jobs) journalières continuent à tourner jusqu'à la publication suivante, afin d'assurer la stabilité. + +**Tâches actuelles et critères d'acceptation pour les releases Mojaloop (helm) :** + +Exemple de story : [3122](https://github.com/mojaloop/project/issues/3122) , [3847](https://github.com/mojaloop/project/issues/3847) + +Les décisions concernant les fonctionnalités à inclure, celles jugées prêtes et retenues, ne sont pas listées ici car elles interviennent en phases de planification (et selon les livrables attendus) + +- [x] S’assurer que tous les services cœur et les services inclus dans la release respectent les standards concernant : + - [x] Alertes Dependabot + - [x] Fichiers de licence + - [x] En-têtes de licence dans les sources + - [x] Alertes Snyk + - [x] Fichiers codeowners + - [x] Règles de protection des branches principales vérifiées + - [x] Revue des issues ouvertes + - [x] Revue des pull requests ouvertes + - [x] Revue des exceptions d’audit fournies et effacer/réduire de la liste +- [x] Mise à jour des manifests pour le workflow Github "Release Pull Request (PR)" +- [x] Valider le PR de release ainsi que le processus associé +- [x] Déployer les valeurs par défaut avec le RC dans l'environnement AWS moja* + - [x] Valider que la collection GP passe à 100 % + - [x] Valider que les tests FX et inter-schéma fonctionnent à 100 % +- [x] Déployer et valider le RC sur un second environnement + - [x] Valider que la collection GP passe à 100 % + - [x] Valider que les tests FX et inter-schéma fonctionnent à 100 % +- [x] Identifier les problèmes éventuels avec les scripts QA ; les corriger et retester +- [x] QA pour bugs, régressions, les consigner +- [x] Corriger les bugs remontés si critique +- [x] Valider avec la collection GP de TTK +- [x] Tester l’option de configuration "on-us" (changement en déploiement) et vérifier que les tests on-us passent +- [x] Publication du dépôt de scénarios de tests TTK +- [x] Notes de version pour le RC Helm rédigées + - [x] Guide de migration depuis une version publiée (peut nécessiter une story séparée si suffisamment important / complexe) +- [x] Mise à jour des notes de version avec le lien du guide de stratégie de mise à jour +- [x] Release Helm publiée +- [x] Déploiement du Helm publié sur un environnement de dev + - [x] Release Helm déployée sur dev avec succès + - [x] Tests de régression sur dev avec collections TTK + - [x] Collection GP + - [x] Collection Core Bulk + - [x] Collection Third-party + - [x] Collection SDK Bulk + - [x] Collection SDK R2P + - [x] Tests mode ISO 20022 + - [x] Collection (ou tests) FX + - [x] Collection tests inter-schéma + - [x] Validation avec les tests de régression "Golden Path" de CGS + - [x] Test de la capacité de mise à jour depuis la version précédente (v16.0.4 / v16.0.0) +- [x] Déploiement du Helm publié sur un environnement QA + - [x] Release Helm déployée sur QA avec succès + - [x] Validation avec tests de régression "Golden Path" sur QA + - [x] Collection GP + - [x] Collection Core Bulk + - [x] Collection Third-party + - [x] Collection SDK Bulk + - [x] Collection SDK R2P + - [x] Collection FX (ou tests) + - [x] Tests mode ISO 20022 + - [x] Collection tests inter-schéma +- [x] Valider que les cronJobs quotidiens de GP sur dev/qa et les scripts de nettoyage s'exécutent correctement, ainsi que les scripts de nettoyage +- Valider la capacité à réaliser une mise à niveau depuis la version stable précédente, et en profiter pour identifier tout "piège" à gérer dans la release ou mettre à jour les notes de version (à la charge de la personne qui effectue la montée de version). + + +## 2. Processus de publication Mojaloop – évolutions proposées : + +Proposer un calendrier de release et des échéances + +1. Exemple : le gel des fonctionnalités pour une release majeure doit précéder d'au moins six semaines le prochain kick-off PI (ou événement communautaire) +1. Le gel des corrections de bugs (non critiques) doit intervenir quatre semaines avant la date de publication +1. Le RC doit être validé par au moins un intégrateur / utilisateur aval : Mini-loop, IaC, Core-test-harness ou un autre +1. La release peut être publiée dans les temps si aucun bug de priorité haute ou moyenne n'est ouvert dans le RC et si les validations sont faites sur un environnement de dev et par une équipe downstream +1. Harmoniser la numérotation des versions entre les différents composants de la plateforme Mojaloop, tel que le Finance Portal +1. Inclure des mesures de performance et des détails sur l'environnement de référence utilisé pour ces mesures +1. Ressources : capturer l'empreinte des ressources d'une publication de base +1. Documenter les mécanismes de support pour les releases Mojaloop + +## 3. Contenu de la release Helm Mojaloop + +Services Mojaloop prenant en charge les fonctionnalités cœur de la plateforme ainsi que d'autres services clés, sans oublier les outils nécessaires aux tests comme les simulateurs + +Fonctionnalité principale avec options de configuration : +1. Recherche de comptes (Account Lookup) + - Admin de recherche de comptes + - Oracles + - ALS (Account Lookup Service) +2. Devis (Quoting) + - Prise en charge des modes persistant/passe-plat (paramétrable) +3. Transferts (Clearing) + - Prise en charge des transferts on-us (paramétrable) +4. Règlement (Settlement) + - Prise en charge de plusieurs types, granularités, fréquences +5. Requêtes de transaction (fonctionnalité Request-to-pay) +6. Services 3PPI (Interface Fournisseur Tiers) +7. Couche API — pour parties, devis, transferts et requêtes de transaction +8. Notifications + - ML-API-Adapter +9. Conversion de devises +10. Fonctionnalités étendues + - Central Event Processor + - Email Notifier (avant la version 15) + - Suivi et surveillance (Traceability & Monitoring) + - Instrumentation +11. Audit + - Capacités d’audit étendues +12. Services de support & outils pour tests + - ML TTK (Testing Toolkit) + - ML Simulator + - SDK-Scheme-Adapters + - Instances Payment Manager +13. Adaptateurs de schéma tiers + - Intégration avec des schémas tiers +14. Gestion du cycle de vie des participants + - Création de participants + - Mise à jour de participants +15. Support aux participants + - Outils simples d'utilisation pour les adoptants (Exemple : [SDK-Scheme-Adapter](https://github.com/mojaloop/sdk-scheme-adapter), [Integration Toolkit](https://github.com/mojaloop/integration-toolkit/tree/main)) + - Fonctionnalités et support d'intégration + +## 4. Plateforme Mojaloop +1. Release principale Mojaloop (helm) et configuration avec : + - Moteur central de compensation incluant la prise en charge du Bulk + - Quoting + - Recherche de comptes et ses composants associés + - Moteur de règlement + - Couche API + - La prise en charge du pour request-to-pay (requêtes de transaction) + - Gestion du cycle de vie des participants + - Réf : Release Helm Mojaloop (exemple : v15.1.0) +2. Fonctionnalité PISP / 3PPI +3. Gateway(s) API + - Assurer une couche API sécurisée + - Fournir entrée, sortie (Ingress/Egress), filtrage IP, pare-feux + - Prise en charge des mécanismes de sécurité : JWS, mTLS + - Référence : WSO2 +4. Composants de sécurité : + - HSM si pertinent/utilisé + - Gestion des identités & accès + - Gestion des certificats + - Gestion des connexions +5. Portail Finance, Reporting + - Portails pour les équipes d’Opérations du Hub, Ops métier + - Portails et capacités pour équipes techniques d’Ops + - Réf : FP v3 basé sur le Business Operations Framework +6. Prise en charge de monitoring : + - Support opérationnel et traçabilité (ex : EFK, Prometheus, Grafana, Loki) + - IaC utilise Grafana, Prometheus et Loki +7. Utiliser IaC comme référence, exemple : https://github.com/mojaloop/iac-modules/releases/tag/v5.7.0 + + + +## Releases actuelles + +> *Remarque : Les versions ci-dessous sont les dernières versions publiées pour chaque artefact de release distinct, à titre de référence. Consultez les notes de version de la release Helm pour savoir quelles versions sont incluses dans la version [Helm Charts Packaged Release](#helm-charts-packaged-releases).* + +* Helm : [![Git Releases](https://img.shields.io/github/release/mojaloop/helm.svg?style=flat)](https://github.com/mojaloop/helm/releases) +* Central-Ledger : [![Git Releases](https://img.shields.io/github/release/mojaloop/central-ledger.svg?style=flat)](https://github.com/mojaloop/central-ledger/releases) +* Ml-API-Adapter : [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-api-adapter.svg?style=flat)](https://github.com/mojaloop/ml-api-adapter/releases) +* Account-Lookup-Service : [![Git Releases](https://img.shields.io/github/release/mojaloop/account-lookup-service.svg?style=flat)](https://github.com/mojaloop/account-lookup-service/releases) +* Quoting-Service : [![Git Releases](https://img.shields.io/github/release/mojaloop/quoting-service.svg?style=flat)](https://github.com/mojaloop/quoting-service/releases) +* Transaction-Request-Service : [![Git Releases](https://img.shields.io/github/release/mojaloop/transaction-requests-service.svg?style=flat)](https://github.com/mojaloop/transaction-requests-service/releases) +* Bulk-API-Adapter : [![Git Releases](https://img.shields.io/github/release/mojaloop/bulk-api-adapter.svg?style=flat)](https://github.com/mojaloop/bulk-api-adapter/releases) +* Central-Settlement : [![Git Releases](https://img.shields.io/github/release/mojaloop/central-settlement.svg?style=flat)](https://github.com/mojaloop/central-settlement/releases) +* Central-Event-Processor : [![Git Releases](https://img.shields.io/github/release/mojaloop/central-event-processor.svg?style=flat)](https://github.com/mojaloop/central-event-processor/releases) +* Email-Notifier : [![Git Releases](https://img.shields.io/github/release/mojaloop/email-notifier.svg?style=flat)](https://github.com/mojaloop/email-notifier/releases) +* SDK-Scheme-Adapter : [![Git Releases](https://img.shields.io/github/release/mojaloop/sdk-scheme-adapter.svg?style=flat)](https://github.com/mojaloop/sdk-scheme-adapter/releases) +* Thirdparty-SDK : [![Git Releases](https://img.shields.io/github/release/mojaloop/thirdparty-sdk.svg?style=flat)](https://github.com/mojaloop/thirdparty-sdk/releases) +* Thirdparty-Api-Svc : [![Git Releases](https://img.shields.io/github/release/mojaloop/thirdparty-api-svc.svg?style=flat)](https://github.com/mojaloop/thirdparty-api-svc/releases) +* Auth-Svc : [![Git Releases](https://img.shields.io/github/release/mojaloop/auth-service.svg?style=flat)](https://github.com/mojaloop/auth-service/releases) +* ML-Testing-Toolkit : [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-testing-toolkit.svg?style=flat)](https://github.com/mojaloop/ml-testing-toolkit/releases) +* ML-Testing-Toolkit-Ui : [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-testing-toolkit-ui.svg?style=flat)](https://github.com/mojaloop/ml-testing-toolkit-ui/releases) + +Pour une liste exhaustive des releases helm, veuillez consulter la [page des releases Helm](https://github.com/mojaloop/helm/releases). diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md new file mode 100644 index 000000000..4e0eea1ec --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md @@ -0,0 +1,63 @@ +# Prise en charge des transferts groupés par le SDK — vue d’ensemble + +Ce document de conception décrit les évolutions du SDK Scheme Adapter pour le cas d’usage des transferts groupés. + +## Pourquoi ? — Dépasser les limites des transferts groupés Mojaloop + +L’implémentation des transferts groupés dans Mojaloop présente les limites suivantes, que cette évolution du SDK vise à atténuer. + +1. Seuls les transferts individuels adressés au même DFSP payeur peuvent figurer dans un appel de devis groupés ou de transferts groupés. +2. Le nombre de devis et de transferts individuels par appel `bulkQuotes` / `bulkTransfers` est plafonné à 1000. +3. Pour activer les transferts groupés, chaque DFSP bénéficiaire doit intégrer la messagerie groupée — si le cas d’usage *bulk* était introduit dans un schéma existant, tous les DFSP connectés devraient mettre à jour leurs intégrations vers leurs systèmes *core banking*. +4. Il n’existe pas aujourd’hui d’appel de découverte (*discovery*) groupé. + +## Exigences de l’évolution *bulk* du SDK Scheme Adapter + +Les évolutions permettent notamment : + +1. Des transferts sans phase de découverte préalable. +2. Aucune limite stricte sur le nombre de transferts (limitée par les capacités de l’infrastructure et du réseau, au-delà du plafond de 1 000 transferts fixé par ML FSPIOP). +3. L’intégration *bulk* côté bénéficiaire devient optionnelle. +4. En option : prise en charge de scénarios tels qu’un appel unique combinant découverte, accord et transfert ; acceptation indépendante des recherches de partie ; acceptation indépendante des devis ; plafond de frais pour l’acceptation automatique des devis ; saut de la phase de découverte ; exécution de la seule phase de découverte ; expiration du message groupé ; identifiants de transaction *home* pour le message groupé et pour chaque transfert ; appels API synchrones et asynchrones. + +## Fonctionnalités implémentées + +L’implémentation actuelle ne couvre pas encore toutes les fonctionnalités prévues. Toutes les fonctionnalités complétées sont fonctionnelles et immédiatement utilisables. Des fonctionnalités supplémentaires peuvent être ajoutées selon les priorités de Mojaloop et de la communauté, conformément à l’approche MVP (Minimum Viable Product) agile. + +| Fonctionnalité | Statut d’implémentation | Version | +|---|---|---| +| Mode asynchrone | publié | v14.1.0 RC | +| Mode synchrone | non démarré | | +| Acceptation auto des parties | non démarré | | +| Acceptation auto des devis (avec plafond de frais) | non démarré | | +| Validation des parties uniquement | non démarré | | +| Ignorer la recherche de partie | non démarré | | +| Expiration du lot | non démarré | | +| SDK bénéficiaire — démultiplexage des devis groupés | non démarré | | +| SDK bénéficiaire — démultiplexage des transferts groupés | non démarré | | +| Mojaloop — notification *bulk patch* | non démarré | | +| SDK bénéficiaire — démultiplexage *bulk patch* | non démarré | | + +### Diagramme fonctionnel + +![Diagramme fonctionnel](../assets/BulkSDKEnhancements.drawio.svg) + +## Diagramme d’architecture + +L’architecture par *event sourcing* répartit l’implémentation en quatre composants : + +1. **Backend API** : reçoit les appels API, produit les événements de domaine correspondants et, en réaction aux événements, déclenche les *callbacks* API. +2. **Domain Event Handler** : consomme les événements de domaine et produit des événements de commande. +3. **Command Event Handler** : consomme les événements de commande et produit des événements de domaine. +4. **FSPIOP API** : surveille les événements de domaine pour produire les appels FSPIOP correspondants, et surveille les callbacks API pour produire les événements de domaine correspondants. + +![Diagramme d’architecture](../assets/BulkSDKEnhancements-Architecture.drawio.svg) + + +## Diagramme de séquence — vue d’ensemble + +Voici un diagramme de séquence décrivant le rôle que jouera le SDK Scheme Adapter lors d’un appel groupé, côté DFSP payeur et DFSP bénéficiaire. + +![Vue d’ensemble du diagramme de séquence des transferts groupés](../assets/sequence/SDKBulkSequenceDiagram.svg) + + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md new file mode 100644 index 000000000..3ed09fb68 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md @@ -0,0 +1,161 @@ +# Prise en charge des transferts groupés par le SDK — API + +Les évolutions du SDK Scheme Adapter côté payeur sont exposées dans l’API sous l’endpoint `BulkTransactions` : + +- **POST** `/bulkTransactions` +- **PUT** `/bulkTransactions` +- **PUT** `/bulkTransactions` (*callback*) + +La définition OpenAPI sortante (*outbound*) se trouve [ici](https://github.com/mojaloop/api-snippets/blob/master/sdk-scheme-adapter/v2_0_0/outbound/openapi.yaml). +La définition OpenAPI entrante (*inbound*) se trouve [ici](https://github.com/mojaloop/api-snippets/blob/master/sdk-scheme-adapter/v2_0_0/inbound/openapi.yaml). + + +## Diagramme de séquence technique + +![Diagramme de séquence technique des transferts groupés](https://raw.githubusercontent.com/mojaloop/sdk-scheme-adapter/master/docs/design-bulk-transfers/assets/api-sequence-diagram.svg) + +## Tableaux d’erreurs pour les transferts groupés + +[Table des codes d’erreur](../assets/sequence/BULK-ERRORCODES.md) + +### Phase de découverte + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* agira comme relais transparent (*pass-through*) pour toutes les erreurs renvoyées par le commutateur. + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — recherche de partie** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur de traitement | +| Erreur interne du serveur | 2001 | 503 | Erreur de traitement | +| Délai d’attente dépassé lors de la résolution de la partie | 2004 | 503 | Erreur de traitement | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Partie introuvable | 3204 | 202 | Erreur de traitement | + +### Phase d’accord + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* agira comme relais transparent (*pass-through*) pour toutes les erreurs renvoyées par le commutateur. + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — devis** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur technique | +| Erreur interne du serveur | 2001 | 503 | Erreur technique | +| Non implémenté | 2002 | 501 | Erreur de traitement | +| Service actuellement indisponible | 2003 | 503 | Erreur de traitement | +| Délai d’attente du serveur dépassé | 2004 | 503 | Erreur de traitement | +| Serveur occupé | 2005 | 503 | Erreur de traitement | +| Erreur client générique | 3000 | 400 | Erreur de validation de la requête | +| Version demandée inacceptable | 3001 | 406 | Erreur « non acceptable » | +| URI inconnue | 3002 | 404 | Erreur « introuvable » | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Syntaxe incorrecte | 3101 | 400 | Erreur de validation de la requête | +| Élément obligatoire manquant | 3102 | 400 | Erreur de validation de la requête | +| Trop d’éléments | 3103 | 400 | Erreur de validation de la requête | +| Charge utile trop volumineuse | 3104 | 400 | Erreur de validation de la requête | +| Signature invalide | 3105 | 403 | Erreur « interdit » | +| Erreur du FSP de destination | 3201 | 404 | Erreur « introuvable » | +| Identifiant FSP payeur introuvable | 3202 | 404 | Erreur « introuvable » | +| Identifiant FSP bénéficiaire introuvable | 3203 | 404 | Erreur « introuvable » | +| Identifiant de devis introuvable | 3205 | 404 | Erreur « introuvable » | +| Identifiant de devis groupé introuvable | 3209 | 404 | Erreur « introuvable » | +| Erreur d’expiration générique | 3300 | 503 | Erreur de traitement | +| Devis expiré | 3302 | 503 | Erreur de traitement | +| Erreur payeur générique | 4000 | 400 | Erreur de validation de la requête | +| Rejet payeur générique | 4100 | 403 | Erreur « interdit » | +| Erreur de limite payeur | 4200 | 400 | Erreur de validation de la requête | +| Erreur d’autorisation payeur | 4300 | 403 | Erreur « interdit » | +| Erreur de blocage payeur générique | 4400 | 403 | Erreur « interdit » | +| Erreur bénéficiaire générique | 5000 | 503 | Erreur de traitement | +| Liquidité insuffisante côté FSP bénéficiaire | 5001 | 503 | Erreur de traitement | +| Rejet bénéficiaire générique | 5100 | 403 | Erreur « interdit » | +| Devis rejetée par le bénéficiaire | 5101 | 503 | Erreur de traitement | +| Type de transaction non pris en charge par le FSP bénéficiaire | 5102 | 503 | Erreur de traitement | +| Devis rejetée par le bénéficiaire | 5103 | 503 | Erreur de traitement | +| Devise non prise en charge par le bénéficiaire | 5106 | 503 | Erreur de traitement | +| Erreur de limite bénéficiaire | 5200 | 503 | Erreur de traitement | +| Erreur d’autorisation bénéficiaire | 5300 | 403 | Erreur « interdit » | +| Erreur de blocage bénéficiaire générique | 5400 | 403 | Erreur « interdit » | + + + +### Phase de transfert + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* agira comme relais transparent (*pass-through*) pour toutes les erreurs renvoyées par le commutateur. + +``` + "lastError": { + "httpStatusCode": 404, + "mojaloopError": { + "errorInformation": { + "errorCode": "3210", + "errorDescription": "Bulk transfer ID not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — transfert** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur de traitement | +| Erreur interne du serveur | 2001 | 503 | Erreur de traitement | +| Délai d’attente du serveur dépassé | 2004 | 503 | Erreur de traitement | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Identifiant de transfert groupé introuvable | 3210 | 404 | Erreur de traitement | +| Erreur d’expiration générique | 3300 | 503 | Erreur de traitement | +| Demande de transaction expirée | 3301 | 503 | Erreur de traitement | +| Transfert expiré | 3303 | 503 | Erreur de traitement | +| Erreur bénéficiaire générique | 5000 | 400 | Erreur de traitement | +| Liquidité insuffisante côté FSP bénéficiaire | 5001 | 400 | Erreur de traitement | +| Rejet bénéficiaire générique | 5100 | 400 | Erreur de traitement | +| Devis rejetée par le bénéficiaire | 5101 | 400 | Erreur de traitement | +| Type de transaction non pris en charge par le FSP bénéficiaire | 5102 | 400 | Erreur de traitement | +| Devis rejetée par le FSP bénéficiaire | 5103 | 400 | Erreur de traitement | +| Transaction rejetée par le bénéficiaire | 5104 | 400 | Erreur de traitement | +| Transaction rejetée par le FSP bénéficiaire | 5105 | 400 | Erreur de traitement | +| Devise non prise en charge par le bénéficiaire | 5106 | 400 | Erreur de traitement | +| Erreur de limite bénéficiaire | 5200 | 400 | Erreur de traitement | +| Erreur d’autorisation bénéficiaire | 5300 | 403 | Erreur de traitement | +| Erreur de blocage bénéficiaire générique | 5400 | 400 | Erreur de traitement | diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md new file mode 100644 index 000000000..ef5197b8c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md @@ -0,0 +1,191 @@ +# Prise en charge des transferts groupés par le SDK — conception DDD et *event sourcing* + +## Vue d’ensemble de la conception + +Ce diagramme présente une vue d’ensemble de la conception du SDK. + +![Vue d’ensemble de la conception](../assets/overview-drawio.png) + +Une réponse HTTP 202 lors de la soumission d’une requête asynchrone signifie que le SDK a **accepté** la requête, qu’elle sera traitée et qu’une réponse sera fournie. Compte tenu des délais potentiellement longs pour traiter un grand nombre de paiements groupés de façon asynchrone, une nouvelle approche de conception du SDK était nécessaire pour respecter les attentes liées à la réponse 202. + +## Conception DDD et *event sourcing* + +Un modèle fondé sur le *event sourcing* et le domain‑driven design a été retenu : il répond aux exigences de fiabilité et d’évolutivité tout en s’appuyant sur les bibliothèques et outils construits pour l’architecture Mojaloop vNext. + +## SDK Scheme Adapter DFSP payeur (groupé sortant) + +### Diagramme de séquence *event sourcing* sortant + +![Diagramme de séquence sortant](../assets/sequence/outbound-sequence.svg) + +## SDK Scheme Adapter DFSP bénéficiaire + +### Diagramme de séquence *event sourcing* — devis groupés entrantes + +![Séquence des devis groupés entrantes](../assets/sequence/inbound-bulk-quotes-sequence.svg) + +### Diagramme de séquence *event sourcing* — transferts groupés entrants + +![Séquence des transferts groupés entrants](../assets/sequence/inbound-bulk-transfers-sequence.svg) + + +## Mappage des données Redis pour le transfert groupé sortant + +### 1. États (global et par élément) + +#### Commande : +``` +HSET +``` +#### Clé : +``` +outboundBulkTransaction_< bulkTransactionId > +``` + +#### Attributs : +- **bulkTransactionId** : identifiant de transaction groupée +- **bulkHomeTransactionID** : identifiant de transaction *home* +- **request** : { + options: Options, + extensionList: liste d’extensions *bulk* +} +- **individualItem_< transactionId >** : sérialisation de ({ + id: transactionId + request: {} + state: état individuel + batchId: `` + partyRequest: {} + quotesRequest: {} + transfersRequest: {} + partyResponse: {} + quotesResponse: {} + transfersResponse: {} + lastError: {} + acceptParty: bool + acceptQuotes: bool +}) +- **state** : état global + - RECEIVED + - DISCOVERY_PROCESSING +- **bulkBatch_< batchId >** : sérialisation de ({ + id: batchId + state: état individuel + - AGREEMENT_PROCESSING + - TRANSFER_PROCESSING + bulkQuoteId: `` + bulkTransferId: `` (peut être batchId) +}) +- **partyLookupTotalCount** : nombre total de demandes de recherche de partie +- **partyLookupSuccessCount** : nombre de recherches de partie réussies +- **partyLookupFailedCount** : nombre de recherches de partie en échec +- **bulkQuotesTotalCount** : nombre total de demandes de devis groupés +- **bulkQuotesSuccessCount** : nombre de demandes de devis réussies +- **bulkQuotesFailedCount** : nombre de demandes de devis en échec +- **bulkTransfersTotalCount** : nombre total de demandes de transferts groupés +- **bulkTransfersSuccessCount** : nombre de demandes de transfert réussies +- **bulkTransfersFailedCount** : nombre de demandes de transfert en échec + +::: tip Remarques +- Les messages Kafka doivent contenir le *bulkID*. +- Pour mettre à jour l’état global, utiliser la commande `HSET bulkTransaction_< bulkTransactionId > state < stateValue >` +::: + +### 2. Mappage des *callbacks* individuels avec les éléments individuels du lot + +#### Commande : +``` +HSET outboundBulkCorrelationMap +``` + +#### Attributs : +- partyLookup_``_``(_``) : "{ bulkTransactionId: ``, transactionId: `` }" +- bulkQuotes_`` : "{ bulkTransactionId: ``, batchId: `` }" +- bulkTransfers_`` : "{ bulkTransactionId: ``, batchId: ``, bulkQuoteId: `` }" +- bulkHomeTransactionId_`` : "{ bulkTransactionId: `` }" + +::: tip Remarques +- On peut utiliser la commande `HKEYS` pour récupérer tous les identifiants de transferts individuels d’un lot et itérer +::: + +## Format des messages Redis pour le transfert groupé entrant + +### 1. Devis groupés + +#### Commande : +``` +HSET +``` +#### Clé : +``` +inboundBulkQuotes_< bulkQuotesId > +``` + +#### Attributs : +- **bulkQuotesId** : identifiant des devis groupés +- **individualItem_< quotesId >** : sérialisation de ({ + id: quotesId + request: {} + state: état individuel + quotesRequest: {} + quotesResponse: {} + lastError: {} +}) +- **state** : état global + - RECEIVED + - PROCESSING +- **bulkQuotesTotalCount** : nombre total de demandes de devis groupés +- **bulkQuotesSuccessCount** : nombre de demandes de devis réussies +- **bulkQuotesFailedCount** : nombre de demandes de devis en échec + +::: tip Remarques +- Les messages Kafka doivent contenir le *bulkQuotesId*. +- Pour mettre à jour l’état global, utiliser la commande `HSET bulkQuotes_< bulkQuotesId > state < stateValue >` +::: + +### 2. Transferts groupés + +#### Commande : +``` +HSET +``` +#### Clé : +``` +inboundBulkTransfer_< bulkTransferId > +``` + +#### Attributs : +- **bulkTransferId** : identifiant du transfert groupé +- **individualItem_< transferId >** : sérialisation de ({ + id: transferId + request: {} + state: état individuel + transfersRequest: {} + transfersResponse: {} + lastError: {} +}) +- **state** : état global + - RECEIVED + - PROCESSING +- **bulkTransferTotalCount** : nombre total de demandes de transferts groupés +- **bulkTransferSuccessCount** : nombre de demandes de transfert réussies +- **bulkTransferFailedCount** : nombre de demandes de transfert en échec + +::: tip Remarques +- Les messages Kafka doivent contenir le *bulkTransferId*. +- Pour mettre à jour l’état global, utiliser la commande `HSET bulkTransfer_< bulkTransferId > state < stateValue >` +::: + +### 3. Mappage des *callbacks* individuels avec les éléments du lot + +#### Commande : +``` +HSET inboundBulkCorrelationMap +``` + +#### Attributs : +- quotes_`` : "{ bulkQuoteId: `` }" +- transfers_`` : "{ bulkTransferId: ``, bulkQuoteId: `` }" + +::: tip Remarques +- On peut utiliser la commande `HKEYS` pour récupérer tous les identifiants de transferts individuels d’un lot et itérer +::: diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md new file mode 100644 index 000000000..c2ce4f454 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md @@ -0,0 +1,207 @@ +# Prise en charge des transferts groupés par le SDK — tests + +## Stratégie de test + +La qualité de la solution livrée est à la hauteur de la qualité des tests et de la stratégie de test adoptée. La nature distribuée de cette solution fondée sur l’*event sourcing* a influé sur la stratégie retenue. Plusieurs types de tests ont été créés, se renforçant mutuellement et visant à détecter les défauts le plus tôt possible. + +Le gestionnaire d’événements de commande et le gestionnaire d’événements de domaine disposent tous deux de tests unitaires et de tests d’intégration ciblés comme socle. Les composants API FSPIOP et API *backend* n’ont que des tests unitaires. + +Une forte insistance a été mise sur les tests fonctionnels, qui vérifient les quatre composants ensemble, sur des scénarios nominaux et d’échec. + +### Tests d’intégration ciblés + +Ces tests sont écrits avec Jest et vérifient par exemple le magasin d’état mis à jour et les événements produits à partir d’un événement de commande généré. + +**Banc d’essai d’intégration du gestionnaire de commandes** + +![Configuration de test locale](../assets/CHIntegrationTestHarness.drawio.svg) + +### Banc d’essai des tests fonctionnels + +Le test fonctionnel s’appuie sur le TTK (*Testing Toolkit*), qui simule les *backends* DFSP payeur et bénéficiaire. + +:::tip Remarque +Ce banc d’essai couvre à la fois le SDK payeur et le SDK bénéficiaire. +::: + +![Configuration de test locale](../assets/bulk-functional-local-test-setup.drawio.svg) + +:::tip Remarque +Ces tests peuvent être exécutés sur le dépôt *monorepo* extrait en local ; ils sont lancés dans le pipeline CI et inclus dans Helm comme tests Helm pour valider le déploiement. +::: + +## Matrice des tests d’intégration DFSP payeur + +
    + +|Cas de test|C1|C2|C3|C4|C5|C6|C7|C8|C9|C10|C11|C12| +|---|---|---|---|---|---|---|---|---|---|---|---|---| +|INT D-1||||x||||||||| +|INT D-2||x||||||||||| +|INT D-3||x||||||||||| +|INT D-4|x|||||||||||| +|INT D-5|||x|||||||||| +|INT D-6|||x|||||||||| +|INT A-1||||||x||||||| +|INT A-2|||||x|||||||| +|INT T-1|||||||||||x|| +|INT T-2||||||||||x||| +|INT T-3|||||||||x|||| +|INT T-4|||||||||||x|| +|INT T-5|||||||x|||||| +|INT T-6||||||||||||x| + +
    + +## Matrice des tests fonctionnels DFSP payeur + +
    + +|Cas de test|B1|B2|B3|B4|B5|F1|F2|F3|F4|F5|F6|F7|F8|F9|D1|D2|D3|D4|D5|D6|D7|D8|D9|D10|D11|D12|D13|D14|D15|D16|D17|D18|D19|D20|C1|C2|C3|C4|C5|C6|C7|C8|C9|C10|C11|C12| +|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +|FUNC 1|x|x|x|x|x|x|x||x|x||x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x|x|x|x|x|x|x|x|x|x|x||x|x|x|x +|FUNC 2|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 3|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 4|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 5|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 6|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|TC-BQ1|x|x|x|||x|x||x||x||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x +|TC-BQ2|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x +|TC-BQ3|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ4|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ5|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ6|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ7|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ8|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ9|x|x|x|||x|x||x|x|x||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ10|x|x|x|||x|x||x||x||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x| +|TC-BQ11|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x||||||| +|TC-BQ13|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x||||||| +|TC-BT1|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT2|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT3|x|x|x|x|x|x|x||x|x|x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT4|x|x|x|x|x|x|x||x|x|x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT5|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT6|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT7|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT8|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| + +
    + +## Référence des fonctionnalités DFSP payeur + +|#|Fonctionnalité sortante|Détail| +|---|---|---| +|B1|API *backend*|POST /bulkTransactions SDKBulkRequest| +|B2|API *backend*|Événement SDKOutboundBulkAcceptPartyInfoRequested| +|B3|API *backend*|PUT /bulkTransactions/{bulkTransactionId} Acceptation de partie| +|B4|API *backend*|PUT /bulkTransactions/{bulkTransactionId} Acceptation de devis| +|B5|API *backend*|PUT /bulkTransactions/{bulkTransactionId} Résultats| +|F1|API FSPIOP|GET /parties| +|F2|API FSPIOP|PUT /parties/{Type}/{ID}| +|F3|API FSPIOP|PUT /parties/{Type}/{ID}/error| +|F4|API FSPIOP|POST /bulkQuotes| +|F5|API FSPIOP|PUT /bulkQuotes/{ID}| +|F6|API FSPIOP|PUT /bulkQuotes/{ID}/error| +|F7|API FSPIOP|POST /bulkTransfers| +|F8|API FSPIOP|PUT /bulkTransfers/{ID}| +|F9|API FSPIOP|PUT /bulkTransfers/{ID}/error| +|D1|Gestionnaire d’événements de domaine|SDKOutboundBulkRequestReceived| +|D2|Gestionnaire d’événements de domaine|SDKOutboundBulkPartyInfoRequested| +|D3|Gestionnaire d’événements de domaine|PartyInfoCallbackReceived| +|D4|Gestionnaire d’événements de domaine|PartyInfoCallbackProcessed| +|D5|Gestionnaire d’événements de domaine|SDKOutboundBulkPartyInfoRequestProcessed| +|D6|Gestionnaire d’événements de domaine|SDKOutboundBulkAcceptPartyInfoReceived| +|D7|Gestionnaire d’événements de domaine|SDKOutboundBulkAutoAcceptPartyInfoRequested| +|D8|Gestionnaire d’événements de domaine|SDKOutboundBulkAcceptPartyInfoProcessed| +|D9|Gestionnaire d’événements de domaine|BulkQuotesCallbackReceived| +|D10|Gestionnaire d’événements de domaine|BulkQuotesCallbackProcessed| +|D11|Gestionnaire d’événements de domaine|SDKOutboundBulkQuotesRequestProcessed| +|D12|Gestionnaire d’événements de domaine|SDKOutboundBulkAcceptQuoteReceived| +|D13|Gestionnaire d’événements de domaine|SDKOutboundBulkAcceptQuoteProcessed| +|D14|Gestionnaire d’événements de domaine|SDKOutboundBulkAutoAcceptQuoteRequested| +|D15|Gestionnaire d’événements de domaine|SDKOutboundBulkAutoAcceptQuoteProcessed| +|D16|Gestionnaire d’événements de domaine|BulkTransfersCallbackReceived| +|D17|Gestionnaire d’événements de domaine|BulkTransfersCallbackProcessed| +|D18|Gestionnaire d’événements de domaine|SDKOutboundBulkTransfersRequestProcessed| +|D19|Gestionnaire d’événements de domaine|SDKOutboundBulkResponseSent| +|D20|Gestionnaire d’événements de domaine|SDKOutboundBulkResponseSentProcessed| +|C1|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkRequest| +|C2|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkPartyInfoRequest| +|C3|Gestionnaire d’événements de commande|ProcessPartyInfoCallback| +|C4|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkAcceptPartyInfo| +|C5|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkQuotesRequest| +|C6|Gestionnaire d’événements de commande|ProcessBulkQuotesCallback| +|C7|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkAcceptQuote| +|C8|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkAutoAcceptQuote| +|C9|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkTransfersRequest| +|C10|Gestionnaire d’événements de commande|ProcessBulkTransfersCallback| +|C11|Gestionnaire d’événements de commande|PrepareSDKOutboundBulkResponse| +|C12|Gestionnaire d’événements de commande|ProcessSDKOutboundBulkResponseSent| + +## Référence des cas de test + +|Groupe|N° cas de test|Type de test|Statut|Détail| +|--- |--- |--- |--- |--- | +|**Découverte** — tests d’intégration du gestionnaire de commandes||||| +|(process_bulk_accept_party_info.test.ts)|INT D-1|Intégration|Réussi|Étant donné la réception de l’événement de commande entrant ProcessSDKOutboundBulkAcceptPartyInfo, la logique doit parcourir chaque transfert individuel de la requête groupée, mettre à jour l’état de chaque transfert en DISCOVERY_ACCEPTED ou DISCOVERY_REJECTED selon la valeur de l’événement entrant, mettre l’état global à DISCOVERY_ACCEPTANCE_COMPLETED et publier l’événement sortant SDKOutboundBulkAcceptPartyInfoProcessed.| +|(process_bulk_party_info_request.test.ts)|INT D-2|Intégration|Réussi|Étant donné qu’aucune information de partie n’existe encore pour les transferts individuels et que la recherche de partie n’est pas ignorée, à la réception de ProcessSDKOutboundBulkPartyInfoRequest, l’état global doit passer à DISCOVERY_PROCESSING, un événement Kafka PartyInfoRequested doit être publié pour chaque transfert individuel, et l’état de chaque transfert doit passer à DISCOVERY_PROCESSING.| +|(process_bulk_party_info_request.test.ts)|INT D-3|Intégration|Réussi|Étant donné que les informations de partie existent pour les transferts individuels et que la recherche de partie n’est pas ignorée, à la réception de ProcessSDKOutboundBulkPartyInfoRequest, l’état global doit passer à DISCOVERY_PROCESSING, aucun événement sortant PartyInfoRequested ne doit être publié pour chaque transfert individuel, et l’état de chaque transfert doit passer à RECEIVED.| +|(process_bulk_request.test.ts)|INT D-4|Intégration|Réussi|À la réception de ProcessSDKOutboundBulkRequest, l’événement sortant SDKOutboundBulkPartyInfoRequested doit être publié et l’état global doit passer à RECEIVED.| +|(process_party_info_callback.test.ts)|INT D-5|Intégration|Réussi|Étant donné que les informations de partie reçues n’existent pas et que la recherche de partie a réussi, à la réception de ProcessPartyInfoCallback, l’état des recherches réussies doit passer à DISCOVERY_SUCCESS, les données Redis de chaque transfert concerné doivent être mises à jour avec les informations reçues, l’événement PartyInfoCallbackProcessed doit être publié ; si toutes les recherches ne sont pas terminées, ProcessSDKOutboundBulkPartyInfoRequestProcessed ne doit pas être publié, et SDKOutboundBulkAutoAcceptPartyInfoRequested ne doit pas non plus l’être.| +|(process_party_info_callback.test.ts)|INT D-6|Intégration|Réussi|Étant donné que les informations de partie reçues n’existent pas et que la recherche de partie a réussi, à la réception de ProcessPartyInfoCallback, l’état des recherches réussies doit passer à DISCOVERY_SUCCESS, les données Redis doivent être mises à jour, PartyInfoCallbackProcessed doit être publié ; si toutes les recherches sont terminées, SDKOutboundBulkPartyInfoRequestProcessed doit être publié ; si l’acceptation automatique de partie est fausse, SDKOutboundBulkAcceptPartyInfoRequested doit être publié.| +|**Accord** — tests d’intégration du gestionnaire de commandes||||| +|(process_bulk_quotes_callback.test.ts)|INT A-1|Intégration|Réussi|Étant donné une BulkTransaction avec les options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false }, un *callback* de lot de devis réussi et un mélange de réponses réussies et échouées par devis individuelle, à la réception de ProcessBulkQuotesCallback, la logique doit mettre l’état du lot à AGREEMENT_COMPLETED ou AGREEMENT_FAILED, chaque transfert du lot à AGREEMENT_SUCCESS ou AGREEMENT_FAILED selon le cas, mettre à jour les données de devis dans Redis, l’état global de la BulkTransaction à AGREEMENT_ACCEPTANCE_PENDING, et publier les événements de domaine BulkQuotesCallbackProcessed et SDKOutboundBulkQuotesRequestProcessed.| +|(process_bulk_quotes_callback.test.ts)|INT A-2|Intégration|Réussi|À la réception de ProcessSDKOutboundBulkQuotesRequest, la logique doit mettre l’état global à AGREEMENT_PROCESSING, créer des lots par FSP en état DISCOVERY_ACCEPTED selon maxEntryConfigPerBatch, publier BulkQuotesRequested pour chaque lot et mettre l’état de chaque lot à AGREEMENT_PROCESSING.| +|**Transferts** — tests d’intégration du gestionnaire de commandes||||| +|(prepare_sdk_outbound_bulk_response.test.ts)|INT T-1|Intégration|Réussi|Étant donné une BulkTransaction avec les options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false }, à la réception de PrepareSDKOutboundBulkResponseCmdEvt, SDKOutboundBulkResponsePreparedDmEvt doit être publié pour chaque lot de transferts et l’état global de la transaction groupée doit passer à RESPONSE_PROCESSING.| +|(process_bulk_transfers_callback.test.ts )|INT T-2|Intégration|Réussi|Étant donné une BulkTransaction avec les mêmes options, à la réception de ProcessBulkTransfersCallbackCmdEvt, l’état du lot de transferts doit passer à TRANSFERS_COMPLETED, les devis en échec restent AGREEMENT_FAILED, la logique doit parcourir les transferts et mettre à jour TRANSFER_SUCCESS ou TRANSFER_FAILED, publier BulkTransferProcessedDmEvt pour chaque lot ainsi que BulkQuotesCallbackProcessed, SDKOutboundBulkQuotesRequestProcessed, SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt, BulkTransfersRequestedDmEvt, BulkTransfersCallbackProcessed et SDKOutboundBulkTransfersRequestProcessed.| +|(process_bulk_transfers_request.test.ts)|INT T-3|Intégration|Réussi|Étant donné une BulkTransaction avec les mêmes options, un *callback* de devis réussi et un mélange de réponses par devis, à la réception de ProcessSDKOutboundBulkTransfersRequestCmdEvt, l’état global doit passer à TRANSFERS_PROCESSING, l’état de chaque lot à TRANSFERS_PROCESSING ou TRANSFERS_FAILED, chaque transfert à AGREEMENT_ACCEPTED ou AGREEMENT_REJECTED selon acceptQuotes TRUE/FALSE, sans modifier les transferts déjà en AGREEMENT_FAILED, mettre à jour Redis et publier BulkQuotesCallbackProcessed, SDKOutboundBulkQuotesRequestProcessed, SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt et BulkTransfersRequestedDmEvt.| +|(process_prepare_bulk_response.test.ts)|INT T-4|Intégration|Réussi|À la réception de PrepareSDKOutboundBulkResponseCmdEvt, SDKOutboundBulkResponsePreparedDmEvnt doit être publié.| +|(process_sdk_outbound_bulk_accept_quote.test.ts)|INT T-5|Intégration|Réussi|Étant donné une BulkTransaction avec les mêmes options et un *callback* de devis avec succès et échecs mixtes, à la réception de ProcessSDKOutboundBulkAcceptQuote, l’état global doit passer à AGREEMENT_ACCEPTANCE_COMPLETED, l’état de chaque lot à AGREEMENT_COMPLETED ou AGREEMENT_FAILED, les transferts à AGREEMENT_ACCEPTED ou AGREEMENT_REJECTED selon acceptQuotes, mettre à jour Redis et publier BulkQuotesCallbackProcessed, SDKOutboundBulkQuotesRequestProcessed, SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt et BulkTransfersRequestedDmEvt.| +|(process_sdk_outbound_bulk_response_sent.test.ts)#|INT T-6|Intégration|Réussi|Étant donné une BulkTransaction avec les mêmes options, à la réception de ProcessSDKOutboundBulkResponseSentCmdEvt, SDKOutboundBulkResponseSentProcessedDmEvt doit être publié pour chaque lot et l’état global doit passer à RESPONSE_SENT.| +|**Chemin nominal :** (bulk-happy-path.json)||||| +|- 1 transfert avec acceptParty et acceptQuote à true||||| +||TC-BHP1|Fonctionnel|Réussi|4 transferts vers 2 DFSP, avec acceptParty et acceptQuote à true| +||TC-BHP2|Validation|Réussi|Transaction groupée avec une erreur de format| +|**Erreurs parties :** (bulk-parties-error-cases.json)||||| +|- 1 transfert dans la requête||||| +||TC-BP1|Fonctionnel|Réussi|Le récepteur renvoie une erreur dans la réponse *parties*| +||TC-BP2|Fonctionnel|Réussi|Délai dépassé côté récepteur| +||TC-BP3|Fonctionnel|Réussi|skipPartyLookup est false et les informations du récepteur sont déjà présentes dans la requête.| +|- 2 transferts dans la requête||||| +||TC-BP4|Fonctionnel|Réussi|Le récepteur renvoie une erreur pour l’un des transferts| +||TC-BP5|Fonctionnel|Réussi|Le récepteur dépasse le délai pour l’un des transferts| +||TC-BP6|Fonctionnel|Réussi|Aucune réponse du récepteur pour les deux transferts| +|**Erreurs devis :** (bulk-quotes-error-cases.json)||||| +|- 2 transferts avec le même FSP bénéficiaire ||||| +|- acceptParty pour tous les transferts||||| +||TC-BQ1|Fonctionnel|Réussi|Le FSP récepteur fait échouer tout le lot| +||TC-BQ2|Fonctionnel|Réussi|Le FSP récepteur dépasse le délai sur tout le lot| +||TC-BQ3|Fonctionnel|Réussi|Le FSP récepteur n’envoie qu’une réponse et ignore l’autre| +||TC-BQ4|Fonctionnel|Hors périmètre MVP|Le FSP récepteur envoie une réponse de succès et une d’échec (non implémenté — issue 3015)| +|- acceptParty variable||||| +||TC-BQ5|Fonctionnel|Réussi|Un true, un false| +||TC-BQ6|Fonctionnel|Hors périmètre MVP|Acceptation de partie false pour toutes les réponses — alors seuls les détails de partie, pas de devis, état final COMPLETED (non implémenté — issue 3015)| +||TC-BQ7|Fonctionnel|Hors périmètre MVP|True envoyé pour une seule devis dans PUT /bulkTxn acceptParty, la seconde ignorée (non implémenté — issue 3015)| +||TC-BQ8|Fonctionnel|Hors périmètre MVP|False envoyé pour une seule devis dans PUT /bulkTxn acceptParty, la seconde ignorée (non implémenté — issue 3015)| +|- 2 transferts avec des FSP bénéficiaires différents — acceptParty pour tous||||| +||TC-BQ9|Fonctionnel|Réussi|Un lot renvoie une erreur| +||TC-BQ10|Fonctionnel|Réussi|Les deux lots renvoient une erreur| +||TC-BQ11|Fonctionnel|Réussi|Un lot dépasse le délai| +|- 3 transferts : 2 partagent un FSP bénéficiaire, le 3e un autre||||| +||TC-BQ12|Fonctionnel|Hors périmètre MVP|Le lot à 2 transferts n’envoie qu’une réponse de transfert et l’autre lot envoie le succès (non implémenté — issue 3015)| +||TC-BQ13|Fonctionnel|Hors périmètre MVP|Erreur sur le commutateur pour devise non prise en charge — (issue —| +|**Erreurs transferts :** (bulk-transfer-errors.json)||||| +|- Un bulkTransfer avec 2 transferts ||||| +|- acceptQuote pour tous les transferts||||| +||TC-BT1|Fonctionnel|Réussi|Le récepteur fait échouer tout le lot| +||TC-BT2|Fonctionnel|Réussi|Le récepteur dépasse le délai sur tout le lot| +||TC-BT3|Fonctionnel|Hors périmètre MVP|Le FSP récepteur n’envoie qu’une réponse et ignore l’autre (non implémenté — issue 3015)| +||TC-BT4|Fonctionnel|Défauts intermittents|Le FSP récepteur envoie une réponse de succès et une d’échec — (issue : 3019)| +|- acceptQuote variable||||| +||TC-BT5|Fonctionnel|Hors périmètre MVP|Un true et un false — TC2 — bug 2958| +||TC-BT6|Fonctionnel|Hors périmètre MVP|Acceptation de devis — tous à false (non implémenté — issue 3015)| +||TC-BT7|Fonctionnel|Hors périmètre MVP|True envoyé pour un seul transfert dans PUT /bulkTxn acceptParty, le second ignoré (non implémenté — issue 3015)| +||TC-BT8|Fonctionnel|Hors périmètre MVP|False envoyé pour un seul transfert dans PUT /bulkTxn acceptParty, le second ignoré (non implémenté — issue 3015)| + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md b/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md new file mode 100644 index 000000000..13a0e6217 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md @@ -0,0 +1,38 @@ +# Intégration des systèmes *core banking* via les transferts groupés + +Il existe trois modèles pour construire l’intégration du DFSP payeur dans le cadre des transferts groupés. + +1. Intégration de transfert en **trois phases**. Ce modèle s’aligne sur les trois phases de transaction Mojaloop : découverte, accord et transfert. +1. **Intégration double API**. Ce modèle est détaillé dans le diagramme de séquence ci‑dessous. Il regroupe les phases Découverte et Accord en une première phase ; les résultats sont présentés au payeur pour confirmation ; la phase Transfert s’exécute ensuite en seconde phase. + +![Modèle de flux d’intégration double API — transferts groupés, DFSP payeur](./assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg) + +1. **Intégration API unique**. Ce modèle est détaillé dans le diagramme de séquence ci‑dessous. Les trois phases sont regroupées en un seul appel de transfert synchrone. + +![Modèle de flux d’intégration API unique — transferts groupés, DFSP payeur](./assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg) + + +::: tip Commit en deux phases +Tous les modèles d’intégration DFSP payeur prennent en charge un commit en deux phases (phase de réservation puis phase d’engagement). +::: + +## Exigences côté DFSP bénéficiaire + +Les évolutions du SDK Scheme Adapter garantiront que les DFSP ayant déjà intégré Mojaloop n’auront pas à modifier leur intégration pour recevoir des transferts groupés : le SDK Scheme Adapter recevra les messages de transfert groupé et les convertira en messages de transfert individuels. Si un DFSP bénéficiaire souhaite tirer parti du message de transfert groupé, une intégration dédiée aux messages de transfert groupé peut être mise en œuvre lorsque cela s’avère pertinent pour le DFSP bénéficiaire concerné. + + +## Modèle de flux idéal côté bénéficiaire (groupé) + +Ici, les contrôles LBC/FT sont effectués et les frais calculés en phase d’accord, et la phase de transfert comporte une phase de réservation puis une phase d’engagement. + +![Modèle d’intégration idéal — transferts groupés, DFSP bénéficiaire](./assets/sequence/PayeeDFSPBulkIdealPattern.svg) + +## API éditeur limitée à un seul appel + +Si le système *core banking* ne propose qu’un **seul** appel API pour toutes les vérifications et phases du transfert, c’est le modèle le plus couramment supporté. + +### Appel du transfert sur la notification PATCH + +![Intégration DFSP bénéficiaire lors de la notification PATCH (groupé)](./assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg) + +Toute défaillance **après** la notification PATCH (étape **19**) peut entraîner une erreur de réconciliation. On peut y remédier en prévoyant des mécanismes de compensation (par exemple initier un transfert de remboursement en cas d’erreur après l’étape 19). diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md b/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md new file mode 100644 index 000000000..cae1a671a --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md @@ -0,0 +1,56 @@ +# Intégration des systèmes *core banking* à Mojaloop — modèles + +L’intégration d’un système *core banking* dans un flux de transaction temps réel de type *push* peut poser des difficultés, en grande partie selon les API d’intégration fournies par l’éditeur. Ce document décrit à quoi devrait ressembler une intégration idéale, certaines limitations typiques des API éditeurs, les modèles de flux utilisés pour pallier ces limitations, et les risques associés. + +## Modèles d’intégration côté DFSP payeur + +Trois modèles peuvent être utilisés pour construire l’intégration du DFSP payeur : + +1. Intégration de transfert en **trois phases**. Aligné sur les trois phases de transaction Mojaloop : découverte, accord et transfert. +1. **Intégration double API**. Ce modèle est détaillé dans le diagramme de séquence ci‑dessous. Il regroupe les phases Découverte et Accord en une première phase ; les résultats sont présentés au payeur pour confirmation ; la phase Transfert s’exécite ensuite en seconde phase. + +![Modèle de flux d’intégration double API — DFSP payeur](./assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg) + +1. **Intégration API unique**. Ce modèle est détaillé dans le diagramme de séquence ci‑dessous. Les trois phases sont regroupées en un seul appel de transfert synchrone. + +![Modèle de flux d’intégration API unique — DFSP payeur](./assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg) + +::: tip Commit en deux phases +Tous les modèles d’intégration DFSP payeur prennent en charge un commit en deux phases (phase de réservation puis phase d’engagement). +::: + +## Modèle idéal d’intégration côté DFSP bénéficiaire + +Idéalement, les API de l’éditeur permettent : + +1. D’effectuer les contrôles LBC/FT **avant** et **indépendamment** du transfert. +1. De calculer les frais d’un transfert **avant** et **indépendamment** du transfert. +1. D’exécuter le transfert en **deux phases** : une phase de réservation, puis une phase d’engagement. + +Lorsque ces capacités existent dans l’API éditeur, une intégration « idéale » peut réduire les écarts de réconciliation lors d’erreurs inattendues et présente le niveau de risque le plus faible pour le DFSP. + +### Modèle de flux idéal côté bénéficiaire + +Ici, les contrôles LBC/FT et les frais sont traités en phase d’accord, et la phase de transfert comporte une réservation puis un engagement. + +![Modèle d’intégration idéal — DFSP bénéficiaire](./assets/sequence/PayeeDFSPIdealPattern.svg) + +::: warning Limitation fréquente +Une limitation courante des API éditeurs est de regrouper toutes ces opérations en un **seul** appel, en une **seule** phase, pour effectuer le transfert. +::: + +## API éditeur limitée à un seul appel + +Si le système *core banking* ne propose qu’un **seul** appel API pour toutes les vérifications et phases du transfert, deux modèles méritent d’être envisagés. + +1. Appeler le transfert sur la notification PATCH + +![Intégration DFSP bénéficiaire lors de la notification PATCH](./assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg) + +Toute défaillance **après** la notification PATCH (étape **17**) peut entraîner une erreur de réconciliation. On peut y remédier en prévoyant des mécanismes de compensation (par exemple initier un transfert de remboursement en cas d’erreur après l’étape 17). + +1. Appeler le transfert pendant la phase de transfert + +![Intégration DFSP bénéficiaire pendant la phase de transfert](./assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg) + +Ce modèle est en général déconseillé, car l’annulation d’un transfert est souvent impossible. Il devient pertinent lorsque le transfert porte sur un compte interne (par exemple remboursement de prêt). diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/README.md b/docs/fr/technical/technical/sdk-scheme-adapter/README.md new file mode 100644 index 000000000..65a8e8edd --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/README.md @@ -0,0 +1,56 @@ +# SDK Scheme Adapter + +Un *scheme adapter* est un service qui assure l’interface entre un *switch* conforme à l’API Mojaloop et une plateforme dorsale DFSP qui n’implémente pas nativement l’API Mojaloop. + +L’API entre le *scheme adapter* et le backend DFSP est du HTTP synchrone, tandis que l’interface entre le *scheme adapter* et le *switch* est l’API Mojaloop native. Il existe une exception à cette règle : les intégrations en masse (*bulk*), qui peuvent être configurées en mode synchrone ou asynchrone. + +Le **SDK-Scheme-Adapter** est soutenu par la communauté Mojaloop et est considéré comme la référence en matière de méthode de bonne pratique pour qu’un DFSP se connecte à une API Mojaloop. Le SDK-Scheme-Adapter est le plus souvent utilisé et déployé directement au sein de la solution. Ci-dessous figure un résumé des différentes façons dont cela peut être réalisé. + +## Modèles d’adoption du SDK + +Selon les règles du système, les DFSP interagissent avec le Hub Mojaloop central selon quatre modes courants. Ce résumé met en évidence le rôle que joue le SDK-Scheme-Adapter dans chacun des modes, fournit un bref aperçu de chaque mode et souligne les avantages dont bénéficient les DFSP. + +### 1. DFSP utilisant une solution tierce (ex. Payment Manager) intégrant le SDK Scheme Adapter + +Plusieurs solutions tierces proposent un support, des outils et des intégrations au sein des systèmes dorsaux en s’appuyant sur le SDK-Scheme-Adapter afin de prendre en charge l’intégration synchrone (selon les bonnes pratiques Mojaloop) pour se connecter à l’API Mojaloop. + +*Payment Manager*, outil *open source*, en est un exemple. *Payment Manager* offre des avantages supplémentaires à ce sujet ; des informations complémentaires sont disponibles [ici](https://rtplex.io/). *Payment Manager* peut être déployé en SaaS ou en auto-hébergement. + +![SDK-Scheme-Adapter Mode 1](./assets/SDKSchemeAdapterMode1.svg) + +- Le SDK Scheme Adapter est intégré directement à l’implémentation personnalisée. +- Maintenu par la communauté, il offre une trajectoire de montée de version vers les nouvelles versions de l’API Mojaloop. +- Solution normalisée pour une intégration rapide +- *Core Connector* co-développé avec des intégrateurs ou éditeurs bancaires +- L’interface utilisateur de *Payment Manager* prend également en charge les opérations métier, l’intégration sécurité (*security onboarding*) ainsi que l’automatisation de la maintenance + +:::tip Composants open source +Ils sont sous licence Apache v2.0, choisie pour limiter les conflits avec les politiques d’entreprise. Sans contrainte de type copyleft, les adoptants peuvent personnaliser des éléments — tels que les *core connectors* — sans être obligés de reverser ces détails confidentiels à la communauté. +::: + + +### 2. DFSP avec son propre Core Connector et le SDK Scheme Adapter + +Dans ce cas, le DFSP choisit de développer un *Core Connector* sur mesure entre son système dorsal et le SDK Scheme Adapter Mojaloop. Il peut s’appuyer sur les guides open source pour développer ce *Core Connector*. + +![SDK-Scheme-Adapter Mode 2](./assets/SDKSchemeAdapterMode2.svg) + +- SDK Scheme Adapter intégré directement à l’implémentation personnalisée. +- Trajectoire de montée de version grâce à la maintenance communautaire. +- Développement selon les guides *Core Connector* open source +- Support de la communauté Mojaloop +- Exploitation par les équipes techniques du DFSP + +### 3. Solution de connexion Mojaloop entièrement développée par le DFSP + +Aucune connexion standard n’est utilisée : le DFSP choisit de développer sa propre connexion au Hub Mojaloop. + +![SDK-Scheme-Adapter Mode 3](./assets/SDKSchemeAdapterMode3.svg) + +- Basé sur la documentation de conception open source +- Support de la communauté Mojaloop +- Exploitation par les équipes techniques du DFSP +- Le SDK Scheme Adapter peut éventuellement être utilisé comme référence +- Cette implémentation dialogue directement avec les API asynchrones Mojaloop + + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/RequestToPay.md b/docs/fr/technical/technical/sdk-scheme-adapter/RequestToPay.md new file mode 100644 index 000000000..fb317118b --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/RequestToPay.md @@ -0,0 +1,28 @@ +# Demande de paiement (R2P) — prise en charge du cas d’usage + +Cette documentation décrit comment le SDK Scheme Adapter prend en charge le cas d’usage *request to pay* (demande de paiement). Ce cas d’usage est à la base de tous les transferts initiés par le bénéficiaire. La prise en charge exige que chaque DFSP sur un commutateur Mojaloop traite automatiquement un transfert dès qu’une demande de transfert est reçue et validée. L’intégration de ce cas dans le SDK Scheme Adapter est importante car elle réduit l’effort de développement de chaque DFSP lorsqu’un schéma impose le support par les participants. Ce cas d’usage est particulièrement intéressant d’un point de vue test, car il permet des tests à distance en tant que DFSP payeur et DFSP bénéficiaire. + +> Points importants : +> +> 1. Toutes les fonctionnalités n’ont pas été entièrement testées et mises en conformité avec la spécification FSPIOP ; consulter l’épique suivante pour l’avancement : [#3344 — Améliorer le SDK Scheme Adapter pour le cas Request to Pay](https://github.com/mojaloop/project/issues/3344) ; +> 2. Il n’existe actuellement pas de tests de bout en bout couvrant l’ensemble des fonctionnalités, y compris l’authentification au moyen d’un OTP. Voir la [publication de la collection de cas de test du Testing Toolkit](https://github.com/mojaloop/testing-toolkit-test-cases/releases) pour ce qui est testé aujourd’hui : [testing-toolkit-test-cases@v15.0.1](https://github.com/mojaloop/testing-toolkit-test-cases/releases/tag/v15.0.1) ; et +> 3. Tous les cas d’échec n’ont peut‑être pas été entièrement implémentés. Se reporter à nouveau à l’épique [#3344](https://github.com/mojaloop/project/issues/3344). +> + +## Diagramme de séquence + +1. Le DFSP bénéficiaire démarre le cas R2P par un appel API **POST** `/RequestToPay`. +2. Le DFSP bénéficiaire peut, en option, valider le payeur. +3. Le DFSP payeur exécute la demande R2P par un appel **POST** `/requestToPayTransfer`. Si le type d’authentification n’est pas fourni dans cet appel, le flux suppose que le payeur confirmera le transfert et ses modalités via un **PUT** `/requestToPayTransfer` ; sinon, le flux d’authentification approprié est exécuté. + +Le diagramme suivant résume ce flux. + + +![Diagramme de séquence R2P](./assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg) + +## Diagramme de séquence détaillé + +Ci‑dessous, un diagramme de séquence plus détaillé pour le cas demande de paiement et les appels API du SDK Scheme Adapter. + +![Diagramme de séquence détaillé R2P](./assets/sequence/SDKrequestToPay.svg) + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg new file mode 100644 index 000000000..579441a56 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg @@ -0,0 +1,3 @@ + + +
    SDK-Scheme-Adapter with Bulk Enabled
    SDK-Scheme-Adapter with Bulk Enabled
    Payer DFSP

    Core banking system / Beneficiary Management System
    Payer DFSP...
    Mojaloop FSPIOP
    Mojaloop FSPIOP
    Backend API
    Backend API
    Domain Event Handler
    Domain Ev...
    Command Event Handler
    Command Event...
    FSPIOP API
    FSPIOP API
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    State
    Store
    State...
    State
    Store
    State...
    Infrastructure
    Infrastructure
    State
    Store
    State...
    Producer
    Producer
    Consumer
    Consumer
    Dependency Injection
    Dependency Injection
    Kafka
    Kafka
    Domain Events 
    Domain...
    Command Events 
    Command...
    Redis
    Redis
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio new file mode 100644 index 000000000..b308a656b --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio @@ -0,0 +1 @@ +7Vxtc6M2EP41nmk/xAMSrx+TOLnMtJmmzc302m8yCKMLRj4hkri/vhIIDAi/JdhxcsnNZZAQAvbZZ3e1KzKCl/PnLwwt4lsa4mQEjBkj4QhORgCY4r/oWKAZbnXIEffkv6rTUL05CXHWGsgpTThZtDsDmqY44K0+xBh9ag+LaKI/xn2AEqz1/k1CHpe9HnBX/TeYzOLqRqbjl2fmqBqsHjyLUUifGl3wagQvGaW8PJo/X+JESqaSS3nd9Zqz9YMxnPJdLsj/DazfEP6GF06ef7m8QR78ceaUszyiJFcvfIeWmImuyfX9nXpwvqykwWiehlhOaIzgxVNMOL5foECefRLgir6YzxPRMsVhiLK4GCsbEU25AtP0ZJskySVNKCsmhlEUgSAQ/Y+YcSLEf56QWSrOcbqorlaPIWfLOKMPuHF96Ewd2xFn1PuIWfDzWkGZtfiFUmI6x5wtxZD2Bcuy5Sj4nlboW6bCOG4gD301ECkFm9UTr0ARBwqXPTCqNL8B0i39jhIqRAOMm3z6OpikbK/RnCTyhW9w8oglAG3IgKlDFiLsRUEfGE7g4WnUA1s/uANAZpvuNtBgJcbjgAY1zLLw4SwLYjzHZyhECy5Z9hrcGOWIE5qq0bsRp0s7W/5T4xr95U8vtsVPh9DWMCgCt00909BhNK0+7tkH456t4fjl6utImtpr8WKcCFfURRGHwoOoZkpTXGDVBJYyHtMZTVHyu+Rwicx3zPlSCRTlnLbBFhJky2/q+qLxj2yM7ao5eW6enCxVq8Sv8lzOjnQ3y4nCc+kvRXua0OCh7LomSdKvS6GNvdDq0xkPTGGhMwma4uQCBQ+zQiDVECWkTKg6SWfqyUuxSlm+UJuMsQEMr61QVtlkOBHUeWzP3Kc7avI7SsQ965mhZ7Sndez2FBnNWYDVVU2X3JnIhm5nIjjuTMURm2G+YapqII2iDHNN4Wu5vJwDrkaBLYbrBfrdVD7Y1PczASO0O0pv+FvUfn/V1ImyVf/xM+EFJceGD1VbPqA5NjzVXD2ebCwbjTvMiAAGs+bzdzs382VXhgikCn3c5K0UpKW2bRhYxr1rOSfQMqvgSOk0NAbhnOm1fUO9HtiXcxBaY9fezN8TIJ3pHMevKB02G/qrvMpa9X2ZTwHmC3xKFGEn6I0xQ9efGvv4iR1Y4Pfr9is11+tENTUjtmjbUJrk95hvJxGiuRALB2cmDyYkC6gI3ZbVGXGj+mQ9mlU9f+GMCozlKxS3X1AuZE1QUggrIAsimpmM22ISxHItXIRqwJgW1xQESqVkaSRtTozVclNeIuLZqivD7JEIwLo8EAEmb2vxerO+zhEgFSUH4kmludXC5zkJQ3nD3ii8Tbum77IHWs90AwNQBwaNWBi4PUsa71ChcI/bf98WSawZ97dI2BQ65PbpnO+4EDnDWiRzjZoMbZK6SnNgk2Sa223S+YxhsVaWD7CLTbpChaUps1YGkaZkwegjkbpYGRS6WAiFzFPCpQyF4okxmEWUzcXR+e3v4rdYnwcPWWGg5HUolL8DmhXmjMq8WChtZV7at2IKXN6ZM5RmUc+ifgdzVavOOmV7Z+YKWPrC/cjGCn4aq53WPUMaK3AYY9WJ/OGR4ycTbDdWX2vyv9BWMfwjxxkvjRUtjVeAi+YT4XFtwiorMxbHIgzLk8IOCbAKM5UIQRfXlNZL3uCX7FdxlFJOIoLD8WcwJbOF9psHU6anKdXdH/cqsTjNk4c/cxFUHym3WOcxfKdlxxzobLRk7yApuUO4tjnJ0perGdBmAqUHWxMv6yLBVeLFcKsIvU6fj4bIvFhGO9upkWJr5uUI2RJ9kdumU2Wgj8soc2yAdmTggffOqFen+Q/MqCo62M6oNeFKXT4wLcNqE8oehFDQ1TKQNcdOiVN63l/uDaiSNRqRshgtCjoEXMK9rXzZjRGmlHM6H9VloAvVnpxZ3qr3a8FAy+oJjtulzteHDX5nIwCw9UWN1RMzHKwWWW0k2VSI+XAgdCp4fSvL44LQl7r44CB4/poM9puBoFflj+PXm1VJ0HHR1oGcNDyMkz5owXGr84XGRo2Tzhe2mV+vw1+bTmhHs3Bvz7u+jqh58ROoIwJLo8olTSPC5uXmIVWEkXtZpPxJKtOh6tQxGXXihHr9OrKPbgMSCjgbCSUMFtB2wwwTznYIBdx9N8McIZTVOCDwwBEJCCqEdItSNFPFBuM+n2bLjOP58fy6CzS/7nWU1tL0HRzA08OOo3/zaEvfnzxFvFVv6VnRJwlZZJJ0FWD5XHBZEJAm21HbeeHctBDVDjYNoEEw6RDM0pOXdh8o9qFA0ReGUVEa21YJ+2jAAF/bSQSdN8ZGzyu3sFHs+eDAOCfGGKiv3H9CVGAn8nbgG6OyfheC8MVpCwznR05VMW91VBTzOtH0muKdXh8sb1GVCDvQb6vKKZx6oBuyFtcfb+wUXzc+TgDGMPrjdqp4ph6b1N9atT4OONgnHmAI/bnIkwcxdEKyac6yKggtisKckdkMM6lIP5/anA1W/u18VOK9ud7skL068Q31O+zL/cAb6t9g+7vrjw3Tsmzg+Z7nGG4nKw6tse+ZruM4ru0b/gs/R4GgkyBw4NjvTnYCOS2orwo/P8oa9eatdiDq50dZ7/GjLNj3VdbJbuvfM05pquc6hX5nm84Ou4NfNFd/SKBUsdXfWoBX/wM=7V3blpu4Ev0aP7YXQkjAY1/SmT6ZrOlMP0xy3jDINmkMPhj35Xz9SIDMRcLQNhho21lJTCEEVG1tVRVWMYG3q7evobVefg8c4k1UZRG6zgTeTVQV0L9UsLYWpCBgLZ7c/3Ohkkq3rkM2hYZREHiRuy4K7cD3iR0VZFYYBq/FZvPAEy/jybY8Ikj/cZ1omUgNVc/kfxB3seQnAthM9qws3ji98M3ScoLXnAh+mcDbMAii5Nvq7ZZ4TDNcL8lx9xV7dxcWEj9qcoD+nx//De6dHw/fyOzX5ufXV/frjytDS7p5sbxtesdPd9+unuwlWZGra8daRySk+19dejeqcrP1nul/X3xr5hEnva/onSsrDLa+Q9j5lAm8eV26EXlaWzbb+0ptT2XLaOXRLUC/OtZmGbdlG5soDJ53Gqa6uZkHfpRaHyC6/ULCyKV2ufbchU+FUbDmrdILSDXCGpK3SiWBneopIEmwIlH4TpvwA4zUWu/Jtpluvma21/RUtszZHXGhlcJrses6Mwn9klrlIxbSBTUTh0I03QzCaBksAt/yvmTSm6IhsjZ/BkxrscZ/kyh6TxVsbaOgaBzy5kY/c99/sa6mKN26e0t7jjfe+YZP75cddKVMFQC4JDlUQyoXZEfHW4XDH0noUr1RzCXCIi6gBBebyAqjazawqWTmBfYzF9673u52fIc38QOfJJJ0PztNomKm1/24oWYItqFN9tiLc5IVLki0px2U4zAknhW5L8XraB1UfKhko36iYi9io9J9oV8XUayURMQ0zu6cUzH+35Zx1g3IvpYPmRUAy1uxjq6Sbq5pA4DXb8kxpV4erfeYdO7unx4njNXSTsPyaei9zySy5IIFseTWhnC3p7m92yAk9Cpmlv/s+gt2we+biKxi9d4zZic+mbu2a8Uo/G75dGJbkVgVT2lL+ZmOmQLmdATeBl4QxsfCOWJ/UtXl5Mlnxwa5PTj+7K7jKOrXiswPsEj9QJFQP+iM+tVBj9LvwW/LY/OJqtBx+vDXYwuwbRFMjkWMuS0FjW2Q2bwd0GBjcKgxjD4dBu4VJLO+3tBjAFMFFv0FA6NP4C8cMb+nhz4GbjyuU7ypilnAm6ozr6zQSeKhpMfl44FSV0CDQleKZmafUr+JRyP0S/VkveearVmDTfUd7EZIdtr9l7m/Pf2SXEE2YHbaPnwMQYF5byz7mWKACq8fH44kqhwisWQWnBNsS4nL0c2ZorRDXGUgASQSlynhrV0c3jpviZHoXbCyXJ/Fmy+JJ/KH5Tsecw07Vf9crVA/nmHUkrMB1Xr1y+LM7tSPBPXfBquVFUP+pPo3bCLX/8xAGmoJ/ho9dZ3+ATipAbBgAO5WdU45BDiI6DKdm1iHVkuYR7AB5sFJKUfkHEHPC6ro9SSfUmS5r0k+s3ccEavGVNVz065eUBKkuzUV6UBTDfYvFFSmaVPVyB2PNYkK4ZR3EP+L9a40qpxCo3uMKer5g6oCp1IVNOpVtVlaa/bVfvdcOtpDWD/UZwkv/DnbCajnsojZ4q9tRLshqTyNFDV6u9kNYwVJ6CIMIuq0BiztairdhVp7EFWdsC0OlyuApkjPhotqGiKvK1M+++YNz8BhdmVrU7D1Yxg4W1symVINRUWTFtWaBiR5G6QiK02N21SjLCIScuYr13HicE+GoeKEkoNAY/o/xH7a1DQhUk0NAB1rOlAFc0FmrnS3ggyDD5N9g1ZTu+I3Wea0X37js6nkScWQ6I6b5EJ3+61c83xqFHSnifHzbeBvtqszoLuauGNkdCcGJR3QXU2oDKmDbBRgPzanWO9v0sBy3Q52lrg4xY3Mqn+GWeKMneL99hvZLIF6DPor+G0kTjFqEE5c6C4F2MjpDokB0Lk4xTX2GxvdidFNB3RXE0fENFaA/cicYnSS3PseA47HKUbis7nLLFGFqLHPEmLEfS5OcY39xjZL9Bf0V/HbWJziSw6gkZU/Qw4AiTmAs3GKP1UOAJ8kB1DzAxNt7Jli3N/jRVwRow11lsBiOH2ZJaoQNfJZAosR97k4xTX2G9ss0V/QX8VvI3GK8SUH0MjKnyEHgMUcwLk4xTX2GxvdyXIAuRV89avvqhbfPdEhRhos/jzmDPGK0Ubr9E5APHhaMJgKDkRdzXSKwRQWVwaoJpjyXE6eFsxdqJGHFuxsdYAsKXKB0nChBJE2UCjpjYPM9ldod7OEorSWTZMsLNFki3l21T7aH65iXuvBn4cW1c/WjrZsOJQ0fuh6HrXsYqXTe5PyKrvCKVXlVQ6fyPUKk/VnEtEiktX0TclwkMQGZN54+ybko44vD01HnWTluyEzsNKVgbk32ENwWaMqqNdpCsgWe0LUlaYaJGv7wmuf0WOCoEozYp2vtefxYybJhyBIgvrOyj0AcTYfT27sSIaqsRcsEpTMVkCBorFU2JWtTvLLoRYYCkjSYcCQqEpTy+Un2lNWg1zhWZJUxdP9QZOUrLrAWDJax5LUfnsNjqR00Tm4I2tCdePb7Lof/N+UlBj4h2m5D9aVbJ9S95WCwhI3T+1q1BniqPtmzZ+tz2G4j5f+PGRiNNXC8ISiTWUm7S53I4tx8kk6bpAsC+eReSTm5Iq1dTZUbK2YSfzZJgn895dd3BfpisWzcsCqZlkkSTfVl0Iq4iQb0IfU5kpNfqVMDZ4jy9kZSezMZUdW9ULFOQCaJfg0LemlKzUdVdTwyjriDYP5fEMKbdoqraXL3LpDEFwqTzRQCDcorfMpIFyq0qaVJ7VDIawBc2rmP8MDdK8FmrOizL8muQqL8nKLdOPjBRNzY4GXS8yKIcqquDatX9dKueWkio44EI6EMyw9UmjKpK2Bqt8ingVQgW5BJS2w2ahKZ6/A0ypyT0cCD5g9A88cDvC6YLMCsFLo5XGlHMB4jcvntQO8bhhPKz9ELc/gHQOPPysaAvC6YLxW6g73yniom5LGEPTLeAYYDvDGwngnBh7qBHiIPzDuC3ji84wL8AYFPNyNj4f7Zjw4HOCNZao9rY+HOvLx1CLjndzHE3/Y/jdx3I0AxzN5IFGznBEUU2EIiBm9kz58MHqNDS+vIuv21SKYw4v/Wlk78MUiWDep0kt9aVMT5NdSNeKdj75bBJffFZLeQuWV7m8/6eTdIma/gW5hFF3ez9P2ICq9D+qI9/Ng/gOo076fB0NQPu3+y9zf/qNjiG5mr0RNmmdvjYVf/gU=5Vrdc+I2EP9reAxjSf58TAJcM3eZ0iG93j11HFsB94zl2uKA/vVd25KxJZMQaiBDH2Cs1Vof+/Hb1coDcr/cfMr8dPHIQhoPsDHPonBARgOMEfyAkPpz2iIUHLPoH0k0BHUVhTRvMXLGYh6lbWLAkoQGvEXzs4yt22wvLNaXMQv8mGrUP6KQLyqqi50d/RcazRdyImR7Vc/Sl8xi4fnCD9m6QSLjAbnPGOPV03JzT+NCMlIu1XuTPb31wjKa8ENecKbf53/dPnz98uckHbvh42NKnm7EKD/9eCU2PPW3NAPSbPRZrJtvpTAytkpCWoxnDMjdehFxOkv9oOhdg26BtuDLGFoIHl+iOL5nMcvKd8lkMrY8D+hiRppxutm7FVQLCMyGsiXl2RZYxAvYsapXtoJbyni9U1FNWzTVI4m+sIJ5PfZOcvAghPcOQeJOQdKTCPJ+7E36EaRlGB9NkEQTZK/SG9sjYzTuR3qEtM2QIF162D6r9My3pUeT8LbAQWglLKFtaVXcNJyr8PemTBp7tjq2LGkZjX0e/WwP3yUGMcOURTBxLXLTaRusSRRJ5myVBVS81UTDNwaqdScH4n42p1wbqNRKve3jFWXtB96HR01nYKO8raicZ+wHlYYtFNm0dUHy42ieQDMA/cHw5K6w+Aji263oWEZhWEzT6UdtT+vDZRTkJrbuMmaH+ZzMYez9uH3NejC9D6YHpwO47LgQ9jM8zHm57YrwwkpH3qnF/nvFZMdNXmaMt8CA3HSz65SjPD19lgPBQqux2uMDuTHn1VoAaluAaeoW4J7TAtx3ha4g9vM8CtqqoJuIf4PnG2NowPYqwvdCZkPXxKI92gghlo1tozGlWQR7KZRT0kI/X5Qif09khAWXIeitFOdSERQbSu7sGEMTIceGiGi5Lib4uICq5eSOsrQ9ARUU6m8bbGnBkO9fP7IUu0Xo1XWp/HJdO1OtVtBrdPc0W0ZDaE9/nT0NCgeaPK/iH0+b5HrhBeG22HEHvJw1wMj8rg98QUPDcFvwgiz3w8DLhRN0Re+qQg/FE+1oStyh5xHLMkzbsTwkw9eZ8nWkV0pw4dKfxsKjQVM8ovn1erSpBo6O065zVo/Way7v9uhD3e5S7mRjLVof6U5qwq8enHsKz7aWBhivrkvll+s6aXhGepGJ/L+c2Tb3wPSlsn/0vspVd3hOYCXfmo0qOBNLtnfBuWxtm62ewnPlRx82PCswgOwj031LBSb7MDzpzYX1AppZpti/qy48eRhdrx+rp3hkXTrN1gtqVksv9cnnqvWiXg3gDr10JUvEPZVeugpsRx5/5IGmQlcsCy17Tj4SlI02KDtvgfJJqy8fHafVKg1WryeOxmk1gewp78MKEBHz9bxP5ZcbPG3ep9cY7VfAyfCDlE/5tq5EZ7Is7AfQ89uKcXq9EIbV282Lp4h6Vc1fcXYbBBTUBOF+W9X9X/w4px06q3krxTV5r1WHRC2Wdlzvd6GYmsz195lEj1U4GUNEJEIHhqEhQl4zFBWXBficJ4TDCngHRKiL3iNohT6vpwhVG+mZThJYr+wdddNYXiAql413EE8KTdKcR8kcnm7g94UBHhTDUr5KBxhWbSQM/mbriAcLeHimfE1pUlrPlmYveVpIIwkFgZaEfVeY/rJAkuQ5Tw+7vswo7MN/LhkMAZPVzsruwwFNZAgwjXU3sEbd+NiJo23YK/YjPvtDrmyLHUhV/aebCfXIpGOi3fXJk2qWB2AiNHff91X2uvsEkoz/BQ==7Vpbd5s4EP41fkwOIMD4MXbSJtm0zTZ7afuyRwbZVg3IFXJs59evZCRAIN8S3/ZsHhKjYRAw8803oxEt0EvmHymcjD6RCMUtxxpSHLXAdctxbP7HBRM4RJpAaDzhFyW0pHSKI5RpioyQmOGJLgxJmqKQaTJIKZnpagMSNx/jKYQxakj/xhEb5dLAaZfyW4SHI3Uj2+/kZxKolOWDZyMYkVlFBG5aoEcJYflRMu+hWFhG2SW/7sOKs8WDUZSybS6YfOz+ShP848vt4CrLfo5/BJ27CznLM4yn8oXv0gGFGaPTkE0pko/OFsoelEzTCIkprRbozkaYoacJDMXZGXcvl41YEvORzQ8HJGXSg45QH+A47pGYUC5IScrl3Qhmo+V0Qp/flowLOztqBnl3ofGMKMPcO1cxHqZcxoi4pXwJfg7NV1rHLmzOkYhIghhdcBV5gWNJvy3ysetJt81Kr7sKg6OqxwMphBJYw2Lu0hn8QPrD7Jtf7t38MXpIX7qzC/j4D5xR9tdFAZzS+iji4JRDQtmIDEkK45tS2tX9U+o8EGGppQ1/IsYW0i1wyojuMzTH7Fvl+LucShxfz6sDYSngXHpy/Igo5i+OqNJJuRGKmcTge3VQzrUcLaqj+lQ6LoCOLNtbakDKrkR4l9Bayj5gYXQ5daQ0+jEJx7lIKtg1eLYcMAhCFIbF7Stn+oEn8KGAJ7yyHnbciWRKQ6l1/Xv46etn8OJ+/vP+no5Y79tkrCKRP/MQsTWoAGYYUxRDhp/15zBBcnkptwNcVBQmBKcsq8z8KARldPgqGmR0eC7QuWaDvoqcMhzyJyiDo3iVN8RLk8w40XFS4DKS8n9PDDK0/CWC2azeCKZDlBmj7AH2eZrSIgNKzgm5bwU0G2SU4CjKgxBl+AX2l/MJmEjz8sm9bsu7NuA3FrfrwnA8XAZwjSS1jCbnLRPLBt5bwy0r2dC6BG3fz+faDVkNKNgaEC7sGluSwSDjeK9z5W5wWBdQFTS0HD9mIufgZ344FIcSErmc36Zyyqi9BI5ZuwYinu4n4jBcxJgzMgWb02U/5+6HfiEoAPFlyvg0KgtmFeRUkeTvJxe6HT0XenYzFwamVGjtIRUafekYfFmzt7DT5E2BsqFAcF3dKJ5IfXWz2G2DXYB3ILOAzWY5FQwp4ZGFiaDFTr304xk0gigYGHOrHwaoP9gWyKvRstKRflv5TXFSKal4UjlNA3j7UAB3G558pCSahjzP1D3KzcF0h+k2lDnDUGtvn8BMCNEry1fRziu8BfRCwuQp2wJNVzngQJ7yzoGK/I38bAcGo7gFZe3dLP47Fa1Ey3+LitoNT/ZImk2T/wEVrffW2VFRp+GpryjCzfXMebhpm05PPYqLzs/bSbMgyYI07Yb7fFPxdqj2TnN98hscjOG798yxp68j3aCZ8o7rvaDhvrsUM8yXkzwArT9QxhqePEL37jSdsshDQeSaUmjg9IHvb9ng2LWPtkt/TOLowrr0PF9fyRU9iTd2Ohy3xjD1znDe25NXlfjbtRln+/p9QLvW+N+gr57L2Iwrr95rh8YcQ80EpjfsJCFaCcqyVY26Q7fDVRfbyhvdx+xjq9irhqeth6eMnzI6DQXuFn1s1fRXx8UbGpv+alB/vePGuN4rX70oWccFTsdf0Z88bD+dJys9ndnrQ7iu7znBeYRwswN1v8x8MgFaTyHFk2YmVEvBaRJfhYxUa5Nl4/2RZFgu2fqEMZIYipd8668SqiRfEfaKjd9myBlLlWbhtI+CJdCTDDDsJwJDweIfrGBxz4k+rSPQ576Km237A3uhNm9LajvJNqBbryTaayqJvVUJ3kmAqzLiZVttcK/fCX8HqGH77dgA9YC+c+WvK3X3BdBmR7hHkgSmERfe8p9YdM4sgUfxy0wrw52+qjlVSnNrm/q+YQ1uO4acto9WpZkawGmpYXtmMJXLZ7tWfx1brNsW2PhVy4rO64HTWVBLZ+uq6s1swYfl13y5evnBI7j5Fw==vVfbctowEP0aHtvxNcBjuCSZaUjpOJ2kecko9mIrCMsjCzD9+kpY8gWbQFInD8xoj1aLdHb3SO7Z41V2zVASzWgApGcZIcNBz570LMsUPwEkKIQaID08/FeDhkLXOIC05sgpJRwnddCncQw+r2GIMbqtuy0oaW7D8xGBBvqAAx7l6MDql/gN4DDSf2ReDPOZFdLOauNphAK6rUD2tGePGaU8H62yMRDJjObFvU+my2fr1+3iCe6oO/x992x/y4NdvWdJcQQGMe82tJWH3iCyVnxNrry5Oi/faRIZXccByEBmzx5tI8zBS5AvZ7eiJgQW8RVR0xtgHIsEXBIcxgLjVDosaMw9FfHcAyk/GRCySjrVAa+BroCznXBRs32Vqp0uOWVvy8w7jsKiatZ1jpEqrrAIXTIqBorUdoKHwfJ+Zv4c3D5la8/DlMUkVTmpEtyzLoj421GAN2IYyuEc7VaSCbmLfPKF6TmNiH+vrGgJMkOxqGV2zP9oRo3TGT2ShnMzeDRdtuHU82U382WaLfkadJCu1v3aDaIgEHKiTMp4REMaIzIt0VGdytLnlsrC3xP4CpzvlBSiNad1eiHD/LEy/iNDfXeVNclU5L2x00YsjvtYNSqrpFku21t6XcoR45dSRgXgE5Sm2NfwFSZ6SylndFkIplXUwLktm9I18+ENP5V4ye6bjc2AII43dTFvS7taOqd430iqwiz3QBH6B5Ujzh0CV6sOiqfYxsfryTmir8YI+UuIg0a5iUsmkcMIMiSqSBCfAMNiG6KzC3SuIet07y5wBvoWNt+dx/Old3hAtOOe18ruZ7Vyv0H9jL4iIpvSMm7WL81OJ0S8QeAMSr/iKnMP77I2bbS+UhsHLVfZkepdEMiUyAj9CY7oTROukFxX1eLttTeWwP2oELRDpfqoNH5EhjtWRfX0zEXpdG2fVM9qrRht7x4N/qfMuk69WAs10CHykzdkthHIOdBr2/havR42atyb/BCA50ewAjG4DFAitbiD91T3mmGfIcID93M0uPX1azboHFMmaRznH3e0EyK7f5g2ng0tRPa7ucyEWX5C5mVcfmXb038=3VjbcpswEP0aP7aDuTjOY2znMpOk4w6Tado3FdagRCAihI379ZWMuFngYI+TmfYhE/awWqOze46FR9Y8ym8ZSsJH6gMZmUbAsD+yFiPTHIs/ASQogBYgM1z8pwQNhWbYh7SVyCklHCdt0KNxDB5vYYgxummnrSjRH8P1EAEN/YF9Hhbo1Lyo8TvAQVh+0HhyWdyJUJmsHjwNkU83Dci6HllzRikvrqJ8DkQyU/IydfntNyOdrd/Qr8VYMLF0yZei2M0xS6otMIj5eUubRek1Ipnia3HjLtV++bYkkdEs9kEWGo+s2SbEHNwEefLuRsyEwEIeEXV7DYxj0YArgoNYYJzKhBWNuasqDt2QypMFIW+0U23wFmgEnG1Firp7oVq1LZup4k3dedtWWNjqugKRGq6gKl0zKi4UqUcQbGlcgi/mU4WU8ZAGNEbkukZnNduGiOqcByqZ3HH8ApxvlbZQxmm7A5Bj/ty4/ilLfXVUtMhV5V2wLYNYbPe5GTRWybBetovKdSlHjF9JXQrAIyhNsVfCN5iUj5RyRl8rBYoWzo6bgZRmzIMDebayEsQCOFTPKfJkFw5OFAOCOF63XeTs42H36M+YIe8VYl+bHmFCibwMIUdiKASPCTAsHgZYjS5LyHxfrSucQ+nS46PbMlyal3vStB1NmpUKm9J0zqDMh7URfyfrJ/fpjdzb7sSZvcTVYJ2uzPQVuBf+IzItv7yMTjEOVLGYSD1JgI2UTnmdUeeOrvPO9hrd0/g5snY0Wc+zlNNIYHPKYPdvd7qh7P9ReCXVQxI3PkjinVuYaG14pC+ISH2axl32W3cAQsQxFAZw+hmnGWf/OGPpx5mx2UHo9KMIvdAI7R3fFYFceUW3bfRYToPkPbdtOVjTenU7O9UlT3Hk0/2t37cGnGMmA88x74mvAgc7o/qMJcViw/Ww2u1hrb7wyxLFztWq5nvKXiF7z0YsY69QQY1WaDfQ1cZPPxcY2oy7i3sBuF4IkbTuKx8l0oz7X5KM9w2kxwuGDlKvZ1gDzllT5yweLML65bdgv/59wLr+Cw==1VZLc9owEP41HNsxFo/0GF5hJk2GKYekR8VebAVhMfIaTH9911jyEyhtSWd68Iz202q9+valDhtv0gfNt+GT8kF2XCfQwu+wScd1u/QRsOUB1IBMYyl+WNAxaCJ8iGuKqJREsa2Dnooi8LCGca3Vvq62UrLtxtLjElroi/AxzNE7d1jicxBBaH/UHXzJdzbcKhvH45D7al+B2LTDxlopzFebdAwyY8bykp+bndktHNMQ4TUHvu2fHx5XjzDnXff5hYvJ8N75ZKzsuEzMhSez5cI4jAfLglZJ5ENmqNtho30oEJZb7mW7ewoqYSFupNnegUZBDN5LEUSEocoUVirCpbFo/0qKkJ69TrcgiVIH1AZQH0jFHrC8HizzRt6XYWIDg4W1EBmQm0wICtsle7QwBP4Gmf0Wb+BTMhlRaQxVoCIupyU6Kpl1SCp1vqqMtSOf74B4MIXAE1R1tiEV+FpZf89Mfe4baZIay0fhYIWIrvtaFSqnMrE8dpTsuRi5xvusiAjwJI9j4Vl4JqR1KUat1kW5UAxHOTEZG5ejTeSpRHtwgWTX1DzXAeAFPXY6ezRIjmJX9+PmmeCeKStnxL01RH4rUag5bLNlCCmn+BNlW9CCnAFdogsLub8uwpVIwXbPbhGBv6u4fqPiev1WxRXFVa24/kcVHGvRPE5iVBvCntQ7l1kNuc44nwSCaHWdpZJJvvwPI8CaPe9UBNi/jECvFYEK8fPkrd0RpaRJDVfQd+N50R80uGPteVHMlCp3dx/F3bDF3dmkXElITd+lluyfacFtuMJnfdAUj5GjsAb0wqLHN5v3n06LGzZ9dmXT751OgWqInVNPAgtePR3MPxZK0FXK+mx0yJ7TyJ38ouZU9a3WMNRrGGJNQzkTLUPHPCwufio1SSyfnLl6+Spn058= \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg new file mode 100644 index 000000000..728a19418 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg @@ -0,0 +1,3 @@ + + +
    Payer DFSP
    Payer DFSP
    Mojaloop Hub
    Mojaloop Hub
    sdk-scheme-adapter
    sdk-scheme-adapter
    GET /parties
    GET /parties
    Discovery
    Resolve all potential recipients which might be at any of the DFSPs on the service
    Discovery...
    Agreement
    Each DFSP is provided the opportunity to perform AML checks and add costs or discounts to each transfer
    Agreement...
    Transfer
    Each DFSP is requested to proceed with the transfer. Results are collated and DFSP(s) notified.
    Transfer...
    POST /bulkQuotes
    POST /bulkQuotes
    POST /bulkTransfers
    POST /bulkTransfers
    Payee DFSP
    Payee...
    Confirmation of party information
    Confirmation of party information
    Beneficiary Management Subsystem
    Benefi...
    batch transfers
    batch tran...
    for each transfer
    for each t...
    for each batch
    for each b...
    for each batch
    for each b...
    Confirmation to proceed with transfer
    Confirmation to proceed with trans...
    Bulk Disbursement is triggered
    Bulk Disbursement is triggered
    GET /parties
    GET /parties
    Discovery
    Resolve all potential recipients which might be at any of the DFSPs
    Discovery...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg new file mode 100644 index 000000000..d139c9f6c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg @@ -0,0 +1,3 @@ + + +
    Infrastructure
    Infrastructure
    Assert on State Store Changes
    Assert on State Store Changes
    State
    Store
    State...
    Producer
    Producer
    Consumer
    Consumer
    Redis
    Redis
    Kafka
    Kafka
    Initiates Test
    Initiates Test
    Assert on Kafka messges
    Assert on Kafka messges
    Jest Test Script
    Jest...
    Command Handler under test
    Command Handler...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg new file mode 100644 index 000000000..483b2dc7c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    Payment
    Manager
    Payment...
    DFSP Backend
    DFSP Backend
    Mojaloop Hub
    Mojaloop Hub
    SDK Scheme Adapter
    SDK Scheme Ada...
    Core Connector
    Core Connec...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg new file mode 100644 index 000000000..b3143177b --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    DFSP Backend
    DFSP Backend
    Custom Core Connector
    Custom Core Conn...
    Mojaloop Hub
    Mojaloop Hub
    SDK Scheme Adapter
    SDK Scheme Ada...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg new file mode 100644 index 000000000..814b57fa0 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    DFSP Backend
    DFSP Backend
    Custom Mojaloop Connection Solution
    Custom Mojaloop Conne...
    Mojaloop Hub
    Mojaloop Hub
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg new file mode 100644 index 000000000..ab1c426df --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg @@ -0,0 +1,3 @@ + + +
    Payer SDK
    Payer SDK
    Payee SDK
    Payee SDK
    Payer SIM
    Payer...
    Payee SIM
    Payee...
    TTK
    TTK
    1. POST /bulkTxn
    1. POS...
    2. GET /parties
    2. GET /par...
    3. GET /parties
    3. GET /parti...
    4. PUT /parties/ID
    4. PUT...
    5. PUT /bulkTxn/ID
    5. PUT /bul...
    6. PUT /bulkTxn/ID acptPty
    accptQuote
    6. PUT /bulkT...
    autoAcceptParty: false
    autoAcceptQuote: false
    autoAcceptParty: false...
    Bulk testing - Local setup, no Switch between payerfsp and payeefsp 
    Bulk testing - Local setup, no Switch between payerfsp and payeefsp 
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png b/docs/fr/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png new file mode 100644 index 000000000..855dcba55 Binary files /dev/null and b/docs/fr/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png differ diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md new file mode 100644 index 000000000..2c85db925 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md @@ -0,0 +1,145 @@ +# Transferts groupés + +## Cas d’erreur + +### Phase de découverte + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* relaie les erreurs renvoyées par le commutateur (*pass-through*). + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — recherche de partie** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur de traitement | +| Erreur interne du serveur | 2001 | 503 | Erreur de traitement | +| Délai d’attente dépassé lors de la résolution de la partie | 2004 | 503 | Erreur de traitement | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Partie introuvable | 3204 | 202 | Erreur de traitement | + +### Phase d’accord + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* relaie les erreurs renvoyées par le commutateur. + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — devis** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur technique | +| Erreur interne du serveur | 2001 | 503 | Erreur technique | +| Non implémenté | 2002 | 501 | Erreur de traitement | +| Service actuellement indisponible | 2003 | 503 | Erreur de traitement | +| Délai d’attente du serveur dépassé | 2004 | 503 | Erreur de traitement | +| Serveur occupé | 2005 | 503 | Erreur de traitement | +| Erreur client générique | 3000 | 400 | Erreur de validation de la requête | +| Version demandée inacceptable | 3001 | 406 | Erreur « non acceptable » | +| URI inconnue | 3002 | 404 | Erreur « introuvable » | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Syntaxe incorrecte | 3101 | 400 | Erreur de validation de la requête | +| Élément obligatoire manquant | 3102 | 400 | Erreur de validation de la requête | +| Trop d’éléments | 3103 | 400 | Erreur de validation de la requête | +| Charge utile trop volumineuse | 3104 | 400 | Erreur de validation de la requête | +| Signature invalide | 3105 | 403 | Erreur « interdit » | +| Erreur FSP destinataire | 3201 | 404 | Erreur « introuvable » | +| Identifiant FSP payeur introuvable | 3202 | 404 | Erreur « introuvable » | +| Identifiant FSP bénéficiaire introuvable | 3203 | 404 | Erreur « introuvable » | +| Identifiant de devis introuvable | 3205 | 404 | Erreur « introuvable » | +| Identifiant de devis groupé introuvable | 3209 | 404 | Erreur « introuvable » | +| Erreur d’expiration générique | 3300 | 503 | Erreur de traitement | +| Devis expiré | 3302 | 503 | Erreur de traitement | +| Erreur payeur générique | 4000 | 400 | Erreur de validation de la requête | +| Rejet payeur générique | 4100 | 403 | Erreur « interdit » | +| Erreur de plafond payeur | 4200 | 400 | Erreur de validation de la requête | +| Erreur d’autorisation payeur | 4300 | 403 | Erreur « interdit » | +| Erreur de blocage payeur générique | 4400 | 403 | Erreur « interdit » | +| Erreur bénéficiaire générique | 5000 | 503 | Erreur de traitement | +| Liquidité insuffisante côté FSP bénéficiaire | 5001 | 503 | Erreur de traitement | +| Rejet bénéficiaire générique | 5100 | 403 | Erreur « interdit » | +| Devis rejetée par le bénéficiaire | 5101 | 503 | Erreur de traitement | +| Type de transaction non pris en charge par le FSP bénéficiaire | 5102 | 503 | Erreur de traitement | +| Devis rejetée par le bénéficiaire | 5103 | 503 | Erreur de traitement | +| Devise non prise en charge par le bénéficiaire | 5106 | 503 | Erreur de traitement | +| Erreur de plafond bénéficiaire | 5200 | 503 | Erreur de traitement | +| Erreur d’autorisation bénéficiaire | 5300 | 403 | Erreur « interdit » | +| Erreur de blocage bénéficiaire générique | 5400 | 403 | Erreur « interdit » | + + + +### Phase de transfert + +Toutes les erreurs rencontrées pendant cette phase sont agrégées dans le *mojaloop-connector*, ajoutées à l’objet `lastError` et renvoyées au FSP payeur avec l’ensemble des transferts réussis ou en échec inclus dans la requête de transfert groupé. + +Le *mojaloop-connector* relaie les erreurs renvoyées par le commutateur. + +``` + "lastError": { + "httpStatusCode": 404, + "mojaloopError": { + "errorInformation": { + "errorCode": "3210", + "errorDescription": "Bulk transfer ID not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Codes d’erreur — transfert** + +| Description de l’erreur | Code erreur | Code HTTP | Catégorie | +|------------------------------------------------------------------------|-------------|------------------|----------------------------------------------------------| +| Erreur de communication | 1000 | 503 | Erreur technique | +| Erreur de communication vers la destination | 1001 | 503 | Erreur technique | +| Erreur serveur générique | 2000 | 503 | Erreur de traitement | +| Erreur interne du serveur | 2001 | 503 | Erreur de traitement | +| Délai d’attente du serveur dépassé | 2004 | 503 | Erreur de traitement | +| Erreur de validation générique | 3100 | 400 | Erreur de validation de la requête | +| Identifiant de transfert groupé introuvable | 3210 | 404 | Erreur de traitement | +| Erreur d’expiration générique | 3300 | 503 | Erreur de traitement | +| Demande de transaction expirée | 3301 | 503 | Erreur de traitement | +| Transfert expiré | 3303 | 503 | Erreur de traitement | +| Erreur bénéficiaire générique | 5000 | 400 | Erreur de traitement | +| Liquidité insuffisante côté FSP bénéficiaire | 5001 | 400 | Erreur de traitement | +| Rejet bénéficiaire générique | 5100 | 400 | Erreur de traitement | +| Devis rejetée par le bénéficiaire | 5101 | 400 | Erreur de traitement | +| Type de transaction non pris en charge par le FSP bénéficiaire | 5102 | 400 | Erreur de traitement | +| Devis rejetée par le FSP bénéficiaire | 5103 | 400 | Erreur de traitement | +| Transaction rejetée par le bénéficiaire | 5104 | 400 | Erreur de traitement | +| Transaction rejetée par le FSP bénéficiaire | 5105 | 400 | Erreur de traitement | +| Devise non prise en charge par le bénéficiaire | 5106 | 400 | Erreur de traitement | +| Erreur de plafond bénéficiaire | 5200 | 400 | Erreur de traitement | +| Erreur d’autorisation bénéficiaire | 5300 | 403 | Erreur de traitement | +| Erreur de blocage bénéficiaire générique | 5400 | 400 | Erreur de traitement | diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML new file mode 100644 index 000000000..8f7e09906 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML @@ -0,0 +1,89 @@ +@startuml PayeeDFSPBulkIdealPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPBulkIdealPattern +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Discovery == + +Switch->MC: **GET** /parties/{Type}/{Id} +MC-->Switch: HTTP 202 Response +MC->CC: **GET** /parties/{Type}/{Id} +activate MC +CC->CBS: **GET** [account lookup] +CBS-->CC: Response +CC-->MC: Response +deactivate MC +alt If Success response +MC-->Switch: **PUT** /parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId}) +else if Error response +MC-->Switch: **PUT** /parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error) +end + +== Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check == + +Switch->MC: **POST** /bulkquotes +MC-->Switch: HTTP 202 Response +loop X times for each transfer in bulk message + MC->CC: **POST** /quoterequest + activate MC + CC->CBS: **AML** checks + CBS-->CC: Response + CC->CBS: **Calculate Fees** + CBS-->CC: Response + CC-->MC: Response + deactivate MC + MC->MC: Update transaction status \nand attach quote response +end Loop +MC-->Switch: **PUT** /bulkquotes/{Id} +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /bulktransfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds at indivial transfer level + Switch->MC: **POST** /bulktransfers + loop X times for each transfer in bulk message + MC->CC: Create & Reserve Transfer\n **POST** /transfers + activate MC + CC->CBS: Reserve funds + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC -> MC:Update transaction status \nand attach transfer response + end Loop + MC-->Switch: **PUT** /bulktransfers/{id} (BulkStatus='PROCESSING') + Switch-->Switch: Commit funds at indivial transfer level in DFSP ledgers + Switch -> MC: **PATCH** /bulktransfers/{id} (BulkStatus='COMPLETED') + loop X times for each transfer in bulk message + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} \n(TransferStatus='COMMITTED', homeTransactionId) + activate MC + CC->CBS: Commit funds + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + deactivate MC + end loop + + + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg new file mode 100644 index 000000000..f4c0069b0 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg @@ -0,0 +1,183 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Discovery[1]GET/parties/{Type}/{Id}[2]HTTP 202 Response[3]GET/parties/{Type}/{Id}[4]GET[account lookup][5]Response[6]Responsealt[If Success response][7]PUT/parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId})[if Error response][8]PUT/parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error)Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check[9]POST/bulkquotes[10]HTTP 202 Responseloop[X times for each transfer in bulk message][11]POST/quoterequest[12]AMLchecks[13]Response[14]Calculate Fees[15]Response[16]Response[17]Update transaction statusand attach quote response[18]PUT/bulkquotes/{Id}[19]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/bulktransfers[20]Perform liquidity(NDC)check[21]Reserve Funds at indivial transfer level[22]POST/bulktransfersloop[X times for each transfer in bulk message][23]Create & Reserve Transfer POST/transfers[24]Reserve funds[25]response (homeTransactionId)[26]response (homeTransactionId)[27]Generate Fulfilment[28]Update transaction statusand attach transfer response[29]PUT/bulktransfers/{id} (BulkStatus='PROCESSING')[30]Commit funds at indivial transfer level in DFSP ledgers[31]PATCH/bulktransfers/{id} (BulkStatus='COMPLETED')loop[X times for each transfer in bulk message][32]Commit Transfer PATCH/transfers/{id}(TransferStatus='COMMITTED', homeTransactionId)[33]Commit funds[34]Release funds to Payee[35]response[36]response \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML new file mode 100644 index 000000000..438ef1779 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML @@ -0,0 +1,84 @@ +@startuml PayeeDFSPBulkSingleIntegrationApiOnPatch +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPBulkSingleIntegrationApiOnPatch +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH == + +Switch->MC: **POST** /bulkquotes +MC-->Switch: HTTP 202 Response +loop X times for each transfer in bulk message + MC->CC: **POST** /quoterequest + activate MC + CC->CC: Do nothing + CC-->MC: Response + deactivate MC + MC->MC: Update transaction status \nand attach quote response +end Loop +MC-->Switch: **PUT** /bulkquotes/{Id} + +Switch->Switch: Pass Quote to Payer DFSP +note left +Obtain consent to +proceed with the transfer +Via **POST** /bulktransfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds at indivial transfer level + Switch->MC: **POST** /bulktransfers + loop X times for each transfer in bulk message + MC->CC: **POST** /transfers + activate MC + CC->CC: Do Nothing + CC-->MC: response + deactivate MC + MC->MC: Generate Fulfilment + MC -> MC:Update transaction status \nand attach transfer response + end Loop + MC-->Switch: **PUT** /bulktransfers/{id} (BulkStatus='PROCESSING') + Switch-->Switch: Commit funds at indivial transfer level in DFSP ledgers + Switch -> MC: **PATCH** /bulktransfers/{id} (BulkStatus='COMPLETED') + loop X times for each transfer in bulk message + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + activate MC + CC->CBS: Performn AML checks and transfer funds + alt if (AML checks pass) + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + else if (AML checks fail) + CBS->CBS: Compensation action for AML failure. \n Return error response. + CBS-->CC: response + CC-->MC: response + deactivate MC + rnote left MC + Payee DFSP AML checks / other errors result in: + + **Reconciliation Error** + Payer has sent funds + Payer DFSP has sent funds + Hub considers that the Payee DFSP has received funds + Payee DFSP has rejected the transaction + Payee has not received funds + endrnote + end + end Loop + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg new file mode 100644 index 000000000..5fe598782 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg @@ -0,0 +1,173 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH[1]POST/bulkquotes[2]HTTP 202 Responseloop[X times for each transfer in bulk message][3]POST/quoterequest[4]Do nothing[5]Response[6]Update transaction statusand attach quote response[7]PUT/bulkquotes/{Id}[8]Pass Quote to Payer DFSPObtain consent toproceed with the transferViaPOST/bulktransfers[9]Perform liquidity(NDC)check[10]Reserve Funds at indivial transfer level[11]POST/bulktransfersloop[X times for each transfer in bulk message][12]POST/transfers[13]Do Nothing[14]response[15]Generate Fulfilment[16]Update transaction statusand attach transfer response[17]PUT/bulktransfers/{id} (BulkStatus='PROCESSING')[18]Commit funds at indivial transfer level in DFSP ledgers[19]PATCH/bulktransfers/{id} (BulkStatus='COMPLETED')loop[X times for each transfer in bulk message][20]Commit Transfer PATCH/transfers/{id} (TransferStatus='COMMITTED')[21]Performn AML checks and transfer fundsalt[if (AML checks pass)][22]Release funds to Payee[23]response[24]response[if (AML checks fail)][25]Compensation action for AML failure.Return error response.[26]response[27]responsePayee DFSP AML checks / other errors result in: Reconciliation ErrorPayer has sent fundsPayer DFSP has sent fundsHub considers that the Payee DFSP has received fundsPayee DFSP has rejected the transactionPayee has not received funds \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML new file mode 100644 index 000000000..dace0ab8b --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML @@ -0,0 +1,80 @@ +@startuml PayeeDFSPIdealPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPIdealPattern +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Discovery == + +Switch->MC: **GET** /parties/{Type}/{Id} +MC-->Switch: HTTP 202 Response +MC->CC: **GET** /parties/{Type}/{Id} +activate MC +CC->CBS: **GET** [account lookup] +CBS-->CC: Response +CC-->MC: Response +deactivate MC +alt If Success response +MC-->Switch: **PUT** /parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId}) +else if Error response +MC-->Switch: **PUT** /parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error) +end + +== Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CBS: **AML** checks (velocity,etc...) +CBS-->CC: Response +CC->CBS: **Calculate Fees** +CBS-->CC: Response +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: Create & Reserve Transfer\n **POST** /transfers + activate MC + CC->CBS: Reserve funds + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch->Switch: Commit funds in DFSP ledgers + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} \n(TransferStatus='COMMITTED', homeTransactionId) + activate MC + CC->CBS: Commit funds + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + deactivate MC + + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg new file mode 100644 index 000000000..577ff3030 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg @@ -0,0 +1,165 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Discovery[1]GET/parties/{Type}/{Id}[2]HTTP 202 Response[3]GET/parties/{Type}/{Id}[4]GET[account lookup][5]Response[6]Responsealt[If Success response][7]PUT/parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId})[if Error response][8]PUT/parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error)Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check[9]POST/quotes[10]HTTP 202 Response[11]POST/quoterequest[12]AMLchecks (velocity,etc...)[13]Response[14]Calculate Fees[15]Response[16]Response[17]PUT/quotes/{Id}[18]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[19]Perform liquidity(NDC)check[20]Reserve Funds[21]POST/transfers[22]Create & Reserve Transfer POST/transfers[23]Reserve funds[24]response (homeTransactionId)[25]response (homeTransactionId)[26]Generate Fulfilment[27]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[28]Commit funds in DFSP ledgers[29]PATCH/transfers/{id} (TransferStatus='COMMITTED')[30]Commit Transfer PATCH/transfers/{id}(TransferStatus='COMMITTED', homeTransactionId)[31]Commit funds[32]Release funds to Payee[33]response[34]response \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML new file mode 100644 index 000000000..1f12dce39 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML @@ -0,0 +1,76 @@ +@startuml PayeeDFSPSingleIntegrationApiOnPatchPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPSingleIntegrationApiOnPatch +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CC: Do nothing +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} + +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: **POST** /transfers + activate MC + CC->CC: Do Nothing + CC-->MC: response + deactivate MC + MC->MC: Generate Fulfilment + MC-->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch-->Switch: Commit funds in DFSP ledgers + + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + activate MC + CC->CBS: Perform AML checks and transfer funds + alt if (AML checks pass) + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + else if (AML checks fail) + CBS->CBS: Compensation action for AML failure. \n Return error response. + CBS-->CC: response + CC-->MC: response + rnote left MC + Payee DFSP AML error checks (and other errors) result in: + + **Reconciliation Error** + Payer has sent funds + Payer DFSP has sent funds + Hub considers that the Payee DFSP has received funds + Payee DFSP has rejected the transaction + Payee has not received funds + endrnote + end + deactivate MC + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg new file mode 100644 index 000000000..ed8a23a77 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg @@ -0,0 +1,157 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH[1]POST/quotes[2]HTTP 202 Response[3]POST/quoterequest[4]Do nothing[5]Response[6]PUT/quotes/{Id}[7]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[8]Perform liquidity(NDC)check[9]Reserve Funds[10]POST/transfers[11]POST/transfers[12]Do Nothing[13]response[14]Generate Fulfilment[15]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[16]Commit funds in DFSP ledgers[17]PATCH/transfers/{id} (TransferStatus='COMMITTED')[18]Commit Transfer PATCH/transfers/{id} (TransferStatus='COMMITTED')[19]Perform AML checks and transfer fundsalt[if (AML checks pass)][20]Release funds to Payee[21]response[22]response[if (AML checks fail)][23]Compensation action for AML failure.Return error response.[24]response[25]responsePayee DFSP AML error checks (and other errors) result in: Reconciliation ErrorPayer has sent fundsPayer DFSP has sent fundsHub considers that the Payee DFSP has received fundsPayee DFSP has rejected the transactionPayee has not received funds \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML new file mode 100644 index 000000000..c9e8b2a41 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML @@ -0,0 +1,67 @@ +@startuml PayeeDFSPSingleIntegrationApiOnTransferPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPSingleIntegrationApiOnTransfer +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during POST transfer == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CC: Do nothing +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} + +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: **POST** /transfers + activate MC + CC->CBS: Perform AML checks and transfer funds + CBS->CBS: Release of funds to Payee + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC-->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch->Switch: Commit funds in DFSP ledgers + alt if (Transfer status == 'ABORTED') + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='ABORTED', homeTransactionId) + MC->CC: Abort Transfer\n **PATCH** /transfers/{id} (TransferStatus='ABORTED') + CC->CBS: Abort Transfer + CBS->CBS: Compensate action for abort + CBS-->CC: response + else if (Transfer status == 'COMMITTED') + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED', homeTransactionId) + MC->CC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + CC->CC: Do nothing + CC-->MC: response + end + + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg new file mode 100644 index 000000000..811cbdc15 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg @@ -0,0 +1,139 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during POST transfer[1]POST/quotes[2]HTTP 202 Response[3]POST/quoterequest[4]Do nothing[5]Response[6]PUT/quotes/{Id}[7]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[8]Perform liquidity(NDC)check[9]Reserve Funds[10]POST/transfers[11]POST/transfers[12]Perform AML checks and transfer funds[13]Release of funds to Payee[14]response (homeTransactionId)[15]response (homeTransactionId)[16]Generate Fulfilment[17]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[18]Commit funds in DFSP ledgersalt[if (Transfer status == 'ABORTED')][19]PATCH/transfers/{id} (TransferStatus='ABORTED', homeTransactionId)[20]Abort Transfer PATCH/transfers/{id} (TransferStatus='ABORTED')[21]Abort Transfer[22]Compensate action for abort[23]response[if (Transfer status == 'COMMITTED')][24]PATCH/transfers/{id} (TransferStatus='COMMITTED', homeTransactionId)[25]PATCH/transfers/{id} (TransferStatus='COMMITTED')[26]Do nothing[27]response \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML new file mode 100644 index 000000000..7d193ae2c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML @@ -0,0 +1,100 @@ +@startuml PayerDFSPBulkDoubleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayerDFSPBulkDoubleIntegrationApi +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "Mojaloop\nConnector" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - with user confirmation == + +CBS->CC: **POST** /bulkTransactions\n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**, synchronous = false) +Loop n times (in parallel) + hnote left of CC + For each individual transfer + in bulk message + end hnote + CC -> CC: validate MSISDN & Prefix +end Loop +CC->MC: **POST** /bulkTransactions\n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**, synchronous = false) +activate MC +loop N times & within bulkExpiration timelimit (in parallel) +hnote left of MC + For each transfer + in bulk message +end hnote + activate MC + MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} + Switch-->MC: HTTP 202 response + Switch->Switch: Determine Payee DFSP using oracle + Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties + Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} + MC-->Switch: HTTP 200 Response +end Loop + +rnote left MC + Accept Party +endrnote + +loop Quote Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC->MC: Check bulkExpiration + MC->MC: Create bulkTransactionId + MC -> MC: Calculate bulk expiry \nbased on both expirySeconds config and \nbulkExpiration + MC->Switch: **POST** /bulkquotes + Switch-->MC: HTTP 202 response + Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /bulkquotes + Switch->MC: **PUT** /bulkquotes/{Id} + MC-->Switch: HTTP 200 Response +end loop + MC->CC: **PUT** /bulkTransactions/{Id} + + deactivate MC + CC->CBS: **PUT** /bulkTransactions/{Id} + + +CBS->CBS: Obtain concent from Payer on Fees and Payee Info +CBS->CBS: Reserve funds +CBS->CC: **PUT** /bulkTransactions/{bulkhometransferId} +CC->MC: **PUT** /bulkTransactions/{bulktransactionId} + +loop Transfer Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + + activate MC + MC->Switch: **POST** /bulktransfers + Switch-->MC: HTTP 202 response + Switch->Switch: Reserve Payer DFSP funds + Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /bulktransfers + Switch->Switch: Commit Payer DFSP funds + Switch->MC: **PUT** /bulktransfers/{Id} + MC-->Switch: HTTP 200 Response +end loop + +MC->CC: **PUT** /bulkTransactions/{Id} + +deactivate MC +CC->CBS: **PUT** /bulkTransactions/{Id} +CBS->CBS: Commit funds + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg new file mode 100644 index 000000000..19e336a0a --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg @@ -0,0 +1,205 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorMojaloopConnectorMojaloopConnectorMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - with user confirmation[1]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false, synchronous = false)loop[n times (in parallel)]For each individual transferin bulk message[2]validate MSISDN & Prefix[3]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false, synchronous = false)loop[N times & within bulkExpiration timelimit (in parallel)]For each transferin bulk message[4]GET/parties/{Type}/{ID}/{SubId}[5]HTTP 202 response[6]Determine Payee DFSP using oracle[7]Lookup Payee Information from Payee DFSPusingGET/parties[8]PUT/parties/{Type}/{ID}/{SubId}[9]HTTP 200 ResponseAccept Partyloop[Quote Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[10]Check bulkExpiration[11]Create bulkTransactionId[12]Calculate bulk expirybased on both expirySeconds config andbulkExpiration[13]POST/bulkquotes[14]HTTP 202 response[15]Pass on quote to Payee DFSPusingPOST/bulkquotes[16]PUT/bulkquotes/{Id}[17]HTTP 200 Response[18]PUT/bulkTransactions/{Id}[19]PUT/bulkTransactions/{Id}[20]Obtain concent from Payer on Fees and Payee Info[21]Reserve funds[22]PUT/bulkTransactions/{bulkhometransferId}[23]PUT/bulkTransactions/{bulktransactionId}loop[Transfer Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[24]POST/bulktransfers[25]HTTP 202 response[26]Reserve Payer DFSP funds[27]Pass on transfer to Payee DFSPusingPOST/bulktransfers[28]Commit Payer DFSP funds[29]PUT/bulktransfers/{Id}[30]HTTP 200 Response[31]PUT/bulkTransactions/{Id}[32]PUT/bulkTransactions/{Id}[33]Commit funds \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML new file mode 100644 index 000000000..38e3d8d6c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML @@ -0,0 +1,95 @@ +@startuml PayerDFSPBulkSingleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayerDFSPBulkSingleIntegrationApi +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - single phase == + +CBS->CBS: Reserve funds +CBS->CC: **POST** /bulkTransactions \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false) +Loop n times (in parallel) + hnote left of CC + For each individual transfer + in bulk message + end hnote + CC -> CC: validate MSISDN & Prefix +end Loop +CC->MC: **POST** /bulkTransactions \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false) +activate MC +loop N times & within bulkExpiration timelimit (in parallel) +hnote left of MC + For each transfer + in bulk message +end hnote + MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} + Switch-->MC: HTTP 202 response + Switch->Switch: Determine Payee DFSP using oracle + Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties + Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} + MC-->Switch: HTTP 200 Response + MC -> MC: Update transaction status and\n attach get parties response + MC -> MC: Add to next phase FSP bulk call +end Loop + +rnote left MC + Accept Party +endrnote + +loop Quote Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC->MC: Check bulkExpiration + MC->MC: Create bulkTransactionId + MC -> MC: Calculate bulk expiry \nbased on both expirySeconds config and \nbulkExpiration + MC->Switch: **POST** /bulkquotes + Switch-->MC: HTTP 202 response + Switch->Switch: Pass on bulkquote to Payee DFSP\n using **POST** /bulkquotes + Switch->MC: **PUT** /bulkquotes/{Id} + MC-->Switch: HTTP 200 Response +end loop + +rnote left MC + Accept Quote +endrnote +loop Transfer Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC -> MC: Confirm Fees meets auto accept levels\n and bulkExpiration timelimit not reached \n-> Update Transfer Status + + MC->Switch: **POST** /bulktransfers + Switch-->MC: HTTP 202 response + Switch->Switch: Reserve Payer DFSP funds + Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /bulktransfers + Switch->Switch: Commit Payer DFSP funds + Switch->MC: **PUT** /bulktransfers/{Id} + MC-->Switch: HTTP 200 Response +end loop + +MC->CC: **PUT** /bulkTransactions/{Id} + +deactivate MC +CC->CBS: **PUT** /bulkTransactions/{Id} +CBS->CBS: Commit funds + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg new file mode 100644 index 000000000..e136c59bd --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg @@ -0,0 +1,195 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - single phase[1]Reserve funds[2]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false)loop[n times (in parallel)]For each individual transferin bulk message[3]validate MSISDN & Prefix[4]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false)loop[N times & within bulkExpiration timelimit (in parallel)]For each transferin bulk message[5]GET/parties/{Type}/{ID}/{SubId}[6]HTTP 202 response[7]Determine Payee DFSP using oracle[8]Lookup Payee Information from Payee DFSPusingGET/parties[9]PUT/parties/{Type}/{ID}/{SubId}[10]HTTP 200 Response[11]Update transaction status andattach get parties response[12]Add to next phase FSP bulk callAccept Partyloop[Quote Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[13]Check bulkExpiration[14]Create bulkTransactionId[15]Calculate bulk expirybased on both expirySeconds config andbulkExpiration[16]POST/bulkquotes[17]HTTP 202 response[18]Pass on bulkquote to Payee DFSPusingPOST/bulkquotes[19]PUT/bulkquotes/{Id}[20]HTTP 200 ResponseAccept Quoteloop[Transfer Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[21]Confirm Fees meets auto accept levelsand bulkExpiration timelimit not reached-> Update Transfer Status[22]POST/bulktransfers[23]HTTP 202 response[24]Reserve Payer DFSP funds[25]Pass on transfer to Payee DFSPusingPOST/bulktransfers[26]Commit Payer DFSP funds[27]PUT/bulktransfers/{Id}[28]HTTP 200 Response[29]PUT/bulkTransactions/{Id}[30]PUT/bulkTransactions/{Id}[31]Commit funds \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML new file mode 100644 index 000000000..540789924 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML @@ -0,0 +1,66 @@ +@startuml PayerDFSPDoubleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Core-Connector transactional flow patterns +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - with user confirmation == + +CBS->CC: **POST** /sendMoney \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**) +CC->MC: **POST** /transfers +activate MC +MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} +Switch-->MC: HTTP 202 response +Switch->Switch: Determine Payee DFSP using oracle +Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties +Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Party +endrnote +MC->Switch: **POST** /quotes +Switch-->MC: HTTP 202 response +Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /quotes +Switch->MC: **PUT** /quotes/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: Response +deactivate MC +CC-->CBS: Response +CBS->CBS: Obtain concent from Payer on Fees and Payee Info +CBS->CBS: Reserve funds +CBS->CC: **PUT** /sendmoney/{transferId} +CC->MC: **PUT** /transfers + +activate MC +MC->Switch: **POST** /transfers +Switch-->MC: HTTP 202 response +Switch->Switch: Reserve Payer DFSP funds +Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /transfers +Switch->Switch: Commit Payer DFSP funds +Switch->MC: **PUT** /transfers/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: response +deactivate MC +CC-->CBS: response +alt if (transferStatus== 'COMMITTED') +CBS->CBS: Finalise transfer +else else +CBS->CBS: Rollback transfer +end +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg new file mode 100644 index 000000000..175a64e31 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg @@ -0,0 +1,137 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - with user confirmation[1]POST/sendMoney(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false)[2]POST/transfers[3]GET/parties/{Type}/{ID}/{SubId}[4]HTTP 202 response[5]Determine Payee DFSP using oracle[6]Lookup Payee Information from Payee DFSPusingGET/parties[7]PUT/parties/{Type}/{ID}/{SubId}[8]HTTP 200 ResponseAccept Party[9]POST/quotes[10]HTTP 202 response[11]Pass on quote to Payee DFSPusingPOST/quotes[12]PUT/quotes/{Id}[13]HTTP 200 Response[14]Response[15]Response[16]Obtain concent from Payer on Fees and Payee Info[17]Reserve funds[18]PUT/sendmoney/{transferId}[19]PUT/transfers[20]POST/transfers[21]HTTP 202 response[22]Reserve Payer DFSP funds[23]Pass on transfer to Payee DFSPusingPOST/transfers[24]Commit Payer DFSP funds[25]PUT/transfers/{Id}[26]HTTP 200 Response[27]response[28]responsealt[if (transferStatus== 'COMMITTED')][29]Finalise transfer[else][30]Rollback transfer \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML new file mode 100644 index 000000000..4884dec9c --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML @@ -0,0 +1,63 @@ +@startuml PayerDFSPSingleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Payer DFSP Single Phase Integration Pattern +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - single phase == + +CBS->CBS: Reserve funds +CBS->CC: **POST** /sendMoney \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true) +CC->MC: **POST** /transfers +activate MC +MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} +Switch-->MC: HTTP 202 response +Switch->Switch: Determine Payee DFSP using oracle +Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties +Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Party +endrnote +MC->Switch: **POST** /quotes +Switch-->MC: HTTP 202 response +Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /quotes +Switch->MC: **PUT** /quotes/{Id} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Quote +endrnote +MC->Switch: **POST** /transfers +Switch-->MC: HTTP 202 response +Switch->Switch: Reserve Payer DFSP funds +Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /transfers +Switch->Switch: Calculate fees +Switch->Switch: Commit Payer DFSP funds +Switch->MC: **PUT** /transfers/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: response +deactivate MC +CC-->CBS: response +alt if (transferStatus== 'COMMITTED') +CBS->CBS: Finalise transfer +else else +CBS->CBS: Rollback transfer +end + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg new file mode 100644 index 000000000..8c3b55365 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg @@ -0,0 +1,131 @@ +Payment ManagerCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - single phase[1]Reserve funds[2]POST/sendMoney(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true)[3]POST/transfers[4]GET/parties/{Type}/{ID}/{SubId}[5]HTTP 202 response[6]Determine Payee DFSP using oracle[7]Lookup Payee Information from Payee DFSPusingGET/parties[8]PUT/parties/{Type}/{ID}/{SubId}[9]HTTP 200 ResponseAccept Party[10]POST/quotes[11]HTTP 202 response[12]Pass on quote to Payee DFSPusingPOST/quotes[13]PUT/quotes/{Id}[14]HTTP 200 ResponseAccept Quote[15]POST/transfers[16]HTTP 202 response[17]Reserve Payer DFSP funds[18]Pass on transfer to Payee DFSPusingPOST/transfers[19]Calculate fees[20]Commit Payer DFSP funds[21]PUT/transfers/{Id}[22]HTTP 200 Response[23]response[24]responsealt[if (transferStatus== 'COMMITTED')][25]Finalise transfer[else][26]Rollback transfer \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml new file mode 100644 index 000000000..362d9c085 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml @@ -0,0 +1,132 @@ +@startuml +/'******** +-------------- +*********'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Bulk Transactions pattern using the Mojaloop Connector +' declare actors + +box "Payer DFSP" #LightGrey + participant "Backend System" as MFICC + participant "sdk-scheme-adapter" as MFIMC +end box +participant "Mojaloop\nSwitch" as MJW +box "Payee DFSP" #LightGrey + participant "sdk-scheme-adapter" as PayeeFSPMC + participant "Backend System" as PayeeFSPCC +end box + +== MVP Bulk Transfers using SDK-Scheme-Adapter == + +autonumber 1 1 "[0]" +MFICC->>MFIMC: **POST** /bulkTransactions +note left +Bulk Disbursement is triggerd +by beneficiary management sub-system +end note + +loop Discovery Processing: For each individualTransfer in bulk message +hnote left of MFIMC + Resolving all potential recipients + which might be at any of the DFSPs + on the service. +end hnote + MFIMC ->> MJW: **GET** /parties/* + activate MFIMC + MJW->MJW: query oracle to \ndetermine Payee DFSP + MJW->>PayeeFSPMC: **GET** /parties/* + PayeeFSPMC->PayeeFSPCC: **GET** /parties/* + note right + Lookup / validate party information + end note + PayeeFSPMC-->>MJW: **PUT** /parties/{type}/{id} + MJW-->>MFIMC: **PUT** /parties/{type}/{id} + deactivate MFIMC + +end Loop + MFIMC-->>MFICC: **PUT** /bulkTransactions/{bulkTransactionId} + MFICC->>MFIMC: **PUT** /bulkTransactions/{bulkTransactionId} + note left + Confirmation of party integration + end note + +MFIMC->MFIMC: Group Valid Transfers into batches +loop Agreement Processing: For each batch in bulk message +hnote left of MFIMC + Each DFSP is provided the opportunity to + perform AML checks and add costs + or discounts to each transfer. +end hnote + MFIMC ->> MJW: **POST** /bulkquotes + activate MFIMC + MJW->>PayeeFSPMC: **POST** /bulkquotes + alt if (HasSupportForBulkQuotes) + PayeeFSPMC->PayeeFSPCC: **POST** /bulkquotes + note right + Bulk AML checks + Bulk Fee calculations + end note + else if (!HasSupportForBulkQuotes) + loop X times for each transfer in bulk message + PayeeFSPMC->PayeeFSPCC: **POST** /quoterequests + note right + AML checks + Fee calculations + end note + end Loop + end + PayeeFSPMC-->>MJW: **PUT** /bulkquotes/{id) + MJW-->>MFIMC: **PUT** /bulkquotes/{id) + deactivate MFIMC +end loop + + MFIMC-->>MFICC: **PUT** /bulkTransactions/{bulkTransactionId} + MFICC->>MFIMC: **PUT** /bulkTransactions/{bulkTransactionId} + note left + confirmation of quote integration + end note + +loop Transfer Processing: For each batch in bulk message + hnote left of MFIMC + Each DFSP is messaged to proceed + with the transfer. Results + are captured and returned. + end hnote + MFIMC ->> MJW: **POST** /bulktransfers + activate MFIMC + MJW-> MJW: Perform liquidity(NDC) check\n at individual transfer level + MJW->MJW: Reserve Funds + MJW ->> PayeeFSPMC: **POST** /bulktransfers + alt if (HasSupportForBulkTransfers) + PayeeFSPMC->PayeeFSPCC: **POST** /bulktransfers + note right + Bulk Transfer integration + end note + else if (!HasSupportForBulkTransfers) + loop X times for each transfer in bulk message + PayeeFSPMC->PayeeFSPCC: **POST** /transfers + note right + Single Transfer integration + end note + end Loop + end + PayeeFSPMC -->> MJW: **PUT** /bulktransfers/{id} (BulkStatus) + MJW->MJW: Commit funds at indivial transfer level + MJW-->>MFIMC:**PUT** /bulktransfers/{id} + + deactivate MFIMC +end loop +MFIMC-->>MFICC:Callback Response \n**PUT** /bulkTransactions/{bulkTransactionId}\nTransfer Response (success & fail) +note left + Result of bulk disbursement received. +end note + + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg new file mode 100644 index 000000000..a6fc96ca3 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg @@ -0,0 +1,295 @@ + + + + + Payer DFSP + + Payee DFSP + + + + + + + + + + + + + + + + + Backend System + + Backend System + + sdk-scheme-adapter + + sdk-scheme-adapter + + Mojaloop + Switch + + Mojaloop + Switch + + sdk-scheme-adapter + + sdk-scheme-adapter + + Backend System + + Backend System + + + + + + + + MVP Bulk Transfers using SDK-Scheme-Adapter + + + + [1] + POST + /bulkTransactions + + + Bulk Disbursement is triggerd + by beneficiary management sub-system + + + loop + [Discovery Processing: For each individualTransfer in bulk message] + + Resolving all potential recipients + which might be at any of the DFSPs + on the service. + + + + [2] + GET + /parties/* + + + + + [3] + query oracle to + determine Payee DFSP + + + + [4] + GET + /parties/* + + + [5] + GET + /parties/* + + + Lookup / validate party information + + + + [6] + PUT + /parties/{type}/{id} + + + + [7] + PUT + /parties/{type}/{id} + + + + [8] + PUT + /bulkTransactions/{bulkTransactionId} + + + + [9] + PUT + /bulkTransactions/{bulkTransactionId} + + + Confirmation of party integration + + + + + [10] + Group Valid Transfers into batches + + + loop + [Agreement Processing: For each batch in bulk message] + + Each DFSP is provided the opportunity to + perform AML checks and add costs + or discounts to each transfer. + + + + [11] + POST + /bulkquotes + + + + [12] + POST + /bulkquotes + + + alt + [if (HasSupportForBulkQuotes)] + + + [13] + POST + /bulkquotes + + + Bulk AML checks + Bulk Fee calculations + + [if (!HasSupportForBulkQuotes)] + + + loop + [X times for each transfer in bulk message] + + + [14] + POST + /quoterequests + + + AML checks + Fee calculations + + + + [15] + PUT + /bulkquotes/{id) + + + + [16] + PUT + /bulkquotes/{id) + + + + [17] + PUT + /bulkTransactions/{bulkTransactionId} + + + + [18] + PUT + /bulkTransactions/{bulkTransactionId} + + + confirmation of quote integration + + + loop + [Transfer Processing: For each batch in bulk message] + + Each DFSP is messaged to proceed + with the transfer. Results + are captured and returned. + + + + [19] + POST + /bulktransfers + + + + + [20] + Perform liquidity(NDC) check + at individual transfer level + + + + + [21] + Reserve Funds + + + + [22] + POST + /bulktransfers + + + alt + [if (HasSupportForBulkTransfers)] + + + [23] + POST + /bulktransfers + + + Bulk Transfer integration + + [if (!HasSupportForBulkTransfers)] + + + loop + [X times for each transfer in bulk message] + + + [24] + POST + /transfers + + + Single Transfer integration + + + + [25] + PUT + /bulktransfers/{id} (BulkStatus) + + + + + [26] + Commit funds at indivial transfer level + + + + [27] + PUT + /bulktransfers/{id} + + + + [28] + Callback Response + PUT + /bulkTransactions/{bulkTransactionId} + Transfer Response (success & fail) + + + Result of bulk disbursement received. + + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml new file mode 100644 index 000000000..2485c6f54 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml @@ -0,0 +1,195 @@ +@startuml + +actor "Payer" as Payer +box Payer DFSP +participant "Core Banking System" as PayerDFSP +participant "SDK" as PayerSDK +end box +participant "Mojaloop" as Mojaloop #d4f2f9 + +box Payee DFSP +participant "SDK" as PayeeSDK +participant "Core Banking System" as PayeeDFSP +end box +actor "Payee" as Payee +autonumber 1 "[0]" + +alt if (User Initiated OTP) +Payer->PayerDFSP: Generate an OTP for me +PayerDFSP->PayerDFSP:Generate +PayerDFSP-->Payer: Here is your OTP +end +=== Payee initiated request to pay (R2P) == +Payee->PayeeDFSP: I would like \nto receive 1000 TZS\n from +1234567890 +PayeeDFSP->PayeeDFSP: Payer not within Payee System + +PayeeDFSP->PayeeSDK: **POST** /requestToPayTransfer +note right +{ + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "+1234567890", + "idSubValue": "string" + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "scenario": {...}, + "initiator": "PAYEE", + "initiatorType": "CONSUMER", + "note": "Note sent to Payee." +} +end note +activate PayeeSDK + +PayeeSDK->>Mojaloop: **GET** /parties +Mojaloop->>PayerSDK: **GET** /parties +PayerSDK->PayerDFSP: **GET** /parties +PayerDFSP->PayerDFSP: Lookup Validate Payer Account +PayerDFSP-->PayerSDK: return Payer information +note left +Payer information +end note +PayerSDK->>Mojaloop: **PUT** /parties +Mojaloop->>PayeeSDK: **PUT** /parties + +alt If AutoAcceptParty = false + PayeeSDK-->PayeeDFSP: **POST**\n /requestToPayTransfer \n(synchronous return) + note left +{ + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "1234567890", + "idSubValue": "string", + "displayName": "ryZ037pWP'lHu,Tu9,Tjl MRMbdMSpRGAHt4m6 2jk5L4'ePRWT", + "firstName": "Henrik", + "middleName": "Johannes", + "lastName": "Karlsson", + "dateOfBirth": "1966-06-16", + "fspId": "string", + "extensionList": [] + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "transactionType": "TRANSFER", + "note": "Note sent to Payee.", + "currentState": "WAITING_FOR_PARTY_ACCEPTANCE", +} + end note +PayeeDFSP->PayeeSDK: **PUT** /requestToPay/\n{requestToPayId} +note right + { + acceptParty: true + } +end note +else +PayeeSDK->PayeeSDK: Automatically \nAcceptParty by updating\n status +end + +PayeeSDK->>Mojaloop: **POST** /transactionRequests +Mojaloop->>PayerSDK: **POST** /transactionRequests +PayerSDK->PayerDFSP: **POST** /transactionRequests +PayerDFSP->PayerDFSP: Validate request\n to pay request +PayerDFSP-->PayerSDK: return +PayerSDK->>Mojaloop: **PUT** /transactionRequests/{ID} +note left +{ + "transactionId": "b51ec534-ee48-4575-b6a9-ead2955b8069", + "transactionRequestState": "RECEIVED", + "AuthenticationType": {} + "extensionList": {extension:[]} +} +end note +Mojaloop->>PayeeSDK: **PUT** /transactionRequests +PayeeSDK-->PayeeDFSP: return +deactivate PayeeSDK + +=== Payer DFSP executes R2P request == + +PayerDFSP->PayerSDK: **POST** /RequestToPayTransfer +note left +Initiate R2P with AuthType +end note +activate PayerSDK +PayerSDK->>Mojaloop: **POST** /quotes +Mojaloop->>PayeeSDK: **POST** /quotes +PayeeSDK->PayeeDFSP: **POST** /quoterequest +PayeeDFSP->PayeeSDK: return quote +PayeeSDK->>Mojaloop: **PUT** /quotes +Mojaloop->>PayerSDK: **PUT** /quotes + +PayerSDK-->PayerDFSP: return \n(**POST** /RequestToPayTransfer) +deactivate PayerSDK + +alt if AuthenticateType is null +PayerDFSP->Payer: Present payment terms\n to Payer for acceptance +Payer->PayerDFSP: I accept the payment terms +else if AuthenticateType is OTP +alt if (Automatic generated OTP) + +PayerDFSP->PayerDFSP: Generate OTP +PayerDFSP->Payer: Present OTP to Payer +end + +loop x retries +PayerDFSP->PayerSDK: **PUT** /RequestToPayTransfer +note left + accept quote = true + retries left = x +end note + +PayerSDK->>Mojaloop: **GET** \n/authorizations/\n{transactionRequestID} +Mojaloop->>PayeeSDK: **GET** \n/authorizations/\n{transactionRequestID} +PayeeSDK->PayeeDFSP: **GET** \n/auth/{authtype}/{requestToPayId} +PayeeDFSP->Payee: Get Payee to get\n Payer to enter OTP\n on POS +Payer->PayeeDFSP: Enter OTP +PayeeDFSP-->PayeeSDK: return OTP +note right +{ + "otpValue": "string" +} +end note +PayeeSDK->>Mojaloop: **PUT** /authorizations/{ID} +Mojaloop->>PayerSDK: **PUT** /authorizations/{ID} +PayerSDK-->PayerDFSP: synchronous return \n **POST** /requestToPayTransfer/\n{requestToPayTransactionId} +PayerDFSP->PayerDFSP: Validate OTP + +end loop + +end + + + +alt if can proceed with transfer +PayerDFSP->PayerDFSP: Reserve funds against \nPayer's account +PayerDFSP-->PayerSDK: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId} + +PayerSDK->>Mojaloop: **POST** /transfers +activate PayerSDK +Mojaloop->>PayeeSDK: **POST** /transfers +PayeeSDK-->PayeeDFSP: **PUT** / **POST**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n return +PayeeDFSP->Payee: Notify user +PayeeSDK->>Mojaloop: **PUT** /transfers \nreturn fulfilment +Mojaloop->>PayerSDK: **PUT** /transfers +deactivate PayerSDK +PayerSDK->PayerDFSP: **POST** \n/newAPI \nNotify payer of transfer +PayerDFSP->PayerDFSP: Commit transfer \nto Payer's account +PayerDFSP->Payer: Notify Payer + +else if rejected + +PayerDFSP-->PayerSDK: return +PayerSDK->>Mojaloop: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId}\n rejected +Mojaloop->>PayeeSDK: **PUT**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n rejected +PayeeSDK-->X PayeeDFSP: return rejected +end + + +@enduml \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg new file mode 100644 index 000000000..f734170e5 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg @@ -0,0 +1,532 @@ + + + + + Payer DFSP + + Payee DFSP + + + + + + + + + + + + + + + + + Payer + + + Payer + + + + Core Banking System + + Core Banking System + + SDK + + SDK + + Mojaloop + + Mojaloop + + SDK + + SDK + + Core Banking System + + Core Banking System + Payee + + + Payee + + + + + + + + alt + [if (User Initiated OTP)] + + + [1] + Generate an OTP for me + + + + + [2] + Generate + + + [3] + Here is your OTP + + + + + Payee initiated request to pay (R2P) + + + [4] + I would like + to receive 1000 TZS + from +1234567890 + + + + + [5] + Payer not within Payee System + + + [6] + POST + /requestToPayTransfer + + + { + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "+1234567890", + "idSubValue": "string" + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "scenario": {...}, + "initiator": "PAYEE", + "initiatorType": "CONSUMER", + "note": "Note sent to Payee." + } + + + + [7] + GET + /parties + + + + [8] + GET + /parties + + + [9] + GET + /parties + + + + + [10] + Lookup Validate Payer Account + + + [11] + return Payer information + + + Payer information + + + + [12] + PUT + /parties + + + + [13] + PUT + /parties + + + alt + [If AutoAcceptParty = false] + + + [14] + POST + /requestToPayTransfer + (synchronous return) + + + { + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "1234567890", + "idSubValue": "string", + "displayName": "ryZ037pWP'lHu,Tu9,Tjl MRMbdMSpRGAHt4m6 2jk5L4'ePRWT", + "firstName": "Henrik", + "middleName": "Johannes", + "lastName": "Karlsson", + "dateOfBirth": "1966-06-16", + "fspId": "string", + "extensionList": [] + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "transactionType": "TRANSFER", + "note": "Note sent to Payee.", + "currentState": "WAITING_FOR_PARTY_ACCEPTANCE", + } + + + [15] + PUT + /requestToPay/ + {requestToPayId} + + + { + acceptParty: true + } + + + + + + [16] + Automatically + AcceptParty by updating + status + + + + [17] + POST + /transactionRequests + + + + [18] + POST + /transactionRequests + + + [19] + POST + /transactionRequests + + + + + [20] + Validate request + to pay request + + + [21] + return + + + + [22] + PUT + /transactionRequests/{ID} + + + { + "transactionId": "b51ec534-ee48-4575-b6a9-ead2955b8069", + "transactionRequestState": "RECEIVED", + "AuthenticationType": {} + "extensionList": {extension:[]} + } + + + + [23] + PUT + /transactionRequests + + + [24] + return + + + + + Payer DFSP executes R2P request + + + [25] + POST + /RequestToPayTransfer + + + Initiate R2P with AuthType + + + + [26] + POST + /quotes + + + + [27] + POST + /quotes + + + [28] + POST + /quoterequest + + + [29] + return quote + + + + [30] + PUT + /quotes + + + + [31] + PUT + /quotes + + + [32] + return + ( + POST + /RequestToPayTransfer) + + + alt + [if AuthenticateType is null] + + + [33] + Present payment terms + to Payer for acceptance + + + [34] + I accept the payment terms + + [if AuthenticateType is OTP] + + + alt + [if (Automatic generated OTP)] + + + + + [35] + Generate OTP + + + [36] + Present OTP to Payer + + + loop + [x retries] + + + [37] + PUT + /RequestToPayTransfer + + + accept quote = true + retries left = x + + + + [38] + GET +   + /authorizations/ + {transactionRequestID} + + + + [39] + GET +   + /authorizations/ + {transactionRequestID} + + + [40] + GET +   + /auth/{authtype}/{requestToPayId} + + + [41] + Get Payee to get + Payer to enter OTP + on POS + + + [42] + Enter OTP + + + [43] + return OTP + + + { + "otpValue": "string" + } + + + + [44] + PUT + /authorizations/{ID} + + + + [45] + PUT + /authorizations/{ID} + + + [46] + synchronous return +   + POST + /requestToPayTransfer/ + {requestToPayTransactionId} + + + + + [47] + Validate OTP + + + alt + [if can proceed with transfer] + + + + + [48] + Reserve funds against + Payer's account + + + [49] + PUT +   + /requestToPayTransfer/ + {requestToPayTransactionId} + + + + [50] + POST + /transfers + + + + [51] + POST + /transfers + + + [52] + PUT + / + POST + /requestToPayTransfer/ + {requestToPayTransactionId} + return + + + [53] + Notify user + + + + [54] + PUT + /transfers + return fulfilment + + + + [55] + PUT + /transfers + + + [56] + POST +   + /newAPI + Notify payer of transfer + + + + + [57] + Commit transfer + to Payer's account + + + [58] + Notify Payer + + [if rejected] + + + [59] + return + + + + [60] + PUT +   + /requestToPayTransfer/ + {requestToPayTransactionId} + rejected + + + + [61] + PUT + /requestToPayTransfer/ + {requestToPayTransactionId} + rejected + + + + [62] + return rejected + + diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg new file mode 100644 index 000000000..c395e3caa --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg @@ -0,0 +1 @@ +Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payeetopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventsloop[for each transfer in bulk]alt[Bulk quotes supported][Bulk quotes NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventsPOST /bulkquotesProcess Trace HeadersInboundBulkQuotesRequestReceivedAcceptedProcessInboundBulkQuotesRequestUpdate the bulk state: RECEIVEDCheck if bulkQuotes supported by payeeSDKBulkQuotesRequestedUpdate the bulk state: PROCESSINGProcess outbound Trace HeadersPOST /bulkQuotesAcceptedPUT /bulkQuotesProcess inbound Trace HeadersSDKBulkQuotesCallbackReceivedAcceptedQuoteRequestedUpdate the individual state: QUOTES_PROCESSINGProcess outbound Trace HeadersPOST /quotesSynchronous responseProcess Inbound Trace HeadersQuotesResponseReceivedProcessQuotesResponseUpdate the individual state: QUOTES_SUCCESS / QUOTES_FAILEDQuotesResponseProcessedCheck the status of the remaining items in the bulkProcessInboundBulkQuotesRequestCompleteUpdate the bulk state: COMPLETEDInboundBulkQuotesRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkQuotes/{bulkQuoteId}AcceptedInboundBulkQuotesReponseSentProcessInboundBulkQuotesReponseSentUpdate bulk state "RESPONSE_SENT"Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payee \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg new file mode 100644 index 000000000..6deaf1f7a --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg @@ -0,0 +1 @@ +Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payeetopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-command-eventstopic-sdk-domain-eventsloop[for each transfer in bulk]alt[Bulk transfers supported][Bulk transfers NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-command-eventstopic-sdk-domain-eventsloop[for each transfer in bulk]alt[Bulk transfers supported][Bulk transfers NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventsalt[bulkStatus == 'ACCEPTED']POST /bulkTransfersProcess Trace HeadersInboundBulkTransfersRequestReceivedAcceptedProcessInboundBulkTransfersRequestUpdate the bulk state: RECEIVEDCheck if bulkQuotes supported by payeeSDKBulkTransfersRequestedUpdate the bulk state: PROCESSINGProcess outbound Trace HeadersPOST /bulkTransfersAcceptedPUT /bulkTransfersProcess inbound Trace HeadersSDKBulkTransfersCallbackReceivedAcceptedTransferRequestedUpdate the individual state: TRANSFERS_PROCESSINGProcess outbound Trace HeadersPOST /transfersSynchronous ResponseProcess Inbound Trace HeadersTransfersCallbackReceivedProcessTransfersCallbackUpdate the individual state: TRANSFERS_SUCCESS / TRANSFERS_FAILEDTransfersCallbackProcessedCheck the status of the remaining items in the bulkProcessInboundBulkTransfersRequestCompleteUpdate the bulk state: COMPLETED?InboundBulkTransfersRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkTransfers/{bulkTransferId}AcceptedInboundBulkTransfersResponseSentProcessInboundBulkTransfersResponseSentUpdate bulk state "RESPONSE_SENT"Check bulkStatusPATCH /bulkTransfers/{bulkTransferId}AcceptedProcess Trace HeadersInboundBulkTransfersPatchRequestReceivedAcceptedProcessInboundBulkTransfersPatchRequestUpdate the bulk state: PATCH_RECEIVEDCheck if bulkTransfers supported by payeeSDKBulkTransfersPatchRequestedUpdate the bulk state: PATCH_PROCESSINGProcess outbound Trace HeadersPATCH /bulkTransfers/{bulkTransferId}AcceptedResponse to Patch /bulkTransfersProcess inbound Trace HeadersSDKBulkTransfersPatchCallbackReceivedAcceptedTransfersPatchRequestedUpdate the individual state: TRANSFERS_PATCH_PROCESSINGProcess outbound Trace HeadersPATCH /transfers/{transferId}AcceptedProcess Inbound Trace HeadersTransfersPatchCallbackReceivedAcceptedProcessTransfersPatchCallbackUpdate the individual state: TRANSFERS_PATCH_SUCCESS / TRANSFERS_PATCH_FAILEDTransfersPatchCallbackProcessedCheck the status of the remaining items in the bulkProcessInboundBulkTransfersPatchRequestCompleteUpdate the bulk state: COMPLETEDInboundBulkTransfersPatchRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkTransfers/{bulkTransferId}AcceptedInboundBulkTransfersPatchResponseSentProcessInboundBulkTransfersPatchResponseSentUpdate bulk state "PATCH_RESPONSE_SENT"Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payee \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg new file mode 100644 index 000000000..d611c2057 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg @@ -0,0 +1 @@ +Core ConnectorSDK Backend APISDK Outbound Domain Event HandlerSDK Outbound Command Event HandlerSDK FSPIOP APIMojaloop Switchtopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventsalt[party info already exists][party info doesn't exist]topic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventsloop[Party Lookup per transfer]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsalt[autoAcceptParty == false][autoAcceptParty == true (In future we can make this optional and an external service can handle this)]loop[for each transfer in bulk]topic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[through items in batch]topic-sdk-outbound-domain-eventsloop[BulkQuotes requests per batch]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[for each individual transfer in bulk]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[for each individual transfer in bulk]topic-sdk-outbound-domain-eventsalt[autoAcceptQuote == false][autoAcceptQuote == true]topic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[through items in batch]topic-sdk-outbound-domain-eventsloop[BulkTransfers requests per each batch and include only items with AGREEMENT_ACCEPTED]topic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsSDKBulkRequest1Scheme Validation2Process Trace Headers3SDKOutboundBulkRequestReceived4Accepted5ProcessSDKOutboundBulkRequest6Store initial data into redis (Generate UUIDs and map to persistent model, break the JSON into smaller parts)7Update global state "RECEIVED"8SDKOutboundBulkPartyInfoRequested9ProcessSDKOutboundBulkPartyInfoRequest10Update global state "DISCOVERY_PROCESSING"11Update the global state to DISCOVERY_RECEIVED12PartyInfoCallbackReceived13Update the party request14PartyInfoRequested (includes info for SDK for making a party call)15Set individual state: DISCOVERY_PROCESSING16Process outbound Trace Headers17GET /parties18PUT /parties19Process Inbound Trace Headers20PartyInfoCallbackReceived21ProcessPartyInfoCallback22Update the individual state: DISCOVERY_SUCCESS / DISCOVERY_FAILED23Update the party response24PartyInfoCallbackProcessed25Check the status of the remaining items in the bulk26Update global state "DISCOVERY_COMPLETED"27SDKOutboundBulkPartyInfoRequestProcessed28check options.autoAcceptParty in redis29SDKOutboundBulkAcceptPartyInfoRequested30Update global state "DISCOVERY_ACCEPTANCE_PENDING"31Process outbound Trace Headers32PUT /bulkTransactions/{bulkTransactionId}33Accepted34PUT /bulkTransactions/{bulkTransactionId}35Process inbound Trace Headers36SDKOutboundBulkAcceptPartyInfoReceived37Accepted38ProcessSDKOutboundBulkAcceptPartyInfo39SDKOutboundBulkAutoAcceptPartyInfoRequested40Create SDKOutboundBulkAcceptPartyInfo with acceptParty=true for individual items with DISCOVERY_SUCCESS state41ProcessSDKOutboundBulkAcceptPartyInfo42Update the individual state: DISCOVERY_ACCEPTED / DISCOVERY_REJECTED43Update global state "DISCOVERY_ACCEPTANCE_COMPLETED"44SDKOutboundBulkAcceptPartyInfoProcessed45ProcessSDKOutboundBulkQuotesRequest46Update global state "AGREEMENT_PROCESSING"47Create bulkQuotes batches from individual items with DISCOVERY_ACCEPTED state per FSP and maxEntryConfigPerBatch48Update bulkQuotes request49BulkQuotesRequested50Update the batch state: AGREEMENT_PROCESSING51Process outbound Trace Headers52POST /bulkQuotes53Accepted54PUT /bulkQuotes55Process inbound Trace Headers56BulkQuotesCallbackReceived57Accepted58ProcessBulkQuotesCallback59Update the batch state: AGREEMENT_COMPLETED / AGREEMENT_FAILED60Update the individual state: AGREEMENT_SUCCESS / AGREEMENT_FAILED61Update the quote response62BulkQuotesCallbackProcessed63Check the status of the remaining items in the bulk64Update global state "AGREEMENT_COMPLETED"65SDKOutboundBulkQuotesRequestProcessed66check autoAcceptQuote67SDKOutboundBulkAcceptQuoteRequested68Update global state "AGREEMENT_ACCEPTANCE_PENDING"69Process outbound Trace Headers70PUT /bulkTransactions/{bulkTransactionId}71Accepted72PUT /bulkTransactions/{bulkTransactionId}73Process inbound Trace Headers74SDKOutboundBulkAcceptQuoteReceived75Accepted76ProcessSDKOutboundBulkAcceptQuote77Update the individual state: AGREEMENT_ACCEPTED / AGREEMENT_REJECTED78Update global state "AGREEMENT_ACCEPTANCE_COMPLETED"79SDKOutboundBulkAcceptQuoteProcessed80SDKOutboundBulkAutoAcceptQuoteRequested81ProcessSDKOutboundBulkAutoAcceptQuote82Check fee limits83Update the individual state: AGREEMENT_ACCEPTED / AGREEMENT_REJECTED84Update global state "AGREEMENT_ACCEPTANCE_COMPLETED"85SDKOutboundBulkAutoAcceptQuoteProcessed86ProcessSDKOutboundBulkTransfersRequest87Update global state "TRANSFERS_PROCESSING"88Update the request89BulkTransfersRequested90Update the batch state: TRANSFERS_PROCESSING91Process outbound Trace Headers92POST /bulkTransfers93Accepted94PUT /bulkTransfers95Process inbound Trace Headers96BulkTransfersCallbackReceived97Accepted98ProcessBulkTransfersCallback99Update the batch state: TRANSFERS_COMPLETED / TRANSFERS_FAILED100Update the individual state: TRANSFERS_SUCCESS / TRANSFERS_FAILED101Update the transfer response102BulkTransfersCallbackProcessed103Check the status of the remaining items in the bulk104Update global state "TRANSFERS_COMPLETED"105SDKOutboundBulkTransfersRequestProcessed106PrepareSDKOutboundBulkResponse107Build response from redis state108SDKOutboundBulkResponsePrepared109Update global state "RESPONSE_PROCESSING"110Process outbound Trace Headers111Send the response as callback112Accepted113SDKOutboundBulkResponseSent114ProcessSDKOutboundBulkResponseSent115Update global state "RESPONSE_SENT"116SDKOutboundBulkResponseSentProcessed117Core ConnectorSDK Backend APISDK Outbound Domain Event HandlerSDK Outbound Command Event HandlerSDK FSPIOP APIMojaloop Switch \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg new file mode 100644 index 000000000..998a7145b --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg @@ -0,0 +1,4 @@ + + + +
    Payee
    Core
    Payee...
    POST /transactionRequest
    POST /transactionRequest
    (Add authenticationType)
    (Add authenticationType)
    PUT /transactionRequest
    PUT /transactionRequest
    Payer SDK
    Payer...
    Payee SDK
    Payee...
    POST /transactionRequest
    POST /transactionRequest
    PUT /transactionRequest
    PUT /transactionRequest
    Switch
    Switch
    Payer
    Core
    Payer...
    POST /RequestToPay
    POST /RequestToPay
    (Add authenticationType,
    rename homeTxId to homeR2PTrxId
    )
    (Add authenticationType,...
    POST /transactionRequest
    POST /transactionRequest
    RES: POST /RequestToPay
    RES: POST /RequestToPay
    POST /quotes
    POST /quotes
    POST /quotes
    POST /quotes
    POST /quotesrequest
    POST /quotesrequest
    (Add homeR2PTrxId)
    (Add homeR2PTrxId)
    PUT /quotes
    PUT /quotes
    PUT /quotes
    PUT /quotes
    PUT /RequestToPay
    PUT /RequestToPay
    RES: PUT /RequestToPay
    RES: PUT /RequestToPay
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    (Add authResponse)
    (Add authResponse)
    RES: POST /transactionRequest
    RES: POST /transactionRequest
    (Add homeR2PTxId (optional),
    rename transferAmount to 
    transactionRequestState 
    )
    (Add homeR2PTxId (optional),...
    POST /requestToPayTransfer
    POST /requestToPayTransfer
    (Add homeR2PTxId,
    Add authenticationType,
    Rename rTPayTrxId to tReqId)
    (Add homeR2PTxId,...
    GET /authorizations
    GET /authorizations
    (authenticationType hardcoded,
    retriesLeft hardcoded
    )
    (authenticationType hardcoded,...
    Accept payment and terms
    and generate OTP
    Accept pay...
    GET /authorizations
    GET /authorizations
    GET /otp
    GET /otp
    (rename rtpId to
    tRequestId,
    Add homeR2PTrxId,
    Add retriesLeft
    )
    (rename rtpId to...
    PUT /authorizations
    PUT /authorizations
    PUT /authorizations
    PUT /authorizations
    If OTP
    If OTP
    RES: POST /requestToPayTransfer
    RES: POST /requestToPayTransfer
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (accept quote,
    Add retriesLeft)
    (accept quote,...
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (accept quote/auth)
    (accept quote/auth)
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    Payer
    Payer
    POST /transfers
    POST /transfers
    POST /transfers
    POST /transfers
    PUT /transfers
    PUT /transfers
    PUT /transfers
    PUT /transfers
    Payer provides OTP
    Payer prov...
    Payer
    Payer
    POST /transfers
    POST /transfers
    (Add transactionRequestId, 
    Add homeR2PTrxId
    )
    (Add transactionRequestId,...
    Validate Payer Details
    Validate P...
    Payer
    Payer
    Calculate fees and set terms.
    Present to Payer to validate.
    Calculate...
    Payer
    Payer
    PoS - Point of Sale device at Merchant
    PoS - Point of Sale devic...
    Payee PoS
    Payee PoS
    Payee Pos
    Payee Pos
    Payee PoS
    Payee PoS
    PUT /parties
    PUT /parties
    GET /parties
    GET /parties
    PUT /Parties
    PUT /Parties
    GET /parties
    GET /parties
    GET /parties
    GET /parties
    PoS displays
    Payment Confirmation
    PoS displa...
    Payer
    Payer
    Payee PoS
    Payee PoS
    Validate RTP
    Validate R...
    Initiate RTP with
    AuthType
    Initiate R...
    Validate OTP
    Validate O...
    Retry on
    OTP Failure
    Retry...
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (reject)
    (reject)
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    PUT /transactionRequest
    PUT /transactionRequest
    (rejected state)
    (rejected state)
    PUT /RequestToPay
    PUT /RequestToPay
    (rejected state)
    (rejected state)
    If Rejected
    If Rejected
    PUT /transactionRequest
    PUT /transactionRequest
    (rejected state)
    (rejected state)
    If Accepted
    If Accepted
    Payer Receives
    Payment Confirmation
    Payer Rece...
    Payer
    Payer
    Payer Receives
    Rejection Notification
    Payer Rece...
    Payer
    Payer
    PoS displays
    Rejection Notification
    PoS displa...
    Payer
    Payer
    Payee PoS
    Payee PoS
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/usage/README.md b/docs/fr/technical/technical/sdk-scheme-adapter/usage/README.md new file mode 100644 index 000000000..2e8b98b88 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/usage/README.md @@ -0,0 +1,46 @@ +# Vue d’ensemble des scénarios d’usage testés du SDK + +Un *scheme adapter* est un service qui fait l’interface entre un *switch* conforme à l’API Mojaloop et une plateforme backend DFSP qui n’implémente pas nativement l’API Mojaloop. + +L’API entre le *scheme adapter* et le backend DFSP est du HTTP synchrone ; l’interface entre le *scheme adapter* et le *switch* est l’API Mojaloop native. + +Ce document présente différentes configurations qu’un DFSP peut tester avec le *scheme adapter*. + +# Scénarios + +Scénarios testés et documentés : + +* [[Scheme Adapter + Mock DFSP Backend] → [Scheme Adapter + Mojaloop Simulator]](./scheme-adapter-to-scheme-adapter/README.md) +* [[Scheme Adapter + Mock DFSP Backend] → [Cluster K8s local]](./scheme-adapter-and-local-k8s/README.md) +* [[Scheme Adapter + Mojaloop Simulator] → [Switch Mojaloop public compatible WSO2]](./scheme-adapter-and-wso2-api-gateway/README.md) + +## [Scheme Adapter + Mock DFSP Backend] → [Scheme Adapter + Mojaloop Simulator] + +Le *scheme adapter* peut être utilisé en combinaison avec les backends simulés déjà implémentés : *Mock DFSP Backend* et *Mojaloop Simulator*. Dépôts : + +https://github.com/mojaloop/sdk-mock-dfsp-backend.git + +https://github.com/mojaloop/mojaloop-simulator.git + +L’idée est d’associer le *scheme adapter* et le backend simulé DFSP d’un côté, et le simulateur Mojaloop de l’autre — par exemple payeur et bénéficiaire. En suivant cet exemple, vous pouvez envoyer et recevoir des fonds d’un DFSP à l’autre. + +Voir la [documentation détaillée](./scheme-adapter-to-scheme-adapter/README.md). + +![SchemeAdapterToSchemeAdapter](./scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png) + +## [Scheme Adapter + Mock DFSP Backend] → [Cluster K8s local] + +Si l’on souhaite intercaler un *switch* entre les DFSP, on peut simuler cet environnement avec un cluster Kubernetes local. Suivre le guide de déploiement : https://mojaloop.io/documentation/deployment-guide/ + +Voir la [documentation](./scheme-adapter-and-local-k8s/README.md). + +![SchemeAdapterAndK8S](./scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png) + +## [Scheme Adapter + Mojaloop Simulator] → [Switch Mojaloop public compatible WSO2] + +Avec accès à l’API Mojaloop WSO2, les tests décrits ici utilisent l’authentification par jeton et le chiffrement SSL du *scheme adapter* (contrairement aux deux scénarios précédents). + +Voir la [documentation](./scheme-adapter-and-wso2-api-gateway/README.md). + + +![SchemeAdapterAndWSO2APIGateway](./scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png) diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md new file mode 100644 index 000000000..61e23e028 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md @@ -0,0 +1,208 @@ +# SDK Scheme Adapter et cluster Kubernetes local + +Documentation pour tester un déploiement Mojaloop sur cluster Kubernetes avec le *scheme adapter* et un *mock backend* DFSP. + +![Vue d’ensemble](scheme-adapter-and-local-k8s-overview.png) + +## Prérequis + +* Cluster Kubernetes Mojaloop opérationnel (local ou cloud) +* Service *DFSP mock backend* +* `sdk-scheme-adapter` > 8.6.0 + +## Configuration et démarrage des services + +### Déploiement Mojaloop sur Kubernetes local + +Suivre : https://mojaloop.io/documentation/deployment-guide/ + +Linux est recommandé ; prévoir au moins 16 Go de RAM et 4 cœurs. + +Après installation, exécuter la collection Postman `OSS-New-Deployment-FSP-Setup.postman_collection` depuis https://github.com/mojaloop/postman + +Vérifier la configuration des *oracles* et des endpoints, et l’exécution réussie de la *Golden Path Collection*. + +### *Mock backend* DFSP et SDK Scheme Adapter + +Utiliser une version du SDK *scheme adapter* supérieure à 8.6.0. +L’étape suivante démarre le *scheme adapter* via `docker-compose`. + +Cloner : https://github.com/mojaloop/sdk-mock-dfsp-backend + +Vérifier `docker-compose.yml` : + +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 +``` + +Mettre à jour `backend.env` : +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Mettre à jour `scheme-adapter.env` avec les hôtes adaptés (fichier `/etc/hosts` ou `extra_hosts`, voir ci-dessous) : + +``` +DFSP_ID=safsp +CACHE_HOST=redis2 +ALS_ENDPOINT=account-lookup-service.local +QUOTES_ENDPOINT=quoting-service.local +TRANSFERS_ENDPOINT=ml-api-adapter.local +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true +``` + +### Résolution de noms — macOS uniquement + +Ajouter à `/etc/hosts` (remplacer l’IP par celle de la machine) : +``` +192.168.5.101 ml-api-adapter.local account-lookup-service.local central-ledger.local central-settlement.local account-lookup-service-admin.local quoting-service.local moja-simulator.local central-ledger central-settlement ml-api-adapter account-lookup-service account-lookup-service-admin quoting-service simulator host.docker.internal moja-account-lookup-mysql +``` + +Remplacer `192.168.5.101` par votre adresse IP réelle accessible depuis les conteneurs si besoin. + +### Résolution de noms — Linux uniquement + +Ajouter `extra_hosts` sous `scheme-adapter2` dans `docker-compose.yml` pour résoudre `account-lookup-service.local`, `quoting-service.local` et `ml-api-adapter.local`, par exemple : + +``` + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 + extra_hosts: + - "account-lookup-service.local:172.17.0.1" + - "quoting-service.local:172.17.0.1" + - "ml-api-adapter.local:172.17.0.1" +``` + +`172.17.0.1` est l’interface `docker0` par défaut ; vérifier qu’elle convient à votre installation. + +### Démarrage + +``` +cd src +docker-compose up -d +``` + +## Tests + +### Configurer un nouveau FSP + +Télécharger : + +* [Mojaloop-Local.postman_environment_modified.json](assets/postman_files/Mojaloop-Local.postman_environment_modified.json) — variables d’environnement pointant vers votre installation locale +* [OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json](assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json) — provisionnement d’un nouveau FSP + +`SCHEME_ADAPTER_ENDPOINT` doit cibler votre *scheme adapter* local. Sous macOS, `http://host.docker.internal:4000` est souvent correct. Sous Linux, utiliser l’interface `docker0` (souvent `172.17.0.1`), comme indiqué plus haut. + +Dans Postman, sélectionner l’environnement et exécuter la collection pour créer un FSP `safsp`. Les endpoints de `safsp` correspondront à l’URL du *scheme adapter* définie dans l’environnement. + +### Ajouter le MSISDN cible au simulateur bénéficiaire (dans le cluster) + +``` +curl -X POST \ + http://moja-simulator.local/payeefsp/parties/MSISDN/27713803912 \ + -H 'Accept: */*' \ + -H 'Accept-Encoding: gzip, deflate' \ + -H 'Cache-Control: no-cache' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 406' \ + -H 'Content-Type: application/json' \ + -H 'Host: moja-simulator.local' \ + -H 'User-Agent: PostmanRuntime/7.20.1' \ + -H 'cache-control: no-cache' \ + -d '{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "27713803912", + "fspId": "payeefsp" + }, + "name": "Siabelo Maroka", + "personalInfo": { + "complexName": { + "firstName": "Siabelo", + "lastName": "Maroka" + }, + "dateOfBirth": "1974-01-01" + } + } +}' + +curl -X POST \ + http://account-lookup-service.local/participants/MSISDN/27713803912 \ + -H 'Accept: application/vnd.interoperability.participants+json;version=1' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 50' \ + -H 'Content-Type: application/vnd.interoperability.participants+json;version=1.0' \ + -H 'Date: Fri, 21 Dec 2018 12:17:01 GMT' \ + -H 'FSPIOP-Source: payeefsp' \ + -H 'Host: account-lookup-service.local' \ + -H 'User-Agent: PostmanRuntime/7.11.0' \ + -H 'accept-encoding: gzip, deflate' \ + -H 'cache-control: no-cache,no-cache' \ + -d '{ + "fspId": "payeefsp", + "currency": "USD" +}' +``` + +### Essayer un envoi de fonds + +Envoyer des fonds depuis `safsp` (*Mock DFSP*) vers un MSISDN enregistré chez `payeefsp` (simulateur dans le cluster). + +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "27713803912" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" +}' +``` + +La réponse doit indiquer `currentState` à **COMPLETED**. diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json rename to docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json rename to docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png rename to docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md new file mode 100644 index 000000000..3197e0379 --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md @@ -0,0 +1,215 @@ +# SDK Scheme Adapter et passerelle API WSO2 + +Guide pour tester le *scheme adapter* contre une passerelle WSO2 publique avec TLS et authentification par jeton *bearer*. + + +![Vue d’ensemble](scheme-adapter-and-wso2-api-gateway-overview.png) + +## Prérequis + +* Accès à l’API de production WSO2 avec jeton généré +* `sdk-scheme-adapter` +* `mojaloop-simulator` + +## Générer le jeton d’accès et les URL WSO2 + +* Se connecter au *store* WSO2, menu *Applications* : créer une application et des clés d’accès si nécessaire. +* Menu *APIs* : s’abonner aux deux API ci-dessous (application et *tier* depuis la page de chaque API). + * **Central Ledger Admin API** — création de FSP et configuration des endpoints (demander à l’équipe infra les URL HTTPS correctes sur le Hub). + * **FSPIOP API** — recherche de compte, devis et transferts. +* Tester des requêtes dans l’onglet *API Console* avec le jeton généré. +* Noter les URL des deux API et le jeton d’accès. + + +## Côté infrastructure + +Points généralement gérés par l’équipe infrastructure (les contacter pour le détail) : + +* Machine avec IP publique fixe et nom de domaine pointant vers cette IP pour recevoir les réponses. +* Certificats client/serveur (portail MCM, outil de *keychain*) pour la communication en *mutual* TLS. +* Publication des endpoints vers votre adresse HTTPS dans WSO2 / HAProxy. +* Mise en place de l’authentification JWS. +* **Déploiement AWS** (exemple) + * Créer une instance EC2 (**t2.micro**, **Ubuntu 18.04**), connexion SSH avec la clé fournie par la console. + * Installer Docker et Docker Compose sur l’instance. + * Ouvrir le port TCP **4000** dans le groupe de sécurité ; associer une *Elastic IP* pour une adresse statique. + * Associer un nom DNS (Route 53 ou autre) à cette IP — nécessaire car Let’s Encrypt ne délivre pas de certificats pour une IP seule. + + +## Configurer le Scheme Adapter avec Mojaloop Simulator + +Cloner le simulateur : +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Remplacer les certificats et clés dans `src/secrets` par ceux générés précédemment. + +* Adapter `src/docker-compose.yml`, par exemple : + + ``` + version: '3' + services: + redis: + image: "redis:5.0.4-alpine" + container_name: redis + backend: + image: "mojaloop/mojaloop-simulator-backend" + env_file: ./sim-backend.env + container_name: ml_simulator + ports: + - "3000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + volumes: + - ./secrets:/src/secrets + ports: + - "3500:3000" + - "4000:4000" + depends_on: + - redis + ``` + +* `src/sim-backend.env` : + + ``` + OUTBOUND_ENDPOINT=http://src_scheme-adapter_1:4001 + DFSP_ID=extpayerfsp + ``` + +* `src/scheme-adapter.env` : + + ``` + MUTUAL_TLS_ENABLED=true + CACHE_HOST=redis + DFSP_ID=extpayerfsp + BACKEND_ENDPOINT=ml_simulator:3000 + PEER_ENDPOINT= + AUTO_ACCEPT_QUOTES=true + ``` + +Démarrer : +``` +cd src/ +docker-compose up -d +``` + +L’API de test du simulateur est sur le port **3003**. + +## Provisionner le DFSP `extpayerfsp` avec les bons endpoints + +Créer un FSP (nom libre, ex. `extpayerfsp`). + +Utiliser la section d’intégration FSP de la collection Postman `OSS-New-Deployment-FSP-Setup` — dépôt https://github.com/mojaloop/postman. + +* Dupliquer l’environnement `Mojaloop-Local` et ajuster : + * `payerfsp` → `extpayerfsp` + * `HOST_ML_API_ADAPTER`, `HOST_ML_API`, `HOST_SWITCH_TRANSFERS`, `HOST_ACCOUNT_LOOKUP_SERVICE`, `HOST_QUOTING_SERVICE` → l'endpoint FSPIOP WSO2 + * `HOST_CENTRAL_LEDGER` → API d’administration des services centraux WSO2 + * `HOST_CENTRAL_SETTLEMENT` → règlement central WSO2 (optionnel pour ces tests) + * `HOST_SIMULATOR` et `HOST_SIMULATOR_K8S_CLUSTER` → `https://:4000` +* Dans *FSP Onboarding*, remplacer les URL `payerfsp` par `extpayerfsp`. +* Pour tout le dossier *Payer FSP Onboarding* : authentification *Bearer Token* avec le jeton WSO2 ; URL en HTTPS fournies par l’infra. +* Exécuter le dossier *Payer FSP Onboarding* avec le nouvel environnement. + +Un passage à 100 % valide la création du FSP et la configuration des endpoints. + +## Provisionner `payeefsp` et enregistrer un participant (simulateur MSISDN) + +Le simulateur côté *switch* inclut généralement `payeefsp` ; enregistrer un participant (numéro) au choix. + +Référence Postman : `p2p_happy_path SEND QUOTE / Register Participant {{pathfinderMSISDN}} against MSISDN Simulator for PayeeFSP` dans la collection `Golden_Path`. + +La requête envoie un `POST` sur `/participants/MSISDN/` avec le corps et les en-têtes requis, par exemple : +``` +{ + "fspId": "payeefsp", + "currency": "USD" +} +``` + +## Envoyer des fonds + +### En une étape + +Activer `AUTO_ACCEPT_QUOTES` et `AUTO_ACCEPT_PARTY` dans `scheme_adapter.env`. + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "919848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + } +]' + +``` + +### En deux étapes + +Demander d’abord une devis, puis accepter après vérification des frais et de la partie : + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + }, + { + "name": "scenario2", + "operation": "putTransfers", + "params": { + "transferId": "{{scenario1.result.transferId}}" + }, + "body": { + "acceptQuote": true + } + } +]' + +``` diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png rename to docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png diff --git a/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md new file mode 100644 index 000000000..41dc9aadb --- /dev/null +++ b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md @@ -0,0 +1,183 @@ +# Test Scheme Adapter vers Scheme Adapter + +Documentation pour les DFSP qui souhaitent tester un transfert d’un *scheme adapter* vers un autre, en s’appuyant sur le *mock backend* et les services du simulateur Mojaloop. + +![Vue d’ensemble](scheme-adapter-to-scheme-adapter-overview.png) + +## Prérequis + +* Mojaloop Simulator +* Service *DFSP mock backend* +* Le *scheme adapter* est déjà inclus dans les deux *docker-compose* ci-dessous + +## Configuration et démarrage des services + +L’idée est d’exécuter en parallèle les deux *docker-compose*. Pour éviter les conflits, éditez chaque `docker-compose.yml` et fixez explicitement les noms de conteneurs. + +### Service Mojaloop Simulator + +Cloner le dépôt du simulateur Mojaloop : +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Modifier `src/docker-compose.yml` et ajouter les `container_name` pour tous les services — voir l’exemple : + +``` +version: '3' +services: + redis1: + image: "redis:5.0.4-alpine" + container_name: redis1 + sim: + image: "mojaloop-simulator-backend" + build: ../ + env_file: ./sim-backend.env + container_name: ml_sim1 + ports: + - "13000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim1 + ports: + - "13500:3000" + - "14000:4000" + depends_on: + - redis1 +``` + +* Modifier `src/sim-backend.env` et pointer vers le bon nom de conteneur du *scheme adapter* : + +``` +OUTBOUND_ENDPOINT=http://sa_sim1:4001 +``` + +* Modifier `src/scheme-adapter.env` avec les noms du second *scheme adapter* et du simulateur, par exemple : + +``` +DFSP_ID=payeefsp +CACHE_HOST=redis1 +PEER_ENDPOINT=sa_sim2:4000 +BACKEND_ENDPOINT=ml_sim1:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +Puis lancer : +``` +cd src/ +docker-compose up -d +``` + +L’API de test du simulateur est alors disponible sur le port **3003**. + +Ajouter une partie au simulateur (adapter les champs si besoin) : +``` +curl -X POST "http://localhost:3003/repository/parties" -H "accept: */*" -H "Content-Type: application/json" -d "{\"displayName\":\"Test Payee1\",\"firstName\":\"Test\",\"middleName\":\"\",\"lastName\":\"Payee1\",\"dateOfBirth\":\"1970-01-01\",\"idType\":\"MSISDN\",\"idValue\":\"9876543210\"}" +``` + +Vérifier les parties : +``` +curl -X GET "http://localhost:3003/repository/parties" -H "accept: */*" +``` + +Ensuite, configurer la seconde instance (*scheme adapter* + *mock DFSP*). + +### Service DFSP Mock Backend + +Le *mock backend* est une implémentation minimale d’exemple ; seules des fonctions de base sont prises en charge. + +Cloner : +``` +git clone https://github.com/mojaloop/sdk-mock-dfsp-backend.git +``` + +Éditer `src/docker-compose.yml`, `src/backend.env` et `src/scheme-adapter.env` et définir les noms de conteneurs — voir : + +docker-compose.yml +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + depends_on: + - redis2 +``` +scheme-adapter.env +``` +DFSP_ID=payerfsp +CACHE_HOST=redis2 +PEER_ENDPOINT=sa_sim1:4000 +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +backend.env +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Démarrer : +``` +cd src/ +docker-compose up -d +``` + +## Essayer un envoi de fonds + +Envoyer des fonds depuis `payerfsp` (*Mock DFSP*) vers un MSISDN présent chez `payeefsp` (simulateur Mojaloop), via le *scheme adapter*. + +Exemple d’appel vers le *Mock DFSP* : +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9876543210" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "test payment", + "homeTransactionId": "123ABC" +}' +``` + +La réponse doit indiquer un `currentState` à **COMPLETED**. diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png b/docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png rename to docs/fr/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png diff --git a/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png new file mode 100644 index 000000000..736a5190c Binary files /dev/null and b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png differ diff --git a/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml new file mode 100644 index 000000000..088f3c16d --- /dev/null +++ b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml @@ -0,0 +1,107 @@ +@startuml dependency-vulnerability-management-process +!theme cerulean + +skinparam ActivityBackgroundColor #f0f0f0 +skinparam ActivityBorderColor #333333 +skinparam ArrowColor #333333 +skinparam backgroundColor white +skinparam ActivityFontColor black +skinparam ActivityFontSize 14 +skinparam noteFontColor black +skinparam ArrowFontColor black +skinparam PartitionFontColor #000000 +skinparam PartitionFontStyle bold +skinparam PartitionBorderColor #333333 +skinparam PartitionBackgroundColor #f8f8f8 + +title Processus de gestion des vulnérabilités des dépendances + +start + +partition "Outils de détection des vulnérabilités" { + :Identifier la vulnérabilité; + fork + :Alertes GitHub Dependabot; + fork again + :npm run audit:check; + note right: audit-ci.jsonc avec liste d’autorisation + fork again + :Analyse d’image Grype; + note right: .grype.yaml avec section d’ignorance + end fork +} + +partition "Processus de tri" { + :Trier la vulnérabilité; + :Évaluer le niveau de gravité; + fork + :Critique : 1 à 3 jours; + note right #FF6666: Action immédiate + fork again + :Élevé : 30 jours; + note right #FFCC66: Priorité élevée + fork again + :Moyen : 60 jours; + note right #FFFF66: Priorité moyenne + fork again + :Faible : 90 jours; + note right #99FF99: Priorité faible + end fork + :Agir selon la gravité\net les échéances de correction; +} + +partition "Processus de mise à jour" { + :Choisir un seul module à mettre à jour; + :Mettre à jour package.json; + :Exécuter les tests; + if (Tests OK ?) then (Oui) + :Créer une pull request; + else (Non) + if (Correction impossible ?) then (Oui) + fork + :Mettre à jour audit-ci.jsonc; + note right #F9E0FF: Pour les problèmes npm + fork again + :Mettre à jour .grype.yaml; + note right #F9E0FF: Pour les conteneurs + end fork + :Créer une pull request; + else (Non) + :Ajuster la mise à jour; + note right #F9E0FF + Envisager des solutions de repli + Contacter le mainteneur du paquet + end note + :Réexécuter les tests; + endif + endif + :Revue de code; + if (Résultat de la revue) then (Approuvé) + :Fusionner la PR; + else (Modifications demandées) + :Mettre à jour la PR; + endif +} + +partition "CI/CD" { + :Pipeline CI/CD; + :Contrôles de sécurité; + fork + :Contrôle audit-ci; + fork again + :Analyse Grype; + end fork + if (Contrôles OK ?) then (Oui) + :Publication / release; + else (Non) + :Corriger les problèmes de sécurité; + endif +} + +if (Autres vulnérabilités ?) then (Oui) + :Revenir au choix du module; +else (Non) + stop +endif + +@enduml diff --git a/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg new file mode 100644 index 000000000..a58b4cfa9 --- /dev/null +++ b/docs/fr/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg @@ -0,0 +1,305 @@ + + Processus de gestion des vulnérabilités des dépendances + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Processus de gestion des vulnérabilités des dépendances + + + + Outils de détection des vulnérabilités + + Identifier la vulnérabilité + + + Alertes GitHub Dependabot + + + audit-ci.jsonc avec liste d’autorisation + + npm run audit:check + + + .grype.yaml avec section d’ignorance + + Analyse d’image Grype + + + + Processus de tri + + Trier la vulnérabilité + + Évaluer le niveau de gravité + + + + Action immédiate + + Critique : 1 à 3 jours + + + Priorité élevée + + Élevé : 30 jours + + + Priorité moyenne + + Moyen : 60 jours + + + Priorité faible + + Faible : 90 jours + + + Agir selon la gravité + et les échéances de correction + + + Processus de mise à jour + + Choisir un seul module à mettre à jour + + Mettre à jour package.json + + Exécuter les tests + + Tests OK ? + Oui + Non + + Créer une pull request + + Correction impossible ? + Oui + Non + + + + Pour les problèmes npm + + Mettre à jour audit-ci.jsonc + + + Pour les conteneurs + + Mettre à jour .grype.yaml + + + Créer une pull request + + + Envisager des solutions de repli + Contacter le mainteneur du paquet + + Ajuster la mise à jour + + Réexécuter les tests + + + + Revue de code + + Résultat de la revue + Approuvé + Modifications demandées + + Fusionner la PR + + Mettre à jour la PR + + + + CI/CD + + Pipeline CI/CD + + Contrôles de sécurité + + + Contrôle audit-ci + + Analyse Grype + + + Contrôles OK ? + Oui + Non + + Publication / release + + Corriger les problèmes de sécurité + + + Revenir au choix du module + + Oui + Autres vulnérabilités ? + Non + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png new file mode 100644 index 000000000..551ea6515 Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png differ diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png new file mode 100644 index 000000000..4c14b2661 Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png differ diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png new file mode 100644 index 000000000..a77a907b2 Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png differ diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png new file mode 100644 index 000000000..d9d3a289b Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png differ diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png new file mode 100644 index 000000000..3a35c25b3 Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png differ diff --git a/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png new file mode 100644 index 000000000..2c313578f Binary files /dev/null and b/docs/fr/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png differ diff --git a/docs/fr/technical/technical/security/dependency-vulnerability-management.md b/docs/fr/technical/technical/security/dependency-vulnerability-management.md new file mode 100644 index 000000000..7b3d27d18 --- /dev/null +++ b/docs/fr/technical/technical/security/dependency-vulnerability-management.md @@ -0,0 +1,605 @@ +# Guide de gestion des vulnérabilités de dépendances Mojaloop + +Ce guide décrit le processus de gestion des vulnérabilités de sécurité dans les dépendances des dépôts GitHub de l'organisation Mojaloop. + +Ce guide se concentre principalement sur les vulnérabilités des dépendances. Pour les vulnérabilités découvertes dans le code source propre à Mojaloop (et non dans les dépendances), veuillez envoyer des informations détaillées par email à security@mojaloop.io et suivre la politique de Divulgation Coordonnée des Vulnérabilités (CVD). + +La politique CVD de Mojaloop prévoit un processus structuré pour le signalement, la validation et la remédiation des vulnérabilités dans le code Mojaloop. Elle garantit une divulgation responsable qui équilibre le besoin de protéger les utilisateurs tout en fournissant des informations transparentes sur les problèmes de sécurité. Cette politique inclut des délais clairs pour la réponse, la validation, la remédiation et la divulgation publique, permettant à l’équipe Sécurité de Mojaloop de traiter les vulnérabilités de façon coordonnée et d’en minimiser le risque pour les adoptants et utilisateurs du logiciel. + +## Table des matières + +- [Résumé exécutif](#executive-summary) +- [Vue d'ensemble](#overview) +- [Guide de démarrage rapide](#quickstart-guide) +- [Guide détaillé](#detailed-guide) + - [1. Comprendre ce qu’est une vulnérabilité et où les trouver](#1-understanding-what-is-a-vulnerability-and-where-to-find-them) + - [2. Flux de gestion pour les mises à jour de vulnérabilités de dépendances](#2-processflow-for-handling-dependency-vulnerability-updates) + - [3. Guide pratique pour les mises à jour de package.json](#3-practical-guide-to-packagejson-updates) + - [4. Bonnes pratiques de revue de code pour les PRs de sécurité](#4-code-review-best-practices-for-security-prs) + - [5. Intégration des développeurs et formation sur la gestion des vulnérabilités de dépendances](#5-developer-onboarding-and-dependency-vulnerability-management-education) + - [6. Amélioration continue](#6-continuous-improvement) + - [7. Conclusion](#7-conclusion) +- [Outils et ressources](#tools-and-resources) +- [Documentation associée](#related-documentation) + +## Résumé exécutif + +Ce guide propose une approche structurée pour le traitement des vulnérabilités de sécurité dans les dépendances des dépôts Mojaloop. Il répond au besoin actuel d’un processus standardisé pouvant aider les développeurs à comprendre les rapports de vulnérabilités (notamment les alertes GitHub Dependabot, résultats de npx audit et des scans grype), à appliquer les correctifs appropriés et à prioriser les mises à jour de sécurité à travers l’ensemble de la base de code. + +## Vue d’ensemble + +Le processus de gestion des vulnérabilités des dépendances de Mojaloop vise à : +- Identifier les vulnérabilités de sécurité dans les dépendances et le code +- Évaluer l’impact et la sévérité des vulnérabilités +- Prioriser les efforts de remédiation +- Suivre et vérifier les correctifs +- Maintenir la conformité en matière de sécurité + +## Guide de démarrage rapide + +Ce guide de démarrage rapide fournit les étapes essentielles pour la gestion des vulnérabilités dans les dépôts Mojaloop sans informations préalables. Pour des explications détaillées, voir les sections complètes ci-après. + +### 1. Détecter les vulnérabilités + +- Lancez `npm run audit:check` pour identifier les vulnérabilités des packages npm +- Vérifiez les alertes GitHub Dependabot dans l’onglet Sécurité de votre dépôt (si vous avez accès à l’onglet Sécurité) +- Utilisez Grype pour analyser les images de conteneurs, déclenché automatiquement si vous utilisez Mojaloop orb pour CircleCI et le rapport peut être consulté sur CircleCI (si vous avez accès à CircleCI) + +### 2. Évaluer et Prioriser + +- **Critique** : Corrigez sous 1 à 3 jours ouvrés +- **Élevé** : Corrigez sous 30 jours +- **Moyen** : Corrigez sous 60 jours +- **Faible** : Corrigez sous 90 jours + +### 3. Processus de correction + +1. Agir selon la sévérité et les dates cibles de correction +2. Sélectionnez un seul module à mettre à jour +3. Mettez à jour la dépendance vulnérable dans package.json +4. Exécutez les tests comme indiqué dans le README du dépôt pour vérifier la fonctionnalité +5. Si les tests passent, créez une pull request +6. Si les tests échouent et que vous ne pouvez pas corriger : + - Ajoutez à la allowlist dans audit-ci.jsonc (pour les packages npm) + - Ajoutez à la section ignore dans .grype.yaml (pour les vulnérabilités en conteneur) +7. Incluez tous les détails sur la vulnérabilité corrigée dans la PR + +### 4. Modèle de PR + +```markdown +## Correction de sécurité : [GHSA-ID ou CVE-ID] + +### Détails de la vulnérabilité +- Sévérité : [Critique/Élevé/Moyen/Faible] +- Package affecté : [nom du package] +- Versions vulnérables : [plage de versions] +- Version corrigée : [numéro de version] + +### Description +Brève description de la vulnérabilité et de son impact potentiel. + +### Modifications +- Mise à jour de [nom du package] de [ancienne version] à [nouvelle version] + +### Tests +- [X] Tests unitaires réussis +- [X] Tests d’intégration réussis +- [X] Tests manuels effectués +``` + +### 5. Revue et fusion + +- Veillez à ce que la mise à jour corrige correctement la vulnérabilité +- Vérifiez que les modifications dans package.json sont minimales +- Confirmez que tous les tests passent +- Contrôlez l’absence d’effets de bord inattendus +- Fusionnez après approbation + +## Guide détaillé + +Les sections suivantes apportent des explications complètes, des informations contextuelles et des procédures détaillées pour la gestion des vulnérabilités dans les dépôts Mojaloop. + +## 1. Comprendre ce qu’est une vulnérabilité et où les trouver + +Une vulnérabilité est identifiée par un identifiant CVE (Common Vulnerabilities and Exposures), qui est un identifiant standardisé pour les vulnérabilités de sécurité connues publiquement. + +### Systèmes d’identifiants de vulnérabilité : CVE et GHSA + +#### CVE (Common Vulnerabilities and Exposures) +Les CVE sont des identifiants standardisés pour les vulnérabilités de cybersécurité connues publiquement, maintenus par la société MITRE et financés par le département américain de la Sécurité intérieure. Chaque CVE a un identifiant unique au format CVE-YYYY-NNNNN (année-numéro). + +#### GHSA (GitHub Security Advisory) +Les identifiants GHSA sont des identifiants spécifiques à GitHub utilisés dans la base de conseils de sécurité GitHub. Ils suivent le format GHSA-XXXX-YYYY-ZZZZ, où X, Y et Z sont des caractères alphanumériques. + +#### Relation entre CVE et GHSA +- Un GHSA peut référencer un ou plusieurs CVE, car GitHub peut regrouper plusieurs vulnérabilités liées +- Tous les GHSAs n'ont pas un CVE correspondant, en particulier pour les vulnérabilités nouvellement découvertes +- GitHub assigne souvent un identifiant GHSA avant qu’un CVE ne soit attribué par MITRE +- Les deux systèmes décrivent les mêmes vulnérabilités mais peuvent contenir des informations légèrement différentes : + - Les CVE sont la norme utilisée dans les outils et bases de données de sécurité + - Les GHSAs contiennent souvent plus d’informations propres à l'écosystème et des conseils de remédiation pour les utilisateurs GitHub + +#### Apparition des identifiants selon les différents outils + +- **Alertes GitHub Dependabot** : Affichent à la fois les identifiants GHSA et CVE (lorsqu’un CVE est attribué) + + ![Liste des alertes GitHub Dependabot](./assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png) + *Vue des alertes Dependabot dans GitHub Sécurité* + + ![Détail d'une alerte GitHub Dependabot](./assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png) + *Alerte dependabot détaillée* + +- **npm run audit:check** : Les résultats affichent les identifiants GHSA pour les vulnérabilités + + ![Script Audit Check](./assets/screenshots/vulnerabilityManagement/audit-check-script.png) + *Exécution du script npm run audit:check* + + ![Niveau de sévérité autorisé](./assets/screenshots/vulnerabilityManagement/severity-level-allowed.png) + *Augmentation du niveau de vulnérabilité accepté à low, précédemment moderate* + + ![ID de sévérité autorisé](./assets/screenshots/vulnerabilityManagement/severity-id-allowed.png) + *Allowlist d'un identifiant de vulnérabilité à ignorer lors de npm run audit:check* + +- **Scan Grype** : Affiche les vulnérabilités portant des identifiants GHSA + + ![Vulnérabilités Grype Scan](./assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png) + *Vulnérabilités détectées par Grype dans CircleCI* + +#### Accéder aux informations détaillées d’une vulnérabilité + +Les identifiants GHSA peuvent être utilisés comme URLs directes pour accéder à plus d’informations. Il suffit d’ajouter l’ID GHSA à l’URL de base des avis de sécurité GitHub : + +``` +https://github.com/[owner]/[repo]/security/advisories/[GHSA-ID] +``` + +ou utilisez l’URL générique de la base d’avis GitHub : + +``` +https://github.com/advisories/[GHSA-ID] +``` + +Par exemple, une vulnérabilité du package multer est accessible via : +https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5 + +De même, lorsqu’un CVE est attribué à une vulnérabilité, vous pouvez consulter son dossier officiel via : + +``` +https://www.cve.org/CVERecord?id=[CVE-ID] +``` + +Pour le même exemple multer, l’information CVE correspondante se trouve sur : +https://www.cve.org/CVERecord?id=CVE-2025-47935 + +#### Sources d’information sur les vulnérabilités + +**Pages d’avis de sécurité GitHub :** +- Descriptions détaillées des vulnérabilités +- Versions affectées et corrigées +- ID CVE (lorsqu’attribués) +- Scores de sévérité (généralement CVSS) +- Conseils de remédiation +- Références à des issues et commits liés + +**Pages d’enregistrement CVE :** +- Descriptions officielles des vulnérabilités +- Références vers des ressources liées +- Produits et versions affectés +- Informations standardisées sur la sévérité +- Informations d’attribution + +Lors de l’investigation de vulnérabilités, il est souvent utile de consulter les deux sources, car elles peuvent contenir des informations complémentaires. + +En travaillant sur des vulnérabilités Mojaloop, vous pouvez rencontrer les deux types d’identifiants : +- CVE dans les bulletins et outils généraux (npm audit) +- GHSA dans les alertes GitHub Dependabot et dans les fichiers de configuration .grype.yaml + +La section des alertes Dependabot d’un dépôt GitHub est accessible dans l’onglet Sécurité > Alertes de vulnérabilité. Cliquez sur Dependabot pour obtenir la liste des alertes, puis sur une alerte pour voir le détail. + +Note : Votre compte GitHub doit disposer de l’autorisation d’accès à l’onglet Sécurité et Dependabot doit être activé sur le dépôt en question. Contactez un administrateur GitHub Mojaloop si besoin. + +### 1.1 Niveaux de sévérité des vulnérabilités + +Les vulnérabilités sont classées selon quatre niveaux de sévérité : + +- **Critique** : Nécessite une attention immédiate. Généralement exécution de code à distance, contournement d’authentification ou autres failles graves menant à la compromission du système. +- **Élevé** : Vulnérabilités sérieuses à corriger avant la fin d’un incrément de programme (PI), cible de 30 jours. Elles peuvent inclure des vulnérabilités par injection, une désérialisation non sécurisée ou des failles de type cross-site scripting pouvant entraîner une exposition significative de données. +- **Moyen** : Risques modérés à corriger dans le PI en cours si possible, cible de 60 jours. +- **Faible** : Problèmes mineurs à faible risque à traiter si possible sous 90 jours. + +**Note sur les identifiants CVE :** Quand un rapport de vulnérabilité ne mentionne pas de CVE, cela peut signifier : +1. La vulnérabilité vient d’être découverte (pas encore de CVE attribué) +2. Il s’agit d’un problème lié à l’implémentation spécifique au sein de votre projet +3. C’est une dépendance de développement qui n’affecte pas la production + +L’absence de CVE ne signifie pas que la vulnérabilité n’est pas importante – elle doit tout de même être évaluée selon sa sévérité et son impact potentiel. + +### 1.2 Comprendre les plages de versions dans les alertes Dependabot + +Les plages de versions dans les alertes Dependabot indiquent quelles versions d’un package/dépendance sont affectées. Notez que dans une alerte Dependabot, le "package" correspond à une dépendance du package.json d’un projet NodeJS. Les dépendances et leurs packages suivent la gestion sémantique de version. Comprendre ces notations est crucial : + +- **`<=M.m.p`** : Toutes les versions inférieures ou égales à la version spécifiée sont vulnérables. + - Exemple : `<=1.2.3` signifie toutes les versions jusqu’à 1.2.3 inclus. + +- **Plage `>M.m.p 1.0.0 <1.2.0` signifie toutes les versions après 1.0.0 et avant 1.2.0. + +Autres spécificateurs fréquents : + +- **Caret (`^`)** : Permet les changements ne modifiant pas le chiffre non nul le plus à gauche. + - Exemple : `^1.2.3` autorise toutes les versions à partir de 1.2.3 jusqu’à 2.0.0 non inclus. + - Pour `^0.2.3`, versions de 0.2.3 à 0.3.0 non inclus. + - Pour `^0.0.3`, versions de 0.0.3 à 0.0.4 non inclus. + +- **Tilde (`~`)** : Permet les mises à jour du patch si une version mineure est spécifiée. + - Exemple : `~1.2.3` autorise toute version de 1.2.3 jusqu’à 1.3.0 non inclus. + +## Sources de vulnérabilité + +Les vulnérabilités peuvent être introduites via : +1. Dépendances directes +2. Dépendances transitives +3. Environnements d’exécution +4. Composants d’infrastructure +5. Code personnalisé + +## Détection et Évaluation + +### Outils de détection des vulnérabilités + +Mojaloop utilise plusieurs outils pour détecter les vulnérabilités : + +1. **Alertes GitHub Dependabot** + - Détection automatique des vulnérabilités dans GitHub + - Informations détaillées sur les versions affectées et les correctifs + - Disponible sous l’onglet Sécurité de GitHub + - **Assets scannés :** dépendances NodeJS déclarées dans les package.json des dépôts GitHub + +2. **npm audit via audit-ci** + - S’exécute localement via `npm run audit:check` + - Configurable via `audit-ci.jsonc` avec allowlist pour les problèmes connus + - Intégré dans les pipelines CI/CD pour éviter le déploiement de code vulnérable + - **Assets scannés :** dépendances NodeJS directes et transitives (package.json et package-lock.json) + +3. **Scan d’images Grype** + - Scanner de vulnérabilités d’images de conteneur + - Configurable par `.grype.yaml` avec section d’ignorés pour soucis connus + - Analyse les vulnérabilités dans les images conteneur et leurs dépendances + - **Assets scannés :** images Docker, incluant les images de base, paquets OS installés et dépendances applicatives + - NOTE : Grype scanne aussi les images Docker si le dépôt en produit, des vulnérabilités peuvent y figurer ; si oui, une mise à jour de l’image de base dans le Mojaloop CircleCI orb est nécessaire. + +### Fichiers de configuration pour la gestion des vulnérabilités + +1. **audit-ci.jsonc** + - Contient une liste d’autorisation des vulnérabilités à ignorer temporairement + - À utiliser si une vulnérabilité ne peut pas être corrigée immédiatement + - Utilise les ID GHSA pour identifier les vulnérabilités à ignorer + - Doit inclure une justification et un suivi pour chaque vulnérabilité autorisée + - Exemple : + ```json + { + "allowlist": [ + { + "id": "GHSA-XXXX-YYYY-ZZZZ", + "reason": "Pas encore de correctif, plan B en place, suivi sur issue #123" + } + ] + } + ``` + +2. **.grype.yaml** + - Fichier de configuration pour le scan Grype + - Contient une section ignore avec des ID GHSA + - Utilisé pour les vulnérabilités spécifiques au conteneur non traitables immédiatement + - Exemple : + ```yaml + ignore: + - vulnerability: GHSA-XXXX-YYYY-ZZZZ + package: + name: nom-package + version: 1.2.3 + until: "2023-12-31" + reason: "Étude de solutions alternatives, pas exploitable dans notre contexte" + ``` + +### Scan automatisé +- Scan régulier des dépendances via npm audit +- Scan des images conteneur +- Scan de vulnérabilités de l’infrastructure +- Analyse statique du code + +### Revue manuelle +- Revues de code de sécurité +- Tests d’intrusion (pentest) +- Modélisation de menace +- Audits de conformité + +## 2. Flux de gestion pour les mises à jour de vulnérabilités de dépendances + +Le schéma suivant illustre le processus de gestion des vulnérabilités de dépendances pour les dépôts Mojaloop : + +![Processus de gestion des vulnérabilités de dépendances](./assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png) + +### 2.1 Processus standard + +1. **Triage** + - Révision régulière des alertes GitHub Dependabot. + - Classification selon la sévérité (Critique, Élevé, Moyen, Faible). + - Suivi des vulnérabilités dans un projet GitHub privé dédié aux issues de sécurité. Accès restreint, sur demande : contactez le comité Sécurité Mojaloop si besoin d’accès. + +2. **Processus de mise à jour** + - **Étape 1** : Choisissez un seul module (service Mojaloop ou librairie) avec vulnérabilité signalée. + - **Étape 2** : Mettez à jour la dépendance incriminée dans le package.json. + - **Étape 3** : Effectuez des tests de fumée pour garantir que la fonctionnalité n’est pas rompue. Voir le README du dépôt. + - **Étape 4** : Si les tests sont OK, créez une pull request. + - **Étape 5** : Proposez une PR pour chaque module avec un seul patch correctif de sécurité. + - **Étape 6** : Ajoutez dans la PR les détails de la vulnérabilité corrigée : ID CVE, dépendances mises à jour dans package.json, et toute information contextuelle utile. + +3. **Principes importants** + - **Isolation** : Un correctif de vulnérabilité à la fois. + - **Pas d’agrégation** : Aucun regroupement de correctifs de sécurité non liés. + - **Historique propre** : Rebasez les commits pour garder l’historique propre. + - **Tests systématiques** : Lancez systématiquement les tests requis (voir README). + +### 2.2 Cadre de priorisation + +- **Sévérité critique** : Attention immédiate ; objectif : 1 à 3 jours ouvrés. +- **Sévérité élevée** : Corriger avant la fin du PI actuel, cible 30 jours. +- **Sévérité moyenne** : Corriger avant la fin du PI actuel si possible, cible 60 jours. +- **Sévérité faible** : Traiter lors des cycles de maintenance courants, cible 90 jours. + +### 2.3 Critères d’évaluation des vulnérabilités + +Mojaloop suit les bonnes pratiques OpenSSF et OWASP. Les décisions finales relèvent du comité Sécurité Mojaloop. + +Pour décider de corriger ou d’ignorer : +- Si un correctif existe, il doit être appliqué. +- Une vulnérabilité ne doit être ignorée ou ajoutée à la liste d’autorisation que si le correctif rompt des fonctionnalités existantes, ce qui doit être confirmé soit par l’échec des tests automatisés (tels que décrits dans le README du dépôt concerné), soit par des tests manuels. +- Pour les failles « zero-day », le comité Sécurité Mojaloop précisera la marche à suivre au cas par cas. + +## 3. Guide pratique pour la mise à jour de package.json + +### 3.1 Outils recommandés + +- **npm run audit:check** : Pour rechercher les vulnérabilités ; le script doit aider à identifier les vulnérabilités et doit correspondre à celles listées dans Dependabot + ```bash + npm run audit:check + ``` + +- **npm run dep:check & npm run dep:update** : Pour gérer les mises à jour de dépendances, attention aux modifications massives +- **.ncurc.yaml** : Pour déclarer les dépendances à exclure des upgrades (dernier recours) + +### 3.2 Étapes pas à pas + +1. **Identifier le package vulnérable** : + ```bash + npm audit + ``` + +2. **Mettre à jour un package unique** : + ```bash + # Pour les dépendances directes + npm update [nom-du-package] + + # Pour corriger une vulnérabilité spécifique + npm run audit:fix + + # Pour les cas complexes qui cassent la compatibilité + npm audit fix --force # À utiliser avec précaution + ``` + +3. **Tester la mise à jour :** + ```bash + npm test + # Lancez aussi les autres tests projet + ``` + +4. **Commit et création de PR :** + ```bash + git checkout -b fix/security-vulnerability-[CVE-ID] + git add package.json package-lock.json + git commit -m "fix: mise à jour [package] pour [CVE-ID]" + git push origin fix/security-vulnerability-[CVE-ID] + ``` + +### 3.3 Gestion des cas complexes + +Quand `npm run audit:fix` ne résout pas : + +1. **Dépendances sans correctifs disponibles :** + - Vérifiez si la faille est réellement exploitable dans votre contexte. + - Étudiez un remplacement. + - Contactez le mainteneur du package. + - Documentez la faille et l’évaluation du risque. + +2. **Si la correction casse la fonctionnalité :** + - Si les tests échouent, aucune solution immédiate : + - Pour npm : Ajouter à la allowlist `audit-ci.jsonc` + - Pour les conteneurs : Ajouter à la section ignore de `.grype.yaml` + - Documentez la raison, le numéro d’issue, explication du risque, date cible de résolution et toute mesure compensatoire. + +3. **Intégration CI/CD :** + - Les contrôles de sécurité sont intégrés aux pipelines + - Les vulnérabilités critiques font échouer le pipeline sauf si correctement ignorées + - Toutes les vulnérabilités ignorées doivent être revues régulièrement + - Les scans doivent détecter en continu de nouvelles vulnérabilités + +### 3.4 Gestion des vulnérabilités des conteneurs + +Pour les images Docker : + +1. **Configuration Grype :** + - Grype est utilisé pour scanner les images conteneur + - Pour la configuration détaillée, voir [documentation Mojaloop CI Config Orb](https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration) + +2. **Sécurité de l’image de base :** + - Les services Mojaloop utilisent généralement les images Node.js Alpine + - L’image de base courante : [node:22.15.1-alpine3.21](https://hub.docker.com/layers/library/node/22.15.1-alpine3.21/images/sha256-d1068d8b737ffed2b8e9d0e9313177a2e2786c36780c5467ac818232e603ccd0) + - Cette page liste les vulnérabilités de l’image de base et le scan grype les détecte aussi. + +## Stratégie de mise à jour + +Pour corriger les vulnérabilités : +1. Suivez la séquence de mise à jour du dépôt ([Guide de mise à jour Mojaloop](./mojaloop-repository-update-guide.md)) +2. Priorisez les failles critiques et à haute sévérité +3. Considérez l’impact sur les services dépendants +4. Testez en profondeur hors production +5. Planifiez des mises à jour coordonnées entre les services concernés + +## 4. Bonnes pratiques de revue de code pour les PRs de sécurité + +1. **PR focalisées** : Chaque PR doit traiter une seule vulnérabilité. + +2. **Informations requises dans les PRs** : + - ID CVE ou identifiant de vulnérabilité + - Niveau de sévérité + - Description de la vulnérabilité + - Description du correctif + - Tests effectués + - Évaluation de l’impact potentiel + +3. **Checklist de review** : + - Vérifiez que la mise à jour corrige effectivement la faille + - Vérifiez que les modifs à package.json sont minimales + - Vérifiez que tous les tests passent + - Confirmez que les tests de fumée décrits dans le README ont été suivis + - Vérifiez qu’il n’y a pas d’effets de bord inattendus + +4. **Modèle de description de PR** : + ```markdown + ## Correction de sécurité : [CVE-ID] + + ### Détails de la vulnérabilité + - Sévérité : [Critique/Élevé/Moyen/Faible] + - Package concerné : [nom-du-package] + - Plages de versions vulnérables : [plage] + - Version corrigée : [numéro] + + ### Description + Brève description de la vulnérabilité et de son impact potentiel. + + ### Modifications + - Mise à jour de [nom-du-package] de [ancienne version] à [nouvelle version] + + ### Tests + - [X] Tests unitaires réussis + - [X] Tests d’intégration réussis + - [X] Tests manuels réalisés + - [X] Utilisation du dispositif de tests (test harness) sur le poste de travail du développeur + - [X] Harness de tests CI/CD ou tests Golden Path effectifs + + ### Notes additionnelles + Toutes autres informations pertinentes. + ``` + +## Signalement et communication + +- Centralisez le suivi des vulnérabilités et limitez l’accès aux besoins +- Documentez tous les problèmes identifiés +- Suivez l’avancée des corrections +- Communiquez sur l’état aux parties prenantes +- Respectez les principes de divulgation responsable + +## 5. Intégration des développeurs et formation gestion des vulnérabilités + +Pour utiliser la gestion des vulnérabilités comme point de départ pour les nouveaux devs de Mojaloop : + +### 5.1 Ressources pédagogiques + +- Créer une section dédiée dans la doc pour la gestion des vulnérabilités +- Inclure des exemples pratiques et des tutoriels pas-à-pas +- Proposer des liens vers les ressources Node.js sécurité + +### 5.2 Processus de mentorat + +1. **Vulnérabilités simples assignées** : Débutez les nouveaux devs par la correction de failles à faible priorité. +2. **Reviews en binôme** : Les PRs des nouveaux sont relues par des développeurs expérimentés. +3. **Montée en autonomie** : Confiez progressivement des tâches de sécurité plus complexes. + +### 5.3 Mise à jour de la documentation + +- Maintenir une base de connaissances sur les vulnérabilités fréquentes dans le code +- Documenter les leçons apprises lors des corrections précédentes +- Mettre à jour ce guide de gestion des vulnérabilités au fil de l’évolution des processus + +### 5.4 La sécurité dans le développement quotidien + +Lors de l’intégration, ce document sera partagé et la conformité vérifiée lors des revues de code (PRs). Plusieurs outils open source d’analyse de sécurité IDE sont à l’étude pour améliorer encore le flux de travail des développeurs. + +## Meilleures pratiques + +1. **Prévention** + - Mises à jour régulières des dépendances + - Pratiques de développement centrées sur la sécurité + - Tests de sécurité automatisés + - Bonnes pratiques de codage sécurisé + +2. **Réponse** + - Voies d’escalade claires + - Délais de réponse définis + - Revues de sécurité régulières + - Supervision continue + +3. **Documentation** + - Suivi des vulnérabilités + - Procédures de remédiation + - Rapports d’incidents de sécurité + - Leçons apprises + +## 6. Amélioration continue + +### 6.1 Revues de sécurité régulières + +- Revues hebdomadaires des nouveaux rapports de vulnérabilités +- Suivi des métriques de délai de résolution par sévérité +- Comparatif avec les standards du secteur + +### 6.2 Automatisation + +- Étudier l’adoption de DefectDojo (open source) pour centraliser et automatiser la gestion du cycle de vie des vulnérabilités + - [Communauté DefectDojo](https://defectdojo.com/community) + - [Dépôt GitHub DefectDojo](https://github.com/DefectDojo/django-DefectDojo) + - [Projet OWASP DefectDojo](https://owasp.org/www-project-defectdojo/) + - [Documentation DefectDojo](https://docs.defectdojo.com/en/about_defectdojo/about_docs/) +- Implémenter des hooks pre-commit pour la vérification des dépendances +- Planifier des jobs réguliers d’audits de sécurité + +### 6.3 Partage de connaissances + +- Rédiger et maintenir documentation et formation sur la gestion des vulnérabilités +- Créer des vidéos pas-à-pas pour corriger les failles courantes +- Établir un programme de ‘security champions’ dans la communauté + +## 7. Conclusion + +En appliquant cette approche structurée, la communauté Mojaloop assure une gestion cohérente, rapide et efficace des problèmes de sécurité. Ce processus renforce la sécurité du code tout en offrant une excellente porte d’entrée pour intégrer de nouveaux développeurs et renforcer la culture sécurité. + +La gestion des vulnérabilités de dépendances ne se limite pas à corriger des problèmes : il s’agit avant tout de développer une culture de la sécurité. + +## Outils et ressources + +- [Qu’est-ce qu’un CVE ?](https://www.ibm.com/think/topics/cve) +- [Documentation Mojaloop](https://docs.mojaloop.io/) +- [Node.js – Bonnes pratiques de sécurité](https://nodejs.org/en/learn/getting-started/security-best-practices) +- [Documentation npm Audit](https://docs.npmjs.com/cli/v10/commands/npm-audit) +- [Spécification SemVer](https://semver.org/) +- [Calculateur npm Semver](https://semver.npmjs.com/) +- [Fonctionnalités de sécurité GitHub](https://docs.github.com/en/code-security) +- [Guide rapide GitHub Dependabot](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide) +- [Mojaloop CI Config - Configuration du scan de vulnérabilité image](https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration) +- [Communauté DefectDojo](https://defectdojo.com/community) +- [Dépôt GitHub DefectDojo](https://github.com/DefectDojo/django-DefectDojo) +- [Projet OWASP DefectDojo](https://owasp.org/www-project-defectdojo/) +- [Documentation DefectDojo](https://docs.defectdojo.com/en/about_defectdojo/about_docs/) +- npm audit +- GitHub Security Advisories +- Outils de scan de conteneur +- Outils d’analyse statique +- Systèmes de surveillance de sécurité + +## Documentation associée + +- [Guide de stratégie de mise à niveau](./upgrade-strategy-guide.md) +- [Guide de mise à jour des dépôts Mojaloop](./mojaloop-repository-update-guide.md) +- [Dépannage du déploiement](./deployment-troubleshooting.md) +- [Politique de Divulgation Coordonnée des Vulnérabilités Mojaloop](https://docs.mojaloop.io/community/contributing/cvd.html) \ No newline at end of file diff --git a/docs/fr/technical/technical/security/security-overview.md b/docs/fr/technical/technical/security/security-overview.md new file mode 100644 index 000000000..270c95ac9 --- /dev/null +++ b/docs/fr/technical/technical/security/security-overview.md @@ -0,0 +1,180 @@ + +

    Processus de Gestion des Vulnérabilités Mojaloop

    + +Contenu : +1. [Introduction](#1-introduction) +2. [Comité de sécurité](#2-commité-de-sécurité) +3. [Gestion d’une vulnérabilité potentielle](#3-gestion-d-une-vulnérabilité-potentielle) +4. [Processus de gestion des vulnérabilités Mojaloop en place](#4-processus-de-gestion-des-vulnérabilités-mojaloop-en-place) +5. [Périmètre](#5-périmètre) + +

    1. Introduction

    + +Ce document décrit le Processus de Gestion des Vulnérabilités Mojaloop et fournit des lignes directrices à la communauté Mojaloop pour identifier, signaler, évaluer et traiter les vulnérabilités de sécurité dans les logiciels Mojaloop. En respectant les normes de sécurité reconnues, telles que l’ISO 27001, Mojaloop vise à assurer une approche cohérente pour maintenir la sécurité et la résilience. + +Ce processus s’appuie sur les pratiques déjà établies par Mojaloop, garantissant un périmètre bien défini et des directives sur lesquelles les adoptants du logiciel peuvent s’appuyer. Il met l'accent sur une gestion responsable des vulnérabilités jusqu’à ce que des correctifs vérifiés soient disponibles et correctement communiqués. + +Un processus de gestion des vulnérabilités structuré, transparent et efficace est essentiel pour maintenir la confiance et la protection de l’écosystème Mojaloop. + +

    2. Comité de sécurité

    + +Le processus de gestion des vulnérabilités de Mojaloop est soutenu par un "Comité de sécurité" désigné, groupe central chargé de coordonner tous les aspects de la gestion des vulnérabilités. Ce comité supervise notamment : + +1. La révision et la validation des signalements de vulnérabilités. +2. La décision d’accepter ou de rejeter les vulnérabilités signalées. +3. La définition des correctifs appropriés et la planification des annonces. +4. La coordination des versions intégrant des correctifs de sécurité. + +Le comité de sécurité est composé de contributeurs principaux et de leaders de la communauté, garantissant une gestion efficace et sécurisée des vulnérabilités au sein de Mojaloop. Sa structure et ses responsabilités sont conçues pour préserver la sécurité et l’intégrité de l’écosystème Mojaloop. + +

    3. Gestion d’une vulnérabilité potentielle

    + +Politique de divulgation des vulnérabilités Mojaloop (CVD) : [https://docs.mojaloop.io/community/contributing/cvd.html](https://docs.mojaloop.io/community/contributing/cvd.html) + +Le processus par défaut pour gérer une éventuelle vulnérabilité de sécurité dans Mojaloop est décrit dans le lien ci-dessus. Les projets requérant un processus différent doivent le documenter clairement et publiquement. + +Le processus concernant les dépendances tierces générales et autres modules open source est détaillé dans le guide [gestion des vulnérabilités de dépendances](dependency-vulnerability-management.md). + +

    Sécurité pour les membres de la communauté Mojaloop

    + +Les membres de la communauté Mojaloop et les organisations membres jouent un rôle clé dans la gestion des vulnérabilités, en particulier pour le respect des procédures établies en cas de découverte de vulnérabilités. Voici les étapes attendues : + +* Évitez d’entrer les détails des vulnérabilités dans des suivis de bugs publics, sauf si l’accès y est strictement limité. +* Les communications concernant la sécurité doivent être limitées à des canaux privés dédiés. Ces canaux ne constituent pas des systèmes de notification destinés au grand public. + +

    Travailler en privé

    + +Les informations sur une vulnérabilité ne doivent pas être rendues publiques avant qu'une annonce officielle n'ait été faite à la fin du processus. Cela signifie : + +* **Ne créez pas de tickets dans des suivis publics (par ex. GitHub/Zenhub) pour suivre l’incident**, car cela le rendrait public. +* **Les messages associés aux commits de code ne doivent pas mentionner la nature sécuritaire du commit.** +* **Les discussions autour de la vulnérabilité, des corrections potentielles et des annonces doivent avoir lieu sur des canaux privés**, tels qu’une liste de diffusion sécurité du projet ou un canal dédié aux mainteneurs. +* Travaillez avec l’équipe sécurité Mojaloop (security at mojaloop dot io) pour suivre le processus CVD : https://docs.mojaloop.io/community/contributing/cvd.html + +

    Déclarer

    + +La personne ayant identifié la vulnérabilité (le rapporteur) doit remplir le rapport et l’envoyer par email à : **[security@mojaloop.io](mailto:security@mojaloop.io)**. +Des modèles de rapports peuvent s’inspirer du modèle de bug ici : https://github.com/mojaloop/project/issues . + +Liste des problèmes jugés pertinents : +1. Problèmes/vulnérabilités de sécurité dans les services principaux Mojaloop (code applicatif) +2. Problèmes/vulnérabilités de sécurité dans les services de support Mojaloop +3. Vulnérabilités à large diffusion ou de type zero-day dans les dernières versions des dépendances critiques utilisées par les services principaux ou de support (ex : nodejs, kafka, mysql) + +Liste des problèmes non critiques ou à faible priorité (réponses pouvant être différées) : + +1. Vulnérabilités concernant le site [mojaloop.io](mojaloop.io) +2. Vulnérabilités concernant le site [docs.mojaloop.io](docs.mojaloop.io) + +

    Accuser réception

    + +L’équipe sécurité Mojaloop doit envoyer un email d’accusé de réception au rapporteur initial. L’accusé de réception inclura idéalement une copie à la liste de diffusion sécurité privée concernée. + +

    Analyser et répondre

    + +L’équipe analyse le rapport et le rejette ou l’accepte. + +1. L’information peut être partagée avec des experts du domaine en privé, à condition qu’ils comprennent qu’elle n’est pas destinée à être rendue publique. +2. En cas de rejet, l’équipe explique sa décision au rapporteur, avec copie à la liste de diffusion sécurité concernée. +3. En cas d’acceptation, l’équipe notifie au rapporteur que le rapport est en cours de traitement. + +

    Résoudre

    + +* L’équipe convient d’un correctif, généralement sur une liste privée. +* Les détails de la vulnérabilité et du correctif doivent être documentés pour générer des annonces préliminaires. +* Le rapporteur peut recevoir une copie du correctif ainsi que le projet d’annonce afin d’y apporter ses commentaires. +* Le correctif est intégré sans mention du caractère sécurité dans le message du commit. +* Une version intégrant le correctif est publiée. Plus de détails dans la politique CVD Mojaloop. + +

    Annonce

    + +* Après la publication, la vulnérabilité et son correctif sont annoncés publiquement. +* L’annonce doit être envoyée aux destinataires et canaux appropriés, notamment le rapporteur de la vulnérabilité, les listes de sécurité du projet et éventuellement les listes publiques de sécurité. + +

    Clôturer

    + +Les pages publiques de sécurité du projet doivent être mises à jour avec l’information sur la vulnérabilité afin d’assurer la transparence vis-à-vis des utilisateurs. + +

    4. Processus de gestion des vulnérabilités Mojaloop en place

    + +Mojaloop a mis en place une série de processus et outils robustes permettant de gérer les vulnérabilités tout au long du cycle de vie du développement logiciel, en conformité avec les meilleures pratiques du secteur et notamment la norme ISO 27001. + +

    Gestion des vulnérabilités

    + +La surveillance continue des composants open source pour les vulnérabilités est intégrée au pipeline CI/CD. Ce processus est automatisé pour évaluer chaque version, commit et pull request, en s’appuyant sur Node Package Manager (NPM) pour l’évaluation des vulnérabilités des dépendances. + +

    Test de sécurité applicatif statique (SAST)

    + +Mojaloop utilise plusieurs outils de SAST, offrant une vision détaillée des vulnérabilités dans le code, via l’usage de bases de données publiques de vulnérabilités, parmi lesquelles : + +1. **Outils de sécurité GitHub** : dont Dependabot pour le scan de dépendances (basé sur la base de données GitHub Advisory), CodeQL pour l’analyse du code, et Secret Scanning pour éviter l’introduction d’informations sensibles. +2. **SonarCloud** : analyse chaque commit, pull request et version pour la qualité du code et les failles de sécurité, en utilisant notamment les données publiques telles que CVE (Common Vulnerabilities and Exposures). + +

    SBOM (Software Bill of Materials) et gestion des dépendances

    + +Un outil SBOM est utilisé pour générer un inventaire des dépendances tierces, permettant : + +1. L’identification des vulnérabilités et des questions de conformité de licences ; +2. La génération de rapports réguliers pour les besoins réglementaires et d’audit ; +3. La surveillance permanente des versions de bibliothèques sur tous les dépôts ; +4. S’assurer que seuls les paquets et dépendances bien maintenus et correctement administrés sont utilisés, et que les paquets obsolètes font l’objet d’une gestion appropriée. + +Plus d’informations sur le SBOM dans Mojaloop : https://github.com/mojaloop/ml-depcheck-utility?tab=readme-ov-file#sbom-generation-tool-for-mojaloop-repositories + +

    Sécurité des conteneurs

    + +Les images de conteneurs sont analysées pour détecter les vulnérabilités à l’aide de Grype avant la publication. Grype est configuré conformément aux meilleures pratiques, et des configurations plus strictes sont recommandées pour les adoptants. Configuration Grype de l’Orb CI utilisée par Mojaloop : https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration . + +

    Conformité des licences

    + +Un outil automatisé de scan de licences s’assure que seules les composantes à licence compatible soient utilisées. Les contrôles de conformité sont intégrés au processus CI/CD, bloquant la fusion ou le déploiement du code non conforme. + +

    Provenance des images

    + +Depuis la version Mojaloop v17.1.0, les chart helm Mojaloop sont signés lors de la publication et peuvent être vérifiés lors de l’installation/le déploiement (cette fonctionnalité est supportée nativement par Helm), ce qui assure la provenance des artefacts associés. À l’avenir, cela pourra être étendu à d’autres artefacts comme les images. + +

    Processus sécurité CI/CD de Mojaloop

    + +Mojaloop dispose d’un pipeline CI/CD intégrant automatiquement des contrôles de sécurité à toutes les étapes du développement, garantissant ainsi une application systématique de la sécurité sans intervention manuelle. Des règles de protection des branches imposent des contrôles continus à chaque commit, pull request et version. + +Intégration sécurité CI/CD : + +1. **Sécurité des conteneurs** : … +2. **Conformité des licences** : … +3. **Analyse des vulnérabilités des dépendances** : … + +Toutes les vulnérabilités critiques sont consignées et le pipeline bloque la publication des images ou paquets concernés tant que ces problèmes ne sont pas résolus. Ces mécanismes automatisés dans le pipeline garantissent un code testé en continu, sécurisé et conforme, maintenant ainsi un haut niveau de sécurité au sein du processus de développement. + +

    Divulgation coordonnée des vulnérabilités (CVD)

    + +Mojaloop applique une démarche CVD, garantissant aux parties concernées un délai suffisant pour traiter et corriger les vulnérabilités avant toute divulgation publique. + +Politique de divulgation Mojaloop (CVD) : [https://docs.mojaloop.io/community/contributing/cvd.html](https://docs.mojaloop.io/community/contributing/cvd.html) + +

    Rapport et conformité

    + +Des rapports complets sont générés après chaque analyse, détaillant les résultats, actions correctives et leur efficacité. + +Tous les rapports sont archivés pour audit et conformité, garantissant la transparence et la responsabilité. + +Le rapport provenant du scan de licences au niveau helm est intégré aux notes de version Mojaloop (ce qui confirme le contrôle réussi des licences et garantit la présence de licences autorisées uniquement). Le fichier résumé des licences est joint aux notes de version (en bas de page) : [https://github.com/mojaloop/helm/releases/tag/v17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) en fournit un exemple. + +Les rapports d’analyse d’images sont disponibles pour consultation dans l’outil CI (CircleCI), permettant d’enregistrer la réussite ou l’échec du contrôle (le pipeline ne poursuit que si cette étape est validée). Par exemple, un résultat Grype est consultable ici : [https://app.circleci.com/pipelines/github/mojaloop/account-lookup-service/2165/workflows/d420ef53-85a7-46d3-af1e-1527baf3a207/jobs/16509/artifacts](https://app.circleci.com/pipelines/github/mojaloop/account-lookup-service/2165/workflows/d420ef53-85a7-46d3-af1e-1527baf3a207/jobs/16509/artifacts) (à titre d’exemple : cette référence peut devenir obsolète avec le temps). + +

    5. Périmètre

    + +Le processus de gestion des vulnérabilités Mojaloop s’applique à tous les composants faisant partie de la publication Helm Mojaloop. + +Cela inclut : + +1. Tous les composants et services principaux explicitement définis dans les charts Helm Mojaloop. +2. Les dépendances comprises dans la release Helm Mojaloop, automatiquement scannées dans le cadre du processus de gestion des vulnérabilités. + +Exclusions : + +1. Les dépôts ne faisant pas partie de la version principale de Mojaloop sont considérés comme hors production et exclus du processus de gestion des vulnérabilités. +2. Les composants externes requis pour un déploiement Mojaloop typique (par ex. MySQL, Redis, MongoDB, Kafka) ne sont pas maintenus par la Fondation Mojaloop et sont exclus du processus de gestion des vulnérabilités spécifique au code applicatif Mojaloop, bien qu’ils relèvent de la gestion générale des vulnérabilités (en tant que dépendances OSS tierces). + +Cette approche garantit la sécurité constante des composants de base Mojaloop, tout en définissant clairement la limite de responsabilité autour des dépendances externes et en fournissant des lignes directrices concernant tous les autres paquets OSS (internes ou tiers), dépendances et outils. + +

    diff --git a/docs/fr/technical/technical/transaction-requests-service/README.md b/docs/fr/technical/technical/transaction-requests-service/README.md new file mode 100644 index 000000000..5959a1abd --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/README.md @@ -0,0 +1,8 @@ +# Service des demandes de transaction + +## Diagramme de séquence + +![](./assets/diagrams/sequence/trx-service-overview-spec.svg) + +* Le **transaction-requests-service** est un service cœur Mojaloop qui permet les cas d’usage initiés par le Bénéficiaire, tels que la « demande de paiement du marchand » (*Merchant Request to Pay*). +* Il s’agit d’un service de transit qui inclut également les **Autorisations**. diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml new file mode 100644 index 000000000..2a8963f04 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml @@ -0,0 +1,64 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Service des demandes de transaction — Autorisations +participant "FSP payeur" +participant "Commutateur\ntransaction-requests-service" as Switch +participant "FSP bénéficiaire" + +autonumber +"FSP bénéficiaire" --\ "FSP bénéficiaire": Recherche, demande de transaction,\ntraitement non illustré ici +note over "FSP bénéficiaire", Switch: Le FSP bénéficiaire génère une demande de transaction vers le FSP payeur +"FSP payeur" --> "FSP payeur": Offre de change, génération d'OTP,\nnotification utilisateur (non illustré) +"FSP payeur" -\ Switch: GET /authorizations/{TransactionRequestID} +Switch --/ "FSP payeur": 202 Accepted + +alt la demande d'autorisation est valide + + Switch -> Switch: Valider GET /authorizations/{TransactionRequestID} (validation interne) + Switch -> Switch: Récupérer les endpoints du FSP bénéficiaire + note over Switch, "FSP bénéficiaire": Le commutateur transmet GET /authorizations au FSP bénéficiaire + Switch -\ "FSP bénéficiaire": GET /authorizations/{TransactionRequestID} + "FSP bénéficiaire" --/ Switch: 202 Accepted + "FSP bénéficiaire" -> "FSP bénéficiaire": Traiter la demande d'autorisation\n(le payeur approuve ou rejette la transaction\nvia l'OTP) + + note over Switch, "FSP bénéficiaire": Le FSP bénéficiaire répond avec PUT /authorizations/{TransactionRequestID} + "FSP bénéficiaire" -\ Switch: PUT /authorizations/{TransactionRequestID} + Switch --/ "FSP bénéficiaire": 200 Ok + + note over "FSP payeur", Switch: Le commutateur transmet PUT /authorizations/{TransactionRequestID} au FSP payeur + Switch -> Switch: Récupérer les endpoints du FSP payeur + Switch -\ "FSP payeur": PUT /authorizations/{TransactionRequestID} + "FSP payeur" --/ Switch: 200 Ok + + +else la demande d'autorisation est invalide + note over "FSP payeur", Switch: Le commutateur renvoie un rappel d'erreur au FSP payeur + Switch -\ "FSP payeur": PUT /authorizations/{TransactionRequestID}/error + "FSP payeur" --/ Switch: 200 OK + "FSP payeur" --> "FSP payeur": Valider l'OTP envoyé par le FSP bénéficiaire +end +@enduml diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg new file mode 100644 index 000000000..75425c490 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg @@ -0,0 +1,132 @@ + + Service des demandes de transaction — Autorisations + + + Service des demandes de transaction — Autorisations + + + + + + FSP payeur + + FSP payeur + + Commutateur + transaction-requests-service + + Commutateur + transaction-requests-service + + FSP bénéficiaire + + FSP bénéficiaire + + + + + 1 + Recherche, demande de transaction, + traitement non illustré ici + + + Le FSP bénéficiaire génère une demande de transaction vers le FSP payeur + + + + + 2 + Offre de change, génération d'OTP, + notification utilisateur (non illustré) + + + 3 + GET /authorizations/{TransactionRequestID} + + + 4 + 202 Accepted + + + alt + [la demande d'autorisation est valide] + + + + + 5 + Valider GET /authorizations/{TransactionRequestID} (validation interne) + + + + + 6 + Récupérer les endpoints du FSP bénéficiaire + + + Le commutateur transmet GET /authorizations au FSP bénéficiaire + + + 7 + GET /authorizations/{TransactionRequestID} + + + 8 + 202 Accepted + + + + + 9 + Traiter la demande d'autorisation + (le payeur approuve ou rejette la transaction + via l'OTP) + + + Le FSP bénéficiaire répond avec PUT /authorizations/{TransactionRequestID} + + + 10 + PUT /authorizations/{TransactionRequestID} + + + 11 + 200 Ok + + + Le commutateur transmet PUT /authorizations/{TransactionRequestID} au FSP payeur + + + + + 12 + Récupérer les endpoints du FSP payeur + + + 13 + PUT /authorizations/{TransactionRequestID} + + + 14 + 200 Ok + + [la demande d'autorisation est invalide] + + + Le commutateur renvoie un rappel d'erreur au FSP payeur + + + 15 + PUT /authorizations/{TransactionRequestID}/error + + + 16 + 200 OK + + + + + 17 + Valider l'OTP envoyé par le FSP bénéficiaire + + diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml new file mode 100644 index 000000000..aa66039d3 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml @@ -0,0 +1,93 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Service des demandes de transaction — Création +participant "FSP payeur" +participant "Commutateur\ntransaction-requests-service" as Switch +participant "FSP bénéficiaire" + +autonumber +"FSP bénéficiaire" -\ "FSP bénéficiaire": Processus de recherche\n(non illustré ici) +note over "FSP bénéficiaire", Switch: Le FSP bénéficiaire génère une demande de transaction vers le FSP payeur +"FSP bénéficiaire" -\ Switch: POST /transactionRequests +Switch -> Switch: Valider le schéma POST /transactionRequests +Switch --/ "FSP bénéficiaire": 202 Accepted + +alt la demande de transaction est valide + + Switch -> Switch: Valider POST /transactionRequests (validation interne) + Switch -> Switch: Récupérer les endpoints du FSP payeur + note over Switch, "FSP payeur": Le commutateur transmet la requête POST /transactionRequests au FSP payeur + Switch -\ "FSP payeur": POST /transactionRequests + "FSP payeur" --/ Switch: 202 Accepted + "FSP payeur" -> "FSP payeur": Traiter la demande de transaction + + alt le FSP payeur traite avec succès la demande de transaction + + note over "FSP payeur", Switch: Le FSP payeur répond au POST /transactionRequests + "FSP payeur" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "FSP payeur": 200 Ok + + Switch -> Switch: Valider PUT /transactionRequests/{ID} + + alt la réponse est valide + + note over Switch, "FSP bénéficiaire": Le commutateur relaie la réponse au FSP bénéficiaire + Switch -> Switch: Récupérer les endpoints du FSP bénéficiaire + + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID} + "FSP bénéficiaire" --/ Switch: 200 Ok + + note over "FSP bénéficiaire" #3498db: Attente d'une offre de change, d'un transfert par le FSP payeur\nou d'une demande de transaction rejetée + else réponse invalide + + note over Switch, "FSP payeur": Le commutateur renvoie une erreur au FSP payeur + + Switch -\ "FSP payeur": PUT /transactionRequests/{ID}/error + "FSP payeur" --/ Switch : 200 Ok + + note over Switch, "FSP payeur" #ec7063: Dans ce scénario, le FSP bénéficiaire\npeut ne pas recevoir de réponse + + end + else échec du traitement ou rejet par le FSP payeur + + note over "FSP payeur", Switch: Le FSP payeur renvoie une erreur au commutateur + + "FSP payeur" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "FSP payeur": 200 OK + + note over "FSP bénéficiaire", Switch: Le commutateur renvoie une erreur au FSP bénéficiaire + + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID}/error + "FSP bénéficiaire" --/ Switch: 200 OK + + end +else la demande de transaction est invalide + note over "FSP bénéficiaire", Switch: Le commutateur renvoie une erreur au FSP bénéficiaire + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID}/error + "FSP bénéficiaire" --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg new file mode 100644 index 000000000..4dc10b2a3 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg @@ -0,0 +1,184 @@ + + Service des demandes de transaction — Création + + + Service des demandes de transaction — Création + + + + + + + + FSP payeur + + FSP payeur + + Commutateur + transaction-requests-service + + Commutateur + transaction-requests-service + + FSP bénéficiaire + + FSP bénéficiaire + + + + + 1 + Processus de recherche + (non illustré ici) + + + Le FSP bénéficiaire génère une demande de transaction vers le FSP payeur + + + 2 + POST /transactionRequests + + + + + 3 + Valider le schéma POST /transactionRequests + + + 4 + 202 Accepted + + + alt + [la demande de transaction est valide] + + + + + 5 + Valider POST /transactionRequests (validation interne) + + + + + 6 + Récupérer les endpoints du FSP payeur + + + Le commutateur transmet la requête POST /transactionRequests au FSP payeur + + + 7 + POST /transactionRequests + + + 8 + 202 Accepted + + + + + 9 + Traiter la demande de transaction + + + alt + [le FSP payeur traite avec succès la demande de transaction] + + + Le FSP payeur répond au POST /transactionRequests + + + 10 + PUT /transactionRequests/{ID} + + + 11 + 200 Ok + + + + + 12 + Valider PUT /transactionRequests/{ID} + + + alt + [la réponse est valide] + + + Le commutateur relaie la réponse au FSP bénéficiaire + + + + + 13 + Récupérer les endpoints du FSP bénéficiaire + + + 14 + PUT /transactionRequests/{ID} + + + 15 + 200 Ok + + + Attente d'une offre de change, d'un transfert par le FSP payeur + ou d'une demande de transaction rejetée + + [réponse invalide] + + + Le commutateur renvoie une erreur au FSP payeur + + + 16 + PUT /transactionRequests/{ID}/error + + + 17 + 200 Ok + + + Dans ce scénario, le FSP bénéficiaire + peut ne pas recevoir de réponse + + [échec du traitement ou rejet par le FSP payeur] + + + Le FSP payeur renvoie une erreur au commutateur + + + 18 + PUT /transactionRequests/{ID}/error + + + 19 + 200 OK + + + Le commutateur renvoie une erreur au FSP bénéficiaire + + + 20 + PUT /transactionRequests/{ID}/error + + + 21 + 200 OK + + [la demande de transaction est invalide] + + + Le commutateur renvoie une erreur au FSP bénéficiaire + + + 22 + PUT /transactionRequests/{ID}/error + + + 23 + 200 OK + + diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml new file mode 100644 index 000000000..d7d6c5e67 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml @@ -0,0 +1,90 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Service des demandes de transaction — Consultation +participant "FSP payeur" +participant "Commutateur\ntransaction-requests-service" as Switch +participant "FSP bénéficiaire" + +autonumber +note over "FSP bénéficiaire", Switch: Le FSP bénéficiaire demande le statut d'une demande de transaction au FSP payeur.\nL'ID est celui d'une demande de transaction créée précédemment +"FSP bénéficiaire" -\ Switch: GET /transactionRequests/{ID} +Switch -> Switch: Valider GET /transactionRequests/{ID} +Switch --/ "FSP bénéficiaire": 202 Accepted + +alt la requête de consultation est valide + + Switch -> Switch: Récupérer les endpoints du FSP payeur + note over Switch, "FSP payeur": Le commutateur transmet GET /transactionRequests/{ID} au FSP payeur + Switch -\ "FSP payeur": GET /transactionRequests/{ID} + "FSP payeur" --/ Switch: 202 Accepted + "FSP payeur" -> "FSP payeur": Récupérer la demande de transaction + + alt le FSP payeur récupère avec succès la demande de transaction + + note over "FSP payeur", Switch: Le FSP payeur répond par le rappel\nPUT /transactionRequests/{ID} + "FSP payeur" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "FSP payeur": 200 Ok + + Switch -> Switch: Valider PUT /transactionRequests/{ID} + + alt la réponse est valide + + note over Switch, "FSP bénéficiaire": Le commutateur relaie la réponse au FSP bénéficiaire + Switch -> Switch: Récupérer les endpoints du FSP bénéficiaire + + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID} + "FSP bénéficiaire" --/ Switch: 200 Ok + + else réponse invalide + + note over Switch, "FSP payeur": Le commutateur renvoie une erreur au FSP payeur + + Switch -\ "FSP payeur": PUT /transactionRequests/{ID}/error + "FSP payeur" --/ Switch : 200 Ok + + note over Switch, "FSP payeur" #ec7063: Dans ce scénario, le FSP bénéficiaire\npeut ne pas recevoir de réponse + + end + else le FSP payeur ne peut pas récupérer la demande de transaction + + note over "FSP payeur", Switch: Le FSP payeur renvoie une erreur au commutateur + + "FSP payeur" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "FSP payeur": 200 OK + + note over "FSP bénéficiaire", Switch: Le commutateur renvoie une erreur au FSP bénéficiaire + + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID}/error + "FSP bénéficiaire" --/ Switch: 200 OK + + end +else la demande de transaction est invalide + note over "FSP bénéficiaire", Switch: Le commutateur renvoie une erreur au FSP bénéficiaire + Switch -\ "FSP bénéficiaire": PUT /transactionRequests/{ID}/error + "FSP bénéficiaire" --/ Switch: 200 OK +end +@enduml diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg new file mode 100644 index 000000000..16afa5cea --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg @@ -0,0 +1,169 @@ + + Service des demandes de transaction — Consultation + + + Service des demandes de transaction — Consultation + + + + + + + + FSP payeur + + FSP payeur + + Commutateur + transaction-requests-service + + Commutateur + transaction-requests-service + + FSP bénéficiaire + + FSP bénéficiaire + + + Le FSP bénéficiaire demande le statut d'une demande de transaction au FSP payeur. + L'ID est celui d'une demande de transaction créée précédemment + + + 1 + GET /transactionRequests/{ID} + + + + + 2 + Valider GET /transactionRequests/{ID} + + + 3 + 202 Accepted + + + alt + [la requête de consultation est valide] + + + + + 4 + Récupérer les endpoints du FSP payeur + + + Le commutateur transmet GET /transactionRequests/{ID} au FSP payeur + + + 5 + GET /transactionRequests/{ID} + + + 6 + 202 Accepted + + + + + 7 + Récupérer la demande de transaction + + + alt + [le FSP payeur récupère avec succès la demande de transaction] + + + Le FSP payeur répond par le rappel + PUT /transactionRequests/{ID} + + + 8 + PUT /transactionRequests/{ID} + + + 9 + 200 Ok + + + + + 10 + Valider PUT /transactionRequests/{ID} + + + alt + [la réponse est valide] + + + Le commutateur relaie la réponse au FSP bénéficiaire + + + + + 11 + Récupérer les endpoints du FSP bénéficiaire + + + 12 + PUT /transactionRequests/{ID} + + + 13 + 200 Ok + + [réponse invalide] + + + Le commutateur renvoie une erreur au FSP payeur + + + 14 + PUT /transactionRequests/{ID}/error + + + 15 + 200 Ok + + + Dans ce scénario, le FSP bénéficiaire + peut ne pas recevoir de réponse + + [le FSP payeur ne peut pas récupérer la demande de transaction] + + + Le FSP payeur renvoie une erreur au commutateur + + + 16 + PUT /transactionRequests/{ID}/error + + + 17 + 200 OK + + + Le commutateur renvoie une erreur au FSP bénéficiaire + + + 18 + PUT /transactionRequests/{ID}/error + + + 19 + 200 OK + + [la demande de transaction est invalide] + + + Le commutateur renvoie une erreur au FSP bénéficiaire + + + 20 + PUT /transactionRequests/{ID}/error + + + 21 + 200 OK + + diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml new file mode 100644 index 000000000..e8f8fe453 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation +- Name Surname + +* Henk Kodde +-------------- +******'/ + +@startuml transactionRequests + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "FSP\npayeur" as payerfsp +participant "Commutateur\n(optionnel)" as Switch +participant "FSP\nbénéficiaire" as payeefsp +actor "<$actor>\nBénéficiaire" as Payee + +' start flow +payeefsp <- Payee: Je souhaite recevoir des fonds\nen provenance du +123456789 +activate payeefsp +payeefsp <- payeefsp: Recherche du +123456789\n(processus non illustré ici) +Switch <<- payeefsp: **POST /transactionRequest/**\n(Informations bénéficiaire,\ndétails de la transaction) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepté) +payerfsp <<- Switch: **POST /transactionRequests/**\n(Informations bénéficiaire,\ndétails de la transaction) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepté) +payeefsp -> payeefsp: Effectuer une validation facultative +payerfsp ->> Switch: **PUT /transactionRequests/**\n(statut reçu) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(statut reçu) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Attendre une offre de change et\nun transfert, ou une demande\nde transaction rejetée par le payeur +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg new file mode 100644 index 000000000..2c8bea0fc --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + FSP + payeur + + Commutateur + (optionnel) + + FSP + bénéficiaire + + Bénéficiaire + + + + + + + + Je souhaite recevoir des fonds + en provenance du +123456789 + + + + + Recherche du +123456789 + (processus non illustré ici) + + + + POST /transactionRequest/ + (Informations bénéficiaire, + détails de la transaction) + + + + HTTP 202 + (Accepté) + + + + POST /transactionRequests/ + (Informations bénéficiaire, + détails de la transaction) + + + + HTTP 202 + (Accepté) + + + + + Effectuer une validation facultative + + + + PUT /transactionRequests/ + <ID> + (statut reçu) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (statut reçu) + + + + HTTP 200 + (OK) + + + + + Attendre une offre de change et + un transfert, ou une demande + de transaction rejetée par le payeur + + diff --git a/docs/fr/technical/technical/transaction-requests-service/authorizations.md b/docs/fr/technical/technical/transaction-requests-service/authorizations.md new file mode 100644 index 000000000..346f47333 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/authorizations.md @@ -0,0 +1,8 @@ +# Demandes de transaction — Autorisations + +GET /authorizations/{TransactionRequestID} et PUT /authorizations/{TransactionRequestID} pour prendre en charge les autorisations dans la « demande de paiement du marchand » (*Merchant Request to Pay*) et d'autres cas d'usage initiés par le Bénéficiaire. + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg) + diff --git a/docs/fr/technical/technical/transaction-requests-service/transaction-requests-get.md b/docs/fr/technical/technical/transaction-requests-service/transaction-requests-get.md new file mode 100644 index 000000000..eb24580db --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/transaction-requests-get.md @@ -0,0 +1,8 @@ +# Demandes de transaction — Consultation + +GET /transactionRequests et PUT /transactionRequests pour prendre en charge la « demande de paiement du marchand » (*Merchant Request to Pay*). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg) + diff --git a/docs/fr/technical/technical/transaction-requests-service/transaction-requests-post.md b/docs/fr/technical/technical/transaction-requests-service/transaction-requests-post.md new file mode 100644 index 000000000..694408fa9 --- /dev/null +++ b/docs/fr/technical/technical/transaction-requests-service/transaction-requests-post.md @@ -0,0 +1,8 @@ +# Demandes de transaction + +POST /transactionRequests et PUT /transactionRequests pour prendre en charge la « demande de paiement marchande » (*Merchant Request to Pay*). + +## Diagramme de séquence + +![](./assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg) + diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 000000000..29ea5c047 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,24 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + + +1. [Frequently Asked Questions](./faqs) +2. [License](./license.md) +3. [Review Mojaloop APIs](/api/) +4. [Take a training program](https://mojaloop.io/mojaloop-training-program/) +5. [Contribute to Mojaloop](/community/) +6. [Install Mojaloop](./installation/installing-mojaloop.md) +7. [Demos](./demos/mojaloop-overview.md) + + 7.1. [Why Mojaloop?](./demos/why-mojaloop.md) + + 7.2. [Working with Mojaloop?](./demos/working-with-mojaloop.md) + + 7.3. [Financial inclusion 101 ](./demos/financial-inclusion-101.md) + + 7.4. [What is RTP?](./demos/what-is-rtp.md) + + 7.5. [What Makes a Successful Financial Ecosystem?](./demos/what-makes-a-successful-financial-ecosystem.md) + + 7.6. [Inside the Loop](./demos/inside-the-loop.md) diff --git a/docs/getting-started/demo-one.md b/docs/getting-started/demo-one.md new file mode 100644 index 000000000..e8071921d --- /dev/null +++ b/docs/getting-started/demo-one.md @@ -0,0 +1,3 @@ +# Demo One + +Details of Demo one goes here diff --git a/docs/getting-started/demo.md b/docs/getting-started/demo.md new file mode 100644 index 000000000..245a52d18 --- /dev/null +++ b/docs/getting-started/demo.md @@ -0,0 +1,6 @@ +# Demos + +## Demos List + +TODO: A list of demos + diff --git a/docs/getting-started/demos/financial-inclusion-101.md b/docs/getting-started/demos/financial-inclusion-101.md new file mode 100644 index 000000000..feaab07f2 --- /dev/null +++ b/docs/getting-started/demos/financial-inclusion-101.md @@ -0,0 +1,11 @@ +# Financial Inclusion 101 + + \ No newline at end of file diff --git a/docs/getting-started/demos/inside-the-loop.md b/docs/getting-started/demos/inside-the-loop.md new file mode 100644 index 000000000..8d7842c9e --- /dev/null +++ b/docs/getting-started/demos/inside-the-loop.md @@ -0,0 +1,26 @@ +# Inside the Loop + + +## Part 1 + + + +## Part 2 + + \ No newline at end of file diff --git a/docs/getting-started/demos/mojaloop-overview.md b/docs/getting-started/demos/mojaloop-overview.md new file mode 100644 index 000000000..46b479495 --- /dev/null +++ b/docs/getting-started/demos/mojaloop-overview.md @@ -0,0 +1,11 @@ +# Mojaloop Overview + + \ No newline at end of file diff --git a/docs/getting-started/demos/what-is-rtp.md b/docs/getting-started/demos/what-is-rtp.md new file mode 100644 index 000000000..394347196 --- /dev/null +++ b/docs/getting-started/demos/what-is-rtp.md @@ -0,0 +1,11 @@ +# What is RTP? + + \ No newline at end of file diff --git a/docs/getting-started/demos/what-makes-a-successful-financial-ecosystem.md b/docs/getting-started/demos/what-makes-a-successful-financial-ecosystem.md new file mode 100644 index 000000000..45c0b43fc --- /dev/null +++ b/docs/getting-started/demos/what-makes-a-successful-financial-ecosystem.md @@ -0,0 +1,11 @@ +# What Makes a Successful Financial Ecosystem? + + \ No newline at end of file diff --git a/docs/getting-started/demos/why-mojaloop.md b/docs/getting-started/demos/why-mojaloop.md new file mode 100644 index 000000000..5230c5e03 --- /dev/null +++ b/docs/getting-started/demos/why-mojaloop.md @@ -0,0 +1,11 @@ +# Why Mojaloop? + + \ No newline at end of file diff --git a/docs/getting-started/demos/working-with-mojaloop.md b/docs/getting-started/demos/working-with-mojaloop.md new file mode 100644 index 000000000..febc571b9 --- /dev/null +++ b/docs/getting-started/demos/working-with-mojaloop.md @@ -0,0 +1,11 @@ +# Working with Mojaloop + + \ No newline at end of file diff --git a/docs/getting-started/faqs.md b/docs/getting-started/faqs.md new file mode 100644 index 000000000..7193a2036 --- /dev/null +++ b/docs/getting-started/faqs.md @@ -0,0 +1,6 @@ +# Frequently Asked Questions + +This document contains some of the most frequently asked questions from the community. + +- [General FAQs](/getting-started/general-faqs) +- [Technical FAQs](/getting-started/technical-faqs) \ No newline at end of file diff --git a/docs/getting-started/general-faqs.md b/docs/getting-started/general-faqs.md new file mode 100644 index 000000000..5afab4b63 --- /dev/null +++ b/docs/getting-started/general-faqs.md @@ -0,0 +1,59 @@ +# General FAQs + +This document contains some of the most frequently asked questions from the community. + +## 1. What is Mojaloop? + +Mojaloop is open-source software for building interoperable digital payments platforms on a national scale. It makes it easy for different kinds of providers to link up their services and deploy low-cost financial services in new markets. + + +## 2. How does it work? + +Most digital financial providers run on their own networks, which prevents customers who use different services from transacting with each other. Mojaloop functions like a universal switchboard, routing payments securely between all customers, regardless of which network they're on. It consists of three primary layers, each with a specific function: an interoperability layer, which connects bank accounts, mobile money wallets, and merchants in an open loop; a directory service layer, which navigates the different methods that providers use to identify accounts on each side of a transaction; a transactions settlement layer, which makes payments instant and irrevocable; and components which protect against fraud. + +## 3. Who is it for? + +There are many components to the code, and everyone either directly or indirectly working with digital financial transactions-fintech developers, bankers, entrepreneurs, startups-is invited to explore and use whatever parts are useful or appealing. The software as a whole is meant to be implemented on a national scale, and so it will be most applicable to mobile money providers, payments associations, central banks, and country regulators. + +Developers at fintech and financial services companies can use the code in three ways: adapt the code to the financial services standards for a country, use the code to update their own products and services or create new ones, and improve the code by proposing updates and new versions of it for other users. + +For example: + +- A central bank may commission the use of the software by their commercial partners to speed up the deployment of a national payment gateway. +- A major payment processor can use the software to modernize their current offering, to achieve lower transaction costs without major R&D investments. +- A fintech startup can use the code to understand practically how to comply with interoperable payment APIs. +- A bank can use the code to modify their internal systems so that they easily interoperate with other payment providers. + +## 4. Why does it exist? + +Providers trying to reach developing markets with innovative, low-cost digital financial services have to build everything on their own. This raises costs and segregates services from each other. Mojaloop can be used as a foundation to help build interoperable platforms, lowering costs for providers and allowing them to integrate their services with others in the market. + +## 5. Who's behind it? + +Mojaloop was built in collaboration with a group of leading tech and fintech companies: [Ripple](https://github.com/ripple), [Dwolla](https://github.com/dwolla), [Software Group](http://www.softwaregroup-bg.com/), [ModusBox](http://www.modusbox.com/) and [Crosslake Technologies](http://www.crosslaketech.com/). Mojaloop was created by the Gates Foundation's Mojaloop, which is aimed at leveling the economic playing field by crowding in expertise and resources to build inclusive payment models to benefit the world's poor. It is free to the public as open-source software under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). + +## 6. What platforms does Mojaloop run on? + +The Mojaloop platform was developed for modern cloud-computing environments. Open-source methods and widely used platforms, like Node.js, serve as the foundation layer for Mojaloop. The microservices are packaged in Docker and can be deployed to local hardware or to cloud computing environments like Amazon Web Services or Azure. + +## 7. Is it really open-source? + +Yes, it is really open-source. All core modules, documentation and white papers are available under a [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). Mojaloop relies on commonly used open-source software, including node.js, MuleCE, Java and PostgreSQL. Mojaloop also uses the [Interledger Protocol](https://github.com/interledger) to choreograph secure money transfers. The licenses for all of these platforms and their imported dependencies allow for many viable uses of the software. + +## 8. How can I contribute to Mojaloop? + +You can contribute by helping us create new functionality on our roadmap or by helping us improve the platform. For our roadmap, go to the [Mojaloop Roadmap](../mojaloop-roadmap.md). We recommend starting with the onboarding guide and sample problem. This has been designed by the team to introduce the core ideas of the platform and software, the build methods, and our process for check-ins. + +## 9. Using Mojaloop to do payment using crypto-currency? + +Not with the current Specification and with this platform. Currently this is limited to currencies listed in the ISO 4217. Since the specification and platform is all about digital transfers, it should be possible to investigate a use-case for this possible requirement. Alternatively, I guess an FSP can provide that conversion (like many do already from crypto to one of the listed currencies). + +## 10. How is the Mojaloop source accessible? + +Here are some resources to start with: +1. Docs: https://github.com/mojaloop/documentation. +2. Look at the repos that have “CORE COMPONENT (Mojaloop)” in the description and these are core components. “CORE RELATED (Mojaloop)” repos are the ones that are needed to support the current Mojaloop Switch implementation/deployment. +3. As a generic point of note, for latest code, please use the ‘develop’ branch for the time-being. +4. Current architecture: https://github.com/mojaloop/docs/tree/master/Diagrams/ArchitectureDiagrams. Please note that these are currently being migrated to https://github.com/mojaloop/documents. +5. You may use this for current deployment architecture and deployment information: https://github.com/mojaloop/documentation/tree/master/deployment-guide. + diff --git a/docs/getting-started/installation/installing-mojaloop.md b/docs/getting-started/installation/installing-mojaloop.md new file mode 100644 index 000000000..3aaa4011b --- /dev/null +++ b/docs/getting-started/installation/installing-mojaloop.md @@ -0,0 +1,16 @@ +# Installing Mojaloop + +Mojaloop is packaged and released as a set of [Helm Charts](https://github.com/mojaloop/helm) with various options for deployment and customization. +Even if you are new to Mojaloop and unfamiliar with [Helm](https://helm.sh) / [Kubernetes](https://kubernetes.io) or if you just want to get the software up and running quickly, there are several options avaiable to deploy Mojaloop. + +1. **Manual Deployment** - The Mojaloop [Deployment Guide](../../technical/deployment-guide/) is intended for those familiar with [Kubernetes](https://kubernetes.io) and [Helm](https://helm.sh). This is a great place to start if you are thinking of deploying Mojaloop on an existing Kubernetes environment, or if you are interested in setting one up yourself. + +2. **IaC (Infrastructure as Code)** - A comprehensive Mojaloop deployment aimed at giving users a starting point for production. IaC is highly automated ([Terraform](https://www.terraform.io), [Ansible](https://www.ansible.com)) and is extensible. To learn more about an the IaC review the [IaC Deployment blog](https://infitx.com/deploying-mojaloop-using-iac). + + IaC currently supports the following modular configurations: + - [IaC AWS (Amazon Web Services) Platform](https://github.com/mojaloop/iac-aws-platform) + - On-Prem (Coming Soon) + +3. **Mini-Loop** - Install utilities for Mojaloop that offers an easy and efficient way to get started. The [mini-Loop](https://github.com/tdaly61/mini-loop) scripts enable you to deploy Mojaloop in the cloud or on your laptop / server with just a couple of commands. You can then easily run the [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit#mojaloop-testing-toolkit) to interact and test your deployment. + +4. **Azure Marketplace** - This is an Azure AKS native deployment and aims to give users a starting point for POC or pilot testing. It is a simple deployment, with highly automated Microsoft ARM templates and deploys to managed Kubernetes for easier management. Run the [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit#mojaloop-testing-toolkit) to interact and test your deployment. Refer to the [PI 21 Mojaloop Azure Presentation](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/pi_21_march_2023/presentations/Mojaloop%20Azure%20Deployment.pdf) for more information. diff --git a/docs/getting-started/license.md b/docs/getting-started/license.md new file mode 100644 index 000000000..65a7f20bf --- /dev/null +++ b/docs/getting-started/license.md @@ -0,0 +1,10 @@ +# LICENSE + +Copyright © 2020-2024 Mojaloop Foundation + +The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 +(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + +You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/docs/getting-started/quickstart-one.md b/docs/getting-started/quickstart-one.md new file mode 100644 index 000000000..4148ea4d6 --- /dev/null +++ b/docs/getting-started/quickstart-one.md @@ -0,0 +1,3 @@ +# Quickstart One + +Quickstart goes here \ No newline at end of file diff --git a/docs/getting-started/quickstart-two.md b/docs/getting-started/quickstart-two.md new file mode 100644 index 000000000..ada2469e4 --- /dev/null +++ b/docs/getting-started/quickstart-two.md @@ -0,0 +1,3 @@ +# Quickstart Two + +Quickstart two goes here \ No newline at end of file diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md new file mode 100644 index 000000000..0ed1d5a64 --- /dev/null +++ b/docs/getting-started/quickstart.md @@ -0,0 +1,3 @@ +# Quickstarts + +View a list of quickstarts here \ No newline at end of file diff --git a/docs/getting-started/technical-faqs.md b/docs/getting-started/technical-faqs.md new file mode 100644 index 000000000..04674b55a --- /dev/null +++ b/docs/getting-started/technical-faqs.md @@ -0,0 +1,160 @@ +# Technical FAQs + +This document contains some of the frequently asked technical questions from the community. + +## 1. What is supported? + +Currently the Central ledger components are supported by the team. The DFSP components are outdated and thus the end-to-end environment and full setup is challenging to install. + +## 2. Can we connect directly to Pathfinder in a development environment? + +For the local and test environment, we recommend interfacing with the 'mock-pathfinder' service instead. Pathfinder is a 'paid by usage' service. + +Access the https://github.com/mojaloop/mock-pathfinder repository to download and install mock-pathfinder. Run command npm install in mock-pathfinder directory to install dependencies after this update Database_URI in mock-pathfinder/src/lib/config.js. + +## 3. Should i register DFSP via url http://central-directory/commands/register or i need to update configuration in default.json? + +You should register using the API provided, using postman or curl. Client is using LevelOne code. Needs to implement the current Mojaloop release with the current Postman scripts. + +## 4. Status of the pod pi3-kafka-0 is still on CrashLoopBackOff? + +- More background related to the question: + + When I tired to get logs of the container centralledger-handler-admin-transfer, I get the following error: + Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing + And the status of the pod pi3-kafka-0 is still on CrashLoopBackOff. + I am using a vps on ubuntu 16.04 with RAM 12GB, 2vCores, 2.4GHz, Rom 50GB at OVH for the deployment. + +Increased RAM to 24 GB and CPU to 4 resolved the issues. Appears to be a timeout on Zookeeper due depletion of available resources, resulting in the services shutting down. + +## 5. Why am I getting an error when we try to create new DFSP using Admin? + +Please insure you are using the most current Postman scripts available on https://github.com/mojaloop/mock-pathfinder repository. + + +## 6. Can I spread Mojaloop components over different physical machines and VM's? + +You should be able to setup on different VM's or physical machines. The distribution pretty much depend on your requirements and would be implementation specific. We utilise Kubernetes to assist with the Container Orchestration. This enables us to schedule the deployments through the Kubernetes runtime to specific machines if required, and request specific resources if required. The helm charts in the helm repository could be used as guideline to how best allocate and group the components in your deployment. Naturally you would need to update the configurations to complement your custom implementation. + +## 7. Can we expect all the endpoints defined in the API document are implemented in Mojaloop? + +The Mojaloop Specification API for transfers and the Mojaloop Open Source Switch implementation are independent streams, though obviously the implementation is based on the Specification. Based on the use-cases prioritized for a time-frame and based on the end-points needed to support those use-cases, implementation will be done. If a few end-points are not prioritized then implementation for them may not be available. However, I think the goal is to eventually support all the end-points specified though it may take time. Thanks for the collection. We do have some of these on the ‘postman’ repo in the mojaloop GitHub org. + +## 8. Does Mojaloop store the payment initiator FSP’s quote/status info? + +At the moment, the Mojaloop Open source Switch implementation does *not* store Quotes related information. The onus is on the Payer, Payee involved in the process to store the relevant information. + +## 9. Does Mojaloop handle workflow validation? + +Not at the moment, but this may happen in the future. Regarding correlating requests that are related to a specific transfer, you may look at the ‘transaction’ end-point/resource in the Specification for more information on this. In addition to this, I can convey that some background work is ongoing regarding the specification to make this correlation more straight-forward and simpler i.e., to correlate quote and transfer requests that come under a single transaction. + + +## 10. How to register a new party in Mojaloop? + +There is no POST on /parties resource, as specified in section 6.1.1 of the API Defintion. Please refer to section: 6.2.2.3 `POST /participants//` in the API Defintion. + +” _The HTTP request `POST /participants//` (or `POST /participants///`) is used to create information on the server regarding the provided identity, defined by ``, ``, and optionally `` (for example, POST_ + _/participants/MSISDN/123456789 or POST /participants/BUSINESS/shoecompany/employee1). See Section 5.1.6.11 for more information regarding addressing of a Party._ ”. + +## 11. Does the participant represent an account of a customer in a bank? + +For more on this, please refer to this doc (Section 3..2): https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +” _In the API, a Participant is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource Participants is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system._ ” + +In essence, a participant is any FSP participating in the Scheme (usually not a customer). For account lookup, a directory service such as *Pathfinder* can be used, which provides user lookup and the mapping. If such a directory service is not provided, an alternative is provided in the Specification, where the Switch hosts an Account Lookup Service (ALS) but to which the participants need to register parties. I addressed this earlier. But one thing to note here is that the Switch does not store the details, just the mapping between an ID and an FSP and then the calls to resolve the party are sent to that FSP. + +https://github.com/mojaloop/mojaloop-specification CORE RELATED (Mojaloop): + +This repo contains the specification document set of the Open API for FSP Interoperability - mojaloop/mojaloop-specification. + +## 12. How to register _trusted_ payee to a payer, to skip OTP? + +To skip the OTP, the initial request on the /transactionRequests from the Payee can be programmatically (or manually for that matter) made to be approved without the use of the /authorizations endpoint (that is need for OTP approval). Indeed the FSP needs to handle this, the Switch does not. This is discussed briefly in section 6.4 of the Specification. + +## 13. Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file? + +From the official kubernetes github repository in the README.md, the latest link to use is "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Be sure to always verify 3rd party links before implementing. Open source applications are always evolving. + +## 14. When installing nginx-ingress for load balancing & external access - Error: no available release name found? + +Please have a look at the following addressing a similar issue. To summarise - it is most likely an RBAC issue. Have a look at the documentation to set up Tiller with RBAC. https://docs.helm.sh/using_helm/#role-based-access-control goes into detail about this. The issue logged: helm/helm#3839. + +## 15. Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command. + +Found a solution here https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Ubuntu 14 here, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. First, I want to build latest stable (seems it's 0.9.2) librdkafka into /opt/librdkafka. curl https://codeload.github.com/ede... + +Here are the steps to rebuild librdkafka: + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout ` + +cd librdkafka && ./configure && make && make install && ldconfig + +After that I'm able to import stuff without specifying LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +The Apache Kafka C/C++ library. Contribute to edenhill/librdkafka development by creating an account on GitHub. + +## 16. Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only? + +We can use mojaloop for interoperability to support mobile wallet and other such money transfers. This is not a software for a DFSP (there are open source projects that cater for these such as Finserv etc). Mojaloop is for a Hub/Switch primarily and an API that needs to be implemented by a DFSP. But this is not for managing mobile wallets as such. + +## 17. Describe companies that helps to deploy & support for mojaloop? + +Mojaloop is an open source software and specification. + +## 18. Can you say something about mojaloop & security? + +The Specification is pretty standard and has good security standards. But these need to be implemented by the adopters and deployers. Along with this, the security measures need to be coupled with other Operational and Deployment based security measures. Moreover, the coming few months will focus on security perspective for the Open Source community. + +## 19. What are the benefit(s) from using mojaloop as interoperabilty platform? + +Benefits: Right now for example, an Airtel mobile money user can transfer to another Airtel mobile money user only. With this, he/she can transfer to any Financial service provider such as another mobile money provider or any other bank account or Merchant that is connected to the Hub, irrespective of their implementation. They just need to be connected to the same Switch. Also, this is designed for feature phones so everyone can use it. + +## 20. What are the main challenges that companies face using mojaloop? + +At this point, the main challenges are around expectations. Expectations of the adopters of mojaloop and what really mojaloop is. A lot of adopters have different understanding of what mojaloop is and about its capabilities. If they have a good understanding, a lot of current challenges are mitigated.. +Yes, forensic logging is a security measure as well for auditing purposes which will ensure there is audit-able log of actions and that everything that is a possible action of note is logged and rolled up, securely after encryption at a couple of levels. + +## 21. Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform? + +This also ensures all the services always run the code they’re meant to run and anything wrong/bad is stopped from even starting up. Also, for reporting and auditors, reports can have a forensic-log to follow. + +## 22. How do the financial service providers connect with mojaloop? + +There is an architecture diagram that presents a good view of the integration between the different entities. https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +## 23. Is there any open source ISO8583-OpenAPI converter/connector available? + +I don't believe a generic ISO8583 `<-> Mojaloop integration is available currently. We're working on some "traditional payment channel" to Mojaloop integrations (POS and ATM) which we hope to demo at the next convening. These would form the basis for an ISO8583 integration we might build and add to the OSS stack but bare in mind that these integrations will be very use case specific. + +## 24. How do I know the end points to setup postman for testing the deployment? + +On the Kubernetes dashboard, select the correct NAMESPACE. Go to Ingeresses. Depending on how you deployed the helm charts, look for 'moja-centralledger-service'. Click on edit, and find the tag ``. This would contain the endpoint for this service. + +If you use the CLI, find the 'Host' column in `kubectl describe ingress moja-centralledger-service` + +## 25. Why are there no reversals allowed on a Mojaloop? + +*Irrevocability* is a core Level One Principle (edited) and not allowing reversals is essential for that. Here is the section from the API Definition addressing this: + +_*6.7.1.2 Transaction Irrevocability*_ +_The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions._ +_As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using POST /transfers including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer’s expiry time is exceeded before the Payee FSP responds (see Sections 6.7.1.3 and 6.7.1.5 for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties._ + +However, *Refunds* is a use case supported by the API. + +## 26. ffg. error with microk8s installation "MountVolume.SetUp failed"? + +Would appear if it is a space issue, but more the 100GiB of EBS storage was allocated. +The issue resolved itself after 45 minutes. Initial implementation of the mojaloop project can take a while to stabilize. + +## 27. Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"? + +You need to create the corresponding Hub accounts (HUB_MULTILATERAL_SETTLEMENT and HUB_RECONCILIATION) for the specified currency before setting up the participants. +In this Postman collection you can find the requests to perform the operation in the "Hub Account" folder: https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Find also the related environments in the Postman repo: https://github.com/mojaloop/postman diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..29dda5cd4 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,26 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: This is the official documentation of the Mojaloop project +# actionText: Getting Started → +# actionLink: /getting-started/ +# features: +# - title: Business +# details: Making the business case for Mojaloop +# - title: Community +# details: Learn about the community behind the tech +# - title: Technical +# details: See inside the different components, and deploy Mojaloop for yourself! +# - title: Product +# details: Mojaloop product features, requirements and roadmap +--- + +
    +
    + +| | | | | +|:----:|:----:|:----:|:----:| +|

    **[Adoption](/adoption/)**

    |

    **[Community](/community/)**

    |

    **[Product](/product/)**

    |

    **[Technical](/technical/)**

    | +| Making the business case for Mojaloop | Learn about the community behind the tech | Mojaloop product features, requirements and roadmap | Look inside the different components and deploy Mojaloop for yourself! | + +
    \ No newline at end of file diff --git a/docs/product/README.md b/docs/product/README.md new file mode 100644 index 000000000..b44b23e26 --- /dev/null +++ b/docs/product/README.md @@ -0,0 +1,5 @@ +# Welcome to Mojaloop the Product + +This section is devoted to Product-related documentation of Mojaloop, setting out from a business perspective its feature set, functionality, APIs, support for connecting DFSPs, the establishment of Mojaloop-based merchant payments schemes, cross-border transactions, ISO 20022, etc; in fact, all the features a potential adopter needs to know about when considering the shape of their scheme. It does not provide technical/engineering detail, which is available elsewhere on this site. + +It represents the outputs of the open source Mojaloop Community over a period of years. Should the reader wish to help shape the future of Mojaloop, then come and join the discussions held on the #product-council Slack channel and Community Central (https://community.mojaloop.io/). \ No newline at end of file diff --git a/docs/product/features/ComplexXB.svg b/docs/product/features/ComplexXB.svg new file mode 100644 index 000000000..4e87239dd --- /dev/null +++ b/docs/product/features/ComplexXB.svg @@ -0,0 +1,4 @@ + + + +
    Jurisdiction B
    Jurisdiction B
    Jurisdiction A
    Jurisdiction A
    Scheme 1
    Scheme 1
    Scheme 2
    Scheme 2
    DFSP 2
    DFSP 2
    Proxy
    Proxy
    FXP 1
    FXP 1
    FXP 3
    FXP 3
    FXP 2
    FXP 2
    Proxy
    Proxy
    Existing Scheme 1.1
    Existing Scheme 1.1
    DFSP 1
    DFSP 1
    DFSP 3
    DFSP 3
    \ No newline at end of file diff --git a/docs/product/features/CrossBorder.md b/docs/product/features/CrossBorder.md new file mode 100644 index 000000000..c54b43a0e --- /dev/null +++ b/docs/product/features/CrossBorder.md @@ -0,0 +1,25 @@ +# Cross Border Transactions + +*This page assumes the reader is familiar with both Mojaloop's [**interscheme capabilities**](./InterconnectingSchemes.md) and the operation of [**foreign exchange**](./ForeignExchange.md).* + +The current version of Mojaloop treats a cross-border transaction as a transaction that leaves one payments scheme, and is passed to another in a different regulatory jurisdiction. It is therefore, in Mojaloop terms, an interscheme transaction that includes a foreign exchange. + +The following diagram illustrates how Mojaloop implements this functionality. + +![Cross Border Transactions](./XB.svg) + +In this context, a Proxy acts as the link between two Mojaloop schemes operating in different countries (regulatory jurisdictions), facilitating transactions and ensuring their end-to-end non-repudiation. Multiple FXPs are illustrated, two in jurisdiction A and one in jurisdiction B, so the various business models proposed for FX transactions can be supported. + +This model can be extended further, so that countries with existing domestic instant payment systems can be interconnected, as follows: + +![Interconnecting Domestic Schemes to Offer Cross Border transactions](./ComplexXB.svg) + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22nd April 2025| Paul Makin|Added version history; clarified some wording| +|1.0|14th April 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Discovery.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Discovery.plantuml new file mode 100644 index 000000000..2e20cd471 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Discovery.plantuml @@ -0,0 +1,216 @@ +@startuml FXAPI_Discovery + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Discovery - Mojaloop Connector Integration +actor "$senderName" as A1 + participant "Payer CBS" as PayerCBS +box "Payer DFSP" #LightBlue + participant "Core Connector" as PayerCC + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +box "Discovery Service" #LightYellow + participant "ALS Oracle" as ALS +end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +' participant "Backend FX API" as FXPBackend +'end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 + participant "Core Connector" as PayeeCC +end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:I'd like to pay $receiverName\n$payerSendAmount $payerCurrency, please +PayerCBS->PayerCC: Initiate remittance transfer +!if ($advancedCoreConnectorFlow != true) + PayerCC->D1: **POST /transfers** + !if ($simplified != true) + note left + { + "homeTransactionId": "$homeTransactionId", + "from": { + "dateOfBirth": "$senderDOB", + "displayName": "$senderName", + "firstName": "$senderFirstName", + "middleName": "$senderMiddleName", + "lastName": "$senderLastName" + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" + }, + "to": { + "idType": "MSISDN", + "idValue": "$payeeMSISDN" + }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + } + end note + !endif +!else +PayerCC->D1: **GET /parties/MSISDN/$payeeMSISDN** +!endif + +activate D1 +D1->>S1:I want to send to MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +S1->ALS:Who owns MSISDN $payeeMSISDN? +activate ALS +ALS-->S1:It's $payeeFSPID +deactivate ALS +S1->>D2:Do you own MSISDN $payeeMSISDN? +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +deactivate S1 +!endif +D2->PayeeCC: **GET** /parties +PayeeCC->PayeeCC: Validate whether the party \n can receive the transfer +PayeeCC->PayeeCC: Check account and\n get currency type +!if ($simplified != true) +PayeeCC-->D2: Result +!endif +deactivate S1 +D2->>S1:Yes, it's $receiverName.\n He can receive in $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +note right + PUT /parties + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName" + }, + "supportedCurrencies": [ "$payeeCurrency" ] + } +end note +!else +!endif +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +deactivate D2 +S1->>D1:Yes, it's $receiverName. \nHe can receive in $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif +deactivate S1 + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC: Here is the party information\nand supported currencies + note right + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" + }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_PARTY_ACCEPTANCE**", + "getPartiesResponse": { + "body": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } + } + } + end note +!else + D1-->PayerCC: Here is the party information\nand supported currencies + !if ($simplified != true) + note right of PayerCC + { + "party": { + "body": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif +deactivate D1 +PayerCC-->PayerCBS:Here's are the \nreceiver details +PayerCBS->A1:Hi, $senderName: \nThe number belongs to $receiverName \nLet me know if you want to\n go ahead +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Discovery.svg b/docs/product/features/CurrencyConversion/FXAPI_Discovery.svg new file mode 100644 index 000000000..c1b690c59 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Discovery.svg @@ -0,0 +1 @@ +Discovery - Mojaloop Connector IntegrationPayer DFSPDiscovery ServicePayee DFSPJohnJohnPayer CBSPayer CBSCore ConnectorCore ConnectorPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchALS OracleALS OraclePayeeMojaloopConnectorPayeeMojaloopConnectorCore ConnectorCore Connector1I'd like to pay Yaro300 BWP, please2Initiate remittance transfer3POST /transfers{"homeTransactionId": "string","from": {"dateOfBirth": "1966-06-16","displayName": "John","firstName": "$senderFirstName","middleName": "$senderMiddleName","lastName": """fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321"},"to": {"idType": "MSISDN","idValue": "2551234567890"},"amountType": "SEND","currency": "BWP","amount": "300"}4I want to send to MSISDN 2551234567890GET /parties/MSISDN/25512345678905202 I'll get back to you6Who owns MSISDN 2551234567890?7It's PayeeFSP8Do you own MSISDN 2551234567890?9202 I'll get back to you10GET/parties11Validate whether the partycan receive the transfer12Check account andget currency type13Result14Yes, it's Yaro.He can receive in TZSPUT /parties/MSISDN/2551234567890PUT /parties{"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890","fspId": "PayeeFSP"},"name": "Yaro"},"supportedCurrencies": [ "TZS" ]}15200 Gotcha16Yes, it's Yaro.He can receive in TZSPUT /parties/MSISDN/255123456789017200 Gotcha18Here is the party informationand supported currencies{"transferId": "d9ce59d4359843968630581bb0","homeTransactionId": "string","from": {"displayName": "John","fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321"},"to": {"type": "CONSUMER","idType": "MSISDN","idValue": "2551234567890","displayName": "Yaro","fspId": "PayeeFSP""supportedCurrencies": [ "TZS" ]},"amountType": "SEND","currency": "BWP","amount": "300""currentState": "WAITING_FOR_PARTY_ACCEPTANCE","getPartiesResponse": {"body": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890","fspId": "PayeeFSP"},"name": "Yaro","supportedCurrencies": [ "TZS" ]}}}19Here's are thereceiver details20Hi, John:The number belongs to YaroLet me know if you want togo ahead \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml new file mode 100644 index 000000000..9f71b0acb --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.plantuml @@ -0,0 +1,236 @@ +@startuml FXAPI_Payer_Agreement + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415..." +!$conversionId = "581f68efb54f41..." +!$homeTransactionId = "string" +!$quoteId = "382987a875ce403..." +!$transactionId = "d9ce59d43598439..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843..." +!$transferId = "d9ce59d43598439..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Agreement Phase - Mojaloop Connector Integration +'actor "$senderName" as A1 +' participant "Payer CBS" as PayerCBS +box "Payer DFSP" #LightBlue + participant "Core Connector" as PayerCC + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +' participant "Backend FX API" as FXPBackend +'end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 + participant "Core Connector" as PayeeCC +end box + +'actor "$receiverName" as A2 +autonumber + +!if ($advancedCoreConnectorFlow != true) +PayerCC->D1: I want to get a quote from the FSP\n**PUT /transfers** +note left +{"acceptConversion": true} +end note +!else +PayerCC->D1: I want to get a quote from the FSP\n**POST /quotes** + !if ($simplified != true) + note right of PayerCC + { + "fspId": "$payeeFSPID", + "quotesPostRequest": { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID" + }, + "name": "$senderName", + }, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" + } + } + end note + !endif +!endif + + +D1->>S1:Please quote for a transfer which \nsends $fxpTargetAmount $payeeCurrency.\n**POST /quotes** +!if ($simplified != true) +note left +**POST /quotes** +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID"}, + "name": "$senderName"}, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif + +S1->>D2:**POST /quotes** +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +!endif +deactivate S1 +D2->PayeeCC:**POST /quoterequests** +!if ($simplified != true) +note left +**POST /quoterequests** +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ]}, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID"}, + "name": "$senderName"}, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" +} +end note +!endif +PayeeCC->PayeeCC:OK, so I will charge $payeeFee $payeeCurrency for this.\nNow I create terms of the transfer +PayeeCC-->D2:Here are the terms +!if ($simplified != true) +note right +**POST /quoterequests** response +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayerExpiration" +} +end note +!endif +D2->D2:Now I will sign the transaction object +D2->>S1:Here's the signed quote +note right +**put /quotes/$quoteId** +{ + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition" +} + +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +deactivate D2 +S1->>D1:Here's the signed quote\n**PUT /quotes/$quoteId** +activate D1 +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif +deactivate S1 +D1->D1:OK, I can see that there \nare going to be $payeeFee $payeeCurrency in charges. +@enduml diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg new file mode 100644 index 000000000..b9d56798d --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Agreement.svg @@ -0,0 +1 @@ +Agreement Phase - Mojaloop Connector IntegrationPayer DFSPPayee DFSPCore ConnectorCore ConnectorPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchPayeeMojaloopConnectorPayeeMojaloopConnectorCore ConnectorCore Connector1I want to get a quote from the FSPPUT /transfers{"acceptConversion": true}2Please quote for a transfer whichsends 48000 TZS.POST /quotesPOST /quotes{"quoteId": "382987a875ce403...","transactionId": "d9ce59d43598439...","payee": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890","fspId": "PayeeFSP"},"name": "Yaro","supportedCurrencies": [ "TZS" ] },"payer": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "26787654321","fspId": "PayerFSP"},"name": "John"},"amountType": "SEND","amount": {"currency": "TZS","amount": "48000"},"converter": "PAYER","expiration": "2021-08-25T14:17:09.663+01:00"}3202 I'll get back to you4POST /quotes5202 I'll get back to you6POST /quoterequestsPOST /quoterequests{"quoteId": "382987a875ce403...","transactionId": "d9ce59d43598439...","payee": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890","fspId": "PayeeFSP"},"name": "Yaro","supportedCurrencies": [ "TZS" ]},"payer": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "26787654321","fspId": "PayerFSP"},"name": "John"},"amountType": "SEND","amount": {"currency": "TZS","amount": "48000"},"converter": "PAYER","expiration": "2021-08-25T14:17:09.663+01:00"}7OK, so I will charge 4000 TZS for this.Now I create terms of the transfer8Here are the termsPOST /quoterequestsresponse{"quoteId": "382987a875ce403...","transactionId": "d9ce59d43598439...","payeeFspFeeAmount": "4000","payeeFspFeeAmountCurrency": "TZS","payeeReceiveAmount": "44000","payeeReceiveAmountCurrency": "TZS","transferAmount": "48000","transferAmountCurrency": "TZS""expiration": "2021-08-25T14:17:09.663+01:00"}9Now I will sign the transaction object10Here's the signed quoteput /quotes/382987a875ce403...{"transferAmount": {"currency": "TZS","amount": "48000"},"payeeReceiveAmount": {"currency": "TZS","amount": "44000"},"payeeFspFee": {"currency": "TZS","amount": "4000"},"expiration": "$payeeQuoteExpiration","ilpPacket": "<This is encoded transaction object.>","condition": "HOr22-H3AfTDHrSkP..."} 11200 Gotcha12Here's the signed quotePUT /quotes/382987a875ce403...13200 Gotcha14OK, I can see that thereare going to be 4000 TZS in charges. \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml new file mode 100644 index 000000000..994fc0f2d --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.plantuml @@ -0,0 +1,384 @@ +@startuml FXAPI_Payer_CurrencyConversion + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Agreement Phase Currency Conversion - Mojaloop Connector Integration +actor "$senderName" as A1 +participant "Payer CBS" as PayerCBS +box "Payer DFSP" #LightBlue + participant "Core Connector" as PayerCC + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP + participant "Backend FX API \n(Core Connector)" as FXPBackend +end box + +'box "Payee DFSP" #LightBlue +' participant "Payee\nMojaloop\nConnector" as D2 +' participant "Core Connector" as PayeeCC +'end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:Yes please, go ahead +PayerCBS->PayerCC: Payer has accepted\n the party information + +!if ($shortCutSingleFXP != true) + +!if ($advancedCoreConnectorFlow != true) +PayerCC->>D1:Get quotation\n**PUT /transfers/$transferId** +note left +{ "acceptParty": true } +end note +D1->D1:Hmmm. I can only send in $payerCurrency.\nI need to get some currency conversion +!else +PayerCC->PayerCC:Hmmm. I can only send in $payerCurrency.\nI need to get some currency conversion +PayerCC->>PayerCC:Lookup the local cached FXPs\n that can provide the conversion +!endif + +D1->>D1:Lookup the local cached FXPs\n that can provide the conversion + + +!if ($advancedCoreConnectorFlow != true) +' TODO: We can pause the execution here if required to allow the core connector to select the FXP +D1->D1:I'll ask FDH FX to perform my conversion +!else +D1->>PayerCC:Here are the available FXPs +note right of PayerCC + { + "providers": [ + "$fxpID" + ] + } +end note + +PayerCC->PayerCC:I'll ask FDH FX to perform my conversion +PayerCC->D1: I want to get a quote from this FXP\n**POST /fxQuotes** + !if ($simplified != true) + note right of PayerCC + { + "homeTransactionId": "$homeTransactionId", + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency" + }, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } + end note + !endif +!endif +!endif + +deactivate S1 + +!if ($shortCutSingleFXP != true) +D1->>S1:Here is the initial version of the transfer.\nPlease quote me for the currency conversion. +!else +D1->>FXP:Here is the initial version of the transfer.\nPlease quote me for the currency conversion. +!endif +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note +!if ($shortCutSingleFXP != true) +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D1 +S1->>FXP:Here is the initial version of the transfer.\nPlease quote me for the currency conversion.\n**POST /fxQuote** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +deactivate S1 +!else +!if ($simplified != true) +FXP-->>D1:202 I'll get back to you +!endif +!endif +FXP->FXPBackend:Lookup FX rate +!if ($simplified != true) +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note +!endif +note over FXPBackend + I will add a $fxpChargesSource $payerCurrency fee for undertaking the conversion. + Now I'll set an expiry time, sign the quotation object, +end note +FXPBackend-->FXP:Return FX rate +!if ($simplified != true) +note right + **post /fxQuotes** response + { + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +!endif + +note over FXP + Now I'll sign the quotation object, + create an ILP prepare packet and return it in the intermediary object. + + **NOTE:** the ILP prepare packet contains the following items, all encoded: + - The amount being sent (i.e. in the source currency) + - An expiry time + - The condition + - The name of the FXP + - The content of the conversion terms +end note + +!if ($shortCutSingleFXP != true) +FXP->>S1:Here's the signed conversion object +note right + **PUT /fxQuotes/$conversionRequestId** + { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +deactivate FXP +S1->>D1:Here's the signed conversion object\n**PUT /fxQuotes/$conversionRequestId** +activate D1 +!if ($simplified != true) +D1-->>S1:Gotcha +!endif +deactivate S1 +!else +FXP-->>D1:Here's the signed conversion object\n**PUT /fxQuotes/$conversionRequestId** +!if ($simplified != true) +D1-->>FXP:202 I'll get back to you +!endif +activate D1 +!endif + + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC: Here are the conversion terms + note right + **POST/PUT /transfers** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ]}, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_CONVERSION_ACCEPTANCE**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": { + "body": { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [{ + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]}} + }, + "fxQuotesResponseSource": "$payeeFSPID", + } + end note +!else + D1->PayerCC: Here are the conversion terms + !if ($simplified != true) + note right of PayerCC + { + "homeTransactionId": "$homeTransactionId", + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget" + } + } + ] + } + } + end note + !endif +!endif + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg new file mode 100644 index 000000000..8114a5163 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg @@ -0,0 +1 @@ +Agreement Phase Currency Conversion - Mojaloop Connector IntegrationPayer DFSPFX providerJohnJohnPayer CBSPayer CBSCore ConnectorCore ConnectorPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorBackend FX API(Core Connector)Backend FX API(Core Connector)1Yes please, go ahead2Payer has acceptedthe party information3Get quotationPUT /transfers/d9ce59d4359843968630581bb0{ "acceptParty": true }4Hmmm. I can only send in BWP.I need to get some currency conversion5Lookup the local cached FXPsthat can provide the conversion6I'll ask FDH FX to perform my conversion7Here is the initial version of the transfer.Please quote me for the currency conversion.post /fxQuotes{"conversionRequestId": "828cc75f1654415e8fcddf76cc","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS"},"expiration": "2021-08-25T14:17:09.663+01:00"}}8202 I'll get back to you9Here is the initial version of the transfer.Please quote me for the currency conversion.POST /fxQuote10202 I'll get back to you11Lookup FX ratepost /fxQuotes{"conversionRequestId": "828cc75f1654415e8fcddf76cc","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS"},"expiration": "2021-08-25T14:17:09.663+01:00"}}I will add a 33 BWP fee for undertaking the conversion.Now I'll set an expiry time, sign the quotation object,12Return FX ratepost /fxQuotesresponse{"conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"expiration": "2021-08-25T14:17:09.663+01:00""charges": [{"chargeType": "string","sourceAmount": {"currency": "BWP","amount": "33"},"targetAmount": {"currency": "TZS","amount": "6000"}}]}}Now I'll sign the quotation object,create an ILP prepare packet and return it in the intermediary object. NOTE:the ILP prepare packet contains the following items, all encoded:- The amount being sent (i.e. in the source currency)- An expiry time- The condition- The name of the FXP- The content of the conversion terms13Here's the signed conversion objectPUT /fxQuotes/828cc75f1654415e8fcddf76cc{"condition": "GRzLaTP7DJ9t4P-a_B...","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"expiration": "2021-08-25T14:17:09.663+01:00""charges": [{"chargeType": "string","sourceAmount": {"currency": "BWP","amount": "33"},"targetAmount": {"currency": "TZS","amount": "6000"}}]}}14200 Gotcha15Here's the signed conversion objectPUT /fxQuotes/828cc75f1654415e8fcddf76cc16Gotcha17Here are the conversion termsPOST/PUT /transfersresponse{"transferId": "d9ce59d4359843968630581bb0","homeTransactionId": "string","from": {"displayName": "John","fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321"},"to": {"type": "CONSUMER","idType": "MSISDN","idValue": "2551234567890","displayName": "Yaro","fspId": "PayeeFSP""supportedCurrencies": [ "TZS" ]},"amountType": "SEND","currency": "BWP","amount": "300""currentState": "WAITING_FOR_CONVERSION_ACCEPTANCE","getPartiesResponse": {<Same as the previous responses>},"conversionRequestId": "828cc75f1654415e8fcddf76cc","fxQuotesResponse": {"body": {"condition": "GRzLaTP7DJ9t4P-a_B...","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"expiration": "2021-08-25T14:17:09.663+01:00""charges": [{"chargeType": "string","sourceAmount": {"currency": "BWP","amount": "33"},"targetAmount": {"currency": "TZS","amount": "6000"}}]}}},"fxQuotesResponseSource": "PayeeFSP",} \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml new file mode 100644 index 000000000..53bde892c --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.plantuml @@ -0,0 +1,241 @@ +@startuml FXAPI_Payer_Receive_Agreement + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Agreement - Currency Conversion with Amount Type RECEIVE +'actor "$senderName" as A1 +box "Payer DFSP" #LightBlue +' participant "Payer CBS" as PayerCBS + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP + participant "Backend FX API" as FXPBackend +end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +' participant "Payee CBS" as PayeeCBS +end box + +'actor "$receiverName" as A2 +autonumber + +D1->>S1:Please quote for a payment\n of $payeeReceiveAmount $payeeCurrency.\n**POST /quotes** +!if ($simplified != true) +note left + **POST /quotes** + { + "quoteId": "382987a875ce...", + "transactionId": "d9ce59d43598...", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN" }} + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}}, + "amountType": **"RECEIVE"**, + "amount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"} + "validity": "2021-08-25T14:17:09.663+01:00" + } +end note +!endif +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D1 +S1->>D2:**POST /quotes** +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +deactivate S1 +!endif +D2->D2: Let me get a quote to do the conversion +!if ($shortCutSingleFXP != true) + + +D2->D2:OK, so I will charge $payeeFee $payeeCurrency for this.\nNow I create terms of the transfer \nand sign the transaction object +D2->>S1:Here's the signed quote +note right +**put /quotes/382987a875ce...** +{ + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" }, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "2021-08-25T14:17:09.663+01:00, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "$payeeFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}}, + "payer": { + "fspId": "$payerFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}}, + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "converter": "PAYER"}, + "condition": "BfNFPRgfKF8Ke9kpo..." +} +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +deactivate D2 +S1->>D1:Here's the signed quote\n**PUT /quotes/382987a875ce...** +activate D1 +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif +deactivate S1 +D1->D1:OK, I can see that there are going\n to be $payeeFee $payeeCurrency in charges and \nI need send $targetAmount $payeeCurrency to make \nthis transfer + +group Currency Conversion +D1->D1:Now I need to find out what the \nexchange rate is +deactivate S1 +D1->D1:I'll ask FDH FX to\n perform my conversion + +!if ($shortCutSingleFXP != true) +D1->>S1:Here is the initial version \nof the transfer.Please quote\n me for the currency conversion. +!else +D1->>FXP:Here is the initial version\n of the transfer.Please quote\n me for the currency conversion. +!endif +note left + **post /fxQuotes** + { + "conversionRequestId": "828cc75f1654...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "counterPartyFsp": "FDH_FX", + "amountType": "RECEIVE", + "sourceAmount": { + "currency": "$payerCurrency"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "validity": "2021-08-25T14:17:09.663+01:00"} + } +end note +!if ($shortCutSingleFXP != true) +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D1 +S1->>FXP:Here is the initial version\n of the transfer. Please quote\n me for the currency conversion.\n**POST /fxQuote** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +deactivate S1 +!else +!endif +FXP->FXPBackend:Lookup FX rate +FXPBackend-->FXP:Return FX rate +' !if ($shortCutSingleFXP != true) + +note right + I will add a $fxpChargesSource $payerCurrency fee for + undertaking the conversion. Now I'll set an expiry time, + sign the quotation object, create an ILP prepare packet + and return it in the intermediary object. + + **NOTE:** the ILP prepare packet contains the following + items, all encoded: + - The amount being sent (i.e. in the source currency) + - An expiry time + - The condition + - The name of the FXP + - The content of the conversion terms + + **PUT /fxQuotes/828cc75f1654...** + { + "condition": "bdbcf517cfc7e...", + "conversionTerms": { + "conversionId": "581f68efb54f...", + "initiatingFsp": "$payerFSPID" + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency"", + "amount": "$fxpTargetAmount" + }, + "charges": [{ + "chargeType": "Conversion fee", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"}}], + "validity": "2021-08-25T14:17:09.663+01:00"} + } +end note +!if ($shortCutSingleFXP != true) +FXP->>S1:Here's the signed \nconversion object +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +deactivate FXP +S1->>D1:Here's the signed conversion object\n**PUT /fxQuotes/828cc75f1654...** +activate D1 +!if ($simplified != true) +D1-->>S1:Gotcha +!endif +deactivate S1 +!else +FXP-->>D1:Here's the signed conversion object\n**PUT /fxQuotes/828cc75f1654...** +activate D1 +!endif + +end group + +@enduml diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg new file mode 100644 index 000000000..1d646e96c --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg @@ -0,0 +1 @@ +Agreement - Currency Conversion with Amount Type RECEIVEPayer DFSPFX providerPayee DFSPPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorBackend FX APIBackend FX APIPayeeMojaloopConnectorPayeeMojaloopConnector1Please quote for a paymentof 50000 TZS.POST /quotesPOST /quotes{"quoteId": "382987a875ce...","transactionId": "d9ce59d43598...","payee": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890" }}"payer": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "26787654321"}},"amountType":"RECEIVE","amount": {"currency": "TZS","amount": "50000"}"validity": "2021-08-25T14:17:09.663+01:00"}2202 I'll get back to you3POST /quotes4202 I'll get back to you5Let me get a quote to do the conversion6OK, so I will charge 4000 TZS for this.Now I create terms of the transferand sign the transaction object7Here's the signed quoteput /quotes/382987a875ce...{"transferAmount": {"currency": "TZS","amount": "54000" },"payeeReceiveAmount": {"currency": "TZS","amount": "50000"},"payeeFspFee": {"currency": "TZS","amount": "4000"},"expiration": "2021-08-25T14:17:09.663+01:00,"transaction": {"transactionId": "d9ce59d43598...","quoteId": "382987a875ce...","payee": {"fspId": "PayeeFSP","partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890"}},"payer": {"fspId": "PayerFSP","partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "26787654321"}},"amount": {"currency": "TZS","amount": "54000"},"payeeReceiveAmount": {"currency": "TZS","amount": "50000"},"converter": "PAYER"},"condition": "BfNFPRgfKF8Ke9kpo..."}8200 Gotcha9Here's the signed quotePUT /quotes/382987a875ce...10200 Gotcha11OK, I can see that there are goingto be 4000 TZS in charges andI need send 54000 TZS to makethis transferCurrency Conversion12Now I need to find out what theexchange rate is13I'll ask FDH FX toperform my conversion14Here is the initial versionof the transfer.Please quoteme for the currency conversion.post /fxQuotes{"conversionRequestId": "828cc75f1654...","conversionTerms": {"conversionId": "581f68efb54f...","counterPartyFsp": "FDH_FX","amountType": "RECEIVE","sourceAmount": {"currency": "BWP"},"targetAmount": {"currency": "TZS","amount": "54000"},"validity": "2021-08-25T14:17:09.663+01:00"}}15202 I'll get back to you16Here is the initial versionof the transfer. Please quoteme for the currency conversion.POST /fxQuote17202 I'll get back to you18Lookup FX rate19Return FX rateI will add a 33 BWP fee forundertaking the conversion. Now I'll set an expiry time,sign the quotation object, create an ILP prepare packetand return it in the intermediary object. NOTE:the ILP prepare packet contains the followingitems, all encoded:- The amount being sent (i.e. in the source currency)- An expiry time- The condition- The name of the FXP- The content of the conversion terms PUT /fxQuotes/828cc75f1654...{"condition": "bdbcf517cfc7e...","conversionTerms": {"conversionId": "581f68efb54f...","initiatingFsp": "PayerFSP""sourceAmount": {"currency": "BWP","amount": "330"},"targetAmount": {"currency": "TZS"","amount": "54000"},"charges": [{"chargeType": "Conversion fee","sourceAmount": {"currency": "BWP","amount": "33"},"targetAmount": {"currency": "TZS","amount": "6000"}}],"validity": "2021-08-25T14:17:09.663+01:00"}}20Here's the signedconversion object21200 Gotcha22Here's the signed conversion objectPUT /fxQuotes/828cc75f1654...23Gotcha \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml new file mode 100644 index 000000000..ea6b0de21 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.plantuml @@ -0,0 +1,112 @@ +@startuml FXAPI_Payer_Receive_Discovery + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "267876..." +!$payeeMSISDN = "255123..." +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Discovery - Currency Conversion with Amount Type RECEIVE +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer CBS" as PayerCBS + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +box "Discovery Service" #LightYellow + participant "ALS Oracle" as ALS +end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +' participant "Backend FX API" as FXPBackend +'end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 + participant "Payee CBS" as PayeeCBS +end box + +'actor "$receiverName" as A2 +autonumber + +A1->PayerCBS:I'd like to pay $receiverName\n$payeeReceiveAmount $payeeCurrency for \nhis latest book, please +PayerCBS->D1: Initiate merchant payment +activate D1 +D1->>S1:I want to send to MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D1 +S1->ALS:Who owns MSISDN $payeeMSISDN? +activate ALS +ALS-->S1:It's $payeeFSPID +deactivate ALS +S1->>D2:Do you own MSISDN $payeeMSISDN? +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +!endif +deactivate S1 +D2->D2: Check Sanction list status \n& trigger a refresh of the status +D2->PayeeCBS: Check account and get\n currency type +!if ($simplified != true) +PayeeCBS-->D2: Result +!endif +D2->>S1:Yes, it's $receiverName. He can receive in $payeeCurrency,\n and I can convert from $payerCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +!if ($simplified != true) +note right + **PUT /parties** + { + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}, + "name": "$receiverName", + "supportedCurrencies":["$payeeCurrency"]} + } +end note +!else +note over D2 + Payee Info with Encrypted KYC Data +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +deactivate D2 +S1->>D1:Yes, it's $receiverName. He can receive in $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +activate D1 +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif +deactivate S1 + +D1->D1: I will need to perform currency conversion. +note left +I need to calculate +how much currency I need. +Let me find a currency +conversion provider before I start. +end note + +@enduml diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg new file mode 100644 index 000000000..5177277c1 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg @@ -0,0 +1 @@ +Discovery - Currency Conversion with Amount Type RECEIVEPayer DFSPDiscovery ServicePayee DFSPKeeyaKeeyaPayer CBSPayer CBSPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchALS OracleALS OraclePayeeMojaloopConnectorPayeeMojaloopConnectorPayee CBSPayee CBS1I'd like to pay Yaro50000 TZS forhis latest book, please2Initiate merchant payment3I want to send to MSISDN 255123...GET /parties/MSISDN/255123...4202 I'll get back to you5Who owns MSISDN 255123...?6It's PayeeFSP7Do you own MSISDN 255123...?8202 I'll get back to you9Check Sanction list status& trigger a refresh of the status10Check account and getcurrency type11Result12Yes, it's Yaro. He can receive in TZS,and I can convert from BWPPUT /parties/MSISDN/255123...PUT /parties{"party": {"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "255123..."},"name": "Yaro","supportedCurrencies":["TZS"]}}13200 Gotcha14Yes, it's Yaro. He can receive in TZSPUT /parties/MSISDN/255123...15200 Gotcha16I will need to perform currency conversion.I need to calculatehow much currency I need.Let me find a currencyconversion provider before I start. \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml new file mode 100644 index 000000000..8bffb60ec --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.plantuml @@ -0,0 +1,57 @@ +@startuml FXAPI_Payer_Receive_SenderConfirmation + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Currency Conversion with Amount Type RECEIVE +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer CBS" as PayerCBS + participant "Payer\nMojaloop\nConnector" as D1 +end box + +'participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +' participant "Backend FX API" as FXPBackend +'end box + +'box "Payee DFSP" #LightBlue +' participant "Payee\nMojaloop\nConnector" as D2 +' participant "Payee CBS" as PayeeCBS +'end box + +'actor "$receiverName" as A2 +autonumber + + +D1->PayerCBS:Here's the quote for the transfer\nIt expires at 2021-08-25T14:17:09.663+01:00 +PayerCBS->A1:Hi, $senderName: I can do the transfer.\nIt'll cost you $totalChargesSourceCurrency $payerCurrency in fees\n$fxpSourceAmount $payerCurrency will be deducted from your account,\nand $receiverName will receive\n$payeeReceiveAmount $payeeCurrency.\nLet me know if you want to go ahead +A1-->PayerCBS:Great! Yes please, go ahead + +PayerCBS-->D1: Payer has accepted the terms please proceed + +@enduml diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg new file mode 100644 index 000000000..5c94fddac --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg @@ -0,0 +1 @@ +Currency Conversion with Amount Type RECEIVEPayer DFSPKeeyaKeeyaPayer CBSPayer CBSPayerMojaloopConnectorPayerMojaloopConnectorSender Confirmation1Here's the quote for the transferIt expires at 2021-08-25T14:17:09.663+01:002Hi, Keeya: I can do the transfer.It'll cost you 55 BWP in fees330 BWP will be deducted from your account,and Yaro will receive50000 TZS.Let me know if you want to go ahead3Great! Yes please, go ahead4Payer has accepted the terms please proceed \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml new file mode 100644 index 000000000..a5b9f2977 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.plantuml @@ -0,0 +1,254 @@ +@startuml FXAPI_Payer_Receive_TransferPhase + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$senderName = "Keeya" +!$receiverName = "Yaro" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "50000" +!$payeeFee = "4000" +!$targetAmount = "54000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "330" +!$fxpTargetAmount = "54000" +!$totalChargesSourceCurrency = "55" + + +title Transfer - Currency Conversion with Amount Type RECEIVE +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue +' participant "Payer CBS" as PayerCBS + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP + participant "Backend FX API" as FXPBackend +end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +end box + participant "Payee CBS" as PayeeCBS + +'actor "$receiverName" as A2 +autonumber + +D1->D1:First, activate the conversion +D1->>S1:Please confirm your\n part of the transfer +note left +**POST /fxTransfers** +{ + "commitRequestId": "77c9d78dc26a4474...", + "determiningTransactionId": "d9ce59d435...", + "requestingFsp": "$payerFSPID", + "respondingFxp": "FDH_FX", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "bdbcf517cfc7..." +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:OK, so this is an FX confirmation. +S1->S1: Does the sender have an account \nin this currency? Yes, it does. +!endif +S1->S1: Liquidity check and reserve on\n Payer DFSP's account +!if ($hideSwitchDetail != true) +note over S1 +Reservations: + +**$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Please confirm the currency \nconversion part of the transfer\n **POST /fxTransfers** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +deactivate S1 +FXP->FXPBackend:Reserve funds for\n FX conversion +FXPBackend->FXP:Success +FXP->>S1:Confirmed. Here's the fulfilment +note right +**PUT /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "188909ceb6cd5c...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00" + "conversionState": "RESERVED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +deactivate FXP +!if ($simplified != true) +S1->S1:Check fulfilment \nmatches and cancel if not. +alt Conversion failed +S1->FXP:Sorry. Conversion failed +note left +**PATCH /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "188909ceb6cd5c35...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Acknowledged +FXP->FXP:Remove any reservations\nor obligations +deactivate FXP + +S1->>D1:Sorry. Conversion failed +note right +**PUT /fxTransfers/77c9d78dc26a.../error** +{ + "errorCode": "9999", + "errorDescription": "Whatever the error was" +} +end note +activate D1 +else Conversion succeeded +S1->D1:Conversion succeeded subject\n to transfer success\n**PUT /fxTransfers/77c9d78dc26a...** + +end +!else +S1->D1:Conversion succeeded subject\n to transfer success\n**PUT /fxTransfers/77c9d78dc26a...** +!endif +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif +deactivate S1 +D1->D1:OK, so that's all right\nNow I can send the transfer itself + +D1->S1:Please do the transfer \n**POST /transfers** +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "c720ae14fc72...", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "transaction": { + "transactionId": "d9ce59d43598...", + "quoteId": "382987a875ce...", + "payee": { + "fspId": "$payeeFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN"}}, + "payer": { + "fspId": "$payerFSPID", + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN"}} + } +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 I'll get back to you +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer? Yes +!endif +S1->S1:Perform liquidity check and\n reserve funds against creditor\n party to dependent transfer +note over S1 +**Reservations:** + +$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency +**FDH_FX has a reservation of $targetAmount $payeeCurrency** +end note + +S1->D2:Please do the transfer\n**POST /transfers** +activate D2 +!if ($simplified != true) +D2-->S1:202 I'll get back to you +!endif +deactivate S1 +D2->D2:Let me check that the terms \nof the dependent transfer are\n the same as the ones I agreed\n to and that the fulfilment\n and condition match +D2->D2:Yes, they do. \nI approve the transfer +D2->PayeeCBS:Please credit $receiverName's account\n with $payeeReceiveAmount $payeeCurrency +D2->S1:Transfer is confirmed, here's the fulfilment +note right +**PUT /transfers/c720ae14fc72...** +{ + "fulfilment": "mhPUT9ZAwdXLfe...", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" +} +end note +activate S1 +!if ($simplified != true) +S1-->D2:200 Gotcha +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer?\nYes, there is. +S1->S1:Is this dependency against the\n debtor party to the transfer?\nYes, it is. +S1->S1:Create an obligation from the\n debtor party to the party named\n in the dependency (the FXP) +S1->S1:Is the transfer denominated in\n the currency of the payee \nreceive amount? Yes, it is. +S1->S1:Create an obligation from the\n party named in the dependency\nto the creditor party for the transfer +!else +S1->S1:Create obligations from the\n payer to the FXP and from \nFXP to the payee +!endif +S1->FXP:The transfer succeeded.\nYou can clear it in your ledgers +note left +**PATCH /fxTransfers/77c9d78dc26a...** +{ + "fulfilment": "2e6870fb4ed...", + "completedTimeStamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Let's just check: does \nthis match the stuff I sent? +FXP->FXP:It does. Great. \nI'll clear the conversion +FXP-->S1:200 Gotcha +deactivate FXP +note over S1 + **Ledger positions:** + $payerFSPID has a debit of $fxpSourceAmount $payerCurrency + FDH_FX has a credit of $fxpSourceAmount $payerCurrency + FDH_FX has a debit of $fxpTargetAmount $payeeCurrency + $payeeFSPID has a credit of $targetAmount $payeeCurrency +end note +S1->D1:Transfer is complete\n**PUT /transfers/c720ae14fc72...** +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif +deactivate S1 +D1->D1:Commit the funds in my ledgers +D1->A1:Transfer was completed successfully +deactivate D1 + +@enduml diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg new file mode 100644 index 000000000..0ca638f9b --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg @@ -0,0 +1 @@ +Transfer - Currency Conversion with Amount Type RECEIVEPayer DFSPFX providerPayee DFSPKeeyaKeeyaPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorBackend FX APIBackend FX APIPayeeMojaloopConnectorPayeeMojaloopConnectorPayee CBSPayee CBS1First, activate the conversion2Please confirm yourpart of the transferPOST /fxTransfers{"commitRequestId": "77c9d78dc26a4474...","determiningTransactionId": "d9ce59d435...","requestingFsp": "PayerFSP","respondingFxp": "FDH_FX","sourceAmount": {"currency": "BWP","amount": "330"},"targetAmount": {"currency": "TZS","amount": "54000"},"condition": "bdbcf517cfc7..."}3202 I'll get back to you4OK, so this is an FX confirmation.5Does the sender have an accountin this currency? Yes, it does.6Liquidity check and reserve onPayer DFSP's accountReservations: PayerFSP has a reservation of 330 BWP7Please confirm the currencyconversion part of the transfer POST /fxTransfers8202 I'll get back to you9Reserve funds forFX conversion10Success11Confirmed. Here's the fulfilmentPUT /fxTransfers/77c9d78dc26a...{"fulfilment": "188909ceb6cd5c...","completedTimeStamp": "2021-08-25T14:17:08.175+01:00""conversionState": "RESERVED"}12200 Gotcha13Check fulfilmentmatches and cancel if not.alt[Conversion failed]14Sorry. Conversion failedPATCH /fxTransfers/77c9d78dc26a...{"fulfilment": "188909ceb6cd5c35...","completedTimeStamp": "2021-08-25T14:17:08.175+01:00","conversionState": "ABORTED"}15Acknowledged16Remove any reservationsor obligations17Sorry. Conversion failedPUT /fxTransfers/77c9d78dc26a.../error{"errorCode": "9999","errorDescription": "Whatever the error was"}[Conversion succeeded]18Conversion succeeded subjectto transfer successPUT /fxTransfers/77c9d78dc26a...19200 Gotcha20OK, so that's all rightNow I can send the transfer itself21Please do the transferPOST /transfersPOST /transfers{"transferId": "c720ae14fc72...","payeeFsp": "PayeeFSP","payerFsp": "PayerFSP","amount": {"currency": "TZS","amount": "54000"},"transaction": {"transactionId": "d9ce59d43598...","quoteId": "382987a875ce...","payee": {"fspId": "PayeeFSP","partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890"}},"payer": {"fspId": "PayerFSP","partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "26787654321"}}}}22202 I'll get back to you23Is there a dependent transfer? Yes24Perform liquidity check andreserve funds against creditorparty to dependent transferReservations: PayerFSP has a reservation of 330 BWPFDH_FX has a reservation of 54000 TZS25Please do the transferPOST /transfers26202 I'll get back to you27Let me check that the termsof the dependent transfer arethe same as the ones I agreedto and that the fulfilmentand condition match28Yes, they do.I approve the transfer29Please credit Yaro's accountwith 50000 TZS30Transfer is confirmed, here's the fulfilmentPUT /transfers/c720ae14fc72...{"fulfilment": "mhPUT9ZAwdXLfe...","completedTimestamp": "2021-08-25T14:17:08.227+01:00","transferState": "COMMITTED"}31200 Gotcha32Is there a dependent transfer?Yes, there is.33Is this dependency against thedebtor party to the transfer?Yes, it is.34Create an obligation from thedebtor party to the party namedin the dependency (the FXP)35Is the transfer denominated inthe currency of the payeereceive amount? Yes, it is.36Create an obligation from theparty named in the dependencyto the creditor party for the transfer37The transfer succeeded.You can clear it in your ledgersPATCH /fxTransfers/77c9d78dc26a...{"fulfilment": "2e6870fb4ed...","completedTimeStamp": "2021-08-25T14:17:08.175+01:00","conversionState": "COMMITTED"}38Let's just check: doesthis match the stuff I sent?39It does. Great.I'll clear the conversion40200 GotchaLedger positions:PayerFSP has a debit of 330 BWPFDH_FX has a credit of 330 BWPFDH_FX has a debit of 54000 TZSPayeeFSP has a credit of 54000 TZS41Transfer is completePUT /transfers/c720ae14fc72...42200 Gotcha43Commit the funds in my ledgers44Transfer was completed successfully \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml new file mode 100644 index 000000000..5b0d81e16 --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.plantuml @@ -0,0 +1,157 @@ +@startuml FXAPI_Payer_SenderConfirmation + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Payer DFSP requests conversion with SEND amount +actor "$senderName" as A1 +participant "Payer CBS" as PayerCBS + +box "Payer DFSP" #LightBlue + participant "Core Connector" as PayerCC + participant "Payer\nMojaloop\nConnector" as D1 +end box + +'participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow + 'participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +' participant "Backend FX API" as FXPBackend +'end box + +'box "Payee DFSP" #LightBlue +' participant "Payee\nMojaloop\nConnector" as D2 +' participant "Core Connector" as PayeeCC +'end box + +'actor "$receiverName" as A2 +autonumber + + +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC:Here's the quote for the transfer\nIt expires at $quotePayeeExpiration + note right + **POST/PUT /transfers** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN" }, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ] }, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**WAITING_FOR_QUOTE_ACCEPTANCE**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": {}, + "fxQuotesResponseSource": "$payeeFSPID", + "quoteId": "$quoteId", + "quoteResponse": { + "body": { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition"},}, + "quoteResponseSource": "$payeeFSPID", + } + end note +!else + D1-->PayerCC:Here's the quote for the transfer\nIt expires at $quotePayeeExpiration + !if ($simplified != true) + note right of PayerCC + { + "quotes": { + "body": { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" + }, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount" + }, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee" + }, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": " + + ", + "condition": "$condition" + }, + "headers": {} + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif +PayerCC->PayerCBS:Here's the quote +PayerCBS->A1:Hi, $senderName: I can do the transfer.\nIt'll cost you $totalChargesSourceCurrency $payerCurrency($totalChargesTargetCurrency $payeeCurrency) in fees\nand $receiverName will receive\n$payeeReceiveAmount $payeeCurrency.\nLet me know if you want to go ahead +A1->PayerCBS:Great! Yes please, go ahead + +PayerCBS->PayerCC: Payer has accepted the terms please proceed + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg new file mode 100644 index 000000000..1f3622fef --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg @@ -0,0 +1 @@ +Payer DFSP requests conversion with SEND amountPayer DFSPJohnJohnPayer CBSPayer CBSCore ConnectorCore ConnectorPayerMojaloopConnectorPayerMojaloopConnector1Here's the quote for the transferIt expires at 2021-08-25T14:17:09.663+01:00POST/PUT /transfersresponse{"transferId": "d9ce59d4359843968630581bb0","homeTransactionId": "string","from": {"displayName": "John","fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321" },"to": {"type": "CONSUMER","idType": "MSISDN","idValue": "2551234567890","displayName": "Yaro","fspId": "PayeeFSP""supportedCurrencies": [ "TZS" ] },"amountType": "SEND","currency": "BWP","amount": "300""currentState": "WAITING_FOR_QUOTE_ACCEPTANCE","getPartiesResponse": {<Same as the previous responses>},"conversionRequestId": "828cc75f1654415e8fcddf76cc","fxQuotesResponse": {<Same as the previous responses>},"fxQuotesResponseSource": "PayeeFSP","quoteId": "382987a875ce4037b500c475e0","quoteResponse": {"body": {"transferAmount": {"currency": "TZS","amount": "48000"},"payeeReceiveAmount": {"currency": "TZS","amount": "44000"},"payeeFspFee": {"currency": "TZS","amount": "4000"},"expiration": "$payeeQuoteExpiration","ilpPacket": "<This is encoded transaction object.>","condition": "HOr22-H3AfTDHrSkP..."},},"quoteResponseSource": "PayeeFSP",}2Here's the quote3Hi, John: I can do the transfer.It'll cost you 55 BWP(10000 TZS) in feesand Yaro will receive44000 TZS.Let me know if you want to go ahead4Great! Yes please, go ahead5Payer has accepted the terms please proceed \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml b/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml new file mode 100644 index 000000000..4cf1da01c --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.plantuml @@ -0,0 +1,466 @@ +@startuml FXAPI_Payer_Transfer + +!$simplified = false +!$shortCutSingleFXP = false +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = false +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Transfer Phase - Mojaloop Connector +actor "$senderName" as A1 + participant "Payer CBS" as PayerCBS +box "Payer DFSP" #LightBlue + participant "Core Connector" as PayerCC + participant "Payer\nMojaloop\nConnector" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP + participant "Backend FX API" as FXPBackend +end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 + participant "Core Connector" as PayeeCC +end box + +actor "$receiverName" as A2 +autonumber + +!if ($advancedCoreConnectorFlow != true) +PayerCC->D1: Proceed with the transfer\nPUT /transfers +note left +{"acceptQuote": true} +end note +!else +PayerCC->D1: Proceed with the transfer\n**POST /fxTransfers** + !if ($simplified != true) + note left + { + "homeTransactionId": "$homeTransactionId", + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" + } + end note + !endif +!endif + +!if ($advancedCoreConnectorFlow != true) +D1->D1:First, activate the conversion +!endif +D1->>S1:Please confirm your part of the transfer +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:OK, so this is an FX confirmation. +S1->S1: Is there any transfer with determiningTransactionId?\nNo, it does'nt. +!endif +S1->S1: Liquidity check and reserve on Payer DFSP's account +!if ($hideSwitchDetail != true) +note over S1 +Reservations: + +**$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Please confirm the currency conversion part of the transfer\n** POST /fxTransfers** +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +deactivate S1 +FXP->FXPBackend:Reserve funds for FX conversion +note left +**POST /fxTransfers** +{ + "homeTransactionId": "$homeTransactionId", + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +FXPBackend-->FXP:Success +note right +{ + "homeTransactionId": "$homeTransactionId", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +FXP->>S1:Confirmed. Here's the fulfilment +note right +**PUT /fxTransfers/$commitRequestId** +{ + "fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +deactivate FXP +!if ($simplified != true) +S1->S1:Check fulfilment matches and cancel if not. +alt Conversion failed +S1->FXP:Sorry. Conversion failed +note right +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Acknowledged +FXP->FXPBackend:Remove any reservations or obligations +note left +**PUT /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +FXPBackend-->FXP:Ok +deactivate FXP + +S1->>D1:Sorry. Conversion failed +note right +**PUT /fxTransfers/$commitRequestId/error** +{ + "errorCode": "9999", + "errorDescription": "Whatever the error was" +} +end note +else Conversion succeeded +S1->D1:Conversion succeeded subject to transfer success\n**PUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc** + +end +!else +S1->D1:Conversion succeeded subject to transfer success\n**PUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc** +!endif +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif +deactivate S1 + +!if ($advancedCoreConnectorFlow != true) + D1->D1:OK, so that's all right\nNow I can send the transfer itself + ' TODO: Need to add PUT /transfers response here +!else + D1-->PayerCC:Confirmed. You can proceed with the transfer. + note right of PayerCC + **PUT /fxTransfers/$commitRequestId** + { + "fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + end note + + PayerCC-->D1:Please do the transfer **POST /simpleTransfers** + !if ($simplified != true) + note right of PayerCC + { + "fspId": "$payeeFSPID", + "transfersPostRequest": { + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount" + }, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" + } + } + end note + !endif +!endif + +D1->S1:Please do the transfer **POST /transfers** +!if ($simplified != true) +note over D1 +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 I'll get back to you +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer? Yes +!endif +S1->S1:Perform liquidity check and reserve funds\nagainst creditor party to dependent transfer +note over S1 +Reservations: + +$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency +**$fxpID has a reservation of $targetAmount $payeeCurrency** +end note + +S1->D2:Please do the transfer\n**POST /transfers** +activate D2 +!if ($simplified != true) +D2-->S1:202 I'll get back to you +!endif +deactivate S1 +D2->D2:Let me check that the terms of the dependent transfer\nare the same as the ones I agreed to\nand that the fulfilment and condition match + +D2->PayeeCC:Please credit $receiverName's account with $payeeReceiveAmount $payeeCurrency +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "$transferId", + "amount": "$targetAmount", + "currency": "$payeeCurrency", + "amountType": "SEND", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "displayName": "$receiverName", + "fspId": "$payeeFSPID", + "idType": "MSISDN", + "idValue": "$payeeMSISDN"}, + "quote": { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayeeExpiration"}, + "transactionType": "TRANSFER", + "ilpPacket": {"data": } +} +end note +!endif + +PayeeCC-->D2:Done +PayeeCC->A2:You have received $payeeReceiveAmount $payeeCurrency +!if ($simplified != true) +note right of D2 +{ + "homeTransactionId": "string", + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + **Note: fulfilment is optional: SDK will create if not found** + "transferState": "COMMITTED" +} +end note +!endif + +D2->>S1:Transfer is confirmed, here's the fulfilment +note over D2 +**PUT /transfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer?\nYes, there is. +S1->S1:Is this dependency against \nthe debtor party to the transfer?\nYes, it is. +S1->S1:Create an obligation from the\n debtor party to the party named in the dependency (the FXP) +S1->S1:Is the transfer denominated in\n the currency of the payee receive amount?\nYes, it is. +S1->S1:Create an obligation from the \nparty named in the dependency\nto the creditor party for the transfer +!else +S1->S1:Create obligations from the payer to the FXP and from FXP to the payee +!endif +S1->>FXP:The transfer succeeded.\nYou can clear it in your ledgers +note over S1 +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Let's just check: does this match the stuff I sent? +FXP->FXP:It does. Great. I'll clear the conversion +FXP-->>S1:200 Gotcha +deactivate FXP +note over S1 + Ledger positions: + $payerFSPID has a debit of $fxpSourceAmount $payerCurrency + $fxpID has a credit of $fxpSourceAmount $payerCurrency + $fxpID has a debit of $fxpTargetAmount $payeeCurrency + $payeeFSPID has a credit of $targetAmount $payeeCurrency +end note +S1->>D1:Transfer is complete\n**PUT /transfers/$commitRequestId** +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif +deactivate S1 +!if ($advancedCoreConnectorFlow != true) + D1-->PayerCC:Transfer was completed successfully + note right of PayerCC + **POST/PUT /transfers/** response + { + "transferId": "$transferId", + "homeTransactionId": "$homeTransactionId", + "from": { + "displayName": "$senderName", + "fspId": "$payerFSPID", + "idType": "MSISDN", + "idValue": "$payerMSISDN"}, + "to": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "$payeeMSISDN", + "displayName": "$receiverName", + "fspId": "$payeeFSPID" + "supportedCurrencies": [ "$payeeCurrency" ]}, + "amountType": "SEND", + "currency": "$payerCurrency", + "amount": "$payerSendAmount" + "currentState": "**COMPLETED**", + "getPartiesResponse": {}, + "conversionRequestId": "$conversionRequestId", + "fxQuotesResponse": {}, + "fxQuotesResponseSource": "$payeeFSPID", + "quoteId": "$quoteId", + "quoteResponse": {}, + "quoteResponseSource": "$payeeFSPID", + "fulfil": { + "body": { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED"},}, + } + end note +!else + D1-->PayerCC:Transfer was completed successfully + !if ($simplified != true) + note right of PayerCC + { + "transfer": { + "body": { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "transferState": "COMMITTED" + }, + "headers": {} + }, + "currentState": "COMPLETED" + } + end note + !endif +!endif + +PayerCC->PayerCBS:Transfer was completed successfully +PayerCBS->PayerCBS:Commit the funds in my ledgers +PayerCBS->A1:Your transfer is successful +deactivate D1 +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg b/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg new file mode 100644 index 000000000..1cb78ebdb --- /dev/null +++ b/docs/product/features/CurrencyConversion/FXAPI_Payer_Transfer.svg @@ -0,0 +1 @@ +Transfer Phase - Mojaloop ConnectorPayer DFSPFX providerPayee DFSPJohnJohnPayer CBSPayer CBSCore ConnectorCore ConnectorPayerMojaloopConnectorPayerMojaloopConnectorMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorBackend FX APIBackend FX APIPayeeMojaloopConnectorPayeeMojaloopConnectorCore ConnectorCore ConnectorYaroYaro1Proceed with the transferPUT /transfers{"acceptQuote": true}2First, activate the conversion3Please confirm your part of the transferPOST /fxTransfers{"commitRequestId": "77c9d78dc26a44748b3c99b96a","determiningTransferId": "d9ce59d4359843968630581bb0","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"condition": "GRzLaTP7DJ9t4P-a_B..."}4202 I'll get back to you5OK, so this is an FX confirmation.6Is there any transfer with determiningTransactionId?No, it does'nt.7Liquidity check and reserve on Payer DFSP's accountReservations: PayerFSP has a reservation of 300 BWP8Please confirm the currency conversion part of the transferPOST /fxTransfers**9202 I'll get back to you10Reserve funds for FX conversionPOST /fxTransfers{"homeTransactionId": "string","commitRequestId": "77c9d78dc26a44748b3c99b96a","determiningTransferId": "d9ce59d4359843968630581bb0","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"condition": "GRzLaTP7DJ9t4P-a_B..."}11Success{"homeTransactionId": "string","completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "RESERVED"}12Confirmed. Here's the fulfilmentPUT /fxTransfers/77c9d78dc26a44748b3c99b96a{"fulfilment": "188909ceb6cd5c35d5c6b394f0a9e5a0571199c332fbd013dc1e6b8a2d5fff42","completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "RESERVED"}13200 Gotcha14Check fulfilment matches and cancel if not.alt[Conversion failed]15Sorry. Conversion failedPATCH /fxTransfers/77c9d78dc26a44748b3c99b96a{"completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "ABORTED"}16Acknowledged17Remove any reservations or obligationsPUT /fxTransfers/77c9d78dc26a44748b3c99b96a{"completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "ABORTED"}18Ok19Sorry. Conversion failedPUT /fxTransfers/77c9d78dc26a44748b3c99b96a/error{"errorCode": "9999","errorDescription": "Whatever the error was"}[Conversion succeeded]20Conversion succeeded subject to transfer successPUT /fxTransfers/77c9d78d-c26a-4474-8b3c-99b96a814bfc21200 Gotcha22OK, so that's all rightNow I can send the transfer itself23Please do the transferPOST /transfersPOST /transfers{"transferId": "d9ce59d4359843968630581bb0","payeeFsp": "PayeeFSP","payerFsp": "PayerFSP","amount": {"currency": "TZS","amount": "48000"},"ilpPacket": "<Encoded transaction object>","condition": "HOr22-H3AfTDHrSkP...","expiration": "2016-05-24T08:38:08.699-04:00"}24202 I'll get back to you25Is there a dependent transfer? Yes26Perform liquidity check and reserve fundsagainst creditor party to dependent transferReservations: PayerFSP has a reservation of 300 BWPFDH_FX has a reservation of 48000 TZS27Please do the transferPOST /transfers28202 I'll get back to you29Let me check that the terms of the dependent transferare the same as the ones I agreed toand that the fulfilment and condition match30Please credit Yaro's account with 44000 TZSPOST /transfers{"transferId": "d9ce59d4359843968630581bb0","amount": "48000","currency": "TZS","amountType": "SEND","from": {"displayName": "John","fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321"},"to": {"displayName": "Yaro","fspId": "PayeeFSP","idType": "MSISDN","idValue": "2551234567890"},"quote": {"quoteId": "382987a875ce4037b500c475e0","transactionId": "d9ce59d4359843968630581bb0","payeeFspFeeAmount": "4000","payeeFspFeeAmountCurrency": "TZS","payeeReceiveAmount": "44000","payeeReceiveAmountCurrency": "TZS","transferAmount": "48000","transferAmountCurrency": "TZS""expiration": "2021-08-25T14:17:09.663+01:00"},"transactionType": "TRANSFER","ilpPacket": {"data": <decoded ilpPacket>}}31Done32You have received 44000 TZS{"homeTransactionId": "string","completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s",    Note: fulfilment is optional: SDK will create if not found"transferState": "COMMITTED"}33Transfer is confirmed, here's the fulfilmentPUT /transfers/77c9d78dc26a44748b3c99b96a{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s","transferState": "COMMITTED"}34200 Gotcha35Is there a dependent transfer?Yes, there is.36Is this dependency againstthe debtor party to the transfer?Yes, it is.37Create an obligation from thedebtor party to the partynamed in the dependency (the FXP)38Is the transfer denominated inthe currency of the payee receive amount?Yes, it is.39Create an obligation from theparty named in the dependencyto the creditor party for the transfer40The transfer succeeded.You can clear it in your ledgersPATCH /fxTransfers/77c9d78dc26a44748b3c99b96a{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s","transferState": "COMMITTED"}41Let's just check: does this match the stuff I sent?42It does. Great. I'll clear the conversion43200 GotchaLedger positions:PayerFSP has a debit of 300 BWPFDH_FX has a credit of 300 BWPFDH_FX has a debit of 48000 TZSPayeeFSP has a credit of 48000 TZS44Transfer is completePUT /transfers/77c9d78dc26a44748b3c99b96a45200 Gotcha46Transfer was completed successfullyPOST/PUT /transfers/response{"transferId": "d9ce59d4359843968630581bb0","homeTransactionId": "string","from": {"displayName": "John","fspId": "PayerFSP","idType": "MSISDN","idValue": "26787654321"},"to": {"type": "CONSUMER","idType": "MSISDN","idValue": "2551234567890","displayName": "Yaro","fspId": "PayeeFSP""supportedCurrencies": [ "TZS" ]},"amountType": "SEND","currency": "BWP","amount": "300""currentState": "COMPLETED","getPartiesResponse": {<Same as the previous responses>},"conversionRequestId": "828cc75f1654415e8fcddf76cc","fxQuotesResponse": {<Same as the previous responses>},"fxQuotesResponseSource": "PayeeFSP","quoteId": "382987a875ce4037b500c475e0","quoteResponse": {<Same as the previous responses>},"quoteResponseSource": "PayeeFSP","fulfil": {"body": {"completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s","transferState": "COMMITTED"},},}47Transfer was completed successfully48Commit the funds in my ledgers49Your transfer is successful \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml b/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml new file mode 100644 index 000000000..c50bf7548 --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.plantuml @@ -0,0 +1,182 @@ +@startuml PAYER_SEND_Agreement + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Payer DFSP requests quote from Payee DFSP +'actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +'end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +end box + +'actor "$receiverName" as A2 +autonumber + + +D1->>S1:Please quote for a transfer which sends $fxpTargetAmount $payeeCurrency.\n**POST /quotes** +deactivate D1 +!if ($simplified != true) +note left +POST /quotes + + { + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID" + }, + "name": "$receiverName", + "personalInfo": { + "complexName": { + "firstName": "$receiverFirstName", + "middleName": "$receiverMiddleName", + "lastName": "$receiverLastName" + }, + "dateOfBirth": "$receiverDOB", + "kycInformation": "" + }, + "supportedCurrencies": [ "$payeeCurrency" ] + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payerMSISDN", + "fspId": "$payerFSPID" + }, + "name": "$senderName", + "personalInfo": { + "complexName": { + "firstName": "$senderFirstName", + "middleName": "$senderMiddleName", + "lastName": "$senderLastName" + }, + "dateOfBirth": "$senderDOB" + } + }, + "amountType": "SEND", + "amount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "converter": "PAYER", + "expiration": "$quotePayerExpiration" + } +end note +!endif +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif + +S1->>D2:**POST /quotes** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +!endif + +D2->D2:OK, so I will charge $payeeFee $payeeCurrency for this.\nNow I create terms of the transfer +!if ($simplified != true) +note right of D2 +{ + "quoteId": "$quoteId", + "transactionId": "$transactionId", + "payeeFspFeeAmount": "$payeeFee", + "payeeFspFeeAmountCurrency": "$payeeCurrency", + "payeeReceiveAmount": "$payeeReceiveAmount", + "payeeReceiveAmountCurrency": "$payeeCurrency", + "transferAmount": "$targetAmount", + "transferAmountCurrency": "$payeeCurrency" + "expiration": "$quotePayerExpiration" +} +end note +!endif +D2->D2:Now I will sign the transaction object +D2->>S1:Here's the signed quote +note right + **put /quotes/$quoteId** + { + "transferAmount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "payeeReceiveAmount": { + "currency": "$payeeCurrency", + "amount": "$payeeReceiveAmount"}, + "payeeFspFee": { + "currency": "$payeeCurrency", + "amount": "$payeeFee"}, + "expiration": "$payeeQuoteExpiration", + "ilpPacket": "", + "condition": "$condition" + } +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +S1->>D1:Here's the signed quote\n**PUT /quotes/$quoteId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif +D1->D1:OK, I can see that there are going to be $payeeFee $payeeCurrency in charges. + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg b/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg new file mode 100644 index 000000000..02cc3a5b4 --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Agreement.svg @@ -0,0 +1 @@ +Payer DFSP requests quote from Payee DFSPPayer DFSPPayee DFSPPayer DFSPPayer DFSPMojaloop SwitchMojaloop SwitchPayeeMojaloopConnectorPayeeMojaloopConnector1Please quote for a transfer which sends 48000 TZS.POST /quotes2POST /quotes3OK, so I will charge 4000 TZS for this.Now I create terms of the transfer4Now I will sign the transaction object5Here's the signed quoteput /quotes/382987a875ce4037b500c475e0{"transferAmount": {"currency": "TZS","amount": "48000"},"payeeReceiveAmount": {"currency": "TZS","amount": "44000"},"payeeFspFee": {"currency": "TZS","amount": "4000"},"expiration": "$payeeQuoteExpiration","ilpPacket": "<This is encoded transaction object.>","condition": "HOr22-H3AfTDHrSkP..."}6Here's the signed quotePUT /quotes/382987a875ce4037b500c475e07OK, I can see that there are going to be 4000 TZS in charges. \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml b/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml new file mode 100644 index 000000000..2ebc792ac --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.plantuml @@ -0,0 +1,78 @@ +@startuml PAYER_SEND_Confirmation +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Payer DFSP presents the terms to the Payer +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +'participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +'end box + +'box "Payee DFSP" #LightBlue +' participant "Payee\nMojaloop\nConnector" as D2 +'end box + +'actor "$receiverName" as A2 +autonumber + +D1->A1: Present the terms of the transfer to the Payer +note right +Hi, $senderName: +I can do the transfer. +It'll cost you $totalChargesSourceCurrency $payerCurrency($totalChargesTargetCurrency $payeeCurrency) in fees +and $receiverName will receive $payeeReceiveAmount $payeeCurrency. +**Let me know if you want to go ahead?** +end note +A1->D1: Great! Yes please, go ahead + +D1->D1: Payer has accepted the terms please proceed +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg b/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg new file mode 100644 index 000000000..b9161ef46 --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Confirmation.svg @@ -0,0 +1 @@ +Payer DFSP presents the terms to the PayerPayer DFSPJohnJohnPayer DFSPPayer DFSP1Present the terms of the transfer to the PayerHi, John:I can do the transfer.It'll cost you 55 BWP(10000 TZS) in feesand Yaro will receive 44000 TZS.Let me know if you want to go ahead?2Great! Yes please, go ahead3Payer has accepted the terms please proceed \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml b/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml new file mode 100644 index 000000000..14b49b3e9 --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.plantuml @@ -0,0 +1,193 @@ +@startuml PAYER_SEND_CurrencyConversion + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Payer DFSP requests conversion with SEND amount +' actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP +end box + +'box "Payee DFSP" #LightBlue +' participant "Payee\nMojaloop\nConnector" as D2 +'end box + +'actor "$receiverName" as A2 +autonumber + + +D1->D1:Hmmm. I can only send in $payerCurrency.\nI need to get some currency conversion +D1->D1: Look up the local cached FXPs\n that can provide the conversion +D1->D1:I'll ask FDH FX to perform my conversion + + +D1->>S1:Here is the initial version of the transfer.\nPlease quote me for the currency conversion. + +note left + **post /fxQuotes** + { + "conversionRequestId": "$conversionRequestId", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$payerSendAmount"}, + "targetAmount": { + "currency": "$payeeCurrency"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + } + } +end note + +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +S1->>FXP:Here is the initial version of the transfer.\nPlease quote me for the currency conversion.\n**POST /fxQuote** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif + +note over FXP + I will add a $fxpChargesSource $payerCurrency fee for undertaking the conversion. + Now I'll set an expiry time, sign the quotation object, +end note +!if ($simplified != true) +note right of FXP + { + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +!endif + +note over FXP + Now I'll sign the quotation object, + create an ILP prepare packet and return it in the intermediary object. + + **NOTE:** the ILP prepare packet contains the following items, all encoded: + - The amount being sent (i.e. in the source currency) + - An expiry time + - The condition + - The name of the FXP + - The content of the conversion terms +end note + + +FXP->>S1:Here's the signed conversion object +note right + **PUT /fxQuotes/$conversionRequestId** + { + "condition": "$fxCondition", + "conversionTerms": { + "conversionId": "$conversionId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "expiration": "2021-08-25T14:17:09.663+01:00" + "charges": [ + { + "chargeType": "string", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpChargesSource"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpChargesTarget"} + }]} + } +end note +deactivate FXP +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +S1->>D1:Here's the signed conversion object\n**PUT /fxQuotes/$conversionRequestId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:Gotcha +!endif +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg b/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg new file mode 100644 index 000000000..8078364ed --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_CurrencyConversion.svg @@ -0,0 +1 @@ +Payer DFSP requests conversion with SEND amountPayer DFSPFX providerPayer DFSPPayer DFSPMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnector1Hmmm. I can only send in BWP.I need to get some currency conversion2Look up the local cached FXPsthat can provide the conversion3I'll ask FDH FX to perform my conversion4Here is the initial version of the transfer.Please quote me for the currency conversion.post /fxQuotes{"conversionRequestId": "828cc75f1654415e8fcddf76cc","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS"},"expiration": "2021-08-25T14:17:09.663+01:00"}}5Here is the initial version of the transfer.Please quote me for the currency conversion.POST /fxQuoteI will add a 33 BWP fee for undertaking the conversion.Now I'll set an expiry time, sign the quotation object,Now I'll sign the quotation object,create an ILP prepare packet and return it in the intermediary object. NOTE:the ILP prepare packet contains the following items, all encoded:- The amount being sent (i.e. in the source currency)- An expiry time- The condition- The name of the FXP- The content of the conversion terms6Here's the signed conversion objectPUT /fxQuotes/828cc75f1654415e8fcddf76cc{"condition": "GRzLaTP7DJ9t4P-a_B...","conversionTerms": {"conversionId": "581f68efb54f416f9161ac34e8","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"expiration": "2021-08-25T14:17:09.663+01:00""charges": [{"chargeType": "string","sourceAmount": {"currency": "BWP","amount": "33"},"targetAmount": {"currency": "TZS","amount": "6000"}}]}}7Here's the signed conversion objectPUT /fxQuotes/828cc75f1654415e8fcddf76cc \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml b/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml new file mode 100644 index 000000000..bd3cb95f5 --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.plantuml @@ -0,0 +1,259 @@ +@startuml PAYER_SEND_Transfer + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f165441..." +!$conversionId = "581f68efb5..." +!$homeTransactionId = "string" +!$quoteId = "382987a875ce..." +!$transactionId = "d9ce59d4359843..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26..." +!$determiningTransferId = "d9ce59d4359843..." +!$transferId = "d9ce59d4359843..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + +title Remittance Transfer using Mojaloop FX APIs POC\nPayer DFSP requests conversion with SEND amount +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP +end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +end box + +actor "$receiverName" as A2 +autonumber + +D1->>S1:Please confirm your part\n of the transfer +deactivate D1 +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +!if ($hideSwitchDetail != true) +S1->S1:OK, so this is an FX confirmation. +S1->S1: Is there any transfer with \ndeterminingTransactionId?\nNo, it does'nt. +!endif +S1->S1: Liquidity check and reserve\n on Payer DFSP's account +!if ($hideSwitchDetail != true) +note over S1 +**Reservations:** + +**$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Please confirm the currency \nconversion part of the transfer\n **POST /fxTransfers** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +FXP->FXP:Reserve funds for FX conversion +FXP->>S1:Confirmed. Here's the fulfilment +note right +**PUT /fxTransfers/$commitRequestId** +{ + "fulfilment": "188909ceb6cd5c35d..", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" +} +end note +deactivate FXP +activate S1 +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +!if ($simplified != true) +S1->S1:Check fulfilment matches and cancel if not. +alt Conversion failed +S1->FXP:Sorry. Conversion failed +note left +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" +} +end note +activate FXP +FXP-->S1:Acknowledged +FXP->FXP:Remove any reservations or obligations +deactivate FXP + +S1->>D1:Sorry. Conversion failed +note right +**PUT /fxTransfers/$commitRequestId/error** +{ + "errorCode": "9999", + "errorDescription": "Whatever the error was" +} +end note +else Conversion succeeded +S1->D1:Conversion succeeded subject \nto transfer success\n**PUT /fxTransfers/$commitRequestId** + +end +!else +S1->D1:Conversion succeeded subject \nto transfer success\n**PUT /fxTransfers/$commitRequestId** +!endif +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif + +D1->D1:OK, so that's all right\nNow I can send the transfer itself + +D1->S1:Please do the transfer\n **POST /transfers** +!if ($simplified != true) +note left +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->D1:202 I'll get back to you +!endif +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer? \nYes +!endif +S1->S1:Perform liquidity check and \nreserve funds against creditor\n party to dependent transfer +note over S1 +**Reservations:** + +$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency +**$fxpID has a reservation of $targetAmount $payeeCurrency** +end note + +S1->D2:Please do the transfer\n**POST /transfers** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->S1:202 I'll get back to you +!endif +D2->D2:Let me check that the terms\n of the dependent transfer\nare the same as the ones I \nagreed to and that the \nfulfilment and condition match + +D2->A2: Hi $receiverName's, you got inbound \ntransfer $payeeReceiveAmount $payeeCurrency + +D2->>S1:Transfer is confirmed, here's the fulfilment +note right +**PUT /transfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08...", + "fulfilment": "mhPUT9ZAwd-BXLfeSd...", + "transferState": "COMMITTED" +} +end note +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer?\nYes, there is. +S1->S1:Is this dependency against the\n debtor party to the transfer?\nYes, it is. +S1->S1:Create an obligation from the\n debtor party to the party named \nin the dependency (the FXP) +S1->S1:Is the transfer denominated in\n the currency of the payee \nreceive amount? Yes, it is. +S1->S1:Create an obligation from the\n party named in the\n dependency to the creditor \nparty for the transfer +!else +S1->S1:Create obligations from the payer to the FXP and from FXP to the payee +!endif +note over S1 + **Ledger positions:** + $payerFSPID has a debit of $fxpSourceAmount $payerCurrency + $fxpID has a credit of $fxpSourceAmount $payerCurrency + $fxpID has a debit of $fxpTargetAmount $payeeCurrency + $payeeFSPID has a credit of $targetAmount $payeeCurrency +end note +S1->>FXP:The transfer succeeded.\nYou can clear it in your ledgers +note left +**PATCH /fxTransfers/$commitRequestId** +{ + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "COMMITTED" +} +end note +activate FXP +FXP->FXP:Let's just check: does this match the stuff I sent? +FXP->FXP:It does. Great. I'll clear the conversion +FXP-->>S1:200 Gotcha +deactivate FXP +S1->>D1:Transfer is complete\n**PUT /transfers/$commitRequestId** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif + +D1->A1:Your transfer is successful +deactivate D1 + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg b/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg new file mode 100644 index 000000000..e0b71bc2d --- /dev/null +++ b/docs/product/features/CurrencyConversion/PAYER_SEND_Transfer.svg @@ -0,0 +1 @@ +Remittance Transfer using Mojaloop FX APIs POCPayer DFSP requests conversion with SEND amountPayer DFSPFX providerPayee DFSPJohnJohnPayer DFSPPayer DFSPMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorPayeeMojaloopConnectorPayeeMojaloopConnectorYaroYaro1Please confirm your partof the transferPOST /fxTransfers{"commitRequestId": "77c9d78dc26...","determiningTransferId": "d9ce59d4359843...","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"condition": "GRzLaTP7DJ9t4P-a_B..."}2OK, so this is an FX confirmation.3Is there any transfer withdeterminingTransactionId?No, it does'nt.4Liquidity check and reserveon Payer DFSP's accountReservations: PayerFSP has a reservation of 300 BWP5Please confirm the currencyconversion part of the transfer POST /fxTransfers6Reserve funds for FX conversion7Confirmed. Here's the fulfilmentPUT /fxTransfers/77c9d78dc26...{"fulfilment": "188909ceb6cd5c35d..","completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "RESERVED"}8Conversion succeeded subjectto transfer successPUT /fxTransfers/77c9d78dc26...9OK, so that's all rightNow I can send the transfer itself10Please do the transfer POST /transfers11Is there a dependent transfer?Yes12Perform liquidity check andreserve funds against creditorparty to dependent transferReservations: PayerFSP has a reservation of 300 BWPFDH_FX has a reservation of 48000 TZS13Please do the transferPOST /transfers14Let me check that the termsof the dependent transferare the same as the ones Iagreed to and that thefulfilment and condition match15Hi Yaro's, you got inboundtransfer 44000 TZS16Transfer is confirmed, here's the fulfilmentPUT /transfers/77c9d78dc26...{"completedTimestamp": "2021-08-25T14:17:08...","fulfilment": "mhPUT9ZAwd-BXLfeSd...","transferState": "COMMITTED"}17Is there a dependent transfer?Yes, there is.18Is this dependency against thedebtor party to the transfer?Yes, it is.19Create an obligation from thedebtor party to the party namedin the dependency (the FXP)20Is the transfer denominated inthe currency of the payeereceive amount? Yes, it is.21Create an obligation from theparty named in thedependency to the creditorparty for the transferLedger positions:PayerFSP has a debit of 300 BWPFDH_FX has a credit of 300 BWPFDH_FX has a debit of 48000 TZSPayeeFSP has a credit of 48000 TZS22The transfer succeeded.You can clear it in your ledgersPATCH /fxTransfers/77c9d78dc26...{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","transferState": "COMMITTED"}23Let's just check: does this match the stuff I sent?24It does. Great. I'll clear the conversion25200 Gotcha26Transfer is completePUT /transfers/77c9d78dc26...27Your transfer is successful \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml b/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml new file mode 100644 index 000000000..d1fe241fd --- /dev/null +++ b/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.plantuml @@ -0,0 +1,337 @@ +@startuml Payer_SEND_ABORT_TransferPhase + +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f16..." +!$conversionId = "581f68efb..." +!$homeTransactionId = "string" +!$quoteId = "382987a875..." +!$transactionId = "d9ce59d435..." +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc2..." +!$determiningTransferId = "d9ce59d43..." +!$transferId = "d9ce59d435..." +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Currency Conversion Transfer Phase ABORT flows +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +box "FX provider" + participant "FXP\nConnector" as FXP +end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +end box + +actor "$receiverName" as A2 +autonumber + +D1->>S1:Please confirm your part of the transfer +note left +**POST /fxTransfers** +{ + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$payerFSPID", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount"}, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount"}, + "condition": "$fxCondition" +} +end note +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +deactivate D2 +!if ($hideSwitchDetail != true) +S1->S1:OK, so this is an FX confirmation. +S1->S1: Is there any transfer with determiningTransactionId?\nNo, it does'nt. +!endif +S1->S1: Liquidity check and reserve on Payer DFSP's account +!if ($hideSwitchDetail != true) +note over S1 +Reservations: + +**$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency** +end note +!endif +S1->>FXP:Please confirm the currency\n conversion part of the transfer\n **POST /fxTransfers** +deactivate S1 +activate FXP +!if ($simplified != true) +FXP-->>S1:202 I'll get back to you +!endif +alt conversion failed + FXP->>S1:Failed. + note right + **PUT /fxTransfers/$commitRequestId**/error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "error message"} + } + ( **or** ) + **PUT /fxTransfers/$commitRequestId** + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + end note +else conversion success + FXP->FXP:Reserve funds for FX conversion + FXP->>S1:Confirmed. Here's the fulfilment + note right + **PUT /fxTransfers/$commitRequestId** + { + "fulfilment": "188909ceb6cd5...", + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "RESERVED" + } + end note + deactivate FXP + S1->S1:Check fulfilment matches and cancel if not. + alt Conversion failed + S1->FXP:Sorry. Conversion failed + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.175+01:00", + "conversionState": "ABORTED" + } + end note + activate FXP + FXP-->S1:Acknowledged + FXP->FXP:Remove any reservations or obligations + deactivate FXP + end +end +!if ($simplified != true) +S1-->>FXP:200 Gotcha +!endif +deactivate FXP + +alt Conversion failed + S1->S1: Abort the fxTransfer. Revert \nthe position changes involved in this\n fxTransfer. + note over S1 + **Note:** + Incase of payee side conversion, there will be dependent transfer. + But do not cancel that transfer as DFSP can try currency conversion with + another FXP. But make sure that while processing the fulfilment of the original + transfer, it shouldn't pickup this fxTransfer as the dependent transfer. + (Maybe by removing the entry from watchlist) + end note + S1->>D1:Sorry. Conversion failed + note right + **PUT /fxTransfers/$commitRequestId/error** + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "error message"} + } + ( **or** ) + **PUT /fxTransfers/$commitRequestId** + { + "conversionState": "ABORTED", + "extensionList": {"extension": [{"key": "reason","value": "some reason"}]} + } + end note +else Conversion succeeded + S1->D1:Conversion succeeded subject to\n transfer success\n**PUT /fxTransfers/77c9d78dc26a...** + activate D1 +end + +!if ($simplified != true) +D1-->S1:200 Gotcha +!endif +D1->D1:OK, so that's all right\nNow I can send the transfer itself + +D1->S1:Please do the transfer\n **POST /transfers** +deactivate D1 +!if ($simplified != true) +note over D1 +**POST /transfers** +{ + "transferId": "$transferId", + "payeeFsp": "$payeeFSPID", + "payerFsp": "$payerFSPID", + "amount": { + "currency": "$payeeCurrency", + "amount": "$targetAmount"}, + "ilpPacket": "", + "condition": "$condition", + "expiration": "2016-05-24T08:38:08.699-04:00" +} +end note +!endif +activate S1 +!if ($simplified != true) +S1-->D1:202 I'll get back to you +!endif +deactivate D1 +!if ($hideSwitchDetail != true) +S1->S1:Is there a dependent transfer? Yes +!endif +S1->S1:Perform liquidity check and reserve funds\nagainst creditor party to dependent transfer +note over S1 +Reservations: + +$payerFSPID has a reservation of $fxpSourceAmount $payerCurrency +**$fxpID has a reservation of $targetAmount $payeeCurrency** +end note + +S1->D2:Please do the transfer\n**POST /transfers** +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->S1:202 I'll get back to you +!endif +D2->D2:Let me check that the terms \nof the dependent transfer are \nthe same as the ones I agreed\n to and that the fulfilment and \ncondition match + +D2->A2: Hi $receiverName's, you got inbound \ntransfer $payeeReceiveAmount $payeeCurrency +deactivate D2 + +alt transfer failed + D2->>S1:Transfer is rejected + note right + **PUT /transfers/$commitRequestId**/error + { + "errorInformation": { + "errorCode": "5100", + "errorDescription": "error message"} + } + ( **or** ) + { + "transferState": "ABORETED" + } + end note + + activate S1 + !if ($simplified != true) + S1-->>D2:200 Gotcha + !endif + + S1->S1: Revert the position changes \ninvolved in this transfer + S1->S1: If there are dependency fxTransfers,\n abort the fxTransfers as well and \nrevert the position changes involved \nin those fxTransfers + + S1->>FXP: The linked transfer is failed.\nRemove any reservations or obligations + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "transferState": "ABORTED" + } + end note + activate FXP + FXP->FXP: Oops! + FXP-->>S1:200 Gotcha + deactivate FXP + S1->>D1:Transfer is complete\n**PUT /transfers/$commitRequestId/error** + activate D1 + !if ($simplified != true) + D1-->S1:200 Gotcha + !endif + deactivate S1 + D1->A1:Your transfer is failed + deactivate D1 +else transfer success + D2->>S1:Transfer is confirmed, here's the fulfilment + note right + **PUT /transfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + end note + activate S1 + !if ($simplified != true) + S1-->>D2:200 Gotcha + !endif + + !if ($hideSwitchDetail != true) + S1->S1:Is there a dependent transfer?\nYes, there is. + S1->S1:Is this dependency against the\n debtor party to the transfer?\nYes, it is. + S1->S1:Create an obligation from the \ndebtor party to the party named \nin the dependency (the FXP) + S1->S1:Is the transfer denominated in \nthe currency of the payee receive\n amount?\nYes, it is. + S1->S1:Create an obligation from the \nparty named in the dependency\nto the creditor party for the transfer + !else + S1->S1:Create obligations from the payer to the FXP and from FXP to the payee + !endif + S1->>FXP:The transfer succeeded.\nYou can clear it in your ledgers + note left + **PATCH /fxTransfers/$commitRequestId** + { + "completedTimestamp": "2021-08-25T14:17:08.227+01:00", + "fulfilment": "mhPUT9ZAwd...", + "transferState": "COMMITTED" + } + end note + activate FXP + FXP->FXP:Let's just check: does this match the stuff I sent? + FXP->FXP:It does. Great. I'll clear the conversion + FXP-->>S1:200 Gotcha + deactivate FXP + note over S1 + **Ledger positions:** + $payerFSPID has a debit of $fxpSourceAmount $payerCurrency + $fxpID has a credit of $fxpSourceAmount $payerCurrency + $fxpID has a debit of $fxpTargetAmount $payeeCurrency + $payeeFSPID has a credit of $targetAmount $payeeCurrency + end note + S1->>D1:Transfer is complete\n**PUT /transfers/$commitRequestId** + activate D1 + !if ($simplified != true) + D1-->S1:200 Gotcha + !endif + deactivate S1 + + D1->A1:Your transfer is successful + deactivate D1 +end + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg b/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg new file mode 100644 index 000000000..5cc482459 --- /dev/null +++ b/docs/product/features/CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg @@ -0,0 +1 @@ +Remittance Transfer using Mojaloop FX APIs POCPayer DFSP requests conversion with SEND amountPayer DFSPFX providerPayee DFSPJohnJohnPayer DFSPPayer DFSPMojaloop SwitchMojaloop SwitchFXPConnectorFXPConnectorPayeeMojaloopConnectorPayeeMojaloopConnectorYaroYaro1Please confirm your part of the transferPOST /fxTransfers{"commitRequestId": "77c9d78dc2...","determiningTransferId": "d9ce59d43...","initiatingFsp": "PayerFSP","counterPartyFsp": "FDH_FX","amountType": "SEND","sourceAmount": {"currency": "BWP","amount": "300"},"targetAmount": {"currency": "TZS","amount": "48000"},"condition": "GRzLaTP7DJ9t4P-a_B..."}2OK, so this is an FX confirmation.3Is there any transfer with determiningTransactionId?No, it does'nt.4Liquidity check and reserve on Payer DFSP's accountReservations: PayerFSP has a reservation of 300 BWP5Please confirm the currencyconversion part of the transfer POST /fxTransfersalt[conversion failed]6Failed.PUT /fxTransfers/77c9d78dc2.../error{"errorInformation": {"errorCode": "5100","errorDescription": "error message"}}(or)PUT /fxTransfers/77c9d78dc2...{"conversionState": "ABORTED","extensionList": {"extension": [{"key": "reason","value": "some reason"}]}}[conversion success]7Reserve funds for FX conversion8Confirmed. Here's the fulfilmentPUT /fxTransfers/77c9d78dc2...{"fulfilment": "188909ceb6cd5...","completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "RESERVED"}9Check fulfilment matches and cancel if not.alt[Conversion failed]10Sorry. Conversion failedPATCH /fxTransfers/77c9d78dc2...{"completedTimestamp": "2021-08-25T14:17:08.175+01:00","conversionState": "ABORTED"}11Acknowledged12Remove any reservations or obligationsalt[Conversion failed]13Abort the fxTransfer. Revertthe position changes involved in thisfxTransfer.Note:Incase of payee side conversion, there will be dependent transfer.But do not cancel that transfer as DFSP can try currency conversion withanother FXP. But make sure that while processing the fulfilment of the originaltransfer, it shouldn't pickup this fxTransfer as the dependent transfer.(Maybe by removing the entry from watchlist)14Sorry. Conversion failedPUT /fxTransfers/77c9d78dc2.../error{"errorInformation": {"errorCode": "5100","errorDescription": "error message"}}(or)PUT /fxTransfers/77c9d78dc2...{"conversionState": "ABORTED","extensionList": {"extension": [{"key": "reason","value": "some reason"}]}}[Conversion succeeded]15Conversion succeeded subject totransfer successPUT /fxTransfers/77c9d78dc26a...16OK, so that's all rightNow I can send the transfer itself17Please do the transfer POST /transfers18Is there a dependent transfer? Yes19Perform liquidity check and reserve fundsagainst creditor party to dependent transferReservations: PayerFSP has a reservation of 300 BWPFDH_FX has a reservation of 48000 TZS20Please do the transferPOST /transfers21Let me check that the termsof the dependent transfer arethe same as the ones I agreedto and that the fulfilment andcondition match22Hi Yaro's, you got inboundtransfer 44000 TZSalt[transfer failed]23Transfer is rejectedPUT /transfers/77c9d78dc2.../error{"errorInformation": {"errorCode": "5100","errorDescription": "error message"}}(or){"transferState": "ABORETED"}24Revert the position changesinvolved in this transfer25If there are dependency fxTransfers,abort the fxTransfers as well andrevert the position changes involvedin those fxTransfers26The linked transfer is failed.Remove any reservations or obligationsPATCH /fxTransfers/77c9d78dc2...{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","transferState": "ABORTED"}27Oops!28200 Gotcha29Transfer is completePUT /transfers/77c9d78dc2.../error30Your transfer is failed[transfer success]31Transfer is confirmed, here's the fulfilmentPUT /transfers/77c9d78dc2...{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd...","transferState": "COMMITTED"}32Is there a dependent transfer?Yes, there is.33Is this dependency against thedebtor party to the transfer?Yes, it is.34Create an obligation from thedebtor party to the party namedin the dependency (the FXP)35Is the transfer denominated inthe currency of the payee receiveamount?Yes, it is.36Create an obligation from theparty named in the dependencyto the creditor party for the transfer37The transfer succeeded.You can clear it in your ledgersPATCH /fxTransfers/77c9d78dc2...{"completedTimestamp": "2021-08-25T14:17:08.227+01:00","fulfilment": "mhPUT9ZAwd...","transferState": "COMMITTED"}38Let's just check: does this match the stuff I sent?39It does. Great. I'll clear the conversion40200 GotchaLedger positions:PayerFSP has a debit of 300 BWPFDH_FX has a credit of 300 BWPFDH_FX has a debit of 48000 TZSPayeeFSP has a credit of 48000 TZS41Transfer is completePUT /transfers/77c9d78dc2...42Your transfer is successful \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml b/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml new file mode 100644 index 000000000..d997b7c62 --- /dev/null +++ b/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.plantuml @@ -0,0 +1,113 @@ +@startuml Payer_SEND_Discovery +!$simplified = true +!$hideSwitchDetail = false +!$advancedCoreConnectorFlow = true +!$senderName = "John" +!$senderLastName = "" +!$senderDOB = "1966-06-16" +!$receiverName = "Yaro" +!$receiverFirstName = "Yaro" +!$receiverMiddleName = "" +!$receiverLastName = "" +!$receiverDOB = "1966-06-16" +!$payerCurrency = "BWP" +!$payeeCurrency = "TZS" +!$payerFSPID = "PayerFSP" +!$payeeFSPID = "PayeeFSP" +!$fxpID = "FDH_FX" +!$payerMSISDN = "26787654321" +!$payeeMSISDN = "2551234567890" +!$payeeReceiveAmount = "44000" +!$payerSendAmount = "300" +!$payeeFee = "4000" +!$targetAmount = "48000" +!$fxpChargesSource = "33" +!$fxpChargesTarget = "6000" +!$fxpSourceAmount = "300" +!$fxpTargetAmount = "48000" +!$totalChargesSourceCurrency = "55" +!$totalChargesTargetCurrency = "10000" +!$conversionRequestId = "828cc75f1654415e8fcddf76cc" +!$conversionId = "581f68efb54f416f9161ac34e8" +!$homeTransactionId = "string" +!$quoteId = "382987a875ce4037b500c475e0" +!$transactionId = "d9ce59d4359843968630581bb0" +!$quotePayerExpiration = "2021-08-25T14:17:09.663+01:00" +!$quotePayeeExpiration = "2021-08-25T14:17:09.663+01:00" +!$commitRequestId = "77c9d78dc26a44748b3c99b96a" +!$determiningTransferId = "d9ce59d4359843968630581bb0" +!$transferId = "d9ce59d4359843968630581bb0" +!$fxCondition = "GRzLaTP7DJ9t4P-a_B..." +!$condition = "HOr22-H3AfTDHrSkP..." + + +title Currency Conversion Discovery +actor "$senderName" as A1 +box "Payer DFSP" #LightBlue + participant "Payer DFSP" as D1 +end box + +participant "Mojaloop Switch" as S1 + +'box "Discovery Service" #LightYellow +' participant "ALS Oracle" as ALS +'end box + +'box "FX provider" +' participant "FXP\nConnector" as FXP +'end box + +box "Payee DFSP" #LightBlue + participant "Payee\nMojaloop\nConnector" as D2 +end box + +'actor "$receiverName" as A2 +autonumber + +A1->D1:I'd like to pay $receiverName\n$payerSendAmount $payerCurrency, please + +activate D1 +D1->>S1:I want to send to MSISDN $payeeMSISDN\n**GET /parties/MSISDN/$payeeMSISDN** +deactivate D1 +activate S1 +!if ($simplified != true) +S1-->>D1:202 I'll get back to you +!endif +S1->S1:Who owns MSISDN $payeeMSISDN?\nIt's $payeeFSPID +S1->>D2:Do you own MSISDN $payeeMSISDN? +deactivate S1 +activate D2 +!if ($simplified != true) +D2-->>S1:202 I'll get back to you +!endif +D2->D2: Check Sanction list status & trigger a refresh of the status +D2->>S1:Yes, it's $receiverName. He can receive in $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +note right + **PUT /parties** + { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "$payeeMSISDN", + "fspId": "$payeeFSPID"}, + "name": "$receiverName", + "supportedCurrencies": [ "$payeeCurrency" ] + } +end note + +deactivate D2 +activate S1 +!if ($simplified != true) +S1-->>D2:200 Gotcha +!endif +S1->>D1:Yes, it's $receiverName. He can receive in $payeeCurrency\n**PUT /parties/MSISDN/$payeeMSISDN** +deactivate S1 +activate D1 +!if ($simplified != true) +D1-->>S1:200 Gotcha +!endif + +D1->A1: Hi, $senderName: The number belongs to $receiverName \nLet me know if you want to go ahead +deactivate D1 +A1->D1: Payer has accepted the party information + +@enduml \ No newline at end of file diff --git a/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.svg b/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.svg new file mode 100644 index 000000000..a4cc63b7f --- /dev/null +++ b/docs/product/features/CurrencyConversion/Payer_SEND_Discovery.svg @@ -0,0 +1 @@ +Currency Conversion DiscoveryPayer DFSPPayee DFSPJohnJohnPayer DFSPPayer DFSPMojaloop SwitchMojaloop SwitchPayeeMojaloopConnectorPayeeMojaloopConnector1I'd like to pay Yaro300 BWP, please2I want to send to MSISDN 2551234567890GET /parties/MSISDN/25512345678903Who owns MSISDN 2551234567890?It's PayeeFSP4Do you own MSISDN 2551234567890?5Check Sanction list status & trigger a refresh of the status6Yes, it's Yaro. He can receive in TZSPUT /parties/MSISDN/2551234567890PUT /parties{"partyIdInfo": {"partyIdType": "MSISDN","partyIdentifier": "2551234567890","fspId": "PayeeFSP"},"name": "Yaro","supportedCurrencies": [ "TZS" ]}7Yes, it's Yaro. He can receive in TZSPUT /parties/MSISDN/25512345678908Hi, John: The number belongs to YaroLet me know if you want to go ahead9Payer has accepted the party information \ No newline at end of file diff --git a/docs/product/features/FXP.svg b/docs/product/features/FXP.svg new file mode 100644 index 000000000..396e2ff2a --- /dev/null +++ b/docs/product/features/FXP.svg @@ -0,0 +1,4 @@ + + + +
    Scheme
    Scheme
    DFSP 1
    DFSP 1
    DFSP 2
    DFSP 2
    FXP
    FXP
    \ No newline at end of file diff --git a/docs/product/features/ForeignExchange.md b/docs/product/features/ForeignExchange.md new file mode 100644 index 000000000..139534f39 --- /dev/null +++ b/docs/product/features/ForeignExchange.md @@ -0,0 +1,51 @@ +# Foreign Exchange + +An important aspect of a modern payment system is the ability to support transactions in more than one currency; and Mojaloop is no different, with support for multiple transaction currencies built-in. It is an important precept that these currencies operate independently, so that a transaction debited from the debtor in currency X will always be credited to the creditor in currency X. + +Sometimes, however, it is necessary to provide a "bridge" between these currencies. This is facilitated by a function typically known as foreign exchange, and involves a third party called, in Mojaloop parlance, a Foreign Exchange Provider (FXP). + +Note that this function is not necessarily related to sending funds cross border, since there are legitimate reasons why a person in a single jurisdiction might wish to hold funds denominated in multiple currencies, not least because there are countries where multiple currencies are commonly in circulation. + +The following diagram shows how Mojaloop implements this functionality. + +![Foreign Exchange](./FXP.svg) + +Currently, Mojaloop only supports a single business model for the implementation of a foreign exchange transaction. This model implements the following "Payer Decides" model. + +### Payer Decides + +1. A customer of DFSP1 wishes to send 10 of currency X to the payee. +2. Discovery shows that the payee's account is hosted by DFSP 2. +3. DFSP 1 proposes the transaction to DFSP 2, who notes that the payment must be forwarded in currency Y. +4. DFSP 1 sends 10 X to the FXP, who forwards the equivalent value in currency Y to DFSP 2, and pays out to the payee (less fees, currency spread, etc). + +Further details of the implementation of this FX capability can be found in the [**FX documentation**](./fx.md). + +Other, more complex business models will be supported in an upcoming release. These are currently planned to include: + +### Multiple FXPs + +1. A customer of DFSP1 wishes to send 10 of currency X to the payee. +2. Discovery shows that the payee's account is hosted by DFSP 2. +3. DFSP 1 proposes the transaction to DFSP 2, who notes that the payment must be forwarded in currency Y. +4. DFSP 1 proposes the transaction to multiple FXPs, selects the one with the most beneficial terms and sends 10 X to that FXP, who forwards the equivalent value in currency Y to DFSP 2, pays out to the payee (less fees, currency spread, etc). + +### Payee Decides + +1. A customer of DFSP1 wishes to send 10 of currency X to the payee. +2. Discovery shows that the payee's account is hosted by DFSP 2. +3. DFSP 1 proposes the transaction to DFSP 2, who notes that the payment should be forwarded in the payer's currency, X. +4. DFSP 1 sends 10 X to DFSP 2 +5. DFSP 2 proposes the transaction to multiple FXPs, selects the one with the most beneficial terms and sends 10 X to that FXP, who returns the equivalent value in currency Y back to DFSP 2, who then pays out to the payee (less fees, currency spread, etc). + +The following page will be of interest to those who wish to review how interscheme and foreign exchange capabilities relate to [**cross border transactions**](./CrossBorder.md). + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22nd April 2025| Paul Makin|Added version history| +|1.0|13th March 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/InterconnectingSchemes.md b/docs/product/features/InterconnectingSchemes.md new file mode 100644 index 000000000..dd32fd695 --- /dev/null +++ b/docs/product/features/InterconnectingSchemes.md @@ -0,0 +1,32 @@ +# Interconnecting Payment Schemes + +Mojaloop, as a single deployment, is intended to be used to operate one (or more) payment schemes, operating on a single platform. Of course, it is quite common for a country to host multiple payment schemes operating on separate platforms, built around differing requirements for different sectors. + +Ultimately, though, as a payment scheme grows, then the need to be interconnected or interoperable with other payment schemes in a country grows. Mojaloop accommodates this, through a mechanism we call "Interscheme". + +Mojaloop's Interscheme approach uses a specialised type of DFSP Participant, which we call a Proxy. A Proxy is a lightweight DFSP that exists in both interconnecting schemes, and has the following characteristics: +- The Proxy does no message processing; all it does is pass messages (transactions) between the connected schemes; +- Ensuring non-repudiation across schemes means that the proxy is not involved in the agreement of terms, which helps reduce costs; +- It plays no part in the clearing of transactions. + +The consequence of this is that a Proxy preserves the three phases of a Mojaloop transfer, as well as ensuring end-to-end non-repudiation. Consequently, the agreement reached during a transfer remains between the originating and receiving DFSPs, whichever scheme they are connected to. + +![Simple Interscheme Connection](./SimpleInterscheme.svg) + +Further, the Mojaloop scheme interconnection model supports cross-scheme discovery; in other words, an alias used in one scheme can be used to route a payment from another. + +The current version of Mojaloop only supports the interconnection of Mojaloop-based schemes. Work continues to extend this to support other payment schemes, connected to a Mojaloop-based scheme. + +Further details of the implementation of this scheme interconnection capability can be found in the [**interscheme documentation**](./interscheme.md). + +The following pages will be of interest to those who wish to review how interscheme capabilities relate to [**foreign exchange**](./ForeignExchange.md) and [**cross border transactions**](./CrossBorder.md). + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|22nd April 2025| Paul Makin|Added version history; clarified some wording| +|1.0|14th April 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Agreement.plantuml b/docs/product/features/Interscheme/Interscheme-Agreement.plantuml new file mode 100644 index 000000000..96faa68f5 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Agreement.plantuml @@ -0,0 +1,72 @@ +@startuml Interscheme-Agreement + +title Interscheme - Agreement + + +participant "Payer DFSP" as payerDFSP +box Scheme A #LightBlue + participant "Mojaloop\nScheme A" as schemeA + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box Scheme B #d1e0c3 + participant "Mojaloop\nScheme B" as schemeB + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: POST /quotes +schemeA -->> payerDFSP: 202 OK +note left +header + source: payerDFSP + destination: payeeDFSP +JWS signed by payerDFSP +end note +schemeA -> pc_A: Destination not in Scheme\n Lookup proxy for payeeDFSP = Proxy AB +schemeA ->> xnp: POST /quotes +xnp ->> schemeB: POST /quotes\nmessage unmodified +note left +header + source: payerDFSP + destination: payeeDFSP + fxpiop-proxy: proxyAB +JWS signed by payerDFSP +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK +schemeB->>payeeDFSP: POST /quotes +payeeDFSP-->>schemeB: 202 OK +note right +Checks JWS signed by payerDFSP +end note +payeeDFSP->>schemeB: PUT /quotes +note right +header + source: payeeDFSP + destination: payerDFSP +JWS signed by payeeDFSP +end note +schemeB-->>payeeDFSP: 200 OK +schemeB -> pc_B: Destination not in Scheme\n Lookup proxy for payerDFSP = Proxy AB +schemeB->>xnp: PUT /quotes +xnp->>schemeA: PUT /quotes\nmessage unmodified +note right +header + source: payeeDFSP + destination: payerDFSP + fxpiop-proxy: proxyAB +JWS signed by payeeDFSP +end note +schemeA-->>xnp: 200 OK +xnp-->>schemeB: 200 OK +schemeA->>payerDFSP: PUT /quotes +note left +Checks JWS signed by payeeDFSP +end note +payerDFSP -->> schemeA: 200 OK + + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Agreement.svg b/docs/product/features/Interscheme/Interscheme-Agreement.svg new file mode 100644 index 000000000..73a3e83e4 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Agreement.svg @@ -0,0 +1 @@ +Interscheme - AgreementScheme AScheme BPayer DFSPPayer DFSPMojaloopScheme AMojaloopScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABMojaloopScheme BMojaloopScheme BProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFS[1]POST /quotes[2]202 OKheadersource: payerDFSPdestination: payeeDFSPJWS signed by payerDFSP[3]Destination not in SchemeLookup proxy for payeeDFSP = Proxy AB[4]POST /quotes[5]POST /quotesmessage unmodifiedheadersource: payerDFSPdestination: payeeDFSPfxpiop-proxy: proxyABJWS signed by payerDFSP[6]202 OK[7]202 OK[8]POST /quotes[9]202 OKChecks JWS signed by payerDFSP[10]PUT /quotesheadersource: payeeDFSPdestination: payerDFSPJWS signed by payeeDFSP[11]200 OK[12]Destination not in SchemeLookup proxy for payerDFSP = Proxy AB[13]PUT /quotes[14]PUT /quotesmessage unmodifiedheadersource: payeeDFSPdestination: payerDFSPfxpiop-proxy: proxyABJWS signed by payeeDFSP[15]200 OK[16]200 OK[17]PUT /quotesChecks JWS signed by payeeDFSP[18]200 OK \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-ErrorCases.plantuml b/docs/product/features/Interscheme/Interscheme-ErrorCases.plantuml new file mode 100644 index 000000000..d77655558 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-ErrorCases.plantuml @@ -0,0 +1,114 @@ +@startuml Interscheme-ErrorCases + +title Interscheme - Error Cases + +participant "Payer DFSP" as payerDFSP +box "Scheme A" #LightBlue + participant "ALS\nScheme A" as schemeA + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box "Scheme B" #d1e0c3 + participant "ALS\nScheme B" as schemeB + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +== POST == +payerDFSP ->> schemeA: POST/GET/PATCH/PUT /xxx +note left +header + source: payerDFSP + destination: payeeDFSP +end note + +alt if OpenAPI Error + schemeA -->> payerDFSP: 400 Bad Request +end +schemeA-->>payerDFSP: 202 OK + + alt if error in schemeA + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + note right + Error Codes: 2xxx, 3xxx, 4xxx, 5xxx + end note + payerDFSP -->> schemeA: 200 OK + end + + schemeA -> pc_A: lookup proxy for payeeDFSP = Proxy AB + alt if not in proxy cache + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + note right + Error Code: 3201 + end note + payerDFSP -->> schemeA: 200 OK + end + schemeA ->> xnp: POST/GET/PATCH/PUT /xxx + + alt if error in xnp + xnp -->> schemeA: 503 { ErrorCode: 3100} + + xnp ->> schemeA: PUT /xxx/{ID}/error + note right + header + source: Proxy AB + destination: payerDFSP + JWS Signed by Proxy AB + Error Codes: 3100 + end note + schemeA -->> xnp: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> schemeB: POST/GET/PATCH/PUT /xxx + schemeB -->> xnp: 202 OK + xnp -->> schemeA: 202 OK + + alt if error in schemeB + schemeB ->> xnp: PUT /xxx/{ID}/error + note right + Error Codes: 2xxx, 3xxx, 4xxx, 5xxx + end note + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> schemeA: PUT /xxx/{ID}/error + schemeA -->> xnp: 200 OK + xnp -->> schemeB: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + + schemeB ->> payeeDFSP: POST/GET/PATCH/PUT /xxx + payeeDFSP -->> schemeB: 200 OK + + alt if error in payeeDFSP + payeeDFSP->> schemeB: PUT /xxx/{ID}/error + note right + header destination: PayerDFSP + Error Codes: 5xxx + end note + schemeB -->> payeeDFSP: 200 OK + schemeB -> schemeB: Lookup proxy for payerDFSP = Proxy AB + schemeB ->> xnp: PUT /xxx/{ID}/error + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> schemeA: PUT /xxx/{ID}/error + schemeA -->> xnp: 200 OK + xnp -->> schemeB: 200 OK + schemeA ->> payerDFSP: PUT /xxx/{ID}/error + payerDFSP -->> schemeA: 200 OK + end + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-ErrorCases.svg b/docs/product/features/Interscheme/Interscheme-ErrorCases.svg new file mode 100644 index 000000000..8c6b3db2c --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-ErrorCases.svg @@ -0,0 +1 @@ +Interscheme - Error CasesScheme AScheme BPayer DFSPPayer DFSPALSScheme AALSScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABALSScheme BALSScheme BProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFSPOST[1]POST/GET/PATCH/PUT /xxxheadersource: payerDFSPdestination: payeeDFSPalt[if OpenAPI Error][2]400 Bad Request[3]202 OKalt[if error in schemeA][4]PUT /xxx/{ID}/errorError Codes: 2xxx, 3xxx, 4xxx, 5xxx[5]200 OK[6]lookup proxy for payeeDFSP = Proxy ABalt[if not in proxy cache][7]PUT /xxx/{ID}/errorError Code: 3201[8]200 OK[9]POST/GET/PATCH/PUT /xxxalt[if error in xnp][10]503 { ErrorCode: 3100}[11]PUT /xxx/{ID}/errorheadersource: Proxy ABdestination: payerDFSPJWS Signed by Proxy ABError Codes: 3100[12]200 OK[13]PUT /xxx/{ID}/error[14]200 OK[15]Add headerfxpiop-proxy = "Proxy AB"[16]POST/GET/PATCH/PUT /xxx[17]202 OK[18]202 OKalt[if error in schemeB][19]PUT /xxx/{ID}/errorError Codes: 2xxx, 3xxx, 4xxx, 5xxx[20]Add headerfxpiop-proxy = "Proxy AB"[21]PUT /xxx/{ID}/error[22]200 OK[23]200 OK[24]PUT /xxx/{ID}/error[25]200 OK[26]POST/GET/PATCH/PUT /xxx[27]200 OKalt[if error in payeeDFSP][28]PUT /xxx/{ID}/errorheader destination: PayerDFSPError Codes: 5xxx[29]200 OK[30]Lookup proxy for payerDFSP = Proxy AB[31]PUT /xxx/{ID}/error[32]Add headerfxpiop-proxy = "Proxy AB"[33]PUT /xxx/{ID}/error[34]200 OK[35]200 OK[36]PUT /xxx/{ID}/error[37]200 OK \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-GETTransfer.plantuml b/docs/product/features/Interscheme/Interscheme-GETTransfer.plantuml new file mode 100644 index 000000000..f29ce2212 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-GETTransfer.plantuml @@ -0,0 +1,57 @@ +@startuml Interscheme-GETTransfer + +title Interscheme - GET Transfers + +participant "Payer DFSP" as payerDFSP +box Scheme A #LightBlue + participant "Mojaloop\nScheme A" as schemeA + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box Scheme B #d1e0c3 + participant "Mojaloop\nScheme B" as schemeB + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: GET /transfers/1234 +note left +header + source: payerDFSP + destination: payeeDFSP +JWS signed by payerDFSP +end note +schemeA -->> payerDFSP: 202 OK +schemeA -> schemeA: Load transfer information + + +schemeA->>payerDFSP: PUT /transfers/1234 +note right +header + source: schemeB + destination: payerDFSP +JWS signed by schemeB +end note +payerDFSP -->> schemeA: 200 OK + +payeeDFSP->>schemeB: GET /transfers/1234 +note right +header + source: scheme A +JWS signed by schemeA +end note +schemeB -->> payeeDFSP: 202 OK +schemeB -> schemeB: Load transfer informtaion\nand check if payeeDFSP is in scheme +schemeB->>payeeDFSP: Yes; return information\nPUT /transfers/1234 +note left +header + source: schemeB + destination: payeeDFSP +JWS signed by schemeB +end note +schemeB -->> payeeDFSP: 200 OK + + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-GETTransfer.svg b/docs/product/features/Interscheme/Interscheme-GETTransfer.svg new file mode 100644 index 000000000..d332a1cc5 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-GETTransfer.svg @@ -0,0 +1 @@ +Interscheme - GET TransfersScheme AScheme BPayer DFSPPayer DFSPMojaloopScheme AMojaloopScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABMojaloopScheme BMojaloopScheme BProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFS[1]GET /transfers/1234headersource: payerDFSPdestination: payeeDFSPJWS signed by payerDFSP[2]202 OK[3]Load transfer information[4]PUT /transfers/1234headersource: schemeBdestination: payerDFSPJWS signed by schemeB[5]200 OK[6]GET /transfers/1234headersource: scheme AJWS signed by schemeA[7]202 OK[8]Load transfer informtaionand check if payeeDFSP is in scheme[9]Yes; return informationPUT /transfers/1234headersource: schemeBdestination: payeeDFSPJWS signed by schemeB[10]200 OK \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Happypath.plantuml b/docs/product/features/Interscheme/Interscheme-Happypath.plantuml new file mode 100644 index 000000000..84e0b4ebe --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Happypath.plantuml @@ -0,0 +1,106 @@ +@startuml Interscheme-Happypath + +title Interscheme - General Pattern + +participant "Payer DFSP" as payerDFSP +box "Scheme A" #LightBlue + participant "Handler\nScheme A" as schemeA + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box "Scheme B" #d1e0c3 + participant "Handler\nScheme B" as schemeB + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +== POST == +payerDFSP ->> schemeA: POST /xxx +note left +header + source: payerDFSP + destination: payeeDFSP +body + {ID: 1234} +end note +schemeA-->>payerDFSP: http 202 response +schemeA -> pc_A: Destination not in scheme:\n payeeDFSP has a proxy mapped\n need to send to 'Proxy AB' +schemeA ->> xnp: POST /xxx +xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note +xnp ->> schemeB: POST /xxx +note left +Message if forwarded to schemeB unmodified +end note + +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK + +schemeB ->> payeeDFSP: POST /xxx +payeeDFSP-->>schemeB: http 202 response + +== GET == +payerDFSP -> schemeA: GET /xxx/{ID} \nwithout destination +note left + source: payerDFSP +end note +schemeA-->>payerDFSP: http 202 response + +schemeA->schemeA: lookup if ID result and triggers put + +payerDFSP -> schemeA: GET /xxx/{ID} \nwith destination +note left + source: payerDFSP + destination: payeeDFSP +end note +schemeA-->>payerDFSP: http 202 response + +schemeA -> pc_A: Destination not in scheme:\n payeeDFSP has a proxy mapped\n need to send to 'Proxy AB' +schemeA ->> xnp: GET /xxx +xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note +xnp ->> schemeB: GET /xxx +note left +Message if forwarded to schemeB unmodified +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK + +schemeB ->> payeeDFSP: GET /xxx +payeeDFSP-->>schemeB: http 202 response + + + +== PUT == + + +payeeDFSP -> schemeB: PUT /xxx +note right + source: payeeDFSP + destination: payerDFSP +end note +schemeB-->>payeeDFSP: http 200 response + +schemeB -> pc_B: Destination not in scheme:\n payerDFSP has a proxy mapped\n need to send to 'Proxy AB' +schemeB -> xnp: PUT /xxx +xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note +xnp -> schemeA: PUT /xxx +note right +Message if forwarded to schemeA unmodified +end note +schemeA -->> xnp: 200 OK +xnp -->> schemeB: 200 OK + +schemeA -> payerDFSP: PUT /xxx +payerDFSP-->>schemeA: http 200 response + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Happypath.svg b/docs/product/features/Interscheme/Interscheme-Happypath.svg new file mode 100644 index 000000000..2af53e645 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Happypath.svg @@ -0,0 +1 @@ +Interscheme - General PatternScheme AScheme BPayer DFSPPayer DFSPHandlerScheme AHandlerScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABHandlerScheme BHandlerScheme BProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFSPOST[1]POST /xxxheadersource: payerDFSPdestination: payeeDFSPbody{ID: 1234}[2]http 202 response[3]Destination not in scheme:payeeDFSP has a proxy mappedneed to send to 'Proxy AB'[4]POST /xxx[5]Add headerfxpiop-proxy = "Proxy AB"[6]POST /xxxMessage if forwarded to schemeB unmodified[7]202 OK[8]202 OK[9]POST /xxx[10]http 202 responseGET[11]GET /xxx/{ID}without destinationsource: payerDFSP[12]http 202 response[13]lookup if ID result and triggers put[14]GET /xxx/{ID}with destinationsource: payerDFSPdestination: payeeDFSP[15]http 202 response[16]Destination not in scheme:payeeDFSP has a proxy mappedneed to send to 'Proxy AB'[17]GET /xxx[18]Add headerfxpiop-proxy = "Proxy AB"[19]GET /xxxMessage if forwarded to schemeB unmodified[20]202 OK[21]202 OK[22]GET /xxx[23]http 202 responsePUT[24]PUT /xxxsource: payeeDFSPdestination: payerDFSP[25]http 200 response[26]Destination not in scheme:payerDFSP has a proxy mappedneed to send to 'Proxy AB'[27]PUT /xxx[28]Add headerfxpiop-proxy = "Proxy AB"[29]PUT /xxxMessage if forwarded to schemeA unmodified[30]200 OK[31]200 OK[32]PUT /xxx[33]http 200 response \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml b/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml new file mode 100644 index 000000000..43daf9c05 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.plantuml @@ -0,0 +1,140 @@ +@startuml Interscheme-OnDemandDiscovery + +title Interscheme - On Demand Discovery + +participant "Payer DFSP" as payerDFSP +box "Scheme A" #LightBlue + participant "ALS\nScheme A" as ALS_A + participant "Proxy Cache\nScheme A" as pc_A + participant "Oracle\nScheme A" as Oracle_A +end box +participant "other Proxies" as dfspsA +participant "Proxy AB" as xnp +box "Scheme B" #d1e0c3 + participant "ALS\nScheme B" as ALS_B + participant "Proxy Cache\nScheme B" as pc_B + participant "Oracle\nScheme B" as Oracle_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> ALS_A: GET /parties/{Type}/{ID} +note left + header source = payerDFSP +end note +ALS_A -->> payerDFSP: 202 OK +ALS_A-> Oracle_A: GET /participant/{ID} +alt if not found in Oracle + +Oracle_A--> ALS_A: no dfsp found +ALS_A ->> ALS_A: Are there any proxies\n in Scheme A? + ALS_A ->> ALS_A: Cache Proxies that \nwill receive messages + note left + SentToProxies[{ID}] = + {['Proxy AB', 'Proxy CD', 'Proxy EF']} + end note + + loop for all Proxys in Scheme A and not source + alt if Proxy AB + ALS_A ->> xnp: GET /parties/{Type}/{ID} + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_B: GET /parties/{Type}/{ID} + ALS_B -->> xnp: 202 OK + xnp -->> ALS_A: 202 OK + ALS_B -> pc_B: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payer DFSP' to\n 'Proxy AB' mapping + pc_B -> pc_B: Add new mapping \nto cache + note left + Payer DFSP : Proxy AB + end note + + ALS_B-> Oracle_B: GET /participant/{ID} + Oracle_B--> ALS_B: dfps = payeeDFSP + ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID} + payeeDFSP -->> ALS_B: 202 OK + payeeDFSP ->> ALS_B: PUT /parties/{ID} + note right + header destination = payerDFSP + source = payeeDFSP + end note + ALS_B -->> payeeDFSP: 200 Ok + ALS_B -> pc_B: Lookup payerDFSP proxy + ALS_B ->> xnp: PUT /parties/{ID} + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_A: PUT /parties/{ID} + ALS_A -->> xnp: 200 OK + xnp -->> ALS_B: 200 OK + ALS_A -> pc_A: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payee DFSP' to \n'Proxy AB' mapping + pc_A -> pc_A: New mapping\nCheck JWS \nsignature &\n Add to cache + note left + Payee DFSP : Proxy AB + end note + ALS_A -> Oracle_A: Update Oracle with mapping\n**POST /participants/{Type}/{ID}** \n{{"fspId": "Payee DFSP"}} + Oracle_A--> ALS_A: return + ALS_A ->> payerDFSP: PUT /parties/{ID} + payerDFSP -->> ALS_A: 200 OK + else if other Proxy in Scheme A + ALS_A ->> dfspsA: GET /parties/{Type}/{ID} + dfspsA -->> ALS_A: 202 OK + dfspsA ->> ALS_A: PUT /parties/{ID}/error + ALS_A -->> dfspsA: 200 OK + ALS_A ->> ALS_A: Mark message as \nreceived from proxy + note left + remove other Proxy from + list SentToProxies[{ID}] + end note + + alt if SentToProxies[{ID}] is empty + ALS_A ->> payerDFSP: PUT /parties/{ID}/error + note right + SentToProxies[{ID}] is empty + end note + payerDFSP -->> ALS_A: 200 OK + end + end +end loop +else if found in Oracle + Oracle_A--> ALS_A: dfsp = payeeDFSP + + ALS_A->ALS_A: Payee DFSP is \nnot in scheme A + ALS_A-> pc_A: Lookup proxy for\n Payee DFSP + alt if header source is a member of Scheme A + ALS_A->ALS_A: Add destination to header + note left + destination dfsp: Payee DFSP + end note + + ALS_A ->> xnp: GET /parties/{Type}/{ID} + xnp ->> ALS_B: GET /parties/{Type}/{ID} + ALS_B -->> xnp: 202 OK + xnp -->> ALS_A: 202 OK + end + ALS_B->ALS_B: Forward to destination + ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID} + payeeDFSP -->> ALS_B: 202 OK + payeeDFSP ->> ALS_B: PUT /parties/{ID} + note right + header destination = payerDFSP + end note + ALS_B -->> payeeDFSP: 200 Ok + ALS_B -> pc_B: Lookup payerDFSP proxy + ALS_B ->> xnp: PUT /parties/{ID} + xnp ->> ALS_A: PUT /parties/{ID} + ALS_A -->> xnp: 200 OK + xnp -->> ALS_B: 200 OK + ALS_A -> pc_A: Source not in Scheme: \nAdd 'Payee DFSP' to\n 'Proxy AB' mapping + pc_A -> pc_A: Got Mapping + ALS_A ->> payerDFSP: PUT /parties/{ID} + payerDFSP -->> ALS_A: 200 OK +end + + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg b/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg new file mode 100644 index 000000000..a73a08b38 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-OnDemandDiscovery.svg @@ -0,0 +1 @@ +Interscheme - On Demand DiscoveryScheme AScheme BPayer DFSPPayer DFSPALSScheme AALSScheme AProxy CacheScheme AProxy CacheScheme AOracleScheme AOracleScheme Aother Proxiesother ProxiesProxy ABProxy ABALSScheme BALSScheme BProxy CacheScheme BProxy CacheScheme BOracleScheme BOracleScheme BPayee DFSPayee DFS[1]GET /parties/{Type}/{ID}header source = payerDFSP[2]202 OK[3]GET /participant/{ID}alt[if not found in Oracle][4]no dfsp found[5]Are there any proxiesin Scheme A?[6]Cache Proxies thatwill receive messagesSentToProxies[{ID}] ={['Proxy AB', 'Proxy CD', 'Proxy EF']}loop[for all Proxys in Scheme A and not source]alt[if Proxy AB][7]GET /parties/{Type}/{ID}[8]Add headerfxpiop-proxy = "Proxy AB"[9]GET /parties/{Type}/{ID}[10]202 OK[11]202 OK[12]Source not in Scheme:fxpiop-proxy = "Proxy AB"Add 'Payer DFSP' to'Proxy AB' mapping[13]Add new mappingto cachePayer DFSP : Proxy AB[14]GET /participant/{ID}[15]dfps = payeeDFSP[16]GET /parties/{Type}/{ID}[17]202 OK[18]PUT /parties/{ID}header destination = payerDFSPsource = payeeDFSP[19]200 Ok[20]Lookup payerDFSP proxy[21]PUT /parties/{ID}[22]Add headerfxpiop-proxy = "Proxy AB"[23]PUT /parties/{ID}[24]200 OK[25]200 OK[26]Source not in Scheme:fxpiop-proxy = "Proxy AB"Add 'Payee DFSP' to'Proxy AB' mapping[27]New mappingCheck JWSsignature &Add to cachePayee DFSP : Proxy AB[28]Update Oracle with mappingPOST /participants/{Type}/{ID} {{"fspId": "Payee DFSP"}}[29]return[30]PUT /parties/{ID}[31]200 OK[if other Proxy in Scheme A][32]GET /parties/{Type}/{ID}[33]202 OK[34]PUT /parties/{ID}/error[35]200 OK[36]Mark message asreceived from proxyremove other Proxy fromlist SentToProxies[{ID}]alt[if SentToProxies[{ID}] is empty][37]PUT /parties/{ID}/errorSentToProxies[{ID}] is empty[38]200 OK[if found in Oracle][39]dfsp = payeeDFSP[40]Payee DFSP isnot in scheme A[41]Lookup proxy forPayee DFSPalt[if header source is a member of Scheme A][42]Add destination to headerdestination dfsp: Payee DFSP[43]GET /parties/{Type}/{ID}[44]GET /parties/{Type}/{ID}[45]202 OK[46]202 OK[47]Forward to destination[48]GET /parties/{Type}/{ID}[49]202 OK[50]PUT /parties/{ID}header destination = payerDFSP[51]200 Ok[52]Lookup payerDFSP proxy[53]PUT /parties/{ID}[54]PUT /parties/{ID}[55]200 OK[56]200 OK[57]Source not in Scheme:Add 'Payee DFSP' to'Proxy AB' mapping[58]Got Mapping[59]PUT /parties/{ID}[60]200 OK \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml b/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml new file mode 100644 index 000000000..934c98a7d --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.plantuml @@ -0,0 +1,90 @@ +@startuml Interscheme-StalePartyIdentifierCache + +title Stale Party Identifier Cache + +participant "Payer DFSP" as payerDFSP +box "Scheme A" #LightBlue + participant "ALS\nScheme A" as ALS_A + participant "Oracle\nScheme A" as Oracle_A + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box "Scheme B" #d1e0c3 + participant "ALS\nScheme B" as ALS_B + participant "Oracle\nScheme A" as Oracle_B + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> ALS_A: **GET** /parties/{Type}/{ID} +note left + header source = payerDFSP +end note + + ALS_A-> Oracle_A: **GET** /participant/{ID} + Oracle_A--> ALS_A: found DFSP = payeeDFSP + ALS_A ->> ALS_A: DFSP not in scheme + ALS_A -> pc_A: Who is payee DFSP's proxy? + alt proxy representative not found + pc_A --> ALS_A: Proxy not found + ALS_A -> Oracle_A: Remove mapping in Oracle\n **DELETE** \participants\{Type}\{ID} + note left + **Self heal** if proxy + reference is not found + end note + ALS_A ->> ALS_A: Restart the ALS get parties process + else + pc_A --> ALS_A: forward to Proxy AB + end + + ALS_A ->> xnp: **GET** /parties/{Type}/{ID} + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + + xnp ->> ALS_B: **GET** /parties/{Type}/{ID} + ALS_B ->> pc_B: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payer DFSP' to 'Proxy AB' mapping +alt not MVP + pc_B -> pc_B: Check JWS signature +end + pc_B -> pc_B: Add new mapping to cache +note left +Payer DFSP : Proxy AB +end note +ALS_B-> Oracle_B: **GET** /participant/{ID} + Oracle_B--> ALS_B: dfps = payeeDFSP + alt if dfsp is a member of Scheme B + ALS_B ->> payeeDFSP: **GET** /parties/{Type}/{ID} + payeeDFSP ->> ALS_B: **PUT** /parties/{ID}/error + note right + header desitination = payerDFSP + end note + end + ALS_B -> pc_B: Lookup payerDFSP proxy + ALS_B ->> xnp: **PUT** /parties/{ID}/error + xnp->xnp: Add header + note left + fxpiop-proxy = "Proxy AB" + end note + xnp ->> ALS_A: **PUT** /parties/{ID}/error + alt message from proxy & error & no proxy message cache + note left ALS_A + **Self heal** if error in routing + fxpiop-proxy = "Proxy AB" + PUT /parties error + SentToProxies[{ID}] list undefined + end note + ALS_A -> Oracle_A: Remove mapping in Oracle\n **DELETE** \participants\{Type}\{ID} + ALS_A ->> payerDFSP: **PUT** /parties/{ID}/error + note right + {ErrorCode: "2003"} + (Service Unavailable) + end note + else + ALS_A->>payerDFSP: **PUT** /parties/{ID}/error +end + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg b/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg new file mode 100644 index 000000000..cd5ae6924 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-StalePartyIdentifierCache.svg @@ -0,0 +1 @@ +Stale Party Identifier CacheScheme AScheme BPayer DFSPPayer DFSPALSScheme AALSScheme AOracleScheme AOracleScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABALSScheme BALSScheme BOracleScheme AOracleScheme AProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFS[1]GET/parties/{Type}/{ID}header source = payerDFSP[2]GET/participant/{ID}[3]found DFSP = payeeDFSP[4]DFSP not in scheme[5]Who is payee DFSP's proxy?alt[proxy representative not found][6]Proxy not found[7]Remove mapping in Oracle DELETE\participants\{Type}\{ID}Self healif proxyreference is not found[8]Restart the ALS get parties process[9]forward to Proxy AB[10]GET/parties/{Type}/{ID}[11]Add headerfxpiop-proxy = "Proxy AB"[12]GET/parties/{Type}/{ID}[13]Source not in Scheme:fxpiop-proxy = "Proxy AB"Add 'Payer DFSP' to 'Proxy AB' mappingalt[not MVP][14]Check JWS signature[15]Add new mapping to cachePayer DFSP : Proxy AB[16]GET/participant/{ID}[17]dfps = payeeDFSPalt[if dfsp is a member of Scheme B][18]GET/parties/{Type}/{ID}[19]PUT/parties/{ID}/errorheader desitination = payerDFSP[20]Lookup payerDFSP proxy[21]PUT/parties/{ID}/error[22]Add headerfxpiop-proxy = "Proxy AB"[23]PUT/parties/{ID}/erroralt[message from proxy & error & no proxy message cache]Self healif error in routingfxpiop-proxy = "Proxy AB"PUT /parties errorSentToProxies[{ID}] list undefined[24]Remove mapping in Oracle DELETE\participants\{Type}\{ID}[25]PUT/parties/{ID}/error{ErrorCode: "2003"}(Service Unavailable)[26]PUT/parties/{ID}/error \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Transfer.plantuml b/docs/product/features/Interscheme/Interscheme-Transfer.plantuml new file mode 100644 index 000000000..9fda3da00 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Transfer.plantuml @@ -0,0 +1,80 @@ +@startuml Interscheme-Transfer + +title Interscheme - Transfer + +participant "Payer DFSP" as payerDFSP +box Scheme A #LightBlue + participant "Mojaloop\nScheme A" as schemeA + participant "Proxy Cache\nScheme A" as pc_A +end box +participant "Proxy AB" as xnp +box Scheme B #d1e0c3 + participant "Mojaloop\nScheme B" as schemeB + participant "Proxy Cache\nScheme B" as pc_B +end box +participant "Payee DFS" as payeeDFSP + +autonumber 1 "[0]" + +payerDFSP ->> schemeA: POST /transfers +note left +header + source: payerDFSP + destination: payeeDFSP +JWS signed by payerDFSP +body + transferId: 1234 +end note +schemeA -->> payerDFSP: 202 OK +schemeA -> schemeA: Payer DFSP\n - Checks limits\n - Updates position +schemeA -> pc_A: Destination not in Scheme\nLookup proxy for payeeDFSP = Proxy AB +schemeA ->> xnp: POST /transfers +xnp ->> schemeB: POST /transfers +note left +header + source: payerDFSP + destination: payeeDFSP + fxpiop-proxy: proxyAB +JWS signed by payerDFSP +body + transferId: 1234 +end note +schemeB -->> xnp: 202 OK +xnp -->> schemeA: 202 OK +schemeA -> schemeA: Disable timeout + +schemeB -> schemeB: Proxy AB\n **- No limit check**\n - Updates position +schemeB->>payeeDFSP: POST /transfers +note right +Checks JWS signed by payerDFSP +end note +payeeDFSP->>schemeB: PUT /transfers \n{fulfilment: "xyz", transferState: "RESERVED"} +note right +header + source: payeeDFSP + destination: payerDFSP +JWS signed by payeeDFSP +end note +schemeB -> schemeB: Payer DFSP\n - Updates position +schemeB -> pc_B: Lookup proxy for payerDFSP = Proxy AB +schemeB->>xnp: PUT /transfers +xnp->>schemeA: PUT /transfers +note right +header + source: payeeDFSP + destination: payerDFSP + fxpiop-proxy: proxyAB +JWS signed by payeeDFSP +end note +schemeA-->>xnp: 200 OK +xnp-->>schemeB: 200 OK +schemeB->>payeeDFSP: PATCH /transfers \n{transferState: "COMMITTED"} +payeeDFSP-->>schemeB: 200 OK +schemeA -> schemeA: NX Proxy\n - Updates position +schemeA->>payerDFSP: PUT /transfers +note left +Checks JWS signed by payeeDFSP +end note +payerDFSP -->> schemeA: 200 OK + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/Interscheme-Transfer.svg b/docs/product/features/Interscheme/Interscheme-Transfer.svg new file mode 100644 index 000000000..65bb79a94 --- /dev/null +++ b/docs/product/features/Interscheme/Interscheme-Transfer.svg @@ -0,0 +1 @@ +Interscheme - TransferScheme AScheme BPayer DFSPPayer DFSPMojaloopScheme AMojaloopScheme AProxy CacheScheme AProxy CacheScheme AProxy ABProxy ABMojaloopScheme BMojaloopScheme BProxy CacheScheme BProxy CacheScheme BPayee DFSPayee DFS[1]POST /transfersheadersource: payerDFSPdestination: payeeDFSPJWS signed by payerDFSPbodytransferId: 1234[2]202 OK[3]Payer DFSP- Checks limits- Updates position[4]Destination not in SchemeLookup proxy for payeeDFSP = Proxy AB[5]POST /transfers[6]POST /transfersheadersource: payerDFSPdestination: payeeDFSPfxpiop-proxy: proxyABJWS signed by payerDFSPbodytransferId: 1234[7]202 OK[8]202 OK[9]Disable timeout[10]Proxy AB - No limit check- Updates position[11]POST /transfersChecks JWS signed by payerDFSP[12]PUT /transfers{fulfilment: "xyz", transferState: "RESERVED"}headersource: payeeDFSPdestination: payerDFSPJWS signed by payeeDFSP[13]Payer DFSP- Updates position[14]Lookup proxy for payerDFSP = Proxy AB[15]PUT /transfers[16]PUT /transfersheadersource: payeeDFSPdestination: payerDFSPfxpiop-proxy: proxyABJWS signed by payeeDFSP[17]200 OK[18]200 OK[19]PATCH /transfers{transferState: "COMMITTED"}[20]200 OK[21]NX Proxy- Updates position[22]PUT /transfersChecks JWS signed by payeeDFSP[23]200 OK \ No newline at end of file diff --git a/docs/product/features/Interscheme/InterschemeAccounts-Clearing.png b/docs/product/features/Interscheme/InterschemeAccounts-Clearing.png new file mode 100644 index 000000000..a219b4c67 Binary files /dev/null and b/docs/product/features/Interscheme/InterschemeAccounts-Clearing.png differ diff --git a/docs/product/features/Interscheme/SettingUpProxys.plantuml b/docs/product/features/Interscheme/SettingUpProxys.plantuml new file mode 100644 index 000000000..4d1ddb131 --- /dev/null +++ b/docs/product/features/Interscheme/SettingUpProxys.plantuml @@ -0,0 +1,31 @@ +@startuml SettingUpProxys +title Central Ledger API / Admin API + +participant "Onboarding Script" as script +participant "Mojaloop\nScheme A" as schemeA +participant "XN Proxy" as xnp +participant "Mojaloop\nScheme B" as schemeB + +autonumber 1 "[0]" + +== Create Participant Types == + +script -> schemeA: POST /participants +note left +{ + "name": "XN Proxy", + "currency": "USD", + "isProxy": true +} +end note + +script -> schemeB: POST /participants +note left +{ + "name": "XN Proxy", + "currency": "USD", + "isProxy": true +} +end note + +@enduml \ No newline at end of file diff --git a/docs/product/features/Interscheme/SettingUpProxys.svg b/docs/product/features/Interscheme/SettingUpProxys.svg new file mode 100644 index 000000000..f29814093 --- /dev/null +++ b/docs/product/features/Interscheme/SettingUpProxys.svg @@ -0,0 +1 @@ +Central Ledger API / Admin APIOnboarding ScriptOnboarding ScriptMojaloopScheme AMojaloopScheme AXN ProxyXN ProxyMojaloopScheme BMojaloopScheme BCreate Participant Types[1]POST /participants{"name": "XN Proxy","currency": "USD",  "isProxy": true}[2]POST /participants{"name": "XN Proxy","currency": "USD",  "isProxy": true} \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/Appendix.md b/docs/product/features/Iso20022/v1.0/Appendix.md new file mode 100644 index 000000000..7e0c862cd --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/Appendix.md @@ -0,0 +1,50 @@ +# 8. Appendix A: Payment Identifier Type Codes +## 8.1 FSPIOP Identifier types +|Code|Description| +| -- | -- | +|MSISDN|An MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.| +|EMAIL|An email is used as reference to a participant. The format of the email should be according to the informational RFC 3696.| +|PERSONAL_ID|A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.| +|BUSINESS|A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.| +|DEVICE|A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.| +|ACCOUNT_ID|A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.| +|IBAN|A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.| +|ALIAS| alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.| + + +## 8.2 Personal Identifier Code Table +These type are not yet supported. + +|Code|Description| +| -- | -- | +|ARNU|AlienRegistrationNumber| +|CCPT|PassportNumber| +|CUST|CustomerIdentificationNumber| +|DRLC|DriversLicenseNumber| +|EMPL|EmployeeIdentificationNumber| +|NIDN|NationalIdentityNumber| +|SOSE|SocialSecurityNumber| +|TELE|TelephoneNumber| +|TXID|TaxIdentificationNumber| +|POID|PersonCommercialIdentification| + + +## 8.3 Organisation Identifier Code Table +These type are not yet supported. + +|Code|Description +| -- | -- | +|BANK|BankPartyIdentification| +|CBID|CentralBankIdentificationNumber| +|CHID|ClearingIdentificationNumber| +|CINC|CertificateOfIncorporationNumber| +|COID|CountryIdentificationCode| +|CUST|CustomerNumber| +|DUNS|DataUniversalNumberingSystem| +|EMPL|EmployerIdentificationNumber| +|GS1G|GS1GLNIdentifier| +|SREN|SIREN| +|SRET|SIRET| +|TXID|TaxIdentificationNumber| +|BDID|BusinessDomainIdentifier| +|BOID|BusinessOtherIdentification| diff --git a/mojaloop-technical-overview/central-ledger/.gitkeep b/docs/product/features/Iso20022/v1.0/IntegrationPatterns.md similarity index 100% rename from mojaloop-technical-overview/central-ledger/.gitkeep rename to docs/product/features/Iso20022/v1.0/IntegrationPatterns.md diff --git a/docs/product/features/Iso20022/v1.0/MarketPracticeDocument.md b/docs/product/features/Iso20022/v1.0/MarketPracticeDocument.md new file mode 100644 index 000000000..2eba5b06e --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/MarketPracticeDocument.md @@ -0,0 +1,237 @@ +# v1.0: Mojaloop ISO 20022 Market Practice Document + + + +- [1. Mojaloop ISO 20022 Market Practice Document](#_1-mojaloop-iso-20022-market-practice-document) +- [2. Introduction](#_2-introduction) + - [2.1. How to Use This Document?](#_2-1-how-to-use-this-document) + - [2.1.1. Relationship with Scheme-Specific Rules Documents](#_2-1-1-relationship-with-scheme-specific-rules-documents) + - [2.1.2. Distinction Between Generic Practices and Scheme-Specific Requirements](#_2-1-2-distinction-between-generic-practices-and-scheme-specific-requirements) +- [3. Message Expectations, Obligations, and Rules](#_3-message-expectations-obligations-and-rules) + - [3.1. Currency Conversion](#_3-1-currency-conversion) + - [3.2. JSON Messages](#_3-2-json-messages) + - [3.3. APIs](#_3-3-apis) + - [3.3.1. Header Details](#_3-3-1-header-details) + - [3.3.2. Supported HTTP Responses](#_3-3-2-supported-http-responses) + - [3.3.3. Common Error Payload](#_3-3-3-common-error-payload) + - [3.4. ULIDs as Unique Identifiers](#_3-4-ulids-as-unique-identifiers) + - [3.5. Inter-ledger Protocol v4 to represent the Cryptographic Terms](#_3-5-inter-ledger-protocol-v4-to-represent-the-cryptographic-terms) + - [3.6. ISO 20022 Supplementary Data Fields](#_3-6-iso-20022-supplementary-data-fields) +- [4. Discovery Phase](#_4-discovery-phase) + - [4.1. Message flow](#_4-1-message-flow) + - [4.2. Parties Resource](#_4-2-parties-resource) +- [5. Agreement Phase](#_5-agreement-phase) + - [5.1. Currency Conversion Agreement Sub-Phase](#_5-1-currency-conversion-agreement-sub-phase) + - [5.1.1. Message flow](#_5-1-1-message-flow) + - [5.1.2. fxQuotes Resource](#_5-1-2-fxquotes-resource) + - [5.2. Transfer Terms Agreement Sub-Phase](#_5-2-transfer-terms-agreement-sub-phase) + - [5.2.1. Message flow](#_5-2-1-message-flow) + - [5.2.2. Quotes Resource](#_5-2-2-quotes-resource) +- [6. Transfer Phase](#_6-transfer-phase) + - [6.1. Accepting Currency Conversion terms](#_6-1-accepting-currency-conversion-terms) + - [6.1.1. Message flow](#_6-1-1-message-flow) + - [6.1.2. fxTransfers Resource](#_6-1-2-fxtransfers-resource) + - [6.2. Transfer Execution and Clearing](#_6-2-transfer-execution-and-clearing) + - [6.2.1. Message flow](#_6-2-1-message-flow) + - [6.2.2. Transfers Resource](#_6-2-2-transfers-resource) + + +# 2. Introduction + +By combining the principles of financial inclusion with the robust capabilities of ISO 20022, Mojaloop ensures that DFSPs and other stakeholders can deliver real-time payment solutions that are cost-effective, secure, and scalable to meet the demands of inclusive financial ecosystems. This document is version 1.0 of the Mojaloop ISO-20022 market practice. + +## 2.1 How to Use This Document? +This document provides a foundational reference for implementing ISO 20022 messaging for IIPS within Mojaloop-based schemes. It outlines general guidelines and practices that apply universally across Mojaloop schemes, focusing on the base-level requirements. However, it is designed to be supplemented by scheme-specific rules documents, which can define additional message fields, validations, and rules necessary to meet the unique regulations and requirements of individual schemes. This layered approach enables each scheme to tailor its implementation details while maintaining consistency with the broader Mojaloop framework. + +### 2.1.1 Relationship with Scheme-Specific Rules Documents +This document serves as a foundation for understanding how ISO 20022 is applied in Mojaloop, focusing on core principles and practices. However, it does not prescribe the detailed business requirements, validations, and governance frameworks that are specific to individual schemes. Scheme-specific rules address these details, including mandatory and optional field specifications, tailored compliance protocols, and defined procedures for error handling. They also encompass business rules governing message flows, participant roles, and responsibilities within the scheme. The flexibility of this document allows scheme administrators to adapt and extend its guidance to meet their unique operational needs. + +### 2.1.2 Distinction Between Generic Practices and Scheme-Specific Requirements +This document distinctly separates generic practices from scheme-specific requirements to achieve a balance between consistency and adaptability in ISO 20022 implementations within Mojaloop. The generic practices outlined here establish foundational principles, including expectations for message structures, required fields to meet switch requirements, supported fields, and transactional flows. Additionally, they provide a high-level overview of the Mojaloop P2P FX transfer lifecycle. + +Scheme-specific requirements, documented separately, delve into additional field mappings, enhanced validations, and precise rules for settlement, reconciliation, and dispute resolution. These requirements also encompass governance policies and compliance obligations tailored to the unique needs of individual schemes. + +This distinction enables DFSPs to implement a consistent core messaging framework while granting scheme administrators the flexibility to define operational specifics. The generic practices presented in this document are purposefully designed to be extensible, ensuring seamless integration with scheme-specific rules and supporting adherence to Mojaloop’s ISO 20022 for IIPS standards. + +# 3 Message Expectations, Obligations, and Rules +The Mojaloop transfer process is divided into three key phases, each essential to ensuring secure and efficient transactions. These phases use specific resources to enable participant interactions, ensuring clear communication, agreement, and execution. While some phases and resources are optional, the ultimate goal is to ensure every transfer is accurate, secure, and aligns with agreed terms. +1. [Discovery](#_4-discovery-phase) +2. [Agreement](#_5-agreement-phase) +3. [Transfer](#_6-transfer-phase) + +## 3.1 Currency Conversion +Currency conversion is included to support cross-currency transactions. As it is not always required, the associated messages and flows are only used when needed, ensuring flexibility for both single-currency and multi-currency scenarios. + +## 3.2 JSON Messages +Mojaloop adopts a JSON variant of ISO 20022 messages, moving away from the traditional XML format to enhance efficiency and compatibility with modern APIs. The ISO 20022 organization is actively developing a canonical JSON representation of its messages, and Mojaloop aims to align with this standard as it evolves. + +## 3.3 APIs +ISO 20022 messages are exchanged in Mojaloop via REST-like API calls. This approach enhances interoperability, reduces data overhead through lightweight JSON messages, and supports scalable and modular implementations. By integrating ISO 20022 with REST APIs, Mojaloop delivers a robust, adaptable framework that balances global standards with practical implementation needs. + +### 3.3.1 Header Details +The API message header should contain the following details. Required headers are specified with an `*` asterisks. + +| Name                                | Description | +|--|--| +|**Content-Length**
    *integer*
    (header)|The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body.**Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes).| +| * **Type**
    *string*
    (path)|The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`.| +| * **ID**
    *string*
    (path)| The identifier value.| +| * **Content-Type**
    *string*
    (header)|The `Content-Type` header indicates the specific version of the API used to send the payload body.| +| * **Date**
    *string*
    (header)|The `Date` header field indicates the date when the request was sent.| +| **X-Forwarded-For**
    *string*
    (header)|The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API.**Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`.| +| * **FSPIOP-Source**
    *string*
    (header)|The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`).| +| **FSPIOP-Destination**
    *string*
    (header)|The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.| +| **FSPIOP-Encryption**
    *string*
    (header) | The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request.| +| **FSPIOP-Signature**
    *string*
    (header)| The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature.| +| **FSPIOP-URI**
    *string*
    (header) | The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://docs.mojaloop.io/technical/api/fspiop/).| +| **FSPIOP-HTTP-Method**
    *string*
    (header) | The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://docs.mojaloop.io/technical/api/fspiop/).| + +### 3.3.2 Supported HTTP Responses + +| **HTTP Error Code** | **Description and Common Causes** | +|---|----| +|**400 Bad Request** | **Description**: The server could not understand the request due to invalid syntax. This response indicates that the request was malformed or contained invalid parameters.
    **Common Causes**: Missing required fields, invalid field values, or incorrect request format. | +|**401 Unauthorized** | **Description**: The client must authenticate itself to get the requested response. This response indicates that the request lacks valid authentication credentials.
    **Common Causes**: Missing or invalid authentication token. | +|**403 Forbidden** | **Description**: The client does not have access rights to the content. This response indicates that the server understood the request but refuses to authorize it.
    **Common Causes**: Insufficient permissions to access the resource. | +|**404 Not Found** | **Description**: The server can not find the requested resource. This response indicates that the specified resource does not exist.
    **Common Causes**: Incorrect resource identifier or the resource has been deleted. | +|**405 Method Not Allowed** | **Description**: The request method is known by the server but is not supported by the target resource. This response indicates that the HTTP method used is not allowed for the endpoint.
    **Common Causes**: Using an unsupported HTTP method (e.g., POST instead of PUT). | +|**406 Not Acceptable** | **Description**: The server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers. This response indicates that the server cannot generate a response that is acceptable according to the Accept headers sent in the request.
    **Common Causes**: Unsupported media type or format specified in the Accept header. | +|**501 Not Implemented** | **Description**: The server does not support the functionality required to fulfill the request. This response indicates that the server does not recognize the request method or lacks the ability to fulfill the request.
    **Common Causes**: The requested functionality is not implemented on the server. | +|**503 Service Unavailable** | **Description**: The server is not ready to handle the request. This response indicates that the server is temporarily unable to handle the request due to maintenance or overload.
    **Common Causes**: Server maintenance, temporary overload, or server downtime. | + +### 3.3.3 Common Error Payload + +All error responses return a common payload structure that includes a specific message. The payload typically contains the following fields: + +- **errorCode**: A code representing the specific error. +- **errorDescription**: A description of the error. +- **extensionList**: An optional list of key-value pairs providing additional information about the error. + +This common error payload helps clients understand the nature of the error and take appropriate actions. + + + +## 3.4 ULIDs as Unique Identifiers +Mojaloop employs Universally Unique Lexicographically Sortable Identifiers (ULIDs) as the standard for unique identifiers across its messaging system. ULIDs offer a robust alternative to traditional UUIDs, ensuring globally unique identifiers while also enabling natural ordering by time of creation. This lexicographical sorting simplifies traceability, troubleshooting, and operational analytics. + +## 3.5 Inter-ledger Protocol (v4) to represent the Cryptographic Terms +Mojaloop leverages the Inter-ledger Protocol (ILP) version 4 to define and represent cryptographic terms in its transfer processes. ILP v4 provides a standardized framework for secure and interoperable exchange of payment instructions, ensuring integrity and non-repudiation of transactions. By integrating ILP's cryptographic capabilities, Mojaloop supports precise and tamper-proof agreements between participants, enabling secure end-to-end transfer execution while maintaining compatibility with global payment ecosystems. + +## 3.6 ISO 20022 Supplementary Data Fields + +It is not expected that ISO 20022 supplementary data fields will be required for any of the messages used. If supplementary data is provided, the switch will not reject the message; however, it will ignore its contents and behave as if the supplementary data was not present. + +
    + +# 4. Discovery Phase +The Discovery Phase is an optional step in the transfer process, necessary only when the payee (end party) must be identified and confirmed before initiating an agreement. This phase utilizes the parties resource, which facilitates the retrieval and validation of the payee’s information to ensure they are eligible to receive the transfer. Key checks performed during this phase include verifying that the payee's account is active, identifying the currencies that can be transferred into the account, and confirming the account owner’s details. This information allows the payer to verify the payee's details accurately, reducing the risk of errors and ensuring a secure foundation for the subsequent phases of the transfer process. + +## 4.1 Message flow + +The sequence diagram shows the discovery example messages in a Payer initiated P2P transfer. +![Discovery Flow](./SequenceDiagrams/Discovery.svg) + +## 4.2 Parties Resource +The Parties resource provides all the necessary functionality in the discovery phase of a transfer. The functionality is always initiated with a GET /parties call, and responses to this are returned to the originator through a PUT /parties callback. Error messages are returned through the PUT /parties/.../error callback. These endpoints support an optional sub id type. + + +| Endpoint | Message | +|--- | --- | +|[GET /parties/{type}/{partyIdentifier}[/{subId}]](./script/parties_GET.md) | | +|[PUT /parties/{type}/{partyIdentifier}[/{subId}]](./script/parties_PUT.md) | acmt.024.001.04 | +|[PUT /parties/{type}/{partyIdentifier}[/{subId}]/error](./script/parties_error_PUT.md) | acmt.024.001.04 | + +
    + +# 5. Agreement Phase +The **Agreement Phase** is a critical step in the Mojaloop transfer process, ensuring that all parties involved have a shared understanding of the transfer terms before any funds are committed. This phase serves several essential purposes: +1. **Calculation and Agreement of Fees**
    +The Agreement Phase provides an opportunity for the calculation and mutual agreement on any applicable fees. This ensures transparency and prevents disputes related to charges after the transfer is initiated. +1. **Pre-Commitment Validation**
    +It allows each participating organization to verify whether the transfer can proceed. This step helps identify and address potential issues early, reducing errors during the transfer and minimizing reconciliation discrepancies. +1. **Cryptographic Signing of Terms**
    +The terms of the transfer are cryptographically signed during this phase. This mechanism ensures non-repudiation, meaning that parties cannot deny their involvement in or agreement to the transaction. The Interledger Protocol is used to perform this cryptographic signing. Details on how to produce an ILP packet are defined here: [Mojaloop FSPIOP API Documentation](https://docs.mojaloop.io/technical/api/fspiop/). +1. **Promoting Financial Inclusion**
    +By presenting all parties with the complete terms of the transfer upfront, the Agreement Phase ensures that participants are fully informed before making any commitments. This transparency supports financial inclusively by enabling fair and informed decision-making for all stakeholders. + +The Agreement Phase not only improves the reliability and efficiency of Mojaloop transfers but also aligns with its broader goal of fostering trust and inclusively in digital financial ecosystems. + +The agreement phase is further divided into two phases. + +## 5.1 Currency Conversion Agreement Sub-Phase +The Currency Conversion Agreement Sub-Phase is an optional step within the Agreement Phase, activated only when the transfer involves a currency conversion. During this sub-phase, the payer DFSP (Digital Financial Services Provider) coordinates with a foreign exchange (FX) provider to secure cross-currency liquidity required to complete the transaction. This step establishes the FX rates and associated fees, ensuring that both the DFSP and the FXP can rely on transparent and agreed-upon conversion terms. By addressing currency conversion needs before committing to the transfer, this sub-phase helps prevent delays and discrepancies, supporting a seamless cross-border transaction experience. + +### 5.1.1 Message flow + + +The sequence diagram shows the discovery example messages in a Payer initiated P2P transfer. +![Agreement Conversion Flow](./SequenceDiagrams/AgreementConversion.svg) + +### 5.1.2 fxQuotes Resource + +| Endpoint | Message | +|--- | --- | +|[POST /fxQuotes/{ID}](./script/fxquotes_POST.md) | **pacs.091.001** | +|[PUT /fxQuotes/{ID}](./script/fxquotes_PUT.md) | **pacs.092.001** | +|[PUT /fxQuotes/{ID}/error](./script/fxquotes_error_PUT.md) | **pacs.002.001.15** | + +## 5.2 Transfer Terms Agreement Sub-Phase +The End-to-End Terms Agreement Sub-Phase involves the collaborative establishment of the transfer terms between the payer DFSP and the payee DFSP. This process ensures both parties are aligned on critical details such as the amount to be transferred, fees, and timing requirements. This sub-phase also facilitates the cryptographic signing of these terms, providing a robust framework for non-repudiation and accountability. By finalizing the transfer terms in a transparent manner, this sub-phase minimizes the risk of errors or disputes, enhancing the efficiency and trustworthiness of the overall Mojaloop transfer process. + +### 5.2.1 Message flow + +The sequence diagram shows the discovery example messages in a Payer initiated P2P transfer. +![Agreement Flow](./SequenceDiagrams/Agreement.svg) + +### 5.2.2 Quotes Resource + +| Endpoint | Message | +| ------------- | --- | +|[POST /quotes/{ID}](./script/quotes_POST.md) | **pacs.081.001** | +|[PUT /quotes/{ID}](./script/quotes_PUT.md) | **pacs.082.001** | +|[PUT /quotes/{ID}/error](./script/quotes_error_PUT.md) | **pacs.002.001.15** | + +
    + +# 6. Transfer Phase +Once the agreements have been successfully established during the Agreement Phase, accepting these terms triggers the Transfer Phase, where the actual movement of funds occurs. This phase is executed with precision to ensure that the agreed terms are honored, and all participants fulfill their commitments. The Transfer Phase is divided into two sub-phases: the Currency Conversion Execution Sub-Phase and the Transfer Clearing Sub-Phase, each corresponding to its respective sub-phase in the Agreement Phase. + +## 6.1 Accepting Currency Conversion terms +The Currency Conversion Execution Sub-Phase occurs if the transfer involves a currency exchange. In this step, the foreign exchange provider, as agreed during the Agreement Phase, executes the currency conversion. The liquidity required for the cross-currency transfer is provided, and the converted funds are prepared for onward movement to the payee DFSP. This sub-phase is an opportunity for the FXP to ensure that the FX rates and fees agreed upon earlier are adhered to, safeguarding the transaction's financial integrity and transparency. + +### 6.1.1 Message flow + + +The sequence diagram shows the transfer example messages in a Payer initiated P2P transfer. +![Conversion Transfer Flow](./SequenceDiagrams/ConversionTransfer.svg) + +### 6.1.2 fxTransfers Resource + +| Endpoint | Message | +| -------- | --- | +|[POST /fxTransfers/{ID}](./script/fxtransfers_POST.md) | **pacs.009.001** | +|[PUT /fxTransfers/{ID}](./script/fxtransfers_PUT.md) | **pacs.002.001.15** | +|[PUT /fxTransfers/{ID}/error](./script/fxtransfers_error_PUT.md) | **pacs.002.001.15** | +|[PATCH /fxTransfers/{ID}/error](./script/fxtransfers_PATCH.md) | **pacs.002.001.15** | + +## 6.2 Transfer Execution and Clearing +The Funds Settlement Sub-Phase involves the actual transfer of funds between the payer DFSP and the payee DFSP. This step ensures that the amount agreed upon, including any associated fees, is accurately cleared in the appropriate accounts. This sub-phase completes the financial transaction, fulfilling the commitments made during the Agreement Phase. Through secure and efficient fund movement mechanisms, this sub-phase ensures that the transfer is completed smoothly and in compliance with the agreed terms. + +### 6.2.1 Message flow + + +The sequence diagram shows the discovery example messages in a Payer initiated P2P transfer. +![Transfer Flow](./SequenceDiagrams/Transfer.svg) + +### 6.2.2 Transfers Resource + +| Endpoint | Message | +| --------- | --- | +|[POST /transfers/{ID}](./script/transfers_POST.md) | **pacs.008.001** | +|[PUT /transfers/{ID}](./script/quotes_PUT.md) | **pacs.002.001.15** | +|[PUT /transfers/{ID}/error](./script/quotes_error_PUT.md) | **pacs.002.001.15** | +|[PATCH /transfers/{ID}/error](./script/transfers_PATCH.md) | **pacs.002.001.15** | + + + + diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml new file mode 100644 index 000000000..175ce5d06 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.plantuml @@ -0,0 +1,96 @@ +@startuml + +Title Discovery ISO 20022 Message Flow +participant PayerDFSP as "Payer DFSP" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "Payee DFSP" + +autonumber + +PayerDFSP -> Mojaloop: POST /quotes +note left +**pacs.081.001.01** +**Financial Institution to Financial Institution** +**Customer Credit Transfer Quote Request** +{ +"GrpHdr": { + "MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y", + "CreDtTm": "2024-11-04T12:57:42.066Z", + "NbOfTxs": "1", + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z", + "SttlmInf": { "SttlmMtd": "CLRG" } + }, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM19DFKNRWC21FGJNTHRAT", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002" }}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}}, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001" }}}, + "Name": "Joe Blogs"}, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}, + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "Purp": { "Prtry": "TRANSFER"}, + "ChrgBr": "CRED"} +} +end note +Mojaloop -> PayeeDFSP: POST /quotes +PayeeDFSP -> PayeeDFSP: Check to see if Payee can receive the payment. +alt if Payee can receive the payment +PayeeDFSP -> Mojaloop: PUT /quotes/{ID} +note right +**pacs.082.001.01** +**Financial Institution to Financial Institution** +**Customer Credit Transfer Quote Response** +"GrpHdr": { + "MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD", + "CreDtTm": "2024-11-04T12:57:42.455Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z" +}, +"CdtTrfTxInf": { "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" }, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001"} } }, + "Name": "Payer Joe" }, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"} } }, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002"} } }, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } }, + "ChrgBr": "CRED", + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080" }, + "InstdAmt": { + "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "1080" }, + "ChrgsInf": { + "Amt": { "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "0" }, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } } }, + "VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." } } +} +end note +Mojaloop -> PayerDFSP: PUT/quotes/{ID} + +else + +PayeeDFSP -> Mojaloop: PUT/quotes/{ID}/error +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +end note +Mojaloop -> PayerDFSP: PUT/quotes/{ID}/error + +end + +@enduml \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg new file mode 100644 index 000000000..bce7b2a4e --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Agreement.svg @@ -0,0 +1 @@ +Discovery ISO 20022 Message FlowPayer DFSPPayer DFSPMojaloopMojaloopPayee DFSPPayee DFSP1POST /quotespacs.081.001.01Financial Institution to Financial Institution Customer Credit Transfer Quote Request{"GrpHdr": {"MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y","CreDtTm": "2024-11-04T12:57:42.066Z","NbOfTxs": "1","PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z","SttlmInf": { "SttlmMtd": "CLRG" }},"CdtTrfTxInf": {"PmtId": {"TxId": "01JBVM19DFKNRWC21FGJNTHRAT","EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"},"Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" },"Id": "16665551002" }}}},"CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}},"Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" },"Id": "16135551001" }}},"Name": "Joe Blogs"},"DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}},"IntrBkSttlmAmt": {"Ccy": "MWK","ActiveCurrencyAndAmount": "1080"},"Purp": { "Prtry": "TRANSFER"},"ChrgBr": "CRED"}}2POST /quotes3Check to see if Payee can receive the payment.alt[if Payee can receive the payment]4PUT /quotes/{ID}pacs.082.001.01Financial Institution to Financial Institution Customer Credit Transfer Quote Response"GrpHdr": {"MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD","CreDtTm": "2024-11-04T12:57:42.455Z","NbOfTxs": "1","SttlmInf": { "SttlmMtd": "CLRG" },"PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z"},"CdtTrfTxInf": { "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" },"Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" },"Id": "16135551001"} } },"Name": "Payer Joe" },"DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"} } },"Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" },"Id": "16665551002"} } },"CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } },"ChrgBr": "CRED","IntrBkSttlmAmt": {"Ccy": "MWK","ActiveCurrencyAndAmount": "1080" },"InstdAmt": {"Ccy": "MWK","ActiveOrHistoricCurrencyAndAmount": "1080" },"ChrgsInf": {"Amt": { "Ccy": "MWK","ActiveOrHistoricCurrencyAndAmount": "0" },"Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"} } } },"VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." } }}5PUT/quotes/{ID}6PUT/quotes/{ID}/errorpacs.002.001.15Financial Institution to Financial Institution Payment Status Report"GrpHdr": {"MsgId":"01JBVM1CGC5A18XQVYYRF68FD1","CreDtTm":"2024-11-04T12:57:45.228Z"},"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}}7PUT/quotes/{ID}/error \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml new file mode 100644 index 000000000..f41bee1ce --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.plantuml @@ -0,0 +1,92 @@ +@startuml + +Title Agreement phase on providing liquidity ISO 20022 Message Flow +participant PayerDFSP as "Payer DFSP" +participant Mojaloop as "Mojaloop" +participant FXP as "Foreign Exchange Provider" + +autonumber + +PayerDFSP -> Mojaloop: POST /fxQuotes +note left +**pacs.091.001.01** +**Financial Institution Credit Transfer Quote Request** +"GrpHdr": { + "MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2", + "CreDtTm": "2024-11-04T12:57:39.427Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM16V1ZXP2DM34BQT40NW9", + "InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" }, + "Dbtr": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** } } }, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": {"Ccy": **"ZMW"**, + "ActiveOrHistoricCurrencyAndAmount": **"21"**}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": **"fxp"**}}}, + "IntrBkSttlmAmt": { "Ccy": **"MWK"**, + "ActiveCurrencyAndAmount": "0"}, + "InstrForCdtrAgt": {"InstrInf": **"SEND"**}} +} +end note +Mojaloop -> FXP: POST /fxQuotes +FXP -> FXP: Check to see if liqidity can be provided \n and provide rates. +alt if FXP can provide the payment liquidity +FXP -> Mojaloop: PUT /fxQuotes/{ID} +note right +**pacs.092.001.01** +**Financial Institution Credit Transfer Quote Response** +{ +"GrpHdr": { + "MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8", + "CreDtTm": "2024-11-04T12:57:39.791Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z"}, +"CdtTrfTxInf": { + "VrfctnOfTerms": {"Sh256Sgntr": **"KVHFmdTD6A..."**}, + "PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "TxId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr": {"FinInstnId": {"Othr": {"Id": **"payer-dfsp"**}}}, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": { "Ccy": **"ZMW"**, + "ActiveOrHistoricCurrencyAndAmount": **"21"**}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": **"fxp"**}}}, + "IntrBkSttlmAmt": {"Ccy": **"MWK"**, + "ActiveCurrencyAndAmount": **"1080"**}, + "InstrForCdtrAgt": {"InstrInf": **"SEND"**}} +} +end note +Mojaloop -> PayerDFSP: PUT /fxQuotes/{ID} + +else + +FXP -> Mojaloop: PUT /fxQuotes/{ID}/error +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +end note +Mojaloop -> PayerDFSP: PUT /fxQuotes/{ID}/error +end + + +@enduml \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg new file mode 100644 index 000000000..13041e821 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/AgreementConversion.svg @@ -0,0 +1 @@ +Agreement phase on providing liquidity ISO 20022 Message FlowPayer DFSPPayer DFSPMojaloopMojaloopForeign Exchange ProviderForeign Exchange Provider1POST /fxQuotespacs.091.001.01Financial Institution Credit Transfer Quote Request"GrpHdr": {"MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2","CreDtTm": "2024-11-04T12:57:39.427Z","NbOfTxs": "1","SttlmInf": { "SttlmMtd": "CLRG" },"PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z"},"CdtTrfTxInf": {"PmtId": {"TxId": "01JBVM16V1ZXP2DM34BQT40NW9","InstrId": "01JBVM16V1ZXP2DM34BQT40NWA","EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" },"Dbtr": { "FinInstnId": { "Othr": { "Id":"payer-dfsp"} } },"UndrlygCstmrCdtTrf": {"Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}},"DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}},"Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}},"CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}},"InstdAmt": {"Ccy":"ZMW","ActiveOrHistoricCurrencyAndAmount":"21"}},"Cdtr": {"FinInstnId": {"Othr": {"Id":"fxp"}}},"IntrBkSttlmAmt": { "Ccy":"MWK","ActiveCurrencyAndAmount": "0"},"InstrForCdtrAgt": {"InstrInf":"SEND"}}}2POST /fxQuotes3Check to see if liqidity can be providedand provide rates.alt[if FXP can provide the payment liquidity]4PUT /fxQuotes/{ID}pacs.092.001.01Financial Institution Credit Transfer Quote Response{"GrpHdr": {"MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8","CreDtTm": "2024-11-04T12:57:39.791Z","NbOfTxs": "1","SttlmInf": { "SttlmMtd": "CLRG" },"PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z"},"CdtTrfTxInf": {"VrfctnOfTerms": {"Sh256Sgntr":"KVHFmdTD6A..."},"PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA","TxId": "01JBVM13SQYP507JB1DYBZVCMF"},"Dbtr": {"FinInstnId": {"Othr": {"Id":"payer-dfsp"}}},"UndrlygCstmrCdtTrf": {"Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}},"DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}},"Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}},"CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}},"InstdAmt": { "Ccy":"ZMW","ActiveOrHistoricCurrencyAndAmount":"21"}},"Cdtr": {"FinInstnId": {"Othr": {"Id":"fxp"}}},"IntrBkSttlmAmt": {"Ccy":"MWK","ActiveCurrencyAndAmount":"1080"},"InstrForCdtrAgt": {"InstrInf":"SEND"}}}5PUT /fxQuotes/{ID}6PUT /fxQuotes/{ID}/errorpacs.002.001.15Financial Institution to Financial Institution Payment Status Report{"GrpHdr": {"MsgId":"01JBVM1CGC5A18XQVYYRF68FD1","CreDtTm":"2024-11-04T12:57:45.228Z"},"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}}}7PUT /fxQuotes/{ID}/error \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml new file mode 100644 index 000000000..a617ecf3f --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.plantuml @@ -0,0 +1,88 @@ +@startuml + +Title Committing to providing Liquidity ISO 20022 Message Flow +participant PayerDFSP as "Payer DFSP" +participant Mojaloop as "Mojaloop" +participant FXP as "Foreign Exchange Provider" + +autonumber + +PayerDFSP -> Mojaloop: POST /fxTransfers +note left +**pacs.009.001.12** +**Execute Financial Institution Credit Transfer** +{ +"GrpHdr":{ + "MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT", + "CreDtTm":"2024-11-04T12:57:44.580Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "UndrlygCstmrCdtTrf":{ + "Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "InstdAmt":{"Ccy":"ZMW", + "ActiveOrHistoricCurrencyAndAmount":"21"}}, + "Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}} +} +end note +Mojaloop -> FXP: POST /fxTransfers +FXP -> FXP: Check to see liquidity for the transfer can still be provided. +alt if FXP can provide the payment liquidity +FXP -> Mojaloop: PUT /fxTransfers/{ID} +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +end note +Mojaloop -> PayerDFSP: PUT /fxTransfers/{ID} + +else + +FXP -> Mojaloop: PUT /fxTransfers/{ID}/error +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}} +end note +Mojaloop -> PayerDFSP: PUT /fxTransfer/{ID}/error +end + +Mojaloop -> Mojaloop: When the determining transfer is committed, \n the FX conversion is committed. + +Mojaloop->FXP: PATCH /fxTransfers/{ID} +note left +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{"PrcgDt":{ + "DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" +end note + +@enduml \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg new file mode 100644 index 000000000..5d8929a8c --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/ConversionTransfer.svg @@ -0,0 +1 @@ +Committing to providing Liquidity ISO 20022 Message FlowPayer DFSPPayer DFSPMojaloopMojaloopForeign Exchange ProviderForeign Exchange Provider1POST /fxTransferspacs.009.001.12Execute Financial Institution Credit Transfer{"GrpHdr":{"MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT","CreDtTm":"2024-11-04T12:57:44.580Z","NbOfTxs":"1","SttlmInf":{"SttlmMtd":"CLRG"},"PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"},"CdtTrfTxInf":{"PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA","EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"},"Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}},"UndrlygCstmrCdtTrf":{"Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}},"DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}},"Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}},"CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}},"InstdAmt":{"Ccy":"ZMW","ActiveOrHistoricCurrencyAndAmount":"21"}},"Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}},"IntrBkSttlmAmt":{"Ccy":"MWK","ActiveCurrencyAndAmount":"1080"},"VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}}}2POST /fxTransfers3Check to see liquidity for the transfer can still be provided.alt[if FXP can provide the payment liquidity]4PUT /fxTransfers/{ID}pacs.002.001.15Financial Institution to Financial Institution Payment Status Report{"GrpHdr": {"MsgId":"01JBVM1CGC5A18XQVYYRF68FD1","CreDtTm":"2024-11-04T12:57:45.228Z"},"TxInfAndSts":{"ExctnConf":"ou1887jmG-l...","PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"},"TxSts":"RESV"}}5PUT /fxTransfers/{ID}6PUT /fxTransfers/{ID}/errorpacs.002.001.15Financial Institution to Financial Institution Payment Status Report"GrpHdr": {"MsgId":"01JBVM1CGC5A18XQVYYRF68FD1","CreDtTm":"2024-11-04T12:57:45.228Z"},"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}7PUT /fxTransfer/{ID}/error8When the determining transfer is committed,the FX conversion is committed.9PATCH /fxTransfers/{ID}pacs.002.001.15Financial Institution to Financial InstitutionPayment Status Report"GrpHdr":{"MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976","CreDtTm":"2024-11-04T12:57:46.828Z"},"TxInfAndSts":{"PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"},"TxSts":"COMM"}}" \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml new file mode 100644 index 000000000..e74db7ddd --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.plantuml @@ -0,0 +1,59 @@ +@startuml + +Title Discovery ISO 20022 Message Flow +participant PayerDFSP as "Payer DFSP" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "Payee DFSP" + +autonumber + +PayerDFSP -> Mojaloop: GET /parties/{type}/{PartyIdentifier} +Mojaloop -> PayeeDFSP: GET /parties/{type}/{PartyIdentifier} +PayeeDFSP -> PayeeDFSP: Validate payees account status. +alt if account active +PayeeDFSP -> Mojaloop: PUT /parties/{type}/{PartyIdentifier} \n Returns supported currencies and account owner details. +note right +**acmt.024.001.04** +**Account Identification Verification Report** +{ +"Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQB5", + "CreDtTm": "2024-11-04T12:57:37.318Z", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfps"** }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** }}}}} +"Rpt": { + "Vrfctn": true, + "OrgnlId": **"MSISDN/16665551002"**, + "UpdtdPtyAndAcctId": {"Pty": {"Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry": **"MSISDN"**}, + "Id": **"16665551002"**}}}, + "Nm": **"Chikondi Banda"**}, + "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfsp"** }}}, + "Acct": { "Ccy": **"MWK"** }} +} +end note +Mojaloop -> PayerDFSP: PUT /parties/{type}/{PartyIdentifier} + +else if account inactive + +PayeeDFSP -> Mojaloop: PUT /parties/{type}/{PartyIdentifier}/error \n Returns error code 3204 Party not found. +note right +**acmt.024.001.04** +**Account Identification Verification Report** +{ + "Assgnmt": { + "Id": 123, + "CreDtTm": "2013-03-07T16:30:00", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payee-dfsp"** }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": **"payer-dfsp"** }}}}}, + "Rpt": { + "Vrfctn": false, + "OrgnlId": **"MSISDN/16665551002"**, + "CreDtTm": "2013-03-07T16:30:00", + "Rsn": { "Prtry": **3204** }} +} +end note +Mojaloop -> PayerDFSP: PUT /parties/{type}/{PartyIdentifier}/error + +end + +@enduml \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg new file mode 100644 index 000000000..a4d5d4587 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Discovery.svg @@ -0,0 +1 @@ +Discovery ISO 20022 Message FlowPayer DFSPPayer DFSPMojaloopMojaloopPayee DFSPPayee DFSP1GET /parties/{type}/{PartyIdentifier}2GET /parties/{type}/{PartyIdentifier}3Validate payees account status.alt[if account active]4PUT /parties/{type}/{PartyIdentifier}Returns supported currencies and account owner details.acmt.024.001.04Account Identification Verification Report{"Assgnmt": {"MsgId": "01JBVM14S6SC453EY9XB9GXQB5","CreDtTm": "2024-11-04T12:57:37.318Z","Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id":"payee-dfps"}}}},"Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id":"payer-dfsp"}}}}}"Rpt": {"Vrfctn": true,"OrgnlId":"MSISDN/16665551002","UpdtdPtyAndAcctId": {"Pty": {"Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry":"MSISDN"},"Id":"16665551002"}}},"Nm":"Chikondi Banda"},"Agt": { "FinInstnId": { "Othr": { "Id":"payee-dfsp"}}},"Acct": { "Ccy":"MWK"}}}5PUT /parties/{type}/{PartyIdentifier}[if account inactive]6PUT /parties/{type}/{PartyIdentifier}/errorReturns error code 3204 Party not found.acmt.024.001.04Account Identification Verification Report{"Assgnmt": {"Id": 123,"CreDtTm": "2013-03-07T16:30:00","Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id":"payee-dfsp"}}}},"Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id":"payer-dfsp"}}}}},"Rpt": {"Vrfctn": false,"OrgnlId":"MSISDN/16665551002","CreDtTm": "2013-03-07T16:30:00","Rsn": { "Prtry":3204}}}7PUT /parties/{type}/{PartyIdentifier}/error \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml new file mode 100644 index 000000000..aafcc570b --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.plantuml @@ -0,0 +1,88 @@ +@startuml + +Title Transfer - ISO 20022 Message Flow +participant PayerDFSP as "Payer DFSP" +participant Mojaloop as "Mojaloop" +participant PayeeDFSP as "Payee DFSP" + +autonumber + +PayerDFSP -> Mojaloop: POST /transfers +note left +**pacs.008.001.13** +**Financial Institution to Financial Institution** +**Customer Credit Transfer** +{ +"GrpHdr":{ + "MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM", + "CreDtTm":"2024-11-04T12:57:45.812Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "ChrgBr":"CRED", + "Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16665551002"}}}}, + "Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16135551001"}}}, + "Name":"Joe Blogs"}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}} +} +end note +Mojaloop -> PayeeDFSP: POST /transfers +PayeeDFSP -> PayeeDFSP: Check to see if Payee can receive the payment. +alt if Payee can receive the payment +PayeeDFSP -> Mojaloop: PUT /transfers/{ID} +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +{ +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{ + "ExctnConf":"-rL3liKeLrsNy7GHJaKgAzeDL_8IVnvER5zUlP1YAoc", + "PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"} +} +end note +Mojaloop -> PayerDFSP: PUT/transfers/{ID} + +else + +Mojaloop -> PayerDFSP: PUT/transfers/{ID}/error +note right +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +end note +end + +Mojaloop->Mojaloop: If transfer fails, is timed-out,\n or is reserved PUT /transfers message. + +Mojaloop->PayeeDFSP: PATCH /transfers/{ID} +note left +**pacs.002.001.15** +**Financial Institution to Financial Institution** +**Payment Status Report** +{ +"GrpHdr":{ + "MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976", + "CreDtTm":"2024-11-04T12:57:46.828Z"}, +"TxInfAndSts":{"PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"}, + "TxSts":"COMM"}}" +} +end note +@enduml \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg new file mode 100644 index 000000000..1358e9c60 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/SequenceDiagrams/Transfer.svg @@ -0,0 +1 @@ +Transfer - ISO 20022 Message FlowPayer DFSPPayer DFSPMojaloopMojaloopPayee DFSPPayee DFSP1POST /transferspacs.008.001.13Financial Institution to Financial Institution Customer Credit Transfer{"GrpHdr":{"MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM","CreDtTm":"2024-11-04T12:57:45.812Z","NbOfTxs":"1","SttlmInf":{"SttlmMtd":"CLRG"},"PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"},"CdtTrfTxInf":{"PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"},"ChrgBr":"CRED","Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"},"Id":"16665551002"}}}},"Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"},"Id":"16135551001"}}},"Name":"Joe Blogs"},"CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}},"DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}},"IntrBkSttlmAmt":{"Ccy":"MWK","ActiveCurrencyAndAmount":"1080"},"VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}}}2POST /transfers3Check to see if Payee can receive the payment.alt[if Payee can receive the payment]4PUT /transfers/{ID}pacs.002.001.15Financial Institution to Financial Institution Payment Status Report{"GrpHdr":{"MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976","CreDtTm":"2024-11-04T12:57:46.828Z"},"TxInfAndSts":{"ExctnConf":"-rL3liKeLrsNy7GHJaKgAzeDL_8IVnvER5zUlP1YAoc","PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"},"TxSts":"COMM"}}5PUT/transfers/{ID}6PUT/transfers/{ID}/errorpacs.002.001.15Financial Institution to Financial Institution Payment Status Report{"GrpHdr": {"MsgId":"01JBVM1CGC5A18XQVYYRF68FD1","CreDtTm":"2024-11-04T12:57:45.228Z"},"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}}}7If transfer fails, is timed-out,or is reserved PUT /transfers message.8PATCH /transfers/{ID}pacs.002.001.15Financial Institution to Financial InstitutionPayment Status Report{"GrpHdr":{"MsgId":"01JBVM1E2CRWFZFPN7W4AZJ976","CreDtTm":"2024-11-04T12:57:46.828Z"},"TxInfAndSts":{"PrcgDt":{"DtTm":"2024-11-04T12:57:46.812Z"},"TxSts":"COMM"}}"} \ No newline at end of file diff --git a/docs/product/features/Iso20022/v1.0/script/fxquotes_POST.md b/docs/product/features/Iso20022/v1.0/script/fxquotes_POST.md new file mode 100644 index 000000000..678514b71 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxquotes_POST.md @@ -0,0 +1,779 @@ +## 7.4 POST /fxQuotes/ +| Financial Institution Credit Transfer Quote Request - **pacs.091.001.01**| +|--| + +#### Context +*(DFSP -> FXP)* + +This message is initiated by a DFSP who is requesting liquidity cover in another currency to fund a transfer. The message is sent to a foreign exchange provider and is a request for conversion terms. The source currency is specified in `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.Ccy` and the target currency is specified in `CdtTrfTxInf.IntrBkSttlmAmt.Ccy`. + +#### Conversion Type `SEND` +If the `CdtTrfTxInf.InstrForCdtrAgt.InstrInf` is defined as `SEND`, then the source currency amount is expected to be defined `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount`, and the target currency amount will be calculated based on the source currency amount and fees. (The target amount `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` should be specified as 0 and will not be used in the calculation.) + +#### Conversion Type `RECEIVE` +If the `CdtTrfTxInf.InstrForCdtrAgt.InstrInf` is defined as `RECEIVE`, then the target currency amount is expected to be defined `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount`, and the source currency amount will be calculated based on the target currency amount and fees. (The source amount `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount` should be specified as 0 and will not be used in the calculation.) + +In this phase of the transfer all participants to agree on the terms, and are expected to validate whether the transfer will be able to proceed. The Foreign Exchange provider is expected to respond to this request with a PUT /fxQuotes callback. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId": "01JBVM16V3Q4MSV8KTG0BRJGZ2", + "CreDtTm": "2024-11-04T12:57:39.427Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM16V1ZXP2DM34BQT40NW9", + "InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF" }, + "Dbtr": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" } } }, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": {"Ccy": "ZMW", + "ActiveOrHistoricCurrencyAndAmount": "21"}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "IntrBkSttlmAmt": { "Ccy": "MWK", + "ActiveCurrencyAndAmount": "0"}, + "InstrForCdtrAgt": {"InstrInf": "SEND"}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - FxRequest_FICreditTransferProposal[1..1]Credit Transfer Transaction Information
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstrForCdtrAgt - InstructionForCreditorAgent[1..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Purp - Purpose[0..1]Underlying reason for the payment transaction.
             Cd - Code[0..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[0..1]
    Purpose, in a proprietary form.
         RmtInf - RemittanceInformation2[0..0]
         UndrlygAllcn - TransactionAllocation1[0..0]
         UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
    TBD
             UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
             InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
             RmtInf - RemittanceInformation22[0..0]
             InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxquotes_PUT.md b/docs/product/features/Iso20022/v1.0/script/fxquotes_PUT.md new file mode 100644 index 000000000..7f13e852d --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxquotes_PUT.md @@ -0,0 +1,776 @@ +## 7.5 PUT /fxQuotes/{ID} +|Financial Institution Credit Transfer Quote Response - **pacs.092.001.01**| +|--| + +#### Context +*(FXP -> DFSP)* + +This is triggered as a callback response to the POST /fxQuotes call. The message is generated by the foreign exchange provider and is a message response that includes the conversion terms. The FXP is expected to respond with this message if a terms requested are favorable and the FXP would like to participate in the transaction. + +The source currency amount is expected to be defined `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount`, and the target currency amount is provided in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` field. These are clearing amounts and must have fees already included in their calculation. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the terms presented. It is the responsibility of the FXP to enforce this expiry in the transfer phase of a transaction. + +The `CdtTrfTxInf.VrfctnOfTerms.Sh256Sgntr` must contain the ILPv4 cryptographically signed condition, which is a cryptographic version of the conversion terms. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId": "01JBVM176FTHB9F2ZQJJ7AFCN8", + "CreDtTm": "2024-11-04T12:57:39.791Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:39.425Z" +}, +"CdtTrfTxInf": { + "VrfctnOfTerms": {"Sh256Sgntr": "KVHFmdTD6A..."}, + "PmtId": {"InstrId": "01JBVM16V1ZXP2DM34BQT40NWA", + "TxId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "UndrlygCstmrCdtTrf": { + "Dbtr": {"Id": {"OrgId": {"Othr": {"Id": "payer-dfsp"}}}}, + "DbtrAgt": {"FinInstnId": {"Othr": {"Id": "payer-dfsp"}}}, + "Cdtr": {"Id": {"OrgId": {"Othr": {"Id": "fxp"}}}}, + "CdtrAgt": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "InstdAmt": { "Ccy": "ZMW", + "ActiveOrHistoricCurrencyAndAmount": "21"}}, + "Cdtr": {"FinInstnId": {"Othr": {"Id": "fxp"}}}, + "IntrBkSttlmAmt": {"Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "InstrForCdtrAgt": {"InstrInf": "SEND"}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction68_FX_Quotes[1..1]Set of elements providing information specific to the individual credit transfer(s).
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstrForCdtrAgt - InstructionForCreditorAgent[1..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Purp - Purpose[0..1]Underlying reason for the payment transaction.
             Cd - Code[0..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[0..1]
    Purpose, in a proprietary form.
         RmtInf - RemittanceInformation2[0..0]
         UndrlygAllcn - TransactionAllocation1[0..0]
         UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
    TBD
             UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
             InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
             RmtInf - RemittanceInformation22[0..0]
             InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md b/docs/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md new file mode 100644 index 000000000..e1c8da125 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxquotes_error_PUT.md @@ -0,0 +1,180 @@ + +## 7.6 PUT /fxQuotes/{ID}/error + +|Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15** | +|--| + +#### Context +*(DFSP -> FXP, FXP -> DFSP, HUB -> DFSP, HUB -> FXP)* + +This is triggered as a callback response to the POST /fxQuotes call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, the HUB, or the FPX. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[1..1]Specifies the reason for the status report.
                 Cd - Code[1..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[0..1]Specified date.
             DtTm - DateTime[0..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md b/docs/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md new file mode 100644 index 000000000..84574f8b1 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxtransfers_PATCH.md @@ -0,0 +1,182 @@ +## 7.13 PATCH /fxTransfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(HUB -> FXP)* + +This message use by the HUB to inform the foreign exchange provider participant in a cross currency transfer of the successful conclusion of the conversion. This message is only generated if the dependent transfer is committed in the hub. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "PrcgDt":{ + "DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"COMM"} +} +``` + +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[1..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[0..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[0..1]Specifies the reason for the status report.
                 Cd - Code[0..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[0..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[1..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[1..1]Specified date.
             DtTm - DateTime[1..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxtransfers_POST.md b/docs/product/features/Iso20022/v1.0/script/fxtransfers_POST.md new file mode 100644 index 000000000..1124263f3 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxtransfers_POST.md @@ -0,0 +1,776 @@ +## 7.10 POST /fxTransfers +| Execute Financial Institution Credit Transfer - **pacs.009.001.12**| +|--| + +#### Context +*(DFSP -> FXP)* + +This message is initiated by a DFSP who is requesting to transfer funds in another currency. The message is sent to the foreign exchange provider who provided the conversion terms. This message is an acknowledgement that the terms of the conversion are accepted, and is thus an instruction to proceed with the conversion. + +The source amount and currency are defined here `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.ActiveOrHistoricCurrencyAndAmount` and here `CdtTrfTxInf.UndrlygCstmrCdtTrf.InstdAmt.Ccy`, and the target amount and currency are defined `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and here `CdtTrfTxInf.IntrBkSttlmAmt.Ccy`. + +This message includes can be seen as an agreement to the terms that have previously been set up and established in the fxQuotes resource. The `CdtTrfTxInf.UndrlygCstmrCdtTrf.VrfctnOfTerms.Sh256Sgntr` field is a reference to the ILPv4 cryptographic condition of those terms. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the this transfer message. It is the responsibility of the HUB to enforce this expiry. The status of which a DFSP can query by making a `GET /fxTransfers/{ID}` request. + +The currency conversion is dependent on a transfer (the determiningTransferId) and is specified in the `CdtTrfTxInf.PmtId.EndToEndId` field. + +Here is an example of the message: +```json +{ +"GrpHdr":{ + "MsgId":"01JBVM1BW4J0RJZSQ539QB9TKT", + "CreDtTm":"2024-11-04T12:57:44.580Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:44.579Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM16V1ZXP2DM34BQT40NWA", + "EndToEndId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "Dbtr":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "UndrlygCstmrCdtTrf":{ + "Dbtr":{"Id":{"OrgId":{"Othr":{"Id":"payer-dfsp"}}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "Cdtr":{"Id":{"OrgId":{"Othr":{"Id":"fxp"}}}}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "InstdAmt":{"Ccy":"ZMW", + "ActiveOrHistoricCurrencyAndAmount":"21"}}, + "Cdtr":{"FinInstnId":{"Othr":{"Id":"fxp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"Sh256Sgntr":"KVHFmdTD6A..."}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader.[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransactionInformation.[1..1]Set of elements providing information specific to the individual credit transfer(s).
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAcct - DebtorAccount[0..1]Account used to process a payment.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[0..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[0..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[0..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAcct - CreditorAccount[0..1]Account to which a credit entry is made.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
         Purp - Purpose[0..1]Underlying reason for the payment transaction.
             Cd - Code[0..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[0..1]
    Purpose, in a proprietary form.
         RmtInf - RemittanceInformation2[0..0]
         UndrlygAllcn - TransactionAllocation1[0..0]
         UndrlygCstmrCdtTrf - CreditTransferTransaction63[1..1]Underlying Customer Credit Transfer
    TBD
             UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             Dbtr - PartyIdentification272[1..1]Party that owes an amount of money to the (ultimate) creditor.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             DbtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             DbtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the debtor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
             IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
             CdtrAgt - BranchAndFinancialInstitutionIdentification8[1..1]Financial institution servicing an account for the creditor.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             Cdtr - PartyIdentification272[1..1]Party to which an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             CdtrAcct - CashAccount40[0..0]Provides the details to identify an account.
             UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
             InstrForCdtrAgt - InstructionForCreditorAgent3[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor agent.
             InstrForNxtAgt - InstructionForNextAgent1[0..0]Further information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             Tax - TaxData1[0..0]Details about tax paid, or to be paid, to the government in accordance with the law, including pre-defined parameters such as thresholds and type of account.
             RmtInf - RemittanceInformation22[0..0]
             InstdAmt - InstructedAmount[1..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md b/docs/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md new file mode 100644 index 000000000..782654982 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxtransfers_PUT.md @@ -0,0 +1,98 @@ +## 7.11 PUT /fxTransfers/{ID} + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(FXP -> DFSP)* + +This message is a response to the `POST \fxTransfers` call initiated by the DFSP who is requesting to proceed with the conversion terms presented in the `PUT \fxquotes`. It is the FXP's responsibility to check that the clearing amounts align with the agreed conversion terms, and if all requirements are met, use this message to lock-in the agreed terms. Once the hub receives this acceptance message, the conversion can no-longer timeout. Final completion of the conversion will only occur once the dependent transfer is committed. + +The cryptographic ILP fulfillment provided in the `TxInfAndSts.ExctnConf` field, is released by the FXP as an indication to the HUB that the terms have been met. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader113[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[0..0]Specifies a numeric string with a maximum length of 15 digits.
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - SettlementInstruction15[0..0]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction62[0..0]
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md b/docs/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md new file mode 100644 index 000000000..1e636b8c1 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/fxtransfers_error_PUT.md @@ -0,0 +1,178 @@ +## 7.12 PUT /fxTransfers/{ID}/error + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(FXP -> DFSP, FXP -> HUB, DFSP -> HUB, DFSP -> FXP, HUB -> DFSP)* + +This is triggered as a callback response to the POST /fxTransfers call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[1..1]Specifies the reason for the status report.
                 Cd - Code[1..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[0..1]Specified date.
             DtTm - DateTime[0..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    diff --git a/docs/product/features/Iso20022/v1.0/script/parties_GET.md b/docs/product/features/Iso20022/v1.0/script/parties_GET.md new file mode 100644 index 000000000..32017ee06 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/parties_GET.md @@ -0,0 +1,9 @@ +## 7.1 GET /parties/{type}/{partyIdentifier}[/{subId}] +The GET /parties endpoint does not support or require a payload, and can be seen as an instruction to trigger an Account identification Verification report. +- **{type}** - Party identifier types
    +The **{type}** refers to the classification of the party Identifier type. Each scheme only supports a limited number of these codes. The codes supported by the scheme may be derived from the ISO 20022 external organisation or personal identification codes, or they could be FSPIOP supported codes. The full list of supported codes is available in the [**Appendix A**](../Appendix.md). + - **partyIdentifier**
    + This is the party identifier of the party being represented and of the type specified by the {type} above. + - **{subId}**
    + This represent a sub-identifier or sub-type for the party that some implementations require in order to ensure uniqueness of the identifier. + diff --git a/docs/product/features/Iso20022/v1.0/script/parties_PUT.md b/docs/product/features/Iso20022/v1.0/script/parties_PUT.md new file mode 100644 index 000000000..1fd19e0c0 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/parties_PUT.md @@ -0,0 +1,676 @@ +## 7.2 PUT /Parties/{type}/{partyIdentifier}[/{subId}] +|**Account Identification Verification Report - acmt.024.001.04**| +|--| + +#### Context +*(DFSP -> DFSP)* + +This is triggers as a callback response to the GET /parties call. The message is between DFSPs connected in the scheme and is a check that validates that the account represented is active. + +Here is an example of the message: +``` json +{ +"Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQB5", + "CreDtTm": "2024-11-04T12:57:37.318Z", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfps" }}}}, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}}}, +"Rpt": { + "Vrfctn": true, + "OrgnlId": "MSISDN/16665551002", + "UpdtdPtyAndAcctId": { + "Pty": { + "Id": {"PrvtId": {"Othr": {"SchmeNm": {"Prtry": "MSISDN"}, + "Id": "16665551002"}}}, + "Nm": "Chikondi Banda"}, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp" }}}, + "Acct": { "Ccy": "MWK" }}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    Assgnmt - Assignment[1..1]Identifies the identification assignment.
         MsgId - MessageIdentification[1..1]Unique identification, as assigned by the assigner, to unambiguously identify the message.
         CreDtTm - CreationDateTime[1..1]Date and time at which the identification assignment was created.
         Cretr - Party50Choice[0..0]
         FrstAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         Assgnr - Assignor[1..1]Party that assigns the identification assignment to another party. This is also the sender of the message.
             Pty - Party[1..1]Identification of a person or an organisation.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Agt - Agent[1..1]Identification of a financial institution.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
         Assgne - Assignee[1..1]Party that the identification assignment is assigned to. This is also the receiver of the message.
             Pty - Party[1..1]Identification of a person or an organisation.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Agt - Agent[1..1]Identification of a financial institution.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
    OrgnlAssgnmt - MessageIdentification8[0..0]
    Rpt - Report[1..1]Information concerning the verification of the identification data for which verification was requested.
         OrgnlId - OriginalIdentification[1..1]Unique identification, as assigned by a sending party, to unambiguously identify the party and account identification information group within the original message.
         Vrfctn - Verification[1..1]Identifies whether the party and/or account information received is correct. Boolean value.
         Rsn - Reason[0..1]Specifies the reason why the verified identification information is incorrect.
             Cd - Code[0..1]Reason why the verified identification information is incorrect, as published in an external reason code list.
             Prtry - Proprietary[0..1]Reason why the verified identification information is incorrect, in a free text form.
         OrgnlPtyAndAcctId - OriginalPartyAndAccountIdentification[0..1]Provides party and/or account identification information as given in the original message.
             Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Acct - Account[0..1]Unambiguous identification of the account of a party.
                 Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                     IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                     Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 Tp - Type[0..1]Specifies the nature, or use of the account.
                     Cd - Code[0..1]Account type, in a coded form.
                     Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
                 Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
                 Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
                 Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                     Tp - Type[0..1]Type of the proxy identification.
                         Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                     Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
             Agt - Agent[0..1]Financial institution servicing an account for a party.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
         UpdtdPtyAndAcctId - UpdatedPartyAndAccountIdentification[1..1]Provides party and/or account identification information.
             Pty - Party[1..1]Account owner that owes an amount of money or to whom an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Acct - Account[0..1]Unambiguous identification of the account of a party.
                 Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                     IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                     Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 Tp - Type[0..1]Specifies the nature, or use of the account.
                     Cd - Code[0..1]Account type, in a coded form.
                     Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
                 Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
                 Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
                 Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                     Tp - Type[0..1]Type of the proxy identification.
                         Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                     Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
             Agt - Agent[0..1]Financial institution servicing an account for a party.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
    SplmtryData - SupplementaryData[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/parties_error_PUT.md b/docs/product/features/Iso20022/v1.0/script/parties_error_PUT.md new file mode 100644 index 000000000..3d7111c9c --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/parties_error_PUT.md @@ -0,0 +1,675 @@ + +## 7.3 PUT /parties/{type}/{partyIdentifier}[/{subId}]/error +|**Account Identification Verification Report - acmt.024.001.04**| +|--| + +#### Context +*(DFSP -> DFSP)* + +This is triggered as a callback response to the GET /parties call when an error occurs. The message is between DFSPs connected in the scheme and indicates an error in the account verification process. All DFSP participating the the scheme are expected to respond with this message. + +Here is an example of the message: +```json +{ + "Assgnmt": { + "MsgId": "01JBVM14S6SC453EY9XB9GXQBW", + "CreDtTm": "2013-03-07T16:30:00", + "Assgnr": { "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp" } } } }, + "Assgne": { "Agt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" } } } } + }, + "Rpt": { + "Vrfctn": false, + "OrgnlId": "MSISDN/16665551002", + "CreDtTm": "2013-03-07T16:30:00", + "Rsn": { "Prtry": 3204 } + } +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    Assgnmt - Assignment[1..1]Information related to the identification assignment.
         MsgId - MessageIdentification[1..1]Unique identification, as assigned by the assigner, to unambiguously identify the message.
         CreDtTm - CreationDateTime[1..1]Date and time at which the identification assignment was created.
         Cretr - Party50Choice[0..0]
         FrstAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         Assgnr - Assignor[1..1]Party that assigns the identification assignment to another party. This is also the sender of the message.
             Pty - Party[1..1]Identification of a person or an organisation.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Agt - Agent[1..1]Identification of a financial institution.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
         Assgne - Assignee[1..1]Party that the identification assignment is assigned to. This is also the receiver of the message.
             Pty - Party[1..1]Identification of a person or an organisation.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[1..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[1..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Agt - Agent[1..1]Identification of a financial institution.
                 FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[1..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
    OrgnlAssgnmt - MessageIdentification8[0..0]
    Rpt - Report[1..1]Information concerning the verification of the identification data for which verification was requested.
         OrgnlId - OriginalIdentification[1..1]Unique identification, as assigned by a sending party, to unambiguously identify the party and account identification information group within the original message.
         Vrfctn - Verification[1..1]Identifies whether the party and/or account information received is correct. Boolean value.
         Rsn - Reason[1..1]Specifies the reason why the verified identification information is incorrect.
             Cd - Code[1..1]Reason why the verified identification information is incorrect, as published in an external reason code list.
             Prtry - Proprietary[1..1]Reason why the verified identification information is incorrect, in a free text form.
         OrgnlPtyAndAcctId - OriginalPartyAndAccountIdentification[0..1]Provides party and/or account identification information as given in the original message.
             Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Acct - Account[0..1]Unambiguous identification of the account of a party.
                 Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                     IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                     Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 Tp - Type[0..1]Specifies the nature, or use of the account.
                     Cd - Code[0..1]Account type, in a coded form.
                     Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
                 Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
                 Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
                 Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                     Tp - Type[0..1]Type of the proxy identification.
                         Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                     Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
             Agt - Agent[0..1]Financial institution servicing an account for a party.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
         UpdtdPtyAndAcctId - UpdatedPartyAndAccountIdentification[0..1]Provides party and/or account identification information.
             Pty - Party[0..1]Account owner that owes an amount of money or to whom an amount of money is due.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous way to identify an organisation.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Max256Text[0..1]Identification for an organisation. FSPIOP equivalent to Party Identifier for an organisation in ISO 20022. Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - PrivateIdentification[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryOfResidence[0..1]Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - ContactDetails[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Name prefix to be used before the name of the person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - Max2048Text[0..0]Specifies a character string with a maximum length of 2048 characters.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - Other[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredMethod[0..1]Preferred method used to reach the contact.
             Acct - Account[0..1]Unambiguous identification of the account of a party.
                 Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                     IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                     Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 Tp - Type[0..1]Specifies the nature, or use of the account.
                     Cd - Code[0..1]Account type, in a coded form.
                     Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
                 Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
                 Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
                 Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                     Tp - Type[0..1]Type of the proxy identification.
                         Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                     Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
             Agt - Agent[0..1]Financial institution servicing an account for a party.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Definition: Identifies a specific branch of a financial institution.
    Usage: This component should be used in case the identification information in the financial institution component does not provide identification up to branch level.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEIIdentifier[0..1]Legal Entity Identifier
    Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
    SplmtryData - SupplementaryData[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + + diff --git a/docs/product/features/Iso20022/v1.0/script/quotes_POST.md b/docs/product/features/Iso20022/v1.0/script/quotes_POST.md new file mode 100644 index 000000000..6cf8c9c88 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/quotes_POST.md @@ -0,0 +1,631 @@ +## 7.7 POST /quotes +|**Financial Institution to Financial Institution Customer Credit Transfer Quote Request - pacs.081.001.01**| +|--| + +#### Context +*(DFSP -> DFSP)* + +This request for quote message that is initiated by the payer DFSP who is requesting the payee DFSP to provide the terms of the transfer. The reply to this request is a callback made on the PUT /quotes endpoint. In this phase of the transfer all participants present and agree on the terms of the transfer, and are expected to validate whether the transfer will be able to proceed. + +If this transaction includes currency conversion, then the transfer amount and currency specified must be in target currency. The transfer amounts is specified in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` fields. +Both the `ChrgBr` type `CRED` and `DEBT` are supported. +#### Charge Type `CRED` +If the `CdtTrfTxInf.ChrgBr` is defined as `CRED`, then the transfer amount is expected to remain the same in the returned transfer terms and the payee party receive amount is adjusted to account for any fees. + +#### Charge Type `DEBT` +If the `CdtTrfTxInf.ChrgBr` is defined as `DEBT`, then the amount the payee party receives must equal the transfer amount specified. The transfer amount in returned transfer terms is adjusted to account for any fees. + +The Identifier for this request must be a ULID generated identifier and is specified in the `CdtTrfTxInf.PmtId.TxId` field. If this transfer is part of a wider transaction, then that too is represented by a ULID specified in the `CdtTrfTxInf.PmtId.EndToEndId` field. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId": "01JBVM19DJQ96BS9X6VA5AMW2Y", + "CreDtTm": "2024-11-04T12:57:42.066Z", + "NbOfTxs": "1", + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.063Z", + "SttlmInf": { "SttlmMtd": "CLRG" } + }, +"CdtTrfTxInf": { + "PmtId": { + "TxId": "01JBVM19DFKNRWC21FGJNTHRAT", + "EndToEndId": "01JBVM13SQYP507JB1DYBZVCMF"}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002" }}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "test-mwk-dfsp" }}}, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001" }}}, + "Name": "Joe Blogs"}, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp" }}}, + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080"}, + "Purp": { "Prtry": "TRANSFER"}, + "ChrgBr": "CRED"} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
    date and a mandatory time component, expressed in either UTC time
    format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
    (YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
    (YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
    "XML Schema Part 2: Datatypes Second Edition -
    W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

    Note on the time format:
    1) beginning / end of calendar day
    00:00:00 = the beginning of a calendar day
    24:00:00 = the end of a calendar day

    2) fractions of second in time format
    Decimal fractions of seconds may be included. In this case, the
    involved parties shall agree on the maximum number of digits that are allowed.
         PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
         ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
         ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
             Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
             Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             Tp - Type[0..1]Defines the type of charges.
                 Cd - Code[0..1]Charge type, in a coded form.
                 Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                     Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         MndtRltdInf - CreditTransferMandateData1[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
         Purp - Purpose[1..1]Underlying reason for the payment transaction.
             Cd - Code[1..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[1..1]
    Purpose, in a proprietary form.
         RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
             DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Authrty - Authority[0..1]
    Entity requiring the regulatory reporting information.
                 Nm - Name[0..1]
    Name of the entity requiring the regulatory reporting information.
                 Ctry - Country[0..1]
    Country of the entity that requires the regulatory reporting information.
             Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
                 Tp - Type[0..1]
    Specifies the type of the information supplied in the regulatory reporting details.
                 Dt - Date[0..1]
    Date related to the specified type of regulatory reporting details.
                 Ctry - Country[0..1]
    Country related to the specified type of regulatory reporting details.
                 Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
                 Amt - Amount[0..1]
    Amount of money to be reported for regulatory and statutory requirements.
                 Inf - Information[0..1]
    Additional details that cater for specific domestic regulatory requirements.
         Tax - Tax[0..1]Provides details on the tax.
             Cdtr - Creditor[0..1]
    Party on the credit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the creditor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
             Dbtr - Debtor[0..1]
    Party on the debit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             UltmtDbtr - UltimateDebtor[0..1]
    Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             AdmstnZone - AdministrationZone[0..1]
    Territorial part of a country to which the tax payment is related.
             RefNb - ReferenceNumber[0..1]
    Tax reference information that is specific to a taxing agency.
             Mtd - Method[0..1]
    Method used to indicate the underlying business or how the tax is paid.
             TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
    Total amount of money on which the tax is based.
             TtlTaxAmt - TotalTaxAmount[0..1]
    Total amount of money as result of the calculation of the tax.
             Dt - Date[0..1]
    Date by which tax is due.
             SeqNb - SequenceNumber[0..1]
    Sequential number of the tax report.
             Rcrd - Record[0..1]
    Details of the tax record.
                 Tp - Type[0..1]
    High level code to identify the type of tax details.
                 Ctgy - Category[0..1]
    Specifies the tax code as published by the tax authority.
                 CtgyDtls - CategoryDetails[0..1]
    Provides further details of the category tax code.
                 DbtrSts - DebtorStatus[0..1]
    Code provided by local authority to identify the status of the party that has drawn up the settlement document.
                 CertId - CertificateIdentification[0..1]
    Identification number of the tax report as assigned by the taxing authority.
                 FrmsCd - FormsCode[0..1]
    Identifies, in a coded form, on which template the tax report is to be provided.
                 Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                     Yr - Year[0..1]
    Year related to the tax payment.
                     Tp - Type[0..1]
    Identification of the period related to the tax payment.
                     FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                         FrDt - FromDate[0..1]Start date of the range.
                         ToDt - ToDate[0..1]End date of the range.
                 TaxAmt - TaxAmount[0..1]
    Set of elements used to provide information on the amount of the tax record.
                     Rate - Rate[0..1]
    Rate used to calculate the tax.
                     TaxblBaseAmt - TaxableBaseAmount[0..1]
    Amount of money on which the tax is based.
                     TtlAmt - TotalAmount[0..1]
    Total amount that is the result of the calculation of the tax for the record.
                     Dtls - Details[0..1]
    Set of elements used to provide details on the tax period and amount.
                         Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                             Yr - Year[0..1]
    Year related to the tax payment.
                             Tp - Type[0..1]
    Identification of the period related to the tax payment.
                             FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                                 FrDt - FromDate[0..1]Start date of the range.
                                 ToDt - ToDate[0..1]End date of the range.
                         Amt - Amount[0..1]
    Underlying tax amount related to the specified period.
                 AddtlInf - AdditionalInformation[0..1]
    Further details of the tax record.
         RltdRmtInf - RemittanceLocation8[0..0]
         RmtInf - RemittanceInformation22[0..0]
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/quotes_PUT.md b/docs/product/features/Iso20022/v1.0/script/quotes_PUT.md new file mode 100644 index 000000000..c48d358c7 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/quotes_PUT.md @@ -0,0 +1,634 @@ +## 7.8 PUT /quotes/{ID} +|Financial Institution to Financial Institution Customer Credit Transfer Quote Response - **pacs.082.001.01**| +|--| + +#### Context +*(DFSP -> DFSP)* + +This is triggered as a callback response to the POST /quotes call. The message is generated by the payee DFSP and is a message response that includes the transfer terms. The payee DFSP is expected to respond with this message if a terms requested are favorable and the payee DFSP would like to participate in the transaction. + +The transfer amounts is specified in the `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` and the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` fields. These are clearing amounts and must have fees already included in their calculation. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the terms presented. It is the responsibility of the payee DFSP to enforce this expiry in the transfer phase of a transaction. + +The `CdtTrfTxInf.PmtId.TxId` must reference the message that this is a response to and is the same as what is included in the path as `{ID}`. + +The `CdtTrfTxInf.VrfctnOfTerms.IlpV4PrepPacket` must contain the ILPv4 cryptographically signed packet, which is a cryptographic version of the transfers terms. These are the terms against with the payer DFSP agrees, and against which the non-repudiation of the transfer is base. It is thus important that the payer DFSP inspects these terms. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId": "01JBVM19SPQAQV9EEP0QC1RNAD", + "CreDtTm": "2024-11-04T12:57:42.455Z", + "NbOfTxs": "1", + "SttlmInf": { "SttlmMtd": "CLRG" }, + "PmtInstrXpryDtTm": "2024-11-04T12:58:42.450Z" +}, +"CdtTrfTxInf": { + "PmtId": { "TxId": "01JBVM19DFKNRWC21FGJNTHRAT" }, + "Dbtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16135551001"}}}, + "Name": "Payer Joe" }, + "DbtrAgt": { "FinInstnId": { "Othr": { "Id": "payer-dfsp"}}}, + "Cdtr": { "Id": { "PrvtId": { "Othr": { "SchmeNm": { "Prtry": "MSISDN" }, + "Id": "16665551002"}}}, + "CdtrAgt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"}}}, + "ChrgBr": "CRED", + "IntrBkSttlmAmt": { + "Ccy": "MWK", + "ActiveCurrencyAndAmount": "1080" }, + "InstdAmt": { + "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "1080" }, + "ChrgsInf": { + "Amt": { "Ccy": "MWK", + "ActiveOrHistoricCurrencyAndAmount": "0" }, + "Agt": { "FinInstnId": { "Othr": { "Id": "payee-dfsp"}}}}, + "VrfctnOfTerms": { "IlpV4PrepPacket": "DIICzQAAAA..." }}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
    Set of elements providing information specific to the individual credit transfer(s).
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
    date and a mandatory time component, expressed in either UTC time
    format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
    (YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
    (YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
    "XML Schema Part 2: Datatypes Second Edition -
    W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

    Note on the time format:
    1) beginning / end of calendar day
    00:00:00 = the beginning of a calendar day
    24:00:00 = the end of a calendar day

    2) fractions of second in time format
    Decimal fractions of seconds may be included. In this case, the
    involved parties shall agree on the maximum number of digits that are allowed.
         PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
         ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
         ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
             Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
             Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             Tp - Type[0..1]Defines the type of charges.
                 Cd - Code[0..1]Charge type, in a coded form.
                 Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                     Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         MndtRltdInf - CreditTransferMandateData1[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
         Purp - Purpose[0..1]Underlying reason for the payment transaction.
             Cd - Code[0..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[0..1]
    Purpose, in a proprietary form.
         RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
             DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Authrty - Authority[0..1]
    Entity requiring the regulatory reporting information.
                 Nm - Name[0..1]
    Name of the entity requiring the regulatory reporting information.
                 Ctry - Country[0..1]
    Country of the entity that requires the regulatory reporting information.
             Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
                 Tp - Type[0..1]
    Specifies the type of the information supplied in the regulatory reporting details.
                 Dt - Date[0..1]
    Date related to the specified type of regulatory reporting details.
                 Ctry - Country[0..1]
    Country related to the specified type of regulatory reporting details.
                 Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
                 Amt - Amount[0..1]
    Amount of money to be reported for regulatory and statutory requirements.
                 Inf - Information[0..1]
    Additional details that cater for specific domestic regulatory requirements.
         Tax - Tax[0..1]Provides details on the tax.
             Cdtr - Creditor[0..1]
    Party on the credit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the creditor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
             Dbtr - Debtor[0..1]
    Party on the debit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             UltmtDbtr - UltimateDebtor[0..1]
    Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             AdmstnZone - AdministrationZone[0..1]
    Territorial part of a country to which the tax payment is related.
             RefNb - ReferenceNumber[0..1]
    Tax reference information that is specific to a taxing agency.
             Mtd - Method[0..1]
    Method used to indicate the underlying business or how the tax is paid.
             TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
    Total amount of money on which the tax is based.
             TtlTaxAmt - TotalTaxAmount[0..1]
    Total amount of money as result of the calculation of the tax.
             Dt - Date[0..1]
    Date by which tax is due.
             SeqNb - SequenceNumber[0..1]
    Sequential number of the tax report.
             Rcrd - Record[0..1]
    Details of the tax record.
                 Tp - Type[0..1]
    High level code to identify the type of tax details.
                 Ctgy - Category[0..1]
    Specifies the tax code as published by the tax authority.
                 CtgyDtls - CategoryDetails[0..1]
    Provides further details of the category tax code.
                 DbtrSts - DebtorStatus[0..1]
    Code provided by local authority to identify the status of the party that has drawn up the settlement document.
                 CertId - CertificateIdentification[0..1]
    Identification number of the tax report as assigned by the taxing authority.
                 FrmsCd - FormsCode[0..1]
    Identifies, in a coded form, on which template the tax report is to be provided.
                 Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                     Yr - Year[0..1]
    Year related to the tax payment.
                     Tp - Type[0..1]
    Identification of the period related to the tax payment.
                     FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                         FrDt - FromDate[0..1]Start date of the range.
                         ToDt - ToDate[0..1]End date of the range.
                 TaxAmt - TaxAmount[0..1]
    Set of elements used to provide information on the amount of the tax record.
                     Rate - Rate[0..1]
    Rate used to calculate the tax.
                     TaxblBaseAmt - TaxableBaseAmount[0..1]
    Amount of money on which the tax is based.
                     TtlAmt - TotalAmount[0..1]
    Total amount that is the result of the calculation of the tax for the record.
                     Dtls - Details[0..1]
    Set of elements used to provide details on the tax period and amount.
                         Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                             Yr - Year[0..1]
    Year related to the tax payment.
                             Tp - Type[0..1]
    Identification of the period related to the tax payment.
                             FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                                 FrDt - FromDate[0..1]Start date of the range.
                                 ToDt - ToDate[0..1]End date of the range.
                         Amt - Amount[0..1]
    Underlying tax amount related to the specified period.
                 AddtlInf - AdditionalInformation[0..1]
    Further details of the tax record.
         RltdRmtInf - RemittanceLocation8[0..0]
         RmtInf - RemittanceInformation22[0..0]
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/quotes_error_PUT.md b/docs/product/features/Iso20022/v1.0/script/quotes_error_PUT.md new file mode 100644 index 000000000..17eb44914 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/quotes_error_PUT.md @@ -0,0 +1,180 @@ + +## 7.9 PUT /quotes/{ID}/error +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(DFSP -> DFSP, HUB -> DFSP)* + +This is triggered as a callback response to the POST /quotes call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` + +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[1..1]Specifies the reason for the status report.
                 Cd - Code[1..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[0..1]Specified date.
             DtTm - DateTime[0..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/transfers_PATCH.md b/docs/product/features/Iso20022/v1.0/script/transfers_PATCH.md new file mode 100644 index 000000000..d72267e16 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/transfers_PATCH.md @@ -0,0 +1,180 @@ +## 7.17 PATCH /transfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(HUB -> DFSP)* + +This message use by the HUB to inform a payee DFSP participant of the successful conclusion of a transfer. This message is only generated if the payee DFSP response with a Reserved status when providing the fulfillment in the `PUT \transfers` message. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "PrcgDt":{"DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"COMM"} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[1..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[0..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[0..1]Specifies the reason for the status report.
                 Cd - Code[0..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[0..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[1..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[1..1]Specified date.
             DtTm - DateTime[1..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/transfers_POST.md b/docs/product/features/Iso20022/v1.0/script/transfers_POST.md new file mode 100644 index 000000000..2fccb0fee --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/transfers_POST.md @@ -0,0 +1,623 @@ +## 7.14 POST /transfers +| Financial Institution to Financial Institution Customer Credit Transfer - **pacs.008.001.13**| +|--| + +#### Context +*(DFSP -> DFSP)* + +This message is initiated by a payer DFSP who is requesting to transfer funds. The message is sent to the payee DFSP who provided the transfer terms in the `PUT /quotes` message. This message is an acknowledgement that the terms of the transfer are accepted, and is thus an instruction to proceed with the transfer. + +The transfer amount which is the clearing amount that the payee DFSP receives is defined in the `CdtTrfTxInf.IntrBkSttlmAmt.Ccy` and `CdtTrfTxInf.IntrBkSttlmAmt.ActiveCurrencyAndAmount` fields. If this transfer includes currency conversion, then this amount an currency must correspond with the target amount and currency. + +This message can be seen as an agreement to the terms that have previously been set up and established in the `PUT \quotes` message. The `CdtTrfTxInf.VrfctnOfTerms.IlpV4PrepPacket` field is the ILP packet containing the terms that have been agreed to. + +The `GrpHdr.PmtInstrXpryDtTm` specifies the expiry of the this transfer message. It is the responsibility of the HUB to enforce this expiry. The status of which a DFSP can query by making a `GET /transfers/{ID}` request. + +Here is an example of the message: +```json +{ +"GrpHdr":{ + "MsgId":"01JBVM1D2MR6D4WBWWYY3ZHGMM", + "CreDtTm":"2024-11-04T12:57:45.812Z", + "NbOfTxs":"1", + "SttlmInf":{"SttlmMtd":"CLRG"}, + "PmtInstrXpryDtTm":"2024-11-04T12:58:45.810Z"}, +"CdtTrfTxInf":{ + "PmtId":{"TxId":"01JBVM13SQYP507JB1DYBZVCMF"}, + "ChrgBr":"CRED", + "Cdtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16665551002"}}}}, + "Dbtr":{"Id":{"PrvtId":{"Othr":{"SchmeNm":{"Prtry":"MSISDN"}, + "Id":"16135551001"}}}, + "Name":"Joe Blogs"}, + "CdtrAgt":{"FinInstnId":{"Othr":{"Id":"payee-dfsp"}}}, + "DbtrAgt":{"FinInstnId":{"Othr":{"Id":"payer-dfsp"}}}, + "IntrBkSttlmAmt":{"Ccy":"MWK", + "ActiveCurrencyAndAmount":"1080"}, + "VrfctnOfTerms":{"IlpV4PrepPacket":"DIICzQAAAAAAAaX..."}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - Group Header[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - Message Identification[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
         CreDtTm - ISODateTime[1..1]Creation Date and Time
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[1..1]Number of Transactions
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - Settlement Information[1..1]Group Header Set of characteristics shared by all individual transactions included in the message.
             SttlmMtd - SettlementMethod1Code[1..1]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
             SttlmAcct - CashAccount40[0..0]Provides the details to identify an account.
             ClrSys - ClearingSystemIdentification3Choice[0..0]
             InstgRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstgRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             InstdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             InstdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
             ThrdRmbrsmntAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
             ThrdRmbrsmntAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction64[1..1]Credit Transfer Transaction Information
    Set of elements providing information specific to the individual credit transfer(s).
         PmtId - PaymentIdentification[1..1]Set of elements used to reference a payment instruction.
             InstrId - Max35Text[0..1]InstructionIdentification (FSPIOP equivalent: transactionRequestId)

    Definition: Unique identification, as assigned by an instructing party for an instructed party, to
    unambiguously identify the instruction.

    Usage: The instruction identification is a point to point reference that can be used between the
    instructing party and the instructed party to refer to the individual instruction. It can be included in
    several messages related to the instruction.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             EndToEndId - Max35Text[0..1]EndToEndIdentification (FSPIOP equivalent: transactionId)

    Definition: Unique identification, as assigned by the initiating party, to unambiguously identify the
    transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain.

    Usage: The end-to-end identification can be used for reconciliation or to link tasks relating to the
    transaction. It can be included in several messages related to the transaction.

    Usage: In case there are technical limitations to pass on multiple references, the end-to-end
    identification must be passed on throughout the entire end-to-end chain.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             TxId - Max35Text[1..1]TransactionIdentification (FSPIOP equivalent: quoteId in quote request, transferId in transfer request)

    Definition: Unique identification, as assigned by the first instructing agent, to unambiguously identify the
    transaction that is passed on, unchanged, throughout the entire interbank chain.

    Usage: The transaction identification can be used for reconciliation, tracking or to link tasks relating to
    the transaction on the interbank level.

    Usage: The instructing agent has to make sure that the transaction identification is unique for a preagreed period.

    This field has been changed from the original ISO20022 `Max35Text`` schema to a ULIDIdentifier schema.
             UETR - UETR[0..1]Universally unique identifier to provide an end-to-end reference of a payment transaction.
             ClrSysRef - ClearingSystemReference[0..1]Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
         PmtTpInf - PaymentTypeInformation[0..1]Set of elements used to further specify the type of transaction.
             InstrPrty - Priority2Code[0..1]Indicator of the urgency or order of importance that the instructing party
    would like the instructed party to apply to the processing of the instruction.

    HIGH: High priority
    NORM: Normal priority
             ClrChanl - ClearingChannel2Code[0..1]Specifies the clearing channel for the routing of the transaction, as part of
    the payment type identification.

    RTGS: RealTimeGrossSettlementSystem Clearing channel is a real-time gross settlement system.
    RTNS: RealTimeNetSettlementSystem Clearing channel is a real-time net settlement system.
    MPNS: MassPaymentNetSystem Clearing channel is a mass payment net settlement system.
    BOOK: BookTransfer Payment through internal book transfer.
             SvcLvl - ServiceLevel[0..1]Agreement under which or rules under which the transaction should be processed.
                 Cd - Code[0..1]Specifies a pre-agreed service or level of service between the parties, as published in an external service level code list.
                 Prtry - Proprietary[0..1]Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
             LclInstrm - LocalInstrument[0..1]Definition: User community specific instrument.
    Usage: This element is used to specify a local instrument, local clearing option and/or further qualify the service or service level.
                 Cd - Code[0..1]Specifies the local instrument, as published in an external local instrument code list.
                 Prtry - Proprietary[0..1]Specifies the local instrument, as a proprietary code.
             CtgyPurp - CategoryPurpose[0..1]Specifies the high level purpose of the instruction based on a set of pre-defined categories.
                 Cd - Code[0..1]Category purpose, as published in an external category purpose code list.
                 Prtry - Proprietary[0..1]Category purpose, in a proprietary form.
         IntrBkSttlmAmt - InterbankSettlementAmount[1..1]Amount of money moved between the instructing agent and the instructed agent.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmPrty - Priority3Code[0..0]
         SttlmTmIndctn - SettlementDateTimeIndication1[0..0]
         SttlmTmReq - SettlementTimeRequest2[0..0]
         AccptncDtTm - ISODateTime[0..0]A particular point in the progression of time defined by a mandatory
    date and a mandatory time component, expressed in either UTC time
    format (YYYY-MM-DDThh:mm:ss.sssZ), local time with UTC offset format
    (YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), or local time format
    (YYYY-MM-DDThh:mm:ss.sss). These representations are defined in
    "XML Schema Part 2: Datatypes Second Edition -
    W3C Recommendation 28 October 2004" which is aligned with ISO 8601.

    Note on the time format:
    1) beginning / end of calendar day
    00:00:00 = the beginning of a calendar day
    24:00:00 = the end of a calendar day

    2) fractions of second in time format
    Decimal fractions of seconds may be included. In this case, the
    involved parties shall agree on the maximum number of digits that are allowed.
         PoolgAdjstmntDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         InstdAmt - InstructedAmount[0..1]Amount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
         XchgRate - ExchangeRate[0..1]Factor used to convert an amount from one currency into another. This reflects the price at which one currency was bought with another currency.
         ChrgBr - ChargeBearerType1Code[1..1]Provides further details specific to the individual transaction(s) included in the message.
         ChrgsInf - ChargesInformation[0..1]Provides information on the charges to be paid by the charge bearer(s) related to the payment transaction.
             Amt - Amount[0..1]Transaction charges to be paid by the charge bearer.
             Agt - Agent[0..1]Agent that takes the transaction charges or to which the transaction charges are due.
                 FinInstnId - FinancialInstitutionIdentification[0..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                     BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                     ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                         ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                             Cd - Code[0..1]Clearing system identification code, as published in an external list.
                             Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                         MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                     LEI - LEI[0..1]Legal entity identifier of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
                     Othr - Other[0..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                     Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                     LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                     Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                     PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                         AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                             Cd - Code[0..1]Type of address expressed as a code.
                             Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                                 Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                                 Issr - Issuer[0..1]Entity that assigns the identification.
                                 SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                         CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                         Dept - Max70Text[0..1]Name of a department within an organization.
                         SubDept - Max70Text[0..1]Name of a sub-department within a department.
                         StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                         BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                         BldgNm - Max140Text[0..1]Name of the building, if applicable.
                         Flr - Max70Text[0..1]Floor number or identifier within a building.
                         UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                         PstBx - Max16Text[0..1]Post office box number.
                         Room - Max70Text[0..1]Room number or identifier within a building.
                         PstCd - Max16Text[0..1]Postal code or ZIP code.
                         TwnNm - Max140Text[0..1]Name of the town or city.
                         TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                         DstrctNm - Max140Text[0..1]Name of the district or region.
                         CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                         Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                         AdrLine - Max70Text[0..1]Free-form text line for the address.
             Tp - Type[0..1]Defines the type of charges.
                 Cd - Code[0..1]Charge type, in a coded form.
                 Prtry - Proprietary[0..1]Type of charge in a proprietary form, as defined by the issuer.
                     Id - Identification[0..1]Name or number assigned by an entity to enable recognition of that entity, for example, account identifier.
                     Issr - Issuer[0..1]Entity that assigns the identification.
         MndtRltdInf - CreditTransferMandateData1[0..0]
         PrvsInstgAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         PrvsInstgAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         PrvsInstgAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt1Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt2 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt2Acct - CashAccount40[0..0]Provides the details to identify an account.
         IntrmyAgt3 - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         IntrmyAgt3Acct - CashAccount40[0..0]Provides the details to identify an account.
         UltmtDbtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InitgPty - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         Dbtr - Debtor[1..1]Party that owes an amount of money to the (ultimate) creditor.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         DbtrAcct - DebtorAccount[0..1]Unambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         DbtrAgt - DebtorAgent[1..1]Financial institution servicing an account for the debtor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         DbtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         CdtrAgt - CreditorAgent[1..1]Financial institution servicing an account for the creditor.
             FinInstnId - FinancialInstitutionIdentification[1..1]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
                 BICFI - BICFI[0..1]Code allocated to a financial institution by the ISO 9362 Registration Authority as described in ISO 9362 "Banking - Banking telecommunication messages - Business identifier code (BIC)"
                 ClrSysMmbId - ClearingSystemMemberIdentification[0..1]Information used to identify a member within a clearing system
                     ClrSysId - ClearingSystemIdentification[0..1]Specification of a pre-agreed offering between clearing agents or the channel through which the payment instruction is processed.
                         Cd - Code[0..1]Clearing system identification code, as published in an external list.
                         Prtry - Proprietary[0..1]Proprietary identification of the clearing system.
                     MmbId - MemberIdentification[0..1]Identification of a member of a clearing system.
                 LEI - LEI[0..1]Legal entity identifier of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..0]Specifies a character string with a maximum length of 140 characters.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..0]Specifies a character string with a maximum length of 16 characters.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Othr - Other[1..1]Unique identification of an agent, as assigned by an institution, using an identification scheme.
                     Id - Identification[1..1]Unique and unambiguous identification of a person.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             BrnchId - BranchIdentification[0..1]Identifies a specific branch of a financial institution.
                 Id - Identification[0..1]Unique and unambiguous identification of a branch of a financial institution.
                 LEI - LEI[0..1]Legal entity identification for the branch of the financial institution.
                 Nm - Name[0..1]Name by which an agent is known and which is usually used to identify that agent.
                 PstlAdr - PostalAddress[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
         CdtrAgtAcct - CashAccount40[0..0]Provides the details to identify an account.
         Cdtr - Creditor[1..1]Party to which an amount of money is due.
             Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
             PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                 AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                     Cd - Code[0..1]Type of address expressed as a code.
                     Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                         Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                         SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                 CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                 Dept - Max70Text[0..1]Name of a department within an organization.
                 SubDept - Max70Text[0..1]Name of a sub-department within a department.
                 StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                 BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                 BldgNm - Max140Text[0..1]Name of the building, if applicable.
                 Flr - Max70Text[0..1]Floor number or identifier within a building.
                 UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                 PstBx - Max16Text[0..1]Post office box number.
                 Room - Max70Text[0..1]Room number or identifier within a building.
                 PstCd - Max16Text[0..1]Postal code or ZIP code.
                 TwnNm - Max140Text[0..1]Name of the town or city.
                 TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                 DstrctNm - Max140Text[0..1]Name of the district or region.
                 CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                 Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                 AdrLine - Max70Text[0..1]Free-form text line for the address.
             Id - Identification[1..1]Unique and unambiguous identification of a party.
                 OrgId - Organisation[1..1]Unique and unambiguous way to identify an organisation.
                     AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                     LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                     Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Identification assigned by an institution.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
                 PrvtId - Person[1..1]Unique and unambiguous identification of a person, for example a passport.
                     DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                         BirthDt - BirthDate[0..1]Date on which a person was born.
                         PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                         CityOfBirth - CityOfBirth[0..1]City where a person was born.
                         CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                     Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                         Id - Identification[0..1]Unique and unambiguous identification of a person.
                         SchmeNm - SchemeName[0..1]Name of the identification scheme.
                             Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                             Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                         Issr - Issuer[0..1]Entity that assigns the identification.
             CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
             CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                 NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                 MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                 FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                 URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                 EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                 EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                 JobTitl - JobTitle[0..1]Title of the function.
                 Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                 Dept - Department[0..1]Identification of a division of a large organisation or building.
                 Othr - OtherContact[0..1]Contact details in another form.
                     ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                     Id - Identifier[0..1]Communication value such as phone number or email address.
                 PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
         CdtrAcct - CreditorAccount[0..1]Unambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
             Id - Identification[0..1]Unique and unambiguous identification for the account between the account owner and the account servicer.
                 IBAN - IBAN[0..1]International Bank Account Number (IBAN) - identifier used internationally by financial institutions to uniquely identify the account of a customer. Further specifications of the format and content of the IBAN can be found in the standard ISO 13616 "Banking and related financial services - International Bank Account Number (IBAN)" version 1997-10-01, or later revisions.
                 Othr - Other[0..1]Unique identification of an account, as assigned by the account servicer, using an identification scheme.
                     Id - Identification[0..1]Identification assigned by an institution.
                     SchmeNm - SchemeName[0..1]Name of the identification scheme.
                         Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                         Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                     Issr - Issuer[0..1]Entity that assigns the identification.
             Tp - Type[0..1]Specifies the nature, or use of the account.
                 Cd - Code[0..1]Account type, in a coded form.
                 Prtry - Proprietary[0..1]Nature or use of the account in a proprietary form.
             Ccy - Currency[0..1]Identification of the currency in which the account is held.
    Usage: Currency should only be used in case one and the same account number covers several currencies and the initiating party needs to identify which currency needs to be used for settlement on the account.
             Nm - Name[0..1]Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account.
    Usage: The account name is different from the account owner name. The account name is used in certain user communities to provide a means of identifying the account, in addition to the account owner's identity and the account number.
             Prxy - Proxy[0..1]Specifies an alternate assumed name for the identification of the account.
                 Tp - Type[0..1]Type of the proxy identification.
                     Cd - Code[0..1]Proxy account type, in a coded form as published in an external list.
                     Prtry - Proprietary[0..1]Proxy account type, in a proprietary form.
                 Id - Identification[0..1]Identification used to indicate the account identification under another specified name.
         UltmtCdtr - PartyIdentification272[0..0]Specifies the identification of a person or an organisation.
         InstrForCdtrAgt - InstructionForCreditorAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the creditor's agent.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
         InstrForNxtAgt - InstructionForNextAgent[0..1]Set of elements used to provide information on the remittance advice.
             Cd - Code[0..1]Coded information related to the processing of the payment instruction, provided by the initiating party, and intended for the next agent in the payment chain.
             InstrInf - InstructionInformation[0..1]Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
         Purp - Purpose[0..1]Underlying reason for the payment transaction.
             Cd - Code[0..1]
    Underlying reason for the payment transaction, as published in an external purpose code list.
             Prtry - Proprietary[0..1]
    Purpose, in a proprietary form.
         RgltryRptg - RegulatoryReporting[0..1]Information needed due to regulatory and statutory requirements.
             DbtCdtRptgInd - DebitCreditReportingIndicator[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
             Authrty - Authority[0..1]
    Entity requiring the regulatory reporting information.
                 Nm - Name[0..1]
    Name of the entity requiring the regulatory reporting information.
                 Ctry - Country[0..1]
    Country of the entity that requires the regulatory reporting information.
             Dtls - Details[0..1]Identifies whether the regulatory reporting information applies to the debit side, to the credit side or to both debit and credit sides of the transaction.
                 Tp - Type[0..1]
    Specifies the type of the information supplied in the regulatory reporting details.
                 Dt - Date[0..1]
    Date related to the specified type of regulatory reporting details.
                 Ctry - Country[0..1]
    Country related to the specified type of regulatory reporting details.
                 Cd - Code[0..1]Specifies the nature, purpose, and reason for the transaction to be reported for regulatory and statutory requirements in a coded form.
                 Amt - Amount[0..1]
    Amount of money to be reported for regulatory and statutory requirements.
                 Inf - Information[0..1]
    Additional details that cater for specific domestic regulatory requirements.
         Tax - Tax[0..1]Provides details on the tax.
             Cdtr - Creditor[0..1]
    Party on the credit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the creditor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
             Dbtr - Debtor[0..1]
    Party on the debit side of the transaction to which the tax applies.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             UltmtDbtr - UltimateDebtor[0..1]
    Ultimate party that owes an amount of money to the (ultimate) creditor, in this case, to the taxing authority.
                 TaxId - TaxIdentification[0..1]
    Tax identification number of the debtor.
                 RegnId - RegistrationIdentification[0..1]
    Unique identification, as assigned by an organisation, to unambiguously identify a party.
                 TaxTp - TaxType[0..1]
    Type of tax payer.
                 Authstn - Authorisation[0..1]
    Details of the authorised tax paying party.
                     Titl - Title[0..1]
    Title or position of debtor or the debtor's authorised representative.
                     Nm - Name[0..1]
    Name of the debtor or the debtor's authorised representative.
             AdmstnZone - AdministrationZone[0..1]
    Territorial part of a country to which the tax payment is related.
             RefNb - ReferenceNumber[0..1]
    Tax reference information that is specific to a taxing agency.
             Mtd - Method[0..1]
    Method used to indicate the underlying business or how the tax is paid.
             TtlTaxblBaseAmt - TotalTaxableBaseAmount[0..1]
    Total amount of money on which the tax is based.
             TtlTaxAmt - TotalTaxAmount[0..1]
    Total amount of money as result of the calculation of the tax.
             Dt - Date[0..1]
    Date by which tax is due.
             SeqNb - SequenceNumber[0..1]
    Sequential number of the tax report.
             Rcrd - Record[0..1]
    Details of the tax record.
                 Tp - Type[0..1]
    High level code to identify the type of tax details.
                 Ctgy - Category[0..1]
    Specifies the tax code as published by the tax authority.
                 CtgyDtls - CategoryDetails[0..1]
    Provides further details of the category tax code.
                 DbtrSts - DebtorStatus[0..1]
    Code provided by local authority to identify the status of the party that has drawn up the settlement document.
                 CertId - CertificateIdentification[0..1]
    Identification number of the tax report as assigned by the taxing authority.
                 FrmsCd - FormsCode[0..1]
    Identifies, in a coded form, on which template the tax report is to be provided.
                 Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                     Yr - Year[0..1]
    Year related to the tax payment.
                     Tp - Type[0..1]
    Identification of the period related to the tax payment.
                     FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                         FrDt - FromDate[0..1]Start date of the range.
                         ToDt - ToDate[0..1]End date of the range.
                 TaxAmt - TaxAmount[0..1]
    Set of elements used to provide information on the amount of the tax record.
                     Rate - Rate[0..1]
    Rate used to calculate the tax.
                     TaxblBaseAmt - TaxableBaseAmount[0..1]
    Amount of money on which the tax is based.
                     TtlAmt - TotalAmount[0..1]
    Total amount that is the result of the calculation of the tax for the record.
                     Dtls - Details[0..1]
    Set of elements used to provide details on the tax period and amount.
                         Prd - Period[0..1]
    Set of elements used to provide details on the period of time related to the tax payment.
                             Yr - Year[0..1]
    Year related to the tax payment.
                             Tp - Type[0..1]
    Identification of the period related to the tax payment.
                             FrToDt - FromToDate[0..1]
    Range of time between a start date and an end date for which the tax report is provided.
                                 FrDt - FromDate[0..1]Start date of the range.
                                 ToDt - ToDate[0..1]End date of the range.
                         Amt - Amount[0..1]
    Underlying tax amount related to the specified period.
                 AddtlInf - AdditionalInformation[0..1]
    Further details of the tax record.
         RltdRmtInf - RemittanceLocation8[0..0]
         RmtInf - RemittanceInformation22[0..0]
         SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    SplmtryData - SupplementaryData1[0..0]Additional information that cannot be captured in the structured fields and/or any other specific block.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/transfers_PUT.md b/docs/product/features/Iso20022/v1.0/script/transfers_PUT.md new file mode 100644 index 000000000..af096fbc0 --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/transfers_PUT.md @@ -0,0 +1,99 @@ +## 7.15 PUT /transfers/{ID} +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(DFSP -> DFSP, DFSP -> HUB, HUB -> DFSP)* + +This message is a response to the `POST \transfers` call initiated by the DFSP who is requesting to proceed with the transfer terms presented in the `PUT \quotes`. It is the payee DFSPs responsibility to check that the clearing amounts align with the agreed transfer terms, and if all requirements are met, this message is used to lock-in the agreed terms. Once the hub receives this acceptance message, the transfer can no-longer timeout and will be committed. If this transfer is a dependent transfer in a currency conversion, then that currency conversion will be committed at the same time as this transfer. + +The cryptographic ILP fulfillment provided in the `TxInfAndSts.ExctnConf` field, is released by the payee DFSP as an indication to the HUB that the terms have been met. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{ + "ExctnConf":"ou1887jmG-l...", + "PrcgDt":{ + "DtTm":"2024-11-04T12:57:45.213Z"}, + "TxSts":"RESV"} +} +``` + +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader113[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         BtchBookg - BatchBookingIndicator[0..0]
         NbOfTxs - Max15NumericText[0..0]Specifies a numeric string with a maximum length of 15 digits.
         CtrlSum - DecimalNumber[0..0]
         TtlIntrBkSttlmAmt - ActiveCurrencyAndAmount[0..0]A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
         IntrBkSttlmDt - ISODate[0..0]A particular point in the progression of time in a calendar year expressed in the YYYY-MM-DD format. This representation is defined in "XML Schema Part 2: Datatypes Second Edition - W3C Recommendation 28 October 2004" which is aligned with ISO 8601.
         SttlmInf - SettlementInstruction15[0..0]Only the CLRG: Clearing option is supported.
    Specifies the details on how the settlement of the original transaction(s) between the
    instructing agent and the instructed agent was completed.
         PmtTpInf - PaymentTypeInformation28[0..0]Provides further details of the type of payment.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
    CdtTrfTxInf - CreditTransferTransaction64[0..0]
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Iso20022/v1.0/script/transfers_error_PUT.md b/docs/product/features/Iso20022/v1.0/script/transfers_error_PUT.md new file mode 100644 index 000000000..459cb3cdd --- /dev/null +++ b/docs/product/features/Iso20022/v1.0/script/transfers_error_PUT.md @@ -0,0 +1,179 @@ +## 7.16 PUT /transfers/{ID}/error + +| Financial Institution to Financial Institution Payment Status Report - **pacs.002.001.15**| +|--| + +#### Context +*(DFSP -> DFSP, DFSP -> HUB, HUB -> DFSP)* + +This is triggered as a callback response to the POST /transfers call when an error occurs. The message is generated by the entity who first encounter the error which can either be the DFSP, or the HUB. All other participants involved are informed by this message. The `TxInfAndSts.StsRsnInf.Rsn.Cd` contains the Mojaloop error code, which specified the source and cause of the error. + +Here is an example of the message: +```json +{ +"GrpHdr": { + "MsgId":"01JBVM1CGC5A18XQVYYRF68FD1", + "CreDtTm":"2024-11-04T12:57:45.228Z"}, +"TxInfAndSts":{"StsRsnInf":{"Rsn": {"Prtry":"ErrorCode"}}} +} +``` +#### Message Details +The details on how to compose and make this API are covered in the following sections: +1. [Core Data Elements](#core-data-elements)
    This section specifies which fields are required, which fields are optional, and which fields are unsupported in order to meet the message validating requirements. +2. [Header Details](../MarketPracticeDocument.md#_3-3-1-header-details)
    This general section specifies the header requirements for the API are specified. +3. [Supported HTTP Responses](../MarketPracticeDocument.md#_3-3-2-supported-http-responses)
    This general section specifies the http responses that must be supported. +4. [Common Error Payload](../MarketPracticeDocument.md#_3-3-3-common-error-payload)
    This general section specifies the common error payload that is provided in synchronous http error response. + +#### Core Data Elements +Here are the core data elements that are needed to meet this market practice requirement. + +The background colours indicate the classification of the data element. + + + + + + + +
    Data Model Type Key Description
    requiredThese fields are required in order to meet the message validating requirements.
    optionalThese fields can be optionally included in the message. (Some of these fields may be required for a specific scheme as defined in the Scheme Rules for that scheme.)
    unsupportedThese fields are actively not supported. The functionality specifying data in these fields are not compatible with a Mojaloop scheme, and will fail message validation if provided.
    +

    + + +Here is the defined core data element table. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ISO 20022 FieldData ModelDescription
    GrpHdr - GroupHeader120[1..1]Set of characteristics shared by all individual transactions included in the message.
         MsgId - MessageIdentification[1..1]Definition: Point to point reference, as assigned by the instructing party, and sent to the next party in the chain to unambiguously identify the message.
    Usage: The instructing party has to make sure that MessageIdentification is unique per instructed party for a pre-agreed period.
         CreDtTm - CreationDateTime[1..1]Date and time at which the message was created.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlBizQry - OriginalBusinessQuery1[0..0]
    OrgnlGrpInfAndSts - OriginalGroupHeader22[0..0]
    TxInfAndSts - PaymentTransaction161[1..1]Information concerning the original transactions, to which the status report message refers.
         StsId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to unambiguously identify the status report.
         OrgnlGrpInf - OriginalGroupInformation29[0..0]
         OrgnlInstrId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original instruction.

    (FSPIOP equivalent: transactionRequestId)
         OrgnlEndToEndId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original end-to-end transaction.

    (FSPIOP equivalent: transactionId)
         OrgnlTxId - Max35Text[0..1]Unique identification, as assigned by the original sending party, to
    unambiguously identify the original transaction.

    (FSPIOP equivalent: quoteId)
         OrgnlUETR - UUIDv4Identifier[0..1]Unique end-to-end transaction reference, as assigned by the original sending party, to unambiguously identify the original transaction.
         TxSts - ExternalPaymentTransactionStatus1Code[0..1]Specifies the status of the transaction.
         StsRsnInf - StatusReasonInformation14[1..1]Information concerning the reason for the status.
             Orgtr - Originator[0..1]Party that issues the status.
                 Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                 PstlAdr - Postal Address[0..1]Information that locates and identifies a specific address, as defined by postal services.
                     AdrTp - AddressType3Choice[0..1]Type of address, as defined by the postal services.
                         Cd - Code[0..1]Type of address expressed as a code.
                         Prtry - Proprietary[0..1]Type of address expressed as a proprietary code.
                             Id - Identification[0..1]Proprietary information, often a code, issued by the data source scheme issuer.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                             SchmeNm - SchemeName[0..1]Short textual description of the scheme.
                     CareOf - Max140Text[0..1]Name of the person or entity the mail is directed to, if different from the recipient.
                     Dept - Max70Text[0..1]Name of a department within an organization.
                     SubDept - Max70Text[0..1]Name of a sub-department within a department.
                     StrtNm - Max140Text[0..1]Name of the street or thoroughfare.
                     BldgNb - Max16Text[0..1]Number that identifies a building on the street.
                     BldgNm - Max140Text[0..1]Name of the building, if applicable.
                     Flr - Max70Text[0..1]Floor number or identifier within a building.
                     UnitNb - Max16Text[0..1]Unit or apartment number within a building.
                     PstBx - Max16Text[0..1]Post office box number.
                     Room - Max70Text[0..1]Room number or identifier within a building.
                     PstCd - Max16Text[0..1]Postal code or ZIP code.
                     TwnNm - Max140Text[0..1]Name of the town or city.
                     TwnLctnNm - Max140Text[0..1]Name of the location within a town or city.
                     DstrctNm - Max140Text[0..1]Name of the district or region.
                     CtrySubDvsn - Max35Text[0..1]Name of the country subdivision, such as a state or province.
                     Ctry - CountryCode[0..1]Country code, as defined by ISO 3166-1 alpha-2.
                     AdrLine - Max70Text[0..1]Free-form text line for the address.
                 Id - Identification[0..1]Unique and unambiguous identification of a party.
                     OrgId - Organisation[0..1]Unique and unambiguous way to identify an organisation.
                         AnyBIC - AnyBIC[0..1]Business identification code of the organisation.
                         LEI - LEI[0..1]Legal entity identification as an alternate identification for a party.
                         Othr - Other[0..1]Unique identification of an organisation, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Identification assigned by an institution.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                     PrvtId - Person[0..1]Unique and unambiguous identification of a person, for example a passport.
                         DtAndPlcOfBirth - DateAndPlaceOfBirth[0..1]Date and place of birth of a person.
                             BirthDt - BirthDate[0..1]Date on which a person was born.
                             PrvcOfBirth - ProvinceOfBirth[0..1]Province where a person was born.
                             CityOfBirth - CityOfBirth[0..1]City where a person was born.
                             CtryOfBirth - CountryOfBirth[0..1]Country where a person was born.
                         Othr - Other[0..1]Unique identification of a person, as assigned by an institution, using an identification scheme.
                             Id - Identification[0..1]Unique and unambiguous identification of a person.
                             SchmeNm - SchemeName[0..1]Name of the identification scheme.
                                 Cd - Code[0..1]Name of the identification scheme, in a coded form as published in an external list.
                                 Prtry - Proprietary[0..1]Name of the identification scheme, in a free text form.
                             Issr - Issuer[0..1]Entity that assigns the identification.
                 CtryOfRes - CountryCode[0..1]Country of Residence
    Country in which a person resides (the place of a person's home). In the case of a company, it is the country from which the affairs of that company are directed.
                 CtctDtls - Contact Details[0..1]Set of elements used to indicate how to contact the party.
                     NmPrfx - NamePrefix[0..1]Specifies the terms used to formally address a person.
                     Nm - Name[0..1]Name by which a party is known and which is usually used to identify that party.
                     PhneNb - PhoneNumber[0..1]Collection of information that identifies a phone number, as defined by telecom services.
                     MobNb - MobilePhoneNumber[0..1]Collection of information that identifies a mobile phone number, as defined by telecom services.
                     FaxNb - FaxNumber[0..1]Collection of information that identifies a fax number, as defined by telecom services.
                     URLAdr - URLAddress[0..1]Address for the Universal Resource Locator (URL), for example an address used over the www (HTTP) service.
                     EmailAdr - EmailAddress[0..1]Address for electronic mail (e-mail).
                     EmailPurp - EmailPurpose[0..1]Purpose for which an email address may be used.
                     JobTitl - JobTitle[0..1]Title of the function.
                     Rspnsblty - Responsibility[0..1]Role of a person in an organisation.
                     Dept - Department[0..1]Identification of a division of a large organisation or building.
                     Othr - OtherContact[0..1]Contact details in another form.
                         ChanlTp - ChannelType[0..1]Method used to contact the financial institution's contact for the specific tax region.
                         Id - Identifier[0..1]Communication value such as phone number or email address.
                     PrefrdMtd - PreferredContactMethod[0..1]Preferred method used to reach the contact.
             Rsn - Reason[1..1]Specifies the reason for the status report.
                 Cd - Code[1..1]Reason for the status, as published in an external reason code list.
                 Prtry - Proprietary[1..1]Reason for the status, in a proprietary form.
             AddtlInf - AdditionalInformation[0..1]Additional information about the status report.
         ChrgsInf - Charges16[0..0]NOTE: Unsure on description.

    Seemingly a generic schema for charges, with an amount, agent, and type.
         AccptncDtTm - ISODateTime[0..1]Date and time at which the status was accepted.
         PrcgDt - DateAndDateTime2Choice[0..1]Date/time at which the instruction was processed by the specified party.
             Dt - Date[0..1]Specified date.
             DtTm - DateTime[0..1]Specified date and time.
         FctvIntrBkSttlmDt - DateAndDateTime2Choice[0..0]Specifies the reason for the status.
         AcctSvcrRef - Max35Text[0..1]Unique reference, as assigned by the account servicing institution, to unambiguously identify the status report.
         ClrSysRef - Max35Text[0..1]Reference that is assigned by the account servicing institution and sent to the account owner to unambiguously identify the transaction.
         InstgAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         InstdAgt - BranchAndFinancialInstitutionIdentification8[0..0]Unique and unambiguous identification of a financial institution or a branch of a financial institution.
         OrgnlTxRef - OriginalTransactionReference42[0..0]
         SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
             PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
             Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    SplmtryData - SupplementaryData1[0..1]Additional information that cannot be captured in the structured elements and/or any other specific block.
         PlcAndNm - PlaceAndName[0..1]Unambiguous reference to the location where the supplementary data must be inserted in the message instance.
         Envlp - Envelope[0..1]Technical element wrapping the supplementary data.
    Technical component that contains the validated supplementary data information. This technical envelope allows to segregate the supplementary data information from any other information.
    + diff --git a/docs/product/features/Production_Readiness_Technical_Assessment.md b/docs/product/features/Production_Readiness_Technical_Assessment.md new file mode 100644 index 000000000..5b9db651e --- /dev/null +++ b/docs/product/features/Production_Readiness_Technical_Assessment.md @@ -0,0 +1,26 @@ +| Category| Requirement Description | +| --- | --- | +| General | Your production Mojaloop instance Kubernetes cluster has at least 3 master nodes and 3 worker nodes that meet the following minimum specifications:

    - 3 master/worker nodes: Mid-level enterprise grade server, minimum 128 CPU cores, 1024GB RAM x4 500GB NVMe HDD in RAID mirroring configuration, x2 10GbE
    - 5 worker nodes and up: Mid-level enterprise grade server, minimum 64 CPU cores 512GB RAM x4 500GB NVMe HDD in RAID mirroring configuration, x2 10GbE

    Notes:
    - Worker nodes may also be master nodes but this is not recommended for production workloads.
    - Node specifications need to be higher if fewer are available. | +| Security | You are using one of the following methods to terminate mTLS between participants and the switch:
    - Cloud provider application gateway
    - Cloud provider firewall
    - Cloud provider load balancer
    - Kubernetes NGINX ingress
    - Kubernetes API gateway e.g. ISTIO.
    - Enterprise firewall appliance | +| | You are using one or more of the following methods to secure secrets in your production environment?
    - In-cluster Hashicorp Vault
    - Cloud provider secure secret store
    - Enterprise grade secure secret storage appliance | +| | You are using one or more of the following methods for operating your certificate authority for mTLS keypair generation and participant certificate signing:

    - Mojaloop connection manager
    - In-cluster Hashicorp Vault
    - Enterprise CA platform
    - Trusted 3rd Party certificate authority e.g. DigiCert, GlobalSign etc... | +| | You have configured RBAC on all Mojaloop portals to restrict access to authorised staff. | +| | You are using IP allow list filtering to control access to Mojaloop services.

    (default = block) | +| | You are using an IP firewall to control access to your production infrastructure. | +| User management | Your participants are all performing JWS message signing and signature verification. | +| | You enforce process and technical controls for all staff accessing the Mojaloop platform infrastructure and application services. | +| Resilience and Reliability | You are running a minimum of 3 healthy instances of the following pods at all times:

    ml-api-adapter, ml-api-adapter-handler-notification, central-ledger-service, central-ledger-handler-admin, central-ledger-handler-prepare, central-ledger-handler-position, central-ledger-handler-fulfil, central-ledger-handler-get, account-lookup-service, account-lookup-service-admin, moja-quoting-service, moja-centralsettlement-handler-deferred, moja-centralsettlement-handler-gross, moja-centralsettlement-handler-rules, moja-centralsettlement-service, (moja-cl-handler-bulk-transfer-fulfil, moja-cl-handler-bulk-transfer-get, moja-cl-handler-bulk-transfer-prepare, moja-cl-handler-bulk-transfer-processing)

    Note: items in brackets depend on optionally utilized features. | +| | You have successfully tested Kubernetes pod recovery mechanisms to cope with pod failures and replace unhealthy pods in a timely manner in order to maintain your defined SLAs. | +| | All mojaloop database data stores are running as synchronously replicated instances with a minimum of 3 healthy replicas at all times. | +| | All stateful mojaloop pods are using one of the following underlying storage technologies:

    - Encrypted, RAID mirrored on-node NVMe storage (see node specs in general section)
    - Encrypted, replicated cloud provider storage.
    - Encrypted, enterprise grade, replicated SAN (not recommended for production). | +| | All mojaloop database data store pods are scheduled to run on and store their data to different physical nodes. | +| | All Kafka zookeeper pods are scheduled to run on and store their data to different physical nodes. | +| | All Kafka broker pods are scheduled to run on and store their data to different physical nodes. | +| | A data archiving process is defined to ensure production data stores to not grown beyond an appropriate size which would limit performance or risk free space exhaustion. | +| | Your archive data storage is encrypted at rest, replicated and of sufficient grade to satisfy your business and regulatory operating requirements. | +| Testing | You have successfully executed the Mojaloop golden path test suite and all tests are passing. | +| Note: This section is currently being extended by the QA Framework Workstream | You have successfully executed adjacent test suites for custom or supplementary features and all tests are passing. | +| | You have conducted a successful load test to prove your production instance can cope with your expected normal and peak traffic demands while maintaining your defined SLAs. | +| | You have conducted a successful soak test to prove your production instance is stable over long periods of time without any unexpected failures or unrecoverable errors occurring. | +| | You have conducted a successful penetration test of your production instance and supporting infrastructure and no vulnerabilities were found.| +| | You have conducted successful chaos testing of your production instance and proved that simultaneous failure of multiple components is tolerated and the system continues to operate without falling into inconsistent or unrecoverable states.

    Note: The number and nature of tolerable simultaneous failures is somewhat subjective but you should be able to prove that a "reasonably well anticipated" set of failures can be tolerated without breaking your defined SLAs. \ No newline at end of file diff --git a/docs/product/features/SimpleInterscheme.svg b/docs/product/features/SimpleInterscheme.svg new file mode 100644 index 000000000..33e945028 --- /dev/null +++ b/docs/product/features/SimpleInterscheme.svg @@ -0,0 +1,4 @@ + + + +
    Scheme 1
    Scheme 1
    Scheme 2
    Scheme 2
    DFSP 1
    DFSP 1
    DFSP 2
    DFSP 2
    Proxy
    Proxy
    \ No newline at end of file diff --git a/docs/product/features/Test.png b/docs/product/features/Test.png new file mode 100644 index 000000000..c68bb2e19 Binary files /dev/null and b/docs/product/features/Test.png differ diff --git a/docs/product/features/XB.svg b/docs/product/features/XB.svg new file mode 100644 index 000000000..ac97cc76a --- /dev/null +++ b/docs/product/features/XB.svg @@ -0,0 +1,4 @@ + + + +
    Jurisdiction B
    Jurisdiction B
    Jurisdiction A
    Jurisdiction A
    Scheme 1
    Scheme 1
    Scheme 2
    Scheme 2
    DFSP 1
    DFSP 1
    DFSP 2
    DFSP 2
    Proxy
    Proxy
    FXP 1
    FXP 1
    FXP 3
    FXP 3
    FXP 2
    FXP 2
    \ No newline at end of file diff --git a/docs/product/features/connectivity.md b/docs/product/features/connectivity.md new file mode 100644 index 000000000..703fe3a76 --- /dev/null +++ b/docs/product/features/connectivity.md @@ -0,0 +1,43 @@ +# Onboarding DFSPs + +In principle, having developed and documented the [Mojaloop APIs](./transaction.md#Mojaloop APIs), this should be sufficient to enable DFSPs to connect to a Mojaloop Hub. However, as part of the Mojaloop Community's mission to address financial inclusion, it has long been felt that the key to minimising the cost and complexity of connecting a DFSP's back office to a Mojaloop Hub is through the provision of a portfolio of connectivity solutions, allowing a DFSP to select the approach that best meets their needs. These are supplemented by a DFSP Onboarding Playbook, encapsulating the business processes that are needed to onboard a DFSP. +## Business Onboarding +There are many steps needed in the onboarding of a DFSP to a Mojaloop Hub that are nothing to do with technology, and these are addressed in the DFSP Onboarding Playbook. + +This playbook, which has been donated by Thitsaworks, comprises a set of tools and templates to assist with the planning and execution of a Mojaloop deployment, specifically focusing on DFSP onboarding. The tools are: +- A workplan template, including samples used in past deployments; +- An example end to end test case, in this case for payee-side DFSP integration; +- A Technical assessment form, used to define the technical assistance required by candidate DFSPs; +- A technical onboarding checklist; +- An API mapping template, used to map between Mojaloop Hub API elements and the corresponding actions required by the DFSP's back office; +- A plan for the setup of the security of the DFSP's connection to the Mojaloop Hub. + +You can [download the Thitsaworks DFSP Onboarding Playbook by clicking on this link](https://github.com/mojaloop/product-council/tree/main/Documentation/DFSP%20Playbook). + +## Technical Onboarding +The current connectivity portfolio includes the Integration Toolkit (ITK) which will allow a Systems Integrator (SI) to create a connection by combining the various elements of a toolkit in a way that best meets the DFSP's needs. These elements include: + - Mojaloop Connection Manager (MCM); + - Mojaloop Connector (for integrating with the Mojaloop Hub); + - A set of example Core Connectors (for integrating with the DFSP's back office); + - Documentation, including "how to" guides and templates. + +For larger DFSPs, the Mojaloop Community offers Payment Manager as an alternative to the ITK. Also known as Payment Manager for Mojaloop (PM4ML), it which offers all of the functionality and flexibility a large bank might require. + +The various connectivity tools available to onboard a DFSP to a Mojaloop Hub are discussed further in the [Mini Guides](./connectivity/participation_tools_mini_guides.md), and detailed guidance on which connectivity solution is most appropriate for different participant types and requirements is presented in the [Participant Feature Matrix](./connectivity/participant-matrix.md). + +All DFSPs should be aware that reaping the benefits of an inclusive instant payments solution such as Mojaloop relies on the implementation of a "whole ecosystem" approach - and this means extending the reach of the Mojaloop service into the DFSPs' domains, giving them and their customers the advantages of assurance of transaction finality, lower cost and the reliable delivery of every valid transaction. + +Note that the mode of deployment of the ITK affects the type of service a DFSP can provide to their customers, as highlighted in the [Mini Guides](./connectivity/participation_tools_mini_guides.md). The most resource intense options are suitable for DFSPs with high throughout and reliability requirements, a moderate deployment option places some limits on throughput and availability and may be best suited to medium or small DFSPs, and the most frugal option places strict limits on throughput and availability and removes the ability to initiate bulk payments, and so may only be suitable for small DFSPs. + +## Applicability + +This version of this document relates to Mojaloop Version [17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.4|17th December 2025| Paul Makin |Added link to the Mini Guides; clarified the text to highlight the role of the ITK| +|1.3|6th November 2025| Paul Makin|Linked to Thitsaworks' DFSP Onboarding Playbook| +|1.2|9th June 2025| Tony Williams|Added reference to participant feature matrix| +|1.1|14th April 2025| Paul Makin|Updates related to the release of V17| +|1.0|5th February 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/connectivity/images/ITK_architecture.png b/docs/product/features/connectivity/images/ITK_architecture.png new file mode 100644 index 000000000..fdc1aa0e6 Binary files /dev/null and b/docs/product/features/connectivity/images/ITK_architecture.png differ diff --git a/docs/product/features/connectivity/images/PM4ML_system_architecture.png b/docs/product/features/connectivity/images/PM4ML_system_architecture.png new file mode 100644 index 000000000..568cb6cdf Binary files /dev/null and b/docs/product/features/connectivity/images/PM4ML_system_architecture.png differ diff --git a/docs/product/features/connectivity/participant-matrix.md b/docs/product/features/connectivity/participant-matrix.md new file mode 100644 index 000000000..981709f26 --- /dev/null +++ b/docs/product/features/connectivity/participant-matrix.md @@ -0,0 +1,176 @@ +# Participant Feature Matrix + +This document provides a comprehensive matrix of different participant types, their requirements, and recommended connectivity solutions for Mojaloop integration. + + + +## Payment Use-Case DFSPs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Participant CategoryDescriptionExpected Use-CasesInfrastructure Requirements for Mojaloop IntegrationExpected Production SLALikely Relevant RegulationSpecial Security RequirementsSolution Options
    Small self-hosting DFSP- Small FI with single branch.
    - Own workstations
    - Minimal cloud and/or SaaS.
    - All moja transfer types except bulk.
    - Open banking (incl PISP, AISP)
    - Single, cheap, low-end dedicated mini-pc (e.g. RPi)
    - Single small business broadband Internet connection
    - Self-hosted core banking system e.g. Mifos
    - Use OS/Software firewall on same HW node as integration layer.
    - "Some" downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - May take many days/weeks to purchase replacement hardware on total failure.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - ~10 TPS peak sustained for 1 hour.
    - Max capable of 864000 per 24 hours.
    - Record keeping?
    - Security?
    - No need to integrate with existing enterprise security platforms.
    - Need a fully secure solution "in-a-box" following best industry practice for internet facing services i.e. including firewall.
    The “Standard Service Manager” is recommended: A minimal functionality Integration Toolkit-based solution (accessible locally by means of a BI tool). This can be hosted in a basic server, ranging from a mid-specification server for a large MFI or a small bank, right down to a Raspberry PI for the smallest DFSPs with less rigorous service continuity requirements and lower transaction volumes. The Standard Service Manager does not support bulk payments.
    - Docker compose based integration layer.
    - Minimal, self-contained integration layer.
    Low Medium self-hosted DFSP- Small FI with one or two branches.
    - Own "data centre" i.e. broom cupboard with a few servers, router, firewall etc...
    - Some cloud knowledge and/or SaaS usage.
    - All moja transfer types
    - Bulk (1000's of transfers).
    - Open banking (incl PISP, AISP)
    - Single enterprise grade server hardware node.
    - Use OS/Software firewall on same HW node as integration layer OR dedicated HW firewall.
    - "Some" downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - May take hours to replace hardware on total failure.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - ~50 TPS peak sustained for 1 hour.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...
    ?? needs more clarification
    The “Enhanced Service Manager” is recommended: Based on the “Standard Service Manager” described earlier, this extends it by adding a Kafka deployment and support for bulk payments. It can be hosted at minimum in a basic server in the DFSP's own "data centre".
    - Docker compose or docker swarm based integration layer.
    - Minimal, self-contained integration layer.
    High Medium self-hosted DFSP- Small FI with one or two branches.
    - Own "data centre" i.e. broom cupboard with a few servers, router, firewall etc...
    - Some cloud knowledge and/or SaaS usage.
    - All moja transfer types
    - Bulk (1000's of transfers).
    - Open banking (incl PISP, AISP)
    - In order to tolerate failure on 1 hardware node 3 or more hardware nodes are required. (2n+1)- "Some" limited (minutes) downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - Should have spare hardware waiting or very fast replacement services in case of failures.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - ~50 TPS peak sustained for 1 hour.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...The “Enhanced Service Manager” is recommended: Based on the “Standard Service Manager” described earlier, this extends it by adding a Kafka deployment and support for bulk payments. It can be hosted at minimum in a redundant, multiple server configuration in the DFSP's own "data centre".
    - Kubernetes based integration layer
    - Possibly have existing integration technology.
    Large self-hosted DFSP- Mature, multi-branch FI with high internal IT capability
    - Has own data centre and experts to manage systems
    - Comfortable with Cloud and hybrid applications
    - Has internal software engineering capability.
    - All moja transfer types including bulk.
    - Bulk (1000000's of transfers in a transaction @ 1000 per chunk, sorted per payee DFSP).
    - Open banking (incl PISP, AISP)
    - High availability of internal infrastructure is necessary
    - Multiple active instances of all critical integration services spread across multiple hardware nodes.
    - High availability, replicated data storage.
    - may be multi-site / availability zone / region.
    - No downtime acceptable
    - High-availability of connectivity.
    - multiple active connections via diverse routes.
    - Optional persistent storage.
    - Scheme connection and integration layer SLA should match SLA for existing internal infrastructure.
    - Up to 800 TPS peak sustained for 1 hour for e.g. FXPs.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...The “Premium Service Manager” is recommended: A fully functional, Payment Manager-type service, for use by larger DFSPs. Operation of this needs significant resources; it must be hosted either in the DFSP’s existing data centre or in the cloud.
    - Kubernetes based integration layer
    - Possibly have existing integration technology.
    + +## Fintechs which use PISP and/or AISP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Participant CategoryDescriptionExpected Use-CasesInfrastructure Requirements for Mojaloop IntegrationExpected Production SLALikely Relevant RegulationSpecial Security RequirementsSolution Options
    Small self-hosting PISP/AISP- Small org with single "branch" fintech with one or two products.
    - Own workstations / servers
    - Minimal cloud and/or SaaS.
    - Relatively small bulk payments e.g. salary payments for SMEs- Single, cheap, low-end dedicated mini-pc (e.g. RPi)
    - Single small business broadband Internet connection
    - Self-hosted core banking system e.g. Mifos
    - Use OS/Software firewall on same HW node as integration layer.
    - "Some" downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - May take many days/weeks to purchase replacement hardware on total failure.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - Bulk interface SLA?
    - How should this be defined? Batch size? time to send batch over API? response time for callbacks?
    - Max batch size approx 10k payments
    - Sending 10k payments via bulk API should take < 30 seconds.
    - Responding to callbacks should take < 5 seconds.
    - Record keeping?
    - Security?
    - No need to integrate with existing enterprise security platforms.
    - Need a fully secure solution "in-a-box" following best industry practice for internet facing services i.e. including firewall.
    - Docker compose based integration layer.
    - Minimal, self-contained integration layer.
    Low Medium self-hosting PISP/AISP- Small org with one or two branches.
    - Own "data centre" i.e. broom cupboard with a few servers, router, firewall etc...
    - Some cloud knowledge and/or SaaS usage.
    - Relatively small bulk payments e.g. salary payments for SMEs
    - Account aggregation
    - Single enterprise grade server hardware node.
    - Use OS/Software firewall on same HW node as integration layer OR dedicated HW firewall.
    - "Some" downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - May take hours to replace hardware on total failure.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - Bulk interface SLA?
    - How should this be defined? Batch size? time to send batch over API? response time for callbacks?
    - Max batch size approx 25k payments
    - Sending 25k payments via bulk API should take < 60 seconds.
    - Responding to callbacks should take < 10 seconds.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...
    ?? needs more clarification
    - Docker compose or docker swarm based integration layer.
    - Minimal, self-contained integration layer.
    High Medium self-hosting PISP/AISP- Small org with one or two branches.
    - Own "data centre" i.e. broom cupboard with a few servers, router, firewall etc...
    - Some cloud knowledge and/or SaaS usage.
    - Bulk payment for large organisations e.g. government depts.
    - Account aggregation
    - In order to tolerate failure on 1 hardware node 3 or more hardware nodes are required. (2n+1)- "Some" limited (minutes) downtime acceptable if hardware fails.
    - Some schemes may rule out DFSPs that cant meet a certain downtime SLA.
    - Should have spare hardware waiting or very fast replacement services in case of failures.
    - Full Mojaloop security feature set: mTLS, JWS, ILP
    - Bulk interface SLA?
    - How should this be defined? Batch size? time to send batch over API? response time for callbacks?
    - Max batch size approx 100-200k payments
    - Sending 100-200k payments via bulk API should take < 300 seconds.
    - Responding to callbacks should take < 120 seconds.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...- Kubernetes based integration layer
    - Possibly have existing integration technology.
    Large self-hosting PISP/AISP- Mature, multi-branch org with high internal IT capability
    - Has own data centre and experts to manage systems
    - Comfortable with Cloud and hybrid applications
    - Has internal software engineering capability.
    - Bulk payment for large organisations e.g. government depts.- High availability of internal infrastructure is necessary
    - Multiple active instances of all critical integration services spread across multiple hardware nodes.
    - High availability, replicated data storage.
    - may be multi-site / availability zone / region.
    - No downtime acceptable
    - High-availability of connectivity.
    - multiple active connections via diverse routes.
    - Optional persistent storage.
    - Scheme connection and integration layer SLA should match SLA for existing internal infrastructure.
    - Bulk interface SLA?
    - How should this be defined? Batch size? time to send batch over API? response time for callbacks?
    - Max batch size approx 1mil payments
    - Sending 1mil payments via bulk API should take < 600 seconds.
    - Responding to callbacks should take < 300 seconds.
    - Record keeping?
    - Security?
    - May need integration with existing enterprise security platforms e.g. firewalls, gateways etc...- Kubernetes based integration layer
    - Possibly have existing integration technology.
    + +## Document History +|Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|9th June 2025|Tony Williams|Initial version| \ No newline at end of file diff --git a/docs/product/features/connectivity/participation_tools_mini_guides.md b/docs/product/features/connectivity/participation_tools_mini_guides.md new file mode 100644 index 000000000..1817d5606 --- /dev/null +++ b/docs/product/features/connectivity/participation_tools_mini_guides.md @@ -0,0 +1,129 @@ +# Guide to the Selection and Use of Participation Tools + +# Background + +The Mojaloop Community has developed a range of tools for the use of participating DFSPs, which facilitate the connection between a DFSP’s back office and a Mojaloop-based scheme (the Hub). Each acts as an adapter layer that handles the complexities of Mojaloop's APIs and security requirements, allowing a DFSP to more easily connect its back office. This can greatly ease the integration process, reducing both the direct cost (the participation tools are open source, and can be freely downloaded) and the indirect cost (the integration time is greatly reduced, because the complexity is handled within the tool) of integration. Ongoing maintenance cost is also much reduced, as the participation tools are maintained by the Mojaloop Community, and only need to be “personalised” by individual DFSPs. + +Unlike the Mojaloop Hub itself, the participation tools are intended to be deployed within the DFSP’s domain, and their implementation and use remains the responsibility of the individual DFSP, though with the support of the Mojaloop Community. + +The Community has recognised that different DFSPs have different requirements and constraints that they would place on the participation tools, and that is reflected in the range of offerings. + +# Functionality + +One of the core purposes of the participation tools is to hide the complexity of the Mojaloop API. As well as all of the security, the tools handle complex, multi-step Mojaloop procedures—such as party lookups, agreement of terms, and transfers—and present them to the DFSP's systems in a more straightforward way. + +To achieve this, the participation tools all offer the following services: + +1. Management of the connection between the DFSP and Mojaloop Hub, specifically including the setup and operation of the security, including key certificate exchange. +2. Full API integration with the Mojaloop Hub, covering: + 1. Administration, for example, setting up routing/aliases for a DFSP’s customers; + 2. The participation in transactions as either debtor or creditor institution; + 3. Support for authorisation (including continuing authorisation) for third-party initiated transactions (for example, fintechs). +3. A range of open source tools to facilitate the connection between the participation tool and the DFSP’s back office (either directly into the core banking system, or into the payments engine, or into a messaging backplane). + +# Common Architectural Elements + +The common architecture of all of the participation tools consists of several key components that work together to facilitate the connection and management of transactions. + +## Core Connector + +This is the central integration component that acts as a "translator" between the DFSP's back office and the participation tool. Templates are provided in both the Apache Camel framework, which provides a declarative, integration-focused language, and TypeScript, a commonly known and understood programming language. System integrators and/or participants may choose to use these templates or create a custom connector in a technology stack of their choosing. The use of templates allows the core connector to be customized to fit the DFSP's existing backend technology rather than forcing the DFSP to change its own systems. + +## Mojaloop Connector + +This component communicates directly with the Mojaloop Hub and contains two key sub-components: +**Mojaloop-SDK:** Provides the necessary security components and handles HTTP header processing in a Mojaloop-compliant manner. + +**Simplified API:** Offers a more synchronous and use-case-oriented version of the Mojaloop FSPIOP API, which is easier for the DFSP's backend systems to consume. + +## Mojaloop Connection Manager (MCM) Client + +This client automates and simplifies the process of configuring connections to different Mojaloop environments. It handles the creation, signing, and exchange of digital certificates, which is a critical security requirement for the Mojaloop ecosystem. + +# High-level transaction flow + +The participation tools all facilitate the transaction process by acting as the DFSP's gateway to the Mojaloop Hub: + +* A transaction is initiated by the DFSP's back office. +* The back office sends the request to the Core Connector within the participation tool. +* The Core Connector translates the request for the Mojaloop Connector and its simplified API. +* The Mojaloop Connector communicates securely with the Mojaloop Switch (Hub) using the Mojaloop-SDK. +* Payments are routed and orchestrated by the Mojaloop Hub to the destination DFSP. +* The participation tool provides status updates and reconciliation information to the DFSP via monitoring portals, where these are implemented. + +# Available Participation Tools + +There are two broad groups of participation tools; first, Payment Manager, which offers all of the functionality and flexibility a large bank might require; and second, a group of solutions based around Mojaloop’s Integration Toolkit, which can be sized and hosted to meet the varying requirements of a broad range of other DFSPs. + +## Payment Manager + +Also known as Payment Manager for Mojaloop (PM4ML), Payment Manager is a full-function Mojaloop participation tool that offers all the features a large corporate bank would expect. It can be deployed either in the cloud or in a bank’s data centre, and supports all of the DR options such a bank would expect. It also has comprehensive management and reporting capabilities. + +

    + PM4ML Architecture +

    +**Figure 1: Payment Manager Architecture** + +The above diagram represents a high level view of the architecture of Payment Manager, and also indicates the elements of a Mojaloop Hub that it interacts with. + +### Payment Manager’s Portals + +PM4ML’s business and technical Portals provide user-friendly interfaces with dashboards for monitoring critical information: +- **Transaction monitoring**: Displays real-time and historical transaction statuses. +- **Service status**: Allows DFSPs to monitor the health and performance of their connections. +- **Configuration management**: Provides a single point for managing security keys, certificates, and endpoint configurations. + +## Integration Toolkit + +The Integration Toolkit set of participation tools is architected to allow significant flexibility in how a DFSP chooses to connect to a Mojaloop Hub, and can be deployed on a variety of environments to meet the needs of everything from the smallest MFI to the largest bank. + +### Overview + +

    + ITK Architecture +

    +**Figure 2: ITK Architecture** + +As would be expected, and as illustrated in the above diagram, there are common features with Payment Manager: + +* Both Core Connector and Mojaloop Connector function as before. +* The Mojaloop Connection Manager Client (MCM Client) remains responsible for the creation, signing, and exchange of digital certificates, underpinning the security of the connection to the Mojaloop Hub. + +However, there are some significant differences. The operation of the MCM Client is now subject to the control of MCM Agent Services, which orchestrates the management of the security using a state machine. Control and configurations of the Agent Services is carried out using the ITK Configuration Utility, which presents a console-type interface to the DFSP’s operational staff. This performs the same function as Payment Manager’s Configuration portal. + +The security of the ITK Configuration Utility/console is subject to the DFSP's own infrastructure security. The server (or the Virtual Machine (VM)) the ITK components run on must be secured as per any other server infrastructure within the DFSP's administrative boundary. + +Unlike Payment Manager, the ITK doesn't include any portals for monitoring transactions (which is expected to be handled by the DFSP's existing back office systems) or service status, while the ITK Configuration Utility fulfils the same role as Payment Manager's configuration management portal. + +### ITK Deployment Options + +The options for deploying ITK are catalogued in the [Participant Feature Matrix](https://docs.mojaloop.io/product/features/connectivity/participant-matrix.html) and can be summarised as follows: + +* **A small DFSP**, such as a small MFI or bank, is expected to self-host the ITK. This approach will support all use cases except the initiation of bulk payments (bulk payments can still be received). Low transaction levels are expected (max 10 TPS), and some downtime (potentially a few hours) is acceptable. + * It is recommended that a minimal functionality version of ITK be deployed on a small server, right down to a single board computer such as a Raspberry PI for the smallest DFSPs. + * Transaction monitoring should be carried out through the DFSP's existing back office. + * Deployment is via Docker Compose. + +* **A low-medium sized DFSP**, such as a bank or MFI with one or two branches and their own “broom cupboard” data centre, is expected to self-host the ITK. This approach will support all use cases, including the initiation of small scale bulk payments. Peak transaction levels of around 50 TPS are supported, and some limited downtime (measured in hours) is acceptable. + * It is recommended that a fully functional version of ITK be deployed on a basic server, hosted in the DFSP’s own data centre. + * A Kafka deployment is needed to support bulk payments. + * Deployment is via Docker Compose or Docker Swarm. + * Minimal integration with existing enterprise security platforms. + * Transaction monitoring should be carried out through the DFSP's existing back office. + +* **A medium-large sized DFSP**, such as a medium-sized FI with a few branches and their own self-hosted data centre and some reasonable internal IT skills, is expected to host the ITK. This approach will support all use cases, including the initiation of small/medium scale bulk payments. Peak transaction levels of around 50 TPS are supported, and some limited downtime (measured in minutes) is acceptable. + * In order to achieve the maximum downtime requirements, a multiple server configuration is required, managed using Kubernetes. + * It is recommended that a fully functional version of ITK be deployed, with transaction monitoring carried out through the DFSP's existing back office. + * A Kafka deployment is needed to support bulk payments. + * Deployment is via Kubernetes. + * May need integration with existing enterprise security platforms. +* **A large DFSP**, such as a mature, multi-branch FI with its own industry-standard data centre and sophisticated internal IT skills, is recommended to use Payment Manager. + +## Applicability + +This version of this document relates to Mojaloop Version [17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|17th December 2025| Paul Makin |Initial version| diff --git a/docs/product/features/deployment.md b/docs/product/features/deployment.md new file mode 100644 index 000000000..169876c92 --- /dev/null +++ b/docs/product/features/deployment.md @@ -0,0 +1,22 @@ +# Deploying Mojaloop +There is a range of different reasons to deploy Mojaloop, ranging from a desire to learn more about Mojaloop or a wish to evaluate its suitability for some purpose, through developers who wish to develop or test new features, or perhaps an adopter who wishes to evaluate its functionality and connectivity, through to a production-grade deployment of a national payments system. + +## Deployment Guide + +For each scenario, the Mojaloop Community has developed appropriate deployment tools. The following [deployment guide](./deployment/deploying.md) includes a matrix cross-referencing user types and the purpose of the deployment, including notes about the footprint/hardware expectation and the associated SLAs. For each, a deployment tool is recommended, and a separate table provides a brief introduction to each tool. + +## Deployment Tools + +Having established which deployment tool is appropriate for the reader's requirements, the [deployment tools guide](./deployment/tools.md) provides more details for each of the tools, including performance and security features each supports. + +## Production Readiness + +The Community has developed a self assessment matrix that can be used by adopters to assess the readiness of their Mojaloop deployment and their organisation to move to Production. Note that this document is not intended to form the basis of any formal assessment of production readiness of any Mojaloop deployment or scheme. It is intended only as a set of basic checks to ensure some important aspects of a production system have been considered. A full assessment of fit-for-purpose readiness of a Mojaloop deployment remains the responsibility of the scheme operator only. + +You can [view the matrix here](./Production_Readiness_Technical_Assessment.md), and the form can be [downloaded here](https://github.com/mojaloop/product-council/tree/main/Documentation/Deployment%20Readiness) when you are ready to begin an assessment. + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|18th December 2025| Paul Makin, Julie Guetta|Added a link to the Production Readiness document| +|1.0|3rd June 2025| Paul Makin|Initial version| diff --git a/docs/product/features/deployment/deploying.md b/docs/product/features/deployment/deploying.md new file mode 100644 index 000000000..332126912 --- /dev/null +++ b/docs/product/features/deployment/deploying.md @@ -0,0 +1,233 @@ +# Deploying Mojaloop + +This section details the deployment aspects of the Mojaloop Hub. + +## Deployment of Mojaloop Hub (excluding participant integrations) + +The following table provides guidance on which Mojaloop deployment scenario is most appropriate for different user types and use cases. + +For detailed information about each deployment tool, please refer to the [Deployment Tools](./tools) documentation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Deployment Scenario / User typeLearningEvaluation (choosing Mojaloop)Use-case TestingFeature Development and Dev TestingProduction
    StudentFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    N/AFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint: Single machine e.g. laptop or single VM.
    SLA: None
    N/A
    DeveloperFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    N/AFootprint:
    - Single machine e.g. laptop or single VM.
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Single machine e.g. laptop or single VM.
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    N/A
    Business analystFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint:
    - Single machine e.g. laptop or single VM.
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    N/A
    Potential adopterFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    N/A
    Auditor / External QA / Security AnalystFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    N/AN/A
    System IntegratorFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Fully redundant, replicated, high availability deployment
    - On-premises or cloud
    SLA: High SLA in many areas.
    Hub OperatorFootprint: Single machine e.g. laptop or single VM.
    SLA: None
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Low resource usage, single cluster
    - Production like environment (sandbox? lower SLA than prod)
    SLA:
    - Lower than prod but possibility of testing NFRs.
    Footprint:
    - Fully redundant, replicated, high availability deployment
    - On-premises or cloud
    SLA: High SLA in many areas.
    + +## Deployment Tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ToolFeaturesMinimum Resource RequirementsSecurityDocumentationSLACaveats, Assumptions, Limitations etc...
    core test harness- single node
    - docker-compose
    - "profiles" available
    - No HELM
    - No gateway
    - No ingress/egress components
    - No IAM stack
    - Deploys:
    - core services & backing services
    - portals (optional)
    - monitoring stack (optional)

    Used in CI pipelines for integration testing.
    Mid level laptop or desktop workstationZero security- Developer focused documentation.
    - Non-technical user documentation to support learning objectives.
    - Product level documentation to explain features e.g. what it does and where it is appropriate for use
    - No SLA- Never to be used in production.
    - Never to be used to process real money transactions.
    HELM deploy- Just HELM charts needed to deploy Mojaloop services and backing services.- High end laptop or workstation
    - Small cloud kubernetes cluster.
    User is required to harden their own Kubernetes cluster.- Developer focused documentation
    - Semi-technical / BA focused documentation to support use-case experimentation and testing.
    - Product level documentation to explain features e.g. what it does and where it is appropriate for use.
    - Must be able to achieve SLAs (given baseline hardware specs):
    - Availability:
    - ? 4/5 9's?
    - RTO/RPO: ? As close to zero as possible.
    - Throughput/Performance
    - TPS: 1000+ (sustained for 1 hour)
    - Latency (Percentiles) (excluding external latencies):
    - Clearing: 99% < 1 second.
    - Lookup: 99% < second.
    - Agreement of Terms: 99% < 1 second.
    - Data management:
    - Mitigations against data loss i.e. replication, disaster recovery.
    - Retention (audit, compliance)
    - Archiving.

    NB: Strategy is high availability over disaster recovery.
    - Can be used in production.
    - Safe for processing real money transactions.
    - User/adopter is required to deploy and configure their own infrastructure, including Kubernetes cluster(s), ingress/egress, firewalls etc...
    - Security is limited to what HELM charts provide. Additional security design and configuration is required.
    Infrastructure as Code- multiple deployment platform targets
    - AWS, On-prem, other clouds, (modular)
    - multiple orchestration layer options
    - managed k8s, microk8s, eks
    - GitOps pattern (control centre)
    - can deploy and manage multiple hub instances / environments
    - Deploys:
    - control centre
    - core services & backing services (options for managed backing services)
    - portals
    - IAM stack
    - monitoring stack
    - pm4ml
    - GitOps pattern
    - High end cloud or on-premise infrastructure.Full security- Multiple levels of documentation targeting all levels of "user".
    - Developer docs to enable use, maintenance, enhancement, extenstion of IaC capabilities e.g. adding new targets / services / features.
    - Detailed architecture diagrams and explanation to enable deep understanding.
    - Tech ops focused docs to enable "infrastructure engineer" level users to use IaC to deploy and maintain multiple mojaloop instances for development, testing and production.
    - Product level documentation to explain IaC features e.g. what it does and where it is appropriate for use.
    - Must be able to achieve SLAs (given baseline hardware specs):
    - Availability:
    - ? 4/5 9's?
    - RTO/RPO: ? As close to zero as possible.
    - Throughput/Performance
    - TPS: 1000+ (sustained for 1 hour)
    - Latency (Percentiles) (excluding external latencies):
    - Clearing: 99% < 1 second.
    - Lookup: 99% < second.
    - Agreement of Terms: 99% < 1 second.
    - Data management:
    - Mitigations against data loss i.e. replication, disaster recovery.
    - Retention (audit, compliance)
    - Archiving.

    NB: Strategy is high availability over disaster recovery.
    - Can be used in production.
    - Safe for processing real money transactions.
    + +## Document History +|Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.2|20th August 2025|Sam Kummary|Updated sections to use helm as deployment option where relevant| +|1.1|3rd June 2025|Paul Makin|Removed performance section, moved it to new doc| +|1.0|7th May 2025|Tony Williams|Initial version| \ No newline at end of file diff --git a/docs/product/features/deployment/tools.md b/docs/product/features/deployment/tools.md new file mode 100644 index 000000000..ed3f77c3e --- /dev/null +++ b/docs/product/features/deployment/tools.md @@ -0,0 +1,134 @@ +# Mojaloop Deployment Tools + +This document outlines the three deployment options for Mojaloop, ordered by complexity and production-readiness. Each tool serves specific use cases and deployment scenarios. + +## Core Test Harness + +
    +
    + Development and Testing Environment +
    + +The Core Test Harness provides a single-node development environment using docker-compose. This tool implements a minimal Mojaloop stack without production components, making it suitable for development and testing. + +> **🔗 Technical Documentation:** +> **GAP** - No dedicated technical documentation found for Core Test Harness. Related references in: +> - [Deployment Guide - Prerequisite Backend Helm Deployment](../../../technical/technical/deployment-guide/README.md#_5-1-prerequisite-backend-helm-deployment) (mentions docker-compose examples) +> - [Release Notes](../../../technical/technical/releases.md) (mentions Core-test-harness validation) + +### Implementation Details + +The Core Test Harness runs on a single machine using docker-compose for orchestration. It deploys core services and backing services without production-grade components like gateways, ingress/egress, or IAM stacks. The implementation uses configurable profiles to manage different deployment scenarios. + +Resource requirements include a mid-level laptop or desktop workstation with sufficient memory for container orchestration. The tool integrates with CI pipelines for automated testing and validation. + +### Development Workflow + +Developers interact with the Core Test Harness through docker-compose commands. The tool supports local development workflows with hot-reloading capabilities. Configuration occurs through environment variables and docker-compose override files. + +### Testing Capabilities + +The Core Test Harness enables unit testing, integration testing, and end-to-end testing of Mojaloop components. It provides a controlled environment for testing service interactions and validating business logic. + +## HELM Deploy + +
    +
    + Production Deployment Solution +
    + +HELM Deploy provides production-ready deployment capabilities through HELM charts. This implementation requires a pre-configured Kubernetes cluster and implements production-grade security and performance requirements. + +> **🔗 Technical Documentation:** +> - [Mojaloop Deployment Guide](../../../technical/technical/deployment-guide/README.md) - Comprehensive HELM deployment documentation +> - [Upgrade Strategy Guide](../../../technical/technical/deployment-guide/upgrade-strategy-guide.md) - HELM upgrade procedures +> - [Deployment Troubleshooting](../../../technical/technical/deployment-guide/deployment-troubleshooting.md) - Common issues and solutions + +### Infrastructure Requirements + +The deployment requires: +- A hardened Kubernetes cluster +- Network policies and security configurations +- Storage class definitions +- Resource quotas and limits + +### Performance Specifications + +The implementation must meet these performance criteria: +- 1000+ TPS sustained for one hour +- 99th percentile latency under 1 second for: + - Clearing operations + - Lookup operations + - Agreement of Terms +- 99.99% availability +- Zero RTO/RPO for critical operations + +### Security Implementation + +Security implementation includes: +- Network policy enforcement +- Pod security policies +- Service mesh integration +- Secret management +- Certificate management + +## Infrastructure as Code + +
    +
    + Enterprise Deployment Solution +
    + +The Infrastructure as Code (IaC) implementation provides a comprehensive deployment solution supporting multiple platforms and orchestration layers. It implements GitOps patterns for managing multiple hub instances. + +> **🔗 Technical Documentation:** +> **GAP** - Limited internal technical documentation for IaC setup and configuration +> - [IaC Installation Guide](../../../getting-started/installation/installing-mojaloop.md) - Basic IaC overview (see item 2) +> - [IaC Deployment Blog](https://infitx.com/deploying-mojaloop-using-iac) - External detailed guide +> - [IaC AWS Platform Repository](https://github.com/mojaloop/iac-aws-platform) - AWS-specific implementation + +### Platform Support + +The implementation supports: +- AWS deployment through CloudFormation/Terraform +- On-premises deployment through Terraform +- Multi-cloud deployment through provider-agnostic modules +- Multiple Kubernetes distributions: + - Managed k8s services + - Microk8s + - EKS + +### Control Center Architecture + +The control center implements GitOps patterns for: +- Multi-environment management +- Configuration versioning +- Deployment automation +- State management +- Drift detection + +### Component Deployment + +The implementation deploys: +- Control center services +- Core Mojaloop services +- Backing services +- Portal applications +- IAM infrastructure +- Monitoring stack +- PM4ML components + +### Performance and Security + +The IaC implementation enforces: +- Production-grade security controls +- Performance requirements matching HELM Deploy +- High availability configurations +- Disaster recovery procedures +- Compliance requirements + +## Document History +|Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|5th June 2025| Tony Williams|Added links to technical documentation| +|1.0|14th May 2025| Tony Williams|Initial version| \ No newline at end of file diff --git a/docs/product/features/development.md b/docs/product/features/development.md new file mode 100644 index 000000000..0c180ccbc --- /dev/null +++ b/docs/product/features/development.md @@ -0,0 +1,42 @@ +# Ongoing Development +No software is ever finished, and Mojaloop is no exception. There are always new features to be considered, new APIs to be implemented, new portals to be added, and of course there is always ongoing maintenance, and security requires constant vigilance. + +The Mojaloop Roadmap addresses and prioritises these needs, placing them on a timeline, and defines them as a set of workstreams. Each of these work streams has a workstream lead, responsible for defining, managing and delivering the workstream to the Mojaloop Community. The workstream lead is supported by a number of contributors, who may be engineers helping to implement a feature, or those who can document the feature, or people helping to define the requirements. + +## Active Workstreams +The current active workstreams are: + +- [Participation Tools](./workstreams/participation.html) +- [Participation Tools for Fintechs](./workstreams/fintech_participation.html) +- [Deployment Tools](./workstreams/deployment.html) +- [QA Framework](./workstreams/qa.html) +- [Dispute Management](./workstreams/dispute.html) +- [LEI Addressing](./workstreams/lei.html) +- [ISO 20022 Refinement](./workstreams/iso20022.html) +- [Mojaloop Evolution](./workstreams/evolution.html) +- [Performance](./workstreams/performance.html) +- [Platform Quality and Security](./workstreams/pqs.html) +- [Core and Releases](./workstreams/core.html) + +Click on each to find out details of the workstream, such as objectives and which community members are contributing. + +## Candidate Workstreams +As well as the currently active workstreams, we have a number of candidate workstreams that are "fast followers" behind them - that is, these have been identified as high priority, but as things stand there is insufficient capacity within the Community to address them. These are: + +- Implementation of PISP V2.0 +- Implementation of Settlement V3.0 +- Operator Portal enhancements - improving the UI, addressing perceived gaps in functionality +- Enhanced forensic audit support +- Merchant Payments - extending the current relatively simple solution for merchant registration and merchant-presented QR code payments to include some of the richer elements a live merchant payments scheme would need. + +Please contact the Product Director if you'd like to discuss any of these candidate workstreams - in particular, how we make them active. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|25th November 2025| Paul Makin|Reviewed/amended the list of candidate workstreams| +|1.0|4th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/ecosystem.svg b/docs/product/features/ecosystem.svg new file mode 100644 index 000000000..e18dc9867 --- /dev/null +++ b/docs/product/features/ecosystem.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/product/features/engineering.md b/docs/product/features/engineering.md new file mode 100644 index 000000000..e02c0f17d --- /dev/null +++ b/docs/product/features/engineering.md @@ -0,0 +1,84 @@ +# Engineering Principles + +This section details the principles behind the engineering aspects of +the Mojaloop Hub. + +## Logging + +Industry-standard logging mechanisms for containers (stdout, stderr) are +the default. + +## Transfers + +1. Resource identifiers are unique within a scheme and enforced by the hub. + +2. API methods which can potentially return large result sets are paged + by default. + +3. Settlement model lookups use the currencies of payer and payee DFSP. + +4. Resources/entities are typed so they can be differentiated + +5. Names (of objects, methods, types, functions etc...) are clear and + not open to misinterpretation. + +## Accounts & Balances + +1. Ledger implementation uses a strongly consistent underlying data + store. + +2. Critical financial data is replicated to multiple geographically + distributed nodes in a manner that is strongly consistent and highly + performant, such that the failure of multiple physical nodes will + result in zero data loss. + +## Participants + +1. Participant connectivity concerns are handled at a gateway layer to + facilitate the use of industry standard tooling. + +## Scalability and Resilience + +1. Overall system transfer throughput (all three transfer phases) is + scalable in as near linear manner as possible by the addition of low + specification, commodity hardware nodes. + +2. Business critical data can be replicated to multiple geographically + distributed nodes in a manner that is strongly consistent and highly + performant; Failure of multiple physical nodes will result in zero + data loss. + +## Mojaloop Specification + +1. JWS is supported + +2. Mutually authenticated (x.509) TLS v1.2 should be supported between + participants and the hub + +## General + +1. Context specific processing is done once and results cached in + memory where required later in the same call stack. + +2. All log messages contain contextual information. + +3. Failures are anticipated and handled as gracefully as possible. + +4. Cross process / network queries ask for only the data required. + +5. Layers of abstraction are kept to an absolute minimum. + +6. Interprocess communication uses the same transport mechanism + wherever possible. + +7. Aggregates are stateless. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History +|Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14th April 2025| Paul Makin|Removed deployment sections| +|1.0|5th February 2025| James Bush|Initial version| \ No newline at end of file diff --git a/docs/product/features/fx.md b/docs/product/features/fx.md new file mode 100644 index 000000000..3e6b007b5 --- /dev/null +++ b/docs/product/features/fx.md @@ -0,0 +1,127 @@ +# Foreign Exchange - Currency Conversion + +The Mojaloop currency conversion functionality enables foreign exchange (FX) transactions, supporting multiple approaches for currency conversion within the ecosystem. Currently, the system implements **Payer DFSP currency conversion**, where the Payer DFSP (Digital Financial Services Provider) coordinates with a foreign exchange provider (FXP) to obtain liquidity in another currency to facilitate a transfer. + +Future enhancements to the currency conversion design include: +1. **Payee DFSP conversion**
    The Payee DFSP arranges for foreign exchange conversion. +1. **Reference currency conversion**
    Both the Payer and Payee DFSPs engage with FXPs to convert funds via a reference currency. +1. **Bulk conversion**
    DFSPs can procure currency liquidity from an FXP in bulk. + +## Role of the Foreign Exchange Provider (FXP) + +A core feature of Mojaloop's currency conversion capability is its support for a competitive FX marketplace, where multiple FXPs can provide real-time exchange rate quotes. This design fosters an open and dynamic environment for foreign exchange transactions. + +The currency conversion process follows a three-step workflow: +1. **Quote Request**
    The Payer DFSP requests a quote from an FXP. For example, a Zambian DFSP can obtain a conversion quote for a specific transfer. +1. **Quote Agreement**
    The Payer DFSP reviews the exchange rate and terms provided by the FXP. Once accepted, the FXP locks in the rate. +1. **Transfer Finalization**
    Upon notification from the Mojaloop scheme that the dependent transfer has been completed, the conversion process is finalized. + +This streamlined approach ensures transparency and competitiveness in FX transactions, benefiting both DFSPs and end users. + +## Impact of Amount Type on Currency Conversion + +The Payer DFSP conversion implementation supports two distinct scenarios based on the amount type specified in the transaction: +1. **Sending funds in the source (local) currency** +1. **Making a payment in target (a foreign) currency** + +### Sending Funds to an Account in Another Currency +In this use case, the **Payer DFSP** initiates a transfer using the amount type **SEND**, specifying the transfer amount in the payer's local currency (source currency). This method is commonly used for **P2P remittance** transfers, where the sender transfers funds in their local currency, and the recipient receives the equivalent amount in their respective currency after conversion. + +### Currency Conversion Transfer (source currency) +Below is a simplified sequence diagram showing the flows between the Participant organizations, the foreign exchange providers and the Mojaloop switch for a currency conversion transfer specified in source currency. + +The flow is divided up into: +1. [Discovery Phase](#discovery-phase) +1. [Agreement Phase - Currency Conversion](#agreement-phase---currency-conversion) +1. [Agreement Phase](#agreement-phase) +1. [Payer DFSP presents terms to Payer](#payer-dfsp-presents-terms-to-payer) +1. [Transfer Phase](#transfer-phase) + +#### Discovery Phase +The Payer DFSP identifies the Payee DFSP organization and confirms the account validity and currency. + +![Discovery Phase](./CurrencyConversion/Payer_SEND_Discovery.svg) + +#### Agreement Phase - Currency Conversion +The Payer DFSP makes a request to the FXP for liquidity cover for transfer. The currency conversion terms are returned. +![Currency Conversion](./CurrencyConversion/PAYER_SEND_CurrencyConversion.svg) + +#### Agreement Phase +The Payer DFSP makes a request to the Payee DFSP for the transfer terms. +![Agreement](./CurrencyConversion/PAYER_SEND_Agreement.svg) + +#### Payer DFSP presents terms to Payer +At this point the party information, the conversion terms, and the transfer terms have been provided to the Payer DFSP. The Payer DFSP presents these terms to the Payer and asks wether to proceed or not. +![Send Confirmation](./CurrencyConversion/PAYER_SEND_Confirmation.svg) + +#### Transfer Phase +Now that the terms of the transfer have been agreed to, the transfer can proceed. +Both the Conversion and the transfer terms are comitted together. +![Transfer](./CurrencyConversion/PAYER_SEND_Transfer.svg) + + +### Mojaloop Connector Integration for Currency Conversion + +Below is a detailed sequence diagram that shows the complete flow, and includes the **Mojaloop Connector** and integration APIs for all participant organizations. (This is a useful view if you are building integrations as a participant organization.) + +#### Discovery phase - Mojaloop Connector +Mojaloop make use of an Oracle to identify the DFSP organization associated with the Party identifier. The Payee DFSP must respond to the GET /parties to confirm that the account exists and is active for that Party identifier. The supported currencies for that account are returned. +![Discovery Phase](./CurrencyConversion/FXAPI_Discovery.svg) + + +#### Agreement Phase Currency Conversion - Mojaloop Connector +The Payer DFSP does not transact in any of the Payee DFPSs supported currencies. This triggers the requirement for currency conversion inside the Mojaloop Connector. The Payer DFSP uses it's local cache of FXPs to select and makes a request to the Foreign Exchange provider for liquidity cover and a conversion rate. +![Currecny Conversion](./CurrencyConversion/FXAPI_Payer_CurrencyConversion.svg) + +#### Agreement Phase - Mojaloop Connector +Liquidity in target currency has been secured. The Payer DFSP can now proceed to request an agreement of terms from the Payee DFSP. These terms are in target currency. +![Agreement Phase](./CurrencyConversion/FXAPI_Payer_Agreement.svg) + +#### Sender Confirmation +All the terms for the currency conversion and transfer have been obtained by the Payer DFSP and FXP. It is now time to collate those terms and present them to the Payer for confirmation. +![Confirmatiom](./CurrencyConversion/FXAPI_Payer_SenderConfirmation.svg) + +#### Transfer Phase +The terms of the transfer have been accepted. The transfer phase can now commence. +![Transfer](./CurrencyConversion/FXAPI_Payer_Transfer.svg) + +## Currency Conversion Transfer (target currency) +For this use case, the Payer DFSP will specify the transfer with amount type **RECEIVE** and define the transfer amount in the **Payee's local currency** (the target currency). +An secondary use case example for this is a cross boarder Merchant Payment. + +Below is a detailed sequence diagram that shows the complete flow, and includes the Mojaloop connector and integration APIs for all participant organizations. + +#### Discovery +Mojaloop make use of an Oracle to identify the DFSP organization associated with the Party identifier. The Payee DFSP must respond to the GET /parties to confirm that the account exists and is active for that Party identifier. The supported currencies for that account are returned. +![Discovery](./CurrencyConversion/FXAPI_Payer_Receive_Discovery.svg) + + +#### Agreement +The Payer DFSP does not support any of the Payee DFSP's currencies, requiring currency conversion within the Mojaloop Connector. Since the payment request is in the target currency, an agreement with the Payee DFSP must be established before initiating a liquidity request with the foreign exchange provider. The Payer DFSP first negotiates the transfer terms with the Payee DFSP, then uses its local cache of foreign exchange providers to select one and request liquidity coverage and a conversion rate. +![Agreement](./CurrencyConversion/FXAPI_Payer_Receive_Agreement.svg) + +#### Sender Confirmation +All the terms for the currency conversion and transfer have been obtained by the Payer DFSP and FXP. It is now time to collate those terms and present them to the Payer for confirmation. +![Sender Confirmation](./CurrencyConversion/FXAPI_Payer_Receive_SenderConfirmation.svg) + +#### Transfer +The terms of the transfer have been accepted. The transfer phase can now commence. +![Transfer](./CurrencyConversion/FXAPI_Payer_Receive_TransferPhase.svg) + + +## Abort flows +This sequence diagram show how the design implements abort messages during the currency conversion transfer phase. + +![Transfer](./CurrencyConversion/Payer_SEND_ABORT_TransferPhase.svg) + +## Open API References +These Open API references are designed to be readable for both software an review person. The show the detailed requirements and implementations of the API design. + +- [FSPIOP v2.0 specification](https://mojaloop.github.io/api-snippets/?urls.primaryName=v2.0) - [Open Api definition](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v2.0-document-set/fspiop-v2.0-openapi3-implementation-draft.yaml). +- [FSPIOP v2.0 ISO 20022 specification](https://mojaloop.github.io/api-snippets/?urls.primaryName=v2.0_ISO20022) - [Open Api definition](https://github.com/mojaloop/api-snippets/blob/main/docs/fspiop-rest-v2.0-ISO20022-openapi3-snippets.yaml). +- [API Snippets Open Api definition](https://github.com/mojaloop/api-snippets/blob/main/docs/fspiop-rest-v2.0-openapi3-snippets.yaml) +- [Mojaloop Connector backend](https://mojaloop.github.io/api-snippets/?urls.primaryName=SDK%20Backend%20v2.1.0) - [Open Api definition](https://github.com/mojaloop/api-snippets/blob/main/docs/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets.yaml) +- [Mojaloop Connector outbound](https://mojaloop.github.io/api-snippets/?urls.primaryName=SDK%20Outbound%20v2.1.0) - [Open Api definition](https://github.com/mojaloop/api-snippets/blob/main/docs/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets.yaml) + + + diff --git a/docs/product/features/htlc.md b/docs/product/features/htlc.md new file mode 100644 index 000000000..8bedf0b08 --- /dev/null +++ b/docs/product/features/htlc.md @@ -0,0 +1,34 @@ +# Hashed Timelock Contracts +Mojaloop uses ILP's cryptographic locks to ensure atomic, conditional transfers between DFSPs. The mechanism centres around Hashed Timelock Contracts (HTLCs), which allow Mojaloop to support conditional transfers — ensuring a transfer either completes fully across all participating parties, or not at all. + +A contract is agreed between the Payee and Payer DFSPs during the Agreement of Terms phase of a Mojaloop transaction, which begins when the Payer DFSP proposes a transaction, by means of a quotation request. + +When the Payee DFSP is satisfied that the transaction can go ahead (having completed its own internal checks), the Payee DFSP: +- Amends the proposed terms of the transaction to set out the conditions on which it will carry out the transaction (which might include, for example, the fees it will charge and any compliance conditions); +- Creates the Transaction object, which defines the terms on which it is prepared to honour the payment request; +- Creates and retains the Fulfilment, which is a hash of the Transaction object, itself signed with the Payee DFSP's private key (a key created specifically for, and restricted to, this purpose); +- Creates the Condition, which is a hash of the Fulfilment; +- Appends the Condition to the Transaction object; +- And returns it to the Payer DFSP in a quotation response. + +If the Payer DFSP accepts the terms of the transaction, it sends a transfer request, comprising the Transaction object, the received Condition and an expiry time, to the Mojaloop Hub. + +The Mojaloop Hub stores the Condition, and forwards the transfer request to the Payee DFSP. It also starts a timer to match the specified expiry time. + +On receipt of the transfer request, the Payee DFSP: +- Verifies that the Condition received matches that agreed (this includes a check that the payment requested is the same as the payment it agreed to), and satisfies itself that the compliance conditions have been met; +- Returns the Fulfilment to the Mojaloop Hub in a transfer response. + +The Mojaloop Hub hashes the returned Fulfilment to validate that it matches the Condition received from the Payer DFSP, and if successful notifies the Payer DFSP (and the Payee DFSP, if this has been requested) that an obligation has been created between them; that is, that the payment has been cleared. + +The notification to the Payer DFSP includes the fulfilment, which acts as cryptographic proof of irrevocable completion. If the Payer DFSP re-generates the Condition and finds that it has changed from that agreed, then they should raise a dispute with the Payee DFSP. + +Note that if the transaction timer expires at the Hub before the Fulfilment is received from the Payee DFSP, the Hub will notify each DFSP that the transaction has been cancelled. + +## Applicability +This document relates to Mojaloop Version 17.0.0 +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|2nd July 2025| Paul Makin|Updated after review by Michael Richards| +|1.0|30th June 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/interscheme.md b/docs/product/features/interscheme.md new file mode 100644 index 000000000..17be33f59 --- /dev/null +++ b/docs/product/features/interscheme.md @@ -0,0 +1,79 @@ +# Interscheme + +Interscheme is the approach adopted by the Mojaloop community to connect schemes while preserving the three phases of a Mojaloop transfer and ensuring end-to-end non-repudiation. This means that the agreement reached during a transfer remains between the originating and receiving DFSP/FXP organizations, regardless of the routing path or the number of schemes involved. + + +:::tip Non-repudiation +Ensuring non-repudiation across schemes means that the proxy is not involved in the agreement of terms which helps reduce costs. +::: + +The initial implementation of this feature enables the connection of multiple Mojaloop schemes. Over time, this ecosystem is expected to expand as additional national schemes adopt this protocol and new connectors are developed to enhance interoperability. + +To support this effort, Mojaloop introduced a new proxy participant organization. The proxy adapter serves as the implementation of the Mojaloop-to-Mojaloop connection component. + +## What is a Proxy +Schemes are connected via a proxy participant, which is registered to act as an intermediary within the scheme for adjacent DFSPs/FXPs in other schemes. + +## Dynamic Routing of Parties +This implementation makes use of a dynamic routing. This meaning that no initial and ongoing maintenance of party identifiers is required between schemes. The system makes use of a broadcast to scheme discovery that identifier and caches the organisation associated with a party identifier. + +## Assumptions +This approach is based off the following assumptions: +1. No two connected participants share the same identifier. +1. Each connected scheme is responsible for routing party identifiers within its own system. (In Mojaloop, this means each scheme maintains the oracles needed to route payments for participant parties in its network.) + +## General Patterns +There are certain general patterns that emerge +### Happy Path Patterns +![Happy Path Patterns](./Interscheme/Interscheme-Happypath.svg) + +### Error Patterns +![Error Patterns](./Interscheme/Interscheme-ErrorCases.svg) + +## Interscheme On Demand Discovery Design +The discovery flows are summarized as follows: +1. On Demand loading of cross network identifiers - using Oracles for identifier lookups in local scheme +2. On Demand loading for all identifiers + +### Using Oracles to Cache Identifiers +- Scheme uses Oracles to map local identifiers to participants of the scheme +- Identifiers for other schemes are discovered via a depth first search, but asking all participants. Proxy participant then forward the request to the connected scheme +- This diagram shows two connected schemes, but this design work for any number of connected schemes. + +![Interscheme - On Demand Discovery Sequence Diagram](./Interscheme/Interscheme-OnDemandDiscovery.svg) + + +### On Demand Discover with incorrectly cached results +- When an identifier moved to another dfsp provider, then the store cache for that participant will route to an unsuccessful get \parties call. +- Self heal if there is an error routing the payment or proxy cache reference is lost + +Here is a sequence diagram show how that gets updated. +#### Sequence Diagram +![Interscheme - Managing Stale Cache](./Interscheme/Interscheme-StalePartyIdentifierCache.svg) + +## Interscheme - Agreement Phase +The Agreement phase makes use of the proxy cache to route the messages. +Here are the implementation details. + +![Interscheme - Agreement](./Interscheme/Interscheme-Agreement.svg) + +## Interscheme - Transfer Phase +The Transfer phase makes use of the proxy cache to route the messages. +Here are the implementation details. + +![Interscheme - Transfers](./Interscheme/Interscheme-Transfer.svg) + +## Interscheme - GET Transfer +The GET Transfer is resolved locally to return the local schemes status of the transfer. +Here are the implementation details. +![Interscheme - GET Transfers](./Interscheme/Interscheme-GETTransfer.svg) + +## Admin API - defining Proxy Participants +This is how Proxies are defined. +![Admin API](./Interscheme/SettingUpProxys.svg) + +## Clearing Accounts for Inter-scheme FX transfers +This diagram illustrated how the obligations are updated during transaction clearing. + +![Clearing Accounts](./Interscheme/InterschemeAccounts-Clearing.png) + diff --git a/docs/product/features/invariants.md b/docs/product/features/invariants.md new file mode 100644 index 000000000..ddc0945d1 --- /dev/null +++ b/docs/product/features/invariants.md @@ -0,0 +1,360 @@ +# Invariants + +## General Principles + +**The primary function of the platform is to clear payments in real-time +and facilitate regular settlement, by the end of the value day.** + +1. The platform allows participants to clear funds immediately to their + customers while keeping the risks and costs associated with this to + a minimum. + +2. The platform supports per-transfer checks on available liquidity + where these are required in support of the first objective. + +3. The hub is optimized for critical path. + +4. Intra-day Automated Settlement; configured by scheme and + implementation using recommended settlement models for financial + market infrastructure. + +**The hub supports fully automatic straight-through processing.** + +1. Straight through processing helps reduce human errors in the + transfer process which ultimately reduces costs. + +2. The automated nature of straight through processing leads to faster + value transfers between end customers. + +**The hub requires no manual reconciliation as the protocol for +interacting with the hub guarantees deterministic outcomes.** + +1. When a transfer is finalized, there can be no doubt about the status + of that transfer (alternatively, it is not finalized and active + notice is provided to participants). +2. The hub guarantees deterministic outcomes for transfers and is + accepted by all participants as the final authority ("system of + record") on the status of transfers. +3. Determinism means individual transfers are traceable, auditable + (based on limits, constraints), with final result provided within + guaranteed time limit. +4. For the avoidance of doubt, batch transfers are processed + line-by-line with potentially differing deterministic outcomes for + each. + +**Transaction setup logic, which is use case-specific, is separated from +the policy-free transfer of money.** + +1. Transaction details and business rules should be captured and agreed + as scheme rules and technical operating guidelines. They may then be + applied during the quoting phase by those counterparties, and will + be carried between those counterparties by the Hub. +2. The agreement phase establishes a signed use-case specific + transaction object which incorporates all transaction-specific + details. +3. The transfer phase orchestrates the clearance of the transfer of + retail value between institutions for the benefit of the + counterparties (i.e only system limit checks are applied) and + without reference to transaction details. +4. No additional transaction-specific processing during the transfer + phase. + +**The hub doesn't parse or act on end-to-end transaction details; +transfer messages contain only the values required to complete clearing +and settlement.** + +1. Checks & validations during the transfer step are only for + conformance to scheme rules, limit checks, signature authentication, + and validation of payment condition and fulfillment. +2. Transfers that are committed for settlement are final and are + guaranteed to settle under the scheme rules. + +**Credit-push transfer semantics are reduced to their simplest form and +standardized for all transaction types.** + +1. Simplifies implementation and participant integration as many + transaction types and use-cases can reuse the same underlying value + transfer message flow. +2. Abstracts use-case complexity away from the critical path. + +**Internet-based API service hub is not a "message switch."** + +1. The service hub provides real-time API services for participants to + support retail credit-push instant transfers. +2. API services such as ID-to-participant look-up, transaction + agreement between participants, submission of prepared transfers, + and submission of fulfillment advice. +3. Auxiliary API services for participants are provided to support + onboarding, position management, reporting for reconciliation, and + other non-realtime functions not associated with transfer + processing. +4. All messages are validated for conformance to the API specification; + non-conforming messages are actively rejected with a standardized + machine-interpretable reason code. + +**The hub exposes asynchronous interfaces** + +1. To maximize system throughput and overall efficiency. +2. To isolate leaf-node connectivity issues so they don't impact other + end-users. +3. To enable the hub system to process requests in its own priority + order and without holding an active connection-per-transfer. +4. To handle numerous concurrent long-running processes through + internal batching and load balancing. +5. To have a single mechanism for handling requests (Examples are + transactions such as bulk or those needing end user input or that + span multiple hops). +6. To better support real world networking as issues with connection + speed and reliability for one participant should have minimal impact + on other participants or system availability more generally. + +**The transfer API is idempotent** + +1. This ensures duplicate requests may be made safely by message + originators in conditions of degraded network connectivity. +2. Duplicate requests are recognized and result in the same outcome + (valid duplicates) or are rejected as duplicate (when not allowed by + specification) with reference to the original. + +**Finalized Transfer records are held for a scheme-configurable period +to support scheme processes such as reconciliation, billing, and for +forensic purposes** + +1. It is not possible to query the "sub-status" of an in-process + Transfer; the API provides a deterministic outcome with active + notice provided within the guaranteed service time. + +**Transfer records for finalized transfers are held indefinitely in +long-term storage to support business analysis by the scheme operator +and by participants (through appropriate interfaces)** + +1. Availability of Transfer records may lag online process finality to + accommodate separation of record-keeping from real-time processing + of Transfer requests. + +**Hub may serve as a proxy for some inter-participant messages +(e.g. during the Agreement phase) to simplify interconnection, but +without parsing, storing (other than to support forwarding), or further +processing the messages.** + +1. In some messaging flows e.g. party lookup, it may be desirable for + participants to have a single point of contact for routing of scheme + related messages, even when the messages are not intended for the + hub, nor require any inspection or other processing. + +**To ensure system is arithmetically consistent, only fixed point +arithmetic is used.** + +1. For the avoidance of doubt, floating point calculations may lose + accuracy and must not be used in any financial calculation. +2. See Level One Decimal Type representation and forms. +3. This specification enables seamless interchange with XML-based + financial systems without loss of precision or accuracy + +## Security and Safety + +**API messages are confidential, tamper-evident, and non-repudiable.** + +1. Confidentiality is required to protect the privacy of the + participants and their customers. +2. There are legal requirements in many regulatory domains where + Mojaloop is expected to operate and as such, the hub must employ + best practices to ensure that the privacy of the participants and + their customers is protected. +3. Tamper-evident integrity mechanisms are required to ensure that + messages cannot be altered in transit. +4. To ensure the integrity of the overall system, each recipient of a + message should be able to independently tell, with a high degree of + confidence, that the message was not altered in transit. +5. Public key cryptography (digital signing) provides the current best + known mechanism for tamper-evident messaging. +6. The security of the sender's private (signing) key is critical. +7. Scheme rules must be established to clarify the responsibilities for + key management and the potential for financial liability upon + compromise of a private key. +8. Non-repudiation is required to ensure that the message was sent by + the party which purported to send it and that provenance can not be + repudiated by the sender. +9. This is important for determining the liable party during audit and + dispute resolution processes. + +**API messages are authenticated upon receipt prior to acceptance or +further processing** + +1. Authentication gives a degree of confidence that the message was + sent by the party which purported to send it. +2. Authentication gives a degree of confidence that the message was not + sent by an unauthorized party. + +**Authenticated Messages are not acknowledged as accepted until safely +recorded to permanent store** + +1. The Mojaloop API assigns significant scheme related business meaning + to certain HTTP response codes at various points in transaction + flows. +2. Certain HTTP responses, e.g. "202 Accepted", are intended to provide + financial guarantees to participants, and as such must only be sent + once the receiving entity is confident it has made safe, permanent + record(s) in support of: + - Facilitating system wide recovery to a consistent state after + failure(s) in one or more distributed components/entities. + - Accurate settlement processes + - Audit and dispute resolution processes +3. For example a "202 Accepted" from the hub to the payee participant + upon receipt of a transfer fulfilment message indicates a guarantee + of transaction settlement to the payee. +4. The Mojaloop API is designed to operate safely under imperfect + network conditions and as such has built in support for retries and + state synchronisation between participants. + +**Three levels of communication security to ensure integrity, +confidentiality, and non-repudiation of messages between an API server +and API client.** + +1. Secure Connections: mTLS required for all communications between the + hub and authorized participants. + - Ensures communications are confidential, between known + correspondents, and communications are protected against + tampering. +2. Secure Messages: JSON message content is cryptographically signed + according to the JWS specification. + - Assures recipients that messages were sent by the party which + purported to send them, and that provenance cannot be repudiated + by the sender. +3. Secure Terms of Transfer: Interledger Protocol (ILP) between Payer + and Payee participants. + - Protects the integrity of the payment condition and its + fulfilment. + - Limits the time within which a transfer instruction is valid. + +## Operational Characteristics + +**Baseline system demonstrated on minimal hardware supports clearing +1,000 transfers per second, sustained for one hour, with not more than +1% (of transfer stage) taking more than 1 second through the hub.** + +1. This measurement includes all necessary hardware and software + components with production grade security and data persistence in + place. +2. This measurement includes all three transfer stages: discovery, + agreement, and transfer. +3. This measurement does not include any participant-introduced + latency. +4. A one hour period is a reasonable approximation of a demand peak for + a national payment system. +5. A lower unit cost to scale than to initially provision. +6. 1000 transfers (clearing) per second is a reasonable starting point + for a national payment system. +7. 1% of transfers (clearing) taking more than 1 second is a reasonable + starting point for a national payment system. +8. Mojaloop schemes should be able to start at a reasonable cost point, + for national financial infrastructure, and scale economically as + demand grows. + +**Properly deployed, the hub is highly available and resilient to +failures.** + +1. In this instance we define the term "highly available" as meaning + "the ability to provide and maintain an acceptable level of service + in the face of faults and challenges to normal operation." +2. Although schemes may determine their own definition of what + constitutes an "acceptable level of service", Mojaloop makes certain + contributing tradeoff choices: + - When fault modes permit, service is degraded across the entire + participant population rather than individual participants + suffering total outages while others remain serviceable. + - The hub has no single point of failure; meaning that it + continues to operate with minimum degradation of service in the + event of a failure of any single component. + - Multiple active instances of each component are deployed in a + distributed manner behind load balancers. + - Each active component instance can handle requests from any + client/participant, meaning no single participant loses the + ability to transact in the event of a failure of any single + component. +3. Given appropriate infrastructure to operate upon, the Mojaloop + software can be deployed in configurations which deliver 99.999% + uptime (five nines) overall. +4. This includes active:active and active:passive multiple, + geographically distributed data center configurations where both + services and data are replicated across multiple physical nodes + which are expected to fail independently. +5. Note that it is expected that nodes in replication groups (and/or + clusters) will be located in diverse physical locations (racks + and/or data centres) with independent power supplies and network + interconnects. +6. Should multiple component failures occur which have not been + mitigated either in the Mojaloop software, deployment configuration + or infrastructure, the Mojaloop API provides mechanisms for each + entity in the scheme to recover to a consistent state, with the hub + being the ultimate source of truth upon full restoration of service. +7. Also see further points relating to resistance to data loss in the + event of failures. +8. Given that Mojaloop schemes are intended to form parts of national + financial infrastructure they must have as close to zero downtime as + possible, given reasonable cost constraints. +9. Failures in hardware and software components are to be expected, + even in the highest quality components available. Best practice + suggests these failures should be anticipated and planned for as + much as possible in the design of the hub with a view to minimising + loss or degradation of service and/or data. +10. For the avoidance of doubt this means the tradeoffs chosen favour + overall service availability and state consistency over performance, + so that: + + - All participants can continue to transact at a reduced rate rather + than some participants being unable to transact at all. + - Inconsistencies in state between scheme entities are resolvable post + service restoration via the Mojaloop API, with minimal manual + reconciliation necessary; the hub being the ultimate source of + truth. + +**The hub is resistant to loss of data in the event of failures.** + +1. Given appropriate infrastructure to operate upon, the Mojaloop + software can be deployed in configurations which reliably replicate + data across multiple, redundant physical storage nodes prior to + processing. +2. Database engine components which are provided by the Mojaloop + deployment mechanisms support the following: + + - Primary:secondary asynchronous replication. + - Primary:primary synchronous replication. + - Synchronous quorum consensus algorithm based replication. + +3. The replication mechanisms available are dependant on the particular + storage layer and database technologies employed. +4. Should multiple component failures occur which have not been + mitigated either in the Mojaloop software, deployment configuration + or infrastructure, the Mojaloop API provides mechanisms for each + entity in the scheme to recover to a consistent state with minimal + financial exposure risk. +5. Transfers become financially binding only when the hub has + successfully responded to a transfer fulfilment message from the + payee participant. This response is only sent when the hub has + persisted the fulfilment message and its outcome to its ledger + database. +6. Expiration timestamps on all financially significant API messages + facilitate timely and deterministic failure path outcomes for all + participants via automated retry mechanisms. +7. When Mojaloop schemes are intended to form parts of national + financial infrastructure, they must do as much as possible, given + reasonable cost constraints, to avoid loss of data in the event of a + failure. +8. Failures in hardware and software components are to be expected, + even in the highest quality components available. Best practice + suggests these failures should be anticipated and planned for in the + design of the hub with a view to avoiding data loss. +9. Participants need timely confidence in the status of financial + transactions across the scheme in order to minimise exposure risk + and deliver excellent customer experiences. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14th April 2025| Paul Makin|Added version control| +|1.0|5th February 2025| James Bush|Initial version| \ No newline at end of file diff --git a/docs/product/features/iso20022.md b/docs/product/features/iso20022.md new file mode 100644 index 000000000..457bb3149 --- /dev/null +++ b/docs/product/features/iso20022.md @@ -0,0 +1,33 @@ +--- +footerCopyright: Apache 2.0 Licensed | Copyright © 2020 - 2024 Mojaloop Foundation +--- + +# ISO 20022 Market Practice + +The ISO 20022 Market Practice for Mojaloop provides a standardized messaging framework that enables financial institutions to participate in the Mojaloop ecosystem using globally recognized ISO 20022 standards. This specification defines how ISO 20022 messages are implemented within the Mojaloop framework as an alternative to the FSPIOP API. + +## Market Practice Documents + +* Market Practice Document + * [ISO 20022 v1.0 (Current)](./Iso20022/v1.0/MarketPracticeDocument.md) + +## Key Features + +The Mojaloop ISO 20022 implementation provides: + +- **(JSON Message Format**: Adopts a JSON variant of ISO 20022 messages for enhanced API compatibility +- **Three-Phase Transaction Flow**: Maintains Mojaloop's Discovery, Agreement, and Transfer phases +- **Currency Conversion Support**: Handles cross-currency transactions with FX provider integration +- **Cryptographic Security**: Implements ILP v4 for secure message signing and non-repudiation +- **REST API Integration**: Seamless integration with modern REST-based API architectures + +## Scheme Flexibility + +The market practice documents provide: + +- **Generic Practices**: Universal guidelines applicable across all Mojaloop schemes +- **Extensible Framework**: Allows scheme-specific customizations and requirements +- **Compliance Support**: Alignment with regulatory requirements and industry standards +- **Version Management**: Structured approach to managing evolving standards and requirements + +For questions or support, please engage with the Mojaloop community through the official channels. diff --git a/docs/product/features/merchant-payments.md b/docs/product/features/merchant-payments.md new file mode 100644 index 000000000..1f7f87d69 --- /dev/null +++ b/docs/product/features/merchant-payments.md @@ -0,0 +1,32 @@ +# Merchant Payments + +!!!! **WORK IN PROGRESS - WILL BE COMPLETED SHORTLY** !!!! + +## Where Merchant Payments Fits In +In the Mojaloop world, merchant payments is not something that is built into the Hub itself. Instead it's an overlay service, which uses the services of the Hub, and forms part of the complete Mojaloop open source package. + +In terms of scheme operations, a merchant payments scheme could be offered as part of an overall payments service by the operator of the Mojaloop Hub. It's also possible that a merchant payments scheme could be offered by an entirely separate operator, in collaboration with the Hub operator. +## Concepts +Merchants must be registered as such in the Mojaloop model (note that this is different from being registered as a business; the "sole trader" model is also supported). During this process, merchant KYB data is captured in the Merchant Registry, and a DFSP-agnostic merchant ID is generated. This merchant ID can be displayed by merchants in their premises, for the purpose of USSD payments by customers with feature phones. It is also intended to be embedded in static QR codes, for scanning by customers with smartphones whose DFSP app supports this. + +The model adopted for merchant payments is based on a P2B push payment. The alias resolution capability of the Mojaloop Hub is used to resolve merchant IDs (either extracted from a QR code, or directly entered via USSD) to merchant accounts at participating DFSPs. This ensures that no sensitive information is leaked by displaying merchants' DFSPs or account numbers. When used with a QR code, best practice is to display the merchant's Trading Name to the customer for their verification, and to request that they enter the transaction value and authenticate themselves (for example, by entering a PIN) to authorise the transaction. Once the transaction has completed, both eh customer and the merchant will receive a notification, and the merchant may then release the purchased item(s) to the customer. +## Registration +Merchant registration is intended to be carried out by DFSPs, as part of their relationship with the merchant I their "Issuer" role. The merchant data is held in a shared Merchant Registry, but the registering DFSP retains their relationship with the merchant. + +The merchant data captured + +![Merchant Payments Entity Relationship Diagram](./ecosystem.svg) + + + + + +At the time of registration, a significant amount of information is captured about the merchant in the Merchant Registry. + +Addressing: +USSD vs QR +Merchant Registry - the link to LEIs +Creation of a QR code (with reference to EMVCo) +Customisation of the QR code - how to make it conform to a scheme's or a country's standard. + +In future: link to GLEIF \ No newline at end of file diff --git a/docs/product/features/metadata.md b/docs/product/features/metadata.md new file mode 100644 index 000000000..e056ce135 --- /dev/null +++ b/docs/product/features/metadata.md @@ -0,0 +1,18 @@ + +# Metadata +The very nature of Mojaloop as a switch interconnecting DFSPs means that Mojaloop cannot ascribe meaning to the transaction. However, transactions do also have the potential to carry metadata alongside the payment details, and it is this metadata that can be used by a scheme to link the payment to transactions outside Mojaloop, so supporting interoperability by carrying context across DFSPs. This applies to either a push or an RTP transaction. + +Metadata helps describe, contextualize, or manage the payment beyond just the amount, sender, and recipient. It is not strictly required to move money, but it is crucial for reconciliation, automation, compliance and customer experience. + +At the simplest level this can be used to, for example, tie a payment to a bill, so it can be recognised as being in payment of an electricity bill. Another example would be to use it to carry an invoice number alongside a payment in settlement of a B2B liability. Or it might describe the purpose of a payment, such as “Tuition for Q3 2025”, “Salary June 2025”, or “Loan repayment”. + +Where this metadata is intended to be used for payment automation, this "meaning" is defined by the scheme operator and the participating DFSPs, not the Mojaloop Hub. Automation would commonly be implemented as part of the [Core Connector customisation in the participation tools](./connectivity.md). + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|16th July 2025| Paul Makin|First version.| \ No newline at end of file diff --git a/docs/product/features/ml-feature-list.md b/docs/product/features/ml-feature-list.md new file mode 100644 index 000000000..efec417af --- /dev/null +++ b/docs/product/features/ml-feature-list.md @@ -0,0 +1,118 @@ +# Introduction to Mojaloop + +Mojaloop is open source instant payments software that interconnects +disparate financial institutions in a manner that promotes financial +inclusion and provides robust risk management for all participants. It is available for use by any body that wishes to use it to implement and operate an inclusive instant payments scheme (IIPS). + +## Regulators' and Operators' Perspective +Mojaloop provides the foundation for an operator to establish an Inclusive Instant Payment System (IIPS), and is intended to be integrated with a settlement partner. The partner may be the national RTGS, though other settlement mechanisms are also supported. In this way, Mojaloop enables the delivery of a comprehensive payments interoperability service to participating financial institutions (FIs). + +Once deployed, Mojaloop allows the scheme operator to: +- Onboard, suspend, or reactivate participating FIs as required; +- Set net debit caps for each participant to manage both risk and liquidity; +- Select and operate the settlement model best aligned to scheme and national requirements; +- Define multiple settlement periods across the operational day, with the closure of each period generating a settlement file (according to the chosen model) for the settlement partner’s action. + +The Mojaloop Hub underpins these functions by: +- Processing payments between debtor and creditor FIs on a continuous 24/7 basis; +- Updating each participant’s position in real time as debits and credits occur; +- Validating every payment to ensure sufficient liquidity and compliance with the participant’s net debit cap, rejecting transactions if these conditions are not met; +- Updating participant positions at the end of each settlement window to reflect the value of funds settled. + +In addition, Mojaloop supports an **indirect participation model**, designed to extend access to smaller financial institutions — particularly non-bank entities such as MFIs — that are not eligible to participate directly in the national RTGS. This ensures broad inclusion within the payments ecosystem while maintaining financial stability. + + +## Technical Perspective + +In order to deliver the IIPS described above, Mojaloop implements a set of core functions: + + |Alias Resolution|Clearing|Settlement| +|:--------------:|:--------------:|:--------------:| +|Payee address or **alias resolution**, ensuring that the account-holding institution – and thereby the correct payee account - is reliably identified|**Clearing** of payments end to end, with robust measures that remove any element of doubt about the success of a transaction|Orchestration of **Settlement** of cleared transactions between financial institutions using a model agreed between those institutions, and according to a predefined schedule.| + +  + +These core functions are supported by some [unique characteristics](./transaction.html#unique-transaction-characteristics), which +together make Mojaloop a low cost, inclusive instant payments system: + +1. **A Three Phase Transaction Flow**, as follows: + + **Discovery,** when the Payer's DFSP works with the Mojaloop Hub to determine where the payment should be sent, so ensuring that transactions are not misdirected. This phase resolves an alias to a specific Payee DFSP and, in collaboration with that DFSP, an individual account. + + + **Agreement of Terms, or Quotation,** when the two DFSP parties to the transaction both agree that the transaction can go ahead (supporting, for example, restrictions relating to tiered KYC), and on what terms (including fees), **before** either commits to it. + + + **Transfer,** when the transaction between the two DFSPs (and by proxy their customers' accounts) is cleared, and it is guaranteed that both parties have the same, real-time view of the success or failure of the transaction. +  + +2. **End to End Non-Repudiation** guarantees that each party to a message can be assured that the message has not been modified, and that it really was sent by the purported originator. This underlying technology is leveraged by Mojaloop to guarantee that a transaction will only be committed if *both* the Payer *and* the Payee DFSPs accept that it is, and neither party can repudiate the transaction. Naturally, it also guarantees that no third party can modify the transaction. +3. **The PISP API is made available through the Mojaloop Hub,** not by individual DFSPs. Consequently a fintech can integrate with the Hub and immediately be connected to **all** connected DFSPs.  + +**Note** In Mojaloop terms, a DFSP - or Digital Financial Service Provider - is a generic term for any financial institution, of any size or status, that is able to transact digitally. It applies equally to the largest international bank and the smallest Microfinance Institution or mobile wallet operator. "DFSP" is used throughout this document. +  + +# The Mojaloop Ecosystem +## The Core +In reading this document, it is important to understand the terminology used to identify the various actors, and how they interact. The following diagram provides a high level view of the Mojaloop ecosystem. + +![Mojaloop Ecosystem](./ecosystem.svg) + +## Overlay Services +Around the core illustrated in the above diagram there are a set of overlay services, which also form part of the complete Mojaloop open source package. These are: +- The **Account Lookup Service** (ALS), and a number of oracles that are used by the ALS in alias resolution; +- A set of **portals**, built to use the Business Operations Framework, which allow a hub operator to interact with/manage the Mojaloop Hub; +- A **Merchant Payments** module, which supports merchant registration and the issuing of merchant IDs, including the generation of QR Codes which can be scanned to initiate a merchant transaction; +- The **Testing Toolkit** (TTK), which allows engineers to simulate any aspect of the Mojaloop core ecosystem, to facilitate their development, integration and testing efforts; +- An **Integration Toolkit** (ITK), part of the [connectivity support](./connectivity.md) library, which facilitates the connection between a DFSP and a Mojaloop Hub; +- **ISO 8583 integration**, which allows ATMs (or an ATM switch) to be integrated with a Mojaloop Hub, for cash withdrawals; +- [**MOSIP integration**](https://www.mosip.io), which allow payments to be routed to a MOSIP-based digital identity, rather than (say) a mobile phone number. + +## Feature List + +This document presents a feature list which covers the following aspects of Mojaloop: + +- [**Use Cases**](./use-cases.md), describing the use cases supported by every Mojaloop deployment. +- [**Transactions**](./transaction.md), describing the Mojaloop APIs, how a transaction proceeds, and the aspects of a Mojaloop transaction that make it uniquely suited to the implementation of an inclusive instant payments service. + +- [**Risk Management**](./risk.md), setting out the measures taken to ensure that no DFSP participating in a Mojaloop scheme is exposed to any counterparty risk, and that the integrity of the scheme as a whole is protected. + +- [**Connectivity Support**](./connectivity.md), describing the various tools and options for straightforward onboarding of participating DFSPs. + +- [**Portals and Operational Features**](./product.md), such as portals for user and service management, and the configuration and operation of a Mojaloop Hub. +- [**Fees and Tariffs**](./tariffs.md) sets out the mechanisms that Mojaloop provides to support a range of different tariff models and the opportunities for participants and hub operators to levy fees. + +- [**Performance**](./performance.md), outlining the transaction processing performance adopters might expect. +- [**Deployment**](./deployment.md), describing the different ways to deploy Mojaloop for a range of different purposes, and the tools that facilitate these deployment types. +- [**Security**](./security.md), covering the security of the transactions between connected DFSPs and the Mojaloop Hub, the security of the Hub itself (including the operator portals), and the QA Framework currently being developed to validate the security and quality of a Mojaloop deployment. +- [**Engineering Principles**](./engineering.md), such as algorithmic adherence to the Mojaloop specification, code quality, security practices, scalability and performance patterns (amongst others). + +- [**Invariants**](./invariants.md), setting out the development and operational principles to which any Mojaloop implementation must adhere. This includes the principles which ensure the security and integrity of a Mojaloop deployment. + +  +## Continuous Development +No software is ever finished, and Mojaloop is no exception. There are always new features to be considered, new APIs to be implemented, new portals to be added, and of course there is always ongoing maintenance, and security requires constant vigilance. + +The Mojaloop Roadmap addresses and prioritises these needs, placing them on a timeline, and defines them as a set of workstreams. Each of these work streams has a workstream lead, responsible for defining, managing and delivering the workstream to the Mojaloop Community. The workstream lead is supported by a number of contributors, who may be engineers helping to implement a feature, or those who can document the feature, or people helping to define the requirements. + +You can view the current set of workstreams and their latest status reports in the [**Continuous Development** section](./development.md). + +# About This Document + +## Purpose of This Document + +This document catalogues the features of Mojaloop, independent of +implementation. It is intended to both inform potential adopters of the features they can expect and (where appropriate) how those features can be expected to function, and to inform developers of the features they must implement in order for their efforts to be accepted as an official instance of Mojaloop. + +The Mojaloop Foundation (MLF) defines an implementation as being an +official instance of Mojaloop if it implements all of the features of +Mojaloop, without exception, and they pass the standard set of Mojaloop tests. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.5|4th December 2025| Paul Makin|Added the "Continuous Development" sub-section| +|1.4|28th August 2025| Paul Makin|Added the "Regulators' and Operators' Perspective"| +|1.3|23rd June 2025| Paul Makin|Added the ecosystem text and diagram| +|1.2|14th April 2025| Paul Makin|Updates related to the release of V17| \ No newline at end of file diff --git a/docs/product/features/mojaloop_security_layers.jpg b/docs/product/features/mojaloop_security_layers.jpg new file mode 100644 index 000000000..d70949b68 Binary files /dev/null and b/docs/product/features/mojaloop_security_layers.jpg differ diff --git a/docs/product/features/performance.md b/docs/product/features/performance.md new file mode 100644 index 000000000..b9b1326d2 --- /dev/null +++ b/docs/product/features/performance.md @@ -0,0 +1,26 @@ +# Performance +Naturally, transaction throughput performance - usually measured as transactions per second - is a key metric for adopters, who need to be confident that Mojaloop can support their requirements, whether it be a national deployment, or sector-specific, or multi-national. + +For this reason, the Mojaloop Community has established a performance baseline, and works continuously to refine and improve the efficiency of transaction processing. + +## Performance Baseline + +Version 17.0.0 of the Mojaloop Hub has been demonstrated to support the following performance characteristics on ***minimal*** hardware: + +- Clearing 1,000 transfers per second +- Sustained for one hour +- With not more than 1% (of transfer stage) taking more than 1 second through the hub + +This baseline performance can be used as a reference point for system sizing and capacity planning. + +Naturally, higher performance may be expected using greater hardware resources. + +## Future Performance Expectations + +Work continues to replace Mojaloop's existing ledger technology with the [TigerBeetle](https://tigerbeetle.com/) financial transactions database. As the ledger performance is a significant element of the overall performance of Mojaloop, a significant uptick in that performance is expected through the adoption of TigerBeetle, with this expected to be completed by the time of the release of Mojaloop Version 19.0. + + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|3rd June 2025| Paul Makin|Initial version; performance text moved from deployment documentation| \ No newline at end of file diff --git a/docs/product/features/product.md b/docs/product/features/product.md new file mode 100644 index 000000000..aa4bf0610 --- /dev/null +++ b/docs/product/features/product.md @@ -0,0 +1,211 @@ +# Portals and Operational Features + +The aspects of portals and other operational features that are addressed are: + +- User Management + +- Participant Management + +- Transaction Review + +- Settlement + +- Logging & Audit + +- Hub Management + +- Oracle Management + +- Participant Portal + +- Reporting + +These functions are provided through Mojaloop's Business Operations +Framework (BOF), which not only provides the core functions described +here but also provides a set of APIs to allow a Hub operator to extend +these portals, and create new ones, to meet their specific requirements. + +The BOF channels all activity through a single Identity and Access +Management (IAM) framework, which incorporates Role Based Access +Controls (RBACs), giving a hub operator granular control of an individual's +access to the management capabilities of the Mojaloop Hub. + +Access to each of the above functions is implemented using the BOF, and +is managed using the IAM and RBAC. + +## User Management + +These features relate to the management of the hub operator's staff +using the integrated IAM module, rather than management of the service +itself. + +1. Create and manage user accounts for staff of the hub operator and + participants through the IAM portal. +2. Define roles associated with access to various sub-elements of the + portals. +3. Assign roles to user accounts, defining which users have access to + which features of the portals. +4. For sensitive functions, define a maker/checker requirement, + including the roles that must be held by the maker and the checker, + and any restrictions. +5. Enable/disable user accounts. +6. Create user accounts for participants, to facilitate self service + through the Participant Portal (when it is implemented). +7. Allow a user to be a maker and a checker (but not of their own + work). + +Note that the Participant Portal is not yet implemented by any Mojaloop +hub, and so it is not currently a requirement. + +## Participant Management + +Features that allow a hub operator to manage a participating DFSP (note +that this is distinct from the Participant Portal). + +1. Onboarding a participating DFSP. +2. Define and manage end-points (including specification of + certificates and source IPs) +3. Manage Participant contacts (name, email, MSISDN, role etc). +4. Define thresholds (for notifications). +5. Define and manage accounts for Participant by type, currency. +6. Disable a participating DFSP (though it should not be possible to + disable a DFSP with outstanding/unsettled transactions). +7. Pause/Resume a Participant's connection. +8. Assign/adjust liquidity (for multiple currencies), controlled with + maker/checker. +9. Assign/adjust a Net Debit Cap (NDC) for each Participant, controlled + by maker/checker, to include two options for NDC: fixed value + (manual adjustment after each liquidity change), or variable (as a + fixed percentage of available liquidity). +10. Restrict Participant connection to send or receive only. + +## Transaction Review + +The hub operator's staff need to be able to find details about a +transaction, whatever its status. They are able to search by: + +- Date/time range + +- Payer or Payee DFSP (Participant) + +- Value - Mojaloop transaction ID + +- Transfer state + +- Settlement Batch ID + +- Transaction type + +- Error code + +The search returns a list of all the transactions matching the search +criteria, each clickable for a detailed view, which gives access to: + +- All details held by the Mojaloop Hub, grouped in a set of + sub-windows to improve usability + +This will include the settlement window/batch ID, which is itself +clickable to allow the operator to review the settlement status of the +batch and therefore the transaction itself. + +## Settlement + +Management of the settlement function of the Mojaloop Hub needs to be +robust and reliable. The related features are: + +1. To define the settlement model to be used for the service +2. To close a settlement window or batch either manually or + automatically, according to a predefined schedule +3. To automatically create all of the necessary settlement files for + integration with settlement partner(s) when a settlement window is + closed +4. To review the positions of all Participants in the settlement + window/batch +5. Once settlement has been completed/finalised, to automatically + update the positions and current available liquidity based on + reports from the settlement partner(s) +6. To provide tools to support the integration between the Mojaloop Hub + and settlement partner(s). + +Note that at least one settlement window or batch will always be open, +and transactions will be added to the open settlement window/batch as +they are processed. This means that the creation of a new settlement +window is automatic when the existing settlement window is closed. + +## Logging & Audit + +The Mojaloop Hub provides a range of tools that support the logging and +audit of operator activity, in addition to low level audit functions for +the detailed analysis of transaction processing (which are defined +elsewhere in this document). These tools have been developed with the +requirements of both Hub operator management and external auditors in +mind. + +1. All modifications arising from hub operator activity (including user + management) are logged in an uneditable data store, with the + operator's credentials attached + +2. "Auditor" is a default hub user role; auditors have unrestricted + read access to the logs. + +3. An audit portal is available, which has Search/refine functionality + available + +4. Log/audit entries include changes to Hub configuration. + +## Hub Management + +There are some basic requirements for the configuration of a Mojaloop +Hub, defining the service that it supports. + +1. A Mojaloop Hub supports all ISO-defined currencies by default. Each + is enabled for use by a particular deployment by the creation of + settlement and position accounts for that currency. In support of + this, there is a requirement to be able to view the balances in Hub + operating accounts (settlement and position, replicated per currency + supported) + +2. Add/view/delete the CA certificates needed for normal operation. + +## Oracle Management + +Management of the oracles used by the Account Lookup Service (ALS) for +the resolution of aliases to DFSPs/Participants (and then, in +collaboration with the identified DFSP, to a specific account). + +1. View the registered oracles + +2. Register an Oracle + +3. Define an endpoint + +4. Test the health of an oracle + +## Participant Portal + +Currently, the Mojaloop Hub does not offer a Participant Portal. +Instead, this functionality is provided by another open source project, +Payment Manager (). Other tools, such as +Mojaloop's Integration Toolkit, provide an API to allow DFSPs to access +the same information. + +## Reports + +Mojaloop provides a flexible reporting engine as part of the Business +Operations Framework, which allows a Hub operator's staff to design and +generate a wide range of reports based on data held in Mojaloop's +databases and ledgers. The Framework also supports the integration of +those reports into any of the operator portals, allowing the reports to +be generated as required by operations staff. + +This includes the reports relating to settlement. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14th April 2025| Paul Makin|Updates related to the release of V17| +|1.0|5th February 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/risk.md b/docs/product/features/risk.md new file mode 100644 index 000000000..4d6dd0c60 --- /dev/null +++ b/docs/product/features/risk.md @@ -0,0 +1,54 @@ +# Risk Management + +A key aspect of the operation of a payment scheme that is built around a +Mojaloop hub is the management of risk between transacting parties, who +will themselves have different appetites for risk. The principles +applied are: + +1. All Participants (FSPs) are required to deposit an agreed form of + liquidity with the Scheme settlement partner. This liquidity can + only be withdrawn, in whole or in part, from the Scheme with the + agreement of the Scheme Operator. +   +2. A transaction will only be cleared (during the Transfer phase) if + there is sufficient liquidity available to cover it, as measured + against the liquidity balance, the DFSP's current Position (the net + total of previously-cleared transactions since the last settlement + activity, as either payer or payee), and any reserved funds. +   +3. The value of a cleared transaction will be added to the payer DFSP's Position, and debited from the payee DFSP's Position. +   +4. During settlement, for each DFSP, a negative Position will be debited from the + Liquidity balance and transferred to the settlement partner for + distribution to the creditors; a positive Position will be credited + to the Liquidity balance by the settlement partner, using funds from the debtors. +   +5. Successful settlement clears the value represented by the transactions in the associated settlement window/batch from each DFSP's Position. +   +6. A DFSP is expected to manage their liquidity, adding to it if it + drops to a level where anticipated transaction values will result in + failed transactions, or withdrawing some (on application to the + scheme operator) if the value is too high. This activity takes place + outside of Mojaloop, but it is a requirement that it is declared + within the Mojaloop scheme, by either the DFSP or the settlement + partner. +   +7. Where the settlement partner is not available 24/7, a DFSP can + deposit extra balance to their liquidity account, for example to + cover anticipated transactions over a holiday period. A DFSP can + manage this extra balance using a Net Debit Cap (NDC), which might + be used for example to limit the use of liquidity to the levels that + are expected on a particular day, in order to ensure that the DFSP + can continue to trade throughout the whole of the holiday period. + The NDC is used in tandem with the liquidity balance in the + authorisation of transactions during the Quotation phase. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|14th April 2025| Paul Makin|Updates related to the release of V17| +|1.0|13th March 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/security.md b/docs/product/features/security.md new file mode 100644 index 000000000..d9f330550 --- /dev/null +++ b/docs/product/features/security.md @@ -0,0 +1,78 @@ +# Security +## Open Source and Security +A common misconception is that open-source software is inherently less secure than closed-source software, simply because attackers can inspect the code. The argument goes: if the code is public, it must be easier to discover vulnerabilities. In reality, this view misunderstands how modern cybersecurity works. + +Mojaloop’s security does not depend on hiding its inner workings. Instead, it is built on well-established, open source cryptographic algorithms, developed by leading experts and published openly for peer review. These algorithms are rigorously tested by the global cryptographic community, ensuring that weaknesses are identified and addressed quickly. When a flaw is found, fixes are shared openly and rapidly, benefiting all users — Mojaloop included. + +This approach is directly comparable to the world of physical locks. The mechanism of a Yale lock, for example, is no secret: the patents are public, and anyone can study how it works. Yet the lock remains secure, not because the mechanism is hidden, but because only the correct, unique key can open it. Cryptography works the same way. Modern algorithms rely on the secrecy of keys, not on concealing the algorithm itself. + +The same applies to the entire Mojaloop codebase - since it is open source, anyone is able to review the source code and help to identify any vulnerabilities. Teams within the Mojaloop community take an active interest in this process, and highlight any issues identified during the quality and security process for review and remediation. Potential vulnerabilities are regularly raised by interested parties outside the core community, and these are reviewed and addressed by the quality and security teams. Further details are provided in the [Maintaining Security](#Maintaining-Security) section, below + +## Mojaloop Security +Mojaloop has built on these open source practices and cryptographic algorithms to create a security model that is multi-layered, complex, and subject to continuous oversight and review. + +It can be broken down into three areas of scope: + +- The security of the connection between the Mojaloop Hub and the Participating DFSPs (this includes both the security of transactions and the security, establishment and maintenance of the underlying connection itself); +- The security of the Hub's operations, as reflected in the activities of the operational staff; +- The quality and security of the Mojaloop Hub deployment. + +How Mojaloop approaches each of these areas is explored in the following sections. + +## DFSP Connection Security +The connection between a participant DFSP and the Mojaloop Hub benefits from three levels of security which together ensure the integrity, confidentiality, and non-repudiation of messages between a DFSP, the Mojaloop Hub, and (where appropriate) the other DFSP participating in a transaction. + +The following diagram illustrates these three levels. + +![Mojaloop's Connection Security Layers](./mojaloop_security_layers.jpg) + +At the lowest level, the security of the point-to-point connection between a DFSP (an authorised participant) and the Mojaloop Hub is assured through the use of mTLS, which ensures that communications are confidential and between known correspondents, and that communications are protected against tampering. + +Next, the content of the JSON messages used to communicate between the Hub and the DFSPs is cryptographically signed, according to the method defined in the JWS specification ([see RFC 7515](https://www.rfc-editor.org/rfc/rfc7515.html)). This assures recipients that messages were sent by the party which purported to send them, and simultaneously that that provenance cannot be repudiated by the sender. + +Finally, the terms of a transaction/ transfer are secured using the Interledger Protocol (ILP) between Payer and Payee participants. ILP uses a [Hashed Timelock Contract (HTLC)](./htlc.html) to protect the integrity of the payment condition and its fulfilment. In this way, Mojaloop ensures that a transfer either completes fully across all participating parties, or not at all. It also limits the time within which a transfer instruction is valid. + +These three layers are all built into the Mojaloop Hub. On the DFSP side, these can be directly established and managed by the DFSP's own engineering teams. However, the Mojaloop Community also [makes available a set of tools](./connectivity.html) which both establish these security layers and maintain them during the lifetime of the connection. The tools also help a DFSP to manage and orchestrate their use of the various communications/APIs with the Mojaloop Hub, handling many of the complexities on behalf of the DFSP, whilst existing entirely within the DFSP's own domain (and so not forming part of the Mojaloop Hub). + +## Hub Operational Security +Security at the Mojaloop Hub itself reaches beyond the connections to participating DFSPs (as described in the previous section), and includes the security of operator actions through the use of the various [Hub Portals](.product.html). + +Portals are implemented using Mojaloop's Business Operations Framework (BOF), which not only provides the core Mojaloop portals, but also provides a set of APIs to allow a Hub operator to extend these portals, and create new ones, to meet their specific requirements. + +In order to facilitate the management of the security of these portals, the BOF channels all activity through a single Identity and Access Management (IAM) framework, which incorporates Role Based Access Controls (RBACs), and intrinsically supports industry-standard Maker/Checker (also known as Four Eyes) controls. + +This approach gives a Mojaloop Hub operator granular control of an individual's access to the management capabilities of the Mojaloop Hub, as well as the controls applied to every activity. However, it remains the responsibility of the Hub operator to ensure that their staff are properly screened before recruitment, that they are registered on the IAM to access the portals, that they are assigned appropriate roles, and the the RBAC framework properly assigns roles to patrol management functions (including, where appropriate, maker/checker controls). In particular, policies such as password expiry, lengths and content of passwords, re-use etc are directly supported by the IAM framework, and it also supports the use of Multi-Factor Authentication (MFA) for all operators, as determined by the Hub operator (though the use of SMS or USSD as an MFA channel is strongly discouraged). + +In addition, it remains the responsibility of the hub operator to ensure that control points appropriate to the operation of a financial service are put in place (such as, where it applies, physical access to the servers hosting the Mojaloop Hub, control of operator use of mobile phones, video surveillance, supply chain management, visitor management, etc), and that business processes are defined to ensure the correct application of those control points. + +## Maintaining Security +The Mojaloop Community has defined a set of procedures and techniques to ensure that the security of a Mojaloop deployment is maintained as attacks evolve and vulnerabilities are identified, either in Mojaloop itself of in one of the myriad of other open source programs that Mojaloop relies on. This is collectively referred to as the Vulnerability Management Process, and comprises: +- A Security Committee, whose role is the coordination of all aspects of vulnerability management. +- Processes for handling possible vulnerabilities, when they have been brought to the attention of the Security Committee. +- Pro-active vulnerability identification and management processes, including: + - The continuous monitoring of open-source components for vulnerabilities; + - Static Application Security Testing (SAST), using multiple tools which together provide detailed insights into code-level vulnerabilities by leveraging public vulnerability databases; + - Automated maintenance of a Software Bill of Materials (SBOM), which facilitates inventory and dependency management; + - The scanning of container images for vulnerabilities before release; + - The use of an automated license scanner to ensure that only external components with compatible licenses are used; + - Following Mojaloop Release v17.1.0, Mojaloop's helm charts are signed at publishing and can be verified at install / deploy time, to ensure the provenance of artefacts related to charts; + - Mojaloop employs a CI/CD pipeline that automatically integrates security checks throughout the software development process; + - Mojaloop operates a Coordinated Vulnerability Disclosure (CVD) process, ensuring responsible parties have adequate time to address and remedy vulnerabilities before public disclosure; + - Comprehensive reports are generated after each scan, detailing outcomes, remediation actions, and their effectiveness. All reports are stored for auditing and compliance, ensuring transparency and accountability. + +The reader can find more detailed, technical information on the [Mojaloop Vulnerability Management Process here](https://docs.mojaloop.io/technical/technical/security/security-overview.html). + + +## Deployment Quality and Security +Members of the Mojaloop Community are currently developing a Quality Assessment Framework, the purpose of which is to develop a Toolkit that can be used to validate the configuration, functionality, security, interoperability readiness and performance of a deployment. + +This framework might be used by adopters to "self certify", or it might be used by an external reviewer in order to create a higher level of assurance for supervisory authorities and participants. + +## Applicability +This document relates to Mojaloop Version 17.1.0 +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.2|13th October 2025| Paul Makin|Added the "Open Source and Security" introductory section.| +|1.1|15th July 2025| Paul Makin|Added the "Maintaining Security" section.| +|1.0|24th June 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/tariffs.md b/docs/product/features/tariffs.md new file mode 100644 index 000000000..eada27727 --- /dev/null +++ b/docs/product/features/tariffs.md @@ -0,0 +1,53 @@ +# Fees and Tariffs +Mojaloop supports transaction fees using a flexible rules-driven architecture designed to ensure transparency and agreement at every stage of a payment. + +## **Agreement of Terms – Fee Negotiation** + +Before a transaction occurs, Mojaloop uses its **Agreement of Terms** transaction phase to allow DFSPs to calculate and agree all associated fees and commissions. + +At the beginning of this phase, the Payer's DFSP proposes the transaction to the Payee's DFSP, including a choice of charging model, being that either fees are added to the amount the sender pays, or they are deducted from the amount the beneficiary receives. + +If the Payer's DFSP wishes to proceed, then they submit a confirmation. In this, the Payee's DFSP submits their fees (and other conditions) to the Payer's DFSP in the form of a contract, including either an acceptance of the chosen charging model, or a rejection. + +If the Payer DFSP wishes to proceed on the terms presented by the Payee DFSP, then it presents the terms of the transfer to the Payer, including the total to be paid by the Payer based on the selected charging model. + +| Charging Model | Payer Pays| Payee Receives | +| -------------- | ---------------------- | -------------------- | +| Sender Pays | Value + Payer DFSP Fee + Payee DFSP Fee |Value| +| Beneficiary Pays| Value + Payer DFSP Fee|Value - Payee DFSP Fee| + + +If the Payer accepts the terms and wishes to proceed, the agreed transfer value is debited from the Payer's account by the Payer's DFSP, which then retains their own fees and submits a transfer request for the remaining value, together with the Payee's contract, to the Mojaloop Hub. + +The Payee DFSP, on completion of the transfer, retains their agreed fees, and credits the Payee's account with the remainder. + +In this way, all of the fees are consolidated into a single quote so the payer knows the exact cost before proceeding - including whether the Payee DFSP's fees are paid by the Payer or the Payee. + +## **Rules Handler – Interchange Fees** + +Mojaloop supports advanced fee rules like **interchange fees** via its Rules Handler, which evaluates transactions in-flight. For example, in a wallet-to-wallet peer‑to‑peer payment involving different DFSPs, Mojaloop can automatically apply a 0.6% fee charged by the Payee DFSP to the Payer DFSP. These are recorded as ledger entries and settled later. + +## **Hub Fees (Operator Fees)** + +Beyond per-transaction charges, hub operators may impose additional infrastructure–use or subscription fees on participating DFSPs. These “hub fees” are typically minimal — just enough to cover operational costs — with the aim of keeping end-user fees as low as possible in a “cost‑recovery plus" model. + +--- + +### In Summary + +| Fee Type | Handled By | When & How | +| ----------------------- | ---------------------- | --------------------------------------------- | +| Transaction Fees | Agreement of Terms Service | Quoted up front, agreed before execution | +| Interchange Fees | Rules Handler + Ledger | Applied during processing based on rules | +| Hub Infrastructure Fees | Hub Operator | Charged separately to recover operating costs | + +This layered approach gives Mojaloop strong support for fee transparency, configurability, automation, and settlement consistency—crucial for interoperable and cost-effective financial inclusion systems. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|17th July 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/transaction.md b/docs/product/features/transaction.md new file mode 100644 index 000000000..8d3e910c7 --- /dev/null +++ b/docs/product/features/transaction.md @@ -0,0 +1,93 @@ + +# Mojaloop Transactions +This section deals with all of the aspects of a Mojaloop transaction. + +## Phases of a Mojaloop Transaction + +A payments hub based on the Mojaloop platform clears (routes and guarantees) payments between accounts held by end parties (people, business, +government departments etc) at DFSPs, and integrates with a settlement +partner to orchestrate the movement of funds in settlement between +participating DFSPs either simultaneously (continuous gross settlement) or at a later time (various forms of net settlement), according to an agreed settlement +schedule. + +All Mojaloop transactions are asynchronous (to ensure the most efficient +use of resources), and proceed through three phases: + +1. **Discovery,** when the Payer's DFSP works with the Mojaloop Hub to determine where the payment should be sent. This phase resolves an alias to a specific Payee DFSP and, in collaboration with that DFSP, an individual account. +   +2. **Agreement of Terms, or Quotation,** when the two DFSP parties to the transaction agree that the transaction can go ahead (subject to, for example, restrictions relating to tiered KYC), and on what terms (including fees). +   + +3. **Transfer,** when the transaction between the two DFSPs (and by proxy their customers' accounts) is cleared. +  + +These phases are complemented by the asynchronous nature of Mojaloop. A transaction is always unique, ensuring that it will only be processed once, regardless of how frequently it is submitted for processing. This quality is known as idempotency, and ensures that even if a customer experiences intermittent connectivity, they can be assured that their account will only be debited once, regardless of the number of retries. + +This three-phase approach, complemented by idempotency, has been designed to minimize the risk of transaction failures or duplication. Consequently, Mojaloop eliminates the technical need for transaction reconciliation by DFSPs, reduces most causes of disputes, and thereby minimizes costs for all parties. + +Coupled with the Mojaloop approach to [Risk Management](./risk.md), this ensures that even the smallest MFI and the largest international bank can participate on equal terms, without either imposing risk on the other or indeed on the Hub itself. + +  +## Mojaloop APIs + +The Mojaloop Hub supports four APIs. The first two relate to end-customer transactions, whilst the last two relate to the administration of the Hub's relationship with participating DFSPs, and the settlement of cleared transactions: + +1. **Transactional API** +Mojaloop offers two functionally-equivalent transactional APIs, which each support direct connections with Participants for the purpose of conducting transactions. Both support all of the [**Mojaloop use cases**](./use-cases.md), and have been developed in accordance with the [Level One Principles](https://www.leveloneproject.org/project_guide/level-one-project-design-principles/). These APIs are: + - **FSP Interoperability (FSPIOP) API**, the long-established and well-proven API; +  + - An **ISO 20022 Messaging Schema**, using an ISO 20022 message set provisionally agreed by the Mojaloop Foundation with the ISO 20022 Registration Management Group (RMG),and tailored to the needs of an Inclusive Instant Payments System (IIPS)such as Mojaloop. This is offered to adopters as an alternative to FSPIOP. Full details of the Mojaloop implementation of the ISO20022 messaging schema and how it is expected that participating DFSPs will use it can be found in the [**Mojaloop ISO 20022 Market Practice Document**](./iso20022.md). + +2. **Third-party Payment Initiation (3PPI/PISP) API** + + This API is used to manage third party payment arrangements - payments initiated by fintechs on behalf of their customers from accounts held by those customers at DFSPs connected to the Mojaloop Hub. - and to initiate those payments when authorized. + + +3. **Administration API** + + The purpose of the Administration API is to enable Hub Operators to manage admin processes around: + + - creating/activating/deactivating participants in the Hub + + - adding and updating participant endpoint information + + - managing participant accounts, limits, and positions + + - creating Hub accounts + + - performing Funds In and Funds Out operations + + - creating/updating/viewing settlement models, for subsequent management using the Settlement API + + - retrieving transfer details + +4. **Settlement API** + + The settlement API is used to manage the settlement process. It is not intended for the purpose of managing settlement models. + +  + +## Unique Transaction Characteristics + +Most, if not all, of the functions Mojaloop supports are also offered by +other payment clearing hubs. What differentiates Mojaloop is: + +1. **The Three Phase Transaction Flow and Idempotency**, described above.   +2. **The Agreement of Terms, or Quotation,** phase of a transaction, + which allows two DFSPs to agree that a transaction can take place *before* it is committed. This supports some of the most complex aspects of transactions between differing types of Participant; a Payee DFSP can verify that the customer's account can receive the payment, that it hasn't been suspended, or the payment won't breach transaction or balance limits. If that's all OK, then the Payee DFSP will indicate that it can accept the transaction, subject to any fees that it will charge (any Hub fees are outside of the transaction itself). Only if the Payer DFSP, and the Payer him/herself, agree to those charges (and any other conditions attached to the terms returned by the Payee DFSP) will the transaction then be initiated. This removes the uncertainty, and all but guarantees that the transaction will succeed, even before it happens. + +3. **End to End Non-Repudiation** in the Transfer phase of the transaction guarantees that each party to a message can be assured that the message has not been modified, and that it really was sent by the purported originator. This underlying technology is leveraged by Mojaloop to guarantee that a transaction will only be committed if *both* the Payer *and* the Payee DFSPs accept that it is, and neither party can repudiate the transaction. This obviates the need for transaction-level reconciliation, which drives down on the level of disputed transactions and eliminates exception processing, and so substantially reduces costs for all participants. This also directly supports the financial inclusion objectives of the Mojaloop Foundation, since it addresses one of the key barriers to inclusion: lack of certainty, and therefore confidence, in payments. + + The Mojaloop community provides a number of tools that can be freely used by DFSPs to connect to a Mojaloop Hub. These remain within the DFSP's domain, and are not the concern of the hub operator or any other party. As well as managing the connection to the Hub and facilitating transactions, these tools also ensure the security of the connection and in particular provide the key DFSP link to this non-repudiation capability. +   +4. **The PISP API is made available through the Mojaloop Hub,** not by individual Participants. Consequently a fintech can integrate with the Hub and immediately be connected to all connected DFSPs, rather than needing to complete an API integration with the all individually. This substantially reduces costs and increases reliability for fintechs and their customers. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.3|30th June 2025| Paul Makin|Minor clarifications to the Agreement of Terms description| +|1.2|14th April 2025| Paul Makin|Updates related to the release of V17| \ No newline at end of file diff --git a/docs/product/features/use-cases.md b/docs/product/features/use-cases.md new file mode 100644 index 000000000..b074d5ad2 --- /dev/null +++ b/docs/product/features/use-cases.md @@ -0,0 +1,99 @@ + +# Use Cases + +A Mojaloop Hub's core function is the clearing of the transfer of funds between two accounts, each of which is held at a DFSP connected to the Hub, commonly referred to as a push payment. This enables it to support a wide range of use cases. However this is not the only transfer type that Mojaloop supports. + +The following description of the use cases supported by Mojaloop is grouped according to the underlying protocol types, in order to demonstrate the extensible nature of a Mojaloop Hub. So we have: +- **Push payments**, which supports the core use cases of P2P, B2B, etc; +- **Request To Pay**, which supports some types of merchant payments, e-commerce and collections; +- A range of **cash services**, including CICO and offline; +- **PISP/3PPI protocols**, which allow fintechs and others to develop services such as merchant payments, small-scale salary runs, collections etc; +- **Bulk payments**, to support nation-scale social payments and salaries; +- **Cross-Border payments**, including both remittances and merchant payments. + +These are described in more detail below. When reading these descriptions, it should be remembered that many of these transaction types [support the transport of metadata along with the payment itself](./metadata.md). + +(For an API-led view of use cases, please refer to the [use cases section of the Mojaloop API documentation](https://docs.mojaloop.io/api/fspiop/use-cases.html#table-1)) +## "Push Payment" Use Cases +A Mojaloop Hub directly supports the following use cases, which are all "flavours" of push payments: +- Person to Person (**P2P**); +- Person to Business (**P2B**), including simple forms of merchant payments, both face to face and remote (online); +- Business to Business (**B2B**); +- Business to Government (**B2G**); +- Simple forms of Person to Government (**P2G**) payments + +In all types of merchant payment, a payment can be facilitated using merchant IDs (for USSD) or QR codes (smartphones). + +## "Request To Pay" Use Cases + +As well as push payments, Mojaloop supports Request To Pay (RTP) transactions, in which a payee requests a payment from a payer, and _when the payer consents_ their DFSP pushes the payment to the payee on their behalf. This supports the following use cases: + +- **Merchant payments**, in a face to face environment, for example using a QR code; + - The practicalities of configuring Mojaloop's Merchant Payments solution, including the content of QR codes, are explored in [**How to Configure Merchant Payments for Mojaloop**](./merchant-payments.md). + - In all types of face to face merchant payment, a payment can be facilitated using merchant IDs (for USSD) or QR codes (smartphones). +- **e-Commerce**, sometimes also known as remote merchant payments, when for example a checkout page (web page or mobile app) would include a "pay from my bank account" button, which would trigger an RTP. + +- **Collections**, including P2G, P2B, B2B and B2G. This would commonly used for the payment of utility bills. This can also be achieved through the fintech/3PPI interface described below - the decision is a matter for a scheme operator. + +## Cash Services +A Mojaloop Hub directly supports the common interoperable cash in/out transactions that every DFSP (and their customers) would expect: +- **Cardless ATM**, through integration with ATM networks, using the ISO 8583 protocol; +- **Cash In / Cash Out (CICO) at off-us Agent**; +- **Offline Cash**: + - A Mojaloop Hub is able to offer support to **offline cash** payment schemes because such a payment scheme is viewed as cash - albeit digital. So a withdrawal to an offline cash wallet (a load) is analogous to a "cash out" transaction; and a deposit from an offline cash wallet (an upload) is analogous to a "cash in" transaction. However, the operator of such a scheme might consider that all such wallet load/upload transactions, whether on-us or off-us, should be processed through the Mojaloop Hub, for ease of reconciliation by the offline scheme. + +## "3PPI" Use Cases - Fintechs and Others +A Mojaloop Hub directly supports Third Party Payment Initiation (3PPI), so that Payment Initiation Service Providers (PISPs) - better known as fintechs - can, using their own smartphone apps, recruit customers, and offer them a unified or enhanced payments service. Most DFSPs connected to a Mojaloop Hub can support 3PPI services, if they have a reasonably modern back office. + +A fintech can use the 3PPI service to initiate a Request To Pay (RTP) - asking their customer's DFSP to initiate a payment to a payee. This supports the following use cases: +- **Collections**, in particular P2G and P2B; +- **Salary payments**, essentially the processing of a bulk payments list, on behalf of small/medium businesses; +- **Merchant payments** (P2B), using a QR code for initiation. + +## "Bulk Payment" Use Cases +Every payments service needs to facilitate bulk payments, and Mojaloop offers this service using an extremely efficient model. All but the very smallest DFSPs are able to offer this service to their customers, allowing them to submit payments lists that can reach every customer of every connected DFSP. This is in support of: +- **Pensions, Social and other payments** (G2P); +- **Salaries** (G2P and B2P). + +In addition, the bulk payment functionality is available through the **3PPI service** (above), which would enable all DFSPs - even the very smallest - to offer a smaller scale bulk payments service through either a fintech, or directly through their own 3PPI service. + + +## "Cross Border" Use Cases + +A Mojaloop Hub can enable a DFSP's customers to send money across borders in a cost-effective manner, facilitating the foreign exchange (FX) process as part of the transaction. This supports the following use cases: +- **P2P** and **P2B** (sending money to friend and family in another country, or paying a bill in another country); +- **Merchant Payments**, using RTP cross-border (supporting, for example, a small merchant that wishes to cross a nearby border to trade at a local market, taking payments in the local currency) + +In order to explore the aspects of the Mojaloop ecosystem that enable this, it is recommended to review: +1. The ability to connect a Mojaloop Hub to neighbouring payment schemes, either within the same country or elsewhere, so that interoperability is supported. This capability [**is introduced here**](./InterconnectingSchemes.md). + +2. The support for foreign exchange providers (FXPs) to connect to a Mojaloop Hub and offer FX services. Neither the payer not the payee needs to define the currency to be used for a transaction; they each transact in their own currency, and the Mojaloop Hub(s) facilitate the interchange. This capability [**is introduced here**](./ForeignExchange.md). + +3. How the interconnection/interscheme and foreign exchange capabilities are brought together to support [**cross border transactions**](./CrossBorder.md). +## Others; Card Payments +Many potential adopters ask about the possibility of using Mojaloop to switch card transactions. The answer is that, from a technical perspective, it is perfectly possible to switch a card transaction; the card Personal Account Number (PAN) can be used as an alias to initiate an RTP transaction, particularly as the Bank Identification Number (BIN), which forms part of the PAN, identifies the DFSP that holds the customer's account, to which the RTP should be routed. + +However, the practicality is that the card Point of Sale (PoS) device would need to be updated to route transactions accordingly; domestic transactions via an RTP to the Mojaloop switch, the rest to the issuing card network. And those PoS devices often belong to the acquiring banks, who may be unlikely to grant access (larger retailers, who often own their, usually integrated, PoS devices, might be more amenable). + +Further, re-routing transactions initiated using a card bearing the logo of an international payment scheme would be wholly inappropriate, and would almost certainly place everyone involved in a precarious legal position. Consequently this is something that should only ever be considered when a domestic card scheme is used, and the owner of that scheme is willing for their cards to be used in this way. + +Finally, using such an approach for debit cards is a closer match to a Mojaloop RTP transaction; using it for a credit card, which might include placing a funds reservation on an account (when checking into a hotel, for example), would add further complexity. + +## Extended Use Cases + +In addition to these standard use cases, Mojaloop supports the implementation of more complex use cases by adopters, which add additional features and are layered over the top of the standard use cases. + +These scheme-specific use cases can readily be added by individual scheme operators. + +## Applicability + +This version of this document relates to Mojaloop Version [17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.6|24th July 2025| Paul Makin|Fixed some broken links.| +|1.5|16th July 2025| Paul Makin|Changed the sub-headings to reflect how the introductory text talks about use cases. Refined the descriptions. Added a link to a metadata description. Added a note about card transactions.| +|1.4|12th June 2025| Paul Makin|Extended the introductory text to explain the use case grouping.| +|1.3|10th June 2025| Paul Makin|Added a description of e-commerce payments using RTP. Retitled 3PPI payments as Fintech payments.Clarified bulk payment initiation via 3PPI. Finally, some cosmetic updates to highlight hyperlinks to other documents.| +|1.2|14th April 2025| Paul Makin|Updates related to the release of V17, including links to the interscheme and FX documentation.| \ No newline at end of file diff --git a/docs/product/features/workstreams/core.md b/docs/product/features/workstreams/core.md new file mode 100644 index 000000000..b360e53fc --- /dev/null +++ b/docs/product/features/workstreams/core.md @@ -0,0 +1,33 @@ +# Core and Releases Workstream +The Mojaloop Core and Releases workstream maintains the Mojaloop core (maintenance items such as fixes to critical bugs, prioritized feature enhancements, node upgrades) and undertakes the Release process of the core services and some adjacent services or products that are part of the Mojaloop Platform. + +The workstream also aims to support other workstreams delivering features to core or supporting services by helping package services that are of release quality (the new features need to follow Mojaloop’s adopted quality standards and best practices such as automated tests, documentation, helm charts and such). This involves the community support aspect as well. + +# Business Justification +The management of the Mojaloop Core and the releases of the open source platform is foundational to the offering. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Sam Kummary | Shashi Hirugade
    Juan Correa | + +## Latest Update (Summary) +The codebase for 17.2.0 RC passes ~80% of automated tests across eight major collections; remaining tests are blocked by security-related changes to the Testing Toolkit. Once resolved, and once all security vulnerabilities are cleared, the release will proceed. + +Version 17.2.0 will deliver: +- Major performance enhancements +- LEI support in merchant services +- Inclusion of Connection Manager in Helm +- Significant DRPP-originating bug fixes + +The team will evaluate in early 2026 whether the next release will be a minor revision or the TigerBeetle-based v18. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/deployment.md b/docs/product/features/workstreams/deployment.md new file mode 100644 index 000000000..38f3212cb --- /dev/null +++ b/docs/product/features/workstreams/deployment.md @@ -0,0 +1,25 @@ +# Deployment Tools Workstream +This workstream is concerned with the provision of tools, documentation and support to enable adopters to deploy the Mojaloop software in a variety of environments, cloud and on-premises. + +# Business Justification +Providing a well documented, comprehensive suite of tools that enable adopters to engage with, develop, test, evaluate and operate our software is critical to supporting the establishment and long term sustainability of Mojaloop based IIPS. + +The aim is to enable adopters to deploy Mojaloop easily, in the environment of their choice, and with minimal support from the Community. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| James Bush | Tony Williams
    Vanda Illyes
    Sam Kummary
    Paul Makin
    Paul Baker
    Michael Richards| + +## Latest Update (Summary) +Recent DRPP contributions to IaC increased infrastructure costs by optimising for high-scale multi-instance deployments. To address the needs of smaller schemes, the team has developed a lightweight alternative—provisionally “IAC Lite.” Test deployments are running in AWS and on Foundation lab equipment. The objective is to deliver a streamlined, low-overhead, open-source deployment experience requiring minimal manual steps. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/dispute.md b/docs/product/features/workstreams/dispute.md new file mode 100644 index 000000000..a68dbacc7 --- /dev/null +++ b/docs/product/features/workstreams/dispute.md @@ -0,0 +1,25 @@ +# Dispute Management Workstream +This workstream aims to develop a Dispute Management solution that can be integrated with the Mojaloop Core and connected DFSPs to meet the needs of Hub Operators and participating DFSPs, across the full range of deployment types. + +# Business Justification +The reliable nature of Mojaloop transactions has meant that there is a need to develop a bespoke, open source solution for dispute management. + +Off the shelf alternatives generally assume that switches operate with limited discovery and little or no agreement of terms, so giving plenty of opportunity for dispute, and consequently these platforms are not a good match for a Mojaloop deployment. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Promesse Ishimwe | Derrick Wamatu | + +## Latest Update (Summary) +There was no update from the Dispute Management workstream in this cycle. Promesse was unable to attend the call, and no written update was provided. An update is expected at the next session once the workstream is able to report on current progress and priorities. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/evolution.md b/docs/product/features/workstreams/evolution.md new file mode 100644 index 000000000..cef5f646c --- /dev/null +++ b/docs/product/features/workstreams/evolution.md @@ -0,0 +1,32 @@ +# Mojaloop Evolution Workstream +This workstream is aimed at carrying out a significant evolution in Mojaloop's most critical central services: +- Replacing the accounting ledger functionality at the heart of Mojaloop with TigerBeetle. +- Replace the heart of the settlement engine with TigerBeetle functionality updating it with Settlement V3 capabilities. + +# Business Justification +This workstream has strategic importance; TigerBeetle is the next generation ledger technology developed specifically with Mojaloop in mind, and offers the potential of a transaction throughput performance improvement of at least an order of magnitude. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Michael Richards | James Bush
    Lewis Daley
    Sam Kummary
    Paul Makin | + +## Latest Update (Summary) +### Forensic Audit +The forensic audit redesign is ready for implementation but awaits funding from forthcoming adoption projects. No significant progress is expected until mid-Q1 2026. +### New Accounting Model +The new accounting model is broadly agreed and represents a major shift toward alignment with international accounting standards. This addresses concerns raised by global institutions and enhances Mojaloop’s credibility as a financial infrastructure platform. The initial target is TigerBeetle, though the team has not yet decided whether a MySQL version of the new model will also be produced. +### TigerBeetle Integration +Given the accounting model’s increased complexity, TigerBeetle is the preferred ledger engine. Integration planning is underway, with work expected to begin before Christmas. +### Settlement v3 +Settlement v3 introduces deterministic settlement batches, addressing long-standing reconciliation challenges and enabling multi-scheme scalability. TigerBeetle will store settlement batch keys, while SQL components and admin APIs will require substantial enhancement to support model configuration, batch tracking, and settlement operations. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/fintech_participation.md b/docs/product/features/workstreams/fintech_participation.md new file mode 100644 index 000000000..b670bf5db --- /dev/null +++ b/docs/product/features/workstreams/fintech_participation.md @@ -0,0 +1,25 @@ +# Participation Tools for Fintechs Workstream +The overall objective of this workstream is to develop a “Fintech Tools” portfolio, with the intention of supporting Fintechs and others in the integration of their systems with a Mojaloop Hub through the PISP interface. + +# Business Justification +Make it easier for fintechs to offer services by connecting to a Mojaloop-based payments scheme by reducing time, cost and complexity barriers both technically and from a business perspective. + +It is hoped this will foster faster growing and ultimately larger and more inclusive Mojaloop based schemes, which delivers impact in giving more people access to inclusive instant payments. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Alain Kajangwe | Jean de Dieu Uwizeye
    Bonaparte Ituze
    Yvan Rugwe | + +## Latest Update (Summary) +There was no update from the Participation Tools for Fintechs (Open Banking) workstream in this cycle. Alain was unable to attend the call, and no written update was provided. An update is expected at the next session once the workstream is able to report on current progress and priorities. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/iso20022.md b/docs/product/features/workstreams/iso20022.md new file mode 100644 index 000000000..dfad7387a --- /dev/null +++ b/docs/product/features/workstreams/iso20022.md @@ -0,0 +1,22 @@ +# ISO 20022 Refinement Workstream +This workstream focusses on refining the ISO 20022 implementation released with Mojaloop V17.0.0 based on the experiences of adopters. This includes any refinements to the ISO 20022 messages defined in the Market Practice Document (MPD), and updates to the MPD itself. + +# Business Justification +ISO 20022 is rapidly becoming the global standard for payment-system messaging, and Mojaloop’s ISO 20022 IIPS message standards, including Agreement of Terms (AoT), align with this global shift. However, the details re not yet finalised, and further refinement may well be likely. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Michael Richards |Paul Baker
    Julie Guetta | + +## Latest Update (Summary) +No recent updates. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/lei.md b/docs/product/features/workstreams/lei.md new file mode 100644 index 000000000..0c6ef90f2 --- /dev/null +++ b/docs/product/features/workstreams/lei.md @@ -0,0 +1,25 @@ +# LEI Addressing Workstream +This workstream is focused on supporting domestic and cross-border merchant transactions through the adoption of the international LEI identifier. This workstream is a collaboration between the Mojaloop Foundation and GLEIF, and is intended to culminate in a pilot, in cooperation with a Mojaloop adopter. + +# Business Justification +Collaboration with GLEIF has strategic advantages for the Mojaloop Foundation, since GLEIF has the backing of the financial sector's "establishment" - the FSB and the G20. + +It also helps our credibility in cross-border merchant payments, and complements our work in ISO 20022 by helping introduce LEIs into the Mojaloop ecosystem. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Clare Rowley
    Ololade Osunsanya | Michael Richards
    Paul Makin
    Shuchita Prakash
    Sam Kummary
    James Bush
    Xiaodi Wang | + +## Latest Update (Summary) +Documentation is currently the primary focus. The workstream is integrating LEI-related process flows into the Introduction to Mojaloop document, and preparing to collaborate with the ISO 20022 workstream on additional message examples, especially a P2B use case featuring LEI as a beneficiary identifier. Broader questions around applying LEIs to DFSP identities have been deferred due to complexity and regulatory implications. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/participation.md b/docs/product/features/workstreams/participation.md new file mode 100644 index 000000000..169b16e6a --- /dev/null +++ b/docs/product/features/workstreams/participation.md @@ -0,0 +1,26 @@ +# Participation Tools Workstream +The overall objective of the Participation Tools workstream is to develop a “DFSP Tools” portfolio, with the intention of supporting DFSPs and SIs in the integration of the DFSP’s systems with a Mojaloop Hub. Rather than only offering semi-finalised solutions, the portfolio will comprise the tools to carry out an integration, plus a set of exemplar implementations, each tailored to a specific type of DFSP. + +It should be emphasised to all DFSPs that reaping the benefits of an inclusive instant payments solution such as Mojaloop relies on the implementation of a “whole ecosystem” approach - and this means extending the reach of the Mojaloop service into the DFSPs’ domains, giving them and their customers the advantages of assurance of transaction finality, lower cost and the reliable delivery of every valid transaction. + +# Business Justification +By making it easier for different types of DFSP to join a Mojaloop-based payments scheme by reducing time, cost and complexity barriers both technically and from a business perspective, it is hoped this will foster faster growing and ultimately larger and more inclusive Mojaloop based schemes, which delivers impact in giving more people access to inclusive instant payments. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| James Bush | Sam Kummary
    Yevhen Kryiukha
    Paul Baker
    Vijay Kumar
    Phil Green
    Steve Haley
    Paul Makin | + +## Latest Update (Summary) +The workstream continues to make progress on participant onboarding, driven by improvements to the Mojaloop Connection Manager (MCM). With MCM now decoupled from the IAC codebase, schemes can adopt it independently, broadening its utility. Documentation has emerged as the most urgent need; a dedicated technical writer is preparing comprehensive materials spanning MCM, Payment Manager, and the Integration Toolkit. Donated documentation from Infitx will be generalised for broader community use. New mini-guides have been published to simplify navigation of Mojaloop tooling. + + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/performance.md b/docs/product/features/workstreams/performance.md new file mode 100644 index 000000000..d8446c1f7 --- /dev/null +++ b/docs/product/features/workstreams/performance.md @@ -0,0 +1,25 @@ +# Performance Optimisation Workstream +Demonstrate the performance of Mojaloop in a variety of deployment configurations, and develop and publish a whitepaper. Use a baseline on-premises configuration to measure changes in performance between Mojaloop releases. + +# Business Justification +A whitepaper that demonstrates how Mojaloop exceeds the performance requirements of adopters would be a valuable tool for the Mojaloop community. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| James Bush | Julie Guetta
    Shashi Hirugade
    Sam Kummary
    Nathan Delma
    Ablipay (Jerome, team)| + +## Latest Update (Summary) +The workstream achieved a major milestone by reaching 1,000 TPS prior to the Nairobi convening. With replication enabled, throughput remains high (950 TPS). The team is now scaling to 2,000 and 2,500 TPS as part of the performance white paper, which will include concrete hardware sizing recommendations. Early TigerBeetle tests suggest dramatic performance improvement and reduced infrastructure cost. + +Long-term storage tiering requirements were flagged as essential for regulatory data-retention obligations in high-volume schemes. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/pqs.md b/docs/product/features/workstreams/pqs.md new file mode 100644 index 000000000..81433b9aa --- /dev/null +++ b/docs/product/features/workstreams/pqs.md @@ -0,0 +1,23 @@ +# Platform Quality and Security Workstream +The PQS workstream is dedicated to the assessment, maintenance and enhancements to security and quality of the Mojaloop platform, encompassing connectivity to participating DFSPs (including transactions) and the security of hub operator portals, and of the Mojaloop Open source codebase and related artefacts. + +# Business Justification +This ensures the Mojaloop platform quality & security is maintained; vulnerability management is done and mitigations planned. Working with adopters, community members to improve security and quality incrementally. Provide features to support compliance and address gaps. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Sam Kummary | Juan Correa
    Devarsh Shah
    Shuchita Prakash
    Shashi Hirugade | + +## Latest Update (Summary) +The team is working toward a year-end release candidate of 17.2.0, focusing on security hardening, dependency updates, and CI reliability. AI-powered tooling is now generating automated PRs for dependency updates across Mojaloop’s internal packages, significantly reducing manual workload. The Finance Portal requires a more comprehensive rewrite due to outdated technology. The workstream also assessed the Mojaloop IAC sandbox against the new QA Framework. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/product/features/workstreams/qa.md b/docs/product/features/workstreams/qa.md new file mode 100644 index 000000000..09e815471 --- /dev/null +++ b/docs/product/features/workstreams/qa.md @@ -0,0 +1,28 @@ +# QA Framework Workstream +The overall objective of this workstream is to develop a QA Framework that can be used to validate the configuration, functionality, security, interoperability readiness and performance of a deployment. This framework might be used by adopters to "self certify", or it might be used by an external reviewer to create a level of assurance for supervisory authorities and participants. + +# Business Justification +A QA Framework provides a consistent approach for stakeholders to assess the quality and readiness of Mojaloop deployments, supporting independent evaluations of resilience, security, and functional integrity. By establishing a structured approach to assessing deployments, the framework helps: + +- Deployment teams identify and address gaps early +- Participants assess operational readiness before onboarding +- Regulators or supervisory bodies interpret implementation quality based on objective inputs +- The Mojaloop community share best practices and align on minimum expectations. + +## Contributors +|Workstream Lead|Contributors| +|:--------------:|:--------------:| +| Moses Kipchirchir | Denis Mariru
    Brian Njoroge
    Ei Nghon Phoo
    Sam Kummary | + +## Latest Update (Summary) +The draft QA Framework is now published on GitHub and Slack and available for immediate use by the community. Feedback from adopters will shape future refinement. Early discussions explore the possibility of an automated version of the framework to assess deployment quality as part of the deployment pipeline. Full automation remains a longer-term goal. + +## Applicability + +This version of this document relates to Mojaloop [Version 17.1.0](https://github.com/mojaloop/helm/releases/tag/v17.1.0) + +## Document History + |Version|Date|Author|Detail| +|:--------------:|:--------------:|:--------------:|:--------------:| +|1.1|4th December 2025| Paul Makin|Added latest update| +|1.0|25th November 2025| Paul Makin|Initial version| \ No newline at end of file diff --git a/docs/pt/index.md b/docs/pt/index.md new file mode 100644 index 000000000..5d3ee471a --- /dev/null +++ b/docs/pt/index.md @@ -0,0 +1,26 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: Esta é a documentação oficial do projeto Mojaloop +# actionText: Comece Agora → +# actionLink: /getting-started/ +# features: +# - title: Negócios +# details: Justificando o caso de negócios para o Mojaloop +# - title: Comunidade +# details: Conheça a comunidade por trás da tecnologia +# - title: Técnico +# details: Veja os diferentes componentes e implemente o Mojaloop você mesmo! +# - title: Produto +# details: Funcionalidades, requisitos e roadmap do produto Mojaloop +--- + +
    +
    + +| | | | | +|:----:|:----:|:----:|:----:| +|

    **[Adoção](/adoption/)**

    |

    **[Comunidade](/community/)**

    |

    **[Produto](/product/)**

    |

    **[Técnico](/technical/)**

    | +| Justificando o caso de negócios para o Mojaloop | Conheça a comunidade por trás da tecnologia | Funcionalidades, requisitos e roadmap do produto Mojaloop | Veja os diferentes componentes e implemente o Mojaloop você mesmo! | + +
    \ No newline at end of file diff --git a/docs/quickstarts/README.md b/docs/quickstarts/README.md new file mode 100644 index 000000000..ee06bcdbe --- /dev/null +++ b/docs/quickstarts/README.md @@ -0,0 +1,10 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + +1. [View the quickstarts](/1-overview/) +1. [Watch a demo](/99-demos/) +1. [Read the documentation](/1-overview/) +1. [Test out Mojaloop APIs](/1-overview/#apis) +1. [Take a training program](/3-guides/1_dfsp_setup/) +1. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/docs/technical/README.md b/docs/technical/README.md new file mode 100644 index 000000000..cad24cb63 --- /dev/null +++ b/docs/technical/README.md @@ -0,0 +1,16 @@ +# Mojaloop Technical Overview + +## Mojaloop Services + +The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers (DFSPs) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. The following diagrams shows the Mojaloop interconnects between DFSPs and the Mojaloop Hub (schema implementation example) for a Peer-to-Peer (P2P) Transfer: + +Mojaloop addresses these issues in several key ways: +* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. +* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. + +![Mojaloop End-to-end Architecture Flow PI5](./technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg) + +The Mojaloop Hub is the primary container and reference we use to describe the Mojaloop ecosystem which is split in to the following domains: +* Mojaloop Open Source Services - Core Mojaloop Open Source Software (OSS) that has been supported by the Bill & Melinda Gates Foundation in partnership with the Open Source Community. +* Mojaloop Hub - Overall Mojaloop reference (and customizable) implementation for Hub Operators is based on the above OSS solution. \ No newline at end of file diff --git a/docs/technical/api/README.md b/docs/technical/api/README.md new file mode 100644 index 000000000..ef01e4ff5 --- /dev/null +++ b/docs/technical/api/README.md @@ -0,0 +1,17 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# API Catalog + +The Mojaloop Family of APIs is a set of several different APIs that cater for several business or transactional functions. So far, the well defined and adopted APIs are: + +- [FSP Interoperability (FSPIOP) APIs](./fspiop/) +- [Administration API](./administration/) +- [Settlement API](./settlement/) +- [Third-party Payment Initiation (3PPI/PISP) API](./thirdparty/) + +There are other APIs that are either in active development and design or on the roadmap: + +- Cross-network API (FX) +- Reporting API diff --git a/docs/technical/api/administration/README.md b/docs/technical/api/administration/README.md new file mode 100644 index 000000000..80323e1b1 --- /dev/null +++ b/docs/technical/api/administration/README.md @@ -0,0 +1,15 @@ +# Administration API + +The Administration API includes the following documents. + +## Administration Central Ledger API + +[The specification of the Central Ledger API](./central-ledger-api.md) introduces and describes the **Central Ledger API**. The purpose of the API is to enable Hub Operators to manage admin processes around: + +- Creating/activating/deactivating participants in the Hub +- Adding and updating participant endpoint information +- Managing participant accounts, limits, and positions +- Creating Hub accounts +- Performing Funds In and Funds Out operations +- Creating/updating/viewing settlement models +- Retrieving transfer details diff --git a/docs/technical/api/administration/central-ledger-api.md b/docs/technical/api/administration/central-ledger-api.md new file mode 100644 index 000000000..0b63b5d7f --- /dev/null +++ b/docs/technical/api/administration/central-ledger-api.md @@ -0,0 +1,1728 @@ +--- +showToc: true +--- +# Central Ledger API + +## Introduction + +This document provides detailed information about the Central Ledger API. The Central Ledger API is a Mojaloop API enabling Hub Operators to manage admin processes around: + +- Creating/activating/deactivating participants in the Hub +- Adding and updating participant endpoint information +- Managing participant accounts, limits, and positions +- Creating Hub accounts +- Performing Funds In and Funds Out operations +- Creating/updating/viewing settlement models +- Retrieving transfer details + + For background information about the participant and settlement model details that the Hub Operator can administer using the Central Ledger API, see section [Basic concepts](#basic-concepts). + +
    + +## Basic concepts + +To provide context for the admin operations that the Central Ledger API enables, this section gives a brief definition of some basic concepts. + +### Participant + +Either the Hub itself or a Digital Financial Service Provider (DFSP) that is a participant in a Mojaloop scheme. + +### Endpoint + +The DFSP callback URL where the Hub routes API callbacks. The URL specified is the endpoint set up in the outbound API gateway. + +### Limit + +Currently, only one type of limit is supported, it is called "_Net Debit Cap (NDC)_". In the future, it is possible to add support for further types of limits. + +The _Net Debit Cap_ represents the liquidity cover available for a specific account (the Position account). It is the total amount of good funds which the scheme attests are available to guarantee that a participant is able to settle the liabilities it incurs on the Position account as a consequence of transferring funds. This amount of good funds is represented as the balance of an account (the Settlement account), which is tied to the Position account by a settlement model. The source of the funds in this account can be either funds recorded by the scheme's administrators as having been deposited to or withdrawn from the Settlement account, or funds which are automatically credited to or debited from the account by the scheme if the account is the Settlement account for an immediate gross settlement model. + +It should also be possible for a participant to specify that an amount, or a proportion, of the funds available in a Settlement account should be excluded from the Net Debit Cap calculation. In cases where a participant is a long-term net beneficiary of funds via settlement, or where participants keep extra funds in their Settlement account to cover periods when it may not be possible to deposit funds to those accounts, it may wish to exclude part of the balance of its Settlement account from use as cover for transfers. + +### Account + +Also called _Ledger_. The Hub maintains a number of internal accounts to keep track of the movement of money (both e-money and real money) between DFSPs. + +### Position + +The Position represents the net of: +- transfers on that account which have cleared but have not yet settled, and +- transfers on that account where: + - the DFSP is the debtor party, and + - the transfer has been accepted for processing by the Hub, but has not yet cleared. + +The Position for a given account is always verifiably up to date. + +When a transfer is requested, the Hub will check that the DFSP has liquidity cover available on that account to cover the amount of the transfer. If it does not, the transfer will be rejected. + +We currently allow liabilities to the participant which have been created as a consequence of transfers on the account where the participant is the beneficiary to reduce the participant's Position as if the liabilities had already been settled. + +### Funds In and Funds Out + +Funds In and Funds Out operations are used to track (in the Hub accounts) money movements related to deposits and withdrawals, as well as settlements. + +Funds In operations record either the deposit of money into a DFSP's settlement bank account or the settlement amount for a receiving DFSP. + +Funds Out operations record either the withdrawal of money from a DFSP's settlement bank account or the settlement amount for a sending DFSP. + +### Settlement model + +Refers to how settlement happens within a scheme. Settlement is the process of transferring funds from one DSFP to another, so that the payer's DFSP reimburses the payee's DFSP for funds given to the payee during a transaction. A settlement model specifies if participants settle with each other separately or settle with the scheme, whether transfers are settled one by one or as a batch, whether transfers are settled immediately or with a delay, and so on. + +
    + +## HTTP details + +This section contains detailed information regarding the use of the application-level protocol HTTP in the API. + +### HTTP header fields + +HTTP headers are generally described in [RFC 7230](https://tools.ietf.org/html/rfc7230). Any headers specific to the Central Ledger API will be standardised in the future. + +### HTTP methods + +The following HTTP methods, as defined in [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4), are supported by the API: + +- `GET` – The HTTP GET method is used from a client to retrieve information about a previously-created object on a server. +- `POST` – The HTTP POST method is used from a client to request an object to be created on the server. +- `PUT` – The HTTP PUT method is used from a client to request an object already existing on the server to be modified (to replace a representation of the target resource with the request payload). + +> **NOTE:** The `DELETE` method is not supported. + +### HTTP response status codes + +The [HTTP response status codes](#http-response-status-codes) table lists the HTTP response status codes that the API supports: + +|Status Code|Reason|Description| +|---|---|---| +|**200**|OK|Standard response for a successful `GET`, `PUT`, or `POST` operation. The response will contain an entity corresponding to the requested resource.| +|**201**|Created|The `POST` request has been fulfilled, resulting in the creation of a new resource. The response will not contain an entity describing or containing the result of the action.| +|**202**|Accepted|The request has been accepted for processing, but the processing has not been completed.| +|**400**|Bad Request|The server could not understand the request due to invalid syntax.| +|**401**|Unauthorized|The request requires authentication in order to be processed.| +|**403**|Forbidden|The request was denied and will be denied in the future.| +|**404**|Not Found|The requested resource is not available at the moment.| +|**405**|Method Not Allowed|An unsupported HTTP method for the request was used.| +|**406**|Not Acceptable|The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.| +|**500**|Internal Server Error|A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.| +|**501**|Not Implemented|The server does not support the requested service. The client should not retry.| +|**503**|Service Unavailable|The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame.| + +
    + +## API services + +This section introduces and details all services that the API supports for each resource and HTTP method. + +### High-level API services + +On a high level, the API can be used to perform the following actions: + +- **`/participants`**: View, create, update participant-related details, such as limit (Net Debit Cap), position, or endpoints configured. +- **`/settlementModels`**: View, create, update settlement-model-related details, such as granularity, delay, liquidity check, and so on. +- **`/transactions`**: View transaction details for a particular transfer. + +### Supported API services + +The [Supported API services](#supported-api-services) table includes high-level descriptions of the services that the API provides. For more detailed information, see the sections that follow. + +| URI | HTTP method `GET`| HTTP method `PUT` | HTTP method `POST` | HTTP method `DELETE` | +|---|---|---|---|---| +| **`/participants`** | Get information about all participants | Not supported | Create participants in the Hub | Not supported | +| `/participants/limits` | View limits for all participants | Not supported | Not supported | Not supported | +| `/participants/{name}` | Get information about a particular participant | Update participant details (activate/deactivate a participant) | Not supported | Not supported | +| `/participants/{name}/endpoints` | View participant endpoints | Not supported | Add/Update participant endpoints | Not supported | +| `/participants/{name}/limits` | View participant limits | Adjust participant limits | Not supported | Not supported | +| `/participants/{name}/positions` | View participant positions | Not supported | Not supported | Not supported | +| `/participants/{name}/accounts` | View participant accounts and balances | Not supported | Create Hub accounts | Not supported | +| `/participants/{name}/accounts/{id}` | Not supported | Update participant accounts | Record Funds In or Out of participant account | Not supported | +| `/participants/{name}/accounts/{id}/transfers/{transferId}` | Not supported | Not supported | Record a Transfer as a Funds In or Out transaction for a participant account | Not supported | +| `/participants/{name}/initialPositionAndLimits` | Not supported | Not supported | Add initial participant limits and position | Not supported | +| **`/settlementModels`** | View all settlement models | Not supported | Create a settlement model | Not supported | +| `/settlementModels/{name}` | View settlement model by name | Update a settlement model (activate/deactivate a settlement model) | Not supported | Not supported | +| **`/transactions/{id}`** | Retrieve transaction details by `transferId` | Not supported | Not supported | Not supported | + + +
    + +## API Resource `/participants` + +The services provided by the resource `/participants` are primarily used by the Hub Operator for viewing, creating, and updating participant-related details, such as limit (Net Debit Cap), position, or endpoints configured. + +### GET /participants + +Retrieves information about all participants. + +#### Example request + +``` +curl 'http:///participants' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "greenbankfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp", + "created": "\"2021-03-04T14:20:17.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp" + }, + "accounts": [ + { + "id": 15, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 16, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 21, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + }, + { + "name": "Hub", + "id": "dev1-central-ledger.mojaloop.live/participants/Hub", + "created": "\"2021-03-04T13:37:25.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/Hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 2, + "ledgerAccountType": "HUB_RECONCILIATION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### POST /participants + +Creates a participant in the Hub. + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"name": "payerfsp", "currency": "USD"}' \ + http:///participants +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency that the participant will transact in. | + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-01-12T10:56:30.000Z\"", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 30, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 31, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### GET /participants/limits + +Retrieves limits information for all participants. + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | +| `limit` | no | [String](#string) | Limit type. | + +#### Example request + +``` +curl 'http:///participants/limits' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "payerfsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + }, + { + "name": "payeefsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Response data model + +Each limit in the returned list is applied to the specified participant name and currency in each object. + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### GET /participants/{name} + +Retrieves information about a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### PUT /participants/{name} + +Updates participant details (activates/deactivates a participant). + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the participant is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### GET /participants/{name}/endpoints + +Retrieves information about the endpoints configured for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/endpoints' +``` + +#### Example response +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_DELETE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_AUTHORIZATIONS", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_QUOTES", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRX_REQ_SERVICE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}/error" + }, + { + "type": "NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", + "value": "some.email@gmail.com" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Type of endpoint. | +| `value` | yes | [String](#string) | Endpoint value. | + +
    + +### POST /participants/{name}/endpoints + +Adds/updates endpoints for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", "value": "some.email@org.com"}' + http:///participants/payerfsp/endpoints +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Type of endpoint. | +| `value` | yes | [String](#string) | Endpoint value. | + +#### Example response + +``` +HTTP/1.1 201 Created +Content-Type: application/json +``` + +
    + + +### GET /participants/{name}/limits + +Retrieves limits information for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | +| `limit` | no | [String](#string) | Limit type. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/limits' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Response data model + +Each limit in the returned list is applied to the specified participant name and currency in each object. + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### PUT /participants/{name}/limits + +Adjusts limits for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": NET_DEBIT_CAP", \ + "value": 10000, \ + "alarmPercentage": 20 + } \ + }' \ + http:///participants/payerfsp/limits +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 20 + } +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### GET /participants/{name}/positions + +Retrieves the position of a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/positions' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "value": 150, + "changedDate": "2021-05-10T08:01:38.000Z" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `value` | yes | [Number](#number) | Position value. | +| `changedDate` | yes | [DateTime](#datetime) | Date and time when the position last changed. | + +
    + +### GET /participants/{name}/accounts + +Retrieves the accounts and balances of a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/accounts' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "value": 150, + "reservedValue": 0, + "changedDate": "2021-05-10T08:01:38.000Z" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": -165000, + "reservedValue": 0, + "changedDate": "2021-05-10T14:27:02.000Z" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": 0, + "reservedValue": 0, + "changedDate": "2021-03-30T12:23:06.000Z" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [Integer](#integer) | Identifier of the ledger account. | +| `ledgerAccountType` | yes | [String](#string) | Type of ledger account. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the ledger account. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the ledger account is active. Possible values are `1` and `0`. | +| `value` | yes | [Number](#number) | Account balance value. | +| `reservedValue` | yes | [Number](#number) | Value reserved in the account. | +| `changedDate` | yes | [DateTime](#datetime) | Date and time when the ledger account last changed. | + +
    + +### POST /participants/{name}/accounts + +Creates accounts in the Hub. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"currency": "USD", "type": "HUB_MULTILATERAL_SETTLEMENT"}' \ + http:///participants/payerfsp/accounts +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the participant ledger account. | +| `type` | yes | [String](#string) | Type of ledger account. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "hub", + "id": "dev1-central-ledger.mojaloop.live/participants/hub", + "created": "2021-01-12T10:56:30.000Z", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": "2021-01-12T10:56:30.000Z", + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### POST /participants/{name}/accounts/{id} + +Records Funds In or Out of a participant account. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | + +#### Example request + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "transferId": "bfd38d14-893f-469d-a6ca-a312a0223949", \ + "externalReference": "660616", \ + "action": "recordFundsIn", \ + "reason": "settlement", \ + "amount": { \ + "amount": "5000", \ + "currency": "USD" \ + }, \ + "extensionList": { \ + "extension": [ \ + { \ + "key": "scheme", \ + "value": "abc" \ + } \ + ] \ + } \ + }' \ + http:///participants/payerfsp/accounts/2 +```` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | +| `externalReference` | yes | [String](#string) | Reference to any external data, such as an identifier from the settlement bank. | +| `action` | yes | [Enum](#enum) | The action performed on the funds. Possible values are: `recordFundsIn` and `recordFundsOutPrepareReserve`. | +| `reason` | yes | [String](#string) | The reason for the FundsIn or FundsOut action. | +| `amount` | yes | [Money](#money) | The FundsIn or FundsOut amount. | +| `extensionList` | no | [ExtensionList](#extensionlist) | Additional details. | + +#### Example response + +```` +HTTP/1.1 202 Accepted +```` + +
    + +### PUT /participants/{name}/accounts/{id} + +Updates a participant account. Currently, updating only the `isActive` flag is supported. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp/account/2 +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the participant account is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +``` + +
    + +### PUT /participants/{name}/accounts/{id}/transfers/{transferId} + +Records a transfer as a Funds In or Out transaction for a participant account. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"action": "recordFundsOutCommit", "reason": "fix"}' \ + http:///participants/payerfsp/account/2/transfers/bfd38d14-893f-469d-a6ca-a312a0223949 +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `action` | yes | [Enum](#enum) | The FundsOut action performed. Possible values are: `recordFundsOutCommit` and `recordFundsOutAbort`. | +| `reason` | yes | [String](#string) | The reason for the FundsOut action. | + +#### Example response + +``` +HTTP/1.1 202 Accepted +``` + +
    + +### POST /participants/{name}/initialPositionAndLimits + +Adds initial limits and a position for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": "NET_DEBIT_CAP", \ + "value": "10000" \ + }, \ + "initialPosition": 0 \ + }' \ + http:///participants/payerfsp/initialPositionAndLimits +```` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | +| `initialPosition` | no | [Number](#number) | Initial Position. | + +#### Example response + +``` +HTTP/1.1 201 Created +``` + +
    + +## API Resource `/settlementModels` + +The services provided by the resource `/settlementModels` are used by the Hub Operator for creating, updating, and viewing settlement models. + +### GET /settlementModels + +Retrieves information about all settlement models. + +#### Example request + +``` +curl 'http:///settlementModels' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "settlementModelId": 1, + "name": "DEFERREDNETUSD", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true + }, + { + "settlementModelId": 4, + "name": "DEFERREDNETEUR", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "EUR", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "SETTLEMENT", + "autoPositionReset": true + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active.| +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +### POST /settlementModels + +Creates a settlement model. + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "name": "DEFERREDNET", \ + "settlementGranularity": "NET", \ + "settlementInterchange": "MULTILATERAL", \ + "settlementDelay": "DEFERRED", \ + "requireLiquidityCheck": true, \ + "ledgerAccountType": "POSITION", \ + "autoPositionReset": true \ + }' \ + http:///settlementModels +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | Settlement model name. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `settlementAccountType` | yes | [String](#string) | A special type of ledger account into which settlements should be settled. Possible values are:
    `SETTLEMENT`: A settlement account for the principal value of transfers (that is, the amount of money that the Payer wants the Payee to receive).
    `INTERCHANGE_FEE_SETTLEMENT`: A settlement account for the fees associated with transfers. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +#### Example response + +``` +HTTP/1.1 201 Created +``` + +
    + +### GET /settlementModels/{name} + +Retrieves information about a particular settlement model. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the settlement model. | + +#### Example request + +``` +curl 'http:///settlementModels/DEFERREDNET' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +### PUT /settlementModels/{name} + +Updates a settlement model (activates/deactivates a settlement model). + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the settlement model. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///settlementModels/DEFERREDNET +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +## API Resource `/transactions` + +The services provided by the resource `/transactions` are used by the Hub Operator for retrieving transfer details. + +### GET /transactions/{id} + +Retrieves information about a particular transaction. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [UUID](#uuid) | Transfer identifier. | + +#### Example request + +``` +curl 'http:///transactions/85feac2f-39b2-491b-817e-4a03203d4f14' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "transactionRequestId": "a8323bc6-c228-4df2-ae82-e5a997baf898", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoneyAbc" + }, + "name": "John Doe", + "personalInfo": { + "complexName": { + "firstName": "John", + "middleName": "William", + "lastName": "Doe" + }, + "dateOfBirth": "1966-06-16" + } + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "987654321", + "fspId": "MobileMoneyXyz" + }, + "name": "Jane Doe", + "personalInfo": { + "complexName": { + "firstName": "Mary", + "middleName": "Jane", + "lastName": "Doe" + }, + "dateOfBirth": "1975-05-15" + } + }, + "amount": { + "currency": "USD", + "amount": "50" + }, + "transactionType": { + "scenario": "DEPOSIT", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + } +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `quoteId` | | [UUID](#uuid) | Quote identifier. | +| `transactionId` | | [UUID](#uuid) | Transaction identifier. | +| `transactionRequestId` | | [String](#string) | Identifies an optional previously-sent transaction request. | +| `payee` | | [Party](#party) | Payee details. | +| `payer` | | [Party](#party) | Payer details. | +| `amount` | | [Money](#money) | Transaction amount. | +| `transactionType` | | [TransactionType](#transactiontype) | Transaction details. | +| `note` | | [String](#string) | A memo that will be attached to the transaction. | +| `extensionList` | | [ExtensionList](#extensionlist) | Additional details. | + +
    + +## Data models used by the API + +### Format + +For details on the formats used for element data types used by the API, see section [Element Data Type Formats](../fspiop/logical-data-model#element-data-type-formats) in the Mojaloop FSPIOP API Definition. + +### Element Data Type Formats + +This section defines element data types used by the API. + +#### Amount + +For details, see section [Amount](../fspiop/logical-data-model#amount) in the Mojaloop FSPIOP API Definition. + +#### Boolean + +A `"true"` or `"false"` value. + +#### DateTime + +For details, see section [DateTime](../fspiop/logical-data-model#datetime) in the Mojaloop FSPIOP API Definition. + +#### Enum + +For details, see section [Enum](../fspiop/logical-data-model#enum) in the Mojaloop FSPIOP API Definition. + +#### Integer + +For details, see section [Integer](../fspiop/logical-data-model#integer) in the Mojaloop FSPIOP API Definition. + +#### Number + +The API data type `Number` is a an arbitrary-precision, base-10 decimal number value. + +#### String + +For details, see section [String](../fspiop/logical-data-model#string) in the Mojaloop FSPIOP API Definition. + +#### UUID + +For details, see section [UUID](../fspiop/logical-data-model#uuid) in the Mojaloop FSPIOP API Definition. + +
    + +## Element Definitions + +This section defines element types used by the API. + +#### IsActive + +Data model for the element **IsActive**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not a ledger account / participant is active. Possible values are `1` (active) and `0` (not active). | + +#### IsActiveBoolean + +Data model for the element **IsActiveBoolean**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not an account / participant / settlement model is active. | + +#### CurrencyEnum + +For details, see section [Currency](../fspiop/logical-data-model#currencycode-enum) enum in the Mojaloop FSPIOP API Definition. + +#### RequireLiquidityCheck + +Data model for the element **RequireLiquidityCheck**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `requireLiquidityCheck` | yes | [Boolean](#boolean) | A flag to indicate whether or not a settlement model requires liquidity check. | + +#### Self + +Data model for the element **Self**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `self` | yes | [String](#string) | Fully qualified domain name combined with the `fspId` of the participant. | + +#### SettlementDelay + +Data model for the element **SettlementDelay**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementDelay` | yes | [Enum](#enum) of String | Specifies if settlement happens immediately after a transfer has completed or with a delay. Allowed values for the enumeration are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule. | + +#### SettlementGranularity + +Data model for the element **SettlementGranularity**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementGranularity` | yes | [Enum](#enum) of String | Specifies whether transfers are settled one by one or as a batch. Allowed values for the enumeration are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time. | + +#### SettlementInterchange + +Data model for the element **SettlementInterchange**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementInterchange` | yes | [Enum](#enum) of String | Specifies the type of settlement arrangement between parties. Allowed values for the enumeration are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party. | + +
    + +## Complex types + +#### Accounts + +The list of ledger accounts configured for the participant. For details on the account object, see [IndividualAccount](#individualaccount). + +#### ErrorInformation + +For details, see section [ErrorInformation](../fspiop/logical-data-model#errorinformation) in the Mojaloop FSPIOP API Definition. + +#### ErrorInformationResponse + +Data model for the complex type object that contains an optional element [ErrorInformation](#errorinformation) used along with 4xx and 5xx responses. + +#### Extension + +For details, see section [Extension](../fspiop/logical-data-model#extension) in the Mojaloop FSPIOP API Definition. + +#### ExtensionList + +For details, see section [ExtensionList](../fspiop/logical-data-model#extensionlist) in the Mojaloop FSPIOP API Definition. + +#### IndividualAccount + +Data model for the complex type **IndividualAccount**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [Integer](#integer) | Identifier of the ledger account. | +| `ledgerAccountType` | yes | [String](#string) | Type of the ledger account (for example, POSITION). | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the account. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the ledger account is active. Possible values are `1` and `0`. | +| `createdDate` | yes | [DateTime](#datetime) | Date and time when the ledger account was created. | +| `createdBy` | yes | [String](#string) | The entity that created the ledger account. | + +#### Limit + +Data model for the complex type **Limit**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Limit type. | +| `value` | yes | a positive [Number](#number) | Limit value. | + +#### Money + +For details, see section [Money](../fspiop/logical-data-model#mondey) in the Mojaloop FSPIOP API Definition. + +#### Participant + +Data model for the complex type **Participant**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +#### ParticipantFunds + +Data model for the complex type **ParticipantFunds**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | +| `externalReference` | yes | [String](#string) | Reference to any external data, such as an identifier from the settlement bank. | +| `action` | yes | [Enum](#enum) | The action performed on the funds. Possible values are: `recordFundsIn` and `recordFundsOutPrepareReserve`. | +| `reason` | yes | [String](#string) | The reason for the FundsIn or FundsOut action. | +| `amount` | yes | [Money](#money) | The FundsIn or FundsOut amount. | +| `extensionList` | no | [ExtensionList](#extensionlist) | Additional details. | + +#### ParticipantLimit + +Data model for the complex type **ParticipantLimit**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | The type of participant limit (for example, `NET_DEBIT_CAP`.) | +| `value` | yes | [Number](#number) | The value of the limit that has been set for the participant. | +| `alarmPercentage` | yes | [Number](#number) | An alarm notification is triggered when a pre-specified percentage of the limit is reached. Specifying an `alarmPercentage` is optional. If not specified, it will default to 10 percent, expressed as `10`. | + +#### ParticipantsNameEndpointsObject + +Data model for the complex type **ParticipantsNameEndpointsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | The endpoint type. | +| `value` | yes | [String](#string) | The endpoint value. | + +#### ParticipantsNameLimitsObject + +Data model for the complex type **ParticipantsNameLimitsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +#### Party + +For details, see section [Party](../fspiop/logical-data-model#party) in the Mojaloop FSPIOP API Definition. + +#### PartyComplexName + +For details, see section [PartyComplexName](../fspiop/logical-data-model#partycomplexname) in the Mojaloop FSPIOP API Definition. + +#### PartyIdInfo + +For details, see section [PartyIdInfo](../fspiop/logical-data-model#partyidinfo) in the Mojaloop FSPIOP API Definition. + +#### PartyPersonalInfo + +For details, see section [PartyPersonalInfo](../fspiop/logical-data-model#partypersonalinfo) in the Mojaloop FSPIOP API Definition. + +#### RecordFundsOut + +Data model for the complex type **RecordFundsOut**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `action` | yes | [Enum](#enum) | The FundsOut action performed. Possible values are: `recordFundsOutCommit` and `recordFundsOutAbort`. | +| `reason` | yes | [String](#string) | The reason for the FundsOut action. | + +#### Refund + +Data model for the complex type **Refund**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `originalTransactionId` | yes | [UUID](#uuid) | Reference to the original transaction id that is requested to be refunded. | +| `refundReason` | no | [String(1-128)](#string) | Free text indicating the reason for the refund. | + +#### SettlementModelsObject + +Data model for the complex type **SettlementModelsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `autoPositionReset` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +#### TransactionType + +For details, see section [TransactionType](../fspiop/logical-data-model#transactiontype) in the Mojaloop FSPIOP API Definition. diff --git a/docs/technical/api/assets/diagrams/images/figure1-platforms-layout.svg b/docs/technical/api/assets/diagrams/images/figure1-platforms-layout.svg new file mode 100644 index 000000000..8a12de358 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure1-platforms-layout.svg @@ -0,0 +1,3 @@ + + +
    CA
    CA
    ALS
    ALS
    FSP-1
    FSP-1
    FSP-2
    FSP-2
    Switch
    Switch
    FSP-3
    FSP-3
    FSP-4
    FSP-4
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Legend:
    Solid lines indicate TLS-secured communication.
    Dashed lines indicate certificate owner.
    Legend:...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure11.svg b/docs/technical/api/assets/diagrams/images/figure11.svg new file mode 100644 index 000000000..773d8495b --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure11.svg @@ -0,0 +1,4 @@ + + + +
     1 USD 
     1 USD 
    Agent Commission account
    Agent Comm...
     2 USD 
     2 USD 
    Fee account
    Fee account
     98 USD 
     98 USD 
    Payer's account
    Payer's ac...
     99 USD 
     99 USD 
    Payer FSP's Switch account
    Payer FSP'...
     99 USD 
     99 USD 
    Payer FSP Switch account
    Payer FSP...
     99 USD 
     99 USD 
    Payee FSP Switch account
    Payee FSP...
     98 USD 
     98 USD 
    1 USD
    1 USD
    Payee FSP's Switch account
    Payee FSP'...
    FSP Commision account
    FSP Commis...
    Fee account
    Fee account
    Agent Commision account
    Agent Comm...
    Payee's account
    Payee's ac...
    FSO Commission account
    FSO Commis...
    Payer FSP
    Payer FSP
    Payee FSP
    Payee FSP
    Switch
    Switch
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure12.svg b/docs/technical/api/assets/diagrams/images/figure12.svg new file mode 100644 index 000000000..c5183f904 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure12.svg @@ -0,0 +1,3 @@ + + +
    Payer FSP fee
    [Not supported by viewer]
    Payer
    Payer
     Payee FSP transaction fee 
    [Not supported by viewer]
    Payee FSP commission
    to subsidize transaction 
    [Not supported by viewer]
    Internal Payee fee to Payee FSP
    <font color="#ff3333">Internal Payee fee to Payee FSP</font>
    Internal Payee FSP
    bonus/commission
    to Payee
    [Not supported by viewer]
    Payee
    Payee
    InternalPayer FSP
    bonus/ commission
    to Payer
    [Not supported by viewer]
    Switch
    Switch
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure14.svg b/docs/technical/api/assets/diagrams/images/figure14.svg new file mode 100644 index 000000000..070228ec6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure14.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    1 USD
    1 USD
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure16.svg b/docs/technical/api/assets/diagrams/images/figure16.svg new file mode 100644 index 000000000..8f8828555 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure16.svg @@ -0,0 +1,3 @@ + + +
     2 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     98 USD 
     98 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     98 USD 
     98 USD 
    1 USD
    1 USD
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure18.svg b/docs/technical/api/assets/diagrams/images/figure18.svg new file mode 100644 index 000000000..a50ef985a --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure18.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     99 USD 
     99 USD 
    Payer's account
    Payer's account
     97 USD 
     97 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     97 USD 
     97 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     97 USD 
     97 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     3 USD 
     3 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     2 USD 
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure20.svg b/docs/technical/api/assets/diagrams/images/figure20.svg new file mode 100644 index 000000000..12a57a2a1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure20.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure22.svg b/docs/technical/api/assets/diagrams/images/figure22.svg new file mode 100644 index 000000000..60b81e1c7 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure22.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     98 USD 
     98 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     98 USD 
     98 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     98 USD 
     98 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     2 USD 
     2 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     2 USD 
    [Not supported by viewer]
    Agent
    Agent
    Customer
    Customer
    $
    [Not supported by viewer]
    100 USD in cash from Payee (Customer) to Payer (Agent)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure24.svg b/docs/technical/api/assets/diagrams/images/figure24.svg new file mode 100644 index 000000000..411df60cc --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure24.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
    Agent
    Agent
    Customer
    Customer
    $
    [Not supported by viewer]
    101 USD in cash from Payee (Customer) to Payer (Agent)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure26.svg b/docs/technical/api/assets/diagrams/images/figure26.svg new file mode 100644 index 000000000..cee48e5df --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure26.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     100 USD 
     100 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
    Customer
    Customer
    Merchant
    Merchant
     1 USD 
     1 USD 
    Goods/Service worth
    100 USD from Merchant (Payee)
     to Customer (Payer)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure28.svg b/docs/technical/api/assets/diagrams/images/figure28.svg new file mode 100644 index 000000000..2083fcd31 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure28.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     102 USD 
     102 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     102 USD 
     102 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     102 USD 
     102 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     3 USD 
     3 USD 
     2 USD 
     2 USD 
     2 USD 
     2 USD 
    Customer
    Customer
    Agent
    Agent
    $
    [Not supported by viewer]
    100 USD in cash from Agent (Payee) to Customer (Payer)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure30.svg b/docs/technical/api/assets/diagrams/images/figure30.svg new file mode 100644 index 000000000..f91ca847a --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure30.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     97 USD 
     97 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     97 USD 
     97 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     3 USD 
     3 USD 
     2 USD 
     2 USD 
     2 USD 
     2 USD 
    Customer
    Customer
    Agent
    Agent
    $
    [Not supported by viewer]
    97 USD in cash from Agent (Payee) to Customer (Payer)
    97 USD in cash from Agent (Payee) to Customer (Payer)
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure32.svg b/docs/technical/api/assets/diagrams/images/figure32.svg new file mode 100644 index 000000000..943d49ae4 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure32.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     102 USD 
     102 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     102 USD 
     102 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     102 USD 
     102 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     3 USD 
     3 USD 
     2 USD 
     2 USD 
     2 USD 
     2 USD 
    Customer
    Customer
    Agent
    Agent
    $
    [Not supported by viewer]
    100 USD in cash from Agent (Payee) to Customer (Payer)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure34.svg b/docs/technical/api/assets/diagrams/images/figure34.svg new file mode 100644 index 000000000..db4f8f046 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure34.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     101 USD 
     101 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     101 USD 
     101 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     101 USD 
     101 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
    Customer
    Customer
    Merchant
    Merchant
     1 USD 
     1 USD 
    Goods/Service worth
    100 USD from Merchant (Payee)
    to Customer (Payer)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure36.svg b/docs/technical/api/assets/diagrams/images/figure36.svg new file mode 100644 index 000000000..d5941799f --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure36.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     101 USD 
     101 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     101 USD 
     101 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     101 USD 
     101 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
    Customer
    Customer
     2 USD 
    [Not supported by viewer]
    $
    [Not supported by viewer]
    100 USD in cash from ATM (Payee) to Customer (Payer)
    100 USD in cash from ATM (Payee) to Customer (Payer)
    ATM
    ATM
    diff --git a/docs/technical/api/assets/diagrams/images/figure38.svg b/docs/technical/api/assets/diagrams/images/figure38.svg new file mode 100644 index 000000000..9e6187188 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure38.svg @@ -0,0 +1,3 @@ + + +
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
    Customer
    Customer
    Merchant
    Merchant
     1 USD 
     1 USD 
    Goods/Service worth
    100 USD from Merchant (Payee)
    to Customer (Payer)
    [Not supported by viewer]
     1 USD 
     1 USD 
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure40.svg b/docs/technical/api/assets/diagrams/images/figure40.svg new file mode 100644 index 000000000..ae2cf6677 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure40.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
     1 USD 
     1 USD 
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP 
    Commission account
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
     1 USD 
    [Not supported by viewer]
    Customer
    Customer
    Agent
    Agent
     1 USD 
    [Not supported by viewer]
    $
    [Not supported by viewer]
    101 USD in cash from Agent (Payee) to Customer (Payer)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure46.svg b/docs/technical/api/assets/diagrams/images/figure46.svg new file mode 100644 index 000000000..75093833a --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure46.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    PENDING
    <b>PENDING</b>
    REJECTED
    <b>REJECTED</b>
    ACCEPTED
    <b>ACCEPTED</b>
    Payer FSP receives
    the transaction
    request from 
    the Payee FSP
    [Not supported by viewer]
    Payer FSP sends
    the transaction
    request to 
    the Payee
    [Not supported by viewer]
    Payer 
    responds
    [Not supported by viewer]
    Payer  approved 
    the transaction
    [Not supported by viewer]
    Payer rejected 
    the transaction
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure48.svg b/docs/technical/api/assets/diagrams/images/figure48.svg new file mode 100644 index 000000000..1a7fa406f --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure48.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    PENDING
    <b>PENDING</b>
    REJECTED
    <b>REJECTED</b>
    ACCEPTED
    <b>ACCEPTED</b>
    Peer FSP 
    receives the 
    request 
    from the FSP
    [Not supported by viewer]
    Peer FSP 
    validates 
    the quote 
    request
    [Not supported by viewer]
    Peer FSP
    tries to 
    create a 
    quote
    [Not supported by viewer]
    Peer FSP 
    successfully 
    create a quote
    [Not supported by viewer]
    Peer FSP 
    failed to 
    create a quote
    [Not supported by viewer]
    EXPIRED
    <b>EXPIRED</b>
    The quote 
    expires and 
    is no longer 
    valid
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure56.svg b/docs/technical/api/assets/diagrams/images/figure56.svg new file mode 100644 index 000000000..b0d58be95 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure56.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    RESERVED
    <b>RESERVED</b>
    ABORTED
    <b>ABORTED</b>
    COMMITTED
    <b>COMMITTED</b>
    The ledger 
    receives a 
    transfer 
    request
    [Not supported by viewer]
    The ledger 
    reserves 
    the transfer
    [Not supported by viewer]
    The ledger 
    receives 
    results 
    from the 
    next ledger
    [Not supported by viewer]
    Next ledger 
    successfully 
    performed the 
    transfer
    [Not supported by viewer]
    Next ledger 
    failed to 
    perform the 
    transfer or the 
    transfer expired
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure58.svg b/docs/technical/api/assets/diagrams/images/figure58.svg new file mode 100644 index 000000000..5d8ba0c93 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure58.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    PENDING
    <b>PENDING</b>
    REJECTED
    <b>REJECTED</b>
    COMPLETED
    <b>COMPLETED</b>
    Payee FSP
    receives the
    transaction
    from the
    Payer FSP
    [Not supported by viewer]
    Payee FSP 
    validates 
    the
    transaction
    [Not supported by viewer]
    Payee FSP 
    tries to 
    perform the 
    transaction
    [Not supported by viewer]
    Payee FSP 
    successfully 
    performed the 
    transaction
    [Not supported by viewer]
    Payee FSP failed 
    to 
    perform 
    the transaction
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure60.svg b/docs/technical/api/assets/diagrams/images/figure60.svg new file mode 100644 index 000000000..9f97ba682 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure60.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    PENDING
    <b>PENDING</b>
    REJECTED
    <b>REJECTED</b>
    ACCEPTED
    <b>ACCEPTED</b>
    Payee FSP 
    receives the 
    request 
    from the 
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    validates 
    the bulk 
    quote 
    request
    [Not supported by viewer]
    Payee FSP 
    tries to 
    create a 
    quote
    [Not supported by viewer]
    Payee FSP 
    successfully 
    created a quote
    [Not supported by viewer]
    Payee FSP 
    failed to 
    create a quote
    [Not supported by viewer]
    EXPIRED
    <b>EXPIRED</b>
    The quote 
    expires and 
    is no longer 
    valid
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure62.svg b/docs/technical/api/assets/diagrams/images/figure62.svg new file mode 100644 index 000000000..466446b23 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure62.svg @@ -0,0 +1,3 @@ + + +
    RECEIVED
    <b>RECEIVED</b>
    PENDING
    <b>PENDING</b>
    REJECTED
    <b>REJECTED</b>
    ACCEPTED
    <b>ACCEPTED</b>
    Payee FSP 
    receives 
    the bulk 
    transfer 
    from the 
    Payer FSP
    [Not supported by viewer]
    Payee FSP 
    validates 
    the bulk 
    transfer
    [Not supported by viewer]
    Payee FSP 
    finishes 
    validation 
    of the bulk 
    transfer
    [Not supported by viewer]
    Payee FSP 
    accepts to 
    process 
    the bulk 
    transfer
    [Not supported by viewer]
    Payee FSP 
    rejects to 
    process the 
    bulk transfer
    [Not supported by viewer]
    PROCESSING
    <b>PROCESSING</b>
    Payee FSP 
    starts to 
    transfer 
    funds to 
    the Payees
    [Not supported by viewer]
    COMPLETED
    <b>COMPLETED</b>
    Payee FSP 
    completes 
    transfer of 
    funds to 
    the Payees
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure63.svg b/docs/technical/api/assets/diagrams/images/figure63.svg new file mode 100644 index 000000000..1f262897d --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure63.svg @@ -0,0 +1,3 @@ + + +
    High-level 
    category
    [Not supported by viewer]
    Low-level 
    category
    [Not supported by viewer]
    Specific error
    Specific error
    1 digit
    1 digit
    1 digit
    1 digit
    2 digit
    2 digit
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure7.svg b/docs/technical/api/assets/diagrams/images/figure7.svg new file mode 100644 index 000000000..e3b0e5548 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure7.svg @@ -0,0 +1,3 @@ + + +
    Payer fee to Payer FSP
    <font color="#ff3333">Payer fee to Payer FSP</font>
    Payer
    Payer
     Payee FSP transaction fee 
    [Not supported by viewer]
    Payee FSP commission
    to Payer FSP
    [Not supported by viewer]
    Internal Payee fee to Payee FSP
    <font color="#ff3333">Internal Payee fee to Payee FSP</font>
    internal Payee FSP
    bonus/commission
    to Payee
    [Not supported by viewer]
    Payee
    Payee
    Payer FSP
    bonus/commission
     to Payee
    [Not supported by viewer]
    Switch
    Switch
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure73.svg b/docs/technical/api/assets/diagrams/images/figure73.svg new file mode 100644 index 000000000..148715368 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure73.svg @@ -0,0 +1,3 @@ + + +
    Switch
    (Identifier = Switch)
    Switch<br>(Identifier = <b>Switch</b>)
    FSP
    (Identifier = MobileMoney)
    FSP<br>(<b>Identifier = MobileMoney</b>)
    FSP
    (Identifier = BankNrOne)
    FSP<br>(<b>Identifier = BankNrOne</b>)
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/images/figure9.svg b/docs/technical/api/assets/diagrams/images/figure9.svg new file mode 100644 index 000000000..68f6c3716 --- /dev/null +++ b/docs/technical/api/assets/diagrams/images/figure9.svg @@ -0,0 +1,3 @@ + + +
     1 USD 
    [Not supported by viewer]
    Agent Commission account
    Agent Commission account
     1 USD 
     1 USD 
    Fee account
    Fee account
     100 USD 
     100 USD 
    Payer's account
    Payer's account
     99 USD 
     99 USD 
    Payer FSP's Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payer FSP Switch account
    [Not supported by viewer]
     99 USD 
     99 USD 
    Payee FSP Switch account
    [Not supported by viewer]
     100 USD 
     100 USD 
    1 USD
    1 USD
    Payee FSP's Switch account
    [Not supported by viewer]
    FSP Commission account
    FSP Commission account
    Fee account
    Fee account
    Agent Commission account
    Agent Commission account
    Payee's account
    Payee's account
    FSP Commission account
    FSP Commission account
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Switch
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/api/assets/diagrams/sequence/figure1.plantuml b/docs/technical/api/assets/diagrams/sequence/figure1.plantuml new file mode 100644 index 000000000..e80fedf1c --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure1.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP POST call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(Service information, ID) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **POST /service**\n(Service information, ID) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Create service object\naccording to request +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service\nobject information +FSP -[hidden]> Switch +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure1.svg b/docs/technical/api/assets/diagrams/sequence/figure1.svg new file mode 100644 index 000000000..50be4512d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure1.svg @@ -0,0 +1,77 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + + Create service object + according to request + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service + object information + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure10.plantuml b/docs/technical/api/assets/diagrams/sequence/figure10.plantuml new file mode 100644 index 000000000..41c039e8f --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure10.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of non-disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to Payee to\nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee\nor commission for\nhandeling transaction in\nPayee FSP => fee 1 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeReceiveamount=98 USD\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeReceiveamount=98 USD\npayeeFspFee=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Show total fees to Payer +PayerFSP ->> Payer: Payee will receive 98 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure10.svg b/docs/technical/api/assets/diagrams/sequence/figure10.svg new file mode 100644 index 000000000..83d930001 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure10.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to Payee to + send 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee + or commission for + handeling transaction in + Payee FSP => fee 1 USD + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeReceiveamount=98 USD + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeReceiveamount=98 USD + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + + Show total fees to Payer + + + + Payee will receive 98 USD + if you send 100 USD + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure13.plantuml b/docs/technical/api/assets/diagrams/sequence/figure13.plantuml new file mode 100644 index 000000000..7ea6e0dfa --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure13.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to send\n100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or\ncommission for handeling\ntransaction in Payee FSP =>\nFSP commission 1 USD +group Optional + hnote left of PayeeFSP + Notify/Ask Payee + for approval + end note + PayeeFSP ->> Payee: If accepted, you will receive\n100 USD + PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeFspCommission=1 USD,\npayeeReceivedAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\nPayeeFspCommission=1 USD\npayeeReceivedAmouint=100 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Transaction is subsidized with the\ncommission as fees are disclosed,\nshow total fees to Payer +PayerFSP ->> Payer: Sending 100 USD to Payee\nwill cost 0 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure13.svg b/docs/technical/api/assets/diagrams/sequence/figure13.svg new file mode 100644 index 000000000..63a4002d7 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure13.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to send + 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or + commission for handeling + transaction in Payee FSP => + FSP commission 1 USD + + + Optional + + Notify/Ask Payee + for approval + + + + If accepted, you will receive + 100 USD + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeFspCommission=1 USD, + payeeReceivedAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + PayeeFspCommission=1 USD + payeeReceivedAmouint=100 USD) + + + + HTTP 200 + (OK) + + + + + Transaction is subsidized with the + commission as fees are disclosed, + show total fees to Payer + + + + Sending 100 USD to Payee + will cost 0 USD in fees + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure15.plantuml b/docs/technical/api/assets/diagrams/sequence/figure15.plantuml new file mode 100644 index 000000000..2c33654b8 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure15.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to\ nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee\nor commission for\nhandeling transaction in\nPayee FSP => fee 1 USD +group Optional +PayeeFSP ->> Payee: If accepted, you will receive\n98 USD out of Payer's 100 USD +hnote left of PayeeFSP + Notify/Ask Payee + for approval +end note +PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=98 USD,\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=98 USD\npayeeFspFees=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Show total fees to Payer +PayerFSP ->> Payer: Payee will receive 98 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure15.svg b/docs/technical/api/assets/diagrams/sequence/figure15.svg new file mode 100644 index 000000000..94a536f15 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure15.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to\ nsend 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee + or commission for + handeling transaction in + Payee FSP => fee 1 USD + + + Optional + + + + If accepted, you will receive + 98 USD out of Payer's 100 USD + + Notify/Ask Payee + for approval + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=98 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=98 USD + payeeFspFees=1 USD) + + + + HTTP 200 + (OK) + + + + + Show total fees to Payer + + + + Payee will receive 98 USD + if you send 100 USD + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure17.plantuml b/docs/technical/api/assets/diagrams/sequence/figure17.plantuml new file mode 100644 index 000000000..e95153b41 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure17.plantuml @@ -0,0 +1,146 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example of disclosing send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to \nsend 100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Rate fee for Payer for\nhandling transaction in\nPayer FSP => fee 1 USD +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD, fees=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or commission\nfor handeling transaction in\nPayee FSP => FSP commission 3\nUSD (1 USD to pay for Payer's\nfee, 2 USD in excess commission) +group Optional +PayeeFSP ->> Payee: If accepted, you will receive\n100 USD out of Payer's 100 USD +hnote left of PayeeFSP + Notify/Ask Payee + for approval +end note +PayeeFSP <<- Payee: OK +end +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=97 USD,\npayeeReceivedAmount=100 USD,\npayeeFspCommission=3 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=97 USD,\npayeeReceiveAmount=100 USD\npayeeFspCommission=3 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer should pay 100 USD, Payer\nFSP will earn in total 3 USD in fees\n(Payer fee of 1 USD paid by\nPayeeFSP, plus 2 USD in access\ncommission) +PayerFSP ->> Payer: Payee will receive 100 USD\nif you send 100 USD +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure17.svg b/docs/technical/api/assets/diagrams/sequence/figure17.svg new file mode 100644 index 000000000..aa3f4fdb4 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure17.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to + send 100 USD to Payee + + + + + Rate fee for Payer for + handling transaction in + Payer FSP => fee 1 USD + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD, fees=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or commission + for handeling transaction in + Payee FSP => FSP commission 3 + USD (1 USD to pay for Payer's + fee, 2 USD in excess commission) + + + Optional + + + + If accepted, you will receive + 100 USD out of Payer's 100 USD + + Notify/Ask Payee + for approval + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=97 USD, + payeeReceivedAmount=100 USD, + payeeFspCommission=3 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=97 USD, + payeeReceiveAmount=100 USD + payeeFspCommission=3 USD) + + + + HTTP 200 + (OK) + + + + + Payer should pay 100 USD, Payer + FSP will earn in total 3 USD in fees + (Payer fee of 1 USD paid by + PayeeFSP, plus 2 USD in access + commission) + + + + Payee will receive 100 USD + if you send 100 USD + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure19.plantuml b/docs/technical/api/assets/diagrams/sequence/figure19.plantuml new file mode 100644 index 000000000..33ed308f9 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure19.plantuml @@ -0,0 +1,159 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title P2P Transfer example with receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like Payee\nto receive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Commission is 1 USD in\nPayee FSP for P2P +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer FSP keeps commission\nas fee, Payer also should pay\nfee of 1 USD +PayerFSP ->> Payer: Transfering 100 USD to Payee\nwill cost you 101 USD\nincluding fees +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Receive 101 USD from Payer\naccount, 99 USD to Switch\naccount, 1 USD to fee account,\n1 USD to FSP commission account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Receive 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount and 1 USD from\ncommission account\nto Payee account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful,\nyou have paid 1 USD in fee +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure19.svg b/docs/technical/api/assets/diagrams/sequence/figure19.svg new file mode 100644 index 000000000..cb8eef462 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure19.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like Payee + to receive 100 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Commission is 1 USD in + Payee FSP for P2P + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer FSP keeps commission + as fee, Payer also should pay + fee of 1 USD + + + + Transfering 100 USD to Payee + will cost you 101 USD + including fees + + + + Perform transaction + + + + + Receive 101 USD from Payer + account, 99 USD to Switch + account, 1 USD to fee account, + 1 USD to FSP commission account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Receive 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account and 1 USD from + commission account + to Payee account + + + You have received 100 USD + from Payer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, + you have paid 1 USD in fee + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml b/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml new file mode 100644 index 000000000..0b5116c3f --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam sequencearrowcolor Black + +hide footbox + +' declare title +' title HTTP POST call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(Service information, ID) +activate FSP +activate Switch +FSP <<[#Red]-- Switch : **HTTP 202** (Accepted) +Switch ->> PEERFSP: **POST /service**\n(Service information, ID) +activate PEERFSP +Switch <<[#Red]-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Create service object\naccording to request +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch --[#Red]>> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP --[#Red]>> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object information +FSP -[hidden]> Switch +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg b/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg new file mode 100644 index 000000000..49c15b416 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure1_http-timeout.svg @@ -0,0 +1,76 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + POST /service + (Service information, ID) + + + + HTTP 202 + (Accepted) + + + + + Create service object + according to request + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object information + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure2.plantuml b/docs/technical/api/assets/diagrams/sequence/figure2.plantuml new file mode 100644 index 000000000..5a7668cd6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure2.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declare skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP GET call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /service/**//// +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **GET /service/**//// +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Lookup service\ninformation regarding\nservice with//// +Switch <<- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object\ninformation update +FSP -[hidden]> FSP +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure2.svg b/docs/technical/api/assets/diagrams/sequence/figure2.svg new file mode 100644 index 000000000..0b32be0cf --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure2.svg @@ -0,0 +1,79 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Lookup service + information regarding + service with + <ID> + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object + information update + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure21.plantuml b/docs/technical/api/assets/diagrams/sequence/figure21.plantuml new file mode 100644 index 000000000..294c13d52 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure21.plantuml @@ -0,0 +1,167 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-initiated Cash-In example with send amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n(OTC)" as PayerOTC +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee + +' start flow +PayerOTC ->> Payer: I would like to Cash-in\nthis 100 USD bill +PayerOTC <<- Payer: OK, you will receive a\nnotification from your FSP\ndisplaying the fees +Payer ->> PayerFSP: I would like to send\n100 USD to Payee +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 2 USD in Payer\nFSP for Cash-in,\nPayer will receive 1\nUSD in internal commission. +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=98 USD, fees=2 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=98 USD, fees=2 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payee FSP decides to give\n2 USD in FSP commission to\nPayer so that\nCash-in is free +PayeeFSP ->> Payee: By paying 100 USD in cash\nto Payer, you will receive\n100 USD to your account +PayeeFSP <<-- Payee: OK +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=98 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=98 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <<- PayerFSP: Payee will receive 100 USD\nand has accepted the\nquote, you will receive\n1 USD in commission +deactivate PayerFSP +PayerOTC <<- Payer: You will receive 100 USD\non your account. Please give\nme the 100 USD bill +PayerOTC ->> Payer: OK, here is 100 USD +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 98 USD to Switch\naccount and 2 USD to fee account,\n1 USD from agent commission\naccount to Payer +PayerFSP ->> Switch: **POST /transfers**\n(amount=98 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 98 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=98 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 98 USD from Switch\naccount and 2 USD from\nFSP commission account\nto Payee account +PayeeFSP -> Payee: You have Cash-in 100 USD +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful, you have\nsent 100 USD and received\n1 USD in commission +deactivate PayerFSP +PayerOTC <- Payer: Thank you! +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure21.svg b/docs/technical/api/assets/diagrams/sequence/figure21.svg new file mode 100644 index 000000000..35f3955eb --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure21.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + (OTC) + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + + + + + + + + + I would like to Cash-in + this 100 USD bill + + + + OK, you will receive a + notification from your FSP + displaying the fees + + + + I would like to send + 100 USD to Payee + + + + + Fee is 2 USD in Payer + FSP for Cash-in, + Payer will receive 1 + USD in internal commission. + + + + POST /quotes + (amountType=SEND, + amount=98 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=98 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + + Payee FSP decides to give + 2 USD in FSP commission to + Payer so that + Cash-in is free + + + + By paying 100 USD in cash + to Payer, you will receive + 100 USD to your account + + + + OK + + + + PUT /quotes/ + <ID> + (transferAmount=98 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=98 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=2 USD) + + + + HTTP 200 + (OK) + + + + Payee will receive 100 USD + and has accepted the + quote, you will receive + 1 USD in commission + + + + You will receive 100 USD + on your account. Please give + me the 100 USD bill + + + + OK, here is 100 USD + + + + Perform transaction + + + + + Reserve 100 USD from Payer + account, 98 USD to Switch + account and 2 USD to fee account, + 1 USD from agent commission + account to Payer + + + + POST /transfers + (amount=98 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 98 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=98 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 98 USD from Switch + account and 2 USD from + FSP commission account + to Payee account + + + You have Cash-in 100 USD + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, you have + sent 100 USD and received + 1 USD in commission + + + Thank you! + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure23.plantuml b/docs/technical/api/assets/diagrams/sequence/figure23.plantuml new file mode 100644 index 000000000..bb636328f --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure23.plantuml @@ -0,0 +1,167 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-initiated Cash-In example with received amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n(OTC)" as PayerOTC +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee + +' start flow +PayerOTC ->> Payer: I would like to Cash-in\nso that I receive 100 USD +PayerOTC <<- Payer: OK, you will receive a\nnotification from your FSP\ndisplaying the fees +Payer ->> PayerFSP: I would like Agent (Payee) to\nreceive 100 USD +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 2 USD in Payer\nFSP for Cash-in,\nPayer will receive 1\nUSD in internal commission. +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=2 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD, fees=2 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payee FSP decides to give\n1 USD in commission to\nPayer so that\nCash-in only costs 1 USD +PayeeFSP ->> Payee: By paying 101 USD in cash\nto Payer, you will receive\n100 USD to your account +PayeeFSP <<-- Payee: OK +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeReceiveAmount=100 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <<- PayerFSP: Payee will receive 100 USD\nand fee is 1 USD, you will receive\n1 USD in commission +deactivate PayerFSP +PayerOTC <<- Payer: You will receive 100 USD on your\naccount. Please give me 101 USD +PayerOTC ->> Payer: OK, here is 101 USD +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 1 USD from Agent\ncommission to Payer account,\n100 USD from Payer account,\n99 USD to Switch account and 1\nUSD to fee account, 1 USD from\nFSP Commission to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount = 99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount = 99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount and 1 USD from\ninternal commission account\nto Payee account +PayeeFSP -> Payee: You have Cashed-in 100 USD +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful, you have\nsent 100 USD and received\n1 USD in commission +deactivate PayerFSP +PayerOTC <- Payer: Thank you! +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure23.svg b/docs/technical/api/assets/diagrams/sequence/figure23.svg new file mode 100644 index 000000000..84b41a512 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure23.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + (OTC) + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + + + + + + + + + I would like to Cash-in + so that I receive 100 USD + + + + OK, you will receive a + notification from your FSP + displaying the fees + + + + I would like Agent (Payee) to + receive 100 USD + + + + + Fee is 2 USD in Payer + FSP for Cash-in, + Payer will receive 1 + USD in internal commission. + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD, fees=2 USD) + + + + HTTP 202 + (Accepted) + + + + + Payee FSP decides to give + 1 USD in commission to + Payer so that + Cash-in only costs 1 USD + + + + By paying 101 USD in cash + to Payer, you will receive + 100 USD to your account + + + + OK + + + + PUT /quotes/ + <ID> +   + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeReceiveAmount=100 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + Payee will receive 100 USD + and fee is 1 USD, you will receive + 1 USD in commission + + + + You will receive 100 USD on your + account. Please give me 101 USD + + + + OK, here is 101 USD + + + + Perform transaction + + + + + Reserve 1 USD from Agent + commission to Payer account, + 100 USD from Payer account, + 99 USD to Switch account and 1 + USD to fee account, 1 USD from + FSP Commission to fee account + + + + POST /transfers + (amount = 99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount = 99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account and 1 USD from + internal commission account + to Payee account + + + You have Cashed-in 100 USD + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, you have + sent 100 USD and received + 1 USD in commission + + + Thank you! + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure25.plantuml b/docs/technical/api/assets/diagrams/sequence/figure25.plantuml new file mode 100644 index 000000000..97b9d89ee --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure25.plantuml @@ -0,0 +1,163 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Merchant Payment example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to buy\nthis goods or service +Payee ->> PayerOTC: The goods or service cost\n100 USD before any fees,\nplease initiate the transaction +Payer ->> PayerFSP: I would like Payee to\nreceive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Interoperable fee is 0 USD in\nPayee FSP for Merchant\nPayment, but 1 USD in\ninternal Payee fee for Merchant +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=100 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Fee is 1 USD in Payer\nFSP for Merchant Payment,\ntotal fee is 1 USD +Payer <<- PayerFSP: Will you approve Merchant Payment\nof 100 USD to Payee? It will\ncost you 1 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 101 USD from Payer\naccount, 100 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 100 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 100 USD from Switch\naccount to Payee account, 1 USD\nfrom Payee to fee account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer and paid 1 USD\nin internal fee. Please give\ngoods or service to Payer. +Payee ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Payment successful, you\nhave paid 100 USD to Payee\nplus 1 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure25.svg b/docs/technical/api/assets/diagrams/sequence/figure25.svg new file mode 100644 index 000000000..54293ab7b --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure25.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee +   + + + + Payer + (OTC) + + + + + + + + + + + + I would like to buy + this goods or service + + + + The goods or service cost + 100 USD before any fees, + please initiate the transaction + + + + I would like Payee to + receive 100 USD + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Interoperable fee is 0 USD in + Payee FSP for Merchant + Payment, but 1 USD in + internal Payee fee for Merchant + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + + Fee is 1 USD in Payer + FSP for Merchant Payment, + total fee is 1 USD + + + + Will you approve Merchant Payment + of 100 USD to Payee? It will + cost you 1 USD in fees. + + + + Perform transaction + + + + + Reserve 101 USD from Payer + account, 100 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 100 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 100 USD from Switch + account to Payee account, 1 USD + from Payee to fee account + + + You have received 100 USD + from Payer and paid 1 USD + in internal fee. Please give + goods or service to Payer. + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Payment successful, you + have paid 100 USD to Payee + plus 1 USD in fees + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure27.plantuml b/docs/technical/api/assets/diagrams/sequence/figure27.plantuml new file mode 100644 index 000000000..41fcc2b28 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure27.plantuml @@ -0,0 +1,163 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Cash-Out example (receive amount) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +Payee ->> PayerOTC: Please initiate the transaction +Payer ->> PayerFSP: I would like to Cash-Out\n100 USD from Agent (Payee) +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee\nFSP to cover agent\ncommission, agent will receive\n1 USD in agent commission +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=102 USD,\nPayFspFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFspFee=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Cash-Out, total fee\nis 3 USD +Payer <<- PayerFSP: Will you approve Cash-Out\nof 100 USD? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 103 USD from Payer\naccount, 102 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=102 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 102 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=102 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 102 USD from Switch\naccount, 101 USD to Payee\n(1 USD commission), and\n1 USD to fee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer plus 1 USD in\ncommission, please give 100 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 100 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure27.svg b/docs/technical/api/assets/diagrams/sequence/figure27.svg new file mode 100644 index 000000000..45e0d08a2 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure27.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + Please initiate the transaction + + + + I would like to Cash-Out + 100 USD from Agent (Payee) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee + FSP to cover agent + commission, agent will receive + 1 USD in agent commission + + + + PUT /quotes/ + <ID> +   + (transferAmount=102 USD, + PayFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Cash-Out, total fee + is 3 USD + + + + Will you approve Cash-Out + of 100 USD? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 103 USD from Payer + account, 102 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 102 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 102 USD from Switch + account, 101 USD to Payee + (1 USD commission), and + 1 USD to fee account + + + + You have received 100 USD + from Payer plus 1 USD in + commission, please give 100 USD + in cash to Payer + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 100 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure29.plantuml b/docs/technical/api/assets/diagrams/sequence/figure29.plantuml new file mode 100644 index 000000000..e6886c6b9 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure29.plantuml @@ -0,0 +1,164 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Customer-Initiated Cash-Out example (send amount) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +Payee ->> PayerOTC: Please initiate the transaction +Payer ->> PayerFSP: I would like to Cash-Out from\nAgent (Payee) so that 100 USD is\nwithdrawn from my account +activate PayerFSP +PayerFSP -> PayerFSP: Fee is 1 USD in Payer\nFSP from Cash-Out +PayerFSP ->> Switch: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=SEND,\namount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee FSP to\ncover agent commission, agent will\nreceive 1 USD in internal commission +Switch <<- PayeeFSP: **PUT /quotes/** \n(transferAmount=99 USD,\nPayeeFspFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspFee=2 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Calculate Payee receive amount\nas not sent from Payee FSP\n(transferAmount -\npayeeFspFee=97 USD) +Payer <<- PayerFSP: Will you approve Cash-Out\nof 97 USD? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 99 USD to Switch\naccount and 1 USD to\nfee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount, 2 USD to fee account and\n98 USD (including 1 USD in\ncommission) to Payee +PayeeFSP ->> Payee: You have received 97 USD\nfrom Payer plus 1 USD in\ncommission, please give 97 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 97 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 97 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure29.svg b/docs/technical/api/assets/diagrams/sequence/figure29.svg new file mode 100644 index 000000000..8e1c5bd64 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure29.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + Please initiate the transaction + + + + I would like to Cash-Out from + Agent (Payee) so that 100 USD is + withdrawn from my account + + + + + Fee is 1 USD in Payer + FSP from Cash-Out + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=SEND, + amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee FSP to + cover agent commission, agent will + receive 1 USD in internal commission + + + + PUT /quotes/ + <ID> +   + (transferAmount=99 USD, + PayeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Calculate Payee receive amount + as not sent from Payee FSP + (transferAmount - + payeeFspFee=97 USD) + + + + Will you approve Cash-Out + of 97 USD? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 100 USD from Payer + account, 99 USD to Switch + account and 1 USD to + fee account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account, 2 USD to fee account and + 98 USD (including 1 USD in + commission) to Payee + + + + You have received 97 USD + from Payer plus 1 USD in + commission, please give 97 USD + in cash to Payer + + + + Here is your 97 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 97 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml b/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml new file mode 100644 index 000000000..4834069c2 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.plantuml @@ -0,0 +1,68 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declare skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP GET call flow + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /service/**//// +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PEERFSP: **GET /service/**//// +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Lookup service\ninformation regarding\nservice with//// +Switch <<[#Red]- PEERFSP: **PUT /service/**////\n(Service object information) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +FSP <<[#Red]- Switch: **PUT /service/**////\n(Service object information) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +FSP -> FSP: Handle service object\ninformation update +FSP -[hidden]> FSP +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg b/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg new file mode 100644 index 000000000..43254c4a9 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure2_callback_timeout.svg @@ -0,0 +1,79 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + GET /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Lookup service + information regarding + service with + <ID> + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + PUT /service/ + <ID> + (Service object information) + + + + HTTP 200 + (OK) + + + + + Handle service object + information update + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure3.plantuml b/docs/technical/api/assets/diagrams/sequence/figure3.plantuml new file mode 100644 index 000000000..04af955c2 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure3.plantuml @@ -0,0 +1,59 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP DELETE call flow + +' Actor Keys: +' participant - FSP and Account Lookup + +' declare actors +participant "\nFSP" as FSP +participant "Account\nLookup" as ALS + +' start flow +FSP ->> ALS: **DELETE /service/**//// +activate FSP +activate ALS +FSP <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Delete object\naccording to request +FSP <<- ALS: **PUT /service/**////\n(Delete object information) +FSP -->> ALS: **HTTP 200** (OK) +deactivate ALS +FSP -> FSP: Handle delete object\ninformation +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure3.svg b/docs/technical/api/assets/diagrams/sequence/figure3.svg new file mode 100644 index 000000000..abeab0e1e --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure3.svg @@ -0,0 +1,50 @@ + + + + + + + + +   + FSP + + Account + Lookup + + + + + + DELETE /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Delete object + according to request + + + + PUT /service/ + <ID> + (Delete object information) + + + + HTTP 200 + (OK) + + + + + Handle delete object + information + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure31.plantuml b/docs/technical/api/assets/diagrams/sequence/figure31.plantuml new file mode 100644 index 000000000..5f62c990d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure31.plantuml @@ -0,0 +1,177 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Agent-Initiated Cash-Out example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(Agent/OTC) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to\nCash-Out 100 USD +PayeeFSP <<- Payee: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequest**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 2 USD in Payee FSP\nto cover agent\ncommission, agent will\nreceive 1 USD in commission +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFSPFee=2 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=102 USD,\npayeeFSPFee=2 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Cash-Out, total fees\nare 3 USD +Payer <<- PayerFSP: Will you approve Cash-out of\n100 USD to Payee? It will\ncost you 3 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 103 USD for Payer\naccount, 102 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=102 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 102 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=102 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 102 USD from Switch\naccount, 101 USD to Payee\n(1 USD commission), and\n1 USD to fee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer plus 1 USD in\ncommission, please give 100 USD\nin cash to Payer +Payee ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou should receive 100 USD\nin cash from Payee. You have\npaid 3 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure31.svg b/docs/technical/api/assets/diagrams/sequence/figure31.svg new file mode 100644 index 000000000..ee320e69b --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure31.svg @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + + + + I would like to + Cash-Out 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequest + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 2 USD in Payee FSP + to cover agent + commission, agent will + receive 1 USD in commission + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFSPFee=2 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=102 USD, + payeeFSPFee=2 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Cash-Out, total fees + are 3 USD + + + + Will you approve Cash-out of + 100 USD to Payee? It will + cost you 3 USD in fees. + + + + Perform transaction + + + + + Reserve 103 USD for Payer + account, 102 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 102 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=102 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 102 USD from Switch + account, 101 USD to Payee + (1 USD commission), and + 1 USD to fee account + + + + You have received 100 USD + from Payer plus 1 USD in + commission, please give 100 USD + in cash to Payer + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you should receive 100 USD + in cash from Payee. You have + paid 3 USD in fees. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure33.plantuml b/docs/technical/api/assets/diagrams/sequence/figure33.plantuml new file mode 100644 index 000000000..188829960 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure33.plantuml @@ -0,0 +1,177 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Merchant-Initiated Merchant Payment example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(Agent)" as Payee +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payee <<- PayerOTC: I would like to buy goods\nor service for 100 USD +PayeeFSP <<- Payee: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Receives status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Fee is 0 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=100 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer\nFSP for Merchant Payment +Payer <<- PayerFSP: Will you approve Merchant Payment\nof 100 USD to Payee? It will\ncost you 1 USD in fees. +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 101 USD from Payer\naccount, 100 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 100 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 100 USD from Switch\naccount to Payee account +PayeeFSP ->> Payee: You have received 100 USD\nfrom Payer. Please give goods\nor service to Payer +Payee ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **PUT /transfers/** +PayerFSP ->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <<- PayerFSP: Transaction successful,\nyou have paid 100 USD to Payee\nplus 1 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure33.svg b/docs/technical/api/assets/diagrams/sequence/figure33.svg new file mode 100644 index 000000000..67ccb5047 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure33.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (Agent) + + + + Payer + (OTC) + + + + + + + + + + + + + + + I would like to buy goods + or service for 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Receives status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Fee is 0 USD + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=100 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer + FSP for Merchant Payment + + + + Will you approve Merchant Payment + of 100 USD to Payee? It will + cost you 1 USD in fees. + + + + Perform transaction + + + + + Reserve 101 USD from Payer + account, 100 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 100 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 100 USD from Switch + account to Payee account + + + + You have received 100 USD + from Payer. Please give goods + or service to Payer + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + Transaction successful, + you have paid 100 USD to Payee + plus 1 USD in fees. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure35.plantuml b/docs/technical/api/assets/diagrams/sequence/figure35.plantuml new file mode 100644 index 000000000..1bbc06eb6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure35.plantuml @@ -0,0 +1,205 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title ATM-Initiated Cash-Out example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(ATM)" as PayeeATM +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +Payer -> PayerFSP: Pre-generate OTP for me so that\nI can use it for ATM Cash-Out +activate PayerFSP +PayerFSP -> PayerFSP: Generate OTP +Payer <<-- PayerFSP: "12345 is your OTP" +deactivate PayerFSP +PayeeATM <<- PayerOTC: I would like to\nCash-Out 100 USD +PayeeFSP <<- PayeeATM: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +activate PayerFSP +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Payer fee is 1 USD for\nATM Cash-Out +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=101 USD,\npayeeFspFee=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=101 USD,\npayeeFspFee=1 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer fee is 1 USD in Payer FSP\nfor ATM Cash-Out, total fee 2 USD +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: OTP is pre-generated +Payer <<- PayerFSP: Use you pre-generated OTP to accept\ntransaction of 100 USD, 2 USD\nin fees. +PayerFSP ->> Switch: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=2 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=2 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeeATM: Total fee for Cash-Out of\n100 USD is 2 USD +PayeeATM ->> PayerOTC: Please enter you OTP\nto confirm Cash-Out of 100 USD,\nfee is 2 USD +PayeeATM <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeeATM: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n{transactionRequestID}\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n{transactionRequestID}\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP OK +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 102 USD from Payer\naccount, 101 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=101 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 101 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=101 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 101 USD from Switch\naccount, 100 USD to Payee,\n1 USD to fee account +PayeeFSP ->> PayeeATM: Dispense 100 USD in Cash +PayeeATM ->> PayerOTC: Here is your 100 USD in cash +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch <- Switch: Commit reserved transfer +Switch ->> PayerFSP: **PUT /transfers/** +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP <- PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transfer successful,\nyou should receive 100 USD\nin cash from ATM. You have\npaid 2 USD in fees. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure35.svg b/docs/technical/api/assets/diagrams/sequence/figure35.svg new file mode 100644 index 000000000..7ca43eff6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure35.svg @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (ATM) + + + + Payer + (OTC) + + + + + + + + + + + + + + + + + + Pre-generate OTP for me so that + I can use it for ATM Cash-Out + + + + + Generate OTP + + + + "12345 is your OTP" + + + + I would like to + Cash-Out 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Payer fee is 1 USD for + ATM Cash-Out + + + + PUT /quotes/ + <ID> + (transferAmount=101 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=101 USD, + payeeFspFee=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer fee is 1 USD in Payer FSP + for ATM Cash-Out, total fee 2 USD + + + + + OTP is pre-generated + + + + Use you pre-generated OTP to accept + transaction of 100 USD, 2 USD + in fees. + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=2 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=2 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total fee for Cash-Out of + 100 USD is 2 USD + + + + Please enter you OTP + to confirm Cash-Out of 100 USD, + fee is 2 USD + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP OK + + + + + Reserve 102 USD from Payer + account, 101 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=101 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 101 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=101 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 101 USD from Switch + account, 100 USD to Payee, + 1 USD to fee account + + + + Dispense 100 USD in Cash + + + + Here is your 100 USD in cash + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transfer successful, + you should receive 100 USD + in cash from ATM. You have + paid 2 USD in fees. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure37.plantuml b/docs/technical/api/assets/diagrams/sequence/figure37.plantuml new file mode 100644 index 000000000..04e62ac13 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure37.plantuml @@ -0,0 +1,196 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Merchant-Initiated Merchant Payment authorized on POS example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +PayeePOS <<- PayerOTC: I would like to buy goods\nor service for 100 USD +PayeeFSP <<- PayeePOS: I would like to receive\n100 USD from Payer +activate PayeeFSP +PayeeFSP ->> Switch: **POST /transactionRequests**\n(amount=100 USD) +activate Switch +PayeeFSP <<-- Switch: **HTTP 202** (Accepted) +activate PayerFSP +PayerFSP <<- Switch: **POST /transactionRequests**\n(amount=100 USD) +PayerFSP -->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP ->> Switch: **POST /quotes**\n(amount=100 USD,\namountType=RECEIVE) +activate PayerFSP +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amount=100 USD,\namountType=RECEIVE) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: FSP Commission is 1 USD\nin Payee FSP for\nMerchant Payment +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch ->> PayerFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer FSP uses the\nFSP commission as\na transaction fee +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Generate OTP, "12345" +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant of 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n{TransactionRequestID}\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter you OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeePOS: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/***\n{transactionRequestID}\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +PayerFSP <<- Switch: **PUT /authorizations/***\n{transactionRequestID}\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP OK +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve 100 USD from Payer\naccount, 99 USD to Switch\naccount, 1 USD to fee account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfers**\n(amount=99 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Transfer 99 USD from Switch\naccount, 1 USD from\ncommission account\nto Payee account +PayeeFSP ->> PayeePOS: You have received 100 USD\nfrom Payer. Please give goods\nor service to Payer. +PayeePOS ->> PayerOTC: Here is your goods or service +Switch <<- PayeeFSP: **PUT /transfers/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch <- Switch: Commit reserved transfer +Switch ->> PayerFSP: **PUT /transfers/** +Switch <<-- PayerFSP: **HTTP 200** (OK) +deactivate Switch +PayerFSP <- PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Payment successful, you\nhave paid 100 USD to Payee. +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure37.svg b/docs/technical/api/assets/diagrams/sequence/figure37.svg new file mode 100644 index 000000000..ffc7084e2 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure37.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + + + + + + + I would like to buy goods + or service for 100 USD + + + + I would like to receive + 100 USD from Payer + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + POST /quotes + (amount=100 USD, + amountType=RECEIVE) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amount=100 USD, + amountType=RECEIVE) + + + + HTTP 202 + (Accepted) + + + + + FSP Commission is 1 USD + in Payee FSP for + Merchant Payment + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer FSP uses the + FSP commission as + a transaction fee + + + + + Generate OTP, "12345" + + + + Use OTP "12345" to accept + transaction to Merchant of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + {TransactionRequestID} + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter you OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + * + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + * + {transactionRequestID} + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP OK + + + + + Reserve 100 USD from Payer + account, 99 USD to Switch + account, 1 USD to fee account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Transfer 99 USD from Switch + account, 1 USD from + commission account + to Payee account + + + + You have received 100 USD + from Payer. Please give goods + or service to Payer. + + + + Here is your goods or service + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + PUT /transfers/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Payment successful, you + have paid 100 USD to Payee. + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure39.plantuml b/docs/technical/api/assets/diagrams/sequence/figure39.plantuml new file mode 100644 index 000000000..187a75c8a --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure39.plantuml @@ -0,0 +1,162 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Refund example + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer(OTC/Agent) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like a Refund\nof my Agent Cash-in of 101 USD +activate PayerFSP +PayerFSP -> PayerFSP: Find original transaction, FSP\ncommission was 1 USD which\nmeans Payer FSP wants 1 USD\nin fee to reverse. +PayerFSP ->> Switch: **POST /quotes**\n(transactionScenario=REFUND\namountType=SEND,\namount=100 USD, fee=1 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202**\n(Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(transactionScenario=REFUND\namountType=SEND,\namount=100 USD, fee=1 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202**\n(Accepted) +PayeeFSP -> PayeeFSP:Find original transaction, 1 USD\nwas received in FSP commission, \ngive back in FSP commission.\nReverse Agent commission. +PayeeFSP ->> Payee:Customer wants a refund of Cash-in,\nyou will lose 1 USD in commission\nand 100 USD will be transfered to\nyour account, please pay customer\n101 USD in cash +PayeeFSP <<- Payee: OK +Switch <<- PayeeFSP: **PUT /quote/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quote/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Payer gets fee subsizidized by\nFSP commission. +Payer <<- PayerFSP: By refunding 100 USD to Agent, you\nshould receive 101 USD in cash +deactivate PayerFSP +Payer ->> PayerFSP: Perform transaction +activate PayerFSP +PayerFSP -> PayerFSP: Reverse original transaction by\nreversing 100 USD from Payer\nAccount, 99 USD to Switch account,\n1 USD to commission account +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from Payer FSP\naccount to Payee FSP account +Switch ->> PayeeFSP: **POST /transfer/** +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reverse original transaction by\ntransferring 100 USD to Payee\naccount, 99 USD from Switch\naccount, 1 USD from fee account,\nand 1 USD from fee account to\ninternal commission account +PayeeFSP -> Payee: You have received 100 USD\nfrom Payer in Cash-in refund,\nplease pay customer his 101 USD +Switch <<- PayeeFSP: **POST /transfer/** +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit reserved transfer +PayerFSP <<- Switch: **POST /transfer/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit reserved transfer +Payer <- PayerFSP: Transaction successful,\nyou have paid 1 USD in fee +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure39.svg b/docs/technical/api/assets/diagrams/sequence/figure39.svg new file mode 100644 index 000000000..c10af8f4f --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure39.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + +   + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like a Refund + of my Agent Cash-in of 101 USD + + + + + Find original transaction, FSP + commission was 1 USD which + means Payer FSP wants 1 USD + in fee to reverse. + + + + POST /quotes + (transactionScenario=REFUND + amountType=SEND, + amount=100 USD, fee=1 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (transactionScenario=REFUND + amountType=SEND, + amount=100 USD, fee=1 USD) + + + + HTTP 202 + (Accepted) + + + + + Find original transaction, 1 USD + was received in FSP commission, + give back in FSP commission. + Reverse Agent commission. + + + + Customer wants a refund of Cash-in, + you will lose 1 USD in commission + and 100 USD will be transfered to + your account, please pay customer + 101 USD in cash + + + + OK + + + + PUT /quote/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quote/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + Payer gets fee subsizidized by + FSP commission. + + + + By refunding 100 USD to Agent, you + should receive 101 USD in cash + + + + Perform transaction + + + + + Reverse original transaction by + reversing 100 USD from Payer + Account, 99 USD to Switch account, + 1 USD to commission account + + + + POST /transfers + (amount=99 USD) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from Payer FSP + account to Payee FSP account + + + + POST /transfer/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + Reverse original transaction by + transferring 100 USD to Payee + account, 99 USD from Switch + account, 1 USD from fee account, + and 1 USD from fee account to + internal commission account + + + You have received 100 USD + from Payer in Cash-in refund, + please pay customer his 101 USD + + + + POST /transfer/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + + POST /transfer/ + <ID> + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + + + Transaction successful, + you have paid 1 USD in fee + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure4.plantuml b/docs/technical/api/assets/diagrams/sequence/figure4.plantuml new file mode 100644 index 000000000..db01171d2 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure4.plantuml @@ -0,0 +1,64 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title HTTP PATCH call flow + +' Actor Keys: +' participant - Switch and FSP + +' declare actors +participant "Switch" as Switch +participant "FSP" as FSP + +' start flow +activate Switch +activate FSP +Switch ->> FSP: **POST /service/**//// +FSP -->> Switch: **HTTP 202** (Accepted) +FSP ->> FSP: Create object, state of \ncreated object is a \nnon-fiinalized state +FSP ->> Switch: **PUT /service/** \n(Non-finalized state) +Switch -->> FSP: **HTTP 200** (OK) +deactivate FSP +Switch ->> Switch: Handle callback, send\nnotificaction to FSP regarding\nthe object's finalized state +Switch ->> FSP: **PATCH /service/**\n(Finalized state) +activate FSP +FSP -->> Switch: **HTTP 202** (Accepted) +deactivate Switch +FSP ->> FSP: Update object's state\naccording to new\ninformation +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure4.svg b/docs/technical/api/assets/diagrams/sequence/figure4.svg new file mode 100644 index 000000000..4d6eb7612 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure4.svg @@ -0,0 +1,73 @@ + + + + + + + + + + Switch + + FSP + + + + + + + POST /service/ + <ID> + + + + HTTP 202 + (Accepted) + + + + + + Create object, state of + created object is a + non-fiinalized state + + + + PUT /service/ + <ID> + (Non-finalized state) + + + + HTTP 200 + (OK) + + + + + + Handle callback, send + notificaction to FSP regarding + the object's finalized state + + + + PATCH /service/ + <ID> + (Finalized state) + + + + HTTP 202 + (Accepted) + + + + + + Update object's state + according to new + information + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure41.plantuml b/docs/technical/api/assets/diagrams/sequence/figure41.plantuml new file mode 100644 index 000000000..ee5053cd8 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure41.plantuml @@ -0,0 +1,139 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the services provided by /participants if there is no common Account Lookup System + +' Actor Keys: +' participant - FSP(User's) and FSP +' actor - User + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "\nFSP 1" as fsp1 +participant "\nFSP 2" as fsp2 + +' start flow +user ->> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system,\nask FSP 1 +userfsp ->> fsp1: **GET /participants/MSISDN/123456789** +activate fsp1 +userfsp <<-- fsp1: **HTTP 202** (Accepted) +fsp1 -> fsp1: +123456789 is not\nwithin this system +userfsp <<- fsp1: **PUT /participants/MSISDN/123456789/error** +userfsp -->> fsp1: **HTTP 200** (OK) +deactivate fsp1 +userfsp -> userfsp: Not in FSP 1, ask FSP 2 +userfsp ->> fsp2: **GET /participants/MSISDN/123456789** +activate fsp2 +userfsp <<-- fsp2: **HTTP 202** (Accepted) +fsp2 -> fsp2: +123456789 is\nwithin this system +userfsp <<- fsp2: **PUT /participants/MSISDN/123456789/error** +userfsp -->> fsp2: **HTTP 200** (OK) +deactivate fsp2 +userfsp -> userfsp: +123456789 found\nin FSP 2 +userfsp -[hidden]>fsp2 +deactivate userfsp +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure41.svg b/docs/technical/api/assets/diagrams/sequence/figure41.svg new file mode 100644 index 000000000..cf028451c --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure41.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + User + + + + User's + FSP + +   + FSP 1 + +   + FSP 2 + + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system, + ask FSP 1 + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + +123456789 is not + within this system + + + + PUT /participants/MSISDN/123456789/error + + + + HTTP 200 + (OK) + + + + + Not in FSP 1, ask FSP 2 + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + +123456789 is + within this system + + + + PUT /participants/MSISDN/123456789/error + + + + HTTP 200 + (OK) + + + + + +123456789 found + in FSP 2 + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure42.plantuml b/docs/technical/api/assets/diagrams/sequence/figure42.plantuml new file mode 100644 index 000000000..05ba8f242 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure42.plantuml @@ -0,0 +1,128 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the services provided by /participants if there is no common Account Lookup System + +' Actor Keys: +' participant - FSP(User's) and Account Lookup Service +' actor - User + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "Account\nLookup" as ALS + +' start flow +user ->> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system +userfsp ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +userfsp <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to. +userfsp <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP ID) +userfsp -->> ALS: **HTTP 200** (OK) +deactivate ALS +deactivate userfsp +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure42.svg b/docs/technical/api/assets/diagrams/sequence/figure42.svg new file mode 100644 index 000000000..1f9cf748e --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure42.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + User + + + + User's + FSP + + Account + Lookup + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to. + + + + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure43.plantuml b/docs/technical/api/assets/diagrams/sequence/figure43.plantuml new file mode 100644 index 000000000..cc7a269f5 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure43.plantuml @@ -0,0 +1,144 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for /parties resource + +' Actor Keys: +' participant - FSP(User's), Switch, Account Lookup and FSP +' actor - Payee/Payer(User) + +' declare actors +actor "<$actor>\nUser" as user +participant "User's\nFSP" as userfsp +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "\nFSP 1" as fsp1 + +' start flow +user -> userfsp: I would like to pay or receive\nfunds to/from +123456789 +activate userfsp +userfsp -> userfsp: +123456789 is not\nwithin this system +userfsp ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +userfsp <<-- Switch: **HTTP 202** (Accepted) +Switch ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to. +Switch <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP 1) +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +Switch ->> fsp1: **GET /parties/MSISDN/123456789** +activate fsp1 +Switch <<-- fsp1: **HTTP 202** (Accepted) +fsp1 -> fsp1: Lookup party information\nfor +123456789 +Switch <<- fsp1: **PUT /parties/MSISDN/123456789**\n(Party information) +Switch -->> fsp1: **HTTP 200** (OK) +deactivate fsp1 +userfsp <<- Switch: **PUT /parties/MSISDN/123456789**\n(Party information) +userfsp -->> Switch: **HTTP 200** (OK) +deactivate Switch +user <- userfsp: Is "name" correct? +deactivate userfsp +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure43.svg b/docs/technical/api/assets/diagrams/sequence/figure43.svg new file mode 100644 index 000000000..0c6980acc --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure43.svg @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + User + + + + User's + FSP + + Optional + Switch + + Account + Lookup + +   + FSP 1 + + + + + + + I would like to pay or receive + funds to/from +123456789 + + + + + +123456789 is not + within this system + + + + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to. + + + + PUT /participants/MSISDN/123456789 + (FSP 1) + + + + HTTP 200 + (OK) + + + + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party information + for +123456789 + + + + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + Is "name" correct? + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure44.plantuml b/docs/technical/api/assets/diagrams/sequence/figure44.plantuml new file mode 100644 index 000000000..ed8d8bd0e --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure44.plantuml @@ -0,0 +1,137 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +payeefsp <- Payee: I would like to receive\nfunds from +123456789 +activate payeefsp +payeefsp <- payeefsp: Lookup +123456789\n(process not shown her) +Switch <<- payeefsp: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepted) +payerfsp <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepted) +payeefsp -> payeefsp: Perform optional validation +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Received status) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Received status) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Wait for either quote and\ntransfer, or rejected\ntransaction request by Payer +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure44.svg b/docs/technical/api/assets/diagrams/sequence/figure44.svg new file mode 100644 index 000000000..e073588f1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure44.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + I would like to receive + funds from +123456789 + + + + + Lookup +123456789 + (process not shown her) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + Wait for either quote and + transfer, or rejected + transaction request by Payer + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure45.plantuml b/docs/technical/api/assets/diagrams/sequence/figure45.plantuml new file mode 100644 index 000000000..bcaad8a0d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure45.plantuml @@ -0,0 +1,131 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process in which a transaction request is rejected + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +activate payerfsp +payerfsp -> payerfsp: Transaction request and\nquoting (process not shown) +payerfsp -> payerfsp: User rejection, OTP not correct,\nor automatic rejection +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Rejected state) +activate Switch +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Rejected state) +activate payeefsp +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> Payee: Transaction failed due\nto user rejection +deactivate payeefsp +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure45.svg b/docs/technical/api/assets/diagrams/sequence/figure45.svg new file mode 100644 index 000000000..5b94d8fd5 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure45.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + Transaction request and + quoting (process not shown) + + + + + User rejection, OTP not correct, + or automatic rejection + + + + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + Transaction failed due + to user rejection + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure47.plantuml b/docs/technical/api/assets/diagrams/sequence/figure47.plantuml new file mode 100644 index 000000000..86deaaefd --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure47.plantuml @@ -0,0 +1,150 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for resource /quotes + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(Transaction details) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the quote and Payer name + PayeeFSP <- Payee: I confirm +end +Switch <<- PayeeFSP: ** PUT /quotes/**\n(Payee FSP fee/commission, condition) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP fee/commission, condition) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +Payer <- PayerFSP: Present fees and optionally\npayee name +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure47.svg b/docs/technical/api/assets/diagrams/sequence/figure47.svg new file mode 100644 index 000000000..e18393d9b --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure47.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + Payee + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Rate Payer FSP quote + (depending on fee model) + + + + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + Here is the quote and Payer name + + + I confirm + + + + + PUT /quotes/** + <ID> + (Payee FSP fee/commission, condition) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + (Payee FSP fee/commission, condition) + + + + HTTP 200 + (OK) + + + + + Rate Payer FSP quote + (depending on fee model) + + + Present fees and optionally + payee name + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure49.plantuml b/docs/technical/api/assets/diagrams/sequence/figure49.plantuml new file mode 100644 index 000000000..553dfc514 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure49.plantuml @@ -0,0 +1,156 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example process for resource /authorizations + +' Actor Keys: +' participant - FSP(Payee) and Switch +' actor - Payee/Payer(POS/ATM) + +' declare actors +'actor "<$actor>\nPayer" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS/ATM)" as Payee + +' start flow +PayeeFSP <- Payee: I would like to receive\nfunds from +123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Lookup +123456789\n(process not shown here) +Switch <<- PayeeFSP: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate PayerFSP +PayerFSP ->> Switch: **HTTP 202** (Accepted) +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +PayerFSP <<- Switch: **HTTP 200** (OK) +deactivate PayerFSP +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +activate PayerFSP +PayerFSP -> PayerFSP: Do quote, generate OTP,\nnotify user (process\nnot shown here) +PayerFSP ->> Switch: **GET /authorizations/**\n\n(Amount including fees) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(Amount including fees) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> Payee: Show fees on POS +Payee -> Payee: Payer approves/rejects\ntransaction using OTP +PayeeFSP <<-- Payee: +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(OTP) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(OTP) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure49.svg b/docs/technical/api/assets/diagrams/sequence/figure49.svg new file mode 100644 index 000000000..3a5ae346a --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure49.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + +   + Payer + FSP + +   + Optional + Switch + +   + Payee + FSP + + Payee + (POS/ATM) + + + + + + + + + + + I would like to receive + funds from +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + Do quote, generate OTP, + notify user (process + not shown here) + + + + GET /authorizations/ + <TransactionRequestID> + (Amount including fees) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (Amount including fees) + + + + HTTP 202 + (Accepted) + + + Show fees on POS + + + + + Payer approves/rejects + transaction using OTP + + + + + + + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure5.plantuml b/docs/technical/api/assets/diagrams/sequence/figure5.plantuml new file mode 100644 index 000000000..0b48ee49c --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure5.plantuml @@ -0,0 +1,69 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Using the customized HTTP header fields FSPIOP-Destination and FSPIOP-Source + +' Actor Keys: +' participant - FSP, Peer FSP and Optional Switch + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **POST /service**\n(**FSPIOP-Source=**FSP,\n**FSPIOP-Destination=**Peer FSP) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Route message according\nto **FSPIOP-Destination** +Switch ->> PEERFSP: **POST /service**\n(**FSPIOP-Source=**FSP,\n**FSPIOP-Destination=**Peer FSP) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Optionally validate messages signature\nusing stored certificate for\nFSP in **FSPIOP-Source** +PEERFSP -> PEERFSP: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination**\nand visa versa for routing of callback +Switch <<- PEERFSP: **PUT /service/**////\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +Switch -->> PEERFSP: **HTTP 200** (OK) +Switch -> Switch: Route message according\nto **FSPIOP-Destination** +deactivate PEERFSP +FSP <<- Switch: **PUT /service/**////\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure5.svg b/docs/technical/api/assets/diagrams/sequence/figure5.svg new file mode 100644 index 000000000..54a0efff5 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure5.svg @@ -0,0 +1,112 @@ + + + + + + + + + + +   + FSP + + Optional + Switch + + Peer + FSP + + + + + + + POST /service + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Route message according + to + FSPIOP-Destination + + + + POST /service + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Optionally validate messages signature + using stored certificate for + FSP in + FSPIOP-Source + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and visa versa for routing of callback + + + + PUT /service/ + <ID> + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + + + + Route message according + to + FSPIOP-Destination + + + + PUT /service/ + <ID> + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure50.plantuml b/docs/technical/api/assets/diagrams/sequence/figure50.plantuml new file mode 100644 index 000000000..29daf6dff --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure50.plantuml @@ -0,0 +1,145 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer requests resend of authorization value (OTP) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(OTC/POS) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +activate PayerFSP +PayerFSP -> PayerFSP: Transaction request and\nquoting process (not shown) +PayerFSP -> PayerFSP: Generate OTP, "12345", Payer FSP\nsets maximum retries to 2 +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter your OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: OTP not received +PayeeFSP <<- PayeePOS: OTP not received +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(resend OTP) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(resend OTP) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Resend OTP (optionally\nregenerate) as customer\ndid not receive it +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP -> PayerFSP: Resend GET /authorizations\n(not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure50.svg b/docs/technical/api/assets/diagrams/sequence/figure50.svg new file mode 100644 index 000000000..70b657a1b --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure50.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + Transaction request and + quoting process (not shown) + + + + + Generate OTP, "12345", Payer FSP + sets maximum retries to 2 + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter your OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + OTP not received + + + + OTP not received + + + + PUT /authorizations/ + <TransactionRequestID> + (resend OTP) + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (resend OTP) + + + + HTTP 200 + (OK) + + + + + Resend OTP (optionally + regenerate) as customer + did not receive it + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + + Resend GET /authorizations + (not shown here) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure51.plantuml b/docs/technical/api/assets/diagrams/sequence/figure51.plantuml new file mode 100644 index 000000000..505e8f947 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure51.plantuml @@ -0,0 +1,160 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer enters incorrect authorization value (OTP) + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(OTC/POS) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nPayee\nFSP" as PayeeFSP +actor "<$actor>\nPayee\n(POS)" as PayeePOS +actor "<$actor>\nPayer\n(OTC)" as PayerOTC + +' start flow +activate PayerFSP +PayerFSP -> PayerFSP: Transaction request and\nquoting process (not shown) +PayerFSP -> PayerFSP: Generate OTP, "12345", Payer FSP\nsets maximum retries to 2 +Payer <<- PayerFSP: Use OTP "12345" to accept\ntransaction to Merchant\nof 100 USD,\n0 USD in fees. +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=2, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Total amount is 100 USD,\nfee is 0 USD +PayeePOS ->> PayerOTC: Please enter your OTP\nto confirm Merchant Payment\nof 100 USD, fee is 0 USD +PayeePOS <<- PayerOTC: Enters "12346" +PayeeFSP <<- PayeePOS: "12346" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(authenticationValue="12346") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(authenticationValue="12346") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP,\nOTP incorrect, decrease retriesLeft +PayerFSP ->> Switch: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=1, type=OTP) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /authorizations/**\n\n(amount=100 USD, fees=0 USD,\nretriesLeft=1, type=OTP) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP ->> PayeePOS: Incorrect OTP,\n1 retry left +PayeePOS ->> PayerOTC: Please enter your OTP to\nconfirm Merchant Payment of\n100 USD, fee is 0 USD, last retry +PayeePOS <<- PayerOTC: Enters "12345" +PayeeFSP <<- PayeePOS: "12345" is the OTP +Switch <<- PayeeFSP: **PUT /authorizations/**\n\n(otp="12345") +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /authorizations/**\n\n(otp="12345") +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Validates OTP sent by\nPayee FSP, OTP OK, perform\ntransfer (not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure51.svg b/docs/technical/api/assets/diagrams/sequence/figure51.svg new file mode 100644 index 000000000..7918e48dc --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure51.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   +   + Switch + +   + Payee + FSP + + Payee + (POS) + + + + Payer + (OTC) + + + + + + + + + + + + Transaction request and + quoting process (not shown) + + + + + Generate OTP, "12345", Payer FSP + sets maximum retries to 2 + + + + Use OTP "12345" to accept + transaction to Merchant + of 100 USD, + 0 USD in fees. + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=2, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Total amount is 100 USD, + fee is 0 USD + + + + Please enter your OTP + to confirm Merchant Payment + of 100 USD, fee is 0 USD + + + + Enters "12346" + + + + "12346" is the OTP + + + + PUT /authorizations/ + <TransactionRequestID> + (authenticationValue="12346") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (authenticationValue="12346") + + + + HTTP 200 + (OK) + + + + + Validate OTP sent by Payee FSP, + OTP incorrect, decrease retriesLeft + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=1, type=OTP) + + + + HTTP 202 + (Accepted) + + + + GET /authorizations/ + <TransactionRequestID> + (amount=100 USD, fees=0 USD, + retriesLeft=1, type=OTP) + + + + HTTP 202 + (Accepted) + + + + Incorrect OTP, + 1 retry left + + + + Please enter your OTP to + confirm Merchant Payment of + 100 USD, fee is 0 USD, last retry + + + + Enters "12345" + + + + "12345" is the OTP + + + + PUT /authorizations/ + <TransactionRequestID> + (otp="12345") + + + + HTTP 200 + (OK) + + + + PUT /authorizations/ + <TransactionRequestID> + (otp="12345") + + + + HTTP 200 + (OK) + + + + + Validates OTP sent by + Payee FSP, OTP OK, perform + transfer (not shown here) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure52.plantuml b/docs/technical/api/assets/diagrams/sequence/figure52.plantuml new file mode 100644 index 000000000..a162cad3d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure52.plantuml @@ -0,0 +1,155 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the POST /transfers service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, conditions, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, conditions, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Perform transfer from Switch\naccount to Payee account,\ngenerate fulfilment +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +PayeeFSP -> Payee: Transaction notification +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure52.svg b/docs/technical/api/assets/diagrams/sequence/figure52.svg new file mode 100644 index 000000000..f66d00cc6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure52.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote + (process not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, conditions, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, conditions, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer from Switch + account to Payee account, + generate fulfilment + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + Transaction notification + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from Payer + account to Payee FSP account + + + Transaction notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure53.plantuml b/docs/technical/api/assets/diagrams/sequence/figure53.plantuml new file mode 100644 index 000000000..4d9e48767 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure53.plantuml @@ -0,0 +1,156 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Optional additional clearing check + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Perform transfer from\nSwitch account to\nPayee account +PayeeFSP -> Payee: Transaction notification +Switch -> Switch: Expiry time reached,\ncancel reservation +PayerFSP <<- Switch: **PUT /transfers/**/**error** +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Mark transfer for\nReconciliation as Payee\nFSP has completed and\nPayer FSP has cancelled +deactivate PayeeFSP +PayerFSP -> PayerFSP: Cancel transfer from Payer\naccount to Switch +deactivate Switch +Payer <- PayerFSP: Transaction failure notification +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure53.svg b/docs/technical/api/assets/diagrams/sequence/figure53.svg new file mode 100644 index 000000000..8eea5e412 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure53.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer from + Switch account to + Payee account + + + Transaction notification + + + + + Expiry time reached, + cancel reservation + + + + PUT /transfers/ + <ID> + / + error + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + HTTP 200 + (OK) + + + + + Mark transfer for + Reconciliation as Payee + FSP has completed and + Payer FSP has cancelled + + + + + Cancel transfer from Payer + account to Switch + + + Transaction failure notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure54.plantuml b/docs/technical/api/assets/diagrams/sequence/figure54.plantuml new file mode 100644 index 000000000..608a813b0 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure54.plantuml @@ -0,0 +1,159 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Optional additional clearing check where commit in Switch failed + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reserve transfer from Switch\naccount to Payee account,\ngenerate fulfilment +PayeeFSP -> PayeeFSP: Request commit notification\nfrom Switch by sending transfer\nstate as reserved +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment,\ntransferState=RESERVED) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP,\nsend commit notification\nto Payee FSP +Switch ->> PayeeFSP: **PATCH /transfers/**\n(transferState=COMMITTED,\ncompletedTimestamp) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayeeFSP -> PayeeFSP: Commit reserved transfer\nfrom Switch to Payee +PayeeFSP -> Payee: Transaction notification +deactivate PayeeFSP +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure54.svg b/docs/technical/api/assets/diagrams/sequence/figure54.svg new file mode 100644 index 000000000..3a80063b6 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure54.svg @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from Switch + account to Payee account, + generate fulfilment + + + + + Request commit notification + from Switch by sending transfer + state as reserved + + + + PUT /transfers/ + <ID> + (Fulfilment, + transferState=RESERVED) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP, + send commit notification + to Payee FSP + + + + PATCH /transfers/ + <ID> + (transferState=COMMITTED, + completedTimestamp) + + + + HTTP 200 + (OK) + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit reserved transfer + from Switch to Payee + + + Transaction notification + + + + + Commit transfer from Payer + account to Payee FSP account + + + Transaction notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure55.plantuml b/docs/technical/api/assets/diagrams/sequence/figure55.plantuml new file mode 100644 index 000000000..b0b15412e --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure55.plantuml @@ -0,0 +1,158 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Commit notification where commit of transfer in Switch failed + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee/Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Switch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Quote (process\nnot shown here) +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=30 seconds) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details,\nexpiry=20 seconds) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Reserve transfer from Switch\naccount to Payee account,\ngenerate fulfilment +PayeeFSP -> PayeeFSP: Request commit notification\nfrom Switch by sending transfer\nstate as reserved +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment,\ntransferState=RESERVED) +Switch -->> PayeeFSP: **HTTP 200** (OK) +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP\nfailed, notify both FSPs +Switch ->> PayeeFSP: **PATCH /transfers/**\n(transferState=ABORTED,\ncompletedTimestamp) +Switch <<-- PayeeFSP: **HTTP 200** (OK) +PayeeFSP -> PayeeFSP: Rollback reserved transfer\nfrom Switch to Payee +PayerFSP <<- Switch: **PUT /transfers/**/**error** +deactivate PayeeFSP +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Rollback reserved transfer from\nPayer to Switch +Payer <- PayerFSP: Transaction notification +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure55.svg b/docs/technical/api/assets/diagrams/sequence/figure55.svg new file mode 100644 index 000000000..56263ad83 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure55.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Switch + + Payee + FSP + + Payee + + + + + + + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Quote (process + not shown here) + + + + + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=30 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details, + expiry=20 seconds) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from Switch + account to Payee account, + generate fulfilment + + + + + Request commit notification + from Switch by sending transfer + state as reserved + + + + PUT /transfers/ + <ID> + (Fulfilment, + transferState=RESERVED) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + Payer FSP to Payee FSP + failed, notify both FSPs + + + + PATCH /transfers/ + <ID> + (transferState=ABORTED, + completedTimestamp) + + + + HTTP 200 + (OK) + + + + + Rollback reserved transfer + from Switch to Payee + + + + PUT /transfers/ + <ID> + / + error + + + + HTTP 200 + (OK) + + + + + Rollback reserved transfer from + Payer to Switch + + + Transaction notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure57.plantuml b/docs/technical/api/assets/diagrams/sequence/figure57.plantuml new file mode 100644 index 000000000..615c2acec --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure57.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example transaction process + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP + +' start flow +Payer -> PayerFSP: I would like to pay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Lookup +123456789\n(process not shown here) +PayerFSP -> PayerFSP: Perform quote\n(process not shown here) +PayerFSP -> PayerFSP: Perform transfer\n(process not shown here) +PayerFSP ->> Switch: **GET /transactions/** +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **GET /transactions/** +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Lookup transaction\ninformation +Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction detail) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction detail) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +Payer <- PayerFSP: Transaction notification\nincluding transaction\ndata(e.g. token ID) +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure57.svg b/docs/technical/api/assets/diagrams/sequence/figure57.svg new file mode 100644 index 000000000..98acfada5 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure57.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + + + + + I would like to pay 100 USD + to +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + + Perform quote + (process not shown here) + + + + + Perform transfer + (process not shown here) + + + + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + Lookup transaction + information + + + + PUT /transactions/ + <TransactionID> + (Transaction detail) + + + + HTTP 200 + (OK) + + + + PUT /transactions/ + <TransactionID> + (Transaction detail) + + + + HTTP 200 + (OK) + + + Transaction notification + including transaction + data(e.g. token ID) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure59.plantuml b/docs/technical/api/assets/diagrams/sequence/figure59.plantuml new file mode 100644 index 000000000..f90967b30 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure59.plantuml @@ -0,0 +1,147 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example bulk quote process + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP + +' start flow +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +PayerFSP -> PayerFSP: Lookup in which FSP each\nPayee is located in, divide\nPayees into FSP separate files\n(process not shown here) +Loop #OldLace + hnote left of PayerFSP #OldLace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(process not shown here) + PayerFSP ->> Switch: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch ->> PayeeFSP: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + Switch <<- PayeeFSP: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + PayerFSP <<- Switch: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + PayerFSP -> PayerFSP: Rate payer FSP bulk quote\n(depending on fee model) +end Loop +PayerFSP -> PayerFSP: Handle quote results for\nall Payee FSPs +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure59.svg b/docs/technical/api/assets/diagrams/sequence/figure59.svg new file mode 100644 index 000000000..558bc47e8 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure59.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + + + + + I would like to upload + a file of bulk transactions + + + + + Lookup in which FSP each + Payee is located in, divide + Payees into FSP separate files + (process not shown here) + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (process not shown here) + + + + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + + Rate payer FSP bulk quote + (depending on fee model) + + + + + Handle quote results for + all Payee FSPs + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure6.plantuml b/docs/technical/api/assets/diagrams/sequence/figure6.plantuml new file mode 100644 index 000000000..7f28f23c9 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure6.plantuml @@ -0,0 +1,77 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Example scenario where FSPIOP-Destination is unknown by FSP + +' Actor Keys: +' participant - FSP, Peer FSP, Optional Switch and Account Lookup + +' declare actors +participant "\nFSP" as FSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Peer\nFSP" as PEERFSP + +' start flow +FSP ->> Switch: **GET /parties/msisdn/123456789**\n(**FSPIOP-Source=**FSP) +activate FSP +activate Switch +FSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> ALS: **GET /participants/msisdn/123456789**\n(**FSPIOP-Source=**Switch,\n**FSPIOP-Destination=**Account Lookup) +activate ALS +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination**\nand vice versa for\nrouting of callback +Switch <<- ALS: **PUT /participants/msisdn/123456789**\n(**FSPIOP-Source=**Account Lookup,\n**FSPIOP-Destination=**Switch) +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +Switch -> Switch: Set **FSPIOP-Destination**\nin original messages according\nto results of **PUT /participants** +Switch ->> PEERFSP: **GET /parties/msisdn/123456789**\n(**FSPIOP-Source=**FSP, **FSPIOP-Destination=**Peer FSP) +activate PEERFSP +Switch <<-- PEERFSP: **HTTP 202** (Accepted) +PEERFSP -> PEERFSP: Optionally validate message\nsignature using stored certificate\nfor FSP in **FSPIOP-Source** +PEERFSP -> PEERFSP: Replace **FSPIOP-Source**\nwith **FSPIOP-Destination** and\nvice versa for routing of callback +Switch <<- PEERFSP: **PUT /parties/msisdn/123456789**\n(**FSPIOP-Source=**Peer FSP, **FSPIOP-Destination=**FSP) +Switch -->> PEERFSP: **HTTP 200** (OK) +deactivate PEERFSP +Switch -> Switch: Route messages according\nto **FSPIOP-Destination** +FSP <<- Switch: **PUT /parties/msisdn/123456789**\n(**FSPIOP-Source=**Peer FSP,\n**FSPIOP-Destination=**FSP) +FSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate FSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure6.svg b/docs/technical/api/assets/diagrams/sequence/figure6.svg new file mode 100644 index 000000000..c61416d66 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure6.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + +   + FSP + + Optional + Switch + + Account + Lookup + + Peer + FSP + + + + + + + + GET /parties/msisdn/123456789 + ( + FSPIOP-Source= + FSP) + + + + HTTP 202 + (Accepted) + + + + GET /participants/msisdn/123456789 + ( + FSPIOP-Source= + Switch, + FSPIOP-Destination= + Account Lookup) + + + + HTTP 202 + (Accepted) + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and vice versa for + routing of callback + + + + PUT /participants/msisdn/123456789 + ( + FSPIOP-Source= + Account Lookup, + FSPIOP-Destination= + Switch) + + + + HTTP 200 + (OK) + + + + + Set + FSPIOP-Destination + in original messages according + to results of + PUT /participants + + + + GET /parties/msisdn/123456789 + ( + FSPIOP-Source= + FSP, + FSPIOP-Destination= + Peer FSP) + + + + HTTP 202 + (Accepted) + + + + + Optionally validate message + signature using stored certificate + for FSP in + FSPIOP-Source + + + + + Replace + FSPIOP-Source + with + FSPIOP-Destination + and + vice versa for routing of callback + + + + PUT /parties/msisdn/123456789 + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + + + + Route messages according + to + FSPIOP-Destination + + + + PUT /parties/msisdn/123456789 + ( + FSPIOP-Source= + Peer FSP, + FSPIOP-Destination= + FSP) + + + + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure61.plantuml b/docs/technical/api/assets/diagrams/sequence/figure61.plantuml new file mode 100644 index 000000000..5f0ab8b64 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure61.plantuml @@ -0,0 +1,153 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Example bulk transfer process + +' Actor Keys: +' participant - FSP(Payer/Payee(s)) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +PayerFSP -> PayerFSP: Lookup in which FSP each\nPayee is located in, divide\nPayees into FSP separate files\n(process not shown here) +PayerFSP -> PayerFSP: Perform bulk quoting per\nPayee FSP\n(process not shown here) +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +Payer -> PayerFSP: Execute my bulk +Loop #OldLace + hnote left of PayerFSP #OldLace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account + PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + PayeeFSP -> PayeeFSP: Perform each transfer from \nPayer FSP account to Payee \naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **PUT /bulkTransfers/**\n(List of fulfilments) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + PayerFSP <<- Switch: **PUT /bulkTransfers/**\n(List of fulfilments) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure61.svg b/docs/technical/api/assets/diagrams/sequence/figure61.svg new file mode 100644 index 000000000..31fb7c70d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure61.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + Payer +   + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + I would like to upload + a file of bulk transactions + + + + + Lookup in which FSP each + Payee is located in, divide + Payees into FSP separate files + (process not shown here) + + + + + Perform bulk quoting per + Payee FSP + (process not shown here) + + + Bulk has finished processing, + present fees + + + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Perform each transfer from + Payer FSP account to Payee + account, generate fulfilments + + + Transaction notification + for each Payee + + + + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer account + to Payee account + + + Your bulk has been executed + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure64.plantuml b/docs/technical/api/assets/diagrams/sequence/figure64.plantuml new file mode 100644 index 000000000..589e9e159 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure64.plantuml @@ -0,0 +1,258 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer Initiated Transaction pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to\npay 100 USD\nto +123456789 +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Payee not within\nPayer FSP system +autonumber resume +PayerFSP ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> ALS: **GET /participants/MSISDN/123456789** +activate ALS +autonumber stop +Switch <<-- ALS: **HTTP 202** (Accepted) +ALS -> ALS: Lookup which\nFSP MSISDN\n+123456789\nbelongs to +autonumber resume +Switch <<- ALS: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +Switch -->> ALS: **HTTP 200** (OK) +deactivate ALS +autonumber resume +Switch ->> PayeeFSP: **GET /parties/MSISDN/123456789** +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Lookup party\ninformation\nRegarding\nMSISDN\n+123456789 +autonumber resume +Switch <<- PayeeFSP: **Put /parties/MSISDN/123456789**\n(Party information) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /parties/MSISDN/123456789**\n(Party information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate PayerFSP +autonumber resume +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /quote**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +Payer <- PayerFSP: Present fees and\noptionally payee name +deactivate PayerFSP +autonumber resume +Payer -> PayerFSP: I approve the\ntransaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +autonumber resume +PayerFSP -> Switch: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +autonumber stop +activate Switch +PayerFSP <-- Switch: **HTTL 202** (Accepted) +autonumber resume +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber stop +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch\naccount to Payee\naccount, generate\nfulfilment +autonumber stop +PayeeFSP -> Payee: Transaction notification +autonumber resume +Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +autonumber stop +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Switch account +group #OldLace Optional + hnote left of PayerFSP #OldLace + Get transaction data + end hnote + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch <<- PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch -->> PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch +end +autonumber resume +Payer <- PayerFSP: Transaction notification\nincluding optional\ntransaction data\n(e.g. token ID) +deactivate PayerFSP +autonumber stop +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure64.svg b/docs/technical/api/assets/diagrams/sequence/figure64.svg new file mode 100644 index 000000000..a5fe0d64d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure64.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + [1] + I would like to + pay 100 USD + to +123456789 + + + + + Payee not within + Payer FSP system + + + + [2] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + [3] + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which + FSP MSISDN + +123456789 + belongs to + + + + [4] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [5] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party + information + Regarding + MSISDN + +123456789 + + + + [6] + Put /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + [7] + PUT /parties/MSISDN/123456789 + (Party information) + + + + HTTP 200 + (OK) + + + + + [9] + Rate Payer FSP quote + (depending on fee model) + + + + [10] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [11] + POST /quote + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + [12] + Rate Payee FSP + fee/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + [15] + PUT /quotes/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + + [16] + Rate Payer FSP quote + (depending on fee model) + + + Present fees and + optionally payee name + + + [17] + I approve the + transaction + + + + + Reserve transfer from Payer + account to Switch account + + + [18] + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + HTTL 202 + (Accepted) + + + + + [19] + Reserve transfer from + Payer FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [20] + Perform transfer + from Switch + account to Payee + account, generate + fulfilment + + + Transaction notification + + + + [21] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [22] + Commit transfer from + Payer FSP to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [23] + Commit transfer from Payer + account to Switch account + + + Optional + + Get transaction data + + + + [24] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + [25] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + [26] + Lookup + transaction + information + + + + [27] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + [28] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + [29] + Transaction notification + including optional + transaction data + (e.g. token ID) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure64a.plantuml b/docs/technical/api/assets/diagrams/sequence/figure64a.plantuml new file mode 100644 index 000000000..673e1daca --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure64a.plantuml @@ -0,0 +1,212 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payer-Initiated Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to\npay 100 USD\nto +123456789 +activate PayerFSP +PayerFSP -> PayerFSP: Payee not within\nPayer FSP system +autonumber stop +PayerFSP ->> Switch: **Lookup Party Information**\n(MSISDN 123456789) +activate Switch +autonumber resume +Switch ->> ALS: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +ALS -> ALS: Lookup which\nFSP MSISDN\n+123456789\nbelongs to +autonumber stop +Switch <<- ALS: **Return Participant Information**\n(FSP ID) +deactivate ALS +autonumber resume +Switch ->> PayeeFSP: **Lookup Party Information**\n(MSISDN 123456789) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Lookup party\ninformation\nregarding\nMSISDN\n+123456789 +autonumber stop +Switch <<- PayeeFSP: **Return Party Information**\n(Party Information) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **Return Party Information**\n(Party Information) +deactivate Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction details) +activate Switch +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +Payer <- PayerFSP: Present fees and\noptionally payee name +deactivate PayerFSP +autonumber resume +Payer -> PayerFSP: I approve the\ntransaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +autonumber resume +PayerFSP -> Switch: **Preform Transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate Switch +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber stop +Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) +activate PayeeFSP +autonumber resume +PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch\naccount to Payee\naccount, generate\nfulfilment +PayeeFSP -> Payee: Transaction notification +autonumber stop +Switch <<- PayeeFSP: **Return Transfer Information**\n(Fulfilment) +deactivate PayeeFSP +autonumber resume +Switch -> Switch: Commit transfer from\nPayer FSP to Payee FSP +autonumber stop +PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Switch account +group #OldLace Optional + hnote left of PayerFSP #OldLace + Get transaction data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch <<- PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction details) + deactivate PayeeFSP + PayerFSP <<- Switch: **Return Transaction Information**\n(Transaction details) + deactivate Switch +end +Payer <- PayerFSP: Transaction notification\nincluding optional\ntransaction data\n(e.g. token ID) +deactivate PayerFSP +autonumber stop +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure64a.svg b/docs/technical/api/assets/diagrams/sequence/figure64a.svg new file mode 100644 index 000000000..44df91386 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure64a.svg @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + [1] + I would like to + pay 100 USD + to +123456789 + + + + + [2] + Payee not within + Payer FSP system + + + + Lookup Party Information + (MSISDN 123456789) + + + + [3] + Lookup Participant Information + (MSISDN 123456789) + + + + + [4] + Lookup which + FSP MSISDN + +123456789 + belongs to + + + + Return Participant Information + (FSP ID) + + + + [5] + Lookup Party Information + (MSISDN 123456789) + + + + + [6] + Lookup party + information + regarding + MSISDN + +123456789 + + + + Return Party Information + (Party Information) + + + + [7] + Return Party Information + (Party Information) + + + + + [9] + Rate Payer FSP quote + (depending on fee model) + + + + [10] + Calculate Quote + (Transaction details) + + + + [11] + Calculate Quote + (Transaction details) + + + + + [12] + Rate Payee FSP + fee/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + [15] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + + [16] + Rate Payer FSP quote + (depending on fee model) + + + Present fees and + optionally payee name + + + [17] + I approve the + transaction + + + + + Reserve transfer from Payer + account to Switch account + + + [18] + Preform Transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [19] + Reserve transfer from + Payer FSP to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [20] + Perform transfer + from Switch + account to Payee + account, generate + fulfilment + + + [21] + Transaction notification + + + + Return Transfer Information + (Fulfilment) + + + + + [22] + Commit transfer from + Payer FSP to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + [23] + Commit transfer from Payer + account to Switch account + + + Optional + + Get transaction data + + + + [24] + Retrieve Transaction Information + (Transaction ID) + + + + [25] + Retrieve Transaction Information + (Transaction ID) + + + + + [26] + Lookup + transaction + information + + + + [27] + Return Transaction Information + (Transaction details) + + + + [28] + Return Transaction Information + (Transaction details) + + + [29] + Transaction notification + including optional + transaction data + (e.g. token ID) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure65.plantuml b/docs/technical/api/assets/diagrams/sequence/figure65.plantuml new file mode 100644 index 000000000..369c7624a --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure65.plantuml @@ -0,0 +1,283 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee Initiated Transaction pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Payer not\nwithin Payee\nFSP system +autonumber stop +ALS <<- PayeeFSP: **GET /participants/MSISDN/123456789** +activate ALS +ALS -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS ->> PayeeFSP: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +ALS <<-- PayeeFSP: **HTTP 200** (OK) +deactivate ALS +deactivate PayeeFSP +autonumber resume +Switch <<- PayeeFSP: **Post /transactionRequests**\n(Payee information, transaction details) +activate PayeeFSP +activate Switch +autonumber stop +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details) +activate PayerFSP +autonumber stop +PayerFSP -->> Switch: **HTTP 202** (Accepted) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Received status) +autonumber stop +activate Switch +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Received status) +autonumber stop +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +deactivate Switch +autonumber resume +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /quotes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /quotes**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + autonumber resume + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quotes/**\n(Payee FSP fee/commission,condition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(Payee FSP\nfee/commission,condition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on the fee model) +Payer <- PayerFSP: Will you approve the\ntransaction request\nfor 100 USD\n(plus fees)\nto Payee? +deactivate PayerFSP +Alt #OldLace Alternatives + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + autonumber resume + Payer -> PayerFSP: I reject the\ntransaction request + activate PayerFSP + PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Rejected state) + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate PayerFSP + autonumber resume + Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Rejected state) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayeeFSP -> Payee: Transaction failed\ndue to user\nrejection + deactivate PayeeFSP + autonumber stop +else + hnote over of Payer #OldLace + User approves + transaction request + end hnote + Payer -> PayerFSP: I approve the\ntransaction request + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer\nFSP to Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account + group #LightGrey Optional + hnote over PayerFSP #LightGrey + Get transaction data + end hnote + autonumber resume + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch ->> PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Looksup transaction\ninformation + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + end + autonumber resume + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure65.svg b/docs/technical/api/assets/diagrams/sequence/figure65.svg new file mode 100644 index 000000000..e606726df --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure65.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + [1] + I would like + to receive + 100 USD from + +123456789 + + + + + [2] + Payer not + within Payee + FSP system + + + + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + [3] + Lookup which FSP MSISDN + +123456789 belongs to + + + + [4] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [5] + Post /transactionRequests + (Payee information, transaction details) + + + + HTTP 202 + (Accepted) + + + + [6] + POST /transactionRequests + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + [7] + Perform optional validation + + + + [8] + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + [9] + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + [10] + Rate Payer FSP quote + (depending on fee model) + + + + [11] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [12] + POST /quotes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + PUT /quotes/ + <ID> + (Payee FSP fee/commission,condition) + + + + HTTP 200 + (OK) + + + + [15] + PUT /quotes/ + <ID> + (Payee FSP + fee/commission,condition) + + + + HTTP 200 + (OK) + + + + + [16] + Rate Payer FSP quote + (depending on the fee model) + + + [17] + Will you approve the + transaction request + for 100 USD + (plus fees) + to Payee? + + + alt + [Alternatives] + + User rejects + transaction request + + + [18] + I reject the + transaction request + + + + [19] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + [20] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + [21] + Transaction failed + due to user + rejection + + + User approves + transaction request + + + I approve the + transaction request + + + + + [22] + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [23] + Reserve transfer + from Payer + FSP to Payee FSP + + + + POST /transfers + (Transfer ID, condition, ILP packet + including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + [24] + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + [25] + Transaction + notification + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [26] + Commit transfer + from Payer FSP + to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + [27] + Commit transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction data + + + + [28] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + [29] + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + [30] + Looksup transaction + information + + + + [31] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + [32] + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + [33] + Transaction + notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure65a.plantuml b/docs/technical/api/assets/diagrams/sequence/figure65a.plantuml new file mode 100644 index 000000000..86398225a --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure65a.plantuml @@ -0,0 +1,234 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee Initiated Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +PayeeFSP <- PayeeFSP: Payer not\nwithin Payee\nFSP system +autonumber stop +ALS <<- PayeeFSP: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +autonumber resume +ALS -> ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS ->> PayeeFSP: **Returns Participant Information**\n(FSP ID) +deactivate ALS +deactivate PayeeFSP +Switch <<- PayeeFSP: **Perform Transaction Request**\n(Payee information, transaction details) +activate PayeeFSP +activate Switch +PayerFSP <<- Switch: **Perform Transaction Request**\n(Payee information,\ntransaction details) +deactivate Switch +activate PayerFSP +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Received status) +activate Switch +deactivate PayerFSP +Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Received status) +deactivate PayeeFSP +deactivate Switch +activate PayerFSP +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction detail) +activate Switch +autonumber resume +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +group #OldLace Optional + hnote left of PayeeFSP #OldLace + Confirm quote + end hnote + PayeeFSP -> Payee: Here is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commission,condition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP\nfee/commission,condition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on the fee model) +Payer <- PayerFSP: Will you approve\ntransaction\nrequest for\n100 USD(plusfees)\nto Payee? +deactivate PayerFSP +Alt #OldLace Alternatives + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + Payer -> PayerFSP: I reject the\ntransaction request + activate PayerFSP + PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Rejected state) + deactivate PayerFSP + activate Switch + Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Rejected state) + deactivate Switch + activate PayeeFSP + PayeeFSP -> Payee: Transaction failed\ndue to user\nrejection + deactivate PayeeFSP + autonumber stop +else + hnote over of Payer #OldLace + User rejects + transaction request + end hnote + Payer -> PayerFSP: I approve the\ntransaction request + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer\nFSP to Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate PayeeFSP + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **Retrun Transfer Information**\n(Fulfilment) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit transfer from Payer\naccount to Payee FSP account + group #LightGrey Optional + hnote over PayerFSP #LightGrey + Get transaction data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch ->> PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Looksup transaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction detail) + deactivate PayeeFSP + PayerFSP <<- Switch: **Return Transaction Information**\n(Transaction detail) + deactivate Switch + end + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +autonumber stop +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure65a.svg b/docs/technical/api/assets/diagrams/sequence/figure65a.svg new file mode 100644 index 000000000..cb9409cac --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure65a.svg @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + [1] + I would like + to receive + 100 USD from + +123456789 + + + + + [2] + Payer not + within Payee + FSP system + + + + Lookup Participant Information + (MSISDN 123456789) + + + + + [3] + Lookup which FSP MSISDN + +123456789 belongs to + + + + [4] + Returns Participant Information + (FSP ID) + + + + [5] + Perform Transaction Request + (Payee information, transaction details) + + + + [6] + Perform Transaction Request + (Payee information, + transaction details) + + + + + [7] + Perform optional validation + + + + [8] + Return Transaction + Request Information + (Received status) + + + + [9] + Return Transaction Request Information + (Received status) + + + + + [10] + Rate Payer FSP quote + (depending on fee model) + + + + Calculate Quote + (Transaction detail) + + + + [11] + Calculate Quote + (Transaction details) + + + + + [12] + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm quote + + + [13] + Here is the + quote and + Payer name + + + I confirm + + + + [14] + Return Quote Information + (Payee FSP fee/commission,condition) + + + + [15] + Return Quote Information + (Payee FSP + fee/commission,condition) + + + + + [16] + Rate Payer FSP quote + (depending on the fee model) + + + [17] + Will you approve + transaction + request for + 100 USD(plusfees) + to Payee? + + + alt + [Alternatives] + + User rejects + transaction request + + + [18] + I reject the + transaction request + + + + [19] + Return Transaction + Request Information + (Rejected state) + + + + [20] + Return Transaction Request Information + (Rejected state) + + + [21] + Transaction failed + due to user + rejection + + + User rejects + transaction request + + + I approve the + transaction request + + + + + [22] + Reserve transfer from Payer + account to Switch account + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [23] + Reserve transfer + from Payer + FSP to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + [24] + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + [25] + Transaction + notification + + + + Retrun Transfer Information + (Fulfilment) + + + + + [26] + Commit transfer + from Payer FSP + to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + [27] + Commit transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction data + + + + [28] + Retrieve Transaction Information + (Transaction ID) + + + + [29] + Retrieve Transaction Information + (Transaction ID) + + + + + [30] + Looksup transaction + information + + + + [31] + Return Transaction Information + (Transaction detail) + + + + [32] + Return Transaction Information + (Transaction detail) + + + [33] + Transaction + notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure66.plantuml b/docs/technical/api/assets/diagrams/sequence/figure66.plantuml new file mode 100644 index 000000000..179a4e1b1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure66.plantuml @@ -0,0 +1,346 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' Payee Initiated Transaction using OTP pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Group #Oldlace Option #1 + hnote left of Payer #Oldlace + User + initiated + OTP + end hnote + Payer -> PayerFSP: Generate\nOTP for me + activate PayerFSP + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Your OTP\nis 12345 + deactivate PayerFSP +end +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +autonumber stop +PayeeFSP <- PayeeFSP: MSISDN not within\nPayee FSP system +autonumber resume +ALS <<- PayeeFSP: **GET /participants/MSISDN/123456789** +activate ALS +autonumber stop +ALS -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +ALS <- ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS -> PayeeFSP: **PUT /participants/MSISDN/123456789**\n(FSP ID) +autonumber stop +ALS <<-- PayeeFSP: **HTTP 200** (OK) +deactivate ALS +deactivate PayeeFSP +autonumber resume +Switch <<- PayeeFSP: **POST /transactionRequests**\n(Payee information, transaction details, OTP authorization) +activate PayeeFSP +activate Switch +autonumber stop +Switch -->> PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayerFSP <<- Switch: **POST /transactionRequests**\n(Payee information,\ntransaction details, OTP authorization) +activate PayerFSP +autonumber stop +PayerFSP -->> Switch: **HTTP 202** (Accepted) +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Put /transactionRequests/**\n(Received status) +autonumber stop +PayerFSP <<-- Switch: **HTTP 200** (OK) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **Put /transactionRequests/**\n(Received status) +autonumber stop +Switch <<-- PayeeFSP: **HTTP 200** (OK) +deactivate Switch +deactivate PayeeFSP +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +PayerFSP ->> Switch: **POST /qoutes**\n(Transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202**\n(Accepted) +autonumber resume +Switch ->> PayeeFSP: **POST /qoutes**\n(Transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202**\n(Accepted) +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #Oldlace Optional + hnote left of PayeeFSP #Oldlace + Confirm + quote + end hnote + autonumber resume + PayeeFSP -> Payee: Her is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /quote/**\n(Payee FSP fee/commission,\ncondition) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Option #2 + hnote left of Payer #Oldlace + Automatic + generated + OTP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Use OTP\nto confirm +end +PayerFSP ->> Switch: **GET /authorizations/**\n(Amount and fees) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> PayeeFSP: **GET /authorizations/**\n(Amount and fees) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +autonumber resume +PayeeFSP -> Payee: Show fees\non POS +Payee -> Payee: Payer\napproves/rejects\ntransaction\nusing OTP +autonumber stop +PayeeFSP <<-- Payee: Entered OTP +autonumber resume +Switch <<- PayeeFSP: **PUT /authorizations/**\n(OTP) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +autonumber resume +PayerFSP <<- Switch: **PUT /authorizations/**\n(OTP) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Alternatives + hnote left of Payer #Oldlace + OTP + validation + failed + end hnote + autonumber resume + PayerFSP ->> Switch: **PUT /transactionRequests/**\n(Rejected state) + activate PayerFSP + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate PayerFSP + autonumber resume + Switch ->> PayeeFSP: **PUT /transactionRequests/**\n(Rejected state) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayeeFSP -> Payee: Transaction\nfailed due to\nincorrect OTP + deactivate PayeeFSP + autonumber stop +else + hnote left of Payer #Oldlace + OTP + validation + successful + end hnote + PayerFSP -[hidden]> Switch + autonumber 33 1 + activate PayerFSP + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition,\nILP packet including transaction ID) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, \nILP packet including transaction ID) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **PUT /transfers/**\n(Fulfilment) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commits transfer from Payer\naccount to Payee FSP account + autonumber stop + PayerFSP -[hidden]> Switch + Group #Lightgrey Optional + hnote left of PayerFSP #Lightgrey + Get transaction + data + end hnote + autonumber resume + PayerFSP ->> Switch: **GET /transactions/** + activate Switch + autonumber stop + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch ->> PayeeFSP: **GET /transactions/** + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + autonumber resume + Switch <<- PayeeFSP: **PUT /transactions/**\n(Transaction details) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP ->> Switch: **PUT /transactions/**\n(Transaction details) + autonumber stop + PayerFSP <<-- Switch: **HTTP 200** (OK) + deactivate Switch + end + autonumber resume + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure66.svg b/docs/technical/api/assets/diagrams/sequence/figure66.svg new file mode 100644 index 000000000..10475e8cf --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure66.svg @@ -0,0 +1,568 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + + + + Option #1 + + User + initiated + OTP + + + [1] + Generate + OTP for me + + + + + [2] + Generate OTP + + + [3] + Your OTP + is 12345 + + + [4] + I would like + to receive + 100 USD from + +123456789 + + + + + MSISDN not within + Payee FSP system + + + + [5] + GET /participants/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + [6] + Lookup which FSP MSISDN + +123456789 belongs to + + + [7] + PUT /participants/MSISDN/123456789 + (FSP ID) + + + + HTTP 200 + (OK) + + + + [8] + POST /transactionRequests + (Payee information, transaction details, OTP authorization) + + + + HTTP 202 + (Accepted) + + + + [9] + POST /transactionRequests + (Payee information, + transaction details, OTP authorization) + + + + HTTP 202 + (Accepted) + + + + + [10] + Perform optional validation + + + + [11] + Put /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + [12] + Put /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + [13] + Rate Payer FSP quote + (depending on fee model) + + + + [14] + POST /qoutes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + [15] + POST /qoutes + (Transaction details) + + + + HTTP 202 + (Accepted) + + + + + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm + quote + + + [16] + Her is the + quote and + Payer name + + + I confirm + + + + [17] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + [18] + PUT /quote/ + <ID> + (Payee FSP fee/commission, + condition) + + + + HTTP 200 + (OK) + + + + + [19] + Rate Payer FSP quote + (depending on fee model) + + + Option #2 + + Automatic + generated + OTP + + + + + [20] + Generate OTP + + + [21] + Use OTP + to confirm + + + + [22] + GET /authorizations/ + <TransactionRequestID> + (Amount and fees) + + + + HTTP 202 + (Accepted) + + + + [23] + GET /authorizations/ + <TransactionRequestID> + (Amount and fees) + + + + HTTP 202 + (Accepted) + + + [24] + Show fees + on POS + + + + + [25] + Payer + approves/rejects + transaction + using OTP + + + + Entered OTP + + + + [26] + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + [27] + PUT /authorizations/ + <TransactionRequestID> + (OTP) + + + + HTTP 200 + (OK) + + + + + [28] + Validate OTP sent by Payee FSP + + + Alternatives + + OTP + validation + failed + + + + [29] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + + [30] + PUT /transactionRequests/ + <ID> + (Rejected state) + + + + HTTP 200 + (OK) + + + [31] + Transaction + failed due to + incorrect OTP + + + OTP + validation + successful + + + + + 33 + Reserve transfer from Payer + account to Switch account + + + + POST /transfers + (Transfer ID, condition, + ILP packet including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + 34 + Reserve transfer + from Payer FSP + to Payee FSP + + + + POST /transfers + (Transfer ID, condition, + ILP packet including transaction ID) + + + + HTTP 202 + (Accepted) + + + + + 35 + Lookup + transaction + information + + + 36 + Transaction + notification + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + 37 + Commit transfer + from Payer FSP + to Payee FSP + + + + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + 38 + Commits transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction + data + + + + 39 + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + 40 + GET /transactions/ + <TransactionID> + + + + HTTP 202 + (Accepted) + + + + + 41 + Lookup + transaction + information + + + + 42 + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + + 43 + PUT /transactions/ + <TransactionID> + (Transaction details) + + + + HTTP 200 + (OK) + + + 44 + Transaction + notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure66a.plantuml b/docs/technical/api/assets/diagrams/sequence/figure66a.plantuml new file mode 100644 index 000000000..8e944f64d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure66a.plantuml @@ -0,0 +1,288 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Payee-Initiated Transaction using OTP + +' Actor Keys: +' participant - FSP(Payer/Payee), Switch and Account Lookup +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Account\nLookup" as ALS +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +autonumber 1 1 "[0]" +Group #Oldlace Option #1 + hnote left of Payer #Oldlace + User + initiated + OTP + end hnote + Payer -> PayerFSP: Generate\nOTP for me + activate PayerFSP + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Your OTP\nis 12345 + deactivate PayerFSP +end +PayeeFSP <- Payee: I would like\nto receive\n100 USD from\n+123456789 +activate PayeeFSP +autonumber stop +PayeeFSP <- PayeeFSP: MSISDN not within\nPayee FSP system +autonumber resume +ALS <<- PayeeFSP: **Lookup Participant Information**\n(MSISDN 123456789) +activate ALS +ALS <- ALS: Lookup which FSP MSISDN\n+123456789 belongs to +ALS -> PayeeFSP: **Return Participant Information**\n(FSP ID) +deactivate ALS +deactivate PayeeFSP +Switch <<- PayeeFSP: **Perform Transaction Request**\n(Payee information, transaction details, OTP authorization) +activate PayeeFSP +activate Switch +PayerFSP <<- Switch: **Perform Transaction Request**\n(Payee information,\ntransaction details, OTP authorization) +activate PayerFSP +autonumber stop +autonumber resume +PayerFSP -> PayerFSP: Perform optional validation +PayerFSP ->> Switch: **Return Transaction**\n**Request Information**\n(Received status) +deactivate PayerFSP +autonumber resume +Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Received status) +deactivate Switch +deactivate PayeeFSP +autonumber stop +PayerFSP -[hidden]> Switch +activate PayerFSP +autonumber resume +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP ->> Switch: **Calculate Quote**\n(Transaction details) +activate Switch +autonumber resume +Switch ->> PayeeFSP: **Calculate Quote**\n(Transaction details) +activate PayeeFSP +PayeeFSP -> PayeeFSP: Rate Payee FSP\nfees/commission,\ngenerate condition +Group #Oldlace Optional + hnote left of PayeeFSP #Oldlace + Confirm + quote + end hnote + autonumber resume + PayeeFSP -> Payee: Her is the\nquote and\nPayer name + autonumber stop + PayeeFSP <- Payee: I confirm +end +autonumber resume +Switch <<- PayeeFSP: **Return Quote Information**\n(Payee FSP fee/commision, condition) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Quote Information**\n(Payee FSP fee/commission,\ncondition) +deactivate Switch +PayerFSP -> PayerFSP: Rate Payer FSP quote\n(depending on fee model) +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Option #2 + hnote left of Payer #Oldlace + Automatic + generated + OTP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP -> PayerFSP: Generate OTP + Payer <- PayerFSP: Use OTP\nto confirm +end +PayerFSP ->> Switch: **Perform Authorization**\n(Amount and fees) +activate Switch +Switch ->> PayeeFSP: **Perform Authorization**\n(Amount and fees) +activate PayeeFSP +PayeeFSP -> Payee: Show fees\non POS +Payee -> Payee: Payer\napproves/rejects\ntransaction\nusing OTP +autonumber stop +PayeeFSP <<-- Payee: Entered OTP +autonumber resume +Switch <<- PayeeFSP: **Return Authorization Result**\n(OTP) +deactivate PayeeFSP +PayerFSP <<- Switch: **Return Authorization Result**\n(OTP) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +autonumber resume +PayerFSP -> PayerFSP: Validate OTP sent by Payee FSP +autonumber stop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +Group #Oldlace Alternatives + hnote left of Payer #Oldlace + OTP + validation + failed + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + autonumber resume + PayerFSP ->> Switch: **Return Transaction Request Information**\n(Rejected state) + activate Switch + deactivate PayerFSP + Switch ->> PayeeFSP: **Return Transaction Request Information**\n(Rejected state) + activate PayeeFSP + deactivate Switch + PayeeFSP -> Payee: Transaction\nfailed due to\nincorrect OTP + deactivate PayeeFSP + autonumber stop +else + hnote left of Payer #Oldlace + OTP + validation + successful + end hnote + PayerFSP -[hidden]> Switch + autonumber 33 1 + activate PayerFSP + PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account + autonumber stop + PayerFSP ->> Switch: **Perform Transfer**\n(Transfer ID, condition, ILP packet\nincluding transaction ID) + activate Switch + autonumber resume + Switch -> Switch: Reserve transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Transfer**\n(Transfer ID, condition, \nILP packet including transaction ID)\n + activate PayeeFSP + autonumber resume + PayeeFSP -> PayeeFSP: Perform transfer\nfrom Switch account\nto Payee account,\ngenerate fulfilment + PayeeFSP -> Payee: Transaction\nnotification + autonumber stop + Switch <<- PayeeFSP: **Return Transfer Information**\n(Fulfilment) + deactivate PayeeFSP + autonumber resume + Switch -> Switch: Commit transfer\nfrom Payer FSP\nto Payee FSP + autonumber stop + PayerFSP <<- Switch: **Return Transfer Information**\n(Fulfilment) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commits transfer from Payer\naccount to Payee FSP account + Group #Lightgrey Optional + hnote left of PayerFSP #Lightgrey + Get transaction + data + end hnote + PayerFSP ->> Switch: **Retrieve Transaction Information**\n(Transaction ID) + activate Switch + Switch ->> PayeeFSP: **Retrieve Transaction Information**\n(Transaction ID) + activate PayeeFSP + PayeeFSP -> PayeeFSP: Lookup\ntransaction\ninformation + Switch <<- PayeeFSP: **Return Transaction Information**\n(Transaction details) + deactivate PayeeFSP + PayerFSP ->> Switch: Return Transaction Information**\n(Transaction details) + deactivate Switch + end + Payer <- PayerFSP: Transaction\nnotification + deactivate PayerFSP +end +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure66a.svg b/docs/technical/api/assets/diagrams/sequence/figure66a.svg new file mode 100644 index 000000000..25303cb58 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure66a.svg @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Account + Lookup + + Payee + FSP + + Payee + + + + + + + + + + + + + + + + + + + + + + + + + Option #1 + + User + initiated + OTP + + + [1] + Generate + OTP for me + + + + + [2] + Generate OTP + + + [3] + Your OTP + is 12345 + + + [4] + I would like + to receive + 100 USD from + +123456789 + + + + + MSISDN not within + Payee FSP system + + + + [5] + Lookup Participant Information + (MSISDN 123456789) + + + + + [6] + Lookup which FSP MSISDN + +123456789 belongs to + + + [7] + Return Participant Information + (FSP ID) + + + + [8] + Perform Transaction Request + (Payee information, transaction details, OTP authorization) + + + + [9] + Perform Transaction Request + (Payee information, + transaction details, OTP authorization) + + + + + [10] + Perform optional validation + + + + [11] + Return Transaction + Request Information + (Received status) + + + + [12] + Return Transaction Request Information + (Received status) + + + + + [13] + Rate Payer FSP quote + (depending on fee model) + + + + Calculate Quote + (Transaction details) + + + + [14] + Calculate Quote + (Transaction details) + + + + + [15] + Rate Payee FSP + fees/commission, + generate condition + + + Optional + + Confirm + quote + + + [16] + Her is the + quote and + Payer name + + + I confirm + + + + [17] + Return Quote Information + (Payee FSP fee/commision, condition) + + + + [18] + Return Quote Information + (Payee FSP fee/commission, + condition) + + + + + [19] + Rate Payer FSP quote + (depending on fee model) + + + Option #2 + + Automatic + generated + OTP + + + + + [20] + Generate OTP + + + [21] + Use OTP + to confirm + + + + [22] + Perform Authorization + (Amount and fees) + + + + [23] + Perform Authorization + (Amount and fees) + + + [24] + Show fees + on POS + + + + + [25] + Payer + approves/rejects + transaction + using OTP + + + + Entered OTP + + + + [26] + Return Authorization Result + (OTP) + + + + [27] + Return Authorization Result + (OTP) + + + + HTTP 200 + (OK) + + + + + [28] + Validate OTP sent by Payee FSP + + + Alternatives + + OTP + validation + failed + + + + [29] + Return Transaction Request Information + (Rejected state) + + + + [30] + Return Transaction Request Information + (Rejected state) + + + [31] + Transaction + failed due to + incorrect OTP + + + OTP + validation + successful + + + + + 33 + Reserve transfer from Payer + account to Switch account + + + + Perform Transfer + (Transfer ID, condition, ILP packet + including transaction ID) + + + + + 34 + Reserve transfer + from Payer FSP + to Payee FSP + + + + Perform Transfer + (Transfer ID, condition, + ILP packet including transaction ID) +   + + + + + 35 + Perform transfer + from Switch account + to Payee account, + generate fulfilment + + + 36 + Transaction + notification + + + + Return Transfer Information + (Fulfilment) + + + + + 37 + Commit transfer + from Payer FSP + to Payee FSP + + + + Return Transfer Information + (Fulfilment) + + + + + 38 + Commits transfer from Payer + account to Payee FSP account + + + Optional + + Get transaction + data + + + + 39 + Retrieve Transaction Information + (Transaction ID) + + + + 40 + Retrieve Transaction Information + (Transaction ID) + + + + + 41 + Lookup + transaction + information + + + + 42 + Return Transaction Information + (Transaction details) + + + + 43 + Return Transaction Information** + (Transaction details) + + + 44 + Transaction + notification + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure67.plantuml b/docs/technical/api/assets/diagrams/sequence/figure67.plantuml new file mode 100644 index 000000000..0576dc323 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure67.plantuml @@ -0,0 +1,222 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Bulk Transactions pattern using the asynchronous REST binding + +' Actor Keys: +' participant - FSP(Payer/Payee(s)), Switch and Account Lookup Services (ALS) +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nAccount\nLookup" as ALS +participant "\nPayee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + transaction + in bulk file + end hnote + PayerFSP -> PayerFSP: Locate Payee, if not\nwithin Payer FSP\nuse Account Lookup + PayerFSP ->> ALS: **GET /participants/****/** + activate ALS + autonumber stop + PayerFSP <<-- ALS: **HTTP 202** (Accepted) + autonumber resume + ALS -> ALS: Lookup FSP for\nrequested Type/ID + autonumber stop + PayerFSP ->> ALS: **PUT /participants/****/** + PayerFSP <<-- ALS: **HTTP 200** (OK) + deactivate ALS + autonumber resume + PayerFSP -> PayerFSP: Place transaction\nin bulk file\nper Payee FSP + autonumber stop +end Loop +PayerFSP -[hidden]> Switch +deactivate PayerFSP +PayerFSP -[hidden]> Switch +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) + autonumber resume + PayerFSP ->> Switch: **POST /bulkQuotes**\n(Bulk info and list\nof individual quotes) + autonumber stop + activate Switch + autonumber resume + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + Switch ->> PayeeFSP: **POST /bulkQuotes**\n(Bulk info and list of individual quotes) + activate PayeeFSP + autonumber stop + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + autonumber stop + Switch <<- PayeeFSP: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **PUT /bulkQuotes/**\n(List of individual quote results\nand condition per transfer) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) +end Loop + +PayerFSP -> PayerFSP: Calculate total fee for Payer +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +deactivate PayerFSP +Payer -> PayerFSP: Execute my bulk +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account + autonumber stop + PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch + PayerFSP <<-- Switch: **HTTP 202** (Accepted) + autonumber resume + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP + Switch <<-- PayeeFSP: **HTTP 202** (Accepted) + autonumber resume + PayeeFSP -> PayeeFSP: Perform each transaction from\nPayer FSP account to Payee\naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **PUT /bulkTransfers/**\n(List of fulfilments) + autonumber stop + Switch -->> PayeeFSP: **HTTP 200** (OK) + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + autonumber resume + PayerFSP <<- Switch: **PUT /bulkTransfers/**\n(List of fulfilments) + autonumber stop + PayerFSP -->> Switch: **HTTP 200** (OK) + deactivate Switch + autonumber resume + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee FSP account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure67.svg b/docs/technical/api/assets/diagrams/sequence/figure67.svg new file mode 100644 index 000000000..7372a33e3 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure67.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   + Optional + Switch + +   + Account + Lookup + +   + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + + + + + + [1] + I would like to upload + a file of bulk transactions + + + loop + + For each + transaction + in bulk file + + + + + [2] + Locate Payee, if not + within Payer FSP + use Account Lookup + + + + [3] + GET /participants/ + <PartyIdType> + / + <PartyId> + + + + HTTP 202 + (Accepted) + + + + + [4] + Lookup FSP for + requested Type/ID + + + + PUT /participants/ + <PartyIdType> + / + <PartyId> + + + + HTTP 200 + (OK) + + + + + [5] + Place transaction + in bulk file + per Payee FSP + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (depending on fee model) + + + + [6] + POST /bulkQuotes + (Bulk info and list + of individual quotes) + + + + [7] + HTTP 202 + (Accepted) + + + + [8] + POST /bulkQuotes + (Bulk info and list of individual quotes) + + + + HTTP 202 + (Accepted) + + + + + [9] + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + [10] + PUT /bulkQuotes/ + <ID> + (List of individual quote results + and condition per transfer) + + + + HTTP 200 + (OK) + + + + + [11] + Rate Payer FSP bulk quote + (depending on fee model) + + + + + [12] + Calculate total fee for Payer + + + [13] + Bulk has finished processing, + present fees + + + [14] + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + [15] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + [16] + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + [17] + Perform each transaction from + Payer FSP account to Payee + account, generate fulfilments + + + [18] + Transaction notification + for each Payee + + + + [19] + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + [20] + PUT /bulkTransfers/ + <ID> + (List of fulfilments) + + + + HTTP 200 + (OK) + + + + + [21] + Commit each successful + transfer from Payer account + to Payee FSP account + + + [22] + Your bulk has been executed + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure67a.plantuml b/docs/technical/api/assets/diagrams/sequence/figure67a.plantuml new file mode 100644 index 000000000..9f4ba3a5d --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure67a.plantuml @@ -0,0 +1,200 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title Bulk Transaction + +' Actor Keys: +' participant - FSP(Payer/Payee(s)), Switch and Account Lookup Services (ALS) +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nPayer\n" as Payer +participant "\nPayer\nFSP" as PayerFSP +participant "\nOptional\nSwitch" as Switch +participant "\nAccount\nLookup" as ALS +participant "\nPayee\nFSP(s)" as PayeeFSP +actor "<$actor>\nPayees\n(multiple)" as Payee + +' start flow +autonumber 1 1 "[0]" +Payer -> PayerFSP: I would like to upload\na file of bulk transactions +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + transaction + in bulk file + end hnote + PayerFSP -> PayerFSP: Locate Payee, if not\nwithin Payer FSP\nuse Account Lookup + PayerFSP ->> ALS: **Lookup Participant Information**\n(Payee Party ID Type and Party ID) + activate ALS + ALS -> ALS: Lookup FSP for\nrequested Type/ID + PayerFSP ->> ALS: **Return Participant Information**\n(FSP ID) + autonumber stop + deactivate ALS + PayerFSP -> PayerFSP: Place transaction\nin bulk file\nper Payee FSP + PayerFSP -[hidden]> Switch + deactivate PayerFSP +end Loop +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -[hidden]> Switch + activate PayerFSP + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) + autonumber resume + PayerFSP ->> Switch: **Calculate Bulk Quote**\n(Bulk info and list\nof individual quotes) + Switch ->> PayeeFSP: **Calculate Bulk Quote**\n(Bulk info and list of individual quotes) + activate PayeeFSP + activate Switch + PayeeFSP -> PayeeFSP: Rate Payee FSP\nfee/commission and\ngenerate condition per\nindividual transfer + autonumber stop + Switch <<- PayeeFSP: **Return Bulk Quote Information**\n(List of individual quote results\nand condition per transfer) + deactivate PayeeFSP + autonumber resume + PayerFSP <<- Switch: **Return Bulk Quote Information**\n(List of individual quote results\nand condition per transfer) + deactivate Switch + PayerFSP -> PayerFSP: Rate Payer FSP bulk quote\n(depending on fee model) +end Loop +autonumber resume +PayerFSP -> PayerFSP: Calculate total fee for Payer +Payer <- PayerFSP: Bulk has finished processing,\npresent fees +deactivate PayerFSP +Payer -> PayerFSP: Execute my bulk +activate PayerFSP +Loop #Oldlace + hnote left of PayerFSP #Oldlace + For each + created bulk + file per + Payee FSP + end hnote + PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account +autonumber stop + PayerFSP ->> Switch: **Perform Bulk Transfer**\n(List of individual transfers\nincluding ILP packet and condition) + activate Switch +autonumber resume + Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP + autonumber stop + Switch ->> PayeeFSP: **Perform Bulk Transfer**\n(List of individual transfers\nincluding ILP packet and condition) + activate PayeeFSP +autonumber resume + PayeeFSP -> PayeeFSP: Perform each transaction from\nPayer FSP account to Payee\naccount, generate fulfilments + PayeeFSP -> Payee: Transaction notification\nfor each Payee + Switch <<- PayeeFSP: **Return Bulk Transfer Information**\n(List of fulfilments) + autonumber stop + deactivate PayeeFSP + Switch -> Switch: Commit each successful\ntransfer from Payer\nFSP to Payee FSP + autonumber resume + PayerFSP <<- Switch: **Return Bulk Transfer Information**\n(List of fulfilments) + deactivate Switch + PayerFSP -> PayerFSP: Commit each successful\ntransfer from Payer account\nto Payee FSP account +end Loop +Payer <- PayerFSP: Your bulk has been executed +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure67a.svg b/docs/technical/api/assets/diagrams/sequence/figure67a.svg new file mode 100644 index 000000000..11e7f3675 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure67a.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Payer +   + + + +   + Payer + FSP + +   + Optional + Switch + +   + Account + Lookup + +   + Payee + FSP(s) + + Payees + (multiple) + + + + + + + + + + + + + [1] + I would like to upload + a file of bulk transactions + + + loop + + For each + transaction + in bulk file + + + + + [2] + Locate Payee, if not + within Payer FSP + use Account Lookup + + + + [3] + Lookup Participant Information + (Payee Party ID Type and Party ID) + + + + + [4] + Lookup FSP for + requested Type/ID + + + + [5] + Return Participant Information + (FSP ID) + + + + + Place transaction + in bulk file + per Payee FSP + + + loop + + For each + created bulk + file per + Payee FSP + + + + + Rate Payer FSP bulk quote + (depending on fee model) + + + + [6] + Calculate Bulk Quote + (Bulk info and list + of individual quotes) + + + + [7] + Calculate Bulk Quote + (Bulk info and list of individual quotes) + + + + + [8] + Rate Payee FSP + fee/commission and + generate condition per + individual transfer + + + + Return Bulk Quote Information + (List of individual quote results + and condition per transfer) + + + + [9] + Return Bulk Quote Information + (List of individual quote results + and condition per transfer) + + + + + [10] + Rate Payer FSP bulk quote + (depending on fee model) + + + + + [11] + Calculate total fee for Payer + + + [12] + Bulk has finished processing, + present fees + + + [13] + Execute my bulk + + + loop + + For each + created bulk + file per + Payee FSP + + + + + [14] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + Perform Bulk Transfer + (List of individual transfers + including ILP packet and condition) + + + + + [15] + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + Perform Bulk Transfer + (List of individual transfers + including ILP packet and condition) + + + + + [16] + Perform each transaction from + Payer FSP account to Payee + account, generate fulfilments + + + [17] + Transaction notification + for each Payee + + + + [18] + Return Bulk Transfer Information + (List of fulfilments) + + + + + Commit each successful + transfer from Payer + FSP to Payee FSP + + + + [19] + Return Bulk Transfer Information + (List of fulfilments) + + + + + [20] + Commit each successful + transfer from Payer account + to Payee FSP account + + + [21] + Your bulk has been executed + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure68.plantuml b/docs/technical/api/assets/diagrams/sequence/figure68.plantuml new file mode 100644 index 000000000..2acdac867 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure68.plantuml @@ -0,0 +1,64 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Error on server during processing of request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +activate server +client <<-- server: **HTTP 202** (Accepted) +autonumber stop +server -> server: Some processing error\noccurs, i.e. the request\ncan not be handled as\nrequested. +autonumber resume +client <<- server: **PUT /service/****/error** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure68.svg b/docs/technical/api/assets/diagrams/sequence/figure68.svg new file mode 100644 index 000000000..f1b5d40d1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure68.svg @@ -0,0 +1,47 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + [2] + HTTP 202 + (Accepted) + + + + + Some processing error + occurs, i.e. the request + can not be handled as + requested. + + + + [3] + PUT /service/ + <ID> + /error + + + + [4] + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure69.plantuml b/docs/technical/api/assets/diagrams/sequence/figure69.plantuml new file mode 100644 index 000000000..c1f3ba428 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure69.plantuml @@ -0,0 +1,81 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Handling of error callback from POST /transfers + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch + + +' declare actors +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP + +' start flow +autonumber 1 1 "[0]" +activate PayerFSP +PayerFSP -> PayerFSP: Reserve transfer from Payer\naccount to Switch account +PayerFSP ->> Switch: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve transfer from\nPayer FSP to Payee FSP +autonumber resume +Switch ->> PayeeFSP: **POST /transfers**\n(Transfer ID, condition, ILP Packet\nincluding transaction details) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Some processing error occurs,\ne.g. a limit breach +autonumber resume +Switch <<- PayeeFSP: **PUT /transfers/****/error** +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Cancel transfer from\nPayer FSP to Payee FSP +autonumber resume +PayerFSP <<- Switch: **PUT /transfers/****/error**\n(Error information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Cancel transfer from Payer\naccount to Payee FSP account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure69.svg b/docs/technical/api/assets/diagrams/sequence/figure69.svg new file mode 100644 index 000000000..c8e47a23b --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure69.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + + + + + + + [1] + Reserve transfer from Payer + account to Switch account + + + + [2] + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details) + + + + HTTP 202 + (Accepted) + + + + + Reserve transfer from + Payer FSP to Payee FSP + + + + [3] + POST /transfers + (Transfer ID, condition, ILP Packet + including transaction details) + + + + HTTP 202 + (Accepted) + + + + + Some processing error occurs, + e.g. a limit breach + + + + [4] + PUT /transfers/ + <ID> + /error + + + + HTTP 200 + (OK) + + + + + Cancel transfer from + Payer FSP to Payee FSP + + + + [5] + PUT /transfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel transfer from Payer + account to Payee FSP account + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure70.plantuml b/docs/technical/api/assets/diagrams/sequence/figure70.plantuml new file mode 100644 index 000000000..42f6da819 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure70.plantuml @@ -0,0 +1,81 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Handling of error callback from API Service /bulkTransfers + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch + + +' declare actors +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP(s)" as PayeeFSP + +' start flow +autonumber 1 1 "[0]" +activate PayerFSP +PayerFSP -> PayerFSP: Reserve each individual\ntransfer from Payer\naccount to Payee FSP account +PayerFSP ->> Switch: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve each individual\ntransfer from Payer FSP\nto Payee FSP +autonumber resume +Switch ->> PayeeFSP: **POST /bulkTransfers**\n(List of individual transfers\nincluding ILP packet and condition) +activate PayeeFSP +autonumber stop +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Some processing error occurs,\ne.g. a validation failure that prevents\nthe bulk transfer to be performed +autonumber resume +Switch <<- PayeeFSP: **PUT /bulkTransfers/****/error**\n(Error information) +autonumber stop +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +Switch -> Switch: Cancel each reserved\ntransfer from Payer\nFSP to Payee FSP +autonumber resume +PayerFSP <<- Switch: **PUT /bulkTransfers/****/error**\n(Error information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Cancel each transfer\nfrom Payer account\nto Payee FSP account +PayerFSP -[hidden]> Switch +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure70.svg b/docs/technical/api/assets/diagrams/sequence/figure70.svg new file mode 100644 index 000000000..bbdcd79ec --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure70.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP(s) + + + + + + + + [1] + Reserve each individual + transfer from Payer + account to Payee FSP account + + + + [2] + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Reserve each individual + transfer from Payer FSP + to Payee FSP + + + + [3] + POST /bulkTransfers + (List of individual transfers + including ILP packet and condition) + + + + HTTP 202 + (Accepted) + + + + + Some processing error occurs, + e.g. a validation failure that prevents + the bulk transfer to be performed + + + + [4] + PUT /bulkTransfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel each reserved + transfer from Payer + FSP to Payee FSP + + + + [5] + PUT /bulkTransfers/ + <ID> + /error + (Error information) + + + + HTTP 200 + (OK) + + + + + Cancel each transfer + from Payer account + to Payee FSP account + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure71.plantuml b/docs/technical/api/assets/diagrams/sequence/figure71.plantuml new file mode 100644 index 000000000..858f8bca1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure71.plantuml @@ -0,0 +1,70 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +' declare title +' title Error handling from client using resend of request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +client -> client: Timeout, resend\nservice request +client ->> server: **POST /service** +activate server +client <<-- server: **HTTP 202** (Accepted) +autonumber stop +client -> client: Timeout, resend\nservice request +autonumber resume +client ->> server: **POST /service** +autonumber stop +client <<-- server: **HTTP 202** (Accepted) +autonumber resume +client <<- server: **PUT /service/** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure71.svg b/docs/technical/api/assets/diagrams/sequence/figure71.svg new file mode 100644 index 000000000..155304af7 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure71.svg @@ -0,0 +1,66 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + + [2] + Timeout, resend + service request + + + + [3] + POST /service + + + + [4] + HTTP 202 + (Accepted) + + + + + Timeout, resend + service request + + + + [5] + POST /service + + + + HTTP 202 + (Accepted) + + + + [6] + PUT /service/ + <ID> + + + + [7] + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure72.plantuml b/docs/technical/api/assets/diagrams/sequence/figure72.plantuml new file mode 100644 index 000000000..6bf57abd8 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure72.plantuml @@ -0,0 +1,67 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke + +hide footbox + +' declare title +' title Error handling from client using GET request + +' Actor Keys: +' participant - Client and Server + + +' declare actors +participant "Client" as client +participant "Server" as server + +' start flow +autonumber 1 1 "[0]" +client ->> server: **POST /service** +activate client +activate server +client <<-- server: **HTTP 202** (Accepted) +'autonumber stop +client -> client: No update received within\nreasonable time period,\ncheck status +'autonumber resume +client ->> server: **GET /service** +autonumber stop +client <<-- server: **HTTP 202** (Accepted) +autonumber resume +client <<- server: **PUT /service/** +client -->> server: **HTTP 200** (OK) +deactivate server +deactivate client +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure72.svg b/docs/technical/api/assets/diagrams/sequence/figure72.svg new file mode 100644 index 000000000..148863300 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure72.svg @@ -0,0 +1,57 @@ + + + + + + + + + Client + + Server + + + + + + [1] + POST /service + + + + [2] + HTTP 202 + (Accepted) + + + + + [3] + No update received within + reasonable time period, + check status + + + + [4] + GET /service + <ID> + + + + HTTP 202 + (Accepted) + + + + [5] + PUT /service/ + <ID> + + + + [6] + HTTP 200 + (OK) + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure74.plantuml b/docs/technical/api/assets/diagrams/sequence/figure74.plantuml new file mode 100644 index 000000000..752507fa1 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure74.plantuml @@ -0,0 +1,220 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title End-to-end flow, from provision of account holder FSP information to a successful transaction + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payer/Payee(s) + +' declare actors +actor "<$actor>\nMats\nHagman" as Payer +participant "\nBank\nNrOne" as PayerFSP +participant "\n\nSwitch" as Switch +participant "\nMobile\nMoney" as MM +actor "<$actor>\nHenrik\nKarlsson" as Payee + +' start flow +autonumber 1 1 "[0]" +Switch <<- MM: **POST /participants/MSISDN/123456789**\n(fspid=MobileMoney) +activate Switch +activate MM +autonumber stop +Switch -->> MM: **HTTP 202** (Accepted) +autonumber resume +Switch <<-- Switch: Save FSP information for\nMSISDN 123456789 +Switch ->> MM: **PUT /participants/MSISDN/123456789**\n(fspid=MobileMoney) +autonumber stop +Switch <<-- MM: **HTTP 200** (OK) +deactivate MM +deactivate Switch +autonumber resume +Payer -> PayerFSP: I would like MSISDN +123456789\nto receive 100 USD +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: MSISDN +123456789\nnot within BankNrOne +autonumber resume +PayerFSP ->> Switch: **GET /parties/MSISDN/123456789** +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Lookup which FSP MSISDN\n+123456789 belongs to +autonumber resume +Switch ->> MM: **GET /parties/MSISDN/123456789** +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Lookup party information\nregarding MSISDN +123456789 +autonumber resume +Switch <<- MM: **PUT /Parties/MSISDN/123456789**\n(Party Information) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +autonumber resume +PayerFSP <<- Switch: **PUT /Parties/MSISDN/123456789**\n(Party Information) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +deactivate PayerFSP +autonumber resume +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVE, amount=100) +activate PayerFSP +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +autonumber resume +Switch ->> MM: **POST /quotes**\n(amountType=RECEIVE, amount=100) +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Internal rating for fees/commission,\n1 USD in FSP commission, generate\nand store fulfilment, generate\ncondition out of fulfilment +autonumber resume +Switch <<- MM: **PUT /quotes/**\n(transferAmount=99 USD\npayeeFspCommission=1 USD) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +autonumber resume +PayerFSP <<- Switch: **PUT /quotes/**\n(transferAmount=99 USD\npayeeFspCommission=1 USD) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: BankNrOne keeps commission as\nfee, transaction is free for Mats +autonumber resume +Payer <- PayerFSP: Transferring 100 USD to Henrik\nKarlsson will cost 0 USD in fees +deactivate PayerFSP +Payer -> PayerFSP: I approve the transaction +activate PayerFSP +autonumber stop +PayerFSP -> PayerFSP: Reserve 100 USD from Mats\nHagman's account,\n99 USD to Switch and\n1 USD to FSP commission +autonumber resume +PayerFSP ->> Switch: **POST /transfers**\n(amount=99 USD, PayerFsp=BankNrOne\npayeeFsp=MobileMoney) +activate Switch +autonumber stop +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch -> Switch: Reserve 99 USD from\nBankNrOne to MobileMoney +autonumber resume +Switch ->> MM: **POST /transfers**\n(amount=99 USD, PayerFsp=BankNrOne\npayeeFsp=MobileMoney) +activate MM +autonumber stop +Switch <<-- MM: **HTTP 202** (Accepted) +MM -> MM: Perform transfer of 100 USD to\nHenrik Karlsson's account,\n99 USD from Switch\naccount, and 1 USD from FSP\ncommission account +autonumber resume +MM -> MM: Retrieve fulfilment +MM -> Payee: You have received 100 USD\nfrom Mats Hagman +Switch <<- MM: **PUT /transfers/**\n(Fulfilment) +autonumber stop +Switch -->> MM: **HTTP 200** (OK) +deactivate MM +Switch -> Switch: Commit transfer from\nBankNrOne to MobileMoney +autonumber resume +PayerFSP <<- Switch: **PUT /transfers/**\n(Fulfilment) +autonumber stop +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Commit transfer from Mats\nHagman's account to\nSwitch account +autonumber resume +Payer <- PayerFSP: You have transferred 100 USD\nto Henrik Karlsson +autonumber stop +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure74.svg b/docs/technical/api/assets/diagrams/sequence/figure74.svg new file mode 100644 index 000000000..0d00d55c4 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure74.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mats + Hagman + + + +   + Bank + NrOne + +   +   + Switch + +   + Mobile + Money + + Henrik + Karlsson + + + + + + + + + + + + + + + + + [1] + POST /participants/MSISDN/123456789 + (fspid=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + + [2] + Save FSP information for + MSISDN 123456789 + + + + [3] + PUT /participants/MSISDN/123456789 + (fspid=MobileMoney) + + + + HTTP 200 + (OK) + + + [4] + I would like MSISDN +123456789 + to receive 100 USD + + + + + MSISDN +123456789 + not within BankNrOne + + + + [5] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup which FSP MSISDN + +123456789 belongs to + + + + [6] + GET /parties/MSISDN/123456789 + + + + HTTP 202 + (Accepted) + + + + + Lookup party information + regarding MSISDN +123456789 + + + + [7] + PUT /Parties/MSISDN/123456789 + (Party Information) + + + + HTTP 200 + (OK) + + + + [8] + PUT /Parties/MSISDN/123456789 + (Party Information) + + + + HTTP 200 + (OK) + + + + [9] + POST /quotes + (amountType=RECEIVE, amount=100) + + + + HTTP 202 + (Accepted) + + + + [10] + POST /quotes + (amountType=RECEIVE, amount=100) + + + + HTTP 202 + (Accepted) + + + + + Internal rating for fees/commission, + 1 USD in FSP commission, generate + and store fulfilment, generate + condition out of fulfilment + + + + [11] + PUT /quotes/ + <ID> + (transferAmount=99 USD + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + [12] + PUT /quotes/ + <ID> + (transferAmount=99 USD + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + + BankNrOne keeps commission as + fee, transaction is free for Mats + + + [13] + Transferring 100 USD to Henrik + Karlsson will cost 0 USD in fees + + + [14] + I approve the transaction + + + + + Reserve 100 USD from Mats + Hagman's account, + 99 USD to Switch and + 1 USD to FSP commission + + + + [15] + POST /transfers + (amount=99 USD, PayerFsp=BankNrOne + payeeFsp=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + Reserve 99 USD from + BankNrOne to MobileMoney + + + + [16] + POST /transfers + (amount=99 USD, PayerFsp=BankNrOne + payeeFsp=MobileMoney) + + + + HTTP 202 + (Accepted) + + + + + Perform transfer of 100 USD to + Henrik Karlsson's account, + 99 USD from Switch + account, and 1 USD from FSP + commission account + + + + + [17] + Retrieve fulfilment + + + [18] + You have received 100 USD + from Mats Hagman + + + + [19] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from + BankNrOne to MobileMoney + + + + [20] + PUT /transfers/ + <ID> + (Fulfilment) + + + + HTTP 200 + (OK) + + + + + Commit transfer from Mats + Hagman's account to + Switch account + + + [21] + You have transferred 100 USD + to Henrik Karlsson + + diff --git a/docs/technical/api/assets/diagrams/sequence/figure8.plantuml b/docs/technical/api/assets/diagrams/sequence/figure8.plantuml new file mode 100644 index 000000000..69a6186af --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure8.plantuml @@ -0,0 +1,135 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation + +- Name Surname +-------------- +******'/ + +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} +hide footbox + +' declare title +' title Example of non-disclosing receive amount + +' Actor Keys: +' participant - FSP(Payer/Payee) and Optional Switch +' actor - Payee and Payer + +' declare actors +actor "<$actor>\nPayer" as Payer +participant "Payer\nFSP" as PayerFSP +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as PayeeFSP +actor "<$actor>\nPayee" as Payee + +' start flow +Payer ->> PayerFSP: I would like to Payee to\nreceive 100 USD +activate PayerFSP +PayerFSP ->> Switch: **POST /quotes**\n(amountType=RECEIVED,\namount=100 USD) +activate Switch +PayerFSP <<-- Switch: **HTTP 202** (Accepted) +Switch ->> PayeeFSP: **POST /quotes**\n(amountType=RECEIVE,\namount=100 USD) +activate PayeeFSP +Switch <<-- PayeeFSP: **HTTP 202** (Accepted) +PayeeFSP -> PayeeFSP: Rate transaction fee or\ncommission for handeling\ntransaction in Payee FSP => \nFSP commission 1 USD +Switch <<- PayeeFSP: **PUT /quotes/**\n(transferAmount=99 USD,\npayeeFspCommission=1 USD) +Switch -->> PayeeFSP: **HTTP 200** (OK) +deactivate PayeeFSP +PayerFSP <<- Switch: **PUT /quotes/** +PayerFSP -->> Switch: **HTTP 200** (OK) +deactivate Switch +PayerFSP -> PayerFSP: Keep commission\nfee for Payer for\nhandling transaction in\nPayer FSP => total fee 1 USD +PayerFSP ->> Payer: Sending 100 USD to Payee\nwill cost 1 USD in fees +deactivate PayerFSP +@enduml diff --git a/docs/technical/api/assets/diagrams/sequence/figure8.svg b/docs/technical/api/assets/diagrams/sequence/figure8.svg new file mode 100644 index 000000000..7ffa03a23 --- /dev/null +++ b/docs/technical/api/assets/diagrams/sequence/figure8.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + Payer + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + + I would like to Payee to + receive 100 USD + + + + POST /quotes + (amountType=RECEIVED, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + POST /quotes + (amountType=RECEIVE, + amount=100 USD) + + + + HTTP 202 + (Accepted) + + + + + Rate transaction fee or + commission for handeling + transaction in Payee FSP => + FSP commission 1 USD + + + + PUT /quotes/ + <ID> + (transferAmount=99 USD, + payeeFspCommission=1 USD) + + + + HTTP 200 + (OK) + + + + PUT /quotes/ + <ID> + + + + HTTP 200 + (OK) + + + + + Keep commission + fee for Payer for + handling transaction in + Payer FSP => total fee 1 USD + + + + Sending 100 USD to Payee + will cost 1 USD in fees + + diff --git a/docs/technical/api/assets/figure1-platforms-layout.svg b/docs/technical/api/assets/figure1-platforms-layout.svg new file mode 100644 index 000000000..8a12de358 --- /dev/null +++ b/docs/technical/api/assets/figure1-platforms-layout.svg @@ -0,0 +1,3 @@ + + +
    CA
    CA
    ALS
    ALS
    FSP-1
    FSP-1
    FSP-2
    FSP-2
    Switch
    Switch
    FSP-3
    FSP-3
    FSP-4
    FSP-4
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Legend:
    Solid lines indicate TLS-secured communication.
    Dashed lines indicate certificate owner.
    Legend:...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/api/assets/scheme-rules-figure-1-http-timeout.png b/docs/technical/api/assets/scheme-rules-figure-1-http-timeout.png new file mode 100644 index 000000000..9d3faf74e Binary files /dev/null and b/docs/technical/api/assets/scheme-rules-figure-1-http-timeout.png differ diff --git a/docs/technical/api/assets/scheme-rules-figure-2-callback-timeout.png b/docs/technical/api/assets/scheme-rules-figure-2-callback-timeout.png new file mode 100644 index 000000000..04f5da996 Binary files /dev/null and b/docs/technical/api/assets/scheme-rules-figure-2-callback-timeout.png differ diff --git a/docs/technical/api/assets/sequence-diagram-figure-1.png b/docs/technical/api/assets/sequence-diagram-figure-1.png new file mode 100644 index 000000000..53215785d Binary files /dev/null and b/docs/technical/api/assets/sequence-diagram-figure-1.png differ diff --git a/docs/technical/api/fspiop/README.md b/docs/technical/api/fspiop/README.md new file mode 100644 index 000000000..2211014c5 --- /dev/null +++ b/docs/technical/api/fspiop/README.md @@ -0,0 +1,28 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# FSPIOP API + +The Open API for FSP Interoperability Specification includes the following documents: + +## Logical Documents + +* [Logical Data Model](./logical-data-model.md) +* [Generic Transaction Patterns](./generic-transaction-patterns.md) +* [Use Cases](./use-cases.md) + +## Asynchronous REST Binding Documents + +* API Definition + * [FSPIOP v1.1](./v1.1/api-definition.md) + * [FSPIOP v1.0](./v1.0/api-definition.md) +* [Central Ledger API](#central-ledger-api) +* [JSON Binding Rules](#json-binding-rules) +* [Scheme Rules](./scheme-rules.md) + +## Data Integrity, Confidentiality, and Non-Repudiation + +* [PKI Best Practices](./pki-best-practices.md) +* [Signature](./v1.1/signature.md) +* [Encryption](./v1.1/encryption.md) diff --git a/docs/technical/api/fspiop/definitions.md b/docs/technical/api/fspiop/definitions.md new file mode 100644 index 000000000..e89691b20 --- /dev/null +++ b/docs/technical/api/fspiop/definitions.md @@ -0,0 +1,13 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# FSPIOP API + +## Versions + +|Version|Date|Change Description| +|---|---|---| +|[1.0](./v1.0/api-definition)|2018-03-13|Initial version| +|[1.1](./v1.1/api-definition)|2020-05-19|1. This version contains a new option for a Payee FSP to request a commit notification from the Switch. The Switch should then send out the commit notification using the new request **PATCH /transfers/**_{ID}_. The option to use commit notification replaces the previous option of using the ”Optional Additional Clearing Check”. The section describing this has been replaced with the new section ”Commit Notification”. As the **transfers** resource has been updated with the new **PATCH** request, this resource has been updated to version 1.1. As part of adding the possibility to use a commit notification, the following changes has been made:
    a. PATCH has been added as an allowed HTTP Method in Section 3.2.2. b. The call flow for **PATCH** is described in Section 3.2.3.5.
    c. Table 6 in Section 6.1.1 has been updated to include **PATCH** as a possible HTTP Method.
    d. Section 6.7.1 contains the new version of the **transfers** resource.
    e. Section 6.7.2.6 contains the process for using commit notifications
    f. Section 6.7.3.3 describes the new **PATCH /transfers**/_{ID}_ request.

    2. In addition to the changes mentioned above regarding the commit notification, the following non-API affecting changes has been made:
    a. Updated Figure 6 as it contained a copy-paste error.
    b. Added Section 6.1.2 to describe a comprehensive view of the current version for each resource.
    c. Added a section for each resource to be able to see the resource version history.
    d. Minor editorial fixes.

    3. The descriptions for two of the HTTP Header fields in Table 1 have been updated to add more specificity and context
    a. The description for the **FSPIOP-Destination** header field has been updated to indicate that it should be left empty if the destination is not known to the original sender, but in all other cases should be added by the original sender of a request.
    b. The description for the **FSPIOP-URI** header field has been updated to be more specific.

    4. The examples used in this document have been updated to use the correct interpretation of the Complex type ExtensionList which is defined in Table 84. This doesn’t imply any change as such.
    a. Listing 5 has been updated in this regard.

    5. The data model is updated to add an optional ExtensionList element to the **PartyIdInfo** complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 103 has been updated. For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.

    6. A new Section 6.5.2.2 is added to describe the process involved in the rejection of a quote.

    7. A note is added to Section 6.7.4.1 to clarify the usage of ABORTED state in **PUT /transfers/**_{ID}_ callbacks.| +|**1.1.1**|2021-09-22|This document version only adds information about optional HTTP headers regarding tracing support in [Table 2](#table-2), see _Distributed Tracing Support for OpenAPI Interoperability_ for more information. There are no changes in any resources as part of this version.| \ No newline at end of file diff --git a/docs/technical/api/fspiop/generic-transaction-patterns.md b/docs/technical/api/fspiop/generic-transaction-patterns.md new file mode 100644 index 000000000..8e0828344 --- /dev/null +++ b/docs/technical/api/fspiop/generic-transaction-patterns.md @@ -0,0 +1,1854 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# Generic Transaction Patterns + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document introduces the four generic transaction patterns that are supported in a logical version of the Interoperability API. Additionally, all logical services that are part of the API are presented on a high-level. + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](#) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Logical API Services + +The Interoperability API consists of a number of logical API resources. Each resource defines one or more services that clients can use to connect to a server that has implemented the API. This section introduces these services. + +**Note:** API services identified in this section may not be relevant to (and therefore may not appear in) the generic transaction patterns identified in [Generic Transaction Patterns](#generic-transaction-patterns). + +For example, some services are used for provisioning of information, are part of error cases, or are for retrieving information that is not necessary in a generic transaction pattern. + +
    + +### Common Functionality + +This section introduces functionality that is used by more than one logical API resource or service. + +#### Party Addressing + +A Party is an entity such as an individual, a business, an organization that has a financial account in one of the FSPs. A party is addressed by a combination of an _ID type_ and an _ID_, and possibly also a _subtype_ or _sub ID_. Some examples of _ID type_ and _ID_ combinations are: + +- _ID type_: **MSISDN**, _ID_: **+123456789** + +- _ID type_: **Email**, _ID_: **john@doe.com** + +#### Interledger + +The API includes basic support for the Interledger Protocol (ILP) by defining a concrete implementation of the Interledger Payment Request protocol[1](https://interledger.org/rfcs/0011-interledger-payment-request)(ILP) in the logical API resources **Quotes** and **Transfers**. More details of the ILP protocol can be found on the Interledger project website[2](https://interledger.org), in the Interledger Whitepaper[3](https://interledger.org/interledger.pdf), and in the Interledger architecture specification[4](https://interledger.org/rfcs/0001-interledger-architecture). + +
    + +### API Resource Participants + +In the API, a _Participant_ is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource **Participants** is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Lookup Participant Information + +The logical API service request `Lookup Participant Information` is used from an FSP to request from another system, which could be another FSP or a common system, information regarding in which FSP a counterparty in an interoperable financial transaction is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +##### Create Participant Information + +The logical API service request `Create Participant Information` is used to provision information regarding in which FSP a party is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +##### Create Bulk Participant Information + +The logical API service request `Create Bulk Participant Information` is used to provision information regarding in which FSP one or more parties are located. + +- Successful response: [Return Bulk Participant Information](#return-bulk-participant-information) + +- Error response: [Return Bulk Participant Information Error](#return-bulk-participant-information-error) + +##### Delete Participant Information + +The logical API service request `Delete Participant Information` is used to remove information regarding in which FSP a party is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Participant Information + +The logical API service response `Return Participant Information` is used to return information from the requests [Lookup Participant Information](#lookup-participant-information), [Create Participant Information](#create-participant-information) and [Delete Participant Information](#delete-participant-information). + +##### Return Bulk Participant Information + +The logical API service response `Return Bulk Participant Information` is used to return information from the request [Create Bulk Participant Information](#create-bulk-participant-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Participant Information Error + +The logical API service error response `Return Participant Information Error` is used to return error information regarding the requests [Lookup Participant Information](#lookup-participant-information), [Create Participant Information](#create-participant-information) and [Delete Participant Information](#delete-participant-information). + +##### Return Bulk Participant Information Error + +The logical API service error response `Return Bulk Participant Information Error` is used to return information from the request [Create Bulk Participant Information](#create-bulk-participant-information). + +
    + +### API Resource Parties + +In the API, a _Party_ is an individual, a business, an organization, or a similar entity, that has a financial account in one of the FSPs. The primary purpose of the logical API resource **Parties** is for FSPs to ascertain information regarding a counterparty in an interoperable financial transaction, such as name and birth date of the Party. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Lookup Party Information + +The logical API service request `Lookup Party Information` is used by an FSP to request from another FSP information regarding a counterparty in an interoperable financial transaction. + +- Successful response: [Return Party Information](#return-party-information). + +- Error response: [Return Party Information Error](#return-party-information-error). + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Party Information + +The logical API service response `Return Party Information` is used to return information from the request [Lookup Party Information](#lookup-party-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Party Information Error + +The logical API service error response `Return Party Information Error` is used to return error information regarding the request [Lookup Party Information](#lookup-party-information). + +
    + +### API Resource Transaction Requests + +In the API, a _Transaction Request_ is a request from a Payee to a Payer to transfer electronic funds to the Payee, which the Payer can accept or reject. The primary purpose of the logical API resource **Transaction Requests** is for a Payee FSP to send the request to transfer to the Payer FSP. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Transaction Request + +The logical API service request `Perform Transaction Request` is used to send a Transaction Request from a Payee FSP to the Payer FSP; that is, to ask if a Payer will accept or reject a transaction from the Payer to the Payee. + +- Successful response: [Return Transaction Request Information](#return-transaction-request-information) + +- Error response: [Return Transaction Request Information Error](#return-transaction-request-information-error) + +##### Retrieve Transaction Request Information + +The logical API service request `Retrieve Transaction Request Information` is used from a Payee FSP to a Payer FSP to request information regarding a previously-sent Transaction Request. + +- Successful response: [Return Transaction Request Information](#return-transaction-request-information) + +- Error response: [Return Transaction Request Information Error](#return-transaction-request-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transaction Request Information + +The logical API service response `Return Transaction Request Information` is used to return information from the requests [Perform Transaction Request](#perform-transaction-request) or [Retrieve Transaction Request Information](#retrieve-transaction-request-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transaction Request Information Error + +The logical API service error response `Return Transaction Request Information Error` is used to return error information regarding the requests [Perform Transaction Request](#perform-transaction-request) or [Retrieve Transaction Request Information](#retrieve-transaction-request-information). + +
    + +### API Resource Quotes + +In the API, a _Quote_ is the price for performing an interoperable financial transaction from the Payer FSP to the Payee FSP. The primary purpose of the logical API resource **Quotes** is for a Payer FSP to request a Payee FSP to calculate the Payee FSP's part of the quote. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Calculate Quote + +The logical API service request `Calculate Quote` is used from a Payer FSP to ask a Payee FSP to calculate the Payee FSP's part of the quote to perform an interoperable financial transaction. The Payee FSP should also create the ILP Packet and the condition (see [Interledger](#interledger) section for links to more information) when receiving the request. + +- Successful response: [Return Quote Information](#return-quote-information) + +- Error response: [Return Quote Information Error](#return-quote-information-error) + +
    + +##### Retrieve Quote Information + +The logical API service request `Retrieve Quote Information` is used by a Payer FSP to request that a Payee FSP ask for information regarding a previously-sent [Calculate Quote](#calculate-quote) request. + +- Successful response: [Return Quote Information](#return-quote-information) + +- Error response: [Return Quote Information Error](#return-quote-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Quote Information + +The logical API service response `Return Quote Information` is used to return information from the requests [Calculate Quote](#calculate-quote) or [Retrieve Quote Information](#retrieve-quote-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Quote Information Error + +The logical API service error response `Return Quote Information Error` is used to return error information regarding the requests [Calculate Quote](#calculate-quote) or [Retrieve Quote Information](#retrieve-quote-information). + +
    + +### API Resource Authorizations + +In the API, an _Authorization_ is an approval from a Payer to perform an interoperable financial transaction by entering the applicable credentials in a Payee FSP system. An example where this kind of approval is used, is when a Payer is using an ATM that is managed by another FSP. The primary purpose of the logical API resource **Authorizations** is for a Payer FSP to request a Payee FSP to ask the Payer to enter the credentials. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Authorization + +The logical API service request `Perform Authorization` is used from a Payer FSP to ask a Payee FSP to enter the applicable credentials to approve an interoperable financial transaction. + +- Successful response: [Return Authorization Result](#return-authorization-result) + +- Error response: [Return Authorization Error](#return-authorization-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Authorization Result + +The logical API service response `Return Authorization Result` is used to return information from the request [Perform Authorization](#perform-authorization). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Authorization Error + +The logical API service error response `Return Authorization Error` is used to return error information regarding the request [Perform Authorization](#perform-authorization). + +
    + +### API Resource Transfers + +In the API, a _Transfer_ is hop-to-hop ILP (see [Interledger](#interledger) section for links to more information) transfer of funds. + +The transfer also contains information regarding the end-to-end interoperable financial transaction. The primary purpose of the logical API resource **Transfers** is for an FSP or Switch to request that the next entity in the chain of the ILP Payment perform the transfer involved in the interoperable financial transaction. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Transfer + +The logical API service request `Perform Transfer` is used by an FSP or Switch to request the next entity in the chain of the ILP Payment to reserve the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +##### Retrieve Transfer Information + +The logical API service request `Retrieve Transfer Information` is used by an FSP or Switch to request the next entity in the chain of the ILP Payment for information regarding the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transfer Information + +The logical API service response `Return Transfer Information` is used to return information from the requests [Perform Transfer](#perform-transfer) or [Retrieve Transfer Information](#retrieve-transfer-information). On receiving the [Return Transfer Information](#return-transfer-information) response, the FSP or Switch should validate the fulfilment (see [Interledger](#interledger) section for links to more information) and commit the reserved transfer if the validation is successful. + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transfer Information Error + +The logical API service error response `Return Transfer Information Error` is used to return error information regarding the requests [Perform Transfer](#perform-transfer) or [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +### API Resource Transactions + +In the API, a _Transaction_ is an end-to-end interoperable financial transaction between the Payer FSP and Payee FSP. The primary purpose of the logical API resource **Transactions** is for a Payer FSP to request end-to-end information from the Payee FSP regarding an interoperable financial transaction; for example, in order to get a token or code that the Payer can use to redeem a service or product. + +### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Retrieve Transaction Information + +The logical API service request `Retrieve Transaction Information` is used by a Payer FSP to request that a Payee FSP get information regarding a previously-performed interoperable financial transaction (by using the logical API resource **Transfers**, see [API Resource Tarnsfers](#api-resource-transfers) section). + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transaction Information + +The logical API service response`*Return Transaction Information` is used to return information from the request [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transaction Information Error + +The logical API service error response `Return Transaction Information Error` is used to return error information regarding the request [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +### API Resource Bulk Quotes + +In the API, a _Bulk Quote_ is a collection of individual quotes (see [API Resource Quotes](#api-resource-quotes) section for information regarding a single quote) for performing more than one interoperable financial transaction from the Payer FSP to the Payee FSP. + +The primary purpose of the logical API resource **Bulk Quotes** is for a Payer FSP to request a Payee FSP to calculate the Payee FSP's part of the bulk quote. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Calculate Bulk Quote + +The logical API service request `Calculate Bulk Quote` is used by a Payer FSP to request that a Payee FSP calculate the Payee FSP's part of the quotes to perform more than one interoperable financial transaction. + +The Payee FSP should also create the ILP Packet and the condition (see [Interledger](#interledger) section for links to more information) per quote when receiving the request. + +- Successful response: [Return Bulk Quote Information](#return-bulk-quote-information) + +- Error response: [Return Bulk Quote Information Error](#return-bulk-quote-information-error) + +##### Retrieve Bulk Quote Information + +The logical API service request `Retrieve Bulk Quote Information` is used by a Payer FSP to request that a Payee FSP ask for information regarding a previously-sent [Calculate Bulk Quote](#calculate-bulk-quote) request. + +- Successful response: [Return Bulk Quote Information](#return-bulk-quote-information) + +- Error response: [Return Bulk Quote Information Error](#return-bulk-quote-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Bulk Quote Information + +The logical API service response `Return Bulk Quote Information` is used to return information from the requests [Calculate Bulk Quote](#calculate-bulk-quote) or [Retrieve Bulk Quote Information](#retrieve-bulk-quote-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Bulk Quote Information Error + +The logical API service error response `Return Bulk Quote Information Error` is used to return error information regarding the requests [Calculate Bulk Quote](#calculate-bulk-quote) or [Retrieve Bulk Quote Information](#retrieve-bulk-quote-information). + +
    + +### API Resource Bulk Transfers + +In the API, a _Bulk Transfer_ is a collection of hop-to-hop ILP (see [Interledger.](#interledger)section for links to more information) transfers of funds. The transfers also contain information regarding the end-to-end interoperable financial transactions. + +The primary purpose of the logical API resource **Bulk Transfers** is to enable an FSP or Switch to request that the next entity in the chain of the ILP Payment perform the transfers involved in the interoperable financial transactions. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Bulk Transfer + +The logical API service request `Perform Bulk Transfer` is used by an FSP or Switch to request that the next entity in the chain of the ILP Payment reserve the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Bulk Transfer Information](#return-bulk-transfer-information) + +- Error response: [Return Bulk Transfer Information Error](#return-bulk-transfer-information-error) + + +##### Retrieve Bulk Transfer Information + +The logical API service request `Retrieve Bulk Transfer Information` is used from an FSP or Switch to request that the next entity in the chain of the ILP Payment for information regarding the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Bulk Transfer Information](#return-bulk-transfer-information) + +- Error response: [Return Bulk Transfer Information Error](#return-bulk-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Bulk Transfer Information + +The logical API service response `Return Bulk Transfer Information` is used to return information from the requests [Perform Bulk Transfer](#perform-bulk-transfer) or [Retrieve Bulk Transfer Information](#retrieve-bulk-transfer-information). + +On receiving the response **Return Bulk Transfer Information**, the FSP or Switch should validate the fulfilments (see [Interledger](#interledger) section for links to more information) and commit the reserved transfers if the validations are successful. + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Bulk Transfer Information Error + +The logical API service error response `Return Bulk Transfer Information Error` is used to return error information regarding the requests [Perform Bulk Transfer](#perform-bulk-transfer) or [Retrieve Bulk Transfer Information](#retrieve-bulk-transfer-information). + +
    + +## Generic Transaction Patterns + +This section provides information about the three primary transaction patterns defined in the Interoperability API: + +- [Payer-Initiated Transaction](#payer-initiated-transaction) + +- [Payee-Initiated Transaction](#payee-initiated-transaction) + +- [Bulk Transaction](#bulk-transaction) + +Each transaction pattern defines how funds can be transferred from a Payer located in one Financial Service Provider (FSP) to a Payee located in another FSP. + +Both the [Payer-Initiated Transaction](#payer-initiated-transaction) and the [Payee-Initiated Transaction](#payee-initiated-transaction) patterns are intended for a single transfer of funds from one Payer to one Payee. The significant difference between the two patterns is in which of the participants in the transaction is responsible for the initiation of the transaction. + +The [Bulk Transaction](#bulk-transaction) pattern should be used when a single Payer would like to transfer funds to multiple Payees, possibly in different FSPs, in a single transaction. + +This section also provides information about _Payee-Initiated Transaction using OTP_. which is an alternative to the [Payee-Initiated Transaction](#payee-initiated-transaction). + +Additionally, the section provides high-level information about all logical services that are part of the API. + +
    + +### Payer-Initiated Transaction + +In a _Payer-Initiated Transaction_, the `Payer` initiates the transaction. + +#### Business Process Pattern Description + +The _Payer-Initiated Transaction_ pattern should be used whenever a `Payer` would like to transfer funds to another party whose account is not located in the same FSP. + +In most implementations, `Payee` involvement is limited to receiving a notification in the event of a successful transaction. Exceptions in which the Payee is more involved are: + +- In countries that require the `Payee` to confirm receipt of funds. + +- Cases in which the `Payee` should accept the terms of the transaction (for example, Agent-Initiated Cash-In). + +#### Participants and Roles + +The actors in a _Payer-Initiated Transaction_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + + +The intermediary objects used in a _Payer-Initiated Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + + +#### Business Process Sequence Diagram + +Figure 1 shows the UML sequence diagram for a _Payer-Initiated Transaction_. + +![](../assets/diagrams/sequence/figure64a.svg) + +**Figure 1 -- Payer-Initiated Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in [Figure 1](#business-process-sequence-diagram). + +##### Lookup Counterparty + +1. **Description** + + The `Payer` initiates the transaction by requesting to send funds to a `Payee`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +2. **Description** + + The `Payer FSP` tries to find the `Payee` within the FSP system. Because the `Payee` cannot be found in the `Payer FSP` system, the request [Lookup Party Information](#lookup-party-information) is sent by the `Payer FSP` to the optional `Switch` to get information regarding the `Payee`, including in which FSP the `Payee` is located. + + **Assumptions** + + The Payee is assumed to be in a different FSP than the `Payer`. Also, a `Switch` is assumed to be placed between the `Payer FSP` and the `Payee FSP` to route the messages between FSPs. The `Switch` is optional in the process, as the request [Lookup Party Information](#lookup-party-information) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. As the `Payer FSP` should not know in which FSP the `Payee` is located if there is no `Switch` present, the request might need to be sent to more than one FSP. + +3. **Description** + + The `Switch` receives the request [Lookup Party Information](#lookup-party-information). The `Switch` then tries to find in which FSP the `Payee` is located by sending the request [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + + **Assumptions** + + An `Account Lookup System` is assumed to exist in a different server than the `Switch`. It is possible that the `Account Lookup System` is in the same system as the `Switch`. + +4. **Description** + + The `Account Lookup System` receives the request [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payee` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the Switch about which FSP the `Payee` is located in. + + **Assumptions** + + The `Payee` can be found by the `Account Lookup System`. + +5. **Description** + + The `Switch` receives the response [Return Participant Information](#return-participant-information). As the `Switch` now knows in which FSP the `Payee` is located, the `Switch` sends the request [Lookup Participant Information](#lookup-participant-information) to the `Payee FSP` to get more information about the `Payee`. + + **Assumptions** + + None. + +6. **Description** + + The `Payee FSP` receives the request [Lookup Participant Information](#lookup-participant-information). The `Payee FSP` then does an internal lookup to find more information regarding the `Payee` and sends the response [Return Participant Information](#return-participant-information) to the `Switch`. + + **Assumptions** + + None. + +7. **Description** + + The `Switch` receives the response [Return Party Information](#return-party-information). The `Switch` then routes the [Return Party Information](#return-party-information) response to the `Payer FSP` to send the information about the `Payee`. + + **Assumptions** + + None. + +8. **Description** + + The `Payer FSP` receives the response [Return Party Information](#return-party-information) containing information about the `Payee`. + + **Assumptions** + + None. + +
    + +##### Calculate Quote + +9. **Description** + + Depending on the fee model used, the `Payer FSP` rates the transaction internally and includes the quote information in the request [Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request[Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +10. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +11. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition are then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None. + + **Optional procedure: Quote Confirmation by Payee** + + a. **Description** + + Depending on the use case and the fee model used, the `Payee` might be informed of the quote in order to confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front-end API (outside the scope of this API). The `Payee` receives the quote including information regarding the transaction including fees and optionally `Payer` name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API), and the `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee` FSP to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional procedure** + +12. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +13. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` will then route the response to the `Payer FSP`. + + **Assumptions** + + None. + +14. **Description** + + The `Payer FSP` receives the response[Return Quote Information](#return-quote-information) from the `Switch`. The `Payer FSP` then informs the `Payer` using a front-end API (outside the scope of this API) about the total fees to perform the transaction, along with the `Payee` name. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. Also, the `Payee` name was allowed to be sent during the counterparty lookup (depending on regulation on privacy laws). + +15. **Description** + + The `Payer` receives the transaction information including fees, taxes and optionally `Payee` name. If the `Payer` rejects the transaction, the sequence ends here. + + **Assumptions** + + The `Payer` is assumed to approve the transaction in this sequence. If the `Payer` would reject the transaction at this stage, no response regarding the rejection is sent to the `Payee FSP`. The created quote at the `Payee FSP` should have an expiry time, at which time it is automatically deleted. + +
    + +##### Perform Transfer + +16. **Description** + + The `Payer FSP` receives an approval of the interoperable financial transaction using a front-end API (out of scope of this API). The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the Switch to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + Internal validations and reservation are assumed to be successful. In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +17. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks blacklist check and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Payee FSP`, including the same ILP Packet and condition as was received from the `Payer FSP`. The expiry time should be decreased by the `Switch` so that the `Payee FSP` should answer before the `Switch` answers to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +18. **Description** + + The `Payee FSP` receives the request [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a `Payer FSP` account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API) and the response **Return Transfer Information** is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +19. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +20. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` then uses the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +21. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The `Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +**Optional fragment: Get Transaction Details** + +22. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`, such as a code or a voucher token, the `Payer FSP` can use the request [Return Transfer Information](#return-transfer-information) to get the additional transaction information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the `Switch`. + + **Assumptions** + + None. + +23. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the [Retrieve Transaction Information](#retrieve-transaction-information) request to the `Payee FSP`. + + **Assumptions** + + None. + +24. **Description** + + The `Payee FSP` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and sends the response [Return Transaction Information](#return-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the `Payee FSP`. + +25. **Description** + + The `Switch` receives the response [Return Transaction Information](#return-transaction-information). The Switch then routes the [Return Transaction Information](#return-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +26. **Description** + + The `Payer FSP` receives the response [Return Transaction Information](#return-transaction-information). + + **Assumptions** + + None. + + **End of Optional fragment** + +28. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +29. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Payee-Initiated Transaction + +In a _Payee-Initiated Transaction_, the `Payee` (that is, the recipient of electronic funds) initiates the transaction. + +#### Business Process Pattern Description + +The pattern should be used whenever a `Payee` would like to receive funds from another party whose account is not located in the same FSP. + +In all alternatives to this pattern, the `Payer` must in some way confirm the request of funds. Some possible alternatives for confirming the request are: + +- **Manual approval** -- A transaction request is routed from the Payee to the Payer, the Payer can then either approve or reject the transaction. + +- **Pre-approval of Payee** -- A Payer can pre-approve a specific Payee to request funds, used for automatic approval of, for example, school fees or electric bills. + +Another alternative for approval is to use the business pattern [Payee-Initiated Transaction using OTP](#payee-initiated-transaction-using-otp). + +#### Participants and Roles + +The actors in a _Payee-Initiated Transaction_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + +The intermediary objects used in a _Payee-Initiated Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + +#### Business Process Sequence Diagram + +Figure 2 shows the UML sequence diagram for a _Payee-Initiated Transaction_. + +![](../assets/diagrams/sequence/figure65a.svg) + +**Figure 2 -- Payee-Initiated Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 2 above. + +##### Lookup Counterparty + +1. **Description** + + The `Payee` initiates the transaction by requesting to receive funds from a `Payer`, using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +2. **Description** + + The `Payee FSP` tries to find the Payer within the FSP system. Because the `Payer` cannot be found in the `Payee FSP` system, the `Payee FSP` sends the request to the optional `Account Lookup System` to get information regarding in which FSP the `Payer` is located. + + **Assumptions** + + The `Payer` is assumed to be located in a different FSP than the `Payee`. Also, an `Account Lookup System` is assumed to exist. + + The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the` Payer FSP` if there is no `Account Lookup System`. As the `Payee FSP` should not know in which FSP the Payer is located if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payee FSP` would like more information about the `Payer` before a transaction request is sent; in that case the request [Lookup Participant Information](#lookup-participant-information), either to the Switch or directly to the `Payer FSP`, should be sent instead of [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +3. **Description** + + The `Account Lookup System` receives the [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payer` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the `Payee FSP` about which FSP the `Payer` is located. + + **Assumptions** + + The `Payer` can be found by the `Account Lookup System`. + +4. **Description** + + The `Payee FSP` receives the response [Return Participant Information](#return-participant-information). + + **Assumptions** + + None. + + **Transaction Request** + +5. **Description** + + The `Payee FSP` sends the request [Perform Transaction Request](#perform-transaction-request) to the `Switch`. The request contains the transaction details including the amount that the Payee would like to receive. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payee FSP` and the `Payer FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transaction Request](#perform-transaction-request) could also be sent directly to the `Payer FSP` if there is no Switch in-between. + +6. **Description** + + The `Switch` receives the [Perform Transaction Request](#perform-transaction-request). The `Switch` then routes the request to the `Payer FSP`, using the same parameters. + + **Assumptions** + + None. + +7. **Description** + + The `Payer FSP` receives the request [Perform Transaction Request](#perform-transaction-request). The `Payer FSP` then optionally validates the transaction request (for example, whether the `Payer` exists) and uses the response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` via the `Switch` that the transaction request has been received. + + **Assumptions** + + The optional validation succeeds. + +8. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information). The `Switch` then sends the same response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` about the successfully delivered transaction request to the `Payer FSP`. + + **Assumptions** + + None. + +9. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Switch`. + + **Assumptions** + + None. + +
    + +##### Calculate Quote + +10. **Description** + + The `Payer FSP` rates the transaction internally based on the fee model used and includes the quote information in the request[Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details, including a reference to the earlier sent transaction request, are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +11. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`. + + **Assumptions** + + None. + +12. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition are then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None + +13. **Description** + + Depending on use case and the fee model used, the `Payee` might be informed of the quote so that the `Payee` can confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front-end API (outside the scope of this API). The `Payee` receives the quote including information regarding the transaction including fees and optionally Payer name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API). The `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The quote is assumed to be sent to the `Payer` for confirmation, and the `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee FSP` to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional fragment** + +14. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +15. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` then routes the response to the `Payer FSP`. + + **Assumptions** + + None. + +16. **Description** + + The `Payer FSP` receives the response [Return Quote Information](#return-quote-information) from the `Switch`. The `Payer FSP` then informs the `Payer` using a front-end API (outside the scope of this API) about the transaction request from the `Payee`, including the amount and the total fees required to perform the transaction, along with the `Payee` name. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. Also, the `Payee` name was allowed to be sent during the counterparty lookup (depending on regulation on privacy laws). + +17. **Description** + + The `Payer` receives the transaction request information including fees, taxes and optionally `Payee` name. + + **Assumptions** + + If the `Payer` rejects the transaction request, the sequence proceeds to Step 18. If the `Payer` approves the transaction request, the sequence proceeds to Step 22. + + **Alternative: Transaction Rejection** + +18. **Description** + + The `Payer FSP` receives the rejection of the transaction request using a front-end API (out of scope of this API). The `Payer FSP` then uses the response [Return Transaction Request Information](#return-transaction-request-information) with a rejected status to inform the `Switch` that the transaction was rejected. + + **Assumptions** + + The `Payer` is assumed to reject the transaction request in Step 17. + +19. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Payer FSP`. The `Switch` then routes the response [Return Transaction Request Information](#return-transaction-request-information) to the `Payee FSP`. + + **Assumptions** + + None. + +20. **Description** + + The `Payee FSP` receives the response *[Return Transaction Request Information](#return-transaction-request-information) with a rejected status from the `Switch`. The `Payee FSP` then informs the Payee using a front-end API (outside the scope of this API) about the rejected transaction request. + + **Assumptions** + + None. + +21. **Description** + + The `Payee` receives the notification that the transaction was rejected. The process ends here as the transaction request was rejected and the `Payee` has been informed of the decision. + + **Assumptions** + + None. + + **Alternative: Perform Transfer** + +22. **Description** + + The `Payer FSP` receives an approval of the interoperable financial transaction using a front-end API (out of scope of this API). The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the `Switch` to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + The `Payer` is assumed to approve the transaction request in Step 17. Internal validations and reservation are assumed to be successful. In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +23. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Payee FSP`, including the same ILP Packet and condition as was received from the Payer FSP. The expiry time should be decreased by the `Switch`, so that the `Payee FSP` should answer before the `Switch` should answer to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +24. **Description** + + The `Payee FSP` receives the request [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a `Payer FSP` account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the Payee using a front-end API (out of scope of this API) and the response [Return Transfer Information](#return-transfer-information) is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +25. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +26. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` then uses the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +27. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The `Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + + **Optional fragment: Get Transaction Details** + +28. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`; for example, a code or a voucher token, the `Payer FSP` can use the request [Retrieve Transaction Information](#retrieve-transaction-information) to get the additional information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the `Switch`. + + **Assumptions** + + None. + +29. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the request [Retrieve Transaction Information](#retrieve-transaction-information) to the `Payee FSP`. + + **Assumptions** + + None. + +30. **Description** + + The `Payee FSP` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and uses the response [Retrieve Transaction Information](#retrieve-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the Payee FSP. + +31. **Description** + + The `Switch` receives the response [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the [Retrieve Transaction Information](#retrieve-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +32. **Description** + + The `Payer FSP` receives the response [Retrieve Transaction Information](#retrieve-transaction-information) from the `Switch`. + + **Assumptions** + + None. + + **End of Optional fragment** + +33. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +34. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Payee-Initiated Transaction using OTP + +A _Payee-Initiated Transaction using OTP_ is very similar to a [Payee-Initiated Transaction](#payee-initiated-transaction), but the transaction information (including fees and taxes) and approval for the `Payer` is shown/entered on a `Payee` device instead. + +#### Business Process Pattern Description + +The pattern should be used when a `Payee` would like to receive funds from another party whose account is not located in the same FSP, and both the transaction information (including fees and taxes) and approval is shown/entered on a `Payee` device instead. + +- **Approval using OTP** -- A `Payer` can approve a transaction by first creating an OTP in his/her FSP. An alternative to user- initiated creation of OTP is that the OTP is automatically generated and sent by the `Payer FSP`. The same OTP is then entered by the `Payer` in a `Payee` device, usually a POS device or an ATM. The OTP in the transaction request is automatically matched by the `Payer FSP` to either approve or reject the transaction. The OTP does not need to be encrypted as it should only be valid once during a short time period. + +#### Participants and Roles + +The actors in a _Payee-Initiated Transaction using OTP_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + +The intermediary objects used in a _Payee-Initiated Transaction using OTP_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + +#### Business Process Sequence Diagram + +Figure 3 shows the UML sequence diagram for a _Payee-Initiated Transaction using OTP_. + +![](../assets/diagrams/sequence/figure66a.svg) + +**Figure 3 -- Payee-Initiated Transaction using OTP** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 3 above. + +##### Optional fragment: Manual OTP request + +1. **Description** + + The `Payer` requests that an OTP be generated, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + There are two alternatives for generating an OTP; either it is generated upon request by the `Payer` (this option), or it is automatically generated in Step 19. + +2. **Description** + + The `Payer FSP` receives the request to generate an OTP and returns a generated OTP to the `Payer`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +3. **Description** + + `Payer` receives the generated OTP. The OTP can then be used by the `Payer` in Step 25 for automatic approval. + + **Assumptions** + + None. + + **End of Optional fragment** + +###### Lookup Counterparty + +4. **Description** + + The `Payee` initiates the transaction by requesting to receive funds from a `Payer`, using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +5. **Description** + + The `Payee FSP` tries to find the `Payer` within the FSP system. Because the `Payer` cannot be found in the `Payee FSP` system, the request **Lookup Participant Information** is sent by the `Payee FSP` to the optional Account Lookup System to get information regarding in which FSP the Payer is located. + + **Assumptions** + + The `Payer` is assumed to be in a different FSP than the `Payee`. Also, an `Account Lookup System` is assumed to exist. The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the `Payer FSP` if there is no `Account Lookup System`. As the `Payee FSP` should not know in which FSP the `Payer` is located if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payee FSP` would like more information about the Payer before a transaction request is sent; in that case the request [Lookup Party Information](#lookup-party-information), either to the `Switch` or directly to the `Payer FSP`, should be sent instead of [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +6. **Description** + + The `Account Lookup System` receives the [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payer` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the `Payee FSP` about which FSP the `Payer` is located in. + + **Assumptions** + + The `Payer` can be found by the `Account Lookup System`. + +7. **Description** + + The `Payee FSP` receives the response [Return Participant Information](#return-participant-information). + + **Assumptions** + + None. + +##### Transaction Request + +8. **Description** + + The Payee FSP sends the request [Perform Transaction Request](#perform-transaction-request) to the `Switch`. The request contains the transaction details including the amount that the `Payee` would like to receive, and that the request should be validated using an OTP (possibly a QR code containing a OTP). + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payee FSP` and the `Payer FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transaction Request](#perform-transaction-request) could also be sent directly to the `Payer FSP` if there is no `Switch` in-between. + +9. **Description** + + The `Switch` receives the request [Perform Transaction Request](#perform-transaction-request). The `Switch` then routes the request to the `Payer FSP`, using the same parameters. + + **Assumptions** + + None. + +10. **Description** + + The `Payer FSP` receives the request [Perform Transaction Request](#perform-transaction-request). The `Payer FSP` then optionally validates the transaction request (for example, whether the `Payer` exists or not) and sends the response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` via the `Switch` that the transaction request has been received. + + **Assumptions** + + The optional validation succeeds. + +11. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information). The `Switch` then uses the same response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` about the successfully delivered transaction request to the `Payer FSP`. + + **Assumptions:** + + None. + +12. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Switch`. + + **Assumptions** + + None. + + **Calculate Quote** + +13. **Description** + + The `Payer FSP` rates the transaction internally based on the fee model used and includes the quote information in the request [Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details, including a reference to the transaction request, are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +14. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +15. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition is then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None. + + **Optional fragment: Quote Confirmation by Payee** + +16. **Description** + + Depending on the fee model used and which use case it is, the `Payee` might be informed of the quote to be able to confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front- end API (outside the scope of this API. The `Payee` receives the quote including information regarding the transaction including fees and optionally `Payer` name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API). The `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The quote is assumed to be sent to the Payer for confirmation, and the `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee FSP` to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional fragment** + +17. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +18. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` will then route the request to the `Payer FSP`. + + **Assumptions** + + None. + +19. **Description** + + The `Payer FSP` receives the response [Return Quote Information](#return-quote-information) from the Switch. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. + + **Optional fragment: Automatic OTP generation** + +20. **Description** + + The `Payer FSP` automatically generates an OTP and sends it to the `Payer`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + There are two alternatives for generating the OTP. Either it is generated upon request by the `Payer` (Step 1), or it is automatically generated (this option). + +21. **Description** + + The `Payer` receives the automatically-generated OTP. + + **Assumptions** + + None. + + **End of Optional fragment** + +22. **Description** + + The `Payer FSP` sends the request [Perform Authorization](#perform-authorization) to the `Switch`, to get an authorization to perform the transaction from the Payer via a POS, ATM, or similar payment device, in the `Payee FSP`. The request includes the amount to be withdrawn from the `Payer`'s account, and how many retries are left for the `Payer` to retry the OTP. + + **Assumptions** + + None. + +23. **Description** + + The `Switch` receives the request [Perform Authorization](#perform-authorization) from the `Payer FSP`. The `Switch` then routes the [Perform Authorization](#perform-authorization) to the `Payee FSP`. + + **Assumptions** + + None. + +24. **Description** + + The `Payee FSP` receives the request [Perform Authorization](#perform-authorization) from the `Switch`. The `Payee FSP` sends the authorization request to the `Payee` device (POS, ATM, or similar payment device) using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +25. **Description** + + The `Payee` device receives the authorization request, and the `Payer` can see the amount that will be withdrawn from his or her account. The `Payer` then uses the OTP received in Step 3 or Step 21, depending on whether the OTP was manually requested or automatically generated. The entered or scanned OTP is then sent to the `Payee FSP` using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + The `Payer` has received the OTP in Step 3 or Step 21. + +26. **Description** + + The `Payee FSP` receives the OTP from the `Payee` device. The `Payee FSP` then sends the response [Return Authorization Result](#return-authorization-result) to the Switch containing the OTP from the Payer. + + **Assumptions** + + None. + +27. **Description** + + The `Switch` receives the request [Return Authorization Result](#return-authorization-result) from the `Payee FSP`. The `Switch` then routes the [Return Authorization Result](#return-authorization-result) to the `Payer FSP`. + + **Assumptions** + + None. + +28. **Description** + + The `Payer FSP` receives the request [Return Authorization Result](#return-authorization-result) to the `Switch`. The `Payer FSP` then validates the OTP received from the OTP generated in Step 2 or Step 20. If the `Payer FSP` is unable to validate the OTP (for example, because the OTP is incorrect) and this was the last remaining retry for the Payer, the sequence continues with Step 29. If the `Payer FSP` correctly validates the OTP, the sequence continues with Step 33. + + **Assumptions** + + None. + + **Alternative: OTP validation failed** + +29. **Description** + + The validation in Step 28 fails and this was the final retry for the Payer. The `Payer FSP` then uses the response [Return Transaction Request Information](#return-transation-request-information) with a rejected state to inform the `Switch` that the transaction was rejected. + + **Assumptions** + + The OTP validation in Step 28 is assumed to fail and no more retries remains for the Payer. + +30. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transation-request-information) from the Payer FSP. The `Switch` then routes the [Return Transaction Request Information](#return-transation-request-information) response to the `Payee FSP`. + + **Assumptions** + + None. + +31. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transation-request-information) with a rejected status from the `Switch`. The `Payee FSP` then informs the `Payee` using a front-end API (outside the scope of this API) about the rejected transaction request. + + **Assumptions** + + None. + +32. **Description** + + The `Payee` receives the notification that the transaction was rejected. The process ends here as the transaction request was rejected and the `Payee` has been informed of the decision. The `Payer` is also assumed to receive the notification via the `Payee` device. + + **Assumptions** + + None. + + **Alternative: OTP validation succeed** + +33. **Description** + + The validation in Step 28 is successful. The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined Switch account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the `Switch` to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + The OTP validation in Step 28 is assumed to be successful. Internal validations and reservation are assumed to be successful. In this sequence, a Switch is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no Switch in-between. + + 34. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the Payee FSP, including the same ILP Packet and condition as was received from the Payer FSP. The expiry time should be decreased by the Switch so that the `Payee FSP` should answer before the Switch should answer to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +35. **Description** + + The `Payee FSP` receives the [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct, and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a Payer FSP account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API) and the response [Return Transfer Information](#return-transfer-information) is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +36. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +37. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` will then use the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +38. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The` Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + + **Optional fragment: Get Transaction Details** + +39. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`, such as a code or a voucher token, the `Payer FSP` can use the request [Retrieve Transaction Information](#retrieve-transaction-information) to get the additional information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the Switch. + + **Assumptions** + + None. + +40. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the request[Retrieve Transaction Information](#retrieve-transaction-information) to the `Payee FSP`. + + **Assumptions** + + None. + +41. **Description** + + The `Payee FSP` receives the request *[Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and uses the response [Return Transaction Information](#return-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the `Payee FSP`. + +42. **Description** + + The `Switch` receives the response [Return Transaction Information](#return-transaction-information). The `Switch` then routes the [Return Transaction Information](#return-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +43. **Description** + + The `Payer FSP` receives the response [Return Transaction Information](#return-transaction-information) from the `Switch`. + + **Assumptions** + + None. + + **End of Optional fragment** + +44. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +45. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Bulk Transactions + +In a _Bulk Transaction_, the `Payer` (that is, the sender of funds) initiates multiple transactions to multiple Payees, potentially located in different FSPs. + +#### Business Process Pattern Description + +The pattern should be used whenever a `Payer` would like to transfer funds to multiple Payees in the same transaction. The Payees can potentially be located in different FSPs. + +#### Participants and Roles + +The actors in a _Bulk Transaction_ are: + +- **Payer** -- The sender of funds. + +- **Payees** -- The recipients of funds. There should be multiple Payees in a _Bulk Transaction_. + +The intermediary objects used in a _Bulk Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of transactions between different FSPs. This object can be removed if transactions should be routed directly between a Payer and `Payee FSP`. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which a Payee's account is located. There may be multiple Payee FSPs in a _Bulk Transaction_. + +#### Business Process Sequence Diagram + +Figure 4 below shows the UML sequence diagram for a _Bulk Transaction_. + +![](../assets/diagrams/sequence/figure67a.svg) + +**Figure 4 -- Bulk Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 4. + +##### Lookup Counterparties + +1. **Description** + + The `Payer` initiates the bulk transaction process by uploading a bulk file to the `Payer FSP`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + + **Loop for each Transaction in bulk file** + +2. **Description** + + `Payer FSP` tries to find the Payee within the `Payer FSP` system. + + **Assumptions** + + The `Payee` is assumed to be located in a different FSP than the `Payer`. If the `Payee` is within the `Payer FSP`, the transaction can be handled internally in the `Payer FSP` (outside the scope of this API). + +3. **Description** + + The `Payer FSP` sends the request [Lookup Participant Information](#lookup-participant-information) to the optional `Account Lookup System` to get information regarding in which FSP the `Payer` is present in. + + **Assumptions** + + The `Payee` is assumed to in a different FSP than the `Payer`. Also, an `Account Lookup System` is assumed to exist. The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the `Payee FSP`s if there is no `Account Lookup System`. As the `Payer FSP `should not know in which FSP the `Payee` is located in if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payer FSP` would like more information about the `Payee` before a bulk transaction is executed; for example, for additional verification purposes of the `Payee` name. In that case, the request [Lookup Party Information](#lookup-party-information), either to the `Switch` or directly to the `Payee FSP`, should be sent instead of the request [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +4. **Description** + + The `Account Lookup System` receives the request [Lookup Participant Information](#lookup-participant-information) It then performs an internal lookup to find in which FSP the `Payee` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the Payer FSP about which FSP the `Payee` is located in. + + **Assumptions** + + The `Payee` can be found by the `Account Lookup System`. + +5. **Description** + + The `Payer FSP` receives the response [Return Participant Information](#return-participant-information). The `Payee` and the related transaction is then placed in a new bulk file separated per `Payee FSP`. + + **Assumptions** + + None. + + **End of loop for each Transaction** + +##### Calculate Bulk Quote + + **Loop for each `Payee FSP` to Calculate Bulk Quote** + +6. **Description** + + The `Payer FSP` uses the request [Calculate Bulk Quote](#calculate-bulk-quote) on a `Switch` to retrieve a quote for performing the bulk transaction from the `Payer FSP` to the `Payee FSP`. The request contains details for each individual transaction in the bulk transaction. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Calculate Bulk Quote](#calculate-bulk-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +7. **Description** + + The `Switch` receives the [Calculate Bulk Quote](#calculate-bulk-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +8. **Description** + + The `Payee FSP` receives the [Calculate Bulk Quote](#calculate-bulk-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing each individual transaction in the bulk transaction. For each individual transaction, the `Payee FSP` then constructs an ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition is then generated out of the ILP Packet combined with a local secret. It then uses the response [Return Bulk Quote Information](#return-bulk-quote-information) to the `Switch` to inform the `Payer FSP` about the fees involved in performing the bulk transaction and the ILP Packet and condition. The bulk quote has an expiration date and time, to inform the `Payer FSP` until which time the bulk quote is valid. + + **Assumptions** + + The bulk quote can be calculated by the `Payee FSP`. + +9. **Description** + + The Switch receives the response [Return Bulk Quote Information](#return-bulk-quote-information). The `Switch` then routes the response to the Payer FSP. + + **Assumptions** + + None. + +10. **Description** + + The `Payer FSP` receives the response [Return Bulk Quote Information](#return-bulk-quote-information) from the `Switch`. + + **Assumptions** + + None. + + **End of loop for each `Payee FSP`** + +11. **Description** + + The `Payer FSP` calculates any internal bulk fees and taxes, and informs the `Payer` using a front-end API (outside the scope of this API) about the total fees and taxes to perform the bulk transaction. + + **Assumptions** + + None. + +12. **Description** + + The `Payer` receives the notification about the completed processing of the bulk transaction and the fees and taxes to perform the bulk transaction. The `Payer` then decides to execute the bulk transaction. + + **Assumptions** + + The `Payer` is assumed to execute the bulk transaction. If the `Payer` would reject the bulk transaction at this stage, no response is sent to the `Payee FSP`. The created bulk quote at the `Payee FSP`s should have an expiry date; that is, at which time it's automatically deleted. + +##### Perform Bulk Transfer** + +13. **Description** + + The `Payer FSP` receives the request to execute the bulk transaction from the `Payer`. + + **Assumptions** + + None. + + **Loop for each `Payee FSP` to perform Bulk Transfer** + +14. **Description** + + The `Payer FSP` performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on) for the bulk transaction to the `Payee FSP`. If the validations are successful, a transfer of funds is reserved from the Payer's account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Bulk Transfer](#perform-bulk-transfer) is sent to the `Switch`. The request [Perform Bulk Transfer](#perform-bulk-transfer) includes a reference to the earlier bulk quote, an expiry of the bulk transfer, and the ILP Packets and condition per transfer that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the Payer FSP. The interoperable bulk transaction is now irrevocable from the Payer FSP. + + **Assumptions** + + In this sequence, a Switch is placed between the `Payer FSP `and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request *[Perform Bulk Transfer](#perform-bulk-transfer) could also be sent directly to the `Payee FSP` if there is no Switch in-between. + +15. **Description** + + The Switch receives the request [Perform Bulk Transfer](#perform-bulk-transfer). The Switch then performs all applicable internal transfer validations (such as limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a Payer FSP account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Bulk Transfer](#perform-bulk-transfer) is sent to the `Payee FSP`, including the same ILP Packets and conditions for each transfer that were received from the `Payer FSP`. The expiry time should be decreased by the Switch so that the `Payee FSP` should answer before the Switch should answer to the `Payer FSP`. The bulk transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +16. **Description** + + The `Payee FSP` receives the request [Perform Bulk Transfer](#perform-bulk-transfer). The `Payee FSP` then performs all applicable internal transaction validations (such as limit checks, and blacklist checks) for each individual transaction in the bulk transaction. If the validations are successful, a transfer of funds is performed from either a combined Switch account or a `Payer FSP` account, depending on setup, to each of the Payees' accounts and the fulfilment of each condition is regenerated, using the same secret as in Step 8. After each transfer to a `Payee` has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API). After each of the individual transactions in the bulk transaction has been completed, the response [Return Bulk Transfer Information](#return-bulk-transfer-information) is sent to the Switch to inform the Switch and the Payer FSP of the result including each fulfilment. The transactions in the bulk transaction are now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfers of funds are successful. + +17. **Description** + + Each `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +18. **Description** + + The `Switch` receives the response [Return Bulk Transfer Information](#return-bulk-transfer-information). The `Switch` then validates the fulfilments and commits the earlier reserved transfers. The `Switch` then uses the response [Return Bulk Transfer Information](#return-bulk-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + Each individual transaction in the bulk transaction is assumed to be successful in the `Payee FSP`, and the validation of the fulfilments is also assumed to be correct. If one or more of the transactions in the bulk transaction were unsuccessful, the earlier reserved, now unsuccessful, transfer or transfers in the `Switch` would need to be cancelled. + +19. **Description** + + The `Payer FSP` receives the response [Return Bulk Transfer Information](#return-bulk-transfer-information). The `Payer FSP` then commits the earlier reserved transfers. After the bulk transaction has been successfully committed, a transaction notification is sent to the `Payer` using a front-end API (out of scope of this API). + + **Assumptions** + + Each individual transaction in the bulk transaction is assumed to be successful in the `Payee FSP`, and the validation of the fulfilments is also assumed to be correct. If one or more of the transactions in the bulk transaction were unsuccessful, the earlier reserved transfer in the `Payer FSP` would need to be updated with the total amount of all successful transactions before being committed. + + **End of loop for each `Payee FSP`** + +20. **Description** + + After each of the `Payee FSP`s has executed their part of the bulk transaction, a response is sent to the Payer using a front- end API (out of scope for this API). + + **Assumptions** + + None. + +21. **Description** + + The `Payer` receives a bulk transaction notification containing information about the successfully performed bulk transaction. + + **Assumptions** + + None. + +## References + +1 [https://interledger.org/rfcs/0011-interledger-payment-request/ - Interledger Payment Request (IPR)](https://interledger.org/rfcs/0011-interledger-payment-request) + +2 [https://interledger.org/ - Interledger](https://interledger.org) + +3 [https://interledger.org/interledger.pdf - A Protocol for Interledger Payments](https://interledger.org/interledger.pdf) + +4 [https://interledger.org/rfcs/0001-interledger-architecture/ - Interledger Architecture](https://interledger.org/rfcs/0001-interledger-architecture) + + + +**List of Figures** + +[Figure 1 -- Payer-Initiated Transaction](#443-business-process-sequence-diagram) + +[Figure 2 -- Payee-Initiated Transaction](#423-business-process-sequence-diagram) + +[Figure 3 -- Payee-Initiated Transaction using OTP](#433-business-process-sequence-diagram) + +[Figure 4 -- Bulk Transaction](#443-business-process-sequence-diagram) diff --git a/docs/technical/api/fspiop/glossary.md b/docs/technical/api/fspiop/glossary.md new file mode 100644 index 000000000..cce7b8bf7 --- /dev/null +++ b/docs/technical/api/fspiop/glossary.md @@ -0,0 +1,286 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Glossary + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +| **Type of Information** | **Convention** | **Example** | +| :--- | :--- | :--- | +| **Elements of the API, such as resources** | Boldface | **/authorization** | +| **Variables** | Italics within curled brackets | _{ID}_ | +| **Glossary** | Italics on first occurrence; defined in _Glossary_ | The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of **terms** electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. | +| **Library documents** | Italics | User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +| **Version** | **Date** | **Change Description** | +| :--- | :--- | :--- | +| **1.0** | 2018-03-13 | Initial version | + +
    + +## Introduction + +This document provides the glossary for the Open API for FSP Interoperability Specification. Terms have been compiled from three sources: + +- ITU-T Digital Financial Services Focus Group Glossary (ITU-T)[ITU-T Digital Financial Services Focus Group Glossary (ITU-T)](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-E.pdf), + +- Feedback from Technology Service Providers (TSPs) in the Product Development Partnership (PDP) work groups, and + +- Feedback from the L1P IST Reference Implementation team (RI). + +Information is shared in accordance with Creative Commons Licensing[LICENSE](https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md). + + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](#) + +
    + + +## API Glossary + +| **Term** | **Alternative and Related Terms** | **Definition** | **Source** | +| --- | --- | --- | --- | +| **Access Channel** | POS ("Point of Sale"), Customer Access Point, ATM, Branch, MFS Access Point | Places or capabilities that are used to initiate or receive a payment. Access channels can include bank branch offices, ATMs, terminals at the POS, agent outlets, mobile phones, and computers. | ITU-T | +| **Account ID** | | A unique identifier assigned by the FSP that created the account. | PDP | +| **Account Lookup System** | | Account Lookup System is an abstract entity used for retrieving information regarding in which FSP an account, wallet, or identity is hosted. The Account Lookup System itself can be hosted in its own server, as part of a financial switch, or in the different FSPs. | PDP | +| **Active User** | | A term used by many providers in describing how many of their account holders are frequent users of their service. | +| **Agent** | Agent Til , Agent Outlet | An entity authorized by the provider to handle various functions such as customer enrollment, cash-in and cash-out using an agent til . | ITU-T | +| **Agent Outlet** | Access Point | A physical location that carries one or more agent tills, enabling it to perform enrollment, cash-in, and cash-out transactions for customers on behalf of one or more providers. National law defines whether an agent outlet may remain exclusive to one provider. Agent outlets may have other businesses and support functions. | ITU-T | +| **Agent Till** | Registered Agent | An agent till is a provider-issued registered “line”, either a special SIM card or a POS machine, used to perform enrollment, cash-in and cash-out transactions for clients. National law dictates which financial service providers can issue agent tills. | ITU-T | +| **Aggregator** | Merchant Aggregator | A specialized form of a merchant services provider, who typically handles payment transactions for a large number of small merchants. Scheme rules often specify what aggregators are allowed to do. | ITU-T | +| **Anti-Money Laundering** | AML; also "Combating the Financing of Terrorism", or CFT | Initiatives to detect and stop the use of financial systems to disguise the use of funds that have been criminally obtained. | ITU-T | +| **API** | Application Programming Interface | A set of clearly defined methods of communication to allow interaction and sharing of data between different software programs. |PDP | +| **Arbitration** | | The use of an arbitrator, rather than courts, to resolve disputes. | ITU-T | +| **Authentication** | Verification, Validation | The process of ensuring that a person or a transaction is valid for the process (account opening, transaction initiation, and so on) being performed. | ITU-T | +| **Authorization** | | A process used during a "pull" payment (such as a card payment), in which the payee requests (through their provider) confirmation from the payer's bank that the transaction is good. | ITU-T | +| **Authorized /institution entity** | | Non-financial institutions that have followed the appropriate authorization by State Bank and/or relevant regulatory authorities to partake in the provisioning of mobile financial services. | PDP | +| **Automated Clearing House** | ACH | An electronic clearing system in which payment orders are exchanged among payment service providers, primarily via magnetic media or telecommunications networks, and then cleared amongst the participants. All operations are handled by a data processing center. An ACH typically clears credit transfers and debit transfers, and in some cases also cheques. | ITU-T | +| **Bank** | Savings Bank, Credit Union, Payments Bank | A chartered financial system within a country that has the ability to ITU-T accept deposits and make and receive payments into customer accounts. | ITU-T | +| **Bank Accounts and Transaction Services** | Mobile Banking, Remote Banking, Digital Banking| A transaction account held at a bank. This account may be accessible by ITU-T a mobile phone, in which case it is sometimes referred to as "mobile banking".| ITU-T | +| **Bank-Led Model** | Bank-Centric Model| A reference to a system in which banks are the primary providers of digital financial services to end users. National law may require this. | ITU-T | +| **Basic Phone** | | Minimum device required to use digital financial services. | PDP | +| **Bill Payment** | C2B, Utility Payments, School Payments | Making a payment for a recurring service, either in person ("face to face") or remotely. | ITU-T | +| **Biometric Authentication** | | The use of a physical characteristic of a person (fingerprint, IRIS, and so on) to authenticate that person. | ITU-T | +| **Biometric Authentication** | | Any process that validates the identity of a user who wishes to sign into a system by measuring some intrinsic characteristic of that user. | ITU-T | +| **Blacklist** | | A list or register of entities (registered users) that are being denied/blocked from a particular privilege, service, mobility, access or recognition. Entities on the list will not be accepted, approved and or recognized. It is the practice of identifying entities that such entities are denied, unrecognized, or ostracized. Where entities are registered users (or user accounts, if granularity allows) and services are informational (for example, balance check), transactional (for example, debit/credit) payments services or lifecycle (for example, registration, closure) services. | PDP | +| **Blockchain** | Digital Currency, Cryptocurrency, Distributed Ledger Technology| The technology underlying bitcoin and other cryptocurrencies—a shared digital ledger, or a continually updated list of all transactions.| ITU-T | +| **Borrowing** | | Borrowing money to finance a short-term or long-term need. | ITU-T | +| **Bulk Payments** | G2C, B2C, G2P, Social Transfers| Making and receiving payments from a government to a consumer: benefits, cash transfers, salaries, pensions, and so on | ITU-T | +| **Bulk Payment Services** | | A service which allows a government agency or an enterprise to make payments to a large number of payees - typically consumers but can be businesses as well | ITU-T | +| **Bulk upload service** | | A service allowing the import of multiple transactions per session, most often via a bulk data transfer file which is used to initiate payments. Example: salary payment file. | ITU-T | +| **Bundling** | Packaging, Tying | A business model in which a provider which groups a collection of services into one product which an end user agrees to buy or use.| ITU-T | +| **Business** | | Entity such as a public limited or limited company or corporation that uses mobile money as a service; for example, making and accepting bill payments and disbursing salaries.| PDP | +| **Cash Management** | Agent Liquidity Management | Management of cash balances at an agent. | ITU-T | +| **Cash-In** | CICO (Cash-In Cash-Out) | Receiving eMoney credit in exchange for physical cash - typically done at an agent. | ITU-T | +| **Cash-Out** | CICO (Cash-In Cash-Out) | Receiving physical cash in exchange for a debit to an eMoney account - typically done at an agent. | ITU-T | +| **Certificate Signing Request** | CSR | Message sent from an applicant to a Certificate Authority in order to apply for a digital identity certificate. | | +| **Chip Card** | EMV Chip Card, Contactless Chip Card | A chip card contains a computer chip: it may be either contactless or contact (requires insertion into terminal). Global standards for chip cards are set by EMV. | ITU-T | +| **Clearing** | | The process of transmitting, reconciling, and, in some cases, confirming transactions prior to settlement, potentially including the netting of transactions and the establishment of final positions for settlement. Sometimes this term is also used (imprecisely) to cover settlement. For the clearing of futures and options, this term also refers to the daily balancing of profits and losses and the daily calculation of collateral requirements. | RI | +| **Clearing House** | | A central location or central processing mechanism through which financial institutions agree to exchange payment instructions or other financial obligations (for example, securities). The institutions settle for items exchanged at a designated time based on the rules and procedures of the clearinghouse. In some cases, the clearinghouse may assume significant counterparty, financial, or risk management responsibilities for the clearing system.| ITU-T | +| **Client Authentication** | TLS | A client authentication certificate is a certificate used to authenticate clients during an SSL handshake. It authenticates users who access a server by exchanging the client authentication certificate. ... This is to verify that the client is who they claim to be (Source: Techopedia). | | +| **Closed-Loop** | | A payment system used by a single provider, or a very tightly constrained group of providers.| ITU-T | +| **Combatting Terrorist Financing** | | Initiatives to detect and stop the use of financial systems to transfer funds to terrorist organizations or people. | ITU-T | +| **Commission** | | An incentive payment made, typically to an agent or other intermediary who acts on behalf of a DFS provider. Provides an incentive for agent. | ITU-T | +| **Commit** | | Part of a 2-phase transfer operation in which the funds that were reserved to be transferred, are released to the payee; the transfer is completed between the originating/payer and destination/payee accounts. | PDP | +| **Condition** | | In the Interledger protocol, a cryptographic lock used when a transfer is reserved. Usually in the form of a SHA-256 hash of a secret preimage. When provided as part of a transfer request the transfer must be reserved such that it is only committed if the fulfillment of the condition (the secret preimage) is provided. | PDP | +| **Counterparty** | Payee, Payer, Borrower, Lender | The other side of a payment or credit transaction. A payee is the counterparty to a payer, and vice-versa. | ITU-T | +| **Coupon** | | A token that entitles the holder to a discount or that may be exchanged for goods or services.| PDP | +| **Credit History** | Credit Bureaus, Credit Files | A set of records kept for an end user reflecting their use of credit, including borrowing and repayment. | ITU-T | +| **Credit Risk Management** | | Tools to manage the risk that a borrower or counterparty will fail to meet its obligations in accordance with agreed terms. | ITU-T | +| **Credit Scoring** | | A process which creates a numerical score reflecting credit worthiness. | ITU-T | +| **Cross Border Trade Finance Services** | | Services which enable one business to sell or buy to businesses or individuals in other countries; may include management of payments transactions, data handling, and financing. | ITU-T | +| **Cross-FX Transfer** | | Transfer involving multiple currencies including a foreign exchange calculation.| PDP | +| **Customer Database Management** | | The practices that providers do to manage customer data: this may be enabled by the payment platform the provider is using. | ITU-T | +| **Customer Financial Data** | Customer Financial Data | Means a set of financial information of the customer, which includes account balances, deposits and data relating to financial transactions, and so on | PDP | +| **Data Controller** | Data Controller | Data Controller shall mean any person, public authority, agency or any other body which alone or jointly with others determines the purposes and means of the processing of personal data; where the purposes and means of processing are determined by national or Community laws or regulations, the controller or the specific criteria for his nomination may be designated by national or Community law. Also, Data Controller is responsible for providing a secure infrastructure in support of the data, including, but not limited to, providing physical security, backup and recovery processes, granting authorized access privileges and implementing and administering controls. | PDP | +| **Data Portability** | Data Portability | Data Portability shall mean a data subject’s ability to request a copy of personal data being processed in a format usable by this person and be able to transmit it electronically to another processing system | PDP | +| **Data Protection** | PCI-DSS | The practices that enterprises do to protect end user data and credentials. "PCI-DSS" is a card industry standard for this. | ITU-T | +| **Deposit Guarantee System** | Deposit Insurance | A fund that insures the deposits of account holders at a provider; often a government function used specifically for bank accounts. | ITU-T | +| **Diffie-Hellman solution** | | A secure mechanism for exchanging a shared symmetric key between two anonymous peers. | | +| **Digital Financial Services** | DFS, Mobile Financial Services | Digital financial services include methods to electronically store and transfer funds; to make and receive payments; to borrow, save, insure and invest; and to manage a person's or enterprise's finances. | ITU-T | +| **Digital Liquidity** | | A state in which a consumer willing to leave funds (eMoney or bank deposits) in electronic form, rather than performing a "cash-out". | ITU-T | +| **Digital Payment** | Mobile Payment, Electronic Funds Transfer | A broad term including any payment which is executed electronically. Includes payments which are initiated by mobile phone or computer. Card payments in some circumstances are considered to be digital payments. The term "mobile payment" is equally broad and includes a wide variety of transaction types which in some way use a mobile phone. | ITU-T | +| **Dispute Resolution** | | A process specified by a provider or by the rules of a payment scheme to resolve issues between end users and providers, or between an end user and its counter party. | ITU-T | +| **Electronic consent** | Electronic consent |Any sound, symbol, or process which is:
    1. Related to technology
      a. Having electrical, digital, magnetic, wireless, optical, electromagnetic, or similar capabilities, including (but not limited to) mobile telephone, facsimile and internet and
      b. Which may only be accessed through a security access code, and


    2. Logically associated with a legally binding agreement or authorization and executed or adopted by a person with the intent to be bound by such agreement or authorization.
    | PDP | +| **Electronic Invoicing, ERP, Digital Accounting, Supply Chain Solutions, Services, Business Intelligence** | | Services which support merchant or business functions relating to DFS services. | ITU-T | +| **eMoney** |eFloat, Float, Mobile Money, Electronic Money, Prepaid Cards, Electronic Funds | A record of funds or value available to a consumer stored on a payment device such as chip, prepaid cards, mobile phones or on computer systems as a non-traditional account with a banking or non-banking entity. | ITU-T | +| **eMoney Accounts and Transaction Services** | Digital Wallet, Mobile Wallet, Mobile Money Account |A transaction account held at a non-bank. The value in such an account is referred to as eMoney. | ITU-T | +| **eMoney Issuer** | Issuer, Provider | A provider (bank or non-bank) who deposits eMoney into an account they establish for an end user. eMoney can be created when the provider receives cash ("cash-in") from the end user (typically at an agent location) or when the provider receives a digital payment from another provider. | ITU-T | +| **Encryption** |Decryption | The process of encoding a message so that it can be read only by the sender and the intended recipient. | ITU-T | +| **End User** |Consumer, Customer, Merchant, Biller | The customer of a digital financial services provider: the customer may be a consumer, a merchant, a government, or another form of enterprise. | ITU-T | +| **External Account** | | An account hosted outside the FSP, regularly accessible by an external provider interface API. | PDP | +| **FATF** | | The Financial Action Task Force is an intergovernmental organization to combat money laundering and to act on terrorism financing. | ITU-T | +| **Feature Phone** | |A mobile telephone without significant computational . | ITU-T | +| **Fees** | | The payments assessed by a provider to their end user. This may either be a fixed fee, a percent-of-value fee, or a mixture. A Merchant Discount Fee is a fee charged by a Merchant Services Provider to a merchant for payments acceptance. Payments systems or schemes, as well as processors, also charge fees to their customer (typically the provider.) | ITU-T | +| **Financial Inclusion** | | The sustainable provision of affordable digital financial services that bring the poor into the formal economy.| ITU-T | +| **Financial Literacy** | |Consumers and businesses having essential financial skills, such as preparing a family budget or an understanding of concepts such as the time value of money, the use of a DFS product or service, or the ability to apply for such a service. | ITU-T | +| **FinTech** | |A term that refers to the companies providing software, services, and products for digital financial services: often used in reference to newer technologies. | ITU-T | +| **Float** | |This term can mean a variety of different things. In banking, float is created when one party's account is debited or credited at a different time than the counterparty to the transaction. eMoney, as an obligation of a non-bank provider, is sometimes referred to as float. | ITU-T | +| **Fraud** | Fraud Management, Fraud Detection, Fraud Prevention | Criminal use of digital financial services to take funds from another individual or business, or to damage that party in some other way. | ITU-T | +| **Fraud Risk Management** | | Tools to manage providers' risks, and at times user's risks (for example, for merchants or governments) in providing and/or using DFS services. | ITU-T | +| **FSP** | Provider, Financial Service Provider (FSP), Payment Service Provider, Digital Financial Services Provider (DFSP) | The entity that provides a digital financial service to an end user (either a consumer, a business, or a government.) In a closed-loop payment system, the Payment System Operator is also the provider. In an open- loop payment system, the providers are the banks or non-banks which participate in that system. | ITU-T | +| **FSP On-boarding** | | The process of adding a new FSP to this financial network. | RI | +| **Fulfillment** | | In the Interledger protocol, a secret that is the preimage of a SHA-256 hash, used as a condition on a transfer. The preimage is required in the commit message to trigger the transfer to be committed.| PDP | +| **FX** | | Foreign Exchange | PDP | +| **Government Payments Acceptance Services** | | Services which enable governments to collect taxes and fees from individuals and businesses. | ITU-T | +| **HCE** | | Host Card Emulation. A communication technology that enables payment data to be safely stored without using the Secure Element in the phone. | ITU-T | +| **Identity** | National Identity, Financial Identity, Digital Identity |A credential of some sort that identifies an end user. National identities are issued by national governments. In some countries a financial identity is issued by financial service providers. | ITU-T | +| **Immediate Funds Transfer** | Real Time | A digital payment which is received by the payee almost immediately upon the payer having initiated the transaction | ITU-T | +| **Insurance Products** | | A variety of products which allow end user to insure assets or lives that they wish to protect.| ITU-T | +| **Insuring Lives or assets** | | Paying to protect the value of a life or an asset. | ITU-T | +| **Interchange** | Swipe Fee, Merchant Discount Fee | A structure within some payments schemes which requires one provider to pay the other provider a fee on certain transactions. Typically used in card schemes to effect payment of a fee from a merchant to a consumer's card issuing bank. | ITU-T | +| **Interledger** | | The Interledger protocol is a protocol for transferring monetary value across multiple disconnected payment networks using a choreography of conditional transfers on each network. | PDP | +| **International Remittance** | P2P; Remote Cross-Border Transfer of Value, Cross-Border Remittance | Making and receiving payments to another person in another country. | ITU-T | +| **Interoperability** | Interconnectivity | When payment systems are interoperable, they allow two or more proprietary platforms or even different products to interact seamlessly. The result is the ability to exchange payments transactions between and among providers. This can be done by providers participating in a scheme, or by a variety of bilateral or multilateral arrangements. Both technical and business rules issues need to be resolved for interoperability to work. | ITU-T | +| **Interoperability Service for Transfers (IST)** | Switch | An entity which receives transactions from one provider and routes those transactions on to another provider. A switch may be owned or hired by a scheme or be hired by individual providers. A switch may connect to a settlement system for inter-participant settlement and could also implicitly host other services - such as a common account locator service. | ITU-T | +| **Interoperability settlement bank** | | Entity that facilitates the exchange of funds between the FSPs. The settlement bank is one of the main entities involved in any inter-FSP transaction. | PDP | +| **Investment Products** | | A variety of products which allow end users to put funds into investments other than a savings account.| ITU-T | +| **Irrevocable** | |A transaction that cannot be "called back" by the payer; an irrevocable payment, once received by a payee, cannot be taken back by the payer. | ITU-T | +| **JSON** | JavaScript Object Notation | JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 (Source: www.json.org). | | +| **Know Your Customer** | KYC, Agent and Customer Due Diligence, Tiered KYC, Zero Tier | The process of identifying a new customer at the time of account opening, in compliance with law and regulation. The identification requirements may be lower for low value accounts ("Tiered KYC"). The term is also used in connection with regulatory requirements for a provider to understand, on an ongoing basis, who their customer is and how they are using their account. | ITU-T | +| **Liability** | Agent Liability, Issuer Liability, Acquirer Liability | A legal obligation of one party to another; required by either national law, payment scheme rules, or specific agreements by providers. Some scheme rules transfer liabilities for a transaction from one provider to another under certain conditions. | ITU-T | +| **Liquidity** | Agent Liquidity | The availability of liquid assets to support an obligation. Banks and non-bank providers need liquidity to meet their obligations. Agents need liquidity to meet cash-out transactions by consumers and small merchants.| ITU-T | +| **Loans** | Microfinance, P2P Lending, Factoring, Cash Advances, Credit, Overdraft, Facility | Means by which end users can borrow money. | ITU-T | +| **M2C** | | Merchant to Customer or Consumer. | PDP | +| **mCommerce** | eCommerce | Refers to buying or selling in a remote fashion: by phone or tablet (mCommerce) or by computer (eCommerce). | ITU-T | +| **Merchant** | Payments Acceptor | An enterprise which sells goods or services and receives payments for such goods or services. | ITU-T | +| **Merchant Acquisition** | Onboarding | The process of enabling a merchant for the receipt of electronic payments.| ITU-T | +| **Merchant payment - POS** | C2B, Proximity Payments | Making a payment for a good or service in person ("face to face"); includes kiosks and vending machines. | ITU-T | +| **Merchant payment - Remote** |C2b, eCommerce Payment, Mobile Payment | Making a payment for a good or service remotely; transacting by phone, computer, and so on | ITU-T | +| **Merchant Payments Acceptance Services** | Acquiring Services | A service which enables a merchant or other payment acceptor to accept one or more types of electronic payments. The term "acquiring" is typically used in the card payments systems. | ITU-T | +| **Merchant Service Provider** | Acquirer | A provider (bank or non-bank) who supports merchants or other payments acceptors requirements to receive payments from customers. The term "acquirer" is used specifically in connection with acceptance of card payments transactions. | ITU-T | +| **Mobile Network Operator** | MNO | An enterprise which sells mobile phone services, including voice and data communication. | ITU-T | +| **Money Transfer Operator** | | A specialized provider of DFS who handles domestic and/or international remittances. | ITU-T | +| **MSISDN** | | Number uniquely identifying a subscription in a mobile phone network. These numbers use the E.164 standard that defines numbering plan for a world-wide public switched telephone network (PSTN).| RI | +| **Mutual Authentication** | TLS | Mutual authentication or two-way authentication refers to two parties authenticating each other at the same time, being a default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS) (Source: Wikipedia). | | +| **Near Field Communication** | NFC | A communication technology used within payments to transmit payment data from an NFC equipped mobile phone to a capable terminal.| ITU-T | +| **Netting** | | The offsetting of obligations between or among participants in the settlement arrangement, thereby reducing the number and value of payments or deliveries needed to settle a set of transactions.| RI | +| **Non-Bank** | Payments Institution, Alternative Lender | An entity that is not a chartered bank, but which is providing financial services to end users. The requirements of non-banks to do this, and the limitations of what they can do, are specified by national law| ITU-T | +| **Non-Bank-Led Model** | MNO-Led Model | A reference to a system in which non-banks are the providers of digital financial services to end users. Non-banks typically need to meet criteria established by national law and enforced by regulators.| ITU-T | +| **Non-repudiation** | | Ability to prove the authenticity of a transaction, such as by validating a digital signature.| PDP | +| **Nostro Account** | | From the Payer's perspective: Payer FSP funds/accounts held/hosted at Payee FSP.| PDP | +| **Notification** | | Notice to a payer or payee regarding the status of transfer. |PDP | +| **Off-Us Payments** | Off-Net Payments | Payments made in a multiple-participant system or scheme, where the payer's provider is a different entity as the payee's provider. | ITU-T | +| **On-Us Payments** | On-Net Payments | Payments made in a multiple-participant system or scheme, where the payer's provider is the same entity as the payee's provider. | ITU-T | +| **Open-Loop** | | A payment system or scheme designed for multiple providers to participate in. Payment system rules or national law may restrict participation to certain classes of providers.| ITU-T | +| **Operations Risk Management** | | Tools to manage providers' risks in operating a DFS system. | ITU-T | +| **Organization** | Business | An entity such as a business, charity or government department that uses mobile money as a service; for example, taking bill payments, making bill payments and disbursing salaries. | PDP | +| **OTP** | One-Time Password | OTP is a credential which by definition can only be used once. It is generated and later validated by the same FSP for automatic approval. The OTP is usually tied to a specific Payer in a Payment. The generated OTP is usually a numeric between 4 and 6 digits. | PDP | +| **Over The Counter Services** | OTC, Mobile to Cash | Services provided by agents when one end party does not have an eMoney account: the (remote) payer may pay the eMoney to the agent's account, who then pays cash to the non- account holding payee. | ITU-T | +| **P2P** | Domestic Remittance, Remote Domestic Transfer of Value| Making and receiving payments to another person in the same country. | ITU-T | +| **Participant** | | A provider who is a member of a payment scheme, and subject to that scheme's rules.| ITU-T | +| **Partner Bank** | | Financial institution supporting the FSP and giving it access to the local banking ecosystem. | PDP | +| **Payee** | Receiver | The recipient of electronic funds in a payment transaction. | ITU-T | +| **Payee FSP** | | Payee's Financial Service Provider. | PDP | +| **Payer** | Sender | The payer of electronic funds in a payment transaction. | ITU-T | +| **Payer FSP** | | Payer's Financial Service Provider. | PDP | +| **Paying for Purchases** | C2B - Consumer to Business | Making payments from a consumer to a business: the business is the "payment acceptor” or merchant. | ITU-T | +| **Payment Device** | ATM (Automated Teller Machine), POS (Point of Sale), Access Point, Point of Sale Device | Payment device is the abstract notion of an electronic device, other than the Payer’s own device, that is capable of letting a Payer accept a transaction through the use of a credential (some kind of OTP). Examples of (Payment) Devices are ATM and POS. | PDP | +| **Payment Instruction** | Payment Instruction | An instruction by a sender to a sender’s payment service provider, transmitted orally, electronically, or in writing, to pay, or to cause another payment service provider to pay, a fixed or determinable amount of money to a payee if:
    a) The instruction does not state a condition of payment to the payee other than time of payment; and

    b) The instruction is transmitted by the sender directly to the sender’s payment service provider or to an agent, electronic fund transfers system or communication system for transmittal to the sender’s payment service provider.
    | PDP | +| **Payment System** | Payment Network, Money Transfer System | ncompasses all payment-related activities, processes, mechanisms, infrastructure, institutions and users in a country or a broader region (for example a common economic area). | ITU-T | +| **Payment System Operator** | Mobile Money Operator, Payment Service Provider | The entity that operates a payment system or scheme. | ITU-T | +| **Peer FSP** | | The counterparty financial service provider. | PDP | +| **PEP** | | Politically Exposed Person. Someone who has been entrusted with a prominent public function. A PEP generally presents a higher risk for potential involvement in bribery and corruption by virtue of their position and the influence that they may hold (for example, ‘senior foreign political figure', 'senior political figure', foreign official', and so on).| PDP | +| **Platform** | Payment Platform, Payment Platform Provider, Mobile Money Platform |A term used to describe the software or service used by a provider, a scheme, or a switch to manage end user accounts and to send and receive payment transactions. | ITU-T | +| **Posting** | Clearing | The act of the provider of entering a debit or credit entry into the end user's account record. | ITU-T | +| **Pre-approval** |Debit Authorization, Mandate |Pre-approval means that a Payer is allowing a specific Payee to withdraw funds without the Payer having to manually accept the payment transaction. The pre-approval can be valid one time, valid during a specific time period or valid until the Payer cancels the pre-approval.| PDP | +| **Prefunding** | | The process of adding funds to Vostro/Nostro accounts. | PDP | +| **Prepaid Cards** | |eMoney product for general purpose use where the record of funds is stored on the payment card (on magnetic stripe or the embedded integrated circuit chip) or a central computer system, and which can be drawn down through specific payment instructions to be issued from the bearer’s payment card. | ITU-T | +| **Processing of Personal/Consumer Data** | Processing of Personal/Consumer Data | Processing of personal/consumer data shall mean any operation or set of operations which is performed upon personal/consumer data, whether or not by automatic means, such as collection, recording, organization, storage, adaptation or alteration, retrieval, consultation, use, disclosure by transmission, dissemination or otherwise making available, alignment or combination, blocking, erasure or destruction. | PDP | +| **Processor** | Gateway | An enterprise that manages, on an out-sourced basis, various functions for a digital financial services provider. These functions may include transaction management, customer database management, and risk management. Processors may also do functions on behalf of payments systems, schemes, or switches. | ITU-T | +| **Promotion** | | FSP marketing initiative offering the user a transaction/service fee discount on goods or services. May be implemented through the use of a coupon. | PDP | +| **Pull Payments** | | A payment type which is initiated by the payee: typically, a merchant or payment acceptor, whose provider "pulls" the funds out of the payer's account at the payer's provider. | ITU-T | +| **Push Payments** | |A payment type which is initiated by the payer, who instructs their provider to debit their account and "push" the funds to the receiving payee at the payee's provider. | ITU-T | +| **Quote** | | Quote can be seen as the price for performing a hypothetical financial transaction. Some factors that can affect a Quote are Fees, FX rate, Commission, and Taxes. A Quote is usually guaranteed a short time period, after that the Quote expires and is no longer valid. | PDP | +| **Reconciliation** | | Cross FSP Reconciliation is the process of ensuring that two sets of records, usually the balances of two accounts, are in agreement between FSPs. Reconciliation is used to ensure that the money leaving an account matches the actual money transferred. This is done by making sure the balances match at the end of a particular accounting period. | PDP | +| **Recourse** | | Rights given to an end user by law, private operating rules, or specific agreements by providers, allowing end users the ability to do certain things (sometimes revoking a transaction) in certain circumstances. | ITU-T | +| **Refund** | | A repayment of a sum of money (i.e. repayment, reimbursement or rebate) to a customer returning the goods/services bought. | PDP | +| **Registration** | Enrollment, Agent Registration, User Creation, User On- Boarding | The process of opening a provider account. Separate processes are used for consumers, merchants’ agents, and so on | ITU-T | +| **Regulator** | | A governmental organization given power through national law to set and enforce standards and practices. Central Banks, Finance and Treasury Departments, Telecommunications Regulators, and Consumer Protection Authorities are all regulators involved in digital financial services. | ITU-T | +| **Reserve** | Prepare | Part of a 2-phase transfer operation in which the funds to be transferred are locked (the funds cannot be used for any purpose until either rolled back or committed). This is usually done for a predetermined duration, the expiration of which results in the reservation being rolled back.| PDP | +| **Reversal** | | The process of reversing a completed transfer. | PDP | +| **Risk Management** | Fraud Management | The practices that enterprises do to understand, detect, prevent, and manage various types of risks. Risk management occurs at providers, at payments systems and schemes, at processors, and at many merchants or payments acceptors.| ITU-T | +| **Risk-based Approach** | | A regulatory and/or business management approach that creates different levels of obligation based on the risk of the underlying transaction or customer. | ITU-T | +| **Roll back** | Reject | Roll back means that the electronic funds that were earlier reserved are put back in the original state. The financial transaction is cancelled. The electronic funds are no longer locked for usage.| PDP | +| **Rollback** | | The process of reversing a transaction - restoring the system (i.e. account balances affected by the transaction) to a previously defined state, typically to recover from an error and via an administrator-level user action. | PDP | +| **Rules** | | The private operating rules of a payments scheme, which bind the direct participants (either providers, in an open-loop system, or end users, in a closed-loop system). | ITU-T | +| **Saving and Investing** | | Keeping funds for future needs and financial return. | ITU-T | +| **Savings Products** | | An account at either a bank or non-bank provider, which stores funds with the design of helping end users save money. | ITU-T | +| **Scheme** | | A set of rules, practices and standards necessary for the functioning of payment services. | ITU-T | +| **Secure Element** | | A secure chip on a phone that can be used to store payment data. | ITU-T | +| **Security Access Code** | Security Access Code | A personal identification number (PIN), password/one-time password (OTP), biometric recognition, code or any other device providing a means of certified access to a customer’s account for the purposes of, among other things, initiating an electronic fund transfer. | PDP | +| **Security Level** | | Security specification of the system which defines effectiveness of risk protection. | ITU-T | +| **Sensitive Consumer Data** | Sensitive Consumer Data |Consumer Sensitive Data means any or all information that is used by a consumer to authenticate identity and gain authorization for performing mobile banking services, including but not limited to User ID, Password, Mobile PIN, Transaction PIN. Also includes data relating to religious or other beliefs, sexual orientation, health, race, ethnicity, political views, trades union membership, criminal record. | PDP | +| **Settlement** | Real Time Gross Settlement (RTGS) | An act that discharges obligations in respect of funds or securities transfers between two or more parties. | RI | +| **Settlement Instruction** | | Means an instruction given to a settlement system by a settlement system participant or by a payment clearing house system operator on behalf of a Central Bank settlement system participant to effect settlement of one or more payment obligations, or to discharge any other obligation of one system participant to another system participant.| PDP | +| **Settlement Obligation** | | Means an indebtedness that is owed by one settlement system participant to another as a result of one or more settlement instructions. | PDP | +| **Settlement System** | Net Settlement, Gross Settlement, RTGS | A system used to facilitate the settlement of transfers of funds, assets or financial instruments. Net settlement system: a funds or securities transfer system which settles net settlement positions during one or more discrete periods, usually at pre-specified times in the course of the business day. Gross settlement system: a transfer system in which transfer orders are settled one by one. | ITU-T | +| **Short Message Service** | | A service for sending short messages between mobile phones. | ITU-T | +| **SIM Card** | SIM ToolKit, Thin SIM | A smart card inside a cellular phone, carrying an identification number unique to the owner, storing personal data, and preventing operation if removed. A SIM Tool Kit is a standard of the GSM system which enables various value-added services. A "Thin SIM" is an additional SIM card put in a mobile phone. | ITU-T | +| **Smart Phone** | | A device that combines a mobile phone with a computer. | ITU-T | +| **Standards Body** | EMV, ISO, ITU, ANSI, GSMA | An organization that creates standards used by providers, payments schemes, and payments systems. | ITU-T | +| **Stored Value Account** | SVA | Account in which funds are kept in a secure, electronic format. May be a bank account or an eMoney account. | PDP | +| **Storing Funds** | Account, Wallet, Cash-In, Deposit | Converting cash into electronic money and keeping funds in secure electronic format. May be a bank account or an eMoney account. | PDP | +| **Super-Agent** | Master Agent | In some countries, agents are managed by Super Agents or Master Agents who are responsible for the actions of their agents to the provider. | ITU-T | +| **Supplier Payment** | B2B - Business to Business, B2G - Business to Government | Making a payment from one business to another for supplies, and so on: may be in-person or remote, domestic or cross border. Includes cross- border trade. | ITU-T | +| **Suspicious Transaction Report** | Suspicious Transaction Report | If a financial institution notes something suspicious about a transaction or activity, it may file a report with the Financial Intelligence Unit that will analyze it and cross check it with other information. The information on an STR varies by jurisdiction. | PDP | +| **Systemic Risk** | | In payments systems, the risk of collapse of an entire financial system or entire market, as opposed to risk associated with any one individual provider or end user. | ITU-T | +| **Tax Payment** | C2G, B2G |Making a payment from a consumer to a government, for taxes, fees, and so on | ITU-T | +| **Tokenization** | | The use of substitute a token ("dummy numbers") in lieu of "real" numbers, to protect against the theft and misuse of the "real" numbers. Requires a capability to map the token to the "real" number. | ITU-T | +| **Trading** | International Trade | The exchange of capital, goods, and services across international borders or territories. | ITU-T | +| **Transaction Accounts** | | Transaction account: broadly defined as an account held with a bank or other authorized and/or regulated service provider (including a non- bank) which can be used to make and receive payments. Transaction accounts can be further differentiated into deposit transaction accounts and eMoney accounts. Deposit transaction account: deposit account held with banks and other authorized deposit-taking financial institutions that can be used for making and receiving payments. Such accounts are known in some countries as current accounts, chequing accounts or other similar terms. | ITU-T | +| **Transaction Cost** | | The cost to a DFS provider of delivering a digital financial service. This could be for a bundle of services (for example, a "wallet") or for individual transactions. | ITU-T | +| **Transaction Request** | Payment Request | Transaction Request is a request sent by a Payee, meant for a Payer to transfer electronic funds to the Payee. The Transaction Request usually requires manual approval by the Payer to perform the financial transaction, but the Payee can also be pre-approved or a credential (usually OTP) can be sent as part of the transaction request for automatic validation and approval. | PDP | +| **Transfer** | | Generic term to describe any financial transaction where value is transferred from one account to another. | PDP | +| **Transfer Funds** | Sending or Receiving Funds | Making and receiving payments to another person. | ITU-T | +| **Transport Layer Security** | TLS, client authentication, mutual authentication | Transport Layer Security (TLS) is a cryptographic protocol that provides communications security over a computer network, used to secure point to point communication (Source: Wikipedia). | | +| **Trust Account** | Escrow, Funds Isolation, Funds Safeguarding, Custodian Account, Trust Account | A means of holding funds for the benefit of another party. eMoney Issuers are usually required by law to hold the value of end users' eMoney accounts at a bank, typically in a Trust Account. This accomplishes the goals of funds isolation and funds safeguarding. | ITU-T | +| **Trusted Execution Environment** | | A development execution environment that has security capabilities and meets certain security-related requirements. | ITU-T | +| **Ubiquity** | | The ability of a payer to reach any (or most) payees in their country, regardless of the provider affiliation of the receiving payee. Requires some type of interoperability. | ITU-T | +| **Unbanked** | Underbanked, Underserved| Unbanked people do not have a transaction account. Underbanked people may have a transaction account but do not actively use it. Underserved is a broad term referring to people who are the targets of financial inclusion initiatives. It is also sometimes used to refer to a person who has a transaction account but does not have additional DFS services. | ITU-T | +| **User ID** | | A unique identifier of a user. This may be an MSISDN, bank account, some form of DFSP-provided ID, national ID, and so on. In a transaction, money is generally addressed to a user ID and not directly to an account ID. | PDP | +| **USSD** | | A communication technology that is used to send text between a mobile phone and an application program in the network. | ITU-T | +| **Vostro Account** | | From the Payee's perspective: Payer FSP funds/accounts held/hosted at Payee FSP. | PDP | +| **Voucher** | | A monetary value instrument commonly used to transfer funds to customers (Payees) who do not have an account at the Payer's FSP. This could be Payees with no account or account at another FSP. | ITU-T | +| **Wallet** | eWallet | Repository of funds for an account. Relationship of Wallet to Account can be many to one. | PDP | +| **Whitelist** | | A list or register of entities (registered users) that are being provided a particular privilege, service, mobility, access or recognition, especially those that were initially blacklisted. Entities on the list will be accepted, approved and/or recognized. Whitelisting is the reverse of blacklisting, the practice of identifying entities that are denied, unrecognized, or ostracized. Where entities are registered users (or user accounts, if granularity allows) and services are informational (for example, balance check), transactional (for example, debit/credit) payments services or lifecycle (for example, registration, closure) services. | PDP | +| **'x'-initiated** | | Used when referring to the side that initiated a transaction; for example, agent-initiated cash-out vs. user-initiated cash-out. | PDP | diff --git a/docs/technical/api/fspiop/json-binding-rules.md b/docs/technical/api/fspiop/json-binding-rules.md new file mode 100644 index 000000000..915a0dba6 --- /dev/null +++ b/docs/technical/api/fspiop/json-binding-rules.md @@ -0,0 +1,1287 @@ +--- +showToc: true +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# JSON Binding Rules + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +## Introduction + +The purpose of this document is to express the data model used by the Open API for FSP Interoperability (hereafter cited as "the API") in the form of JSON Schema binding rules, along with the validation rules for their corresponding instances. + +This document adds to and builds on the information provided in _Open API for FSP Interoperability Specification._ The contents of the Specification are listed in [FSPIOP API Overview](/). + +The types used in the PDP API fall primarily into three categories: + +- Basic data types and Formats used + +- Element types + +- Complex types + +The various types used in _API Definition_, _Data Model_ and the _Open API Specification_, as well as the JSON transformation rules to which their instances must adhere, are identified in the following sections. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](#) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Keywords and Usage + +The _keywords_ used in the JSON Schemas and rules are derived from _JSON Schema Specification_[1](http://json-schema.org/documentation.html). The types of keywords used are identified in [Validation Keywords](#validation-keywords), [Metadata Keywords](#metadata-keywords) and [Instance-and-$ref](#instance-and-$ref) sections. As discussed in detail later, some of these keywords specify validation parameters whereas others are more descriptive, such as Metadata. The description that follows specifies details such as whether a field MUST[2](https://www.ietf.org/rfc/rfc2119.txt) be present in the definition and whether a certain field is associated with a particular data type. + +### Validation Keywords + +This section[3](http://json-schema.org/latest/json-schema-validation.html) provides descriptions of the keywords used for validation in _API Definition_. Validation keywords in a schema impose requirements for successful validation of an instance. + +#### maxLength + +The value of this keyword MUST be a non-negative integer. A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. The length of a string instance is defined as the number of its characters as defined by RFC 7159[RFC7159]. + +#### minLength + +The value of this keyword MUST be a non-negative integer. A string instance is valid against this keyword if its length is greater than, or equal to, the value of this keyword. The length of a string instance is defined as the number of its characters as defined by RFC 7159[RFC7159]. Omitting this keyword has the same behaviour as assigning it a value of **0**. + +#### pattern + +The value of this keyword MUST be a string. This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect. A string instance is considered valid if the regular expression matches the instance successfully. Recall: regular expressions are not implicitly anchored. + +#### items + +The value of `items` MUST be either a valid JSON Schema or an array of valid JSON Schemas. This keyword determines how child instances validate for arrays; it does not directly validate the immediate instance itself. If `items` is a schema, validation succeeds if all elements in the array successfully validate against that schema. If `items` is an array of schemas, validation succeeds if each element of the instance validates against the schema at the same position, if such a schema exists. Omitting this keyword has the same behaviour as specifying an empty schema. + +#### maxItems + +The value of this keyword MUST be a non-negative integer. An array instance is valid against `maxItems` if its size is less than, or equal to, the value of this keyword. + +#### minItems + +The value of this keyword MUST be a non-negative integer. An array instance is valid against `minItems` if its size is greater than, or equal to, the value of this keyword. Omitting this keyword has the same behaviour as a value of **0**. + +#### required + +The value of this keyword MUST be an array. Elements of this array (if there are any) MUST be strings and MUST be unique. An object instance is valid against this keyword if every item in the array is the name of a property in the instance. Omitting this keyword results in the same behaviour as does having the array be empty. + +#### properties + +The value of `properties` MUST be an object. Each value of this object MUST be a valid JSON Schema. This keyword determines how child instances validate for objects; it does not directly validate the immediate instance itself. Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, the child instance for that name successfully validates against the corresponding schema. Omitting this keyword results in the same behaviour as does having an empty object. + +#### enum + +The value of this keyword MUST be an array. This array SHOULD have at least one element. Elements in the array SHOULD be unique. An instance validates successfully against this keyword if its value is equal to one of the elements in this keyword's array value. Elements in the array might be of any value, including null. + +#### type + +The value of this keyword MUST be either a string or an array. If it is an array, elements of the array MUST be strings and MUST be unique. String values MUST be one of the six primitive types (null, boolean, object, array, number, or string), or integer which matches any number with a zero-fractional part. An instance validates if and only if the instance is in any of the sets listed for this keyword. + +This specification uses string type for all basic types and element types, but enforces restrictions using regular expressions as `patterns`. Complex types are of object type and contain properties that are either element or object types in turn. Array types are used to specify lists, which are currently only used as part of complex types. + +### Metadata Keywords + +This section provides descriptions of the fields used in the JSON definitions of the types used. The description specifies whether a field MUST be present in the definition and specifies whether a certain field is associated with a primary data type. Validation keywords in a schema impose requirements for successful validation of an instance. + +#### definitions + +This keyword's value MUST be an object. Each member value of this object MUST be a valid JSON Schema. This keyword plays no role in validation. Its role is to provide a standardized location for schema authors to incorporate JSON Schemas into a more general schema. + +#### title and description + +The value of both keywords MUST be a string. Both keywords can be used to provide a user interface with information about the data produced by this user interface. A title will preferably be short, whereas a description will provide explanation about the purpose of the instance described in this schema. + +### Instance and $ref + +Two keywords, **Instance** and **$ref** are used in either the JSON Schema definitions or the transformation rules in this document, which are described in [Instance](#instance) and [Schema References with $ref](#schema-references-with-$ref-keyword) sections. `Instance` is not used in the Open API Specification; this term is used in this document to describe validation and transformation rules. `$ref` contains a URI value as a reference to other types; it is used in the Specification. + +#### Instance + +JSON Schema interprets documents according to a data model. A JSON value interpreted according to this data model is called an `instance`[4](http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2). An instance has one of six primitive types, and a range of possible values depending on the type: + +- **null**: A JSON `null` production. + +- **boolean**: A `true` or `false` value, from the JSON `true` or `false` productions. + +- **object**: An unordered set of properties mapping a string to an instance, from the JSON `object` production. + +- **array**: An ordered list of instances, from the JSON `array` production. + +- **number**: An arbitrary-precision, base-10 decimal number value, from the JSON `number` production. + +- **string**: A string of Unicode code points, from the JSON `string` production. + +Whitespace and formatting concerns are outside the scope of the JSON Schema. Since an object cannot have two properties with the same key, behaviour for a JSON document that tries to define two properties (the `member` production) with the same key (the `string` production) in a single object is undefined. + +#### Schema references with $ref keyword + +The `$ref`[5](http://json-schema.org/latest/json-schema-core.html\#rfc.section.8) keyword is used to reference a schema and provides the ability to validate recursive structures through self- reference. An object schema with a `$ref` property MUST be interpreted as a `"$ref"` reference. The value of the `$ref` property MUST be a URI Reference. Resolved against the current URI base, it identifies the URI of a schema to use. All other properties in a `"$ref"` object MUST be ignored. + +The URI is not a network locator, only an identifier. A schema need not be downloadable from the address if it is a network- addressable URL, and implementations SHOULD NOT assume they should perform a network operation when they encounter a network-addressable URI. A schema MUST NOT be run into an infinite loop against a schema. For example, if two schemas "#alice" and "#bob" both have an "allOf" property that refers to the other, a naive validator might get stuck in an infinite recursive loop trying to validate the instance. Schemas SHOULD NOT make use of infinite recursive nesting like this; the behavior is undefined. + +It is used with the syntax `"$ref"` and is mapped to an existing definition. From the syntax, the value part of `_$ref_`, `#/definitions/`, indicates that the type being referenced is from the Definitions section of the Open API Specification (Typically, an Open API Specification has sections named Paths, Definitions, Responses and Parameters.). An example for this can be found in [Listing 26](#listing-26), where the types for properties _authentication_ and _authenticationValue_ are provided by using references to `Authenticationtype` and `AuthenticationValue` types, respectively. + +### JSON Definitions and Examples + +JSON definitions and examples are provided after most sections defining the transformation rules, where relevant. These are provided in JSON form, taken from the JSON version of the Open API Specification. The Regular Expressions in the examples may have minor differences (sometimes having an additional '**\\**' symbol) when compared to the ones in rules and descriptions because the regular expressions in the examples are taken from the JSON version whereas the rules and descriptions are from the standard Open API (Swagger) Specification. They are provided in the relevant section as a numbered Listing. For example, [Listing 1](#listing-1) provides the JSON representation of the definition of data type `Amount`. + +For each of the data types, a description of the JSON Schema from the Open API Specification and (where relevant) an example of that type are provided. Following the Schema description are transformation rules that apply to an instance of that particular type. + +
    + +## Element and Basic Data Types + +This section contains the definitions of and transformation rules for the basic formats and _element_ types used by the API as specified in _API Definition_ and _API Data Model_. These definitions are basic in the context of the API specification, but *not* the Open API Technical Specification. Often, these basic data types are derived from the basic types supported by Open API Specification standards, such as string type. + +### Data Type Amount + +This section provides the JSON Schema definition for the data type `Amount`. [Listing 1](#listing-1) provides a JSON Schema for the `Amount` type. + +- JSON value pair with Name "**title**" and Value "**Amount**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^(\[0\]\|(\[1-9\]\[0-9\]{0,17}))(\[.\]\[0-9\]{0,3}\[1-9\])?\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.**" + +##### Listing 1 + + +```JSON +"Amount": { + "title": "Amount", + "type": "string", + "pattern": + "^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$", + "maxLength": 32, + "description": "The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons." +} +``` +**Listing 1 -- JSON Schema for Data type Amount** + +The transformation rules for an instance of Amount data type are as follows: + +- A given Instance of `Amount` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\[0\]\|(\[1-9\]\[0-9\]{0,17}))(\[.\]\[0-9\]{0,3}\[1-9\])?\$** + +- The length of this instance is restricted by the regular expression above as 23, with 18 digits in the major currency unit and four digits in the minor currency unit. Valid example values for Amount type: **124.45**, **5, 5.5, 4.4444, 0.5, 0, 181818181818181818** + +### Data Type BinaryString + +This section provides the JSON Schema definition for the data type BinaryString. [Listing 2](#listing-2) provides a JSON Schema for the BinaryString type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BinaryString**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$**" + +- JSON value pair with Name "**description**" and Value the content of Property **description** + +##### Listing 2 + +```JSON +"BinaryString":{ + "title":"BinaryString", + "type":"string", + "pattern":"^[A-Za-z0-9-_]+[=]{0,2}$", + "description":"The API data type BinaryString is a JSON String. The string is the base64url encoding of a string of raw bytes, where padding (character '=') is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters. +} +``` +**Listing 2 -- JSON Schema for Data type BinaryString** + +The section on [BinaryString Type IlpPacket](#binarystring-type-ilppacket) gives an example for `BinaryString` type. + +The transformation rules for an instance of `BinaryString` data type are as follows: + +- A given Instance of `BinaryString` type MUST be of string type. +- The instance MUST be a match for the regular expression **^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$** + +An example value for `BinaryString` type is + +``` +AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgyOVc4bXFmNEpLMHlGTFGCAUBQU0svMS4wCk5vbmNlOiB1SXlweUYzY3pYSXBFdzVVc05TYWh3CkVuY3J5cHRpb246IG5vbmUKUGF5bWVudC1JZDogMTMyMzZhM2ItOGZhOC00MTYzLTg0NDctNGMzZWQzZGE5OGE3CgpDb250ZW50LUxlbmd0aDogMTM1CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbgpTZW5kZXItSWRlbnRpZmllcjogOTI4MDYzOTEKCiJ7XCJmZWVcIjowLFwidHJhbnNmZXJDb2RlXCI6XCJpbnZvaWNlXCIsXCJkZWJpdE5hbWVcIjpcImFsaWNlIGNvb3BlclwiLFwiY3JlZGl0TmFtZVwiOlwibWVyIGNoYW50XCIsXCJkZWJpdElkZW50aWZpZXJcIjpcIjkyODA2MzkxXCJ9Ig +``` + +#### BinaryString Type IlpPacket + +This section provides the JSON Schema definition for the `BinaryString` type `IlpPacket`. [Listing 3](listing-3) provides a JSON Schema for the IlpPacket type. The transformation rules for an instance of `IlpPacket` are the same as those of data type `BinaryString`. + + - JSON value pair with Name "**title**" and Value "**IlpPacket**" + + - JSON value pair with Name "**type**" and Value "**string**" + + - JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$**" + + - JSON value pair with Name "**minLength**" and Value **1** + + - JSON value pair with Name "**pattern**" and Value **32768** + + - JSON value pair with Name "**description**" and Value "**Information for recipient (transport layer information).**" + +##### Listing 3 + +```json +"IlpPacket":{ + "title":"IlpPacket", + "type":"string", + "pattern":"^[A-Za-z0-9-_]+[=]{0,2}$", + "minLength":1 + "maxLength":32768 + "description":"Information for recipient (transport layer information)." +} +``` + +**Listing 3 -- JSON Schema for BinaryString type IlpPacket** + +### Data Type BinaryString32 + +This section provides the JSON Schema definition for the data type `BinaryString32`. [Listing 4](#listing-4) provides a JSON Schema for the `BinaryString32` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BinaryString32**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]{43}\$**" + +- JSON value pair with Name "**description**" and Value the content of Property **description** + +##### Listing 4 + +```json +"BinaryString32":{ + "title":"BinaryString32", + "type":"string", + "pattern":"^[A-Za-z0-9-_]{43}$", + "description":"The API data type BinaryString32 is a fixed size version of the API data type BinaryString, where the raw underlying data is always of 32 bytes. The data type BinaryString32 should not use a padding character as the size of the underlying data is fixed." +} +``` + +**Listing 4 -- JSON Schema for Data type BinaryString32** + +The section on [BinaryString32 Type IlpCondition](#binarystring32-type-ilpcondition) gives an example for `BinaryString32` type. Another example in the API of `BinaryString32` type is `IlpFulfilment`. The transformation rules for an instance of `BinaryString32` data type are as follows: + +- A given Instance of `BinaryString32` type MUST be of string type. + +- The instance MUST be a match for the regular expression "**^\[A-Za-z0-9-\_\]{43}\$**". + +An example value for `BinaryString32` type is: + +``` +AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgyOVc4bXFmNEpLMHlGTFGCAUBQU0svMS4wCk5vbmNlOiB1SXlweUYzY3pYSXBFdzVVc05TYWh3CkVuY3J5cHRpb246IG5vbmUKUGF5bWVudC1JZDogMTMyMzZhM2ItOGZhOC00MTYzLTg0NDctNGMzZWQzZGE5OGE3CgpDb250ZW50LUxlbmd0aDogMTM1CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbgpTZW5kZXItSWRlbnRpZmllcjogOTI4MDYzOTEKCiJ7XCJmZWVcIjowLFwidHJhbnNmZXJDb2RlXCI6XCJpbnZvaWNlXCIsXCJkZWJpdE5hbWVcIjpcImFsaWNlIGNvb3BlclwiLFwiY3JlZGl0TmFtZVwiOlwibWVyIGNoYW50XCIsXCJkZWJpdElkZW50aWZpZXJcIjpcIjkyODA2MzkxXCJ9IgA +``` + +#### BinaryString32 Type IlpCondition + +This section provides the JSON Schema definition for the `BinaryString32` type `IlpCondition`. [Listing 5](#listing-5) provides a JSON Schema for the `IlpCondition` type. The transformation rules for an instance of `IlpCondition` are the same as those of data type `BinaryString32`. + +- JSON value pair with Name "**title**" and Value "**IlpCondition**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]{43}\$**" + +- JSON value pair with Name "**maxLength**" and Value **48** + +- JSON value pair with Name "**description**" and Value "**Condition that must be attached to the transfer by the Payer.**" + +##### Listing 5 + +```json +"IlpCondition":{ + "title":"IlpCondition", + "type":"string", + "pattern":"^[A-Za-z0-9-_]{43}$", + "maxLength":48, + "description":"Condition that must be attached to the transfer by the Payer." +} +``` + +**Listing 5 -- JSON Schema for BinaryString32 type IlpCondition** + +### Data Type BopCode + +This section provides the JSON Schema definition for the data type `BopCode`. [Listing 6](#listing-6) provides a JSON Schema for the `BopCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BalanceOfPayments**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\\d{2}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type BopCode is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/).**" + +#### Listing 6 + +```json +"BalanceOfPayments":{ + "title":"BalanceOfPayments", + "type":"string", + "pattern":"^[1-9]\d{2}$", + "description":"(BopCode) The API data type BopCode is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. https://www.imf.org/external/np/sta/bopcode/" +} +``` + +**Listing 6 -- JSON Schema for Data type BopCode** + +The transformation rules for an instance of `BopCode` data type are as follows: + +- A given Instance of `BopCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\\d{2}\$**. + +An example value for `BopCode` type is **124**. + +### Data Type Enum + +This section provides the JSON Schema definition for the data type `Enum`. These are generic characteristics of an `Enum` type, alternately known as `CodeSet`. [Listing 8](#listing-8) provides an example JSON Schema for the data type Enumeration (CodeSet). + +- CodeSet.Name is the name of the JSON object. + +- JSON value pair with Name "**title**" and Value "**CodeSet.Name**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**enum**" and Value the array containing all the CodeSetLiteral values of the CodeSet + +- If Property description is not empty, JSON value pair with Name "**description**" and Value the content of Property description An example for Enum/CodeSet type -- "AmountType" can found in the [Enumeration AmountType](#enumeration-amounttype) section. [Listing 7](#listing-7) lists the other Enum types defined and used in the API. + +##### Listing 7 + +``` +AuthenticationType, AuthorizationResponse, BulkTransferState, Currency, PartyIdentifier, PartyIdType, PartySubIdOrType , PersonalIdentifierType, TransactionInitiator, TransactionInitiatorType, TransactionRequestState, TransactionScenario, TransactionState, TransferState. +``` + +**Listing 7 -- List of Enum types specified and used in the API** + +The transformation rules for an instance of Enum data type are as +follows: + +- A given Instance of `Enum` type MUST be of string type. + +- The instance MUST be one of the values specified in the `CodeSetLiteral` values. + +#### Enumeration AmountType + +This section provides the JSON Schema definition for the Enum type `AmountType`. [Listing 8](#listing-8) provides a JSON Schema for the `AmountType` type. + +- CodeSet.Name "**AmountType**" + +- JSON value pair with Name "**title**" and Value "**AmountType**" + +- JSON value pair with Name "**type**"and Value "**string**" + +- JSON value pair with Name **description** and Value "**_Below are the allowed values for the enumeration AmountType_** + - **_SEND The amount the Payer would like to send, i.e. the amount that should be withdrawn from the Payer account including any fees._** + - **_RECEIVE The amount the Payer would like the Payee to receive, i.e. the amount that should be sent to the receiver exclusive fees._**" + +- JSON value pair with Name **enum** and Value the array containing the values: + + → **SEND** + + → **RECEIVE** + +###### Listing 8 + +```json +"AmountType":{ + "title":"AmountType", + "type":"string", + "enum":[ + "SEND", + "RECEIVE" + ], + "description":"Below are the allowed values for the enumeration AmountType - SEND The amount the Payer would like to send, i.e. the amount that should be withdrawn from the Payer account including any fees. - RECEIVE The amount the Payer would like the Payee to receive, i.e. the amount that should be sent to the receiver exclusive fees." +} +``` + +**Listing 8 -- JSON Schema for Enumeration Type AmountType** + +The transformation rules for an instance of `AmountType` data type are as follows (same as those of Data Type Enum, but listing the rules here to demonstrate a valid set of literal values): + +- A given Instance of AmountType type MUST be of string type. + +- The instance MUST be one of the values defined in the set: {"**SEND**", "**RECEIVE**"}. + +An example value for `AmountType` type is "**SEND**". + +### Data Type Date + +This section provides the JSON Schema definition for the data type `Date`. [Listing 9](#listing-9) provides a JSON Schema for the `Date` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Date**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Date is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601 containing a date only. A more readable version of the format is "yyyy-MM-dd", e.g. "1982-05-23" or "1987-08- 05"**." + +##### Listing 9 + +```json +"Date": { + "title": "Date", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$", + "description": "The API data type Date is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601 containing a date only. A more readable version of the format is “yyyy-MM-dd”, e.g. "1982-05-23" or "1987-08-05”." +} +``` + +**Listing 9 -- JSON Schema for Data type Date** + +The transformation rules for an instance of `Date` data type are as follows: + +- A given Instance of `Date` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**. + +An example value for `Date` type is **1971-12-25**. + +#### Data Type DateOfBirth + +This section provides the JSON Schema definition for the Date type `DateOfBirth`. [Listing 10](#listing-10) provides a JSON Schema for the `DateOfBirth` type. The transformation rules for an instance of `DateOfBirth` are the same as those of data type `Date`. + +- JSON value pair with Name "**title**" and Value "**DateOfBirth (type Date)**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**description**" and Value "**Date of Birth for the Party**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**" + +##### Listing 10 + +```json +"DateOfBirth": { + "title": "DateOfBirth (type Date)", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$", + "description": "Date of Birth for the Party." +} +``` + +**Listing 10 -- JSON Schema for Date type DateOfBirth** + +### Data Type DateTime + +The JSON Schema definition for this section provides the JSON Schema definition for the data type `DateTime`. [Listing 11](#listing-11) provides a JSON Schema for the `DateTime` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**DateTime**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)T(?:\[01\]\\d\|2\[0-3\]):\[0-5\]\\d:\[0-5\]\\d(?:(\\.\\d{3}))(?:Z\|\[+-\]\[01\]\\d:\[0-5\]\\d)\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601, expressed in a combined date, time and time zone format. A more readable version of the format is "yyyy-MM-ddTHH:mm:ss.SSS\[-HH:MM\]", e.g. \"2016-05-24T08:38:08.699-04:00\" or \"2016-05-24T08:38:08.699Z\" (where Z indicates Zulu time zone, same as UTC)**." + +##### Listing 11 + +```json +"DateTime": { + "title":"DateTime", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\\d)$", + "description": "The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601, expressed in a combined date, time and time zone format. A more readable version of the format is “yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]”, e.g. "2016-05-24T08:38:08.699-04:00" or "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC)." +} +``` + +**Listing 11 -- JSON Schema for Data type DateTime** + +The transformation rules for an instance of DateTime data type are as follows: + +- A given Instance of type `DateTime` MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0-8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1-9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)T(?:\[01\]\\d\|2\[0-3\]):\[0-5\]\\d:\[0-5\]\\d(?:(\\.\\d{3}))(?:Z\|\[+-\]\[01\]\\d:\[0-5\]\\d)\$**. + +An example value for `DateTime` type is **2016-05-24T08:38:08.699-04:00**. + +### Data Type ErrorCode + +This section provides the JSON Schema definition for the data type `ErrorCode`. [Listing 12](#listing-12) provides a JSON Schema for the `ErrorCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**ErrorCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\\d{3}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type ErrorCode is a JSON String of 4 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Specific error number in the form _{C}{E}{SS}_ where _{C}_ is a one-digit category _{E}_ is a one-digit error within the category _{SS}_ is a scheme defined two-digit sub-error within the error. Please refer to x.x for the list of the possible category/error codes**". + +##### Listing 12 + +```json +"ErrorCode": { + "title": "ErrorCode", + "type": "string", + "pattern": "^[1-9]\d{3}$", + "description": "The API data type ErrorCode is a JSON String of 4 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Specific error number in the form {C}{E}{SS} where {C} is a one-digit category {E} is a one-digit error within the category {SS} is a scheme defined two-digit sub-error within the error. Please refer to x.x for the list of the possible category/error codes" +} +``` + +**Listing 12 -- JSON Schema for Data type ErrorCode** + +The transformation rules for an instance of `ErrorCode` data type are as follows: + +- A given Instance of `ErrorCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\d{3}\$**. + +An example value for `ErrorCode` type is **5100**. + +### Data Type Integer + +This section provides the JSON Schema definition for the data type `Integer`. [Listing 13](#listing-13) provides a JSON Schema for the Integer type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Integer**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\d\*\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Integer is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits.**" + +##### Listing 13 + +```json +"Integer": { + "title": "Integer", + "type": "string", + "pattern": "^[1-9]\d*$", + "description": "The API data type Integer is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits." +} +``` + +**Listing 13 -- JSON Schema for Data type Integer** + +The transformation rules for an instance of `Integer` data type are as follows: + +- A given Instance of Integer type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\d\*\$**. + +An example value for `Integer` type is **12345**. + +### Data Type Latitude + +This section provides the JSON Schema definition for the data type `Latitude`. [Listing 14](#listing-14) provides a JSON Schema for the `Latitude` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Latitude**" + +- JSON value pair with Name "**pattern**" and Value "**^(\\+\|-)?(?:90(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-8\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons**". + +##### Listing 14 + +```json +"Latitude": { + "title": "Latitude", + "type": "string", + "pattern": "^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$", + "description": "The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons." +} +``` + +**Listing 14 -- JSON Schema for Data type Latitude** + +The transformation rules for an instance of `Latitude` data type are as follows: + +- A given Instance of `Latitude` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\\+\|-)?(?:90(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-8\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**. + +An example value for `Latitude` type is **+45.4215**. + +### Data Type Longitude + +This section provides the JSON Schema definition for the data type `Longitude`. [Listing 15](#listing-15) provides a JSON Schema for the `Longitude` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Longitude**" + +- If Property pattern is not empty, JSON value pair with Name "**pattern**" and Value "**^(\\+\|-)?(?:180(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-9\]\[0-9\]\|1\[0-7\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**". + +- JSON value pair with Name "**description**" and Value "**The API data type Longitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons.**" + +##### Listing 15 + +```json +"Longitude": { + "title": "Longitude", + "type": "string", + "pattern": "^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$", + "description": "The API data type Longitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons." +} +``` + +**Listing 15 -- JSON Schema for Data type Longitude** + +The transformation rules for an instance of `Longitude` data type are as follows: + +- A given Instance of `Longitude` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\\+\|-)?(?:180(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-9\]\[0-9\]\|1\[0-7\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**. + +An example value for `Longitude` type is **+75.6972**. + +### Data Type MerchantClassificationCode + +This section provides the JSON Schema definition for the data type `MerchantClassificationCode`. [Listing 16](#listing-16) provides a JSON Schema for the `MerchantClassificationCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**MerchantClassificationCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[\\d\]{1,4}\$**". + +- JSON value pair with Name "**description**" and Value "**A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.**" + +##### Listing 16 + +```json +"MerchantClassificationCode": { + "title": "MerchantClassificationCode", + "type": "string", + "pattern": "^[\d]{1,4}$", + "description": "A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc." +} +``` + +**Listing 16 -- JSON Schema for Data type MerchantClassificationCode** + +The transformation rules for an instance of `MerchantClassificationCode` data type are as follows: + +- A given Instance of `MerchantClassificationCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[\\d\]{1,4}\$**. + +An example value for `MerchantClassificationCode` type is **99**. + +### Data Type Name + +This section provides the JSON Schema definition for the data type `Name`. [Listing 17](#listing-17) provides the JSON Schema for a `Name` type. [Name Type Firstname](#name-type-firstname) contains an example of `Name` type -- "First Name". Other Name types used in the API are "Middle Name" and "Last Name". + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Name**" + +- JSON value pair with Name "**minLength**" and Value the content of Property **minLength** + +- JSON value pair with Name "**maxLength**" and Value the content of Property **maxLength** + +- JSON value pair with Name "**pattern**" and Value "**^(?!\\\\s\*\$)\[\\\\w .,'-\]+\$**". + +- JSON value pair with Name "**description**" and Value "**The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. The restriction will not allow a string consisting of whitespace only, all Unicode characters should be allowed, as well as the characters ".", "'" (apostrophe), "-", "," and " " (space). Note - In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag UNICODE\_CHARACTER\_CLASS needs to be enabled to allow Unicode characters.**" + +##### Listing 17 + +```json +"Name": { + "title": "Name", + "type": "string", + "pattern": "^(?!\\s*$)[\\w .,'-]+$", + "description": "The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. The restriction will not allow a string consisting of whitespace only, all Unicode characters should be allowed, as well as the characters ".", "'" (apostrophe), "- ", "," and " " (space). Note - In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag UNICODE_CHARACTER_CLASS needs to be enabled to allow Unicode characters." +} +``` + +**Listing 17 -- JSON Schema for Data type Name** + +The transformation rules for an instance of `Name` data type are as follows: + +- A given Instance of `Name` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?!\\\\s\*\$)\[\\\\w .,'-\]+\$**. + +An example value for `Name` type is **Bob**. + +#### Name Type FirstName + +This section provides the JSON Schema definition for the `Name` type `FirstName`. [Listing 18](#listing-18) provides a JSON Schema for the `FirstName` type. The transformation rules for an instance of `FirstName` are the same as those of data type `Name`. + +- JSON value pair with Name "**title**" and Value "**FirstName**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^(?!\\s\*\$)\[\\w .,\'-\]+\$**" + +- JSON value pair with Name "**maxLength**" and Value **128** + +- JSON value pair with Name "**minLength**" and Value **1** + +- JSON value pair with Name "**description**" and Value "**First name of the Party (Name type).**" + +##### Listing 18 + +```json +"FirstName": { + "title": "FirstName", + "type": "string", + "minLength": 1, + "maxLength": 128, + "pattern": "^(?!\s*$)[\w .,'-]+$", + "description": "First name of the Party (Name Type)." +} +``` + +**Listing 18 -- JSON Schema for Name type FirstName** + +### Data Type OtpValue + +This section provides the JSON Schema definition for the data type `OtpValue`. [Listing 19](#listing-19) provides a JSON Schema for the `OtpValue` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**OtpValue**" + +- JSON value pair with Name "**pattern**" and Value "**^\\d{3,10}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type OtpValue is a JSON String of 3 to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed.**" + +##### Listing 19 + +```json +"OtpValue": { + "title": "OtpValue", + "type": "string", + "pattern": "^\d{3,10}$", + "description": "The API data type OtpValue is a JSON String of 3 to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed." +} +``` + +**Listing 19 -- JSON Schema for Data type OtpValue** + +The transformation rules for an instance of `OtpValue` data type are as follows: + +- A given Instance of `OtpValue` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\\d{3,10}\$**. + +An example value for `OtpValue` type is **987345**. + +### Data Type String + +This section provides the JSON Schema definition for the data type `String`. [Listing 21](#listing-21) provides an example JSON Schema for a `String` type. + +- **String.Name** is the name of the JSON object. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**String.Name**" + +- JSON value pair with Name "**minLength**" and Value the content of Property "**minLength**" + +- JSON value pair with Name "**maxLength**" and Value the content of Property "**maxLength**" + +- If Property pattern is not empty, JSON value pair with Name **pattern** and Value the content of Property **pattern**. + +- JSON value pair with Name "**description**" and Value the content of Property **description**. [Below](#string-type-errordescription), is an example for Stri`ng type, `ErrorDescription`. [Listing 20](#listing-20) has other `String` types specified and used in the API. + +##### Listing 20 + +``` +AuthenticationValue, ExtensionKey, ExtensionValue, FspId, Note, PartyName, QRCODE, RefundReason, TransactionSubScenario. +``` + +**Listing 20 -- String types specified and used in the API** + +The transformation rules for an instance of `String` data type are as follows: + +- A given Instance of `String` type MUST be of string type. + +- The length of this instance MUST not be greater than the **maxLength** specified. + +- The length of this instance MUST not be less than the **minLength** specified. + +- The instance MUST be a match for the regular expression specified by a **pattern** property if one is specified. + +An example value for `String` type is **Financial Services for the Poor**. + +### String Type ErrorDescription + +This section provides the JSON Schema definition for the `String` type `ErrorDescription`. [Listing 21](#listing-21) provides a JSON Schema for the `ErrorDescription` type. + +- JSON value pair with Name "**title**" and Value "**ErrorDescription**" + +- JSON value pair with Name "**type**" and Value "**ErrorDescription**" + +- JSON value pair with Name "**description**" and Value "**Error description string**" + +- JSON value pair with Name "**minLength**" and Value **1** + +- JSON value pair with Name "**maxLength**" and Value **128** + +##### Listing 21 + +```json +"ErrorDescription": { + "title": "ErrorDescription", + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "Error description string." +} +``` + +**Listing 21 -- JSON Schema for Data type ErrorDescription** + +The transformation rules for an instance of `ErrorDescription` data type are as follows (same as those of `Data` Type String, but listing the rules here to demonstrate a valid set of values for length properties): + +- A given Instance of `ErrorDescription` type MUST be of String Type. + +- The length of this instance MUST not be greater than 128. + +- The length of this instance MUST not be less than 1. + +An example value for `ErrorDescription` type is **This is an error description**. + +### Data Type TokenCode + +This section provides the JSON Schema definition for the data type `TokenCode`. [Listing 22](#listing-22) provides a JSON Schema for the `TokenCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**TokenCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-zA-Z\]{4,32}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type TokenCode is a JSON String between 4 and 32 characters, consisting of digits or characters from a to z (case insensitive).**" + +##### Listing 22 + +```json +"TokenCode": { + "title": "TokenCode", + "type": "string", + "pattern": "^[0-9a-zA-Z]{4,32}$", + "description": "The API data type TokenCode is a JSON String between 4 and 32 characters, consisting of digits or characters from a to z (case insensitive)." +} +``` + +**Listing 22 -- JSON Schema for Data type TokenCode** + +The transformation rules for an instance of `TokenCode` data type are as follows: + +- A given Instance of `TokenCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[0-9a-zA-Z\]{4,32}\$**. + +An example value for `TokenCode` type is **Test-Code**. + +#### TokenCode Type Code + +This section provides the JSON Schema definition for the `TokenCode` type `Code`. [Listing 23](#listing-23) provides a JSON Schema for the `Code` type. The transformation rules for an instance of `Code` are the same as those of Data Type `TokenCode`. + +- JSON value pair with Name "**title**" and Value "**Code**" + +- JSON value pair with Name "**type**" and Value "**String**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-zA-Z\]{4,32}\$**" + +- JSON value pair with Name "**description**" and Value "**Any code/token returned by the Payee FSP (TokenCode type).**" + +##### Listing 23 + +```json +"Code": { + "title": "Code", + "type": "string", + "pattern": "^[0-9a-zA-Z]{4,32}$", + "description": "Any code/token returned by the Payee FSP (TokenCode Type)." +} +``` + +**Listing 23 -- JSON Schema for TokenCode type Code** + +### Data Type UndefinedEnum + +This section provides the JSON Schema definition for the data type `UndefinedEnum`. [Listing 24](#listing-24) provides the JSON Schema for the data type `UndefinedEnum` (Enumeration). + +- JSON value pair with Name "**title**" and Value "**UndefinedEnum**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Z\_\]{1,32}\$**" + +- If Property description is not empty, JSON value pair with Name "**description**" and Value "**The API data type UndefinedEnum is a JSON String consisting of 1 to 32 uppercase characters including "\_" (underscore).**" + +##### Listing 24 + +```json +"UndefinedEnum": { + "title": "UndefinedEnum", + "type": "string", + "pattern": "^[A-Z_]{1,32}$", + "description": "The API data type UndefinedEnum is a JSON String consisting of 1 to 32 uppercase characters including "_" (underscore)." +} +``` + +**Listing 24 -- JSON Schema for Data type UndefinedEnum** + +The transformation rules for an instance of `UndefinedEnum` data type are as follows: + +- A given Instance of UndefinedEnum type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[A-Z\_\]{1,32}\$**. + +An example value for `UndefinedEnum` type depends on the list of values specified. + +### Data Type UUID + +This section provides the JSON Schema definition for the data type `UUID`. [Listing 25](#listing-25) provides a JSON Schema for `CorrelationId` which is of `UUID` type. Since `CorrelationId` is an element type in the *API Definition*, it is being used interchangeably with `UUID` in the Open API Specification version. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and "**Value CorrelationId**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[1-5\]\[0-9a-f\]{3}-\[89ab\]\[0-9a-f\]{3}-\[0-9a- f\]{12}\$**" + +- JSON value pair with Name "**description**" and Value "**Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122, that is restricted by a regular expression for interoperability reasons. An example of a UUID is "b51ec534-ee48-4575-b6a9-ead2955b8069". An UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes ("-").**" + +##### Listing 25 + +```json +"CorrelationId": { + "title": "CorrelationId", + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a- f]{12}$", + "description": "Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122, that is restricted by a regular expression for interoperability reasons. An example of a UUID is "b51ec534-ee48-4575-b6a9- ead2955b8069". An UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes ("-")." +} +``` + +**Listing 25 -- JSON Schema for Data type UUID** + +The transformation rules for an instance of `UUID` data type are as follows: + +- A given Instance of `UUID` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[1-5\]\[0-9a-f\]{3}-\[89ab\]\[0-9a- f\]{3}-\[0-9a-f\]{12}\$**. + +An example value for `UUID` type is **b51ec534-ee48-4575-b6a9-ead2955b8069**. + +## Complex Types + +This section contains definitions of and transformation characteristics for complex types that are used by the API. Along with the complex types defined in the [API Definition]() and [Data Model]() documents, there are other complex types defined in the PDP Open API Specification based on the objects present in several requests and responses in the **body** section. These are discussed in the [Types of Objects in Requests or Responses](#types-of-objects-in-requests-or-responses) section. + +### Complex Type Definition, Transformation + +This section provides the JSON Schema definition for a complex type. [Listing 26](#listing-26) provides an example JSON Schema for a complex type, `AuthenticationInfo`. Transformation rules specific to a complex type are listed [here](#complex-type-authenticationinfo). + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**complextype.Name**" + +- If Property **description** is not empty, JSON value pair with Name "**description**" and Value the content of Property **description**. + +- An array with Name "**required**" and Value the list of properties that MUST be present in an instance of complex type. + +- A JSON object **properties** with the following content: + + - A list of key, value pairs with Name **key.Name** and Value of element, complex or Array type + + - JSON value pair with Name **$ref** and as Value the concatenation of **#/definitions/** with **key.Type** type. An example for a complex type is provided under the [Complex Type AuthenticationInfo](#complex-type-authenticationinfo) section. + +#### Complex Type AuthenticationInfo + +This section provides the JSON Schema definition for the complex type `AuthenticationInfo` can be expressed as follows. [Listing 26](#listing-26) provides the JSON Schema for `AuthenticationInfo`. + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**AuthenticationInfo**" + +- JSON value pair with Name "**description**" and Value "**complex type AuthenticationInfo**" + +- An array with Name "**required**" and as Value a list with elements "**authentication**" and "**authenticationValue**" + +- A JSON object **properties** with the following content: + + - A JSON object **authentication** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the concatenation of **#/definitions/** with Authenticationtype type. + + - A JSON object **authenticationValue** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the concatenation of **#/definitions/** with AuthenticationValue type. + +##### Listing 26 + +```json +"AuthenticationInfo": { + "title": "AuthenticationInfo", + "type": "object", + "description": "complex type AuthenticationInfo", + "properties": { + "authentication": { + "$ref": "#/definitions/AuthenticationType", + "description": "The type of authentication." + }, + "authenticationValue":\ { + "$ref": "#/definitions/AuthenticationValue", + "description": " The authentication value." + } + }, + "required": [ + "authentication", + "authenticationValue" + ] +} +``` + +**Listing 26 -- JSON Schema for complex type AuthenticationInfo** + +The transformation rules for an instance of `AuthenticationInfo` complex type are as follows: + +- A given Instance of AuthenticationInfo type MUST be of `Object` type. + +- The instance MUST contain a property with name **authentication**. + +- The JSON object titled **authentication** MUST be an instance of AuthenticationType type, provided in the definitions. + +- The instance MUST contain a property with name **authenticationValue**. + +- The JSON object titled **authenticationValue** MUST be an instance of AuthenticationValue type, provided in the definitions. An example instance for AuthenticationInfo complex type is given in [Listing 27](#listing-27). + +##### Listing 27 + +```json +"authenticationInfo": { + "authentication": "OTP", + "authenticationValue": "1234" +} +``` + +**Listing 27 -- Example instance of AuthenticationInfo complex type** + +#### Complex Types in the API + +The examples for complex type from the API appear in [Listing 28](#listing-28). The list includes complex types defined in [API Definition]() and [Data Model]() documents and does not contain the complex types defined only in the Open API version of the specification which captures the objects in Requests and Reponses. + +##### Listing 28 + +``` +ErrorInformation, Extension, ExtensionList, GeoCode, IndividualQuote, IndividualQuoteResult, IndividualTransfer, IndividualTransferResult, Money, Party, PartyComplexName, PartyIdInfo, PartyPersonalInfo, PartyResult, Refund, Transaction, TransactionType. +``` + +**Listing 28 -- Complex type Examples** + +### Types of Objects in Requests or Responses + +This section contains the definitions and transformation characteristics of the complex types that are used in the API Specification of the PDP API to capture objects in Requests and Responses. These have the same characteristics as the complex data types discussed in the Complex Type section. + +#### Complex Type AuthorizationsIDPutResponse + +This section provides the JSON Schema definition for the complex type `AuthorizationsIDPutResponse`. [Listing 29](#listing-29) provides a JSON Schema for complex type `AuthorizationsIDPutResponse`. + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**AuthorizationsIDPutResponse**". + +- JSON value pair with Name "**description**" and Value "**PUT /authorizations/{ID} object**". + +- A JSON object "**properties**" with the following content: + + - If Property "**authenticationInfo**" is present, a JSON object "**authenticationInfo**" with the following content: + + - JSON value pair with Name "**$ref**" and as Value the definition of AuthenticationInfo type, located under **definitions** as indicated by **#/definitions/** + + - A JSON object **responseType** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the definition of AuthorizationResponse type, located under **definitions** as indicated by "**#/definitions/**". + +- An array **required** and as Value a list with single element "**responseType**" + +##### Listing 29 + +```json +"AuthorizationsIDPutResponse": { + "title": "AuthorizationsIDPutResponse", + "type": "object", + "description": "PUT /authorizations/{ID} object", + "properties": { + "authenticationInfo": { + "$ref": "#/definitions/AuthenticationInfo", + "description": "OTP or QR Code if entered, otherwise empty." + } + "responseType": { + "$ref": "#/definitions/AuthorizationResponse", + "description": "Enum containing response information; if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value." + } + }, + "required ": [ + "responseType" + ] +} +``` + +**Listing 29 -- JSON Schema for complex type AuthorizationsIDPutResponse** + +The transformation rules for an instance of `AuthorizationsIDPutResponse` complex type are as follows: + +- A given Instance of `AuthorizationsIDPutResponse` type MUST be of object type. + +- The instance MUST contain a property with name "**authenticationInfo**". + +- The JSON object titled "**authenticationInfo**" MUST be an instance of AuthenticationInfo type, provided in the definitions. + +- The instance MUST contain a property with name "**responseType**". + +- The JSON object titled "**responseType**" MUST be an instance of AuthorizationReponse type, provided in the definitions. + +An example instance for `AuthorizationsIDPutResponse` complex type is given in [Listing 30](#listing-30). + +##### Listing 30 + +```json +{ + "authenticationInfo": { + "authentication": "OTP", + "authenticationValue": "1234" + }, + "responseType": "ENTERED" +} +``` + +**Listing 30 -- Example instance of AuthorizationsIDPutResponse complex type** + +**5.2.2 Other Complex types in Requests and Responses** + +Other complex type examples from the API used in Requests or Responses can be found in [Listing 31](#listing-31). + +##### Listing 31 + +``` +BulkQuotesPostRequest, BulkQuotesIDPutResponse, BulkTransfersPostRequest, BulkTransfersIDPutResponse, ErrorInformationObject, ErrorInformationResponse, ParticipantsTypeIDSubIDPostRequest, ParticipantsTypeIDPutResponse, ParticipantsIDPutResponse, ParticipantsPostRequest, QuotesPostRequest, QuotesIDPutResponse, TransactionRequestsIDPutResponse, TransactionsIDPutResponse, TransfersPostRequest, TransactionRequestsPostRequest, TransfersIDPutResponse. +``` + +**Listing 31 -- Complex type Examples for Objects in Requests and Responses in the API** + +## References + +1 The link for this is: [http://json-schema.org/documentation.html](http://json-schema.org/documentation.html) + +2 MUST, MAY, OPTIONAL in this document are to be interpreted as described\ in [RFC2119](https://www.ietf.org/rfc/rfc2119.txt) + +3 Most of the items in this section and the next one, "Metadata Keywords" are taken from: [http://json-schema.org/latest/json-schema-validation.html](http://json-schema.org/latest/json-schema-validation.html). Some changes are made based on Open API limitations or constraints. Also, only relevant keywords are referenced. + +4 The description for "Instance" keyword is taken from: [http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2](http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2) + +5 Meaning and usage of \$ref as specified here: [http://json-schema.org/latest/json-schema-core.html\#rfc.section.8](http://json-schema.org/latest/json-schema-core.html\#rfc.section.8) + + + +## Table of Listings + +[Listing 1 -- JSON Schema for Data type Amount](#listing-1) + +[Listing 2 -- JSON Schema for Data type BinaryString](#listing-2) + +[Listing 3 -- JSON Schema for BinaryString type IlpPacket](#listing-3) + +[Listing 4 -- JSON Schema for Data type BinaryString32](#listing-4) + +[Listing 5 -- JSON Schema for BinaryString32 type IlpCondition](#listing-5) + +[Listing 6 -- JSON Schema for Data type BopCode](#listing-6) + +[Listing 7 -- List of Enum types specified and used in the API](#listing-7) + +[Listing 8 -- JSON Schema for Enumeration Type AmountType](#listing-8) + +[Listing 9 -- JSON Schema for Data type Date](#listing-9) + +[Listing 10 -- JSON Schema for Date type DateOfBirth](#listing-10) + +[Listing 11 -- JSON Schema for Data type DateTime](#listing-11) + +[Listing 12 -- JSON Schema for Data type ErrorCode](#listing-12) + +[Listing 13 -- JSON Schema for Data type Integer](#listing-13) + +[Listing 14 -- JSON Schema for Data type Latitude](#listing-14) + +[Listing 15 -- JSON Schema for Data type Longitude](#listing-15) + +[Listing 16 -- JSON Schema for Data type MerchantClassificationCode](#listing-16) + +[Listing 17 -- JSON Schema for Data type Name](#listing-17) + +[Listing 18 -- JSON Schema for Name type FirstName](#listing-18) + +[Listing 19 -- JSON Schema for Data type OtpValue](#listing-19) + +[Listing 20 -- String types specified and used in the API](#listing-20) + +[Listing 21 -- JSON Schema for Data type ErrorDescription](#listing-21) + +[Listing 22 -- JSON Schema for Data type TokenCode](#listing-22) + +[Listing 23 -- JSON Schema for TokenCode type Code](#listing-23) + +[Listing 24 -- JSON Schema for Data type UndefinedEnum](#listing-24) + +[Listing 25 -- JSON Schema for Data type UUID](#listing-25) + +[Listing 26 -- JSON Schema for complex type AuthenticationInfo](#listing-26) + +[Listing 27 -- Example instance of AuthenticationInfo complex type](#listing-27) + +[Listing 28 -- Complex type Examples](#listing-28) + +[Listing 29 -- JSON Schema for complex type AuthorizationsIDPutResponse](#listing-29) + +[Listing 30 -- Example instance of AuthorizationsIDPutResponse complex type](#listing-30) + +[Listing 31 -- Complex type Examples for Objects in Requests and Responses in the API](#listing-31) \ No newline at end of file diff --git a/docs/technical/api/fspiop/logical-data-model.md b/docs/technical/api/fspiop/logical-data-model.md new file mode 100644 index 000000000..146f85b40 --- /dev/null +++ b/docs/technical/api/fspiop/logical-data-model.md @@ -0,0 +1,2440 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Logical Data Model + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document specifies the logical data model used by Open API (Application Programming Interface) for FSP (Financial Service Provider) Interoperability (hereafter cited as “the API”). + +The [Services Elements](#api-services-elements) section lists elements used by each service. + +The [Supporting Data Model](#api-supporting-data-model) section describes the data model in terms of basic elements, simple data types and complex data types. + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](#) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## API Services Elements + +The section identifies and describes elements used by each service. + +### API Resource Participants + +This section describes the data model of services for the resource **Participants**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Participants**. +
    + +##### Lookup Participant Information + +Table 1 contains the data model for _Lookup Participant Information_. + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party.| + +**Table 1 – Lookup Participant Information data model** + +
    + +##### Create Participant Information + +Table 2 below contains the data model for _Create Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) |The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 1 | [FspId](#fspid-element) | FSP Identifier that the Party belongs to. | +| **currency** | 0..1 | [Currency](#currency-element) | Indicate that the provided Currency is supported by the Party. | + +**Table 2 – Create Participant Information data model** + +
    + +##### Create Bulk Participant Information + +Table 3 below contains the data model for _Create Bulk Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **partyList** | 1..10000 | [PartyIdInfo](#partyidinfo) | List of Party elements that the Client would like to update or create FSP information about. | +| **currency** | 0..1 | [Currency](#currency-enum) | Indicate that the provided Currency is supported by each PartyIdInfo in the list. | + +**Table 3 – Create Bulk Participant Information data model** + +
    + +##### Delete Participant Information + +Table 4 below contains the data model for _Delete Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | + +**Table 4 – Delete Participant Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Participants**. + +##### Return Participant Information + +Table 5 below contains the data model for _Return Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | [FspId](#fspid-element) | FSP Identifier that the Party belongs to. | + +**Table 5 – Return Participant Information data model** + +
    + +##### Return Bulk Participant Information + +Table 6 below contains the data model for _Return Bulk Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **partyList** | 1..10000 | [PartyResult](#partyresult) | List of PartyResult elements for which creation was attempted (and either succeeded or failed). | +| **Currency** | 0..1 | [Currency](#currency-element) | Indicates that the provided Currency was set to be supported by each successfully added PartyIdInfo. | + +**Table 6 – Return Bulk Participant Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Participants**. + +##### Return Participant Information Error + +Table 7 below contains the data model for _Return Participant Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 7 – Return Participant Information Error data model** + +
    + +##### Return Bulk Participant Information Error + +Table 8 below contains the data model for _Return Bulk Participant Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 8 – Return Bulk Participant Information Error data model** + +
    + +### API Resource Parties + +This section describes the data model of services for the resource **Parties**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Parties**. + +##### Lookup Party Information + +Table 9 below contains the data model for _Lookup Party Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | + +**Table 9 – Lookup Party Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Parties**. + +##### Return Party Information + +Table 10 below contains the data model for _Return Party Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | A sub-identifier or sub-type for the Party. | +| **party** | 1 | [Party](#party) | Information regarding the requested Party. | + + +**Table 10 – Return Party Information data model** + + +
    + +#### Error Responses + +##### Return Party Information Error + +Table 11 below contains the data model for _Return Party Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | A sub-identifier or sub-type for the Party. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 11 – Return Party Information Error data model** + +
    + +### API Resource Transaction Requests + +This section describes the data model of services for the resource **Transaction Requests**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transaction Requests**. + +##### Retrieve Transaction Request + +Table 12 below contains the data model for _Retrieve Transaction Request_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for re-sends of the same transaction request. A new ID should be generated for each new transaction request. | + +**Table 12 – Retrieve Transaction Request data model** + + +
    + +##### Perform Transaction Request Information + +Table 13 below contains the data model for _Perform Transaction Request Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [PartyIdInfo](#partyidinfo) | Information about the Payer type, id, subtype/id, FSP Id in the proposed financial transaction. +| **amount** | 1 | [Money](#money) | The requested amount to be transferred from the Payer to Payee. | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction. | +| **note** | 0..1 | [Note](#note-element) | Reason for the transaction request, intended to the Payer. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating party.

    Can be used to detect fraud.

    | +| **authenticationType** | 0..1 | [AuthenticationType](#authenticationtype-element) | OTP or QR Code, otherwise empty. | +| **expiration** | 0..1 | [DateTime](#datetime) | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also useful for notifying Consumer, Agent, Merchant that their request has a time limit. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 13 – Perform Transaction Request Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transaction Requests**. + + +##### Return Transaction Request Information + +Table 14 below contains the data model for _Return Transaction Request Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for re-sends of the same transaction request. A new ID should be generated for each new transaction request. | +| **transactionId** | 0..1 | [CorrelationId](#correlationid-element) | Identifies related /transactions (if a transaction has been created). | +| **transactionRequestState** | 1 | [TransactionRequestState](#transactionrequeststate-element) | The state of the transaction request. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 14 – Return Transaction Request Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Transaction Requests**. + +##### Return Transaction Request Information Error + +Table 15 below contains the data model for _Return Transaction Request Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 15 – Return Transaction Request Information Error data model** + +
    + +### API Resource Quotes + +This section describes the data model of services for the resource **Quotes**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Quotes**. + +##### Retrieve Quote Information + +Table 16 bleow contains the data model for _Retrieve Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message.| + +**Table 16 – Retrieve Quote Information data model** + +
    + +##### Calculate Quote + +Table 17 below contains the data model for _Calculate Quote_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | Identifies transactionRequest message. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [Party](#party) | Information about the Payer in the proposed financial transaction. | +| **amountType** | 1 | [AmountType](#amounttype-element) | SEND for sendAmount, RECEIVE for receiveAmount. | +| **amount** | 1 | [Money](#money) | Depending on amountType:
    If SEND: The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.

    If RECEIVE: The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities.
    | +| **fees** | 0..1 | [Money](#money) | The fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction for which the quote is requested. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating party. Can be used to detect fraud. | +| **note** | 0..1 | [Note](#note-element) | A memo that will be attached to the transaction. | +| **expiration** | 0..1 | [DateTime](#datetime) | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also useful for notifying Consumer, Agent, Merchant that their request has a time limit. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 17 – Calculate Quote data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Quotes**. + +##### Return Quote Information + +Table 18 below contains the data model for _Return Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transferAmount** | 1 | [Money](#money) | The amount of money that the Payer FSP should transfer to the Payee FSP. | +| **payerReceiveAmount** | 1 | [Money](#money) | The amount of money that the Payee should receive in the end-to-end transaction. Optional, as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | [Money](#money) | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | [Money](#money) | Transaction commission from the Payee FSP. | +| **expiration** | 1 | [DateTime](#datetime) | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the Payee. Can be used to detect fraud. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be attached to the transfer by the payer. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment | + +**Table 18 – Return Quote Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Quotes**. + +##### Return Quote Information Error + +Table 19 below contains the data model for _Return Quote Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 19 – Return Quote Information Error data model** + +
    + +### API Resource Authorizations + +This section describes the data model of services for the resource **Authorizations**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Authorizations**. + +##### Perform Authorization + +Table 20 below contains the data model for _Perform Authorization_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **authenticationType** | 0..1 | [AuthenticationType](#authenticationtype-element) | The type of authentication. | +| **retriesLeft** | 0..1 | [NrOfRetries](#nrofretries-element) | Number of retries left. | +| **amount** | 0..1 | [Money](#money) | The authorization amount. | +| **currency** | 0..1 | [CurrencyCode](#currencycode-enum) | The authorization currency. | + +**Table 20 – Perform Authorization data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Authorizations**. + +##### Return Authorization Result + +Table 21 below contains the data model for _Return Authorization Result_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **authenticationInfo** | 0..1 | [AuthenticationInfo](#authenticationinfo) | OTP or QR Code if entered, otherwise empty. | +| **responseType** | 1 | [AuthorizatonResponse](#authorizationresponse-element) | Enum containing response information, if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value. | + +**Table 21 – Return Authorization Result data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Authorizations**. + +##### Return Authorization Error + +Table 22 below contains the data model for _Return Authorization Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 22 – Return Authorization Error data model** + +
    + +### API Resource Transfers + +This section describes the data model of services for the resource **Transfers**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transfers**. + +##### Retrieve Transfer Information + +Table 23 below contains the data model for _Retrieve Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | + +**Table 23 – Retrieve Transfer Information data model** + +
    + +##### Perform Transfer + +Table 24 below contains the data model for _Perform Transfer_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **payeeFsp** | 1 | [FspId](#fspid-element) | Payee FSP in the proposed financial transaction. | +| **payerFsp** | 1 | [FspId](#fspid-element) | Payer FSP in the proposed financial transaction. | +| **amount** | 1 | [Money](#money) | The transfer amount to be sent. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet containing the amount delivered to the payee and the ILP Address of the payee and any other end-to-end data. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be fulfilled to commit the transfer. | +| **expiration** | 1 | [DateTime](#datetime) | Expiration can be set to get a quick failure Expiration of the transfer. The transfer should be rolled back if no fulfilment is delivered before this time. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 24 – Perform Transfer data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transfers**. + +##### Return Transfer Information + +Table 25 below contains the data model for _Return Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **fulfilment** | 0..1 | [IlpFulfilment](#ilpfulfilment-element) | The fulfilment of the condition specified with the transaction. Mandatory if transfer has completed successfully. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the transaction was completed. | +| **transferState** | 1 | [TransferState](#transferstate-enum) | The state of the transfer. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 25 – Return Transfer Information data model** + +
    + +#### Error Responses + +This section describes the data model of error responses used by the server in the API for services provided by the resource **Transfers**. + +##### Return Transfer Information Error + +Table 26 below contains the data model for _Return Transfer Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be reused for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 26 – Return Transfer Information Error data model** + +
    + +### API Resource Transactions + +This section describes the data model of services for the resource **Transactions**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transactions**. + +##### Retrieve Transaction Information + +Table 27 below contains the data model for **Retrieve Transaction Information**. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | + +**Table 27 – Retrieve Transaction Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transactions**. + +##### Return Transaction Information + +Table 28 below contains the data model for _Return Transaction Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the transaction was completed. | +| **transactionState** | 1 | [TransactionState](#transactionstate-element) | The state of the transaction. | +| **code** | 0..1 | [Code](#code-element) | Optional redemption information provided to Payer after transaction has been completed. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 28 – Return Transaction Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Transactions**. + +##### Return Transaction Information Error + +Table 29 below contains the data model for _Return Transaction Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 29 – Return Transaction Information Error data model** + +
    + +### API Resource Bulk Quotes + +This section describes the data model of services for the resource **Bulk Quotes**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Bulk Quotes**. + +##### Retrieve Bulk Quote Information + +Table 30 below contains the data model for _Retrieve Bulk Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be reused for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | + +**Table 30 – Retrieve Bulk Quote data model** + +
    + +##### Calculate Bulk Quote + +Table 31 contains the data model for _Calculate Bulk Quote_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. payer 1 PartyIdInfo Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| **GeoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **expiration** | 0..1 | [DateTime](#datetime) | Proposed expiration of the quote. | +| **individualQuotes** | 1..1000 | [IndividualQuote](#individualquote) | List of `IndividualQuote` elements. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 31 – Calculate Bulk Quote data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Bulk Quotes**. + +##### Return Bulk Quote Information + +Table 32 below contains the data model for _Return Bulk Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **individualQuoteResults** | 0..1000 | [IndividualQuoteResult](#individualquoteresult) | Fees for each individual transaction (if any are charged per transaction). expiration 1 DateTime Date and time until when the quotation is valid and can be honored when used in the subsequent transaction request. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 32 – Return Bulk Quote Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Bulk Quotes**. + +##### Return Bulk Quote Information Error + +Table 33 below contains the data model for _Return Bulk Quote Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 33 – Return Bulk Quote Information Error data model** + +
    + +### API Resource Bulk Transfers + +This section describes the data model of services for the resource **Bulk Transfers**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Bulk Transfers**. + +##### Retrieve Bulk Transfer Information + +Table 34 below contains the data model for _Retrieve Bulk Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | + +**Table 34 – Retrieve Bulk Transfer Information data model** + +
    + +##### Perform Bulk Transfer + +Table 35 contains the data model for _Perform Bulk Transfer_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | This identifies previous quotation request. The fees specified in the previous quotation will have to be honored in the transfer. | +| **payeeFsp** | 1 | [FspId](#fspid-element) | Payee FSP identifier. | +| **payerFsp** | 1 | [FspId](#fspid-element) | Information about the Payer in the proposed financial transaction. | +| **individualTransfers** | 1..1000 | [IndividualTransfer](#individualtransfer) | List of `IndividualTransfer` elements. | +| **expiration** | 1 | [DateTime](#datetime) | Expiration time of the transfers. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 35 – Perform Bulk Transfer data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Bulk Transfers**. + +##### Return Bulk Transfer Information + +Table 36 below contains the data model for _Return Bulk Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the bulk transfer was completed. | +| **individualTransferResults** | 0..1000 | [IndividualTransferResult](#individualtransferresult) | List of `IndividualTransferResult` elements. | +| **bulkTransferState** | 1 | [BulkTransferState](#bulktransferstate-enum) | The state of the bulk transaction. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 36 – Return Bulk Transfer Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Bulk Transfers**. + +##### Return Bulk Transfer Information Error + +Table 37 below contains the data model for _Return Bulk Transfer Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 37 – Return Bulk Transfer Information Error data model** + +
    + +## API Supporting Data Model + +This section defines the data model and contains the following sub-sections: + +- [Length Specification](#length-specification) introduces the formats used for the element data types used by the API. + +- [Element Data Type Formats](#element-data-type-formats) defines the element data types used by the API. + +- [Element Defintions](#element-defintions) defines the elements types used by the API. + +- [Complex Types](#complex-types) identifies the complex types used by the API. + +- [Enumerations](#enumerations) identifies the enumerations used by the API. + +
    + +### Length Specification +All element data types have both a minimum and maximum length. These lengths are indicated by one of the following: + +- A minimum and maximum length +- An exact length +- A regular expression limiting the element such that only a specific length or lengths can be used. + +#### Minimum and Maximum Length + +If a minimum and maximum length is used, this will be indicated after the data type in parentheses: First the minimum value (inclusive value), followed by two period characters (..), and then the maximum value (inclusive value). + +Examples: + +- `String(1..32)` – A String that is minimum one character and maximum 32 characters long. +- `Integer(3..10)` - An Integerr that is minimum 3 digits, but maximum 10 digits long. + +#### Exact Length + +If an exact length is used, this will be indicated after the data type in parentheses containing only one exact value. Other lengths are not allowed. + +Examples: + +- `String(3)` – A String that is exactly three characters long. +- `Integer(4)` – An Integer that is exactly four digits long. + +#### Regular Expressions + +Some element data types are restricted using regular expressions. The regular expressions in this document use the standard for syntax and character classes established by the programming language Perl[1](https://perldoc.perl.org/perlre.html#Regular-Expressions). + +
    + +### Element Data Type Formats + +This section contains the definition of element data types used by the API. + +#### String + +The API data type `String` is a normal JSON String[2](https://tools.ietf.org/html/rfc7159#section-7), limited by a minimum and maximum number of characters. + +##### Example Format I + +`String(1..32)` – A String that is minimum *1* character and maximum *32* characters long. + +An example of `String(1..32)` appears below: + +- _This String is 28 characters_ + +##### Example Format II + +`String(1..128)` – A String that is minimum *1* character and maximum *128* characters long. + +An example of `String(32..128)` appears below: + +- _This String is longer than 32 characters, but less than 128_ + +
    + +#### Enum + +The API data type `Enum` is a restricted list of allowed JSON [String](#string)) values; an enumeration of values. Other values than the ones defined in the list are not allowed. + +##### Example Format + +`Enum of String(1..32)` – A String that is minimum one character and maximum 32 characters long and restricted by the allowed list of values. The description of the element contains a link to the enumeration. + +
    + +#### UndefinedEnum + +The API data type `UndefinedEnum` is a JSON String consisting of one to 32 uppercase characters including an underscore character ( _) . + +##### Regular Expression + +The regular expression for restricting the `UndefinedEnum` type appears in Listing 1 below: + +``` +^[A-Z_]{1,32}$ +``` +**Listing 1 – Regular expression for data type UndefinedEnum** + +
    + +#### Name + +The API data type `Name` is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + +##### Regular Expression + +The regular expression for restricting the `Name` type is shown in Listing 2 below. The restriction will not allow a string consisting of whitespace only, all Unicode[3](http://www.unicode.org/) characters should be allowed, as well as period (.), apostrophe (“), dash (-), comma (,) and space ( ) characters. The maximum number of characters in the **Name** is 128. + +**Note:** In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag `UNICODE_CHARACTER_CLASS` needs to be enabled to allow Unicode characters. + +``` +^(?!\s*$)[\w .,'-]{1,128}$ +``` + +**Listing 2 – Regular expression for data type Name** + +
    + +#### Integer + +The API data type `Integer` is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits. + +##### Regular Expression + +The regular expression for restricting an `Integer` is shown in Listing 3 below. + +``` +^[1-9]\d*$ +``` + +**Listing 3 – Regular expression for data type Integer** + +##### Example Format + +`Integer(1..6)` – An `Integer` that is at minimum one digit long, maximum six digits. + +An example of `Integer(1..6)` appears below: + +- _123456_ + +
    + +#### OtpValue + +The API data type `OtpValue` is a JSON String of three to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed. + +##### Regular Expression + +The regular expression for restricting the `OtpValue` type appears in Listing 4 below. + +``` +^\d{3,10}$ +``` + +**Listing 4 – Regular expression for data type OtpValue** + +
    + +#### BopCode + +The API data type `BopCode` is a JSON String of three characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `BopCode` type appears in Listing 5 below. +``` +^[1-9]\d{2}$ +``` + +**Listing 5 – Regular expression for data type BopCode** + +
    + +#### ErrorCode + +The API data type `ErrorCode` is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `ErrorCode` type appears in Listing 6 below. + +``` +^[1-9]\d{3}$ +``` + +**Listing 6 – Regular expression for data type ErrorCode** + +
    + +#### TokenCode + +The API data type `TokenCode` is a JSON String between four and 32 characters, consisting of digits or upper or lowercase characters from **a** to **z**. + +##### Regular Expression + +The regular expression for restricting the `TokenCode` type appears in Listing 7 below. + +``` +^[0-9a-zA-Z]{4,32}$ +``` + +**Listing 7 – Regular expression for data type TokenCode** + +
    + +#### MerchantClassificationCode + +The API data type `MerchantClassificationCode` is a JSON String consisting of one to four digits. + +##### Regular Expression + +The regular expression for restricting the `MerchantClassificationCode` type appears in Listing 8 below. + +``` +^[\d]{1,4}$ +``` + +**Listing 8 - Regular expression for data type MerchantClassificationCode** + +
    + +#### Latitude + +The API data type `Latitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Latitude` type appears in Listing 9 below. + +``` +^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 9 – Regular expression for data type Latitude** + +
    + +#### Longitude + +The API data type `Longitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Longitude` type is shown in Listing 10 below. + +``` +^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0- +9]{1,6})?))$ +``` + +**Listing 10 – Regular expression for data type Longitude** + +
    + +#### Amount + +The API data type `Amount` is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Amount` type appears in Listing 11 below. This pattern: + +- Does not allow trailing zeroes. +- Allows an amount without a minor currency unit. +- Allows only four digits in the minor currency unit; a negative value is not allowed. +- Does not allow more than 18 digits in the major currency unit. + +The regular expression for restricting the `Amount` type is shown in Listing 11 below. + +``` +^([0]|([1-9][0-9]*))([.][0-9]{0,3}[1-9])?$ +``` + +**Listing 11 – Regular expression for data type Amount** + +##### Examples + +See [table](#results-for-validated-amount-values) below for validation results for some example `Amount` values using the [regular expression](#regular-expression-11) defined above. + +##### Results for validated Amount values + +| Value | Validation result | +| --- | --- | +| _5_ | Accepted | +| _5.0_ | Rejected | +| _5._ | Rejected | +| _5.00_ | Rejected | +| _5.5_ | Accepted | +| _5.50_ | Rejected | +| _5.5555_ | Accepted | +| _5.55555_ | Rejected | +| _555555555555555555_ | Accepted | +| _5555555555555555555_ | Rejected | +| _-5.5_ | Rejected | +| _0.5_ | Accepted | +| _.5_ | Rejected | +| _00.5_ | Rejected | +| _0_ | Accepted | + +**Table 38 – Example results for different values for Amount type** + +
    + +#### DateTime + +The API data type `DateTime` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting `DateTime` appears in Listing 12 below. The format is according to ISO 8601[4](https://www.iso.org/iso-8601-date-and-time-format.html) , expressed in a combined date, time and time format. A more readable version of the format is `yyyy-MM-dd'T'HH:mm:ss.SSS[-HH:MM]` + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])- +(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1- +9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02- +29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ +``` + +**Listing 12 – Regular expression for data type DateTime** + +##### Examples + +Two examples of the `DateTime` type appear below: + +- _2016-05-24T08:38:08.699-04:00_ + +- _2016-05-24T08:38:08.699Z_ (where **Z** indicates Zulu time zone, which is the same as UTC). + +
    + +#### Date + +The API data type `Date` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Date` type appears in Listing 13 below. This format, as specified in ISO 8601, contains a date only. A more readable version of the format is `yyyy-MM-dd`. + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])- +(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1- +9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ +``` + +**Listing 13 – Regular expression for data type Date** + +##### Examples + +Two examples of the `Date` type appear below: + +- _1982-05-23_ + +- _1987-08-05_ + +
    + +#### UUID + +The API data type `UUID` (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122[5](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A `UUID` is always 36 characters long, 32 hexadecimal symbols and four dashes (-). + +##### Regular Expression + +The regular expression is shown in Listing 14 below. + +``` +^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ +``` + +**Listing 14 – Regular expression for data type UUID** + +##### Example + +An example of a `UUID` type appears below: + +- _a8323bc6-c228-4df2-ae82-e5a997baf898_ + +
    + +#### BinaryString + +The API data type `BinaryString` is a JSON String. The String is the base64url[6](https://tools.ietf.org/html/rfc4648#section-5) encoding of a string of raw bytes. The length restrictions for the `BinaryString` type apply to the underlying binary data, indicating the allowed number of bytes. For data types with a fixed size no padding character is used. + +##### Regular Expression + +The regular expression for restricting the **BinaryString** type appears in Listing 15 below. + +``` +^[A-Za-z0-9-_]+[=]?$ +``` + +**Listing 15 – Regular expression for data type BinaryString** + +##### Example Format + +`BinaryString(32)` –32 bytes of data base64url encoded. + +An example of a `BinaryString(32..256)` appears below. Note that a padding character, `'='` has been added to ensure that the string is a multiple of four characters. + +- _QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE=_ + + +
    + +#### BinaryString32 + +The API data type _BinaryString32_ is a fixed size variation of the API data type `BinaryString` defined [here](#binarystring), in which the raw underlying data is always of 32 bytes. The data type _BinaryString32_ should not use a padding character because the size of the underlying data is fixed. + +##### Regular Expression +The regular expression for restricting the _BinaryString32_ type appears in Listing 16 below. + +``` +^[A-Za-z0-9-_]{43}$ +``` + +**Listing 16 – Regular expression for data type BinaryString32** + +##### Example Format +`BinaryString(32)` – 32 bytes of data base64url encoded. + +An example of a `BinaryString32` appears below. Note that this is the same binary data as the example shown in the [Example Format](#example-format-3) of the `BinaryString` type, but due to the underlying data being fixed size, the padding character `'='` is excluded. + +``` +QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE +``` + +
    + +### Element Definitions + +This section contains the definition of the elements types that are used by the API. + +#### AmountType element + +Table 39 below contains the data model for the element `AmountType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AmountType** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the amount type. See [AmountType](#amounttype-enum) enumeration for more information on allowed values. | + +**Table 39 – Element AmountType** + +
    + +#### AuthenticationType element + +Table 40 below contains the data model for the element `AuthenticationType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Authentication** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authentication type. See [AuthenticationType](#authenticationtype-enum) enumeration for possible enumeration values. | + +**Table 40 – Element AuthenticationType** + +
    + +#### AuthenticationValue element + +Table 41 below contains the data model for the element `AuthenticationValue`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthenticationValue** | 1 | Depends on [AuthenticationType](#authenticationtype-element).

    If `OTP`: type is [Integer(1..6)](#integer). For example:**123456**

    OtpValue
    If `QRCODE`: type is [String(1..64)](#string) | This element contains the authentication value. The format depends on the authentication type used in the [AuthenticationInfo](#authenticationinfo) complex type. | + +**Table 41 – Element AuthenticationValue** + +
    + +#### AuthorizationResponse element + +Table 42 below contains the data model for the element `AuthorizationResponse`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthorizationResponse** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authorization response. See [AuthorizationResponse](#authorizationresponse-enum) enumeration for possible enumeration values. | + +**Table 42 – Element AuthorizationResponse** + +
    + +#### BalanceOfPayments element + +Table 43 below contains the data model for the element `BalanceOfPayment`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BalanceOfPayments** | 1 | [BopCode](#bopcode) | The possible values and meaning are defined in [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/) | + +**Table 43 – Element BalanceOfPayments** + +
    + +#### BulkTransferState element + +Table 44 below contains the data model for the element `BulkTransferState`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BulkTransferState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [BulkTransferState](#bulktransferstate-enum) enumeration for information on allowed values| + +**Table 44 – Element BulkTransferState** + +
    + +#### Code element + +Table 45 below contains the data model for the element `Code`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Code** | 1 | [TokenCode](#tokencode) | Any code/token returned by the Payee FSP. | + +**Table 45 – Element Code** + +
    + +#### CorrelationId element + +Table 46 below contains the data model for the element `CorrelationId`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **CorrelationId** | 1 |[UUID](#uuid) | Identifier that correlates all messages of the same sequence. | + + +**Table 46 – Element CorrelationId** + +
    + +#### Currency element + +Table 47 below contains the data model for the element `Currency`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Currency** | 1 | [Enum](#enum) of [String(3)](#string) | See [Currency](#currencycode-enum) enumeration for information on allowed values | + +**Table 47 – Element Currency** + +
    + +#### DateOfBirth element + +Table 48 below contains the data model for the element `DateOfBirth`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **DateOfBirth** | 1 | Examples

    Two examples of the [DateTime](#datetime) type appear below:

    2016-05-24T08:38:08.699-04:00

    2016-05-24T08:38:08.699Z (where Z indicates Zulu time zone, which is the same as UTC).

    Date

    | Date of Birth of the Party.| + +**Table 48 – Element DateOfBirth** + +
    + +#### ErrorCode element + +Table 49 below contains the data model for the element `ErrorCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorCode** | 1 | [ErrorCode](#errorcode) | Four digit error code, see section on [Error Codes](#error-codes) for more information. | + +**Table 49 – Element ErrorCode** + +
    + +#### ErrorDescription element + +Table 50 below contains the data model for the element `ErrorDescription`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorDescription** | 1 | [String(1..128)](#string) | Error description string. | + +**Table 50 – Element ErrorDescription** + +
    + +#### ExtensionKey element + +Table 51 below contains the data model for the element `ExtensionKey`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionKey** | 1 | [String(1..32)](#string) | The extension key. | + +**Table 51 – Element ExtensionKey** + +
    + +#### ExtensionValue element + +Table 52 below contains the data model for the element `ExtensionValue`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionValue** | 1 | [String(1..128)](#string) | The extension value. | + +**Table 52 – Element ExtensionValue** + +
    + +#### FirstName element +Table 53 below contains the data model for the element `FirstName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FirstName** | 1 | [Name](#name) | First name of the Party | + +**Table 53 – Element FirstName** + +
    + +#### FspId element + +Table 54 below contains the data model for the element `FspId`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FspId** | 1 | [String(1..32)](#string)| The FSP identifier. | + +**Table 54 – Element FspId** + +
    + +#### IlpCondition element + +Table 55 below contains the data model for the element `IlpCondition`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpCondition** | 1 | [BinaryString32](#binarystring32) | The condition that must be attached to the transfer by the Payer. | + +**Table 55 – Element IlpCondition** + +
    + +#### IlpFulfilment element + +Table 56 below contains the data model for the element `IlpFulfilment`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpFulfilment** | 1 | [BinaryString32](#binarystring32) | The fulfilment that must be attached to the transfer by the Payee. | + +**Table 56 – Element IlpFulfilment** + +
    + +#### IlpPacket element + +Table 57 below cntains the data model for the element `IlpPacket`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpPacket** | 1 | Example

    An example of a [UUID](#uuid) type appears below:

    a8323bc6-c228-4df2-ae82-e5a997baf898

    [BinaryString(1..32768)](#binarystring)

    | Information for recipient (transport layer information). | + +**Table 57 – Element IlpPacket** + +
    + +#### LastName element + +Table 58 below contains the data model for the element `LastName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **LastName** | 1 | [Name](#name) | Last name of the Party (ISO 20022 definition). | + +**Table 58 – Element LastName** + +
    + +#### MerchantClassificationCode element + +Table 59 below contains the data model for the element `MerchantClassificationCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MerchantClassificationCode** | 1 | [MerchantClassificationCode](#merchantclassificationcode) | A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, and so on. | + +**Table 59 – Element MerchantClassificationCode** + +
    + +#### MiddleName element + +Table 60 below contains the data model for the element `MiddleName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MiddleName** | 1 | [Name](#name) | Middle name of the Party (ISO 20022 definition). | + +**Table 60 – Element MiddleName** + +
    + +#### Note element + +Table 61 below contains the data model for the element `Note`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Note** | 1 | [String(1..128)](#string) | Memo assigned to transaction. | + +**Table 61 – Element Note** + +
    + + +#### NrOfRetries element + +Table 62 below contains the data model for the element `NrOfRetries`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **NrOfRetries** | 1 | [Integer(1..2)](#integer) | Number of retries. | + +**Table 62 – Element NrOfRetries** + +
    + +#### PartyIdentifier element + +Table 63 below contains the data model for the element `PartyIdentifier`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdentifier** | 1 | [String(1..128)](#string) | Identifier of the Party.| + +**Table 63 – Element PartyIdentifier** + +
    + +#### PartyIdType element + +Table 64 below contains the data model for the element `PartyIdType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdType** | 1 | Enum of [String(1..32)](#string) | See [PartyIdType](#partyidtype-enum) enumeration for more information on allowed values. | + +**Table 64 – Element PartyIdType** + +
    + +#### PartyName element + +Table 65 below contains the data model for the element `PartyName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyName** | 1 | `Name` | Name of the Party. Could be a real name or a nickname. | + +**Table 65 – Element PartyName** + +
    + +#### PartySubIdOrType element + +Table 66 below contains the data model for the element `PartySubIdOrType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartySubIdOrType** | 1 | [String(1..128)](#string) | Either a sub-identifier of a [PartyIdentifier](#partyidentifier-element), or a sub-type of the [PartyIdType](#partyidtype-element), normally a `PersonalIdentifierType`. | + +**Table 66 – Element PartySubIdOrType** + +
    + +#### RefundReason element + +Table 67 below contains the data model for the element `RefundReason`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **RefundReason** | 1 | [String(1..128)](#string) | Reason for the refund. | + +**Table 67 – Element RefundReason** + +
    + +#### TransactionInitiator element + +Table 68 below contains the data model for the element `TransactionInitiator`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiator** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiator](#transactioninitiator-enum) enumeration for more information on allowed values. | + +**Table 68 – Element TransactionInitiator** + +
    + +#### TransactionInitiatorType element + +Table 69 below contains the data model for the element `TransactionInitiatorType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiatorType** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiatorType](#transactioninitiatortype-enum) enumeration for more information on allowed values. | + +**Table 69 – Element TransactionInitiatorType** + +
    + +#### TransactionRequestState element + +Table 70 below contains the data model for the element `TransactionRequestState`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionRequestState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionRequestState](#transactionrequeststate-enum) enumeration for more information on allowed values. | + + +**Table 70 – Element TransactionRequestState** + +
    + +#### TransactionScenario element + +Table 71 below contains the data model for the element `TransactionScenario`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionScenario** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionScenario](#transactionscenario-enum) enumeration for more information on allowed values. | + +**Table 71 – Element TransactionScenario** + +
    + +#### TransactionState element + +Table 72 below contains the data model for the element `TransactionState`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionState](#transactionstate-enum) enumeration for more information on allowed values. | + +**Table 72 – Element TransactionState** + +
    + +#### TransferState element + +Table 73 below contains the data model for the element `TransferState`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransferState](#transferstate-enum) enumeration for more information on allowed values. | + +**Table 73 – Element TransferState** + +
    + +#### TransactionSubScenario element + +Table 74 below contains the data model for the element `TransactionSubScenario`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionSubScenario** | 1 | [UndefinedEnum](#undefinedenum) | Possible sub-scenario, defined locally within the scheme.| + +**Table 74 – Element TransactionSubScenario** + +
    + +### Complex Types + +This section contains the complex types that are used by the API. + +#### AuthenticationInfo + +Table 75 below contains the data model for the complex type `AuthenticationInfo`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authentication** | 1 | [AuthenticationType](#authenticationtype-element) | The type of authentication. | +| **authenticationValue** | 1 | [AuthenticationValue](#authenticationvalue-element) | The authentication value. | + +**Table 75 – Complex type AuthenticationInfo** + +
    + +#### ErrorInformation + +Table 76 below contains the data model for the complex type `ErrorInformation`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **errorCode** | 1 | [ErrorCode](#errorcode) | Specific error number. | +| **errorDescription** | 1 | [ErrorDescription](#errordescription-element) | Error description string. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional list of extensions, specific to deployment. | + +**Table 76 – Complex type ErrorInformation** + +
    + +#### Extension + +Table 77 below contains the data model for the complex type `Extension`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **key** | 1 | [ExtensionKey](#extensionkey-element) | The extension key. | +| **value** | 1 | [ExtensionValue](#extensionvalue-element) | The extension value. | + +**Table 77 – Complex type Extension** + +
    + +#### ExtensionList + +Table 78 below contains the data model for the complex type `ExtensionList`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **extension** | 1..16 | [Extension](#extension) | A number of Extension elements. | + +**Table 78 – Complex type ExtensionList** + +
    + +#### IndividualQuote + +Table 79 below contains the data model for the complex type `IndividualQuote`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **amountType** | 1 | [AmountType](#amounttype-element) | `SEND_AMOUNT` for _sendAmount_,

    `RECEIVE_AMOUNT` for _receiveAmount_.

    +| **amount** | 1 | [Money](#money) | Depending on amountType:

    If `SEND`: The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.

    If `RECEIVE`: The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. | +| **fees** | 0..1 | [Money](#money) | The fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction that the quote is requested for. | +| **note** | 0..1 | [Note](#note-element) | A memo that will be attached to the transaction. This is sent in the quote so it can be included in the ILP Packet. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 79 – Complex type IndividualQuote** + +
    + +#### IndividualQuoteResult + +Table 80 below contains the data model for the complex type `IndividualQuoteResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies the quote message. | +| **payeeReceiveAmount** | 0..1 | [Money](#money) | Amount that the Payee should receive in the end-toend transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | [Money](#money) | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | [Money](#money) | Transaction commission from the Payee FSP. | +| **ilpPacket** | 0..1 | [IlpPacket](#ilppacket-element) | The ILP Packet that must be attached to the transfer by the payer. | +| **condition** | 0..1 | [IlpCondition](#ilpcondition-element) | The condition that must be attached to the transfer by the payer. | +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | Error code, category description.

    Note: If errorInformation is set, the following are not set:

    • receiveAmount
    • payeeFspFee
    • payeeFspCommission
    • ilpPacket
    • condtion
    | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment | + +**Table 80 – Complex type IndividualQuoteResult** + +
    + +#### IndividualTransfer + +Table 81 below contains the data model for the complex type `IndividualTransfer`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | Identifies messages related to the same /transfers sequence. | +| **transferAmount** | 1 | [Money](#money) | The transaction amount to be sent. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet containing the amount delivered to the payee and the ILP Address of the payee and any other end-to-end data. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be fulfilled to commit the transfer. +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 81 – Complex type IndividualTransfer** + +
    + +#### IndividualTransferResult + +Table 82 below contains the data model for the complex type `IndividualTransferResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | Identifies messages related to the same /transfers sequence. | +| **fulfilment** | 0..1 | [IlpFulfilment](#ilpfulfilment-element) | The fulfilment of the condition specified with the transaction.

    Note: Either fulfilment is set or errorInformation is set, not both.

    +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | If transactionState is `REJECTED`, error information may be provided.

    Note: Either fulfilment is set or errorInformation is set, not both.

    +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 82 – Complex type IndividualTransferResult** + +#### GeoCode + +Table 83 below contains the data model for the complex type `GeoCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **latitude** | 1 | [Latitude](#latitude) | The Latitude of the service initiating Party. | +| **longitude** | 1 | [Longitude](#longitude) | The Longitude of the service initiating Party. | + +**Table 83 – Complex type GeoCode** + +
    + +#### Money + +Table 84 below contains the data model for the complex type `Money`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **currency** | 1 | [Currency](#currency-element) | The currency of the Amount. | +| **amount** | 1 | [Amount](#amount) | The amount of Money. | + +**Table 84 – Complex type Money** + +
    + +#### Party + +Table 85 below contains the data model for the complex type `Party`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdInfo** | 1 | [PartyIdInfo](#partyidinfo) | Party Id type, id, sub ID or type, and FSP Id. | +| **merchantClassificationCode** | 0..1 | [MerchantClassificationCode](#merchantclassificationcode) | Optional: Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments. | +| **name** | 0..1 | [PartyName](#partyname-element) | The name of the party, could be a real name or a nick name. | +| **personalInfo** | 0..1 | [PartyPersonalInfo](#partypersonalinfo) | Personal information used to verify identity of Party such as first, middle, last name and date of birth. | + +**Table 85 – Complex type Party** + +
    + +#### PartyComplexName + +Table 86 below contains the data model for the complex type `PartyComplexName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **firstName** | 0..1 | [FirstName](#firstname-element) | First name. | +| **middleName** | 0..1 | [MiddleName](#middlename-element) | Middle name. | +| **lastName** | 0..1 | [LastName](#lastname-element) | Last name. | + +**Table 86 – Complex type PartyComplexName** + +
    + +#### PartyIdInfo + +Table 87 below contains the data model for the complex type `PartyIdInfo`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | [FspId](#fspid-element) | The FSP ID (if known) | + +**Table 87 – Complex type PartyIdInfo** + +
    + +#### PartyPersonalInfo + +Table 88 below contains the data model for the complex type `PartyPersonalInfo`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **complexName** | 0..1 | [PartyComplexName](#partycomplexname) | First, middle and last name. | +| **dateOfBirth** | 0..1 | [DateOfBirth](#dateofbirth-element) | Date of birth. | + +**Table 88 – Complex type PartyPersonalInfo** + +
    + +#### PartyResult + +Table 89 below contains the data model for the complex type `PartyResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyId** | 1 | [PartyIdInfo](#partyidinfo) | Party Id type, id, sub ID or type, and FSP Id. | +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | If the Party failed to be added, error information should be provided. Otherwise, this parameter should be empty to indicate success. | + +**Table 89 – Complex type PartyPersonalInfo** + +
    + +#### Refund + +Table 90 below contains the data model for the complex type `Refund`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **originalTransactionId** | 1 | [CorrelationId](#correlationid-element) | Reference to the original transaction ID that is requested to be refunded.| +| **refundReason** | 0..1 | [RefundReason](#refundreason-element) | Free text indicating the reason for the refund. | + +**Table 90 – Complex type Refund** + +
    + +#### Transaction + +Table 91 below contains the data model for the complex type `Transaction`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | ID of the transaction, the ID is determined by the Payer FSP during the creation of the quote. | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | ID of the quote, the ID is determined by the Payer FSP during the creation of the quote. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [Party](#party) | Information about the Payer in the proposed financial transaction. | +| **amount** | 1 | [Money](#money) | The transaction amount to be sent. | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of the transaction. | +| **note** | 0..1 | [Note](#note-element) | Memo associated to the transaction,intended to the Payee. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 91 – Complex type Transaction** + +#### TransactionType + +Table 92 below contains the data model for the complex type `TransactionType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **scenario** | 1 | [TransactionScenario`](#transactionscenario-element) | Deposit, withdrawal, refund, … | +| **subScenario** | 0..1 | [TransactionSubScenario](#transactionsubscenario-element) | Possible sub-scenario, defined locally within the scheme. | +| **initiator** | 1 | [TransactionInitiator](#transactioninitiator-enum) | Who is initiating the transaction: payer or payee | +| **initiatorType** | 1 | [TransactionInitiatorType](#transactioninitiatortype-enum) | Consumer, agent, business, … | +| **refundInfo** | 0..1 | [Refund](#refund) | Extra information specific to a refund scenario. Should only be populated if scenario is `REFUND`. | +| **balanceOfPayments** | 0..1 | [BalanceOfPayments](#balanceofpayments-element) | Balance of Payments code. | + +**Table 92 – Complex type TransactionType** + +
    + + +### Enumerations + +This section contains the enumerations used by the API. + +#### AmountType enum + +Table 93 below contains the allowed values for the enumeration `AmountType`. + +| Name | Description | +| --- | --- | +| **SEND** | The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. | +| **RECEIVE** | The amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive fees. | + +**Table 93 – Enumeration AmountType** + +
    + +#### AuthenticationType enum + +Table 94 below contains the allowed values for the enumeration `AuthenticationType`. + +| Name | Description | +| --- | ---| +| **OTP** | One-time password, either chosen by the Party, or generated by the Party’s FSP. | +| **QRCODE** | QR code used as One Time Password. | + +**Table 94 – Enumeration AuthenticationType** + +
    + +#### AuthorizationResponse enum + +Table 95 below contains the allowed values for the enumeration `AuthorizationResponse`. + +| Name | Description | +| --- | --- | +| **ENTERED** | Consumer entered the authentication value. | +| **REJECTED** | Consumer rejected the transaction. | +| **RESEND** | Consumer requested to resend the authentication value. | + +**Table 95 – Enumeration AuthorizationResponse** + +
    + +#### BulkTransferState + +Table 96 below contains the allowed values for the enumeration `BulkTransferState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payee FSP has received the bulk transfer from the Payer FSP. | +| **PENDING** | Payee FSP has validated the bulk transfer. | +| **ACCEPTED** | Payee FSP has accepted to process the bulk transfer. | +| **PROCESSING** | Payee FSP has started to transfer fund to the Payees. | +| **COMPLETED** | Payee FSP has completed transfer of funds to the Payees. | +| **REJECTED** | Payee FSP has rejected to process the transfer. | + +**Table 96 – Enumeration BulkTransferState** + +
    + +#### CurrencyCode enum + +The currency codes defined in ISO 4217[7](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies. The currency codes from ISO 4217 are not is shown in this document, implementers are instead encouraged to use the information provided by the ISO 4217 standard directly. + +
    + +#### PartyIdType enum + +Table 97 below contains the allowed values for the enumeration `PartyIdType`. + +| Name | Description | +| --- | ---| +| **MSISDN** | Used when an MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. | +| **EMAIL** | Used when an email should be used as reference to a participant. The format of the email should be according to the informational RFC 3696. | +| **PERSONAL_ID** | Used when some kind of personal identifier should be used as reference to a participant. Examples of personal identification can be passport number, birth certificate number, national registration number or similar. The identifier number shall be added in the PartyIdentifier element. The personal identifier type shall be added in the PartySubIdOrType element. | +| **BUSINESS** | Used when a specific Business (for example, an Organization or a Company) should be used as reference to a participant. The Business identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. | +| **DEVICE** | Used when a specific Device (for example, a POS or ATM) ID connected to a specific Business or Organization should be used as reference to a Party. To use a specific device under a specific Business or Organization, the PartySubIdOrType element should be used. | +| **ACCOUNT_ID** | Used when a bank account number or FSP account ID should be used as reference to a participant. The `ACCOUNT_ID` identifier can be in any format, as formats can greatly differ depending on country and FSP. | +| **IBAN** | Used when a bank account number or FSP account ID should be used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without any whitespace. | +| **ALIAS** | Used when an alias should be used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias can be username in the FSP system. The `ALIAS` identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. | + +**Table 97 – Enumeration PartyIdType** + +
    + +#### PersonalIdentifierType enum + +Table 98 below contains the allowed values for the enumeration `PersonalIdentifierType`. + +| Name | Description | +| --- | --- | +| **PASSPORT** | Used when a passport number should be used as reference to a Party | +| **NATIONAL_REGISTRATION** | Used when a national registration number should be used as reference to a Party | +| **DRIVING_LICENSE** | Used when a driving license should be used as reference to a Party | +| **ALIEN_REGISTRATION** | Used when an alien registration number should be used as reference to a Party | +| **NATIONAL_ID_CARD** | Used when a national ID card number should be used as reference to a Party | +| **EMPLOYER_ID** | Used when a tax identification number should be used as reference to a Party | +| **TAXI_ID_NUMBER** | Used when a tax identification number should be used as reference to a Party. | +| **SENIOR_CITIZENS_CARD** | Used when a senior citizens card number should be used as reference to a Party | +| **MARRIAGE_CERTIFICATE** | Used when a marriage certificate number should be used as reference to a Party | +| **HEALTH_CARD** | Used when a health card number should be used as reference to a Party | +| **VOTERS_ID** | Used when a voters identification number should be used as reference to a Party | +| **UNITED_NATIONS** | Used when an UN (United Nations) number should be used as reference to a Party | +| **OTHER_ID** | Used when any other type of identification type number should be used as reference to a Party | + +**Table 98 – Enumeration PersonalIdentifierType** + +
    + +#### TransactionInitiator enum + +Table 99 below contains the allowed values for the enumeration `TransactionInitiator`. + +| Name | Description | +| --- | --- | +| **PAYER** | The sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. | +| **PAYEE** | The recipient of the funds is also initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP, pre-approval of the Payee, or by manually approving in his or her own Device. | + +**Table 99 – Enumeration TransactionInitiator** + +
    + +#### TransactionInitiatorType enum + +Table 100 below contains the allowed values for the enumeration `TransactionInitiatorType`. + +| Name | Description | +| --- | --- | +| **CONSUMER** | Consumer is the initiator of the transaction. | +| **AGENT** | Agent is the initiator of the transaction. | +| **BUSINESS** | Business is the initiator of the transaction. | +| **DEVICE** | Device is the initiator of the transaction. | + +**Table 100 – Enumeration TransactionInitiatorType** + +
    + +#### TransactionRequestState enum + +Table 101 below contains the allowed values for the enumeration `TransactionRequestState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payer FSP has received the transaction from the Payee FSP. | +| **PENDING** | Payer FSP has sent the transaction request to the Payer. | +| **ACCEPTED** | Payer has approved the transaction. | +| **REJECTED** | Payer has rejected the transaction. | + +**Table 101 – Enumeration TransactionRequestState** + +
    + +#### TransactionScenario enum + +Table 102 below contains the allowed values for the enumeration `TransactionScenario`. + +| Name | Description | +| --- | --- | +| **DEPOSIT** | Used for performing a Cash-In (deposit) transaction, where in the normal case electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. | +| **WITHDRAWAL** | Used for performing a Cash-Out (withdrawal) transaction, where in the normal case electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. | +| **TRANSFER** | Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. | +| **PAYMENT** | Typically used for performing a transaction from a Consumer to a Merchant/Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online to purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. | +| **REFUND** | Used for performing a refund of transaction. | + +**Table 102 – Enumeration TransactionScenario** + +
    + +#### TransactionState enum + +Table 103 below contains the allowed values for the enumeration `TransactionState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payee FSP has received the transaction from the Payer FSP. | +| **PENDING** | Payee FSP has validated the transaction. | +| **COMPLETED** | Payee FSP has successfully performed the transaction. | +| **REJECTED** | Payee FSP has failed to perform the transaction. | + +**Table 103 – Enumeration TransactionState** + +
    + +#### TransferState enum + +Table 104 below contains the allowed values for the enumeration `TransferState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | The next ledger has received the transfer. | +| **RESERVED** | The next ledger has reserved the transfer. | +| **COMMITTED** | The next ledger has successfully performed the transfer. | +| **ABORTED** | The next ledger has aborted the transfer due a rejection or failure to perform the transfer. | + +**Table 104 – Enumeration TransferState** + +
    + +### Error Codes + +Each error code in the API is a four-digit number, such as **1234**, where the first number (**1** in the example) represents the highlevel error category, the second number (**2** in the example) represents the low-level error category, and the last two numbers (**34** in the example) represents the specific error. Figure 1 shows the structure of an error code. The following sub-sections contains information and defined error codes per high-level error category. + +![Figure 1 - Error code structure](../assets/sequence-diagram-figure-1.png) + +**Figure 1 – Error code structure** + +Each defined high- and low-level category combination contains a generic error (_x_**0**_xx_), which can be used if there is no specific error, or if the server would not like to return information which is considered private. + +All specific errors below _xx_**40**, that is, _xx_**00** to _xx_**39**, are reserved for future use by the API. All specific errors above and including _xx40_, can be used for scheme-specific errors. If a client receives an unknown scheme-specific error, the unknown scheme-specific error should be interpreted as a generic error for the high- and low-level category combination instead (_xx_**00**). + +#### Communication Errors – 1xxx + +All possible communication or network errors that could arise that cannot be represented by an HTTP status code should use +the high-level error code 1 (error codes **1**_xxx_). Because all services in the API are asynchronous, these error codes should generally be used by a Switch in the Callback to the client FSP if the Peer FSP could not be reached, or if a callback is not received from the Peer FSP within an agreed timeout. + +Low level categories defined under Communication Errors: + +- **Generic Communication Error – 10**_xx_ + +See Table 105 below for all communication errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **1000** | Communication error | Generic communication error. | X | X | X | X | X | X | X | X | X | +| **1001** | Destination communication error | The Destination of the request failed to be reached. This usually indicates that a Peer FSP failed to respond from an intermediate entity. | X | X | X | X | X | X | X | X | X | + +**Table 105 – Communication errors – 1xxx** + +
    + +#### Server Errors – 2xxx + +All errors occurring in the server in which the server failed to fulfil an apparently valid request from the client should use the high-level error code 2 (error codes **2**_xxx_). These error codes should indicate that the server is aware that it has encountered an error or is otherwise incapable of performing the requested service. + +Low-level categories defined under server Errors: + +- **Generic server Error – 20**_xx_ + +See Table 106 below for all server errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **2000** | Generic server error | Generic server error to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **2001** | Internal server error | A generic unexpected exception. This usually indicates a bug or unhandled error case. | X | X | X | X | X | X | X | X | X | +| **2002** | Not implemented | Service requested is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **2003** | Service currently unavailable | Service requested is currently unavailable on the server. This could be because maintenance is taking place, or because of a temporary failure. | X | X | X | X | X | X | X | X | X | +| **2004** | Server timed out | A time out has occurred, meaning the next Party in the chain did not send a callback in time. This could be because a timeout is set too low or because something took longer than it should. | X | X | X | X | X | X | X | X | X | +| **2005** | Server busy | Server is rejecting requests due to overloading. Try again later. | X | X | X | X | X | X | X | X | X | + +**Table 106 – Server errors – 2xxx** + +
    + +#### Client Errors – 3xxx** + +All possible errors occurring in the server where the server’s opinion is that the client have sent one or more erroneous parameters should use the high-level error code 3 (error codes **3**_xxx_). These error codes should indicate that the server could not perform the service according to the request from the client. The server should provide an explanation why the service could not be performed. + +Low level categories defined under client Errors: +- **Generic Client Error – 30**_xx_ + - See Table 107 for the generic client errors defined in the API. +- **Validation Error – 31**_xx_ + - See Table 108 for the validation errors defined in the API. +- **Identifier Error – 32**_xx_ + - See Table 109 for the identifier errors defined in the API. +- **Expired Error – 33**_xx_ + - See Table 110 for the expired errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3000** | Generic client error | Generic client error, to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3001** | Unacceptable version requested | Client requested to use a protocol version which is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **3002** | Unknown URI | The provided URI was unknown by the server. | | | | | | | | | | +| **3003** | Add Party information error | An error occurred while adding or updating information regarding a Party. | X | | | | | | | | | | + +**Table 107 – Generic client errors – 30xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3100** | Generic validation error | Generic validation error to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3101** | Malformed syntax | The format of the parameter is not valid. For example, amount set to 5.ABC. The error description field should specify which element is erroneous. |X | X | X | X | X | X | X | X | X | +| **3102** | Missing mandatory element | A mandatory element in the data model was missing. | X | X | X | X | X | X | X | X | X | +| **3103** | Too many elements | The number of elements of an array exceeds the maximum number allowed. | X | X | X | X | X | X | X | X | X | +| **3104** | Too large payload | The size of the payload exceeds the maximum size. | X | X | X | X | X | X | X | X | X | +| **3105** | Invalid signature | Some parameters have changed in the message, making the signature invalid. This may indicate that the message may have been modified maliciously. |X | X | X | X | X | X | X | X | X | +| **3106** | Modified request | A request with the same ID has previously been processed where the parameters are not the same. | | | X | X | | X | | X | X | +| **3107** | Missing mandatory extension parameter |A scheme mandatory extension parameter was missing. | | | X | X | X | X | X | X | X | + +**Table 108 – Validation Errors – 31xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3200** | Generic ID not found | Generic ID error provided by the client. | X | X | X | X | X | X | X | X | X | +| **3201** | Destination FSP Error| The Destination FSP does not exist or cannot be found. | X | X | X | X | X | X | X | X | X | +| **3202** | Payer FSP ID not found | The provided Payer FSP ID not found. | | | | | | X | | X | X | +| **3203** | Payee FSP ID not found | The provided Payer FSP ID not found. | | | | | | X | | X | X | +| **3204** | Party not found | The Party with the provided identifier, identifier type, and optional sub id or type was not found. | X | X | X | X | | | | | | +| **3205** | Quote ID not found | The provided Quote ID was not found in the server. | | | | X | | X | | | | +| **3206** | Transaction request ID not found | The provided Transaction Request ID was not found in the server. | | | X | | | X | | | | +| **3207** | Transaction ID not found | The provided Transaction ID was not found in the server. | | | | | | | X | | | +| **3208** | Transfer ID not found | The provided Transfer ID was not found in the server. | | | | | | X | | | | +| **3209** | Bulk quote ID not found | The provided Bulk Quote ID was not found in the server. | | | | | | | | X | X | +| **3210** | Bulk transfer ID not found | The provided Bulk Transfer ID was not found in the server. | | | | | | | | | X | + +**Table 109 – Identifier Errors – 32xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3300** |Generic expired error | Generic expired object error, to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3301** | Transaction request expired | Client requested to use a transaction request that has already expired. | | | | X | | | | | | +| **3302** | Quote expired | Client requested to use a quote that has already expired. | | | | | X | | | X | X | +| **3303** | Transfer expired | Client requested to use a transfer that has already expired. | X | X | X | X | X | X | X | X | X | + +**Table 110 – Expired Errors – 33xx** + +
    + +#### Payer Errors – 4xxx + +All possible errors occurring in the server when the Payer or the Payer FSP is the cause of an error should use the high-level error code 4 (error codes **4**_xxx_). These error codes should indicate that there was no error in the server or in the request from the client, but the request failed for some reason due to the Payer or the Payer FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payer Errors: +- **Generic Payer Error – 40**_xx_ +- **Payer Rejection Error – 41**_xx_ +- **Payer Limit Error – 42**_xx_ +- **Payer Permission Error – 43**_xx_ +- **Payer Blocked Error – 44**_xx_ + +See Table 111 below for all Payer errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **4000** | Generic Payer error | Generic error due to the Payer or Payer FSP, to be used for not disclosing information that may be considered private. | | | X | X | X | X | X | X | X | +| **4001** | Payer FSP insufficient liquidity | The Payer FSP has insufficient liquidity to perform the transfer. | | | | | | X | | | | +| **4100** | Generic Payer rejection | Payer or Payer FSP rejected the request. | | | X | X | X | X | X | X | X | +| **4101** | Payer rejected transaction request | Payer rejected the transaction request from the Payee. | | | X | | | | | | | +| **4102** | Payer FSP unsupported transaction type | The Payer FSP does not support or rejected the requested transaction type | | | X | | | | | | | +| **4103** | Payer unsupported currency | Payer doesn’t have an account which supports the requested currency. | | | X | | | | | | | +| **4200** | Payer limit error | Generic limit error, for example, the Payer is making more payments per day or per month than they are allowed to, or is making a payment that is larger than the allowed maximum per transaction. | | | X | X | | X | | X | X | +| **4300** | Payer permission Error | Generic permission error, the Payer or Payer FSP doesn’t have the access rights to perform the service. | | | X | X | X | X | X | X | X | +| **4400** | Generic Payer blocked error | Generic Payer blocked error, the Payer is blocked or has failed regulatory screenings. | | | X | X | X | X | X | X | X | + +**Table 111 – Payer errors – 4xxx** + + +
    + +#### Payee Errors – 5xxx + +All possible errors occurring in the server when the Payee or the Payee FSP is the cause of an error should use the high-level error code 5 (error codes **5**_xxx_). These error codes should indicate that there was no error in the server or in the request from the client, but the request failed for some reason due to the Payee or the Payee FSP. The server should provide an explanation for why the service could not be performed. + +Low level categories defined under Payee Errors: + +- **Generic Payee Error – 50**_xx_ +- **Payee Rejection Error – 51**_xx_ +- **Payee Limit Error – 52**_xx_ +- **Payee Permission Error – 53**_xx_ +- **Payee Blocked Error – 54**_xx_ + +See Table 112 below for all Payee errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **5000** |Generic Payee error |Generic error due to the Payer or Payer FSP, to be used for not disclosing information that may be considered private. | | | X | X | X | X | X | X | X | +| **5001** | Payee FSP insufficient liquidity | The Payee FSP has insufficient liquidity to perform the transfer. | | | | | | X | | | | +| **5100** | Generic Payee rejection | Payee or Payee FSP rejected the request. | | | X | X | X | X | X | X | X | +| **5101** | Payee rejected quote | Payee does not want to proceed with the financial transaction after receiving a quote. | | | | X | | | | X | | +| **5102** | Payee FSP unsupported transaction type | The Payee FSP either does not support or rejected the requested transaction type. | | | | X | | | | X | | +| **5103** | Payee FSP rejected quote | Payee doesn’t want to proceed with the financial transaction after receiving a quote. | | | | X | | | | X | | +| **5104** | Payee rejected transaction | Payee rejected the financial transaction. | | | | | | X | | | X | +| **5105** | Payee FSP rejected transaction | Payee FSP rejected the financial transaction. | | | | | | X | | | X | +| **5106** | Payee unsupported currency | Payee doesn’t have an account which supports the requested currency. | | | | X | | X | | X | X | +| **5200** | Payee limit error | Generic limit error, for example, the Payee is receiving more payments per day or per month than they are allowed to, or is receiving a payment which is larger than the allowed maximum per transaction. | | | X | X | | X | | X | X | +| **5300** | Payee permission error | Generic permission error; the Payee or Payee FSP does not have the access rights to perform the service. | | | X | X | X | X | X | X | X | +| **5400** | Generic Payee blocked error | Generic Payee Blocked error, the Payee is blocked or has failed regulatory screenings. | | | X | X | X | X | X | X | X | + +**Table 112 – Payee errors – 5xxx** + + +
    + +## References + +1 [https://perldoc.perl.org/perlre.html#Regular-Expressions](https://perldoc.perl.org/perlre.html#Regular-Expressions) - perlre - Perl regular expressions + +2 [https://tools.ietf.org/html/rfc7159#section-7](https://tools.ietf.org/html/rfc7159#section-7) – The JavaScript Object Notation (JSON) Data Interchange Format - Strings + +3 [http://www.unicode.org/](http://www.unicode.org/) - The Unicode Consortium + +4 [https://www.iso.org/iso-8601-date-and-time-format.html](https://www.iso.org/iso-8601-date-and-time-format.html) - Date and time format - ISO 8601 + +5 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) - A Universally Unique IDentifier (UUID) URN Namespace + +6 [https://tools.ietf.org/html/rfc4648#section-5](https://tools.ietf.org/html/rfc4648#section-5) - The Base16, Base32, and Base64 Data Encodings - Base 64 Encoding with URL +and Filename Safe Alphabet + +7 [https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html) - Currency codes - ISO 4217 + + + + +## List of Figures + +- [Figure 1](#error-codes) – Error code structure + +## List of Tables + +- [Table 1](#lookup-participant-information) – Lookup Participant Information data model +- [Table 2](#create-participant-information) – Create Participant Information data model +- [Table 3](#create-bulk-participant-information) – Create Bulk Participant Information data model +- [Table 4](#delete-participant-information) – Delete Participant Information data model +- [Table 5](#return-participant-information) – Return Participant Information data model +- [Table 6](#return-bulk-participant-information) – Return Bulk Participant Information data model +- [Table 7](#return-participant-information-error) – Return Participant Information Error data model +- [Table 8](#return-bulk-participant-information-error) – Return Bulk Participant Information Error data model +- [Table 9](#lookup-party-information) – Lookup Party Information data model +- [Table 10](#return-party-information) – Return Party Information data model +- [Table 11](#return-party-information-error) – Return Party Information Error data model +- [Table 12](#retrieve-transaction-request) – Retrieve Transaction Request data model +- [Table 13](#perform-transaction-request-information) – Perform Transaction Request Information data model +- [Table 14](#return-transaction-request-information) – Return Transaction Request Information data model +- [Table 15](#return-transaction-request-information-error) – Return Transaction Request Information Error data model +- [Table 16](#retrieve-quote-information) – Retrieve Quote Information data model +- [Table 17](#calculate-quote) – Calculate Quote data model +- [Table 18](#return-quote-information) – Return Quote Information data model +- [Table 19](#return-quote-information-error) – Return Quote Information Error data model +- [Table 20](#perform-authorization) – Perform Authorization data model +- [Table 21](#return-authorization-result) – Return Authorization Result data model +- [Table 22](#return-authorization-error) – Return Authorization Error data model +- [Table 23](#retrieve-transfer-information) – Retrieve Transfer Information data model +- [Table 24](#perform-transfer) – Perform Transfer data model +- [Table 25](#return-transfer-information) – Return Transfer Information data model +- [Table 26](#return-transfer-information-error) – Return Transfer Information Error data model +- [Table 27](#retrieve-transaction-information) – Retrieve Transaction Information data model +- [Table 28](#return-transaction-information) – Return Transaction Information data model +- [Table 29](#return-transaction-information-error) – Return Transaction Information Error data model +- [Table 30](#retrieve-bulk-quote-information) – Retrieve Bulk Quote data model +- [Table 31](#calculate-bulk-quote) – Calculate Bulk Quote data model +- [Table 32](#return-bulk-quote-information) – Return Bulk Quote Information data model +- [Table 33](#return-bulk-quote-information-error) – Return Bulk Quote Information Error data model +- [Table 34](#retrieve-bulk-transfer-information) – Retrieve Bulk Transfer Information data model +- [Table 35](#perform-bulk-transfer) – Perform Bulk Transfer data model +- [Table 36](#return-bulk-transfer-information) – Return Bulk Transfer Information data model +- [Table 37](#return-bulk-transfer-information-error) – Return Bulk Transfer Information Error data model +- [Table 38](#results-for-validated-amount-values) – Example results for different values for Amount type +- [Table 39](#amounttype-element) – Element AmountType +- [Table 40](#authenticationtype-element) – Element AuthenticationType +- [Table 41](#authenticationvalue-element) – Element AuthenticationValue +- [Table 42](#authorizationresponse-element) – Element AuthorizationResponse +- [Table 43](#balanceofpayments-element) – Element BalanceOfPayments +- [Table 44](#bulktransferstate-element) – Element BulkTransferState +- [Table 45](#code-element) – Element Code +- [Table 46](#correlationid-element) – Element CorrelationId +- [Table 47](#currency-element) – Element Currency +- [Table 48](#dateofbirth-element) – Element DateOfBirth +- [Table 49](#errorcode-element) – Element ErrorCode +- [Table 50](#errordescription-element) – Element ErrorDescription +- [Table 51](#extensionkey-element) – Element ExtensionKey +- [Table 52](#extensionvalue-element) – Element ExtensionValue +- [Table 53](#firstname-element) – Element FirstName +- [Table 54](#fspid-element) – Element FspId +- [Table 55](#ilpcondition-element) – Element IlpCondition +- [Table 56](#ilpfulfilment-element) – Element IlpFulfilment +- [Table 57](#ilppacket-element) – Element IlpPacket +- [Table 58](#lastname-element) – Element LastName +- [Table 59](#merchantclassificationcode-element) – Element MerchantClassificationCode +- [Table 60](#middlename-element) – Element MiddleName +- [Table 61](#note-element) – Element Note +- [Table 62](#nrofretries-element) – Element NrOfRetries +- [Table 63](#partyidentifier-element) – Element PartyIdentifier +- [Table 64](#partyidtype-element) – Element PartyIdType +- [Table 65](#partyname-element) – Element PartyName +- [Table 66](#partysubidortype-element) – Element PartySubIdOrType +- [Table 67](#refundreason-element) – Element RefundReason +- [Table 68](#transactioninitiator-element) – Element TransactionInitiator +- [Table 69](#transactioninitiatortype-element) – Element TransactionInitiatorType +- [Table 70](#transactionrequeststate-element) – Element TransactionRequestState +- [Table 71](#transactionscenario-element) – Element TransactionScenario +- [Table 72](#transactionstate-element) – Element TransactionState +- [Table 73](#transferstate-element) – Element TransferState +- [Table 74](#transactionsubscenario-element) – Element TransactionSubScenario +- [Table 75](#authenticationinfo) – Complex type AuthenticationInfo +- [Table 76](#errorinformation) – Complex type ErrorInformation +- [Table 77](#extension) – Complex type Extension +- [Table 78](#extensionlist) – Complex type ExtensionList +- [Table 79](#individualquote) – Complex type IndividualQuote +- [Table 80](#individualquoteresult) – Complex type IndividualQuoteResult +- [Table 81](#individualtransfer) – Complex type IndividualTransfer +- [Table 82](#individualtransferresult) – Complex type IndividualTransferResult +- [Table 83](#geocode) – Complex type GeoCode +- [Table 84](#money) – Complex type Money +- [Table 85](#party) – Complex type Party +- [Table 86](#partycomplexname) – Complex type PartyComplexName +- [Table 87](#partyidinfo) – Complex type PartyIdInfo +- [Table 88](#partypersonalinfo) – Complex type PartyPersonalInfo +- [Table 89](#partyresult) – Complex type PartyResult +- [Table 90](#refund) – Complex type Refund +- [Table 91](#transaction) – Complex type Transaction +- [Table 92](#transactiontype) – Complex type TransactionType +- [Table 93](#amounttype-enum) – Enumeration AmountType +- [Table 94](#authenticationtype-enum) – Enumeration AuthenticationType +- [Table 95](#authorizationresponse-enum) – Enumeration AuthorizationResponse +- [Table 96](#bulktransferstate-enum) – Enumeration BulkTransferState +- [Table 97](#partyIdtype-enum) – Enumeration PartyIdType +- [Table 98](#personalidentifiertype-enum) – Enumeration PersonalIdentifierType +- [Table 99](#transactioninitiator-enum) – Enumeration TransactionInitiator +- [Table 100](#transactioninitiatortype-enum) – Enumeration TransactionInitiatorType +- [Table 101](#transactionrequeststate-enum) – Enumeration TransactionRequestState +- [Table 102](#transactionscenario-enum) – Enumeration TransactionScenario +- [Table 103](#transactionstate-enum) – Enumeration TransactionState +- [Table 104](#transferstate-enum) – Enumeration TransferState +- [Table 105](#461-communication-errors-–-1xxx) – Communication errors – 1xxx +- [Table 106](#462-server-errors-–-2xxx) – Server errors – 2xxx +- [Table 107](#client-errors-–-3xxx) – Generic client errors – 30xx +- [Table 108](#client-errors-–-3xxx) – Validation Errors – 31xx +- [Table 109](#client-errors-–-3xxx) – Identifier Errors – 32xx +- [Table 110](#client-errors-–-3xxx) – Expired Errors – 33xx +- [Table 111](#463-payer-errors-–-4xxx) – Payer errors – 4xxx +- [Table 112](#464-payee-errors-–-5xxx) – Payee errors – 5xxx + + +## Table of Listings +- [Listing 1](#regular-expression) – Regular expression for data type UndefinedEnum +- [Listing 2](#regular-expression-2) – Regular expression for data type Name +- [Listing 3](#regular-expression-3) – Regular expression for data type Integer +- [Listing 4](#regular-expression-4) – Regular expression for data type OtpValue +- [Listing 5](#regular-expression-5) – Regular expression for data type BopCode +- [Listing 6](#regular-expression-6) – Regular expression for data type ErrorCode +- [Listing 7](#regular-expression-7) – Regular expression for data type TokenCode +- [Listing 8](#regular-expression-8) - Regular expression for data type MerchantClassificationCode +- [Listing 9](#regular-expression-9) – Regular expression for data type Latitude +- [Listing 10](#regular-expression-10) – Regular expression for data type Longitude +- [Listing 11](#regular-expression-11) – Regular expression for data type Amount +- [Listing 12](#regular-expression-12) – Regular expression for data type DateTime +- [Listing 13](#regular-expression-13) – Regular expression for data type Date +- [Listing 14](#regular-expression-14) – Regular expression for data type UUID +- [Listing 15](#regular-expression-15) – Regular expression for data type BinaryString +- [Listing 16](#regular-expression-16) – Regular expression for data type BinaryString32 diff --git a/docs/technical/api/fspiop/pki-best-practices.md b/docs/technical/api/fspiop/pki-best-practices.md new file mode 100644 index 000000000..8fcd2eac9 --- /dev/null +++ b/docs/technical/api/fspiop/pki-best-practices.md @@ -0,0 +1,710 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Public Key Infrastructure Best Practices + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| +|**2.0**|2026-04-08|Second version published to match FSPIOP v2.0 document set| + +## Introduction + +This document explains _Public Key Infrastructure_ (PKI)1 best practices to apply in an _Open API for FSP Interoperability_ (hereafter cited as “the API”) deployment. See [PKI Background](#pki-background) section for more information about PKI. + +The API should be implemented in an environment that consists of either: + +- _Financial Service Providers_ (FSPs) that communicate with other FSPs (in a bilateral setup) or + +- A _Switch_ that acts as an intermediary platform between FSP platforms. There is also an _Account Lookup System_ (ALS) available to identify in which FSP an account holder is located. + +For more information about the environment, see [Network Topology](#network-topology) section. [Certificate Authority PKI Management Strategy](#certificate-authority-pki-management-strategy) and [Platform PKI Management Strategy](#platform-pki-management-strategy) identify management strategies for the CA and for the platform. + +Communication between platforms is performed using a REST (REpresentational State Transfer)-based HTTP protocol (for more information, see _API Definition_). Because this protocol does not provide a means for ensuring either integrity or confidentiality between platforms, extra security layers must be added to protect sensitive information from alteration or exposure to unauthorized parties. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](#) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + + +## PKI Background + +Public Key Infrastructure (PKI) is a set of standards, procedures, and software for implementing authentication using public key cryptography. PKI is used to request, install, configure, manage and revoke digital certificates. PKI offers authentication using digital certificates; these digital certificates are signed and provided by _Certificate Authorities_ (CA). + +PKI uses public key cryptography and works with X.509 standard certificates. It also provides features such as: + +- User authentication + +- Certificate production and distribution + +- Certificate maintenance, management, and revocation + +PKI consists of a number of components that enable the infrastructure to work; it is not a single process or algorithm. In addition to authentication, PKI also enables the provision of integrity, non-repudiation and encryption. + +To obtain a public key, a company must obtain a digital certificate. It should request this certificate from a CA or a _Registration Authority_ (RA) - an organization that processes requests on behalf of a CA. All participants must trust the CA to manage and maintain certificates. The CA requires the company to supply a number of details (_Common Name_ (CN), _Organization_ (O), _Country_ (C) and so on) and validate their request before it provides a certificate. This certificate is proof that the company is who it says it is in the digital world (like a passport in the real world). + +PKI combines well with a _Diffie-Hellman solution_ (a secure mechanism for exchanging a shared symmetric key between two anonymous peers) in providing secure key exchanges. Because Diffie-Hellman does not provide authentication, PKI is used with additional protocols, such as _Pretty Good Privacy_ (PGP) and _Transport Layer Security_ (TLS). + +### Layered Protection + +The API should be used with protection at both the transport- and application-level. + +#### Transport-Level Protection + +To protect the transport level, _Transport Layer Security_2 (TLS) should be used. TLS is a fundamental technique used for securing point-to-point communication. It has been proven to be stable and secure when using strong algorithms with the most recent versions of TLS, and is widely used around the world. TLS is a secure mechanism for exchanging a shared symmetric key between two anonymous peers, with identity verification (that is, trusted certificates). It provides _confidentiality_ (no one has read the content) and _integrity_ (no one has changed the content). Using TLS efficiently as-is requires certificate management. + +#### Application-Level Protection + +This layer provides end-to-end integrity and confidentiality. The API uses the JSON Web Signature3 (JWS) standard for integrity and _non-repudiation_ (provide proof of the integrity and origin of data), and the JSON Web Encryption (JWE) 4 standard for confidentiality. An extended version of JWE is used to support field level encryption. + +Using these standards requires certificate management; therefore, _Certificate Authorities_ (CA) and related PKI techniques are needed. For more information, see PKI Background. + +## Network Topology + +This section identifies the platforms that constitute the API. + +### Platforms Point-to-Point Layout + +Figure 1 shows an example platform point-to-point layout. + +![Figure1 Platforms Layout](../assets/figure1-platforms-layout.svg) + +**Figure 1 - Platforms layout** + +All communication between platforms must be TLS-secured using _client authentication_, also known as _mutual authentication_. + +### Platform Roles + +#### Certificate Authority (CA) + +The CA performs the following functions: + +- Sign _Certificate Signing Requests_ (CSRs) - CSRs is a secure mechanism for exchanging a shared symmetric key between two anonymous peers. The CA signs different types of certificates (for example, TLS, Content signature, Content encryption). + +- Revoke certificates – Mark one or more certificates as invalid. + +- Support CRLs – Maintain and provide certificate revocation lists (CRLs) to be downloaded by clients so that they can see which certificates have been revoked. + +- Support Online Certificate Status Protocol (OCSP) – Provide real-time certificate revocation checks. + +#### Account Lookup System (ALS) + +- Holds basic information about account holders. + +- Answer questions like “Where should I send my financial transaction request for account holder with **MSISDN 0123456**?” + +#### Financial Services Provider (FSP) + +Has account holders to which or from which money is transferred. + +#### Switch + +- Relays transaction information to other platforms. + +- Can perform financial services, as specified in _API Definition_. + +## Certificate Authority PKI Management Strategy + +This section describes the PKI management strategy for Certificate Authorities. + +### Certificate Authority Importance and Selection Criteria + +The Certificate Authority (CA) role is important because: + +- The CA provides a single legal entity that is trustworthy for all platforms. + +- The point-to-point TLS protocol depends on certificates. + +- The end-to-end protocols JWS and JWE depend on certificates for proof of non-repudiation and confidentiality. + +#### Reasons Not to Use a Public CA + +- A public CA can revoke the intermediate certificate used for signing our certificates, thus effectively shutting down all communication between platforms. + +- A public CA also signs certificates which are not part of the _Open API for FSP Interoperability_ setup. Because you trust the certificate the CA signed for you, you then trust all certificates signed by that CA. + +- There is no service in the _Open API for FSP Interoperability_ setup that is open to the public, so there is no reason to have a public CA already trusted by public clients (such as web browsers). + +#### Private CA Options + +- Build your own CA from scratch + +- Build a CA using existing tools (for example, _openssl_) + +- Use a full-featured CA (for example, the open source product _EJBCA_) + +### Trusted Certificate Chain + +A centralized CA makes certificate management easier for the involved platforms. By trusting the same CA certificate, each platform need only trust one certificate; the CA’s self-signed root certificate. + +Thus, the CA should sign all types of certificates (TLS, signature, and encryption), but only for the participants in the _Open API for FSP Interoperability_ setup. + +No intermediate CA certificates are required, because a segmented layout is not used in the _Open API for FSP Interoperability_ setup. + +### CA Root Certificate + +- The CA must create a self-signed root certificate to be used for signing all supported types of certificates (TLS, signing, and encryption). + +- The minimum key length of the asymmetric RSA key pair is 4096 bits, and the signature algorithm should be sha512WithRSAEncryption. + +- The _X.509 Basic Constraints_ must have the attribute **CA** set to **TRUE**. + +- The time validity of the CA root certificate should be ten years. After eight years, a new self-signed root certificate should be created by the CA; the asymmetric RSA key pair must be recreated, not reused. This certificate becomes the certificate to use for signing the platforms CSRs. However, the old CA root certificate must still be active until it expires. This gives the platforms a window of two years to change the CA root certificate without disturbing their ongoing secured communication. + +### Signing Platforms CSRs + +The CA must provide a mechanism for the platforms to get their CSRs signed. Common signing methods are by email and by a web page. The chosen solution and policy must be known to the platforms. + +The CA signs three types of platform certificates; TLS (for communication), JWS (for signature) and JWE (for encryption). Common requirements for these certificates are: + +- The minimum key length of the asymmetric RSA key pair is 2048 bits, and the signature algorithm should be sha256WithRSAEncryption. + +- The _X.509 Basic Constraints_ must have the attribute **CA** set to **FALSE**. + +- The subject distinguished names must contain at least the following attributes: + + - _Common Name_ (CN) – This must be the hostname of the platform which has created the certificate. A N can never be the same for two different platforms or organizations. + + - _Organization_ (O) – The name of the organization. + + - _Country_ (C) – The country of the organization. + +- The URL for platforms to download CRLs must be present. + +- The URL for platforms to send OCSP requests must be present. + +- The time validity should be two years. + +Depending on the type of certificate to sign, the _X.509 Key Usage_ and X.509 Extended Key Usage of the platform’s certificate will differ; see Table 1 for more information. + +| Certificate Type | X.509 Key Usage | X.509 Extended Key Usage | +| --- | --- | --- | +| **TLS Certificates** | Digital Signature, Key Encipherment | TLS Web Server Authentication, TLS Web Client Authentication | +| **Signature Certificates** | Digital Signature | | +| **Encryption Certificates** | Key Encipherment | | + +**Table 1 – Certificate type and key usage** + +### Revoking Certificates + +- The CA must be able to revoke a platform’s certificates. Revoking a certificate means that it will no longer be trusted by any party. It will be marked as invalid by the CA and its revocation status published to the platforms, either in a revocation list (CRL) to be downloaded by platforms, or through a real-time HTTP query using _Online Certificate Status Protocol_ (OCSP) requested by platforms. + +- The CA should support both CRL downloads and OCSP queries. + +- The CA should update and sign the CRL daily and should provide (daily) a HTTP URL to the platforms that points to the CRL to be downloaded. The URL should be stored in the _CRL Distribution Points_ for each signed certificate. + +- The OCSP URL should be stored in the _Authority Information Access_ for each signed certificate. An OCSP response must be signed. Nonce values in an OCSP request should be supported to prevent reply attacks. + +- The CA has the right to revoke certificates, but no obligation to inform the platforms about such revocations. The platforms do not have the right to revoke certificates, but they do have an obligation to check regularly for a certificate’s revocation status. + +### Certificate Enrollment and Renewal + +The CA does not support enrollment or renewal of certificates for which an asymmetric key pair is reused. For increased security, the asymmetric key pairs must be recreated every time a certificate is enrolled or renewed through a new CSR. + +## Platform PKI Management Strategy + +This section describes the PKI management strategy for platforms. + +### Keys, Certificates, and Stores + +A certificate provides the identity of its owner through a trusted CA that has signed the certificate. This can be validated through its signed certificate chain. It also provides the technical means to ensure integrity (signature) and confidentiality (encryption) of data using its asymmetric key pair (known as a _public key and private key_). The public key is within the signed certificate, but its corresponding private key must be kept private and protected. A common solution for handling certificates and private keys is to put them into a protected storage area known as a store. A store can be a file, directory, or something else that provides access and confidentiality. + +A single private key and its associated certificate can be used for all cryptographic purposes, but to enhance security, the following set of keys and certificates is required for each platform: + +- One private key and certificate for TLS communication + +- One private key and certificate for end-to-end integrity using JWS + +- One private key and certificate for end-to-end confidentiality using JWE + +Different keys and types of certificates can all be in the same store, but a more common setup is the following: + +- For TLS communication: + + - One protected key store to hold the private key, its associated certificate, and certificate chain. These items are used for server- and client authentication in TLS. + + - One protected certificate store to hold all trusted TLS certificates. These certificates will be trusted by your platform during a TLS handshake, meaning that they will allow secure communication with the owners of the certificates. Since all participants trust the same CA, it is sufficient to keep only the CA’s root certificate here. + +- For signature and encryption: + + - One protected key store to hold your private keys, their associated certificates, and certificate chains used for signatures and encryption. + + - One private key and certificate chain used for signing using JWS, and one private key and certificate chain used for encryption using JWE. + + - One protected certificate store to hold all trusted signature and encryption certificates from other platforms. Here you must store the certificates (signature and encryption certificates) for each platform that you want to trust for end-to-end integrity and confidentiality. + +### Creating a CSR and Obtaining CA Signature + +To be able to communicate with other platforms, you must create a key store (if one does not already exist), an asymmetric key pair, and an associated certificate that identifies your platform. This unsigned certificate must be signed by the CA before it can be trusted by other platforms. The procedure of getting a certificate signed by a CA begins with a CSR (_Certificate Signing Request_). + +When you create your keys, certificates, and CSRs, the following requirements apply: + +- The minimum key length of the asymmetric RSA key pair is 2048 bits, and the signature algorithm is sha256WithRSAEncryption. + +- The following attributes in the subject distinguished names are mandatory: + + - Common Name (CN) – This must be the hostname of the platform who created the certificate. A CN can never be the same for two different platforms or organizations. + + - Organization (O) – The name of the organization. + + - Country (C) – The country of the organization. + +**For examples of how to create a store, certificate, and CSR, see Appendix C – Common PKI Tasks** + +How to create a store, certificate, and CSR. + +Create your CSR and send it to your CA according to their instructions. + +**Note:** The same procedure must be performed for all your different keys and certificates (TLS, signature, and encryption). + +### Importing a Signed CSR + +After signing your CSR, you will have two certificates in your response from the CA. The first certificate is your own signed certificate. The second is the CA’s own root certificate, which was used for signing your certificate. That certificate must now be trusted by you. + +First you must import your signed certificate into your key store. It must replace your unsigned certificate. For examples, see How to import a signed certificate into your key store. + +Then you must import the CA’s root certificate into the same key store to complete the chain between your certificate and the CA. For examples, see How to import the CA certificate into your key store. + +#### TLS Certificates + +For TLS certificates, you must also import the CA’s root certificate into your TLS trust store to automatically trust the other platforms when establishing new communication channels with them. For examples, see How to import the CA certificate into TLS trust store. + +The above procedure should be performed for each of your signed CSRs. Remember to send your signed certificate and the CA’s root certificate to all other platforms with which you need to communicate. + +The CA will create a validity period of two years for your signed certificate. After 18 months, you should create a new CSR to be signed by the same CA. Your newly signed certificate and the CA’s root certificate should once again be imported into your stores and sent to the other platforms. This will give you and your peers a window of six months to make sure that your new signed certificate works. After two years, the old expired certificate can be deleted. + +### Trusting Certificates from Other Platforms + +Just as your peers must have your certificates to be able to trust you, they must send their certificates to you for you to trust them. + +Make sure that you always receive at least two certificates from a trusted peer: + +- The signed certificate of the peer to trust. + +- The root certificate of the CA that signed the peer’s certificate. + +**Note:** A peer’s CA certificate can differ from yours. This can happen if the CA has created a new CA root certificate when the old one is about to expire. + +You should always view a peer’s certificates (check CN, validity period, and so on) and validate the certificate chain (that is, that each certificate is correctly signed by the given CA) before you import them into your trust store. + +For examples, see How to view a certificate. + +Next, import the peer’s certificate and its CA root certificate into your trust store. For examples, see How to import a trusted certificate. + +### Checking Certificate Revocation Status + +Certificates can be revoked by the CA. A revoked certificate is considered not trusted and should be removed from the trust store. A certificate can also be _on hold_, which means that it is in pending state due to investigation and should not be removed. + +All platforms should perform revocation checks on a regular basis. There are two common ways to find out which certificates have been revoked; either through viewing a revocation list (CRL) to be downloaded by platforms, or through a real-time HTTP query (OCSP) requested by platforms. + +#### Certificate Revocation List + +This is a file maintained by a CA. It contains a list of certificate serial numbers that have been revoked by the CA. This file can be downloaded by any platform at any time. The URL to the CRL file to be downloaded is included in the certificate itself and can be found in _CRL Distribution Points_. A CRL is signed by the CA and should be validated. + +A CRL should be downloaded once per day and cached by the platform. + +For examples, see How to verify a certificate through a CRL. + +#### Online Certificate Status Protocol + +The status of a certificate can be retrieved by sending an OCSP request to an _OCSP Responder_ (which can be the CA). The request contains the serial number of the certificate to be checked. The responder sends back a signed response including the status of the certificate. + +The request should contain a nonce value, which the responder will put in the response, for the platform to validate on receipt. This is to prevent reply attacks. + +An OCSP request/response is considered very fast and can be executed for each received client certificate operation, but depending on the load towards the responder, it might have to be cached by the platform as well. + +The OCSP URL is included in the certificate itself and can be found in _Authority Information Access_. + +For examples, see How to verify a certificate through an OCSP request. + +### Renewing Certificates + +Do not renew certificates for which an asymmetric key pair is reused. For increased security, the asymmetric key pairs must be recreated every time through a new CSR. + +## Transport Layer Protection + +This section describes transport layer protection. + +### TLS + +TLS provides point-to-point integrity and confidentiality, and is used for all communication between peers. + +The setup requires both _server authentication_ - meaning that the server presents itself through its own TLS certificate - and _client authentication_ (also known as mutual authentication) in which the client presents itself through its own TLS certificate. + +#### TLS Protocol Versions + +The TLS protocol version used must be 1.2 or higher. + +#### TLS Cipher Suites + +The following cipher suites should be used: + +- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_RSA_WITH_AES_128_GCM_SHA256 + +## Application Layer Protection + +This section describes the application layer protection. + +### JSON Web Signature + +The _JSON Web Signature_ (JWS) standard is used for providing end-to-end integrity and non-repudiation; that is, to guarantee that the sender is who it claims to be, and that the message was not tampered with. + +The use of JWS is mandatory and certificates must be used. For more information, see _API Signature_. + +JWS's core purpose includes non-repudiation i.e., proving who signed a message. A bare symmetric key (HMAC) can prove a message wasn't tampered with, but can't prove which party signed it since both sides share the same key. Only an asymmetric certificate tied to a CA-verified identity achieves true non-repudiation. The entire PKI model - where each platform trusts a shared CA only works if JWS signatures are certificate-backed. Without it, a platform could generate any key pair and claim any identity. Certificates anchor identity to the CA's vetting process. + +### JSON Web Encryption + +The _JSON Web Encryption_ (JWE) standard is used for providing end-to-end confidentiality; that is, to protect data from being read by unauthorized parties. + +The use of JWE is optional and is applied to specific fields. This is to fulfill regulatory requirements that might exist for certain type of data in certain countries. + +For more information about how to apply JWE to fields in messages, see the extended JWE standard specification _API Encryption_. + + +## List of Appendices + +### Appendix A - Key Lengths and Algorithms + +Table 2 contains the required key length and algorithm for each entity. + +| Entity | Algorithm | Key length/hash size | +| --- | --- | --- | +| CA asymmetric keys | RSA | 4096 bits | +| CA signing algorithm | RSA with SHA2 | >= 256 bits | +| TLS asymmetric keys | RSA | 2048 bits | +| TLS signing algorithm | RSA with SHA2 | >= 256 bits | +| Signature asymmetric keys | RSA | 2048 bits | +| Signature algorithm | RSA with SHA2 | >= 256 bits | +| Encryption asymmetric keys | RSA | 2048 bits | +| HMAC | SHA2 - AES | >= 256 bits| +| Symmetric keys | AES | 256 bits | +| Hashing | SHA2 | >= 256 bits | + +**Table 2 – Key lengths and algorithms** + +### Appendix B - Terminology + +| | | +| --- | --- | +| PKI | Public Key Infrastructure +| API | Application Program Interface +| TLS | Transport Layer Security +| JWS | JSON Web Signature +| JWE | JSON Web Encryption +| FSP | Financial Service Provider +| AL | Account Lookup +| CA | Certificate Authority +| CSR | Certificate Signing Request +| CRL | Certificate Revocation List +| OCSP | Online Certificate Status Protocol +| PEM | Privacy Enhanced Mail +| RSA | Rivest, Shamir, & Adleman +| HMA | Hashed Message Authentication Code +| AES | Advanced Encryption Standard +| SHA | Secure Hash Algorithm + +### Appendix C - Common PKI Tasks + +#### Appendix C.1 - How to create a store, certificate, and CSR + +**Using the Java keytool** + +Use the following command to create an asymmetric RSA key pair and associated certificate information to be signed by the +CA. It will automatically create a JKS key store if the given one does not exist: + +``` +keytool -genkey -dname "CN=" -alias -keyalg RSA - +keystore -keysize 2048 +``` + +**Example** + +``` +keytool -genkey -dname "CN=bank-fsp" -alias tlscert -keyalg RSA -keystore +tlskeystore.jks -keysize 2048 +``` + +**Notes:** + +1. The certificate attribute CN specifies the hostname of the host who identifies itself using this certificate during a TLS session. +2. When asked for password, use the same password for the key as the key store. + +Use the following command to create the actual CSR to be signed by the CA: + +``` +keytool -certreq -alias -keystore –file .csr +``` + +**Example** + +``` +keytool -certreq -alias tlscert -keystore tlskeystore.jks -file tlscert.csr +``` + +**Using openssl** + +Use the following command to create an asymmetric RSA key pair, and CSR to be signed by the CA: + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=" -out +.csr -keyout .key +``` + +**Example** + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=bank-fsp" -out tlscert.csr - +keyout tlscert.key +``` + +**Note:** The certificate attribute CN specifies the hostname of the host who identifies itself using this certificate during a TLS session. + +Important to note is that the created private key is stored unencrypted. Use the following command to encrypt it: + +``` +openssl rsa -aes256 -in -out +``` + +**Example** + +``` +openssl rsa -aes256 -in tlscert.key -out tlscert_encrypted.key +``` + +#### Appendix C.2 - How to import a signed certificate into your key store + +**Using the Java keytool** + +Import your signed certificate into your key store. This certificate should replace the old unsigned one, so make sure that you use the correct alias. + +``` +keytool -importcert -alias -file -keystore +``` + +**Example** + +``` +keytool -importcert -alias tlscert -file bank-fsp.pem -keystore tlskeystore.jks +``` + +**Using openssl** + +Remove your old CSR file and replace it with the new signed certificate. + +#### Appendix C.3 - How to import the CA certificate into your key store + +**Using Java keytool** + +Import the CA certificate into your key store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlskeystore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Using openssl** + +Put the CA certificate with your other certificate files + +#### Appendix C.4 - How to import the CA certificate into TLS trust store + +**Using Java keytool** + +Import the CA certificate into your trust store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlstruststore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` +**Using openssl** + +Put the CA certificate with your other certificate files. + +#### Appendix C.5 - How to view a certificate + +**Using Java keytool** + +Use this command to list all certificates stored in a key store in readable format: + +``` +keytool -list -keystore -v +``` + +**Example:** + +``` +keytool -list -keystore tlskeystore.jks -v +``` + +**Using openssl** + +Use this command to show the content of a PEM encoded certificate in readable format: + +``` +openssl x509 -in -text -nout +``` + +**Example:** + +``` +openssl x509 -in rootca.pem -text -nout +``` + +#### Appendix C.6 - How to import a trusted certificate + +**Using Java keytool** + +Import the certificate into your trust store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias trustedcert -file cert.pem -keystore truststore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Using openssl** + +Put the trusted certificate with your other certificate files. + +#### Appendix C.7 - How to verify a certificate through a CRL + +**Using Java** + +You can use a specific security library for this (for example, Bouncy Castle), or use the in-built support for it, see: +[https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006](#https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006) + +**Using openssl** + +A good example is found at the following link: +[https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html](#https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html) + +#### Appendix C.8 - How to verify a certificate through an OCSP request + +**Using Java** + +Some Java examples is found in the following link: +[https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate](#https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate) + +**Using openssl** + +A good example is found at the following link: +[https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html](#https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html) + + +1 This term, and other italicized terms, are defined in Glossary for Open API for FSP Interoperability Specification. + +2 [https://tools.ietf.org/html/rfc5246](#https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + +3 [https://tools.ietf.org/html/rfc7515](#https://tools.ietf.org/html/rfc7515) - JSON Web Signature (JWS) + +4 [https://tools.ietf.org/html/rfc7516](#https://tools.ietf.org/html/rfc7516) - JSON Web Encryption (JWE) + +
    + +## Table of Figures + +- [Figure 1 - Platforms layout](#platforms-point-to-point-layout) + +
    + +## Table of Tables + +- [Table 1 – Certificate type and key usage](#Table-1–Certificate-type-and-key-usage) + +- [Table 2 – Key lengths and algorithms](#Table-2-Key-lengths-and-algorithms) \ No newline at end of file diff --git a/mojaloop-technical-overview/central-settlements/.gitkeep b/docs/technical/api/fspiop/sandbox.md similarity index 100% rename from mojaloop-technical-overview/central-settlements/.gitkeep rename to docs/technical/api/fspiop/sandbox.md diff --git a/docs/technical/api/fspiop/scheme-rules.md b/docs/technical/api/fspiop/scheme-rules.md new file mode 100644 index 000000000..7c1639b48 --- /dev/null +++ b/docs/technical/api/fspiop/scheme-rules.md @@ -0,0 +1,219 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# Scheme Rules + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +## Introduction + +This document defines scheme rules for Open API for FSP Interoperability (hereafter cited as the API) in three categories. + +1. Business Scheme Rules: + + a. These business rules should be governed by FSPs and an optional regulatory authority implementing the API within a scheme. + + b. The regulatory authority or implementing authority should identify valid values for these business scheme rules in their API policy document. + +2. API implementation Scheme Rules: + + a. These API parameters should be agreed on by FSPs and the optional Switch. These parameters should be part of the implementation policy of a scheme. + + b. All participants should configure these API parameters as indicated by the API-level scheme rules for the implementation with which they are working. + +3. Security and Non-Functional Scheme Rules. + + a. Security and non-functional scheme rules should be determined and identified in the implementation policy of a scheme. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](#) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Business Scheme Rules + +This section describes the business scheme rules. The data model for the parameters in this section can be found in _API Definition._ + +#### Authentication Type + +The authentication type scheme rule controls the authentication types OTP and QR code. It lists the various authentication types available for _Payer_ authentication. A scheme can choose to support all the authentication types mentioned in “AuthenticationTypes” in _API Definition_ or a subset thereof. + +#### Consumer KYC Identification Required + +A scheme can mandate verification of consumer KYC (Know Your Customer) identification by Agent or Merchant at the time of transaction (for example, cash-out, cash-in, merchant payment). The API cannot control this scheme rule; therefore, it should be documented in scheme policy so that it is followed by all participants in a scheme. The scheme can also decide on the valid KYC proof of identification that should be accepted by all FSPs. + +#### Currency + +A scheme may recommend allowing transactions in more than one currency. This scheme may define the list of valid currencies in which transactions can be performed by participants; however, this is not required. A Switch may work as transaction router and doesn’t validate the transaction currency. If a scheme does not define the list of valid currencies, then the Switch works as transaction router and the participating FSP can accept or reject the transaction based on its supported currencies. Foreign exchange is not supported; that is, the transaction currency for the Payer and the _Payee_ should be the same. + +#### FSP ID Format + +A scheme may determine the format of the FSP ID. The FSP ID should be of string type. Each participant will be issued a unique FSP ID by the scheme. Each FSP should prepend the FSP ID to a merchant code (a unique identifier for a merchant) so that the merchant code is unique across all the participants (that is, across the scheme). The scheme can also determine an alternate strategy to ensure that FSP IDs and merchant codes are unique across participating FSPs. + +#### Interoperability Transaction Type + +The API supports the use cases documented in _Use Cases_. A scheme may recommend implementation of all the supported usecases or a subset thereof. A scheme may also recommend to rollout the use cases in phases. Two or more FSPs in the scheme might decide to implement additional use-cases supported by the API. A Switch may work as a transaction router and does not validate transaction type; the FSP can accept or reject the transaction based on its supported transaction types. If a participant FSP initiates a supported API transaction type due to incorrect configuration on the Payer end, then the transaction must be rejected by the peer FSP if the peer FSP doesn’t support the specific transaction type. + +#### Geo-Location Required + +The API supports geolocation of the Payer and the Payee; however, this is optional. A scheme can mandate the geolocation of transactions. In this case, all participants must send the geolocation of their respective party. + +#### Extension Parameters + +The API supports one or more extension parameters. A scheme can recommend that the list of extension parameters be supported. All participants must agree with the scheme rule and support the scheme-mandatory extension parameters. + +#### Merchant Code Format + +The API supports merchant payment transaction. Typically, a consumer either enters or scans a merchant code to initiate merchant payment. In case of merchant payment, the merchant code should be unique across all the schemes. Currently, the merchant code is not unique in the way that mobile numbers or email addresses are unique. Therefore, it is recommended to prepend a prefix or suffix (FSP ID) to the merchant code so that the merchant code is unique across the FSPs. + +#### Max Size Bulk Payments + +The API supports the Bulk Payment use-case. The scheme can define the maximum number of transactions in a bulk payment. + +#### OTP Length + +The API supports One-time Password (OTP) as authentication type. A scheme can define the minimum and maximum length of OTP to be used by all FSPs. + +#### OTP Expiration Time + +An OTP’s expiration time is configured by each FSP. A scheme can recommend it to be uniform for all schemes so that users from different FSPs have a uniform user experience. + +#### Party ID Types + +The API supports account lookup system. An account lookup can be performed based on valid party ID types of a party. A scheme can choose which party ID types to support from **PartyIDType** in API Definition. + +#### Personal Identifier Types + +A scheme can choose the valid or supported personal identifier types mentioned in **PersonalIdentifierType** in API Definition. + +#### QR Code Format + +A scheme should standardize the QR code format in the following two scenarios as indicated. + +##### Payer-Initiated transaction + +Payer scans the QR code of Payee (Merchant) to initiate a Payer-Initiated Transaction. In this case, the QR code should be standardized to include the Payee information, transaction amount, transaction type and transaction note, if any. The scheme should standardize the format of QR code for Payee. + +##### Payee-Initiated Transaction + +Payee scans the QR code of Payer to initiate Payee-Initiated transaction. For example: Merchant scans the QR code of Payer to initiate a Merchant Payment. In this case, the QR code should be standardized to locate the Payer without using the account lookup system. The scheme should standardize the format of QR code; that is, FSP ID, Party ID Type and Payer ID, or only Party ID Type and Party ID. + +## API Implementation Scheme Rules + +This section describes API implementation scheme rules. + +#### API Version + +API version information must be included in all API calls as defined in _API Definition_. A scheme should recommend that all FSPs implement the same version of the API. + +#### HTTP or HTTPS + +The API supports both HTTP and HTTPS. A scheme should recommend that the communication is secured using TLS (see [Communication Security](#communication-security) section). + +#### HTTP Timeout + +FSPs and Switch should configure HTTP timeout. If FSP doesn’t get HTTP response (either **HTTP 202** or **HTTP 200**) for the **POST** or **PUT** request then FSP should timeout. Refer to the diagram in Figure 1 for the **HTTP 202** and **HTTP 200** timeouts shown in dashed lines. + +###### Figure-1 + +![Figure 1 HTTP Timeout](../assets/scheme-rules-figure-1-http-timeout.png) + +**Figure 1 – HTTP Timeout** + +#### Callback Timeouts + +The FSPs and the Switch should configure callback timeouts. The callback timeouts of the initiating FSP should be greater than the callback timeout of the Switch. A scheme should determine callback timeout for the initiating FSP and the Switch. Refer to the diagram in Figure 2 for the callback timeouts highlighted in red. + +###### Figure-2 + +![Figure 1 Callback Timeout](../assets/scheme-rules-figure-2-callback-timeout.png) + + +**Figure 2 – Callback Timeout** + +## Security and Non-Functional Requirements Scheme Rules + +This section describes the scheme rules for security, environment and other network requirements. + +#### Clock Synchronization + +It is important to synchronize clocks between FSPs and Switches. It is recommended that an NTP server or servers be used for clock synchronization. + +#### Data Field Encryption + +Data fields that need to be encrypted will be determined by national and local laws, and any standard that must be complied with. Encryption should follow _Encryption_. + +#### Digital Signing of Message + +A scheme can decide that all messages must be signed as described in _Signature_. Response messages need not to be signed. + +#### Digital Certificates + +To use the signing and encryption features detailed in _Signature_ and _Encryption_ in a scheme, FSPs and Switches must obtain digital certificates as specified by the scheme-designated _CA_ (Certificate Authority). + +#### Cryptographic Requirement + +All parties must support the encoding and encryption ciphers as specified in _Encryption_, if encryption features are to be used in the scheme. + +#### Communication Security + +A scheme should require that all HTTP communication between parties is secured using TLS[1](https://tools.ietf.org/html/rfc5246) version 1.2 or later. + +1 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + + +### Table of Figures + +[Figure 1 – HTTP Timeout](#figure-1) + +[Figure 2 – Callback](#figure-2) \ No newline at end of file diff --git a/docs/technical/api/fspiop/use-cases.md b/docs/technical/api/fspiop/use-cases.md new file mode 100644 index 000000000..33058d029 --- /dev/null +++ b/docs/technical/api/fspiop/use-cases.md @@ -0,0 +1,1102 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Use Cases + + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +The purpose of this document is to define a set of use cases that can be implemented using the Open API for FSP interoperability (hereafter cited as the API). The use cases referenced within this document provide an overview of transaction processing flows and business rules of each transaction step as well as relevant error conditions. + +The primary purpose of the API is to support the movement of financial transactions between one _Financial Services Provider_ (FSP) and another. + +It should be noted that the API is only responsible for message exchange between FSPs and a Switch when a cross-FSP transaction is initiated by an _End User_ in one of the FSPs. This can occur in either of two scenarios: + +- A bilateral scenario in which FSPs communicate with each other + +- A Switch based scenario in which all communication goes through a Switch + +Reconciliation, clearing and settlement after real time transactions is out of scope for the API. Additionally, account lookup is supported by the API, but it relies on the implementation in a local market in which a third party or Switch would provide such services. Therefore, the need for effective on-boarding processes and appropriate scheme rules must be considered when implementing use cases. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### General Documents + +- _Glossary_ + +#### Logical Documents + +- _Logical Data Model_ + +- _Generic Transaction Patterns_ + +- _Use Cases_ + +#### Asynchronous REST Binding Documents + +- _API Definition_ + +- _JSON Binding Rules_ + +- _Scheme Rules_ + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- _PKI Best Practices_ + +- _Signature_ + +- _Encryption_ + +
    + +## Use Case Summaries + +The following generic transaction patterns are introduced in [Generic Transaction Patterns]() to reduce duplication of each use case description. These patterns summarize the common transaction process flows and shared function of the relevant use cases. + +- **Payer-Initiated Transaction** + - In a _Payer-Initiated Transaction_, it is the _Payer_ (that is, the payer of electronic funds) who initiates the transaction. + + The pattern should be used whenever a Payer would like to transfer funds to another party whose account is not located in the same FSP. + +- **Payee-Initiated Transaction** + + - In a _Payee-Initiated Transaction_, it is the _Payee_ (that is, the recipient of electronic funds) who initiates the transaction. + + This pattern should be used whenever a Payee would like to receive funds from another party whose account is not located in the same FSP. + +- **Payee-Initiated Transaction using OTP** + + - A _Payee-Initiated Transaction using One-Time Password (OTP)_ is like a _Payee-Initiated Transaction_, but the transaction information (including fees and taxes) and approval for the Payer is shown or entered on a Payee device instead. + + - This pattern should be used when a Payee would like to receive funds from another party whose account is not located in the same FSP, and both the transaction information (including fees and taxes) and approval is shown or entered on a Payee device instead. + +- **Bulk Transactions** + + - In a _Bulk Transaction_, it is the Payer (that is, the sender of funds) who initiates multiple transactions to multiple Payees, potentially located in different FSPs. + + - The pattern should be used whenever a Payer would like to transfer funds to multiple Payees in the same transaction. The Payees can potentially be in different FSPs. + +It is recommended to read all Generic Transaction Patterns before reading the use cases. For more information, see [Generic Transaction Patterns](). + +Each use case describes variations on and special considerations for the generic transaction pattern to which it refers. The use cases are introduced in [Table 1](#table-1) below: + +##### Table 1 + +| Use Case Name | Description | +| --- | --- | +| P2P |This use case describes the business process and business rules in which an individual End User initiates a transaction to send money to another individual End User who doesn’t belong to the same FSP as the Payer.

    This is usually a remote transaction in which Payer and Payee are not in the same location. | +| Agent-Initiated Cash-In | This use case describes the business process and business rules in which a customer requests an agent of a different FSP to cash-in (deposit funds) to their account.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Agent-Initiated Cash-Out | This use case describes the business process and business rules in which a customer requests that an agent of a different FSP to cash-out (withdraw funds) from their account.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Agent-Initiated Cash-Out
    Authorized on POS
    | This use case describes the business process and business rules in which a customer requests an agent of a different FSP to cash-out (withdraw funds) from their account. In this use case, the agent initiates the transaction through a point-of-sale (_POS_) and the customer inputs OTP on POS to authorize the transaction. Alternatively, the agent can use POS to scan a QR code generated by a customer’s mobile app to initiate the transaction. | +| Customer-Initiated Cash-Out | This use case describes the business process and business rules in which a registered customer initiates a transaction to cash-out (withdraw funds) using an agent who doesn’t belong to the customer’s FSP.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Customer-Initiated Merchant
    Payment
    | This use case describes the business process and business rules in which an individual End User initiates a purchase transaction to pay a merchant who does not belong to the same FSP as the customer.

    This is usually a face to face transaction when a customer buys goods or services at a merchant store.

    A variant of this use case is online payment, in which the online shopping system generates a QR code and displays it on a web page, and the consumer then scans the QR code by handset and completes the payment transaction. | +| Merchant-Initiated Merchant
    Payment
    | This use case describes the business process and business rules in which a merchant initiates a request for payment to the customer; the customer reviews the transaction amount in the request and confirms the request by providing authentication on their own handset. | +| Merchant-Initiated Merchant
    Payment Authorized on POS
    | This use case describes the business process and business rules in which merchant initiates a request for payment from the customer; the customer reviews the payment request on a merchant device and authorizes the payment by OTP or QR code on the merchant device. The customer authentication information is sent from _Payee FSP_ to _Payer FSP_ for authentication by Payer FSP. | +| ATM-Initiated Cash-Out | This use case describes the business process and business rules in which an ATM initiates a cash-out request from a customer account. Customer pregenerates an OTP for cash-out and uses this OTP on the ATM device to initiate ATM cash-out. The Payer FSP validates the OTP received in the ATM-Initiated Cash-Out request for authentication purposes. | +| Bulk Payments | _Bulk Payments_ is used when an organization or business is paying out funds – for example, aid or salary to multiple Payees who have accounts located in the different FSPs. The organization or business can group transactions together to make it easier for uploading and validating individual transactions in bulk before the bulk transaction is executed. It is also possible for the organization to follow up the result of the individual transactions in the bulk transaction after the bulk transaction is executed. | +| Refund | This use case describes the business flow how to refund a completed interoperability transaction. | + +**Table 1 – Use Case Summary** + +
    + +## Use Cases + +This section demonstrates ways in which the API can be used through the use cases identified in [Table 1](#table-1) – _Use Case Summary_. + +For each use case, the following is presented: +- Use Case Description +- Reference to Generic Pattern +- Actors and Roles +- Addition to Generic Transaction Pattern +- Relevant Error Conditions + +### P2P + +#### Use Case Description + +This section describes the business process and business rules for a use case in which an individual End User initiates a transaction to send money to another individual End User who doesn’t belong to the same FSP as the Payer. + +This is usually a remote transaction in which Payer and Payee are not in the same location. + +There are four steps necessary to complete a _P2P_ Transfer transaction from one FSP user to another FSP user. + +##### Step 1 + +Payer initiates a transaction to their FSP, and Payer FSP then locates Payee FSP through an API call to the Account Lookup System or by the agreed-upon _scheme_ rules. + +##### Step 2 + +Payer FSP calculates the transaction fee applied to Payer. Payer FSP sends a quote request through an API call to Payee FSP. + +##### Step 3 + +Payer FSP presents the total transaction fee and Payee name (optional) to the Payer to confirm the transaction. + +##### Step 4 + +Payer accepts the transaction and Payer FSP performs the transaction through an API call to the Switch or to Payee FSP. The transaction completes and notifications are sent to both Payer and Payee; or the Payer rejects the transaction and the transaction ends. + +
    + +### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for P2P are described in [Table 2](#table-2) below: + +##### Table 2 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | An individual who is a registered customer of an FSP who initiates a transaction to send money to another individual. | +| Customer | Payee | The person who will receive money from Payer.

    Payee could be a registered customer of Payee FSP or, if the scheme rules allow it, an unregistered customer who will be registered during the transaction process, which is determined by the design of Payee FSP. + +**Table 2 – P2P Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 2 + +The Payee FSP ID could be determined by the scheme rule without any dependence on the API. Otherwise, **Lookup Party Information** request is an option for determining in which FSP a Payee is located. + +Payer FSP will use the request **Lookup Party Information** to retrieve details of Payee from Payee FSP directly if there is no Switch between Payer FSP and Payee FSP. + +##### Steps 9 – Step 15 + +In the current version of the API, the **Calculate Quote** request to Payee FSP is mandatory even if a wholesale fee is agreed upon in the scheme. Payee FSP needs to receive transaction details from the **Calculate Quote** request to generate the condition for this transaction. + +Payer FSP can use information from response **Return Quote Information** from Payee FSP to calculate the transaction fee it will apply on Payer. The business rules for how Payer FSP calculates the transaction fee could be defined by the scheme rules; this is out of scope for the API. + +In P2P Transfer case, it is the common practice that Payer pays the entire transaction fee, and Payee is free of charge in the transaction. + +##### Step 16 + +There are several ways to push a confirmation message to Payer to authorize the transaction. For example, USSD Push Message, or SMSC notification; then Payer opens the USSD menu to query and confirm the pending transaction + +The interaction between Payer and Payer FSP is designed by each FSP, and is out-of-scope for the API. + +##### Step 19 + +The Quote ID applied in the previous step is verified in the transaction processing step. If the quote is expired, Payee FSP will reject the transaction. + +##### Step 20 + +A notification is sent to the Payee once the transaction is performed by Payee FSP. + +##### Step 28 + +Payer FSP sends notification to Payer to indicate the transaction result. + +#### Relevant Error Conditions +[Table 3](#table-3) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 3 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +|4 | Payee is unreachable | Account Lookup System fails to locate Payee| Cancel the transaction | +|6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +|11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +|17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +|19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breach
  • Payer or Payee is blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +|22 | Funds reservation timed out | Funds reservation at Payer FSP is timed out and the transaction fails at Payer FSP but succeeds at Payee FSP. | Reconcile according to the scheme rules + +**Table 3 – P2P Relevant Error Conditions** + +
    + +### Agent-Initiated Cash-In + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests an agent of a different FSP to cash-in (deposit funds) to their account. This is a two-step transaction: Agent initiates a cash-in transaction from their handset or POS and then receives transaction information including possible fees. Agent can either approve or reject the transaction. Once transaction is completed, the customer gives cash to the agent. + +Agent-Initiated Cash-In is typically a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-In are described in [Table 4](#table-4) below: + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +|Agent | Payer | Payer is an agent (individual or organization) who will receive cash from the customer and transfer money to the customer’s account.

    Agent is a registered party with Payer FSP. | +| Customer | Payee | Customer is an individual who would like to deposit cash into their account.

    Customer is a registered individual in Payee FSP. | + +**Table 4 – Agent-Initiated Cash-In: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +Customer requests that an agent cash-in to their account. + +If a smart phone is used, the agent can scan a static QR code from the customer to capture the customer’s information and initiate the transaction. + +Optionally the agent verifies the identity of the customer. + +##### Step 12 + +This is an optional step. The customer checks cash-in transaction information and related fees on their own handset and then makes the decision to accept or reject the transaction. + +##### Step 16 + +The agent checks fees and taxes and either accepts or rejects. + +##### Step 20 + +A notification is sent to the customer after the transaction is performed by Payee FSP. + +##### Step 28 + +Payer FSP sends notification to the agent to indicate the transaction result. + +#### Relevant Error Conditions + +[Table 5](#table-5) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 5 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +|4 | Payee cannot be found | Account Lookup System fails to locate Payee | Cancel the transaction | +|6 |Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +|9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +|15 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction +|17 | Timeout | **Perform Transfer** request timed out | Query transfer status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +|19 |Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Low balance of Payee
  • Limit breached
  • Quote is expired
  • Payer or Payee blacklisted
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +|22 |Funds reservation timeout | Funds reservation at Payer FSP timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules + +**Table 5 – Agent-Initiated Cash-In: Relevant Error Conditions** + +
    + +### Agent-Initiated Cash-Out + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests an agent of a different FSP to cash-out (withdraw funds) from their account. This is a 2-step transaction, the agent initiates cash-out transaction request and the customer authorizes the transaction on their handset. Once transaction is completed, the agent gives cash to the customer. + +Agent-Initiated Cash-Out is a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-Out are described in [Table 6](#table-6). + +##### Table 6 + +| Role | Map to Generic
    Transaction Pattern
    | Description | +| --- | --- | --- | +|Customer | Payer | Payer is a customer (individual or organization) who wants to withdraw cash using an agent.

    Customer is a registered party in Payer FSP. | +|Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    Agent is a registered party in Payee FSP. | + +**Table 6 – Agent-Initiated Cash-Out: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +The customer requests that an agent cash-out (withdraw funds) from their account. + +If a smart phone is used, the agent can scan a static QR code containing the customer’s information to capture that information and initiate the transaction. + +Optionally, the agent may verify the identity of the customer to satisfy regulatory requirements. + +##### Step 17 + +The Payer FSP shows fees and taxes to the customer. The customer indicates whether they want to proceed or not. + +##### Step 25 + +A transaction notification is sent to the agent after the transaction is performed by Payee FSP. + +##### Step 33 + +After receiving transaction notification, the agent gives the cash-out amount to the customer. + +##### Relevant Error Conditions + +[Table 7](#table-7) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 7 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 3 | Payer cannot be found | Account Lookup System fails to locate the Payer | Cancel the transaction | +| 7 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction supported by Payee FSP | +| 22 | Timeout | **Perform Transfer** request timed out | Query transfer status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 24 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 27 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP. | Reconcile according to scheme rules | + +**Table 7 – Agent-Initiated Cash-Out: Relevant Error Conditions** + +### Agent-Initiated Cash-Out Authorized on POS + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests that an agent of a different FSP cash-out (withdraw funds) from their account. In this use case, the agent initiates the transaction through a POS, and the customer inputs a OTP on POS to authorize the transaction. Alternatively, the agent can use POS to scan a QR code generated by the mobile app of the customer to initiate the transaction. + +- Approval using OTP – A Payer can approve a transaction by first creating an OTP in their FSP. The OTP is then entered in a Payee device (usually a POS device). The OTP in the transaction request is automatically matched by the Payer FSP to either approve or reject the transaction. The OTP does not need to be encrypted as it should only be valid once during a short time period. + +- Approval using QR code – A Payer can approve a transaction by requesting a Payer FSP to generate a QR code that encodes an OTP and customer’s identifier. + +- Approval using NFC – A Payer can approve a transaction by swiping a _Near Field Communication_ (NFC) phone on a POS. The interoperability for NFC POS of one FSP to read data from NFC tag or NFC phone of another FSP should be considered if NFC technology is adopted. + +Agent-Initiated Cash-Out Authorized on POS is typically a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-Out Authorized on POS are described in [Table 8](#table-8). + +##### Table 8 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer (individual or organization) who wants to withdraw cash using an agent.

    The customer is a registered party with Payer FSP.| +| Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    The agent is registered party with Payee FSP. | + +**Table 8 – Agent-Initiated Cash-Out Authorized on POS: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +For OTP: + +- The customer requests Payer FSP to generate an OTP. + +For QR code: + +- The customer enters cash-out amount and requests Payer FSP to generate a QR code. + +- The QR code generation should be approved by customer transaction PIN. + +##### Step 4 + +The customer requests the agent to cash-out some amount from their account. + +For OTP: + +- The agent inputs the customer’s ID and cash-out amount to initiate the transaction + +For mobile app: + +- The agent inputs cash-out amount and then scan QR code of customer via scanner POS + +For NFC: + +- The agent inputs cash-out amount and the customer taps phone on NFC POS. + +- The agent verifies identity of the customer to satisfy regulation requirements. + +##### Step 21 + +There is a risk that someone other than the owner of phone may attempt to use the phone to make a transaction at an agent store. Thus, the transaction should be approved via PIN to allow an OTP to be generated automatically. + +##### Step 25 + +The customer checks fees and taxes. If the customer agrees: + +- For OTP: The customer enters OTP on the agent phone or device. + +- For QR code/NFC: The customer confirms the payment on POS. + +If the customer disagrees: + +- For OTP: The customer doesn’t enter OTP on the agent phone or device. + +- For QR code/NFC: The customer rejects the payment on POS. + +##### Step 36 + +A notification is sent to the agent after the transaction is performed by the Payee FSP. After receiving transaction notification, the agent gives the cash-out amount to the customer. + +##### Step 44 + +The Payer FSP sends a notification of the transaction result to the customer. + +##### Relevant Error Conditions + +[Table 9](#table-9) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 9 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timedout| Retry| +| 6 | Payer cannot be found | Account Lookup System fails to locate the Payer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 28 | OTP is expired | OTP is expired | Push another authentication request to Payee FSP
    or
    Cancel the transaction in the Payer FSP | +| 28 | Invalid OTP | OTP is unrecognized | Push another authentication request to Payee FSP
    or
    Cancel the transaction in the Payer FSP | +| 35 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 38 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 9 – Agent-Initiated Cash-Out Authorized on POS: Relevant Error Conditions** + +### Customer-Initiated Cash-Out + +#### Use Case Description + +This section describes the business process and business rules for a use case in which a registered customer initiates a transaction to withdraw cash using an agent who is in a different FSP. This is two-step business process: a customer initiates cash-out transaction on their handset and then receives transaction information including fees, which can either be rejected or accepted. + +Customer-Initiated Cash-Out usually is a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Customer-Initiated Cash-Out are described in [Table 10](#table-10). + +##### Table 10 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer (individual or organization) who wants to cash-out (withdraw funds) using an agent.

    Customer is a registered party with Payer FSP. | +| Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    Agent is registered party with Payee FSP. | + +**Table 10 – Customer-Initiated Cash-Out: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +The customer requests that the agent cash-out some amount from their account. + +For USSD: + +- The customer inputs cash-out amount and merchant ID to initiate the transaction. + +For mobile app: + +- If a smart phone is used, the customer can scan the static QR code of the agent to capture the agent’s information and initiate transaction. + +Optionally, the agent can verify the identity of the customer to satisfy regulatory requirements. + +##### Step 12 + +This is an optional step. Payee FSP shows fees, taxes or both to the agent. If the agent does not accept the fees or commission, they can reject the transaction. + +##### Step 16 + +Payer FSP shows fees and taxes to the customer. If the customer doesn’t want to proceed, they reject the transaction. + +##### Step 20 + +A notification is sent to the agent once the transaction is performed by Payee FSP. + +##### Step 29 + +After the customer receives transaction notification, the agent gives cash-out amount to the customer. + +#### Relevant Error Conditions + +[Table 11](#table-11) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 11 + +|Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Agent cannot be found | Account Lookup System fails to locate agent | Cancel the transaction | +| 6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 |Timeout | **Calculate Quote** request timed out | Retry with the same ID | +| 11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 11 – Customer-Initiated Cash-Out: Relevant Error Conditions** + +### Customer-Initiated Merchant Payment + +#### Use Case Description + +This section describes the business process and business rules for a use case in which a registered customer initiates a merchant payment transaction to pay a merchant who is in another FSP. + +This could be a face to face transaction; for example, when a customer buys goods or services at the merchant store. Another case is online payment, in which an online shopping system generates a QR code and displays on the web page, and the customer then scans the QR code on the web page and authorizes and completes the payment transaction on their handset. + +**Assumption:** Encoding/Decoding QR code is handled in each FSP and is out of scope of API. The data and its format encoded in the QR code should be defined in the scheme rules to enable QR codes to be interoperable. + +#### Reference to General Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Customer-Initiated Merchant Payment are described in [Table 12](#table-12). + +##### Table 12 + +| Role | Map to Generic Transaction Pattern | Description +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business that sells goods or provide service and then receives payment from the customer. | + +**Table 12 – Customer-Initiated Merchant Payment: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +For feature phone: + +- The customer can initiate a payment transaction by inputting relevant payment information on the USSD menu, such as amount and merchant ID. + +For smart phone: + +- The customer initiates merchant payment transaction by scanning the merchant QR code. After resolving the merchant QR code, there are two scenarios: + + a) The customer inputs transaction amount in their handset to continue the transaction if the transaction amount is not encoded in the QR code. This is the case for face-to-face payment at retailer merchant store. + + b) Transaction amount has already been encoded in the QR code, and then Payer FSP has enough information to continue the transaction. This case then follows the process of the online payment case identified in [4.6.1](#461-use-case-description). + +##### Step 2 + +The merchant FSP ID could be determined by the scheme rules without depending on an Account Lookup System. Otherwise, **Lookup Party Information** request is an option to find out in which FSP the merchant is located. + +In most cases, the merchant FSP ID is captured during initiating the transaction. For example, the customer selects the merchant FSP from USSD menu, or it is already encoded in the merchant QR code. + +##### Step 9 – Step 15 + +In most cases, the customer is free of charge for the purchase transaction. **Calculate Quote** request is still necessary, because all transaction details will be sent to Payee FSP and the condition of the transfer will be generated by Payee FSP for later use (in **Perform Transfer**). + +##### Step 20 + +A notification is sent to the merchant once the transaction is performed by the Payee FSP. + +##### Step 29 + +Customer receives transaction notification and customer receives goods. + +#### Relevant Error Conditions + +[Table 13](#table-13) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 13 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Merchant is unreachable | Account Lookup System fails to locate merchant | Cancel the transaction | +| 6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +| 11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 13 – Customer-Initiated Merchant Payment: Relevant Error Conditions** + +### Merchant-Initiated Merchant Payment + +#### Use Case Description + +This use case describes a merchant payment transaction, initiated by a merchant and then authorized by the customer on their handset. + +The business process involves two parties, a merchant and a customer. The merchant initiates a _request to pay_ transaction to the customer. The customer can review the transaction details and approve or reject the transaction on their mobile device. + +Thus, it is a two-step business process in which the merchant initiates a payment transaction and the customer authorizes the transaction from their account. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction_ + +#### Actors and roles + +The actors and roles for Merchant-Initiated Merchant Payment are described in [Table 14](#table-14). + +##### Table 14 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business who sells goods or provides services and then receives payment from the customer. | + +**Table 14 – Merchant-Initiated Merchant Payment: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the End User as the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +For feature phone: + +- The merchants can input the customers’ ID in their USSD/STK menu when initiating payment transactions. + +For smart phone: + +- To capture the customer’s ID, the merchant may use a scan device or mobile app to scan QR code generated by the customer’s mobile app. + +##### Step 10-16 + +In a merchant payment transaction, the customer is usually free-of-charge. + +##### Step 13 + +This is an optional step. Payee FSP shows the transaction details including fees to the merchant; and the merchant can accept or reject the transaction. + +##### Step 25 + +A notification is sent to the merchant after the transaction is performed by the Payee FSP. + +##### Step 33 + +Payer FSP sends a notification to the customer to indicate the transaction result. + +#### Relevant Error Conditions + +[Table 15](#table-15) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 15 + +| Step | Error Condition | Error Description | Follow Up Action | +| -- | -- | -- | -- | +| 2 | Account Lookup Timeout | **Lookup Party Information** request timed out | Retry | +| 3 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 5 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 10 | Quote request failed | **Calculate Quote** request timed out or failed at Switch or Payee FSP | Cancel the transaction | +| 24 | Quote expired | Quote expired | Cancel the transaction | +| 27 | Reservation timeout | Funds reservation timed out at Payer FSP and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 15 – Merchant-Initiated Merchant Payment: Relevant Error Conditions** + +
    + +### Merchant-Initiated Merchant Payment Authorized on POS + +#### Use Case Description + +This use case describes a merchant payment initiated by a merchant using a device such as POS, and how to authorize a transaction with an OTP or a QR code. + +The merchant initiates a merchant payment transaction using a POS device. This device has the capability to capture the customer’s authorization on POS instead of the customer’s mobile device. The authorization information captured in POS should be sent to Payer FSP to perform the authorization. + +The business process involves two parties, Merchant and Customer. The merchant initiates a request to pay for the customer, and the customer reviews the payment request on POS and authorizes the payment by OTP or QR code on the POS itself. The customer authentication information is sent from Payee FSP to Payer FSP for authentication by Payer FSP. If authentication is successful then transaction will be posted on Payer FSP and Payee FSP. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and roles + +The actors and roles for Merchant-Initiated Merchant Payment Authorized on POS are described in [Table 16](#table-16) below: + +##### Table 16 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business who sells goods or provide service and then receive payment from the customer. | + +**Table 16 – Merchant-Initiated Merchant Payment Authorized on POS: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user, because the interactions between the participating systems are described in the general pattern. + +##### Step 1-3 + +The customer can pre-authorize the transaction by generating a dynamic payment QR code on a mobile app if they have a smart phone. + +The customer can request an OTP on the USSD menu if they have a feature phone. + +##### Step 4 + +For mobile app: + +- The merchant uses a scan device such as a POS to capture the QR code and initiate the payment. + +- Both customer ID and OTP are encoded in the QR code. + +For feature phone: + +- The merchant inputs customer’s ID and amount to initiate the transaction. + +##### Step 20 + +Steps 1-3 are optional and will be used only when OTP is generated by Payer to authenticate the purchase at the merchant +device. However, it would be very rare for a customer to generate the OTP manually; instead Payer FSP would generate an OTP for the customer as described in Step 20. + +##### Step 21 + +There is a risk that someone other than the owner of phone may attempt to use the phone to make a transaction at agent store. Thus, the transaction should be approved via PIN to allow OTP to be generated automatically. + +##### Step 25 + +The customer need only confirm the transaction on POS if initiating transaction with a QR code in step 4, because OTP is encoded in the QR code and parsed in Step 4. + +##### Step 36 + +A notification is sent to the merchant once the transaction is performed by the Payee FSP. After receiving the transaction notification, the merchant gives goods to the customer. + +##### Step 44 +The Payer FSP sends a notification of the transaction result to the customer. + +#### Relevant Error Conditions + +[Table 17](#table-17) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 17 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timed out | Retry | +| 6 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query status and retry | +| 19 | Quote request failed | Quote failed at Switch or Payee FSP | Cancel the transaction | +| 33 | Transfer request timeout | **Perform Transfer** request to Payee FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 35 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 38 | Reservation is expired | Funds reservation timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 17 – Merchant-Initiated Merchant Payment Authorized on POS: Relevant Error Conditions** + +
    + +### ATM-Initiated Cash-Out + +#### Use Case Description + +This section describes the business flows and rules of an _ATM-Initiated Cash-Out_ use case. + +This use case involves two parties: ATM and Customer. ATM initiates a Cash-Out request from the customer account and the customer confirms the request by providing authentication (OTP) on ATM. The customer pre-generates an OTP for cash-out and uses this OTP on ATM device to initiate ATM Cash-out. The Payer FSP validates the OTP received in _ATM-Initiated Cash-Out_ request for the validity of OTP as well as for authentication. If the customer authentication via OTP is successful; then the customer’s account will be debited at Payer FSP and ATM account maintained at Payee FSP will be credited. As a result, the customer receives cash from ATM. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and roles + +The actors and roles for ATM Initiated Cash Out are described in [Table 18](#table-18). + +##### Table 18 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer who wants to withdraw cash from ATM device belonging to another FSP. | +| ATM Provider | Payee | Payee is an ATM provider who provides cash withdrawal service on ATM device to a customer belonging to another FSP. ATM would be connected to a bank network which is connected to Payee FSP. There would be a pre-funded account in Payee FSP corresponding to an ATM or ATMs, or to a Bank Switch. | + +**Table 18 – ATM-Initiated Cash-Out: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user as the interactions between the participating systems are described in the general pattern. + +##### Step 1-3 + +Steps 1 to 3 are optional; however, it is recommended that customer generate an OTP before initiating the transaction request from ATM. + +Alternatively, a customer generates a QR code for cash-out via mobile app other than OTP. + +##### Step 4 + +For mobile app: + +- ATM can scan previously-generated cash-out QR code. + +For feature phone: + +- The customer initiates withdrawal transaction by inputting their account ID and amount. + +##### Step 20 + +In _ATM-Initiated Cash-Out_, it is very rare that an OTP is automatically generated by a Payer FSP, because this will delay the transaction due to SMS delivery, and the ATM transaction will time out. Therefore, it is recommended that customer generate an OTP for ATM Cash-out as mentioned in Steps 1-3. + +##### Step 21 + +There is a risk that someone other than the owner of phone holding the handset may make a transaction at an ATM device. In this case, the transaction should be approved via PIN so that the OTP can be generated automatically. + +##### Step 25 + +If an OTP is used, the customer enters the OTP that was generated in Steps 1-3 or Step 21. + +If a QR code is used to cash-out and it is captured by an ATM when initiating the transaction in Step 4, then the customer must confirm or reject the transaction on the ATM only; inputting security credentials such as OTP or password is not necessary. + +#### Relevant Error Conditions + +[Table 19](#table-19) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 19 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timed out | Retry | +| 6 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** timed out at Switch or Payee FSP | Query and retry | +| 14 | Quote request timeout | **Calculate Quote** request timed out | Retry | +| 15 | Quote request failed | **Calculate Quote** request fails at Switch or Payee FSP | Cancel the transaction | +| 33 | Transfer request timeout | Perform Transfer request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 35 | Transaction request is failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of merchant
  • Payee FSP internal system error

  • | Cancel the transaction and try another new transaction | +| 38 | Reservation is timeout | Funds reservation is timeout and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 19 – ATM-Initiated Cash-Out: Relevant Error Conditions** + +
    + +### Bulk Payments + +#### Use Case Description + +This section describes a _Bulk Payments_ use case. The use case is written from the end-user perspective to give additional information to the _Generic Transaction Patterns_ document. + +Bulk Payments are used when an organization or business is paying out funds; for example, aid or salary to multiple Payees. The organization or business can group transactions together to make it easier to upload and validate individual transactions in bulk before the bulk transaction is executed. It is also possible for the organization to follow up the result of the individual transactions in the bulk transaction after the bulk transaction is executed. + +#### Reference to Generic Pattern + +_Bulk Transactions_ + +#### Actors and roles + +The actors and roles for Bulk Payments are described in [Table 20](#table-20) below: + +##### Table 20 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Payer | Payer | The Payer is a corporate, government or aid organization that is transferring money from its own account to multiple Payees. The reason can for instance be payout of monthly salary or aid disbursement.

    The Payer is a registered user with an account in the Payer FSP. | +| Payee | Payee | The Payee is, for example, an employee at a corporate or receiver of aid that is receiving a payout from the Payer.

    The Payee is a registered user with an account in one of the connected FSPs. | + +**Table 20 – Bulk Payments: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user as the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +The Payer creates a bulk transaction according to the format of the Payer FSP. Each row in the bulk transaction includes information about a transfer between a Payer account and a Payee account. The information includes: + +- A unique transaction ID for the bulk so that the Payer can follow up the status of individual transactions in the bulk. + +- Identifier of the Payee + +- Amount and currency to be transferred + +The Payer will upload the bulk transaction using the interface provided by the Payer FSP. + +##### Step 12 + +The Payer is notified by the Payer FSP that the bulk is ready for review. + +The Payer will get a bulk transaction report and validate that the specified Payees have accounts and can receive funds. + +The Payer can also validate any fees that will be charged for executing the bulk transaction. Fees will be calculated per transaction in the bulk transaction. + +Before the bulk transaction is executed, the Payer must ensure that there are enough funds in the Payer account for the value of the complete bulk transaction to be completed. Depending on scheme rules the Payer FSP needs to ensure that there are enough funds prefunded to the Payee FSP to be able to complete the transactions to the Payee. + +If the Payer is satisfied after reviewing the bulk transaction, then the Payer will initiate the execution of the bulk transaction. + +If the Payer does not want to execute the bulk transaction, then the bulk transaction can be canceled. Cancellation will be +handled internally in the Payer FSP. No information regarding cancelation will be sent to the Payee FSP. + +How execution and cancelation is handled depends on the implementation in the Payer FSP. + +##### Step 21 + +The Payer can review the result of the bulk transaction execution when the Payer FSP has processed all the transactions in the uploaded bulk transaction. + +The Payer will be able to get details about the execution for each individual transaction. + +Any reprocessing that might be needed to be executed (for example, failed transactions) will be treated as a new bulk transaction in the API. + +#### Relevant Error Conditions + +Bulk Transactions have two main types of logical errors: Errors connected to the header and errors related to the transactions in the bulk transaction. + +An error related to the header will fail the complete bulk transaction. For example, if the Payer of the bulk transaction is blocked, then no transaction shall be executed. + +Errors related to an individual transaction within the bulk transaction will get a failed status and be assigned an error code. The amount of the transaction that failed will be rolled back. Other transactions in the bulk transaction will not be affected if one individual transaction fails. + +[Table 21](#table-21) below contains a description of general error cases to give an overview of the bulk transaction use case and how different error cases are handled. Detailed error codes for the operations are not included, nor are codes for communication errors and format validations errors. + +##### Table 21 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Payee not found | Account lookup fails to look up Payee at any FSP. | Payee will be excluded from any bulk transactions request and marked as failed in the bulk transaction response to the Payer | +| 8 | Payee not found | Payee FSP cannot find the Payee account | Payee FSP will mark the individual transaction in the bulk transaction as failed. | +| 15 | Not enough funds on Payer FSP account | The Payer FSP account in the | Switch has not been prefunded to cover for the complete bulk transaction. Switch would fail the complete bulk transaction as the funds for the bulk transaction cannot be reserved. | +| 16 | Not enough funds on Payer FSP account | The Payer FSP account in the Payee FSP has not been prefunded to cover for the complete bulk transaction. | Payee FSP is not able to reserve the amount for the bulk transaction.

    Payee FSP can decide to execute as many transactions as possible or to fail the complete bulk transaction. | +| 16 | Payee transfer not allowed | The Payee FSP cannot complete the transfer of funds to the Payee. This could, for example, be blocked due to an account limit. | The individual transaction will be rolled back and reported in Payer response as failed. | +| 16 | Bulk quote expired | The quote for the bulk transaction has expired | The Payee FSP will fail the complete bulk transaction requests. | + +**Table 21 – Bulk Payments: Relevant Error Conditions** + +
    + +### Refund + +This section describes how to refund a completed interoperability transaction. + +There are several refund scenarios for merchant payment transaction: + +1. The customer has entered an amount incorrectly and paid more than the invoice. + +2. The merchant is not able to deliver the goods as specified by the invoice already paid by the customer, so the merchant wants to refund money to the customer. + +3. An online merchant selling tickets (train, air or bus) provides a refund to a customer when the customer cancels the ticket. + +4. The customer has returned the goods to the merchant and the merchant wants to refund the customer. + +Additional business scenarios may require transaction reversals. For example: + +1. The customer has sent money to incorrect recipient. + +2. The customer accidently created the same transaction twice. + +It is recommended to use refund transaction to fulfill the business purpose. + +The business process will remain as reversal, but the technical implementation would require Payee FSP CCE to initiate a refund transaction. Payer FSP CCE coordinates with Payee CCE manually. If there is a Switch, then Switch administrator may help to facilitate the conversation between Payer FSP and Payee FSP. + +Note the following: + +- Refund can only be initiated by Payee of the original transaction. Alternatively, CCE of Payee FSP in the original transaction can also initiate refund from Payee account. + +- An original transaction can be refunded multiple times. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and roles + +The actors and roles for Bulk Payment are described in [Table 22](#table-22). + +##### Table 22 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | --- | +| Payee | Payee | The End User who has made a wrong payment and requests a refund. | +| Payer | Payer | The End User who has received the payment in the original transaction. | + +**Table 22 – Refund: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user, because the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +Payer of the original transaction can contact Payee or CCE of Payer FSP to request refund. The actual refund amount is negotiated between Payer and Payee before the refund. + +##### Step 9-15 + +Typically, the refund transaction is free-of-charge. + +##### Step 17 + +The original transaction ID should be captured in the refund transaction. + +#### Relevant Error Conditions + +[Table 23](#table-23) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 23 + +| Step | Error Condition | Error Description | Follow on Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Payee cannot be found | Account Lookup System fails to locate Customer | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit Breached
  • Quote is expired
  • Invalid account status of customer
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Funds reservation timeout | Funds reservation at Payer FSP timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 23 – Refund: Relevant Error Conditions** + +
    + +## List of Tables + +[Table 1](#table-1) – Use Case Summary + +[Table 2](#table-2) – P2P Actors and Roles + +[Table 3](#table-3) – P2P Relevant Error Conditions + +[Table 4](#table-4) – Agent-Initiated Cash-In: Actors and Roles + +[Table 5](#table-5) – Agent-Initiated Cash-In: Relevant Error Conditions + +[Table 6](#table-6) – Agent-Initiated Cash-Out: Actors and Roles + +[Table 7](#table-7) – Agent-Initiated Cash-Out: Relevant Error Conditions + +[Table 8](#table-8) – Agent-Initiated Cash-Out Authorized on POS: Actors and Roles + +[Table 9](#table-9) – Agent-Initiated Cash-Out Authorized on POS: Relevant Error Conditions + +[Table 10](#table-10) – Customer-Initiated Cash-Out: Actors and Roles + +[Table 11](#table-11) – Customer-Initiated Cash-Out: Relevant Error Conditions + +[Table 12](#table-12) – Customer-Initiated Merchant Payment: Actors and Roles + +[Table 13](#table-13) – Customer-Initiated Merchant Payment: Relevant Error Conditions + +[Table 14](#table-14) – Merchant-Initiated Merchant Payment: Actors and Roles + +[Table 15](#table-15) – Merchant-Initiated Merchant Payment: Relevant Error Conditions + +[Table 16](#table-16) – Merchant-Initiated Merchant Payment Authorized on POS: Actors and Roles + +[Table 17](#table-17) – Merchant-Initiated Merchant Payment Authorized on POS: Relevant Error Conditions + +[Table 18](#table-18) – ATM-Initiated Cash-Out: Actors and Roles + +[Table 19](#table-19) – ATM-Initiated Cash-Out: Relevant Error Conditions + +[Table 20](#table-20) – Bulk Payments: Actors and Roles + +[Table 21](#table-21) – Bulk Payments: Relevant Error Conditions + +[Table 22](#table-22) – Refund: Actors and Roles + +[Table 23](#table-23) – Refund: Relevant Error Conditions \ No newline at end of file diff --git a/docs/technical/api/fspiop/v1.0/README.md b/docs/technical/api/fspiop/v1.0/README.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/docs/technical/api/fspiop/v1.0/README.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/docs/technical/api/fspiop/v1.0/api-definition.md b/docs/technical/api/fspiop/v1.0/api-definition.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/docs/technical/api/fspiop/v1.0/api-definition.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/docs/technical/api/fspiop/v1.1/api-definition.md b/docs/technical/api/fspiop/v1.1/api-definition.md new file mode 100644 index 000000000..f5708abc5 --- /dev/null +++ b/docs/technical/api/fspiop/v1.1/api-definition.md @@ -0,0 +1,5495 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| +|**1.1**|2020-05-19|1. This version contains a new option for a Payee FSP to request a commit notification from the Switch. The Switch should then send out the commit notification using the new request **PATCH /transfers/**_{ID}_. The option to use commit notification replaces the previous option of using the ”Optional Additional Clearing Check”. The section describing this has been replaced with the new section ”Commit Notification”. As the **transfers** resource has been updated with the new **PATCH** request, this resource has been updated to version 1.1. As part of adding the possibility to use a commit notification, the following changes has been made:
    a. PATCH has been added as an allowed HTTP Method in Section 3.2.2. b. The call flow for **PATCH** is described in Section 3.2.3.5.
    c. Table 6 in Section 6.1.1 has been updated to include **PATCH** as a possible HTTP Method.
    d. Section 6.7.1 contains the new version of the **transfers** resource.
    e. Section 6.7.2.6 contains the process for using commit notifications
    f. Section 6.7.3.3 describes the new **PATCH /transfers**/_{ID}_ request.

    2. In addition to the changes mentioned above regarding the commit notification, the following non-API affecting changes has been made:
    a. Updated Figure 6 as it contained a copy-paste error.
    b. Added Section 6.1.2 to describe a comprehensive view of the current version for each resource.
    c. Added a section for each resource to be able to see the resource version history.
    d. Minor editorial fixes.

    3. The descriptions for two of the HTTP Header fields in Table 1 have been updated to add more specificity and context
    a. The description for the **FSPIOP-Destination** header field has been updated to indicate that it should be left empty if the destination is not known to the original sender, but in all other cases should be added by the original sender of a request.
    b. The description for the **FSPIOP-URI** header field has been updated to be more specific.

    4. The examples used in this document have been updated to use the correct interpretation of the Complex type ExtensionList which is defined in Table 84. This doesn’t imply any change as such.
    a. Listing 5 has been updated in this regard.

    5. The data model is updated to add an optional ExtensionList element to the **PartyIdInfo** complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 103 has been updated. For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.

    6. A new Section 6.5.2.2 is added to describe the process involved in the rejection of a quote.

    7. A note is added to Section 6.7.4.1 to clarify the usage of ABORTED state in **PUT /transfers/**_{ID}_ callbacks.| +|**1.1.1**|2021-09-22|This document version only adds information about optional HTTP headers regarding tracing support in [Table 2](#table-2), see _Distributed Tracing Support for OpenAPI Interoperability_ for more information. There are no changes in any resources as part of this version.| + +## Introduction + +This document introduces and describes the _Open API_ (Application Programming Interface) _for FSP_ (Financial Service Provider) _Interoperability_ (hereafter cited as "the API"). The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. The API does not specify any front-end services between a Payer or Payee and its own FSP; all services defined in the API are between FSPs. FSPs are connected either (a) directly to each other or (b) by a _Switch_ placed between the FSPs to route financial transactions to the correct FSP. + +The transfer of funds from a Payer to a Payee should be performed in near real-time. As soon as a financial transaction has been agreed to by both parties, it is deemed irrevocable. This means that a completed transaction cannot be reversed in the API. To reverse a transaction, a new negated refund transaction should be created from the Payee of the original transaction. + +The API is designed to be sufficiently generic to support both a wide number of use cases and extensibility of those use cases. However, it should contain sufficient detail to enable implementation in an unambiguous fashion. + +Version 1.0 of the API is designed to be used within a country or region, international remittance that requires foreign exchange is not supported. This version also contains basic support for the [Interledger Protocol](#4-interledger-protocol), which will in future versions of the API be used for supporting foreign exchange and multi-hop financial transactions. + +This document: + +- Defines an asynchronous REST binding of the logical API introduced in _Generic Transaction Patterns_. +- Adds to and builds on the information provided in [Open API for FSP Interoperability Specification](#open-api-for-fsp-interoperability-specification). + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](../logical-data-model) + +- [Generic Transaction Patterns](../generic-transaction-patterns) + +- [Use Cases](../use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](../definitions) + +- [JSON Binding Rules](../json-binding-rules) + +- [Scheme Rules](../scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](../pki-best-practices) + +- [Signature](../v1.1/signature) + +- [Encryption](../v1.1/encryption) + +#### General Documents + +- [Glossary](../glossary) + +
    + +## API Definition + +This section introduces the technology used by the API, including: + +- [General Characteristics](#general-characteristics) +- [HTTP Details](#http-details) +- [API Versioning](#api-versioning) + +### General Characteristics + +This section describes the general characteristics of the API. + +#### Architectural Style + +The API is based on the REST (REpresentational State Transfer1) architectural style. There are, however, some differences between a typical REST implementation and this one. These differences include: + +- **Fully asynchronous API** -- To be able to handle numerous concurrent long-running processes and to have a single mechanism for handling requests, all API services are asynchronous. Examples of long-running processes are: + - Financial transactions done in bulk + - A financial transaction in which user interaction is needed + +- **Decentralized** -- Services are decentralized, there is no central authority which drives a transaction. + +- **Service-oriented** -- The resources provided by the API are relatively service-oriented compared to a typical implementation of a REST-based API. + +- **Not fully stateless** -- Some state information must be kept in both client and server during the process of performing a financial transaction. + +- **Client decides common ID** -- In a typical REST implementation, in which there is a clear distinction between client and server, it is the server that generates the ID of an object when the object is created on the server. In this API, a quote or a financial transaction resides both in the Payer and Payee FSP as the services are decentralized. Therefore, there is a need for a common ID of the object. The reason for having the client decide the common ID is two-fold: + - The common ID is used in the URI of the asynchronous callback to the client. The client therefore knows which URI to listen to for a callback regarding the request. + - The client can use the common ID in an HTTP **GET** request directly if it does not receive a callback from the server (see [HTTP Details](#http-details) section for more information). + + To keep the common IDs unique, each common ID is defined as a UUID (Universally Unique IDentifier2 (UUID). To further guarantee uniqueness, it is recommended that a server should separate each client FSP's IDs by mapping the FSP ID and the object ID together. If a server still receives a non-unique common ID during an HTTP **POST** request (see [HTTP Details](#http-details) section for more details). The request should be handled as detailed in [Idempotent Services in server](#idempotent-services-in-server) section. + +#### Application-Level Protocol + +HTTP, as defined in RFC 72303, is used as the application-level protocol in the API. All communication in production environments should be secured using HTTPS (HTTP over TLS4). For more details about the use of HTTP in the API, see [HTTP Details](#http-details). + +#### URI Syntax + +The syntax of URIs follows RFC 39865 to identify resources and services provided by the API. This section introduces and notes implementation subjects specific to each syntax part. + +A generic URI has the form shown in [Listing 1](#listing-1), where the part \[_user:password@_\]_host_\[_:port_\] is the `Authority` part described in [Authority](#authority) section. +_{resource}_. + +###### Listing 1 + +``` +scheme:[//[user:password@]host[:port]][/]path[?query][#fragment] +``` + +**Listing 1 -- Generic URI format** + +##### Scheme + +In accordance with the [Application Level Protocol](#aplication-level-protocol) section, the _scheme_ (that is, the set of rules, practices and standards necessary for the functioning of payment services) will always be either **http** or **https**. + +##### Authority + +The authority part consists of an optional authentication (`User Information`) part, a mandatory host part, followed by an optional port number. + +###### User Information + +User information should in general not be used by API deployments; the security measures detailed in *API Signature* and _API_ _Encryption_ should be used instead. + +###### Host + +The host is the server's address. It can be either an IP address or a hostname. The host will (usually) differ for each deployment. + +###### Port + +The port number is optional; by default, the HTTP port is **80** and HTTPS is **443**, but other ports could also be used. Which port to use might differ from deployment to deployment. + +##### Path + +The path points to an actual API resource or service. The resources in the API are: + +- **participants** +- **parties** +- **quotes** +- **transactionRequests** +- **authorizations** +- **transfers** +- **transactions** +- **bulkQuotes** +- **bulkTransfers** + +All resources found above are also organized further in a hierarchical form, separated by one or more forward slashes (**'/'**). Resources support different services depending on the HTTP method used. All supported API resources and services, tabulated with URI and HTTP method, appear in [Table 6](#table-6). + +##### Query + +The query is an optional part of a URI; it is currently only used and supported by a few services in the API. See the API resources in [API Services](#api-services) section for more details about which services support query strings. All other services should ignore the query string part of the URI, as query strings may be added in future minor versions of the API (see [HTTP Methods](#http-methods)). + +If more than one key-value pair is used in the query string, the pairs should be separated by an ampersand symbol (**'&'**). + +[Listing 2](#listing-2) shows a URI example from the API resource **/authorization**, in which four different key-value pairs are present in the query string, separated by an ampersand symbol. + +###### Listing 2 + +``` +/authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD +``` + +**Listing 2 -- Example URI containing several key-value pairs in the query string** + +##### Fragment + +The fragment is an optional part of a URI. It is not supported for use by any service in the API and therefore should be ignored if received. + +#### URI Normalization and Comparison + +As specified in RFC 72306, the [scheme](#scheme)) and [host](#host)) part of the URI should be considered case-insensitive. All other parts of the URI should be processed in a case-sensitive manner. + +#### Character Set + +The character set should always be assumed to be UTF-8, defined in 36297; therefore, it does not need to be sent in any of the HTTP header fields (see [HTTP Header Fields](#http-header-fields)). No character set other than UTF-8 is supported by the API. + +#### Data Exchange Format + +The API uses JSON (JavaScript Object Notation), defined in RFC 71598, as its data exchange format. JSON is an open, lightweight, human-readable and platform-independent format, well-suited for interchanging data between systems. + +
    + +### HTTP Details + +This section contains detailed information regarding the use of the application-level protocol HTTP in the API. + +#### HTTP Header Fields + +HTTP Headers are generally described in RFC 72309. The following two sections describes the HTTP header fields that should be expected and implemented in the API. + +The API supports a maximum size of 65536 bytes (64 Kilobytes) in the HTTP header. + +#### HTTP Request Header Fields + +[Table 1](#table-1) contains the HTTP request header fields that must be supported by implementers of the API. An implementation should also expect other standard and non-standard HTTP request header fields not listed here. + +###### Table 1 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**Accept**|**application/vnd.interoperability.resource+json**|0..1
    Mandatory in a request from a client. Not used in a callback from the server.
    The **Accept**10 header field indicates the version of the API the client would like the server to use. See [HTTP Accept Header](#http-accept-header) for more information on requesting a specific version of the API.| +|**Content-Length**|**3495**|0..1|The **Content-Length**11 header field indicates the anticipated size of the payload body. Only sent if there is a body.
    **Note**: The API supports a maximum size of 5242880 bytes (5 Megabytes).
    | +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|The **Content-Type**12 header indicates the specific version of the API used to send the payload body. See [Acceptable Version Requested by Client](#acceptable-version-requested-by-client) for more information.| +|**Date**|**Tue, 15 Nov 1994 08:12:31 GMT**|1|The **Date**13 header field indicates the date when the request was sent.| +|**X- Forwarded- For**|**X-Forwarded-For: 192.168.0.4, 136.225.27.13**|1..0|The **X-Forwarded-For**14 header field is an unofficially accepted standard used to indicate the originating client IP address for informational purposes, as a request might pass multiple proxies, firewalls, and so on. Multiple **X-Forwarded-For** values as in the example shown here should be expected and supported by implementers of the API.
    **Note**: An alternative to **X-Forwarded-For** is defined in RFC 723915. However, as of 2018, RFC 7239 is less-used and supported than **X-Forwarded-For**.
    | +|**FSPIOP- Source**|**FSP321**|1|The **FSPIOP-Source** header field is a non- HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing (see [Call Flow Routing](#call-flow-routing-using-fspiop-destination-and-fspiop-source) section) and signature verification (see header field **FSPIOP-Signature**).| +|**FSPIOP- Destination**|**FSP123**|0..1|The **FSPIOP-Destination** header field is a non-HTTP standard field used by the API for HTTP header-based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes (see [Call Flow Routing](#3236-call-flow-routing-using-fspiop-destination-and-fspiop-source) section for more information regarding routing). If the destination is not known (valid for service GET /parties), the field should be left empty.| +|**FSPIOP- Encryption**||0..1|The **FSPIOP-Encryption** header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request.
    For more information, see API Encryption.
    | +|**FSPIOP- Signature**||0..1|The **FSPIOP-Signature** header field is a non-HTTP standard field used by the API for applying an end-to-end request signature.
    For more information, see API Signature.
    | +|**FSPIOP-URI**|**/parties/msisdn/123456789**|0..1|The **FSPIOP-URI** header field is a non- HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see _API Signature_.
    In the context of the Mojaloop FSPIOP API, the value for FSPIOP-URI starts with the **_service_** in the URI value. For example, if a URL is http://stg-simulator.moja.live/payerfsp/participants/MSISDN/123456789, then the FSPIOP-URI value is “/participants/MSISDN/123456789”.| +|**FSPIOP- HTTP- Method**|**GET**|0..1|The **FSPIOP-HTTP-Method** header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature.| + +**Table 1 -- HTTP request header fields that must be supported** + +[Table 2](#table-2) contains the HTTP request header fields that are optional to support by implementers of the API. + +###### Table 2 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**traceparent**|**00-91e502e28cd723686e9940bd3f378f85-b0f903d000944947-01**|0..1|The traceparent header represents the incoming request in a tracing system in a common format. See _Distributed Tracing Support for OpenAPI Interoperability_ for more information.| +|**tracestate**|**banknrone=b0f903d0009449475**|0..1|Provides optional vendor-specific trace information, and support for multiple distributed traces. See _Distributed Tracing Support for OpenAPI Interoperability_ for more information.| + +**Table 2 -- HTTP request header fields that are optional to support** + +##### HTTP Response Header Fields + +[Table 3](#table-3) contains the HTTP response header fields that must be supported by implementers of the API. An implementation should also expect other standard and non-standard HTTP response header fields that are not listed here. + +###### Table 3 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**Content-Length**|**3495**|0..1|The **Content-Length**16 header field indicates the anticipated size of the payload body. Only sent if there is a body.| +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|The **Content-Type**17 header field indicates the specific version of the API used to send the payload body. See [Section 3.3.4.2](#3342-acceptable-version-requested-by-client) for more information.| + +**Table 3 -- HTTP response header fields** + +#### HTTP Methods + +The following HTTP methods, as defined in RFC 723118, are supported by the API: + +- **GET** -- The HTTP **GET** method is used from a client to request information about a previously-created object on a server. As all services in the API are asynchronous, the response to the **GET** method will not contain the requested object. The requested object will instead come as part of a callback using the HTTP **PUT** method. + +- **PUT** -- The HTTP **PUT** method is used as a callback to a previously sent HTTP **GET**, HTTP **POST** or HTTP **DELETE** method, sent from a server to its client. The callback will contain either: + + - Object information concerning a previously created object (HTTP **POST**) or sent information request (HTTP **GET**). + - Acknowledgement that whether an object was deleted (HTTP **DELETE**). + - Error information in case the HTTP **POST** or HTTP **GET** request failed to be processed on the server. + +- **POST** -- The HTTP **POST** method is used from a client to request an object to be created on the server. As all services in the API are asynchronous, the response to the **POST** method will not contain the created object. The created object will instead come as part of a callback using the HTTP **PUT** method. + +- **DELETE** -- The HTTP **DELETE** method is used from a client to request an object to be deleted on the server. The HTTP **DELETE** method should only be supported in a common Account Lookup System (ALS) for deleting information regarding a previously added Party (an account holder in an FSP), no other object types can be deleted. As all services in the API are asynchronous, the response to the HTTP **DELETE** method will not contain the final acknowledgement that the object was deleted or not; the final acknowledgement will come as a callback using the HTTP **PUT** method. + +- **PATCH** -- The HTTP **PATCH** method is used from a client to send a notification regarding an update of an existing object. As all services in the API are asynchronous, the response to the **POST** method will not contain the created object. This HTTP method does not result in a callback, as the **PATCH** request is used as a notification. + +
    + +#### HTTP Sequence Flow + +All the sequences and related services use an asynchronous call flow. No service supports a synchronous call flow. + +##### HTTP POST Call Flow + +[Figure 1](#figure-1) shows the normal API call flow for a request to create an object in a Peer FSP using HTTP **POST**. The service **_/service_** in the flow should be renamed to any of the services in [Table 6](#table-6) that support the HTTP **POST** method. + +###### Figure 1 + +![](../../assets/diagrams/sequence/figure1.svg) + +**Figure 1 -- HTTP POST call flow** + +##### HTTP GET Call Flow + +[Figure 2](#figure-2) shows the normal API call flow for a request to get information about an object in a Peer FSP using HTTP **GET**. The service **/service/**_{ID}_ in the flow should be renamed to any of the services in [Table 6](#table-6) that supports the HTTP **GET** method. + +###### Figure 2 + +![](../../assets/diagrams/sequence/figure2.svg) + + +**Figure 2 -- HTTP GET call flow** + +##### HTTP DELETE Call Flow + +[Figure 3](#figure-3) contains the normal API call flow to delete FSP information about a Party in an ALS using HTTP **DELETE**. The service **/service/**_{ID}_ in the flow should be renamed to any of the services in [Table 6](#table-6) that supports the HTTP DELETE method. HTTP DELETE is only supported in a common ALS, which is why the figure shows the ALS entity as a server only. + +###### Figure 3 + +![](../../assets/diagrams/sequence/figure3.svg) + + +**Figure 3 -- HTTP DELETE call flow** + +**Note:** It is also possible that requests to the ALS be routed through a Switch, or that the ALS and the Switch are the same server. + +##### HTTP PUT Call Flow** + +The HTTP **PUT** is always used as a callback to either a **POST** service request, a **GET** service request, or a **DELETE** service request. + +The call flow of a **PUT** request and response can be seen in [Figure 1](#figure-1), [Figure 2](#figure-2), and [Figure 3](#figure-3). + +##### HTTP PATCH Call Flow + +[Figure 4](#figure-4) shows an example call flow for a HTTP **PATCH**, which is used for sending a notification. First, an object is created using a **POST** service request from the Switch. The object is created in the FSP in a non-finalized state. The FSP then requests to get a notification regarding the finalized state from the Switch by sending the non-finalized state in the **PUT** callback. The Switch handles the callback and sends the notification regarding the finalized state in a **PATCH** service request. The only resource that supports updated object notification using HTTP **PATCH** is /transfers. + +###### Figure 4 + +![](../../assets/diagrams/sequence/figure4.svg) + + +**Figure 4 -- HTTP PATCH call flow** + +**Note:** It is also possible that requests to the ALS be routed through a Switch, or that the ALS and the Switch are the same server. + +##### Call Flow Routing using FSPIOP-Destination and FSPIOP-Source + +The non-standard HTTP header fields **FSPIOP-Destination** and **FSPIOP-Source** are used for routing and message signature verification purposes (see _API Signature_ for more information regarding signature verification). [Figure 5](#figure-5) shows how the header fields are used for routing in an abstract **POST /service** call flow, where the destination (Peer) FSP is known. + +###### Figure 5 + +![](../../assets/diagrams/sequence/figure5.svg) + + +**Figure 5 -- Using the customized HTTP header fields FSPIOP-Destination and FSPIOP-Source** + +For some services when a Switch is used, the destination FSP might be unknown. An example of this scenario is when an FSP sends a **GET /parties** to the Switch without knowing which Peer FSP that owns the Party (see [Section 6.3.2](#632-service-details) describing the scenario). **FSPIOP-Destination** will in that case be empty (or set to the Switch's ID) from the FSP, but will subsequently be set by the Switch to the correct Peer FSP. See [Figure 6](#figure-6) for an example describing the usage of **FSPIOP-Destination** and **FSPIOP-Source**. + +###### Figure 6 + +![](../../assets/diagrams/sequence/figure6.svg) + + +**Figure 6 -- Example scenario where FSPIOP-Destination is unknown to FSP** + +
    + +#### HTTP Response Status Codes + +The API supports the HTTP response status codes19 in [Table 4](#table-4) below: + +###### Table 4 + +|Status Code|Reason|Description| +|---|---|---| +|**200**|`OK`|Standard response for a successful request. Used in the API by the client as a response on a callback to mark the completion of an asynchronous service.| +|**202**|`Accepted`|The request has been accepted for future processing at the server, but the server cannot guarantee that the outcome of the request will be successful. Used in the API to acknowledge that the server has received an asynchronous request.| +|**400**| `Bad Request`|The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions.| +|**401**|`Unauthorized`|The request requires authentication in order to be processed.| +|**403**|`Forbidden`|The request was denied and will be denied in the future.| +|**404**|`Not Found`|The resource specified in the URI was not found.| +|**405**|`Method Not Allowed`|An unsupported HTTP method for the request was used; see Table 6 for information on which HTTP methods are allowed in which services.| +|**406**|`Not acceptable`|The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting.| +|**501**|`Not Implemented`|The server does not support the requested service. The client should not retry.| +|**503**|`Service Unavailable`|The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame.| + + **Table 4 -- HTTP response status codes supported in the API** + +Any HTTP status codes 3*xx*20 returned by the server should not be retried and require manual investigation. + +An implementation of the API should also be capable of handling other errors not defined above as the request could potentially be routed through proxy servers. + +As all requests in the API are asynchronous, additional HTTP error codes for server errors (error codes starting with 5*xx*21 that are *not* defined in [Table 4](#table-4)) are not used by the API itself. Any error on the server during actual processing of a request will be sent as part of an error callback to the client (see [Section 9.2](#92-error-in-server-during-processing-of-request)). + +
    + +##### Error Information in HTTP Response + +In addition to the HTTP response code, all HTTP error responses (4*xx* and 5*xx* status codes) can optionally contain an **ErrorInformation** element, defined in the section on [ErrorInformation](#errorinformation). This element should be used to give more detailed information to the client if possible. + +
    + +##### Idempotent Services in Server + +All services that support HTTP **GET** must be _idempotent_; that is, the same request can be sent from a client any number of times without changing the object on the server. The server is allowed to change the state of the object; for example, a transaction state can be changed, but the FSP sending the **GET** request cannot change the state. + +All services that support HTTP **POST** must be idempotent in case the client is sending the same service ID again; that is, the server must not create a new service object if a client sends the same **POST** request again. The reason behind this is to simplify the handling of resends during error-handling in a client; however, this creates some extra requirements of the server that receives the request. An example in which the same **POST** request is sent several times can be seen [here](#client-missing-response-from-server---using-resend-of-request). + +##### Duplicate Analysis in Server on Receiving a HTTP POST Request + +When a server receives a request from a client, the server should check to determine if there is an already-existing service object with the same ID; for example, if a client has previously sent the request **POST /transfers** with the identical **transferId**. If the object already exists, the server must check to determine if the parameters of the already-created object match the parameters from the new request. + +- If the previously-created object matches the parameter from the new request, the request should be assumed to be a resend from the client. + + - If the server has not finished processing the old request and therefore has not yet sent the callback to the client, this new request can be ignored, because a callback is about to be sent to the client. + - If the server has finished processing the old request and a callback has already been sent, a new callback should be sent to the client, similar to if a HTTP **GET** request had been sent. + +- If the previously-created object does not match the parameters from the new request, an error callback should be sent to the client explaining that an object with the provided ID already exists with conflicting parameters. + +To simplify duplicate analysis, it is recommended to create and store a hash value of all incoming **POST** requests on the server, so that it is easy to compare the hash value against later incoming **POST** requests. + +
    + +### API Versioning + +The strategy of the development of the API is to maintain backwards compatibility between the API and its resources and services to the maximum extent possible; however, changes to the API should be expected by implementing parties. Versioning of the API is specific to the API resource (for example, **/participants**, **/quotes**, **/transfers**). + +There are two types of API resource versions: _Minor_ versions, which are backwards-compatible, and _major_ versions, which are backwards-incompatible. + +- Whenever a change in this document defining the characteristics of the API is updated that in some way affects an API service, the affected resource will be updated to a new major or minor version (depending on whether the changes are backwards-compatible or not). + +- Whenever a change is made to a specific service in the API, a new version of the corresponding resource will be released. + +The format of the resource version is _x_._y_ where _x_ is the major version and _y_ is the minor version. Both major and minor versions are sequentially numbered. When a new major version of a service is released, the minor version is reset to **0**. The initial version of each resource in the API is **1.0**. + +#### Changes not Affecting the API Resource Version + +Some changes will not affect the API resource version; for example, if the order of parameters within a request or callback were to be changed. + +#### Minor API Resource Version + +The following list describes the changes that are considered backwards compatible if the change affects any API service connected to a resource. API implementers should implement their client/server in such a way that the API services automatically support these changes without breaking any functionality. + +- Optional input parameters such as query strings added in a request +- Optional parameters added in a request or a callback +- Error codes added + +These types of changes affect the minor API service version. + +#### Major API Resource Versions + +The following list describes the changes that are considered backwards-incompatible if the change affects any API service connected to a resource. API implementers do _not_ need to implement their client/server in such a way that it automatically supports these changes. + +- Mandatory parameters removed or added to a request or callback +- Optional parameters changed to mandatory in a request or callback +- Parameters renamed +- Data types changed +- Business logic of API resource or connected services changed +- API resource/service URIs changed + +These types of changes affect the major API service version. Please note that the list is not comprehensive; there might be other changes as well that could affect the major API service version. + +#### Version Negotiation between Client and Server + +The API supports basic version negotiation by using HTTP content negotiation between the server and the client. A client should send the API resource version that it would like to use in the **Accept** header to the server (see [HTTP Accept Header](#http-accept-header)). If the server supports that version, it should use that version in the callback (see [Acceptable Version Requested by Client](#acceptable-version-requested-by-client)). If the server does not support the requested version, the server should reply with HTTP status 40622 including a list of supported versions (see [Non-Acceptable Version Requested by Client](#non-acceptable-version-requested-by-client)). + +#### HTTP Accept Header + +See below for an example of a simplified HTTP request which only includes an **Accept** header23. The **Accept** header should be used from a client requesting a service from a server specifying a major version of the API service. The example in [Listing 3](#listing-3) should be interpreted as "I would like to use major version 1 of the API resource, but if that version is not supported by the server then give me the latest supported version". + +###### Listing 3 + +``` +POST /service HTTP/1.1 +Accept: application/vnd.interoperability.{resource}+json;version=1, +application/vnd.interoperability.{resource}+json + +{ + ... +} +``` + +**Listing 3 -- HTTP Accept header example, requesting version 1 or the latest supported version** + +Regarding the example in [Listing 3](#listing-3): + +- The **_POST /service_** should be changed to any HTTP method and related service or resource that is supported by the API (see [Table 6](#table-6)). +- The **Accept** header field is used to indicate the API resource version the client would like to use. If several versions are supported by the client, more than one version can be requested separated by a comma (**,**) as in the example above. + - The application type is always **application/vnd.interoperability.**_{resource}_, where _{resource}_ is the actual resource (for example, **participants** or **quotes**). + - The only data exchange format currently supported is **json**. + - If a client can use any minor version of a major version, only the major version should be sent; for example, **version=1** or **version=2**. + - If a client would like to use a specific minor version, this should be indicated by using the specific _major.minor_ version; for example, **version=1.2** or **version=2.8**. The use of a specific _major.minor_ version in the request should generally be avoided, as minor versions should be backwards-compatible. + +#### Acceptable Version Requested by Client + +If the server supports the API resource version requested by the client in the Accept Headers, it should use that version in the subsequent callback. The used _major.minor_ version should always be indicated in the **Content-Type** header by the server, even if the client only requested a major version of the API. See the example in [Listing 4](#listing-4), which indicates that version 1.0 is used by the server: + +###### Listing 4 + +``` +Content-Type: application/vnd.interoperability.resource+json;version=1.0 +``` + +**Listing 4 -- Content-Type HTTP header field example** + +#### Non-Acceptable Version Requested by Client + +If the server does not support the version requested by the client in the **Accept** header, the server should reply with HTTP status 406, which indicates that the requested version is not supported. + +**Note:** There is also a possibility that the information might be sent as part of an error callback to a client instead of directly in the response; for example, when the request is routed through a Switch which does support the requested version, but the destination FSP does not support the requested version. + +Along with HTTP status 406, the supported versions should be listed as part of the error message in the extensions list, using the major version number as _key_ and minor version number as _value_. Please see error information in the example in [Listing 5](#listing-5), describing the server's supported versions. The example should be interpreted as "I do not support the resource version that you requested, but I do support versions 1.0, 2.1, and 4.2". + +###### Listing 5 + +```json +{ + "errorInformation": { + "errorCode": "3001", + "errorDescription": "The Client requested an unsupported version, see extension list for supported version(s).", + "extensionList": { + "extension": + [ + { "key": "1", "value": "0"}, + { "key": "2", "value": "1"}, + { "key": "4", "value": "2"} + ] + } + } +} +``` + +**Listing 5 -- Example error message when server does not support the requested version** + + +
    + +## Interledger Protocol + +The current version of the API includes basic support for the Interledger Protocol (ILP), by defining a concrete implementation of the Interledger Payment Request protocol24 in API Resource [/quotes](#api-resource-quotes), and API Resource, [**/transfers**](#api-resource-transfers). + +### More Information + +This document contains ILP information that is relevant to the API. For more information about the ILP protocol, see the Interledger project website25, the Interledger Whitepaper26, and the Interledger architecture specification27. + +### Introduction to Interledger + +ILP is a standard for internetworking payment networks. In the same way that the Internet Protocol (IP) establishes a set of basic standards for the transmission and addressing of data packets between different data networks, ILP establishes a set of basic standards for the addressing of financial transactions and transfer of value between accounts on different payment networks. + +ILP is not a scheme. It is a set of standards that, if implemented by multiple payment schemes, will allow those schemes to be interoperable. Therefore, implementing ILP involves adapting an existing scheme to conform to those standards. Conformance means ensuring that transfers between accounts within the scheme are done in two phases (_reserve_ and _commit_) and defining a mapping between the accounts in the scheme and the global ILP Addressing scheme. This can be done by modifying the scheme itself, or by the entities that provide ILP-conformant access to the scheme using scheme adaptors. + +The basic prerequisites for an ILP payment are the Payee ILP address (see [ILP addressing](#ilp-addressing)) and the condition (see [Conditional Transfers](#conditional-transfers)). In the current version of the API, both these prerequisites should be returned by the Payee FSP during quoting API Resource [**/quotes**](#api-resource-quotes)) of the financial transaction. + +### ILP Addressing + +A key component of the ILP standard is the ILP addressing28 scheme. It is a hierarchical scheme that defines one or more addresses for every account on a ledger. + +[Table 5](#table-5) shows some examples of ILP addresses that could be used in different scenarios, for different accounts. Note that while the structure of addresses is standardized, the content is not, except for the first segment (up to the first period (**.**)). + +###### Table 5 + +|ILP Address|Description| +|---|---| +|**g.tz.fsp1.msisdn.1234567890**|A mobile money account at **FSP1** for the user with **MSISDN 1234567890**.| +|**g.pk.fsp2.ac03396c-4dba-4743**|A mobile money account at **FSP2** identified by an opaque account id.| +|**g.us.bank1.bob**|A bank account at **Bank1** for the user **bob**.| + +**Table 5 -- ILP address examples** + +The primary purpose of an ILP addresses is to identify an account in order to route a financial transaction to that account. + +**Note:** An ILP address should not be used for identifying a counterparty in the Interoperability API. See section on [Refund](#refund) regarding how to address a Party in the API. + +It is useful to think of ILP addresses as analogous to IP addresses. They are seldom, if ever, be seen by end users but are used by the systems involved in a financial transaction to identify an account and route the ILP payment. The design of the addressing scheme means that a single account will often have many ILP addresses. The system on which the account is maintained may track these or, if they are all derived from a common prefix, may track a subset only. + +### Conditional Transfers + +ILP depends on the concept of _conditional transfers_, in which all ledgers involved in a financial transaction from the Payer to the Payee can first reserve funds out of a Payer account and then later commit them to the Payee account. The transfer from the Payer to the Payee account is conditional on the presentation of a fulfilment that satisfies the condition attached to the original transfer request. + +To support conditional transfers for ILP, a ledger must support a transfer API that attaches a condition and an expiry to the transfer. The ledger must prepare the transfer by reserving the funds from the Payer account, and then wait for one of the following events to occur: + +- The fulfilment of the condition is submitted to the ledger and the funds are committed to the Payee account. + +- The expiry timeout is reached, or the financial transaction is rejected by the Payee or Payee FSP. The transfer is then aborted and the funds that were reserved from the Payer account are returned. + +When the fulfilment of a transfer is submitted to a ledger, the ledger must ensure that the fulfilment is valid for the condition that was attached to the original transfer request. If it is valid, the transfer is committed, otherwise it is rejected, and the transfer remains in a pending state until a valid fulfilment is submitted or the transfer expires. + +ILP supports a variety of conditions for performing a conditional payment, but implementers of the API should use the SHA-256 hash of a 32-byte pre-image. The condition attached to the transfer is the SHA-256 hash and the fulfilment of that condition is the pre-image. Therefore, if the condition attached to a transfer is a SHA-256 hash, then when a fulfilment is submitted for that transaction, the ledger will validate it by calculating the SHA-256 hash of the fulfilment and ensuring that the hash is equal to the condition. + +See [Interledger Payment Request](#interledger-payment-request) for concrete information on how to generate the fulfilment and the condition. + +### ILP Packet + +The ILP Packet is the mechanism used to package end-to-end data that can be passed in a hop-by-hop service. It is included as a field in hop-by-hop service calls and should not be modified by any intermediaries. The integrity of the ILP Packet is tightly bound to the integrity of the funds transfer, as the commit trigger (the fulfilment) is generated using a hash of the ILP Packet. + +The packet has a strictly defined binary format, because it may be passed through systems that are designed for high performance and volume. These intermediary systems must read the ILP Address and the amount from the packet headers, but do not need to interpret the **data** field in the ILP Packet (see [Listing 6](#listing-6)). Since the intermediary systems should not need to interpret the **data** field, the format of the field is not strictly defined in the ILP Packet definition. It is simply defined as a variable length octet string. [Interledger Payment Request](#interledger-payment-request) contains concrete information on how the ILP Packet is populated in the API. + +The ILP Packet is the common thread that connects all the individual ledger transfers that make up an end-to-end ILP payment. The packet is parsed by the Payee of the first transfer and used to determine where to make the next transfer, and for how much. It is attached to that transfer and parsed by the Payee of the next transfer, who again determines where to make the next transfer, and for how much. This process is repeated until the Payee of the transfer is the Payee in the end-to-end financial transaction, who fulfils the condition, and the transfers are committed in sequence starting with the last and ending with the first. + +The ILP Packet format is defined in ASN.129 (Abstract Syntax Notation One), shown in [Listing 6](#listing-6). The packet is encoded using the canonical Octet Encoding Rules. + +###### Listing 6 + +``` +InterledgerProtocolPaymentMessage ::= SEQUENCE { + -- Amount which must be received at the destination amount UInt64, + -- Destination ILP Address account Address, + -- Information for recipient (transport layer information) data OCTET STRING (SIZE (0..32767)), + -- Enable ASN.1 Extensibility + extensions SEQUENCE { + ... + } +} +``` + +**Listing 6 -- The ILP Packet format in ASN.1 format** + +**Note:** The only mandatory data elements in the ILP Packet are the amount to be transferred to the account of the Payee and the ILP Address of the Payee. + +
    + +## Common API Functionality + +This section describes the common functionality used by the API, including: + +- [Quoting](#quoting) +- [Party Addressing](#party-addressing) +- [Mapping of Use Cases to Transaction Types](#mapping-of-use-cases-to-transaction-types) + +### Quoting + +Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. + +Two different modes for quoting between FSPs are supported in the API: _Non-disclosing of fees_ and _Disclosing of fees_. + +- _Non-Disclosing of fees_ should be used when either the Payer FSP does not want to show the Payee FSP its fee structure, or when the Payer FSP would like to have more control of the fees paid by the Payer after quoting has been performed (the latter is only applicable for _Receive amount_; see next bullet list). + +- _Disclosing of fees_ can be used for use cases in which the Payee FSP wants to subsidize the transaction in some use cases; for example, Cash-In at another FSP's agent. + +The _Non-Disclosing of fees_ mode should be the standard supported way of quoting in most schemes. _Disclosing of fees_ might be used in some schemes; for example, a scheme in which a dynamic fee structure is used and an FSP wants the ability to subsidize the Cash-In use case based on the dynamic cost. + +In addition, the Payer can decide if the amount should be _Receive amount_ or _Send amount_. + +- _Send amount_ should be interpreted as the actual amount that should be deducted from the Payer's account, including any fees. + +- _Receive amount_ should be interpreted as the amount that should be added to the Payee's account, regardless of any interoperable transaction fees. The amount excludes possible internal Payee fees added by the Payee FSP. + +The Payee FSP can choose if the actual receive amount for the Payee should be sent or not in the callback to the Payer FSP. The actual Payee receive amount should include any Payee FSP internal fees on the Payee. + +All taxes are assumed to be FSP-internal, which means that taxes are not sent as part of the API. See [Tax Information](#tax-information) for more information regarding taxes. + +**Note:** Dynamic fees implemented using a Switch, or any other intermediary, are not supported in this version of the API. + + +#### Non-Disclosing of Fees + +The fees and commission payments related to an interoperable transaction when fees are not disclosed are shown in [Figure 7](#figure-7). The fees and commission that are directly part of the API are identified by green text. The FSP internal fees, commission, and bonus payments are identified by red text. These are not part of the transaction between a Payer FSP and a Payee FSP, but the amount that the Payee will receive after any FSP internal fees can be sent for information by the Payee FSP. + +For send amount (see [Non-Disclosing Send Amount](#non-disclosing-send-amount) for more information), internal Payer FSP fees on the Payer will affect the amount that is sent from the Payer FSP. For example, if the Payer FSP has a fee of 1 USD for a 100 USD interoperable financial transaction, 99 USD is sent from the Payer FSP. For receive amount (see [Non-Disclosing Receive Amount](#non-disclosing-receive-amount) for more information), internal Payer FSP fees on the Payer will not affect the amount that is sent from the Payer FSP. Internal Payer FSP bonus or commission on the Payer should be hidden regardless of send or receive amount. + +###### Figure 7 + +![Figure 7](../../assets/diagrams/images/figure7.svg) + +**Figure 7 -- Fees and commission related to interoperability when fees are not disclosed** + +See [Fee Types](#fee-types) for more information on the fee types sent in the Interoperability API. + +#### Non-Disclosing Receive Amount + +[Figure 8](#figure-8) shows an example of non-disclosing receive amount, in which the Payer would like the Payee to receive exactly 100 USD. For non-disclosing receive amount, the Payer FSP need not set the internal rating of the transaction until after the quote has been received because the Payee FSP knows what amount it will receive. + +In this example, the Payee FSP decides to give commission to the Payer FSP since funds are flowing to the Payee FSP, which will later be spent in some way; this results in a future fee income for the Payee FSP. The Payer FSP can then decide how much in fees should be taken from the Payer for cost-plus pricing. In this example, the Payer FSP would like to have 1 USD from the Payer, which means that the Payer FSP will earn 2 USD in total, as the Payer FSP will also receive 1 USD in FSP commission from the Payee FSP. + +###### Figure 8 + +![](../../assets/diagrams/sequence/figure8.svg) + + +**Figure 8 -- Example of non-disclosing receive amount** + +###### Figure 9 + +![Figure 9](../../assets/diagrams/images/figure9.svg) + +**Figure 9 -- Simplified view of money movement for non-disclosing receive amount example** + +To calculate the element **transferAmount** in the Payee FSP for a non-disclosing receive amount quote, the equation in [Listing 9](#listing-9) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 23](#table-23), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is payeeFspCommission in [Table 24](#table-24). + +###### Listing 7 + +``` +Transfer amount = Quote Amount + Payee FSP Fee -- Payee FSP Commission +``` + +**Listing 7 -- Relation between transfer amount and quote amount for non-disclosing receive amount** + +#### Non-Disclosing Send Amount + +[Figure 10](#figure-10) shows an example of non-disclosing send amount, where the Payer would like to send 100 USD from the Payer's account. For non-disclosing send amount, the Payer FSP must rate (determine the internal transaction fees, commission, or both) the transaction before the quote is sent to the Payee FSP so that the Payee FSP knows how much in funds it will receive in the transaction. The actual amount withdrawn from the Payer's account is not disclosed, nor are the fees. + +In the example, the Payer FSP and the Payee FSP would like to have 1 USD each in fees so that the amount that will be received by the Payee is 98 USD. The actual amount that will be received by the Payee is in this example (not mandatory) returned in the callback to the Payer FSP, in the element **payeeReceiveAmount**. + +###### Figure 10 + +![](../../assets/diagrams/sequence/figure10.svg) + + +**Figure 10 -- Example of non-disclosing send amount** + +###### Figure 11 + +[Figure 11](#figure-11) shows a simplified view of the movement of money for the non-disclosing send amount example. + +![Figure 11](../../assets/diagrams/images/figure11.svg) + +**Figure 11 -- Simplified view of money movement for non-disclosing send amount example** + +To calculate the element **transferAmount** in the Payee FSP for a non-disclosing send amount quote, the equation in [Listing 8](#listing-8) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 8 + +``` +Transfer amount = Quote Amount -- Payee FSP Commission +``` + +**Listing 8 -- Relation between transfer amount and quote amount for non-disclosing send amount** + +The reason for a Payee FSP fee to be absent in the equation is that the Payer would like to send a certain amount from their account. The Payee will receive less funds instead of a fee being added on top of the amount. + +#### Disclosing of Fees + +The fees and commission payments related to an interoperable transaction when fees are disclosed can be seen in [Figure 11](#figure-11). The fees and commission that are directly related to the API are marked with green text. Internal Payee fees, bonus, and commission are marked with red text, these will have an implication on the amount that is sent by the Payer and received by the Payee. They are not part of the interoperable transaction between a Payer FSP and a Payee FSP, but the actual amount to be received by the Payee after internal Payee FSP fees have been deducted can be sent for information by the Payee FSP. + +When disclosing of fees are used, the FSP commission that the Payee FSP sends should subsidize the transaction cost for the Payer. This means that any FSP commission sent from the Payee FSP will effectively pay either a part or all of the fees that the Payer FSP has added to the transaction. If the FSP commission amount from the Payee FSP is higher than the actual transaction fees for the Payer, the excess amount should be handled as a fee paid by Payee FSP to Payer FSP. An example of excess FSP commission can be found [here](#excess-fsp-commission-example). + +###### Figure 12 + +![Figure 12](../../assets/diagrams/images/figure12.svg) + +**Figure 12 -- Fees and commission related to interoperability when fees +are disclosed** + +See [Fee Types](#fee-types) for more information on the fee types sent in the Interoperability API. + +#### Disclosing Receive Amount + +[Figure 13](#figure-13) shows an example of disclosing receive amount where the Payer would like the Payee to receive exactly 100 USD. For disclosing receive amount, the Payer FSP must internally rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this example, the Payer FSP would like to have 1 USD in fees from the Payer. The Payee FSP decides to give 1 USD in commission to subsidize the transaction, so that the transaction is free for the Payer. + +###### Figure 13 + +![](../../assets/diagrams/sequence/figure13.svg) + + +**Figure 13 -- Example of disclosing receive amount** + +[Figure 14](#figure-14) shows a simplified view of the movement of money for the disclosing receive amount example. + +###### Figure 14 + +![Figure 14](../../assets/diagrams/images/figure14.svg) + +**Figure 14 -- Simplified view of money movement for disclosing receive amount example** + +To calculate the element **transferAmount** in the Payee FSP for a disclosing receive amount quote, the equation in [Listing 9](#listing-9) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 9 + +``` +Transfer amount = Quote Amount + Payee FSP Fee -- Payee FSP Commission +``` + +**Listing 9 -- Relation between transfer amount and quote amount for disclosing receive amount** + +#### Disclosing Send Amount + +[Figure 15](#figure-15) shows an example of disclosing send amount, where the Payer would like to send 100 USD from the Payer's account to the Payee. For disclosing send amount, the Payer FSP must rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this example, the Payer FSP and the Payee FSP would like to have 1 USD each in fees from the Payer. + +###### Figure 15 + +![](../../assets/diagrams/sequence/figure15.svg) + + +**Figure 15 -- Example of disclosing send amount** + +###### Figure 16 + +[Figure 16](#figure-16) shows a simplified view of the movement of money for the disclosing send amount example. +![Figure 16](../../assets/diagrams/images/figure16.svg) + +**Figure 16 -- Simplified view of money movement for disclosing send amount example** + +To calculate the element **transferAmount** in the Payee FSP for a disclosing send amount quote, the equation in [Listing 10](#listing-10) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), _Payer_ _Fee_ is **fees** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 10 + +``` +If (Payer Fee <= Payee FSP Commission) + Transfer amount = Quote Amount +Else + Transfer amount = Quote Amount -- (Payer Fee - Payee FSP Commission) +``` + +**Listing 10 -- Relation between transfer amount and quote amount for disclosing send amount** + +The reason for a Payee FSP fee to be absent in the equation, is that the Payer would like to send a certain amount from their account. The Payee will receive less funds instead of a fee being added on top of the amount. + +#### Excess FSP Commission Example + +[Figure 17](#figure-17) shows an example of excess FSP commission using disclosing send amount, where the Payer would like to send 100 USD from the Payer's account to the Payee. For disclosing send amount, the Payer FSP must rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this excess commission example, the Payer FSP would like to have 1 USD in fees from the Payer, and the Payee FSP gives 3 USD in FSP commission. Out of the 3 USD in FSP commission, 1 USD should cover the Payer fees, and 2 USD is for the Payer FSP to keep. + +###### Figure 17 + +![](../../assets/diagrams/sequence/figure17.svg) + + +**Figure 17 -- Example of disclosing send amount** + +###### Figure 18 + +[Figure 18](#figure-18) shows a simplified view of the movement of money for the excess commission using disclosing send amount example. + +![Figure 18](../../assets/diagrams/images/figure18.svg) + +**Figure 18 -- Simplified view of money movement for excess commission using disclosing send amount example** + +#### Fee Types + +As can be seen in [Figure 7](#figure-7) and [Figure 12](#figure-12), there are two different fee and commission types in the Quote object between the + +FSPs: + +1. **Payee FSP fee** -- A transaction fee that the Payee FSP would like to have for the handling of the transaction. + +2. **Payee FSP commission** -- A commission that the Payee FSP would like to give to the Payer FSP (non-disclosing of fees) or subsidize the transaction by paying some or all fees from the Payer FSP (disclosing of fees). In case of excess FSP commission, the excess commission should be handled as the Payee FSP pays a fee to the Payer FSP, see [here](#excess-fsp-commission-example) for an example. + +
    + +#### Quote Equations + +This section contains useful equations for quoting that have not already been mentioned. + +#### Payee Receive Amount Relation to Transfer Amount + +The amount that the Payee should receive, excluding any internal Payee FSP fees, bonus, or commission, can be calculated by the Payer FSP using the equation in [Listing 11](#listing-11), where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is payeeFspCommission in [Table 24](#table-24). + +###### Listing 11 + +``` +Payee Receive Amount = Transfer Amount - Payee FSP Fee + Payee FSP Commission +``` + +**Listing 11 -- Relation between transfer amount and Payee receive amount** + +The Payee receive amount including any internal Payee FSP fees can optionally be sent by the Payee FSP to the Payer FSP in the Quote callback, see element **payeeReceiveAmount** in [Table 24](#table-24). +
    + +#### Tax Information + +Tax information is not sent in the API, as all taxes are assumed to be FSP-internal. The following sections contain details pertaining to common tax types related to the API. + +##### Tax on Agent Commission + +Tax on Agent Commission is tax for an _Agent_ as a result of the Agent receiving commission as a kind of income. Either the Agent or its FSP has a relation with the tax authority, depending on how the FSP deployment is set up. As all Agent commissions are FSP-internal, no information is sent through the Interoperability API regarding Tax on Agent Commission. + +##### Tax on FSP Internal Fee + +FSPs could be taxed on FSP internal fees that they receive from the transactions; for example, Payer fees to Payer FSP or Payee fees to Payee FSP. This tax should be handled internally within the FSP and collected by the FSPs because they receive a fee. + +##### Tax on Amount (Consumption tax) + +Examples of tax on amount are VAT (Value Added Tax) and Sales Tax. These types of taxes are typically paid by a Consumer to the Merchant as part of the price of goods, services, or both. It is the Merchant who has a relationship with the tax authority, and forwards the collected taxes to the tax authority. If any VAT or Sales Tax is applicable, a Merchant should include these taxes in the requested amount from the Consumer. The received amount in the Payee FSP should then be taxed accordingly. + +##### Tax on FSP Fee + +In the API, there is a possibility for a Payee FSP to add a fee that the Payer or Payer FSP should pay to the Payee FSP. The Payee FSP should handle the tax internally as normal when receiving a fee (if local taxes apply). This means that the Payee FSP should consider the tax on the fee while rating the financial transaction as part of the quote. The tax is not sent as part of the API. + +##### Tax on FSP Commission + +In the API, there is a possibility for a Payee FSP to add a commission to either subsidize the transaction (if disclosing of fees) or incentivize the Payer FSP (if non-disclosing of fees). + +###### Non-Disclosing of Fees + +For non-disclosing of fees, all FSP commission from the Payee FSP should be understood as the Payer FSP receiving a fee from the Payee FSP. The tax on the received fee should be handled internally within the Payer FSP, similar to the way it is handled in [Tax on FSP Internal Fee](#tax-on-fsp-internal-fee). + +###### Disclosing of Fees + +If the Payee FSP commission amount is less than or equal to the amount of transaction fees originating from the Payer FSP, then the Payee FSP commission should always be understood as being used for covering fees that the Payer would otherwise need to pay. + +If the Payee FSP commission amount is higher than the fees from the Payer FSP, the excess FSP commission should be handled similarly as [Non-Disclosing of Fees](#non-disclosing-of-fees). + +
    + +#### Examples for each Use Case + +This section contains one or more examples for each use case. + +#### P2P Transfer + +A P2P Transfer is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 19](#figure-19) for an example. In this example, the Payer would like the Payee to receive 100 USD. The Payee FSP decides to give FSP commission to the Payer FSP, because the Payee FSP will receive funds into the system. The Payer FSP would also like to have 1 USD in fee from the Payer, so the total fee that the Payer FSP will earn is 2 USD. 99 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 1 USD. + +###### Figure 19 + +![](../../assets/diagrams/sequence/figure19.svg) + + +**Figure 19 -- P2P Transfer example with receive amount** + +###### Simplified View of Money Movement + +###### Figure 20 + +See [Figure 20](#figure-20) for a highly simplified view of the movement of money for the P2P Transfer example. + +![Figure 20](../../assets/diagrams/images/figure20.svg) + +**Figure 20 -- Simplified view of the movement of money for the P2P Transfer example** + +#####Agent-Initiated Cash-In (Send amount) + +[Figure 21](#figure-21) shows an example of an Agent-Initiated Cash-In where send amount is used. The fees are disclosed because the Payee (the customer) would like to know the fees in advance of accepting the Cash-In. In the example, the Payee would like to Cash-In a 100 USD bill using an Agent (the Payer) in the Payer FSP system. The Payer FSP would like to have 2 USD in fees to cover the agent commission. The Payee FSP decides to subsidize the transaction by 2 USD by giving 2 USD in FSP commission to cover the Payer FSP fees. 98 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 2 USD. + +###### Figure 21 + +![](../../assets/diagrams/sequence/figure21.svg) + + +**Figure 21 -- Agent-Initiated Cash-In example with send amount** + +###### Simplified View of Money Movement + +See [Figure 22](#figure-22) for a highly simplified view of the movement of money for the Agent-initiated Cash-In example with send amount. + +###### Figure 22 + +![Figure 22](../../assets/diagrams/images/figure22.svg) + +**Figure 22 -- Simplified view of the movement of money for the Agent-initiated Cash-In with send amount example** + +##### Agent-Initiated Cash-In (Receive amount) + +[Figure 23](#figure-23) shows an example of Agent-Initiated Cash-In where receive amount is used. The fees are disclosed as the Payee (the Consumer) would like to know the fees in advance of accepting the Cash-In. In the example, the Payee would like to Cash-In so that they receive 100 USD using an Agent (the Payer) in the Payer FSP system. The Payer FSP would like to have 2 USD in fees to cover the agent commission; the Payee FSP decides to subsidize the transaction by 1 USD by giving 1 USD in FSP commission to cover 50% of the Payer FSP fees. 99 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 1 USD. + +###### Figure 23 + +![](../../assets/diagrams/sequence/figure23.svg) + + +**Figure 23 -- Agent-initiated Cash-In example with receive amount** + +##### Simplified View of Money Movement + +###### Figure 24 + +See [Figure 24](#figure-24) for a highly simplified view of the movement of money for the Agent-initiated Cash-In example with receive amount. + +![Figure 24](../../assets/diagrams/images/figure24.svg) + +**Figure 24 -- Simplified view of the movement of money for the Agent-initiated Cash-In with receive amount example** + +##### Customer-Initiated Merchant Payment + +A Customer-Initiated Merchant Payment is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 25](#figure-25) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP would not like to charge any fees from the Payer, but 1 USD in an internal hidden fee from the Merchant. The Payer FSP wants 1 USD in fees from the Payer. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 25 + +![](../../assets/diagrams/sequence/figure25.svg) + + +**Figure 25 -- Customer-Initiated Merchant Payment example** + +###### Simplified View of Money Movement + +See [Figure 26](#figure-26) for a highly simplified view of the movement of money for the Customer-Initiated Merchant Payment example. + +###### Figure 26 + +![Figure 26](../../assets/diagrams/images/figure26.svg) + +**Figure 26 -- Simplified view of the movement of money for the Customer-Initiated Merchant Payment example** + +##### Customer-Initiated Cash-Out (Receive amount) + +A Customer-Initiated Cash-Out is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 27](#figure-27) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 102 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 27 + +![](../../assets/diagrams/sequence/figure27.svg) + + +**Figure 27 -- Customer-Initiated Cash-Out example (receive amount)** + +###### Simplified View of Money Movement + +See [Figure 28](#figure-28) for a highly simplified view of the movement of money for the Customer-Initiated Cash-Out with receive amount example. + +###### Figure 28 + +![Figure 28](../../assets/diagrams/images/figure28.svg) + +**Figure 28 -- Simplified view of the movement of money for the Customer-Initiated Cash-Out with receive amount example** + +##### Customer-Initiated Cash-Out (Send amount) + +A Customer-Initiated Cash-Out is typically a receive amount, this +example is shown in [Customer-Initiated Cash-Out](#customer-initiated-cash-out). This section shows an example where send amount is used instead; see [Figure 29](#figure-29) for an example. In the example, the Payer would like to Cash-Out 100 USD from their account. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 99 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 29 + +![](../../assets/diagrams/sequence/figure29.svg) + + +**Figure 29 -- Customer-Initiated Cash-Out example (send amount)** + +###### Simplified View of Money Movement + +See [Figure 30](#figure-30) for a highly simplified view of the movement of money for the Customer-Initiated Cash-Out with send amount example. + +###### Figure 30 + +![Figure 30](../../assets/diagrams/images/figure30.svg) + +**Figure 30 -- Simplified view of the movement of money for the Customer-Initiated Cash-Out with send amount example** + +#### Agent-Initiated Cash-Out + +An Agent-Initiated Cash-Out is typically a receive amount, in which the Payer FSP does not disclose any fees to the Payee FSP. See [Figure 31](#Figure-31) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 102 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 31 + +![](../../assets/diagrams/sequence/figure31.svg) + + +**Figure 31 -- Agent-Initiated Cash-Out example** + +######1 Simplified View of Money Movement + +See [Figure 32](#figure-32) for a highly simplified view of the movement of money for the Agent-Initiated Cash-Out example. + +###### Figure 32 + +![Figure 32](../../assets/diagrams/images/figure32.svg) + +**Figure 32 -- Simplified view of the movement of money for the Agent-Initiated Cash-Out example** + +##### Merchant-Initiated Merchant Payment + +A Merchant-Initiated Merchant Payment is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 33](#figure-33) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP does not want any fees and the Payer FSP would like to have 1 USD in fee. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 33 + +![](../../assets/diagrams/sequence/figure33.svg) + + +**Figure 33 -- Merchant-Initiated Merchant Payment example** + +###### Simplified View of Money Movement + +See [Figure 34](#figure-34) for a highly simplified view of the movement of money for the Merchant-Initiated Merchant Payment example. + +###### Figure 34 + +![Figure 34](../../assets/diagrams/images/figure34.svg) + +**Figure 34 -- Simplified view of the movement of money for the Merchant-Initiated Merchant Payment example** + +##### ATM-Initiated Cash-Out + +An ATM-Initiated Cash-Out is typically a receive amount, in which the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 35](#figure-35) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 1 USD in fees to cover any ATM fees and the Payer FSP would like to have 1 USD in fees. 101 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 35 + +![](../../assets/diagrams/sequence/figure35.svg) + + +**Figure 35 -- ATM-Initiated Cash-Out example** + +###### Simplified View of Money Movement + +See [Figure 36](#figure-36) for a highly simplified view of the movement of money for the ATM-Initiated Cash-Out example. + +###### Figure 36 + +![Figure 36](../../assets/diagrams/images/figure36.svg) + +**Figure 36 -- Simplified view of the movement of money for the ATM-Initiated Cash-Out example** + +##### Merchant-Initiated Merchant Payment authorized on POS + +A Merchant-Initiated Merchant Payment authorized on a POS device is typically a receive amount, in which the Payer FSP does not disclose any fees to the Payee FSP. See [Figure 37](#figure-37) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP decides to give 1 USD in FSP commission, and the Payer FSP decides to use the FSP commission as the transaction fee. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 37 + +![](../../assets/diagrams/sequence/figure37.svg) + + +**Figure 37 -- Merchant-Initiated Merchant Payment authorized on POS example** + +###### Simplified View of Money Movement + +See [Figure 38](#figure-38) for a highly simplified view of the movement of money for the Merchant-Initiated Merchant Payment authorized on POS example. + +###### Figure 38 + +![Figure 38](../../assets/diagrams/images/figure38.svg) + +**Figure 38 -- Simplified view of the movement of money for the +Merchant-Initiated Merchant Payment authorized on POS example** + +##### Refund + +[Figure 39](#figure-39) shows an example of a Refund transaction of the entire amount of the [Agent-Initiated Cash-In (Receive amount)](#agent-initiated-cash-in-receive-amount) example. + +###### Figure 39 + +![](../../assets/diagrams/sequence/figure39.svg) + + +**Figure 39 -- Refund example** + +#### 5.1.6.11.1 Simplified View of Money Movement + +See [Figure 40](#figure-40) for a highly simplified view of the movement of money for the Refund example. + +###### Figure 40 + +![Figure 40](../../assets/diagrams/images/figure40.svg) + +**Figure 40 -- Simplified view of the movement of money for the Refund example** + +
    + +### Party Addressing + +Both Parties in a financial transaction, (that is, the `Payer` and the `Payee`) are addressed in the API by a _Party ID Type_ (element [**PartyIdType**](#partyidtype-element)), a _Party ID_ ([**PartyIdentifier**](#partyidentifier-element)), and an optional _Party Sub ID or Type_ ([PartySubIdOrType](#partysubidortype-element)). Some Sub-Types are pre-defined in the API for personal identifiers ([PersonalIdentifierType](#personalidentifiertype-enum)); for example, for passport number or driver's license number. + +The following are basic examples of how the elements _Party ID Type_ and _Party ID_ can be used: +- To use mobile phone number **+123456789** as the counterparty in a financial transaction, set *Party ID Type* to **MSISDN** and _Party ID_ to **+123456789**. + - Example service to get FSP information: + + **GET /participants/MSISDN/+123456789** + +- To use the email **john\@doe.com** as the counterparty in a financial transaction, set _Party ID Type_ to **EMAIL**, and _Party_ _ID_ to **john\@doe.com**. + + - Example service to get FSP information: + + **GET /participants/EMAIL/john\@doe.com** + +- To use the IBAN account number **SE45 5000 0000 0583 9825 7466** as counterparty in a financial transaction, set _Party_ _ID Type_ to **IBAN**, and _Party ID_ to **SE4550000000058398257466** (should be entered without any whitespace). + + - Example service to get FSP information: + + **GET /participants/IBAN/SE4550000000058398257466** + +The following are more advanced examples of how the elements _Party ID +Type_, _Party ID_, and _Party Sub ID or Type_ can be used: + +- To use the person who has passport number **12345678** as counterparty in a financial transaction, set _Party ID Type_ to **PERSONAL\_ID**, _Party ID_ to **12345678**, and _Party Sub ID or Type_ to **PASSPORT**. + + - Example service to get FSP information: + + **GET /participants/PERSONAL\_ID/123456789/PASSPORT** + +- To use **employeeId1** working in the company **Shoe-company** as counterparty in a financial transaction, set _Party ID_ _Type_ to **BUSINESS**, _Party ID_ to **Shoe-company**, and _Party Sub ID or Type_ to **employeeId1**. + + - Example service to get FSP information: + + **GET /participants/BUSINESS/Shoe-company/employeeId1** + +**5.2.1 Restricted Characters in Party ID and Party Sub ID or Type** + +Because the _Party ID_ and the _Party Sub ID or Type_ are used as part of the URI (see [URI Syntax](#uri-syntax)), some restrictions exist on the ID: + +- Forward slash (**/**) is not allowed in the ID, as it is used by the [Path](#path), to indicate a separation of the Path. + +- Question mark (**?**) is not allowed in the ID, as it is used to indicate the [Query](#query)) part of the URI. + +
    + +### Mapping of Use Cases to Transaction Types + +This section contains information about how to map the currently supported non-bulk use cases in the API to the complex type [**TransactionType**](#transactiontype)), using the elements [TransactionScenario](#transactionscenario)), and [TransactionInitiator](#transactioninitiator)). + +For more information regarding these use cases, see _API Use Cases_. + +#### P2P Transfer + +To perform a P2P Transfer, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **TRANSFER** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER**. + +#### Agent-Initiated Cash In + +To perform an Agent-Initiated Cash In, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **DEPOSIT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT**. + +#### Agent-Initiated Cash Out + +To perform an Agent-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT** + +#### Agent-Initiated Cash Out Authorized on POS + +To perform an Agent-Initiated Cash Out on POS, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT** + + +#### Customer-Initiated Cash Out + +To perform a Customer-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER** + +#### Customer-Initiated Merchant Payment + +To perform a Customer-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER**. + +#### Merchant-Initiated Merchant Payment + +To perform a Merchant-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **BUSINESS** + +#### Merchant-Initiated Merchant Payment Authorized on POS + +To perform a Merchant-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **DEVICE** + +#### ATM-Initiated Cash Out + +To perform an ATM-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **DEVICE** + +#### Refund + +To perform a Refund, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **REFUND** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) depends on the initiator of the Refund. + +Additionally, the [Refund](#refund) complex type must be populated with the transaction ID of the original transaction that is to be refunded. + +
    + +## API Services + +This section introduces and details all services that the API supports for each resource and HTTP method. Each API resource and service is also mapped to a logical API resource and service described in [Generic Transaction Patterns](../generic-transaction-patterns). + + +### High Level API Services + +On a high level, the API can be used to perform the following actions: + +- **Lookup Participant Information** -- Find out in which FSP the counterparty in a financial transaction is located. + + - Use the services provided by the API resource **/participants**. + +- **Lookup Party Information** -- Get information about the counterparty in a financial transaction. + + - Use the services provided by the API resource **/parties**. + +- **Perform Transaction Request** -- Request that a Payer transfer electronic funds to the Payee, at the request of the Payee. The Payer can approve or reject the request from the Payee. An approval of the request will initiate the actual financial transaction. + + - Use the services provided by the API resource **/transactionRequests**. + +- **Calculate Quote** -- Calculate all parts of a transaction that will influence the transaction amount; that is, fees and FSP commission. + + - Use the services provided by the API resource **/quotes** for a single transaction quote; that is, one Payer to one Payee. + - Use the services provided by the API resource **/bulkQuotes** for a bulk transaction quote; that is, one Payer to multiple Payees. + +- **Perform Authorization** -- Request the Payer to enter the applicable credentials when they have initiated the transaction from a POS, ATM, or similar device in the Payee FSP system. + + - Use the services provided by the API resource **/authorizations**. + +- **Perform Transfer** -- Perform the actual financial transaction by transferring the electronic funds from the Payer to the Payee, possibly through intermediary ledgers. + + - Use the services provided by the API resource **/transfers** for single transaction; that is, one Payer to one Payee. + - Use the services provided by the API resource **/bulkTransfers** for bulk transaction; that is, one Payer to multiple Payees. + +- **Retrieve Transaction Information** -- Get information related to the financial transaction; for example, a possible created token on successful financial transaction. + + - Use the services provided by the API resource **/transactions**. + + +#### Supported API services + +[Table 6](#table-6) includes high-level descriptions of the services that the API provides. For more detailed information, see the sections that follow. + +###### Table 6 + +|URI|HTTP method GET|HTTP method PUT|HTTP method POST|HTTP method DELETE|HTTP method PATCH| +|---|---|---|---|---|---| +|**/participants**|Not supported|Not supported|Request that an ALS create FSP information regarding the parties provided in the body or, if the information already exists, request that the ALS update it|Not supported|Not Supported| +|**/participants/**_{ID}_|Not supported|Callback to inform a Peer FSP about a previously-created list of parties.|Not supported|Not Supported|Not Supported| +|**/participants/**_{Type}_/_{ID}_ Alternative: **/participants/**_{Type}_/_{ID}_/_{SubId}_|Get FSP information regarding a Party from either a Peer FSP or an ALS.|Callback to inform a Peer FSP about the requested or created FSP information.|Request an ALS to create FSP information regarding a Party or, if the information already exists, request that the ALS update it|Request that an ALS delete FSP information regarding a Party.|Not Supported| +|**/parties/**_{Type}_/_{ID}_ Alternative: **/parties/**_{Type}_/_{ID}_/_{SubId}_|Get information regarding a Party from a Peer FSP.|Callback to inform a Peer FSP about the requested information about the Party.|Not supported|Not support|Not Supported| +|**/transactionRequests**|Not supported|Not supported|Request a Peer FSP to ask a Payer for approval to transfer funds to a Payee. The Payer can either reject or approve the request.|Not supported|Not Supported| +|**/transactionRequests/**_{ID}_|Get information about a previously-sent transaction request.|Callback to inform a Peer FSP about a previously-sent transaction request.|Not supported|Not supported|Not Supported| +|**/quotes**|Not supported|Not supported|Request that a Peer FSP create a new quote for performing a transaction.|Not supported|Not Supported| +|**/quotes/**_{ID}_|Get information about a previously-requested quote.|Callback to inform a Peer FSP about a previously- requested quote.|Not supported|Not supported|Not Supported| +|**/authorizations/**_{ID}_|Get authorization for a transaction from the Payer whom is interacting with the Payee FSP system.|Callback to inform Payer FSP regarding authorization information.|Not supported|Not supported|Not Supported| +|**/transfers**|Not supported|Not supported|Request a Peer FSP to perform the transfer of funds related to a transaction.|Not supported|Not Supported| +|**/transfers/**_{ID}_|Get information about a previously-performed transfer.|Callback to inform a Peer FSP about a previously-performed transfer.|Not supported|Not supported|Commit notification to Payee FSP| +|**/transactions/**_{ID}_|Get information about a previously-performed transaction.|Callback to inform a Peer FSP about a previously-performed transaction.|Not supported|Not supported|Not Supported| +|**/bulkQuotes**|Not supported|Not supported|Request that a Peer FSP create a new quote for performing a bulk transaction.|Not supported|Not Supported| +|**/bulkQuotes/**_{ID}_|Get information about a previously-requested bulk transaction quote.|Callback to inform a Peer FSP about a previously-requested bulk transaction quote.|Not supported|Not supported|Not Supported| +|**/bulkTransfers**|Not supported|Not supported|Request that a Peer FSP create a bulk transfer.|Not supported|Not Supported| +|**/bulkTransfers/**_{ID}_|Get information about a previously-sent bulk transfer.|Callback to inform a Peer FSP about a previously-sent bulk transfer.|Not supported|Not supported|Not supported| + +**Table 6 – API-supported services** + +#### Current Resource Versions + +[Table 7](#table-7) contains the version for each resource that this document version describes. + +###### Table 7 + +|Resource|Current Version|Last Updated| +|---|---|---| +|/participants|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/parties|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transactionRequests|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/quotes|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/authorizations|1.0|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transfers|1.1|Added possible commit notification using PATCH /transfers/``. The process of using commit notifications is described in Section 6.7.2.6. The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transactions|1.0|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/bulkQuotes|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/bulkTransfers|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 7 – Current resource versions** + +
    + +### API Resource /participants + +This section defines the logical API resource **Participants**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-participants). + +The services provided by the resource **/participants** are primarily used for determining in which FSP a counterparty in a financial transaction is located. Depending on the scheme, the services should be supported, at a minimum, by either the individual FSPs or a common service. + +If a common service (for example, an ALS) is supported in the scheme, the services provided by the resource **/participants** can also be used by the FSPs for adding and deleting information in that system. + +#### Resource Version History + +[Table 8](#table-8) contains a description of each different version of the **/participants** resource. + +###### Table 8 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated. +For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.| + +**Table 8 – Version history for resource /participants** + +#### Service Details + +Different models are used for account lookup, depending on whether an ALS exists. The following sections describe each model in turn. + +#### No Common Account Lookup System + +[Figure 41](#figure-41) shows how an account lookup can be performed if there is no common ALS in a scheme. The process is to ask the other FSPs (in sequence) if they "own" the Party with the provided identity and type pair until the Party can be found. + +If this model is used, all FSPs should support being both client and server of the different HTTP **GET** services under the **/participants** resource. The HTTP **POST** or HTTP **DELETE** services under the **/participants** resource should not be used, as the FSPs are directly used for retrieving the information (instead of a common ALS). + +###### Figure 41 + +![](../../assets/diagrams/sequence/figure41.svg) + + +**Figure 41 -- How to use the services provided by /participants if there is no common Account Lookup System** + +#### Common Account Lookup System + +[Figure 42](#figure-42) shows how an account lookup can be performed if there is a common ALS in a scheme. The process is to ask the common Account Lookup service which FSP owns the Party with the provided identity. The common service is depicted as "Account Lookup" in the flows; this service could either be implemented by the switch or as a separate service, depending on the setup in the market. + +The FSPs do not need to support the server side of the different HTTP **GET** services under the **/participants** resource; the server side of the service should be handled by the ALS. Instead, the FSPs (clients) should provide FSP information regarding its accounts and account holders (parties) to the ALS (server) using the HTTP **POST** (to create or update FSP information, see [POST /participants](#post-participants) and [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id)) and HTTP **DELETE** (to delete existing FSP information, see [DELETE /participants/_{Type}_/_{ID}_](#delete-participantstypeid)) methods. + +###### Figure 42 + +![](../../assets/diagrams/sequence/figure42.svg) + + +**Figure 42 -- How to use the services provided by /participants if there is a common Account Lookup System** + +#### Requests + +This section describes the services that can be requested by a client on the resource **/participants**. + +##### GET /participants/_{Type}_/_{ID}_ + +Alternative URI: **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Lookup Participant Information](../generic-transaction-patterns#lookup-participant-information) + +The HTTP request **GET /participants/**_{Type}_**/**_{ID}_ (or **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to find out in which FSP the requested Party, defined by _{Type}_, _{ID}_ and optionally _{SubId}_, is located (for example, **GET** **/participants/MSISDN/123456789**, or **GET /participants/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +This HTTP request should support a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) for filtering of currency. To use filtering of currency, the HTTP request **GET /participants/**_{Type}_**/**_{ID}_**?currency=**_XYZ_ should be used, where _XYZ_ is the requested currency. + +Callback and data model information for **GET /participants/**_{Type}_**/**_{ID}_ (alternative **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback - [**PUT /participants/**_{Type}_/_{ID}_](#put-participants-type-id) +- Error Callback - [**PUT /participants/**_{Type}_/_{ID}_**/error**](#put-participants-type-iderror) +- Data Model -- Empty body + +##### POST /participants + +Alternative URI: N/A + +Logical API service: [Create Bulk Participant Information](../generic-transaction-patterns#create-bulk-participant-information) + +The HTTP request **POST /participants** is used to create information on the server regarding the provided list of identities. This request should be used for bulk creation of FSP information for more than one Party. The optional currency parameter should indicate that each provided Party supports the currency. + +Callback and data model information for **POST /participants**: + +- Callback -- [**PUT /participants/**_{ID}_](#put-participants-type-id) +- Error Callback -- [**PUT /participants/**_{ID}_ **/error**](#put-participants-type-iderror) +- Data Model -- See [Table 9](#table-9) + +###### Table 9 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**requestId**|1|CorrelationId|The ID of the request, decided by the client. Used for identification of the callback from the server.| +|**partyList**|1..10000|PartyIdInfo|List of PartyIdInfo elements that the client would like to update or create FSP information about.| +|**currency**|0..1|Currency|Indicate that the provided Currency is supported by each PartyIdInfo in the list.| + +**Table 9 - POST /participants data model** + +##### POST /participants/_{Type}_/_{ID}_ + +Alternative URI: **POST /participants/**_{Type}_/_{ID}_/_{SubId}_ + +Logical API service: [Create Participant Information](../generic-transaction-patterns#create-participant-information) + +The HTTP request **POST /participants/**_{Type}_**/**_{ID}_ (or **POST /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to create information on the server regarding the provided identity, defined by _{Type}_, _{ID}_, and optionally _{SubId}_ (for example, **POST** **/participants/MSISDN/123456789** or **POST /participants/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +Callback and data model information for **POST /participants**/_{Type}_**/**_{ID}_ (alternative **POST** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) +- Error Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) +- Data Model -- See [Table 10](#table-10) + +###### Table 10 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**fspId**|1|FspId|FSP Identifier that the Party belongs to.| +|**currency**|0..1|Currency|Indicate that the provided Currency is supported by the Party.| +|**extensionList**| 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 10 -- POST /participants/_{Type}_/_{ID}_ (alternative POST /participants/_{Type}_/_{ID}_/_{SubId}_) data model** + +##### DELETE /participants/_{Type}_/_{ID}_ + +Alternative URI: **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Delete Participant Information](../generic-transaction-patterns#delete-participant-information) + +The HTTP request **DELETE /participants/**_{Type}_**/**_{ID}_ (or **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to delete information on the server regarding the provided identity, defined by _{Type}_ and _{ID}_) (for example, **DELETE** **/participants/MSISDN/123456789**), and optionally _{SubId}_. See [Refund](#refund) for more information regarding addressing of a Party. + +This HTTP request should support a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) to delete FSP information regarding a specific currency only. To delete a specific currency only, the HTTP request **DELETE** **/participants/**_{Type}_**/**_{ID}_**?currency**_=XYZ_ should be used, where _XYZ_ is the requested currency. + +**Note:** The ALS should verify that it is the Party's current FSP that is deleting the FSP information. + +Callback and data model information for **DELETE /participants/**_{Type}_**/**_{ID}_ (alternative **GET** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) + +- Error Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) + +- Data Model -- Empty body + +
    + +#### Callbacks + +This section describes the callbacks used by the server for services provided by the resource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_ + +Alternative URI: **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Return Participant Information](../generic-transaction-patterns#return-participant-information) + +The callback **PUT /participants/**_{Type}_**/**_{ID}_ (or **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to inform the client of a successful result of the lookup, creation, or deletion of the FSP information related to the Party. If the FSP information is deleted, the **fspId** element should be empty; otherwise the element should include the FSP information for the Party. + +See [Table 11](#table-11) for data model. + +###### Table 11 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**fspId**|0..1|FspId|FSP Identifier that the Party belongs to.| + +**Table 11 -- PUT /participants/_{Type}_/_{ID}_ (alternative PUT /participants/_{Type}_/_{ID}_/_{SubId}_) data model** + +##### PUT /participants/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Bulk Participant Information](../generic-transaction-patterns#return-bulk-participant-information) + +The callback **PUT /participants/**_{ID}_ is used to inform the client of the result of the creation of the provided list of identities. + +See [Table 12](#table-12) for data model. + +###### Table 12 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**partyList**|1..10000|PartyResults|List of PartyResult elements that were either created or failed to be created.| +|**currency**|0..1|Currency|Indicate that the provided Currency was set to be supported by each successfully added PartyIdInfo.| + +**Table 12 -- PUT /participants/_{ID}_ data model** + +####Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_/error + +Alternative URI: **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Logical API service: [Return Participant Information Error](../generic-transaction-patterns#return-participant-information-error) + +If the server is unable to find, create or delete the associated FSP of the provided identity, or another processing error occurred, the error callback **PUT /participants/**_{Type}_**/**_{ID}_**/error** (or **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) is used. See [Table 13](#table-13) for data model. + +###### Table 13 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**errorInformation**|1|ErrorInformation|Error code, category description.| + +**Table 13 -- PUT /participants/_{Type}_/_{ID}_/error (alternative PUT /participants/_{Type}_/_{ID}_/_{SubId}_/error) data model** + +##### PUT /participants/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Bulk Participant Information Error](../generic-transaction-patterns#return-bulk-participant-information-error) + +If there is an error during FSP information creation on the server, the error callback **PUT /participants/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **requestId** (see [Table 9](#table-9)) that was used for the creation of the participant information. See [Table 14](#table-14) for data model. + +###### Table 14 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **error Information** | 1 | ErrorInformation | Error code, category description. | + +**Table 14 -- PUT /participants/_{ID}_/error data model** + +#### States + +There are no states defined for the **/participants** resource; either the server has FSP information regarding the requested identity or it does not. + +
    + +### API Resource /parties + +This section defines the logical API resource **Parties,** described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-parties). + +The services provided by the resource **/parties** is used for finding out information regarding a Party in a Peer FSP. + +#### Resource Version History + +[Table 15](#table-15) contains a description of each different version of the **/parties** resource. + +###### Table 15 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 15 – Version history for resource /parties** + +#### Service Details + +[Figure 43](#figure-43) contains an example process for the [**/parties**](../generic-transaction-patterns#api-resource-parties) resource. Alternative deployments could also exist; for example, a deployment in which the Switch and the ALS are in the same server, or one in which the User's FSP asks FSP 1 directly for information regarding the Party. + +###### Figure 43 + +![](../../assets/diagrams/sequence/figure43.svg) + + +**Figure 43 -- Example process for /parties resource** + +
    + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/parties**. + +##### GET /parties/_{Type}_/_{ID}_ + +Alternative URI: **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Lookup Party Information](../generic-transaction-patterns#lookup-party-information) + +The HTTP request **GET /parties/**_{Type}_**/**_{ID}_ (or **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to lookup information regarding the requested Party, defined by _{Type}_, _{ID}_ and optionally _{SubId}_ (for example, **GET /parties/MSISDN/123456789**, or **GET** **/parties/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +Callback and data model information for **GET /parties/**_{Type}_**/**_{ID}_ (alternative **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback - [**PUT /parties/**_{Type}_**/**_{ID}_](#put-partiestypeid) +- Error Callback - [**PUT /parties/**_{Type}_**/**_{ID}_**/error**](#put-partiestypeiderror) +- Data Model -- Empty body + +
    + +#### Callbacks + +This section describes the callbacks that are used by the server for services provided by the resource **/parties**. + +##### PUT /parties/_{Type}_/_{ID}_ + +Alternative URI: **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Return Party Information](../generic-transaction-patterns#return-party-information) + +The callback **PUT /parties/**_{Type}_**/**_{ID}_ (or **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to inform the client of a successful result of the Party information lookup. See [Table 16](#table-16) for data model. + +###### Table 16 + +| **Name** | **Cardinal** | **Type** | **Description** | +| --- | --- | --- | --- | +| **party** | 1 | Party | Information regarding the requested Party. | + +**Table 16 -- PUT /parties/_{Type}_/_{ID}_ (alternative PUT /parties/_{Type}_/_{ID}_/_{SubId}_) data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/parties**. + +#### PUT /parties/_{Type}_/_{ID}_/error + +Alternative URI: **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Logical API service: [Return Party Information Error](../generic-transaction-patterns#return-party-information-error) + +If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback **PUT /parties/**_{Type}_**/**_{ID}_**/error** (or **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) is used. See [Table 17](#table-17) for data model. + +###### Table 17 + +| **Name** | **Cardinality** | **Type** | **Description** | +|---|---|---|---| +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 17 -- PUT /parties/_{Type}_/_{ID}_/error (alternative PUT /parties/_{Type}_/_{ID}_/_{SubId}_/error) data model** + +#### States + +There are no states defined for the **/parties** resource; either an FSP has information regarding the requested identity or it does not. + +
    + +### API Resource /transactionRequests + +This section defines the logical API resource **Transaction Requests**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-transaction-requests). + +The primary service that the API resource **/transactionRequests** enables is for a Payee to request a Payer to transfer electronic funds to the Payee. The Payer can either approve or reject the request from the Payee. The decision by the Payer could be made programmatically if: + +- The Payee is trusted (that is, the Payer has pre-approved the Payee in the Payer FSP), or + +- An authorization value - that is, a _one-time password_ (_OTP_) is correctly validated using the API Resource **/authorizations**, see [Section 6.6](#66-api-resource-authorizations). + +Alternatively, the Payer could make the decision manually. + +#### Resource Version History + +[Table 18](#table-18) contains a description of each different version of the **/transactionRequests** resource. + +###### Table 18 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 18 – Version history for resource /transactionRequests** + +#### Service Details + +[Figure 44](#figure-44) shows how the request transaction process works, using the **/transactionRequests** resource. The approval or rejection is not shown in the figure. A rejection is a callback **PUT /transactionRequests/**_{ID}_ with a **REJECTED** state, similar to the callback in the figure with the **RECEIVED** state, as described in [Section 6.4.2.1](#6421-payer-rejected-transaction-request). An approval by the Payer is not sent as a callback; instead a quote and transfer are sent containing a reference to the transaction request. + +###### Figure 44 + +![](../../assets/diagrams/sequence/figure44.svg) + +**Figure 44 -- How to use the /transactionRequests service** + +##### Payer Rejected Transaction Request + +[Figure 45](#figure-45) shows the process by which a transaction request is rejected. Possible reasons for rejection include: + +- The Payer rejected the request manually. +- An automatic limit was exceeded. +- The Payer entered an OTP incorrectly more than the allowed number of times. + +###### Figure 45 + +![](../../assets/diagrams/sequence/figure45.svg) + +**Figure 45 -- Example process in which a transaction request is rejected** + +#### Requests + +This section describes the services that a client can request on the resource **/transactionRequests**. + +##### GET /transactionRequests/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Transaction Request Information](../generic-transaction-patterns#retrieve-transaction-request-information) + +The HTTP request **GET /transactionRequests/**_{ID}_ is used to get information regarding a previously-created or requested transaction request. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 15](#table-15)) that was used for the creation of the transaction request. + +Callback and data model information for **GET /transactionRequests/**_{ID}_: + +- Callback - [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Error Callback - [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Data Model -- Empty body + +##### POST /transactionRequests + +Alternative URI: N/A + +Logical API service: [Perform Transaction Request](../generic-transaction-patterns#perform-transaction-request) + +The HTTP request **POST /transactionRequests** is used to request the creation of a transaction request for the provided financial transaction on the server. + +Callback and data model information for **POST /transactionRequests**: + +- Callback - [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Error Callback - [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Data Model -- See [Table 19](#table-19) + +###### Table 19 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | CorrelationId | Common ID between the FSPs for the transaction request object, decided by the Payee FSP. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **payee** | 1 | Party | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | PartyInfo | Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| **amount** | 1 | Money | Requested amount to be transferred from the Payer to Payee. | +| **transactionType** | 1 | TransactionType | Type of transaction. | +| **note** | 0..1 | Note | Reason for the transaction request, intended to the Payer. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **authenticationType** | 0.11 | AuthenticationType | OTP or QR Code, otherwise empty. | +| **expiration** | 0..1 | DateTime | Can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, Merchant to know that their request has a time limit. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 19 -- POST /transactionRequests data model** + +####Callbacks + +This section describes the callbacks that are used by the server under the resource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_ + +Alternative URI: N/A + +Logical API service: **Return Transaction Request Information** + +The callback **PUT /transactionRequests/**_{ID}_ is used to inform the client of a requested or created transaction request. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 19](#table-19)) that was used for the creation of the transaction request, or the _{ID}_ that was used in the [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). See [Table 20](#table-20) for data model. + +###### Table 20 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transactionId** | 0..1 | CorrelationId | Identifies a related transaction (if a transaction has been created). | +| **transactionRequestState** | 1 | TransactionRequestState | State of the transaction request. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 20 -- PUT /transactionRequests/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transaction Request Information Error](../generic-transaction-patterns#return-transaction-request-information-error) + +If the server is unable to find or create a transaction request, or another processing error occurs, the error callback **PUT** **/transactionRequests/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 19](#table-19)) that was used for the creation of the transaction request, or the _{ID}_ that was used in the [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). See [Table 21](#table-21) for data model. + +###### Table 21 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | ---| --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 21 -- PUT /transactionRequests/_{ID}_/error data model** + +#### 6.4.6 States + +The possible states of a transaction request can be seen in [Figure 46](#figure-46). + +**Note:** A server does not need to keep transaction request objects that have been rejected in their database. This means that a client should expect that an error callback could be received for a rejected transaction request. + +###### Figure 46 + +![Figure 46](../../assets/diagrams/images/figure46.svg) + +**Figure 46 -- Possible states of a transaction request** + +
    + +### API Resource /quotes + +This section defines the logical API resource **Quotes**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-quotes). + +The main service provided by the API resource **/quotes** is calculation of possible fees and FSP commission involved in performing an interoperable financial transaction. Both the Payer and Payee FSP should calculate their part of the quote to be able to get a total view of all the fees and FSP commission involved in the transaction. + +A quote is irrevocable; it cannot be changed after it has been created. However, it can expire (all quotes are valid only until they reach expiration). + +**Note:** A quote is not a guarantee that the financial transaction will succeed. The transaction can still fail later in the process. A quote only guarantees that the fees and FSP commission involved in performing the specified financial transaction are applicable until the quote expires. + +For more information see [Quoting](#quoting). + +#### Resource Version History + +[Table 22](#table-22) contains a description of each different version of the **/quotes** resource. + +###### Table 22 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 22 – Version history for resource /quotes** + +#### Service Details + +[Figure 47](#figure-47) contains an example process for the API resource **/quotes**. The example shows a Payer Initiated Transaction, but it could also be initiated by the Payee, using the API Resource [**/transactionRequests**](#api-resource-transactionrequests). The lookup process is in that case performed by the Payee FSP instead. + +###### Figure 47 + +![](../../assets/diagrams/sequence/figure47.svg) + + +**Figure 47 -- Example process for resource /quotes** + +#### Quote Expiry Details + +The quote request from the Payer FSP can contain an expiry of the quote, if the Payer FSP would like to indicate when it is no longer useful for the Payee FSP to return a quote. For example, the transaction itself might otherwise time out, or if its quote might time out. + +The Payee FSP should set an expiry of the quote in the callback to indicate when the quote is no longer valid for use by the Payer FSP. + +#### Rejection of Quote + +The Payee FSP can reject a quote request from the Payer FSP by sending the error callback **PUT /quotes/**_{ID}_/**error** instead of the callback **PUT /quotes/**_{ID}_. +Depending on which generic transaction pattern (see Section 8 for more information) that is used, the Payer FSP can reject a quote using one of the following processes: + +- If the transaction is initiated by the Payer (see Section 8.1), the Payer FSP should not inform the Payee FSP regarding the rejection. The created quote at the Payee FSP should have an expiry time, at which time it is automatically deleted. +- If the transaction is initiated by the Payee (see Section 8.2 and 8.3), the Payer FSP should inform the Payee FSP regarding the rejection using the callback **PUT /transactionRequests/**_{ID}_ with a rejected state. The process is described in more detail in Section 6.4.2.1. + +#### Interledger Payment Request + +As part of supporting Interledger and the concrete implementation of the Interledger Payment Request (see [Interledgeer Protocol](#interledger-protocol)), the Payee FSP must: + +- Determine the ILP Address (see [ILP Addressing](#ILP-addressing) for more information) of the Payee and the amount that the Payee will receive. Note that since the **amount** element in the ILP Packet is defined as an UInt64, which is an Integer value, the amount should be multiplied with the currency's exponent (for example, USD's exponent is 2, which means the amount should be multiplied by 102, and JPY's exponent is 0, which means the amount should be multiplied by 100). Both the ILP Address and the amount should be populated in the ILP Packet (see [ILP Packet](#ilp-packet) for more information). + +- Populate the **data** element in the ILP Packet by the [Transaction](#transaction) data model. +- Generate the fulfilment and the condition (see [Conditional Transfers](#conditional-transfers) for more information). Populate the **condition** element in the [PUT /quotes/**_{ID}_](#put-quotes-id)). [Table 19](#table-19) shows data model with the generated condition. + +The fulfilment is a temporary secret that is generated for each financial transaction by the Payee FSP and used as the trigger to commit the transfers that make up an ILP payment. + +The Payee FSP uses a local secret to generate a SHA-256 HMAC of the ILP Packet. The same secret may be used for all financial transactions or the Payee FSP may store a different secret per Payee or based on another segmentation. + +The choice and cardinality of the local secret is an implementation decision that may be driven by scheme rules. The only requirement is that the Payee FSP can determine which secret that was used when the ILP Packet is received back later as part of an incoming transfer (see [API Resource Transfers](#api-resource-transfers)). + +The fulfilment and condition are generated in accordance with the algorithm defined in [Listing 12](#listing-12). Once the Payee FSP has derived the condition, the fulfilment can be discarded as it can be regenerated later. + +###### Listing 12 + +Generation of the fulfilment and condition + +**Inputs:** + +- Local secret (32-byte binary string) +- ILP Packet + +**Algorithm:** + +1. Let the fulfilment be the result of executing the HMAC SHA-256 algorithm on the ILP Packet using the local secret as the key. + +2. Let the condition be the result of executing the SHA-256 hash algorithm on the fulfilment. + +**Outputs:** + +- Fulfilment (32-byte binary string) +- Condition (32-byte binary string) + +**Listing 12 -- Algorithm to generate the fulfilment and the condition** + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/quotes**. + +##### GET /quotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Quote Information](../generic-transaction-patterns#retrieve-quote-information) + +The HTTP request **GET /quotes/**_{ID}_ is used to get information regarding a previously-created or requested quote. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote. + +Callback and data model information for **GET /quotes/**_{ID}_: + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Error Callback -- [**PUT /quotes/**_{ID}_**/_error_**](#put-quotes-iderror) +- Data Model -- Empty body + +##### POST /quotes + +Alternative URI: N/A + +Logical API service: [Calculate Quote Information](../generic-transaction-patterns#calculate-quote-information) + +The HTTP request **POST /quotes** is used to request the creation of a quote for the provided financial transaction on the server. + +Callback and data model information for **POST /quotes**: + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Error Callback -- [**PUT /quotes/**_{ID}_**/error**](#put-quotes-iderror) +- Data Model -- See [Table 23](#table-23) + +###### Table 23 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | CorrelationId | Common ID between the FSPs for the quote object, decided by the Payer FSP. The ID should be reused for resends of the same quote for a transaction. A new ID should be generated for each new quote for a transaction. | +| **transactionId** | 1 | CorrelationId | Common ID (decided by the Payer FSP) between the FSPs for the future transaction object. The actual transaction will be created as part of a successful transfer process. The ID should be reused for resends of the same quote for a transaction. A new ID should be generated for each new quote for a transaction. | +| **transactionRequestId** | 0..1 | CorrelationId | Identifies an optional previously-sent transaction request. | +| **payee** | 1 | Party | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | Party | Information about the Payer in the proposed financial transaction. | +| **amountType** | 1 | AmountType |**SEND** for send amount, **RECEIVE** for receive amount. | +| **amount** | 1 | Money | Depending on **amountType**:
    If **SEND**: The amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.
    If **RECEIVE**: The amount the Payee should receive; that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities.
    | +| **fees** | 0..1 | Money | Fees in the transaction.
  • The fees element should be empty if fees should be non-disclosed.
  • The fees element should be non-empty if fee should be disclosed.
  • | +| **transactionType** | 1 | TransactionType | Type of transaction for which the quote is requested. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **note** | 0..1 | Note | A memo that will be attached to the transaction. | +| **expiration** | 0..1 | DateTime | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, and Merchant to know that their request has a time limit. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 23 -- POST /quotes data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/quotes**. + +#### PUT /quotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Quote Information](../generic-transaction-patterns#return-quote-information) + +The callback **PUT /quotes/**_{ID}_ is used to inform the client of a requested or created quote. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote, or the _{ID}_ that was used in the [**GET /quotes/**_{ID}_](#get-quotesid). See [Table 24](#table-24) for data model. + +###### Table 24 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferAmount** | 1 | Money | The amount of Money that the Payer FSP should transfer to the Payee FSP. | +| **payeeReceiveAmount** | 0..1 | Money | The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | Money | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | Money | Transaction commission from the Payee FSP. | +| **expiration** | 1 | DateTime | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the Payee. Can be used to detect fraud. | +| **ilpPacket** | 1 | IlpPacket | The ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 1 | IlpCondition | The condition that must be attached to the transfer by the Payer. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment | + +**Table 24 -- PUT /quotes/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server +under the resource **/quotes**. + +##### PUT /quotes/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Quote Information Error](../generic-transaction-patterns#return-quote-information-error) + +If the server is unable to find or create a quote, or some other processing error occurs, the error callback **PUT** **/quotes/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote, or the _{ID}_ that was used in the [**GET /quotes/**_{ID}_](#get-quotesid). See [Table 25](#table-25) for data model. + +###### Table 25 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description.| + +**Table 25 -- PUT /quotes/_{ID}_/error data model** + +#### States + +###### Figure 48 + +[Figure 48](#figure-48) contains the UML (Unified Modeling Language) state machine for the possible states of a quote object. + +**Note:** A server does not need to keep quote objects that have been either rejected or expired in their database. This means that a client should expect that an error callback could be received for an expired or rejected quote. + +![Figure 48](../../assets/diagrams/images/figure48.svg) + +**Figure 48 -- Possible states of a quote** + +
    + +### API Resource /authorizations + +This section defines the logical API resource **Authorizations**, described in [Generic Transaction Patterns](../gerneric-transaction-patterns#api-resource-authorizations). + +The API resource **/authorizations** is used to request the Payer to enter the applicable credentials in the Payee FSP system for approving the financial transaction, when the Payer has initiated the transaction from a POS, ATM, or similar, in the Payee FSP system and would like to authorize by an OTP. + +#### Resource Version History + +[Table 26](#table-26) contains a description of each different version of the **/authorizations** resource. + +###### Table 26 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| + +**Table 26 – Version history for resource /authorizations** + +#### Service Details + +[Figure 49](#figure-49) contains an example process for the API resource **/authorizations.** The Payee FSP first sends a [transaction request](#api-resource-transactionrequests)) that is authorized using OTP. The Payer FSP then performs the quoting process (see [API Resource Quotes](#api-resource-quotes)) before an authorization request is sent to the Payee FSP system for the Payer to approve by entering the OTP. If the OTP is correct, the transfer process should be initiated (see [API Resource Transfers](#api-resource-transfers)). + +###### Figure 49 + +![](../../assets/diagrams/sequence/figure49.svg) + + +**Figure 49 -- Example process for resource /authorizations** + +#### Resend Authorization Value + +If the notification containing the authorization value fails to reach the Payer, the Payer can choose to request a resend of the authorization value if the POS, ATM, or similar device supports such a request. See [Figure 50](#figure-50) for an example of a process where the Payer requests that the OTP be resent. + +###### Figure 50 + +![](../../assets/diagrams/sequence/figure50.svg) + + +**Figure 50 -- Payer requests resend of authorization value (OTP)** + +##### Retry Authorization Value + +The Payer FSP must decide the number of times a Payer can retry the authorization value in the POS, ATM, or similar device. This will be set in the **retriesLeft** query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) of the [**GET** **/authorizations/**_{ID}_](#get-authorizationsid) service for more information. If the Payer FSP sends retriesLeft=1, this means that it is the Payer's last try of the authorization value. See [Figure 51](#figure-51) for an example process where the Payer enters the incorrect OTP, and the **retriesLeft** value is subsequently decreased. + +###### Figure 51 + +![](../../assets/diagrams/sequence/figure51.svg) + + +**Figure 51 -- Payer enters incorrect authorization value (OTP)** + +##### Failed OTP authorization + +If the user fails to enter the correct OTP within the number of allowed retries, the process described in [Payer Rejected Transaction Request](#payer-rejected-transaction-request) is performed. + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/authorizations**. + +##### GET /authorizations/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Perform Authorization](../generic-transaction-patterns#perform-authorization) + +The HTTP request **GET /authorizations/**_{ID}_ is used to request the Payer to enter the applicable credentials in the Payee FSP system. The _{ID}_ in the URI should contain the **transactionRequestID** (see [Table 15](#table-15)), received from the [**POST** **/transactionRequests**](#post-transactionrequests)) service earlier in the process. + +This request requires a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) to be included in the URI, with the following key-value pairs: + +- **authenticationType=**_{Type}_, where _{Type}_ value is a valid authentication type from the enumeration [AuthenticationType](#authenticationtype). +- **retriesLeft=**_{NrOfRetries}_, where _{NrOfRetries}_ is the number of retries left before the financial transaction is rejected. _{NrOfRetries}_ must be expressed in the form of the data type [Integer](#integer)). **retriesLeft=1** means that this is the last retry before the financial transaction is rejected. +- **amount=**_{Amount}_, where _{Amount}_ is the transaction amount that will be withdrawn from the Payer's account. _{Amount}_ must be expressed in the form of the data type [Amount](#amount). +- **currency=**_{Currency}_, where _{Currency}_ is the transaction currency for the amount that will be withdrawn from the Payer's account. The _{Currency}_ value must be expressed in the form of the enumeration [CurrencyCode](#currencycode)). + +An example URI containing all the required key-value pairs in the query string is the following: + +**GET /authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD** + +Callback and data model information for **GET /authorization/**_{ID}_: + +- Callback - [**PUT /authorizations/**_{ID}_](#6641-put-authorizationsid) +- Error Callback - [**PUT /authorizations/**_{ID}_**/error**](#6651-put-authorizationsiderror) +- Data Model -- Empty body + +#### 6.6.4 Callbacks + +This section describes the callbacks that are used by the server under the resource **/authorizations**. + +#### 6.6.4.1 PUT /authorizations/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Authorization Result](../generic-transaction-patterns#return-authorization-result) + +The callback **PUT /authorizations/** _{ID}_ is used to inform the client of the result of a previously-requested authorization. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /authorizations/**_{ID}_](#get-authorizationsid). **See** [Table 27](#table-27) **for** data model. + +###### Table 27 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **authenticationInfo** | 0..1 | AuthenticationInfo | OTP or QR Code if entered, otherwise empty. | +| **responseType** | 1 | AuthorizationResponse | Enum containing response information; if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value. | + +**Table 27 – PUT /authorizations/{ID} data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/authorizations**. + +#### PUT /authorizations/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Authorization Error](../generic-transaction-patterns#return-authorization-error) + +If the server is unable to find the transaction request, or another processing error occurs, the error callback **PUT** **/authorizations/**_{ID}_ **/error** is used. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /authorizations/**_{ID}_](#get-authorizationsid). **See** [Table 28](#table-28) **for** data model. + +###### Table 28 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description | + +**Table 28 -- PUT /authorizations/_{ID}_/error data model** + +#### States + +There are no states defined for the **/authorizations** resource. + +
    + +### API Resource /transfers + +This section defines the logical API resource **Transfers**, described in [Generic Transaction Patterns](../generic-transation-patterns#api-resource-transfers). + +The services provided by the API resource **/transfers** are used for performing the hop-by-hop ILP transfer or transfers, and to perform the end-to-end financial transaction by sending the transaction details from the Payer FSP to the Payee FSP. The transaction details are sent as part of the transfer data model in the ILP Packet. + +The Interledger protocol assumes that the setup of a financial transaction is achieved using an end-to-end protocol, but that an ILP transfer is implemented on the back of hop-by-hop protocols between FSPs connected to a common ledger. In the current version of the API, the API Resource **/quotes** performs the setup of the financial transaction. Before a transfer can be performed, the quote must be performed to setup the financial transaction. See [API Resource Quotes](#api-resource-quotes) for more information. + +An ILP transfer is exchanged between two account holders on either side of a common ledger. It is usually expressed in the form of a request to execute a transfer on the common ledger and a notification to the recipient of the transfer that the transfer has been reserved in their favor, including a condition that must be fulfilled to commit the transfer. + +When the Payee FSP presents the fulfilment to the common ledger, the transfer is committed in the common ledger. At the same time, the Payer FSP is notified that the transfer has been committed along with the fulfilment. + +#### Resource Version History + +Table 29 contains a description of each different version of the **/transfers** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The resource is updated to support commit notifications using HTTP Method **PATCH**. The new request **PATCH /transfers/{ID}** is described in Section 6.7.3.3. The process of using commit notifications is described in Section 6.7.2.6.

    The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: [https://github.com/mojaloop/mojaloop-specification/issues/30](https://github.com/mojaloop/mojaloop-specification/issues/30). Following this, the data model as specified in Table 93 has been updated.| + +**Table 29 –- Version history for resource /transfers** + +#### Service Details + +This section provides details regarding hop-by-hop transfers and end-to-end financial transactions. + +#### Process + +[Figure 52](#figure-52) shows how the transaction process works using the **POST /transfers** service. + +###### Figure 52 + +![](../../assets/diagrams/sequence/figure52.svg) + + +**Figure 52 -- How to use the POST /transfers service** + +#### Transaction Irrevocability + +The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions. + +As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using **POST /transfers** including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer's expiry time is exceeded before the Payee FSP responds (see [Expired Quote](#expired-quote) and [Client Receiving Expired Transfer](#client-receiving-expired-transfer) for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties. + +#### Expired Quote + +If a server receives a transaction that is using an expired quote, the server should reject the transfer or transaction. + +#### Timeout and Expiry + +The Payer FSP must always set a transfer expiry time to allow for use cases in which a swift completion or failure is needed. If the use case does not require a swift completion, a longer expiry time can be set. If the Payee FSP fails to respond before the expiry time, the transaction is cancelled in the Payer FSP. The Payer FSP should still expect a callback from the Payee FSP. + +Short expiry times are often required in retail scenarios, in which a customer may be standing in front of a merchant; both parties need to know if the transaction was successful before the goods or services are given to the customer. + +In [Figure 52](#figure-52), an expiry has been set to 30 seconds from the current time in the request from the Payer FSP, and to 20 seconds from the same time in the request from the Switch to the Payee FSP. This strategy of using shorter timeouts for each entity in the chain from Payer FSP to Payee FSP should always be used to allow for extra communication time. + +**Note:** It is possible that a successful callback might be received in the Payer FSP after the expiry time; for example, due to congestion in the network. The Payer FSP should allow for some extra time after the actual expiry time before cancelling the financial transaction in the system. If a successful callback is received after the financial transaction has been cancelled, the transaction should be marked for reconciliation and handled separately in a reconciliation process. + +#### Client Receiving Expired Transfer + +[Figure 53](#figure-53) shows an example of a possible error scenario connected to expiry and timeouts. For some reason, the callback from the Payee FSP takes longer time to send than the expiry time in the optional Switch. This leads to the Switch cancelling the reserved transfer, and an error callback for the transfer is sent to the Payer FSP. Now the Payer FSP and the Payee FSP have two different views of the result of the financial transaction; the transaction should be marked for reconciliation. + +###### Figure 53 + +![](../../assets/diagrams/sequence/figure53.svg) + + +**Figure 53 -- Client receiving an expired transfer** + +To limit these kinds of error scenarios, the clients (Payer FSP and optional Switch in [Figure 52](#figure-52)) participating in the ILP transfer should allow some extra time after actual expiry time during which the callback from the server can be received. The client(s) should also query the server after expiry, but before the end of the extra time, if any callback from the server has been lost due to communication failure. Reconciliation could still be necessary though, even with extra time allowed and querying the server for the transaction. + +#### Commit Notification + +As an alternative option to avoid the error scenario described in [Client Receiving Expired Transfer](#client-receiving-expired-transfer) for use cases where it is complicated to perform a refund, a Payee FSP can (if the scheme allows it) reserve the transfer and then wait for a subsequent commit notification from the Switch. To request a commit notification instead of committing directly is a business decision made by the Payee FSP (if the scheme allows it), based on the context of the transaction. For example, a Cash Out or a Merchant Payment transaction can be understood as a higher-risk transaction, because it is not possible to reverse a transaction if the customer is no longer present; a P2P Transfer can be understood as lower risk because it is easier to reverse by refunding the transaction to the customer. +To request a commit notification from the Switch, the Payee FSP must mark the transfer state (see Section 6.7.6) as reserved instead of committed in the **PUT /transfers/**_{ID}_ callback. Based on the transfer state, the Switch should then perform the following: + +- If the transfer is committed, the Switch should not send a commit notification as the Payee FSP has already accepted the risk that the transfer in some rare cases might fail. This is the default way of committing, shown in [Process](#process). +- If the transfer is reserved, the Switch must send a commit notification to the Payee FSP when the transfer is completed (committed or aborted). + +The commit notification is sent in the request **PATCH /transfers/**_{ID}_ from the Switch to the Payee FSP. If the Payee FSP does not get a commit notification from the Switch within a reasonable time, the Payee FSP should resend the **PUT /transfers/**_{ID}_ callback to the Switch. The Payee FSP needs to receive the commit notification from the Switch before committing the transfer, or accept the risk that the transfer in the Switch might have failed. The Payee FSP is not allowed to rollback the transfer without receiving an aborted state (see Section 6.7.6) from the Switch, as the Payee FSP has sent the fulfilment (which is the commit trigger) to the Switch. +[Figure 54](#figure-54) shows an example where a commit notification is requested by the Payee FSP. In this example the commit was successful in the Switch. + +###### Figure 54 + +![](../../assets/diagrams/sequence/figure54.svg) + + +**Figure 54 -- Commit notification where commit of transfer was successful in Switch** + +[Figure 55](#figure-55) shows an example in which the commit in the Switch failed due to some reason, for example the expiry time had expired in the Switch due to network issues. This is the same example as in [Figure 53](#figure-53), but where no reconciliation is needed as the Payee FSP receives a commit notification before performing the actual transfer to the Payee. + +###### Figure 55 + +![](../../assets/diagrams/sequence/figure55.svg) + + +**Figure 55 -- Commit notification where commit of transfer in Switch failed** + +#### Refunds + +Instead of supporting reversals, the API supports refunds. To refund a transaction using the API, a new transaction should be created by the Payee of the original transaction. The new transaction should revers the original transaction (either the full amount or a partial amount); for example, if customer X sent 100 USD to merchant Y in the original transaction, a new transaction where merchant Y sends 100 USD to customer X should be created. There is a specific transaction type to indicate a refund transaction; for example, if the quote of the transaction should be handled differently than any other type of transaction. The original transaction ID should be sent as part of the new transaction for informational and reconciliation purposes. + +#### Interledger Payment Request + +As part of supporting Interledger and the concrete implementation of the Interledger Payment Request (see [Interledger Protocol](#interledger-protocol)), the Payer FSP must attach the ILP Packet, the condition, and an expiry to the transfer. The condition and the ILP Packet are the same as those sent by the Payee FSP in the callback of the quote; see [Interledger Payment Request](#interledger-payment-request) section for more information. + +The end-to-end ILP payment is a chain of one or more conditional transfers that all depend on the same condition. The condition is provided by the Payer FSP when it initiates the transfer to the next ledger. + +The receiver of that transfer parses the ILP Packet to get the Payee ILP Address and routes the ILP payment by performing another transfer on the next ledger, attaching the same ILP Packet and condition and a new expiry that is less than the expiry of the incoming transfer. + +When the Payee FSP receives the final incoming transfer to the Payee account, it extracts the ILP Packet and performs the following steps: + +1. Validates that the Payee ILP Address in the ILP Packet corresponds to the Payee account that is the destination of the transfer. +2. Validates that the amount in the ILP Packet is the same as the amount of the transfer and directs the local ledger to perform a reservation of the final transfer to the Payee account (less any hidden receiver fees, see [Quoting](#quoting)). +3. If the reservation is successful, the Payee FSP generates the fulfilment using the same algorithm that was used when generating the condition sent in the callback of the quote (see [Interledger Payment Request](#interledger-payment-request)). +4. The fulfilment is submitted to the Payee FSP ledger to instruct the ledger to commit the reservation in favor of the Payee. The ledger will validate that the SHA-256 hash of the fulfilment matches the condition attached to the transfer. If it does, it commits the reservation of the transfer. If not, it rejects the transfer and the Payee FSP rejects the payment and cancels the previously-performed reservation. + +The fulfilment is then passed back to the Payer FSP through the same ledgers in the callback of the transfer. As funds are committed on each ledger after a successful validation of the fulfilment, the entity that initiated the transfer will be notified that the funds it reserved have been committed and the fulfilment will be shared as part of that notification message. + +The final transfer to be committed is the transfer on the Payer FSP's ledger where the reservation is committed from their account. At this point the Payer FSP notifies the Payer of the successful financial transaction. + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/transfers**. + +##### GET /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Authorization Result](../generic-transaction-patterns#return-authorization-result) + +The HTTP request **GET /transfers/**_{ID}_ is used to get information regarding a previously-created or requested transfer. The _{ID}_ in the URI should contain the **transferId** (see [Table 23](#table-23)) that was used for the creation of the transfer. + +Callback and data model information for **GET /transfer/**_{ID}_: + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Error Callback -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Data Model -- Empty body + +##### POST /transfers + +Alternative URI: N/A + +Logical API service: [Perform Transfer](../generic-transaction-patterns#perform-transfer) + +The HTTP request **POST /transfers** is used to request the creation of a transfer for the next ledger, and a financial transaction for the Payee FSP. + +Callback and data model information for **POST /transfers**: + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Error Callback -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Data Model -- See [Table 30](#table-30) + +###### Table 30 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1| CorrelationId | The common ID between the FSPs and the optional Switch for the transfer object, decided by the Payer FSP. The ID should be reused for resends of the same transfer. A new ID should be generated for each new transfer. | +| **payeeFsp** | 1 | FspId | Payee FSP in the proposed financial transaction. | +| **payerFsp** | 1 | FspId | Payer FSP in the proposed financial transaction. | +| **amount** | 1 | Money | The transfer amount to be sent. | +| **ilpPacket** | 1 | IlpPacket | The ILP Packet containing the amount delivered to the Payee and the ILP Address of the Payee and any other end-to-end data. | +| **condition** | 1 | IlpCondition | The condition that must be fulfilled to commit the transfer. | +| **expiration** | 1 | DateTime | Expiration can be set to get a quick failure expiration of the transfer. The transfer should be rolled back if no fulfilment is delivered before this time. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 30 – POST /transfers data model** + +##### PATCH /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Commit Notiifcation](../generic-transaction-patterns#commit-notification) + +The HTTP request **PATCH /transfers/**_{ID}_ is used by a Switch to update the state of an earlier reserved transfer, if the Payee FSP has requested a commit notification when the Switch has completed processing of the transfer. The _{ID}_ in the URI should contain the transferId (see Table 30) that was used for the creation of the transfer. Please note that this request does not generate a callback. See Table 31 for data model. + +###### Table 31 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 1| DateTime | Time and date when the transaction was completed | +| **transferState** | 1 | TransferState | State of the transfer | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 31 –- PATCH /transfers/_{ID}_ data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/transfers**. + +##### PUT /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Transfer Information](../generic-transaction-patterns#return-transfer-information) + +The callback **PUT /transfers/**_{ID}_ is used to inform the client of a requested or created transfer. The _{ID}_ in the URI should contain the **transferId** (see [Table 30](#table-30)) that was used for the creation of the transfer, or the _{ID}_ that was used in the [**GET** **/transfers/**_{ID}_](#6731-get-transfersid). **See** [Table 32](#table-32) **for** data model. + +**Note**: For **PUT /transfers/**_{ID}_ callbacks, the state ABORTED is not a valid enumeration option as **transferState** in Table 32. If a transfer is to be rejected, then the FSP making the callback should use an error callback, i.e., a callback on the /error endpoint. At the same time, it should be noted that a **transferState** value ‘ABORTED’ is valid for a callback to a **GET /transfers/**_{ID}_ call. + +###### Table 32 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **fulfilment** | 0..1 | IlpFulfilment | Fulfilment of the condition specified with the transaction. Mandatory if transfer has completed successfully. | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the transaction was completed | +| **transferState** | 1 | TransferState | State of the transfer | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment | + +**Table 32 -- PUT /transfers/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transfers**. + +##### PUT /transfers/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transfer Information Error](../generic-transaction-patterns#return-transfer-information-error) + +If the server is unable to find or create a transfer, or another processing error occurs, the error callback **PUT** + +**/transfers/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **transferId** (see [Table 30](#table-30)) that was used for the creation of the transfer, or the _{ID}_ that was used in the [**GET /transfers/**_{ID}_](#6731-get-transfersid). See [Table 33](#table-33) for data model. + +###### Table 33 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 33 -- PUT /transfers/_{ID}_/error data model** + +**6.7.6 States** + +###### Figure 56 + +The possible states of a transfer can be seen in [Figure 56](#figure-56). + +![Figure 56](../../assets/diagrams/images/figure56.svg) + +**Figure 56 -- Possible states of a transfer** + +
    + + +### API Resource /transactions + +This section defines the logical API resource **Transactions**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-transactions). + +The services provided by the API resource **/transactions** are used for getting information about the performed end-to-end financial transaction; for example, to get information about a possible token that was created as part of the transaction. + +The actual financial transaction is performed using the services provided by the API Resource [**/transfers**](#67-api-resource-transfers), which includes the end-to-end financial transaction between the Payer FSP and the Payee FSP. + +#### Resource Version History + +[Table 34](#table-34) contains a description of each different version of the **/transactions** resource. + +###### Table 34 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| + +**Table 34 – Version history for resource /transactions** + +#### Service Details + +[Figure 57](#figure-57) shows an example for the transaction process. The actual transaction will be performed as part of the transfer process. The service **GET /transactions/**_{TransactionID}_ can then be used to get more information about the financial transaction that was performed as part of the transfer process. + +###### Figure 57 + +![](../../assets/diagrams/sequence/figure57.svg) + + +**Figure 57 -- Example transaction process** + +#### Requests + +This section describes the services that can be requested by a client on the resource **/transactions**. + +##### GET /transactions/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Transaction Information](../generic-transaction-patterns#retrieve-transaction-information) + +The HTTP request **GET /transactions/**_{ID}_ is used to get transaction information regarding a previously-created financial transaction. The _{ID}_ in the URI should contain the **transactionId** that was used for the creation of the quote (see [Table 23](#table-23)), as the transaction is created as part of another process (the transfer process, see [API Resource Transfers](#api-resource-transfers)). + +Callback and data model information for **GET /transactions/**_{ID}_: + +- Callback -- [**PUT /transactions/**_{ID}_](#put-transactionsid) +- Error Callback -- [**PUT /transactions/**_{ID}_**/error**](#put-transactionsiderror) +- Data Model -- Empty body + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/transactions**. + +##### PUT /transactions/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Transaction Information](../generic-transaction-patterns#return-transaction-information) + +The callback **PUT /transactions/**_{ID}_ is used to inform the client of a requested transaction. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /transactions/**_{ID}_](#get-transactionsid). See [Table 35](#table-35) for data model. + +###### Table 35 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the transaction was completed. | +| **transactionState** | 1 | TransactionState | State of the transaction. | +| **code** | 0..1 | Code | Optional redemption information provided to Payer after transaction has been completed. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 35 -- PUT /transactions/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transactions**. + +##### PUT /transactions/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transaction Information Error](../generic-transaction-patterns#retrieve-transaction-information-error) + +If the server is unable to find or create a transaction, or another processing error occurs, the error callback **PUT** **/transactions/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /transactions/**_{ID}_](#get-transactionsid). See [Table 36](#table-36) for data model. + +###### Table 36 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 36 -- PUT /transactions/_{ID}_/error data model** + +#### States + +###### Figure 58 + +The possible states of a transaction can be seen in [Figure 58](#figure-58). + +**Note:** For reconciliation purposes, a server must keep transaction objects that have been rejected in its database for a scheme-agreed time period. This means that a client should expect a proper callback about a transaction (if it has been received by the server) when requesting information regarding the same. + +![Figure 58](../../assets/diagrams/images/figure58.svg) + +**Figure 58 -- Possible states of a transaction** + +
    + +### API Resource /bulkQuotes + +This section defines the logical API resource **Bulk Quotes**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-bulk-quotes). + +The services provided by the API resource **/bulkQuotes** service are used for requesting the creation of a bulk quote; that is, a quote for more than one financial transaction. For more information regarding a single quote for a transaction, see API Resource [/quotes](#api-resource-quotes). + +A created bulk quote object contains a quote for each individual transaction in the bulk in a Peer FSP. A bulk quote is irrevocable; it cannot be changed after it has been created However, it can expire (all bulk quotes are valid only until they reach expiration). + +**Note:** A bulk quote is not a guarantee that the financial transaction will succeed. The bulk transaction can still fail later in the process. A bulk quote only guarantees that the fees and FSP commission involved in performing the specified financial transaction are applicable until the bulk quote expires. + +#### Resource Version History + +Table 37 contains a description of each different version of the **/bulkQuotes** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 37 –- Version history for resource /bulkQuotes** + +#### Service Details + +[Figure 59](#figure-59) shows how the bulk quotes process works, using the **POST /bulkQuotes** service. When receiving the bulk of transactions from the Payer, the Payer FSP should: + +1. Lookup the FSP in which each Payee is; for example, using the API Resource [/participants](#api-resource-participants). + +2. Divide the bulk based on Payee FSP. The service **POST /bulkQuotes** is then used for each Payee FSP to get the bulk quotes from each Payee FSP. Each quote result will contain the ILP Packet and condition (see [ILP Packet](#ilp-packet) and [Conditional Transfers](#conditional-transfers)) needed to perform each transfer in the bulk transfer (see API Resource [/bulkTransfers](#api-resource-bulktransfers)), which will perform the actual financial transaction from the Payer to each Payee. + +###### Figure 59 + +![](../../assets/diagrams/sequence/figure59.svg) + + +**Figure 59 -- Example bulk quote process** + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/bulkQuotes**. + +##### GET /bulkQuotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Quote Information](../generic-transaction-patterns#retrieve-bulk-quote-information) + +The HTTP request **GET /bulkQuotes/**_{ID}_ is used to get information regarding a previously-created or requested bulk quote. + +The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote. + +Callback and data model information for **GET /bulkQuotes/**_{ID}_: + +- Callback -- [PUT /bulkQuotes/**_{ID}_](#put-bulkquotesid) +- Error Callback -- [PUT /bulkQuotes/**_{ID}_**/error**](#put-bulkquotesiderror) +- Data Model -- Empty body + +##### POST /bulkQuotes + +Alternative URI: N/A + +Logical API service: **Calculate Bulk Quote** + +The HTTP request **POST /bulkQuotes** is used to request the creation of a bulk quote for the provided financial transactions on the server. + +Callback and data model information for **POST /bulkQuotes**: + +- Callback -- [**PUT /bulkQuotes/**_{ID}_](#6941-put-bulkquotesid) +- Error Callback -- [**PUT /bulkQuotes/**_{ID}_**/error**](#6951-put-bulkquotesiderror) +- Data Model -- See [Table 38](#table-38) + +###### Table 38 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | CorrelationId | Common ID between the FSPs for the bulk quote object, decided by the Payer FSP. The ID should be reused for resends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **payer** | 1 | Party | Information about the Payer in the proposed financial transaction. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **expiration** | 0..1 | DateTime | Expiration is optional to let the Payee FSP know when a quote no longer needs to be returned. | +| **individualQuotes** | 1..1000 | IndividualQuote | List of quotes elements. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 38 -- POST /bulkQuotes data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Bulk Quote Information](../generic-transaction-patterns#return-bulk-quote-information) + +The callback **PUT /bulkQuotes/**_{ID}_ is used to inform the client of a requested or created bulk quote. The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote, or the _{ID}_ that was used in the [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). See [Table 39](#table-39) for data model. + +###### Table 39 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **individualQuoteResults** | 0..1000 | IndividualQuoteResult | Fees for each individual transaction, if any of them are charged per transaction. | +| **expiration** | 1 | DateTime | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction request. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 39 -- PUT /bulkQuotes/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Quote Information Error](../generic-transaction-patterns#retrieve-bulk-quote-information-error) + +If the server is unable to find or create a bulk quote, or another processing error occurs, the error callback **PUT** **/bulkQuotes/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote, or the _{ID}_ that was used in the [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). See [Table 40](#table-40) for data model. + +###### Table 40 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 40 -- PUT /bulkQuotes/_{ID}_/error data model** + +#### States + +###### Figure 60 + +The possible states of a bulk quote can be seen in [Figure 60](#figure-60). + +**Note:** A server does not need to keep bulk quote objects that have been either rejected or expired in their database. This means that a client should expect that an error callback could be received for a rejected or expired bulk quote. + +![Figure 60](../../assets/diagrams/images/figure60.svg) + +**Figure 60 -- Possible states of a bulk quote** + +
    + +### API Resource /bulkTransfers + +This section defines the logical API resource **Bulk Transfers**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-bulk-transfers). + +The services provided by the API resource **/bulkTransfers** are used for requesting the creation of a bulk transfer or for retrieving information about a previously-requested bulk transfer. For more information about a single transfer, see API Resource [/transfers](#api-resource-transfers). Before a bulk transfer can be requested, a bulk quote needs to be performed. See API Resource [/bulkQuotes](#api-resource-bulkquotes), for more information. + +A bulk transfer is irrevocable; it cannot be changed, cancelled, or reversed after it has been sent from the Payer FSP. + +#### Resource Version History + +Table 41 contains a description of each different version of the **/bulkTransfers** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 41 –- Version history for resource /bulkTransfers** + +#### Service Details + +[Figure 61](#figure-61) shows how the bulk transfer process works, using the **POST /bulkTransfers** service. When receiving the bulk transactions from the Payer, the Payer FSP should perform the following: + +1. Lookup the FSP in which each Payee is; for example, using the API Resource **/participants**, [Section 6.2](#62-api-resource-participants). +2. Perform the bulk quote process using the API Resource **/bulkQuotes**, [Section 6.9](#69-api-resource-bulkquotes). The bulk quote callback should contain the required ILP Packets and conditions needed to perform each transfer. +3. Perform bulk transfer process in [Figure 61](#figure-61) using **POST /bulkTransfers**. This performs each hop-to-hop transfer and the end-to-end financial transaction. For more information regarding hop-to-hop transfers vs end-to-end financial transactions, see [Section 6.7](#67-api-resource-transfers). + +###### Figure 61 + +![](../../assets/diagrams/sequence/figure61.svg) + + +**Figure 61 -- Example bulk transfer process** + +#### Requests + +This section describes the services that can a client can request on the resource **/bulkTransfers**. + +##### GET /bulkTransfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +The HTTP request **GET /bulkTransfers/**_{ID}_ is used to get information regarding a previously-created or requested bulk transfer. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer. + +Callback and data model information for **GET /bulkTransfers/**_{ID}_: + +- Callback -- [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Error Callback -- [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Data Model -- Empty body + +##### POST /bulkTransfers + +Alternative URI: N/A + +Logical API service: [Perform Bulk Transfer](../generic-transaction-patterns#perform-bulk-transfer) + +The HTTP request **POST /bulkTransfers** is used to request the creation of a bulk transfer on the server. + +- Callback - [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Error Callback - [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Data Model -- See [Table 42](#table-42) + +###### Table 42 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | CorrelationId | Common ID between the FSPs and the optional Switch for the bulk transfer object, decided by the Payer FSP. The ID should be reused for resends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **bulkQuoteId** | 1 | CorrelationId | ID of the related bulk quote | +| **payeeFsp** | 1 | FspId | Payee FSP identifier. | +| **payerFsp** | 1 | FspId | Payer FSP identifier. | +| **individualTransfers** | 1..1000 | IndividualTransfer | List of IndividualTransfer elements. | +| **expiration** | 1 | DateTime | Expiration time of the transfers. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 42 -- POST /bulkTransfers data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +The callback **PUT /bulkTransfers/**_{ID}_ is used to inform the client of a requested or created bulk transfer. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer ([POST /bulkTransfers](#post-bulktransfers)), or the _{ID}_ that was used in the [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). See [Table 43](#table-43) for data model. + +###### Table 43 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the bulk transaction was completed. | +| **individualTransferResults** | 0..1000 | **Error! Reference source not found.** | List of **Error! Reference source not found.** elements. | +| **bulkTransferState** | 1 | BulkTransferState | The state of the bulk transfer. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 43 -- PUT /bulkTransfers/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information Eerror](../generic-transaction-patterns#retrieve-bulk-transfer-information-error) + +If the server is unable to find or create a bulk transfer, or another processing error occurs, the error callback **PUT** **/bulkTransfers/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer ([POST /bulkTransfers](#post-bulktransfers)), or the _{ID}_ that was used in the [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). See [Table 44](#table-44) for data model. + +###### Table 44 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 44 -- PUT /bulkTransfers/_{ID}_/error data model** + +#### States + +###### Figure 62 + +The possible states of a bulk transfer can be seen in [Figure 62](#figure-62). + +**Note:** A server must keep bulk transfer objects that have been rejected in their database during a market agreed time-period for reconciliation purposes. This means that a client should expect a proper callback about a bulk transfer (if it has been received by the server) when requesting information regarding the same. + +![Figure 62](../../assets/diagrams/images/figure62.svg) + +**Figure 62 -- Possible states of a bulk transfer** + +
    + +## API Supporting Data Models + +This section provides information about additional supporting data models used by the API. + +### Format Introduction + +This section introduces formats used for element data types used by the API. + +All element data types have both a minimum and maximum length. These lengths are indicated by one of the following: + +- A minimum and maximum length +- An exact length +- A regular expression limiting the element such that only a specific length or lengths can be used. + +#### Minimum and Maximum Length + +If a minimum and maximum length is used, this will be indicated after the data type in parentheses: First the minimum value (inclusive value), followed by two period characters (..), and then the maximum value (inclusive value). + +Examples: + +- `String(1..32)` – A String that is minimum one character and maximum 32 characters long. +- `Integer(3..10)` - An Integerr that is minimum 3 digits, but maximum 10 digits long. + +#### Exact Length + +If an exact length is used, this will be indicated after the data type in parentheses containing only one exact value. Other lengths are not allowed. + +Examples: + +- `String(3)` – A String that is exactly three characters long. +- `Integer(4)` – An Integer that is exactly four digits long. + +#### Regular Expressions + +Some element data types are restricted using regular expressions. The regular expressions in this document use the standard for syntax and character classes established by the programming language Perl[30](https://perldoc.perl.org/perlre.html#Regular-Expressions). + +### Element Data Type Formats + +This section defines element data types used by the API. + + + +#### String + +The API data type `String` is a normal JSON String[31](https://tools.ietf.org/html/rfc7159#section-7), limited by a minimum and maximum number of characters. + +##### Example Format I + +`String(1..32)` – A String that is minimum *1* character and maximum *32* characters long. + +An example of `String(1..32)` appears below: + +- _This String is 28 characters_ + +##### Example Format II + +`String(1..128)` – A String that is minimum *1* character and maximum *128* characters long. + +An example of `String(32..128)` appears below: + +- _This String is longer than 32 characters, but less than 128_ + +
    + +#### Enum + +The API data type `Enum` is a restricted list of allowed JSON [String](#string)) values; an enumeration of values. Other values than the ones defined in the list are not allowed. + +##### Example Format + +`Enum of String(1..32)` – A String that is minimum one character and maximum 32 characters long and restricted by the allowed list of values. The description of the element contains a link to the enumeration. + +
    + +#### UndefinedEnum + +The API data type **UndefinedEnum** is a JSON String consisting of 1 to 32 uppercase characters including an underscore character (**\_**). + +##### Regular Expression + +The regular expression for restricting the **UndefinedEnum** type appears in [Listing 13](#listing-13). + +###### Listing 13 + +``` +^[A-Z_]{1,32}$ +``` + +**Listing 13 -- Regular expression for data type UndefinedEnum** + +
    + +#### Name + +The API data type `Name` is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + +##### Regular Expression + +The regular expression for restricting the `Name` type appears in [Listing 14](#listing-14) below. The restriction does not allow a string consisting of whitespace only, all Unicode32 characters are allowed, as well as the period (**.**), apostrophe (**'**), dash (**-**), comma (**,**) and space characters ( ). The maximum number of characters in the **Name** is 128. + +**Note:** In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag `UNICODE_CHARACTER_CLASS` needs to be enabled to allow Unicode characters. + +###### Listing 14 + +``` +^(?!\s*$)[\w .,'-]{1,128}$ +``` + +**Listing 14 -- Regular expression for data type Name** + +
    + +#### Integer + +The API data type `Integer` is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits. + +##### 7.2.5.1 Regular Expression + +The regular expression for restricting an `Integer` appears in [Listing 15](#listing-15). + +###### Listing 15 + +``` +^[1-9]\d*$ +``` + +**Listing 15 -- Regular expression for data type Integer** + + +##### Example Format + +`Integer(1..6)` – An `Integer` that is at minimum one digit long, maximum six digits. + +An example of `Integer(1..6)` appears below: + +- _123456_ + +
    + +#### OtpValue + +The API data type `OtpValue` is a JSON String of three to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed. + +##### Regular Expression + +The regular expression for restricting the `OtpValue` type appears in [Listing 16](#listing-16). + +###### Listing 16 + +``` +^\d{3,10}$ +``` + +**Listing 16 -- Regular expression for data type OtpValue** + +
    + +#### BopCode + +The API data type `BopCode` is a JSON String of three characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `BopCode` type appears in [Listing 17](#listing-17). + +###### Listing 17 + +``` +^[1-9]\d{2}$ +``` + +**Listing 17 -- Regular expression for data type BopCode** + +
    + +#### ErrorCode + +The API data type `ErrorCode` is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `ErrorCode` type appears in [Listing 18](#listing-18). + +###### Listing 18 + +``` +^[1-9]\d{3}$ +``` + +**Listing 18 -- Regular expression for data type ErrorCode** + +
    + +#### TokenCode + +The API data type `TokenCode` is a JSON String between four and 32 characters. It can consist of either digits, uppercase characters from **A** to **Z**, lowercase characters from **a** to **z**, or a combination of the three. + +##### 7.2.9.1 Regular Expression + +The regular expression for restricting the `TokenCode` appears in [Listing 19](#listing-19). + +###### Listing 19 + +``` +^[0-9a-zA-Z]{4,32}$ +``` + +**Listing 19 -- Regular expression for data type TokenCode** + +
    + +#### MerchantClassificationCode + +The API data type `MerchantClassificationCode` is a JSON String consisting of one to four digits. + +##### 7.2.10.1 Regular Expression + +The regular expression for restricting the `MerchantClassificationCode` type appears in [Listing 20](#listing-20). + +###### Listing 20 + +``` +^[\d]{1,4}$ +``` + +**Listing 20 -- Regular expression for data type MerchantClassificationCode** + +
    + +#### Latitude + +The API data type `Latitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.11.1 Regular Expression + +The regular expression for restricting the `Latitude` type appears in [Listing 21](#listing-21). + +###### Listing 21 + +``` +^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 21 -- Regular expression for data type Latitude** + +
    + +#### Longitude + +The API data type `Longitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.12.1 Regular Expression + +The regular expression for restricting the `Longitude` type appears in [Listing 22](#listing-22). + +###### Listing 22 + +``` +^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 22 -- Regular expression for data type Longitude** + +
    + +#### Amount + +The API data type `Amount` is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Amount` type appears in [Listing 23](#listing-23). This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed. + +###### Listing 23 + +``` +^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$ +``` + +**Listing 23 -- Regular expression for data type Amount** + +##### Example Values + +See [Table 45](#table-45) for validation results for some example **Amount** values using the [regular expression](#regular-expression-6). + +###### Table 45 + +| **Value** | **Validation result** | +| --- | --- | +| **5** | Accepted | +| **5.0** | Rejected | +| **5.** | Rejected | +| **5.00** | Rejected | +| **5.5** | Accepted | +| **5.50** | Rejected | +| **5.5555** | Accepted | +| **5.55555** | Rejected | +| **555555555555555555** | Accepted | +| **5555555555555555555** | Rejected | +| **-5.5** | Rejected | +| **0.5** | Accepted | +| **.5** | Rejected | +| **00.5** | Rejected | +| **0** | Accepted | + +**Table 45 -- Example results for different values for Amount type** + +
    + +#### DateTime + +The API data type `DateTime` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.14.1 Regular Expression + +The regular expression for restricting the `DateTime` type appears in [Listing 24](#listing-24). The format is according to ISO 860133, expressed in a combined date, time and time zone format. A more readable version of the format is + +_yyyy_**-**_MM_**-**_dd_**T**_HH_**:**_mm_**:**_ss_**.**_SSS_[**-**_HH_**:**_MM_] + +###### Listing 24 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468\][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ +``` + +**Listing 24 -- Regular expression for data type DateTime** + +##### Examples + +Two examples of the `DateTime` type appear below: + +**2016-05-24T08:38:08.699-04:00** + +**2016-05-24T08:38:08.699Z** (where **Z** indicates Zulu time zone, which is the same as UTC). + +
    + +#### Date + +The API data type `Date` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the **Date** type appears in [Listing 25](#listing-25). This format, as specified in ISO 8601, contains a date only. A more readable version of the format is _yyyy_**-**_MM_**-**_dd_. + +###### Listing 25 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ +``` + +**Listing 25 -- Regular expression for data type Date** + +##### Examples + +Two examples of the `Date` type appear below: + +- _1982-05-23_ + +- _1987-08-05_ + +
    + +#### UUID + +The API data type `UUID` (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 412234, that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and four dashes ('**-**'). + +##### 7.2.16.1 Regular Expression + +The regular expression for restricting the `UUID` type appears in [Listing 26](#listing-26). + +###### Listing 26 + +``` +^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ +``` + +**Listing 26 -- Regular expression for data type UUID** + +##### Example + +An example of a `UUID` type appears below: + +- _a8323bc6-c228-4df2-ae82-e5a997baf898_ + +
    + +#### BinaryString + +The API data type `BinaryString` is a JSON String. The string is a base64url35 encoding of a string of raw bytes, where a padding (character '**=**') is added at the end of the data if needed to ensure that the string is a multiple of four characters. The length restriction indicates the allowed number of characters. + +##### Regular Expression + +The regular expression for restricting the `BinaryString` type appears in [Listing 27](#listing-27). + +###### Listing 27 + +``` +^[A-Za-z0-9-_]+[=]{0,2}$ +``` + +**Listing 27 -- Regular expression for data type BinaryString** + +##### Example Format + +`BinaryString(32)` –32 bytes of data base64url encoded. + +An example of a `BinaryString(32..256)` appears below. Note that a padding character, `'='` has been added to ensure that the string is a multiple of four characters. + +- _QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE=_ + +
    + +#### BinaryString32 + +The API data type `BinaryString32` is a fixed size version of the API data type `BinaryString` defined [here](#binarystring), where the raw underlying data is always of 32 bytes. The data type **BinaryString32** should not use a padding character as the size of the underlying data is fixed. + +##### Regular Expression + +The regular expression for restricting the `BinaryString32` type appears in [Listing 28](#listing-28). + +###### Listing 28 + +``` +^[A-Za-z0-9-_]{43}$ +``` + +**Listing 28 -- Regular expression for data type BinaryString32** + +##### Example Format +`BinaryString(32)` – 32 bytes of data base64url encoded. + +An example of a `BinaryString32` appears below. Note that this is the same binary data as the example shown in the [Example Format](#example-format-4) of the `BinaryString` type, but due to the underlying data being fixed size, the padding character `'='` is excluded. + +``` +QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE +``` + +
    + +### Element Definitions + +This section defines elements types used by the API. + +#### AmountType element + +[Table 46](#table-46) below contains the data model for the element `AmountType`. + +###### Table 46 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AmountType** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the amount type. See [AmountType](#amounttype-enum) enumeration for more information on allowed values. | + +**Table 46 – Element AmountType** + +
    + +#### AuthenticationType element + +[Table 47](#table-47) below contains the data model for the element `AuthenticationType`. + +###### Table 47 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Authentication** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authentication type. See [AuthenticationType](#authenticationtype-enum) enumeration for possible enumeration values. | + +**Table 47 – Element AuthenticationType** + +
    + +#### AuthenticationValue element + +[Table 48](#table-48) below contains the data model for the element `AuthenticationValue`. + +###### Table 48 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthenticationValue** | 1 | Depends on [AuthenticationType](#authenticationtype-element).

    If `OTP`: type is [Integer(1..6)](#integer). For example:**123456**

    OtpValue
    If `QRCODE`: type is [String(1..64)](#string) | This element contains the authentication value. The format depends on the authentication type used in the [AuthenticationInfo](#authenticationinfo) complex type. | + +**Table 48 – Element AuthenticationValue** + +
    + +#### AuthorizationResponse element + +[Table 49](#table-49) below contains the data model for the element `AuthorizationResponse`. + +###### Table 49 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthorizationResponse** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authorization response. See [AuthorizationResponse](#authorizationresponse-enum) enumeration for possible enumeration values. | + +**Table 49 – Element AuthorizationResponse** + +
    + +#### BalanceOfPayments element + +[Table 50](#table-50) below contains the data model for the element `BalanceOfPayment`. + +###### Table 50 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BalanceOfPayments** | 1 | [BopCode](#bopcode) | The possible values and meaning are defined in [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/) | + +**Table 50 – Element BalanceOfPayments** + +
    + +#### BulkTransferState element + +[Table 51](#table-51) below contains the data model for the element `BulkTransferState`. + +###### Table 51 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BulkTransferState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [BulkTransferState](#bulktransferstate-enum) enumeration for information on allowed values| + +**Table 51 – Element BulkTransferState** + +
    + +#### Code element + +[Table 52](#table-52) below contains the data model for the element `Code`. + +###### Table 52 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Code** | 1 | [TokenCode](#tokencode) | Any code/token returned by the Payee FSP. | + +**Table 52 – Element Code** + +
    + +#### CorrelationId element + +[Table 53](#table-53) below contains the data model for the element `CorrelationId`. + +###### Table 53 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **CorrelationId** | 1 |[UUID](#uuid) | Identifier that correlates all messages of the same sequence. | + + +**Table 53 – Element CorrelationId** + +
    + +#### Currency element + +[Table 54](#table-54) below contains the data model for the element `Currency`. + +###### Table 54 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Currency** | 1 | [Enum](#enum) of [String(3)](#string) | See [Currency](#currencycode-enum) enumeration for information on allowed values | + +**Table 54 – Element Currency** + +
    + +#### DateOfBirth element + +[Table 55](#table-55) below contains the data model for the element `DateOfBirth`. + +###### Table 55 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **DateOfBirth** | 1 | Examples

    Two examples of the [DateTime](#datetime) type appear below:

    2016-05-24T08:38:08.699-04:00

    2016-05-24T08:38:08.699Z (where Z indicates Zulu time zone, which is the same as UTC).

    Date

    | Date of Birth of the Party.| + +**Table 55 – Element DateOfBirth** + +
    + +#### ErrorCode element + +[Table 56](#table-56) below contains the data model for the element `ErrorCode`. + +###### Table 56 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorCode** | 1 | [ErrorCode](#errorcode) | Four digit error code, see section on [Error Codes](#error-codes) for more information. | + +**Table 56 – Element ErrorCode** + +
    + +#### ErrorDescription element + +[Table 57](#table-57] below contains the data model for the element `ErrorDescription`. + +###### Table 57 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorDescription** | 1 | [String(1..128)](#string) | Error description string. | + +**Table 57 – Element ErrorDescription** + +
    + +#### ExtensionKey element + +[Table 58](#table-58) below contains the data model for the element `ExtensionKey`. + +###### Table 58 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionKey** | 1 | [String(1..32)](#string) | The extension key. | + +**Table 58 – Element ExtensionKey** + +
    + +#### ExtensionValue element + +[Table 59](#table-59) below contains the data model for the element `ExtensionValue`. + +###### Table 59 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionValue** | 1 | [String(1..128)](#string) | The extension value. | + +**Table 59 – Element ExtensionValue** + +
    + +#### FirstName element +[Table 60](#table-60) below contains the data model for the element `FirstName`. + +###### Table 60 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FirstName** | 1 | [Name](#name) | First name of the Party | + +**Table 60 – Element FirstName** + +
    + +#### FspId element + +[Table 61](#table-61) below contains the data model for the element `FspId`. + +###### Table 61 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FspId** | 1 | [String(1..32)](#string)| The FSP identifier. | + +**Table 61 – Element FspId** + +
    + +#### IlpCondition element + +[Table 62](#table-62) below contains the data model for the element `IlpCondition`. + +###### Table 62 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpCondition** | 1 | [BinaryString32](#binarystring32) | The condition that must be attached to the transfer by the Payer. | + +**Table 62 – Element IlpCondition** + +
    + +#### IlpFulfilment element + +[Table 63](#table-63) below contains the data model for the element `IlpFulfilment`. + +###### Table 63 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpFulfilment** | 1 | [BinaryString32](#binarystring32) | The fulfilment that must be attached to the transfer by the Payee. | + +**Table 63 – Element IlpFulfilment** + +
    + +#### IlpPacket element + +[Table 64](#table-64) below cntains the data model for the element `IlpPacket`. + +###### Table 64 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpPacket** | 1 | Example

    An example of a [UUID](#uuid) type appears below:

    a8323bc6-c228-4df2-ae82-e5a997baf898

    [BinaryString(1..32768)](#binarystring)

    | Information for recipient (transport layer information). | + +**Table 64 – Element IlpPacket** + +
    + +#### LastName element + +[Table 65](#table-65) below contains the data model for the element `LastName`. + +###### Table 65 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **LastName** | 1 | [Name](#name) | Last name of the Party (ISO 20022 definition). | + +**Table 65 – Element LastName** + +
    + +#### MerchantClassificationCode element + +[Table 66](#table-66) below contains the data model for the element `MerchantClassificationCode`. + +###### Table 66 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MerchantClassificationCode** | 1 | [MerchantClassificationCode](#merchantclassificationcode) | A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, and so on. | + +**Table 66 – Element MerchantClassificationCode** + +
    + +#### MiddleName element + +[Table 67](#table-67) below contains the data model for the element `MiddleName`. + +###### Table 67 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MiddleName** | 1 | [Name](#name) | Middle name of the Party (ISO 20022 definition). | + +**Table 67 – Element MiddleName** + +
    + +#### Note element + +[Table 68](#table-68) below contains the data model for the element `Note`. + +###### Table 68 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Note** | 1 | [String(1..128)](#string) | Memo assigned to transaction. | + +**Table 68 – Element Note** + +
    + + +#### PartyIdentifier element + +[Table 69](#table-69) below contains the data model for the element `PartyIdentifier`. + +###### Table 69 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdentifier** | 1 | [String(1..128)](#string) | Identifier of the Party.| + +**Table 69 – Element PartyIdentifier** + +
    + +#### PartyIdType element + +[Table 70](#table-70) below contains the data model for the element `PartyIdType`. + +###### Table 70 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdType** | 1 | Enum of [String(1..32)](#string) | See [PartyIdType](#partyidtype-enum) enumeration for more information on allowed values. | + +**Table 70 – Element PartyIdType** + +
    + +#### PartyName element + +[Table 71](#table-71) below contains the data model for the element `PartyName`. + +###### Table 71 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyName** | 1 | `Name` | Name of the Party. Could be a real name or a nickname. | + +**Table 71 – Element PartyName** + +
    + +#### PartySubIdOrType element + +[Table 72](#table-72) below contains the data model for the element `PartySubIdOrType`. + +###### Table 72 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartySubIdOrType** | 1 | [String(1..128)](#string) | Either a sub-identifier of a [PartyIdentifier](#partyidentifier-element), or a sub-type of the [PartyIdType](#partyidtype-element), normally a `PersonalIdentifierType`. | + +**Table 72 – Element PartySubIdOrType** + +
    + +#### RefundReason element + +[Table 73](#table-73) below contains the data model for the element `RefundReason`. + +###### Table 73 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **RefundReason** | 1 | [String(1..128)](#string) | Reason for the refund. | + +**Table 73 – Element RefundReason** + +
    + +#### TransactionInitiator element + +[Table 74](#table-74) below contains the data model for the element `TransactionInitiator`. + +###### Table 74 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiator** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiator](#transactioninitiator-enum) enumeration for more information on allowed values. | + +**Table 74 – Element TransactionInitiator** + +
    + +#### TransactionInitiatorType element + +[Table 75](#table-75) below contains the data model for the element `TransactionInitiatorType`. + +###### Table 75 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiatorType** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiatorType](#transactioninitiatortype-enum) enumeration for more information on allowed values. | + +**Table 75 – Element TransactionInitiatorType** + +
    + +#### TransactionRequestState element + +[Table 76](#table-76) below contains the data model for the element `TransactionRequestState`. + +###### Table 76 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionRequestState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionRequestState](#transactionrequeststate-enum) enumeration for more information on allowed values. | + + +**Table 76 – Element TransactionRequestState** + +
    + +#### TransactionScenario element + +[Table 77](#table-77) below contains the data model for the element `TransactionScenario`. + +###### Table 77 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionScenario** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionScenario](#transactionscenario-enum) enumeration for more information on allowed values. | + +**Table 77 – Element TransactionScenario** + +
    + +#### TransactionState element + +[Table 78](#table-78) below contains the data model for the element `TransactionState`. + +###### Table 78 + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionState](#transactionstate-enum) enumeration for more information on allowed values. | + +**Table 78 – Element TransactionState** + +
    + + +#### TransactionSubScenario element + +[Table 79](#table-79) below contains the data model for the element `TransactionSubScenario`. + +###### Table 79 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionSubScenario** | 1 | [UndefinedEnum](#undefinedenum) | Possible sub-scenario, defined locally within the scheme.| + +**Table 79 – Element TransactionSubScenario** + +
    + +#### TransferState element + +[Table 80](#table-80) below contains the data model for the element `TransferState`. + +###### Table 80 + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransferState](#transferstate-enum) enumeration for more information on allowed values. | + +**Table 80 – Element TransferState** + + +
    + + +### Complex Types + +This section describes complex types used by the API. + +#### AuthenticationInfo + +[Table 81](#table-81) contains the data model for the complex type `AuthenticationInfo`. + +###### Table 81 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **authentication** | 1 | `AuthenticationType` | Type of authentication. | +| **authenticationValue** | 1 | `AuthenticationValue` | Authentication value. | + +**Table 81 -- Complex type AuthenticationInfo** + +
    + +#### ErrorInformation + +[Table 82](#table-82) contains the data model for the complex type `ErrorInformation`. + +###### Table 82 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **errorCode** | 1 | `Errorcode` | Specific error number. | +| **errorDescription** | 1 | `ErrorDescription` | Error description string. | +| **extensionList** | 1 | `ExtensionList` | Optional list of extensions, specific to deployment. | + +**Table 82 -- Complex type ErrorInformation** + +
    + +#### Extension + +[Table 83](#table-83) contains the data model for the complex type `Extension`. + +###### Table 83 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **key** | 1 | `ExtensionKey` | Extension key. | +| **value** | 1 | `ExtensionValue` | Extension value. | + +**Table 83 -- Complex type Extension** + +
    + +#### ExtensionList + +[Table 84](#table-84) contains the data model for the complex type `ExtensionList`. + +###### Table 84 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **extension** | 1..16 | `Extension` | Number of Extension elements. | + +**Table 84 -- Complex type ExtensionList** + +
    + +#### IndividualQuote + +[Table 85](#table-85) contains the data model for the complex type `IndividualQuote`. + +###### Table 85 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifies quote message. | +| **transactionId** | 1 | `CorrelationId` | Identifies transaction message. | +| **payee** | 1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **amountType** | 1 | `AmountType` | **SEND** for sendAmount, **RECEIVE** for receiveAmount. | +| **amount** | 1 | `Money` | Depending on **amountType**:
    If **SEND**: The amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.
    If **RECEIVE**: The amount the Payee should receive; that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. | +| **fees** | 0..1 | `Money` | Fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    +| **transactionType** | 1 | `TransactionType` | Type of transaction that the quote is requested for. | +| **note** | 0..1 | Note | Memo that will be attached to the transaction.| +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 85 -- Complex type IndividualQuote** + +
    + +#### IndividualQuoteResult + +[Table 86](#table-86) contains the data model for the complex type `IndividualQuoteResult`. + +###### Table 86 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifies the quote message. | +| **payee** | 0..1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **transferAmount** | 0..1 | `Money` | The amount of Money that the Payer FSP should transfer to the Payee FSP. | +| **payeeReceiveAmount** | 0..1 | `Money` | Amount that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | `Money` | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | `Money` | Transaction commission from the Payee FSP. | +| **ilpPacket** | 0..1 | `IlpPacket` | ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 0..1 | `IlpCondition` | Condition that must be attached to the transfer by the Payer. | +| **errorInformation** | 0..1 | `ErrorInformation` | Error code, category description.
    **Note: payee, transferAmount, payeeReceiveAmount, payeeFspFee, payeeFspCommission, ilpPacket,** and **condition** should not be set if **errorInformation** is set.
    +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment | + +**Table 86 -- Complex type IndividualQuoteResult** + +
    + +#### IndividualTransfer + +[Table 87](#table-87) contains the data model for the complex type `IndividualTransfer`. + +###### Table 87 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifies messages related to the same **/transfers** sequence. | +| **transferAmount** | 1 | `Money` | Transaction amount to be sent. | +| **ilpPacket** | 1 | `IlpPacket` | ILP Packet containing the amount delivered to the Payee and the ILP Address of the Payee and any other end-to-end data. | +| **condition** | 1 | `IlpCondition` | Condition that must be fulfilled to commit the transfer. | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 87 -- Complex type IndividualTransfer** + +
    + +#### IndividualTransferResult + +[Table 88](#table-88) contains the data model for the complex type `IndividualTransferResult`. + +###### Table 88 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifies messages related to the same /transfers sequence. | +| **fulfilment** | 0..1 | `IlpFulfilment` | Fulfilment of the condition specified with the transaction.
    **Note:** Either **fulfilment** or **errorInformation** should be set, not both. | +| **errorInformation** | 0..1 | `ErrorInformation` | If transfer is REJECTED, error information may be provided.
    **Note:** Either **fulfilment** or **errorInformation** should be set, not both.| +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment.| + +**Table 88 -- Complex type IndividualTransferResult** + +
    + +#### GeoCode + +[Table 89](#table-89) contains the data model for the complex type `GeoCode`. + +###### Table 89 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **latitude** | 1 | `Latitude` | Latitude of the Party. | +| **longitude** | 1 | `Longitude` | Longitude of the Party. | + +**Table 89 -- Complex type GeoCode** + +
    + +#### Money + +[Table 90](#table-90) contains the data model for the complex type `Money`. + +###### Table 90 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **currency** | 1 | `Currency` | Currency of the amount. | +| **amount** | 1 | `Amount` | Amount of money. | + +**Table 90 -- Complex type Money** + +
    + +#### Party + +[Table 91](#table-91) contains the data model for the complex type `Party`. + +###### Table 91 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdInfo** | 1 | `PartyIdInfo` | Party Id type, id, sub ID or type, and FSP Id. | +| **merchantClassificationCode** | 0..1 | `MerchantClassificationCode` | Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments. | +| **name** | 0..1 | `PartyName` | Display name of the Party, could be a real name or a nick name. | +| **personalInfo** | 0..1 | `PartyPersonalInfo` | Personal information used to verify identity of Party such as first, middle, last name and date of birth. | + +**Table 91 -- Complex type Party** + +
    + +#### PartyComplexName + +[Table 92](#table-92) contains the data model for the complex type `PartyComplexName`. + +###### Table 92 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **firstName** | 0..1 | `FirstName` | Party's first name. | +| **middleName** | 0..1 | `MiddleName` | Party's middle name. | +| **lastName** | 0..1 | `LastName` | Party's last name. | + +**Table 92 -- Complex type PartyComplexName** + +
    + +#### PartyIdInfo + +[Table 93](#table-93) contains the data model for the complex type `PartyIdInfo`. + +###### Table 93 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdType** | 1 | `PartyIdType` | Type of the identifier. | +| **partyIdentifier** | 1 | `PartyIdentifier` | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | `PartySubIdOrType` | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | `FspId` | FSP ID (if know) | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 93 -- Complex type PartyIdInfo** + +
    + +#### PartyPersonalInfo + +[Table 94](#table-94) contains the data model for the complex type `PartyPersonalInfo`. + +###### Table 94 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **complexName** | 0..1 | `PartyComplexName` | First, middle and last name for the Party. | +| **dateOfBirth** | 0..1 | `DateOfBirth` | Date of birth for the Party. | + +**Table 94 -- Complex type PartyPersonalInfo** + +
    + +#### PartyResult + +[Table 95](#table-95) contains the data model for the complex type `PartyResult`. + +###### Table 95 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyId** | 1 | `PartyIdInfo` | Party Id type, id, sub ID or type, and FSP Id. | +| **errorInformation** | 0..1 | `ErrorInformation` | If the Party failed to be added, error information should be provided. Otherwise, this parameter should be empty to indicate success. | + +**Table 95 -- Complex type PartyResult** + +
    + +#### Refund + +[Table 96](#table-96) contains the data model for the complex type `Refund`. + +###### Table 96 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **originalTransactionId** | 1 | `CorrelationId` | Reference to the original transaction ID that is requested to be refunded. | +| **refundReason** | 0..1 | `RefundReason` | Free text indicating the reason for the refund. | + +**Table 96 -- Complex type Refund** + +
    + +#### Transaction + +[Table 97](#table-97) contains the data model for the complex type Transaction. The Transaction type is used to carry end-to-end data between the Payer FSP and the Payee FSP in the ILP Packet, see [IlpPacket](#ilp-packet). Both the **transactionId** and the **quoteId** in the data model is decided by the Payer FSP in the [POST /quotes](#post-quotes), see [Table 23](#table-23). + +###### Table 97 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transactionId** | 1 | `CorrelationId` | ID of the transaction, the ID is decided by the Payer FSP during the creation of the quote. | +| **quoteId** | 1 | `CorrelationId` | ID of the quote, the ID is decided by the Payer FSP during the creation of the quote. | +| **payee** | 1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | `Party` | Information about the Payer in the proposed financial transaction. | +| **amount** | 1 | `Money` | Transaction amount to be sent. | +| **transactionType** | 1 | `TransactionType` | Type of the transaction. | +| **note** | 0..1 | `Note` | Memo associated to the transaction, intended to the Payee. | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 97 -- Complex type Transaction** + +
    + +#### TransactionType + +[Table 98](#table-98) contains the data model for the complex type `TransactionType`. + +###### Table 98 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **scenario** | 1 | `TransactionScenario` | Deposit, withdrawal, refund, ... | +| **subScenario** | 0..1 | `TransactionSubScenario` | Possible sub-scenario, defined locally within the scheme. | +| **initiator** | 1 | `TransactionInitiator` | Who is initiating the transaction: Payer or Payee | +| **initiatorType** | 1 | `TransactionInitiatorType` | Consumer, agent, business, ... | +| **refundInfo** | 0..1 | `Refund` | Extra information specific to a refund scenario. Should only be populated if scenario is REFUND. | +| **balanceOfPayments** | 0..1 | `BalanceOfPayments` | Balance of Payments code. | + +**Table 98 -- Complex type TransactionType** + +
    + +### Enumerations + +This section contains the enumerations that are used by the API. + +#### AmountType enum + +[Table 99](#table-99) contains the allowed values for the enumeration `AmountType`. + +###### Table 99 + +| **Name** | **Description** | +| --- | --- | +| **SEND** | Amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. | +| **RECEIVE** | Amount the Payer would like the Payee to receive; that is, the amount that should be sent to the receiver exclusive fees. | + +**Table 99 -- Enumeration AmountType** + +
    + +#### AuthenticationType enum + +[Table 100](#table-100) contains the allowed values for the enumeration `AuthenticationType`. + +###### Table 100 + +| **Name** | **Description** | +| --- | --- | +| **OTP** | One-time password generated by the Payer FSP. | +| **QRCODE** | QR code used as One Time Password. | + +**Table 100 -- Enumeration AuthenticationType** + +
    + +#### AuthorizationResponse enum + +[Table 101](#table-101) contains the allowed values for the enumeration `AuthorizationResponse`. + +###### Table 101 + +| **Name** | **Description** | +| --- | --- | +| **ENTERED** | Consumer entered the authentication value. | +| **REJECTED** | Consumer rejected the transaction. | +| **RESEND** | Consumer requested to resend the authentication value. | + +**Table 101 -- Enumeration AuthorizationResponse** + +
    + +#### BulkTransferState enum + +[Table 102](#table-102) contains the allowed values for the enumeration `BulkTransferState`. + +###### Table 102 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payee FSP has received the bulk transfer from the Payer FSP. | +| **PENDING** | Payee FSP has validated the bulk transfer. | +| **ACCEPTED** | Payee FSP has accepted the bulk transfer for processing. | +| **PROCESSING** | Payee FSP has started to transfer fund to the Payees. | +| **COMPLETED** | Payee FSP has completed transfer of funds to the Payees. | +| **REJECTED** | Payee FSP has rejected processing the bulk transfer. | + +**Table 102 -- Enumeration BulkTransferState** + +
    + +#### CurrencyCode enum + +The currency codes defined in ISO 421736 as three-letter alphabetic codes are used as the standard naming representation for currencies. The currency codes from ISO 4217 are not shown in this document, implementers are instead encouraged to use the information provided by the ISO 4217 standard directly. + +
    + +#### PartyIdType enum + +[Table 103](#Table-103) contains the allowed values for the enumeration `PartyIdType`. + +###### Table 103 + +| **Name** | **Description** | +| --- | --- | +| **MSISDN** | An MSISDN (Mobile Station International Subscriber Directory Number; that is, a phone number) is used in reference to a Party. The MSISDN identifier should be in international format according to the ITU-T E.16437 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. | +| **EMAIL** | An email is used in reference to a Party. The format of the email should be according to the informational RFC 369638. | +| **PERSONAL_ID** | A personal identifier is used in reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the [PartyIdentifier](#partyidentifier-element) element. The personal identifier type is added in the [PartySubIdOrType](#partysubidortype-element) element. | +| **BUSINESS** | A specific Business (for example, an organization or a company) is used in reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the [PartySubIdOrType](#partysubidortype-element) element should be used. | +| **DEVICE** | A specific device (for example, POS or ATM) ID connected to a specific business or organization is used in reference to a Party. For referencing a specific device under a specific business or organization, use the [PartySubIdOrType](#partysubidortype-element) element. | +| **ACCOUNT_ID** | A bank account number or FSP account ID should be used in reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. +| **IBAN** | A bank account number or FSP account ID is used in reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. | +| **ALIAS** | An alias is used in reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the [PartySubIdOrType](#partysubidortype-element) element for identifying an account under an Alias defined by the [PartyIdentifier](#partyidentifier-element). | + +**Table 103 -- Enumeration PartyIdType** + +
    + +#### PersonalIdentifierType enum + +[Table 104](#table-104) contains the allowed values for the enumeration `PersonalIdentifierType`. + +###### Table 104 + +| **Name** | **Description** | +| --- | --- | +| **PASSPORT** | A passport number is used in reference to a Party. | +| **NATIONAL_REGISTRATION** | A national registration number is used in reference to a Party. | +| **DRIVING_LICENSE** | A driving license is used in reference to a Party. | +| **ALIEN_REGISTRATION** | An alien registration number is used in reference to a Party. | +| **NATIONAL_ID_CARD** | A national ID card number is used in reference to a Party. | +| **EMPLOYER_ID** | A tax identification number is used in reference to a Party. | +| **TAX_ID_NUMBER** | A tax identification number is used in reference to a Party. | +| **SENIOR_CITIZENS_CARD** | A senior citizens card number is used in reference to a Party. | +| **MARRIAGE_CERTIFICATE** | A marriage certificate number is used in reference to a Party. | +| **HEALTH_CARD** | A health card number is used in reference to a Party. | +| **VOTERS_ID** | A voter’s identification number is used in reference to a Party. | +| **UNITED_NATIONS** | An UN (United Nations) number is used in reference to a Party. | +| **OTHER_ID** | Any other type of identification type number is used in reference to a Party. | + +**Table 104 -- Enumeration PersonalIdentifierType** + +
    + +#### TransactionInitiator + +[Table 105](#table-105) describes valid values for the enumeration `TransactionInitiator`. + +###### Table 105 + +| **Name** | **Description** | +| --- | --- | +| **PAYER** | Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. | +| **PAYEE** | Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or manually by approving on their own Device. | + +**Table 105 -- Enumeration TransactionInitiator** + +
    + +#### TransactionInitiatorType + +[Table 106](#table-106) contains the allowed values for the enumeration `TransactionInitiatorType`. + +###### Table 106 + +| **Name** | **Description** | +| --- | --- | +| **CONSUMER ** | Consumer is the initiator of the transaction. | +| **AGENT** | Agent is the initiator of the transaction. | +| **BUSINESS** | Business is the initiator of the transaction. | +| **DEVICE** | Device is the initiator of the transaction. | + +**Table 106 -- Enumeration TransactionInitiatorType** + +
    + +#### TransactionRequestState + +[Table 107](#table-107) contains the allowed values for the enumeration `TransactionRequestState`. + +###### Table 107 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payer FSP has received the transaction from the Payee FSP. | +| **PENDING** | Payer FSP has sent the transaction request to the Payer. | +| **ACCEPTED** | Payer has approved the transaction. | +| **REJECTED** | Payer has rejected the transaction. | + +**Table 107 -- Enumeration TransactionRequestState** + +
    + +#### TransactionScenario + +[Table 108](#table-108) contains the allowed values for the enumeration `TransactionScenario`. + +###### Table 108 + +| **Name** | **Description** | +| --- | --- | +| **DEPOSIT** | Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. | +| **WITHDRAWAL** | Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. | +| **TRANSFER** | Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. | +| **PAYMENT** | Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. | +| **REFUND** | Used for performing a refund of transaction. | + +**Table 108 -- Enumeration TransactionScenario** + +
    + +#### TransactionState + +[Table 109](#table-109) contains the allowed values for the enumeration `TransactionState`. + +###### Table 109 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payee FSP has received the transaction from the Payer FSP. | +| **PENDING** | Payee FSP has validated the transaction. | +| **COMPLETED** | Payee FSP has successfully performed the transaction. | +| **REJECTED** | Payee FSP has failed to perform the transaction. | + +**Table 109 -- Enumeration TransactionState** + +
    + +#### TransferState + +[Table 110](#table-110) contains the allowed values for the enumeration `TransferState`. + +###### Table 110 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Next ledger has received the transfer. | +| **RESERVED** | Next ledger has reserved the transfer. | +| **COMMITTED** | Next ledger has successfully performed the transfer. | +| **ABORTED** | Next ledger has aborted the transfer due a rejection or failure to perform the transfer. | + +**Table 110 -- Enumeration TransferState** + +
    + +### Error Codes + +###### Figure 63 + +Each error code in the API is a four-digit number, for example, **1234**, where the first number (**1** in the example) represents the high-level error category, the second number (**2** in the example) represents the low-level error category, and the last two numbers (**34** in the example) represents the specific error. [Figure 63](#figure-63) shows the structure of an error code. The following sections contain information about defined error codes for each high-level error category. + +![Figure 63](../../assets/diagrams/images/figure63.svg) + +**Figure 63 -- Error code structure** + +Each defined high- and low-level category combination contains a generic error (_x_**0**_xx_), which can be used if there is no specific error, or if the server would not like to return information which is considered private. + +All specific errors below _xx_**40**; that is, _xx_**00** to _xx_**39**, are reserved for future use by the API. All specific errors above and including _xx_**40** can be used for scheme-specific errors. If a client receives an unknown scheme-specific error, the unknown scheme-specific error should be interpreted as a generic error for the high- and low-level category combination instead (_xx_**00**). + +#### Communication Errors -- 1_xxx_ + +All possible communication or network errors that could arise that cannot be represented by an HTTP status code should use the high-level error code **1** (error codes **1**_xxx_). Because all services in the API are asynchronous, these error codes should generally be used by a Switch in the Callback to the client FSP if the Peer FSP cannot be reached, or when a callback is not received from the Peer FSP within an agreed timeout. + +Low level categories defined under Communication Errors: + +- **Generic Communication Error** -- **10**_xx_ + +See [Table 111](#table-111) for all communication errors defined in the API. + +###### Table 111 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **1000** | Communication error | Generic communication error. | X | X | X | X | X | X | X | X | X | +| **1001** | Destination communication error | Destination of the request failed to be reached. This usually indicates that a Peer FSP failed to respond from an intermediate entity. | X | X | X | X | X | X | X | X | X | + +**Table 111 -- Communication errors -- 1_xxx_** + +#### Server Errors -- 2_xxx_ + +All possible errors occurring on the server in which it failed to fulfil an apparently valid request from the client should use the high-level error code **2** (error codes **2**_xxx_). These error codes should indicate that the server is aware that it has encountered an error or is otherwise incapable of performing the requested service. + +Low-level categories defined under server errors: + +- **Generic server error** -- **20**_xx_ + +See [Table 112](#Table-112) for server errors defined in the API. + +###### Table 112 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **2000** | Generic server error | Generic server error to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **2001** | Internal server error | Generic unexpected exception. This usually indicates a bug or unhandled error case. | X | X | X | X | X | X | X | X | X | +| **2002** | Not implemented | Service requested is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **2003** | Service currently unavailable | Service requested is currently unavailable on the server. This could be because maintenance is taking place, or because of a temporary failure. | X | X | X | X | X | X | X | X | X | +| **2004** | Server timed out | Timeout has occurred, meaning the next Party in the chain did not send a callback in time. This could be because a timeout is set too low or because something took longer than expected. | X | X | X | X | X | X | X | X | X | +| **2005** | Server busy | Server is rejecting requests due to overloading. Try again later. | X | X | X | X | X | X | X | X | X | + +**Table 112 -- Server errors -- 2_xxx_** + +#### Client Errors -- 3_xxx_ + +All possible errors occurring on the server in which the server reports that the client has sent one or more erroneous parameters should use the high-level error code **3** (error codes **3**_xxx_). These error codes should indicate that the server could not perform the service according to the request from the client. The server should provide an explanation why the service could not be performed. + +Low level categories defined under client Errors: + +- **Generic Client Error** -- **30**_xx_ + + - See [Table 113](#table-113) for generic client errors defined in the API. + +- **Validation Error** -- **31**_xx_ + + - See [Table 114](#table-114) the validation errors defined in the API. + +- **Identifier Error** -- **32**_xx_ + + - See [Table 115](#table-115) for identifier errors defined in the API. + +- **Expired Error** -- **33**_xx_ + + - See [Table 116](#table-116) for expired errors defined in the API. + +###### Table 113 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3000** | Generic client error | Generic client error, used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3001** | Unacceptable version requested | Client requested to use a protocol version which is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **3002** | Unknown URI | Provided URI was unknown to the server. | X | X | X | X | X | X | X | X | X | +| **3003** | Add Party information error | Error occurred while adding or updating information regarding a Party. | X | X | X | X | X | X | X | X | X | + +**Table 113 -- Generic client errors -- 30_xx_** + +###### Table 114 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3100** | Generic validation error | Generic validation error to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3101** | Malformed syntax | Format of the parameter is not valid. For example, amount set to **5.ABC**. The error description field should specify which information element is erroneous. | X | X | X | X | X | X | X | X | X | +| **3102** | Missing mandatory element | Mandatory element in the data model was missing. | X | X | X | X | X | X | X | X | X | +| **3103** | Too many elements | Number of elements of an array exceeds the maximum number allowed. | X | X | X | X | X | X | X | X | X | +| **3104** | Too large payload | Size of the payload exceeds the maximum size. | X | X | X | X | X | X | X | X | X | +| **3105** | Invalid signature | Some parameters have changed in the message, making the signature invalid. This may indicate that the message may have been modified maliciously. | X | X | X | X | X | X | X | X | X | +| **3106** | Modified request | Request with the same ID has previously been processed in which the parameters are not the same. ||| X | X | X | X | X | X | X | +| **3107** | Missing mandatory extension parameter | Scheme-mandatory extension parameter was missing. ||| X | X | X | X | X | X | X | + +**Table 114 -- Validation errors -- 31_xx_** + +###### Table 115 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3200** | Generic ID not found | Generic ID error provided by the client. | X | X | X | X | X | X | X | X | X | +| **3201** | Destination FSP Error | Destination FSP does not exist or cannot be found. | X | X | X | X | X | X | X | X | X | +| **3202** | Payer FSP ID not found |Provided Payer FSP ID not found. |||||| X ||| X | +| **3203** | Payee FSP ID not found |Provided Payee FSP ID not found. |||||| X ||| X | +| **3204** | Party not found |Party with the provided identifier, identifier type, and optional sub id or type was not found. | X | X | X | X |||||| +| **3205** | Quote ID not found |Provided Quote ID was not found on the server. |||| X || X |||| +| **3206** | Transaction request ID not found |Provided Transaction Request ID was not found on the server. ||| X ||| X |||| +| **3207** | Transaction ID not found |Provided Transaction ID was not found on the server. ||||||| X ||| +| **3208** | Transfer ID not found |Provided Transfer ID was not found on the server. |||||| X |||| +| **3209** | Bulk quote ID not found |Provided Bulk Quote ID was not found on the server. |||||||| X | X | +| **3210** | Bulk transfer ID not found |Provided Bulk Transfer ID was not found on the server. ||||||||| X | + +**Table 115 -- Identifier errors -- 32_xx_** + +###### Table 116 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3300** | Generic expired error | Generic expired object error, to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3301** | Transaction request expired | Client requested to use a transaction request that has already expired. |||| X |||||| +| **3302** | Quote expired | Client requested to use a quote that has already expired. ||||| X | X ||| X | +| **3303** | Transfer expired | Client requested to use a transfer that has already expired. | X | X | X | X | X | X | X | X | X | + +**Table 116 -- Expired errors -- 33_xx_** + +#### Payer Errors -- 4_xxx_ + +All errors occurring on the server for which the Payer or the Payer FSP is the cause of the error should use the high-level error code **4** (error codes **4**_xxx_). These error codes indicate that there was no error on the server or in the request from the client, but the request failed for a reason related to the Payer or the Payer FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payer Errors: + +- **Generic Payer Error** -- **40**_xx_ + +- **Payer Rejection Error** -- **41**_xx_ + +- **Payer Limit Error** -- **42**_xx_ + +- **Payer Permission Error** -- **43**_xx_ + +- **Payer Blocked Error** -- **44**_xx_ + +See [Table 117](#table-117) for Payer errors defined in the API. + +###### Table 117 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **4000** | Generic Payer error | Generic error related to the Payer or Payer FSP. Used for protecting information that may be considered private. ||| X | X | X | X | X | X | X | +| **4001** | Payer FSP insufficient liquidity | Payer FSP has insufficient liquidity to perform the transfer. |||||| X |||| +| **4100** | Generic Payer rejection | Payer or Payer FSP rejected the request. ||| X | X | X | X | X | X | X | +| **4101** | Payer rejected transaction request | Payer rejected the transaction request from the Payee. ||| X ||||||| +| **4102** | Payer FSP unsupported transaction type |Payer FSP does not support or rejected the requested transaction type ||| X ||||||| +| **4103** | Payer unsupported currency | Payer does not have an account which supports the requested currency. ||| X ||||||| +| **4200** | Payer limit error | Generic limit error, for example, the Payer is making more payments per day or per month than they are allowed to, or is making a payment which is larger than the allowed maximum per transaction. ||| X | X || X || X | X | +| **4300** | Payer permission error | Generic permission error, the Payer or Payer FSP does not have the access rights to perform the service. ||| X | X | X | X | X | X | X | +| **4400** | Generic Payer blocked error | Generic Payer blocked error; the Payer is blocked or has failed regulatory screenings. ||| X | X | X | X | X | X | X | + +**Table 117 -- Payer errors -- 4_xxx_** + +#### Payee Errors -- 5_xxx_ + +All errors occurring on the server for which the Payee or the Payee FSP is the cause of an error use the high-level error code **5** (error codes **5**_xxx_). These error codes indicate that there was no error on the server or in the request from the client, but the request failed for a reason related to the Payee or the Payee FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payee Errors: + +- **Generic Payee Error** -- **50**_xx_ + +- **Payee Rejection Error** -- **51**_xx_ + +- **Payee Limit Error** -- **52**_xx_ + +- **Payee Permission Error** -- **53**_xx_ + +- **Payee Blocked Error** -- **54**_xx_ + +See [Table 118](#table-118) for all Payee errors defined in the API. + +###### Table 118 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **5000** | Generic Payee error | Generic error due to the Payer or Payer FSP, to be used in order not to disclose information that may be considered private. ||| X | X | X | X | X | X | X | +| **5001** | Payee FSP insufficient liquidity | Payee FSP has insufficient liquidity to perform the transfer. |||||| X |||| +| **5100** | Generic Payee rejection | Payee or Payee FSP rejected the request. ||| X | X | X | X | X | X | X | +| **5101** | Payee rejected quote | Payee does not want to proceed with the financial transaction after receiving a quote. |||| X |||| X || +| **5102** | Payee FSP unsupported transaction type | Payee FSP does not support or has rejected the requested transaction type |||| X ||||| X | +| **5103** | Payee FSP rejected quote | Payee FSP does not want to proceed with the financial transaction after receiving a quote. |||| X |||| X || +| **5104** | Payee rejected transaction | Payee rejected the financial transaction. |||||| X ||| X | +| **5105** | Payee FSP rejected transaction | Payee FSP rejected the financial transaction. |||||| X ||| X | +| **5106** | Payee unsupported currency | Payee does not have an account that supports the requested currency. |||| X || X || X | X | +| **5200** | Payee limit error | Generic limit error, for example, the Payee is receiving more payments per day or per month than they are allowed to, or is receiving a payment that is larger than the allowed maximum per transaction. ||| X | X || X || X | X | +| **5300** |Payee permission error | Generic permission error, the Payee or Payee FSP does not have the access rights to perform the service. ||| X | X | X | X | X | X | X | +| **5400** | Generic Payee blocked error | Generic Payee Blocked error, the Payee is blocked or has failed regulatory screenings. ||| X | X | X | X | X | X | X | + +**Table 118 -- Payee errors -- 5_xxx_** + + +## Generic Transaction Patterns Binding + +This section provides information about how the logical transaction patterns from [Generic Transaction Patterns](../generic-transaction-patterns) are used in the asynchronous REST binding of the API. Much of the information is provided by way of sequence diagrams. For more information regarding the steps in these diagrams, see [Generic Transaction Patterns](../generic-transaction-patterns). + +### Payer Initiated Transaction + +The `Payer Initiated Transaction` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). On a high-level, the pattern should be used whenever a Payer would like to transfer funds to another Party whom is not located in the same FSP as the Payer. [Figure 64](#figure-64) shows the sequence diagram for a `Payer Initiated Transaction` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). + +###### Figure 64 + +![](../../assets/diagrams/sequence/figure64.svg) + + +**Figure 64 -- Payer Initiated Transaction pattern using the asynchronous REST binding** + +### Payee Initiated Transaction + +The `Payee Initiated Transaction` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). On a high-level, the pattern should be used whenever a Payee would like to request that Payer transfer funds to a Payee. The Payer and the Payee are assumed to be in different FSPs, and the approval of the transaction is performed in the Payer FSP. If the transaction information and approval occur on a Payee device instead, use the related Payee Initiated Transaction using OTP](#payee-initiated-transaction-using-otp) instead. [Figure 65](#figure-65) shows the sequence diagram for a `Payee Initiated Transaction` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction). + +###### Figure 65 + +![](../../assets/diagrams/sequence/figure65.svg) + + +**Figure 65 -- Payee Initiated Transaction pattern using the asynchronous REST binding** + +### Payee Initiated Transaction using OTP + +The `Payee Initiated Transaction using OTP` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction-using-otp). On a high-level, this pattern is like the [Payee Initiated Transaction](#payee-initiated-transaction); however, in this pattern the transaction information and approval for the Payer is shown and entered on a Payee device instead. As in other transaction patterns, the Payer and the Payee are assumed to be in different FSPs. [Figure 66](#figure-66) shows the sequence diagram for a `Payee Initiated Transaction using OTP` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction-using-otp). + +###### Figure 66 + +![](../../assets/diagrams/sequence/figure66.svg) + + +**Figure 66 -- Payee Initiated Transaction using OTP pattern using the asynchronous REST binding** + +### Bulk Transactions + +The `Bulk Transactions` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#bulk-transactions). On a high-level, the pattern is used whenever a Payer would like to transfer funds to multiple Payees using one single transaction. The Payees can be in different FSPs. [Figure 67](#figure-67) shows the sequence diagram for a `Bulk Transactions` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#bulk-transactions). + +###### Figure 67 + +![](../../assets/diagrams/sequence/figure67.svg) + + +**Figure 67 -- Bulk Transactions pattern using the asynchronous REST binding** + +
    + +## API Error Handling + +This section describes how to handle missing responses or callbacks, as well as how to handle errors in a server during processing of a request. + +### Erroneous Request + +If a server receives an erroneous service request that can be handled immediately (for example, malformed syntax or resource not found), a valid HTTP client error code (starting with **4_xx_**39) should be returned to the client in the response. The HTTP error codes defined in the API appear in [Table 4](#table-4). The HTTP response may also contain an [**ErrorInformation**](#errorinformation) element for the purpose of describing the error in more detail (for more information, see [Error Information in HTTP Response](#error-information-in-http-response)). + +
    + +### Error in Server During Processing of Request + +[Figure 68](#figure-68) shows an example of how to handle an error on a server during processing. + +###### Figure 68 + +![](../../assets/diagrams/sequence/figure68.svg) + + +**Figure 68 -- Error on server during processing of request** + +#### Internal Processing Steps + +The following list describes the steps in the sequence (see [Figure 68](#figure-68)). + +1. The client would like the server to create a new service object and thus uses a **POST** request. + +2. The server receives the request. It immediately sends an **accepted** response to the client, and then tries to create the object based on the service request. A processing error occurs, and the request cannot be handled as requested. The server sends the callback **_PUT_ /**_{resource}_**/**_{ID}_**/error** including an error code ([Error Codes](#error-codes)) and error description to notify the client of the error. + +3. The client receives the error callback and immediately responds with **OK**. The client then handles the error. + +4. The server receives the **OK** response and the process is completed. + +
    + +### Client Handling on Error Callback + +The following sections explain how a client handles error callbacks from a server. + +#### API Resource /participants + +The typical error from the **/participants** service is that the requested Party could not be found. The client could either try another server, or notify the end user that the requested Party could not be found. + +#### API Resource /parties + +The typical error from the **/parties** service is that the requested Party could not be found. The client could either try another server, or notify the end user that information regarding the requested Party could not be found. + +#### API Resource /quotes + +The typical error from the **/quotes** service is that a quote could not be calculated for the requested transaction. The client should notify the end user that the requested transaction could not be performed. + +#### API Resource /transactionRequests + +The typical error from the **/transactionRequests** service is that the Payer rejected the transaction or that an automatic validation failed. The client should notify the Payee that the transaction request failed. + +#### API Resource /authorizations + +The typical error from the **/authorizations** service is that the transaction request could not be found. The client should notify the Payer that the transaction request has been cancelled. + +#### API Resource /transfers + +The typical error from the **/transfers** service is that either the hop-to-hop transfer process or the end-to-end financial transaction failed. For example, a limit breach was discovered, or the Payee could not be found. The client (the Payer FSP) should in any error case cancel the reservation for the financial transaction that was performed before requesting the transaction to be performed on the server (the Payee FSP). See [Figure 69](#figure-69) for an example including a financial Switch between the FSPs. + +###### Figure 69 + +![](../../assets/diagrams/sequence/figure69.svg) + + +**Figure 69 -- Handling of error callback from POST /transfers** + +##### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 69](#figure-69)). + +1. The transfer is reserved from the Payer's account to either a combined Switch account or a Payee FSP account, depending on setup. After the transfer has been successfully reserved, the request [POST /transfers](#post-transfers) is used on the Switch. The transfer is now irrevocable from the Payer FSP. The Payer FSP then waits for an **accepted** response from the Switch. + +2. The Switch receives the request [POST /transfers](#post-transfers) and immediately sends an **accepted** response to the Payer FSP. The Switch then performs all applicable internal transfer validations. If the validations are successful, a transfer is reserved from a Payer FSP account to a Payee FSP account. After the transfer has been successfully reserved, the request [POST /transfers](#post-transfers) is used on the Payee FSP. The transfer is now irrevocable from the Switch. The Switch then waits for an **accepted** response from the Payee FSP. + +3. The Payee FSP receives the [POST /transfers](#post-transfers) and immediately sends an **accepted** response to the Switch. The Payee FSP then performs all applicable internal transaction validations. The validation is assumed to fail at this point, for example, due to a limit breach. The error callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) is used on the Switch to inform the Payer FSP about the error. The Payee FSP then waits for an **OK** response from the Switch to complete the transfer process. + +4. The Switch receives the error callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) and immediately responds with an **OK** response. The Switch then cancels the earlier reserved transfer, as it has received an error callback. The Switch will then use the callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) to the Payer FSP, using the same parameters, and wait for an **OK** response to complete the transfer process. + +5. The Payer FSP receives the callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) and immediately responds with an **OK** response. The Payer FSP then cancels the earlier reserved transfer because it has received an error callback. + +#### API Resource /transactions + +The normal error case from the **/transactions** service is that the transaction could not be found in the Peer FSP. + +#### API Resource /bulkQuotes + +The typical error from the **/bulkQuotes** service is that a quote could not be calculated for the requested transaction. The client should notify the end user that the requested transaction could not be performed. + +#### API Resource /bulkTransfers + +The typical error case from the **/bulkTransfers** service is that the bulk transaction was not accepted; for example, due to a validation error. The client (the Payer FSP) should in any error case cancel the reservation for the financial transaction that was performed before requesting that the transaction be performed on the server (the Payee FSP). See [Figure 70](#figure-70) for an example including a financial Switch between the FSPs. + +###### Figure 70 + +![](../../assets/diagrams/sequence/figure70.svg) + + +**Figure 70 -- Handling of error callback from API Service /bulkTransfers** + +##### Internal Processing Steps + +The following list describes the steps in the sequence (see [Figure 70](#figure-70)). + +1. Each individual transfer in the bulk transfer is reserved from the Payer's account to either a combined Switch account or a Payee FSP account, depending on setup. After each transfer has been successfully reserved, the request [POST /bulkTransfers](#post-bulktransfers) is used on the Switch. The bulk transfer is now irrevocable from the Payer FSP. The Payer FSP then waits for an **accepted** response from the Switch. + +2. The Switch receives the request [POST /bulkTransfers](#post-bulktransfers) and immediately sends an **accepted** response to the Payer FSP. The Switch then performs all applicable internal transfer validations. If the validations are successful, each individual transfer is reserved from a Payer FSP account to a Payee FSP account. After the transfers have been successfully reserved, the request [POST /bulkTransfers](#post-bulktransfers) is used on the Payee FSP. The bulk transfer is now irrevocable from the Switch. The Switch then waits for an **accepted** response from the Payee FSP. + +3. The Payee FSP receives [POST /bulkTransfers](#post-bulktransfers) and immediately sends an **accepted** response to the Switch. The Payee FSP then performs all applicable internal bulk transfer validations. The validation is assumed to fail due to some reason; for example, a validation failure that prevents the entire bulk transfer from being performed. The error callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) is used on the Switch to inform the Payer FSP about the error. The Payee FSP then waits for an **OK** response from the Switch to complete the bulk transfer process. + +4. The Switch receives the error callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) and immediately responds with an **OK** response. The Switch then cancels all the previous reserved transfers, because it has received an error callback. The Switch then uses the callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) to the Payer FSP, using the same parameters, and waits for an **OK** response to complete the bulk transfer process. + +5. The Payer FSP receives the callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) and immediately responds with an **OK** response. The Payer FSP then cancels all the earlier reserved transfers, as it has received an error callback. + +
    + +### Client Missing Response from Server - Using Resend of Request + +[Figure 71](#figure-71) shows an example UML (Unified Modeling Language) sequence diagram in which a client (FSP or Switch) performs error handling when the client misses a response from a server (Switch or Peer FSP) pertaining to a service request, using resend of the same service request. + +###### Figure 71 + +![](../../assets/diagrams/sequence/figure71.svg) + + +**Figure 71 -- Error handling from client using resend of request** + +#### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 71](#figure-71)). + +1. The client would like the server to create a new service object. The HTTP request is lost somewhere on the way to the server. + +2. The client notes that no response has been received from the server within a specified timeout. The client resends the service request. + +3. The server receives the resent request. It immediately sends an **accepted** response to the client, and then creates the object in accordance with the service request. + +4. The **accepted** HTTP response from the server is lost on the way to the client, and the client notes that no response has been received from the server within a specified timeout. The client resends the service request. + +5. The server receives the resent request. It immediately sends an **accepted** response to the client, and then notes that the service request is the same as in [Step 3](#figure-70). As the service request is a resend, the server should not create a new object based on the service request. The server sends a callback to notify the client about the object created in [Step 3](#figure-70). + +6. The client receives the callback regarding the created object. The client sends an **OK** HTTP response to the server to complete the process. + +7. The server receives the **OK** HTTP response from the client, completing the process. + +
    + +### Server Missing Response from Client + +A server using the API is not responsible for making sure that a callback is properly delivered to a client. However, it is considered good practice to retry if the server does not receive an **OK** response from the client. + +#### Client Missing Callback - Using GET request + +[Figure 72](#figure-72) is a UML sequence diagram showing how a client (Switch or Peer FSP) would perform error handling in case of no callback from a client (FSP or Switch) within a reasonable time. + +###### Figure 72 + +![](../../assets/diagrams/sequence/figure72.svg) + + +**Figure 72 -- Error handling from client using GET request** + +#### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 71](#figure-71)). + +1. The client would like the server to create a new service object; a service request is sent. + +2. The server receives the service request. It immediately sends an **accepted** response to the client, and then creates the object based on the service request. The object creation is a long running process; for example, a bulk transfer consisting of numerous financial transactions. + +3. The server notes that no callback has been received from the client within a reasonable time. The client uses a **GET** service request with the ID that was provided in the original service request. + +4. The server receives the **GET** service request. The server sends an accepted HTTP response to the client to notify that the request will be handled. + +5. The client receives the **accepted** HTTP response and waits for the callback, which arrives sometime later; the client sends an **OK** HTTP response and the process is completed. + +6. The server sends the callback to the client containing the requested information, and an **OK** HTTP response is received from the client, which completes the process. + +
    + +## End-to-End Example + +This section contains an end-to-end example in which an account holder is provisioned, and then a P2P Transfer from a Payer located in one FSP to a Payee located in another FSP is performed. The example includes both HTTP requests and responses, HTTP headers, and data models in JSON, but without additional security features of using JWS (see [_Signature_](./signature.md)) and field level encryption using JWE (see [_Encryption_](./encryption.md)). + +### Example Setup + +This section explains the setup of the example. + +#### Nodes + +###### Figure 73 + +The nodes in the end-to-end example in this section are simplified by having only two FSPs, where one FSP is a bank (identifier **BankNrOne**) and the other FSP is a mobile money operator (identifier **MobileMoney**), and one Switch (identifier **Switch**). The Switch also acts as the Account Lookup System (ALS) in this simplified setup (see [Figure 73](#figure-73)). + +![Figure 73](../../assets/diagrams/images/figure73.svg) + +**Figure 73 -- Nodes in end-to-end example** + +#### Account Holders + +The account holders in the example are: + +- One account holder in the FSP **BankNrOne** named Mats Hagman. Mats Hagman has a bank account with IBAN number **SE4550000000058398257466**. The currency of the account is USD. + +- One account holder in the FSP **MobileMoney** named Henrik Karlsson. Henrik Karlsson has a mobile money account that is identified by his phone number **123456789**. The currency of the account is USD. + +#### Scenario + +The scenario in the example is that Mats Hagman in FSP **BankNrOne** wants to transfer 100 USD to Henrik Karlsson in the FSP **MobileMoney**. Before Henrik Karlsson can be found by FSP **BankNrOne**, Henrik's FSP **MobileMoney** should provide information to the Switch specifying in which FSP Henrik Karlsson can be found in. The end-to-end flow including all used services can be found in [Other Notes](#other-notes). + +#### Other Notes + +The JSON messages used in the examples are formatted with color coding, indentations, and line breaks for very long lines to simplify the read of the examples. + +Both FSPs are assumed to have a pre-funded Switch account in their respective FSPs. + +### End-to-End Flow + +[Figure 74](#figure-74) shows the end-to-end flow of the entire example, from provisioning of FSP information to the actual transaction. + +###### Figure 74 + +![](../../assets/diagrams/sequence/figure74.svg) + + +**Figure 74 -- End-to-end flow, from provision of account holder FSP information to a successful transaction** + +### Provision Account Holder + +Before the Payee Henrik Karlsson can be found by the Payer FSP **BankNrOne**, Henrik Karlsson should be provisioned to the ALS, which is also the Switch in this simplified example, by Henrik's FSP (**MobileMoney**). This is performed through either one of the services [**POST /participants**](#6232-post-participants) (bulk version) or [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) (single version). As the Payee in this example is only one (Henrik Karlsson), the single [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) version is used by FSP **MobileMoney**. The provision could happen anytime, for example when Henrik Karlsson signed up for the financial account, or when the FSP **MobileMoney** connected to the Switch for the first time. + +#### FSP MobileMoney Provisions Henrik Karlsson: Step 1 in End-to-End Flow + +[Listing 29](#listing-29) shows the HTTP request where the FSP **MobileMoney** provisions FSP information for account holder Henrik Karlsson, identified by **MSISDN** and **123456789** (see [Party Addressing](#party-addressing) for more information). The JSON element **fspId** is set to the FSP identifier (MobileMoney), and JSON element **currency** is set to the currency of the account (USD). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, +and [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) for more information about the service ). **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 29 + +``` +POST /participants/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.participants+json;version=1 +Content-Length: 50 +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +Date: Tue, 14 Nov 2017 08:12:31 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 29 -- Provision FSP information for account holder Henrik Karlsson** + +[Listing 30](#listing-30) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 29](#listing-29). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 30 + +``` +HTTP/1.1 202 Accepted +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 30 -- Synchronous response on provision request** + +
    + +#### Switch Handles Provision: Step 2 in End-to-End Flow + +When the Switch has received the HTTP request in [Listing 29](#listing-29) and sent the synchronous response in [Listing 30](#listing-30), the Switch should verify the body of the request in [Listing 29](#listing-29). An example verification is to check that the **fspId** element is the same as the **FSPIOP-Source** , as it should be the FSP of the account holder who provisions the information. A scheme could also have restrictions on which currencies are allowed, which means that the Switch should then check that the currency in the **currency** element is allowed. + +After the Switch has verified the request correctly, the information that the account holder identified by **MSISDN** and **123456789** is located in FSP **MobileMoney** should be stored in the Switch's database. + +
    + +#### Switch Sends Successful Callback: Step 3 in End-to-End Flow + +When the Switch has successfully stored the information that the account holder identified by **MSISDN** and **123456789** is located in FSP **MobileMoney**, the Switch must send a callback using the service [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id) to notify the FSP **MobileMoney** about the outcome of the request in [Listing 29](#listing-29). [Listing 31](#listing-31) shows the HTTP request for the callback. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request. In the callback, the **Accept** header should not be used as this is a callback to an earlier requested service. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 29](#listing-29), as detailed in the section on [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id). + +###### Listing 31 + +``` +PUT /participants/MSISDN/123456789 HTTP/1.1 +Content-Length: 50 +Content-Type: +Date: Tue, 14 Nov 2017 08:12:32 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 31 -- Callback for the earlier requested provision service** + +[Listing 32](#listing-32) shows the synchronous HTTP response where the FSP **MobileMoney** immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 31](#listing-31). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 32 + +``` +HTTP/1.1 200 OK +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 32 -- Synchronous response for the callback** + +
    + +### P2P Transfer + +As the intended Payee Henrik Karlsson is now known by the Switch (which is also the ALS) as detailed in [Provision Account Holder](#provision-account-holder), Mats Hagman can now initiate and approve the use case P2P Transfer from his bank to Henrik Karlsson. + +#### Initiate Use Case: Step 4 in End-to-End Flow + +Mats Hagman knows that Henrik Karlsson has phone number **123456789**, so he inputs that number on his device as recipient and 100 USD as amount. The actual communication between Mats' device and his bank **BankNrOne** is out of scope for this API. + +
    + +#### Request Party Information from Switch: Step 5 in End-to-End Flow + +In Step 5 in the end-to-end flow, **BankNrOne** receives the request from Mats Hagman that he would like the phone number 123456789 to receive 100 USD. **BankNrOne** performs an internal search to see if 123456789 exists within the bank, but fails to find the account internally. **BankNrOne** then uses the service [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) in the Switch to see if the Switch knows anything about the account. + +[Listing 33](#listing-33) shows the HTTP request where the FSP **BankNrOne** asks the Switch for Party information regarding the account identified by **MSISDN** and **123456789**. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) for more information about the service. **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). In this request, the FSP **BankNrOne** does not know in which FSP the other account holder resides. Thus, the **FSPIOP-Destination** is not present. Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 33 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:37 GMT +FSPIOP-Source: BankNrOne +``` + +**Listing 33 -- Get Party information for account identified by MSISDN and 123456789 from FSP BankNrOne** + +[Listing 34](#listing-34) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 33](#listing-33). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 34 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 34 -- Synchronous response on the request for Party information** + +#### Request Party Information from FSP: Step 6 in End-to-End Flow + +When the Switch has received the HTTP request in [Listing 33](#listing-33) and sent the synchronous response in [Listing 34](#listing-34), the Switch can proceed with checking its database if it has information regarding in which FSP the account holder identified by **MSISDN** and **123456789** is located. As that information was provisioned as detailed in [Provisoin Account Holder](#provision-account-holder), the Switch knows that the account is in FSP **MobileMoney**. Therefore, the Switch sends the HTTP request in [Listing 35](#listing-35). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) for more information about the service. **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source); in this request the Switch has added the header **FSPIOP-Destination** because the Switch knew to where the request should be routed. Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + + + +###### Listing 35 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:38 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +``` + +**Listing 35 -- Get Party information for account identified by MSISDN and 123456789 from Switch** + +[Listing 36](#listing-36) shows the synchronous HTTP response where the FSP **MobileMoney** immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 35](#listing-35). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 36 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 36 -- Synchronous response on request for Party information** + +
    + +#### Lookup Party Information in FSP MobileMoney: Step 7 in End-to-End Flow + +When the FSP **MobileMoney** has received the HTTP request in [Listing 35](#listing-35) and sent the synchronous response in [Listing 36](#listing-36), the FSP **MobileMoney** can proceed with checking its database for more information regarding the account identified by **MSISDN** and **123456789**. As the account exists and is owned by Henrik Karlsson, the FSP **MobileMoney** sends the callback in [Listing 37](#listing-37). The FSP **MobileMoney** does not want to share some details, for example birth date, with the other FSP (**BankNrOne**), so some optional elements are not sent. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, +and [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id) for more information about the callback. **In** the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 35](#listing-35), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 37 + +```` +PUT /parties/MSISDN/123456789 HTTP/1.1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Content-Length: 347 +Date: Tue, 15 Nov 2017 10:13:39 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + } +} +```` + +**Listing 37 -- Callback to the request for Party information** + +[Listing 38](#listing-38) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 37](#listing-37). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 38 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 38 -- Synchronous response for the Party information callback** + +
    + +#### Send Callback to FSP BankNrOne: Step 8 in End-to-End Flow + +When the Switch has received the callback in [Listing 37](#listing-37) and sent the synchronous response in [Listing 38](#listing-38), it should relay the exact same callback as in [Listing 37](#listing-37) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the exact same response as in [Listing 38](#listing-38). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 37](#listing-37)) and from **BankNrOne** to the Switch (HTTP response in [Listing 38](#listing-38)) instead. + +
    + +#### Send Quote Request from FSP BankNrOne: Step 9 in End-to-End Flow + +After receiving Party information in the callback [PUT /parties/_{Type}_/_{ID}_](#put-parties-type-id), the FSP **BankNrOne** now knows that the account identified by **MSISDN** and **123456789** exists and that it is in the FSP **MobileMoney**. It also knows the name of the account holder. Depending on implementation, the name of the intended Payee (Henrik Karlsson) could be shown to Mats Hagman already in this step before sending the quote. In this example, a quote request is sent before showing the name and any fees. + +The FSP **BankNrOne** sends the HTTP request in [Listing 39](#listing-39) to request the quote. **BankNrOne** does not want to disclose its fees (see [Quoting](#quoting) for more information about quoting), which means that it does not include the **fees** element in the request. The **amountType** element is set to RECEIVE as Mats wants Henrik to receive 100 USD. The **transactionType** is set according to [Mapping of Use Cases to Transaction Types](#mapping-of-use-cases-to-transaction-types). Information about Mats is sent in the **payer** element. **BankNrOne** has also generated two UUIDs for the quote ID (7c23e80c-d078-4077-8263-2c047876fcf6) and the transaction ID (85feac2f-39b2-491b-817e-4a03203d4f14). These IDs must be unique, as described in [Architectural Style](#architectural-style). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [Section 6.5.3.2](#6532-post-quotes) for more information about the service [POST /quotes](#6532-post-quotes). **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 39 + +```` +POST /quotes HTTP/1.1 +Accept: application/vnd.interoperability.quotes+json;version=1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 975 +Date: Tue, 15 Nov 2017 10:13:40 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amountType": "RECEIVE", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats", + "expiration": "2017-11-15T22:17:28.985-01:00" +} +```` + +**Listing 39 -- Request quote for transaction of 100 USD** + +[Listing 40](#listing-40) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 39](#listing-39). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 40 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Listing 40 -- Synchronous response on quote request** + +#### Send Quote Request from Switch: Step 10 in End-to-End Flow** + +When the Switch has received the quote request in [Listing 39](#listing-39) and sent the synchronous response in [Listing 40](#listing-40), it should relay the same request as in [Listing 39](#listing-39) to the FSP **MobileMoney**, and **MobileMoney** should then respond synchronously with the same response as in [Listing 40](#listing-40). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **MobileMoney** (HTTP request in [Listing 39](#listing-39)) and from **MobileMoney** to the Switch (HTTP response in [Listing 40](#listing-40)) instead. + +
    + +#### Determine fees and FSP commission in FSP MobileMoney: Step 11 in End-to-End Flow + +When the FSP **MobileMoney** has received the HTTP request in [Listing 39](#listing-40) and sent the synchronous response in [Listing 40](#listing-40), the FSP **MobileMoney** should validate the request and then proceed to determine the applicable fees and/or FSP commission for performing the transaction in the quote request. + +In this example, the FSP **MobileMoney** decides to give 1 USD in FSP commission as the FSP **MobileMoney** will receive money, which should later generate more income for the FSP (future possible fees). Since the Payee Henrik Karlsson should receive 100 USD and the FSP commission is determined to 1 USD, the FSP **BankNrOne** only needs to transfer 99 USD to the FSP **MobileMoney** (see [Non Disclosing Receive Amount](#non-disclosing-receive-amount) for the equation). The 99 USD is entered in the transferAmount element in the callback, which is the amount that should later be transferred between the FSPs. + +To send the callback, the FSP **MobileMoney** then needs to create an ILP Packet (see [ILP Packet](#ilp-packet) for more information) that is base64url-encoded, as the **ilpPacket** element in the [PUT /quotes/_{ID}_](#put-quotes-id) callback is defined as a [BinaryString](#binarystring). How to populate the ILP Packet is explained in [Interledger Payment Request](#interledger-payment-request). Henrik's ILP address in the FSP **MobileMoney** has been set to **g.se.mobilemoney.msisdn.123456789** (see [ILP Addressing](#ilp-addressing) for more information about ILP addressing). As the transfer amount is 99 USD and the currency USD's exponent is 2, the amount to be populated in the ILP Packet is 9900 (99 \* 10\^2 = 9900). The remaining element in the ILP Packet is the **data** element. As described in [Interledger Payment Request](#interledger-payment-request), this element should contain the Transaction data model (see [Transaction](#transaction)). With the information from the quote request, the Transaction in this example becomes as shown in [Listing 41](#listing-41). Base64url-encoding the entire ILP Packet with the **amount**, **account**, and the **data** element then results in the **ilpPacket** element in the [PUT /quotes/_{ID}_](#put-quotes-id) callback. + +When the ILP Packet has been created, the fulfilment and the condition can be generated as defined in the algorithm in [Listing 12](#listing-12). Using a generated example secret shown in [Listing 42](#listing-42) (shown as base64url-encoded), the fulfilment becomes as in [Listing 43](#listing-43) (shown as base64url-encoded) after executing the HMAC SHA-256 algorithm on the ILP Packet using the generated secret as key. The FSP **MobileMoney** is assumed to save the fulfilment in the database, so that it does not have to be regenerated later. The condition is then the result of executing the SHA-256 hash algorithm on the fulfilment, which becomes as in [Listing 44](#listing-44) (shown as base64url-encoded). + +The complete callback to the quote request becomes as shown in [Listing 45](#listing-45). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [PUT /quotes/_{ID}_](#put-quotes-id) for more information about the callback. **The** _{ID}_ in the URI should be taken from the quote ID in the quote request, which in the example is 7c23e80c-d078-4077-8263-2c047876fcf6. In the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 39](#listing-39), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 41 + +``` +{ + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amount": { + "amount": "99", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats" +} +``` + +**Listing 41 -- The Transaction JSON object** + +###### Listing 42 + +``` +JdtBrN2tskq9fuFr6Kg6kdy8RANoZv6BqR9nSk3rUbY +``` + +**Listing 42 -- Generated secret, encoded in base64url** + +###### Listing 43 + +``` +mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s +``` + +**Listing 43 -- Calculated fulfilment from the ILP Packet and secret, encoded in base64url** + +###### Listing 44 + +``` +fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG\_fqGnR7Xs +``` + +**Listing 44 -- Calculated condition from the fulfilment, encoded in base64url** + +###### Listing 45 + +``` +PUT /quotes/7c23e80c-d078-4077-8263-2c047876fcf6 HTTP/1.1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 1802 +Date: Tue, 15 Nov 2017 10:13:41 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "transferAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2017-11-15T14:17:09.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", + "condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 45 -- Quote callback** + +**Note:** The element **ilpPacket** in [Listing 45](#listing-45) should be on a single line in a real implementation; it is shown with line breaks in this example in order to show the entire value. + +[Listing 46](#listing-46) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 45](#listing-45). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 46 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Listing 46 -- Synchronous response on the quote callback** + +#### Send Callback to FSP BankNrOne: Step 12 in End-to-End Flow + +When the Switch has received the quote callback in [Listing 45](#listing-45) and sent the synchronous response in [Listing 46](#listing-46), it should relay the exact same callback as in [Listing 45](#listing-45) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the exact same response as in [Listing 46](#listing-46). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 45](#listing-45)) and from **BankNrOne** to the Switch (HTTP response in [Listing 46](#listing-46)) instead. + +
    + +#### Determine fees in FSP BankNrOne: Step 13 in End-to-End Flow + +When the FSP **BankNrOne** has received the quote callback in [Listing 45](#listing-45) and sent the synchronous response in [Listing 46](#listing-46), the FSP **BankNrOne** can proceed with determining the fees for the Payer Mats Hagman. In this example, the fee for the Payer is set to 0 USD, but the FSP commission from the FSP **MobileMoney** is kept as an income for the FSP **BankNrOne**. This means that for the Payee Henrik Karlsson to receive 100 USD, the Payer Mats Hagman must transfer 100 USD from his account. 99 USD will then be transferred between the FSPs **BankNrOne** and **MobileMoney**. + +The FSP **BankNrOne** then notifies Mats Hagman that the transaction to transfer 100 USD to Henrik Karlsson will cost 0 USD in fees. How Mats Hagman is notified is out of scope of this API. + +
    + +#### Payer Accepts Transaction: Step 14 in End-to-End Flow + +In this example, Mats Hagman accepts to perform the transaction. How the acceptance is sent is outside the scope of this API. + +#### Send Transfer Request from FSP BankNrOne: Step 15 in End-to-End Flow + +When Mats Hagman has accepted the transaction, FSP **BankNrOne** reserves the internal transfers needed to perform the transaction. This means that 100 USD will be reserved from Mats Hagman's account, where 1 USD will end up as income for the FSP and 99 USD will be transferred to the prefunded Switch account. After the reservations are successfully performed, the FSP **BankNrOne** sends a [POST /transfers](#post-transfers) to the Switch as in [Listing 47](#listing-47). The same ilpPacket and condition elements are sent as was received in the quote callback and the **amount** is the same as the received **transferAmount**, see [Listing 45](#listing-45). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [Post Transfers](#post-transfers) for more information about the service [POST /transfers](#post-transfers).**More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 47 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:17:01.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 47 -- Request to transfer from FSP BankNrOne to FSP MobileMoney** + +**Note:** The element **ilpPacket** in [Listing 47](#listing-47) should be on a single line in a real implementation, it is shown with line breaks in this example for being able to show the entire value. + +[Listing 48](#listing-48) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 47](#listing-47). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 48 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Listing 48 -- Synchronous response on transfer request** + +
    + +#### Send Transfer Request from Switch: Step 16 in End-to-End Flow + +When the Switch has received the transfer request in [Listing 47](#listing-47) and sent the synchronous response in [Listing 48](#listing-48), it should reserve the transfer from **BankNrOne**'s account in the Switch to **MobileMoney**'s account in the Switch. After the reservation is successful, the Switch relays nearly the same request as in [Listing 47](#listing-47) to the FSP **MobileMoney**; expect that the **expiration** element should be decreased as mentioned in [Timeout and Expiry](#timeout-and-expiry). [Listing 49](#listing-49) shows the HTTP request with the **expiration** decreased by 30 seconds compared to [Listing 47](#listing-47). The FSP **MobileMoney** should then respond synchronously with the same response as in [Listing 48](#listing-48). + +###### Listing 49 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:16:31.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 49 -- Request to transfer from FSP BankNrOne to FSP MobileMoney with decreased expiration** + +**Note:** The element **ilpPacket** in [Listing 49](#listing-49) should be on a single line in a real implementation; it is shown with line breaks in this example in order to show the entire value. + +
    + +#### Perform Transfer in FSP MobileMoney: Step 17 in End-to-End Flow + +When the FSP **MobileMoney** has received the transfer request in [Listing 47](#listing-47), it should perform the transfer as detailed in the earlier quote request, this means that 100 USD should be transferred to Henrik Karlsson's account, where 99 USD is from the prefunded Switch account and 1 USD is from an FSP commission account. + +As proof of performing the transaction, the FSP **MobileMoney** then retrieves the stored fulfilment [(Listing 43](#listing-43)) from the database (stored in [Determine Fees and FSP commission in FSP MobileMoney](#determine-fees-and-fsp-commission-in-fsp-mobilemoney-step-11-in-end-to-end-flow)) and enters that in the **fulfilment** element in the callback [PUT /transfers/_{ID}_](#put-transfersid). The **transferState** is set to COMMITTED and the **completedTimestamp** is set to when the transaction was completed; see [Listing 50](#listing-50) for the complete HTTP request. + +At the same time, a notification is sent to the Payee Henrik Karlsson to +say that he has received 100 USD from Mats Hagman. + +How the notification is sent is out of scope for this API. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [PUT /transfers/_{ID}_](#put-transfersid) for more information about the callback. **The** _{ID}_ in the URI should be taken from the transfer ID in the transfer request, which in the example is 11436b17-c690-4a30-8505-42a2c4eafb9d. In the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 47](#listing-47), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 50 + +``` +PUT /transfers/11436b17-c690-4a30-8505-42a2c4eafb9d HTTP/1.1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 166 +Date: Tue, 15 Nov 2017 10:14:02 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "completedTimestamp": "2017-11-16T04:15:35.513+01:00", + "transferState": "COMMITTED" +} +``` + +**Listing 50 -- Callback for the transfer request** + +[Listing 51](#listing-51) shows the synchronous HTTP response in which the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 50](#listing-50). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 51 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Listing 51 -- Synchronous response on the transfers callback** + +
    + +#### Payee Receives Transaction Notification: Step 18 in End-to-End Flow + +The Payee Henrik Karlsson receives the transaction notification, and is thereby informed of the successful transaction. + +
    + +#### Perform Transfer in Switch: Step 19 in End-to-End Flow + +When the Switch has received the transfer callback in [Listing 50](#listing-50) and sent the synchronous response in [Listing 51](#listing-51), it should validate the fulfilment, perform the earlier reserved transfer and relay the exact same callback as in [Listing 50](#listing-50) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the same response as in [Listing 51](#listing-51). + +The validation of the fulfilment is done by calculating the SHA-256 hash of the fulfilment and ensuring that the hash is equal to the condition from the transfer request. + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 50](#listing-51)) and from **BankNrOne** to the Switch (HTTP response in [Listing 51](#listing-51)) instead. + +
    + +#### Perform Transfer in FSP BankNrOne: Step 20 in End-to-End Flow + +When the FSP **BankNrOne** has received the transfer callback in [Listing 50](#listing-50) and sent the synchronous response in [Listing 51](#listing-51), the FSP **BankNrOne** should validate the fulfilment (see [Section 10.4.16](#10416-perform-transfer-in-switch----step-19-in-end-to-end-flow)) and then perform the earlier reserved transfer. + +After the reserved transfer has been performed, the Payer Mats Hagman should be notified of the successful transaction. How the notification is sent is outside the scope of this API. + +#### Payer Receives Transaction Notification: Step 21 in End-to-End Flow + +The Payer Mats Hagman receives the transaction notification and is thereby informed of the successful transaction. + + + + + +1 [http://www.ics.uci.edu/\~fielding/pubs/dissertation/rest\_arch\_style.htm](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) -- Representational State Transfer (REST) + +2 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- A Universally Unique IDentifier (UUID) URN Namespace + +3 [https://tools.ietf.org/html/rfc7230](https://tools.ietf.org/html/rfc7230) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing + +4 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) -- The Transport Layer Security (TLS) Protocol - Version 1.2 + +5 [https://tools.ietf.org/html/rfc3986](https://tools.ietf.org/html/rfc3986) -- Uniform Resource Identifier (URI): Generic Syntax + +6 [https://tools.ietf.org/html/rfc7230\#section-2.7.3](https://tools.ietf.org/html/rfc7230#section-2.7.3) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing - http and https URI Normalization and Comparison + +7 [https://tools.ietf.org/html/rfc3629](https://tools.ietf.org/html/rfc3629) -- UTF-8, a transformation format of ISO 10646 + +8 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) -- The JavaScript Object Notation (JSON) Data Interchange Format + +9 [https://tools.ietf.org/html/rfc7230\#section-3.2](https://tools.ietf.org/html/rfc7230#section-3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing - Header Fields + +10 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Accept + +11 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing -- Content-Length + +12 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Content-Type + +13 [https://tools.ietf.org/html/rfc7231\#section-7.1.1.2](https://tools.ietf.org/html/rfc7231#section-7.1.1.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Date + +14 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) -- X-Forwarded-For + +15 [https://tools.ietf.org/html/rfc7239](https://tools.ietf.org/html/rfc7239) -- Forwarded HTTP Extension + +16 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing -- Content-Length + +17 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Content-Type + +18 [https://tools.ietf.org/html/rfc7231\#section-4](https://tools.ietf.org/html/rfc7231#section-4) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Request Methods + +19 [https://tools.ietf.org/html/rfc7231\#section-6](https://tools.ietf.org/html/rfc7231#section-6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Response Status Codes + +20 [https://tools.ietf.org/html/rfc7231\#section-6.4](https://tools.ietf.org/html/rfc7231#section-6.4) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Redirection 3xx + +21 [https://tools.ietf.org/html/rfc7231\#section-6.6](https://tools.ietf.org/html/rfc7231#section-6.6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Server Error 5xx + +22 [https://tools.ietf.org/html/rfc7231\#section-6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - 406 Not Acceptable + +23 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Accept + +24 [https://interledger.org/rfcs/0011-interledger-payment-request/](https://interledger.org/rfcs/0011-interledger-payment-request/) -- Interledger Payment Request (IPR) + +25 [https://interledger.org/](https://interledger.org/) -- Interledger + +26 [https://interledger.org/interledger.pdf](https://interledger.org/interledger.pdf) -- A Protocol for Interledger Payments + +27 [https://interledger.org/rfcs/0001-interledger-architecture/](https://interledger.org/rfcs/0001-interledger-architecture/) -- Interledger Architecture + +28 [https://interledger.org/rfcs/0015-ilp-addresses/](https://interledger.org/rfcs/0015-ilp-addresses/) -- ILP Addresses + +29 [https://www.itu.int/rec/dologin\_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items) -- Information technology -- ASN.1 encoding rules: Specification of Octet Encoding Rules (OER) + +30 [https://perldoc.perl.org/perlre.html\#Regular-Expressions](https://perldoc.perl.org/perlre.html#Regular-Expressions) -- perlre - Perl regular expressions + +31 [https://tools.ietf.org/html/rfc7159\#section-7](https://tools.ietf.org/html/rfc7159#section-7) -- The JavaScript Object Notation (JSON) Data Interchange Format - Strings + +32 [http://www.unicode.org/](http://www.unicode.org/) -- The Unicode Consortium + +33 [https://www.iso.org/iso-8601-date-and-time-format.html](https://www.iso.org/iso-8601-date-and-time-format.html) -- Date and time format - ISO 8601 + +34 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- A Universally Unique IDentifier (UUID) URN Namespace + +35 [https://tools.ietf.org/html/rfc4648\#section-5](https://tools.ietf.org/html/rfc4648#section-5) -- The Base16, Base32, and Base64 Data Encodings - Base 64 Encoding with URL and Filename Safe Alphabet + +36 [https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html) -- Currency codes - ISO 4217 + +37 [https://www.itu.int/rec/T-REC-E.164/en](https://www.itu.int/rec/T-REC-E.164/en) -- E.164 : The international public telecommunication numbering plan + +38 [https://tools.ietf.org/html/rfc3696](https://tools.ietf.org/html/rfc3696) -- Application Techniques for Checking and Transformation of Names + +39 [https://tools.ietf.org/html/rfc7231\#section-6.5](https://tools.ietf.org/html/rfc7231#section-6.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Client Error 4xx \ No newline at end of file diff --git a/docs/technical/api/fspiop/v1.1/encryption.md b/docs/technical/api/fspiop/v1.1/encryption.md new file mode 100644 index 000000000..714e27fde --- /dev/null +++ b/docs/technical/api/fspiop/v1.1/encryption.md @@ -0,0 +1,638 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# Encryption + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +| **Type of Information** | **Convention** | **Example** | +| :--- | :--- | :--- | +| **Elements of the API, such as resources** | Boldface | **/authorization** | +| **Variables** | Italics within curly brackets | _{ID}_ | +| **Glossary terms** | Italics on first occurrence; defined in _Glossary_ | The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. | +| **Library documents** | Italics | User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead. | + +### Document Version Information + +| **Version** | **Date** | **Change Description** | +| :--- | :--- | :--- | +|**1.1**|2020-05-19|This version contains these changes: 1. ExstensionList elements in Section 4 have been updated based on the issue [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), to fix the data model of the extensionList Object.| +| **1.0** | 2018-03-13 | Initial version | + +
    + +## Introduction + +This document details security methods to be implemented for Open API (Application Programming Interface) for FSP (Financial Service Provider) Interoperability (hereafter cited as "the API") to ensure confidentiality of API messages between an API client and the API +server. + +In information security, _confidentiality_ means that information is not made available or disclosed to unauthorized individuals, entities, or processes (excerpt from ISO27000[The ISO 27000 Directory](http://www.27000.org)). For the API, confidentiality means that some sensitive fields in the payload of an API message cannot be accessed or identified in an unauthorized or undetected manner by the intermediaries involved in the API communication. That is, if some fields of an API message are encrypted by the API client, then only the expected API recipient can decrypt those fields. + +JSON Web Encryption (JWE, defined in RFC 7516[JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516)) must be applied to the API to provide end to end message confidentiality. When an API client sends an HTTP request (such as an API request or callback message) to a counterparty, the API client can determine whether there are sensitive fields in the API message to be protected according to the regulation or local schema. If there is a field to be protected, then the API client uses JWE to encrypt the value of that field. Subsequently, the cipher text of that field will be transmitted to the counterparty. + +To support encryption for multiple fields of an API message, JWE is extended in this document to adapt to the requirements of the API. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](../json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](#) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## API Encryption Definition + +This section introduces the technology used by API encryption, including: + +- Data exchange format for the encrypted fields of an API message. + +- Mechanism for encrypting and decrypting fields. + +### Encryption Data Model + +The API uses the customized HTTP header parameter **FSPIOP-Encryption** to represent the encrypted fields of an API message; its value is a JSON object serialization. The data model of this parameter is described in [Table 1](#table-1), [Table 2](#table-2) and [Table 3](#table-3). + +**Note**: If **FSPIOP-Encryption** is present in an API message, then it must also be protected by the API signature. That means **FSPIOP-Encryption** must be included in the JWS Protected Header of the signature. + +###### Table 1 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedFields** | 1 | EncryptedFields | Information about the encrypted fields of an API message | +**Table 1 -- Data model of HTTP Header Field FSPIOP-Encryption** + +###### Table 2 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedField** | 1..* | EncryptedField | Information about the encrypted field of an API message | +**Table 2 -- Data model of complex type EncryptedFields** + +###### Table 3 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +|**fieldName** | 1 | String(1..512) | This element identifies the field to be encrypted in the payload of an API message.
    Because the API payload is a JSON Object serialization string, the field name must be able to identify the exact element path in the JSON Object. A single period ('**.**') character is used to separate the elements in an element path. For example, **payer.personalInfo.dateOfBirth** is a valid value for this element for the API request **POST /quotes**.
    | +| **encryptedKey** | 1 | String(1..512) | Encrypted Content Encryption Key (CEK) value. Its value is encoded by BASE64URL(JWE Encrypted Key).
    If there are multiple fields of the API message to be encrypted, we recommend that the same JWE Encrypted Key be used to simplify the implementation; however, this is a decision to be made by each FSP internally based on their implementation.
    | +|**protectedHeader** | 1 | String(1..1024) | This element identifies the Header Parameters that are applied to JWE to encrypt the specified field. Its value is encoded by BASE64URL(UTF8(JWE Protected Header)).
    For example, if the JWE Protected Header applied to the encryption is ```{"alg":"RSA-OAEP- 256","enc":"A256GCM"}```, then the value is ```eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ```.
    | +| **initializationVector** | 1 | String(1..128) | Initialization Vector value used when encrypting the plaintext. Its value is encoded by BASE64URL(JWE Initialization Vector). | +| **authenticationTag** | 1 | String(1..128) | Authentication Tag value resulting from authenticated encryption of the plaintext with Additional Authenticated Data. Its value is encoded by BASE64URL(JWE Authentication Tag) | +**Table 3 -- Data model of complex type EncryptedField** + +### Encrypt Fields of API Message + +This section describes the encryption process for message fields. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. + +1. Determine the algorithm used to determine the CEK value (this is the algorithm recorded in the **alg** (algorithm) Header Parameter of the resulting JWE). Because the CEK should be encrypted with the public key of the API recipient, in the API the available algorithms to protect the CEK can only be **RSA-OAEP-256**. +2. If there are multiple fields to be encrypted in the API message, then perform Steps 3-15 for each field. +3. Generate a random CEK. The FSP can generate the value using either its own application or using the JWE implementation employed. +4. Encrypt the CEK with the algorithm determined by the JWE header parameter **alg**. +5. Compute the encoded key value BASE64URL(JWE Encrypted Key). +6. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm (if required for the algorithm); otherwise, let the JWE Initialization Vector be the empty octet sequence. +7. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). +8. If a **zip** parameter was included, compress the plaintext using the specified compression algorithm and let *M* be the octet sequence representing the compressed plain text; otherwise, let _M_ be the octet sequence representing the plain text. +9. Create the JSON object or objects containing the desired set of header parameters, which together comprise the JWE Protected Header. Besides the parameter **alg**, the parameter **enc** must be included in the JWE Protected Header. The available values for the parameter **enc** in the API can only be: **A128GC**_M_, **A192GC**_M_, **A256GC**_M_. **A256GC**_M_ is recommended. +10. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). +11. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +12. Encrypt *M* using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +13. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). +14. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). +15. Compute the **encryptedField** element (see Table 3) for the HTTP header parameter **FSPIOP-Encryption**. +16. Compute the value for the HTTP Header parameter **FSPIOP-Encryption** as described in [FSPIOP API](/fspiop) documentation. The value for this **FSPIOP-Encryption** is JSON Object Serialization string. + +**Note**: If JWE is used to encrypt some fields of the payload, then the API client should: + +1. Encrypt the desired fields. + +2. Replace those fields' value with the encoded cipher text in the payload. + +3. Sign the payload. + +### Decrypt Fields of API Message + +If the HTTP Header parameter **FSPIOP-Encryption** (which is also protected by the API signature) is present, then the API message recipient should decrypt the encrypted fields of the API message after the API signature is validated successfully. The message decryption process is the reverse of the encryption process. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. If there are multiple fields being encrypted, then all fields must be decrypted successfully; otherwise it indicates the API message is invalid. + +1. Parse the HTTP Header parameter **FSPIOP-Encryption** to get encrypted fields' information, including field name, JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, and JWE Authentication Tag for each field. If there are multiple fields being encrypted, then perform Steps 2-9 for each encrypted field. +2. Get the cipher text of the encrypted field by parsing the payload with the specified field path. The value of the specified field is already encoded with BASE64URL. +3. Verify that the octet sequence resulting from decoding the encoded JWE Protected Header is a UTF-8-encoded representation of a valid JSON object conforming to JSON Data Interchange Format (defined in RFC 7159[The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)); let the JWE Protected Header be this JSON object. +4. Verify that the parameters in the JWE Protected Header understand and can process all fields that are required to support the JWE specification; for example, the algorithm being used. +5. Determine that the algorithm specified by the **alg** (algorithm) Header Parameter matches the algorithm of the public / private key of the API recipient. +6. Decrypt the JWE Encrypted Key with the private key of the API recipient to get the JWE CEK. +7. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +8. Decrypt the JWE Cipher Text using the CEK, the JWE Initialization Vector, the Additional Authenticated Data value, and the JWE Authentication Tag (which is the Authentication Tag input to the calculation) using the specified content encryption algorithm, returning the decrypted plaintext and validating the JWE Authentication Tag in the manner specified for the algorithm. If the JWE Authentication Tag is incorrect, then reject the input without any decryption. +9. If a **zip** parameter was included, then the API recipient should decompress the decrypted plaintext using the specified compression algorithm. + +## API Encryption/Decryption Examples + +This section uses a typical quote process to explain how the API encryption and decryption are implemented using JWE. As the algorithm of public / private key of the API recipient can only be RSA, the RSA key used for this example is represented in JSON Web Key (JWK, defined in RFC 7517[JSON Web Key(JWK)](https://tools.ietf.org/html/rfc7517)) format below (with line breaks and indentation within values for display purposes only): + +```json +{ + "kty": "RSA", + "n": "oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E- + BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9Le + wND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH- + PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5tw + XTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC- + FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm- + L5StowjzGy-_bq6Gw", + "e": "AQAB", + "d": "kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4- + WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93D + t62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3 + kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOz + lpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K- + VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ", + "p": "1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ- + SWxkbk- + moEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lffNn03IXqWF5M + DFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0", + "q": + "wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBmUDdaD + YVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aXIWxKwd4gvxF + ImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc", + "dp": "ZK- + YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo-uz- + KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgq + rXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE", + "dq": + "Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCjywcMlY + Yg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDBUfCAiJVeESOj + JDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis", + "qi": "VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8- + ZW1FxU7AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E + 3eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY" +} +``` + +### Encryption Example + +The following message text is an example of POST /quotes without encryption sent by Payer FSP to a Payee FSP. + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +``` + +```json +{ + "payee": { + "partyIdInfo": { "partyIdType": "MSISDN", "partyIdentifier": "15295558888", + "fspId": "5678" } }, + "amountType": "RECEIVE", + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", "initiatorType": "CONSUMER" }, + "note": "this is a sample for POST /quotes", + "amount": { "amount": "150","currency": "USD" }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1"}, + { "value": "value2", "key": "key2"}, + { "value": "value3", "key": "key3" } + ] + }, + "geoCode": { "latitude": "57.323889", "longitude": "125.520001" + }, + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "complexName": { "firstName": "Bill", "middleName": "Ben", "LastName": "Lee" + }, "dateOfBirth": "1986-02-14" }, + "partyIdInfo": { "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": "16135551212", + "fspId": "1234" + }, "name": "Bill Lee" + }, "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc" +} +``` + +In this case, the Payer FSP would like to encrypt two fields of the API message: **payer** and **payee.partyIdInfo.partyIdentifier**. + +#### Encrypt the Required Fields + +Because there are two fields to be encrypted, the Payer FSP needs to encrypt the two fields one-by-one. + +##### Encrypt "payer" + +The Payer FSP performs the following steps to encrypt the field **payer** in the **POST /quotes** API message. + +1. Determine the algorithm used to determine the CEK value. In this case, assuming it is **RSA-OAEP-256**. +2. Generate a 256-bit random CEK. In this case, its value is (using JSON Array notation): + +``` +191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167 +``` + +3. Encrypt the CEK with the Payee FSP's public key shown in JSON Web +Key format in [API Encryption/Decryption Examples](#api-encryptiondecryption-examples). In this case, the encrypted value is (using JSON Array notation): + +``` +22 210 45 47 153 95 183 79 84 26 194 42 27 152 50 195 163 18 235 121 140 120 224 129 180 120 21 0 46 196 21 114 251 148 127 75 198 42 87 250 186 98 15 136 249 131 224 73 111 108 159 140 107 156 80 30 133 77 86 26 28 13 66 83 248 229 132 77 203 113 229 24 208 155 81 172 9 164 25 126 206 217 25 206 30 218 38 190 128 196 250 233 34 47 86 91 157 140 87 240 29 119 126 136 168 10 87 246 213 23 104 114 215 134 71 87 46 55 131 174 15 193 194 90 194 208 212 15 24 33 143 38 253 125 121 175 220 202 106 95 127 129 192 2 72 137 14 40 147 207 166 239 161 248 159 203 52 223 103 129 54 83 85 199 211 228 56 82 83 135 166 103 42 76 191 146 80 40 192 123 42 18 31 113 25 198 24 58 87 149 47 182 144 86 182 137 253 103 214 34 192 76 254 64 14 114 97 194 28 60 75 164 131 170 210 231 168 205 181 78 79 136 82 115 218 174 5 48 158 162 230 229 164 85 26 135 15 164 206 36 182 131 115 224 207 12 178 234 145 6 181 140 243 41 8 151 +``` + +4. Compute the encoded key value BASE64URL(JWE Encrypted Key). In this case, its value is: + +``` +FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g-BJb2yfjGucUB6 FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE-ukiL1ZbnYxX8B13foioClf21Rdoct eGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU 4emZypMv5JQKMB7KhIfcRnGGDpXlS-2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPa rgUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw +``` + +5. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm. In this case, its value is (using JSON Array notation): + +``` +101 98 192 15 167 157 93 152 54 145 173 236 83 4 6 243 +``` + +6. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). In this case, its value is: + +``` +ZWLAD6edXZg2ka3sUwQG8w +``` + +7. Get the plaintext of the field **payer** of the API message as the payload to be encrypted. In this case, its value is: + +```json +{ + "personalInfo": { + "dateOfBirth": "1986-02-14", "complexName": { + "middleName": "Ben", "lastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": "16135551212" + } +} +``` + +8. Create the JSON object or objects containing the desired set of header parameters, which together comprise the JWE Protected Header. In this case, its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +9. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). In this case, its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +10. Let the Additional Authenticated Data encryption parameter be ASCII(Base64URL(JWE Protected Header)). +11. Encrypt the plain text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +12. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). In this case its value is: + +``` +BfXbxoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs_Nvk ZkE4WlqGNlQ_nBS1xYknxjh7hkPVb-V-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4- 4ejXXv80cbknRJtDl_mmjaU_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8h fPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB1OeZRq06ZBEfKZzAAJ0u3KZqoO BAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6YugwFotZbg +``` + +13. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +9GaZEDZD9wmzqVGCI-FDgQ +``` + +##### Encrypt payee.partyIdInfo.partyIdentifier + +1. Determine the algorithm used to determine the CEK value. In this case, assuming it is **RSA-OAEP-256**. +2. Generate a 256-bit random CEK. In this case, the same CEK defined in [Encryption Data Model](#encryption-data-model) is used., Its value is (using JSON Array notation): + +``` +191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167 +``` + +3. Encrypt the CEK with the Payee FSP's public key represented in JSON Web Key format in [API Encryption/Decryption Examples](#api-encryptiondecryption-examples). In this case, its value is (using JSON Array notation): + +``` +149 174 138 153 221 70 241 229 93 27 56 185 185 210 242 238 81 187 207 88 40 43 24 7 245 121 94 73 151 150 249 19 15 158 11 97 80 99 194 60 143 138 168 211 202 210 52 19 128 211 156 179 101 248 95 163 23 166 217 222 14 12 163 206 242 182 170 211 119 22 84 107 3 97 153 207 240 211 82 113 100 254 39 62 224 183 250 176 156 63 198 73 245 187 239 16 136 127 120 130 146 236 29 47 255 116 223 240 39 224 94 165 102 120 242 9 182 84 138 109 205 55 242 20 186 91 140 49 198 244 250 58 123 3 63 22 51 59 5 183 112 17 160 238 34 217 11 109 79 246 174 221 138 118 82 21 15 239 72 185 77 20 178 20 192 89 45 68 140 190 251 233 82 123 33 49 191 135 49 21 25 42 253 171 211 151 7 238 142 206 201 140 206 6 129 23 173 56 153 159 31 39 52 119 102 147 197 213 230 97 113 71 168 184 6 57 183 109 173 233 206 110 112 202 179 74 56 153 184 122 114 234 151 28 15 131 79 192 80 145 130 170 188 82 92 61 121 90 63 148 37 110 20 132 49 131 +``` + +**Note**: Although the same CEK is used for the two fields **payer** and **payee.partyIdInfo.partyIdentifier**, the encrypted CEK values may be different from each other because of the use of a random number when encrypting the CEK by JWE implementations (for example, jose4j, nimbus-jose-jwt, and so on). This depends on how the JWE is implemented in each FSP system. +4. Compute the encoded key value BASE64URL(JWE Encrypted Key). In this case, its value is: + +``` +la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI-KqNPK0jQTgNOcs2X4X6M XptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u--niH94gpLsHS__dN_wJ-BepW Z48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1Ej L776VJ7ITG_hzEVGSr9q9OXB-6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqz SjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw +``` + +5. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm. In this case, its value is (using JSON Array notation): + +``` +86 250 136 87 147 231 201 138 65 75 164 215 147 100 136 195 +``` + +6. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). In this case, its value is: + +``` +VvqIV5PnyYpBS6TXk2SIww +``` + +7. Get the plain text of the field **payee.partyIdInfo.partyIdentifier** of the API message as the payload to be encrypted. In this case, its value is + +``` +15295558888 +``` + +8. Create the JSON object or objects containing the desired set of Header Parameters, which together comprise the JWE Protected Header. In this case, its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +9. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). In this case, its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +10. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +11. Encrypt the plain text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +12. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). In this case its value is: + +``` +WBQN5nLDGK26EiM +``` + +13. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +6jQVo7kmZq3jMNXfavxoXQ +``` + +#### Producing FSPIOP-Encryption + +Using the given data model of the header **FSPIOP-Encryption**, get the header's value as shown below (line break and indentation are only for display purpose): + +```json +{ + "encryptedFields": + [ + { + "initializationVector":"ZWLAD6edXZg2ka3sUwQG8w", + "fieldName":"payer", + "encryptedKey":"FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g- + BJb2yfjGucUB6FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE- + ukiL1ZbnYxX8B13foioClf21RdocteGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcAC- + SIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU4emZypMv5JQKMB7KhIfcRnGGDpXlS- + 2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPargUwnqLm5aRVGo- + cPpM4ktoNz4M8MsuqRBrWM8ykIlw", + "authenticationTag":"9GaZEDZD9wmzqVGCI-FDgQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + }, + { + "initializationVector":"VvqIV5PnyYpBS6TXk2SIww", + "fieldName":"payee.partyIdInfo.partyIdentifier", + "encryptedKey":"la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI- + KqNPK0jQTgNOcs2X4X6MXptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u-- + niH94gpLsHS__dN_wJ-BepWZ48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEa- + DuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1EjL776VJ7ITG_hzEVGSr9q9OXB- + 6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqzS- + jiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw", + "authenticationTag":"6jQVo7kmZq3jMNXfavxoXQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + } + ] +} +``` + +#### Re-produce API message with encryption + +Using the cipher text of the encrypted field to replace the plain text of the corresponding field of the API message (the string with, **light grey** background in the message text below), add parameter **FSPIOP-Encryption** (the string with **light grey** background in the message text below) into the HTTP header of the API message. + +**Note**: The **FSPIOP-Encryption** parameter should be included in the JWS Protected Header for the signature of the API message, and the HTTP body of the API message below should be the JWS Payload for the signature. The signature process is out-of- scope for this document. + +```json +POST /quotes HTTP/1.1 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +FSPIOP-Destination:5678 +Content-Length:1068 +FSPIOP-Encryption: {"encryptedFields":{ + "initializationVector":"ZWLAD6edXZg2ka3sUwQG8w", + "fieldName":"payer", + "encryptedKey":"FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX- +rpiD4j5g-BJb2yfjGucUB6FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE- +ukiL1ZbnYxX8B13foioClf21RdocteGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu- +h-J_LNN9ngTZTVcfT5DhSU4emZypMv5JQKMB7KhIfcRnGGDpXlS- +2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk- +IUnPargUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw", + "authenticationTag":"9GaZEDZD9wmzqVGCI-FDgQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + }, { + "initializationVector":"VvqIV5PnyYpBS6TXk2SIww", + "fieldName":"payee.partyIdInfo.partyIdentifier", + "encryptedKey":"la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI- +KqNPK0jQTgNOcs2X4X6MXptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u-- +niH94gpLsHS__dN_wJ- +BepWZ48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD- +9IuU0UshTAWS1EjL776VJ7ITG_hzEVGSr9q9OXB- +6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqzSjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw", + "authenticationTag":"6jQVo7kmZq3jMNXfavxoXQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + } + ] +} +{"amount":{"amount":"150","currency":"USD"},"transactionType":{"scenario":"TRANSFER","initiator":"PAYER","subScenario":"P2P Transfer across MM systems","initiatorType":"CONSUMER"},"transactionId":"36629a51-393a-4e3c-b347-c2cb57e1e1fc","quoteId":"59e331fa-345f-4554-aac8-fcd8833f7d50","payer":"BfXbcoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs_NvkZkE4WlqGNlQ_nBS1xYknxjh7hkPVb-B-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4-4ejXXv80cbknRJtDl_mmjaU_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8hfPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB10eZRq06ZBEfKZzAAJ0u3KZqoOBAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6ugwFotZbg","expiration":"2017-05-24T08:40:00.000-04:00","payee":{"partyIdInfo":{"fspId":"5678","partyIdType":"MSISDN","partyIdentifier":"WBQN5nLDGK26EiM"}},"fees":{"amount":"1.5","currency":"USD"},"extensionList":{"extension":[{"value":"value1","key":"key1"},{"value":"value2","key":"key2"},{"value":"value3","key":"key3"}]},"note":"this is a sample for POST/quotes","geoCode":{"longitude":"125.520001","latitude":"57.323889"},"amountType":"RECEIVE"} +``` + +### Decryption Example + +In this example, the Payee FSP receives the POST /quotes API message from Payer FSP. The message is described in [Encryption Data Model](#encryption-data-model). If the Payee FSP detects that the HTTP header parameter **FSPIOP-Encryption** is present in the message, then the Payee FSP knows that some fields were encrypted by the Payer FSP. The Payee FSP then performs the following steps to decrypt the encrypted fields.] + +#### Parse FSPIOP-Encryption + +The Payee FSP verifies that the value of **FSPIOP-Encryption** is a UTF-8-encoded representation of a valid JSON object conforming to RFC 7159. The FSP then parses the HTTP Header parameter **FSPIOP-Encryption** to get encrypted fields information, including field name, JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, and JWE Authentication Tag for each field. + +#### Decrypt the Encrypted Fields + +In this case, the Payee FSP gets two fields **payer** and **payee.partyIdInfo.partyIdentifier** from the HTTP header **FSPIOP- Encryption**. Then the Payee FSP decrypts the two fields one-by-one. + +##### Decrypt payer + +The Payer FSP performs the following steps to decrypt the field **payer** in the **POST /quotes** API message. + +1. Get the encoded BASE64RUL(JWE Protected Header) from the parsed **FSPIOP-Encryption** for the field **payer**. In this case its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +2. Decode the encoded JWE Protected Header. In this case its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM" +``` + +3. Check that the decoded value of JWE Protected Header is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format (RFC 7159), and that the parameters in the JWE Protected Header can process all fields that are required to support the JWE specification. +4. Get the encoded BASE64URL(JWE Encrypted Key). In this case its value is: + +``` +FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g-BJb2yfjGucUB6 FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE-ukiL1ZbnYxX8B13foioClf21Rdoct eGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU 4emZypMv5JQKMB7KhIfcRnGGDpXlS-2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPa rgUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw] +``` + +5. Decode the encoded JWE Encrypted Key. In this case its value is as follows (using JSON Array notation): + +``` +[22 210 45 47 153 95 183 79 84 26 194 42 27 152 50 195 163 18 235 121 140 120 224 129 180 120 21 0 46 196 21 114 251 148 127 75 198 42 87 250 186 98 15 136 249 131 224 73 111 108 159 140 107 156 80 30 133 77 86 26 28 13 66 83 248 229 132 77 203 113 229 24 208 155 81 172 9 164 25 126 206 217 25 206 30 218 38 190 128 196 250 233 34 47 86 91 157 140 87 240 29 119 126 136 168 10 87 246 213 23 104 114 215 134 71 87 46 55 131 174 15 193 194 90 194 208 212 15 24 33 143 38 253 125 121 175 220 202 106 95 127 129 192 2 72 137 14 40 147 207 166 239 161 248 159 203 52 223 103 129 54 83 85 199 211 228 56 82 83 135 166 103 42 76 191 146 80 40 192 123 42 18 31 113 25 198 24 58 87 149 47 182 144 86 182 137 253 103 214 34 192 76 254 64 14 114 97 194 28 60 75 164 131 170 210 231 168 205 181 78 79 136 82 115 218 174 5 48 158 162 230 229 164 85 26 135 15 164 206 36 182 131 115 224 207 12 178 234 145 6 181 140 243 41 8 151] +``` + +6. Decrypt the JWE Encrypted Key using the specified algorithm **RSA-OAEP-256** with the Payee FSP's private key to get the CEK. In this case the decrypted CEK is (using JSON Array notat ion): + +``` +[191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167] +``` + +7. Get the encoded BASE64URL(JWE Initialization Vector). Its value is: + +``` +ZWLAD6edXZg2ka3sUwQG8w +``` + +8. Decode the encoded JWE Initialization Vector. In this case, its value is (using JSON Array notation): + +``` +[101 98 192 15 167 157 93 152 54 145 173 236 83 4 6 243] +``` + +9. Get the value of the field **payer** from the API message as the encoded BASE64URL(JWE Cipher Text) to be decrypted. In this case, its value is + +``` +BfXbxoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs\_Nvk ZkE4WlqGNlQ\_nBS1xYknxjh7hkPVb-V-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4- 4ejXXv80cbknRJtDl\_mmjaU\_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8h fPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB1OeZRq06ZBEfKZzAAJ0u3KZqoO BAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6YugwFotZbg +``` + +10. Get the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +9GaZEDZD9wmzqVGCI-FDgQ +``` + +11. Decrypt the cipher text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to decrypt the JWE Cipher text. In this case, the plain text is + +```json +{ + "personalInfo": { + "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", "lastName": "Lee", + "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { + "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": + "16135551212" + } +} +``` + +12. Verify that the plaintext is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159, and the content matches the data mode definition for the **payer**. + +##### Decrypt payee.partyIdInfo.partyIdentifier + +The Payer FSP performs the following steps to decrypt the field **payee.partyIdInfo.partyIdentifier** in the **POST /quotes** API message. + +1. Get the encoded BASE64RUL(JWE Protected Header) from the parsed **FSPIOP-Encryption** for the field **payee.partyIdInfo.partyIdentifier**. In this case its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +2. Decode the encoded JWE Protected Header. In this case its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +3. Verify that the decoded value of JWE Protected Header is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159, and that the parameters in the JWE Protected Header understand and can process all fields that are required to support the JWE specification. +4. Get the encoded BASE64URL(JWE Encrypted Key). In this case its value is: + +``` +la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI-KqNPK0jQTgNOcs2X4X6M XptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u--niH94gpLsHS__dN_wJ-BepW Z48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1Ej L776VJ7ITG_hzEVGSr9q9OXB-6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqz SjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw +``` + +5. Decode the encoded JWE Encrypted Key. In this case its value is (using JSON Array notation): + +``` +[149 174 138 153 221 70 241 229 93 27 56 185 185 210 242 238 81 187 207 88 40 43 24 7 245 121 94 73 151 150 249 19 15 158 11 97 80 99 194 60 143 138 168 211 202 210 52 19 128 211 156 179 101 248 95 163 23 166 217 222 14 12 163 206 242 182 170 211 119 22 84 107 3 97 153 207 240 211 82 113 100 254 39 62 224 183 250 176 156 63 198 73 245 187 239 167 136 127 120 130 146 236 29 47 255 116 223 240 39 224 94 165 102 120 242 9 182 84 138 109 205 55 242 20 186 91 140 49 198 244 250 58 123 3 63 22 51 59 5 183 112 17 160 238 34 217 11 109 79 246 174 221 138 118 82 21 15 239 72 185 77 20 178 20 192 89 45 68 140 190 251 233 82 123 33 49 191 135 49 21 25 42 253 171 211 151 7 238 142 206 201 140 206 6 129 23 173 56 153 159 31 39 52 119 102 147 197 213 230 97 113 71 168 184 6 57 183 109 173 233 206 110 112 202 179 74 56 153 184 122 114 234 151 28 15 131 79 192 80 145 130 170 188 82 92 61 121 90 63 148 37 110 20 132 49 131] +``` + +6. Decrypt the JWE Encrypted Key using the specified algorithm **RSA-OAEP-256** with the Payee FSP's private key to get the CEK. In this case the decrypted CEK is (using JSON Array notation): + +``` +[191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167] +``` + +7. Get the encoded BASE64URL(JWE Initialization Vector). Its value is: + +``` +VvqIV5PnyYpBS6TXk2SIww +``` + +8. Decode the encoded JWE Initialization Vector. In this case, its value is (using JSON Array notation): + +``` +[86 250 136 87 147 231 201 138 65 75 164 215 147 100 136 195] +``` + +9. Get the value of the field **payee.partyIdInfo.partyIdentifier** from the API message as the encoded BASE64URL(JWE Cipher Text) to be decrypted. In this case, its value is: + +``` +WBQN5nLDGK26EiM +``` + +10. Get the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +6jQVo7kmZq3jMNXfavxoXQ +``` + +11. Decrypt the cipher text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to decrypt the JWE Cipher text. In this case, the plain text is + +``` +15295558888 +``` + +12. Verify that the plain text is a valid **partyIdentifier** value. + +
    + +## Table of Tables +- [Table 1 -- Data model of HTTP Header Field FSPIOP-Encryption](#table-1) +- [Table 2 -- Data model of complex type EncryptedFields](#table-2) +- [Table 3 -- Data model of complex type EncryptedField](#table-3) \ No newline at end of file diff --git a/docs/technical/api/fspiop/v1.1/signature.md b/docs/technical/api/fspiop/v1.1/signature.md new file mode 100644 index 000000000..6512726b1 --- /dev/null +++ b/docs/technical/api/fspiop/v1.1/signature.md @@ -0,0 +1,426 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- +# Signature + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +This document uses the notational conventions for BASE64URL(OCTETS), UTF8(STRING), ASCII(STRING), and || defined in RFC 7515[1](https://tools.ietf.org/html/rfc7515#section-1.1). + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.1**|2020-05-19|This version contains the below changes: 1. Sections 3.1, 3.2 and 3.3 have been updated based on ”Solution Proposal 12 - Clarify usage of FSPIOP-Destination”. 2. ExtensionList elements in Section 4 have been updated based on the issue [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), to fix the data model of the extensionList Object.| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document details the security methods to be implemented for Open API for FSP Interoperability (hereafter cited as the API) to ensure _integrity_ and _non-repudiation_ between the API client and the API server. + +In information security, _data integrity_ means maintaining and assuring the accuracy and completeness of data over its entire life-cycle. For the API, data integrity means that an API message cannot be modified in an unauthorized or undetected manner by parties involved in the API communication. + +In legal terms, _non-repudiation_ means that a person intends to fulfill their obligations to a contract. It also means that one party in a transaction cannot deny having received the transaction, nor can the other party deny having sent the transaction. For the API, non-repudiation means that an API client cannot deny having sent an API message to a counterparty. JSON Web Signature (JWS), as defined in RFC 7515[2](https://tools.ietf.org/html/rfc7515), must be applied to the API to provide message integrity and non-repudiation for either component fields of an API payload or the full API payload. Whenever an API client sends an API message to a counterparty, the API client should sign the message using its private key. After the counterparty receives the API message, the counterparty must validate the signature with the API client’s public key. Only the HTTP request message of an API message need to be signed, any HTTP response message of the APIs SHALL NOT be signed. + +**Note:** The corresponding public key should either be shared in advance with the counterparty or retrieved by the counterparty (for example, the local scheme Certificate Authority). + +Because intermediary fees are not supported in the current version of the API, intermediaries involved in API message-transit may not modify the API message payload. Thus, the signature at full payload level is used to protect the integrity of the full payload of an API message from end-to-end. Regardless of how many intermediaries there are in transit, the original payload cannot be modified by the intermediaries. The final recipient of the API message must validate the signature generated by the original API client based on the message payload received. + +**Note:** Whether the signature needs to be validated by the intermediaries in transit is determined by the internal implementation of each intermediary or the local schema. + +**Note:** In a future version of the API, intermediary fees may be supported; at that time, signature-at-field-level may also be supported. However, both features are out-of-scope for the current version of the API. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./definitions) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](#) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](../glossary) + +
    + +## API Signature Definition + +This section introduces the technology used by the API signature, including the data exchange format for the signature of an API message and the mechanism used to generate and verify a signature. + + +### Signature Data Model + +The API uses a customized HTTP header parameter **FSPIOP-Signature** to represent the signature that is produced by the initiating API client for the API message. The data model for this parameter is described in [Table 1](#table-1). + +**Note:** Currently the API does not support intermediaries in an API message; only the message-initiator can sign a message. If this is required in the future, there will be new customized HTTP header parameter, but this is out-of-scope for the current version of the API. + +###### Table 1 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| protectedHeader | 1 | String(1..32768) |
    This element indicates the HTTP header parameters that are protected by the signature. Its value must be BASE64URL(UTF8(JWS Protected Header)).

    According to JWS specification, the **alg** header parameter must be present to identify the cryptographic algorithm used to secure the JWS.

    A customized parameter **FSPIOP-URI** that represents the URI path and query parameters of HTTP request message of the APIs must be present.

    A customized parameter **FSPIOP-HTTP-Method** that holds the HTTP method used in the HTTP message must be present.

    A customized parameter **FSPIOP-Source** that represents the system which sent the API request must be present.

    The customized HTTP header parameter **FSPIOP-Destination** is mandatory in protectedHeader if the destination FSP is known by the message-initiator. Otherwise this header must not be protected as it can be changed by intermediate systems. See API Definition for more information regarding which services that the header FSPIOP-Destination is optional for.
    | +| signature | 1 | String(1..512) | This element indicates the signature. Its value is part of JWS serialization; that is, BASE64URL(JWS Signature). | +**Table 1 – Data model of HTTP header field FSPIOP-Signature** + +### Generating a Signature + +To create the signature for an API message, the following steps are performed. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. + +1. Create the content to be used as the JWS Payload. Because the signature is currently at full payload level, the full HTTP body of the API message is the JWS Payload. + +2. Compute the encoded payload value BASE64URL(JWS Payload). + +3. Create the JSON object or objects containing the desired JWS Protected Header. + + A. The **alg** JWS Protected Header parameter must be present. In the API, the available algorithms for the signature are **RS256, RS384, RS512**. A key of size 2048 bits or larger must be used with these algorithms. + + B. Other parameters registered in the IANA JSON _Web Signature and Encryption Header Parameters_[3](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) are optional. + + C. The customized parameter **FSPIOP-URI** must be included in JWS Protected Header to protect the URI path and query parameters of the APIs. + + D. The customized parameter **FSPIOP-HTTP-Method** must be included in JWS Protected Header to protect the HTTP request operation method. + + E. The parameter **FSPIOP-Source** must be present, and its value comes from the corresponding HTTP header parameter **FSPIOP-Source**. + + F. The parameter **FSPIOP-Destination** must be present if the destination FSP is known by the message-initiator, and its value must then be the same as the HTTP header parameter **FSPIOP-Destination**. + + G. Other HTTP Header parameters of the APIs are recommended to be included in JWS Protected Header, but they are optional in this JWS Protected Header. + +4. Compute the encoded header value BASE64URL(UTF8(JWS Protected Header)). + +5. Compute the JWS Signature according to the JWS specification using the output of Step 2 and Step 4. + +6. Compute the encoded signature value BASE64URL(JWS Signature). + +7. Compute the value for the HTTP header parameter **FSPIOP-Signature** as described in the [Signature Data Model](#signature-data-model) section. The value for this **FSPIOP-Signature** is a JSON Object Serialization string. + +**Note:** If JSON Web Encryption (JWE) is used to encrypt some fields of the payload (for more information, see Encryption), then the API client should first encrypt the desired fields, then replace the plain text of those fields with the encoded cipher text in the payload, and then finally sign the payload. + +### Validating Signature + +When validating the signature of an API request, the following steps are performed. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. If any of the listed steps fails, then the signature cannot be validated. + +1. Parse the HTTP header parameter **FSPIOP-Signature** to get the components **protectedHeader** and **signature**. + +2. Use BASE64URL to decode the encoded representation of the JWS Protected Header. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format, defined in RFC 7159[4](https://tools.ietf.org/html/rfc7159). + +3. Verify the parameters in the JWS Protected Header. + + a) The parameter **alg** must be present and its value must be one of **RS256, RS384, RS512**. + + b) Other parameters registered in the IANA JSON _Web Signature and Encryption Header Parameters_ are optional. + + c) The parameter **FSPIOP-URI** must be present and Its value must be the same as the input URL value of the request. + + d) The parameter **FSPIOP-HTTP-Method** must be present and its value must be same as the operation method of the request. + + e) The parameter **FSPIOP-Source** must be present, and its value must be the same as the corresponding HTTP header parameter **FSPIOP-Source**. + + f) If the parameter **FSPIOP-Destination** is present in the JWS Protected Header, then its value must be same as the corresponding HTTP header parameter **FSPIOP-Destination**. + + g) If there are other HTTP header parameters present in JWS Protected Header, then their values must be validated with the corresponding HTTP header values. + +4. Compute the encoded payload value BASE64URL(JWS Payload). Because the current signature is at full payload level, the full HTTP body of the API message is the JWS Payload. + +5. Validate the JWS Signature against the JWS Signing Input ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)) in the manner defined for the algorithm being used, which must be accurately represented by the value of the **alg** (algorithm) Header Parameter. + +6. Record whether the validation succeeded. + +
    + +## API Signature Examples + +This section uses a typical quote process to explain how the API signature is implemented using JWS. The FSPs in the API can verify that their internal implementation for API signature is correct using the following case. + +The case in this section uses RS256 as the signature algorithm. The RSA key used for the signature example is represented in JSON Web Key (JWK), defined in RFC 7517[5](https://tools.ietf.org/html/rfc7517), format below (with line breaks and indentation within values for display purposes only): + +```json +{ + "kty": "RSA", + "n": "ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", + "e": "AQAB", + "d": "Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ", + "p": "4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdiYrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPGBY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc", + "q": "uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxaewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc", + "dp": "BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3QCLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0", + "dq": "h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-kyNlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU", + "qi": "IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2oy26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLUW0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U" +} +``` + +### Generating a Sample Signature + +The following message text is an example of `POST /quotes` without a signature sent by Payer FSP to a counterparty (line breaks and indentation within values for display purposes only). + +```json +POST /quotes HTTP/1.1 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Source:1234 +FSPIOP-Destination:5678 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +{ + "amount": { "amount": "150", "currency": "USD" },"transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER","subScenario": "P2P Transfer across MM systems","initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc","quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50","expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer","partyIdentifier": "16135551212" } + }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } + }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { + "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +#### Computing Signature Input + +According to JWS specification, the signature input is BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload). + +Assuming the HTTP header parameters **Date** and **FSPIOP-Destination** are protected by the signature, and the algorithm RS256 is used to sign the message, the JWS Protected Header in this case is as follows (line breaks and indentation within values for display purposes only): + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +Encoding this JWS Protected Header as BASE64URL(UTF8(JWS Protected Header)) gives this value: + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +In this case, JWS Payload is the HTTP Body described in [Generating A Signature](#generating-a-signature) section. Encoding this JWS Payload as BASE64URL(JWS Payload) gives this value: + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +#### Producing Signature + +Use the given RSA Private Key, the JWS Protected Header and the JWS Payload to generate the signature, then encoding the signature as BASE64URL(JWS Signature) produces this value: + +``` +dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-uve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGw-QkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg +``` + +#### Re-produce API Request with Signature + +As described in the [Signature Data Model](#signature-data-model) section, the API signature is represented by a customized HTTP header parameter **FSPIOP-Signature**; thus the API request with the signature in this case is the following message text (line breaks and indentation within values for display purposes only). + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Signature: {"signature": "dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEBuve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGwQkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg", "protectedHeader": "eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9" +} +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +### Validating the Signature + +After the Payee FSP receives the `POST /quotes` API message from Payer FSP, the Payee FSP must validate the signature signed by the Payer FSP. + +#### Parse FSPIOP-Signature + +1. Parse the HTTP header parameter **FSPIOP-Signature** to get the components **protectedHeader** and signature. In this case, the value of **protectedHeader** is: + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjo +iL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYX +kgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +2. Use BASE64URL to decode the encoded representation of the JWS Protected Header. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format, defined in RFC7159. In this case, the decoded JSON object is: + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +3. Verify that the **alg** parameter is valid for the API. That means it must be in the list of **RS256, RS384, RS512**. In this case, the value of **alg** is **RS256**, which is valid. + +4. Verify that the value of the parameter **FSPIOP-URI** is same as the input URL of this API message. + +5. Verify that the value of the parameter **FSPIOP-HTTP-Method** is same as the HTTP method of this API message. + +6. Verify that the value of the HTTP header parameter **FSPIOP-Source** is the same as the corresponding value listed in this JWS Protected Header. + +7. Verify that the values for the HTTP header parameter **FSPIOP-Destination** are the same as the corresponding values stated in this JWS Protected Header. + +8. Verify the other protected HTTP header parameters. In this case, the **Date** parameter is protected by JWS Protected Header. If the parameters **Date** in the HTTP header of this API message and **Date** in the JWS Protected Header are equal, then the validation is successful. Both **Date** parameters in the example should be the following value: + +``` +"Tue, 23 May 2017 21:12:31 GMT" +``` + +The validation is passed. + +#### Verify JWS Signature + +1. In this case, the JWS Payload is the full HTTP body of the API message, that is (line breaks and indentation within values for display purposes only): + +```json +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", + "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} + ``` + +2. Compute the encoded payload value BASE64URL(JWS Payload). Get the encoded value as: + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +3. Validate the JWS Signature against the JWS Signing Input (that is, the JWS Protected Header, JWS Payload) with the specified algorithm **RS256** (specified in the JWS Protected Header), and the public key. Record whether the validation succeeded or not. + +
    + +## References + +1 [https://tools.ietf.org/html/rfc7515#section-1.1](https://tools.ietf.org/html/rfc7515#section-1.1) – JSON Web Signature (JWS) - Notational Conventions + +2 [https://tools.ietf.org/html/rfc7515](https://tools.ietf.org/html/rfc7515) - JSON Web Signature (JWS) + +3 [https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) - JSON Web Signature and Encryption Header Parameters + +4 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) - The JavaScript Object Notation (JSON) Data Interchange Format + +5 [https://tools.ietf.org/html/rfc7517](https://tools.ietf.org/html/rfc7517) - JSON Web Key (JWK) diff --git a/docs/technical/api/license.md b/docs/technical/api/license.md new file mode 100644 index 000000000..4bf2f2526 --- /dev/null +++ b/docs/technical/api/license.md @@ -0,0 +1,27 @@ +# LICENSE + +This API specification is made available by **Ericsson**, **Huawei**, **Mahindra-Comviva**, **Telepin**, and the **Bill & Melinda Gates Foundation** under a **Creative Commons Attribution-NoDerivatives 4.0 International** License. In order to help maintain the integrity of the text of this document that reflects the underlying charitable goals of this project, we are circulating under a CC-BY license that prohibits the creation of derivative works based on this document. We ask that you do not create or distribute derivatives of this documentation. + +The Bill & Melinda Gates Foundation believes that an economy that includes everyone, benefits everyone. In support of this goal, we asked leading mobile wallet technology providers Ericsson, Huawei, Mahindra-Comviva and Telepin to work together to create a set of APIs for interoperability within the digital financial services infrastructure. Together with consultants from **Interledger** and **Modusbox**, the group worked to produce the APIs documented below. + +The underlying charitable goal for the API is to spur innovation and access to digital products and services that serve the financially underserved with a focus on interoperability, and strengthening and accelerating the availability of solutions that reflect the design principles of **L1P** as documented on www.leveloneproject.org. The contributors commit to making the relevant background technology which is provided to the API project necessary to implement the API in furtherance of the charitable goals available on a royalty-free basis. + +[**Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0)**](https://creativecommons.org/licenses/by-nd/4.0/) + +#### You are free to: +Share — copy and redistribute the material in any medium or format for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms. +_____________________ + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + +NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + +No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +________________________________ + +#### Notices: + +You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. \ No newline at end of file diff --git a/docs/technical/api/settlement/README.md b/docs/technical/api/settlement/README.md new file mode 100644 index 000000000..4fe520c99 --- /dev/null +++ b/docs/technical/api/settlement/README.md @@ -0,0 +1,8 @@ +--- +showToc: false +--- +# Settlement API + + + + diff --git a/docs/technical/api/thirdparty/README.md b/docs/technical/api/thirdparty/README.md new file mode 100644 index 000000000..0a05cd1e1 --- /dev/null +++ b/docs/technical/api/thirdparty/README.md @@ -0,0 +1,41 @@ +# Third Party API + +The Third Party API is an API for non-fund-holding participants to interact over a centralized Mojaloop hub. +Specifically, this API allows Payment Initiation Service Providers (PISPs) to act as a proxy in initiating +payments, while allowing for the strong authentication of users. + +## Terms + +The following terms are commonly used across the Third Party API Documentation + +| **Term** | **Alternative and Related Terms** | **Definition** | **Source** | +| --- | --- | --- | --- | +| **Payment Initiation Service Provider** | PISP, 3rd Party Payment Initiator (3PPI) | Regulated entities like retail banks or third parties, that allow customers to make payments without accessing bank accounts or cards | [PSD2](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32015L2366&qid=1633311418487) | +| **FSP** | Provider, Financial Service Provider (FSP), Payment Service Provider, Digital Financial Services Provider (DFSP) | The entity that provides a digital financial service to an end user (either a consumer, a business, or a government.) In a closed-loop payment system, the Payment System Operator is also the provider. In an open-loop payment system, the providers are the banks or non-banks which participate in that system. | [ITU-T](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-E.pdf) | +| **User** | End User | An end user that is shared between a PISP and DFSP. Mostly used in the context of a real human being, but this could also be a machine user, or a business for example | +| **Consent** | Account Link | A representation of an agreement between the DFSP, PISP and User | | +| **Auth-Service** | | A service run by the Mojaloop Hub that is responsible for verifying and storing Consents, and verifying transaction request signatures | | + +## API Definitions + +The Third Party API is defined across the following OpenAPI 3.0 files: + +- [Third Party API - PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +- [Third Party API - DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml) + +The implementation of these APIs will depend on the role of the participant. PISPs should implement the [Third Party API - PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +interface in order to request and manage Account Linking operations, and initiate Third Party Transaction Requests. + +DFSPs who wish to support Account Linking operations, and be able to respond to and verify Third Party Transaction Requests should +implement the [Third Party API - DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml). + +## Transaction Patterns + +The interactions and examples of how a DFSP and PISP will interact with the Third Party API can be found in the following Transaction Patterns Documents: + +1. [Linking](./transaction-patterns-linking.md) describes how an account link and credential can be established between a DFSP and a PISP +2. [Transfer](./transaction-patterns-transfer.md) describes how a PISP can initate a payment from a DFSP's account using the account link + +## Data Models + +The [Data Models Document](./data-models.md) describes in detail the Data Models used in the Third Party API diff --git a/docs/technical/api/thirdparty/_sync_docs.sh b/docs/technical/api/thirdparty/_sync_docs.sh new file mode 100644 index 000000000..fd92ad483 --- /dev/null +++ b/docs/technical/api/thirdparty/_sync_docs.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +## +# Synchronises the definition docs from their disparate locations into one place. +# +# The API Spec for the Third Party API is managed by the api-snippets project +## + +set -eu + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +GIT_URL="https://github.com/mojaloop/api-snippets.git" +BRANCH='master' +CLONE_DIR='/tmp/api-snippets' + +rm -rf ${CLONE_DIR} + +git clone -b ${BRANCH} ${GIT_URL} ${CLONE_DIR} + +# API definition, grab from mojaloop/pisp-project +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-dfsp-api.yaml ${DIR}/thirdparty-dfsp-v1.0.yaml +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-pisp-api.yaml ${DIR}/thirdparty-pisp-v1.0.yaml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml new file mode 100644 index 000000000..b07cf9129 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml @@ -0,0 +1,49 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Pre-linking + +box "Mobile device" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +autonumber 1 "PRE-#" +activate App +App -> PISP ++: What DFSPs are available to link with? + + +PISP -> Switch ++: ""GET /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: pispa""\n""FSPIOP-Destination: switch"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> PISP ++: ""PUT /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: switch""\n""FSPIOP-Destination: pispa""\n\ + ""{""\n\ + "" "serviceProviders": ["" \n\ + "" "dfspa", "dfspb""" \n\ + "" ]"" \n\ + ""}"" +PISP --> Switch: ""200 OK"" + +PISP --> App --: We have dfspa and dfspb\n + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg new file mode 100644 index 000000000..1b57f3a75 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg @@ -0,0 +1,72 @@ + + PISP Linking: Pre-linking + + + PISP Linking: Pre-linking + + Mobile device + + PISP + + Mojaloop + + + + + + + + + App + + PISP + + Switch + + + + + + + PRE-1 + What DFSPs are available to link with? + + + PRE-2 + GET /services/THIRD_PARTY_DFSP + FSPIOP-Source: pispa + FSPIOP-Destination: switch + + + PRE-3 + 202 Accepted + + + PRE-4 + PUT /services/THIRD_PARTY_DFSP + FSPIOP-Source: switch + FSPIOP-Destination: pispa +   + { +    + "serviceProviders": [ +   +    + "dfspa", "dfspb + " +    + ] +   +   + } + + + PRE-5 + 200 OK + + + PRE-6 + We have dfspa and dfspb +   + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml new file mode 100644 index 000000000..c719fb2af --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.puml @@ -0,0 +1,85 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title PISP Linking: Discovery + +box "Mobile device" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +... + +note over App, DFSP + The user will be prompted in the PISP App for the unique ID they use with their DFSP, and the type of identifier they use. This could be a an account ALIAS, MSISDN, email address, etc. +end note + +... + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> Switch ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over App, DFSP + The PISP can now present a list of possible accounts to the user for pairing. +end note + +... + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg new file mode 100644 index 000000000..1a1a475ec --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/1-discovery.svg @@ -0,0 +1,151 @@ + + PISP Linking: Discovery + + + PISP Linking: Discovery + + Mobile device + + PISP + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + App + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + + The user will be prompted in the PISP App for the unique ID they use with their DFSP, and the type of identifier they use. This could be a an account ALIAS, MSISDN, email address, etc. + + + DISC-1 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-2 + 202 Accepted + + + DISC-3 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-4 + 202 Accepted + + + DISC-5 + PUT /accounts/username1234 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + [ +    + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, +    + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } +    + ] + + + DISC-6 + 200 OK + + + DISC-7 + PUT /accounts/username1234 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + [ +    + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, +    + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } +    + ] + + + DISC-8 + 200 OK + + + The PISP can now present a list of possible accounts to the user for pairing. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml new file mode 100644 index 000000000..8d52071bc --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml @@ -0,0 +1,119 @@ +@startuml + + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Request consent (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the consentRequest validity + + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" + +note over PISP, DFSP + Here, the DFSP sends an OTP directly to the user (e.g., via SMS). +end note + +deactivate DFSP + +Switch -> PISP: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +""{""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + At this point, the PISP knows that the OTP authChannel is in use and the PISP App should prompt the user to provide the OTP. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg new file mode 100644 index 000000000..aefe18062 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg @@ -0,0 +1,203 @@ + + PISP Linking: Request consent (OTP) + + + PISP Linking: Request consent (OTP) + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + REQ-5 + Verify the consentRequest validity + + + REQ-6 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa + { +    + authChannels: [ "OTP" ], +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-7 + 200 OK + + + Here, the DFSP sends an OTP directly to the user (e.g., via SMS). + + + REQ-8 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa + { +    + authChannels: [ "OTP" ], +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-9 + 200 OK + + + At this point, the PISP knows that the OTP authChannel is in use and the PISP App should prompt the user to provide the OTP. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml new file mode 100644 index 000000000..de404fc39 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml @@ -0,0 +1,118 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title PISP Linking: Request consent (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" + +DFSP -> DFSP: Verify the consentRequest validity +DFSP -> DFSP: In this case, DFSP chooses to use the Web channel, \n and adds the PISP's callback uri to an allow-list +deactivate Switch + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + At this point, the PISP knows that the Web authChannel is in use and the PISP App should redirect the user to the provided ""authUri"". +end note + + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg new file mode 100644 index 000000000..ab3853b5c --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg @@ -0,0 +1,219 @@ + + PISP Linking: Request consent (Web) + + + PISP Linking: Request consent (Web) + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + + + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa +    + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa +    + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + REQ-5 + Verify the consentRequest validity + + + + + REQ-6 + In this case, DFSP chooses to use the Web channel, + and adds the PISP's callback uri to an allow-list + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web" ], +    + callbackUri: "pisp-app://callback... + " +    + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" +    + } + + + REQ-8 + 200 OK + + + REQ-9 + PUT /consentRequests/11111111-0000-0000-0000-000000000000 +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "Web" ], +    + callbackUri: "pisp-app://callback... + " +    + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" +    + } + + + REQ-10 + 200 OK + + + At this point, the PISP knows that the Web authChannel is in use and the PISP App should redirect the user to the provided + authUri + . + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml new file mode 100644 index 000000000..2fdb17e5d --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml @@ -0,0 +1,62 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +... + +note over PISP, DFSP + Here the user provides the OTP sent directly to them by the DFSP into the PISP App. It's then used as the secret to prove to the DFSP that the user trusts the PISP. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the OTP is correct. + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg new file mode 100644 index 000000000..17b7c6856 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg @@ -0,0 +1,82 @@ + + PISP Linking: Authentication (OTP) + + + PISP Linking: Authentication (OTP) + + Mojaloop + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + Here the user provides the OTP sent directly to them by the DFSP into the PISP App. It's then used as the secret to prove to the DFSP that the user trusts the PISP. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + Verify the OTP is correct. + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. +   + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml new file mode 100644 index 000000000..9d05ec448 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml @@ -0,0 +1,45 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (Third-party FIDO registration) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "3P-FIDO-AUTH-#" + +... + +note over PISP, DFSP + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter indicating to the PISP that it should wait to be notified about a credential. +end note + +... + +autonumber 1 "AUTH-#" + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg new file mode 100644 index 000000000..467116a14 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg @@ -0,0 +1,39 @@ + + PISP Linking: Authentication (Third-party FIDO registration) + + + PISP Linking: Authentication (Third-party FIDO registration) + + Mojaloop + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter indicating to the PISP that it should wait to be notified about a credential. + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. +   + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml new file mode 100644 index 000000000..f31a9ed55 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml @@ -0,0 +1,65 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "WEB-AUTH-#" + +... + +note over PISP, DFSP + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter with a secret provided by the DFSP. +end note + +... + +autonumber 1 "AUTH-#" + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the auth token is correct. + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg new file mode 100644 index 000000000..f1752adad --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg @@ -0,0 +1,83 @@ + + PISP Linking: Authentication (Web) + + + PISP Linking: Authentication (Web) + + Mojaloop + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter with a secret provided by the DFSP. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<SECRET>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<SECRET>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + Verify the auth token is correct. + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. +   + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml new file mode 100644 index 000000000..e0ede15d5 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml @@ -0,0 +1,64 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Grant consent + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +DFSP -> Switch ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" +Switch --> DFSP: ""202 Accepted"" +deactivate DFSP + +Switch -> PISP ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" + +PISP --> Switch: ""202 Accepted"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg new file mode 100644 index 000000000..1dce24129 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg @@ -0,0 +1,82 @@ + + PISP Linking: Grant consent + + + + Mojaloop + PISP Linking: Grant consent + + + + + + + PISP + + Switch + + DFSP + + + GRANT-1 + POST /consents + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { +      + consentId: "22222222-0000-0000-0000-000000000000", +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + { accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + ], +      + } + + + GRANT-2 + 202 Accepted + + + GRANT-3 + POST /consents + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { +      + consentId: "22222222-0000-0000-0000-000000000000", +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + { accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ] }, +      + ], +      + } + + + GRANT-4 + 202 Accepted + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml new file mode 100644 index 000000000..b7cd8fe0e --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml @@ -0,0 +1,219 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Credential registration (verification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 0 "CRED-#" + +... + +note over PISP, DFSP + The PISP uses the FIDO registration flow to generate a new keypair and sign the challenge, relying on the user performing an "unlock action" on their mobile device. + + The PISP uses the PublicKeyCredential as the fidoPayload for the credential, which can be understood by the Auth Service and DFSP + See https://webauthn.guide/#authentication for more information on this object +end note + +... + +PISP -> Switch ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + + +Switch -> DFSP ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: ""202 Accepted"" + + +rnote over DFSP + 1. DFSP checks the signed challenge against the derived challenge from the scopes + + If the DFSP opts to use the hub-hosted Auth-Service it then: + 1. Registers the consent with the Auth Service ""POST /consents"" + 2. If the DFSP recieves a `PUT /consents/{id}` and the callback contains + ""Consent.credential.status"" of ""VERIFIED"", for each scope in the + Consent, the DFSP creates a ""CredentialScope"" else, if it recieves + a `PUT /consents/{id}/error` callback, it knows that the Consent is + invalid, and can propagate the error back to the PISP + +end note + + +DFSP -> Switch: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000"""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000"""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" + +Switch --> DFSP: "202 Accepted" + + +Switch -> Auth: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {...}"" + +Auth --> Switch: "202 Accepted" + + +rnote over Auth + The Auth Service checks the signature against the challenge +end note + +rnote over Auth + The auth service is now the authoritative source for the Consent object. + + It must register the consentId with the ALS + - `Consent` - to allow for `GET /consent/{ID}` calls etc. Will point to the fspId of the Auth Service responsible for the Consent +end note + +Auth -> ALS: ""POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +ALS --> Auth: ""202 Accepted"" + +rnote over ALS #LightGray + ALS registers a new entry in the Consents oracle +end note + +ALS -> Auth: ""PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: account-lookup-service""\n\ +"" FSIOP-Destination: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +Auth --> ALS: ""200 OK"" + +rnote over Auth #LightGray + The auth service now informs the DFSP that the credential is valid +end note + + +Auth -> Switch: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000"""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "VERIFIED",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> Auth: "200 OK" + +Switch -> DFSP: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: "200 OK" + +rnote over DFSP + DFSP is now satisfied that the Consent registered by the PISP is valid. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg new file mode 100644 index 000000000..77bdd635b --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg @@ -0,0 +1,348 @@ + + PISP Linking: Credential registration (verification) + + + + Mojaloop + PISP Linking: Credential registration (verification) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Thirdparty-API-Adapter + + Account Lookup Service + + Auth Service + + DFSP + + + The PISP uses the FIDO registration flow to generate a new keypair and sign the challenge, relying on the user performing an "unlock action" on their mobile device. +   + The PISP uses the PublicKeyCredential as the fidoPayload for the credential, which can be understood by the Auth Service and DFSP + See https://webauthn.guide/#authentication for more information on this object + + + CRED-0 + PUT /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSPIOP-Destination: dfspa + { +      + consentRequestId: "11111111-0000-0000-0000-000000000000", +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "PENDING", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-1 + 202 Accepted + + + CRED-2 + PUT /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSPIOP-Destination: dfspa + {...} + + + CRED-3 + 202 Accepted + + 1. DFSP checks the signed challenge against the derived challenge from the scopes +   + If the DFSP opts to use the hub-hosted Auth-Service it then: + 1. Registers the consent with the Auth Service + POST /consents + 2. If the DFSP recieves a `PUT /consents/{id}` and the callback contains +     + Consent.credential.status + of + VERIFIED + , for each scope in the + Consent, the DFSP creates a + CredentialScope + else, if it recieves + a `PUT /consents/{id}/error` callback, it knows that the Consent is + invalid, and can propagate the error back to the PISP +   + + + CRED-4 + POST /consents +   + FSIOP-Source: dfspa + FSPIOP-Destination: central-auth + { +      + consentId: "22222222-0000-0000-0000-000000000000 + " +      + consentRequestId: "11111111-0000-0000-0000-000000000000 + " +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "ACCOUNTS_TRANSFER" ], +      + } +      + }, +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "PENDING", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-5 + "202 Accepted" + + + CRED-6 + POST /consents +   + FSIOP-Source: dfspa + FSPIOP-Destination: central-auth + {...} + + + CRED-7 + "202 Accepted" + + The Auth Service checks the signature against the challenge + + The auth service is now the authoritative source for the Consent object. +   + It must register the consentId with the ALS + - `Consent` - to allow for `GET /consent/{ID}` calls etc. Will point to the fspId of the Auth Service responsible for the Consent + + + CRED-8 + POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000 +   + FSIOP-Source: central-auth + { + fspId: "central-auth", + } + + + CRED-9 + 202 Accepted + + ALS registers a new entry in the Consents oracle + + + CRED-10 + PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000 +   + FSIOP-Source: account-lookup-service + FSIOP-Destination: central-auth + { + fspId: "central-auth", + } + + + CRED-11 + 200 OK + + The auth service now informs the DFSP that the credential is valid + + + CRED-12 + PUT /consents/22222222-0000-0000-0000-000000000000 +   + FSIOP-Source: central-auth + FSPIOP-Destination: dfspa + { +      + consentRequestId: "11111111-0000-0000-0000-000000000000 + " +      + status: "ISSUED", +      + scopes: [ +      + { +      + accountId: "dfsp.username.1234", +      + actions: [ "accounts.transfer", "accounts.getBalance" ], +      + }, +      + { +      + accountId: "dfsp.username.5678", +      + actions: [ "accounts.transfer", "accounts.getBalance" ], +      + }, +      + ], +      + credential: { +      + credentialType: "FIDO", +      + status: "VERIFIED", +      + fidoPayload: { +      + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", +   +      + response: { +      +          + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", +      +          + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", +      +          + signature: "MEUCIDcJRBu5aOLJVc..." +      + } +      + } +      + } + } + + + CRED-13 + "200 OK" + + + CRED-14 + PUT /consents/22222222-0000-0000-0000-000000000000 +   + FSIOP-Source: central-auth + FSPIOP-Destination: dfspa + {...} + + + CRED-15 + "200 OK" + + DFSP is now satisfied that the Consent registered by the PISP is valid. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml new file mode 100644 index 000000000..791a929de --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml @@ -0,0 +1,97 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Credential registration (verification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch + participant "Account Lookup Service" as ALS +end box + +participant "DFSP" as DFSP + +autonumber 16 "CRED-#" + +... + + +rnote over DFSP + DFSP is now satisfied that the Consent registered by the PISP is valid, + and now proceeds to register with the ALS: + - `THIRD_PARTY_LINK` (optional - for routing of funds to a Third Party Link) + ALS +end note + +loop for each scope in ""Consents.scopes"" + +DFSP -> ALS: ""POST /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +ALS --> DFSP: ""202 Accepted"" + +rnote over ALS #LightGray + ALS registers a new entry in the THIRD_PARTY_LINK oracle +end note + +ALS -> DFSP: ""PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSIOP-Source: account-lookup-service""\n\ +"" FSIOP-Destination: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +DFSP --> ALS: ""200 OK"" +end + + +rnote over DFSP + Now that the Credentials are verified and registered with the Auth Service, + the DFSP can update the PISP with the final status +end note + +DFSP -> Switch: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +DFSP --> Switch: ""200 OK"" + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +PISP --> Switch: ""200 OK"" + + +note over PISP, DFSP + Now we have a new identifier that the PISP can use to initiate transactions, a registered credential, and that credential is stored in the auth-service +end note + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg new file mode 100644 index 000000000..07530567b --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg @@ -0,0 +1,116 @@ + + PISP Linking: Credential registration (verification) + + + + Mojaloop + PISP Linking: Credential registration (verification) + + + + + + + + + + + + + + + PISP + + Switch + + Account Lookup Service + + DFSP + + DFSP is now satisfied that the Consent registered by the PISP is valid, + and now proceeds to register with the ALS: + - `THIRD_PARTY_LINK` (optional - for routing of funds to a Third Party Link) + ALS + + + loop + [for each scope in + Consents.scopes + ] + + + CRED-16 + POST /participants/THIRD_PARTY_LINK/dfsp.username.5678 +   + FSIOP-Source: dfspa + { + fspId: "dfspa", + } + + + CRED-17 + 202 Accepted + + ALS registers a new entry in the THIRD_PARTY_LINK oracle + + + CRED-18 + PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678 +   + FSIOP-Source: account-lookup-service + FSIOP-Destination: dfspa + { + fspId: "dfspa", + } + + + CRED-19 + 200 OK + + Now that the Credentials are verified and registered with the Auth Service, + the DFSP can update the PISP with the final status + + + CRED-20 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSPIOP-Destination: pispa + Content-Type: application/merge-patch+json + { +      + credential: { +      +      + status: "VERIFIED", //this is new! +      + } + } + + + CRED-21 + 200 OK + + + CRED-22 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSPIOP-Destination: pispa + Content-Type: application/merge-patch+json + { +      + credential: { +      +      + status: "VERIFIED", //this is new! +      + } + } + + + CRED-23 + 200 OK + + + Now we have a new identifier that the PISP can use to initiate transactions, a registered credential, and that credential is stored in the auth-service + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml new file mode 100644 index 000000000..4c2ff1b57 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Unlinking + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-A-#" + +activate PISP + +... + +note over PISP, DFSP + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the ""Consent"" object. +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Mark the ""Consent"" object as "REVOKED" + +DFSP -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg new file mode 100644 index 000000000..63e31ab9c --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg @@ -0,0 +1,102 @@ + + PISP Linking: Unlinking + + + + Mojaloop + PISP Linking: Unlinking + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the + Consent + object. + + + UNLINK-A-1 + DELETE /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSIOP-Destination: dfspa + + + UNLINK-A-2 + 202 Accepted + + + UNLINK-A-3 + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + UNLINK-A-4 + 202 Accepted + + + + + UNLINK-A-5 + Mark the + Consent + object as "REVOKED" + + + UNLINK-A-6 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-A-7 + 200 OK + + + UNLINK-A-8 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: dfspa + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + } + + + UNLINK-A-9 + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml new file mode 100644 index 000000000..914dc7704 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml @@ -0,0 +1,105 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Unlinking + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-B-#" + +activate PISP + +... + +note over PISP, DFSP + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the ""Consent"" object. +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> ALS: ""GET /participants/CONSENT/22222222-0000-0000-0000-000000000000"" +ALS --> Switch: ""200 OK""\n\ +"" { "fspId": "central-auth" }"" + +rnote over Switch #LightGray + Hub has determined that 'central-auth- is responsible for ""Consent"" 22222222-0000-0000-0000-000000000000 +end note + +Switch -> Auth ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +Auth --> Switch: ""202 Accepted"" +deactivate Switch + +Auth -> Auth: Mark the ""Consent"" object as "REVOKED" + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +rnote over Auth #LightGray + Auth Service must also inform the DFSP of the updated status +end note + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> DFSP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +DFSP --> Switch: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg new file mode 100644 index 000000000..aaa186304 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg @@ -0,0 +1,164 @@ + + PISP Linking: Unlinking + + + + Mojaloop + PISP Linking: Unlinking + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + Account Lookup Service + + Auth Service + + DFSP + + + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the + Consent + object. + + + UNLINK-B-1 + DELETE /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: pispa + FSIOP-Destination: dfspa + + + UNLINK-B-2 + 202 Accepted + + + UNLINK-B-3 + GET /participants/CONSENT/22222222-0000-0000-0000-000000000000 + + + UNLINK-B-4 + 200 OK + { "fspId": "central-auth" } + + Hub has determined that 'central-auth- is responsible for + Consent + 22222222-0000-0000-0000-000000000000 + + + UNLINK-B-5 + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + UNLINK-B-6 + 202 Accepted + + + + + UNLINK-B-7 + Mark the + Consent + object as "REVOKED" + + + UNLINK-B-8 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: central-auth + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-9 + 200 OK + + + UNLINK-B-10 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: central-auth + FSIOP-Destination: pispa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-11 + 200 OK + + Auth Service must also inform the DFSP of the updated status + + + UNLINK-B-12 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: central-auth + FSIOP-Destination: dfspa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-13 + 200 OK + + + UNLINK-B-14 + PATCH /consents/22222222-0000-0000-0000-000000000000 + FSIOP-Source: central-auth + FSIOP-Destination: dfspa + { + status: "REVOKED", + revokedAt: "2020-06-15T13:00:00.000 + " + } + + + UNLINK-B-15 + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml new file mode 100644 index 000000000..bf5d76ca5 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml @@ -0,0 +1,79 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Discovery error case + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Lookup a user for **username1234** +DFSP -> DFSP: No user found + +DFSP -> Switch ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over Switch + The PISP can now show error message and user can try again with another username or different DFSP. +end note + +... + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg new file mode 100644 index 000000000..9081344f6 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg @@ -0,0 +1,130 @@ + + PISP Linking: Discovery error case + + + PISP Linking: Discovery error case + + PISP + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + DISC-1 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-2 + 202 Accepted + + + DISC-3 + GET /accounts/username1234 +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + + + DISC-4 + 202 Accepted + + + + + DISC-5 + Lookup a user for + username1234 + + + + + DISC-6 + No user found + + + DISC-7 + PUT /accounts/username1234/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6205", +    + errorDescription: "No accounts found" +    + } +    + } + + + DISC-8 + 200 OK + + + DISC-9 + PUT /accounts/username1234/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6205", +    + errorDescription: "No accounts found" +    + } +    + } + + + DISC-10 + 200 OK + + + The PISP can now show error message and user can try again with another username or different DFSP. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml new file mode 100644 index 000000000..e3cbf4565 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml @@ -0,0 +1,162 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title **PISP Linking: consentRequest error cases** + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +== NO_SUPPORTED_SCOPE_ACTIONS == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: The PISP requested permissions \nfor accountId dfsp.username.91011 which \n isn't owned by username1234 + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +== UNTRUSTED_CALLBACK_URI == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { **accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: The callbackUri uses http scheme \ninstead of https. Reject the consentRequest + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg new file mode 100644 index 000000000..249fe4f27 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg @@ -0,0 +1,299 @@ + + **PISP Linking: consentRequest error cases** + + + PISP Linking: consentRequest error cases + + Mojaloop + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + + + + + NO_SUPPORTED_SCOPE_ACTIONS + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.91011", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.91011", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "pisp-app://callback... + " +    + } + + + REQ-4 + 202 Accepted + + + + + DFSP-1 + The PISP requested permissions + for accountId dfsp.username.91011 which + isn't owned by username1234 + + + REQ-5 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6101", +    + errorDescription: "Unsupported scopes were requested" +    + } +    + } + + + REQ-6 + 200 OK + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6101", +    + errorDescription: "Unsupported scopes were requested" +    + } +    + } + + + REQ-8 + 200 OK + + + + + UNTRUSTED_CALLBACK_URI + + + REQ-1 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { **accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "http://phishing.com + " +    + } + + + REQ-2 + 202 Accepted + + + REQ-3 + POST /consentRequests +    + FSIOP-Source: pispa +    + FSIOP-Destination: dfspa + { +    + consentRequestId: "11111111-0000-0000-0000-000000000000", +    + userId: "username1234", +    + scopes: [ +    + { accountId: "dfsp.username.1234", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + { accountId: "dfsp.username.5678", +    + actions: [ "ACCOUNTS_TRANSFER" ] }, +    + ], +    + authChannels: [ "WEB", "OTP" ], +    + callbackUri: "http://phishing.com + " +    + } + + + REQ-4 + 202 Accepted + + + + + DFSP-1 + The callbackUri uses http scheme + instead of https. Reject the consentRequest + + + REQ-5 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6204", +    + errorDescription: "Bad callbackUri" +    + } +    + } + + + REQ-6 + 200 OK + + + REQ-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6204", +    + errorDescription: "Bad callbackUri" +    + } +    + } + + + REQ-8 + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml new file mode 100644 index 000000000..c88560017 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml @@ -0,0 +1,87 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication Invalid authToken + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +== Failure case == + +... + +note over PISP, DFSP + The user enters an incorrect OTP for authentication. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: The OTP is incorrect. + +note over PISP, DFSP + We respond with an error that the OTP is incorrect so the PISP can inform the user. +end note + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg new file mode 100644 index 000000000..205c13319 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg @@ -0,0 +1,137 @@ + + PISP Linking: Authentication Invalid authToken + + + PISP Linking: Authentication Invalid authToken + + Mojaloop + + + + + + + + + + + + + + + + + + + + + PISP + + Switch + + DFSP + + + + + + + + + Failure case + + + The user enters an incorrect OTP for authentication. + + + AUTH-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-2 + 202 Accepted + + + AUTH-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + AUTH-4 + 202 Accepted + + + + + AUTH-5 + The OTP is incorrect. + + + We respond with an error that the OTP is incorrect so the PISP can inform the user. + + + AUTH-6 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6203", +    + errorDescription: "Invalid authentication token" +    + } +    + } + + + AUTH-7 + 200 OK + + + AUTH-8 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "6203", +    + errorDescription: "Invalid authentication token" +    + } +    + } + + + AUTH-9 + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml new file mode 100644 index 000000000..c9e4f772d --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +!pragma teoz true + +title PISP Linking: Grant consent scope retrieval error + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +== Failure case == + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the OTP is correct. + +DFSP -> DFSP: Unable to fetch stored scopes + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg new file mode 100644 index 000000000..b8ba689c8 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg @@ -0,0 +1,127 @@ + + PISP Linking: Grant consent scope retrieval error + + + + Mojaloop + PISP Linking: Grant consent scope retrieval error + + + + + + + + + + + PISP + + Thirdparty-API-Adapter + + Account Lookup Service + + Auth Service + + DFSP + + + + + Failure case + + + GRANT-1 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + GRANT-2 + 202 Accepted + + + GRANT-3 + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 +      + FSIOP-Source: pispa +      + FSIOP-Destination: dfspa + { +      + authToken: "<OTP>" +      + } + + + GRANT-4 + 202 Accepted + + + + + GRANT-5 + Verify the OTP is correct. + + + + + GRANT-6 + Unable to fetch stored scopes + + + GRANT-7 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "7207", +    + errorDescription: "FSP failed retrieve scopes for consent request" +    + } +    + } + + + GRANT-8 + 200 OK + + + GRANT-9 + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error +    + FSIOP-Source: dfspa +    + FSIOP-Destination: pispa +    + { +    + errorInformation : { +    + errorCode: "7207", +    + errorDescription: "FSP failed retrieve scopes for consent request" +    + } +    + } + + + GRANT-10 + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml new file mode 100644 index 000000000..ed4cfbbfe --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.1 Discovery + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + + +== Discovery (Lookup) == +rnote right of D1 #LightGray +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +end note +D1 -> S: ""GET /parties/MSISDN/+4412345678"" +S --> D1: ""202 Accepted"" + +... ALS lookup flow not shown here ... + +rnote over S #LightGray +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspb"" +end note +S -> D3: ""GET /parties/MSISDN/+4412345678"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /parties/MSISDN/+4412345678""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: pispa"" +{ + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + party: { + partyIdInfo: { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + fspId: 'dfspb", + }, + name: "Bhavesh S.", + } +} +end note +D3 -> S: ""PUT /parties/MSISDN/+4412345678"" +S --> D3: ""200 OK"" +S -> D1: ""PUT /parties/MSISDN/+4412345678"" +D1 --> S: ""200 OK"" + +... PISP confirms payee party with their user ... + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg new file mode 100644 index 000000000..9886a2797 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg @@ -0,0 +1,89 @@ + + Transfer: 1.1 Discovery + + + Transfer: 1.1 Discovery + + PISP + + Mojaloop + + DFSP B + + + + + + + + + + + + + + + + + PISP Server + + Switch + + DFSP B + (Payee) + + + + + Discovery (Lookup) + + GET /parties/MSISDN/+4412345678 + FSPIOP-Source: pispa + + + GET /parties/MSISDN/+4412345678 + + + 202 Accepted + ALS lookup flow not shown here + + GET /parties/MSISDN/+4412345678 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspb + + + GET /parties/MSISDN/+4412345678 + + + 202 Accepted + + PUT /parties/MSISDN/+4412345678 + FSPIOP-Source: dfspb + FSPIOP-Destination: pispa + { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + party: { + partyIdInfo: { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + fspId: 'dfspb", + }, + name: "Bhavesh S.", + } + } + + + PUT /parties/MSISDN/+4412345678 + + + 200 OK + + + PUT /parties/MSISDN/+4412345678 + + + 200 OK + PISP confirms payee party with their user + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml new file mode 100644 index 000000000..1ca03bf19 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml @@ -0,0 +1,86 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.1 Agreement + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +== Agreement Phase == +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" +D2 -> D2: Lookup the consent for this ""payer"", verify that they exist, and consent \nis granted with a valid credential +D2 -> D2: Store a referece to the ""consentId"" with the ""transactionRequestId"" +D2 -> D2: Generate a unique transactionId for this transaction request:\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg new file mode 100644 index 000000000..6a74a58bc --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg @@ -0,0 +1,114 @@ + + Transfer: 1.2.1 Agreement + + + Transfer: 1.2.1 Agreement + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + + + Agreement Phase + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + + + Lookup the consent for this + payer + , verify that they exist, and consent + is granted with a valid credential + + + + + Store a referece to the + consentId + with the + transactionRequestId + + + + + Generate a unique transactionId for this transaction request: + 11111111-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "RECEIVED" + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml new file mode 100644 index 000000000..f18da5725 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml @@ -0,0 +1,150 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.2 Authorization + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +rnote left of D2 #LightGray +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +rnote left of D2 #LightGray +**""PUT /quotes/22222222-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "transferAmount": { + "amount": "100", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeFspFee": { + "amount": "1", + "currency": "USD" + }, + "expiration": "2020-06-15T12:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note left of D2 + DFSP A has the quote, they can now ask + the PISP for authorization +end note + +D2 -> D2: Generate a UUID for the authorization Request:\n""33333333-0000-0000-0000-000000000000"" +D2 -> D2: Derive the challenge based \non ""PUT /quotes/{ID}"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/authorizations""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "challenge": """", + "transferAmount": {"amount": "100", "currency": "USD"}, + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + "fees": {"amount": "1", "currency": "USD"}, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T12:00:00.000", +} +end note +D2 -> S: ""POST /thirdpartyRequests/authorizations"" +S --> D2: ""202 Accepted"" +S -> D1: ""POST /thirdpartyRequests/authorizations"" +D1 --> S: ""202 Accepted"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg new file mode 100644 index 000000000..cbaf79e38 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg @@ -0,0 +1,175 @@ + + Transfer: 1.2.2 Authorization + + + Transfer: 1.2.2 Authorization + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + DFSP B + (Payee) + + POST /quotes + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" + } + + + POST /quotes + + + 202 Accepted + + + POST /quotes + + + 202 Accepted + + PUT /quotes/22222222-0000-0000-0000-000000000000 + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "transferAmount": { + "amount": "100", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeFspFee": { + "amount": "1", + "currency": "USD" + }, + "expiration": "2020-06-15T12:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + 200 OK + + + DFSP A has the quote, they can now ask + the PISP for authorization + + + + + Generate a UUID for the authorization Request: + 33333333-0000-0000-0000-000000000000 + + + + + Derive the challenge based + on + PUT /quotes/{ID} + + POST /thirdpartyRequests/authorizations + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "transferAmount": {"amount": "100", "currency": "USD"}, + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + "fees": {"amount": "1", "currency": "USD"}, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T12:00:00.000", + } + + + POST /thirdpartyRequests/authorizations + + + 202 Accepted + + + POST /thirdpartyRequests/authorizations + + + 202 Accepted + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml new file mode 100644 index 000000000..12f1293fc --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml @@ -0,0 +1,76 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Rejected Authorization + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + + + User rejects the terms of the transcationRequest +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "REJECTED" +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" + +note over D2 + User has rejected the transaction request. +end note + +rnote over D2 #LightGray +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "REJECTED", + "transactionId": "11111111-0000-0000-0000-000000000000", +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + PISP can inform the user the transaction did not proceed +end note + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg new file mode 100644 index 000000000..deaaa05cf --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg @@ -0,0 +1,93 @@ + + Transfer: 1.2.3 Rejected Authorization + + + Transfer: 1.2.3 Rejected Authorization + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + + + Agreement Phase + + + PISP looks up the + transactionRequestId + and + checks the quote with the user, +   +   + User rejects the terms of the transcationRequest + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "REJECTED" + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Look up the + transactionRequestId + for this + authorizationId + + + User has rejected the transaction request. + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "REJECTED", + "transactionId": "11111111-0000-0000-0000-000000000000", + } + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PISP can inform the user the transaction did not proceed + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml new file mode 100644 index 000000000..d05d3f6c8 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml @@ -0,0 +1,74 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Signed Authorization FIDO + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the terms with the user. + + If the user agrees to the terms, the PISP + uses the FIDO API on the user's device to sign the + the **""challenge""** string +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" + +note over D2 + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg new file mode 100644 index 000000000..4b6355121 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg @@ -0,0 +1,95 @@ + + Transfer: 1.2.3 Signed Authorization FIDO + + + Transfer: 1.2.3 Signed Authorization FIDO + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + + + Agreement Phase + + + PISP looks up the + transactionRequestId + and + checks the terms with the user. +   + If the user agrees to the terms, the PISP + uses the FIDO API on the user's device to sign the + the + challenge + string + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Look up the + transactionRequestId + for this + authorizationId + + + + + Look up the + consentId + for this + transactionRequestId + + + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml new file mode 100644 index 000000000..2e85d4142 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml @@ -0,0 +1,63 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Signed Authorization + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user. + + If the user agrees to the terms, the PISP uses + the Credential's privateKey to sign the challenge +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" + +note over D2 + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg new file mode 100644 index 000000000..58ab50236 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg @@ -0,0 +1,82 @@ + + Transfer: 1.2.3 Signed Authorization + + + Transfer: 1.2.3 Signed Authorization + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + + + Agreement Phase + + + PISP looks up the + transactionRequestId + and + checks the quote with the user. +   + If the user agrees to the terms, the PISP uses + the Credential's privateKey to sign the challenge + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Look up the + transactionRequestId + for this + authorizationId + + + + + Look up the + consentId + for this + transactionRequestId + + + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml new file mode 100644 index 000000000..d96dbd5c7 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.4 Verify Authorization + + +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +D2 -> D2: Generate a new ""verificationRequestId"", and associate \n it with the ""thirdpartyTransactionRequestId"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Lookup this consent based on consentId +AUTHS -> AUTHS: Ensure the accountAddress matches what is in Consent +AUTHS -> AUTHS: Check that the signed bytes match the \npublickey we have stored for the consent + +rnote right of AUTHS #LightGray +**""PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "authenticationResponse": "VERIFIED" +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note over D2 + DFSPA now knows that the user signed this transaction + and can go ahead and initiate the transfer +end note + + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg new file mode 100644 index 000000000..ec93b340b --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg @@ -0,0 +1,106 @@ + + Transfer: 1.2.4 Verify Authorization + + + Transfer: 1.2.4 Verify Authorization + + Mojaloop + + DFSP A + + + + + Switch + + Auth-Service + + DFSP A + (Payer) + + + + + Generate a new + verificationRequestId + , and associate + it with the + thirdpartyTransactionRequestId + + POST /thirdpartyRequests/verifications + FSPIOP-Source: dfspa + FSPIOP-Destination: central-auth + { + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + + + Lookup this consent based on consentId + + + + + Ensure the accountAddress matches what is in Consent + + + + + Check that the signed bytes match the + publickey we have stored for the consent + + PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000 + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + "authenticationResponse": "VERIFIED" + } + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000 + + + 200 OK + + + DFSPA now knows that the user signed this transaction + and can go ahead and initiate the transfer + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml new file mode 100644 index 000000000..cfd38cc89 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml @@ -0,0 +1,178 @@ +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +hide footbox + +title Transfer: 1.3 Final transfer + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box +actor "<$actor>\nPayee" as CB + + + +== Transfer Phase == + +... DFSP A initiates a normal Mojaloop P2P Transfer ... + +D2 -> D2: Generate a new ""transferId"", and associate \n it with the ""transactionRequestId"" + +rnote over D2 #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /transfers/55555555-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "fulfilment": "...", + "completedTimestamp": "2020-06-15T12:01:00.000", + "transferState": "COMMITTED" +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +D3 -> CB: You have received funds! +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + + +D2 -> D2: Look up ""transactionRequestId"" from the ""transferId"" + +rnote over D2 #LightGray +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", + "transactionState": "COMMITTED" +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + PISP can now inform the user the + funds have been sent +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg new file mode 100644 index 000000000..3c037e93b --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg @@ -0,0 +1,161 @@ + + Transfer: 1.3 Final transfer + + + Transfer: 1.3 Final transfer + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + DFSP B + (Payee) + + Payee + + + + + + + Transfer Phase + DFSP A initiates a normal Mojaloop P2P Transfer + + + + + Generate a new + transferId + , and associate + it with the + transactionRequestId + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + PUT /transfers/55555555-0000-0000-0000-000000000000 + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "fulfilment": "...", + "completedTimestamp": "2020-06-15T12:01:00.000", + "transferState": "COMMITTED" + } + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + 200 OK + + + You have received funds! + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + 200 OK + + + + + Look up + transactionRequestId + from the + transferId + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "ACCEPTED", + "transactionState": "COMMITTED" + } + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PATCH /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PISP can now inform the user the + funds have been sent + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml new file mode 100644 index 000000000..16b214c2e --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml @@ -0,0 +1,90 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.2.1 Bad Thirdparty Transaction Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +== Agreement Phase == +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: DFSP finds something wrong with this transaction request. + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6104", + "errorDescription": "Thirdparty request rejection", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg new file mode 100644 index 000000000..3c48a8ee7 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg @@ -0,0 +1,101 @@ + + Transfer: 3.2.1 Bad Thirdparty Transaction Request + + + Transfer: 3.2.1 Bad Thirdparty Transaction Request + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + + + Agreement Phase + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + + + DFSP finds something wrong with this transaction request. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6104", + "errorDescription": "Thirdparty request rejection", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml new file mode 100644 index 000000000..4ee3e839b --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml @@ -0,0 +1,140 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.3.1 Bad Quote Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +D2 -> D2: Generate a unique transactionId for this transaction request:\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +rnote left of D2 #LightGray +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +D3 -> D3: Quote fails for some reason. + +rnote left of D3 #LightGray +**""PUT /quotes/22222222-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Quote failed, DFSP needs to inform PISP +end note + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream Failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg new file mode 100644 index 000000000..7c1471c24 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg @@ -0,0 +1,177 @@ + + Transfer: 3.3.1 Bad Quote Request + + + Transfer: 3.3.1 Bad Quote Request + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + DFSP B + (Payee) + PISP has initiated Thirdparty Transaction Request with + POST /thirdpartyRequests/transactions + + + + + Generate a unique transactionId for this transaction request: + 11111111-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000 + + + 200 OK + + POST /quotes + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" + } + + + POST /quotes + + + 202 Accepted + + + POST /quotes + + + 202 Accepted + + + + + Quote fails for some reason. + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } + } + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + 200 OK + + + Quote failed, DFSP needs to inform PISP + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream Failure", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml new file mode 100644 index 000000000..31d95a3f8 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml @@ -0,0 +1,122 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.3.2 Bad Transfer Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +... DFSP A has received ""PUT /thirdpartyRequests/verifications from Auth-Service""... + +... DFSP A initiates a normal Mojaloop P2P Transfer ... + +D2 -> D2: Generate a new ""transferId"", and associate \n it with the ""transactionRequestId"" + +rnote over D2 #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #LightGray +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #LightGray +**""PUT /transfers/55555555-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Transfer failed, DFSP needs to inform PISP +end note + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg new file mode 100644 index 000000000..3aa23dd2e --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg @@ -0,0 +1,172 @@ + + Transfer: 3.3.2 Bad Transfer Request + + + Transfer: 3.3.2 Bad Transfer Request + + PISP + + Mojaloop + + DFSP A + + DFSP B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + DFSP B + (Payee) + PISP has initiated Thirdparty Transaction Request with + POST /thirdpartyRequests/transactions + DFSP A has received quote, and asked PISP to verify + DFSP A has received + PUT /thirdpartyRequests/verifications from Auth-Service + DFSP A initiates a normal Mojaloop P2P Transfer + + + + + Generate a new + transferId + , and associate + it with the + transactionRequestId + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + POST /transfers + FSPIOP-Source: dfspa + FSPIOP-Destination: dfspb + { + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", + } + + + POST /transfers + + + 202 Accepted + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspb + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } + } + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + 200 OK + + + Transfer failed, DFSP needs to inform PISP + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream failure", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml new file mode 100644 index 000000000..3d927a08e --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml @@ -0,0 +1,95 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.4.1 Bad Signed Challenge - Self Hosted Auth-Service + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + and uses the FIDO API to sign the + the **""challenge""** string +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" +D2 -> D2: Look up the ""publicKey"" for this ConsentId. Check the signing of the signed challenge + +note over D2 + Signed challenge is invalid. Transaction Request failed. +end note + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg new file mode 100644 index 000000000..fd5f91fad --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg @@ -0,0 +1,134 @@ + + Transfer: 3.4.1 Bad Signed Challenge - Self Hosted Auth-Service + + + Transfer: 3.4.1 Bad Signed Challenge - Self Hosted Auth-Service + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + PISP has initiated Thirdparty Transaction Request with + POST /thirdpartyRequests/transactions + DFSP A has received quote, and asked PISP to verify + + + PISP looks up the + transactionRequestId + and + checks the quote with the user, + and uses the FIDO API to sign the + the + challenge + string + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Look up the + transactionRequestId + for this + authorizationId + + + + + Look up the + consentId + for this + transactionRequestId + + + + + Look up the + publicKey + for this ConsentId. Check the signing of the signed challenge + + + Signed challenge is invalid. Transaction Request failed. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml new file mode 100644 index 000000000..5749390a0 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml @@ -0,0 +1,149 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.4.2 Bad Signed Challenge - Hub Hosted Auth-Service + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + and uses the FIDO API to sign the + the **""challenge""** string +end note + +rnote right of D1 #LightGray +**""PUT /thirdpartyRequests/authorizations""** +**"" /33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Lookup ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Lookup ""consentId"" for this ""transactionRequestId"" + + +D2 -> D2: Generate a new ""verificationRequestId"", and associate \n it with the ""thirdpartyTransactionRequestId"" + +rnote left of D2 #LightGray +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Lookup this consent based on consentId +AUTHS -> AUTHS: Ensure the accountAddress matches what is in Consent +AUTHS -> AUTHS: Check that the signed bytes match the \npublickey we have stored for the consent + +rnote right of AUTHS #LightGray +**""PUT /thirdpartyRequests/verifications""** +**"" /44444444-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note over D2 + Signed challenge is invalid. Transaction Request failed. +end note + + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg new file mode 100644 index 000000000..9789b4778 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg @@ -0,0 +1,222 @@ + + Transfer: 3.4.2 Bad Signed Challenge - Hub Hosted Auth-Service + + + Transfer: 3.4.2 Bad Signed Challenge - Hub Hosted Auth-Service + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + + + + + + + + + + + + PISP Server + + Switch + + Auth-Service + + DFSP A + (Payer) + PISP has initiated Thirdparty Transaction Request with + POST /thirdpartyRequests/transactions + DFSP A has received quote, and asked PISP to verify + + + PISP looks up the + transactionRequestId + and + checks the quote with the user, + and uses the FIDO API to sign the + the + challenge + string + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + } + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + PUT /thirdpartyRequests/authorizations + /33333333-0000-0000-0000-000000000000 + + + 200 OK + + + + + Lookup + transactionRequestId + for this + authorizationId + + + + + Lookup + consentId + for this + transactionRequestId + + + + + Generate a new + verificationRequestId + , and associate + it with the + thirdpartyTransactionRequestId + + POST /thirdpartyRequests/verifications + FSPIOP-Source: dfspa + FSPIOP-Destination: central-auth + { + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": + <base64 encoded binary - the encoded challenge> + , + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + POST /thirdpartyRequests/verifications + + + 202 Accepted + + + + + Lookup this consent based on consentId + + + + + Ensure the accountAddress matches what is in Consent + + + + + Check that the signed bytes match the + publickey we have stored for the consent + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + FSPIOP-Source: central-auth + FSPIOP-Destination: dfspa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/verifications + /44444444-0000-0000-0000-000000000000/error + + + 200 OK + + + Signed challenge is invalid. Transaction Request failed. + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } + } + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + + PUT /thirdpartyRequests/transactions + /00000000-0000-0000-0000-000000000000/error + + + 200 OK + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml new file mode 100644 index 000000000..3c083936d --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml @@ -0,0 +1,77 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.Thirdparty Transaction Request Times Out + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +rnote right of D1 #LightGray +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + + +... DFSP doesn't respond for some reason... + + +D1 -> D1: Thirdparty Transaction Request expiration reached + +note over D1 + PISP informs their user that the transaction failed. + +end note + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg new file mode 100644 index 000000000..3767c779d --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg @@ -0,0 +1,81 @@ + + Transfer: 3.Thirdparty Transaction Request Times Out + + + Transfer: 3.Thirdparty Transaction Request Times Out + + PISP + + Mojaloop + + DFSP A + + + + + + + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + POST /thirdpartyRequests/transactions + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + { + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" + } + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + + + POST /thirdpartyRequests/transactions + + + 202 Accepted + DFSP doesn't respond for some reason + + + + + Thirdparty Transaction Request expiration reached + + + PISP informs their user that the transaction failed. +   + + diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml b/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml new file mode 100644 index 000000000..63224d6a9 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml @@ -0,0 +1,67 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISPGetTransactionRequest + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + +autonumber 1 "GTR-#" + +note over S + Assuming a previously created thirdparty transaction request with id: ""00000000-0000-0000-0000-000000000000"" + +end note + + + +rnote right of D1 #LightGray +**""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +end note + +D1 -> S: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D1: ""202 Accepted"" + +S -> D2: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: DFSP looks up already created \nthirdparty transaction request +D2 -> D2: DFSP ensures that the FSPIOP-Source (pisp)\nis the same as the original sender of \n""POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" + +rnote left of D2 #LightGray +**""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg b/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg new file mode 100644 index 000000000..3ba41a634 --- /dev/null +++ b/docs/technical/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg @@ -0,0 +1,86 @@ + + PISPGetTransactionRequest + + + PISPGetTransactionRequest + + PISP + + Mojaloop + + DFSP A + + + + + PISP Server + + Switch + + DFSP A + (Payer) + + + Assuming a previously created thirdparty transaction request with id: + 00000000-0000-0000-0000-000000000000 +   + + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: pispa + FSPIOP-Destination: dfspa + + + GTR-1 + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-2 + 202 Accepted + + + GTR-3 + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-4 + 202 Accepted + + + + + GTR-5 + DFSP looks up already created + thirdparty transaction request + + + + + GTR-6 + DFSP ensures that the FSPIOP-Source (pisp) + is the same as the original sender of + POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + FSPIOP-Source: dfspa + FSPIOP-Destination: pispa + { + "transactionRequestState": "ACCEPTED", + } + + + GTR-7 + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-8 + 200 OK + + + GTR-9 + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + GTR-10 + 200 OK + + diff --git a/docs/technical/api/thirdparty/data-models.md b/docs/technical/api/thirdparty/data-models.md new file mode 100644 index 000000000..0fa1c4b4a --- /dev/null +++ b/docs/technical/api/thirdparty/data-models.md @@ -0,0 +1,991 @@ +# Data Models + +Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Third Party API Elements](#ThirdPartyAPIElements) + 3.1 [Resources](#Resources) + 3.2 [Data Models](#DataModels) + 3.3 [Error Codes](#ErrorCodes) +# 1. Preface +This section contains information about how to use this document. + +## 1.1 Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2 Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3 References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document specifies the data model used by the Mojaloop Third Party API ("the API"). + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Third Party API Elements + +This section describes the content of the API which will be used by PISPs and DFSPs. + +The content of the API falls into two sections: + +1. [Transaction Patterns - Linking](./transaction-patterns-linking.md) describes the process for linking customer accounts and providing a general permission mechanism for PISPs to perform operations on those accounts +2. [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) describes the transfer of funds at the instigation of a PISP. + +The API is used by the following different types of participant, as follows: + 1. PISPs + 2. DFSPs who offer services to their customer which allow the customer to access their account via one or more PISPs + 3. Auth-Services + 4. The Mojaloop switch + +Each resource in the API definition is accompanied by a definition of the type(s) of participant allowed to access it. + +## 3.1 Resources + +The API contains the following resources: + +### 3.1.1 **/accounts** + +The **/accounts** resource is used to request information from a DFSP relating to the accounts +it holds for a given identifier. The identifier is a user-provided value which the user +uses to access their account with the DFSP, such as a phone number, email address, or +some other identifier previously provided by the DFSP. + +The DFSP returns a set of information about the accounts it is prepared to divulge to the PISP. +The PISP can then display the names of the accounts to the user, and allow the user to select +the accounts with which they wish to link via the PISP. + +The **/accounts** resource supports the endpoints described below. + +#### 3.1.1.1 Requests + +This section describes the services that a PISP can request on the /accounts resource. + +##### 3.1.1.1.1 **GET /accounts/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /accounts/**_{ID}_ is used to lookup information about the requested +user's accounts, defined by an identifier *{ID}*, where *{ID}* is an identifier a user +uses to access their account with the DFSP, such as a phone number, email address, or +some other identifier previously provided by the DFSP. + +Callback and data model information for **GET /accounts/**_{ID}_: +- Callback - **PUT /accounts/**_{ID}_ +- Error Callback - **PUT /accounts/**_{ID}_**/error** +- Data Model – Empty body + +#### 3.1.1.2 Callbacks + +The responses for the **/accounts** resource are as follows + +##### 3.1.1.2.1 **PUT /accounts/**_{ID}_ + +Used by: DFSP + +The **PUT /accounts/**_{ID}_ response is used to inform the requester of the result of a request +for accounts information. The identifier ID given in the call are the +values given in the original request (see Section 3.1.1.1.1 above.) + +The data content of the message is given below. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| accountList | 1 | AccountList | Information about the accounts that the DFSP associates with the identifier sent by the PISP. | + +##### 3.1.1.2.2 **PUT /accounts/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /accounts/**_{ID}_**/error** response is used to inform the requester that an account list +request has given rise to an error. The identifier ID given in the call are +the values given in the original request (see Section 3.1.1.1.1 above.) + +The data content of the message is given below. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.2 **/consentRequests** + +The **/consentRequests** resource is used by a PISP to initiate the process of linking with a DFSP’s +account on behalf of a user. The PISP contacts the DFSP and sends a list of the permissions that +it wants to obtain and the accounts for which it wants permission. + +#### 3.1.2.1 Requests + +This section describes the services that can be requested by a client on the API resource +**/consentRequests**. +##### 3.1.2.1.1 **GET /consentRequests/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /consentRequests/**_{ID}_ is used to get information about a previously +requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the +request by the PISP when the PISP originated the request. + +Callback and data model information for **GET /consentRequests/**_{ID}_: +- Callback – **PUT /consentRequests/**_{ID}_ +- Error Callback – **PUT /consentRequests/**_{ID}_**/error** +- Data Model – Empty body + +##### 3.1.2.1.2 **POST /consentRequests** + +Used by: PISP + +The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more +accounts owned by a customer of the DFSP for the PISP who sends the request. + +Callback and data model for **POST /consentRequests**: +- Callback: **PUT /consentRequests/**_{ID}_ +- Error callback: **PUT /consentRequests/**_{ID}_**/error** +- Data model – see below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| consentRequestId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the consent request object. The ID should be reused for resends of the same consent request. A new ID should be generated for each new consent request. | +| userId | 1 | String(1..128) | The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest` | +| scopes | 1..256 | Scope | One or more requests for access to a particular account. In each case, the address of the account and the types of access required are given. | +| authChannels | 1..256 | ConsentRequestChannelType | A collection of the types of authentication that the DFSP may use to verify that its customer has in fact requested access for the PISP to the accounts requested. | +| callbackUri | 1 | Uri | The callback URI that the user will be redirected to after completing verification via the WEB authorization channel. This field is mandatory as the PISP does not know ahead of time which AuthChannel the DSFP will use to authenticate their user. | + +#### 3.1.2.2 Callbacks + +This section describes the callbacks that are used by the server under the resource /consentRequests. + +##### 3.1.2.2.1 **PUT /consentRequests/**_{ID}_ + +Used by: DFSP + +A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, +and (2) communicate to the PISP which `authChannel` it should use to authenticate their user +with. + +When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all +the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization +process may result in additional privileges being granted by the account holder to the PISP. The +**PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a +particular authorization request. The data model for this call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopes | 1..256 | Scope | One or more requests for access to a particular account. In each case, the address of the account and the types of access required are given. | +| authChannels | 1 | ConsentRequestChannelType | A list of one element, which the DFSP uses to inform the PISP of the selected authorization channel. | +| callbackUri | 0..1 | Uri |The callback URI that the user will be redirected to after completing verification via the WEB authorization channel | +| authUri | 0..1 | Uri | The URI that the PISP should call to complete the linking procedure if completion is required. | + + +##### 3.1.2.2.2 **PATCH /consentRequests/**_{ID}_ + +Used by: PISP + +After the user completes an out-of-band authorization with the DFSP, the PISP will receive +a token which they can use to prove to the DFSP that the user trusts this PISP. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authToken | 1 | BinaryString |The token given to the PISP by the DFSP as part of the out-of-band authentication process | + +#### 3.1.2.3 Error callbacks + +This section describes the error callbacks that are used by the server under the resource +**/consentRequests**. + +##### 3.1.2.3.1 **PUT /consentRequests/**_{ID}_**/error** + +Used by: DFSP + +If the server is unable to complete the consent request, or if an out-of-band processing error or +another processing error occurs, the error callback **PUT /consentRequests/**_{ID}_**/error** is used. The +*{ID}* in the URI should contain the *{ID}* that was used in the **GET /consentRequests/**_{ID}_ +request or the **POST /consentRequests** request. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + + +### 3.1.3 **/consents** + +The **/consents** resource is used to negotiate a series of permissions between the PISP and the +DFSP which owns the account(s) on behalf of which the PISP wants to transact. + +A **/consents** call is originally sent to the PISP by the DFSP following the original consent +request process described in Section 3.1.2.1.2 above. At the close of this process, the DFSP +which owns the customer’s account(s) will have satisfied itself that its customer really has +requested that the PISP be allowed access to their accounts, and will have defined the accounts in +question and the type of access which is to be granted. +#### 3.1.3.1 Requests +The **/consents** resource will support the following requests. +##### 3.1.3.1.1 **GET /consents/**_{ID}_ + +Used by: DFSP + +The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The +*{ID}* used in the URI of the request should be the consent request ID which was used to identify +the consent when it was created. + +Callback and data model information for **GET /consents/**_{ID}_: +- Callback – **PUT /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.3.1.2 **POST /consents** + +Used by: DFSP + +The **POST /consents** request is used to request the creation of a consent for interactions between +a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + +Callback and data model information for **POST /consents/**: + +- Callback – **PUT /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** +- Data Model – defined below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| consentId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the consent object. The ID should be reused for resends of the same consent. A new ID should be generated for each new consent.| +| consentRequestId | 1 | CorrelationId | The ID given to the original consent request on which this consent is based. | +| scopes | 1..256 | Scope | A list Scope objects, which represent the accounts and attached permissions on which the DFSP is prepared to grant specified permissions to the PISP. | +| status | 1 | ConsentStatus | The status of the Consent. | +| credential | 0..1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment | +##### 3.1.3.1.3 **DELETE /consents/**_{ID}_ + +Used by PISP, DFSP + +The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. +For tracing and auditing purposes, the switch should be sure not to delete the consent physically; +instead, information relating to the consent should be marked as deleted and requests relating to the +consent should not be honoured. + +> Note: the ALS should verify that the participant who is requesting the deletion is either the +> initiator named in the consent or the account holding institution named in the consent. If any +> other party attempts to delete a consent, the request should be rejected, and an error raised. + +Callback and data model information for **DELETE /consents/**_{ID}_: +- Callback – **PATCH /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** + +#### 3.1.3.2 Callbacks +The **/consents** resource supports the following callbacks: +##### 3.1.3.2.1 **PATCH/consents/**_{ID}_ + +Used by: Auth-Service, DFSP + +**PATCH /consents/**_{ID}_ is used in 2 places: +1. To inform the PISP that the `consent.credential` is valid and the account linking process completed + successfully. +2. To inform the PISP or the DFSP that the Consent has been revoked. + +In the first case, a DFSP sends a **PATCH/consents/**_{ID}_ request to the PISP with a `credential.status` +of `VERIFIED`. + +In the second case, an Auth-Service or DFSP sends a **PATCH/consents/**_{ID}_ request with a `status` of +`REVOKED`, and the `revokedAt` field set. + +The syntax of this call complies with the JSON Merge Patch specification [RFC-7386](https://datatracker.ietf.org/doc/html/rfc7386) +rather than the JSON Patch specification [RFC-6902](https://datatracker.ietf.org/doc/html/rfc6902). +The **PATCH /consents/**_{ID}_ resource contains a set of proposed changes to the current state of the +permissions relating to a particular authorization grant. The data model +for this call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| status | 0..1 | ConsentStatus | The status of the Consent. | +| revokedAt | 0..1 | DateTime | The DateTime the consent was revoked at. | +| credential | 0..1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | + +##### 3.1.3.2.2 **PUT /consents/**_{ID}_ + +Used by: PISP + +The **PUT /consents/**_{ID}_ resource is used to return information relating to the consent object +whose `consentId` is given in the URI. And for registering a credential for the consent. The +data returned by the call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopes | 1..256 | Scope | The scopes covered by the consent. | +| status | 0..1 | ConsentStatus | The status of the Consent. | +| credential | 1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | +#### 3.1.3.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource **/consents**. +##### 3.1.3.3.1 **PUT /consents/**_{ID}_**/error** + +Used by: PISP, DFSP, Auth-Service + +If the server is unable to complete the consent, or if an out-of-loop processing error or another +processing error occurs, the error callback **PUT /consents/**_{ID}_**/error** is used. The *{ID}* in the +URI should contain the *{ID}* that was used in the **GET /consents/**_{ID}_ request or the +**POST /consents** request. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.4 **/parties** + +The **/parties** resource will be used by the PISP to identify a party to a transfer. This will be +used by the PISP to identify the payee DFSP when it requests a transfer. + +The PISP will be permitted to issue a **PUT /parties** response. Although it does not own any +transaction accounts, there are circumstances in which another party may want to pay a customer +via their PISP identification: for instance, where the customer is at a merchant’s premises and +tells the merchant that they would like to pay via their PISP app. In these circumstances, the PISP +will need to be able to confirm that it does act for the customer. +#### 3.1.4.1 Requests + +The **/parties** resource will support the following requests. +##### 3.1.4.1.1 **GET /parties** + +Used by: PISP + +The **GET /parties** resource will use the same form as the resource described in +[Section 6.3.3.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6331-get-partiestypeid) of Ref. 1 above. +#### 3.1.4.2 Callbacks +The parties resource will support the following callbacks. +##### 3.1.4.2.1 **PUT /parties** + +Used by: DFSP + +The **PUT /parties** resource will use the same form as the resource described in +[Section 6.3.4.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6341-put-partiestypeid) of Ref. 1 above. + +### 3.1.5 **/services** +The **/services** resource is a new resource which enables a participant to query for other +participants who offer a particular service. The requester will issue a `GET` request, specifying +the type of service for which information is required as part of the query string. The switch will +respond with a list of the current DFSPs in the scheme which are registered as providing that +service. +#### 3.1.5.1 Requests +The services resource will support the following requests. +#### 3.1.5.2 **GET /services/**_{ServiceType}_ + +Used by: DFSP, PISP + +The HTTP request **GET /services/**_{ServiceType}_ is used to find out the names of the participants in a +scheme which provide the type of service defined in the *{ServiceType}* parameter. The *{ServiceType}* parameter +should specify a value from the ServiceType enumeration. If it does not, the request will be +rejected with an error. + +Callback and data model information for **GET /services/**_{ServiceType}_: +- Callback - **PUT /services/**_{ServiceType}_ +- Error Callback - **PUT /services/**_{ServiceType}_**/error** +- Data Model – Empty body +#### 3.1.5.3 Callbacks +This section describes the callbacks that are used by the server for services provided by the +resource **/services**. +##### 3.1.5.3.1 **PUT /services/**_{ServiceType}_ + +Used by: Switch + +The callback **PUT /services/**_{ServiceType}_ is used to inform the client of a successful result of +the service information lookup. The information is returned in the following form: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| providers | 0...256 | FspId | A list of the Ids of the participants who provide the service requested. | + +##### 3.1.5.3.2 **PUT /services/**_{ServiceType}_**/error** + +Used by: Switch + +If the server encounters an error in fulfilling a request for a list of participants who +provide a service, the error callback **PUT /services/**_{ServiceType}_**/error** is used to inform the +client that an error has occurred. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.6 **thirdpartyRequests/authorizations** + +The **/thirdpartyRequests/authorizations** resource is analogous to the **/authorizations** resource + described in [Section 6.6](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#66-api-resource-authorizations) of Ref. 1 above. The DFSP uses it to request the PISP to: + +1. Display the information defining the terms of a proposed transfer to its customer; +2. Obtain the customer’s confirmation that they want the transfer to proceed; +3. Return a signed version of the terms which the DFSP can use to verify the consent + +The **/thirdpartyRequests/authorizations** resource supports the endpoints described below. +#### 3.1.6.1 Requests + +This section describes the services that a client can request on the +**/thirdpartyRequests/authorizations** resource. +##### 3.1.6.1.1 **GET /thirdpartyRequests/authorizations/**_{ID}_ + +Used by: DFSP + +The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating +to a previously issued authorization request. The *{ID}* in the request should match the +`authorizationRequestId` which was given when the authorization request was created. + +Callback and data model information for **GET /thirdpartyRequests/authorizations/**_{ID}_: +- Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.6.1.2 **POST /thirdpartyRequests/authorizations** + +Used by: DFSP + +The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a + customer for the transfer described in the request. + +Callback and data model information for **POST /thirdpartyRequests/authorizations:** + +- Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** +- Data Model – See Table below + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authorizationRequestId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the authorization request object. The ID should be reused for resends of the same authorization request. A new ID should be generated for each new authorization request. | +| transactionRequestId | 1 | CorrelationId | The unique identifier of the transaction request for which authorization is being requested. | +| challenge | 1 | BinaryString | The challenge that the PISP’s client is to sign. | +| transferAmount | 1 | Money | The amount that will be debited from the sending customer’s account as a consequence of the transaction. | +| payeeReceiveAmount | 1 | Money | The amount that will be credited to the receiving customer’s account as a consequence of the transaction. | +| fees | 1 | Money | The amount of fees that the paying customer will be charged as part of the transaction. | +| payer | 1 | PartyIdInfo | Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| payee | 1 | Party | Information about the Payee in the proposed transaction | +| transactionType | 1 | TransactionType | The type of the transaction. | +| expiration | 1 | DateTime | The time by which the transfer must be completed, set by the payee DFSP. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment. | + +#### 3.1.6.2 Callbacks +The following callbacks are supported for the **/thirdpartyRequests/authorizations** resource +##### 3.1.6.2.1 **PUT /thirdpartyRequests/authorizations/**_{ID}_ + +Used by: PISP + +After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the +transaction to their user, and request that the client sign the `challenge` field using the credential +they previously registered. + +The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| responseType | 1 | AuthorizationResponseType | `ACCEPTED` or `REJECTED` | +| signedPayload | 0..1 | SignedPayload | If the `responseType` is `ACCEPTED`, `signedPayload` is required. | + +#### 3.1.6.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/authorizations**. +##### 3.1.6.3.1 **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** resource will have the same content +as the **PUT /authorizations/**_{ID}_**/error** resource described in [Section 6.6.5.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6651-put-authorizationsiderror) +of Ref. 1 above. +### 3.1.7 **/thirdpartyRequests/transactions** +The **/thirdpartyRequests/transactions` resource is analogous to the `/transactionRequests** +resource described in [Section 6.4](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#64-api-resource-transactionrequests) of Ref. 1 above. The PISP uses it to request the +owner of the PISP’s customer’s account to transfer a specified amount from the customer’s +account with the DFSP to a named Payee. + +The **/thirdpartyRequests/transactions** resource supports the endpoints described below. +#### 3.1.7.1 Requests + +This section describes the services that a client can request on the +**/thirdpartyRequests/transactions** resource. +##### 3.1.7.1.1 **GET /thirdpartyRequests/transactions/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /thirdpartyRequests/transactions/**_{ID}_ is used to get information +relating to a previously issued transaction request. The *{ID}* in the request should +match the `transactionRequestId` which was given when the transaction request was created. + +Callback and data model information for **GET /thirdpartyRequests/transactions/**_{ID}_: +- Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.7.1.2 **POST /thirdpartyRequests/transactions** + +Used by: PISP + +The HTTP request **POST /thirdpartyRequests/transactions** is used to request the creation +of a transaction request on the server for the transfer described in the request. + +Callback and data model information for **POST /thirdpartyRequests/transactions**: +- Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** +- Data Model – See Table below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| transactionRequestId | 1 | CorrelationId |Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| payee | 1 | Party |Information about the Payee in the proposed financial transaction. | +| payer | 1 | PartyIdInfo |Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| amountType | 1 | AmountType | SEND for send amount, RECEIVE for receive amount. | +| amount | 1 | Money | Requested amount to be transferred from the Payer to Payee. | +| transactionType | 1 | TransactionType |Type of transaction | +| note | 0..1 | Note | Memo assigned to Transaction. | +| expiration | 0..1 | DateTime |Can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, Merchant to know that their request has a time limit. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment. | +#### 3.1.7.2 Callbacks +The following callbacks are supported for the **/thirdpartyRequests/transactions** resource +##### 3.1.7.2.1 **PUT /thirdpartyRequests/transactions/**_{ID}_ + +Used by: DFSP + +After a PISP requests the creation of a Third Party Transaction request (**POST /thirdpartyRequests/transactions**) +or the status of a previously created Third Party Transaction request +(**GET /thirdpartyRequests/transactions/**_{ID}_), the DFSP will send this callback. + +The data model for this endpoint is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| transactionRequestState | 1 | TransactionRequestState | State of the transaction request. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | + +##### 3.1.7.2.2 **PATCH /thirdpartyRequests/transactions/**_{ID}_ + +Used by: DFSP + +The issuing PISP will expect a response to their request for a transfer which describes +the finalised state of the requested transfer. This response will be given by a `PATCH` call on the +**/thirdpartyRequests/transactions/**_{ID}_ resource. The *{ID}* given in the query string should be +the `transactionRequestId` which was originally used by the PISP to identify the transaction +request (see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above.) + +The data model for this endpoint is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| completedTimestamp | 0..1 | DateTime |Time and date when the transaction was completed, if it was completed. | +| transactionRequestState | 1 | TransactionRequestState | State of the transaction request | +| transactionState | 1 | TransactionState | State of the transaction created by the DFSP in response to this transaction request | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment | + +#### 3.1.7.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/transactions**. +##### 3.1.7.3.1 **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** resource will have the same content as +the **PUT /transactionRequests/**_{ID}_**/error** resource described in [Section 6.4.5.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6451-put-transactionrequestsiderror) of Ref. 1 above. + +### 3.1.8 **/thirdpartyRequests/verifications** + +The **/thirdpartyRequests/verifications** resource is used by a Payer DFSP to verify that an authorization +response received from a PISP was signed using the correct private key, in cases where the authentication service +to be used is implemented by the switch and not internally by the DFSP. The DFSP sends the original +challenge and the signed response to the authentication service, together with the `consentId` to be used +for the verification. The authentication service compares the response with the result of signing the +challenge with the private key associated with the `consentId`, and, if the two match, it returns a +positive result. Otherwise, it returns an error. + +The **/thirdpartyRequests/verifications** resource supports the endpoints described below. +#### 3.1.8.1 Requests +This section describes the services that a client can request on the **/thirdpartyRequests/verifications** +resource. +##### 3.1.8.1.1 **GET /thirdpartyRequests/verifications/**_{ID}_ + +Used by: DFSP + +The HTTP request **/thirdpartyRequests/verifications/**_{ID}_ is used to get information regarding a previously +created or requested authorization. The *{ID}* in the URI should contain the verification request ID +(see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) below) that was used for the creation of the transfer.Callback and data model +information for **GET /thirdpartyRequests/verifications/**_{ID}_: + +- Callback – **PUT /thirdpartyRequests/verifications/**_{ID}_ +- Error Callback – **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.8.1.2 **POST /thirdpartyRequests/verifications** + +Used by: DFSP + +The **POST /thirdpartyRequests/verifications** resource is used to request confirmation from an authentication +service that a challenge has been signed using the correct private key. + +Callback and data model information for **POST /thirdpartyRequests/verifications**: +- Callback - **PUT /thirdpartyRequests/verifications/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/verifications /**_{ID}_**/error** +- Data Model – See Table below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| verificationRequestId | 1 | CorrelationId |Common ID between the DFSP and authentication service for the verification request object. The ID should be reused for resends of the same authorization request. A new ID should be generated for each new authorization request. | +| challenge | 1 | BinaryString |The challenge originally sent to the PISP | +| consentId | 1 | CorrelationId |Common Id between the DFSP and the authentication service for the agreement against which the authentication service is to evaluate the signature | +| signedPayloadType | 1 | SignedPayloadType | The type of the SignedPayload, depending on the type of credential registered by the PISP | +| genericSignedPayload | 0..1 | BinaryString | Required if signedPayloadType is GENERIC. The signed challenge returned by the PISP. A BinaryString representing a signature of the challenge + private key of the credential. | +| fidoSignedPayload | 0..1 | FIDOPublicKeyCredentialAssertion | Required if signedPayloadType is FIDO. The signed challenge returned by the PISP in the form of a [`FIDOPublicKeyCredentialAssertion` Object](https://w3c.github.io/webauthn/#iface-pkcredential) | + +#### 3.1.8.2 Callbacks +This section describes the callbacks that are used by the server under the resource +**/thirdpartyRequests/verifications** +##### 3.1.8.2.1 **PUT /thirdpartyRequests/verifications/**_{ID}_ + +Used by: Auth Service + +The callback **PUT /thirdpartyRequests/verifications/**_{ID}_ is used to inform the client of the result +of an authorization check. The *{ID}* in the URI should contain the `authorizationRequestId` +(see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above) which was used to request the check, or the *{ID}* that was +used in the **GET /thirdpartyRequests/verifications/**_{ID}_. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authenticationResponse | 1 | AuthenticationResponse | The result of the authorization check. | +#### 3.1.8.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/verifications**. +##### 3.1.8.3.1 **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** + +Used by: Auth Service + +If the server is unable to complete the authorization request, or another processing error occurs, the +error callback **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** is used.The *{ID}* in the URI should +contain the `verificationRequestId` (see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above) which was used to request the +check, or the *{ID}* that was used in the **GET /thirdpartyRequests/verifications/**_{ID}_. + +The data model for this resource is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +## 3.2 Data Models + +The following additional data models will be required to support the Third Party API + +### 3.2.1 Element definitions +#### 3.2.1.1 Account + +The Account data model contains information relating to an account. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| address | 1 | AccountAddress | An address which can be used to identify the account | +| currency | 1 | Currency | The currency in which the account is denominated | +| accountNickname | 0..1 | Name | Display name of the account, as set by the account owning DFSP. This will normally be a type name, such as “Transaction Account” or “Savings Account” | +#### 3.2.1.2 AccountAddress + +The AccountAddress data type is a variable length string with a maximum size of 1023 characters and consists of: +- Alphanumeric characters, upper or lower case. (Addresses are case-sensitive so that they can contain data encoded in formats such as base64url.) +- Underscore (\_) +- Tilde (~) +- Hyphen (-) +- Period (.) Addresses MUST NOT end in a period (.) character + +An entity providing accounts to parties (i.e. a participant) can provide any value for an `AccountAddress` that is meaningful to that entity. +It does not need to provide an address that makes the account identifiable outside the entity’s domain. + +> ***IMPORTANT:* The policy for defining addresses and the life-cycle of these is at the discretion of the address space owner (the payer DFSP in this case).** +#### 3.2.1.3 AccountList +The AccountList data model is used to hold information about the accounts that a party controls. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| account | 1..256 | Account | Information relating to an account that a party controls. | + + +#### 3.2.1.5 AuthenticationResponse + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| AuthenticationResponse | 1 | Enum of String(1..32) | See [Section 3.2.2.1](#3221-AuthenticationResponse) below (AuthenticationResponse) for more information on allowed values.| +#### 3.2.1.6 BinaryString +The BinaryString type used in these definitions is as defined in [Section 7.2.17](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7217-binarystring) of Ref. 1 above. +#### 3.2.1.7 ConsentRequestChannelType +The ConsentRequestChannelType is used to hold an instance of the ConsentRequestChannelType enumeration. Its data model is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| ConsentRequestChannelType | 1 | Enum of String(1..32) | See [Section 3.2.2.4](#3223-consentrequestchanneltype) below ( ConsentRequestChannelType) for more information on allowed values. | + +#### 3.2.1.8 ConsentStatus +The ConsentStatus type stores the status of a consent request, as described in [Section 3.1.3.2.2](#31322-put-consentsid) above. Its data model is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| ConsentStatus | 1 | Enum of String(1..32) | See [Section 3.2.2.5](#3224-consentstatustype) below (ConsentStatusType) for more information on allowed values.| + +#### 3.2.1.9 CorrelationId +The CorrelationId type used in these definitions is as defined in [Section 7.3.8](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#738-correlationid) of Ref. 1 above. +##### 3.2.1.10 Credential +The Credential object is used to store information about a publicKey and signature that has been registered with a Consent. +This publicKey can be used to verify that transaction authorizations have been signed by the previously-registered privateKey, +which resides on a User's device. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| credentialType | 1 | CredentialType | The type of credential this is - `FIDO` or `GENERIC` | +| status | 1 | CredentialStatus | The current status of the credential. | +| genericPayload | 0..1 | GenericCredential | Required if credentialType is GENERIC. A description of the credential and information which allows the recipient of the credential to test its veracity. | +| fidoPayload | 0..1 | FIDOPublicKeyCredentialAttestation | Required if credentialType is FIDO. A description of the credential and information which allows the recipient of the credential to test its veracity. | + +##### 3.2.1.11 CredentialStatus +The CredentialStatus data type stores the state of a credential request. Its data model is as follows. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| CredentialStatus | 1 | Enum of String(1..32) |See [Section 3.2.2.6](#3225-CredentialStatus) below (CredentialStatus) for more information on allowed values. | + +##### 3.2.1.12 DateTime +The DateTime data type used in these definitions is as defined in [Section 7.2.14](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7214-datetime) of Ref. 1 above. +##### 3.2.1.13 ErrorInformation +The ErrorInformation data type used in these definitions is as defined in [Section 7.4.2](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#742-errorinformation) of Ref. 1 above + +Valid values for ErrorCode and ErrorDescription are defined in [Error Codes](#ErrorCodes) + +##### 3.2.1.14 ExtensionList +The ExtensionList data type used in these definitions is as defined in [Section 7.4.4](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#744-extensionlist) of Ref. 1 above. +##### 3.2.1.15 FspId +The FspId data type used in these definitions is as defined in [Section 7.3.16](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7316-fspid) of Ref. 1 above. + +##### 3.2.1.16 GenericCredential +The GenericCredential object stores the payload for a credential which is validated according to a comparison of the signature created from the challenge using a private key against the same challenge signed using a public key. Its content is as follows. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| publicKey | 1 | BinaryString | The public key to be used in checking the signature. | +| signature | 1 | BinaryString | The signature to be checked against the public key. | + +##### 3.2.1.17 Money +The Money type used in these definitions is a defined in [Section 7.4.10](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7410-money) of Ref. 1 above. +##### 3.2.1.18 Note +The Note data type used in these definitions is as defined in [Section 7.3.23](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7323-note) of Ref. 1 above. +##### 3.2.1.19 Party + +The Note data type used in these definitions is as defined in [Section 7.4.11](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7411-party) of Ref. 1 above. + +##### 3.2.1.20 PartyIdInfo +The PartyIdInfo data type used in these definitions is as defined in [Section 7.4.13](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7413-partyidinfo) of Ref. 1 above. + + +##### 3.2.1.21 Scope +The Scope element contains an identifier defining, in the terms of a DFSP, an account on which access types can be requested or granted. It also defines the access types which are requested or granted. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| address | 1 |AccountAddress | The address of the account to which the PISP wishes to be permitted access, or is being granted access | +| actions | 1..32 |ScopeAction | The action that the PISP wants permission to take in relation to the customer’s account, or that it has been granted in relation to the customer’s account| +##### 3.2.1.22 ScopeAction +The ScopeAction element contains an access type which a PISP can request from a DFSP, or which a DFSP can grant to a PISP. It must be a member of the appropriate enumeration. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopeAction | 1 | Enum of String(1..32)| See [Section 3.2.2.9](#3228-scopeenumeration) below (ScopeEnumeration) for more information on allowed values. | +##### 3.2.1.23 ServiceType +The ServiceType element contains a type of service where the requester wants a list of the participants in the scheme which provide that service. It must be a member of the appropriate enumeration. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| serviceType | 1 | Enum of String(1..32) | See [Section 3.2.2.10](#3229-servicetype) below (ServiceType) for more information on allowed values. | + +##### 3.2.1.24 TransactionType +The TransactionType type used in these definitions is as defined in [Section 7.4.18](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7418-transactiontype) of Ref. 1 above. +##### 3.2.1.25 TransactionState +The TransactionState type used in these definitions is as defined in [Section 7.3.33](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7333-transactionstate) of Ref. 1 above. +##### 3.2.1.26 Uri +The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. The regular expression for restricting the Uri type is as follows: +`^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? ` +##### 3.2.1.27 FIDOPublicKeyCredentialAttestation + +A data model representing a FIDO Attestation result. Derived from [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + +The `PublicKeyCredential` interface represents the below fields with a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). +For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| id | 1 | String(59..118) | The identifier of a keypair created by an authenticator | +| rawId | 0..1 | String(59..118) | The identifier of a keypair created by an authenticator, base64 encoded | +| response | 1 | AuthenticatorAttestationResponse | The attestation response from the authenticator | + +##### 3.2.1.28 FIDOPublicKeyCredentialAssertion + +A data model representing a FIDO Assertion result. Derived from [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential) in [WebAuthN](https://w3c.github.io/webauthn/). + +The `PublicKeyCredential` interface represents the below fields with a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). +For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| id | 1 | String(59..118) | The identifier of a keypair created by an authenticator | +| rawId | 0..1 | String(59..118) | The identifier of a keypair created by an authenticator, base64 encoded | +| response | 1 | AuthenticatorAssertionResponse | The assertion response from the authenticator | + +##### 3.2.1.29 AuthenticatorAttestationResponse + +A data model representing an [AttestationStatement](https://w3c.github.io/webauthn/#attestation-statement) from [WebAuthN](https://w3c.github.io/webauthn/). + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| clientDataJSON | 1 | String(121...512) | JSON string with client data | +| attestationObject | 1 | String(306...2048) | Object encoded in Concise Binary Object Representation(CBOR), as defined in [RFC-8949](https://www.rfc-editor.org/rfc/rfc8949)| + +##### 3.2.1.30 AuthenticatorAssertionResponse + +A data model representing an [AuthenticatorAssertionResponse](https://w3c.github.io/webauthn/#authenticatorassertionresponse). + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authenticatorData | 1 | String(29..256) | Information about the authenticator. | +| clientDataJSON | 1 | String(121..512) | base64 encoded JSON string containing information about the client. | +| signature | 1 | String(59..256) | The signature generated by the private key associated with this credential. | +| userHandle | 0..1 | String(1..88) | This field is optionally provided by the authenticator, and represents the user.id that was supplied during registration, as defined in [WebAuthN's user.id](https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-id).| + +##### 3.2.1.31 SignedPayload + +A data model representing a Third Party Transaction request signature. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| signedPayloadType | 1 | SignedPayloadType | `FIDO` or `GENERIC` | +| genericSignedPayload | 0..1 | BinaryString(256) | Required if signedPayloadType is of type `GENERIC`. A BinaryString(256) of a signature of a sha-256 hash of the challenge. | +| fidoSignedPayload | 0..1 | FIDOPublicKeyCredentialAssertion | Required if signedPayloadType is of type `FIDO`. | + +### 3.2.2 Enumerations +#### 3.2.2.1 AuthenticationResponse +The AuthenticationResponse enumeration describes the result of authenticating verification request. +| Name | Description | +| --- | ----------- | +| VERIFIED | The challenge was correctly signed. | +| REJECTED | The challenge was not correctly signed. | +#### 3.2.2.2 AuthorizationResponseType +The AuthorizationResponseType enumeration is the same as the AuthorizationResponse enumeration described in [Section 7.5.3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#753-authorizationresponse) of Ref. 1 above. +#### 3.2.2.3 ConsentRequestChannelType + +| Name | Description | +| --- | ----------- | +| WEB | DFSP can support authorization via a web-based login | +| OTP | DFSP can support authorization via a One Time PIN | + +#### 3.2.2.4 ConsentStatusType +The ConsentStatusType enumeration describes the allowed status values that a consent item can have. These are as follows: +| Name | Description | +| --- | ----------- | +| ISSUED | The consent has been issued by the DFSP. | +| REVOKED | The consent has been revoked. | + +#### 3.2.2.5 CredentialStatus +This contains the allowed values for the CredentialStatus +| Name | Description | +| --- | ----------- | +| PENDING | The credential has been created but not yet verified. | +| VERIFIED | Authentication service has verified the credential. | + +#### 3.2.2.6 CredentialType +The CredentialType enumeration contains the allowed values for the type of credential which is associated with a permission. +| Name | Description | +| --- | ----------- | +| FIDO | The credential is based on a FIDO challenge. Its payload is a FIDOPublicKeyCredentialAttestation object. | +| GENERIC | The credential is based on a simple public key validation. Its payload is a GenericCredential object | + +#### 3.2.2.7 PartyIdType +The PartyIdType enumeration is extended for PISPs to include a definition for the identifier which represents a link between a specific PISP and an account at a DFSP which a customer has given the PISP permission to access. + +| Name | Description | +| --- | ----------- | +| MSISDN | An MSISDN (Mobile Station International Subscriber Directory Number; that is, a phone number) is used in reference to a Party. The MSISDN identifier should be in international format according to the ITU-T E.16437 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.| +| EMAIL | An email is used in reference to a Party. The format of the email should be according to the informational RFC 369638.| +| PERSONAL_ID | A personal identifier is used in reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.| +| BUSINESS | A specific Business (for example, an organization or a company) is used in reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.| +| DEVICE | A specific device (for example, POS or ATM) ID connected to a specific business or organization is used in reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.| +| ACCOUNT_ID | A bank account number or FSP account ID should be used in reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.| +| IBAN | A bank account number or FSP account ID is used in reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.| +| ALIAS | An alias is used in reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.| +| THIRD_PARTY_LINK | A third-party link which represents an agreement between a specific PISP and a customer’s account at a DFSP. The content of the link is created by the DFSP at the time when it gives permission to the PISP for specific access to a given account.| + +#### 3.2.2.8 ScopeEnumeration + +| Name | Description | +| --- | ----------- | +| ACCOUNTS_GET_BALANCE | PISP can request a balance for the linked account | +| ACCOUNTS_TRANSFER | PISP can request a transfer of funds from the linked account in the DFSP | +| ACCOUNTS_STATEMENT | PISP can request a statement of individual transactions on a user’s account | + +#### 3.2.2.9 ServiceType +The ServiceType enumeration describes the types of role for which a DFSP may query using the /services resource. +| Name | Description | +| --- | ----------- | +| THIRD_PARTY_DFSP| DFSPs which will support linking with PISPs | +| PISP | PISPs | +| AUTH_SERVICE | Participants which provide Authentication Services | + +##### 3.2.2.10 SignedPayloadType +The SignedPayloadType enumeration contains the allowed values for the type of a signed payload +| Name | Description | +| --- | ----------- | +| FIDO | The signed payload is based on a FIDO Assertion Response. Its payload is a FIDOPublicKeyCredentialAssertion object. | +| GENERIC | The signed payload is based on a simple public key validation. Its payload is a BinaryString object | + +##### 3.2.2.11 AmountType +See [7.3.1 AmountType](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#731-amounttype) + +##### 3.2.2.12 TransactionRequestState +See [7.5.10 TransactionRequestState](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7510-transactionrequeststate) + + +## 3.3 Error Codes + +The Third Party API Error Codes are defined in [Section 7.6](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#76-error-codes) of ref 1 above. + +In addition, the Third Party API adds the following error codes, starting with the prefix `6`: + +- General Third Party Error -- **60**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6000** | Third party error | Generic error. | X | X | X | X | X | X | X | X | +| **6001** | Third party request error | Third party request failed. | X | X | X | X | X | X | X | X | +| **6003** | Downstream Failure | The downstream request failed. | X | X | X | X | X | X | X | X | + +- Permission Error -- **61**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6100** | Authentication rejection | Generic authentication rejection | | X | | | | X | | | +| **6101** | Unsupported scopes were requested | PISP requested scopes that the DFSP doesn’t allow/support | | X | X | | | | | | +| **6102** | Consent not granted | User did not grant consent to the PISP | | X | X | | | | | | +| **6103** | Consent not valid | Consent object is not valid or has been revoked | | X | X | | | X | X | X | +| **6104** | Third Party request rejection | The request was rejected | X | X | X | X | X | X | X | X | + +- Validation Error -- **62**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6200** | Invalid Consent Credential | The signature of the credential submitted by the PISP is invalid | | | X | | | | | | +| **6201** | Invalid transaction signature | The signature of the verification response doesn't match the credential | | | | | | X | | X | +| **6203** | Invalid authentication token | DFSP receives invalid authentication token from PISP. | | X | | | | | | | +| **6204** | Bad callbackUri | The callbackUri is deemed invalid or untrustworthy. | | X | | | | | | | +| **6205** | No accounts found | No accounts were found for the given identifier | X | | | | | | | | + diff --git a/docs/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml b/docs/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml new file mode 100644 index 000000000..327d244dd --- /dev/null +++ b/docs/technical/api/thirdparty/thirdparty-dfsp-v1.0.yaml @@ -0,0 +1,2625 @@ +openapi: 3.0.2 +info: + title: Mojaloop Third Party API (DFSP) + version: '1.0' + description: | + A Mojaloop API for DFSPs supporting Third Party functions. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) to perform actions on behalf of a DFSP's user should implement this API. + PISPs should implement the accompanying API - Mojaloop Third Party API (PISP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: 'The object sent in a `PUT /accounts/{ID}` request.' + properties: + accountList: + description: Information about the accounts that the DFSP associates with the identifier sent by the PISP + type: array + items: + title: Account + type: object + description: Data model for the complex type Account. + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + required: + - accountNickname + - id + - currency + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: The object sent in a `POST /consentRequests` request. + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: Scope + Account Identifier mapping for a Consent. + properties: + address: + title: AccountAddress + type: string + description: | + An address which can be used to identify the account. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + description: | + The permissions allowed on a given account by a DFSP as defined in + a consent object + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user’s account + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consentRequest. + - "WEB" - The Web auth channel. + - "OTP" - The OTP auth channel. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: 'The object sent in a `PATCH /consentRequests/{ID}` request.' + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consents: + parameters: + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for resends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatus + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatus + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: | + The type of the Credential. + - "FIDO" - A FIDO public/private keypair + - "GENERIC" - A Generic public/private keypair + status: + title: CredentialStatus + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/credential/properties/payload' + required: + - credentialType + - status + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + type: string + enum: + - VERIFIED + description: 'The Credential is valid, and ready to be used by the PISP.' + payload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + - payload + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: POST /thirdpartyRequests/authorizations request object. + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer’s account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer’s account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/signedPayloadType' + fidoSignedPayload: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/fidoSignedPayload' + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/1/properties/signedPayloadType' + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: The object sent in the POST /thirdpartyRequests/transactions request. + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + $ref: '#/paths/~1accounts~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/accountList/items/properties/currency' + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdPartyRequests/transactions/{ID} request.' + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: 'The object sent in the PATCH /thirdpartyRequests/transactions/{ID} callback.' + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/verifications: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - thirdpartyRequests + - sampled + operationId: PostThirdpartyRequestsVerifications + summary: PostThirdpartyRequestsVerifications + description: | + The HTTP request `POST /thirdpartyRequests/verifications` is used by the DFSP to verify a third party authorization. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The thirdparty authorization details to verify + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsVerificationsPostRequestFIDO + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + An object sent in a `PUT /thirdpartyRequests/authorization/{ID}` request. + based mostly on: https://webauthn.guide/#authentication + AuthenticatorAssertionResponse + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - fidoSignedPayload + - title: ThirdpartyRequestsVerificationsPostRequestGeneric + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - genericSignedPayload + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyRequestsVerificationsById + summary: GetThirdpartyRequestsVerificationsById + description: | + The HTTP request `/thirdpartyRequests/verifications/{ID}` is used to get + information regarding a previously created or requested authorization. The *{ID}* + in the URI should contain the verification request ID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsById + summary: PutThirdpartyRequestsVerificationsById + description: | + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}` is used by the Auth-Service to inform + the DFSP of a successful result in validating the verification of a Thirdparty Transaction Request. + + If the validation fails, The Auth-Service MUST use `PUT /thirdpartyRequests/verifications/{ID}/error` + instead. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The result of validating the Thirdparty Transaction Request + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsVerificationsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdpartyRequests/verifications/{ID} request.' + properties: + authenticationResponse: + type: string + enum: + - VERIFIED + description: The verification passed + required: + - authenticationResponse + example: + authenticationResponse: VERIFIED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsByIdAndError + summary: PutThirdpartyRequestsVerificationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}/error` is used by the Auth-Service to inform + the DFSP of a failure in validating or looking up the verification of a Thirdparty Transaction Request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' diff --git a/docs/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml b/docs/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml new file mode 100644 index 000000000..cb9f52f27 --- /dev/null +++ b/docs/technical/api/thirdparty/thirdparty-pisp-v1.0.yaml @@ -0,0 +1,2830 @@ +openapi: 3.0.1 +info: + title: Mojaloop Third Party API (PISP) + version: '1.0' + description: | + A Mojaloop API for Payment Initiation Service Providers (PISPs) to perform Third Party functions on DFSPs' User's accounts. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) should implement the accompanying API - Mojaloop Third Party API (DFSP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: 'The object sent in a `PUT /accounts/{ID}` request.' + properties: + accountList: + description: Information about the accounts that the DFSP associates with the identifier sent by the PISP + type: array + items: + title: Account + type: object + description: Data model for the complex type Account. + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + required: + - accountNickname + - id + - currency + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: The object sent in a `POST /consentRequests` request. + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: Scope + Account Identifier mapping for a Consent. + properties: + address: + title: AccountAddress + type: string + description: | + An address which can be used to identify the account. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + description: | + The permissions allowed on a given account by a DFSP as defined in + a consent object + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user’s account + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consentRequest. + - "WEB" - The Web auth channel. + - "OTP" - The OTP auth channel. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for PUT consentRequest/{ID} request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: 'The object sent in a `PATCH /consentRequests/{ID}` request.' + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consents: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for resends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatus + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatus + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: | + The type of the Credential. + - "FIDO" - A FIDO public/private keypair + - "GENERIC" - A Generic public/private keypair + status: + title: CredentialStatus + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/credential/properties/payload' + required: + - credentialType + - status + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + type: string + enum: + - VERIFIED + description: 'The Credential is valid, and ready to be used by the PISP.' + payload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + - payload + additionalProperties: false + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: POST /thirdpartyRequests/authorizations request object. + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer’s account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer’s account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + An object sent in a `PUT /thirdpartyRequests/authorization/{ID}` request. + based mostly on: https://webauthn.guide/#authentication + AuthenticatorAssertionResponse + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: The object sent in the POST /thirdpartyRequests/transactions request. + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/merchantClassificationCode' + name: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/name' + personalInfo: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/personalInfo' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + $ref: '#/paths/~1accounts~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/accountList/items/properties/currency' + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: 'The object sent in the PUT /thirdPartyRequests/transactions/{ID} request.' + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: 'The object sent in the PATCH /thirdpartyRequests/transactions/{ID} callback.' + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}': + parameters: + - name: Type + in: path + required: true + schema: + type: string + description: 'The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`.' + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesByTypeAndID + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesByTypeAndID2 + parameters: + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + title: PartiesTypeIDPutResponse + type: object + description: 'The object sent in the PUT /parties/{Type}/{ID} callback.' + properties: + party: + title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. An ExtensionList element has been added to this reqeust in version v1.1 + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + description: |- + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. + - EMAIL - An email is used as reference to a participant. The format of the email should be according to the informational [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. + partyIdentifier: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partyIdentifier' + partySubIdOrType: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partySubIdOrType' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + required: + - party + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubI}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - name: SubId + in: path + required: true + schema: + type: string + description: 'A sub-identifier of the party identifier, or a sub-type of the party identifier''s type. For example, `PASSPORT`, `DRIVING_LICENSE`.' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesSubIdByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesSubIdByTypeAndIDPut + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubId}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesSubIdErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D~1%7BSubId%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}': + parameters: + - name: ServiceType + in: path + required: true + schema: + type: string + description: 'The type of the service identifier. For example, `THIRD_PARTY_DFSP`' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetServicesByServiceType + summary: GetServicesByServiceType + description: | + The HTTP request `GET /services/{ServiceType}` is used to retrieve the list of participants + that support a specified service. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - services + - sampled + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /services/{ServiceType}` is used to return list of participants + that support a specified service. + operationId: PutServicesByServiceType + summary: PutServicesByServiceType + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ServicesServiceTypePutResponse + type: object + description: 'The object sent in a `PUT /services/{ServiceType}` request.' + properties: + providers: + type: array + minLength: 0 + maxLength: 256 + items: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + required: + - providers + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}/error': + parameters: + - $ref: '#/paths/~1services~1%7BServiceType%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /services/{ServiceType}/error` is used to return error information + operationId: PutServicesByServiceTypeAndError + summary: PutServicesByServiceTypeAndError + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' diff --git a/docs/technical/api/thirdparty/transaction-patterns-linking.md b/docs/technical/api/thirdparty/transaction-patterns-linking.md new file mode 100644 index 000000000..359d7b09e --- /dev/null +++ b/docs/technical/api/thirdparty/transaction-patterns-linking.md @@ -0,0 +1,415 @@ +--- +footerCopyright: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) | Ericsson, Huawei, Mahindra-Comviva, Telepin, and the Bill & Melinda Gates Foundation +--- + +# Transaction Patterns - Linking + +Mojaloop Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Linking](#Linking) + 3.1 [Pre-linking](#Pre-linking) + 3.2 [Discovery](#Discovery) + 3.3 [Request consent](#Requestconsent) + 3.4 [Authentication](#Authentication) + 3.5 [Grant consent](#Grantconsent) + 3.6 [Credential registration](#Credentialregistration) +4. [Unlinking](#Unlinking) + 4.1 [Unlinking without a Switch Hosted Auth Service](#UnlinkingwithoutaSwitchHostedAuthService) + 4.2 [Unlinking with a Switch Hosted Auth Service](#UnlinkingwithaSwitchHostedAuthService) +5. [Error Scenarios](#ErrorScenarios) + 5.1 [Discovery](#Discovery-1) + 5.2 [Bad consentRequests](#BadconsentRequests) + 5.3 [Authentication](#Authentication-1) + 5.4 [Grant consent](#Grantconsent-1) + +# 1. Preface + +This section contains information about how to use this document. + +## 1.1. Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2. Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3. References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document introduces the transaction patterns supported by the Third Party API relating +to the establishment of a relationship between a User, a DFSP and a PISP. + +The API design and architectural style of this API are based on [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) of Ref 1. above. + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Linking + +The goal of the linking process is to explain how users establish trust between +all three interested parties: + +1. User +2. DFSP where User has an account +3. PISP that User wants to rely on to initiate payments + +Linking is broken down into several separate phases: + +1. **Pre-linking** + In this phase, a PISP asks what DFSPs are available to link with. +2. **Request consent** + In this phase, a PISP attempts to establish trust between the 3 parties. +3. **Authentication** + In this phase, a User proves their identity to their DFSP. +4. **Grant consent** + In this phase, a PISP proves to the DFSP that the User and PISP have + established trust and, as a result, the DFSP confirms that mutual trust + exists between the 3 parties. +5. **Credential registration** + In this phase, a User establishes the credential they'll use to consent to + future transfers from the DFSP and initiated by the PISP. + +## 3.1 Pre-linking + +In this phase, a PISP Server needs to know what DFSPs are available to link +with. This is *unlikely* to be done on-demand (e.g., when a User clicks "link" +in the PISP mobile App), and far more likely to be done periodically and cached +by the PISP Server. The reason for this is simply that new DFSPs don't typically +join the Mojaloop network all that frequently, so calling this multiple times on +the same day would likely yield the same results. We recommend that the PISP +calls this request once per day to keep the list of available DFSPs up to date. + +The end-goal of this phase is for the PISP Server to have a final list of DFSPs +available and any relevant metadata about those DFPSs that are necessary to +begin the linking process. + +The PISP can display this list of DFSPs to their user, and the user can select +which DFSP they hold an account with for linking. + +![Pre-linking](./assets/diagrams/linking/0-pre-linking.svg) + +## 3.2 Discovery + +In this phase, we ask the user to select the type and value of identifier they use +with the DFSP they intend to link with. This could be a username, MSISDN (phone number), +or email address. + +The result of this phase is a list of potential accounts available for linking. +The user will then choose one or more of these source accounts and the PISP will +provide these to the DFSP when requesting consent. + +The DFSP MAY send back an `accountNickname` to the PISP in the list of accounts. This list +will be displayed to the user in the PISP application for them to select which accounts +they wish to link. A DFSP could obfuscate some of the nickname depending on their requirements +for displaying account information without authorizing the user. + +**NOTE:** When using the Web authentication channel, it's possible that the +choices made (i.e., the accounts to link with) will be overridden by the user in +a web view. In other words, the user may decide during the Authentication phase +that they actually would like to link a different account than those chosen at +the very beginning. This is perfectly acceptable and should be expected from +time to time. + +![Discovery](./assets/diagrams/linking/1-discovery.svg) + +## 3.3 Request consent + +In this phase, a PISP is asking a specific DFSP to start the process of +establishing consent between three parties: + +1. The PISP +2. The specified DFSP +3. A User that is presumed to be a customer of the DFSP in (2) + +The PISPs request to establish consent must include a few important pieces of +information: + +- The authentication channels that are acceptable to the User +- The scopes required as part of the consent (in this case, almost always just + the ability to view a balance of a specific account and send funds from an + account). + +Some information depends on the authentication channel used (either Web or OTP). +Specifically, if the web authentication channel is used, the following extra +information is required: + +- A callback URI of where a user can be redirected with any extra information. + +The end result of this phase depends on the authentication channel used: + +### 3.3.1 Web + +In the web authentication channel, the result is the PISP being instructed on +a specific URL where this supposed user should be redirected. This URL should be +a place where the user can prove their identity (e.g., by logging in). + +![Request consent](./assets/diagrams/linking/2-request-consent-web.svg) + +### 3.3.2 OTP / SMS + +In the OTP authentication channel, the DFSP sends an 'out of bound' OTP message +to their user (e.g. over SMS or Email). The PISP prompts the user for this OTP +message, and includes it in the `authToken` field in the **PATCH /consentRequests/**_{ID}_ +callback. + +![Request consent](./assets/diagrams/linking/2-request-consent-otp.svg) + +## 3.4 Authentication + +In the authentication phase, the user is expected to prove their identity to the +DFSP. Once this is done, the DFSP will provide the User with some sort of secret +(e.g., an OTP or access token). This secret will then be passed along to the +PISP so that the PISP can demonstrate a chain of trust: + +- The DFSP trusts the User +- The DFSP gives the User a secret +- The User trusts the PISP +- The User gives the PISP the secret that came from the DFSP +- The PISP gives the secret to the DFSP +- The DFSP verified that the secret is correct + +This chain results in the conclusion: The DFSP can trust the PISP is acting on +behalf of the User, and mutual trust exists between all three parties. + +The process of establishing this chain of trust depends on the authentication +channel being used: + +### 3.4.1 Web + +In the web authentication channel, the PISP uses the `authUri` field from +the **PUT /consentRequests/**_{ID}_ callback to redirect the user to the DFSP's +website where they can prove their identity (likely by a typical username and +password style login). + + +**Note:** Keep in mind that at this stage, the User may update their choices of +which accounts to link with. The result of this will be seen later on when +during the Grant consent phase, where the DFSP will provide the correct values +to the PISP in the `scopes` field. + +![Authentication (Web)](./assets/diagrams/linking/3-authentication-web.svg) + + +### 3.4.2 OTP + +When using the OTP authentication channel, the DFSP will send the User some sort +of one-time password over a pre-established channel (such as SMS). The PISP +should prompt the user for this one-time password and then provide it back +to the DFSP using the API call **PATCH /consentRequests/**_{ID}_. + +![Authentication (OTP)](./assets/diagrams/linking/3-authentication-otp.svg) +## 3.5 Grant consent + +Now that mutual trust has been established between all three parties, the DFSP +is able to create a record of that fact by creating a new Consent resource. +This resource will store all the relevant information about the relationship +between the three parties, and will eventually contain additional information +for how the User can prove that it consents to each individual transfer in the +future. + +This phase consists exclusively of the DFSP requesting that a new consent be +created. + +![Grant consent](./assets/diagrams/linking/4-grant-consent.svg) + + +## 3.6 Credential registration + +Once the consent resource has been created, the PISP will attempt to establish +with the DFSP the credential that should be used to verify that a user has +given consent for each transfer in the future. + +This will be done by storing a FIDO credential (e.g., a public key) on the Auth +service inside the consent resource. When future transfers are proposed, we will +require that those transfers be digitally signed by the FIDO credential (in this +case, the private key) in order to be considered valid. + +This credential registration is composed of three phases: (1) deriving the +challenge, (2) registering the credential, and (3) finalizing the consent. + +### 3.6.1 Deriving the challenge + +The PISP must derive the challenge to be used as an input to the FIDO Key +Registration step. This challenge must not be guessable ahead of time by +the PISP. + + +1. _Let `consentId` be the value of the `body.consentId` in the **POST /consents** request_ +2. _Let `scopes` be the value of `body.scopes` in the **POST /consents** request_ + +3. The PISP must build the JSON object `rawChallenge` +``` +{ + "consentId": , + "scopes": +} +``` + +4. Next, the PISP must convert this json object to a string representation using a [RFC-8785 Canonical JSON format](https://tools.ietf.org/html/rfc8785) + +5. Finally, the PISP must calculate a SHA-256 hash of the canonicalized JSON string. +i.e. `SHA256(CJSON(rawChallenge))` + +The output of this algorithm, `challenge` will be used as the challenge for the [FIDO registration flow](https://webauthn.guide/#registration) + + +### 3.6.2 Registering the credential + +Once the PISP has derived the challenge, the PISP will generate a new +credential on the device, digitally signing the challenge, and provide additional +information about the credential on the Consent resource: + +1. The `PublicKeyCredential` object - which contains the key's Id, and an [AuthenticatorAttestationResponse](https://w3c.github.io/webauthn/#iface-authenticatorattestationresponse) which contains the public key +2. A `credentialType` field set to `FIDO` +3. A `status` field set to `PENDING` + +> **Note:** Generic `Credential` objects +> While we are focused on FIDO first, we don't want to exclude PISPs who want +> to offer services to users over other channels, eg. USSD or SMS, for this +> reason, the API also supports a `GENERIC` Credential type, i.e.: +>``` +> CredentialTypeGeneric { +> credentialType: 'GENERIC' +> status: 'PENDING', +> payload: { +> publicKey: base64(...), +> signature: base64(...), +> } +> } +>``` + +The DFSP receives the **PUT /consents/**_{ID}_ call from the PISP, and optionally +validates the Credential object included in the request body. The DFSP then +asks the Auth-Service to create the `Consent` object, and validate the Credential. + +If the DFSP receives a **PUT /consents/**_{ID}_ callback from the Auth-Service, with a +`credential.status` of `VERIFIED`, it knows that the credential is valid according +to the Auth Service. + +Otherwise, if it receives a **PUT /consents/**_{ID}_**/error** callback, it knows that something +went wrong with registering the Consent and associated credential, and can inform +the PISP accordingly. + + +The Auth service is then responsible for calling **POST /participants/CONSENTS/**_{ID}_. +This call will associate the `consentId` with the auth-service's `participantId` and +allows us to look up the Auth service given a `consentId` at a later date. + +![Credential registration: Register](./assets/diagrams/linking/5a-credential-registration.svg) + + +### 3.6.3 Finalizing the Consent + +Once the DFSP is satisfied that the credential is valid, it calls +**POST /participants/THIRD_PARTY_LINK/**_{ID}_ for each account in the +`Consent.scopes` list. This entry is a representation of the account +link between the PISP and DFSP, which the PISP can use to specify +the _source of funds_ for the transaction request. + +Finally, the DFSP calls **PUT /consent/**_{ID}_ with the finalized Consent +object it received from the Auth Service. + + +![Credential registration: Finalize](./assets/diagrams/linking/5b-finalize_consent.svg) + + +# 4. Unlinking + +At some point in the future, it's possible that a User, PISP, or DFSP may decide +that the relationship of trust previously established should no longer exist. +For example, a very common scenario might be a user losing their mobile device +and using an interface from their DFSP to remove the link between the lost +device, the PISP, and the DFSP. + +To make this work, we simply need to provide a way for a member on the network +to remove the Consent resource and notify the other parties about the removal. + + +There are 2 scenarios we need to cater for with a **DELETE /consents/**_{ID}_ request: +1. A DFSP-hosted Auth Service, where no details about the Consent are stored in the Switch, and +2. A Switch hosted Auth Service, where the Switch hosted auth service is considered the Authoritative source on the `Consent` object + + +## 4.1 Unlinking without a Switch Hosted Auth Service +In this case, the switch passes on the **DELETE /consents/22222222-0000-0000-0000-000000000000** request to the DFSP in the `FSPIOP-Destination` header. + +![Unlinking-DFSP-Hosted](./assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg) + +In the case where Unlinking is requested from the DFSP's side, the DFSP can +simply call **PATCH /consents/22222222-0000-0000-0000-000000000000** to inform the PISP of an update to the +`Consent` object. + +## 4.2 Unlinking with a Switch Hosted Auth Service + +In this instance, the PISP still addresses it's **DELETE /consents/22222222-0000-0000-0000-000000000000** call to the +DFSP in the `FSPIOP-Destination` header. + +Internally, the switch will lookup the Authoritative source of the `Consent` object, +using the ALS Call, **GET /participants/CONSENT/**_{ID}_. If it is determined that there +is a Switch hosted Auth Service which 'owns' this `Consent`, the HTTP call **DELETE /consents/**_{ID}_ +will be redirected to the Auth Service. + +![Unlinking-Switch-Hosted](./assets/diagrams/linking/6b-unlinking-hub-hosted.svg) + +# 5.Error Scenarios + +## 5.1 Discovery + +When the DFSP is unable to find a user for the identifier in **GET /accounts/**_{ID}_, +the DFSP responds with error code `6205` in **PUT /accounts/**_{ID}_**/error**. + +![Accounts error](./assets/diagrams/linking/error_scenarios/1-discovery-error.svg) + +## 5.2 ConsentRequest Errors +When the DFSP receives the **POST /consentRequests** request from the PISP, the following processing errors +could occur: + +1. DFSP does not support the specified scopes: `6101`. For example, the `userId` specified does not match the specified accounts, or the `scope.actions` field contains permissions that this DFSP does not support. +2. The PISP sent a bad callbackUri: `6204`. For example, the scheme of the callbackUri could be http, which +the DFSP may choose to not trust. +3. Any other checks or validation of the consentRequests on the DFSP's side fail: `6104`. For example, the user's account may be inactive or suspended. + +In this case, the DFSP must inform the PISP of the failure by sending a **PUT /consentRequests/**_{ID}_**/error** callback to the PISP. + +![consentRequests error](./assets/diagrams/linking/error_scenarios/2-request-consent-error.svg) + +## 5.3 Authentication + +When a PISP sends a **PATCH /consentRequests/**_{ID}_ to the DFSP, the `authToken` may be expired or invalid: + +![Authentication Invalid OTP](./assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg) diff --git a/docs/technical/api/thirdparty/transaction-patterns-transfer.md b/docs/technical/api/thirdparty/transaction-patterns-transfer.md new file mode 100644 index 000000000..2b46f3c01 --- /dev/null +++ b/docs/technical/api/thirdparty/transaction-patterns-transfer.md @@ -0,0 +1,380 @@ +# Transaction Patterns - Transfer + +Mojaloop Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Transfers](#Transfers) + 3.1 [Discovery](#Discovery) + 3.2 [Agreement](#Agreement) + 3.3 [Transfer](#Transfer) +4. [Request TransactionRequest Status](#RequestTransactionRequestStatus) +5. [Error Conditions](#ErrorConditions) + 5.1 [Bad Payee Lookup](#badpayeelookup) + 5.2 [Bad Thirdparty Transaction Request](#badtptr) + 5.3 [Downstream FSPIOP-API Failure](#downstreamapifailure) + 5.4 [Invalid Signed Challenge](#invalidsignedchallenge) + 5.5 [Thirdparty Transaction Request Timeout](#thirdpartytransactionrequesttimeout) +6. [Appendix](#Appendix) + 6.1 [Deriving the Challenge](#DerivingtheChallenge) + +# 1. Preface + +This section contains information about how to use this document. + +## 1.1. Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2. Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3. References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document introduces the transaction patterns supported by the Third Party API relating +to the initiation of a Transaction Request from a PISP. + +The API design and architectural style of this API are based on [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) of Ref 1. above. + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Transfers + +Transfers is broken down into the separate sections: +1. **Discovery**: PISP looks up the Payee Party to send funds to + +2. **Agreement** PISP confirms the Payee Party, and looks up the terms of the transaction. If the User accepts the terms of the transaction, they sign the transaction with the credential established in the Linking API flow + +3. **Transfer** The Payer DFSP initiates the transaction, and informs the PISP of the transaction result. + +## 3.1 Discovery + +In this phase, a user enters the identifier of the user they wish to send funds to. The PISP executes a **GET /parties/**_{Type}/{ID}_** (or **GET /parties/**_{Type}/{ID}/{SubId}_) call and awaits a callback from the Mojaloop switch. [Section 6.3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#63-api-resource-parties) +of Ref 1. above describes the **/parties** resource in detail. + +If the **GET /parties/**_{Type}/{ID}_ request is successful, the PISP will receive a **PUT /parties** callback from the Mojaloop switch. The PISP then confirms the Payee with their user. + +Should the PISP receive a **PUT /parties/**_{Type}/{ID}_**/error** (or **PUT /parties/**_{Type}/{ID}/{SubId}_**/error**) callback, the PISP should display the relevant error to their user. + + + +![Discovery](./assets/diagrams/transfer/1-1-discovery.svg) + +## 3.2 Agreement + +### 3.2.1 Thirdparty Transaction Request + +Upon confirming the details of the Payee with their user, the PISP asks the user to enter the `amount` of funds they wish to send to the Payee, and whether or not they wish the Payee to _receive_ that amount, or they wish to _send_ that amount (`amountType` field). + +If the User has linked more than 1 account with the PISP application, the PISP application can ask the user to choose an account they wish to send funds from. Upon confirming the _source of funds_ account, the PISP can determine: +1. the `FSPIOP-Destination` as the DFSP who the User's account is linked with +2. The `payer` field of the **POST /thirdpartyRequests/transactions** request body. The `partyIdType` is `THIRD_PARTY_LINK`, the `fspId` is the fspId of the DFSP who issued the link, and the `partyIdentifier` is the `accountId` specified in the **POST /consents#scopes** body. + +> See [Grant Consent](./transaction-patterns-linking.md#Grantconsent) for more information. + +The PISP then generates a random `transactionRequestId` of type UUID (see [RFC 4122 UUID](https://tools.ietf.org/html/rfc4122)). + +![1-2-1-agreement](./assets/diagrams/transfer/1-2-1-agreement.svg) + +Upon receiving the **POST /thirdpartyRequests/transactions** call from the PISP, the DFSP performs some validation such as: +1. Determine that the `payer` identifier exists, and is one that was issued by this DFSP to the PISP specified in the `FSPIOP-Source`. +2. Confirms that the `Consent` that is identified by the `payer` identifier exists, and is valid. +3. Confirm that the User's account is active and holds enough funds to complete the transaction. +4. Any other validation that the DFSP wishes to do. + +Should this validation succeed, the DFSP will generate a unique `transactionId` for the request, and call **PUT /thirdpartyRequests/transactions/**_{ID}_ with this `transactionId` and a `transactionRequestState` of `RECEIVED`. + +This call informs the PISP that the Thirdparty Transaction Request was accepted, and informs them of the final `transactionId` to watch for at a later date. + +If the above validation fail, the DFSP should send a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** call to the PISP, +with an error message communicating the failure to the PISP. See [Error Codes](./data-models.md#errorcodes) for more information. + +### 3.2.2 Thirdparty Authorization Request + +The Payer DFSP (that is, the institution sending funds at the request of the PISP) may then issue a quotation request (**POST /quotes**) to the Payee DFSP (that is, the institution receiving the funds). Upon receiving the **PUT /quotes/**_{ID}_ callback from the Payee DFSP, the Payer DFSP needs to confirm the details of the transaction with the PISP. + +They use the API call **POST /thirdpartyRequests/authorizations**. The request body is populated with the following fields: + +- `transactionRequestId` - the original id of the **POST /thirdpartyRequests/transactions**. Used by the PISP to correlate an Authorization Request to a Thirdparty Transaction Request +- `authorizationRequestId` - a random UUID generated by the DFSP to identify this Thirdparty Authorization Request +- `challenge` - the challenge is a `BinaryString` which will be signed by the private key on the User's device. While the challenge +could be a random string, we recommend that it be derived from something _meaningful_ to the actors involved in the transaction, +that can't be predicted ahead of time by the PISP. See [Section 4.1](#DerivingtheChallenge) for an example of how the challenge +could be derived. +- `transactionType` the `transactionType` field from the original **POST /thirdpartyRequests/transactions** request + + +![1-2-2-authorization](./assets/diagrams/transfer/1-2-2-authorization.svg) + + +### 3.2.3 Signed Authorization + +Upon receiving the **POST /thirdpartyRequests/authorizations** request from the Payer DFSP, the PISP presents the terms of the proposed +transaction to the user, and asks them if they want to proceed. + +The results of the authorization request are returned to the DFSP via the **PUT /thirdpartyRequests/authorizations/**_{ID}_, where +the *{ID}* is the `authorizationRequestId`. + + +If the user rejects the transaction, the following is the payload sent in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + +```json +{ + "responseType": "REJECTED" +} +``` + +![1-2-3-rejected-authorization](./assets/diagrams/transfer/1-2-3-rejected-authorization.svg) + + +Should the user accept the transaction, the payload will depend on the `credentialType` of the `Consent.credential`: + +1. If `FIDO`, the PISP asks the user to complete the [FIDO Assertion](https://webauthn.guide/#authentication) flow to sign the challenge. + The `signedPayload.fidoSignedPayload` is the `FIDOPublicKeyCredentialAssertion` returned from the FIDO Assertion process. See [3.2.3.1 Signing the Challenge FIDO](#SigningTheChallengeFIDO) + +2. If `GENERIC`, the private key created during the [credential registration process](../linking/README.md#162-registering-the-credential) is + used to sign the challenge. See [3.2.3.2 Signing the Challenge with a GENERIC Credential](#SigningTheChallengeGeneric) + +#### 3.2.3.1 Signing the Challenge FIDO + +For a `FIDO` `credentialType`, the PISP asks the user to complete the [FIDO Assertion](https://webauthn.guide/#authentication) flow to sign the challenge. The `signedPayload.value` is the [`PublicKeyCredential`](https://w3c.github.io/webauthn/#publickeycredential) returned from the FIDO Assertion process, where the `ArrayBuffer`s are parsed as base64 encoded utf-8 strings. As a `PublicKeyCredential` is the response of both the FIDO Attestation and Assertion, we define the following interface: `FIDOPublicKeyCredentialAssertion`: + + +```json +FIDOPublicKeyCredentialAssertion { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" +} +``` + +The final payload of the **PUT /thirdpartyRequests/authorizations/**_{ID}_ is then: + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": FIDOPublicKeyCredentialAssertion + } +} +``` + +![1-2-3-signed-authorization-fido](./assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg) + + +#### 3.2.3.2 Signing the Challenge with a GENERIC Credential + +For a `GENERIC` credential, the PISP will perform the following steps: + + +1. Given the inputs: + - `challenge` (`authorizationRequest.challenge`) as a base64 encoded utf-8 string + - `privatekey` (stored by the PISP when creating the credential), as a base64 encoded utf-8 string + - SHA256() is a one way hash function, as defined in [RFC6234](https://datatracker.ietf.org/doc/html/rfc6234) + - sign(data, key) is a signature function that takes some data and a private key to produce a signature +2. _Let `challengeHash` be the result of applying the SHA256() function over the `challenge`_ +3. _Let `signature` be the result of applying the sign() function to the `challengeHash` and `privateKey`_ + +The response from the PISP to the DFSP then uses this _signature_ as the `signedPayload.genericSignedPayload` field: + + +The final payload of the **PUT /thirdpartyRequests/authorizations/**_{ID}_ is then: + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } +} +``` + +![1-2-3-signed-authorization-generic](./assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg) + + +### 3.2.4 Validate Authorization + +> __Note:__ If the DFSP uses a self-hosted authorization service, this step can be skipped. + +The DFSP now needs to check that challenge has been signed correctly, and by the private key that corresponds to the +public key that is attached to the `Consent` object. + +The DFSP uses the API call **POST /thirdpartyRequests/verifications**, the body of which is comprised of: + +- `verificationRequestId` - A UUID created by the DFSP to identify this verification request. +- `challenge` - The same challenge that was sent to the PISP in [3.2.2 Thirdparty Authorization Request](#ThirdpartyAuthorizationRequest) +- `consentId` - The `consentId` of the Consent resource that contains the credential public key with which to verify this transaction. +- `signedPayloadType` - The type of the SignedPayload, depending on the type of credential registered by the PISP +- `fidoValue` or `genericValue` - The corresponding field from the **PUT /thirdpartyRequests/authorizations** request body from the PISP. +The DFSP must lookup the `consentId` based on the `payer` details of the `ThirdpartyTransactionRequest`. + +![1-2-4-verify-authorization](./assets/diagrams/transfer/1-2-4-verify-authorization.svg) + +## 3.3 Transfer + +Upon validating the signed challenge, the DFSP can go ahead and initiate a standard Mojaloop Transaction using the FSPIOP API. + +After receiving the **PUT /transfers/**_{ID}_ call from the switch, the DFSP looks up the ThirdpartyTransactionRequestId for the given transfer, +and sends a **PATCH /thirdpartyRequests/transactions/**_{ID}_ call to the PISP. + +Upon receiving this callback, the PISP knows that the transfer has completed successfully, and can inform their user. + +![1-3-transfer](./assets/diagrams/transfer/1-3-transfer.svg) + + +# 4. Request TransactionRequest Status + +A PISP can issue a **GET /thirdpartyRequests/transactions/**_{ID}_ to find the status of a transaction request. + +![PISPTransferSimpleAPI](./assets/diagrams/transfer/get_transaction_request.svg) + +1. PISP issues a **GET /thirdpartyRequests/transactions/**_{ID}_ +1. Switch validates request and responds with `202 Accepted` +1. Switch looks up the endpoint for `dfspa` for forwards to DFSP A +1. DFSPA validates the request and responds with `202 Accepted` +1. DFSP looks up the transaction request based on its `transactionRequestId` + - If it can't be found, it calls **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** to the Switch, with a relevant error message + +1. DFSP Ensures that the `FSPIOP-Source` header matches that of the originator of the **POST /thirdpartyRequests/transactions** + - If it does not match, it calls **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** to the Switch, with a relevant error message + +1. DFSP calls **PUT /thirdpartyRequests/transactions/**_{ID}_ with the following request body: + ``` + { + transactionRequestState: TransactionRequestState + } + ``` + + Where `transactionId` is the DFSP-generated id of the transaction, and `TransactionRequestState` is `RECEIVED`, `PENDING`, `ACCEPTED`, `REJECTED`, as defined in [7.5.10 TransactionRequestState](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7510-transactionrequeststate) of the API Definition + + +1. Switch validates request and responds with `200 OK` +1. Switch looks up the endpoint for `pispa` for forwards to PISP +1. PISP validates the request and responds with `200 OK` + +# 5. Error Conditions + +After the PISP initiates the Thirdparty Transaction Request with **POST /thirdpartyRequests/transactions**, the DFSP must send either a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** or **PATCH /thirdpartyRequests/transactions/**_{ID}_ callback to inform the PISP of a final status to the Thirdparty Transaction Request. + +- **PATCH /thirdpartyRequests/transactions/**_{ID}_ is used to inform the PISP of the final status of the Thirdparty Transaction Request. This could be either a Thirdparty Transaction Request that was rejected by the user, or a Thirdparty Transaction Request that was approved and resulted in a successful transfer of funds. +- **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** is used to inform the PISP of a failed Thirdparty Transaction Request. +- If a PISP doesn't receive either of the above callbacks within the `expiration` DateTime specified in the **POST /thirdpartyRequests/transactions**, it can assume the Thirdparty Transaction Request failed, and inform their user accordingly + + +## 5.1 Unsuccessful Payee Lookup + +When the PISP performs a Payee lookup (**GET /parties/**_{Type}/{ID}_), they may receive the callback **PUT /parties/**_{Type}/{ID}_**/error**. + +See [6.3.4 Parties Error Callbacks](https://docs.mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#634-error-callbacks) of the FSPIOP API Definition for details on how to interpret use this error callback. + +In this case, the PISP may wish to display an error message to their user informing them to try a different identifier, or try again at a later stage. +## 5.2 Bad Thirdparty Transaction Request + +When the DFSP receives the **POST /thirdpartyRequests/transactions** request from the PISP, the following processing or validation errors may occur: +1. The `payer.partyIdType` or `payer.partyIdentifier` is not valid, or not linked with a valid **Consent** that the DFSP knows about +2. The user's account identified by `payer.partyIdentifier` doesn't have enough funds to complete the transaction +3. The currency specified by `amount.currency` is not a currency that the user's account transacts in +4. `payee.partyIdInfo.fspId` is not set - it's an optional property, but payee fspId will be required to properly address quote request +5. Any other checks or verifications of the transaction request on the DFSP's side fail + +In this case, the DFSP must inform the PISP of the failure by sending a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + +![3-2-1-bad-tx-request](./assets/diagrams/transfer/3-2-1-bad-tx-request.svg) + +The PISP can then inform their user of the failure, and can ask them to restart the Thirdparty Transaction request if desired. + + +## 5.3 Downstream FSPIOP-API Failure + +The DFSP may not want to (or may not be able to) expose details about downstream failures in the FSPIOP API to PISPs. + +For example, before issuing a **POST /thirdpartyRequests/authorizations** to the PISP, if the **POST /quotes** call with the Payee FSP fails, the DFSP sends a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + +![3-3-1-bad-quote-request](./assets/diagrams/transfer/3-3-1-bad-quote-request.svg) + +Another example is where the **POST /transfers** request fails: + +![3-3-2-bad-transfer-request](./assets/diagrams/transfer/3-3-2-bad-transfer-request.svg) + + +## 5.4 Invalid Signed Challenge + +After receiving a **POST /thirdpartyRequests/authorizations** call from the DFSP, the PISP asks the user to sign the `challenge` using the credential that was registered during the account linking flow. + +The signed challenge is returned to the DFSP with the call **PUT /thirdpartyRequest/authorizations/**_{ID}_. + +The DFSP either: +1. Performs validation of the signed challenge itself +2. Queries the Auth-Service with the **thirdpartyRequests/verifications** resource to check the validity of the signed challenge against the publicKey registered for the Consent. + +Should the signed challenge be invalid, the DFSP sends a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + + +### Case 1: DFSP self-verifies the signed challenge + +![3-4-1-bad-signed-challenge-self-hosted](./assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg) + + +### Case 2: DFSP uses the hub-hosted Auth-Service to check the validity of the signed challenge against the registered credential. + +![3-4-2-bad-signed-challenge-auth-service](./assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg) + +## 5.5 Thirdparty Transaction Request Timeout + +If a PISP doesn't receive either of the above callbacks within the `expiration` DateTime specified in the **POST /thirdpartyRequests/transactions**, it can assume the Thirdparty Transaction Request failed, and inform their user accordingly. + + +![3-6-tpr-timeout](./assets/diagrams/transfer/3-6-tpr-timeout.svg) + +# 6. Appendix + +## 6.1 Deriving the Challenge + +1. _Let `quote` be the value of the response body from the **PUT /quotes/**_{ID}_ call_ +2. _Let the function `CJSON()` be the implementation of a Canonical JSON to string, as specified in [RFC-8785 - Canonical JSON format](https://tools.ietf.org/html/rfc8785)_ +3. _Let the function `SHA256()` be the implementation of a SHA-256 one way hash function, as specified in [RFC-6234](https://tools.ietf.org/html/rfc6234)_ +4. The DFSP must generate the value `jsonString` from the output of `CJSON(quote)` +5. The `challenge` is the value of `SHA256(jsonString)` \ No newline at end of file diff --git a/docs/technical/api/thirdparty/transaction-patterns.md b/docs/technical/api/thirdparty/transaction-patterns.md new file mode 100644 index 000000000..5110f83e0 --- /dev/null +++ b/docs/technical/api/thirdparty/transaction-patterns.md @@ -0,0 +1,6 @@ +## Transaction Patterns + +The interactions and examples of how a DFSP and PISP will interact with the Third Party API can be found in the following Transaction Patterns Documents: + +1. [Linking](./transaction-patterns-linking.md) describes how an account link and credential can be established between a DFSP and a PISP +2. [Transfer](./transaction-patterns-transfer.md) describes how a PISP can initate a payment from a DFSP's account using the account link \ No newline at end of file diff --git a/docs/technical/business-operations-framework/Microfrontend-JAMStack.md b/docs/technical/business-operations-framework/Microfrontend-JAMStack.md new file mode 100644 index 000000000..666f21f27 --- /dev/null +++ b/docs/technical/business-operations-framework/Microfrontend-JAMStack.md @@ -0,0 +1,266 @@ +# Micro-frontend - JAMStack design +## Overview +The objective of the micro-frontend - JAMStack design is to create a framework that: + +- empowers the community to collaborate easily (by enabling independent development of components) +- makes extensions or customizations easy +- enables community members to contribute back into OSS without branching the whole codebase + +### Micro-frontends +The framework uses micro-frontends as a means of decoupling parts of the UI to enable maintainable codebases, autonomous teams, independent releases, and incremental upgrades of parts of the UI. + +### JAMStack +The [JAMStack](https://jamstack.org/) implementation reduces the role of the web server to the distribution static markup files, keeping the functionallity in JavaScript (that is running in the client browser) and in the backend API. +:::warning JAMStack stands for: + **J** - JavaScript + **A** - APIs + **M** - Static markup + ::: +This stack implementation is considered best practice as it: +- is much simpler to keep secure +- provides a good customer experience as it has fast web response times +- is inexpensive to host + +In addition, the following have also been engineered and are normally part of a JAMStack implementation: +- deployment to a content delivery network (CDN) +- atomic deploys +- uses dynamically loaded micro-frontends, so updating to the latest version is automatic + +## Technology stack + +1. **React** +The framework is based on the React library. +This is the most popular Single Page Application (SPA) library in use, and additionally this choice allows us to capitalize on other community efforts facilitating an easy conversion into this library. +It can be enhanced by using state container libraries (Redux, Flux, MobX), however there is no restriction on a specific one to use. +The micro-frontends come with preconfigured, isolated Redux stores. + +2. **Webpack 5** +Webpack 5 is currently the only JavaScript bundler that supports remote build separation. It is done by using the Module Federation Plugin. +It enables runtime composition to provide a smooth and fully transparent user experience to the users, resulting in a traditional Single Page Application. +There are additional benefits over other technologies, all that resulting in a small footprint and overall better experience for users. +Webpack 5 will implement the host / child micro-frontends integration at runtime. + +3. **CI/CD and atomic deployments** (for example, Github Actions) +Each implementation of the Business Operations Framework will need to implement their own atomic deployment solution. +The standard Business Operations project will use Github Actions to perform the task of executing a continuous integration pipeline, running the relevant tests, building the individual micro-frontend and deploying the resulting static files over a CDN and/or creating a Docker image. +Each micro-frontend is released in complete autonomy: the composed application can use the updated versions of each individual micro-frontend automatically, without involving any further coordination. + +4. **Running on a CDN** +The micro-frontends can run on a CDN. Individual builds are composed of only static files (HTML, CSS, JavaScript) and can be deployed in different locations / different URLs. +As long as they are available over a secure connection (HTTPS), micro-frontends can be served from any location and also from different CDNs. + +5. **Running in Kubernetes** +The micro-frontends can run in a Kubernetes environment. There are two approaches that can be taken here: + - The individual micro-frontends and the shell application are containerized (using, for example, Docker) and then hosted in Kubernetes. +The host and the children apps can be deployed on the same cluster or on different clusters as long as they are publicly accessible. + - Deploy a private CDN into the Kubernetes cluster, and host the static markup files on the CDN. +There are various CDNs available that are compatible with Kubernetes. + +## Webpack building + +The host and the children apps include scripts to build the distribution artifacts. The build can be done in the developer host machine, in the CI, and in Docker. + +## Micro-frontend loading + +The host is responsible for loading the children apps at runtime. It gathers information about the available children at runtime, from either an API or a registry. + +The host includes an internal engine responsible for loading only the necessary children when they need to be displayed. + +The individual micro-frontends will not be loaded when not necessary (for example, when a specific page is not accessed by the user). + +**High-level sequence diagram illustrating how microservices are loaded** +![High level sequence diagram illustrating how microservices are loaded](../../.vuepress/public/microfrontendloading.png) + +### Repository of micro-frontends +In order to provide a centralized authority responsible for controlling the individual micro-frontends meeting the necessary requirements, it is suggested to build a solution that works as a registry. + +The registry would serve the following purposes: + +1. allow the community to register the micro-frontends and specify some details +2. expose an API used by the host to retrieve information about the available micro-frontends +3. provide information around the versions of the available micro-frontends + +The registry does not exist yet, nor does it make sense to create it at this time. + +## Deployments + +The following overview diagram shows the deployment of the micro-frontends to a CDN. +::: tip NOTE +The deployment of the bounded context API is not covered in this diagram. +::: +![Overview diagram showing deployment](../../.vuepress/public/BizOps-Framework-Micro-frontend-deploy.png) + +The micro-frontends use atomic deployments and no full-build is ever required. + +Each individual micro-frontend deploys independently from the other ones. + +### Continuous Integration / Continuous Delivery (CI/CD) + +Each micro-frontend has its own CI/CD set up; there is no requirement to share the same setup or use the same CI tool. + +The CI/CD can be configured to support multiple environments, for example, DEV, QA, PROD. + +Here is an example file showing a git action workflow. + +```yml +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Use NodeJS ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache node modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: '**/node_modules' + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - run: yarn install --frozen-lockfile + - run: yarn lint + - run: yarn test + - run: yarn build +# - name: Slack Notification +# uses: rtCamp/action-slack-notify@v2.0.2 +# env: +# SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} +``` + +### CDNs + +The resulting SPA is served by a CDN or multiple CDNs. Individual micro-frontends can live in different CDNs. + +### Kubernetes + +The resulting SPA can run and be served in one or more Kubernetes environments. + +### Host application + +The host application comes with a pre-configured setup out-of-the-box. It does not need any particular configuration different from a traditional SPA more than the Webpack 5 Module Federation configuration. +It will be acting as the orchestrator, loading the remote micro-frontends and providing them with app-wide functionality, for example, authentication, RBAC, client-side routing. + +There is virtually no limit on how the host can grow and how much can be extended. +It is suggested, however, to centralize all the host-child communication and shared components in an external library so that both host and children have the same knowledge and integration will not break. + +### Versioning micro-frontends +​The suggested approach is to build a registry where individual apps are registered. The registry would allow to set some configuration on each app and keep track of all the available versions. +​ +The registry would then expose an API consumed by the host, providing information around the available micro-frontends, the versions, and the artifact locations. +​ +The registry would be administered by a trusted operator through a user interface; it would be the trusted operator's responsibility to decide which version of each individual app would be made public and available to the host to load. +It would also allow to easily test versions and roll back when necessary, all that without needing to rebuild and redeploy the apps. +​ +::: tip NOTE +The JS build artifacts created by Webpack do not include the version in the filename. It could be necessary to upgrade the build in order to differentiate versions. A simpler approach that does not require to update the build configuration would be hosting the versions on different URLs. +::: +​ +### Upgrading the host +​The host is pretty much self-isolated and the only necessary thing to do proper versioning is to use the built-in command `yarn version`. It will create a new git tag and increment the `package.json` version according to how the command is used (interactive CLI). +​ +### Upgrading the remotes +​The remotes are self-isolated and the only necessary thing to do proper versioning is to use the built-in command `yarn version`. It will create a new git tag and increment the `package.json` version according to how the command is used (interactive CLI). + +### Menu / App composition +​The host is configured to dynamically build the _Menu_ and the _Pages_ (with react-router) structure. Currently, the _Menu_ component(s) is imported from the `@modusbox/react-components` library. +​ +It is not strictly necessary to use such components and the host / remotes could use custom components, as long as they allow dynamic composition and support routing. +​​ +## Micro-frontend motivation in more detail + +​Building scalable and distributed user interfaces is complicated; logic complexity, testing setups, build and deployment costs increase over time. ​Architectural decisions taken in the initial phase can raise unnecessary complexity and highly affect development costs in later stages.​ Furthermore, a single project does not scale well with distributed teams co-working on the same codebase.​ Switching to a micro-frontend setup can solve all the above issues; it scales well, atomic deployments do not need a full build, and independent teams can use different codebases.​​ + +### What defines a micro-frontend + +​The main rules that can define a micro-frontend setup can be summarized in the following:​ + +**Single responsibility** +Defined and closed boundaries +Centralized orchestration​ +Single responsibility +​Each micro-frontend app should only provide specific business features. A micro-frontend app does not need to know about other aspects of the business and it can scale independently.​ + +**Defined and closed boundaries** +​Each micro-frontend should be isolated, own its own data, and direct communication between micro-frontends should not be possible.​ + +**Centralized orchestration** +​Each micro-frontend should be loaded, handled, and controlled by a host. Application-wide features are provided by the host (authentication, routing, and so on).​​ + +### Types of micro-frontend setups + +​There are several ways to implement micro-frontends, to list a few:​ +- Iframe composition +- Runtime composition +- Module federation (single framework) composition​ + +**Iframe composition** +​Iframe composition is possibly the oldest and easiest way to implement micro-frontends, due to old HTML support to iframes and the native context isolation it provides. Communication between the host and the micro-frontends is generally hard to achieve and also does not fit well in modern web.​ + +**Runtime composition** +​Runtime composition is the idea of dynamically loading JS scripts located over http/https urls and compose the result locally. ​While it allows you to theoretically use independent technologies for each micro-frontend, it is also very hard to maintain due to the differences between the frameworks used in the micro-frontends.​​ + +**SPA composition** +​Module federation is a technology implemented in Webpack 5 that allows you to dynamically load remote modules at runtime. When combined with a single application framework (for example, React), it allows built applications to be split into multiple micro-frontends without sacrificing the benefits an SPA provides. It also comes with the advantage of smaller build sizes.​​ + +### The chosen setup + +We have chosen to use SPA composition using Webpack 5 and React. It is worth mentioning that in order to build an SPA with multiple micro-frontends, a specific and rigorous contract between the host and the frontends needs to be implemented and respected.​ From now on we will be referring to micro-frontends in the technical form used by Webpack 5: remotes. ​The contract is defined by the following rules:​ + +- The host retrieves the list of remotes dynamically and asynchronously +- The host is responsible of loading the remotes +- The host shares some context with the remotes (routing, authentication) +- The remotes have unique names +- The remotes are deployed in different urls +- The remotes do not use global CSS rules +- The remotes export themselves as defined by the modules federation rules +- The remotes share the same React (and some library) version​ + +When these rules are respected, there is virtually no limit to how the SPA can grow.​ Most of the basic dependencies used in each frontend are provided by the host. That makes it easy when they need to be upgraded. ​Each application is built independently from the others; the CI/CD pipeline remains fast, atomic deployments do not require complex setups and each remote is released at its own pace with no need to modify the host in any way.​ + +### Live example hosted on a CDN + +Check out the following live example: [https://microfrontend-shell-boilerplate.vercel.app/](https://microfrontend-shell-boilerplate.vercel.app/) + +## Git repositories + +Here is a list of Git repositories that are part of this implementation: + + - [Micro frontend-shell-boilerplate](https://github.com/mojaloop/microfrontend-shell-boilerplate) + - [Micro frontend-boilerplate](https://github.com/mojaloop/microfrontend-boilerplate) + - [Micro frontend-utils](https://github.com/modusintegration/microfrontend-utils) +Library shared with both the shell application and the micro-frontend. + - [Reporting-Hub BizOps Role Assignment Micro-frontend](https://github.com/mojaloop/reporting-hub-bop-role-ui) + - [Reporting-Hub BizOps Transaction Tracing Micro-frontend](https://github.com/mojaloop/reporting-hub-bop-trx-ui) + diff --git a/docs/technical/business-operations-framework/README.md b/docs/technical/business-operations-framework/README.md new file mode 100644 index 000000000..b6690c1f7 --- /dev/null +++ b/docs/technical/business-operations-framework/README.md @@ -0,0 +1,58 @@ +# Introduction + +Join the collaboration for building a **“get started quickly”** set of core business processes that are easy to customize, contribute to open source, and follow best practice. + +The Business Operations Framework aims to help Hub Operators in building and deploying business process portals that support their business processes as defined in [Mojaloop business documentation](https://docs.mojaloop.io/mojaloop-business-docs/). The Business Operations Framework supports community collaboration in building a user experience (UX) for a Mojaloop Hub Operator that includes robust APIs, follows best practices, and is secure by design. The aim is to further support adoption and enhance the off-the-shelf value of the Mojaloop solution. + +The resulting user interface (UI) is not intended to be comprehensive, but to demonstrate an exemplar web experience that is easy to extend and customize. It is therefore important that Role Based Access Control (RBAC), interfacing with standard Identity Access Management (IAM) systems, API-level security control, micro-frontends and maker-checker workflows are supported. The UX architecture follows a pre-compiled bundle with a backing API pattern that can be deployed on a Content Delivery Network (CDN). + +This document provides a more detailed design, including security aspects, technologies used, and architecture patterns. + +The framework: +1. Implements a best practice RBAC and IAM integration/implementation. +2. Includes a deployment plan for including the RBAC and IAM solution into Mojaloop. +3. Includes a deployment plan for the UI portal so that it can be deployed into a CDN network. +4. Uses micro-frontends that are built from different repositories to decouple community efforts and facilitate easy extension and customizations. +5. Provides an audit trail of all activities performed. + +Three levels or degrees of control are required when configuring best practice security: +1. Daily access to IAM user interfaces where users are created, suspended, and their roles assigned. +2. Mappings of roles to permissions, which can be edited through a configuration change request. +3. Restrictions on API access on the basis of permissions available to a subject (a user or API client) through their roles. + +## Community effort – to-do list +The initial delivery of this framework includes a thin vertical slice to demonstrate the end-to-end functional implementation of the framework. Although this function that is delivered first serves an important puropse, this is not the end objective of this project. The objective is to provide a framework that other community efforts can contribute to. Here is the current to-do list of API backend process support/micro-frontends that are intended to be added to this framework by Mojaloop community implementation efforts: + +|Category|Description|Contributing Community Effort| +| --- | --- | --- | +|**Platform configuration**|Process to configure the platform so that it enforces the scheme and the scheme rules.| - | +|**Platform management**|Technical operational management controls for the platform.| Currently performed with Kibana Application Performance Monitoring (APM) and Elasticsearch. No current plan to move to framework. | +|**Liquidity management**|Process support for managing liquidity.|Financial Portal V2 - not yet part of framework.| +|**Participant lifecycle management
    (Hub view)**|Manage the onboarding and status transitions of participants.|Financial Portal V2 - not yet part of framework.| +|**Participant lifecycle management
    (DFSP view)**|Allow DFSPs to manage their status and interaction with the Hub.| - | +|**Settlement management**|Management interface for settlement.|DFSP reconciliation reports - Myanmar MFI Digitization (MMD) reports are being incorporated into the framework (accessed through an API).
    Multilateral deferred net settlement - Financal Portal V2 not yet available in framework.| +|**Transfer and transaction management**| Business Operations view of all transactions at the hub. | Financial Portal V2 - being converted into framework with enhancements. Enabling the tracing of a transfer end-to-end. | +|**Agreement (quoting) management**| - | - | +|**Account lookup and discovery management**| - | - | +|**Third-party-initiated payments management**| - | - | +|**Fees (interchange and billing) management**| - | - | +|**Reporting and analytics**| - | - | + +## Reference architecture +The reference architecture workstream has - through a collaborative process - designed the future/next version architecture of Mojaloop. The Business Operations Framework is being designed to work on the existing Mojaloop version (core v1.0). The Business Operations Framework must, however, be compatible with the reference architecture, and wherever possible, facilitate the move towards the reference architecture design. + +The following elements of the Business Operations framework project are directly contributing to the building of a reference architecture: +1. **Security bounded context** +This workstream RBAC implementation used some of the design ideas and seperations as defined in the reference architecture security bounded context. It didn't implement any of the interfaces what are necessry to consider this a security BC implementation. +2. **Reporting bounded context** +Part of the reporting bounded context is being built in this workstream. + +The split of the frontend into micro-frontends that can be built, tested, and released independently; empowering teams that create solutions within each bounded context to independently build API functionality and corresponding UI. Customizations and extensions to each bounded context are also easily supported with this design. + +Here is an overall view of how the operational APIs, experience APIs, and micro-frontends can be combined into the parts that form the Business Operations framework. + +![Architecture overview diagram compatible with the reference architecture ](../../.vuepress/public/BizOps-Framework-BizOps-Framework.png) + + +## IaC 4.xx +The next version of the "Infrastrcuture as Code" project plans on using a different set of tools than those currently in use in the Mojaloop Community; i.e. WSO2 with its Identity Server as a Key Manager (IS-KM) and the HAproxy implementations are to be replaced with Keycloak, Ambassador - Envoy tools. This design is compatible with the next IaC version. \ No newline at end of file diff --git a/docs/technical/business-operations-framework/ReportDeveloperGuide.md b/docs/technical/business-operations-framework/ReportDeveloperGuide.md new file mode 100644 index 000000000..fd6adf7ab --- /dev/null +++ b/docs/technical/business-operations-framework/ReportDeveloperGuide.md @@ -0,0 +1,319 @@ +# Report Developer Guide +This is a developer guide to building and deploying reports for the reporting REST service that is part of the deployment at the Hub. + +## Architecture +![Architecture diagram of reporting service operator](../../.vuepress/public/RestReportingArchitecture.drawio.png) +[Here](https://github.com/mojaloop/reporting) is the repository of the reporting service operator. +The reporting service operator has been designed to be accessed by either a hub operator, or a DFSP operator. +Access to the report is controlled through the RBAC integration that is part of the business operations framework. Ory Oathkeeper protects the reporting API end point, and Keto is checked by the reporting service operator for finer grained report specific authorisation. +The report data is queried from the SQL Reporting database which is at the moment a one way sync of the central ledger database. +Each report is installed on the system as a kubernetes custom resource which is a .yaml file of a particular format that is applied to the kubernetes cluster. [Here](https://github.com/mojaloop/reporting-k8s-templates) is the repository of the open sourced report templates. The custom resource definition for a report is defined [here](https://github.com/mojaloop/reporting-k8s-templates/blob/master/crds/reporting-crd.yaml) which describes the format of the custom resource. + +## RBAC +Access to the reports are controlled through the RBAC when the service is deployed through the standard IaC configuration. +This means that in order to access a report, a user will need to have the correct authorisation assigned. This is acheived through the assignement of roles to the user, and the assignment of participant access. + +The first authorisation check is made by Ory Oathkeeper which has a rule that links the +``` +reportingApi +``` +perission to assess to the reporting service API endpoint. + +The next authorisation check is made by the reporting service operator. Permission to access the particulat report is checked. The permission that is checked is defined in the custom resource. This permission is optional and will otherwise use the name (metadata) of the report as defined in the customer resource. +### Requiring DFSP permission +If the report is intended for a particular participant of DFSP, then it is imporant to use the 'dfspId' parameter. This paramter then first check for participant authoriasation before executing and producing the report. +I.e. +``` yaml + params: + - name: dfspId + required: true +``` +### Running the report +First you will need to login. The easiest way of doing this is to login to the Financial Portal. This create the authorisation and authentication cookie tokens which the report then uses. +Here is an example of accessing the report directly after loggin. +``` +https://bofportal.YourEnvironment.YourDomain.com/proxy/reports/MyReportPath?ReportParamter=25 +``` + +### report output formats +The report supports multiple output formats. To switch between these use the format paramter in the Rest query. +1. Excel file +``` +&format=xlsx +``` +2. Comma seperated values +``` +&format=csv +``` +3. JSON class format +``` +&format=json +``` +4. HTML browser format (this is the default format output) +``` +&format=html +``` + +## Kubernetes Custom Resource +All aspects of a report are controlled through the mojaloopreport custome resource file. The definition of that file looks as follows. + +### Custom Resource Definition +``` yml +kind: CustomResourceDefinition +apiVersion: apiextensions.k8s.io/v1 +metadata: + name: mojaloopreports.mojaloop.io +spec: + group: mojaloop.io + scope: Namespaced + names: + plural: mojaloopreports + singular: mojaloopreport + shortNames: + - mlreport + kind: MojaloopReport + listKind: MojaloopReportList + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: MojaloopReport is the Schema for MojaloopReport API + type: object + properties: + apiVersion: + description: >- + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the + latest internal value, and may reject unrecognized values. More + info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: >- + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the + client submits requests to. Cannot be updated. In CamelCase. + More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MojaloopReport.spec describes the desired state of my resource + type: object + required: + - endpoint + - queries + - template + properties: + permission: + description: Permission to be needed to access this report. This is optional. If unspecified, the name of the resource will be considered as permission. + type: string + endpoint: + description: Reporting endpoint + type: object + required: + - path + properties: + path: + description: Report URL path + type: string + params: + description: Report query params + type: array + items: + description: Query param + type: object + required: + - name + properties: + name: + description: Query param name + type: string + required: + description: Make query param required + type: boolean + default: + description: Default query param value + type: string + queries: + description: The list of queries used in ejs reporting template + type: array + items: + description: permission ID. + type: object + required: + - name + - query + properties: + name: + description: Variable name that the query result will be assigned to + type: string + query: + description: SQL query + type: string + template: + description: ejs reporting template + type: string + + status: + description: The status of this MojaloopReport resource, set by the operator. + type: object + properties: + state: + description: The state of the report. + type: string + additionalPrinterColumns: + - name: endpoint + type: string + description: Reporting endpoint + jsonPath: .spec.endpoint.path + conversion: + strategy: None +``` +Example of reports that conform to this custom resource can be found [here](https://github.com/mojaloop/reporting-k8s-templates/tree/master/templates). +Please note that these Yaml files also contain **helm directives** in these files denoted by the double curly brackets. +``` +{{ some helm directive / function }} +``` +If you intend to manually apply these files to kubernetes, these will need to be removed or replaced. + +### Kubectl +You can use the following command to apply a report custom resource to a kubernetes instance. + ``` + kubectl apply -f resources/examples/participant_list.yaml + ``` + +Let's cover some of the details in the custome resource. + +### Control how the report is called +The first part of the spec: of the report defines how the report is called. +I.e. +``` yaml +spec: + permission: report-dfsp-settlement-detail + endpoint: + path: /dfspSettlementDetail + params: + - name: settlementId + required: true + - name: fspid + required: true +``` +- **permission** this is where the RBAC permission tag for this report is defined +- **path** this is the endpoint path for this report +- **params** here the paramters for the report are defined and specified if they are required paramters or not. + +### Control where the report gets it data from +``` yaml +queries: + - name: dfspInfo + query: | + SELECT participantId, name FROM participant WHERE name = :fspid AND name != 'Hub' + - name: report + query: | + SELECT + pCPayer.participantId as payerFspid, +``` +In the queries section, any number of queries can be defined that are run against the reporting database and loaded into named json classes. +Input parameters can be used in the queries by using a colon in front of the parameter name. e.g. +``` +:paramname +``` +### Control how the reports look like +The template part of the custom resource file contains an EJS script that is use to produce the report. +These scripts look like html with styling, but contain code within script blocks +``` ejs +<% ejs script %> +``` +The EJS scripts are quite versitile and can be used to change a name text, or define formatting functions, or loops that loop through data. + +## Building your development environment +*(Installation this service locally to aid development.)* +Currently the only way to validate the report design, is to apply the report to the kubernetes that the reporting service is running in. The reporting service will initially validate the report, and then enable the endpoint. The report can be run and checked to see if it meets it's requirements. + +This document provides instructions for deploying this service locally, so that a developer can try out their designs before installing the report in a an environment +Since the reporting service follows K8S operator pattern, we need to deploy a mini Kubernetes cluster on our machine and deploy the reporting service along with some dependent services. + +### Pre-requisites +- Please make sure that you have the following softwares installed + - git + - docker + - minikube + - kubectl + - helm + - mysql-client + +### Install K8S +- Start minikube K8S cluster with the following command + ``` + minikube start --driver=docker --kubernetes-version=v1.21.5 + ``` + +### Clone the repository +- Download the repository + ``` + git clone https://github.com/mojaloop/reporting.git + cd reporting + ``` + +### Deploy helm chart +- Install helm chart using the following commands + ``` + helm dep up ./resources/test-integration/ + helm install test1 ./resources/test-integration/ --set reporting-legacy-api.image.tag=v11.0.0 + ``` +- Wait for all the services to be up + You can monitor the pods health or use the following commands to wait for the services + ``` + kubectl -n default rollout status deployment test1-reporting-legacy-api + kubectl -n default rollout status statefulset mysql + ``` + +### Restore mysql database backup +- Port forward the mysql service + ``` + kubectl port-forward -n default service/mysql 3306:3306 + ``` +- Insert sample data into database. You can change the database name and filename in the following command as per your need. + ``` + mysql -h127.0.0.1 -P3306 -uuser -ppassword default < ./resources/examples/participants_db_dump.sql + ``` + +### Load reporting template +- Adding the custom resource using the following command + ``` + kubectl apply -f resources/examples/participant_list.yaml + ``` + +### Get the report +- Port forward the reporting service + ``` + kubectl port-forward -n default service/test1-reporting-legacy-api 8080:80 + ``` +- Get the report by opening the following URL in browser + ``` + http://localhost/participant-list + ``` + +### Cleanup +- Cleanup + ``` + kubectl delete -f resources/examples/participant_list.yaml + helm uninstall test1 + minikube stop + ``` + +## Deploying to a production environment +There are multiple ways that a report custom resource can be deployed into an environment. The method that has been chosen and built into the IaC offering involves the use of a helm chart. (This aligns well with other Mojaloop components.) + +The IaC enables both a public and a private deployment of reports. The process is identical except for the repository being private and residing within organisation's source control. +At a high level the process looks as follows: +1. Branch and commit changes to the repository where the report is deployed from. +2. Create a pull request and merge the changes into the master branch of the repository. +3. Create a new release on the repository. (Depending on configuration this typically kicks off a CICD mechanism that builds and publishes the helm package.) +4. Update the IaC to depoly the new helm release version for the reports. +5. Run the appropriate pipeline to perform the deployment. + diff --git a/docs/technical/business-operations-framework/ReportingBC.md b/docs/technical/business-operations-framework/ReportingBC.md new file mode 100644 index 000000000..5b1eeff49 --- /dev/null +++ b/docs/technical/business-operations-framework/ReportingBC.md @@ -0,0 +1,498 @@ +# Reporting bounded context implementation +One of the objectives of this workstream project is to provide the ability to trace a transfer end to end. In order to deliver on this objective, part of the reporting bounded context (BC) is to be built in line with the reference architecture. + +## Design overview +Here is the overall architectural design. +![Architecture overview diagram of reporting bounded context](../../.vuepress/public/Reporting-&-Auditing-Overview.png) + +In Mojaloop, all the core services are already pushing events to Kafka on a topic (called 'topic-event'). + +There are two fundamental reporting databases: +1. **Reporting DB** +The reporting database is a relational database that keeps track of the latest state of the Mojaloop objects and makes them available through an efficent query interface. \ +\ +In the implementation of this workstream effort, a dedicated replica of the central ledger database will be used for reporting. This does not quite fit the architectural model, as a database owned by the reporting bounded context should not have external depencencies. A central ledger replica database is dependent on the schema of the central ledger and therefore has an external dependency. +::: warning Technical Debt +This should be recognized as **technical debt** that should be paid as more of the reference architecture is built. +::: +There are two approaches that can be adopted when paying this technical debt: + - Changing the replica call to a **one-way data sync** function, which would decouple the schemas of the two databases. + - Rebuilding a new designed **relational database**, which is updated based on subscribed Kafka topics. + +The best approach will depend on the state of the current Mojaloop version at the time that this debt is paid. \ +\ +2. **Event DB store** +The event DB store is a capture of the event details that can provide a more detailed reporting view of what happened. + +**Limitations of the event store effort in this workstream** +This design will be implemented on the current Mojaloop version. + +Currently, only the data required to provide end-to-end tracing of a transfer will be collected and made available through the reporting API. Extensions to this offering can easily be added by extending the event processor to process new use case messages and store them in the Mongo DB, and then configure the generic graphQL resource query in order to query the new data stores appropriately. + +## Alignment with reference architecture +Although the bounded context refers to reporting and auditing, this project only begins to tackle the reporting part of that definition. The current design is independent from other bounded contexts, which is in line with the reference architecture. +(There isn't a complete seperation as the current design is using a replica database as the reporting database. The technical debt and next steps to resolve this are described above.) + +It is important to consider how this bounded context will change as more of the reference architecture design is implemented. + +Bounded contexts will - during the reference architecture implmentation - stop storing data in the central ledger databases. + +There are three approaches that can be adopted to accommodate this change. How the reference architecture is built will determine which is the best approach: +1. Modifying the sync functionality to accomodate the bounded context new data store. +2. Extending the message event processor to capture the required information in the reporting database. +3. Calling newly defined bounded context APIs, to retrieve the required data. + +## Use cases to support the tracing of a transfer + +In order to effectively trace a transfer end to end, four use cases were defined. + +### Use case 1: Dashboard view + +**As a** Hub Operator Business Operations Specialist, +**I want** a high-level dashboard summary of the transfers moving through the hub, which is derived from a date-time range, +**So that** I can proactively monitor the health of the ecosystem. + +:::::: col-wrapper +| Data returned | +| --- | +| Transfer count | +| Transfer amount total per currency | +| Transfer count per error code | +| Transfer count per Payer DFSP | +| Transfer count per Payee DFSP | +| Transfer amount per currency per Payer DFSP | +| Transfer amount per currency per Payee DFSP | +::::::::: + +### Use case 2: Transfer list view + +**As a** Hub Operator Business Operations Specialist, +**I want to** view a list of transfers that can be filtered based on one or more of the following: +- Always required (must be provided in every call) + - Date-time range + +- Optional filters + - A specific Payee DFSP + - A specific Payee ID type + - A specific Payee + - A specific Payer DFSP + - A specific Payer ID type + - A specific Payer + - State of the transfer + - Currency + +- Nice to have filters (not a strict requirement, but should be provided if the design allows for it) + - A specific error code + - Settlement window + - Settlement batch ID: The unique identifier of the settlement batch in which the transfer was settled. If the transfer has not been settled yet, it is blank. + - Search string on messages + +**So that** I can proactively monitor the health of the ecosystem by having a more detailed view of the transfer data moving through the hub. + +:::::: col-wrapper +| Data returned | | +| --- | --- | +| Transfer ID | The unique identifier of the transfer | +| Transfer State | Indicates if the transfer has succeeded, is pending, or an error has occurred | +| Transfer Type | (For example: P2P) | +| Currency | The transfer currency | +| Amount | The transfer amount | +| Payer DFSP | | +| Payer ID Type | | +| Payer | | +| Payee DFSP | | +| Payee ID Type | | +| Payee | | +| Settlement Batch ID | The unique identifier of the settlement batch in which the transfer was settled.
    If the transfer has not been settled yet, it is blank. | +| Date Submitted | The date and time when the transfer was initiated. | +::::::::: + +### Use case 3: Transfer detail view + +**As a** Hub Operator Business Operations Specialist, +**I want to** trace a specific transfer from its transfer ID, +**So that** I can identify: + +- The timing and current state of the transfer +- Any error information that is associated with that transfer +- The associated quoting information and timing for that transfer +- The associated settlement process status and identifiers + +:::::: col-wrapper +| Data returned | | +| --- | --- | +| Transfer ID | The unique identifier of the transfer | +| Transfer State | Indicates if the transfer has succeeded, is pending, or an error has occurred | +| Transfer Type | (For example: P2P) | +| Currency | The transfer currency | +| Amount | The transfer amount | +| Settlement Batch ID | The unique identifier of the settlement batch in which the transfer was settled.
    If the transfer has not been settled yet, it is blank. | +| Payer | | +| Payer Details | The unique identifier of the Payer (typically, a MSISDN, that is, a mobile number) | +| Payer DFSP | | +| Payee DFSP | | +| Payee | | +| Payee Details | The unique identifier of the Payee (typically, a MSISDN, that is, a mobile number) | +| Transfer State | Indicates if the transfer has succeeded, is pending, or an error has occurred | +| Date Submitted | The date and time when the transfer was initiated | +::::::::: + +### Use case 4: Transfer message view + +**As a** Hub Operator Business Operations Specialist, +**I want to** view the detailed messages from its transfer ID, +**So that** I can investigate any unexpected problem associated with that transfer. + +:::::: col-wrapper +| Data returned | | +| --- | --- | +| Scheme Transfer ID | | +| TransferID | | +| QuoteID | | +| Home Transfer ID | | +| Payer and Payee Information | Id Type, Id Value, Display Name, First Name, Middle Name,
    Last Name, Date of birth, Mechant classification code,
    FSP Id, Extension List | +| Party Lookup Response | | +| Quote Request | | +| Quote Response | | +| Transfer Prepare | | +| Transfer Fulfill | | +| Error message/s | | +::::::::: + +## Business workflow +Here is a business workflow that describes how the use cases are called. +![Business workFlow](../../.vuepress/public/BusinessFlowView.png) + +## Tools chosen +### Event Data Store: MongoDB +The MongoDB database was chosen because: + - MongoDB is currently used and deployed in Mojaloop, and is an excepted open-source tool that optionally has standard companies that can provide enterprise support should it be required. + - MongoDB will meet our requirements for this project. + - Other tools were considered but were found not to meet all the requirements for an OSS tool in Mojaloop. + +### API: GraphQL +In addition to the existing reporting API, a GraphQL API will be deployed too. This new API will have the additional functionality of being able to access the event reporting database as supplementary data or standalone query data. + +The GraphQL API implementation was added for these reasons: + - A more natural RBAC modelling implementation + - Easier to mix data from different sources into a single resource + - Existing reporting solution's implementation resulted in very complex SQL statements that required specialist knowledge to build and maintain. Splitting the data into a more natural resource and subsequent SQL statement simplifies both the SQL statement and the useage of that resource. + - In the team we had an GraphQL expert who knew the best lib and tools to use. + - A generic implementation was built so that no special GraphQL knowledge would be required to extend the functionality. + +**Additional advantages of using GraphQL** + - Reusable resources/associated RBAC permissions between reports + - Complex queries are simpler to build because resources are modeled + - Mixing of data sources in a single query (for example, MySQL with MongoDB) + - No requirement for nested fetches + - No requirement for multiple fetches + - No requirement for API version. API naturally supports backward compatibility between versions. + - Self-documenting API + +**Introduction of a new technology** +The introduction of a new technology into the community does bring some risk and a requirement to learn and maintain a new technology. An attempt to reduce the impact of this has been made by implementing the API using a generic or template approach, minimizing the GraphQL knowledge requirement to implement. A GraphQL query example has additionally be supplied. + +The current GraphQL implementation is developer-friendly. + +**Reporting REST implementation** +There is a REST reporting API implementation that has been donated to the Mojaloop community. It is possible to deploy this functionality alongside the GraphQL API implmentation if it becomes neccessary to do so. + +### GraphQL API - generic resource implementation explained +At the heart of the implementation of this bounded context is a generic implementation that links a reporting data store and a query to a GraphQL data resource that has its own RBAC authorization. That is, a new customized resource can be added to this API by doing the following: + +1. Define the data store type +2. Define the query +3. Define the GraphQL resource names and fields +3. Define the user permission that is linked to this resource + +### GraphQL query examples + +**Query transfers that are filtered on a specific Payer DFSP** +```GraphQL +query GetTransfers { + transfers(filter: { + payer: "payerfsp" + }) { + transferId + createdAt + payee { + name + } + } +} +``` + +**Query a summary of the transfers** +```GraphQL +query TransferSumary2021Q1 { + transferSummary( + filter: { + currency: "USD" + startDate: "2021-01-01" + endDate: "2021-03-31" + }) { + count + payer + } +} +``` + + +## Building the event data store +The purpose the event data store is to provide a persistent storage of events of interest that are easily and efficiently found and queried for reporting. + +To achieve this with minimal structure changes from the original message, it was decided to process the message into categories and store these categories as additional metadata inside the message, which can be queried later on. Messages that do not fit within these categories are not stored and are therefore filtered out. + +Here is an example of the metadata that is added to the JSON message: + +```json{7-12} +{ + "event": { + "id" : {}, + "content" : {}, + "type" : {}, + "metadata" : {} + }, + "metadata" : { + "reporting" : { + "transactionId" : "...", + "quoteId": "...", + "eventType" : "Quote" + } + } +} +``` +Where `"eventType"` can be one of the following: +:::::: col-wrapper +::: col-third +::: + +::: col-third +| eventType | +| ------- | +|Quote | +|Transfer | +|Settlement | +::: +::::::::: + +The event stream processor will subscribe to the Kafa topic `'topic-event'`. This message queue contains all the event messages. A sigificant degree of filtering is therefore necessary. + +:::tip NOTE +The code delivering this functionality has been structured so that these filters can easily be modified or extended. +The subscribed and classified messages are represented in 'const' files so they can easily be added to or amended without detailed knowledge of the code. +::: + +### Storing only 'audit' messages + +Only Kafka messages that are of type `'audit'` will be considered for saving, that is, only if: +:::::: col-wrapper +::: col-third +::: +::: col-third +| metadata.event.type | +| ---- | +| audit | +::: +::::::::: + +## 'Transfer' messages that are stored +**ml-api-adapter** + +:::::: col-wrapper +| metadata.trace.service | +| ---- | +| ml_transfer_prepare | +| ml_transfer_fulfil | +| ml_transfer_abort | +| ml_transfer_getById | +| ml_notification_event | +::::::::: + +## 'Quote' messages that are stored +**quoting-service** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| qs_quote_handleQuoteRequest | +| qs_quote_forwardQuoteRequest | +| qs_quote_forwardQuoteRequestResend | +| qs_quote_handleQuoteUpdate | +| qs_quote_forwardQuoteUpdate | +| qs_quote_forwardQuoteUpdateResend | +| qs_quote_handleQuoteError | +| qs_quote_forwardQuoteGet | +| qs_quote_sendErrorCallback | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| qs_bulkquote_forwardBulkQuoteRequest | +| qs_quote_forwardBulkQuoteUpdate | +| qs_quote_forwardBulkQuoteGet | +| qs_quote_forwardBulkQuoteError | +| qs_bulkQuote_sendErrorCallback | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| QuotesErrorByIDPut | +| QuotesByIdGet | +| QuotesByIdPut | +| QuotesPost | +| BulkQuotesErrorByIdPut | +| BulkQuotesByIdGet | +| BulkQuotesByIdPut | +| BulkQuotesPost | +::: +::::::::: + +## 'Settlement' messages that are stored +**central-settlement** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| cs_process_transfer_settlement_window | +| cs_close_settlement_window | +| ... | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| getSettlementWindowsByParams | +| getSettlementWindowById | +| updateSettlementById | +| getSettlementById | +| createSettlement | +| closeSettlementWindow | +| ... | +::: +::::::::: + +## Messages that currently remain unclassified and are filtered out +**account-lookup-service (not in PI - included as a reference)** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ---- | +| ParticipantsErrorByIDPut | +| ParticipantsByIDPut | +| ParticipantsErrorByTypeAndIDPut | +| ParticipantsErrorBySubIdTypeAndIDPut | +| ParticipantsSubIdByTypeAndIDGet | +| ParticipantsSubIdByTypeAndIDPut | +| ParticipantsSubIdByTypeAndIDPost | +| ParticipantsSubIdByTypeAndIDDelete | +| ParticipantsByTypeAndIDGet | +| ParticipantsByTypeAndIDPut | +| ParticipantsByIDAndTypePost | +| ParticipantsByTypeAndIDDelete | +| ParticipantsPost | +| PartiesByTypeAndIDGet | +| PartiesByTypeAndIDPut | +| PartiesErrorByTypeAndIDPut | +| PartiesBySubIdTypeAndIDGet | +| PartiesSubIdByTypeAndIDPut | +| PartiesErrorBySubIdTypeAndIDPut | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| OraclesGet | +| OraclesPost | +| OraclesByIdPut | +| OraclesByIdDelete | +::: + +::: col-third +| metadata.trace.service | +| ---- | +| postParticipants | +| getPartiesByTypeAndID | +| ... | +::: +::::::::: + +**transaction-requests-service (not in PI - included as a reference)** +:::::: col-wrapper +::: col-third +| metadata.trace.service | +| ----- | +| TransactionRequestsErrorByID | +| TransactionRequestsByID | +| TransactionRequestsByIDPut | +| TransactionRequests | +| AuthorizationsIDResponse | +| AuthorizationsIDPutResponse | +| AuthorizationsErrorByID | +::: + +::: col-third +| metadata.trace.service | +| ----- | +| forwardAuthorizationMessage | +| forwardAuthorizationError | +| ... | +::: +::::::::: + +### Useful tools + +#### Kafka explorer +The [‘kowl’](https://github.com/cloudhut/kowl) software from cloudhut is a useful tool to explore all the Kafka messages in a Mojaloop cluster. We can deploy it in the same namespace as the Mojaloop core services. + +The custom values file for the OSS deployment can be found in this [repository](https://github.com/mojaloop/deploy-config/tree/deploy/PI15.2/mojaloop/kowl-kafka-ui). +(This is private repository, you may need permission to access this link.) + +**Steps to install** +``` +helm repo add cloudhut https://raw.githubusercontent.com/cloudhut/charts/master/archives +helm repo update +helm install kowl cloudhut/kowl -f values-moja2-kowl-values.yaml +``` +**Web UI** +Open the URL configured in the `ingress` section in the `values` file. + +**Additional customization** +For information on how to add further customization, see the [reference configuration](https://github.com/cloudhut/kowl/blob/master/docs/config/kowl.yaml) provided by cloudhut. + +#### TTK golden path +The TTK golden path test cases have been designed to explore all the test outcomes possible when sending transfers. This is therefore an important tool that can be used to test that the functionality caters for all eventualities. That is, we can use the in-built TTK to execute different test-cases such as P2P happy path, negative scenarios, settlement-related use cases, and so on. + +## Event processing service + +The event processing service is responsible for subscribing to Kafka topics and filtering through the events by event type. The event type further breaks down into several parts depending on which service the events were produced from. The filtered events will then be processed depending on the context of the event structure, and reporting metadata will be created. + +Example: + +```json +{ + "event": { + "id" : {}, + "content" : {}, + "type" : {}, + "metadata" : {} + }, + "metadata" : { + "reporting" : { + "transactionId" : "...", + "quoteId": "...", + "eventType" : "Quote" + } + } +} +``` + +| eventType | Event origin | +| ------- | ------- | +|Quote | quoting-service | +|Transfer | ml-api-adapter | +|Settlement | central-settlement | + +The event processing service subscribes to the Kafka event stream to build an event transfer related store that is queryable through the operational API. This is in line with the reference architecture. diff --git a/docs/technical/business-operations-framework/SecurityBC.md b/docs/technical/business-operations-framework/SecurityBC.md new file mode 100644 index 000000000..d992996ad --- /dev/null +++ b/docs/technical/business-operations-framework/SecurityBC.md @@ -0,0 +1,887 @@ +# RBAC Operational API implementation +## Introduction to RBAC Operational API implementation +The objectives of this implementation is to provide an RBAC solution to support hub operations and associated functions. This guide outlines the high-level design and explains the thinking that went into the design. + +The security design: +1. implements role based access control to the current Mojaloop version +1. is compatible where possible with the reference architecture and therefore future versions of Mojaloop +1. is compatible with future Infrastructure-as-Code (IaC) deployments +1. provides activity logging that can be used in an audit + +## RBAC Implementation details +1. Users are assigned one or more roles. A user may 'take on' multiple roles, subject to defined rules. +1. Roles are assigned Permissions +1. The Identity and Access Proxy (Ory Oathkeeper) enforces access to endpoints based on permission. +1. Backend API can optionally check permissions through Keto API. +1. Mutually exclusive permission sets can be defined in the system to enforce separation of duties. + +## Enforcing Maker-Checker +There are two approaches that can be taken to enforce a maker-checker validation flow. +1. Enforce using roles and mutually exclusive permissions via security policies. I.e. Makers cannot also be checkers +1. Enforce in application layer security rules; i.e. makers cannot also be checkers within the same validation process. This is often implemented in the application layer when assigning makers and/or checkers as defined in a process flow, and by enforcing that a checker cannot be the same person as the maker in a validation flow. I.e. the code that enforces this will exist within each bounded context. + + +::: tip RBAC responsibility +To support this functionality the RBAC system must provide: +1. the User Identifier to that bounded context. +1. A means for checking authorisation if necessary. +::: + +### Providing the User Identifier +The current configuration provides the User Identifier in the header of the API calls. +Ory Oathkeeper is configured to use a 'header' mutator. This 'header' mutator will transform the request, allowing you to pass the credentials to the upstream application via the headers. For example the API backends will get the following header in the http requests. +``` +X-User: wso2-uuid +``` + +It is worth pointing out that JWT 'id_token' are also easily supported my modifying the Ory Oathkeeper mutator configuration. The 'id_token' mutator takes the authentication information (e.g. subject) and transforms it to a signed JSON Web Token, and more specifically to an OpenID Connect ID Token. The API backends can verify the token by fetching the (public) key from the /.well-known/jwks.json endpoint provided by the Ory Oathkeeper API. + +### Checking authorisation +All authorisation information is maintained within Ory Keto. Ory Keto has a standard API that can be called to check authorisation. +I.e. It answers the question: *'Does this user identifier token have this permission?'* + +## Tools / standards chosen +Here is a list of standard tools that have been chosen to implement the design. +1. **Ory Oathkeeper** +Will be used as the Identity and Access Proxy (IAP) that will check authentication and authorization before providing access to functional endpoints, that is, it will be used to enforce the access control. +2. **Ory Keto** +Will check authorization via subject-role and role-permission mappings. It uses a flexible object-, relationship-, and subject structure pioneered at Google that can model many authorization schemes, including Role Based Access Control (RBAC). +3. **Ory Kratos** +Will use Ory Kratos to create and manage the cookie authorization object. +4. **OpenID Connect** +Is the standard that has been chosen to interact with an identity management system. This is a widely supported standard, and is compatible with all the tools currently in use in the Mojaloop community, that is, WSO2 Identity Server (IS), Keycloak, and Ory Kratos. + +## Architecture overview +Here is a high-level architecture overview of the implementation of this RBAC Operational API onto the current Mojaloop version. + +![Architecture overview diagram of security bounded context implementation](../../.vuepress/public/BizOps-Framework-IaC-3.xx-&-Mojaloop-13.xx.png) + +Here is a table of the services and the roles they are playing. +| Service | Owns | Implements | +| --- | --- | --- | +|**WSO2 IS KM**|Users| 1. User login redirection and UI that creates the cookie token
    2. Standard OpenID Connect (OIDC) authorization code flow | +|**Ory Keto**|1. The roles mapped to users
    2. The participant mapped to users| 1. API RBAC authorization check through Ory Oathkeeper
    2. API RBAC authorization check through operational API call| +|**Ory Oathkeeper**|The permissions related to API access | API gateway for operational APIs with authentication and authorization checks| +|**Ory Kratos**|Nothing|Authentication cookie| +|**BC Operational API**|The permissions related to the operational API calls|Operational API functions| +|**Shim**| nothing | Redirect to configure OIDC| +|**Operator Role**| Nothing | Update Keto to reflect role-permission assignment changes made in the role-resource file| +|**Kubernetes role-resource file**| The roles and the role-permission assignments| Edits of this file are controlled through a version control implementaiton (for example, GitHub or GitLab).| +|**Roles API**|Nothing|1. Role-user API controls
    (list of users, list of roles, list of roles assigned to users, add role to user, remove role from user)
    2. Participant-user API controls
    (list of users, list of participants, list of participants assigned to user, add participant to user, remove participant from user)| + +## How does this design align with the reference architecture? +Let's compare this RBAC Operational API implementation to the security bounded context as defined in the reference architecture. This design differs from the reference architecture in function, purpose and approach, but where appropriate has adopted some of the design ideas. This RBAC implementation's purpose is to adds a layer for security onto the operational API's of the bounded contexts. The Reference Architecture's Security Bounded Context design has been designed to accommodate for the performance requirements of the critical transactional functions of Mojaloop. +Here are the high level areas where these designs diverge: +1. The authorisation functions are centralised in this RBAC implementation. The reference architecture design requires a distributed authorisation that is implemented in each bounded context independently. This extra level of complexity is unnecessary for the operational API use case. +1. The reference architecture design requires interfaces to other bounded contexts to initiate the distributed authorisation functionality. These have not been built for the reason that there are no components that exist that could consume these interfaces. +1. The reference architecture requires the security BC to generate it's own security tokens. This RBAC implementation uses the tokens that are generated by the IAM. +1. The reference architecture requires the permissions to be distributed through the JWT to each bounded context. This is possible to configure in the current toolset, but was not. The reason being that some security experts consider this distribution of user permission sets a security vulnerability, and it was not a requirement for this current RBAC implementation. + +There are parts of the security bounded context that have been adopted in this RBAC Operational API implementation. +1. Each Bounded context owns it's own set of permissions or privileges +1. The RBAC implementation owns all the associations of privileges to users. +1. The user Role Permissions are structured so that they are easily distributed within a Kubernetes cluster. + +## Alignment with IaC 4.xxx +Here is a diagram illustrating how the high-level architecture would look if this RBAC Operational API implementation design was implemented on the next IaC version (IaC 4.xxx version) that uses Keycloak and Ambassador / Envoy amongst other changes. + +![Architecture overview diagram of security bounded context implementation](../../.vuepress/public/BizOps-Framework-IaC-4.xx-&-Mojaloop-13.xx.png) + +## Performance characterisation of the RBAC implementation +A performance characterisation of the RBAC POC implementation was performed in order to evaluate the extent of the performance overhead that the RBAC security layer has. +::: tip In summary: +The RBAC adds 10ms overhead for each API authorisation check per call. +If a particular API call requires and additional API based authorisation call, then the overhead is 20ms. + +This typically in our test queries amounted to: +1. less than 5% for single authorisation checks (Ory Oathkeeper & Ory Keto), +1. and less than 10% for double authorisation checks (Ory Oathkeeper & Ory Keto and an additional Ory Keto call). +::: + +**Characterisation test setup details** +On the same test infrastructure, identical timed calls were made to the same backend API directly and and through the RBAC implementation. +Below are the results of the test calls made to the role API with and without RBAC, and POST Transfers API with and without RBAC. The Role API has a single authorisation check that is performed through Ory Oathkeeper that calls Ory Keto. The Transfer API is a graph QL API that has an additional RBAC + +**Request Statistics** + +|Method| Name| # Requests| # Fails| Average (ms)| Min (ms)| Max (ms)| Average size| (bytes) RPS| Failures/s| +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +|GET| Role API| 321| 0| 248| 221| 499| 604| 9.0| 0.0| +|GET| Role API RBAC| 320| 0| 262| 232| 418| 604| 8.9| 0.0| +|POST| Transfers API| 318| 0| 229| 184| 373| 4873| 8.9| 0.0| +|POST| Transfers API RBAC| 314| 0| 240| 194| 406| 4873| 8.8| 0.0| +| | **Aggregated**| **1273**| **0**| **245**| **184**| **499**| **2723**| **35.5**| **0.0**| + + +**Response Time Statistics** + +|Method| Name| 50%ile (ms)| 60%ile (ms)| 70%ile (ms)| 80%ile (ms)| 90%ile (ms)| 95%ile (ms)| 99%ile (ms)| 100%ile (ms)| +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +|GET| Role API| 240| 240| 240| 250| 270| 290| 400| 500| +|GET| Role API RBAC| 250| 260| 260| 270| 290| 320| 410| 420| +|POST| Transfers API| 220| 220| 240| 250| 290| 330| 360| 370| +|POST| Transfers API RBAC| 230| 240| 250| 280| 310| 330| 400| 410| +| |**Aggregated**| **240**| **250**| **250**| **260**| **290**| **320**| **400**| **500**| + +## Logging into the UI +This sequence diagram illustrates the events that occur when a browser attempt to access a backend API. +- If the browser is already logged in, then the request is forwarded. +- If the browser is not logged in, then a standard OIDC authorization flow is triggered starting with a redirect. + +![Sequence diagram illustrating how a brower logs in](../../.vuepress/public/frontend.png) + +## Querying data using the BC operational API micro-frontend +The following sequence diagram shows more details regarding interactions when: +- the bearer token is valid or invalid +- authorization passes or fails + +The micro-frontend is represented as a client. + +![Sequence diagram illustrating how an API client call has its authorization performed](../../.vuepress/public/client.png) + +In some cases there might be a requirement for a more detailed authorization check to be performed by the operational API. The next sequence diagram describes how that is implemented. + +It is important to note that not all operational APIs will require this level of authorization, and that the Ory Oathkeeper control may or may not be required in this use case. + +![Sequence diagram illustrating how an API client call has its authorization performed](../../.vuepress/public/clientgraphql.png) + +## Enforcing Seperation of Duties +This RBAC implementation supports the enforcement of separation of duties by the enforcement of mutually exclusive permissions sets. The implementation of separation of duty creates tighter security but can lead to complexity for the security administrator and the end users who use the system. Enforcing mutually exclusive permissions can reduce and help manage this complexity. + +An example of mutually exclusive permissions might be a user being able to access the Finance Portal and to carry out sensitive functions such as add/withdraw funds. This user should not also have access to audit functions. + +### Modelling the exclusion +This implementation models this requirements as a set of mutually exclusive permission - permission exclusions that are enforced globally. These exclusions are defined as two sets of permissions that are mutually exclusive which is intuitive and easy to maintain. + +*Justification* +There are three possible ways that this exclusion could have been modelled namely: +1. Permission - Permission exclusions +1. User Role - User Role exclusions +1. User Role - Permission exclusions + +Because this functionality has been added to support the segregation/separation of duties, the cleanest way of enforcing this is to have a permission pair exclusion that is globally enforced. With all the other options, there is the possibility that the exclusion can be bypassed with the addition of a new inclusive role. + +### Synthetic Roles Vs Multiple User Roles +This RBAC implementation does not implement synthetic roles, but rather uses multiple functional user roles assignments. + +*Justification* +These are two methods that can be used to model RBAC permissions with mutually exclusive permissions. +1. Dynamically building up a synthetic role for each user based on rules associated with the current assigned roles and their permissions and exclusions. +1. Defining roles that are associated with user functions. Each user therefore will need to be assigned more than one role. Roles permissions are less likely to change. + +The preference is to implement multiple functional roles. This is because it is much simpler to understand, maintain and support this method. Identifying the cause of a loss of permission in a synthetic role because of multiple role assignments and subsequent rule applications requires a detailed understanding of the process of how the synthetic roles are calculated and implemented. This complexity is avoided with the second option. + +### Multiple user role assignments required dynamic checking of exclusions +Allowing the system administrator to assign more than one role to a user is convenient, flexible and limits the number of roles required within the organisation. This also means that it is possible to violate a mutually exclusive permission by assigning users to roles. Checking and enforcing these exclusions therefore need to be dynamic. + +There are a number of places that this dynamic check needs to take place. +1. On the assignment of a role to a user +1. On the application of a new role-permission resource definition, or the application of a new security policy that may include a wholesale change of permission and role structures. +::: warning Future extension: +If it is possible that a violation can exist in the system, then each time a permission is checked, exclusion violations should also be checked. Currently this is not designed for as it is assumed that 1 & 2 are sufficiently implemented that a violation cannot exist. +It is recommended that this additional check be roadmapped for future extensions as this would ensure that no back-door override can be made to violate this separation of duties. +::: + +::: tip Note: +The change control release and testing on lower environments may not catch these violations. Testing for these violations cannot be done on lower environments without first making sure that the user access control is identical in the lower environments which is normally not the case. +::: + +**Keto relation** +Introduction of a relation that relates two permissions that cannot be held together. +``` +“permission:X excludes permission:Y#allowed” +``` + +**Permission Exclusion Custom Resource Definition** +A permission exclusion custom resources are consumed by the Role Permission Controller, which will upload the exclusions into Keto using this relation. Each will contain two sets of permissions, and holding any permission in one set will mean no permission in the other set can be held. This allows for many flexible scenarios, and the simplest scenario of “any person who can do this one thing cannot do this other thing, and vice versa” remains simple to express. + +**Role Permission Operator API Validation Check** +The Role Permission Resource Controller will provide an API that can be used to check a security permission update’s allowability before it is applied. That API will take a proposed change to a particular Role Permission resource and calculate whether or not any existing users would have mutually exclusive permissions after that change, returning the result. This API will be usable by the administrative UI and CI systems to “preflight” changes for likely problems. + +**Role Permission Operator Change Enforcement** +When a role-permission resource is changed, the role-permission operator will first lock the ability to change user role assignments, then perform the same check as the validation API does, and if the resource does not pass the check it will not accept the changes from that resource, instead maintaining the current role permission assignments, and surfacing the issue as an error in the kubernetes API for instrumentation and alerting. + +**Conflict Check on User Role Assignment** +When a user is assigned a role, the user role assignment API will validate that the change does not result in the user having two mutually excluded permissions. If it does, the change will be rejected and an error returned. + +## Assigning roles and participant access to users +This functionality is implemented in the Roles API service. The following sequence diagram describes how the user role and user participation access is queried and modified through the Roles API. +![Sequence diagram illustrating how roles and participant access is assigned to users](../../.vuepress/public/userroles.png) + +### Roles API +The following table provides a summary of Roles API resources. + +|Category|HTTP method|Endpoint| Description|Error codes| +| --- | --- | --- | --- | --- | +|**HEALTH**| | | | | +| | GET | /health | Used to return the current status of the API | 400, 401, 403, 404, 405, 406, 501, 503 | +| | GET | /metrics | Used to return metrics for the API | 400, 401, 403, 404, 405, 406, 501, 503| +|**PARTICIPANTS**| | | | | +| | GET | /participants | Used to return a list of participant IDs | 400, 401, 403, 404, 405, 406, 501, 503| +|**ROLES**| | | | | +| | GET | /roles | Used to return a list of role IDs |400, 401, 403, 404, 405, 406, 501, 503 | +|**USERS**| | | | | +| | GET | /users | Used to return a list of user IDs | 400, 401, 403, 404, 405, 406, 501, 503| +| | GET | /users/{ID} | Used to return a specifc user |400, 401, 403, 404, 405, 406, 501, 503 | +| | GET | /users/{ID}/participants | Used to return a list of participants assigned to a user |400, 401, 403, 404, 405, 406, 501, 503| +| | PATCH | /users/{ID}/participants | Used to assign a participant to a user | 400, 401, 403, 404, 405, 406, 501, 503| +| | GET | /users/{ID}/roles | Used to return a list of roles assigned to a user|400, 401, 403, 404, 405, 406, 501, 503 | +| | PATCH | /users/{ID}/roles | Used to assign a role to a user|400, 401, 403, 404, 405, 406, 501, 503 | + + +The detailed specification of the Roles API can be found [here](https://docs.mojaloop.io/role-assignment-service/ +). +The GitHub repository of the role assignment service can be found [here](https://github.com/mojaloop/role-assignment-service). + +## Assigning permissions to roles & mutually exclusive permission sets +The permission to role assignment is stored in a `.yml` file that we are calling a role-resource file (`roleresource.yml`). +Access and changes to these role-resource files will be managed through a hosted version control solution like GitHub or GitLab. This is convenient as this keeps a full history of changes and has configurable automatic and manual control points. +These role-resource files are mapped as Kubernetes custom resource definitions (CRDs) to which a role-permission operator subscribes. Changes to the role-resource files trigger the role-permission operator to update Ory Keto with the corresponding appropriate change. A role can be represented by more than one file if necessary. + +There are two types of role resource files, the first contains the role permission assignments and the second the mutually exclusive permission sets. + +Here is an example of a permission assignment role-resource file: +```yml +apiVersion: "mojaloop.io/v1" +kind: MojaloopRole +metadata: + name: arbitrary-name-here +spec: + # must match what is used in Keto, whatever that is + role: RoleIdentifier + permissions: + - permission_01 + - permission_02 + - permission_03 + - permission_04' +``` +The following sequence diagram illustrates how Ory Keto is updated. + +![Sequence diagram illustrating how roles and participant access is assigned to users](../../.vuepress/public/rolepermissions.png) + +## Ory Keto – implementation detail +Ory Keto in this design is the tool that implements the logic of whether a login token has the correct authorization to access an aspect of the system, that is, it is used to enforce RBAC. There are three parts to how this is implemented in Keto: +1. The assignment of roles to users. +This functionality will be maintained and updated from the Roles API module, which will call and update Keto accordingly. +2. The assignment of participant access to a user. +This refers to the DFSP access reports that must only be provided for the configured participants. +This functionality will also be maintained via the Roles API module, which will call and update Keto accordingly. +3. The assignment of permissions or privileges to roles. +This will be controlled through the edits of a GitHub `roleresource.yml` file. The Kubernetes role-permission operator is the service that will monitor these role-resource files, and update Keto to affect the assignments. + +### Adding roles and participant access to users in Keto +The user list (which includes both people and service accounts) will be retrieved from WSO2 Identity Server, and the participant list from the existing API for that purpose. In both cases, a durable permanent identifier should be what is then used as part of the Keto calls. + +The list of roles will be hardcoded, and every role should be given a unique short identifier that is human readable and writeable, as well as a name. The UI should display both the identifier and the name, since the identifier will be needed for use in the role-permission operator. + +There will be two Keto namespaces used for calls: role and participant. The Keto tuples used will be: +``` +role:ROLEID#member@USERID and participant:PARTICIPANTID#member@USERID +``` +(using the notation used for [Keto/Zanzibar](https://www.ory.sh/keto/docs/concepts/relation-tuples) + +The reuse of the relation `"member"` is not an issue, each relation is namespace-specific. If there is a preferred term for the participant-user relationship other than `"member"`, that word can be used instead, and should be documented here. + +To retrieve the role or participant list for a particular user, the [Query Relation Tuples API](https://www.ory.sh/keto/docs/reference/rest-api#query-relation-tuples) will be used, and the namespace, relation, and subject provided as parameters. This will provide a list of tuples in the response, with a next page token if there are additional results, and the identifiers for the participants or roles can be read from the resulting tuples. + +When a role or participant is added or removed for a user, the [create](https://www.ory.sh/keto/docs/reference/rest-api#create-a-relation-tuple) and [delete](https://www.ory.sh/keto/docs/reference/rest-api#delete-a-relation-tuple) relation tuple calls can be used, since only a single tuple is involved at a time. If the call fails, but the failure is not an HTTP 4xx, it should be retried a couple of times. + +Here is an example of the Keto API call used to add roles to users. +::: tip Example: Assign role to user in Ory Keto +PATCH /relation-tuples HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: + +```json +[ + { + "action": "insert", + "relation_tuple": { + "namespace": "role", + "object": "RoleIdentifier", + "relation": "member", + "subject": "userIdentifier" + } + } +] +``` +On success, an HTTP 204 message is returned with no content. + +::: tip NOTE +We use `"member"` as the `"relation"` in our current implementation. +We use `PATCH` instead of `PUT` since `PATCH` works as a bulk create and/or delete. +::: + +### Adding permissions or privileges to roles in Keto +Adding permissions or privileges to roles in KetoThis will be done via a Kubernetes operator for a Custom Resource Definition [(CRD)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/_print/). The operator could be implemented in most any language. Existing ModusBox operator expertise is mostly based around `kopf`, a Python framework, but there are options in Go and Node as well (and others). + +The operator should maintain a memory of all resources it manages, grouped by role. [Kopf's indexing](https://kopf.readthedocs.io/en/latest/indexing/) functionality is ideal for this. + +When a role resource is changed, the list of permissions for that role across all role resources should be compiled, and a change sent through the Keto Patch [Multiple Relation Tuples API](https://www.ory.sh/keto/docs/reference/rest-api#patch-multiple-relation-tuples) using the patch actions `insert` and `delete`. It is necessary to take all role resources into account, because there may be multiple resources for one role, and more than one may include the same permission, so deleting a role resource that maps Role X to Permission P does not necessarily mean that the Keto tuple for that role-permission connection needs to be deleted, since there may still be another role resource mapping Role X to Permission P. + +The Keto tuples will be of the form: +``` +permission:PERMISSIONID#granted@role:ROLEID#member +``` + +The specific operations on resource change are as follows: + +1. Retrieve current permissions granted for role using the [Query Relation Tuples API](https://www.ory.sh/keto/docs/reference/rest-api/#query-relation-tuples). +2. Based on stored index of roles to permissions, compute a diff from the retrieved list. +3. Execute patch from diff. +4. If there are problems, throw an exception so the problem will log and a re-sync will be attempted later. + + +Here is an example of the Keto API call used to add permissions to roles. +::: tip Example: Assign permission/privilege to a role in Ory Keto +PATCH /relation-tuples HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: + +```json +[ + { + "action": "insert", + "relation_tuple": { + "namespace": "permission", + "object": "permissionIdentifier", + "relation": "granted", + "subject": "role:x#member" + } + } +] +``` +On success, an HTTP 204 message is returned with no content. + +::: tip NOTE +We use `"granted"` as the `"relation"` in our current implementation. +We use `PATCH` instead of `PUT` since `PATCH` works as a bulk create and/or delete. +::: + +### Adding mutually exclusive permisions to Keto +The mutually exclusive permission sets are also maintained and modelled in Keto using the 'excludes' relation. +Relation that relates two permissions that cannot be held together are represented with exclusion tuples: +``` +“permission:X excludes permission:Y#allowed” +``` + +::: tip NOTE +We use `"excludes"` as the `"relation"` to define mutually exclusive permissions. +::: + +### Calling the standard Keto API to check authorization +Checking to see if a user has authorization for a privilege or permission is managed by th API gateway, and if necessary can be checked by each bounded context. + +Here is an example of the Keto API call used to check for a user's authorization based on a permission/privilege. +::: tip Example: Checking for authorization in Ory Keto +POST /check HTTP/1.1 +Content-Type: application/json +Accept: application/json +::: +```json +{ + "namespace": "permission", + "object": "PermissionIdentifier", + "relation": "granted", + "subject": "UserIdentifier" +} +``` +Here is the response that comes back: +```json +{ +"allowed": true/false +} +``` +::: tip Note: +Mutally excluded permissions don't need to be check excplicitly through a Keto call because the system is maintained in such a way that role-permission assignments can only be defined if mutually exclusive permission sets are not violated. +::: + +## Ory Oathkeeper – implementation detail +### Configuring Ory Oathkeeper for BizOps + +[ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/next/) authorizes incoming HTTP requests. It can be the Policy Enforcement Point in your cloud architecture, that is, a reverse proxy in front of your upstream API or web server that rejects unauthorized requests and forwards authorized ones to your server. If you want to use another API Gateway (Kong, Nginx, Envoy, AWS API Gateway, and so on), Ory Oathkeeper can also plug into that and act as its Policy Decision Point. + + +The Ory Oathkeeper Helm chart is described at [ORY Oathkeeper Helm Chart | k8s](https://k8s.ory.sh/helm/oathkeeper.html) and defined in [k8s/helm/charts/oathkeeper at master · ory/k8s · GitHub](https://github.com/ory/k8s/tree/master/helm/charts/oathkeeper). The Ory Helm repository is documented at [ORY Helm Charts | k8s](https://k8s.ory.sh/helm/). The Ory Oathkeeper configuration reference is at [Configuration | ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/reference/configuration) but note that the Helm chart values have different ways of doing certain things. Also, every configuration value can be overridden with environment variables. + + +The Ory Oathkeeper Helm chart deploys two key components into Kubernetes: Ory Oathkeeper itself, and the Ory Oathkeeper Maester. Ory Oathkeeper is stateless and config-driven, and seamlessly reloads itself with zero downtime, anytime that config changes. Ory Oathkeeper Maester is a controller for the Rule CRD, and composes the Rule objects in Kubernetes into a single complete rules file that is loaded by Ory Oathkeeper. By default, that is a ConfigMap that Ory Oathkeeper mounts, but it can also be set to run as a sidecar and use a shared mount. + + +Ory Oathkeeper exposes two ports as two services. One service is the API service, and the other is the Proxy service. Long-term, we will be using the API service, which will be queried by the next generation API Gateway using the Access Control Decision API (see [REST API | ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/reference/api/#access-control-decision-api) ) that Ory Oathkeeper provides, but for now we will be using the Proxy service, and exposing that via Ingress. External URLs to services protected by Ory Oathkeeper will be pointed at the Ory Oathkeeper Proxy ingress, which will then proxy access to the internal services at those URLs and apply access control rules. + + +Ory Oathkeeper will be configured to generate and sign a JSON Web Token (JWT) containing claims that internal services can check and verify by pointing at the JSON Web Key Set (JWKS) that Ory Oathkeeper will publish (which is part of the configuration) at the well-known URL for JWKS on the API service (see [REST API | ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/reference/api/#lists-cryptographic-keys) ). If a service does this, then it is operating under a basic zero trust regime, as it will not be possible to call that service except with a token that has been generated by Ory Oathkeeper, and Ory Oathkeeper will only generate a token if the access rules for the given URL allow access. + + + +### Debugging +The responses and logs from Ory Oathkeeper tend to be pretty informative, so start there. Make sure you are looking at the logs for the request that matters. Ory Oathkeeper will also be logging health checks and similar. + + +Some possible debugging actions that have been found useful in different circumstances: + + +* Make a match much more permissive (replacing the entire piece beginning with `<.*>` and then having the minimum currently unique suffix is good). + +* Double-check that each internal URL is the proper internal URL by checking it is accessible inside the cluster with curl. + +* Look at the identity provider (IdP) logs. + +* Make sure that the domains and ports for introspection and the external token endpoint are identical. Keycloak at least does not like it if they are not. + +* Point the Ory Oathkeeper rule at https://httpbin.org/, usually the `/anything` path prefix which will reflect back everything it gets, making it easy to see what the service will see. + + +### Components required in addition to a Helm chart + +The following pieces will be needed in addition to the Helm chart: + +* a JWKS secret +* annotated Helm values + + +#### JWKS secret + + +A secret should be created with key `mutator.id_token.jwks.json` and the value of a JWKS suitable for use with Ory Oathkeeper. An initial one can be generated as described in [Configure and Deploy | ORY Oathkeeper](https://www.ory.sh/oathkeeper/docs/configure-deploy#cryptographic-keys). It will contain both public and private keys. + + +##### Operating with the JWKS secret + + +To rotate the secret, apply the following procedure: + +0. Note the time. +1. Add a public and private key pair to the beginning of the array in the JWKS (make sure all public JWKs have a specified unique `kid`) in the secret. All keys other than the new keys and the previous first public and private keys can be removed. This is because Ory Oathkeeper always signs with the first key. +2. Wait until all requests that Ory Oathkeeper might have received and authorized would have had their JWT handled by the backend service. The main delay here is the time for the secret update to propagate, comprising the delay of the secret manager to the updated secret and the delay of the secret to the updated volume, which is probably at most a minute or two, so wait that long after the time in step 0. +3. If the old secret is being removed (this is only necessary if a breach is suspected, otherwise step 1 is sufficient for periodic key rotation), remove it now. + +#### Annotated Helm values + + +Several places will need to be changed to the rest-of-deployment-specific URLs or other values. Those places are described in the comments in the example below, as well as other commentary. + +How to setup the Proxy ingress is undecided at the time, as it will need to change when the solution is added to the IaC 3.xxx so that area of the config is still unspecified. This leaves the ingress out by default. Changing `ingress.proxy.enabled` to `true` will enable the proxy ingress. See the linked pages at the beginning for options available for the built-in ingress configuration. + +If TLS needs to be terminated at Ory Oathkeeper, see the `tls` sections in the [config documentation](https://www.ory.sh/oathkeeper/docs/reference/configuration), and combine that with secrets and the `deployment.extraVolumes` and `deployment.extraVolumeMounts` values. +Prometheus is at `:9000/metrics` by default, if that is in use. + + +```yaml + +oathkeeper: + config: + log: + # the maximum log level, we'll stick here or maybe debug if this is overwhelming until the config is verified + # then, we'll determine what log level to set based on needs + level: trace + access_rules: + matching_strategy: regexp + authenticators: + cookie_session: + enabled: true + config: + # this should be the internal URL of the public Kratos service's whoami endpoint, which might look like the below + check_session_url: http://kratos-public/sessions/whoami + preserve_path: true + # this means we automatically sweep up all the metadata kratos provides for use + # in, for example, the JWT, if we ever have more + extra_from: "@this" + # kratos will be configured to put the subject from the IdP here + subject_from: "identity.id" + only: + - ory_kratos_session + oauth2_introspection: + enabled: true + config: + introspection_url: https://whatever/the/wso2/url/is/oauth2/introspect + introspection_request_headers: + # see https://is.docs.wso2.com/en/latest/learn/invoke-the-oauth-introspection-endpoint/ for what credentials + # will need to be configured here + # also, this does not seem to be settable via environment variable, which means it is + authorization: "Basic SOME WORKING AUTH HERE" + cache: + # disabled to make debugging easier. enable for caching. + enabled: false + ttl: "60s" + authorizers: + remote_json: + enabled: true + config: + # the check URL for Keto. This will be POST'd to. See https://www.ory.sh/keto/docs/reference/rest-api#operation/postCheck + remote: http://internal-keto-url-here/check + mutators: + id_token: + enabled: true + config: + # this should be the internal base URL for the API service, which will look something like the below + issuer_url: http://whatever-oathkeeper-internal-is-api:4456/ + errors: + fallback: + - json + handlers: + json: + # this gives API clients pretty error JSON + enabled: true + config: + verbose: true + redirect: + enabled: true + config: + # set this to whatever the main URL is, it'll ensure that browser errors redirect there + to: https://whatever-external-main-url-is/ + when: + - error: + - unauthorized + - forbidden + request: + header: + accept: + - text/html +secret: + # without this we would need to put the JWKS in the config, which would mean we couldn't rotate it just by changing the secret + manage: false + # change to whatever is used for secret name + name: oathkeeper-jwks +deployment: + extraEnv: + # for whatever reason this environment variable only gets set if the JWKS is in the config even though the rest of the secret mounting + # and such still happens + - name: MUTATORS_ID_TOKEN_CONFIG_JWKS_URL + value: file:///etc/secrets/mutator.id_token.jwks.json + + +``` + +### Rules + +Rule resources will need to be created in Kubernetes for each backend "match" (URL regex plus HTTP method(s)) protected with a permission. The example provided below provides guidance. + + +As the flexibility to define third-party services and bounded contexts increases, they can define their own rules (perhaps behind a Helm values flag), which express which permissions should be required for which URLs. + + +The biggest potential issue here is that each match MUST be unique. If a request matches multiple, Ory Oathkeeper will complain. Once a general pattern is picked that results in unique regexes, this will not happen except with user error. + +```yaml + +apiVersion: oathkeeper.ory.sh/v1alpha1 +kind: Rule +metadata: + name: a-unique-name +spec: + version: v0.36.0-beta.4 + upstream: + # set to whatever URL this request should be forwarded to + url: http://internal-url-of-backend-service/ + match: + # this might need to be http even if external is https, it depends on how ingress does things + # my recommendation is to have a given prefix, then the "everything else in the domain name" matcher + # so it doesn't need to be changed when the config is moved between various main domains + # then whatever is needed for the specific path (this is set to match all subpaths) + # regexes go in between angle brackets + url: https://example.<[^/]*>/<.*> + methods: + # whatever method(s) this rule applies to + - GET + authenticators: + - handler: oauth2_introspection + # comment out this second one to not allow browser-cookie access + - handler: cookie_session + authorizer: + handler: remote_json + config: + # these will generally be identical for all rules, + # except "object" will be changed to the permission ID that is relevant for + # this URL + payload: | + { + "namespace": "permission", + "object": "PERMISSION IDENTIFIER HERE", + "relation": "granted", + "subject_id": "{{ print .Subject }}" + } + mutators: + # change this to an empty array if the id_token isn't needed, if you want + - handler: id_token + +``` +### Configure Ory Oathkeeper to use Kratos as its cookie Authenticator +This part of the config above is applicable. Reference documentation for Ory Oathkeeper authenticators is found [here](https://www.ory.sh/oathkeeper/docs/next/pipeline/authn). + +```yaml + authenticators: + cookie_session: + enabled: true + config: + # this should be the internal URL of the public Kratos service's whoami endpoint, which might look like the below + check_session_url: http://kratos-public/sessions/whoami + preserve_path: true + # this means we automatically sweep up all the metadata kratos provides for use + # in, for example, the JWT, if we ever have more + extra_from: "@this" + # kratos will be configured to put the subject from the IdP here + subject_from: "identity.id" + only: + - ory_kratos_session + +``` + +### Configure Ory Oathkeeper to use WSO2 ISKM for token introspection +Reference documentation is found [here](https://www.ory.sh/oathkeeper/docs/next/pipeline/authn). + +```yaml + oauth2_introspection: + enabled: true + config: + introspection_url: https://whatever/the/wso2/url/is/oauth2/introspect + introspection_request_headers: + # see https://is.docs.wso2.com/en/latest/learn/invoke-the-oauth-introspection-endpoint/ for what credentials + # will need to be configured here + # also, this does not seem to be settable via environment variable, which means it is + authorization: "Basic SOME WORKING AUTH HERE" + cache: + # disabled to make debugging easier. enable for caching. + enabled: false + ttl: "60s" +``` + +### Configure Ory Oathkeeper to use Ory Keto as its authorizer +This part of the config above is applicable. +Reference documentation about Ory Oathkeeper authorizers is found [here](https://www.ory.sh/oathkeeper/docs/next/pipeline/authz). + +```yaml + authorizers: + remote_json: + enabled: true + config: + # the check URL for Keto. This will be POST'd to. See https://www.ory.sh/keto/docs/reference/rest-api#operation/postCheck + remote: http://internal-keto-url-here/check + +``` + +## Ory Kratos – implementation detail + +Ory Kratos is the part of the Ory Implementation suite that manages all the authentication flows. +It is highly configurable and can connect to a variety and multiple of authentication systems and flows. The [Kratos Documentation](https://www.ory.sh/kratos/docs/next/) explain the extent of the configuration well. I.e. it is likely to cater for your requirements. +In this workstream project, only the User Login and logout flow are required and implemented. +It is useful to know that Kratos can also provided flows for: +- **Self-service Login and Registration:** Allow end-users to create and sign into accounts (we call them identities) using Username / Email and password combinations, Social Sign In ("Sign in with Google, GitHub"), Passwordless flows, and others. +- **Multi-Factor Authentication (MFA/2FA):** Support protocols such as TOTP (RFC 6238 and IETF RFC 4226 - better known as Google Authenticator) +- **Account Verification:** Verify that an E-Mail address, phone number, or physical address actually belong to that identity. +- **Account Recovery:** Recover access using "Forgot Password" flows, Security Codes (in case of MFA device loss), etc. +- **Profile and Account Management:** Update passwords, personal details, email addresses, linked social profiles using secure flows. +- **Admin APIs:** Import, update, delete identities. +... that may become important in future version of the IaC deployment designs. + + +### Deployment details +The Kratos Helm Chart is described at [ORY Kratos Helm Chart | k8s](https://k8s.ory.sh/helm/kratos.html) and defined at [k8s/helm/charts/kratos at master · ory/k8s · GitHub](https://github.com/ory/k8s/tree/master/helm/charts/kratos). Unlike Ory Oathkeeper, it does not have any related Maester handling a CRD. It does, however, need a database (which can be MySQL, PostgreSQL, CockroachDB, or a few others). The Helm repository is the same as for Ory Oathkeeper, and documented at [ORY Helm Charts | k8s](https://k8s.ory.sh/helm/). A configuration reference is at [Configuration | Ory Kratos](https://www.ory.sh/kratos/docs/reference/configuration), but note that the Helm chart works slightly differently. + + +In addition to a database, the other major difference for Kratos is that it requires a user interface, in the form of a small web application that handles rendering the current stage of what’s happening with Kratos to the browser and also doing the necessary backend communication to make that happen securely. In our case, the UI we’ll use is very simple, and is never actually visible—all it will do is immediately forward to the one OIDC Identity Provider (IdP) we’ll have configured and receive the related callback. This UI application has already been created and open sourced in the `modusbox` repository, and releases public docker images in the GitHub docker registry. The UI can be found at [GitHub - modusbox/kratos-ui-oidcer: A Kratos UI for forwarding immediately to a single configured OIDC provider](https://github.com/modusbox/kratos-ui-oidcer), and is a very minimal Rust application with excellent test coverage and a tiny docker image (about 5 megabytes, https://github.com/modusbox/kratos-ui-oidcer/pkgs/container/oidcer ). It is referred to as 'Shim' in the above design documentation. + +For ease of hosting, Kratos and the UI should be mounted on separate paths on the same domain as the main user interface. Alternatively, it is possible to configure them on a different domain and configure Kratos to use cross-domain cookies. This document is written under the assumption the same-domain strategy is chosen. + +### Connecting to the Main UI +A client must be created in the IdP that supports OIDC authorization code grants. This client must be configured to redirect either to any URL under the main UI if it supports wildcards, or the specific URL for the path `/kratos/self-service/methods/oidc/callback/idp` (note that the last segment, `idp`, is the provider ID in the config, so both must change together). This client will be used in the helm chart values config. + +In order to connect successfully with Kratos, the Main UI must behave as follows: + +1. Make a cookies-included request to `/kratos/sessions/whoami` (documented at [HTTP API Documentation | Ory Kratos](https://www.ory.sh/kratos/docs/reference/api/#operation/toSession) ), which returns a 200 and an object containing user metadata if the user is logged in, or a 401 if they are not. +2. If the user is not logged in, either immediately redirect to or provide a link to `/kratos/self-service/registration/browser`. Note: `registration` in the URL is not a typo. This refers to registration with Kratos, which IdP users will not be initially. If the user already exists, Kratos will automatically follow the login flow instead. +3. To log out, link the user to `/kratos/self-service/browser/flows/logout` + +### Annotated Helm Values +This configuration assumes the helm deployment’s name is `kratos` and, that the Kratos service is exposed at `/kratos/` on the same domain as the main UI, and that the Kratos UI is exposed at `/auth/` on the same domain as the main UI. + +The Helm chart does support ingress creation, but is not covered in the documentation. + +```yaml +deployment: + extraVolumes: + - name: extra-config + configMap: + name: kratos-extra-config + extraVolumeMounts: + - name: extra-config + mountPath: /etc/config2 + readOnly: true +kratos: + # NOTE: helm chart deployment does not seem to automatically pick up + # on changes here + identitySchemas: + # TODO note the domain to be replaced in $id, the url doesn't need to resolve + "identity.schema.json": | + { + "$id": "http://REPLACE_THIS_WITH_SOME_MEANINGFUL_DOMAIN/schema/user", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A user", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "email": { + "title": "E-Mail", + "type": "string", + "format": "email" + }, + "subject": { + "title": "Subject", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + } + } + } + } + } + config: + identity: + default_schema_url: file:///etc/config/identity.schema.json + courier: + smtp: + connection_uri: smtp://unused/ + # TODO the appropriate database DSN needs to go here, or be wired up via a secret and the environment variable `DSN` + dsn: TODO DATABASE DSN HERE + hashers: + argon2: + parallelism: 1 + iterations: 3 + # add resources and increase this amount, + # if using passwords (vs oidc) in a production context + memory: 17000 + salt_length: 16 + key_length: 32 + log: + # TODO adjust after successful setup, likely down to info + level: trace + selfservice: + flows: + registration: + # TODO if the place the UI goes changes, this needs to change + ui_url: /auth/ + after: + oidc: + hooks: + - hook: session + logout: + after: + # TODO the IdP's logout URL should go here, with a redirect encoded into it if that's supported (might not work the same way, this is just an example) + default_browser_return_url: https://idp.logout.url.here/logout/path?redirect_uri=https%3A%2F%2Fsomewhere.example.com%2F + methods: + oidc: + enabled: true + config: + providers: + - id: idp + provider: generic + # TODO both the client_id and client_secret need to be set appropriately to the client supporting authorization code grants with openid + # TODO these can alternatively be set via environment variable from a k8s secret + client_id: TODO + client_secret: TODO + mapper_url: file:///etc/config2/oidc.jsonnet + # TODO this should be the right IdP URL to perform OIDC discovery on + # If the IdP does not support discovery, auth_url and token_url can be set here instead + # some IdPs may also need a requested_claims, see Kratos config documentation if there seems to be an issue + issuer_url: https://some.public.idp.url.supporting.discovery/might/have/path/ + scope: + # TODO adjust requested scope based on IdP (WSO2) documentation + - openid + password: + enabled: false + # TODO set this to the base URL of the main UI + default_browser_return_url: "https://somewhere.example.com/" + serve: + public: + # TODO set this to the base URL of the main UI plus the `/kratos` path, will need to be updated if the same-domain approach is not used + base_url: "https://somewhere.example.com/kratos" + autoMigrate: true +``` +### JSonnet ConfigMap +In the Kratos Helm values, it references a ConfigMap `kratos-extra-config` that contains JSonnet (a configuration language) referencing how to transform the IdP’s claims into what Kratos stores about the person. That ConfigMap should contain a key `oidc.jsonnet` with the following contents: + +```javascript +local claims = std.extVar('claims'); + +{ + identity: { + traits: { + email: claims.email, + name: claims.name, + subject: claims.sub + }, + }, +} +``` + +The email and subject claims will probably never need to change, but with some IdPs, the name might be provided differently, in which case that part of the JSonnet will need to be updated. The keys inside `traits` are basically arbitrary (though `subject` has some dependencies elsewhere that would need to be updated), so long as they’re also updated in the schema in the config, but the values are restricted to the list of likely claims inside an OIDC ID Token, and are described in the Kratos documentation. This will probably not come up. + +### UI Deployment & Service +The service will also need to be exposed at an appropriate path, the config assumes `/auth/`, on the same domain as the main UI. + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: kratos-ui + labels: + app: kratos-ui +spec: + ports: + - name: http + port: 80 + targetPort: http + selector: + app: kratos-ui + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kratos-ui + labels: + app: kratos-ui +spec: + replicas: 1 + selector: + matchLabels: + app: kratos-ui + template: + metadata: + labels: + app: kratos-ui + spec: + containers: + - name: kratos-ui + image: ghcr.io/modusbox/oidcer:latest + env: + - name: ROCKET_PORT + value: "80" + - name: ROCKET_REGISTRATION_ENDPOINT + # TODO if the kratos helm chart is given a different name than kratos, + # the domain will be different here, it should be the domain of the kratos service + value: http://kratos-public/self-service/registration/flows + ports: + - name: http + containerPort: 80 + readinessProbe: + httpGet: + path: /healthz + port: 80 +``` +### Ory reference links +- **Configuring Login Sessions.** [docs here](https://www.ory.sh/kratos/docs/guides/login-session) +- **Configuring Session cookies.** Details of the cookies sessions [docs here](https://www.ory.sh/kratos/docs/guides/configuring-cookies) +- **Configuring Kratos for CORS.** [docs here](https://www.ory.sh/kratos/docs/guides/setting-up-cors) +- **Ory Kratos - Ory Oathkeeper integration (OIDC).** [Kratos docs here](https://www.ory.sh/kratos/docs/guides/zero-trust-iap-proxy-identity-access-proxy) +- **Ory Kratos - WSO2 OIDC integration.** [docs here](https://www.ory.sh/kratos/docs/guides/sign-in-with-github-google-facebook-linkedin) + + diff --git a/docs/technical/business-operations-framework/SettlementBC.md b/docs/technical/business-operations-framework/SettlementBC.md new file mode 100644 index 000000000..d85b0ebc6 --- /dev/null +++ b/docs/technical/business-operations-framework/SettlementBC.md @@ -0,0 +1,201 @@ +# Settlement Operational Implementation + +## Introduction + +The objective of this design is to provide a solution that links the business process functions with core-settlement operations on the switch. + +This design is an example implementation of a Mojaloop settlement for a specific use case and is not meant to be comprehensive or cover all scenarios. This guide outlines the high-level design and explains the thinking that went into the design for a specific use-case chosen.``` +Although a version of this design is built and operational, not everything in this design document has been built. +This is an example of a settlement implementation design. The benefit of this design & design document is therefore: +- to use for demonstration; +- to use as an initial version to help 'Getting Started Quickly'; +- to use as a starting design on which improvements can be made before adopting; +- to use as a starting point to elaborate on concepts that are discussed in this design that may need to be addressed in another design. + +## Core-Settlement Operations + +This is the existing Settlement functionality provided by the supporting [Central-Settlement](https://github.com/mojaloop/central-settlement) Mojaloop Core component. Detailed information can be found in the [Mojaloop Technical Overview Documentation](https://github.com/mojaloop/documentation/tree/master/legacy/mojaloop-technical-overview/central-settlements). + +The Core-Settlement operations support the following capabilities: + +- Create a Settlement Matrix Report based on a list of Settlement-Windows +- Process Settlement Acknowledgements for an existing Settlement Matrix Report +- Manage Settlement-Windows (i.e. Create, Close, etc) +- Queries for Settlement Matrix Reports, Settlement-Windows, etc + +The OpenAPI definition is available at the [Mojaloop-Specification repository](https://github.com/mojaloop/mojaloop-specification/tree/master/settlement-api). + + +## High-level Architecture + +![High-level Settlement Architecture](../../.vuepress/public/BizOps-Framework-Settlements.png) + +### Experience layer + +The settlement experience layer is a stateless API that exposes the data to be consumed by its intended audience. Currently it's main function is to add the looked up user information into the API which is injected in the request headers by ORY Oathkeeper proxy. This function is expected to become larger as the product develops. + +### Process layer + +Process APIs provide a means of combining data and orchestrating multiple System APIs for a specific business purpose. The mojaloop central-settlement, and central-ledger API are being consumed by this process API. + +The Settlement Process API should conform to the [Mojaloop naming standards](https://docs.google.com/document/d/1AZbX0UjraytFty0IWOHpyR6z35bh0-MCFG1vGKId_5M/edit?usp=sharing), and as such the following name will be used: `settlement-process-svc`. + +## High-level Settlement Business Process + +This is a process that relies on the existing core-settlement operations to orchestrate the following capabilities: + +1. **Closing a settlement window** +The current settlement window can be closed manually as if there have been transfers linked to the settlement window. The hub operator can select the current open window, and then choose to close the window. +1. **Settlement Initiation** +Settlement Initiation is used by the hub operator to create a settlement batch which controls and drives the settlement process. +To initiate the settlement process, the hub operator selects : + - a set of settlement windows + - and optionally a settlement currency or a settlement model. (If a settlement currency is provided, then this is used to determine the settlement model.) +The position ledgers of the net credit participants are adjusted during Settlement Initiation. +**Note:** It is important to create the batch settlement object in the way that the settlement is to be completed and finalized. +1. A **Settlement initiation report** is generated and used to communicated to the settlement bank the requirements of the settlement. +1. **Settlement Finalization & settlement account re-balancing** +This process needs to occur after the settlement bank has applied the settlement changes. In this step the: + - settlement process is completed and a settlement finalization report has been received from the settlement bank. + - the net debit participants in the settlement have their position ledgers adjusted. + - the settlement ledgers are adjusted for all participants to match the transferred amount for the settlement. + - the settlement ledgers are checked against the real settlement account balances and adjustments processed to ensure that they are aligned. + +### Re-balancing function - is not best practice +It is worth noting that the re-balancing function that is defined in the above settlement finalization process is not the preferred or best-practice approach. +This approach was chosen because of regulatory requirements and limitations of mechanisms available to implement settlement between participants, i.e. it was designed to work on existing in-place financial solutions. Re-balancing has quite a few drawbacks, and is not considered best practice and should be avoided if possible. +These drawbacks are: +1. Out of sequence re-balancing results in incorrect results. This vulnerability therefore requires a business process and supportive management to enforce. +1. Reconciliation of the Mojaloop Settlement Account and the settlement bank account is difficult and complicated. This is because the re-balancing may not directly reflect the activity in the settlement bank account. The transfer amounts are linked to the timing of when the re-balancing action is applied, and when the reports and statements are generated. + +**Recommended solutions** +There are numerous other approaches to implementing settlement that do follow best practice. Please consult one of the experts in the Mojaloop community if you would like to explore this. If your requirement has similar limitations and creating a new mechanism is not an option, then there is a relatively minor adjustment that can be made to improve this solution and should be considered. +Replacing re-balancing mechanism with an import of a statement from the settlement bank account's transactions would remove the timing and reconciling problems mentioned above. + +## Detailed Sequence Diagram +![Settlement Detailed Process](../../.vuepress/public/settlementProcessAPI.svg) + +There are a couple of processes in the sequence diagram that are worth elaborating on. + +### Determining settlement Model + +This need to first determine which currencies are involved in the settlement, and then determine the appropriate list of Settlement Models which should be applied. A Settlement will be created for each of these Settlement Models. + +### Validation of the settlement finalization data + +The data that is presented as part of the settlement finalization needs a significant amount of validations on the data. +Some validations check integrity of the data, and these check will fail the process if not passed. Other validations do not prevent the process continuing, however will show warnings that need to be presented to the operator. +The continuation of the process is only possible once the operator has accepted the confirmed warnings with their resultant effects, and has provided their selected options for how the process should be applied. +It is for this reason that the validation of the data is a necessary step, and must be referenced when accepting and proceeding with the process. + +### Use cases for Finalize Settlement +**Validation scenarios** + +| Validation Description | Expected behaviour | +|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| +| Selected settlement ID does not match report settlement ID | Abort finalization with error | +| Sum of transfers in the report is non-zero | Abort finalization with error | +| Transfer amount does not match net settlement amount | Abort finalization with error | +| Balance not modified corresponding to transfer amount | Continue --> Adjust Settlement Account Balance to align | +| Balance provided in the report is not a positive value | Continue --> Set settlement balance to zero; set NCD = 0; disable participant POSITION account | +| Accounts in settlement not present in report | Abort finalization with error | +| Accounts in report not present in settlement | Abort finalization with error | +| Participant identifiers do not match - participant ID, account ID and participant name must match | Abort finalization with error | +| Account type should be POSITION | Abort finalization with error | +| New balance amount not valid for currency | Abort finalization with error | +| Transfer amount not valid for currency | Abort finalization with error | +| Account ID does not exist in switch | Abort finalization with error | +| Attempted to finalize an aborted settlement | Abort finalization with error | +| Error processing adjustment for participant | Continue with other participants - notify user of error | +| Error attempting to set settlement state to PS_TRANSFERS_RECORDED | Continue with other participants - notify user of error | +| Error attempting to set settlement state to PS_TRANSFERS_RESERVED | Continue with other participants - notify user of error | +| Error attempting to set settlement state to PS_TRANSFERS_COMMITTED | Continue with other participants - notify user of error | +| Errors attempting to settle accounts | Continue with other participants - notify user of error | +| Error attempting to set NDC | Continue with other participants - notify user of error | +| Error attempting to process funds in/out | Continue with other participants - notify user of error | +| Balance unchanged after processing funds in/out | Continue with other participants - notify user of error | +| Incorrect resulting balance after processing funds in/out | Continue with other participants - notify user of error | +| Failed to record settlement participant account state | Continue with other participants - notify user of error | + +### Audit information in the current Mojaloop version + +The process being performed is captured in the settlement reason field, and is therefore available in the audit reports. +Additionally the user and the references are captured in the extension lists. These too can be queried in the audit reports. + +### RBAC + +In order to make full use of the RBAC controls, the above four processes will be implemented as separate API endpoint & HTTP method combinations. This is to allow a different permissions to be associated with each process. + +## Multi-currency support + +Multi-currency settlement execution is determined by two factors: + +1. How the Settlement Models are constructed? + Settlement Models can be linked to a currency or left un-linked and applicable to all currencies. +1. How the settlements are initiated? + Settlement can be initiated with optionally a currency, or optionally a settlement model. + +As it is not easy to separate a settlement once it has been initiated, it is preferable to decide how settlement should be applied, and then design the system accordingly. + +--- +**NOTE** +Running a single currency multi-lateral deferred net settlement model, and using test currencies to perform regular platform health tests. Would prefer to have all settlements of test currencies to be created separately to the real currency. Would prefer not to have to select a currency or settlement model when initiating a settlement. +This can be achieved by creating separate settlement models I.e. one for each test currency, and one for the real currency. +The default action on initiating the settlement with transaction in both currencies, would be that separate settlements are initiated. (The determine settlement model function would find both settlement models.) +___ + + +## Error Cases +### Initiate Settlement + +**Detailed Initiate Settlement Sequence Diagram** + +![Initiate Settlement Process with Errors](../../.vuepress/public/settlementProcessInitiationErrors.svg) + +**Initiate Settlement Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Settlement ID not found | 3100 | 400 | Request Validation Error | +| Currency not valid | 3100 | 400 | Request Validation Error | +| SettlementModel not found | 3100 | 400 | Request Validation Error | +| Not able to create settlement | 2000 | 500 | Internal Server Error | +| Not able to update settlement state | 2000 | 500 | Internal Server Error | +| Technical error while communicating with Mojaloop services | 1000 | 500 | Technical Error | + + +### Finalize Settlement + +**Detailed Finalize Settlement Sequence Diagram** + +![Initiate Settlement Process with Errors](../../.vuepress/public/settlementProcessFinaliseErrors.svg) + +**Finalize Settlement Validation Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Settlement ID not found | 3100 | 400 | Request Validation Error | +| Participant IDs not found | 3000 | 400 | Request Validation Error | +| Participant Account IDs not found | 3000 | 400 | Request Validation Error | +| Technical error while communicating with Mojaloop services | 1000 | 500 | Technical Error | +| Selected settlement ID does not match report settlement ID | 3100 | 500 | Process Validation Error | +| Participant IDs in report not matching participant IDs in settlement | 3000 | 500 | Process Validation Error | +| Accounts in the report not matching with accounts in the settlement | 3000 | 500 | Process Validation Error | +| Sum of transfers in the report is non-zero | 3100 | 500 | Process Validation Error | +| Transfer amount does not match net settlement amount | 3100 | 500 | Process Validation Error | +| New balance amount not valid for currency | 3100 | 500 | Process Validation Error | +| Transfer amount not valid for currency | 3100 | 500 | Process Validation Error | +| Settlement is in ABORTED or invalid state | 3100 | 500 | Process Validation Error | +| Transfer amount not valid for currency | 3100 | 500 | Process Validation Error | + +**Finalize Settlement Confirmation Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Finalisation ID not found | 3100 | 400 | Request Validation Error | +| Settlement ID not found | 3100 | 400 | Request Validation Error | +| Technical error while communicating with Mojaloop services | 1000 | 500 | Technical Error | +| Error while funds in/out | 2001 | 500 | Internal Server Error | +| Not able to update settlement state | 2001 | 500 | Internal Server Error | +| Balances not matching after settlement | 2001 | 500 | Internal Server Error | +| Balances not matching after re-balancing | 2001 | 500 | Internal Server Error | diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml new file mode 100644 index 000000000..1939a92da --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.plantuml @@ -0,0 +1,174 @@ +/' + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + '/ + + +@startuml fx-fulfil-request +' declate title +title 2.1.0. FXP sends an Fulfil Success FX Conversion Request + +autonumber + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-transfer-fulfil" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Settlement Model\nHandler" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group FXP1 sends a fulfil success FX conversion request + FXP1 <-> FXP1: Retrieve fulfilment string generated during\nthe FX quoting process or regenerate it using\n**Local secret** and **ILP Packet** as inputs + note right of FXP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "conversionState": "" + "fulfilment": , + "completedTimestamp": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + FXP1 ->> MLAPI: PUT - /fxTransfers/ + activate MLAPI + MLAPI -> MLAPI: Schema validation\n + break Schema validation failed + MLAPI -->> FXP1: Respond HTTP - 400 (Bad Request) + end + MLAPI -> MLAPI: Validate incoming request \n(e.g transfer has not timed out, completedTimestamp is not in the future)\nError codes: 2001, 3100 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: fx_commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee\nError code: 2001 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2001 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> FXP1: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg 2.1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produce message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consume message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Settlement Model Handler Consume (Success)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'fx_commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'fx_commit' + ||| + ref over FXP1, TOPIC_NOTIFICATIONS: Send notification to Participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg new file mode 100644 index 000000000..c338b9c10 --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + 2.1.0. FXP sends an Fulfil Success FX Conversion Request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + FXP1 + FXP + + + FXP1 + FXP + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + topic-transfer-fulfil + + + topic-transfer-fulfil + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic- + settlement-model + + + topic- + settlement-model + Settlement Model + Handler + + + Settlement Model + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + + + + + + + FXP1 sends a fulfil success FX conversion request + + + + + 1 + Retrieve fulfilment string generated during + the FX quoting process or regenerate it using + Local secret + and + ILP Packet + as inputs + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } + + Payload - transferMessage: + { + "conversionState": "<transferState>" + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /fxTransfers/<ID> + + + + + 3 + Schema validation + + + + break + [Schema validation failed] + + + + 4 + Respond HTTP - 400 (Bad Request) + + + + + 5 + Validate incoming request + (e.g transfer has not timed out, completedTimestamp is not in the future) + Error codes: + 2001, 3100 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: fx_commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 6 + Route & Publish Fulfil event for Payee + Error code: + 2001 + + + + + 7 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2001 + + + 8 + Respond replication acknowledgements have been received + + + + 9 + Respond HTTP - 200 (OK) + + + 10 + Consume message + + + ref + Fulfil Handler Consume (Success) { + + 2.1.1 + + } + + + + 11 + Produce message + + + 12 + Produce message + + + 13 + Consume message + + + ref + Settlement Model Handler Consume (Success) + + + + 14 + Consume message + + + ref + Position Handler Consume (Success) + + + + 15 + Produce message + + + 16 + Consume message + + + opt + [action == 'fx_commit'] + + + ref + Send notification to Participant (Payer) + + + + 17 + Send callback notification + + + 18 + Consume message + + + opt + [action == 'fx_commit'] + + + ref + Send notification to Participant (FXP) + + + + 19 + Send callback notification + + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml new file mode 100644 index 000000000..0f0fb7018 --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.plantuml @@ -0,0 +1,186 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml PayerFSP-fx-conversion-prepare-request + +!$payerCurrency = "" +!$payeeCurrency = "" +!$dfsp1Id = "" +!$fxpID = "" +!$payerMSISDN = "" +!$payeeMSISDN = "" +!$payeeReceiveAmount = "" +!$payerSendAmount = "" +!$payeeFee = "" +!$targetAmount = "" +!$fxpChargesSource = "" +!$fxpChargesTarget = "" +!$fxpSourceAmount = "" +!$fxpTargetAmount = "" +!$conversionRequestId = "" +!$conversionId = "" +!$homeTransactionId = "" +!$quoteId = "" +!$transactionId = "" +!$quotePayerExpiration = "" +!$quotePayeeExpiration = "" +!$commitRequestId = "" +!$determiningTransferId = "" +!$transferId = "" +!$fxCondition = "" +!$condition = "" + +' declate title +title 1.1.0. DFSP1 sends an FX Conversion prepare request to FXP1 + +autonumber + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +group DFSP1 sends an FX Conversion request to FXP1 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload: + { + "commitRequestId": "$commitRequestId", + "determiningTransferId": "$determiningTransferId", + "initiatingFsp": "$dfsp1Id", + "counterPartyFsp": "$fxpID", + "amountType": "SEND", + "sourceAmount": { + "currency": "$payerCurrency", + "amount": "$fxpSourceAmount" + }, + "targetAmount": { + "currency": "$payeeCurrency", + "amount": "$fxpTargetAmount" + }, + "condition": "$fxCondition" + } + end note + DFSP1 ->> MLAPI: POST - /fxTransfers + activate MLAPI + MLAPI -->> DFSP1: Respond HTTP - 202 (Accepted) + alt Schema validation error + MLAPI-->>DFSP1: Respond HTTP - 400 (Bad Request) + end + note right of MLAPI #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: prepare, + action: fx_prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_TRANSFER_PREPARE: Route & Publish FX Prepare event for Payer + activate TOPIC_TRANSFER_PREPARE + TOPIC_TRANSFER_PREPARE <-> TOPIC_TRANSFER_PREPARE: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_TRANSFER_PREPARE --> MLAPI: Replication acknowledgements have been received + deactivate TOPIC_TRANSFER_PREPARE + alt Error publishing event + MLAPI-->>DFSP1: Respond HTTP - 500 (Internal Server Error)\n**Error code:** 2003 + end + deactivate MLAPI + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION : Prepare Handler Consume\n + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER : Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over FXP1, TOPIC_NOTIFICATIONS : Send notification to Participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Send callback notification + ||| +end +deactivate POS_HANDLER +deactivate PREP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg new file mode 100644 index 000000000..d5d22010d --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + 1.1.0. DFSP1 sends an FX Conversion prepare request to FXP1 + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + FXP1 + FXP + + + FXP1 + FXP + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Prepare Event Handler + + + Prepare Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP1 sends an FX Conversion request to FXP1 + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } + + Payload: + { + "commitRequestId": "<UUID>", + "determiningTransferId": "<UUID>", + "initiatingFsp": "<DFSP1>", + "counterPartyFsp": "<fxpId>", + "amountType": "SEND", + "sourceAmount": { + "currency": "<ISO currency code>", + "amount": "<number>" + }, + "targetAmount": { + "currency": "<ISO currency code>", + "amount": "<number>" + }, + "condition": "<ILP condition>" + } + + + + 1 + POST - /fxTransfers + + + + 2 + Respond HTTP - 202 (Accepted) + + + alt + [Schema validation error] + + + + 3 + Respond HTTP - 400 (Bad Request) + + + Message: + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <UUID>, + type: prepare, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish FX Prepare event for Payer + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 6 + Replication acknowledgements have been received + + + alt + [Error publishing event] + + + + 7 + Respond HTTP - 500 (Internal Server Error) + Error code: + 2003 + + + 8 + Consume message + + + ref + Prepare Handler Consume + + + + 9 + Produce message + + + 10 + Consume message + + + ref + Position Handler Consume + + + + 11 + Produce message + + + 12 + Consume message + + + ref + Send notification to Participant (FXP) + + + + 13 + Send callback notification + + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml new file mode 100644 index 000000000..9ce0b9424 --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.plantuml @@ -0,0 +1,273 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml prepare-handler-consume +' declate title +title 1.1.1.a. FX Prepare Handler Consume (single message) + +autonumber + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + note left of PREP_HANDLER #lightgrey + Event is automatically replicated + to the events topic (topic-events) + end note + + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event message + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Filter Event + PREP_HANDLER <-> PREP_HANDLER: Filter event - Rules: type == 'prepare' && action == 'fx_prepare'\nError codes: 2001 + end + end + + group Validate Prepare Transfer + PREP_HANDLER <-> PREP_HANDLER: Schema validation of the incoming message + PREP_HANDLER <-> PREP_HANDLER: Verify the message's signature (to be confirmed in future requirement) + note right of PREP_HANDLER #lightgrey + The above validation steps are already handled by + the ML-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + end note + + group Duplicate Check + ||| + PREP_HANDLER -> DB: Request Duplicate Check + ref over PREP_HANDLER, DB: Request Duplicate Check\n + DB --> PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE + group Process Duplication + alt hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of PREP_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + PREP_HANDLER -> DB: stateRecord = await getFxTransferById(commitRequestId) + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + DB --> PREP_HANDLER: Return stateRecord + deactivate DB + alt [COMMITTED, ABORTED].includes(stateRecord.transferStateEnumeration) + ||| + + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Produce message [functionality = TRANSFER, action = PREPAPE_DUPLICATE] + else + note right of PREP_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + end + end + else hasDuplicateId == FALSE + group Validate Prepare Request + group Validate Payer + PREP_HANDLER -> PREP_HANDLER: Validate FSPIOP-Source header matches initiatingFsp + PREP_HANDLER -> PREP_HANDLER: Validate payload.sourceAmount and payload.targetAmount scale and precision + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer participant is active + PREP_HANDLER <-> PREP_HANDLER: Validate Payer participant position account for the source currency [exists, active] + end + group Validate Payee + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee participant is active + PREP_HANDLER <-> PREP_HANDLER: Validate Payee participant position account for the target currency [exists, active] + end + group Validate Condition and Expiration + PREP_HANDLER <-> PREP_HANDLER: Validate cryptographic condition + PREP_HANDLER <-> PREP_HANDLER: Validate expiration [payload.expiration is valid ISO date and not in the past] + end + group Validate Different FSPs (if ENABLE_ON_US_TRANSFER == false) + PREP_HANDLER <-> PREP_HANDLER: Validate Payer and Payee FSPs are different + end + alt Validate Prepare Transfer (success) + group Persist Transfer State (with transferState='RECEIVED-PREPARE') + PREP_HANDLER -> DB: Request to persist transfer\nError codes: 2003 + activate DB + hnote over DB #lightyellow + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + end note + DB --> PREP_HANDLER: Return success + deactivate DB + end + else Validate Prepare Transfer (failure) + group Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + PREP_HANDLER -> DB: Request to persist transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate DB + hnote over DB #lightyellow + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + fxTransferError + end note + DB --> PREP_HANDLER: Return success + deactivate DB + end + end + end + end + end + + alt Validate Prepare Transfer (success) + group Hydrate Transfer Prepare Message + PREP_HANDLER -> PARTICIPANT_DAO: Get participant and currency for FX transfer (with 'payload.determiningTransferId') + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request participant and currency + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return participant and currency + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return participant and currency + deactivate PARTICIPANT_DAO + + end + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: fx_prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer\nError codes: 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Prepare Transfer (failure) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: fx_prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate PREP_HANDLER +@enduml + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg new file mode 100644 index 000000000..06c43df70 --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg @@ -0,0 +1,469 @@ + + + + + + + + + + + + 1.1.1.a. FX Prepare Handler Consume (single message) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Prepare Event Handler + + + Prepare Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + Prepare Handler Consume + + + Event is automatically replicated + to the events topic (topic-events) + + + 1 + Consume Prepare event message + + + break + + + Filter Event + + + + + 2 + Filter event - Rules: type == 'prepare' && action == 'fx_prepare' + Error codes: + 2001 + + + Validate Prepare Transfer + + + + + 3 + Schema validation of the incoming message + + + + + 4 + Verify the message's signature (to be confirmed in future requirement) + + + The above validation steps are already handled by + the ML-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + + + Duplicate Check + + + 5 + Request Duplicate Check + + + ref + Request Duplicate Check + + + + 6 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE] + + + Process Duplication + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + 7 + stateRecord = await getFxTransferById(commitRequestId) + + fxTransferStateChange + + + 8 + Return stateRecord + + + alt + [[COMMITTED, ABORTED].includes(stateRecord.transferStateEnumeration)] + + + 9 + Produce message [functionality = TRANSFER, action = PREPAPE_DUPLICATE] + + + + Ignore - resend in progress + + [hasDuplicateId == FALSE] + + + Validate Prepare Request + + + Validate Payer + + + + + 10 + Validate FSPIOP-Source header matches initiatingFsp + + + + + 11 + Validate payload.sourceAmount and payload.targetAmount scale and precision + + + 12 + Request to retrieve Payer Participant details (if it exists) + + + 13 + Request Participant details + + participant + participantCurrency + + + 14 + Return Participant details if it exists + + + 15 + Return Participant details if it exists + + + + + 16 + Validate Payer participant is active + + + + + 17 + Validate Payer participant position account for the source currency [exists, active] + + + Validate Payee + + + 18 + Request to retrieve Payee Participant details (if it exists) + + + 19 + Request Participant details + + participant + participantCurrency + + + 20 + Return Participant details if it exists + + + 21 + Return Participant details if it exists + + + + + 22 + Validate Payee participant is active + + + + + 23 + Validate Payee participant position account for the target currency [exists, active] + + + Validate Condition and Expiration + + + + + 24 + Validate cryptographic condition + + + + + 25 + Validate expiration [payload.expiration is valid ISO date and not in the past] + + + Validate Different FSPs (if ENABLE_ON_US_TRANSFER == false) + + + + + 26 + Validate Payer and Payee FSPs are different + + + alt + [Validate Prepare Transfer (success)] + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + 27 + Request to persist transfer + Error codes: + 2003 + + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + + + 28 + Return success + + [Validate Prepare Transfer (failure)] + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 29 + Request to persist transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + fxTransfer + fxTransferParticipant + fxTransferStateChange + fxTransferExtension + fxTransferError + + + 30 + Return success + + + alt + [Validate Prepare Transfer (success)] + + + Hydrate Transfer Prepare Message + + + 31 + Get participant and currency for FX transfer (with 'payload.determiningTransferId') + + + 32 + Request participant and currency + + participant + participantCurrency + + + 33 + Return participant and currency + + + 34 + Return participant and currency + + + Message: + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <hydratedTransferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 35 + Route & Publish Position event for Payer + Error codes: + 2003 + + [Validate Prepare Transfer (failure)] + + + Message: + { + id: <transferMessage.commitRequestId> + from: <ledgerName>, + to: <transferMessage.initiatingFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 35.1.3 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: fx_prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 36 + Publish Notification (failure) event for Payer + Error codes: + 2003 + + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml new file mode 100644 index 000000000..cd55802c7 --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.plantuml @@ -0,0 +1,312 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml position-handler-consume +' declate title +title 1.1.2.a. Position Handler Consume (single message) + +autonumber + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +entity "Position DAO" as POS_DAO +entity "Settlement DAO" as SETTLEMENT_DAO +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant SETTLEMENT_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + note left of POS_HANDLER #lightgrey + Event is automatically replicated + to the events topic (topic-events) + end note + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'fx_prepare' + POS_HANDLER -> POS_HANDLER: Validate 'payload.commitRequestId' or 'message.value.content.uriParams.id' is not empty\n**Error code:** 2003 + end + end + + alt Calulate & Validate Latest Position (success) + group Calculate position and persist change + POS_HANDLER -> SETTLEMENT_DAO: Request active settlement models + activate SETTLEMENT_DAO + SETTLEMENT_DAO -> DB: Retrieve active settlement models + activate DB + hnote over DB #lightyellow + settlementModel + end note + DB --> SETTLEMENT_DAO: Return active settlement models + deactivate DB + SETTLEMENT_DAO --> POS_HANDLER: Return active settlement models + deactivate SETTLEMENT_DAO + POS_HANDLER -> POS_HANDLER: Select currency matching or default settlement model for POSITION ledger account type\n**Error code:** 6000 + + POS_HANDLER -> PARTICIPANT_DAO: Request Payer Participant position account by name and currency + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Retrieve Payer Participant position account by name and currency + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Return Payer Participant position account by name and currency + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Return Payer Participant position account by name and currency + deactivate PARTICIPANT_DAO + + POS_HANDLER -> DB: Retrieve transfer state from DB by 'commitRequestId' + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + DB --> POS_HANDLER: Retrieve transfer state from DB + deactivate DB + DB --> POS_HANDLER: Return transfer state + + POS_HANDLER -> PARTICIPANT_DAO: Request position limits for Payer Participant + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Return position limits + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Return position limits + deactivate PARTICIPANT_DAO + + alt Validate transfer state (transferState='RECEIVED_PREPARE') + POS_HANDLER <-> POS_HANDLER: Update transfer state to RESERVED + POS_HANDLER <-> POS_HANDLER: Calculate latest position for prepare + POS_HANDLER <-> POS_HANDLER: Validate calculated latest position (lpos) against the net-debit cap (netcap) - Rule: lpos < netcap + + POS_HANDLER -> POS_DAO: Request payer participant position for the transfer currency and settlement currency + activate POS_DAO + POS_DAO -> DB: Retrieve payer participant position for the transfer currency and settlement currency + hnote over DB #lightyellow + participantPosiiton + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return payer participant position for the transfer currency and settlement currency + deactivate POS_DAO + + POS_HANDLER <-> POS_HANDLER: Update participant position (increase reserved position by transfer amount) + POS_HANDLER -> DB: Persist payer participant position in DB + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB -> POS_HANDLER: Return success + deactivate DB + + POS_HANDLER -> PARTICIPANT_DAO: Request payer participant limit by currency + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Retrieve payer participant limit by currency + activate DB + hnote over DB #lightyellow + participant + participantCurrency + participantLimit + end note + DB --> PARTICIPANT_DAO: Return payer participant limit by currency + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Return payer participant limit by currency + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculate latest available position based on payer limit and payer liquidity cover + + alt Validate position limits (success) + POS_HANDLER <-> POS_HANDLER: Update transfer state to RESERVED + POS_HANDLER -> DB: Update participant position + activate DB + hnote over DB #lightyellow + participantPosition + end note + deactivate DB + + POS_HANDLER -> DB: Persist transfer state change (RESERVED) to DB + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + + POS_HANDLER -> DB: Insert participant position change record + activate DB + hnote over DB #lightyellow + participantPositionChange + end note + deactivate DB + else Validate position limits (failure) + POS_HANDLER -> DB: Persist transfer state change (ABORTED_REJECTED) to DB, **Error codes:** 4001, 4200 + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + end + else transferState !='RECEIVED_PREPARE' + POS_HANDLER <-> POS_HANDLER: Update transfer state to ABORTED_REJECTED + POS_HANDLER -> DB: Persist aborted transfer state + activate DB + hnote over DB #lightyellow + fxTransferStateChange + end note + deactivate DB + end + + alt Transfer state is RESERVED + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event to FXP + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": , + "errorDescription": "", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer. **Error code:** 2001 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + + end + else Calculate & Validate Latest Position (failure) + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": , + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer **Error codes:** 4001, 4200 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg new file mode 100644 index 000000000..b814e89ed --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + 1.1.2.a. Position Handler Consume (single message) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Settlement DAO + + + Settlement DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler Consume + + + Event is automatically replicated + to the events topic (topic-events) + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + 2 + Validate event - Rule: type == 'position' && action == 'fx_prepare' + + + + + 3 + Validate 'payload.commitRequestId' or 'message.value.content.uriParams.id' is not empty + Error code: + 2003 + + + alt + [Calulate & Validate Latest Position (success)] + + + Calculate position and persist change + + + 4 + Request active settlement models + + + 5 + Retrieve active settlement models + + settlementModel + + + 6 + Return active settlement models + + + 7 + Return active settlement models + + + + + 8 + Select currency matching or default settlement model for POSITION ledger account type + Error code: + 6000 + + + 9 + Request Payer Participant position account by name and currency + + + 10 + Retrieve Payer Participant position account by name and currency + + participant + participantCurrency + + + 11 + Return Payer Participant position account by name and currency + + + 12 + Return Payer Participant position account by name and currency + + + 13 + Retrieve transfer state from DB by 'commitRequestId' + + fxTransferStateChange + + + 14 + Retrieve transfer state from DB + + + 15 + Return transfer state + + + 16 + Request position limits for Payer Participant + + + 17 + Request position limits for Payer Participant + + participant + participantLimit + + + 18 + Return position limits + + + 19 + Return position limits + + + alt + [Validate transfer state (transferState='RECEIVED_PREPARE')] + + + + + 20 + Update transfer state to RESERVED + + + + + 21 + Calculate latest position for prepare + + + + + 22 + Validate calculated latest position (lpos) against the net-debit cap (netcap) - Rule: lpos < netcap + + + 23 + Request payer participant position for the transfer currency and settlement currency + + + 24 + Retrieve payer participant position for the transfer currency and settlement currency + + participantPosiiton + + + 25 + Return payer participant position for the transfer currency and settlement currency + + + + + 26 + Update participant position (increase reserved position by transfer amount) + + + 27 + Persist payer participant position in DB + + participantPosition + + + 28 + Return success + + + 29 + Request payer participant limit by currency + + + 30 + Retrieve payer participant limit by currency + + participant + participantCurrency + participantLimit + + + 31 + Return payer participant limit by currency + + + 32 + Return payer participant limit by currency + + + + + 33 + Calculate latest available position based on payer limit and payer liquidity cover + + + alt + [Validate position limits (success)] + + + + + 34 + Update transfer state to RESERVED + + + 35 + Update participant position + + participantPosition + + + 36 + Persist transfer state change (RESERVED) to DB + + fxTransferStateChange + + + 37 + Insert participant position change record + + participantPositionChange + + [Validate position limits (failure)] + + + 38 + Persist transfer state change (ABORTED_REJECTED) to DB, + Error codes: + 4001, 4200 + + fxTransferStateChange + + [transferState !='RECEIVED_PREPARE'] + + + + + 39 + Update transfer state to ABORTED_REJECTED + + + 40 + Persist aborted transfer state + + fxTransferStateChange + + + alt + [Transfer state is RESERVED] + + + Message: + { + id: <transferMessage.commitRequestId> + from: <transferMessage.initiatingFsp>, + to: <transferMessage.counterPartyFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 41 + Publish Notification event to FXP + + + + Message: + { + id: <transferMessage.commitRequestId> + from: <switch>, + to: <transferMessage.initiatingFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <error code>, + "errorDescription": "<error description>", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 42 + Publish Notification (failure) event for Payer. + Error code: + 2001 + + [Calculate & Validate Latest Position (failure)] + + + Message: + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <error code>, + "errorDescription": "<error description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 43 + Publish Notification (failure) event for Payer + Error codes: + 4001, 4200 + + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml new file mode 100644 index 000000000..ae16da1ca --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.plantuml @@ -0,0 +1,173 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 + (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- +******'/ + +@startuml fx-conversion-abort-request + +title 2.2.0.a. FXP1 sends a PUT call on /error end-point for an FX conversion request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +control "FXP1\nFXP" as FXP1 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "transfer-fulfil-topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant FXP1 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group FXP1 sends a Fulfil Success Transfer request + FXP1 <-> FXP1: During processing of an incoming\nPOST /fxTransfers request, some processing\nerror occurred and an Error callback is made + note right of FXP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage: + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + FXP1 ->> MLAPI: PUT - /fxTransfers//error + activate MLAPI + MLAPI -> MLAPI: Schema validation + alt Schema validation (failure) + MLAPI -> FXP1: Respond HTTP - 400 (Bad Request) + end + MLAPI -> MLAPI: Validate incoming message (e.g error code is valid)\n**Error codes:** 3100 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: fx_abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Abort/Reject event for FXP\nError code: 2001 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2001 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> FXP1: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Reject/Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Abort)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'fx_abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'fx_abort' + ||| + ref over FXP1, TOPIC_NOTIFICATIONS: Send notification to Participant (FXP)\n + NOTIFY_HANDLER -> FXP1: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg new file mode 100644 index 000000000..208a3245f --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + 2.2.0.a. FXP1 sends a PUT call on /error end-point for an FX conversion request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + FXP1 + FXP + + + FXP1 + FXP + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + transfer-fulfil-topic + + + transfer-fulfil-topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + FXP1 sends a Fulfil Success Transfer request + + + + + 1 + During processing of an incoming + POST /fxTransfers request, some processing + error occurred and an Error callback is made + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } + + Payload - errorMessage: + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /fxTransfers/<ID>/error + + + + + 3 + Schema validation + + + alt + [Schema validation (failure)] + + + 4 + Respond HTTP - 400 (Bad Request) + + + + + 5 + Validate incoming message (e.g error code is valid) + Error codes: + 3100 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: fx_abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 6 + Route & Publish Abort/Reject event for FXP + Error code: + 2001 + + + + + 7 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2001 + + + 8 + Respond replication acknowledgements have been received + + + + 9 + Respond HTTP - 200 (OK) + + + 10 + Consume message + + + ref + Fulfil Handler Consume (Reject/Abort) + + + + 11 + Produce message + + + 12 + Consume message + + + ref + Position Handler Consume (Abort) + + + + 13 + Produce message + + + 14 + Consume message + + + opt + [action == 'fx_abort'] + + + ref + Send notification to Participant (Payer) + + + + 15 + Send callback notification + + + 16 + Consume message + + + opt + [action == 'fx_abort'] + + + ref + Send notification to Participant (FXP) + + + + 17 + Send callback notification + + diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml new file mode 100644 index 000000000..cbdee28bf --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.plantuml @@ -0,0 +1,110 @@ +/'***** + License + -------------- + Copyright © 2020 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Mojaloop Foundation for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + + * Steven Oderayi + -------------- + ******'/ + +@startuml send-notification-to-participant-single-message-v2_0 +' declate title +title 1.1.4.a. Send notification to Participant (Payer/Payee/FXP) (single message) v2.0 + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP/FXP\nParticipant" as PAYEE_DFSP_OR_FXP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee or FXP)" #lightGray + participant PAYEE_DFSP_OR_FXP +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participants + note left of NOTIFY_HANDLER #lightgray + Event is automatically replicated + to the events topic (topic-events) + end note + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume Notification event + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + note right of NOTIFY_HANDLER #lightgray + The endpoint details are cached, when the cache + expires, the details are fetched again + end note + NOTIFY_HANDLER -> CSAPI: Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints\nError code: 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Fetch Endpoint details for Participant\nError code: 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Endpoint details for Participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Retrieved Endpoint details for Participant + deactivate DB + PARTICIPANT_DAO --> CSAPI: Return Endpoint details for Participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Return Endpoint details for Participant\nError codes: 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification with Prepare/fulfil result/error to \nPayer DFSP to specified Endpoint - PUT \nError code: 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt event.action === 'reserve' + alt event.status === 'success' + NOTIFY_HANDLER -> PAYEE_DFSP_OR_FXP: Notification to with succesful fulfil result (committed) to Payee DFSP/FXP to specified Endpoint - PATCH \nError code: 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP_OR_FXP: HTTP 200 OK + end + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg new file mode 100644 index 000000000..2d85604fd --- /dev/null +++ b/docs/technical/central-fx-transfers/assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + 1.1.4.a. Send notification to Participant (Payer/Payee/FXP) (single message) v2.0 + + Financial Service Provider (Payer) + + ML API Adapter Service + + Central Service + + Financial Service Provider (Payee or FXP) + + + + + + + + + + + + + + + + Payer DFSP + Participant + + + Payer DFSP + Participant + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + + + Notification-Topic + + + Notification-Topic + Central Service API + + + Central Service API + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + Payee DFSP/FXP + Participant + + + Payee DFSP/FXP + Participant + + + + + + + + + + Send notification to Participants + + + Event is automatically replicated + to the events topic (topic-events) + + + 1 + Consume Notification event + + + The endpoint details are cached, when the cache + expires, the details are fetched again + + + 2 + Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints + Error code: + 2003 + + + 3 + Fetch Endpoint details for Participant + Error code: + 2003 + + + 4 + Fetch Endpoint details for Participant + + participantEndpoint + + + 5 + Retrieved Endpoint details for Participant + + + 6 + Return Endpoint details for Participant + + + 7 + Return Endpoint details for Participant + Error codes: + 3202, 3203 + + + 8 + Notification with Prepare/fulfil result/error to + Payer DFSP to specified Endpoint - PUT + Error code: + 1001 + + + 9 + HTTP 200 OK + + + alt + [event.action === 'reserve'] + + + alt + [event.status === 'success'] + + + 10 + Notification to with succesful fulfil result (committed) to Payee DFSP/FXP to specified Endpoint - PATCH + Error code: + 1001 + + + 11 + HTTP 200 OK + + diff --git a/docs/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md b/docs/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md new file mode 100644 index 000000000..c93519d36 --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/1.1.0-fx-prepare-transfer-request.md @@ -0,0 +1,13 @@ +# FX Prepare Transfer Request + +Sequence design diagram for FX Prepare Transfer Request process. + +## References within Sequence Diagram + +* [FX Prepare Handler Consume (1.1.1.a)](1.1.1.a-fx-prepare-handler-consume.md) +* [FX Position Handler Consume (1.1.2.a)](1.1.2.a-fx-position-handler-consume.md) +* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v2.0.md) + +## Sequence Diagram + +![seq-fx-prepare-1.1.0.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.0.svg) diff --git a/docs/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md b/docs/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md new file mode 100644 index 000000000..f494d5661 --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/1.1.1.a-fx-prepare-handler-consume.md @@ -0,0 +1,7 @@ +# FX Prepare Handler Consume + +Sequence design diagram for FX Prepare Handler Consume process. + +## Sequence Diagram + +![seq-fx-prepare-1.1.1.a.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.1.a.svg) diff --git a/docs/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md b/docs/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md new file mode 100644 index 000000000..a23fc2316 --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/1.1.2.a-fx-position-handler-consume.md @@ -0,0 +1,7 @@ +# FX Position Handler Consume + +Sequence design diagram for FX Position Handler Consume process. + +## Sequence Diagram + +![seq-fx-prepare-1.1.2.a.svg](../assets/diagrams/sequence/seq-fx-prepare-1.1.2.a.svg) diff --git a/docs/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md b/docs/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md new file mode 100644 index 000000000..c57569a2f --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/1.1.4.a-send-notification-to-participant-v2.0.md @@ -0,0 +1,7 @@ +# Send Notification to Participant v2.0 + +Sequence design diagram for the Send Notification to Participant request. + +## Sequence Diagram + +![seq-prepare-1.1.4.a-v2.0.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a-v2.0.svg) diff --git a/docs/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md b/docs/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md new file mode 100644 index 000000000..018e242fb --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/2.1.0-fx-fulfil-transfer-request.md @@ -0,0 +1,13 @@ +# Fulfil Transfer Request success + +Sequence design diagram for the Fulfil Success Transfer request. + +## References within Sequence Diagram + + +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v2.0.md) + +## Sequence Diagram + +![seq-fx-fulfil-2.1.0.svg](../assets/diagrams/sequence/seq-fx-fulfil-2.1.0.svg) diff --git a/docs/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md b/docs/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md new file mode 100644 index 000000000..bbbbafd59 --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/2.2.0-fx-fulfil-reject-transfer.md @@ -0,0 +1,7 @@ +# FXP sends a Fulfil Abort FX Transfer request + +Sequence design diagram for the Fulfil Reject FX Transfer process. + +## Sequence Diagram + +![seq-fx-reject-2.2.0.a.svg](../assets/diagrams/sequence/seq-fx-reject-2.2.0.a.svg) diff --git a/docs/technical/central-fx-transfers/transfers/README.md b/docs/technical/central-fx-transfers/transfers/README.md new file mode 100644 index 000000000..692cfb683 --- /dev/null +++ b/docs/technical/central-fx-transfers/transfers/README.md @@ -0,0 +1,8 @@ +# Mojaloop FX Transfer Operations + +Operational processes that are core to enabling FX transfers: + +- FX Prepare process +- FX Fulfil process +- Notifications process +- FX Reject/Abort process diff --git a/docs/technical/faqs.md b/docs/technical/faqs.md new file mode 100644 index 000000000..afb76ba68 --- /dev/null +++ b/docs/technical/faqs.md @@ -0,0 +1,158 @@ +# Frequently Asked Questions + +This document contains some of the frequently asked technical questions from the community. + +## 1. What is supported? + +Currently the Central ledger components are supported by the team. The DFSP components are outdated and thus the end-to-end environment and full setup is challenging to install. + +### 2. Can we connect directly to Pathfinder in a development environment? + +For the local and test environment, we recommend interfacing with the 'mock-pathfinder' service instead. Pathfinder is a 'paid by usage' service. + +Access the https://github.com/mojaloop/mock-pathfinder repository to download and install mock-pathfinder. Run command npm install in mock-pathfinder directory to install dependencies after this update Database_URI in mock-pathfinder/src/lib/config.js. + +### 3. Should i register DFSP via url http://central-directory/commands/register or i need to update configuration in default.json? + +You should register using the API provided, using postman or curl. Client is using LevelOne code. Needs to implement the current Mojaloop release with the current Postman scripts. + +### 4. Status of the pod pi3-kafka-0 is still on CrashLoopBackOff? + +- More background related to the question: + + When I tired to get logs of the container centralledger-handler-admin-transfer, I get the following error: + Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing + And the status of the pod pi3-kafka-0 is still on CrashLoopBackOff. + I am using a vps on ubuntu 16.04 with RAM 12GB, 2vCores, 2.4GHz, Rom 50GB at OVH for the deployment. + +Increased RAM to 24 GB and CPU to 4 resolved the issues. Appears to be a timeout on Zookeeper due depletion of available resources, resulting in the services shutting down. + +### 5. Why am I getting an error when we try to create new DFSP using Admin? + +Please insure you are using the most current Postman scripts available on https://github.com/mojaloop/mock-pathfinder repository. + + +### 6. Can I spread Mojaloop components over different physical machines and VM's? + +You should be able to setup on different VM's or physical machines. The distribution pretty much depend on your requirements and would be implementation specific. We utilise Kubernetes to assist with the Container Orchestration. This enables us to schedule the deployments through the Kubernetes runtime to specific machines if required, and request specific resources if required. The helm charts in the helm repository could be used as guideline to how best allocate and group the components in your deployment. Naturally you would need to update the configurations to complement your custom implementation. + +### 7. Can we expect all the endpoints defined in the API document are implemented in Mojaloop? + +The Mojaloop Specification API for transfers and the Mojaloop Open Source Switch implementation are independent streams, though obviously the implementation is based on the Specification. Based on the use-cases prioritized for a time-frame and based on the end-points needed to support those use-cases, implementation will be done. If a few end-points are not prioritized then implementation for them may not be available. However, I think the goal is to eventually support all the end-points specified though it may take time. Thanks for the collection. We do have some of these on the ‘postman’ repo in the mojaloop GitHub org. + +### 8. Does Mojaloop store the payment initiator FSP’s quote/status info? + +At the moment, the Mojaloop Open source Switch implementation does *not* store Quotes related information. The onus is on the Payer, Payee involved in the process to store the relevant information. + +### 9. Does Mojaloop handle workflow validation? + +Not at the moment, but this may happen in the future. Regarding correlating requests that are related to a specific transfer, you may look at the ‘transaction’ end-point/resource in the Specification for more information on this. In addition to this, I can convey that some background work is ongoing regarding the specification to make this correlation more straight-forward and simpler i.e., to correlate quote and transfer requests that come under a single transaction. + + +### 10. How to register a new party in Mojaloop? + +There is no POST on /parties resource, as specified in section 6.1.1 of the API Defintion. Please refer to section: 6.2.2.3 `POST /participants//` in the API Defintion. + +” _The HTTP request `POST /participants//` (or `POST /participants///`) is used to create information on the server regarding the provided identity, defined by ``, ``, and optionally `` (for example, POST_ + _/participants/MSISDN/123456789 or POST /participants/BUSINESS/shoecompany/employee1). See Section 5.1.6.11 for more information regarding addressing of a Party._ ”. + +### 11. Does the participant represent an account of a customer in a bank? + +For more on this, please refer to this doc (Section 3..2): https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +” _In the API, a Participant is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource Participants is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system._ ” + +In essence, a participant is any FSP participating in the Scheme (usually not a customer). For account lookup, a directory service such as *Pathfinder* can be used, which provides user lookup and the mapping. If such a directory service is not provided, an alternative is provided in the Specification, where the Switch hosts an Account Lookup Service (ALS) but to which the participants need to register parties. I addressed this earlier. But one thing to note here is that the Switch does not store the details, just the mapping between an ID and an FSP and then the calls to resolve the party are sent to that FSP. + +https://github.com/mojaloop/mojaloop-specification CORE RELATED (Mojaloop): + +This repo contains the specification document set of the Open API for FSP Interoperability - mojaloop/mojaloop-specification. + +### 12. How to register _trusted_ payee to a payer, to skip OTP? + +To skip the OTP, the initial request on the /transactionRequests from the Payee can be programmatically (or manually for that matter) made to be approved without the use of the /authorizations endpoint (that is need for OTP approval). Indeed the FSP needs to handle this, the Switch does not. This is discussed briefly in section 6.4 of the Specification. + +### 13. Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file? + +From the official kubernetes github repository in the README.md, the latest link to use is "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Be sure to always verify 3rd party links before implementing. Open source applications are always evolving. + +### 14. When installing nginx-ingress for load balancing & external access - Error: no available release name found? + +Please have a look at the following addressing a similar issue. To summarise - it is most likely an RBAC issue. Have a look at the documentation to set up Tiller with RBAC. https://docs.helm.sh/using_helm/#role-based-access-control goes into detail about this. The issue logged: helm/helm#3839. + +### 15. Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command. + +Found a solution here https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Ubuntu 14 here, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. First, I want to build latest stable (seems it's 0.9.2) librdkafka into /opt/librdkafka. curl https://codeload.github.com/ede... + +Here are the steps to rebuild librdkafka: + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout ` + +cd librdkafka && ./configure && make && make install && ldconfig + +After that I'm able to import stuff without specifying LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +The Apache Kafka C/C++ library. Contribute to edenhill/librdkafka development by creating an account on GitHub. + +### 16. Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only? + +We can use mojaloop for interoperability to support mobile wallet and other such money transfers. This is not a software for a DFSP (there are open source projects that cater for these such as Finserv etc). Mojaloop is for a Hub/Switch primarily and an API that needs to be implemented by a DFSP. But this is not for managing mobile wallets as such. + +### 17. Describe companies that helps to deploy & support for mojaloop? + +Mojaloop is an open source software and specification. + +### 18. Can you say something about mojaloop & security? + +The Specification is pretty standard and has good security standards. But these need to be implemented by the adopters and deployers. Along with this, the security measures need to be coupled with other Operational and Deployment based security measures. Moreover, the coming few months will focus on security perspective for the Open Source community. + +### 19. What are the benefit(s) from using mojaloop as interoperabilty platform? + +Benefits: Right now for example, an Airtel mobile money user can transfer to another Airtel mobile money user only. With this, he/she can transfer to any Financial service provider such as another mobile money provider or any other bank account or Merchant that is connected to the Hub, irrespective of their implementation. They just need to be connected to the same Switch. Also, this is designed for feature phones so everyone can use it. + +### 20. What are the main challenges that companies face using mojaloop? + +At this point, the main challenges are around expectations. Expectations of the adopters of mojaloop and what really mojaloop is. A lot of adopters have different understanding of what mojaloop is and about its capabilities. If they have a good understanding, a lot of current challenges are mitigated.. +Yes, forensic logging is a security measure as well for auditing purposes which will ensure there is audit-able log of actions and that everything that is a possible action of note is logged and rolled up, securely after encryption at a couple of levels. + +### 21. Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform? + +This also ensures all the services always run the code they’re meant to run and anything wrong/bad is stopped from even starting up. Also, for reporting and auditors, reports can have a forensic-log to follow. + +### 22. How do the financial service providers connect with mojaloop? + +There is an architecture diagram that presents a good view of the integration between the different entities. https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +### 23. Is there any open source ISO8583-OpenAPI converter/connector available? + +I don't believe a generic ISO8583 `<-> Mojaloop integration is available currently. We're working on some "traditional payment channel" to Mojaloop integrations (POS and ATM) which we hope to demo at the next convening. These would form the basis for an ISO8583 integration we might build and add to the OSS stack but bare in mind that these integrations will be very use case specific. + +### 24. How do I know the end points to setup postman for testing the deployment? + +On the Kubernetes dashboard, select the correct NAMESPACE. Go to Ingeresses. Depending on how you deployed the helm charts, look for 'moja-centralledger-service'. Click on edit, and find the tag ``. This would contain the endpoint for this service. + +### 25. Why are there no reversals allowed on a Mojaloop? + +*Irrevocability* is a core Level One Principle (edited) and not allowing reversals is essential for that. Here is the section from the API Definition addressing this: + +_*6.7.1.2 Transaction Irrevocability*_ +_The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions._ +_As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using POST /transfers including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer’s expiry time is exceeded before the Payee FSP responds (see Sections 6.7.1.3 and 6.7.1.5 for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties._ + +However, *Refunds* is a use case supported by the API. + +### 26. ffg. error with microk8s installation "MountVolume.SetUp failed"? + +Would appear if it is a space issue, but more the 100GiB of EBS storage was allocated. +The issue resolved itself after 45 minutes. Initial implementation of the mojaloop project can take a while to stabilize. + +### 27. Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"? + +You need to create the corresponding Hub accounts (HUB_MULTILATERAL_SETTLEMENT and HUB_RECONCILIATION) for the specified currency before setting up the participants. +In this Postman collection you can find the requests to perform the operation in the "Hub Account" folder: https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Find also the related environments in the Postman repo: https://github.com/mojaloop/postman diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png new file mode 100644 index 000000000..818a34706 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png new file mode 100644 index 000000000..21d61c305 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParticipant_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png new file mode 100644 index 000000000..175ca5e37 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldGetParty_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png new file mode 100644 index 000000000..edfac583f Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantAssoc_20220919.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png new file mode 100644 index 000000000..ccb1b42a2 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/assets/aldPartyParticipantDisassoc_20220919.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md new file mode 100644 index 000000000..761369b79 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/accountLookupAndDiscovery/index.md @@ -0,0 +1,73 @@ +# Account Lookup And Discovery BC + +The Accounts Lookup and Discovery BC is responsible for locating and associating participants and parties with party or participant triggered transactions. + +## Terms + +The following terms are used in this BC, also known as a domain. + +| Term | Description | +|---|---| +| **Participant** | Financial Services Provider | +| **Party** | FSP Customer | + +## Functional Overview + +![Use Case - Functional Overview](./assets/ML2RA_bc_accLookDiscvry_Apr22-b400.png) +>BC Functional Diagram: Account Lookup and Discovery Overview + +## Use Cases + +#### Party/Participant Associate + +#### Description + +Where a Participant DFSP requests a given Party ID to be associated with a Participant (itself). + +***Note:*** *Checks and validations of the KYC (Know You Customer) details are not covered here and are left to processes outside of the Mojaloop API calls and should be covered by the Scheme, to ensure that association (or disassociation) requests are valid.* + +#### Flow Diagram + +![Use Case - Party/Participant Associate](./assets/aldPartyParticipantAssoc_20220919.png) +>UC Flow Diagram: Party/Participant Associate + +### Party/Participant Disassociate + +#### Description + +Where a Participant DFSP requests an existing association between a given Party ID and a Participant (itself) to be removed. + +#### Flow Diagram + +![Use Case - Party/Participant Disassociate](./assets/aldPartyParticipantDisassoc_20220919.png) +>UC Workflow Diagram: Party/Participant Disassociate + + + + +### Get Participant + +#### Description + +Where a Participant DFSP requests Participant association information based on a Party identifier, this UC is used by the switch to validate the request and provide the requested association data to the requesting DFSP. + +#### Flow Diagram + +![Use Case - Get Participant](./assets/aldGetParticipant_20210825.png) +>UC Flow Diagram: Get Participant + +### Get Party + +#### Description + +Where a participant DFSP queries another participant DFSP for the details of a Party which the second DFSP holds, this UC is used to validate the request and provide the requested Party data to the requesting DFSP. + +#### Flow Diagram + +![Use Case - Get Party](./assets/aldGetParty_20210825.png) +>UC Flow Diagram: Get Party + + + + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png b/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png new file mode 100644 index 000000000..4da5a26b9 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md b/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md new file mode 100644 index 000000000..4503991da --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/accountsAndBalances/index.md @@ -0,0 +1,121 @@ +# Accounts and Balances BC + +The Accounts and Balances BC acts as the "central ledger" for the system. It interacts primarily with the Settlements BC, Participants Lifecycle BC and Transfers BCs, and is a directed sub-system, which means that it is a dependency of the BCs that use it as a "financial system of record" for the financial accounting. + +**Note:** + +The Accounts and Balances BC contains a limited amount of logic to ensure that **(a)** the correct relationships are created and maintained between entities when an external BC creates, updates, queries or closes accounts and **(b)** the correct account limits are enforced (i.e. set and not exceeded) when an external BC attempts to create journal entries and **\(c\)** avoids duplicate ledger entries by using *Universal Unique Identifiers (UUID)* for unique journal entry identifiers. + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Account** | Refers to a General Ledger account, a record in an accounting system that records the debit or credit entries that represent a financial transaction. | +| **Journal Entry** | Credit/Debit financial records against Account. | +| **Balance** | The amount available in an account, when the debits and credits have been factored in. | + +## Functional Overview - Accounts and Balances + +![Functional Overview - Accounts and Balances](./assets/ML2RA_A&B-bcAccBal-FunctionalOverview_Mar22-c.png) +>BC Functional Diagram: Accounts & Balances Overview + +## Use Cases + +### Create Account + +#### Description + +The workflow provided by this UC enables the Switch to create new participant/transfer/settlement accounts in the System Ledger. (Participant Account creation occurs from both the Participant Lifecycle Management and the Settlement BCs. Examples of both have been provided in the Flow Diagrams below). + +Further, the workflow provides for specification of credit/debit Journal Entry limits, and to ensure that the Account is unique in the System Ledger. + +#### Flow Diagram + +Account creation from [Participant Lifecycle Management BC](../participantLifecycleManagement/index.md) + + + +![Use Case - PLCM BC](../participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png) +![Use Case - Add Participant Account - Approval (P2)](../participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Add Participant Accounts + +Account creation from [Settlements BC](../settlements/index.md) + +![Use Case - Settlements BC](../settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png) +>UC Workflow Diagram: Bootstrap (Startup) Settlement Model via Configuration + +### Close Account + +#### Description + +Close a participant account in the System Ledger and prevent new journal entries from impacting it.
    (Still to be determined: Drain collateral CR balances to another account automatically?) + +### Query Account + +#### Description + +Query the status and balance for participant account. + +#### Flow Diagram + +Query liquidity CR/DR limits from [Participant Lifecycle Management BC](../participantLifecycleManagement/index.md) + + + +![Use Case - PLCM BC](../participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png) +>UC Workflow Diagram: Liquidity Cover Queries + +### Query Journal Entries + +#### Description + +Query Journal debit/credit Entries for an Account. + +### Insert Journal Entry + +#### Description + +Insert a participant journal entry into the System Ledger specifying the debit and credit accounts (There are three ways through which participant journal entries can be made. See the Flow Diagrams below for a description of each.) +Respond with the updated account balance. + +#### Flow Diagram + +Journal Entry insertion from [Transfers BC](../transfers/index.md) + +![Use Case - Transfers BC](../transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png) +>UC Workflow Diagram: Perform Transfer (Universal Mode) + +Journal Entry insertion from [Settlements BC](../settlements/index.md) using `Deferred Net Settlement` (DNS) model + +![Use Case - Settlements BC](../settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png) +>UC Workflow Diagram: Deferred Net Settlement - 19/10/2021 + +Journal Entry insertion from [Settlements BC](../settlements/index.md) using `Immediate Gross Settlement` (IGS) model + +![Use Case - Settlements BC](../settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png) +>UC Workflow Diagram: Immediate Gross Settlement + +## Canonical Model + +- Account + - accountId + - ledgerAccountType + - ledgerAccountState + - debitLimit + - creditLimit + - debitBalance + - creditBalance +- Journal Entry + - journalEntryId + - debitAccountId + - creditAccountId + - journalEntryType + - transferAmount + - transferTimestamp + + + + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png new file mode 100644 index 000000000..8e5c8c2d9 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png new file mode 100644 index 000000000..c2392091e Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png new file mode 100644 index 000000000..67bb2b3b0 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png new file mode 100644 index 000000000..6ec6a7dd0 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/auditing/assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/auditing/index.md b/docs/technical/reference-architecture/boundedContexts/auditing/index.md new file mode 100644 index 000000000..76b8654c8 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/auditing/index.md @@ -0,0 +1,67 @@ +# Auditing BC + +The Auditing BC is responsible for maintaining an immutable record of all of the transactions that take place on the Switch. The Architecture comprises of five main components: + +* Central Forensic Logging Service +* Services +* Immutable Datastore +* Key Management System +* Cryptographic[^1] Provider Modular + +Authorized users are able to interrogate the Auditing BC via an Operation API exposed for this purpose for details of audit-worthy events. + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|---|---| +| **KMS** | Key Management System - Provides encryption/decription and Certificate Authority services to the Switch environment (issue, sign, and verification via the Security BC) | +| **CPM** | Crypto Provider Module - Manages the cryptographic techniques and methodologies employed by the Switch to provide end-to-end encryption and decryption services for any stored or transmitted data. | + +## Functional Overview + +![Use Case - Auditing System Functional Overview](./assets/ML2RA_Audit_bcFunctionalOverview_Mar22_1450.png) +> BC Functional Diagram: Auditing Systen Functional Overview + +## Use Cases + +### Auditing BC Startup + +#### Description + +The Auditing BC Startup UC is triggered during startup (intervals or events) and fetches all of the Public Keys in use by the various Switch Participant BCs from the Security BC that provide KMS services for all of the participant BCs of the Switch. + +#### Flow Diagram + +![Use Case - Auditing BC Startup](./assets/ML2RA_Audit_ucAuditingBCStartup_Mar22_1450.png) +> UC Workflow Diagram: Auditing BC Startup + +### Sync/RPC Audit + +#### Description + +The Sync/RPC Audit UC is activated for audit-worthy events triggered during a transaction noted by a participating BC. The participating BC proceeds to notify the Audit BC via a synchronous RPC audit call. The Audit entry is locally signed by the notifying BC. Upon receipt, the Audit BC runs through a number of procedures that include running though a KMS procedure with the Security BC, and persisting the record to an Append-only Store. + +#### Flow Diagram + +![Use Case - Sync/RPC Audit](./assets/ML2RA_Audit_ucSyncRPCAudit_Mar22_1450.png) +>UC Workflow Diagram: Sync/RPC Audit + +### Event Based Audit + +#### Description + +The Event Based Audit UC is triggered when a participating BC includes local auditing capability, notes an audit-worthy event, and creates a locally signed audit event, which it publishes, and then pushes either a single Event or an Event-batch to the Auditing BC. The Event is validated during a procedure with the Security BC, and persisted to the Append-Only Store. + +#### Flow Diagram + +![Use Case - Event Based Audit](./assets/ML2RA_Audit_ucEventBasedAudit_Mar22_1450.png) +> UC Workflow Diagram: Event Based Audit + + +## Notes + +[^1]: Cryptographic refers to algorithmic techniques and methodologies that are employed by systems to prevent unauthorised systems or persons from accessing, identifying, or using stored data. For further reading please refer to the accompanying Wikipedia article: [Cryptography, From Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Cryptography) + +[^2]: Common Interfaces: [Mojaloop Common Interface List](../../refarch/commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/commonInterfaces/index.md b/docs/technical/reference-architecture/boundedContexts/commonInterfaces/index.md new file mode 100644 index 000000000..f27949892 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/commonInterfaces/index.md @@ -0,0 +1,151 @@ +# Common Interface List + +The Common Interface List includes a list of all of the common interfaces that are in use in the Mojaloop 2.0 Reference Architecture presently. Common Interfaces are used by several Bounded Contexts, hence the name. + +Each Common Interface listed includes the following information: source or publisher event name or endpoint, communications style, publisher/provider Bounded Context, a description of the interface function, and a checklist of Bounded Contexts where it is being used. + +## Common Interfaces + +| Event name OR endpoint | Comms Style | Publisher/Provider BC | Description | FSP Interop API BC | Admin/Operation API BC | Participant Lifecycle Management BC | Transfers BC | Accounts & Balances BC | Settlements BC | Account Lookup BC | Agreements / Quotes BC | 3rd Party Initiated Payments | Notifications & Alerts BC | Scheduling BC | Auding BC | Security - authZ BC | Security - authN BC | Security - auditing BC | Security - loging BC | Security - crypto BC | +|------------------------------------------------------|-------------|-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|------------------------|-------------------------------------|--------------|------------------------|----------------|-------------------|------------------------|------------------------------|---------------------------|---------------|-----------|---------------------|---------------------|------------------------|----------------------|----------------------| +| TransferCommittedFulfiled | Event | Transfers BC | Transfer Committed event indicating the final outcome of the Transfer Commited stage of a transfer has been processed by the Transfers BC | x | | x | | | | | | | | | | | | | | | +| LiquidityThresholdExceeded | gRPC | Transfers BC | An event thrown when a given participant's liquidity threshold is exceeded and a action should be taken | | | X | | | | | | | | | | | | | | | +| TransferPrepared | Event | Transfers BC | Transfer Prepared event indicating the final outcome of the Transfer Prepare stage of a transfer has been processed by the Transfers BC | x | | | | | | | | | | | | | | | | | +| TransferQueryResponse | Event | Transfers BC | Event containing response as a result of a TransferQueryReceived event | x | | | | | | | | | | | | | | | | | +| TransferRejectRequestProcessed | Event | Transfers BC | Event confirming that a Transfer Reject request was processed by the Transfers BC | x | | | | | | | | | | | | | | | | | +| TransferPrepareRequestTimedout | Event | Transfers BC | Event for a Transfer Timeout when a transfer was still being prepared. | x | | | | | | | | | | | | | | | | | +| TransferFulfilComitRequestTimedout | Event | Transfers BC | Event for a Transfer Timeout when a transfer was in a final prepared state (i.e. waiting for a fulfilment, or rejection to be reveived). | x | | | | | | | | | | | | | | | | | +| TransferPrepareDuplicateCheckFailed | Event | Transfers BC | Event representing a failed duplicate check validation failure as a result of processing a TransferPrepareAccountAllocated event. | x | | | | | | | | | | | | | | | | | +| TransferPrepareLiquidityCheckFailed | Event | Transfers BC | Event representing a failed liquidity check validation failure as a result of processing a TransferPrepareAccountAllocated event. | x | | | | | | | | | | | | | | | | | +| TransferPrepareInvalidPayerCheckFailed | Event | Transfers BC | Event representing a failed Payer Participant check validation failure as a result of processing a TransferPrepareAccountAllocated event. | x | | | | | | | | | | | | | | | | | +| TransferPrepareInvalidPayeeCheckFailed | Event | Transfers BC | Event representing a failed Payee Participant check validation failure as a result of processing a TransferPrepareAccountAllocated event. | x | | | | | | | | | | | | | | | | | +| TransferPrepareAccountsAllocated | Event | Settlements BC | Transfer Prepare request event with enriched information containing the applicable accounts for liquidity validation/allocation for each participant | | | | x | | | | | | | | | | | | | | +| /random-number-gen | Event | Security BC - crypto | random number generator. Can be used to generate (1) id (2) secret and (3) FIDO challenge | x | x | | | | | | | | | | | x | x | | | x | +| /hash-gen | HTTP/Rest | Security BC - crypto | Hash generation. Can be used to hash random numbers and user info. Hash is used for basic authentication and signature verification. | x | x | | | | | | | | | | | x | x | | | x | +| /signature-gen | HTTP/Rest | Security BC - crypto | generate signature. used to sign audit records for immutability. | | | | | | | | | | | | x | x | x | x | x | | +| /signature-ver | HTTP/Rest | Security BC - crypto | verify siganture. used for FIDO authentication and authorization. This is also used to validate audit record on retrieval. | x | x | | | | | | | | | | x | x | x | x | x | | +| /encrypt | HTTP/Rest | Security BC - crypto | generic encryption | | | | | | | | | | | | x | | | x | x | x | +| /decrypt | HTTP/Rest | Security BC - crypto | generic decryption | | | | | | | | | | | | x | | | x | x | x | +| /pin-translation | HTTP/Rest | Security BC - crypto | translate banking PIN block from one encryption zone to another. Can be used for Interbank ATM or POS transaction. | | | | | | | | | | | | | | | | | x | +| /fido-register | HTTP/Rest | Security BC - crypto | Composite Crypto function. stores authenticator ECC public key alongside user infor. | x | x | | | | | | | | | | | | | | | | +| /fido-authenticate | HTTP/Rest | Security BC - crypto | authenticate FIDO signature | x | x | | | | | | | | | | | | | | | | +| /fido-authorize | HTTP/Rest | Security BC - crypto | authorize FIDO transaction after gesture (pressed button, finger print, etc) | x | x | | | | | | | | | | | | | | | | +| /kms-key-definition | HTTP/Rest | Security BC - crypto | cryptographic key definition (key usage, duration, label) | | | | | | | | | | | | | | | | | x | +| /kms-aes-key-gen | HTTP/Rest | Security BC - crypto | Cryptographic key generation for symetric encryption | | | | | | | | | | | | | | | | | x | +| /kms-ecc-key-gen | HTTP/Rest | Security BC - crypto | Cryptogrphic key generation for Eliptic Curve key pair generation. | | | | | | | | | | | | | | | | | x | +| /crypto-adapter-set | HTTP/Rest | Security BC - crypto | Cryptographic Provider/adapter set (AWS, AZURE, on-prem HSM, software local libraries ... etc) | | | | | | | | | | | | | | | | | x | +| /iam-token-verifty | HTTP/Rest | Security BC - crypto | basic authentication token verification. Composite call to AIM adapter. | x | x | | x | | | | | | | | | | | | | x | +| /kms-pem-gen | HTTP/Rest | Security BC - crypto | PKI keys for client authention and CLI functions. | x | x | | | | | | | | | | | | | | | x | +| /ssl-terminate | HTTP/Rest | Security BC - crypto | SLL termination | | | | | | | | | | | | | | | | | x | +| /kms-load-key | HTTP/Rest | Security BC - crypto | load cryptographic keys in key store | | | | | | | | | | | | | | | | | x | +| /app-authorize | HTTP/Rest | Security BC - authZ | Calls AuthZ BC to verify the authorization token. This also calls IAM function to verify roles. | x | x | | | | | | | | | | | x | | | | x | +| /app-fido-authorize | HTTP/Rest | Security BC - authZ | Calls Cyrpto BC to authorize transaction | x | x | | | | | | | | | | | | | | | x | +| /app-pem-auth | HTTP/Rest | Security BC - authZ | Uses PKI private and public key to authenticate APIs calls. uses the user IAM profile (user info + role) to auhorize. | | | | | | | | | | | | | | x | | | x | +| /app-basic-auth | HTTP/Rest | Security BC - authN | Calls AuthZ BC to verify id and secret. Returns authorization token | x | x | | | | | | | | | | | | x | | | x | +| CreateScheduleReminder | gRPC | Scheduling BC | Create a schedule reminder with the necessary information to create a event or api callback once the reminder has elapsed | | | | x | | | | | | | | | | | | | | +| DeleteScheduleReminder | gRPC | Scheduling BC | Event indicating that a timeout has occured for a scheduled reminder | | | | x | | | | | | | | | | | | | | +| POST /config/schemas/ | HTTP/Rest | Platform Configuration | (upsert) To publish the initial or new versions of a BC configuration managment object schema at bootstrap - includes version number | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/schemas/ | HTTP/Rest | Platform Configuration | To get schema and current configurations of a all bounded contexts | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/schemas/:boundedContextId | HTTP/Rest | Platform Configuration | To get schema and current configurations of a specifric bounded context | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| ConfigurationValuesChanged | Event | Platform Configuration | Event sent when changes happend on a configuration - should include at least the bounded context ID, maybe the key names with changed values | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| POST /config/schemas/:boundedContextId | HTTP/Rest | Platform Configuration | To publish the initial or new versions of a BC configuration managment object schema at bootstrap - includes version number | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| POST /config/secrets/ | HTTP/Rest | Platform Configuration | (upsert) To publish the list of expected secrets (keys) a bounded context requires to operate - send at bootstrap - includes version number | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/ | HTTP/Rest | Platform Configuration | To a list of secret keys each BC needs to operate - from all bounded contexts | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/:boundedContextId | HTTP/Rest | Platform Configuration | To a list of secret keys each BC needs to operate - from a specifric bounded context | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| GET /config/secrets/:boundedContextId/values | HTTP/Rest | Platform Configuration | This call can only be performed by the owner bouded context (verify sig) and should return the secrets along with the keys for that bounded context | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| SecretsValuesChanged | Event | Platform Configuration | Event sent when changes happend on a secret - should include at least the bounded context ID, maybe the key names with changed secrets | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | +| UpdateParticipantAccountThreshold | gRPC | Participant Lifecycle Management BC | Updates the thresholds of the accounts specified | | | | | X | | | | | | | | | | | | | +| GetParticipantsTransfersData | gRPC | Participant Lifecycle Management BC | Query Service to attain Participant information for Transfer purposes (i.e. validations, etc) | | | | x | | | | | | | | | | | | | | +| GetParticipantCallbackInfo | gRPC | Participant Lifecycle Management BC | API to query Participant information for Callbacks. Example of the FSPIOP Interop APIs BC using this to query the necessary information required for it to produce a NotifyRequested event. | x | | | | | | | | | | | | | | | | | +| GetParticipantQuoteData | gRPC | Participant Lifecycle Management BC | Query Service to attain Participant information for Quote purposes (i.e. validations, etc) | | | | | x | | | | | | | | | | | | | +| CreateParticipant | HTTP/Rest | Participant Lifecycle Management BC | Request to create a new participant with a single payload defining ALL the relevant details of the Participant | | X | | | | | | | | | | | | | | | | +| GetPendingParticipants | HTTP/Rest | Participant Lifecycle Management BC | Retrieves all the participants that are in the PEND-APPROVAL state, i.e. Participants that have not yet been approved or rejected | | X | | | | | | | | | | | | | | | | +| ApproveParticipant | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant that is in a state of pending approval | | X | | | | | | | | | | | | | | | | +| CreateParticipantAccountsWithLimits | gRPC | Participant Lifecycle Management BC | Notify that the participant has been created and subsequint accounts with limits be created aswell | | | | | X | | | | | | | | | | | | | +| ParticipantCreated | Event | Participant Lifecycle Management BC | Notifies that the participant has been created, accounts and limis included. | | | | | | X | | | | | | | | | | | | +| ManageFunds | HTTP/Rest | Participant Lifecycle Management BC | Call to either Withdraw or Deposit funds. | | X | | | | | | | | | | | | | | | | +| GetPendingManageFunds | HTTP/Rest | Participant Lifecycle Management BC | Request all manage funds requests that have to be approved | | X | | | | | | | | | | | | | | | | +| ApproveManageFunds | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Deposit or withdraw request | | X | | | | | | | | | | | | | | | | +| ManageFundsCreditDebitPairInstruction | gRPC | Participant Lifecycle Management BC | Update the accounting with the relevant credit and debit entries. | | | | | X | | | | | | | | | | | | | +| ReserveLiquidityCover | HTTP/Rest | Participant Lifecycle Management BC | Request to reserve an amount of liquidity cover either a value or a % | | X | | | | | | | | | | | | | | | | +| GetPendingLiquidityCoverReservations | HTTP/Rest | Participant Lifecycle Management BC | Get LiquidityCover requests that are currently awaiting approval | | X | | | | | | | | | | | | | | | | +| ApproveLiquidityCoverReservation | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Liquidity Cover Reservation | | X | | | | | | | | | | | | | | | | +| UpdateParticipantState | HTTP/Rest | Participant Lifecycle Management BC | Request to change the current state of a given participant | | X | | | | | | | | | | | | | | | | +| GetPendingStateUpdates | HTTP/Rest | Participant Lifecycle Management BC | Gets all partacipants with status change requests that are pending approval | | X | | | | | | | | | | | | | | | | +| ApproveParticipantStateUpdate | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant state change | | X | | | | | | | | | | | | | | | | +| ParticipantStateUpdated | gRPC | Participant Lifecycle Management BC | Notify BC's that the state of a participant has changed | | | | X | | X | | | | X | | | X | X | X | X | | +| ParticipantLiquidityThresholdExceeded | Event | Participant Lifecycle Management BC | A notification should be sent that a given participant's liquidity threshold is exceeded. | | | | | | | | | | X | | | | | | | | +| AddParticipantAccount | HTTP/Rest | Participant Lifecycle Management BC | Request to create a new account for a given participant | | X | | | | | | | | | | | | | | | | +| GetPendingParticipantsAccounts | HTTP/Rest | Participant Lifecycle Management BC | Gets all participants and accounts that require approval to be created | | X | | | | | | | | | | | | | | | | +| ApproveParticipantAccount | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant account create request | | X | | | | | | | | | | | | | | | | +| CreateParticipantAccountWithLimits | gRPC | Participant Lifecycle Management BC | Creates the relevant accounts within the Accounts and Balances BC | | | | | X | | | | | | | | | | | | | +| ParticipantAccountAdded | Event | Participant Lifecycle Management BC | Event to notify that the participant account has been created | | | | | | X | | | | | | | | | | | | +| UpdateAccountStatus | HTTP/Rest | Participant Lifecycle Management BC | Request to either enable or disable the participant's account based on the information passed | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithStatusUpdates | HTTP/Rest | Participant Lifecycle Management BC | Get all accounts that are pending approval for a status change | | X | | | | | | | | | | | | | | | | +| ApproveAccountStatusUpdate | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant account status change | | X | | | | | | | | | | | | | | | | +| Enabled/DisabledParticipantAccount | gRPC | Participant Lifecycle Management BC | Either enables or disables the account based on the information passed | | | | | X | | | | | | | | | | | | | +| ParticipantAccountEnabled | Event | Participant Lifecycle Management BC | Notify that a participant's account has been enabled | | | | | | X | | | | | | | | | | | | +| ParticipantAccountDisabled | Event | Participant Lifecycle Management BC | Notify that a participant's account has been disabled | | | | | | X | | | | | | | | | | | | +| UpdateAccountLimit | HTTP/Rest | Participant Lifecycle Management BC | Request to update the limits on a given participant's account | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithLimitUpdates | HTTP/Rest | Participant Lifecycle Management BC | Get all accounts with pending updates to the limits | | X | | | | | | | | | | | | | | | | +| ApproveAccountLimitUpdate | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Update account limit request | | X | | | | | | | | | | | | | | | | +| UpdateParticipantAccountLimit | gRPC | Participant Lifecycle Management BC | Update the limits on a given participant's account | | | | | X | | | | | | | | | | | | | +| ParticipantAccountLimitUpdated | Event | Participant Lifecycle Management BC | Event to notify that the participant account's limit has been created | | | | | | X | | | | | | | | | | | | +| UpdateAccountThreshold | HTTP/Rest | Participant Lifecycle Management BC | Request to update the threshold for a given participant account | | X | | | | | | | | | | | | | | | | +| GetPendingAccountsWithThresholdUpdates | HTTP/Rest | Participant Lifecycle Management BC | Get all the accounts with pending threshold updates | | X | | | | | | | | | | | | | | | | +| ApproveAccountThresholdUpdate | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant account threshold update | | X | | | | | | | | | | | | | | | | +| ParticipantAccountThresholdUpdated | Event | Participant Lifecycle Management BC | Event to notify that the accounts' threshold was updated | | | | | | X | | | | | | | | | | | | +| UpdateEndpoints | HTTP/Rest | Participant Lifecycle Management BC | Request to update the endpoints of a given participant | | X | | | | | | | | | | | | | | | | +| GetPendingEndpointUpdates | HTTP/Rest | Participant Lifecycle Management BC | Gets all the participant endpoint update requests that are pending approval | | X | | | | | | | | | | | | | | | | +| ApproveEndpointsUpdate | HTTP/Rest | Participant Lifecycle Management BC | Approve OR Reject - Participant Endupoint Update | | X | | | | | | | | | | | | | | | | +| ParticipantEndpointsUpdated | Event | Participant Lifecycle Management BC | An event to notify that the Participant's endpoint have been updated | | | | X | X | X | X | X | X | | | | | | | | | +| GetParticipantInfo | gRPC | Participant Lifecycle Management BC | Gets all information regarding to a given Participant | X | | | | | | X | X | X | | | | | | | | | +| GetParticipantInfo | HTTP/Rest | Participant Lifecycle Management BC | Gets all information regarding to a given Participant | | X | | | | | | | | | | | | | | | | +| GetLiquidityCoverCurrentState | HTTP/Rest | Participant Lifecycle Management BC | Request to get the current state of liquidity cover | | X | | | | | | | | | | | | | | | | +| NotifyReport | Event | Notifications & Alerts BC | Notification Report event containing a report of the notification, indicating if it was successful (with an applicable response from the destination) or failed with an applicable error/reason | | | | x | | | | | | | | | | | | | | +| /log-read-build-log | HTTP/Rest | Logging BC | log consumer. provides endpoint for applications write log topic. Building logs | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /read-log | HTTP/Rest | Logging BC | read logs. Optionally calls Crypto BC to decrypt and or verify siganture | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| NotifyRequested | Event | FSP Interop API BC | Notification Request event containing the FSPIOP forwarding request or callback that will be send to a specific participant | | | | x | | | | | | | | | | | | | | +| TransferPrepareRequested | Event | FSP Interop API BC | Transfer Prepare request event | | | | | | x | | | | | | | | | | | | +| TransferPrepareCallbackReport | Event | FSP Interop API BC | Transfer Prepare Callback report for the Payee participant | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommittedRequested | Event | FSP Interop API BC | Transfer Fulfilment request event indicating that a "commit" was processed by the Payee participant | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommittedCallbackReport | Event | FSP Interop API BC | Transfer Fulfil Callback report for the Payer/Payee participant | | | | x | | | | | | | | | | | | | | +| TransferQueryReceived | Event | FSP Interop API BC | Event indicating containing information for a Transfer Query | | | | x | | | | | | | | | | | | | | +| TransferQueryResponseCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Query Response callback a Participant participant | | | | x | | | | | | | | | | | | | | +| TransferRejectRequested | Event | FSP Interop API BC | Event for a Transfer Reject from a Payee participant | | | | x | | | | | | | | | | | | | | +| TransferRejectRequestProcessedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Reject Response callback to a Payer participant | | | | x | | | | | | | | | | | | | | +| TransferPrepareRequestTimedoutCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Timeout Response callback to a Payer participant | | | | x | | | | | | | | | | | | | | +| TransferFulfilCommitRequestTimedoutCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Timeout Response callback to a Payer/Payee participants | | | | x | | | | | | | | | | | | | | +| TransferPrepareDuplicateCheckFailedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Prepare Duplicate Check Failed Response callback to a Payer/Payee participants | | | | x | | | | | | | | | | | | | | +| TransferPrepareLiquidityCheckFailedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Prepare Liquidity Check Failed Response callback to a Payer/Payee participants | | | | x | | | | | | | | | | | | | | +| TransferPrepareInvalidPayerCheckFailedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Payer Participant Check Failed Response callback to a Payer/Payee participants | | | | x | | | | | | | | | | | | | | +| TransferPrepareInvalidPayeeCheckFailedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Transfer Payee Participant Check Failed Response callback to a Payer/Payee participants | | | | x | | | | | | | | | | | | | | +| QuoteRequestReceived | Event | FSP Interop API BC | Event containing a Quote Request from a Payer participant | | | | | | | | x | | | | | | | | | | +| QuoteReceivedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Quote Request to a Payee participants | | | | | | | | x | | | | | | | | | | +| QuoteResponseReceived | Event | FSP Interop API BC | Event containing a Quote Request Response from a Payee participant | | | | | | | | x | | | | | | | | | | +| QuoteAcceptedCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Quote Respose to a Payer participants | | | | | | | | x | | | | | | | | | | +| InvalidQuoteRequestCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Invalid Quote Request to a Payer participants | | | | | | | | x | | | | | | | | | | +| InvalidFSPInQuoteRequestCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Invalid FSP in Quote Request to a Payer participants | | | | | | | | x | | | | | | | | | | +| RuleViolatedInQuoteRequestCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Rule Violated in Quote Request to a Payer participants | | | | | | | | x | | | | | | | | | | +| RuleViolatedInQuoteResponseCallbackReport | Event | FSP Interop API BC | Event containing callback response report for a Rule Violated in Quote Response to a Payer participants | | | | | | | | x | | | | | | | | | | +| /app-fido-register | HTTP/Rest | FSP Interop API BC | Calls Cyrpto BC to register user | x | x | | | | | | | | | | | | | | | x | +| /audit-log-write | Event | Auditing BC | Writes audit entries into Kafka audit topic. Consumer calls Crypto BC to encrypt and / or sign logging records. | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /audit-read-build-audit-log | HTTP/Rest | Auditing BC | audit consumer. provides endpoint for applications write audit topic. Building logs | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| /read-audit-log | HTTP/Rest | Auditing BC | read audit logs. calls Crypto BC to decrypt and or verify siganture | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | +| QuoteRequestAccepted | Event | Agreements/Quotes BC | Event for a Quote Request being processed by the Transfers BC | x | | | | | | | | | | | | | | | | | +| QuoteResponseAccepted | Event | Agreements/Quotes BC | Event for a Quote Response being processed by the Transfers BC | x | | | | | | | | | | | | | | | | | +| InvalidQuoteRequest | Event | Agreements/Quotes BC | Event representing a quote validation failure as a result of processing a QuoteReuestReceived event. | x | | | | | | | | | | | | | | | | | +| InvalidFSPInQuoteRequest | Event | Agreements/Quotes BC | Event representing an invalid FSP in Quote Request failure as a result of processing a QuoteReuestReceived event. | x | | | | | | | | | | | | | | | | | +| RuleViolatedInQuoteRequest | Event | Agreements/Quotes BC | Event representing an Rule Violated in Quote Request failure as a result of processing a QuoteReuestReceived event. | x | | | | | | | | | | | | | | | | | +| RuleViolatedInQuoteResponse | Event | Agreements/Quotes BC | Event representing an Rule Violated in Quote Response failure as a result of processing a QuoteReuestReceived event. | x | | | | | | | | | | | | | | | | | +| /app-register | HTTP/Rest | Admin/Operation API BC | Calls Crypto BC to obtain id and secret | x | x | | | | | | | | | | | | x | | | x | +| GetLiquidityCoverHistory | HTTP/Rest | Admin/Operation API BC | Request the account position history | | X | | | | | | | | | | | | | | | | +| GetReservations | HTTP/Rest | Admin/Operation API BC | Request the reservations | | X | | | | | | | | | | | | | | | | +| GetCurrentLiquidityPosition | gRPC | Accounts & Balances BC | Get the current liquidity position for validation to update liquidity cover reservastion | | | X | | | | | | | | | | | | | | | +| RecordLiquidityReservationEntries | gRPC | Accounts & Balances BC | Records the relevant entries for the liquidity cover reservations | | | X | | | | | | | | | | | | | | | +| RequestAccountsPositions | gRPC | Accounts & Balances BC | Get account positions for a given participant | | | X | | | | | | | | | | | | | | | +| RequestAccountPositionHistory | gRPC | Accounts & Balances BC | Get accounts position history for a given participant | | | X | | | | | | | | | | | | | | | +| RequestReservationAccounts | gRPC | Accounts & Balances BC | Request the accounts related to reservations' | | | X | | | | | | | | | | | | | | | +| ProcessTransferPrepare | gRPC | Accounts & Balances BC | Process Transfer Prepare request for debiting the Payer liquidity, and crediting the Payer position via reservation of funds | | | | x | | | | | | | | | | | | | | +| ProcessTransferFulfil | gRPC | Accounts & Balances BC | Process Transfer Fulfil request for debiting the Payer reserved funds, and crediting the Payee liquidity | | | | x | | | | | | | | | | | | | | + | /log-write | Event | | Writes log entries into Kafka logging topic. Consumer optionally calls Crypto BC to encrypt and / or sign logging records. | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | diff --git a/docs/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md b/docs/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md new file mode 100644 index 000000000..d188a1d1e --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/commonTermsConventions/index.md @@ -0,0 +1,19 @@ +# Common Terms and Conventions Used + +The Reference Architecture Team have made use of Common Terms and Conventions throughout the design and documentation for the Mojaloop 2.0 Reference Architecture model.

    Please make use of this list to familiarise yourself with any terms that may be unfamiliar, or forgotten. The list includes references to third-party reference articles and documents that are listed in the Further Reading section of this document. + +| **Convention/Term** | **Description** | +| :------------------------ | :-------------------------- | +| **Actors** | Human or external system Use Case participant. All Use Cases are driven by Actors.| +| **BC** | Bounded Context: A bounded-context is a component of Design-Driven Development and typically contains a single, or multiple subdomains. Bounded Contexts are Solution Space entities, and contain a single solution applicable to a single, or multiple, subdomain/s.

    (*For additional insights, please see: [DDD Inspired Architecture Overview](../../introduction/#ddd-inspired-architecture-overview) section in the Solution Space overview, or our [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents)*)| +| **UC** | Use Case: A Use Case is a list of actions or steps describing interactions between an Actor (human or external system) and a system to achieve a particular objective. An example of a Use Case from Mojaloop is "Perform Transfer with Payee Confirmation".

    (*For additional insights, please see the "Use Case", Wikipedia article reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **Sync** | Synchronous communications, one or two way, part of the originating process. Signified by a solid line in the UC schematics. Typically used for Messages that need to be included in a particular UC workflow in order for it to execute successfully. An example of synch Messaging is a query from the Transfers BC to the Participant Lifecycle Management BC to get Participant data if not cached to complete a Transfer request.| +| **Async** | Asynchronous communications, one or two way, not part of the originating process. Signified by a dotted line in the UC schematics. Typically used for Events which are used to indicate something that has happened, and is immutable and won't change, for example callback reports.| +| **POST** | Utilized to create new resources. In particular, it's used to create subordinate resources. That is, subordinate to some other (e.g. parent) resource. IOW, when creating a new resource, POST to the parent and the service takes care of associating the new resource with the parent, assigning an ID (new resource URI), etc. On successful creation, the system will return a Location header with a link to the newly-created resource with the 201 HTTP status.

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **GET** | Utilized to read (or retrieve) a representation of a resource. In the "happy" (or non-error) path, GET returns a representation in XML or JSON and an HTTP response code of 200 (OK). In an error case, it most often returns a 404 (NOT FOUND) or 400 (BAD REQUEST).

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **PUT** | Utilized for update capabilities, PUT-ing to a known resource URI with the request body containing the newly-updated representation of the original resource. In some instances PUT can also be utilized to create new resources, however owing to complexity, this is not recommended (POST should be used instead).

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **200 (OK)** | HTTP Status code indicating "Success". The request has succeeded. Typically the information returned with the status code is dependent upon the method used in the request. For example, in Mojaloop the methods most commonly used are POST, GET, PUT. For POST, the response would describe or include the result of the action, for GET the requested entity is sent in the response, and for a PUT request, the response would be similar to a POST request.

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **201 (Created)** | HTTP Status code indicating "Created" or fulfilled. This means that the request has been fulfilled and that the new resource is accessible via the URI returned in the entity response. The origin server will create the resource before returning a 201 code, and if it is not able to do so immediately, will return a 202 (Accepted) instead.

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **202 (Accepted)** | HTTP Status code indicating that a request has been accepted for processing, but has not been completed. The request may or may not be acted upon when system allows as it may be disallowed when processing occurs. As the operation is asynchronous, there is also not facility for resending the status code, regardless of outcome. The 202 response is deliberately non-committal to enable a request to be processes without requiring the agent to remain connected until such time as it does. The response should include an indication of system status, and either a pointer to a monitoring platform, or an indication of when the request will be acted upon.

    (*For additional insights, please see the "Restful API Tutor", document reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **OHS** | Open Host Service: Describes documentation of methods to employ to successfully integrate downstream systems into an existing upstream system without requiring any mods to be made to the upstream platform. Typically support is provided for multiple client-types, and will have no particular interest in specific clients. The downstream system will be required to understand the upstream published documentation. OHS and PL are commonly paired by upstream systems.

    Currently utilized in the following entities: FSPIOP External API; ISO External API; Notifications & Alerts BC; PISP ML External API; PISP ISO External API; Scheduling BC; Transfers & Transactions BC; Agreement (Quoting) BC; Accounts & Balances BC; Settlements BC; Participant Lifecycle Management; Account Lookup & Discovery BC)

    (*For additional insights, please see the "Strategic Domain-Driven Design", article reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*)| +| **PL** | Published Language: Described as the closest relative to open host service and often used together. PL uses a documented language, for example XML, for basic I/O operations to the system for which it is being utilized. No particular library or implementation spec is required for connecting to the system provided one conforms to the published language. It is not necessary to run only web services with a Published Language. One can also do things like upload a file to a particular folder, which then triggers an operation that stores the content of the file at an application specified location.

    Currently utilized in the following entities: FSPIOP External API; ISO External API

    (*For additional insights please see the "Strategic Domain-Driven Design", article reference in the [Further Reading: Reference Articles and Documents](../../furtherReading/#reference-articles-and-documents) section of this document*))| diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg new file mode 100644 index 000000000..887629575 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-0-notifications.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg new file mode 100644 index 000000000..e48567cd4 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-0-functional-overview.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg new file mode 100644 index 000000000..a2568a5ac Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-1-party-participant-associate.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg new file mode 100644 index 000000000..061048844 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-2-party-participant-disassociate.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg new file mode 100644 index 000000000..4bc8cc587 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-3-get-participant.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg new file mode 100644 index 000000000..55fcff12a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/0-4-get-party.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg new file mode 100644 index 000000000..4914c1d68 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-1-calculate-quote-happy-path.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg new file mode 100644 index 000000000..b5c5b3316 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-2-get-quote-happy-path.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg new file mode 100644 index 000000000..cfb317673 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-3-calculate-quote-invalid-quote-request.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg new file mode 100644 index 000000000..5b67c0f66 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-4-calculate-quote-invalid-fsps.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg new file mode 100644 index 000000000..d581b8c66 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg new file mode 100644 index 000000000..a9c4f9a77 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg new file mode 100644 index 000000000..3b467d937 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-1-perform-transfer-universal-mode.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg new file mode 100644 index 000000000..29c57e3e6 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-10-perform-transfer-duplicate-none-matching.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg new file mode 100644 index 000000000..26163264b Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg new file mode 100644 index 000000000..4183a0928 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-12-perform-transfer-prepare-rejected.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg new file mode 100644 index 000000000..b53949758 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg new file mode 100644 index 000000000..13a4f7c4a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg new file mode 100644 index 000000000..245172f56 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-2-perform-transfer-payee-confirmation.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg new file mode 100644 index 000000000..27f9b5405 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-3-query-get-transfer.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg new file mode 100644 index 000000000..ef3cfc3dc Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-4-perform-transfer-duplicate-post.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg new file mode 100644 index 000000000..a7a8cdabd Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-5-perform-transfer-duplicate-post-ignor.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg new file mode 100644 index 000000000..f08f8c2fc Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg new file mode 100644 index 000000000..f21f280b7 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-7-perform-transfer-timeout-prepare.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg new file mode 100644 index 000000000..118dbdb1f Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-8-perform-transfer-timeout-pre-committed.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg new file mode 100644 index 000000000..1f88fa39b Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/assets/2-9-perform-transfer-timeout-post-commit.jpg differ diff --git a/docs/technical/reference-architecture/boundedContexts/fspInteropApi/index.md b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/index.md new file mode 100644 index 000000000..8e275f1dc --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/fspInteropApi/index.md @@ -0,0 +1,377 @@ +# FSP Interoperability API BC + +The FSP Interoperability API Bounded Context provides access to the internal operations and resources that the Mojaloop Ecosystem provides to a given Participant. This Bounded Context is responsible for providing a Participant with interfaces whit which the Participant can perform and execute tasks on Mojaloop. It is also responsible for providing communication back to the Participant regarding different notifications and system messages that a participant should expect to receive. + +## Functional Overview + +The FSP IOP API interacts with many different bounded contexts and thus the simplified view is provided here, for further reading on the events and connections that the FSP IOP API provides and consumes please review the Mojaloop Common Interfaces [^1]. The bounded contexts that are integrated with the FSP IOP API are: + +- Account Lookup & Discovery Bounded Context [^14] +- Notifications and Alerts Bounded Context [^27] +- Participant Lifecycle Management Bounded Context [^26] +- Quoting\Agreement Bounded Context [^19] +- Transfers Bounded Context [^22] +- Settlement Bounded Context [^21] + +![Use Case - FSP Interoperability API Functional Overview](./assets/0-0-functional-overview.jpg) + +> FSP Interoperability API Functional Overview + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **(D)FSP** | (Digital) Financial Service Provider | +| **Participant** | Financial Service Provider (FSP) that has registered on the Mojaloop ecosystem. Allowing said FSP to be able to transact with other Participants | +| **FSP IOP API** | Financial Service Provider Interoperability Application Programming Interface, the API that provides access to functions and features of the Mojaloop Ecosystem. | +| **Payer** | The payer of electronic funds in a payment transaction. | +| **Payer FSP** | Payer's Financial Service Provider. | +| **Payee** | The recipient of electronic funds in a payment transaction. | +| **Payee FSP** | Payee's Financial Service Provider. | + +## Use Cases + +### Note + +Use case definitions stipulated in the Open API for FSP Interoperability Specification [^2] have not been altered, and thus the Reference Architecture has been designed to only change the background orchestration of the internal Mojaloop services and Bounded Contexts. + +### Notifications BC - Send Notification + +#### Description + +Notifications pertain to ALL below use cases as a response to requests received in various forms. While the FSP IOP API is busy processing a request received, it might need to sends a request to the requesting DFSP or any other relevant DFSPs. The FSP IOP API will then query the Participant Lifecycle Management Bounded Context [^26] for the Callback URIs for the given participant that the notification needs to be sent to. The FSP IOP API will then send the notification request to the Notification and Alerts Bounded Context [^27]. + +#### Flow Chart + +![Use Case - Notifications BC - Send Notification](./assets/0-0-0-notifications.jpg) + +> + +## Account Lookup & Discovery BCs + +### Party/Participant Associate + +#### Description + +Associate transfer/s Participant/s and/or parties based on the POST Participant request [^5] (POST /participants/{Type}/{ID}). The FSP IOP API then sends a request to the Account Lookup & Discovery BC [^14] which will process the request and respond with a success event. The FSP IOP API then sends a notification PUT Participant response [^15] (PUT /participants/{Type}/{ID}). + +#### Flow Diagram + +![Use Case - Account Lookup & Discovery BC - Party/Participant Associate](./assets/0-1-party-participant-associate.jpg) + +> + +### Party/Participant Disassociate + +#### Description + +Disassociate Participant/s and/or parties based on the DELETE Participant request [^6] (DELETE /participants/{Type}/{ID}). The FSP IOP API sends the request to the Account Lookup & Discovery BC [^14] to disassociate the party. The success response is then received by the FSP IOP API and then responds to the caller by sending a notification PUT Participant response [^15] (PUT /participants/{Type}/{ID}). + +#### Flow Diagram + +![Use Case - Account Lookup & Discovery BC - Party/Participant Disassociate](./assets/0-2-party-participant-disassociate.jpg) + +> + +### Get Participant + +#### Description + +Retrieve participant information based on the GET Participant request [^7] (GET /participants/{Type}/{ID}) , which supplies the ID and structure. The FSP IOP API sends the request to the Account Lookup & Discovery BC [^14] to determine whether the desired participant exists. The FSP IOP API then responds to the requestor with a PUT Participant response [^15] (PUT /participants/{Type}/{ID}). + +#### Flow Diagram + +![Use Case - Account Lookup & Discovery BC - Get Participant](./assets/0-3-get-participant.jpg) + +> + +### Get Party + +#### Description + +Retrieve party information based on the ID passed with the GET Party request [^8] (GET /parties/{Type}/{ID}). The FSP IOP API then sends a request to the Account Lookup & Discovery BC [^14] to determine the target FSP to forward the GET request to. The target FSP then responds with a PUT parties request. The information is then sent to the Account Lookup & Discovery BC to be cached before the PUT Party response [^17] (PUT /parties/{Type}/{ID}) is sent to the original sender of the GET request. + +#### Flow Diagram + +![Use Case - Account Lookup & Discovery BC - Get Party](./assets/0-4-get-party.jpg) + +> + +## Agreement (Quoting) BC + +### Calculate Quote - Happy Path + +#### Description + +When a quote is sent using the POST Quote request [^3] (POST /quotes), the FSP IOP API will sends the request to the Quoting/Agreement BC [^19] to validate the quote. The FSP IOP API will then send the POST Quote to the Payee FSP, which in turn responds with a PUT Quote response [^18] (PUT /quotes/{ID}) and updated relevant information. The FSP IOP API sends the accepted quote to the The Quoting/Agreement BC [^19] to persist the quote information. The FSP IOP API will then forwards the PUT quote request to the Payer FSP and consider the quote successful. + +#### Flow Diagram + +![Use Case - Agreement BC - Calculate Quote - Happy Path](./assets/1-1-calculate-quote-happy-path.jpg) + +> + +### Get Quote - Happy Path + +#### Description + +This allows a FSP to get quote information of an existing quote. The GET Quote request [^4] (GET /quotes/{ID}) is sent to the FSP IOP API that queries the Quoting/Agreement BC [^19] for existing quotes. When the quote is retrieved the information is send back to the requesting FSP by sending the PUT Quote response [^18] (PUT /quotes/{ID}). + +#### Flow Diagram + +![Use Case - Agreement BC - Get Quote - Happy Path](./assets/1-2-get-quote-happy-path.jpg) + +> + +### Calculate Quote - Invalid Quote Request + +#### Description + +When a POST Quote request [^3] (POST /quotes) is , the FSP IOP API sends the request to the Quoting/Agreement BC [^19] for processing. The quote then fails validation the Quoting/Agreement BC [^19] responds with an error response that the FSP IOP API notifies the requesting FSP through the use of the PUT Quote Error response [^20] (PUT /quotes/{ID}/error). + +#### Flow Diagram + +![Use Case - Agreement BC - Calculate Quote - Invalid Quote Request](./assets/1-3-calculate-quote-invalid-quote-request.jpg) + +> + +### Calculate Quote - Invalid FSPs + +#### Description + +When a POST Quote request [^3] (POST /quotes) is sent but the FSP IOP API sends the request to the Quoting/Agreement BC [^19] for processing and it cannot determine that both participants are valid FSPs then an error response is then sent to the FSP IOP API. The FSP IOP API then notifies the requesting FSP through the use of the PUT Quote Error response [^20] (PUT /quotes/{ID}/error). + +#### Flow Diagram + +![Use Case - Agreement BC - Calculate Quote - Invalid FSPs](./assets/1-4-calculate-quote-invalid-fsps.jpg) + +> + +### Calculate Quote - Invalid Scheme Rules detected in Request + +#### Description + +When the Payer FSP sends a POST Quote request [^3] (POST /quotes) the FSP IOP API sends the request to the Quoting/Agreement BC [^19] for processing and the quote does not adhere to the scheme rules defined then an error response is then sent to the FSP IOP API. The FSP IOP API then notifies the Payer FSP through the use of the PUT Quote Error response [^20] (PUT /quotes/{ID}/error) + +#### Flow Diagram + +![Use Case - Agreement BC - Calculate Quote - Invalid Scheme Rules detected in Request](./assets/1-5-calculate-quote-invalid-scheme-rules-request.jpg) + +> + +### Calculate Quote - Invalid Scheme Rules detected in Response + +#### Description + +When the Payer FSP sends a POST Quote request [^3] (POST /quotes) the FSP IOP API sends the request to the Quoting/Agreement BC [^19] for processing and it succeeds initial processing. The FSP IOP API sends the request POST quote request to the Payee FSP. The Payee FSP should react with a accepted quote by sending PUT Quote request [^18] (PUT /quotes/{ID}). The response is sent to Quoting/Agreement BC [^19] for further processing and validation. When the Bounded Context detects that the quote does not adhere to the scheme rules defined then an error response is then sent to the FSP IOP API. The FSP IOP API then notifies both the Payer FSP and the Payee FSP through the use of the PUT Quote Error response [^20] (PUT /quotes/{ID}/error). + +#### Flow Diagram + +![Use Case - Agreement BC - Calculate Quote - Invalid Scheme Rules detected in Response](./assets/1-6-calculate-quote-invalid-scheme-rules-response.jpg) + +> Agreement BC - Calculate Quote - Invalid Scheme Rules detected in Response + +## Transfers BC + +### Perform Transfer (Universal Mode) + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The FSP IOP API then sends an event to the Settlements Bounded Context [^21]. The FSP IOP API waits for an event from the Transfers Bounded Context [^22], to indicate that the transfer has been prepared, to send a POST request to the Payee FSP. The Payee FSP then responds with a PUT Transfers request [^23] (PUT /transfers/{ID}) (transferState = committed) to the FSP IOP API which in turn commits the transfer fulfillment. The PUT transfer is then send to the Payer FSP. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer (Universal Mode)](./assets/2-1-perform-transfer-universal-mode.jpg) + +> + +### Perform Transfer with Payee Confirmation + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The FSP IOP API then sends an event to the Settlements Bounded Context [^21]. The FSP IOP API waits for an event from the Transfers Bounded Context [^22], to indicate that the transfer has been prepared, to send a POST request to the Payee FSP. The Payee FSP then responds with a PUT Transfers request [^23] (PUT /transfers/{ID}) (transferState = reserved) to the FSP IOP API which in turn reservers the transfer fulfillment. The PUT transfer is then send to the Payer FSP. The Payee FSP then receives a PATCH Transfers request [^24] (PATCH /transfers/{ID}) to notify the state change of the transfer. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer with Payee Confirmation](./assets/2-2-perform-transfer-payee-confirmation.jpg) + +> + +### Query Get Transfer + +#### Description + +Gets the transfer info based on the transfer ID used in GET Transfer request [^11] (GET /transfers/{ID}) and receives a PUT Transfers request [^23] (PUT /transfers/{ID}) to get the relevant information about the transfer. + +#### Flow Diagram + +![Use Case - Transfers BC - Query Get Transfer](./assets/2-3-query-get-transfer.jpg) + +> + +### Perform Transfer - Duplicate Post (Resend) + +#### Description + +POST Transfers request [^9] (POST /transfers) has already been processed and a status report is returned to the Payer FSP by receiving a PUT Transfers request [^23] (PUT /transfers/{ID}). + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Duplicate Post (Resend)](./assets/2-4-perform-transfer-duplicate-post.jpg) + +> Transfers BC - Perform Transfer - Duplicate Post (Resend) + +### Perform Transfer - Duplicate Post (Ignore) + +#### Description + +POST Transfers request [^9] (POST /transfers) has already been processed but no response is needed or requested. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Duplicate Post (Ignore)](./assets/2-5-perform-transfer-duplicate-post-ignor.jpg) + +> + +### Perform Transfer - Payee DFSP Rejects Transfer + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The Api then prepares the transfer and then sends the POST request through to the Payee FSP. The Payee FSP then declines the transfer by sending a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the FSP IOP API. The FSP IOP API then notifies the Transfers Bounded Context [^22] that the transfer has been rejected and sends a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the Payer FSP. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Payee DFSP Rejects Transfer](./assets/2-6-perform-transfer-payeefsp-rejects-transfer.jpg) + +> + +### Perform Transfer - Timeout (Prepare) + +#### Description + +POST Transfers request [^9] (POST /transfers) gets rejected because the transfer timed out [^13] while funds are being prepared. The FSP IOP API sends a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) request to the Payer FSP to notify of the error. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Timeout (Prepare)](./assets/2-7-perform-transfer-timeout-prepare.jpg) + +> + +### Perform Transfer - Timeout (Pre-Committed) + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The FSP IOP API then sends an event to the Settlements Bounded Context [^21]. The FSP IOP API waits for an event from the Transfers Bounded Context [^22], to indicate that the transfer has been prepared, to send a POST request to the Payee FSP. The Payee FSP then responds with a PUT Transfers request [^23] (PUT /transfers/{ID}) (transferState = committed) to the FSP IOP API which in turn commits the transfer fulfillment. The transfer times out [^13] while/before the funds are committed and causes the transfer to be rejected. The FSP IOP API then notifies both the Payer and Payee FSPs with a PUT Transfer error request [^25] (PUT /transfers/{ID}/error). + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Timeout (Pre-Committed)](./assets/2-8-perform-transfer-timeout-pre-committed.jpg) + +> + +### Perform Transfer - Timeout (Post-Committed) + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The FSP IOP API then sends an event to the Settlements Bounded Context [^21]. The FSP IOP API waits for an event from the Transfers Bounded Context [^22], to indicate that the transfer has been prepared, to send a POST request to the Payee FSP. The Payee FSP then responds with a PUT Transfers request [^23] (PUT /transfers/{ID}) (transferState = committed) to the FSP IOP API which in turn commits the transfer fulfillment. The transfer times out [^13] after the funds are committed and causes the transfer to be rejected. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Timeout (Post-Committed)](./assets/2-9-perform-transfer-timeout-post-commit.jpg) + +> + +### Perform Transfer - Duplicate Post (None Matching) + +#### Description + +POST Transfers request [^9] (POST /transfers) has already been processed and a status report is returned to the Payer FSP by receiving a PUT Transfer error request [^25] (PUT /transfers/{ID}/error). + +#### Flow Diagram + +![Use Case - Example REPLACE ME](./assets/2-10-perform-transfer-duplicate-none-matching.jpg) + +> + +### Perform Transfer - Payer FSP Insufficient Liquidity + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The FSP IOP API then sends an event to the Settlements Bounded Context [^21]. The FSP IOP API waits for an event from the Transfers Bounded Context [^22], to indicate that the transfer has been prepared, but receives a Liquidity check failure for the Payer FSP. The FSP OIP API then sends a PUT [^25] transfers error request to the Payer FSP to notify of the error. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Payer FSP Insufficient Liquidity](./assets/2-11-perform-transfer-payer-insuficiant-liquidity.jpg) + +> + +### Perform Transfer - Transfer Prepare Rejected + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The Api then prepares the transfer and then sends the POST request through to the Payee FSP. The Payee FSP then declines the transfer by sending a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the FSP IOP API. The FSP IOP API then notifies the Transfers Bounded Context [^22] that the transfer has been rejected and sends a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the Payer FSP. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Transfer Prepare Rejected](./assets/2-12-perform-transfer-prepare-rejected.jpg) + +> + +### Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant) + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The Transfers Bounded Context [^22] notifies the FSP IOP API that the Payer FSP is invalid. Depending on the reason for the Payer FSP being invalid the FSP IOP API will send a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the Payer FSP. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant)](./assets/2-13-perform-transfer-prepare-validation-failure-invalid-payer-participant.jpg) + +> + +### Perform Transfer - Transfer Prepare Validation Failure (Invalid Payee Participant) + +#### Description + +The Payer FSP sends a POST Transfers request [^9] (POST /transfers) to the FSP IOP API. The Transfers Bounded Context [^22] notifies the FSP IOP API that the Payee FSP is invalid. The FSP IOP API will send a PUT Transfer error request [^25] (PUT /transfers/{ID}/error) to the Payer FSP to notify about the failure. + +#### Flow Diagram + +![Use Case - Transfers BC - Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant)](./assets/2-14-perform-transfer-prepare-validation-failure-invalid-payee-participant.jpg) + +> + +## Notes + +### Structure validation on internal events + +Many use cases stipulate that the request structure and semantics should be validated when receiving a event from an internal Bounded Context. This does not happen on a per request basis but rather is a requirement to be met when the building phase of the Reference Architecture is underway. What we are trying to say by showing that is that internally all events and available resources should be standardized and verified. + +[^1]: [Mojaloop Common Interface List](../../commonInterfaces.md) +[^2]: [Open API for FSP Interoperability Specification Documentation](https://docs.mojaloop.io/mojaloop-specification/) +[^3]: [Post Quote - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6532-post-quotes) +[^4]: [Get Quote - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6531-get-quotesid) +[^5]: [Post Participant - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6233-post-participantstypeid) +[^6]: [Delete Participant - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6234-delete-participantstypeid) +[^7]: [Get Participant - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6231-get-participantstypeid) +[^8]: [Get Parties - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6331-get-partiestypeid) +[^9]: [Post Transfers - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6732-post-transfers) +[^10]: [Commit Notification - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6726-commit-notification) +[^11]: [Get Transfers - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6731-get-transfersid) +[^12]: [Transaction Irrevocability - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.#6722-transaction-irrevocability) +[^13]: [Transfers Timeout and Expiry - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6724-timeout-and-expiry) +[^14]: [Account Lookup and Discovery Bounded Context](../accountLookupAndDiscovery/index.md) +[^15]: [Put Participant - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6242-put-participantsid) +[^17]: [Put Party- Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6341-put-partiestypeid) +[^18]: [Put Quote - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6541-put-quotesid) +[^19]: [Quoting\Agreement Bounded Context](../quotingAgreement/index.md) +[^20]: [Put Quote Error - Definition](https://docs.mojmojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6551-put-quotesiderror) +[^21]: [Settlements Bounded Context](../settlements/index.md) +[^22]: [Transfers Bounded Context](../transfers/index.md) +[^23]: [Put Transfers - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6741-put-transfersid) +[^24]: [Patch Transfers - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6733-patch-transfersid) +[^25]: [Put Transfers Error - Definition](https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6751-put-transfersiderror) +[^26]: [Participant Lifecycle Management Bounded Context](../participantLifecycleManagement/index.md) +[^27]: [Notification and Alerts Bounded Context](../notificationsAndAlerts/index.md) diff --git a/docs/technical/reference-architecture/boundedContexts/index.md b/docs/technical/reference-architecture/boundedContexts/index.md new file mode 100644 index 000000000..e04fd4a32 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/index.md @@ -0,0 +1,23 @@ +# Bounded Context + +In this section we take a deep dive into each of the identified Bounded Contexts indicating their purpose (description), Subdomains spanned, Use Cases that each Bounded Context addresses, and concluding remarks where they have been included. + + \ No newline at end of file diff --git a/docs/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png b/docs/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png new file mode 100644 index 000000000..577e56490 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/logging/assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/logging/index.md b/docs/technical/reference-architecture/boundedContexts/logging/index.md new file mode 100644 index 000000000..1b529688c --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/logging/index.md @@ -0,0 +1,20 @@ +# Logging BC + +The Logging Bounded Context is used to store technical information to assist debugging, troubleshooting and problem resolution. Logs are consumed from any other Bounded Context [^1] and stored for querying and reporting. The log information is stored as "technicalities" and should any loss of data take place, then there should be no other consequence than losing technical ability to understand how the system behaves. All system activities are logged and persisted to allow the Auditing Bounded Context [^2] to perform queries against the log data. + +Bounded Contexts should publish the events in a defined format and using whatever mechanism is available from the Logging Bounded Context. The structure implicitly has an abstraction layer built into the event received byt the Logging Bounded Context which in turn is then used to persist the log data. + +## Use Cases + +### Event Based Logging + +#### Flow Diagram + +![Use Case - Event Based Logging](./assets/ML2RA_Logging_ucEventBasedLogging_Apr22-b-1450.png) +>UC Workflow Diagram: Event Based Logging + + +## Notes + +[^1]: [Mojaloop Common Interface List](../../refarch/commonInterfaces.md) +[^2]: [Auditing Bounded Context](../auditing/index.md) diff --git a/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png new file mode 100644 index 000000000..607842c5a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertNotification.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png new file mode 100644 index 000000000..754ec79dc Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/alertRegistration.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png new file mode 100644 index 000000000..b858925b7 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendAsyncNotificationWithDeliveryReport.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png new file mode 100644 index 000000000..b188e7f71 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/assets/sendSyncNotificationWithDeliveryReport.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md new file mode 100644 index 000000000..4bc36afa1 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/notificationsAndAlerts/index.md @@ -0,0 +1,62 @@ +# Notifications and Alerts BC + +The Notifications and Alerts BC acts as the notification-engine of the Mojaloop platform. It provides supporting capabilities for reliable FSPIOP Callbacks by ensuring that delivery reports are made available for compensating actions, and audit purposes. Similarly, these capabilities can be leveraged for sending alerts reliably to internal sub-systems or external consumers. + +Reliability is ensured by several mechanisms: + +- Each Notification command contains + - all the necessary information (headers, payload, transport, etc) required by the BC to deliver it + - retry and delivery configuration on how the Notification BC should handle delivery failures +- Notification or Alert reports are persisted and are queryable. + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|---|---| +| **Notification** | An outbound notification send by the Notifications and Alerts BC normally to an external destination containing contextual headers and payloads. An example of this being the FSPIOP Callbacks as part of the Mojaloop API Specification. | +| **Alert** | Similar to a notification except an Alert is normally used to inform internal sub-systems (i.e. other BC) or a Hub Operator of an "observed" Canonical Event. An example of this being that an FSP has exceeded their available liquidity. | +| **Delivery Report** | A report produced by the Notifications and Alerts BC containing delivery information about a specific Notification or Alert, such as the status of the delivery, the response received by the destination, the number of retries, and information about failures. This report can be either by a domain event, and/or a synchronous response to an API request. | +| **Canonical Event** | This is any Domain Event produced by a Bounded Context | + +## Use Cases + +### Send Asynchronous Notifications with Delivery Report + +#### Flow Diagram + +![Use Case - Send Async Notifications with Delivery Report](./assets/sendAsyncNotificationWithDeliveryReport.png) + +### Send Synchronous Notifications with Delivery Report + +#### Flow Diagram + +![Use Case - Send Sync Notifications with Delivery Report](./assets/sendSyncNotificationWithDeliveryReport.png) + + + +### Alert Registration + +#### Description + +Hub Operators or Sub-systems will be able to call the Alert Registration API to subscribe to specific notification alerts. The AlertRegister operation will include: + +- Domain Message/Event to be monitored +- End-point / Transport information for Notification Delivery +- Template for the Notification Alert that will be used to generate the actual Notification + +#### Flow Diagram + +![Use Case - Send Sync Notifications with Delivery Report](./assets/alertRegistration.png) + +### Alert Notifications + +#### Flow Diagram + +![Use Case - Send Sync Notifications with Delivery Report](./assets/alertNotification.png) + + + diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png new file mode 100644 index 000000000..c16848a1b Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..adbfe0d98 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..ec745aaa8 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..b4abeaf4f Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..177241a98 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png new file mode 100644 index 000000000..eea3ac385 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png new file mode 100644 index 000000000..bc50ae969 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..109050536 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..bd4f49e56 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png new file mode 100644 index 000000000..3bcd8009c Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png new file mode 100644 index 000000000..d3b2129d3 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png new file mode 100644 index 000000000..a833e5ae6 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..4d429dc37 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..fcde920b2 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..26d13ab31 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..b9e206363 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png new file mode 100644 index 000000000..54033e161 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png new file mode 100644 index 000000000..be01060f0 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md new file mode 100644 index 000000000..63416fc0e --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/participantLifecycleManagement/index.md @@ -0,0 +1,192 @@ +# Participant Lifecycle Management BC + +The Participant Lifecycle Bounded Context's primary concern regards anything to do with the management of a Participant within the Mojaloop Environment. When we are defining the Participant Lifecycle Management Bounded Context there are a few key concepts that should be clearly defined. + +#### Maker-Checker Process +The Maker-Checker Process establishes the 6 eye verification and ensure that no write action takes place without being validated by some one with adiquite permissions. These permissions are defined by the Participant Lifecycle Management Bounded Context but are configurable and assignable as needed by the Scheme Rules. It is recommended that the users/roles that receive the maker permissions do not receive the checker permissions, and that the checker permissions are assigned to different users/roles. It will still be possible to assign both responsibilities to the same users/roles but this then voids the security that is provided by the maker-checker process that the system was built to support. + +#### Participant States +The participant state management allows the admin operators to control permissions for a given participant based on their state. During the Platform Configuration phase, the Participant Lifecycle Management Bounded Context expects participant states to be defined and configured with either roles/permissions. The participant states can then be assigned to a given participant through the Participant Status Management process. + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +| ----------- | ------------ | +| **Participant** | Financial Service Provider that register on the Mojaloop ecosystem. Allowing said FSP to be able to transact with other Participants | +| **Maker** | Representative that is responsible for creating data structures through the use of request. | +| **Checker** | Representative that is responsible for approving and accepting data that has been requested to be created. | + +## Functional Overview + +Please review the common interfaces page to see how these interaction take place. [^1] + +![Use Case - Example REPLACE ME](./assets/ML2RA_PLM-bcOverviewFlowDiagram_Apr22-a_1429.png) +>BC Workflow Diagram: Functional Overview + +## Use Cases + +### Create Participant (Single Step Registration) + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to create a Participant on the Mojaloop ecosystem, this usually requires all the information that relates to the participant and the initial accounts needed. + +#### Flow Diagram + +![Use Case - Create Pariticipant Initial](./assets/ML2RA_PLM-ucCreateParticipantInit_Apr22-a_P1-1429.png) +![UC - Create Participant Approve](./assets/ML2RA_PLM-ucCreateParticipantAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Create Participant + +### Manage Funds + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to either withdraw or deposit funds to the Participant's account(s). + +#### Flow Diagram + +![Use Case - Manage Funds - Initial](./assets/ML2RA_PLM-ucManageFundsInit_Apr22-a_P1-1429.png) +![Use Case - Manage Funds - Approve](./assets/ML2RA_PLM-ucManageFundsAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Manage Funds + +### Update Endpoints + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to update the endpoint of a given participant. When the request has been approved the endpoint will be called on a keep alive path to ensure connectivity. + +#### Flow Diagram + +![Use Case - Update Endpoints - Initial](./assets/ML2RA_PLM-ucUpdateEndpointsInit_Apr22-a_P1-1429.png) +![Use Case - Update Endpoints - Initial](./assets/ML2RA_PLM-ucUpdateEndpointAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Update Endpoints + +### Update Participant Status + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to change the status of a given participant to enforce different roles/scheme rules on the participant. + +#### Flow Diagram + +![Use Case - Update Participant Status - Initial](./assets/ML2RA_PLM-ucUpdateParticipantStatusInit_Apr22-a_P1-1429.png) +![Use Case - Update Participant Status - Approve](./assets/ML2RA_PLM-ucUpdateParticipantStatusAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Update Participant Status + +### Get Participant + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to get information with about a given participant. + +#### Flow Diagram + +![Use Case - Get Participant](./assets/ML2RA_PLM-ucGetParticipant_Apr22-a_1429.png) +>UC Workflow Diagram: Get Participant + +### Add Participant Accounts + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to control different aspects of a Participant's accounts, from creating an account, enabling/disabling and updating the limits and threshold warnings of an account. + +- Add Participant Account +- Update Participant Account Status (Enable/Disable) +- Update Liquidity Limits and Warning Thresholds + +#### Flow Diagram + + + +![Use Case - Add Participant Accounts - Initial](./assets/ML2RA_PLM-ucAddParticipantAccountInit_Apr22-a_P1-1429.png) +![Use Case - Add Participant Accounts - Approve](./assets/ML2RA_PLM-ucAddParticipantAccountAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Add Participant Accounts + +### Liquidity Cover Reserve + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to reserve liquidity cover for a Participant and notify the Accounts and Balances BC about the update. + +#### Flow Diagram + +![Use Case - Reserve Liquidity Cover - Initial](./assets/ML2RA_PLM-ucLiquidityCoverReserveInit_Apr22-a_P1-1429.png) +![Use Case - Reserve Liquidity Cover - Approve](./assets/ML2RA_PLM-ucLiquidityCoverReserveAppro_Apr22-a_P2-1429.png) +>UC Workflow Diagram: Liquidity Cover Reserve + +### Liquidity Threshold Exceeded + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to notify the participant that a preset liquidity threshold has been reached and action might be required. + +#### Flow Diagram + +![Use Case - Liquidity Threshold Exceeded](./assets/ML2RA_PLM-ucLiquidityThresholdExceeded_Apr22-a_1429.png) +>UC Workflow Diagram: Liquidity Threshold Exceeded + +### Liquidity Limit Exceeded + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to notify the participant when they have reached the preset liquidity limit of an account. + +#### Flow Diagram + +![Use Case - Liquidity Limit Exceeded](./assets/ML2RA_PLM-ucLiquidityLimitedExceeded_Apr22-a_1429.png) +>UC Workflow Diagram: Liquidity Limit Exceeded + +### Liquidity Threshold & Limit Reset + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which reset the liquidity limit or threshold notification checks when successful transfers have been executed and the participant account position is in a positive state. + +#### Flow Diagram + +![Use Case - Liquidity Threshold & Limit Reset](./assets/ML2RA_PLM-ucLiquidityLimit&ThresholdReset_Apr22-a_1429.png) +>UC Workflow Diagram: Liquidity Threshold and Limit Reset + +### Liquidity Cover Query + +#### Description + +The workflow provided by this UC enables the BC to employ a process through which to query the current liquidity of a participant account, along with additional read operations that are related to the participant's liquidity. + +#### Flow Diagram + + + +![Use Case - Liquidity Cover Query](./assets/ML2RA_PLM-ucLiquidityCoverQuery_Apr22-a_1429.png) +>UC Workflow Diagram: Liquidity Cover Queries + +## Canonical Model + +- Participant + - id + - participantAlias + - endpointURL + - state + - Accounts[] + - accountID + - ledgerAccountType + - accountCurrency + - isActive + - warningThreshold + - limit + - type + - value + +## Concluding Comments + +**Participant Accounts:** Participants can only have one account per allowed currency. +**Update Position Use Case:** Has been changed to the Manage Funds use case +**Maker/Checker Operations:** Retry count has no effect on the way we process/re-process requests. + + + +## Notes + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../boundedContexts/commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png b/docs/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png new file mode 100644 index 000000000..fd9ae7373 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/platformMonitoring/assets/useCaseExample.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/platformMonitoring/index.md b/docs/technical/reference-architecture/boundedContexts/platformMonitoring/index.md new file mode 100644 index 000000000..1fa059c56 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/platformMonitoring/index.md @@ -0,0 +1,23 @@ +# {name} BC + +{overview} + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|---|---| +| Term1 | Description1 | + +## Use Cases + +### Perform Transfer (universal mode) + +![Use Case - Example REPLACE ME](./assets/useCaseExample.png) +> example image - replace + + +## Notes + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png new file mode 100644 index 000000000..ce5c78a4d Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteHappyPath_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png new file mode 100644 index 000000000..80bbd8d7a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidFSPs_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png new file mode 100644 index 000000000..5cb2262e8 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png new file mode 100644 index 000000000..b98cbc26e Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png new file mode 100644 index 000000000..a023e3df6 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png new file mode 100644 index 000000000..72ac92834 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaFunctionalOverview_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png new file mode 100644 index 000000000..5c67aa42b Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaGetQuoteHappyPath.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png new file mode 100644 index 000000000..f4386a449 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/assets/qtaTransfersVelocityRuleEval-Trigger_20210825.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/quotingAgreement/index.md b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/index.md new file mode 100644 index 000000000..f330347b5 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/quotingAgreement/index.md @@ -0,0 +1,120 @@ +# Quoting/Agreements BC + +The Quoting and Agreements Bounded Context provides Participants with quotations for undertaking transfers, and records the participant accept/reject responses. + +## Terms + +The following terms are used in this BC, also known as a domain. + +| Term | Description | +|---|---| +| **(D)FSP** | (Digital) Financial Services Provider | +| **Participant** | Financial Services Provider | + +## Functional Overview + +![Use Case - Functional Overview](./assets/qtaFunctionalOverview_20210825.png) + +## Use Cases + +### Calculate Quote - Happy Path + +#### Description + +This process obtains an array of relevant Participant data including status flags, calculates the cost of Transfer including fees, and provides it to the Participant/s. It also able to support the storing of Participants requests & responses (i.e. accept or reject the quote). + +#### Flow Diagram + +![Use Case - Calculate Quote - Happy Path](./assets/qtaCalculateQuoteHappyPath_20210825.png) + +### Get Quote - Happy Path + +#### Description + +Process to obtain and deliver existing Quote details to Participant/s on request. + +#### Flow Diagram + +![Use Case - Example REPLACE ME](./assets/qtaGetQuoteHappyPath.png) + +### Calculate Quote - Invalid Quote Request + +#### Description + +Process that enables the system to invalidate quote requests by monitoring and responding to invalid Request Events, FSPs, or duplicate requests. + +#### Flow Diagram + +![Use Case - Calculate Quote - Invalid Quote Request](./assets/qtaCalculateQuoteInvalidQuoteRequest_20210825.png) + +### Calculate Quote - Invalid FSPs + +#### Description + +Process that enables the system to invalidate FSP quote requests where the FSP details mismatch the original Quote for either one or both Participants. + +#### Flow Diagram + +![Use Case - Calculate Quote - Invalid FSPs](./assets/qtaCalculateQuoteInvalidFSPs_20210825.png) + +### Calculate Quote - Invalid Scheme Rules Detected In Request + +#### Description + +Process to enable the system to invalidate quote requests where Scheme Rules are violated, by one or more Participants, for example where Quote Period Limit reached. + +#### Flow Diagram + +![Use Case - Calculate Quote - Invalid Scheme Rules detected in Request](./assets/qtaCalculateQuoteInvalidSchemeRulesRequest_20210825.png) + +### Calculate Quote - Invalid Scheme Rules Detected In Response + +#### Desciption + +Process to enable the system to invalidate quote reponses where Scheme Rules are violated by one or more Participants, for example, where invalid terms are detected. + +#### Flow Diagram + +![Use Case - Calculate Quote - Invalid Scheme Rules detected in response](./assets/qtaCalculateQuoteInvalidSchemeRulesResponse_20210825.png) + +## Canonical Quote Model + +The canonical model stores the following details of quotations in the Quotes & Agreements BC: + +- Quote ID +- Transaction ID +- Participants + - payerId + - payeeId +- Payer + - Participant + - participantId + - roleType (e.g. payer) + - Amount Requested (initial amount) + - Value (number) + - Currency (ISO currency code) + - Amount to send (including fees, etc.) + - Value (number) + - Currency (ISO currency code) +- Payee(s) (one or more - should all be added to the "Amount to send") + - '#' + - Participant + - participantId + - roleType (Identify why this "payee" is receiving this amount, i.e.: fee, recipient, etc.) + - reason + - Amount to receive + - value (number) + - currency (ISO currency code) +- Extensions + +## Concluding comments + +- No red flag issues have been observed in the overall BC and Reference Architecture design. +- We need to better understand/clarify the "GET" via "POST" pattern: + - Should a "GET" event be a simple Restful "GET", or does the system need to support the "GET" from duplicate posts? + - Are we required to serve "GET" requests that include FSP details at a later date? + + + + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png new file mode 100644 index 000000000..db2b6246a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png new file mode 100644 index 000000000..723f9b87e Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_functionalOverview_Apr22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png new file mode 100644 index 000000000..5223a2137 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pullReporting_Apr22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png new file mode 100644 index 000000000..13a7d81ae Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_pushReporting_Apr22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png new file mode 100644 index 000000000..98d2ece29 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/reporting/assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/reporting/index.md b/docs/technical/reference-architecture/boundedContexts/reporting/index.md new file mode 100644 index 000000000..d895c3a83 --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/reporting/index.md @@ -0,0 +1,101 @@ +# Reporting BC + +## Overview + +### Strategy & Rules + +The Reporting strategy for this Reference Architecture, is to describe the generic mechanisms by which client BCs' data can be persisted, and kept up to date, in a Reporting Data Store, so users and systems, can later consume this data directly from the Reporting Data Store, or through any Reporting and/or Dashboarding tools connected to the Reporting Data Store. + +- This Reporting Data Store must be write-only from the switch's perspective and read-only by external components. +- The data models on the Reporting Data Store can be different from the internal operational data models that the switch uses; where relevant, for performance or other reasons, multiple models of the same data can be made available in the Reporting Data Store - akin to multiple projections or views. +- A Client BC Reporting Component provided by the switch, will be translating internal events and internal data models to the external data store models - This component can be replaced or, there can even exist many of these for a single Client BC. +- Such component must exists in the Reporting BC for any Client BC's who's data is made available in the Reporting Data Store. +- Any direct data sending, or fetching, from the source Client BC, or its internal data stores, to the Reporting Data Store, constitutes a violation of the decoupling principle and will negatively affect the maintainability of the system by virtue of its tight coupling. + +### Reporting strategies: + +- Event based - Preferred way - On the Reporting BC sits a component (event handler) that is listening to relevant event from its correspondent BC and transforms those events into reporting data store entries - there can be many of these components per Client BC, however, each should be the only one responsible for writing a subset of the reporting data +- Push - The Client BC will call the correspondent Client BC Reporting Component API to send data, this API will be transforming the data and persisting it to the reporting store ([^1] with the source BC, ie, there should be a API per source BC) +- Pull - On the reporting BC sits a Client BC Reporting Component (timer based) that calls an API on the source BC to retrieve its data, that is then persistent to the reporting store ([^1] with the source BC) + +**For performance critical BC we should always try to use the event driven reporting strategy.** + +### Absolutely minimum rules to observe: + +- Only the Reporting Data Store can be used for reporting and dashboarding. External systems are forbidden direct access to Bounded Contexts' own data stores. Operational access for external systems will be available via the Operational or [Interop APIs](/refarch/boundedContexts/fspInteropApi/). +- Client BC's internal source data cannot be "passed" directly to the Reporting Data Store - There must be a translation between the source data structure and the reporting data structure, even if there are no structure changes. Objective is to not have a dependency on the source BC data structure on the reporting side. + +### To Do + +- Decide which initial reports and dashboards should be included as part of the base reporting functionality +- Chose a open source reporting and dashboarding tools to deliver this base functionality +- Compliance / Assurance Reporting - define some of these base reports (KYC, AML) +- Discuss “Process Monitoring (and SLA's)” and decide if this can be done on top of the reporting layer (the definition of the critical numbers, SLI’s & SLO’s, is done via platform configuration) +- Add link to the Operational API BC in the rules section above + +## Terms + +Terms with specific and commonly accepted meaning within the Bounded Context in which they are used. + +| Term | Description | +|---|---| +| **Client BC** | Source (or owner) Bounded Context of data being persisted in the Reporting Data Store| +| **Reporting Data Store** | External data store(s) (can be multiple) where reporting data produced by the Client BC Reporting Components is persisted and kept up to date| +| **Client BC Reporting Component** | This component, can take the form or a service, and will be responsible for the translation of the internal model to the external model(s) stored in the Reporting Data Store | +| **Reporting or dashboard Tool** | External tools that use data in the Reporting Data Store as source to produce reports, dashboards or any other reporting related task | + +## Functional Overview + +![Reporting Functional Overview diagram](./assets/ML2RA_Rpts_functionalOverview_Apr22-b.png) +> BC Function Diagram: Functional Overview + +## Use Cases + +### Event based Reporting (preferred way) + +#### Description + +Strategy to feed the Reporting Data Store by having Client BC Reporting Component listening to the internal events and persisting the related reporting data. + +#### Flow Diagram + +![Event Based Reporting use case diagram](./assets/ML2RA_Rpts_eventBasedReporting_Apr22-b.png) +> UC Workflow Diagram: Event Based Reporting (Preferred Way) + +### Pull based Reporting + +#### Description + +Strategy to feed the Reporting Data Store by having Client BC Reporting Component fetching data from the Client BC API. + +#### Flow Diagram + +![Pull Based Reporting use case diagram](./assets/ML2RA_Rpts_pullReporting_Apr22-b.png) +> UC Workflow Diagram: Pull Reporting + +### Push based Reporting + +#### Description + +Strategy to feed the Reporting Data Store by having the Client BC sending to the Client BC Reporting Component API the data to be reported, and the Client BC Reporting Component translating and persisting it. + +#### Flow Diagram + +![Push Based Reporting use case diagram](./assets/ML2RA_Rpts_pushReporting_Apr22-b.png) +> UC Workflow Diagram: Push Reporting + +### User Report and Dashboard Consumption + +#### Description + +Example of how a user can consume reports nd dashboards + +#### Flow Diagram + +![User Report and Dashboard Consumption diagram](./assets/ML2RA_Rpts_reportDashboardConsumption_Apr22-b.png) +> UC Workflow Diagram: User Reporting & Consumption Dashboard + + +## Notes + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../refarch/commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png new file mode 100644 index 000000000..6db98ef15 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingCreateReminder_20211021.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png new file mode 100644 index 000000000..43a900f75 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingDeleteRecurringReminder_20211021.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png new file mode 100644 index 000000000..00de4e46d Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/schedulingReminderTriggered_20211021.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png new file mode 100644 index 000000000..fd9ae7373 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/scheduling/assets/useCaseExample.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/scheduling/index.md b/docs/technical/reference-architecture/boundedContexts/scheduling/index.md new file mode 100644 index 000000000..6b7ff1edb --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/scheduling/index.md @@ -0,0 +1,131 @@ +# Scheduling BC + +Multiple processes and events in BCs across the Mojaloop Switch platform require functionality to trigger at specific times, or in accordance with a schedule. In order to support this requirement across the Switch, and avoid building scheduling functionality into multiple BCs, a single Scheduling BC will be introduced and implemented for the Switch platform. + +In order to schedule a process or event, a Client BC submits a request to the Scheduling BC to create a reminder for a specific time or time schedule. The Scheduling BC maintains a schedule of all of the reminders that it receives, and, as the time for reminders is reached, it sends notification of the reminder to the appropriate Client BC. + +In addition, the Scheduling BC will also provide services to the Switch to enable Client BCs and Switch Admins to manage reminders that are set within the Scheduling BC. + +## Terms + +The following common term/s are in use in this BC: + +| Term | Description | +|---|---| +| **Client BC** | Any other BC making use of the Scheduling BC Services | + +## Use Cases + + +The status of the UCs for the Scheduling BC is as follows: + +| Available UCs | | | Planned UCs | | +| --- | :-- | --- | --- | :-- | +| **Use Case** | **Description** | | **Use Case** | **Description** | +| **Create Reminder** | Client BC requests a reminder to be created | | **Client Reminder Query** | Client BC queries its own reminders | +| **Delete Reminder** | Client BC requests a reminder to be deleted | | **Admin Reminder Query** | Platform Admin queries all reminders | +| **Reminder Trigger** | Scheduling BC executes reminder trigger when the time comes | | | +| **Update Reminder** | *Not provided. Recommended solution: delete and create a new Reminder* | | | | | + + +### Create Reminder + +#### Description +The workflow provided by this UC enables the Switch to handle authorised Client BC requests to create Reminders. + +#### Flow Diagram + +![Create Reminder](./assets/schedulingCreateReminder_20211021.png) +> +### Reminder Triggered + +#### Description +The workflow provided by this UC enables the Switch to handle reminders messaged from the Scheduling BC to a Client BC to execute a task, or as a reminder only. + +#### Flow Diagram + +![Reminder Triggered](./assets/schedulingReminderTriggered_20211021.png) +> +### Delete (Recurring) Reminder + +#### Description +The workflow provided by this UC enables the switch to handle messages from authorised Client BCs to the Scheduling BC to delete a Reminder. In the event that the Scheduling BC is unable to process the instruction, it sends an Alert message to the Notifications BC. + +#### Flow Diagram + +![Delete (Recurring) Reminder](./assets/schedulingDeleteRecurringReminder_20211021.png) +> + + +## Notes + +#### Create Reminder - Required data + +The Create Reminder request needs to include the following data: + +| Data | Description | +| --- | ---- | +| **Identifier** | name/id | +| **Cron Definition** | recurring?, time interval? | +| **Trigger Transport** | HTTP Callback/Event; Callback URL or Event Topic | +| **Special Payload** | opaque for the scheduling BC | +| **Recovery Conditions** | retry, reschedule, abort, abandon | +| **Alerts** | notification, logging on exceptions | +| **Actions** | register of automatable/schedulable BC processes | + +#### Scheduling BC - Requirements + +The Scheduling BC must meet the following requirements: + +* Reminders must be triggered once only + +* BC must keep track of triggered Reminders + +* BC must keep track of Create/Read/Delete actions + + * Updates will be facilitated through Delete/Create actions as noted in the [Use Case Available UCs](#use-cases) list + +* Job batches + +* Offer multiple interface options (gRPC, REST, HTTP, etc.) + +* Reminders should be triggered with an HTTP callback, not a gRPC call, or to a specific topic + +* It should have no ability to process logic external to the Scheduling BC itself + +* Make use of Linux-based UTC timestamps only in order to avoid synchronization issues + +***Note:*** *It is assumed that the underlying system will keep perfect time.* + +#### Scheduling BC - Outstanding requirements + +Access requirements for the Scheduling BC still require definition. + +#### Scheduling BC - Exceptions + +* Malformed instructions + * Invalid date/time, including times in the past + * Invalid BC or command +* Failed execution (identified through call-back) +* Insufficient authority for the Client BC to perform the CRD operation +* Failure to process/execute Reminder + +#### Questions + +A number of questions came up during the Reference Architecture Work Sessions and, as some were felt to have potential value from which others would benefit, we have included them below: + +* After the scheduled task has been initiated, does the Scheduling BC remain responsible for tracking its progress? + + * Answer: No. When the Reminder is due, it is communicated to the Client BC using the precribed method, and thereafter, the Scheduling BC responsibility for the reminder is passed back to the Client BC. + +* Is the Client BC or the person who scheduled a Reminder noted as the "User" by the Scheduling BC? IOW, whose ID is stamped on the process audit trail? + + * Answer: This should be determined by the Client BC, based on its action on receipt of the Reminder. \ No newline at end of file diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png new file mode 100644 index 000000000..8c67da4bb Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png new file mode 100644 index 000000000..3bf4c83db Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png new file mode 100644 index 000000000..f268daee4 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png new file mode 100644 index 000000000..b67ea6e1a Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png new file mode 100644 index 000000000..798b8681b Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png new file mode 100644 index 000000000..807c85f63 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/security/assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/security/index.md b/docs/technical/reference-architecture/boundedContexts/security/index.md new file mode 100644 index 000000000..68642b23f --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/security/index.md @@ -0,0 +1,94 @@ +# Security BC + +## Overview + +The protocol is request and response based, and the used transport protocol is secure Hypertext Transfer Protocol Secure (HTTPS). All services use the HTTP POST and GET methods. Both the request and response bodies are encoded in JSON-formatted text. + +## Terms + +Terms with specific and commonly accepted meaning within the Security Bounded Context. + +| Module | Description | +|---|---| +| **Crypto providers** | Adapter that will provide cryptographic services and Key Management Services | +| **IAM** | Identity and Access Management. Adapter that will provide services for user management, menus, profiles, roles and permissions. | +| **AuthN** | Authentication module. Requires userid and password and returns a JWT token | +| **AuthZ** | Authorization module. Requires JWT and certificate (public key). Verifies JWT ROLES and signature | +| **JWT** | JSON Web Token. Returned after a successful user authentication. Contains user details, ROLES and signature. | +| **KMS** | Key Management System. Manages cryptographic keys lifecycle (definition, creation and retirement). It is part of the Cyrpto subsystem | + +## Use Cases + +### BC User / Operator login (AuthN) + +#### Description + +The login function requires that the user id and a secret key be passed in the http body. The response contains a signed JWT token. The signature is generated by the Crypto subsystem. The login is performed by the Authorization services or IAM. + +#### Flow Diagram + +![Use Case - BC User / Operator Login (AuthN)](./assets/ML2RA_SecAuth-ucUserOpsLogin(AuthN)_Apr22_1829.png) +> UC Workflow Diagram: BC User/Operator Login (AuthN) + +### BC Authorization Model (AuthZ) + +#### Description + +IAM will provide users / groups, roles and privileges associations. Each BC will also have a list of related roles. When an API function or microservice +is called, the JWT signature is verified using the public key and the role provided in the JWT is compared to the role associated with the BC. If the signature verification and the role are successfully verified, the API function or microservice is executed. + +#### Flow Diagram + +![Use Case - BC Authorization Model (AuthZ)](./assets/ML2RA_SecAuth-ucAuthModel_Apr22_1829.png) +> UC Workflow Diagram: BC Authorization Model (AuthZ) + +### BC Bootstrap + +#### Description + +At bootstrap, the BC will send the list of possible privileges. This is done once per deployement of a new version. + +#### Flow Diagram + +![Use Case - BC Bootstrap](./assets/ML2RA_SecAuth-ucBcBootstrap-OncePerNewVer_Apr22_1829.png) +> UC Workflow Diagram: BC Bootstrap + +### BC Startup + +#### Description + +At startup the BC will request authentication issuer public keys from Security BC Crypto / KMS subsystems and the list of roles / privileges Security BC IAM subsystem. A local crypto library signature verification function will verfiy the JWT signature and the roles in the JWT will be compared with the local list of roles obtained from the central authorization service. + +##### Flow Diagram + +![Use Case - BC Startup](./assets/ML2RA_SecAuth-ucBcStartup_Apr22_1829.png) +> UC Workflow Diagram: BC Startup + +### Role / Privilege association + +#### Description + +Roles are associated with a number of privileges. + +#### Flow Diagram + +![Use Case - BC Startup](./assets/ML2RA_SecAuth-ucRolePriviledgeAssoc_Apr22_1829.png) +> UC Workflow Diagram: Role / Priviledge Association + +### Example Query / call + +#### Description + +Client Authorization should be performed by using an access token. A client first needs to request the Authorization Service to create an access token for the user who requests to access the interface. The user is authenticated in the Authorization Service. The created access token is then used for authorization in the interface. +To use the access token, the client must set the Authorization HTTP header to Bearer [access_token] in each request to the interface. + +#### Flow Diagram + +![Use Case - Example API Query/Call](./assets/ML2RA_SecAuth-ucExampleApiQueryCall_Apr22_1829.png) +> UC Workflow Diagram: Example API Query/Call + + + \ No newline at end of file diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png new file mode 100644 index 000000000..9b04df7c1 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png new file mode 100644 index 000000000..8c8b1977f Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png new file mode 100644 index 000000000..911db5bfe Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png new file mode 100644 index 000000000..5016294ea Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleAbortSettle_20210827.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png new file mode 100644 index 000000000..8c27bfe78 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateSettleAccountsNewPart_20210827.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png new file mode 100644 index 000000000..054b6a2f2 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleCreateUpdateModel_20210827.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png new file mode 100644 index 000000000..153e4c753 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/settlements/assets/settleFunctionalOverview_20210826.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/settlements/index.md b/docs/technical/reference-architecture/boundedContexts/settlements/index.md new file mode 100644 index 000000000..c2e2462ca --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/settlements/index.md @@ -0,0 +1,87 @@ +# Settlements BC + +The Settlements BC is integral to settling Participant transfers using either Deferred Net Settlement or Immediate Gross Settlement methods. It is responsible for creating settlement windows, identifying and deploying the required settlement method (DNS/IGS), settling, closing, and updating batches, and recording all deposits and withdrawals to the appropriate ledger accounts in the Accounts and Balances BC. + +## Terms + +The following terms are used in this BC, also known as a domain. + +| Term | Description | +| -------- | ------------ | +| **DNS** | Deferred Net Settlement | +| **IGS/RTGS** | Immediate Gross Settlement/Real-Time Gross Settlement | +| **Operator** | Person or System issuing instructions/requests | +| **Participant** | FSP/PISP or FSP Customer | +| **Account** | Ledger Journal Account (Cr/Dr) | + +## Functional Overview + +![Use Case - Functional Overview](./assets/settleFunctionalOverview_20210826.png) +> + +## Use Cases + +### Deferred Net Settlement (DNS) + +#### Description +Method of deferring payments to enable settlement on multiple batches according a predetermined schedule. This is useful for environments involving multiple Participants to a transaction requiring a balance of payment due settlement approach. + +#### Flow Diagram + +![Use Case - Deferred Net Settlement (DNS)](./assets/ML2RA_SET-ucDeferNetSettle_Mar22-a-P1-2.png) +>UC Workflow Diagram: Deferred Net Settlement - 19/10/2021 + +### Immediate Gross Settlement (IGS) + +#### Description +Method to enable immediate settlement of batches. This is useful for SME environments where quick payment turnarounds are often desirable in order to maximize their liquidity. IGS is also known as Real-Time Gross Settlement (RTGS) + +#### Flow Diagram + +![Use Case - Immediate Gross Settlement (IGS)](./assets/ML2RA_SET-ucInstantGrossSettle_Mar22-a.png) +>UC Workflow Diagram: Immediate Gross Settlement + +### Abort Settlement + +#### Description +Method that enables the Settlement BC to abort a settlement as required, reversing Participant settlement accounts, updating the settlement status for settlement windows, and updating the settlement state. + +#### Flow Diagram + +![Use Case - Abort Settlement](./assets/settleAbortSettle_20210827.png) +> + +### Create/Update the Settlement Model (DNS/IGS) + +#### Description +Method that enables the Settlement BC to create or update the settlement method for a settlement batch based on the Participant Account Type. Useful in instances where mixed Settlement Methods are required. + +#### Flow Diagram + +![Use Case - Create/Update the Settlement Model (DNS/IGS)](./assets/settleCreateUpdateModel_20210827.png) +> + +### Bootstrap (Startup) Settlement Model via Configuration + +#### Description +Method that configures the Settlement Method (DNS/IGS) based upon the system startup configuration. Useful in instances where all Settlement Models are the same, such as all DNS, or all IGS. + +#### Flow Diagram + +![Use Case - Bootstrap (Startup) Settlement Model via Configuration](./assets/ML2RA_SET-ucBootStrapSettleModViaConfig_Mar22-b.png) +>UC Workflow Diagram: Bootstrap (Startup) Settlement Model via Configuration + +### Create Settlement related accounts for newly created Particpants + +#### Description +The system creates settlement accounts for new Participants to enable fund transfers to managed by the Switch. This enables the Switch to exercise end-to-end management of all transfers irrespective of settlement method. + +#### Flow Diagram + +![Use Case - Create Settlement related accounts for newly created Particpants](./assets/settleCreateSettleAccountsNewPart_20210827.png) +> + + + + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png new file mode 100644 index 000000000..94ef957ff Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png new file mode 100644 index 000000000..f45af2d12 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png new file mode 100644 index 000000000..f40d264f8 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png new file mode 100644 index 000000000..6aa565e7d Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png new file mode 100644 index 000000000..5e3b6a184 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png new file mode 100644 index 000000000..90da29fc6 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png new file mode 100644 index 000000000..dad5d2724 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png new file mode 100644 index 000000000..1cd3f6cfa Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png new file mode 100644 index 000000000..841a8b8c7 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png new file mode 100644 index 000000000..de4844fc8 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png new file mode 100644 index 000000000..7ab02a922 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png new file mode 100644 index 000000000..fcb9eb8ca Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png new file mode 100644 index 000000000..fc5c3934c Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucPispBulkTransactReq_Mar22-a_P1-4.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png new file mode 100644 index 000000000..48601bc8c Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png new file mode 100644 index 000000000..c426cf207 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png new file mode 100644 index 000000000..4900cf6d5 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png new file mode 100644 index 000000000..817f487b9 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png new file mode 100644 index 000000000..8d26fbfad Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png new file mode 100644 index 000000000..5890e84aa Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png new file mode 100644 index 000000000..de4c47de3 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md new file mode 100644 index 000000000..b2c5c062d --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/thirdPartyApi/index.md @@ -0,0 +1,261 @@ +# Third Party API BC + +The Third Party API BC has been implemented with the Mojaloop 2.0 Reference Architecture to enable third-party PISP Operators (typically applications) to interact with the platform. Please note that unless otherwise stipulated, all BC references pertain to the various Mojaloop components or Bounded Contexts (BCs). + +## Terms + +The following common terms are used in this BC: + +| Term | Description | +| ---- | ------------ | +| **PISP** | Payment Initiation Service Provider (e.g. PayPal, ApplePay, GooglePay, etc.) | +| **DFSP** | Digital Financial Service Provider (e.g. Bank, Mobile Money Operator) | +| **User** | DFSP/PISP client (as indicated) | + +## Use Cases + +**Note:** Our Use Cases cover two specific scenarios: + +| Scenarios | Description | +| --------- | ----------- | +| [Linking](#linking-scenarios) | PISP Housekeeping activities | +| [Transfer](#transfer-scenarios) | PISP Transfer initiation activities | + +## Linking Scenarios + +### PISP Gets supported DFSPs + +#### Description + +The workflow provided by this UC enables the Switch to handle authorized PISP User requests to obtain a list of DFSP Account Holders supported by the system. + +#### Flow Diagram + +![Use Case - PISP Gets supported DFSPs](./assets/ML2RA_3PaL_ucPispGetSupportedDFSPs_Feb22a.png) +>UC Workflow Diagram: PISP Gets supported DFSPs + +### PISP Gets list of accounts for a DFSP + Identifier + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where authorized PISP Users wish to lookup their DFSP Account Holder account details using their DFSP Account Holder Identifier to do so. Typically the Identifier is embedded into a PISP-originated app or process. + +#### Flow Diagram + +![Use Case - PISP Gets list of accounts for a DFSP + Identifier](./assets/ML2RA_3PaL-ucPispGetDfspAccList&Id_Feb22-a.png) +>UC Workflow Diagram: PISP Gets list of accounts for a DFSP + Identifier + +### PISP Consent Request + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where an authorised PISP User notifies their DFSP Account Holder of their intention to link one or more of their accounts to a PISP via a Consent Request. The request is fulfilled via an out-of-band [Issue Consent](#dfsp-issue-consent) process upon receipt of an authorization confirmation request response. The result of this process is the establishment of a trust relationship between the PISP User, the PISP, and the DFSP Account Holder. The Switch updates participant account details accordingly. + +#### Flow Diagram + +![Use Case - PISP Consent Request](./assets/ML2RA_3PaL_ucPispConsentRequest_Feb22a.png) +>UC Workflow Diagram: PISP Consent Request + +### DFSP Issue Consent + +#### Description + +The workflow provided by this UC enables the Switch to handle instances in which a DFSP Account Holder responds to a Consent Request received from an authorised and authenticated PISP User. The DFSP Account Holder issues a request to the PISP via the Switch for the PISP User to create an identifying Credential on their device. Upon receipt of the identifying Credential, verified by the issuing DFSP Account Holder, both the Switch and the DFSP Account Holder Account records are updated with the PISP User Credential and linked Accounts, and the PISP User is notified that their DFSP Account Holder Account/s has/have been successfully linked to their PISP profile. + +***Note:*** *The Consent Issue is in response to a Consent Request made by an authorised PISP User to link one or more of their DFSP Account Holder Accounts to their PISP profile and follows the workflow noted in the [PISP Consent Request](#pisp-consent-request) UC above* + +#### Flow Diagram + +![Use Case - DFSP Issue Consent](./assets/ML2RA_3PaL_ucDfspIssueConsent_Feb22a_P1&2.png) +>UC Worflow Diagram - DFSP Issue Consent + +### Unlink Accounts: Hub Hosted Auth + +#### Description + +The workflow provided by this UC enables the Switch to handle an authorised PISP/DFSP Account Holder request to revoke consent for a DFSP Account Holder Account to be linked to their PISP Profile, which the Switch acts upon by updating the system Account Lookup Service to disassociate the PISP Participant/DFSP Account association, and notifying both the DFSP Account Holder (who removes the ALS Participant entry and Link from their system), and the PISP Host who sends a fulfilment notification to the User. + +#### Flow Diagram + +![Use Case - Unlink Accounts - Hub Hosted Auth](./assets/ML2RA_3PaL_ucUnlinkAccounts-HubHostAuth_Feb22-a_P1&2.png) +>UC Workflow Diagram: Unlink Accounts - Hub Hosted Auth + +### Link Accounts - Account Discovery Failure + +#### Description + +The workflow provided by this UC enables the Switch to handle instances in which an authorised PISP User initiates a request to link a DFSP Account to their PISP Profile using an invalid DFSP/Identifier pair not recognized by the DFSP. The DFSP messages the Switch with an error, which notifies the appropriate PISP, and the User receives a message to try another DFSP/Indentifier pair. + +#### Flow Diagram + +![Use Case - Link Accounts - Account Discovery Failure](./assets/ML2RA_3PaL-ucLinkAccnts-AccntDiscoveryFail_Mar22-a.png) +>UC Workflow Diagram: Link Accounts - Account Discovery Failure + +### Link Accounts - DFSP Rejects Consent Request + +#### Description + +The workflow provided by this UC enables the Switch to correctly handle instances where an authorized PISP User requests one or more accounts to be linked to their PISP Profile by the DFSP Account Holder. Where the DFSP Account Holder denies consent for the linking to go ahead for whatever reason, e.g.: a selected account does not support linking, it will message the Switch with an error condition. The Switch notifies the appropriate PISP, and the PISP User receives a message, in-app or otherwise, to retry their request as the previous account linking request failed. + +#### Flow Diagram + +![Use Case - Link Accounts - DFSP Rejects Consent Request](./assets/ML2RA_3PaL-ucLinkAccnts-DfspRejectConsentReq_Mar22-a.png) +>UC Workflow Diagram: Link Accounts - DFSP Rejects Consent Request + +### Credential Registration Error + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where a DFSP Account Holder provides a PISP with a request for a (PISP) User to create a device-embedded credential in order to confirm a Consent Request, and where the credential, which when sent to the DFSP includes either an invalid signed challenge or signed metadata that is rejected. In this instance the DFSP messages the error condition to the Switch, which messages the appropriate PISP who notifies the (PISP) User that the Consent credential was rejected. + +#### Flow Diagram + +![Use Case - Credential Registration Error](./assets/ML2RA_3PaL-ucCredentialRegError_Mar22-a_P1&2.png) +>UC Workflow Diagram: Credential Registration Error + +### Unlink Accounts - Consent not found + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where an authorized PISP User is asked to confirm a consent request issued via either the PISP or DFSP Account Holder to unlink their DFSP Account from their PISP Profile. The Switch refers the consent request response to the Consent Oracle for confirmation of the Consent Owner ID. In instances where the Oracle is unable to confirm the ID of the Consent Owner, the request is failed. The PISP User is alerted via the DFSP Account Holder or PISP profile holder, that the DFSP Account that they sought to unlink from their PISP profile was not found. + +#### Flow Diagram + +![Use Case - Unlink Accounts - Consent not found](./assets/ML2RA_3PaL-ucUnlinkAccnts-ConsentNotFound_Mar22a.png) +>UC Workflow Diagram: Unlink Accounts - Consent Not Found + +### DSPF Rejects OTP/Auth Token from PISP + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where an authorised PISP User requests one or more of their DFSP Account Holder Accounts to be linked to their PISP Profile. The request is directed by the Switch to the DFSP Account Holder who issues an OTP/Web Login Flow to the PISP User for verification purposes which is returned via the PISP to the Switch, and then to the DFSP Account Holder for consent. In instances where the response token is altered or expired, the DFSP Account Holder issues a error condition message to the Switch and the PISP User is notified that the DFSP Account linking request failed. + +#### Flow Diagram + +![Use Case - DFSP Rejects OTP/Auth Token from PISP](./assets/ML2RA_3PaL-ucDfspRejectsOtpAuthTokenFromPisp_Mar22-a_P1&2.png) +>UC Workflow Diagram: DFSP Rejects OTP/Auth Token from PISP + +### Unlink Accounts - Downstream Failure + +#### Description + +The workflow provided by this UC enables the Switch to handle instances in which an authorised PISP User's DFSP Account unlink consent confirmation fails the Switch's Authentication/Authorisation process for whatever reason, example: a downstream FSPIOP API error. The error is messaged by the Switch to the DFSP Account Holder who will review the error and determine how to respond. Where an error has occured, the PISP User is notified by the Switch via the PISP that their request to unlink their DFSP Account failed. + +#### Flow Diagram + +![Use Case - Unlink Accounts - Downstream Failure](./assets/ML2RA_3PaL-ucUnlinkAccntsDownstrmFail_Mar22-a_P1&2.png) +>UC Workflow Diagram: Unlink Accounts - Downstream Failure + +## Transfer Scenarios + +***Note:*** *In the interests of compacting this workflow description, the reader should note that the Third Party API and the 3rd-Party Initiated Payments BCs work in concert to maintain Participant Information. The interaction between the two BCs will not be specifically noted, but is as follows: where the Third Party API BC updates the Transaction state, and where the Participant Information is not cached, the 3rd-Party Initiated Payments BC will request the missing Participant Information from the Participant Lifecycle Management BC and deliver it to the Third Party API BC for inclusion in the Transaction information being presented to the DFSP/PISP systems.* + +### Third Party Initiated Transaction Request + +#### Description + +The workflow provided by this UC enables the Switch to permit authorized PISP Users/Apps to issue a request to a DFSP to execute a transaction on behalf of an Account Holder, typically the PISP User/App, in favor of a third-party recipient or recipients. The transaction is vetted via a DFSP confirmation request to the Account Holder, and concluded upon successful receipt of confirmation. The Switch, per DFSP instructions, manages the transaction and updates all accounts accordingly. + +Some suggested applications of Third Party Payment Initiation UC include: + + - Peer to Peer Payments (e.g.: GPay in India) + - Online checkouts for seamless end-user user experience (UX) (e.g.: PayPal) + - Payroll Clearing Software + +#### Flow Diagram + +![Use Case - Third Party Initiated Transaction Request](./assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png) +>UC Workflow Diagram: Third Party Initiated Transaction Request + +### PISP Bulk Transaction Request + +#### Description + +The workflow provided by this UC enables the Switch to permit authorized PISP Users/Apps to issue a request to a DFSP to execute a number of bulk transactions on behalf of an Account Holder, typically the PISP User/App, in favor of a group of third-party recipients. The transaction is vetted via a DFSP confirmation request sent to the Account Holder, and concluded upon successful receipt of confirmation. The Switch, per DFSP instructions, manages the transaction and updates all accounts accordingly. + +#### Flow Diagram + +![Use Case - Example REPLACE ME](./assets/ML2RA_3PaT-ucThirdPartyInitTransactReq_Mar22-a_P1P2P3bP4.png) +>UC Workflow Diagram: PISP Bulk Transaction Request + +### Pay To A PISP - PISP As A Payee + +#### Description + +The workflow provided by this UC enables the Switch to permit authorized DFSP Users to initiate and execute payments in favor of PISPs as Payees via the Switch. The workflow provides support for payments for both single or multiple PISP Payee/s. + +#### Flow Diagram + +![Use Case - Pay to a PISP - PISP as a Payee](./assets/ML2RA_3PaT-ucPayToPisp-PispAsPayee_Mar22-b_P1-2.png) +>UC Workflow Diagram: Pay To A PISP - PISP As Payee + +### Third Party Transaction Request Failed - Bad Party Lookup + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where an authorised PISP User initiates a transaction using an invalid Participant Identifier. The Switch encounters the error during the Get Parties stage of the transaction preparation, and automatically terminates the request with notification sent to the request originating User indicating the failure and the reason. + +#### Flow Diagram + +![Use Case - Example REPLACE ME](./assets/ML2RA_3PaT-ucTransactReqFail-BadPartyLookup_Mar22-b.png) +>UC Workflow Diagram: Third Party Transaction Request Failed - Bad Party Lookup + +### Third Party Transaction Request Failed - Bad Transaction Request + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where an authorised PISP User initiates a Third Party Transaction Request, correctly confirms the Payee details, but the Payee DFSP fails to locate a valid Agreement for the transaction. The Switch rejects the request and sends notification to the request originating User indicating the failure and suggested follow-up actions. + +#### Flow Diagram + +![Use Case - Third Party Transaction Request Failed - Bad Transaction Request](./assets/ML2RA_3PaT-ucTransactReqFail-BadTransactReq_Mar22-b.png) +>UC Workflow Diagram: Third Party Transaction Request Failed - Bad Transaction Request + +### Third Party Transaction Request Failed - Downstream FSPIOP Failure + +#### Description +The workflow provided by this UC enables the Switch to handle instances where an authorized PISP User requests and confirms a transaction request, which when forwarded to the DFSP Account Holder fails for some reason during the quote process. The Switch is alerted to the failure, and provides a notification to the PISP User via their PISP App/Process. + +#### Flow Diagram + +![Use Case - Third Party Transaction Request Failed - downstream FSPIOP failure](./assets/ML2RA_3PaT-ucTransactReqFail-DownStreamFspiopFail_Mar22-b-P1-2.png) +>UC Workflow Diagram: Third Party Transaction Request Failed - Downstream FSPIOP Failure + +### Third Party Transaction Request Failed - Authorization Was Invalid + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where a third-party transaction journey is initiated, then authorised by a PISP User on request from the DFSP Account Holder, and the Switch detects that the DFSP Challenge response received contained an invalid signature. The Switch can then verify that the error has occurred and notify the DFSP Account Holder who in turn cancels the transaction and the notifies the PISP User via the Switch and their PISP profile holder. + +#### Flow Diagram + +![Use Case - Third Party Transaction Request Failed - authorization was invalid](./assets/ML2RA_3PaT-ucTransactReqFail-AuthInvalid_Mar22-a-P1-3.png) +>UC Workflow Diagram: Third Party Transaction Request Failed - Authorization Was Invalid + +### Third Party Transaction Request Rejected by user + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where a PISP User initiates and confirms a transaction via their PISP, but then declines to complete it upon receipt of the DFSP Account Holder quotation acceptance and signature challenge. Once the transaction is declined, the PISP notifies the DFSP Account Holder via the Switch, who proceeds to cancel the transaction and send a transaction cancellation confirmation notification to the originating PISP. + +#### Flow Diagram + +![Use Case - Third Party Transaction Request Rejected by user](./assets/ML2RA_3PaT-ucTransactReqFail-rejectedByUser_Mar22-a-P1-3.png) +>UC Workflow Diagram: Third Party Transaction Request Rejected By User + +### Third Party Transaction Request Failed - DFSP timeout + +#### Description + +The workflow provided by this UC enables the Switch to handle instances where a PISP User initiates and confirms a transaction via their PISP, but then fails to respond to the DFSP Account Holder quotation acceptance and signature challenge within a predetermined timeout period. Once the timeout is exceeded, the PISP notifies the DFSP Account Holder via the Switch that the required response was not received, and the DFSP cancels the transaction, sending a notification to the PISP User advising them that their transaction request failed. + +#### Flow Diagram + +![Use Case - Third Party Transaction Request Failed - DFSP timeout](./assets/ML2RA_3PaT-ucTransactReqFail-dfspTimeout_Mar22-a-P1-3.png) +>UC Workflow Diagram: Third Party Transaction Request Failed - DFSP Timeout + + + \ No newline at end of file diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png new file mode 100644 index 000000000..363b750a4 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png new file mode 100644 index 000000000..4a8c4de05 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png new file mode 100644 index 000000000..ec6365184 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png new file mode 100644 index 000000000..1487e20c6 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png new file mode 100644 index 000000000..8f9d61adb Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png new file mode 100644 index 000000000..a85064494 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png new file mode 100644 index 000000000..10256bae5 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png new file mode 100644 index 000000000..1a9ffefbb Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png new file mode 100644 index 000000000..2f11f3088 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png new file mode 100644 index 000000000..7d17ba4cf Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png new file mode 100644 index 000000000..a8e55e640 Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png new file mode 100644 index 000000000..0bfbd6a1f Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png new file mode 100644 index 000000000..88d4cc4ce Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepReject_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png new file mode 100644 index 000000000..9ff7d8fda Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png new file mode 100644 index 000000000..4239eb31e Binary files /dev/null and b/docs/technical/reference-architecture/boundedContexts/transfers/assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png differ diff --git a/docs/technical/reference-architecture/boundedContexts/transfers/index.md b/docs/technical/reference-architecture/boundedContexts/transfers/index.md new file mode 100644 index 000000000..cb839102a --- /dev/null +++ b/docs/technical/reference-architecture/boundedContexts/transfers/index.md @@ -0,0 +1,261 @@ +# Transfers BC + +The Transfers BC is responsible for orchestrating transfer requests. It works in concert with a number of other BCs, notably Settlements, Scheduling, Participant Lifecycle Management, Accounts & Balances, and the FSPIOP. + +## Terms + +The following terms are used in this BC, also known as a domain. + +| Term | Description | +|---|---| +| **Accounts** | Refers to accounts used in all transfer activities. They are used to record credit and debit positions, either temporarily in the case of accounts allocated for transfer purposes, or permanently in the case of final transfer updates to participant accounts. | +| **Participant/Actor** | Typically refers to DFSP Payer/Payee parties using Mojaloop. | +| **IGS** | Transfer settle method - Immediate Gross Settlement. This process is typically used in high volume environments such as retail, and is used by individual and shared accounts. In shared account environments, the system is capable of updating Participants balances by updating the proportional value of each Participants holds of the total funds available in the account | +| **DNS** | Transfer settlement method - Deferred Net Settlement. This process is frequently used in enviroments where a party of Participants engage in a single Transfer requiring settlement to all Participants. A typical example might include a scenario where raw materials are sold by Participant A to Participant B to manufacture into a finished product, which is then sold by Participant B back to Participant A. The switch calculates the proportional value that each Participant to the transaction is due, and settles this amount when the Settlement Window closes. | + +## Functional Overview - Transfers - Bulk + +![Functional Overview - Transfers - Bulk](./assets/ML2RA_Trf_ucPerformTrfBulk_2022-03-22-a.png) +>UC Workflow Diagram: Functional Overview - Transfers - Bulk + +## Use Cases + +### Perform Transfer (universal mode) + +#### Description + +The workflow provided by this UC enables the BC to effect a Transfer using a method that excludes Actor intervention. + +#### Flow Diagram + +![Perform Transfer (Universal Mode)](./assets/ML2RA_Trf_ucPerformTrfUniMode_Mar22a.png) +>UC Workflow Diagram: Perform Transfer (Universal Mode) + +### Perform Transfer with Payee Confirmation + +#### Description + +The workflow provided by this UC enables the BC to effect a Transfer using a method that includes Actor intervention. + +#### Flow Diagram + +![Use Case - Perform Transfer with Payee Confirmation](./assets/ML2RA_Trf_ucPerformTrfPayeeConfirm_Mar22a-P1-2.png) +>UC Workflow Diagram: Perform Transfer With Payee Confirmation + +### Query (GET) Transfer + +#### Description + +The workflow provided by this UC enables the BC to effect a method by which a Participant status report Query can be completed. + +#### Flow Diagram + +![Use Case - Query (GET) Transfer](./assets/ML2RA_Trf_ucQueryTrfGET_Mar22a.png) +>UC Flow Diagram: Query (GET) Transfer + +### Perform Transfer - Duplicate POST (Resend) + +#### Description + +The workflow provided by this UC enables the BC to effect a method by which a Duplicate Transfer request is completed. + +#### Flow Diagram + +![Use Case - Perform Transfer - Duplicate POST (Resend)](./assets/ML2RA_Trf_ucPerformTrfDuplicPostResend_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Duplicate POST (Resend) + +### Perform Transfer - Duplicate POST (Ignore) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to ignore a Duplicate Transfer request. + +#### Flow Diagram + +![Use Case - Perform Transfer - Duplicate POST (Ignore)](./assets/ML2RA_Trf_ucPerformTrfDuplicPostIgnor_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Duplicate POST (Ignore) + +## Non-Happy Path Use Case Variations + +### Perform Transfer - PayeeFSP Rejects Transfer + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which a Transfer request rejected by the Payee is terminated. + +#### Flow Diagram + +![Use Case - Perform Transfer - PayeeFSP Rejects Transfer](./assets/ML2RA_Trf_ucPerformTrfPayeeFspReject_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - PayeeFSP Rejects Transfer + +### Perform Transfer - Timeout (Prepare) + +#### Description + +The workflow provided by this UC enables the BC to effect a method to terminate a Transfer Prepare request where a timeout threshold is exceeded. + +#### Flow Diagram + +![Use Case - Perform Transfer - Timeout (Prepare)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPrepare_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Timeout (Prepare) + +### Perform Transfer - Timeout (Pre-Committed) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Pre-Committed Transfer request where a timeout threshold is exceeded. + +#### Flow Diagram + +![Use Case - Perform Transfer - Timeout (Pre-Committed)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPreCommit_Mar22b-P1-2.png) +>UC Workflow Diagram: Perform Transfer - Timeout (Pre-Committed) + +### Perform Transfer - Timeout (Post-Committed) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Post-Committed Transfer request where a timeout is exceeded. + +#### Flow Diagram + +![Use Case - Perform Transfer - Timeout (Post-Committed)](./assets/ML2RA_Trf_ucPerformTrfTimeoutPostCommit_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Timeout (Post-Committed) + +### Perform Transfer - Duplicate POST (None Matching) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Non-Matching Duplicate Transfer request where a timeout is exceeded. + +#### Flow Diagram + +![Use Case - Perform Transfer - Duplicate POST (None Matching)](./assets/ML2RA_Trf_ucPerformTrfTimeoutDuplicPostNoMatch_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Duplicate POST (None Matching) + +### Perform Transfer - Payer FSP Insufficient Liquidity + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer request that is failed due to the Payer having insufficient liquidity to cover the transaction fully. + +#### Flow Diagram + +![Use Case - Perform Transfer - Payer FSP Insufficient Liquidity](./assets/ML2RA_Trf_ucPayerFspInsufficientLiquid_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Payer FSP Insufficient Liquidity + +### Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer Prepare request where the transaction validation is failed due to an invalid/non-existent Payer. + +#### Flow Diagram + +![Use Case - Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant)](./assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayer_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Transfer Prepare Validation Failure (Invalid Payer Participant) + +### Perform Transfer - Transfer Prepare Validation Failure (Invalid Payee Participant) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer Prepare request where the transaction validation is failed due to an invalid/non-existent Payee. + +#### Flow Diagram + +![Use Case - Perform Transfer - Transfer Prepare Validation Failure (Invalid Payee Participant)](./assets/ML2RA_Trf_ucTransferPrepValidationFail-InvalidPayee_Mar22a.png) +>UC Workflow Diagram: Perform Transfer - Transfer Prepare Validation Failure (Invalid Payee Participant) + +### Query (GET) Transfer - Validation Failure (Invalid Payer Participant) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer status query where validation fails due to an invalid/non-existent Payer. + + + +### Query (GET) Transfer - Validation Failure (Invalid Payee Participant) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer status query where validation fails due to an invalid/non-existent Payee. + + + +### Query (GET) Transfer - Validation Failure (Transfer Identifier Not Found) + +#### Description + +The workflow provided by this UC enables the BC to effect a method through which to terminate a Transfer status query where validation fails due to a Transfer Identifier Token not being found. + + + +## Canonical Model + +Mojaloop uses two canonical models to manage funds transfers, one for non-bulk transfers, and one for bulk transfers. + +### Standard Canonical Model + +* Transfer + * transferId + * transferType + * quoteld (optional) + * settlementModelId + * Participants + * Payer + * participantId + * Accounts + * Debit + * accountId + * accountType + * currency + * Credit + * accountId + * accountType + * currency + * Payee + * ParticipantId + * Accounts + * Debit + * accountId + * accountType + * currency + * Credit + * accountId + * accountType + * currency + * Amount (Amount to transfer) + * value (number) + * currency (ISO currency code) + * expiration (ISO dateTime) + * ilpPacket + * Extensions + +### Bulk Canonical Model + +* Transfers + * bulkId + * bulkQuoteId + * Transfers[] + * Transfer* (see above) + +## Concluding Comments + +* The Payer FSP should not be permitted to unilaterally time-out a transfer (irrespective of its expiration time), but should respect the Switch's timeout decisions. +* Validation of cryptographic conditions and fulfillment would be managed by the Transfers BC as it is a fundamental component of the "transfer" process (i.e.: function is not specific to the FSPIOP language) +* The Transfers BC will apply the same validation pattern as the Quoting & Party BC to validate Participants, to determine the ability of an Account to transact, or if a Participant is enabled as mutually exclusive. +* The Transfers BC is the single "source of truth" for all transfers, and is thus responsible for persisting the state/s of transfer's. +* Disabling Participants already in a "prepared" state should not hinder processing of current transfers, however new transfer instructions received by the Transfers BC via the TransferPrepareAccountAllocated events should be declined. + + + + +[^1]: Common Interfaces: [Mojaloop Common Interface List](../../commonInterfaces.md) diff --git a/docs/technical/reference-architecture/furtherReading/README.md b/docs/technical/reference-architecture/furtherReading/README.md new file mode 100644 index 000000000..ec9b22012 --- /dev/null +++ b/docs/technical/reference-architecture/furtherReading/README.md @@ -0,0 +1,55 @@ +# Further Reading + +## Team Resources + +During the Reference Architecture planning work sessions, the Team made use of different resources to build and retain a record of discussions and to build the Use Case Models required to support all of the possible stakeholder requirements for the new architecture. + +Please feel free to visit the Team’s resources using the links provided. + +**P.S.** One resource that you might find particularly useful is Miro, where we keep a record of all of the Bounded Context Use Cases in use by the system. + +***Note:** Please bear in mind that the Reference Architecture document is a living document, and as a result is updated from time to time for various reasons. This means that the resources that we have shared with you are still in use and will change occasionally.* + +| Resource | Purpose | Link/URL | +| --- | --- | --- | +| Miro | Build Use Case flow diagrams | [Miro - Mojaloop Reference Architecture](https://miro.com/app/board/o9J_lJyA1TA=/) | +| Google Docs | Session work notes for the team providing details of Reference Architecture for inclusion in the proposal and introductory documentation. | [Mojaloop 2.0 Reference Architecture Work Sessions](https://docs.google.com/document/d/1Nm6B_tSR1mOM0LEzxZ9uQnGwXkruBeYB2slgYK1Kflo/edit#heading=h.vymmtvqaio5b) | +| Google Sheets | Record of Common Interfaces in use in the Switch architecture, along with various other bits and pieces. | [Mojaloop 2.0 Reference Architecture](https://docs.google.com/spreadsheets/d/1ITmAesHjRZICC0EUNV8vUVV8VDnKLjbSKu_dzhEa5Fw/edit#gid=1810993431) + +## Reference Articles and Documents + +The resources below were sourced to provide additional insight into the architecture models that have been implemented. + +| Resource | Details | +| --- | --- | +|[*Domain-Driven Design*, from Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Domain-driven_design) | Publisher: Wikipedia, the free encyclopedia; Author: Community; Date: non-specific; ±7mins to read | +| [*Domain, Subdomain, Bounded Context, Problem/Solution Space in DDD: Clearly Defined*](https://medium.com/nick-tune-tech-strategy-blog/domains-subdomain-problem-solution-space-in-ddd-clearly-defined-e0b49c7b586c) | Publisher: Medium.com; Author: Nick Tune; Date: 11/07/2020; ±7mins to read | +| [*Strategic Domain-Driven Design*](https://microservices.io/patterns/decomposition/decompose-by-subdomain.html) | Publisher: Vaadin.com; Author: Petter Holmstrom | +| [*Pattern: Decompose by Subdomain Context*](https://microservices.io/patterns/decomposition/decompose-by-subdomain.html) | Publisher: Microservices Architecture; Author: Chris Richardson | +| [*Rest API Tutorial*](https://www.restapitutorial.com/) | Publisher: Self-published; Author: Todd Fredrich; License: [Creative Commons Attribution ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) | +| [*Use Case*, from Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Use_case) | In brief, and quoting from the opening blurb of the Wikipedia article, a use case is a list of actions or event steps typically defining the interactions between a role (known in the Unified Modeling Language (UML) as an actor) and a system to achieve a goal. The actor can be a human or other external system. In systems engineering, use cases are used at a higher level than within software engineering, often representing missions or stakeholder goals. The detailed requirements may then be captured in the Systems Modeling Language (SysML) or as contractual statements. | + +## Project Iteration Convenings + +The resources below are inclusions to the Mojaloop Technical Convenings by the Reference Architecture Team starting at the beginning of 2021. Resources include notes, slides, and video recordings. + +| Project Iteration (PI) | Period | Description | Link/URL | +| --- | --- | --- | --- | +| PI-13 | January 2021 | Mojaloop Performance, Scalability and Architecture Update | [PI-13 Slides & Recording](https://community.mojaloop.io/t/mojaloop-performance-scalability-and-architecture-update/240) | +| PI-14 | April 2021 | Opening and Mojaloop Reference Architecture and TigerBeetle | [PI-14 Recording (YouTube)](https://www.youtube.com/watch?v=UHxULJXIzj8) | +| PI-15 | July 2021 | Reference Architecture v1.0 | [PI-15 Resources](https://mojaloopcommunitymeeting.us2.pathable.com/meetings/virtual/ookcbEc6aDZgwyo2n) / [PI-15 Video Library (YouTube)](https://www.youtube.com/playlist?list=PLSamWCIlxVXujHm4CWfyl6uLzcXJE1Zi_) | +| PI-16 | October 2021 | Reference Architecture and V2 update | [PI-16 Agenda](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/pi_16_october_2021) / [PI-16 Video Library](https://mojaloop.io/video/pi-16-mojaloop-community-meeting-technical-sessions-october-2021/) | +| PI-17 | January 2022 | Reference Architecture: Documentation and v.Next Updates | [PI-17 Reference Architecture Presentation (YouTube)](https://youtu.be/kqbEVbglBEM) | + + \ No newline at end of file diff --git a/docs/technical/reference-architecture/gettingStarted/README.md b/docs/technical/reference-architecture/gettingStarted/README.md new file mode 100644 index 000000000..687ff3899 --- /dev/null +++ b/docs/technical/reference-architecture/gettingStarted/README.md @@ -0,0 +1,6 @@ +# Getting Started + +To help get you started with the Mojaloop Reference Architecture, select which of the options below best suits your needs: + +1. [Sub-menu](./subMenu/) +2. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) diff --git a/docs/technical/reference-architecture/gettingStarted/subMenu/README.md b/docs/technical/reference-architecture/gettingStarted/subMenu/README.md new file mode 100644 index 000000000..ffdfdf924 --- /dev/null +++ b/docs/technical/reference-architecture/gettingStarted/subMenu/README.md @@ -0,0 +1,11 @@ +# Sub Menu + +Some text. + +## Sub title 1 + +Some more text. + +## Sub title 2 + +Some more text. diff --git a/docs/technical/reference-architecture/glossary/README.md b/docs/technical/reference-architecture/glossary/README.md new file mode 100644 index 000000000..ebf7390bd --- /dev/null +++ b/docs/technical/reference-architecture/glossary/README.md @@ -0,0 +1,14 @@ +# TBD Placeholder + + \ No newline at end of file diff --git a/docs/technical/reference-architecture/howToImplement/README.md b/docs/technical/reference-architecture/howToImplement/README.md new file mode 100644 index 000000000..cd51378ea --- /dev/null +++ b/docs/technical/reference-architecture/howToImplement/README.md @@ -0,0 +1,2 @@ +# TBD Placeholder for vNext Implementation architecture + diff --git a/docs/technical/reference-architecture/index.md b/docs/technical/reference-architecture/index.md new file mode 100644 index 000000000..98f223627 --- /dev/null +++ b/docs/technical/reference-architecture/index.md @@ -0,0 +1,17 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: This is the official Reference Architecture documentation for the Mojaloop project. + + +actionText: Introduction → +actionLink: /introduction/ + +features: +- title: What it is + details: In a software system, a Reference Architecture is a set of software design documents, that capture the essence of the product and provide guidance to its technical evolution. The Reference Architecture is the architectural vision of the perfect design. +- title: Objectives + details: Identify abstractions, interfaces and standardization opportunities; Solutions and patterns to common problems; Enforces technical design principles; Provides guidance to the implementation architectures; Foster's innovation and contribution, by defining what can be done and how +- title: Benefits + details: Foundation for a Technical Roadmap; Guidance to decision-making regarding technology choices and implementation strategies; Alignment between technical vision and product vision +--- diff --git a/docs/technical/reference-architecture/introduction/assets/process.png b/docs/technical/reference-architecture/introduction/assets/process.png new file mode 100644 index 000000000..55e8cf7ed Binary files /dev/null and b/docs/technical/reference-architecture/introduction/assets/process.png differ diff --git a/docs/technical/reference-architecture/introduction/index.md b/docs/technical/reference-architecture/introduction/index.md new file mode 100644 index 000000000..004ac437c --- /dev/null +++ b/docs/technical/reference-architecture/introduction/index.md @@ -0,0 +1,109 @@ +# Introduction + +## What is a Reference Architecture? + +In a software system, the Reference Architecture is a set of software design documents that capture the essence of the product and provide guidance to its technical evolution. + +This concept can be further simplified: + +_**The Reference Architecture is the architectural vision of the perfect design.**_ + +In normal conditions that perfect design is never achieved, partly because there is neither enough time nor resources to fully implement it, partly because that design can iterate and improve faster than it can be implemented. +It is the nature of a Reference Architecture to be a living document that is continuously updated and enhanced. + +## What are the objectives of the Reference Architecture + +The main objectives of the Reference Architecture are to: + +* Identify abstractions, interfaces and standardization opportunities +* Propose solutions and patterns to common problems +* Help enforcing technical design principles +* Provide guidance to the implementation architectures +* Foster innovation and contribution, by defining what can be done and how + +## What are the benefits of having a Reference Architecture + +The first benefit is that it is the perfect foundation for a Technical Roadmap. By having the future vision in perspective, a phased Technical Roadmap can easily be created from it, ensuring resources and attention are focused on the long term value. + +Another important benefit is the guidance it provides to decision-making regarding technology choices and implementation strategies. +With the Reference Architecture in mind we can frame any development decision as tactical or strategic: + +* Tactical - something that is required right now which may have exceptions to the Reference Architecture for the sake of a high-value urgent requirement. These exceptions should be documented as technical debt which can be addressed in future. +* Strategic - something that is long-lasting and should be implemented in accordance to the Reference Architecture - should take the implementation closer to it. + +Last but not less important, it ensures alignment between the technical vision and the more important product vision (see below regarding the process and ways of working). + +## Process of creating and maintaining the Reference Architecture + +While creating the initial version of the Reference Architecture, the team followed these steps: + +1. Problem Space mapping - Document the different problem domains and subdomains, and how they are classified according to their importance +2. Solution Space Context mapping - Group similar problems together based on their purpose and context +3. Individual use case mapping - Discuss and document use cases in detail taking into consideration the entire solution + +## How to keep a Reference Architecture up-to-date + +The diagram below shows where a reference architecture exists in reference to other processes of the Mojaloop Platform; what it must incorporate and understand, not only the vision and the principles, but also the requirements, previous experience and even forster technical innovation. + +![Perform Transfer (Universal Mode)](./assets/process.png) +> Introduction (Mojaloop 2.0 Reference Architecture): How to keep the Reference Architecture up to date + + +## Principles guiding this architecture + +The Mojaloop 2.0 Reference Architecture design has been guided by Domain-Driven Design[^1] principles, and inspired by SOLID[^2] object-oriented programming principles for building software applications, especially the single responsibility principle (SRP). + +To provide an understanding of the architecture interpretation by Mojaloop, we include a brief overview of Domain Driven Design architecture. + +### DDD Inspired Architecture Overview + +The DDD Inspired architecture implementation for Mojaloop includes the following concepts: + +* **Problem Space** - Typically DDD-architecture recognises business requirements as belonging to separate domains. For example an eCommerce system is seen as a **_Domain_**. But an eCommerce system has several components in order to work such as an inventory, a shopping cart, checkout, etc. Each component is categorised as a **_Subdomain_** that contributes value to the domain which is the eCommerce system. Mojaloop uses a single domain - it is a switch. + + The Problem Space is one of two containers where all of the identified business problems (improvements/services) that need to be solved are contained. Depending on the complexity of the Business Problem (improvement), or indeed the scale of problems needing to be solved, it is possible to devolve the initial subdomain structure into additional Subdomains. Each problem is assigned to its own Subdomain. Care should be exercised however, to ensure that each Subdomain is absolutely necessary, and focused on delivering value to the domain to avoid an unnecessary and confusing plethora of Subdomains filling the Problem Space. + + Each improvement/service thus contained in a separate Subdomain allows for different teams to develop manageable chunks of the system which is more efficient and less risk-prone than building an entire system in one structure. A sizable benefit to this approach is that the entire development process can be centered around improving and adding value to the platform, and not just adding features. + + Typically, the Problem Space includes three containers which broadly indicate how, or what is going to be used to solve a particular problem, to which a fourth container has been added for Non-Functional Requirements (NFRs) - + + * Core - solutions dependent on internal builds for completion. + * Supporting - solutions that can be implemented using off the shelf products - for example, secure login. + * Generic - solutions that can use off the shelf products, but which need additional coding to implement, not just integration - for example, reporting and authentication + * Non-functional Requirements (NFRs) - solutions that are required to address common needs, but that do not contribute directly to the value of the product + +* **Solution Space** - A second major component of DDD-Architecture is the Solution Space. It differs from the Problem-Space in that its focus is not on what to solve, but how a problem (improvement/service) is going to be solved, and how the multiple solutions relate to each other. The Solution Space thus necessarily includes more technical information and details for how the problems should be solved. + + * The Solution Space introduces a number of elements to aid and align problem-solving development efforts + + * Bounded Contexts were introduced to group cohesive sets of solutions with its specific language. + + Often mapping between Bounded Contexts and Subdomains will not be one-to-one. As Subdomains belong to the Problem Space and Bounded Contexts to the Solution Space, it is quite possible that scenarios will occur where a Subdomain are solved by more than one Bounded Context, or where a Bounded Context may solve multiple Subdomains. + + Typically, and definitely in the Mojaloop environment, solutions are designed and implemented without knowledge of specific infrastructure dependencies or other inner workings of other Bounded Contexts. This approach aids security, amongst other things by ensuring that each Bounded Context is only aware of its own environment, and its interfaces. Communications between Bounded Contexts are all conducted via APIs and secured messaging. Examples of Bounded Contexts (BCs) from the Mojaloop environment include Accounts \& Balances, Transfers \& Transactions, etc. + +* **_Ubiquitous Language_** is an approach to encourage explicit, and commonly understood, language that everyone uses when describing problems and solutions, from end users to developers. There are two main objectives for a Ubiquitous Language: + + 1. It ensures that unique terms are identified and understood to have a single meaning by all parties within its Bounded Context. An example might include the word, “Account”, which could be understood as an Account Profile by one party, and a reference to an Accounting System Account by another. This is not a recommendation to search for an impossible, project or company-wide, universal set of unambiguous terms; instead it assures that each Bounded Context has its own set of terms. + 2. It ensures that the terms of the Ubiquitous Language are present from the user interface, to documentation, to other project related materials, and even in the code. The ubiquitous usage of the same terms everywhere, including in code, guarantees that everyone has the same understanding of the problems and solutions being described and solved. + +* **_Cross Cutting Concerns_**[^3] are aspects of a software solution that must be solved by multiple Bounded Contexts (or functions/modules) and include items such as auditing, security, authentication, and platform (Business and Technical) configuration management. Our approach to these Cross Cutting Concerns, was to separate them from the BC's. Most Cross Cutting Concerns have a distributed nature in this design, with central components and client libraries. These are represented in this documentation as equivalent to Bounded Contexts. + +### SOLID Principles + +In addition to DDD-architecture, Mojaloop’s architecture approach has also been inspired by SOLID principles: + +* Single responsibility and internal interfaces provide the ability to implement additional Domains, such as ISO, without needing to change the core architecture +* Software entities should be extended but never modified. The rule is never hack core, always extend through add-on modules or nodes +* Functions using references to base classes should be able to use objects of derived classes without being aware of it +* Several client-specific interfaces are better than a single all-purpose interface +* Build dependencies on abstractions, not concretions + + +### Notes + +[^1]: Further reading: [Domain-driven design From Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Domain-driven_design) + +[^2]: Further reading: [SOLID From WIkipedia, the free encyclopedia](https://en.wikipedia.org/wiki/SOLID) + +[^3]: Further reading: [Cross-cutting Concern](https://en.wikipedia.org/wiki/Cross-cutting_concern#:~:text=Cross%2Dcutting%20concerns%20are%20parts,oriented%20programming%20or%20procedural%20programming.) - Publisher: Wikipedia, the free encyclopedia diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png new file mode 100644 index 000000000..6402dc462 Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png differ diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png new file mode 100644 index 000000000..17b11b5ab Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png differ diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png new file mode 100644 index 000000000..523373d7a Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png differ diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png new file mode 100644 index 000000000..4034289ad Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png differ diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png new file mode 100644 index 000000000..8ad905989 Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png differ diff --git a/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png new file mode 100644 index 000000000..5d2299425 Binary files /dev/null and b/docs/technical/reference-architecture/refarch/assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png differ diff --git a/docs/technical/reference-architecture/refarch/index.md b/docs/technical/reference-architecture/refarch/index.md new file mode 100644 index 000000000..9697a7531 --- /dev/null +++ b/docs/technical/reference-architecture/refarch/index.md @@ -0,0 +1,113 @@ +# Mojaloop Reference Architecture Overview + +## Problem Space (_Problem space identification and map)_ + +As noted in the DDD-architecture overview, the Problem Space contains a number of solution-oriented containers identified by the system architects’ team which are being used to categorise subdomains where problems (improvements) have been identified. + +### Core Problems + +#### Description + +A number of Core Problems (improvements) have been identified by (Business/Developers/Both Business & Developers). In order to implement the improvements, “internal” development teams will be tasked with developing the required solutions. Typically the Subdomains thus identified generate significant value for the Mojaloop system, therefore care is taken to ensure that the services they provide are not compromised. Examples of Core Problem Subdomains include: Participant Lifecycle Management, Settlements, and Scheduling. + +#### High-Level Map + +![Core Problems](./assets/ML2RA_in_RefArchOver_Core_Apr22c_1670.png) +> Reference Architecture (Mojaloop): Core Problems + +### Generic Problems + +#### Description + +A number of Generic Problems (improvements) have been identified by (Business/Developers/Both Business & Developers). In order to implement the improvements, off-the-shelf solutions will be implemented that require no further customization. They will require integration with the Mojaloop. Examples of Generic problem subdomains include Authentication, FRMS, and Platform Monitoring. + +#### High-Level Map + +![Generic Problems](./assets/ML2RA_in_RefArchOver_Generic_Apr22c_1670.png) +> Reference Architecture (Mojaloop): Generic Problems + +### Supporting Problems + +#### Description + +A number of Supporting Problems (improvements) have been identified by (Business/Developers/Both Business & Developers). In order to implement the improvements, off-the-shelf solutions will be implemented, however in order to fully integrate them with the Mojaloop system and satisfy the identified problems (improvements) additional customization will be required for each of the integrated solutions. Examples of Supporting Problem Subdomains include Access Policy Management, Reporting, and Authorization (Access Policy content verification). + +#### High-Level Map + +![Supporting Problems](./assets/ML2RA_in_RefArchOver_Supporting_Apr22c_1670.png) +> Reference Architecture (Mojaloop): Supporting Problems + +### Non-Functional Requirements + +#### Description + +A number of Non-Functional Requirements have been identified by (Business/Developers/Both Business & Developers). Whilst they do not add direct value to Mojaloop, they are required in order to fulfil a number of business-related problems (improvements). Examples of Non-Functional Requirements include security which does not occupy its own subdomain. All system Subdomains will need to include elements of code pertaining to security in fulfillment of this requirement, alternatively, a central security management service will be implemented that includes centrally managed and constructed security profiles for each Subdomain in the system which they will download upon joining the Domain, or upon initiation, and/or which will be pushed down to them from the central service when updates occur. + +#### High-Level Map + +![Non-Functional Requirements](./assets/ML2RA_in_RefArchOver_NFRs_Apr22c_1670.png) +> Reference Architecture (Mojaloop): Non-Functional Requirements + +### New and Unclassified (non-domain) + +#### Description + +A number of New and Unclassified (non-domain) problems have been identified by both Business and Developers). Once Business and the System Architects have identified the required solution in order to solve the problem, they will be classified into one of the Problem containers and fulfilled in accordance with its processes. + +#### High-Level Map + +![New & Unclassified Problems](./assets/ML2RA_in_RefArchOver_newUnclassified_Apr22c_1670.png) +> Reference Architecture (Mojaloop): New and Unclassified Problems + +## Solution Space (_High level description and the context map)_ + +#### Description + +The Solution Space defined by DDD-architecture is focused on how the business problems (improvements) identified in the Problem Space are going to be solved. As a result it necessarily contains more information and technical details than the Problem Space. It includes elements such as Ubiquitous Language, Bounded Contexts, and Cross-Cutting Concerns. + +#### High-Level Map + +![Solution Space](./assets/ML2RA_in_RefArchOver_SolutionSpace_Apr22a.png) +> Reference Architecture (Mojaloop): Solution Space + +### Ubiquitous Language + +#### Description + +A challenge that most teams face is maintaining a clear understanding of terms that may not be unique with a particular Domain. A classic example of a non-unique term is “account”: this term could refer to a set of financial accounts, entity profile, or a login name. + +As noted in the overview, Ubiquitous Language is used to aid in the elimination of confusion and miscommunication between business and technical teams working to solve a business problem or group of business problems. Whilst it is possible that that each Domain/Subdomain may contain terms that are not unique, as noted above, within a particular context, and in the instance of DDD-architecture, that would be a Bounded Context, it is important to ensure that all terms are unique, clearly understood by all participants, and correctly applied. + +For insights and a description of each of the unique language terms used in the Mojaloop Domain, please refer to the [Glossary](../glossary/README.md) appended to this document. + +### Bounded Contexts + +The following Bounded Contexts have been identified and implemented in Mojaloop: + +> This is a high-level description of each of the Bounded Contexts that have been identified and included in the Mojaloop Reference Architecture. A more detailed view follows in the [Bounded Context](../boundedContexts/index.md) section of this document. + +| Bounded Context | Purpose | Bounded Context | Purpose | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Settlements | Performs Settlements
    Configures settlement models
    Calculate Settlements | Participant Lifecycle Management | Participant Onboarding
    Participant Lifecycle Management
    Participant Self-service
    Participant Self-service UI | +| Account Lookup & Discovery | Internal Oracle core
    Account lookup / discovery
    Bulk transactions
    Duplicate Identifier management
    Inter-scheme connections (incl. settlements) cross-border | Accounts & Balances | System of record of DFSP participant financial activity & balance | +| Transfers & Transactions | Transfer processing
    Liquidity check for each transfer
    Bulk transactions
    Multi-currency, incl.multi-hop transactions | Agreement (Quoting) | Agreement /quoting (core)
    Bulk transactions
    Multi-currency, incl.multi-hop transactions
    Scheme Rule/Patterns Enforcement Happens in each BC | +| Scheduling | Scheduling time-based events of API calls (Core) | Notifications & Alerts | Notification state - priority & SLA aware (Core)
    Trigger & alert management (Core)
    Notifications delivery - priority and SLA aware (Generic) | +| FSP Interop APIs | ISO External API (Bulk; API, Callbacks triggering (transfers only, Missing in AS-IS) | Third Party Initiated Payments | PISP Account Linking
    Consent Management
    3rd Party Payment Initiation (Core) | +| Third party API | | PISP Mojaloop External API
    PISP ISO External API | | + +### Cross cutting concerns + +The following Cross cutting concerns have been identified in Mojaloop: + +| Cross Cutting Concern BC | Purpose | +| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AuthZ & AuthN and Identity Management BC | Manage all aspects of both user and system authentication (AuthN) and authorization (AuthZ). Planned solutions will fit into the Generic and Supporting categories | +| Cryptographic BC | Manage all cryptographic related services including Key and Certificate Management and Storage Systems. Planned solutions will fit into the Generic category. | +| Reporting and Auditing BC | Manage all audit and reporting services including Compliance and Assurance Reporting, Forensic Event Logging and KMS, Forensic Event Log Access and Management, Process Monitoring and SLAs, and System Auditing. (Each BC will include auditing capability. The Reporting and Auditing BC will retain logs from all of the BCs). Planned solutions will fit into all of the Problem Space categories: Core, Supporting, and Generic. | +| Platform Configuration (Business) BC | Manage Scheme rule/patterns management process (Note; Scheme rule/patterns enforcement is maintained in each BC), Scheme mandated transaction patterns, application management and security, identity and access management (including user and team management), bizops API linking consent management, and access policy management. Planned solutions will fit into all of the Problem Space categories: Core, Supporting, and Generic | +| Technical Platform Management BC | Manage platform monitoring, and platform management. Planned solutions will fit into the Generic category. | + + + \ No newline at end of file diff --git a/docs/technical/technical/account-lookup-service/README.md b/docs/technical/technical/account-lookup-service/README.md new file mode 100644 index 000000000..4475e8255 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/README.md @@ -0,0 +1,128 @@ +--- +version: 1.1 +--- + + +# Account Lookup Service + +The **Account Lookup Service** (**ALS**) _(refer to section `6.2.1.2`)_ as per the [Mojaloop {{ $page.frontmatter.version }} Specification](/api) implements the following use-cases: + +* Participant Look-up +* Party Look-up +* Manage Participants Registry information + * Adding Participant Registry information + * Deleting Participant Registry information + +Use-cases that have been implemented over and above for Hub Operational use: +* Admin Operations + * Manage Oracle End-point Routing information + * Manage Switch End-point Routing information + +## 1. Design Considerations + +### 1.1. Account Lookup Service (ALS) +The ALS design provides a generic Central-Service component as part of the core Mojaloop. The purpose of this component is to provide routing and alignment to the Mojaloop API Specification. This component will support multiple Look-up registries (Oracles). This ALS will provide an Admin API to configure routing/config for each of the Oracles similiar to the Central-Service API for the End-point configuration for DFSP routing by the Notification-Handler (ML-API-Adapter Component). The ALS will in all intense purpose be a switch with a persistence store for the storage/management of the routing rules/config. + +#### 1.1.1. Assumptions + +* The ALS design will only cater for a single switch for the time being. +* Support for multiple switches will utilise the same DNS resolution mechanism that is being developed for the Cross Border/Network design. + +#### 1.1.2. Routing + +The routing configuration will be based on the following: +* PartyIdType - See section `7.5.6` of the Mojaloop Specification +* Currency - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, however `isDefault` indicator must be set to `true` if the `Currency` is not provided. +* isDefault - Indicator that a specific Oracle is the default provider for a specific PartyIdType. Note that there can be many default Oracles, but there can only be a single Oracle default for a specific PartyIdType. The default Oracle for a specific PartyIdType will only be selected if the originating request does not include a Currency filter. + + +### 1.2. ALS Oracle +The ALS Oracle be implemented as either a **Service** or **Adapter** (semantic dependant on use - Mediation = Adapter, Service = Implementation) will provide a look-up registry component with similar functionality of the `/participants` Mojaloop API resources. It has however loosely based on the ML API specification as it's interface implements a sync pattern which reduces the correlation/persistence requirements of the Async Callback pattern implemented directly by the ML API Spec. This will provide all ALS Oracle Services/Adapters with a standard interface which will be mediated by the ALS based on its routing configuration. +This component (or back-end systems) will also be responsible for the persistence & defaulting of the Participant details. + +## 2. Participant Lookup Design + +### 2.1. Architecture overview +![Architecture Flow Account-Lookup for Participants](./assets/diagrams/architecture/arch-flow-account-lookup-participants.svg) + +_Note: The Participant Lookup use-case similarly applies to for a Payee Initiated use-case such as transactionRequests. The difference being that the Payee is the initiation in the above diagram._ + +### 2.2. Sequence diagrams + +#### 2.2.1. GET Participants + +- [Sequence Diagram for GET Participants](als-get-participants.md) + +#### 2.2.2. POST Participants + +- [Sequence Diagram for POST Participants](als-post-participants.md) + +#### 2.2.3. POST Participants (Batch) + +- [Sequence Diagram for POST Participants (Batch)](als-post-participants-batch.md) + +#### 2.2.4. DEL Participants + +- [Sequence Diagram for DEL Participants](als-del-participants.md) + +## 3. Party Lookup Design + +### 3.1. Architecture overview +![Architecture Flow Account-Lookup for Parties](./assets/diagrams/architecture/arch-flow-account-lookup-parties.svg) + +### 3.2. Sequence diagram + +#### 3.2.1. GET Parties + +- [Sequence Diagram for GET Parties](als-get-parties.md) + +## 4. ALS Admin Design + +### 4.1. Architecture overview +![Architecture Flow Account-Lookup for Admin Get Oracles](./assets/diagrams/architecture/arch-flow-account-lookup-admin.svg) + +### 4.2. Sequence diagram + +#### 4.2.1 GET Oracles + +- [Sequence Diagram for GET Oracles](als-admin-get-oracles.md) + +#### 4.2.2 POST Oracle + +- [Sequence Diagram for POST Oracle](als-admin-post-oracles.md) + +#### 4.2.3 PUT Oracle + +- [Sequence Diagram for PUT Oracle](als-admin-put-oracles.md) + +#### 4.2.4 DELETE Oracle + +- [Sequence Diagram for DELETE Oracle](als-admin-del-oracles.md) + +#### 4.2.5 DELETE Endpoint Cache + +- [Sequence Diagram for DELETE Endpoint Cache](als-del-endpoint.md) + +## 5. Database Design + +### 5.1. ALS Database Schema + +#### Notes +- `partyIdType` - Values are currently seeded as per section _`7.5.6`_ [Mojaloop {{ $page.frontmatter.version }} Specification](./api). +- `currency` - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, and must provide a "default" config if no Currency is either provided or provide a default if the Currency is provided, but only the "default" End-point config exists. +- `endPointType` - Type identifier for the end-point (e.g. `URL`) which provides flexibility for future transport support. +- `migration*` - Meta-data tables used by Knex Framework engine. +- A `centralSwitchEndpoint` must be associated to the `OracleEndpoint` by the Admin API upon insertion of a new `OracleEndpoint` record. If the `centralSwitchEndpoint` is not provided as part of the API Request, then it must be defaulted. + +![Acount Lookup Service ERD](./assets/entities/AccountLookupService-schema.png) + +* [Acount Lookup Service DBeaver ERD](./assets/entities/AccountLookupDB-schema-DBeaver.erd) +* [Acount Lookup Service MySQL Workbench Export](./assets/entities/AccountLookup-ddl-MySQLWorkbench.sql) + +## 6. ALS Oracle Design + +Detail design for the Oracle is out of scope for this document. The Oracle design and implementation is specific to each Oracle's requirements. + +### 6.1. API Specification + +Refer to **ALS Oracle API** in the [API Specifications](../../api/README.md#als-oracle-api) section. diff --git a/docs/technical/technical/account-lookup-service/als-admin-del-oracles.md b/docs/technical/technical/account-lookup-service/als-admin-del-oracles.md new file mode 100644 index 000000000..3dd7369f3 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-admin-del-oracles.md @@ -0,0 +1,8 @@ +# DELETE Oracles + +Design for the Deletion of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-admin-get-oracles.md b/docs/technical/technical/account-lookup-service/als-admin-get-oracles.md new file mode 100644 index 000000000..f0c687f5e --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-admin-get-oracles.md @@ -0,0 +1,8 @@ +# GET Oracles + +Design for getting a list of all Oracle Endpoints by the Hub Operator with the option of querying but currency and/or type. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-admin-post-oracles.md b/docs/technical/technical/account-lookup-service/als-admin-post-oracles.md new file mode 100644 index 000000000..c78539207 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-admin-post-oracles.md @@ -0,0 +1,8 @@ +# POST Oracles + +Design for the creation of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-admin-put-oracles.md b/docs/technical/technical/account-lookup-service/als-admin-put-oracles.md new file mode 100644 index 000000000..d7e0de1ad --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-admin-put-oracles.md @@ -0,0 +1,8 @@ +# PUT Oracles + +Design for the Update of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-del-endpoint.md b/docs/technical/technical/account-lookup-service/als-del-endpoint.md new file mode 100644 index 000000000..431848981 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-del-endpoint.md @@ -0,0 +1,8 @@ +# DELETE Endpoint Cache + +Design for the disabling of an Oracle by the Hub Operator. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-del-participants.md b/docs/technical/technical/account-lookup-service/als-del-participants.md new file mode 100644 index 000000000..54eebd7c5 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-del-participants.md @@ -0,0 +1,11 @@ +# DEL Participants + +Design for the deletion of a Participant by a DFSP. + +## Notes +- Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. ~ This has been addressed in the design by insuring that the Party currently belongs to the FSPs requesting the deletion of the record. Any other validations are out of scope for the Switch and should be addressed at the schema level. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-get-participants.md b/docs/technical/technical/account-lookup-service/als-get-participants.md new file mode 100644 index 000000000..d3986bfaa --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-get-participants.md @@ -0,0 +1,8 @@ +# GET Participants + +Design for the retrieval of a Participant by a DFSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-get-parties.md b/docs/technical/technical/account-lookup-service/als-get-parties.md new file mode 100644 index 000000000..ae5577fc3 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-get-parties.md @@ -0,0 +1,8 @@ +# GET Parties + +Design for the retrieval of a Party by a DFSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-post-participants-batch.md b/docs/technical/technical/account-lookup-service/als-post-participants-batch.md new file mode 100644 index 000000000..32087549f --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-post-participants-batch.md @@ -0,0 +1,14 @@ +# Sequence Diagram for POST Participants (Batch) + +Design for the creation of a Participant by a DFSP via a batch request. + +## Notes +- Operation only supports requests which contain: + - All Participant's FSPs match the FSPIOP-Source7 + - All Participant's will be of the same Currency, per the `POST /participants` call in the [Mojaloop FSPIOP API](/api/fspiop/v1.1/api-definition.html#post-participants) +- Duplicate POST Requests with matching TYPE and optional CURRENCY will be considered an __update__ operation. The existing record must be completely **replaced** in its entirety. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg) + diff --git a/docs/technical/technical/account-lookup-service/als-post-participants.md b/docs/technical/technical/account-lookup-service/als-post-participants.md new file mode 100644 index 000000000..8f3caff9e --- /dev/null +++ b/docs/technical/technical/account-lookup-service/als-post-participants.md @@ -0,0 +1,8 @@ +# POST Participant + +Design for the creation of a Participant by a DFSP via a request. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg) + diff --git a/mojaloop-technical-overview/central-settlements/assets/.gitkeep b/docs/technical/technical/account-lookup-service/assets/.gitkeep similarity index 100% rename from mojaloop-technical-overview/central-settlements/assets/.gitkeep rename to docs/technical/technical/account-lookup-service/assets/.gitkeep diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg new file mode 100644 index 000000000..d46ffa284 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service Admin
    (ALS)
    Account Lookup Service Adm...
    HUB
    Backend



    HUB...
    Account Lookup Admin
    Account Lookup Admin
    HUB Operator
    HUB Operator
    A1. Request Oracle Endpoints 
    GET /oracles
    A1. Requ...
    A1.3. Return List of Oracles
    A1.3. Re...
    ALS
    DB
    ALS...
    Key
    Key
    A1.2. Lookup All Oracle Registry Service End-points 
    API
    Internal Use-Only
    API...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg new file mode 100644 index 000000000..2bb5d7029 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Participants Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A5. Retrieve Participant End-points GET /participants/<participantId>/endpoints
    A1. Request Participant Lookup
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A3. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A4. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A7. User Lookup
    PUT /participants/<idType>/<id>
    A7. User Lookup <br>PUT /participants/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A6. Retrieve Participant End-point Data
    A6. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    A2. Lookup Oracle Adapter/Service End-points based on <idType>
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg new file mode 100644 index 000000000..0dd8b76e6 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Parties Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    A10. Get 
    receiver 
    details
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A7. Retrieve PayeeFSP Participant End-pointsGET /participants/<participantId>/endpoints
    A1. Request Party Lookup
    GET /parties/<idType>/<id>
    [Not supported by viewer]
    A4. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A9. User Lookup
    GET /parties/<idType>/<id>
    A9. User Lookup <br>GET /parties/<idType>/<id>
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A5. Alt
    [Not supported by viewer]

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A5. Alt
    A5. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A5. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A11. User Lookup
    PUT /parties/<idType>/<id>
    A11. User Lookup <br>PUT /parties/<idType>/<id>
    A14. User Lookup
    PUT /parties/<idType>/<id>
    A14. User Lookup <br>PUT /parties/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A8. Retrieve Participant End-point Data
    A8. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    A3. Lookup Oracle Registry ServiceEnd-points based on <idType>A12. Retrieve PayerFSP Participant End-pointsGET /participants/<participantId>/endpointsA6. Retrieve PayeeFSP Data for ValidationGET /participants/<participantId>(retrieve FSP Data)
    A13. Retrieve Participant End-point Data
    <font style="font-size: 13px">A13. Retrieve Participant End-point Data</font>
    \ No newline at end of file diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml new file mode 100644 index 000000000..3a6a6eecb --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.4 Delete Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "DELETE Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Delete Oracle Endpoint -\nDELETE /oracles/{ID} + activate ALSADM + + ALSADM -> ORC_HANDLER: Delete Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Update existing Oracle Endpoint By ID + hnote over DB #lightyellow + Update isActive = false + end note + alt Delete existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Success + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + alt Delete existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Throws Error (Not Found) + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg new file mode 100644 index 000000000..c15d79f0e --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg @@ -0,0 +1,111 @@ + + 7.3.4 Delete Oracle Endpoint + + + 7.3.4 Delete Oracle Endpoint + + Account Lookup Service + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Account Lookup Service Admin API + + + Account Lookup Service Admin API + + + DELETE Oracle Handler + + + DELETE Oracle Handler + + + ALS Store + + + ALS Store + + + + + + + + + Get Oracle Endpoint + + + 1 + Request to Delete Oracle Endpoint - + DELETE /oracles/{ID} + + + 2 + Delete Oracle Endpoint + + + 3 + Update existing Oracle Endpoint By ID + + Update isActive = false + + + alt + [Delete existing Oracle Endpoint (success)] + + + 4 + Return Success + + + 5 + Return success response + + + 6 + Return + HTTP Status: + 204 + + + alt + [Delete existing Oracle Endpoint (failure)] + + + 7 + Throws Error (Not Found) + + + 8 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 9 + Return + HTTP Status: + 502 + + diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml new file mode 100644 index 000000000..b800d83f9 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.1 Get All Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "Get Oracles Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoints + OPERATOR -> ALSADM: Request to GET all Oracle Endpoints -\nGET /oracles?currency=USD&type=MSISDN + activate ALSADM + + ALSADM -> ORC_HANDLER: Get Oracle Endpoints + activate ORC_HANDLER + ORC_HANDLER -> DB: Get oracle endpoints + activate DB + + alt Get Oracle Endpoints (success) + DB --> ORC_HANDLER: Return Oracle Endpoints + deactivate DB + + deactivate DB + ORC_HANDLER -> ALSADM: Return Oracle Endpoints + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + [ + { + "oracleId": , + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + ] + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 200 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Get Oracle Endpoints (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg new file mode 100644 index 000000000..9a1ab4649 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg @@ -0,0 +1,126 @@ + + 7.3.1 Get All Oracle Endpoints + + + 7.3.1 Get All Oracle Endpoints + + Account Lookup Service + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Account Lookup Service Admin API + + + Account Lookup Service Admin API + + + Get Oracles Handler + + + Get Oracles Handler + + + ALS Store + + + ALS Store + + + + + + + + + Get Oracle Endpoints + + + 1 + Request to GET all Oracle Endpoints - + GET /oracles?currency=USD&type=MSISDN + + + 2 + Get Oracle Endpoints + + + 3 + Get oracle endpoints + + + alt + [Get Oracle Endpoints (success)] + + + 4 + Return Oracle Endpoints + + + 5 + Return Oracle Endpoints + + + Message: + { + [ + { + "oracleId": <string>, + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + ] + } + + + 6 + Return + HTTP Status: + 200 + + + alt + [Get Oracle Endpoints (failure)] + + + 7 + Throw Error + + + 8 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 9 + Return + HTTP Status: + 502 + + diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml new file mode 100644 index 000000000..083b0fac2 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml @@ -0,0 +1,112 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.2 Create Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "POST Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Create Oracle Endpoint -\nPOST /oracles + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Create Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> ORC_HANDLER: Build Oracle Endpoint Data Object + ORC_HANDLER -> DB: Insert Oracle Endpoint Data Object + activate DB + + alt Create Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 201 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Create Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg new file mode 100644 index 000000000..07b6a4441 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg @@ -0,0 +1,127 @@ + + 7.3.2 Create Oracle Endpoints + + + 7.3.2 Create Oracle Endpoints + + Account Lookup Service + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Account Lookup Service Admin API + + + Account Lookup Service Admin API + + + POST Oracle Handler + + + POST Oracle Handler + + + ALS Store + + + ALS Store + + + + + + + + + Get Oracle Endpoint + + + 1 + Request to Create Oracle Endpoint - + POST /oracles + + + Message: + { + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + + + 2 + Create Oracle Endpoint + + + + + 3 + Build Oracle Endpoint Data Object + + + 4 + Insert Oracle Endpoint Data Object + + + alt + [Create Oracle Entry (success)] + + + 5 + Return success response + + + 6 + Return success response + + + 7 + Return + HTTP Status: + 201 + + + alt + [Create Oracle Entry (failure)] + + + 8 + Throw Error + + + 9 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 10 + Return + HTTP Status: + 502 + + diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml new file mode 100644 index 000000000..142eae685 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml @@ -0,0 +1,131 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.3 Update Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "PUT Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Update Oracle Endpoint -\nPUT /oracles/{ID} + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Update Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Find existing Oracle Endpoint + alt Find existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Oracle Endpoint Result + deactivate DB + ORC_HANDLER -> ORC_HANDLER: Update Returned Oracle Data Object + ORC_HANDLER -> DB: Update Oracle Data Object + activate DB + alt Update Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Update Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end + end + alt Find existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Returns Empty Object + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg new file mode 100644 index 000000000..449542355 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg @@ -0,0 +1,170 @@ + + 7.3.3 Update Oracle Endpoint + + + 7.3.3 Update Oracle Endpoint + + Account Lookup Service + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Account Lookup Service Admin API + + + Account Lookup Service Admin API + + + PUT Oracle Handler + + + PUT Oracle Handler + + + ALS Store + + + ALS Store + + + + + + + + + + Get Oracle Endpoint + + + 1 + Request to Update Oracle Endpoint - + PUT /oracles/{ID} + + + Message: + { + "oracleIdType": <PartyIdType>, + "endpoint": { + "value": <string>, + "endpointType": <EndpointType> + }, + "currency": <Currency>, + "isDefault": <boolean> + } + + + 2 + Update Oracle Endpoint + + + 3 + Find existing Oracle Endpoint + + + alt + [Find existing Oracle Endpoint (success)] + + + 4 + Return Oracle Endpoint Result + + + + + 5 + Update Returned Oracle Data Object + + + 6 + Update Oracle Data Object + + + alt + [Update Oracle Entry (success)] + + + 7 + Return success response + + + 8 + Return success response + + + 9 + Return + HTTP Status: + 204 + + + alt + [Update Oracle Entry (failure)] + + + 10 + Throw Error + + + 11 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 12 + Return + HTTP Status: + 502 + + + alt + [Find existing Oracle Endpoint (failure)] + + + 13 + Returns Empty Object + + + 14 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 15 + Return + HTTP Status: + 502 + + diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml new file mode 100644 index 000000000..3095e7bad --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml @@ -0,0 +1,104 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.0 Delete Endpoint Cache + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS API Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service API" as ALSAPI +control "Delete Endpoint Cache Handler" as DEL_HANDLER +database "Cache" as Cache + +box "Account Lookup Service" #LightYellow +participant ALSAPI +participant DEL_HANDLER +participant Cache +end box + +' start flow + +activate OPERATOR +group Delete Endpoint Cache + OPERATOR -> ALSAPI: Request to DELETE Endpoint Cache - DELETE /endpointcache + activate ALSAPI + activate ALSAPI + + ALSAPI -> DEL_HANDLER: Delete Cache + activate DEL_HANDLER + DEL_HANDLER -> Cache: Stop Cache + activate Cache + + + alt Stop Cache Status (success) + Cache --> DEL_HANDLER: Return status + deactivate Cache + + DEL_HANDLER -> Cache: Initialize Cache + activate Cache + Cache -> DEL_HANDLER: Return Status + deactivate Cache + DEL_HANDLER -> ALSAPI: Return Status + deactivate DEL_HANDLER + ALSAPI --> OPERATOR: Return HTTP Status: 202 + + deactivate ALSAPI + deactivate OPERATOR + end + + alt Validate Status (service failure) + Cache --> DEL_HANDLER: Throw Error + deactivate Cache + DEL_HANDLER -> ALSAPI: Throw Error + deactivate DEL_HANDLER + note left of ALSAPI #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSAPI --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSAPI + deactivate OPERATOR + + + end +end + +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg new file mode 100644 index 000000000..916884be8 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg @@ -0,0 +1,120 @@ + + 7.3.0 Delete Endpoint Cache + + + 7.3.0 Delete Endpoint Cache + + Account Lookup Service + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Account Lookup Service API + + + Account Lookup Service API + + + Delete Endpoint Cache Handler + + + Delete Endpoint Cache Handler + + + Cache + + + Cache + + + + + + + + + + + Delete Endpoint Cache + + + 1 + Request to DELETE Endpoint Cache - DELETE /endpointcache + + + 2 + Delete Cache + + + 3 + Stop Cache + + + alt + [Stop Cache Status (success)] + + + 4 + Return status + + + 5 + Initialize Cache + + + 6 + Return Status + + + 7 + Return Status + + + 8 + Return + HTTP Status: + 202 + + + alt + [Validate Status (service failure)] + + + 9 + Throw Error + + + 10 + Throw Error + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 11 + Return + HTTP Status: + 502 + + diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml rename to docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg new file mode 100644 index 000000000..47aa36464 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg @@ -0,0 +1,357 @@ + + 7.1.2. Delete Participant Details + + + 7.1.2. Delete Participant Details + + Financial Service Provider + + Account Lookup Service + + Central Services + + ALS Oracle Service/Adapter + + Financial Service Provider + + + + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Account Lookup + Service (ALS) + + + Account Lookup + Service (ALS) + + + ALS Participant + Handler + + + ALS Participant + Handler + + + ALS Participant Endpoint + Oracle DAO + + + ALS Participant Endpoint + Oracle DAO + + + ALS Database + + + ALS Database + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + ALS Parties + FSP DAO + + + ALS Parties + FSP DAO + + + Central Service API + + + Central Service API + + + Oracle Service API + + + Oracle Service API + + + Payee FSP + + + Payee FSP + + + + + + + + + + + + + + + Get Party Details + + + + 1 + Request to delete Participant details + DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 202 + Error code: + 200x, 300x, 310x, 320x + + + Validate request against + Mojaloop Interface Specification. + Error code: + 300x, 310x + + + 2 + Request to delete Participant details + + + alt + [oracleEndpoint match found & parties information retrieved] + + + + 3 + Get Oracle Routing Config + Error code: + 200x, 310x, 320x + + + ref + GET Participants - + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + 4 + Request FSPIOP-Source participant information + Error code: + 200x + + + 5 + GET - /participants/{FSPIOP-Source} + Error code: + 200x, 310x, 320x + + + 6 + Return FSPIOP-Source participant information + + + 7 + Return FSPIOP-Source participant information + + + + + 8 + Validate FSPIOP-Source participant + Error code: + 320x + + + + + 9 + Validate that PARTICIPANT.fspId == FSPIOP-Source + Error code: + 3100 + + + + 10 + Get Participant Information for PayerFSP + Error code: + 200x, 310x, 320x + + + ref + GET Participants - + + Request Participant Information from Oracle Sequence + + + + + + + Validate Participant Ownership + + + + + 11 + Validate that PARTICIPANT.fspId matches Participant Information retrieved from Oracle. + Error code: + 3100 + + + 12 + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Error code: + 200x, 310x, 320x + + + 13 + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 14 + Return result + + + 15 + Return result + + + 16 + Retrieve the PayerFSP Participant Callback Endpoint + Error code: + 200x + + + 17 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Error code: + 200x, 310x, 320x + + + 18 + List of PayerFSP Participant Callback Endpoints + + + 19 + List of PayerFSP Participant Callback Endpoints + + + + + 20 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 21 + Return delete request result + + + + 22 + Callback indiciating success: + PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + [Validation failure or Oracle was unable process delete request] + + + 23 + Retrieve the PayerFSP Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 24 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 + Error code: + 200x, 310x, 320x + + + 25 + List of PayerFSP Participant Callback Endpoints + + + 26 + List of PayerFSP Participant Callback Endpoints + + + + + 27 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 28 + Handle error + Error code: + 200x, 310x, 320x + + + + 29 + Callback: PUT - /participants/{TYPE}/{ID}/error + + [Empty list of switchEndpoint results returned] + + + + + 30 + Handle error + Error code: + 200x + + Error Handling Framework + + diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml rename to docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg new file mode 100644 index 000000000..70592a767 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg @@ -0,0 +1,308 @@ + + 7.1.0. Get Participant Details + + + 7.1.0. Get Participant Details + + Financial Service Provider + + Account Lookup Service + + Central Services + + ALS Oracle Service/Adapter + + + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Account Lookup + Service (ALS) + + + Account Lookup + Service (ALS) + + + ALS Participant + Handler + + + ALS Participant + Handler + + + ALS Endpoint Type + Config DAO + + + ALS Endpoint Type + Config DAO + + + ALS Participant + Oracle DAO + + + ALS Participant + Oracle DAO + + + ALS Database + + + ALS Database + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + Central Service API + + + Central Service API + + + Oracle Service API + + + Oracle Service API + + + + + + + + + + + + + + + Get Participant's FSP Details + + + + 1 + Request to get participant's FSP details + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 202 +   + Error code: + 200x, 300x, 310x, 320x + + + Validate request against + Mojaloop Interface Specification. + Error code: + 300x, 310x + + + 2 + Request to get participant's FSP details + + + alt + [oracleEndpoint match found] + + + IMPLEMENTATION: Get Oracle Routing Config Sequence + [CACHED] + + + 3 + Fetch Oracle Routing information based on + {TYPE} and {CURRENCY} if provided + Error code: + 200x + + + 4 + Retrieve oracleEndpoint + Error code: + 200x + + oracleEndpoint + endpointType + partyIdType + currency (optional) + + + 5 + Return oracleEndpoint result set + + + 6 + List of + oracleEndpoint + for the Participant + + + opt + [oracleEndpoint IS NULL] + + + + + 7 + Error code: + 3200 + + + IMPLEMENTATION: Request Participant Information from Oracle Sequence + + + 8 + Request to get participant's FSP details + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Error code: + 200x, 310x, 320x + + + 9 + Request to get participant's FSP details + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 10 + Return list of Participant information + + + 11 + Return list of Participant information + + + 12 + Retrieve the PayerFSP Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 13 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 14 + List of PayerFSP Participant Callback Endpoints + + + 15 + List of PayerFSP Participant Callback Endpoints + + + + + 16 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 17 + Return list of Participant information + + + + 18 + Callback: PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + [oracleEndpoint IS NULL OR error occurred] + + + 19 + Retrieve the Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 20 + Retrieve the Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints. + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 21 + List of Participant Callback Endpoints + + + 22 + List of Participant Callback Endpoints + + + + + 23 + Match Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 24 + Handle error + Error code: + 200x, 310x, 320x + + + + 25 + Callback: PUT - /participants/{TYPE}/{ID}/error + + [switchEndpoint IS NULL] + + + + + 26 + Handle error + Error code: + 200x + + Error Handling Framework + + diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml rename to docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg new file mode 100644 index 000000000..6c1cfad73 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg @@ -0,0 +1,389 @@ + + 7.2.0. Get Party Details + + + 7.2.0. Get Party Details + + Financial Service Provider + + Account Lookup Service + + Central Services + + ALS Oracle Service/Adapter + + Financial Service Provider + + + + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Account Lookup + Service (ALS) + + + Account Lookup + Service (ALS) + + + ALS Participant + Handler + + + ALS Participant + Handler + + + ALS Database + + + ALS Database + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + ALS Parties + FSP DAO + + + ALS Parties + FSP DAO + + + Central Service API + + + Central Service API + + + Oracle Service API + + + Oracle Service API + + + Payee FSP + + + Payee FSP + + + + + + + + + + + + + + + + + Get Party Details + + + + 1 + Request to get parties's FSP details + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 202 + Error code: + 200x, 300x, 310x, 320x + + + Validate request against + Mojaloop Interface Specification. + Error code: + 300x, 310x + + + 2 + Request to get parties's FSP details + + + alt + [oracleEndpoint match found & parties information retrieved] + + + + 3 + Get Oracle Routing Config + Error code: + 200x, 310x, 320x + + + ref + GET Participants - + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + 4 + Request FSPIOP-Source participant information + Error code: + 200x + + + 5 + GET - /participants/{FSPIOP-Source} + Error code: + 200x, 310x, 320x + + + 6 + Return FSPIOP-Source participant information + + + 7 + Return FSPIOP-Source participant information + + + + + 8 + Validate FSPIOP-Source participant + Error code: + 320x + + + + 9 + Get Participant Information for PayeeFSP + Error code: + 200x, 310x, 320x + + + ref + GET Participants - + + Request Participant Information from Oracle Sequence + + + + + + + 10 + Request Parties information from FSP. + Error code: + 200x + + + + 11 + Parties Callback to Destination: + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + Response code: + 202 + Error code: + 200x, 310x, 320x + + + + 12 + Callback with Participant Information: + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + Error code: + 200x, 300x, 310x, 320x + + + + + 13 + Validate request against + Mojaloop Interface Specification + Error code: + 300x, 310x + + + 14 + Process Participant Callback Information for PUT + + + 15 + Retrieve the PayerFSP Participant Callback Endpoint + Error code: + 200x + + + 16 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Error code: + 200x, 310x, 320x + + + 17 + List of PayerFSP Participant Callback Endpoints + + + 18 + List of PayerFSP Participant Callback Endpoints + + + + + 19 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTIES_PUT + + + 20 + Return Participant Information to PayerFSP + + + + 21 + Callback with Parties Information: + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + [Empty list of End-Points returned for either (PayeeFSP or Oracle) config information or Error occurred for PayerFSP] + + + 22 + Retrieve the PayerFSP Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 23 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 + Error code: + 200x, 310x, 320x + + + 24 + List of PayerFSP Participant Callback Endpoints + + + 25 + List of PayerFSP Participant Callback Endpoints + + + + + 26 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + 27 + Handle error + Error code: + 200x, 310x, 320x + + + + 28 + Callback: PUT - /participants/{TYPE}/{ID}/error + + [Empty list of End-Points returned for PayerFSP config information or Error occurred for PayeeFSP] + + + 29 + Retrieve the PayeeFSP Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 30 + Retrieve the PayeeFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 + Error code: + 200x, 310x, 320x + + + 31 + List of PayeeFSP Participant Callback Endpoints + + + 32 + List of PayeeFSP Participant Callback Endpoints + + + + + 33 + Match PayeeFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + 34 + Handle error + Error code: + 200x, 310x, 320x + + + + 35 + Callback: PUT - /participants/{TYPE}/{ID}/error + + [Empty list of switchEndpoint results returned] + + + + + 36 + Handle error + Error code: + 200x + + Error Handling Framework + + diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml new file mode 100644 index 000000000..7769e3a8d --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.3 Post Participant Details by Type and ID + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Post Participant's FSP Details + note right of PAYER_FSP #yellow + Headers - postParticipantsByTypeIDHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - postParticipantsByTypeIDMessage: + { + "fspId": "string" + } + end note + PAYER_FSP ->> ALS_API: Request to add participant's FSP details\nPOST - /participants/{Type}/{ID}\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Process create participant's FSP details + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + + '********************* Sort into Participant buckets based on {TYPE} - END ************************ + + alt Validation passed + + + '********************* Fetch Oracle Routing Information - START ************************ + + '********************* Retrieve Oracle Routing Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config based on Type (and optional Currency)\nError code: 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + + '********************* Retrieve Oracle Routing Information - END ************************ + + ||| + +' '********************* Fetch Oracle Routing Information - END ************************ +' +' '********************* Retrieve Switch Routing Information - START ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref +' +' '********************* Retrieve Switch Routing Information - END ************************ +' ||| + + '********************* Validate Participant - START ************************ + group Validate Participant's FSP + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request participant (PARTICIPANT.fspId) information for {Type}\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate participant\nError code: 320x + end group + '********************* Validate Participant - END ************************ + + '********************* Create Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Create participant's FSP details\nPOST - /participants\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Create participant's FSP details\nPOST - /participants\nResponse code: 204 \nError code: 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result of Participant Create request + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result of Participant Create request + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Create Participant Information - END ************************ + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information from ParticipantResult + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID} + + else Validation failure + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg new file mode 100644 index 000000000..b38dcc95a --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg @@ -0,0 +1,326 @@ + + 7.1.3 Post Participant Details by Type and ID + + + 7.1.3 Post Participant Details by Type and ID + + Financial Service Provider + + Account Lookup Service + + Central Services + + ALS Oracle Service/Adapter + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Account Lookup + Service (ALS) + + + Account Lookup + Service (ALS) + + + ALS Participant + Handler + + + ALS Participant + Handler + + + ALS Participant + Oracle DAO + + + ALS Participant + Oracle DAO + + + ALS Database + + + ALS Database + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + Central Service API + + + Central Service API + + + Oracle Service API + + + Oracle Service API + + + + + + + + + + + + + + + Post Participant's FSP Details + + + Headers - postParticipantsByTypeIDHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - postParticipantsByTypeIDMessage: + { + "fspId": "string" + } + + + + 1 + Request to add participant's FSP details + POST - /participants/{Type}/{ID} + Response code: + 202 +   + Error code: + 200x, 300x, 310x, 320x + + + Validate request against + Mojaloop Interface Specification. + Error code: + 300x, 310x + + + 2 + Process create participant's FSP details + + + + + 3 + Validate that PARTICIPANT.fspId == FSPIOP-Source + Error code: + 3100 + + + alt + [Validation passed] + + + + 4 + Get Oracle Routing Config based on Type (and optional Currency) + Error code: + 300x, 310x + + + ref + GET Participants - + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + 5 + Request participant (PARTICIPANT.fspId) information for {Type} + Error code: + 200x + + + 6 + GET - /participants/{PARTICIPANT.fspId} + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 7 + Return participant information + + + 8 + Return participant information + + + + + 9 + Validate participant + Error code: + 320x + + + 10 + Create participant's FSP details + POST - /participants + Error code: + 200x, 310x, 320x + + + 11 + Create participant's FSP details + POST - /participants + Response code: + 204 +   + Error code: + 200x, 310x, 320x + + + 12 + Return result of Participant Create request + + + 13 + Return result of Participant Create request + + + 14 + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 15 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 16 + List of PayerFSP Participant Callback Endpoints + + + 17 + List of PayerFSP Participant Callback Endpoints + + + + + 18 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + 19 + Return list of Participant information from ParticipantResult + + + + 20 + Callback: PUT - /participants/{Type}/{ID} + + [Validation failure] + + + 21 + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 22 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 23 + List of PayerFSP Participant Callback Endpoints + + + 24 + List of PayerFSP Participant Callback Endpoints + + + + + 25 + Match Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + 26 + Handle error + Error code: + 200x, 310x, 320x + + + + 27 + Callback: PUT - /participants/{Type}/{ID}/error + + diff --git a/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml similarity index 100% rename from mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml rename to docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml diff --git a/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg new file mode 100644 index 000000000..aed0ef55f --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg @@ -0,0 +1,368 @@ + + 7.1.1. Post Participant (Batch) Details + + + 7.1.1. Post Participant (Batch) Details + + Financial Service Provider + + Account Lookup Service + + Central Services + + ALS Oracle Service/Adapter + + + + + + + + + + + + + + + + + + + + + + + + + + Payer FSP + + + Payer FSP + + + Account Lookup + Service (ALS) + + + Account Lookup + Service (ALS) + + + ALS Participant + Handler + + + ALS Participant + Handler + + + ALS Participant + Oracle DAO + + + ALS Participant + Oracle DAO + + + ALS Database + + + ALS Database + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Endpoint DAO + + + ALS CentralService + Participant DAO + + + ALS CentralService + Participant DAO + + + Central Service API + + + Central Service API + + + Oracle Service API + + + Oracle Service API + + + + + + + + + + + + + + + Post Participant's FSP Details + + + Headers - postParticipantsHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - postParticipantsMessage: + { + "requestId": "string", + "partyList": [ + { + "partyIdType": "string", + "partyIdentifier": "string", + "partySubIdOrType": "string", + "fspId": "string" + } + ], + "currency": "string" + } + + + + 1 + Request to add participant's FSP details + POST - /participants + Response code: + 202 +   + Error code: + 200x, 300x, 310x, 320x + + + Validate request against + Mojaloop Interface Specification. + Error code: + 300x, 310x + + + 2 + Process create participant's FSP details + + + loop + [for Participant in ParticipantList] + + + + + 3 + Validate that PARTICIPANT.fspId == FSPIOP-Source + Error code: + 3100 + + + + + 4 + Group Participant lists into a Map (ParticipantMap) based on {TYPE} + + + alt + [Validation passed and the ParticipantMap was created successfully] + + + loop + [for keys in ParticipantMap -> TypeKey] + + + + 5 + Get Oracle Routing Config based on TypeKey (and optional Currency) + Error code: + 300x, 310x + + + ref + GET Participants - + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + 6 + Request participant (PARTICIPANT.fspId) information for {TypeKey} + Error code: + 200x + + + 7 + GET - /participants/{PARTICIPANT.fspId} + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 8 + Return participant information + + + 9 + Return participant information + + + + + 10 + Validate participant + Error code: + 320x + + + 11 + Create participant's FSP details + POST - /participants + Error code: + 200x, 310x, 320x + + + 12 + Create participant's FSP details + POST - /participants + Response code: + 204 +   + Error code: + 200x, 310x, 320x + + + 13 + Return result of Participant Create request + + + 14 + Return result of Participant Create request + + + + + 15 + Store results in ParticipantResultMap[TypeKey] + + + loop + [for keys in ParticipantResultMap -> TypeKey] + + + + + 16 + Combine ParticipantResultMap[TypeKey] results into ParticipantResult + + + 17 + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 18 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 19 + List of PayerFSP Participant Callback Endpoints + + + 20 + List of PayerFSP Participant Callback Endpoints + + + + + 21 + Match PayerFSP Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + + 22 + Return list of Participant information from ParticipantResult + + + + 23 + Callback: PUT - /participants/{requestId} + + [Validation failure and/or the ParticipantMap was not created successfully] + + + 24 + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + Error code: + 200x, 310x, 320x + + + 25 + Retrieve the PayerFSP Participant Callback Endpoint + GET - /participants/{FSPIOP-Source}/endpoints + Response code: + 200 +   + Error code: + 200x, 310x, 320x + + + 26 + List of PayerFSP Participant Callback Endpoints + + + 27 + List of PayerFSP Participant Callback Endpoints + + + + + 28 + Match Participant Callback Endpoints for + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + + 29 + Handle error + Error code: + 200x, 310x, 320x + + + + 30 + Callback: PUT - /participants/{requestId}/error + + diff --git a/docs/technical/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..e538b6351 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql @@ -0,0 +1,195 @@ +-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64) +-- +-- Host: 127.0.0.1 Database: account_lookup +-- ------------------------------------------------------ +-- Server version 8.0.12 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `currency` +-- + +LOCK TABLES `currency` WRITE; +/*!40000 ALTER TABLE `currency` DISABLE KEYS */; +INSERT INTO `currency` VALUES ('AED','UAE dirham',1,'2019-03-28 09:07:47'),('AFA','Afghanistan afghani (obsolete)',1,'2019-03-28 09:07:47'),('AFN','Afghanistan afghani',1,'2019-03-28 09:07:47'),('ALL','Albanian lek',1,'2019-03-28 09:07:47'),('AMD','Armenian dram',1,'2019-03-28 09:07:47'),('ANG','Netherlands Antillian guilder',1,'2019-03-28 09:07:47'),('AOA','Angolan kwanza',1,'2019-03-28 09:07:47'),('AOR','Angolan kwanza reajustado',1,'2019-03-28 09:07:47'),('ARS','Argentine peso',1,'2019-03-28 09:07:47'),('AUD','Australian dollar',1,'2019-03-28 09:07:47'),('AWG','Aruban guilder',1,'2019-03-28 09:07:47'),('AZN','Azerbaijanian new manat',1,'2019-03-28 09:07:47'),('BAM','Bosnia-Herzegovina convertible mark',1,'2019-03-28 09:07:47'),('BBD','Barbados dollar',1,'2019-03-28 09:07:47'),('BDT','Bangladeshi taka',1,'2019-03-28 09:07:47'),('BGN','Bulgarian lev',1,'2019-03-28 09:07:47'),('BHD','Bahraini dinar',1,'2019-03-28 09:07:47'),('BIF','Burundi franc',1,'2019-03-28 09:07:47'),('BMD','Bermudian dollar',1,'2019-03-28 09:07:47'),('BND','Brunei dollar',1,'2019-03-28 09:07:47'),('BOB','Bolivian boliviano',1,'2019-03-28 09:07:47'),('BRL','Brazilian real',1,'2019-03-28 09:07:47'),('BSD','Bahamian dollar',1,'2019-03-28 09:07:47'),('BTN','Bhutan ngultrum',1,'2019-03-28 09:07:47'),('BWP','Botswana pula',1,'2019-03-28 09:07:47'),('BYN','Belarusian ruble',1,'2019-03-28 09:07:47'),('BZD','Belize dollar',1,'2019-03-28 09:07:47'),('CAD','Canadian dollar',1,'2019-03-28 09:07:47'),('CDF','Congolese franc',1,'2019-03-28 09:07:47'),('CHF','Swiss franc',1,'2019-03-28 09:07:47'),('CLP','Chilean peso',1,'2019-03-28 09:07:47'),('CNY','Chinese yuan renminbi',1,'2019-03-28 09:07:47'),('COP','Colombian peso',1,'2019-03-28 09:07:47'),('CRC','Costa Rican colon',1,'2019-03-28 09:07:47'),('CUC','Cuban convertible peso',1,'2019-03-28 09:07:47'),('CUP','Cuban peso',1,'2019-03-28 09:07:47'),('CVE','Cape Verde escudo',1,'2019-03-28 09:07:47'),('CZK','Czech koruna',1,'2019-03-28 09:07:47'),('DJF','Djibouti franc',1,'2019-03-28 09:07:47'),('DKK','Danish krone',1,'2019-03-28 09:07:47'),('DOP','Dominican peso',1,'2019-03-28 09:07:47'),('DZD','Algerian dinar',1,'2019-03-28 09:07:47'),('EEK','Estonian kroon',1,'2019-03-28 09:07:47'),('EGP','Egyptian pound',1,'2019-03-28 09:07:47'),('ERN','Eritrean nakfa',1,'2019-03-28 09:07:47'),('ETB','Ethiopian birr',1,'2019-03-28 09:07:47'),('EUR','EU euro',1,'2019-03-28 09:07:47'),('FJD','Fiji dollar',1,'2019-03-28 09:07:47'),('FKP','Falkland Islands pound',1,'2019-03-28 09:07:47'),('GBP','British pound',1,'2019-03-28 09:07:47'),('GEL','Georgian lari',1,'2019-03-28 09:07:47'),('GGP','Guernsey pound',1,'2019-03-28 09:07:47'),('GHS','Ghanaian new cedi',1,'2019-03-28 09:07:47'),('GIP','Gibraltar pound',1,'2019-03-28 09:07:47'),('GMD','Gambian dalasi',1,'2019-03-28 09:07:47'),('GNF','Guinean franc',1,'2019-03-28 09:07:47'),('GTQ','Guatemalan quetzal',1,'2019-03-28 09:07:47'),('GYD','Guyana dollar',1,'2019-03-28 09:07:47'),('HKD','Hong Kong SAR dollar',1,'2019-03-28 09:07:47'),('HNL','Honduran lempira',1,'2019-03-28 09:07:47'),('HRK','Croatian kuna',1,'2019-03-28 09:07:47'),('HTG','Haitian gourde',1,'2019-03-28 09:07:47'),('HUF','Hungarian forint',1,'2019-03-28 09:07:47'),('IDR','Indonesian rupiah',1,'2019-03-28 09:07:47'),('ILS','Israeli new shekel',1,'2019-03-28 09:07:47'),('IMP','Isle of Man pound',1,'2019-03-28 09:07:47'),('INR','Indian rupee',1,'2019-03-28 09:07:47'),('IQD','Iraqi dinar',1,'2019-03-28 09:07:47'),('IRR','Iranian rial',1,'2019-03-28 09:07:47'),('ISK','Icelandic krona',1,'2019-03-28 09:07:47'),('JEP','Jersey pound',1,'2019-03-28 09:07:47'),('JMD','Jamaican dollar',1,'2019-03-28 09:07:47'),('JOD','Jordanian dinar',1,'2019-03-28 09:07:47'),('JPY','Japanese yen',1,'2019-03-28 09:07:47'),('KES','Kenyan shilling',1,'2019-03-28 09:07:47'),('KGS','Kyrgyz som',1,'2019-03-28 09:07:47'),('KHR','Cambodian riel',1,'2019-03-28 09:07:47'),('KMF','Comoros franc',1,'2019-03-28 09:07:47'),('KPW','North Korean won',1,'2019-03-28 09:07:47'),('KRW','South Korean won',1,'2019-03-28 09:07:47'),('KWD','Kuwaiti dinar',1,'2019-03-28 09:07:47'),('KYD','Cayman Islands dollar',1,'2019-03-28 09:07:47'),('KZT','Kazakh tenge',1,'2019-03-28 09:07:47'),('LAK','Lao kip',1,'2019-03-28 09:07:47'),('LBP','Lebanese pound',1,'2019-03-28 09:07:47'),('LKR','Sri Lanka rupee',1,'2019-03-28 09:07:47'),('LRD','Liberian dollar',1,'2019-03-28 09:07:47'),('LSL','Lesotho loti',1,'2019-03-28 09:07:47'),('LTL','Lithuanian litas',1,'2019-03-28 09:07:47'),('LVL','Latvian lats',1,'2019-03-28 09:07:47'),('LYD','Libyan dinar',1,'2019-03-28 09:07:47'),('MAD','Moroccan dirham',1,'2019-03-28 09:07:47'),('MDL','Moldovan leu',1,'2019-03-28 09:07:47'),('MGA','Malagasy ariary',1,'2019-03-28 09:07:47'),('MKD','Macedonian denar',1,'2019-03-28 09:07:47'),('MMK','Myanmar kyat',1,'2019-03-28 09:07:47'),('MNT','Mongolian tugrik',1,'2019-03-28 09:07:47'),('MOP','Macao SAR pataca',1,'2019-03-28 09:07:47'),('MRO','Mauritanian ouguiya',1,'2019-03-28 09:07:47'),('MUR','Mauritius rupee',1,'2019-03-28 09:07:47'),('MVR','Maldivian rufiyaa',1,'2019-03-28 09:07:47'),('MWK','Malawi kwacha',1,'2019-03-28 09:07:47'),('MXN','Mexican peso',1,'2019-03-28 09:07:47'),('MYR','Malaysian ringgit',1,'2019-03-28 09:07:47'),('MZN','Mozambique new metical',1,'2019-03-28 09:07:47'),('NAD','Namibian dollar',1,'2019-03-28 09:07:47'),('NGN','Nigerian naira',1,'2019-03-28 09:07:47'),('NIO','Nicaraguan cordoba oro',1,'2019-03-28 09:07:47'),('NOK','Norwegian krone',1,'2019-03-28 09:07:47'),('NPR','Nepalese rupee',1,'2019-03-28 09:07:47'),('NZD','New Zealand dollar',1,'2019-03-28 09:07:47'),('OMR','Omani rial',1,'2019-03-28 09:07:47'),('PAB','Panamanian balboa',1,'2019-03-28 09:07:47'),('PEN','Peruvian nuevo sol',1,'2019-03-28 09:07:47'),('PGK','Papua New Guinea kina',1,'2019-03-28 09:07:47'),('PHP','Philippine peso',1,'2019-03-28 09:07:47'),('PKR','Pakistani rupee',1,'2019-03-28 09:07:47'),('PLN','Polish zloty',1,'2019-03-28 09:07:47'),('PYG','Paraguayan guarani',1,'2019-03-28 09:07:47'),('QAR','Qatari rial',1,'2019-03-28 09:07:47'),('RON','Romanian new leu',1,'2019-03-28 09:07:47'),('RSD','Serbian dinar',1,'2019-03-28 09:07:47'),('RUB','Russian ruble',1,'2019-03-28 09:07:47'),('RWF','Rwandan franc',1,'2019-03-28 09:07:47'),('SAR','Saudi riyal',1,'2019-03-28 09:07:47'),('SBD','Solomon Islands dollar',1,'2019-03-28 09:07:47'),('SCR','Seychelles rupee',1,'2019-03-28 09:07:47'),('SDG','Sudanese pound',1,'2019-03-28 09:07:47'),('SEK','Swedish krona',1,'2019-03-28 09:07:47'),('SGD','Singapore dollar',1,'2019-03-28 09:07:47'),('SHP','Saint Helena pound',1,'2019-03-28 09:07:47'),('SLL','Sierra Leone leone',1,'2019-03-28 09:07:47'),('SOS','Somali shilling',1,'2019-03-28 09:07:47'),('SPL','Seborgan luigino',1,'2019-03-28 09:07:47'),('SRD','Suriname dollar',1,'2019-03-28 09:07:47'),('STD','Sao Tome and Principe dobra',1,'2019-03-28 09:07:47'),('SVC','El Salvador colon',1,'2019-03-28 09:07:47'),('SYP','Syrian pound',1,'2019-03-28 09:07:47'),('SZL','Swaziland lilangeni',1,'2019-03-28 09:07:47'),('THB','Thai baht',1,'2019-03-28 09:07:47'),('TJS','Tajik somoni',1,'2019-03-28 09:07:47'),('TMT','Turkmen new manat',1,'2019-03-28 09:07:47'),('TND','Tunisian dinar',1,'2019-03-28 09:07:47'),('TOP','Tongan pa\'anga',1,'2019-03-28 09:07:47'),('TRY','Turkish lira',1,'2019-03-28 09:07:47'),('TTD','Trinidad and Tobago dollar',1,'2019-03-28 09:07:47'),('TVD','Tuvaluan dollar',1,'2019-03-28 09:07:47'),('TWD','Taiwan New dollar',1,'2019-03-28 09:07:47'),('TZS','Tanzanian shilling',1,'2019-03-28 09:07:47'),('UAH','Ukrainian hryvnia',1,'2019-03-28 09:07:47'),('UGX','Uganda new shilling',1,'2019-03-28 09:07:47'),('USD','US dollar',1,'2019-03-28 09:07:47'),('UYU','Uruguayan peso uruguayo',1,'2019-03-28 09:07:47'),('UZS','Uzbekistani sum',1,'2019-03-28 09:07:47'),('VEF','Venezuelan bolivar fuerte',1,'2019-03-28 09:07:47'),('VND','Vietnamese dong',1,'2019-03-28 09:07:47'),('VUV','Vanuatu vatu',1,'2019-03-28 09:07:47'),('WST','Samoan tala',1,'2019-03-28 09:07:47'),('XAF','CFA franc BEAC',1,'2019-03-28 09:07:47'),('XAG','Silver (ounce)',1,'2019-03-28 09:07:47'),('XAU','Gold (ounce)',1,'2019-03-28 09:07:47'),('XCD','East Caribbean dollar',1,'2019-03-28 09:07:47'),('XDR','IMF special drawing right',1,'2019-03-28 09:07:47'),('XFO','Gold franc',1,'2019-03-28 09:07:47'),('XFU','UIC franc',1,'2019-03-28 09:07:47'),('XOF','CFA franc BCEAO',1,'2019-03-28 09:07:47'),('XPD','Palladium (ounce)',1,'2019-03-28 09:07:47'),('XPF','CFP franc',1,'2019-03-28 09:07:47'),('XPT','Platinum (ounce)',1,'2019-03-28 09:07:47'),('YER','Yemeni rial',1,'2019-03-28 09:07:47'),('ZAR','South African rand',1,'2019-03-28 09:07:47'),('ZMK','Zambian kwacha (obsolete)',1,'2019-03-28 09:07:47'),('ZMW','Zambian kwacha',1,'2019-03-28 09:07:47'),('ZWD','Zimbabwe dollar (initial)',1,'2019-03-28 09:07:47'),('ZWL','Zimbabwe dollar (3rd denomination)',1,'2019-03-28 09:07:47'),('ZWN','Zimbabwe dollar (1st denomination)',1,'2019-03-28 09:07:47'),('ZWR','Zimbabwe dollar (2nd denomination)',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `currency` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_type_unique` (`type`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `endpointType` +-- + +LOCK TABLES `endpointType` WRITE; +/*!40000 ALTER TABLE `endpointType` DISABLE KEYS */; +INSERT INTO `endpointType` VALUES (1,'URL','REST URLs',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `endpointType` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration` +-- + +LOCK TABLES `migration` WRITE; +/*!40000 ALTER TABLE `migration` DISABLE KEYS */; +INSERT INTO `migration` VALUES (1,'01_currency.js',1,'2019-03-28 11:07:46'),(2,'02_endpointType.js',1,'2019-03-28 11:07:46'),(3,'03_endpointType-indexes.js',1,'2019-03-28 11:07:46'),(4,'04_partyIdType.js',1,'2019-03-28 11:07:46'),(5,'05_partyIdType-indexes.js',1,'2019-03-28 11:07:46'),(6,'08_oracleEndpoint.js',1,'2019-03-28 11:07:47'),(7,'09_oracleEndpoint-indexes.js',1,'2019-03-28 11:07:47'); +/*!40000 ALTER TABLE `migration` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration_lock` +-- + +LOCK TABLES `migration_lock` WRITE; +/*!40000 ALTER TABLE `migration_lock` DISABLE KEYS */; +INSERT INTO `migration_lock` VALUES (1,0); +/*!40000 ALTER TABLE `migration_lock` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `oracleEndpoint` +-- + +DROP TABLE IF EXISTS `oracleEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `oracleEndpoint` ( + `oracleEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `partyIdTypeId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `currencyId` varchar(255) DEFAULT NULL, + `value` varchar(512) NOT NULL, + `isDefault` tinyint(1) NOT NULL DEFAULT '0', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`oracleEndpointId`), + KEY `oracleendpoint_currencyid_foreign` (`currencyId`), + KEY `oracleendpoint_partyidtypeid_index` (`partyIdTypeId`), + KEY `oracleendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `oracleendpoint_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `oracleendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `oracleendpoint_partyidtypeid_foreign` FOREIGN KEY (`partyIdTypeId`) REFERENCES `partyIdType` (`partyidtypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `oracleEndpoint` +-- + +LOCK TABLES `oracleEndpoint` WRITE; +/*!40000 ALTER TABLE `oracleEndpoint` DISABLE KEYS */; +/*!40000 ALTER TABLE `oracleEndpoint` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `partyIdType` +-- + +DROP TABLE IF EXISTS `partyIdType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `partyIdType` ( + `partyIdTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`partyIdTypeId`), + UNIQUE KEY `partyidtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `partyIdType` +-- + +LOCK TABLES `partyIdType` WRITE; +/*!40000 ALTER TABLE `partyIdType` DISABLE KEYS */; +INSERT INTO `partyIdType` VALUES (1,'MSISDN','A MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.',1,'2019-03-28 09:07:47'),(2,'EMAIL','An email is used as reference to a participant. The format of the email should be according to the informational RFC 3696.',1,'2019-03-28 09:07:47'),(3,'PERSONAL_ID','A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(4,'BUSINESS','A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.',1,'2019-03-28 09:07:47'),(5,'DEVICE','A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(6,'ACCOUNT_ID','A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.',1,'2019-03-28 09:07:47'),(7,'IBAN','A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.',1,'2019-03-28 09:07:47'),(8,'ALIAS','An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `partyIdType` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-03-28 11:09:54 diff --git a/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd new file mode 100644 index 000000000..ea177ae89 --- /dev/null +++ b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png new file mode 100644 index 000000000..bdca208cd Binary files /dev/null and b/docs/technical/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png differ diff --git a/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg new file mode 100644 index 000000000..d87484a3c --- /dev/null +++ b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Ledger
    Central-Ledger
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg new file mode 100644 index 000000000..f75130984 --- /dev/null +++ b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Services
    (Ledger - API, Handlers)
    Central-Services<br>(Ledger - API, Handlers)<br>
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    Quoting-Service
    Quoting-Service
    ALS Oracle Simulator
    [Not supported by viewer]
    A 2. *ID based
    lookup
    A 2. *ID based <br>lookup
    \ No newline at end of file diff --git a/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg new file mode 100644 index 000000000..a2fbbe512 --- /dev/null +++ b/docs/technical/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg @@ -0,0 +1,3 @@ + + +
    C 4. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Account Lookup Services
    [Not supported by viewer]
    Pathfinder
    Pathfinder
    FSP
    Backend


    (Does not natively speak Mojaloop API)








    [Not supported by viewer]
    S
    c
    h
    e
    m
    e

    A
    d
    a
    p
    t
    e
    r

    [Not supported by viewer]
    A 2. MSISDN based lookup
    A 2. MSISDN based lookup
    FSP
    Backend
      

    (Natively speaks Mojaloop API)









    [Not supported by viewer]
    A
    A
    A 1. User
    Lookup
    A 1. User <br>Lookup
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based lookup
    A 2. mID based lookup
    Mojaloop Hub
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    C 1. Transfer
        Prepare
    [Not supported by viewer]
    A 3. Receiver
    Details
    A 3. Receiver<br>Details<br>
     Fee /
    Comm
    [Not supported by viewer]
    Get Receiver
    Details
    [Not supported by viewer]
     C 2. Transfer
    Prepare
    [Not supported by viewer]
    C 5. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Transfer
    Prepare
    [Not supported by viewer]
    C 3. Transfer
    Fulfil
    C 3. Transfer<br>Fulfil<br>
    Transfer
    Fulfil
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    Central Services
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote<br>
    Settlement Provider
    Settlement Provider
    Hub Operator
    Hub Operator
    D 1. Create Settlement
    D 1. Create Settlement
    D
    D
    D 2. Query Settlement Report
    (Pull)
    D 2. Query Settlement Report<br>(Pull)<br>
    D 3. Send Acknowledgements
    (Push)
    D 3. Send Acknowledgements<br>(Push)<br>
    Quoting Service
    <font style="font-size: 18px">Quoting Service</font>
    Central Services
    • Transfers
    • Settlements
    • Auditing
    • Notifications
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/assets/diagrams/architecture/central_ledger_block_diagram.png b/docs/technical/technical/assets/diagrams/architecture/central_ledger_block_diagram.png new file mode 100644 index 000000000..48199cf3e Binary files /dev/null and b/docs/technical/technical/assets/diagrams/architecture/central_ledger_block_diagram.png differ diff --git a/docs/technical/technical/central-bulk-transfers/README.md b/docs/technical/technical/central-bulk-transfers/README.md new file mode 100644 index 000000000..c1d0b3d54 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/README.md @@ -0,0 +1,298 @@ +# Bulk Transfers Design + +The Bulk Transfers scenario is described in the API Definition document regarding the resource /bulkTransfers. For details _(refer to section `6.10`)_ as per the [Mojaloop Specification](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) + +1. [Introduction](introduction) +2. [Design Considerations](design-considerations) +3. [Steps involved in the high-level Architecture](steps-involved-in-the-high-level-architecture) +4. [Notes](notes) + 1. [Discussion items](discussion-items) + 2. [Proposed new tables](proposed-new-tables) + 3. [Bulk Transfers States](bulk-transfers-states) + 4. [Additional Notes](additional-notes) +5. [Roadmap Topics](roadmap-topics) + +## 1. Introduction + +The Bulk Transfers process is discussed in section 6.10 of the API Definition 1.0 document, depicted in Figure 60, of which a snapshot is posted below. +![Figure 60](./assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png) + +The key items implied in the specification in its current version 1.0 are that + +- Reservation of funds is done for each individual transfer from the Payer FSP to the Payee FSP +- Even if a single individual transfer fails during the prepare process, the whole bulk is to be rejected. + +## 2. Design Considerations + +According to the Figure-60 of the specification, below are a few key implications from the Specification. + +1. The Payer DFSP performs user look-ups for the individual parties involved in the bulk payment separately +2. The Payer DFSP performs bulk quoting per Payee DFSP +3. The onus is on the Payer DFSP to prepare bulk transfers based on Payee FSPs and send out a bulk transfer request to a single Payee FSP +4. This seems to be an all-or-nothing process where even if a single individual transfer fails to be reserved, then the whole bulk needs to be rejected because it cannot be sent to the Payee as it is if it has an individual transfer for which funds couldn't be reserved. +5. In light of the above, the proposal being made right now is to empower the Switch (needs updating the Specification) to send out the POST /bulkTransfers request with the list of individual transfers for which funds were able to be reserved on the Switch. +6. The implication is that the Switch aggregates commits/failures from the Payee FSP for the bulk and sends out a single PUT /bulkTransfers/{ID} call to the Payer FSP that includes the entire list of transfers that includes individual transfers that failed both at the Switch and the Payee FSP +7. For example: If there are 1000 individual transfers in a Bulk Transfer and if the Switch is able to reserve funds for 900 of the individual transfers, then a prepare bulk transfer request to the Payee DFSP is sent with the list of those 900 individual transfers. Once the Payee FSP sends the Bulk Fulfil request for those 900 transfers of which lets say, 800 can be committed and 100 are aborted, then the Switch processes those individual transfers accordingly and sends out the PUT callback (PUT /bulkTransfers/{ID}) notification to the Payer FSP with all the 1000 individual transfers, 800 of which are committed and 200 of which are aborted. +8. There will be implications to aspects such as Signature, Encryption, PKI and other security aspects that will need to be addressed. +9. The ordering of the individual transfers need to be considered as well by the Scheme. A Goal for implementation in emerging markets is to maximize the number of transactions involved and so a well designed Scheme may re-order individual transfers in the ascending order of the magnitude of amounts and then process them. But this can be a Scheme consideration. +10. However, a recommended Scheme Rule is that the Payee FSPs shouldn't be allowed to re-order the individual transfers in a bulk to avoid bias towards Payee parties. +11. For Settlements with bulk transfers where Government payments are involved with large sums of money needs to be discussed to allow for moving through transfers without strict liquidity rules needs to be discussed. + +## 3. Steps involved in the high-level Architecture + +Below are the steps involved at a high level for bulk transfers. + +![architecture diagram](./assets/diagrams/architecture/bulk-transfer-arch-flows.svg) + +1. [1.0, 1.1, 1.2] An Incoming bulk Transfer request (POST /bulkTransfers) on the bulk-api-adapter is placed in an object store and a notification with a reference to the actual message is sent via a kafka topic “bulk-prepare” and a 202 is sent to the Payer FSP +2. [1.3] Bulk Prepare handler consumes the request, records the status as RECEIVED + + a. Bulk Prepare handler then validates the Bulk and changes state to PENDING if the validation is successful + + b. One validation rule proposed in addition, here is to reject a bulk if there are duplicate transfer IDs used in the bulk itself. + + c. [1.4] If validation fails, Bulk Prepare handler changes the bulkTransferState to PENDING_INVALID (an internal state) and produces a message onto the bulk processing topic + i. Bulk processing Handler then updates the bulkTransferState to REJECTED and sends a notification to the Payer + +3. [1.4] [Continuing 2.a] Bulk Prepare handler breaks down the bulk into individual transfers and puts each of them on the prepare topic + + a. As part of this, each transfer is individually assigned the 'expiration time' of the bulk Transfer itself (and other fields necessary for individual transfers) + +4. [1.5, 1.6, 1.7] Prepare handler, Position handler are refactored to handle individual transfers in a bulk, using flags such as type, action, status, etc. + + a. Reservation of funds --> This is left to the individual handlers and the whole bulk is then aggregated in the Bulk Processing Handler. + +5. [1.8] Position Handler produces messages corresponding to individual transfers that are part of a bulk to bulk processing topic +6. [1.9] For every message consumed from the bulk processing topic a check is made on the Bulk processing Handler to see if that’s the last individual transfer in a bulk for that processing phase. +7. [1.10, 1.11, 1.12] If it is the last transfer, aggregate the state of all the individual transfers and + + a. If all of them are in reserved state --> Send POST /bulkTransfers to the Payee (by producing a message to the notifications topic which is then consumed by the notification handler) + + b. Once the bulkTransfer prepare request is sent to the Payee, then change status to ACCEPTED + +8. In a successful case of Prepare - when the PUT from the Payee FSP for bulkFulfil is received, a notification is put on the bulk fulfil topic with a reference to the actual Fulfil message that's stored in an Object store. +9. This is to be consumed by the bulkFulfilHandler, which then changes state to PROCESSING. +10. The bulk-fulfil-handler breaks down the bulk into individual transfers and sends each of them through the refactored Fulfil, Position Handlers to commit/abort each of them based on the PUT /bulkTransfers/{ID} message by the Payee and commit/release funds on the Switch +11. The bulk-processing-handler is to then aggregate all the individual transfer results and change the state of bulkTransfer to COMPLETED/REJECTED based on success/failure + + a. If the Payee sends COMMITTED for even one of the individual transfers the proposal is to change bulk state to COMPLETED. + + b. However, for step-8 or if the Payee sends REJECTED as bulkTransferState then final state on Switch should be REJECTED. + +12. Send notifications to both Payer and Payee (similar to Single transfers, though diverging from the Spec 1.0). The Payer-FSP receives the notification that includes an exhaustive list of individual transfers, same as the list present in the prepare request sent by the Payer. The Payee-FSP receives a notification only for sub-set of transfers, which were sent to it from the Switch as the Bulk prepare request (that were able to be reserved at the Switch). + +## 4. Implementation Details + +### 4.1 Bulk Transfer States + +Below are the states of a Bulk transfer as per the Mojaloop API Specification + +1. RECEIVED +2. PENDING +3. ACCEPTED +4. PROCESSING +5. COMPLETED +6. REJECTED +7. Internal state - PENDING_PREPARE (mapped to PENDING) +8. Internal state - PENDING_INVALID (mapped to PENDING) +9. Internal state - PENDING_FULFIL (mapped to PROCESSING) +10. Internal state - EXPIRING (mapped to PROCESSING) +11. Internal state - EXPIRED (mapped to COMPLETED) +12. Internal state - INVALID (mapped to REJECTED) +13. Additional micro-states may be added for internal use on the Switch + +### 4.2 Proposed New tables + +Below are the proposed tables as part of designing the Bulk transfers + +- bulkTransfer +- bulkTransferStateChange +- bulkTransferError +- bulkTransferDuplicateCheck +- bulkTransferFulfilment +- bulkTransferFulfilmentDuplicateCheck +- bulkTransferAssociation +- bulkTransferExtension +- bulkTransferState +- bulkProcessingState + +### 4.3 Internal Type-Action-Status combinations + +#### 1. Bulk transfer that passes schema validation [ml-api-adapter -> bulk-prepare-handler] + + 1. type: bulk-prepare + 2. action: bulk-prepare + 3. Status: success + 4. Result: bulkTransferState=RECEIVED, bulkProcessingState=RECEIVED + +#### 2. Duplicate [bulk-prepare-handler -> notification handler] + + 1. type: notification + 2. action: bulk-prepare-duplicate + 3. Status: success + 4. Result: bulkTransferState=N/A, bulkProcessingState=N/A + +#### 3. Validate Bulk Prepare transfer failure [bulk-prepare-handler -> notification-handler] + + 1. type: notification + 2. action: bulk-abort + 3. Status: error + +#### 4. For a Valid Bulk Prepare transfer (broken down and sent as individual transfers) [bulk-prepare-handler -> prepare-handler] + + 1. type: prepare + 2. action: bulk-prepare + 3. Status: success + +#### 5. Duplicate of individual transfer that is part of a bulk-transfer [prepare-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: prepare-duplicate + 3. Status: success + 4. Expected action: Add error message indicating it’s a duplicate + 5. Result: bulkTransferState=PENDING_PREPARE/ACCEPTED (depending on whether it’s the last one), bulkProcessingState=RECEIVED_DUPLICATE + +#### 6. For individual Prepare transfer that’s a valid duplicate in prepare handler [prepare-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: prepare-duplicate + 3. Status: error + 4. Result: bulkTransferState=PENDING_PREPARE/ACCEPTED (depending on whether it’s the last one), bulkProcessingState=RECEIVED_DUPLICATE + +#### 7. For a Valid individual Prepare transfer that’s part of a bulk [prepare-handler -> position-handler] + + 1. type: position + 2. action: bulk-prepare + 3. Status: success + +#### 8. For individual Prepare transfer that’s part of a bulk that failed validation in prepare handler [prepare-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: error + 4. Result: bulkTransferState=PENDING_PREPARE/ACCEPTED (depending on whether it’s the last one), bulkProcessingState=RECEIVED_INVALID + +#### 9. For a Valid individual Prepare transfer that’s part of a bulk [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: success + 4. Result: bulkTransferState=PENDING_PREPARE/ACCEPTED (depending on whether it’s the last one), bulkProcessingState=ACCEPTED + +#### 10. For individual Prepare transfer that’s part of a bulk that failed validation in position handler [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-prepare + 3. Status: error + 4. Result: bulkTransferState=PENDING_PREPARE/ACCEPTED (depending on whether it’s the last one), bulkProcessingState=RECEIVED_INVALID + +#### 11. For a Valid individual Fulfil transfer (for commit) that’s part of a bulk [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-commit + 3. Status: success + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=COMPLETED + +#### 12. For Bulk transfer Fulfil message that passes validation [ml-api-adapter -> bulk-fulfil-handler] + + 1. type: bulk-fulfil + 2. action: bulk-commit + 3. Status: success + +#### 13. For a valid individual transfer part of a bulk that timed-out in position handler [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-reserved + 3. Status: error + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=FULFIL_INVALID + +#### 14. For a Valid individual Fulfil transfer (for reject) that’s part of a bulk [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: reject + 3. Status: success + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=REJECTED + +#### 15. Invalid Fulfil duplicate of an individual transfer in a bulk [fulfil-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: fulfil-duplicate + 3. Status: error + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=FULFIL_DUPLICATE + +#### 16. Valid Fulfil duplicate of an individual transfer in a bulk [fulfil-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: fulfil-duplicate + 3. Status: success + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=FULFIL_DUPLICATE + +#### 17. Valid Fulfil message of an individual transfer in a bulk [fulfil-handler -> position-handler] + + 1. type: position + 2. action: bulk-commit + 3. Status: success + +#### 18. For individual Fulfil transfer that’s part of a bulk that failed validation in fulfil handler [fulfil-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-commit + 3. Status: error + 4. Result: bulkTransferState=PENDING_FULFIL/COMPLETED (depending on whether it’s the last one), bulkProcessingState=FULFIL_INVALID + +#### 19. Fulfil transfer request that’s part of a bulk that passes validation [bulk-fulfil-handler -> fulfil-handler] + + 1. type: bulk-fulfil + 2. action: bulk-commit + 3. Status: success + +#### 20. For Bulk transfers failing validation at bulk-fulfil-handler level [bulk-fulfil-handler -> notification-handler] + + 1. type: notification + 2. action: bulk-abort + 3. Status: error + +#### 21. For Bulk transfer notifications to FSPs [bulk-processing-handler -> notification-handler] + + 1. type: notification + 2. action: bulk-prepare / bulk-commit + 3. Status: success + +#### 22. For timeout notification [timeout-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-received + 3. Status: error + 4. Result: bulkTransferState=COMPLETED (for the last one), bulkProcessingState=EXPIRED + +#### 23. For timeout notification [timeout-handler -> position-handler] + + 1. type: position + 2. action: bulk-timeout-reserved + 3. Status: error + +#### 24. For timeout notification after position adjust [position-handler -> bulk-processing-handler] + + 1. type: bulk-processing + 2. action: bulk-timeout-reserved + 3. Status: error + 4. Result: bulkTransferState=COMPLETED (for the last one), bulkProcessingState=EXPIRED + +### 4.4 Additional Notes + +1. Document GET /bulkTransfers to indicate the difference in responses the Payer-FSP & Payee-FSP receive for Bulk Transfers +2. Used a separate service: bulk-api-adapter to support bulk transfers end-points (that includes persistence as discussed above) + +## 5. Roadmap Topics + +1. Re-assess the need to support multiple Payee FSPs as part of a Bulk and the changes to the Specification needed. +2. Issues, learnings from the PoC that are documented are addressed in order of priority +3. Find out a need to support something like a Bulk make resource (/bulkMake ?) in which the Switch accepts an entire Bulk as it is and then takes care of all three phases - lookup, quote and transfers. +4. Throttling of individual transfers in a bulk? +5. The aspect of ordering in a Bulk - the order of processing at the Switch and at the FSPs. Recommendation to Scheme to incorporate Rule to mandate all FSPs to process transactions a bulk in the existing order and not have preferential processing. On the Switch currently being neutral with ordering but best practice is to sort in ascending order of amounts and process. +6. For Settlements with bulk transfers where Government payments are involved with large sums of money needs to be discussed to allow for moving through transfers without strict liquidity rules needs to be discussed. +7. Implement GET /bulkTransfers +8. Implement notifications/logging for all bulk negative scenarios +9. Full unit tests code coverage +10. Integration testing of successful bulk transfer (golden path) +11. Regression testing, including negative scenarios diff --git a/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..f6995bc85 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql @@ -0,0 +1,1600 @@ +-- MySQL dump 10.13 Distrib 8.0.16, for macos10.14 (x86_64) +-- +-- Host: 127.0.0.1 Database: central_ledger +-- ------------------------------------------------------ +-- Server version 8.0.13 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; + SET NAMES utf8 ; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `amountType` +-- + +DROP TABLE IF EXISTS `amountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `amountType` ( + `amountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`amountTypeId`), + UNIQUE KEY `amounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `balanceOfPayments` +-- + +DROP TABLE IF EXISTS `balanceOfPayments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `balanceOfPayments` ( + `balanceOfPaymentsId` int(10) unsigned NOT NULL, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible values and meaning are defined in https://www.imf.org/external/np/sta/bopcode/', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`balanceOfPaymentsId`), + UNIQUE KEY `balanceofpayments_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='See https://www.imf.org/external/np/sta/bopcode/guide.htm'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkProcessingState` +-- + +DROP TABLE IF EXISTS `bulkProcessingState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkProcessingState` ( + `bulkProcessingStateId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkProcessingStateId`), + UNIQUE KEY `bulkprocessingstate_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransfer` +-- + +DROP TABLE IF EXISTS `bulkTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransfer` ( + `bulkTransferId` varchar(36) NOT NULL, + `bulkQuoteId` varchar(36) DEFAULT NULL, + `payerParticipantId` int(10) unsigned DEFAULT NULL, + `payeeParticipantId` int(10) unsigned DEFAULT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + KEY `bulktransfer_payerparticipantid_index` (`payerParticipantId`), + KEY `bulktransfer_payeeparticipantid_index` (`payeeParticipantId`), + CONSTRAINT `bulktransfer_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferDuplicateCheck` (`bulktransferid`), + CONSTRAINT `bulktransfer_payeeparticipantid_foreign` FOREIGN KEY (`payeeParticipantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `bulktransfer_payerparticipantid_foreign` FOREIGN KEY (`payerParticipantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferAssociation` +-- + +DROP TABLE IF EXISTS `bulkTransferAssociation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferAssociation` ( + `bulkTransferAssociationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `bulkTransferId` varchar(36) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `bulkProcessingStateId` int(10) unsigned NOT NULL, + `lastProcessedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `errorCode` int(10) unsigned DEFAULT NULL, + `errorDescription` varchar(128) DEFAULT NULL, + PRIMARY KEY (`bulkTransferAssociationId`), + UNIQUE KEY `bulktransferassociation_transferid_bulktransferid_unique` (`transferId`,`bulkTransferId`), + KEY `bulktransferassociation_bulktransferid_foreign` (`bulkTransferId`), + KEY `bulktransferassociation_bulkprocessingstateid_foreign` (`bulkProcessingStateId`), + CONSTRAINT `bulktransferassociation_bulkprocessingstateid_foreign` FOREIGN KEY (`bulkProcessingStateId`) REFERENCES `bulkProcessingState` (`bulkprocessingstateid`), + CONSTRAINT `bulktransferassociation_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferError` +-- + +DROP TABLE IF EXISTS `bulkTransferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferError` ( + `bulkTransferErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferErrorId`), + KEY `bulktransfererror_bulktransferstatechangeid_index` (`bulkTransferStateChangeId`), + CONSTRAINT `bulktransfererror_bulktransferstatechangeid_foreign` FOREIGN KEY (`bulkTransferStateChangeId`) REFERENCES `bulkTransferStateChange` (`bulktransferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferExtension` +-- + +DROP TABLE IF EXISTS `bulkTransferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferExtension` ( + `bulkTransferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferExtensionId`), + KEY `bulktransferextension_bulktransferid_index` (`bulkTransferId`), + CONSTRAINT `bulktransferextension_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilment` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferFulfilment` ( + `bulkTransferId` varchar(36) NOT NULL, + `completedDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilment_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferFulfilmentDuplicateCheck` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferFulfilmentDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilmentduplicatecheck_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferState` +-- + +DROP TABLE IF EXISTS `bulkTransferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferState` ( + `bulkTransferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'bulkTransferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferStateChange` +-- + +DROP TABLE IF EXISTS `bulkTransferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferStateChange` ( + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `bulkTransferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateChangeId`), + KEY `bulktransferstatechange_bulktransferid_index` (`bulkTransferId`), + KEY `bulktransferstatechange_bulktransferstateid_index` (`bulkTransferStateId`), + CONSTRAINT `bulktransferstatechange_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`), + CONSTRAINT `bulktransferstatechange_bulktransferstateid_foreign` FOREIGN KEY (`bulkTransferStateId`) REFERENCES `bulkTransferState` (`bulktransferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `contactType` +-- + +DROP TABLE IF EXISTS `contactType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `contactType` ( + `contactTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`contactTypeId`), + UNIQUE KEY `contacttype_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `scale` int(10) unsigned NOT NULL DEFAULT '4', + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `event` +-- + +DROP TABLE IF EXISTS `event`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `event` ( + `eventId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`eventId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `geoCode` +-- + +DROP TABLE IF EXISTS `geoCode`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `geoCode` ( + `geoCodeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL COMMENT 'Optionally the GeoCode for the Payer/Payee may have been provided. If the Quote Response has the GeoCode for the Payee, an additional row is added', + `latitude` varchar(50) NOT NULL COMMENT 'Latitude of the initiating Party', + `longitude` varchar(50) NOT NULL COMMENT 'Longitude of the initiating Party', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`geoCodeId`), + KEY `geocode_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `geocode_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ilpPacket` +-- + +DROP TABLE IF EXISTS `ilpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ilpPacket` ( + `transferId` varchar(36) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `ilppacket_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerAccountType` +-- + +DROP TABLE IF EXISTS `ledgerAccountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ledgerAccountType` ( + `ledgerAccountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ledgerAccountTypeId`), + UNIQUE KEY `ledgeraccounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerEntryType` +-- + +DROP TABLE IF EXISTS `ledgerEntryType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ledgerEntryType` ( + `ledgerEntryTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ledgerEntryTypeId`), + UNIQUE KEY `ledgerentrytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=138 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participant` +-- + +DROP TABLE IF EXISTS `participant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participant` ( + `participantId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantId`), + UNIQUE KEY `participant_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantContact` +-- + +DROP TABLE IF EXISTS `participantContact`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantContact` ( + `participantContactId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `contactTypeId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `priorityPreference` int(11) NOT NULL DEFAULT '9', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantContactId`), + KEY `participantcontact_participantid_index` (`participantId`), + KEY `participantcontact_contacttypeid_index` (`contactTypeId`), + CONSTRAINT `participantcontact_contacttypeid_foreign` FOREIGN KEY (`contactTypeId`) REFERENCES `contactType` (`contacttypeid`), + CONSTRAINT `participantcontact_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantCurrency` +-- + +DROP TABLE IF EXISTS `participantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantCurrency` ( + `participantCurrencyId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantCurrencyId`), + UNIQUE KEY `participantcurrency_pcl_unique` (`participantId`,`currencyId`,`ledgerAccountTypeId`), + KEY `participantcurrency_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + KEY `participantcurrency_participantid_index` (`participantId`), + KEY `participantcurrency_currencyid_index` (`currencyId`), + CONSTRAINT `participantcurrency_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `participantcurrency_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `participantcurrency_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantEndpoint` +-- + +DROP TABLE IF EXISTS `participantEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantEndpoint` ( + `participantEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `value` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantEndpointId`), + KEY `participantendpoint_participantid_index` (`participantId`), + KEY `participantendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `participantendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `participantendpoint_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimit` +-- + +DROP TABLE IF EXISTS `participantLimit`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantLimit` ( + `participantLimitId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `participantLimitTypeId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL DEFAULT '0.0000', + `thresholdAlarmPercentage` decimal(5,2) NOT NULL DEFAULT '10.00', + `startAfterParticipantPositionChangeId` bigint(20) unsigned DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantLimitId`), + KEY `participantlimit_participantcurrencyid_index` (`participantCurrencyId`), + KEY `participantlimit_participantlimittypeid_index` (`participantLimitTypeId`), + KEY `participantlimit_startafterparticipantpositionchangeid_index` (`startAfterParticipantPositionChangeId`), + CONSTRAINT `participantlimit_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `participantlimit_participantlimittypeid_foreign` FOREIGN KEY (`participantLimitTypeId`) REFERENCES `participantLimitType` (`participantlimittypeid`), + CONSTRAINT `participantlimit_startafterparticipantpositionchangeid_foreign` FOREIGN KEY (`startAfterParticipantPositionChangeId`) REFERENCES `participantPositionChange` (`participantpositionchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimitType` +-- + +DROP TABLE IF EXISTS `participantLimitType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantLimitType` ( + `participantLimitTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantLimitTypeId`), + UNIQUE KEY `participantlimittype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantParty` +-- + +DROP TABLE IF EXISTS `participantParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantParty` ( + `participantPartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `partyId` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`participantPartyId`), + UNIQUE KEY `participantparty_participantid_partyid_unique` (`participantId`,`partyId`), + KEY `participantparty_participantid_index` (`participantId`), + CONSTRAINT `participantparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPosition` +-- + +DROP TABLE IF EXISTS `participantPosition`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantPosition` ( + `participantPositionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionId`), + KEY `participantposition_participantcurrencyid_index` (`participantCurrencyId`), + CONSTRAINT `participantposition_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPositionChange` +-- + +DROP TABLE IF EXISTS `participantPositionChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantPositionChange` ( + `participantPositionChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantPositionId` bigint(20) unsigned NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionChangeId`), + KEY `participantpositionchange_participantpositionid_index` (`participantPositionId`), + KEY `participantpositionchange_transferstatechangeid_index` (`transferStateChangeId`), + CONSTRAINT `participantpositionchange_participantpositionid_foreign` FOREIGN KEY (`participantPositionId`) REFERENCES `participantPosition` (`participantpositionid`), + CONSTRAINT `participantpositionchange_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `party` +-- + +DROP TABLE IF EXISTS `party`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `party` ( + `partyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL, + `firstName` varchar(128) DEFAULT NULL, + `middleName` varchar(128) DEFAULT NULL, + `lastName` varchar(128) DEFAULT NULL, + `dateOfBirth` datetime DEFAULT NULL, + PRIMARY KEY (`partyId`), + KEY `party_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `party_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Optional pers. data provided during Quote Request & Response'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyIdentifierType` +-- + +DROP TABLE IF EXISTS `partyIdentifierType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `partyIdentifierType` ( + `partyIdentifierTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) NOT NULL, + PRIMARY KEY (`partyIdentifierTypeId`), + UNIQUE KEY `partyidentifiertype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyType` +-- + +DROP TABLE IF EXISTS `partyType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `partyType` ( + `partyTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(256) NOT NULL, + PRIMARY KEY (`partyTypeId`), + UNIQUE KEY `partytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quote` +-- + +DROP TABLE IF EXISTS `quote`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quote` ( + `quoteId` varchar(36) NOT NULL, + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `transactionRequestId` varchar(36) DEFAULT NULL COMMENT 'Optional previously-sent transaction request', + `note` text COMMENT 'A memo that will be attached to the transaction', + `expirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `transactionInitiatorId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator', + `transactionInitiatorTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator type', + `transactionScenarioId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction scenario', + `balanceOfPaymentsId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type that contains the elements- balance of payment', + `transactionSubScenarioId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type sub scenario as defined by the local scheme', + `amountTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction type that contains valid elements for - Amount Type', + `amount` decimal(18,4) NOT NULL DEFAULT '0.0000' COMMENT 'The amount that the quote is being requested for. Need to be interpert in accordance with the amount type', + `currencyId` varchar(255) DEFAULT NULL COMMENT 'Trading currency pertaining to the Amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`), + KEY `quote_transactionreferenceid_foreign` (`transactionReferenceId`), + KEY `quote_transactionrequestid_foreign` (`transactionRequestId`), + KEY `quote_transactioninitiatorid_foreign` (`transactionInitiatorId`), + KEY `quote_transactioninitiatortypeid_foreign` (`transactionInitiatorTypeId`), + KEY `quote_transactionscenarioid_foreign` (`transactionScenarioId`), + KEY `quote_balanceofpaymentsid_foreign` (`balanceOfPaymentsId`), + KEY `quote_transactionsubscenarioid_foreign` (`transactionSubScenarioId`), + KEY `quote_amounttypeid_foreign` (`amountTypeId`), + KEY `quote_currencyid_foreign` (`currencyId`), + CONSTRAINT `quote_amounttypeid_foreign` FOREIGN KEY (`amountTypeId`) REFERENCES `amountType` (`amounttypeid`), + CONSTRAINT `quote_balanceofpaymentsid_foreign` FOREIGN KEY (`balanceOfPaymentsId`) REFERENCES `balanceOfPayments` (`balanceofpaymentsid`), + CONSTRAINT `quote_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quote_transactioninitiatorid_foreign` FOREIGN KEY (`transactionInitiatorId`) REFERENCES `transactionInitiator` (`transactioninitiatorid`), + CONSTRAINT `quote_transactioninitiatortypeid_foreign` FOREIGN KEY (`transactionInitiatorTypeId`) REFERENCES `transactionInitiatorType` (`transactioninitiatortypeid`), + CONSTRAINT `quote_transactionreferenceid_foreign` FOREIGN KEY (`transactionReferenceId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionrequestid_foreign` FOREIGN KEY (`transactionRequestId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionscenarioid_foreign` FOREIGN KEY (`transactionScenarioId`) REFERENCES `transactionScenario` (`transactionscenarioid`), + CONSTRAINT `quote_transactionsubscenarioid_foreign` FOREIGN KEY (`transactionSubScenarioId`) REFERENCES `transactionSubScenario` (`transactionsubscenarioid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteDuplicateCheck` ( + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(1024) DEFAULT NULL COMMENT 'hash value received for the quote request', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteError` +-- + +DROP TABLE IF EXISTS `quoteError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteError` ( + `quoteErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned DEFAULT NULL COMMENT 'The response to the intial quote', + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`quoteErrorId`), + KEY `quoteerror_quoteid_foreign` (`quoteId`), + KEY `quoteerror_quoteresponseid_foreign` (`quoteResponseId`), + CONSTRAINT `quoteerror_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteerror_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteExtension` +-- + +DROP TABLE IF EXISTS `quoteExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteExtension` ( + `quoteExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned NOT NULL COMMENT 'The response to the intial quote', + `transactionId` varchar(36) NOT NULL COMMENT 'The transaction reference that is part of the initial quote', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteExtensionId`), + KEY `quoteextension_quoteid_foreign` (`quoteId`), + KEY `quoteextension_quoteresponseid_foreign` (`quoteResponseId`), + KEY `quoteextension_transactionid_foreign` (`transactionId`), + CONSTRAINT `quoteextension_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteextension_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`), + CONSTRAINT `quoteextension_transactionid_foreign` FOREIGN KEY (`transactionId`) REFERENCES `transactionReference` (`transactionreferenceid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteParty` +-- + +DROP TABLE IF EXISTS `quoteParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteParty` ( + `quotePartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `partyTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of party this row relates to; typically PAYER or PAYEE', + `partyIdentifierTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of identifier used to identify this party e.g. MSISDN, IBAN etc...', + `partyIdentifierValue` varchar(128) NOT NULL COMMENT 'The value of the identifier used to identify this party', + `partySubIdOrTypeId` int(10) unsigned DEFAULT NULL COMMENT 'A sub-identifier or sub-type for the Party', + `fspId` varchar(255) DEFAULT NULL COMMENT 'This is the FSP ID as provided in the quote. For the switch between multi-parties it is required', + `participantId` int(10) unsigned DEFAULT NULL COMMENT 'Reference to the resolved FSP ID (if supplied/known). If not an error will be reported', + `merchantClassificationCode` varchar(4) DEFAULT NULL COMMENT 'Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments', + `partyName` varchar(128) DEFAULT NULL COMMENT 'Display name of the Party, could be a real name or a nick name', + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL COMMENT 'The role this Party is playing in the transaction', + `ledgerEntryTypeId` int(10) unsigned NOT NULL COMMENT 'The type of financial entry this Party is presenting', + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL COMMENT 'Trading currency pertaining to the party amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quotePartyId`), + KEY `quoteparty_quoteid_foreign` (`quoteId`), + KEY `quoteparty_partytypeid_foreign` (`partyTypeId`), + KEY `quoteparty_partyidentifiertypeid_foreign` (`partyIdentifierTypeId`), + KEY `quoteparty_partysubidortypeid_foreign` (`partySubIdOrTypeId`), + KEY `quoteparty_participantid_foreign` (`participantId`), + KEY `quoteparty_transferparticipantroletypeid_foreign` (`transferParticipantRoleTypeId`), + KEY `quoteparty_ledgerentrytypeid_foreign` (`ledgerEntryTypeId`), + KEY `quoteparty_currencyid_foreign` (`currencyId`), + CONSTRAINT `quoteparty_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteparty_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `quoteparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `quoteparty_partyidentifiertypeid_foreign` FOREIGN KEY (`partyIdentifierTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partysubidortypeid_foreign` FOREIGN KEY (`partySubIdOrTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partytypeid_foreign` FOREIGN KEY (`partyTypeId`) REFERENCES `partyType` (`partytypeid`), + CONSTRAINT `quoteparty_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteparty_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quotePartyView` +-- + +DROP TABLE IF EXISTS `quotePartyView`; +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quotePartyView` AS SELECT + 1 AS `quoteId`, + 1 AS `quotePartyId`, + 1 AS `partyType`, + 1 AS `identifierType`, + 1 AS `partyIdentifierValue`, + 1 AS `partySubIdOrType`, + 1 AS `fspId`, + 1 AS `merchantClassificationCode`, + 1 AS `partyName`, + 1 AS `firstName`, + 1 AS `lastName`, + 1 AS `middleName`, + 1 AS `dateOfBirth`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `quoteResponse` +-- + +DROP TABLE IF EXISTS `quoteResponse`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponse` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `transferAmountCurrencyId` varchar(3) NOT NULL COMMENT 'CurrencyId of the transfer amount', + `transferAmount` decimal(18,4) NOT NULL COMMENT 'The amount of money that the Payer FSP should transfer to the Payee FSP', + `payeeReceiveAmountCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee receive amount', + `payeeReceiveAmount` decimal(18,4) DEFAULT NULL COMMENT 'The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees', + `payeeFspFeeCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp fee amount', + `payeeFspFeeAmount` decimal(18,4) DEFAULT NULL COMMENT 'Payee FSP’s part of the transaction fee', + `payeeFspCommissionCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp commission amount', + `payeeFspCommissionAmount` decimal(18,4) DEFAULT NULL COMMENT 'Transaction commission from the Payee FSP', + `ilpCondition` varchar(256) NOT NULL, + `responseExpirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `isValid` tinyint(1) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponse_quoteid_foreign` (`quoteId`), + KEY `quoteresponse_transferamountcurrencyid_foreign` (`transferAmountCurrencyId`), + KEY `quoteresponse_payeereceiveamountcurrencyid_foreign` (`payeeReceiveAmountCurrencyId`), + KEY `quoteresponse_payeefspcommissioncurrencyid_foreign` (`payeeFspCommissionCurrencyId`), + CONSTRAINT `quoteresponse_payeefspcommissioncurrencyid_foreign` FOREIGN KEY (`payeeFspCommissionCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_payeereceiveamountcurrencyid_foreign` FOREIGN KEY (`payeeReceiveAmountCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponse_transferamountcurrencyid_foreign` FOREIGN KEY (`transferAmountCurrencyId`) REFERENCES `currency` (`currencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='This table is the primary store for quote responses'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteResponseDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponseDuplicateCheck` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'The response to the intial quote', + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(255) DEFAULT NULL COMMENT 'hash value received for the quote response', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponseduplicatecheck_quoteid_foreign` (`quoteId`), + CONSTRAINT `quoteresponseduplicatecheck_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponseduplicatecheck_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseIlpPacket` +-- + +DROP TABLE IF EXISTS `quoteResponseIlpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponseIlpPacket` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `value` text NOT NULL COMMENT 'ilpPacket returned from Payee in response to a quote request', + PRIMARY KEY (`quoteResponseId`), + CONSTRAINT `quoteresponseilppacket_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quoteResponseView` +-- + +DROP TABLE IF EXISTS `quoteResponseView`; +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quoteResponseView` AS SELECT + 1 AS `quoteResponseId`, + 1 AS `quoteId`, + 1 AS `transferAmountCurrencyId`, + 1 AS `transferAmount`, + 1 AS `payeeReceiveAmountCurrencyId`, + 1 AS `payeeReceiveAmount`, + 1 AS `payeeFspFeeCurrencyId`, + 1 AS `payeeFspFeeAmount`, + 1 AS `payeeFspCommissionCurrencyId`, + 1 AS `payeeFspCommissionAmount`, + 1 AS `ilpCondition`, + 1 AS `responseExpirationDate`, + 1 AS `isValid`, + 1 AS `createdDate`, + 1 AS `ilpPacket`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Temporary view structure for view `quoteView` +-- + +DROP TABLE IF EXISTS `quoteView`; +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quoteView` AS SELECT + 1 AS `quoteId`, + 1 AS `transactionReferenceId`, + 1 AS `transactionRequestId`, + 1 AS `note`, + 1 AS `expirationDate`, + 1 AS `transactionInitiator`, + 1 AS `transactionInitiatorType`, + 1 AS `transactionScenario`, + 1 AS `balanceOfPaymentsId`, + 1 AS `transactionSubScenario`, + 1 AS `amountType`, + 1 AS `amount`, + 1 AS `currency`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `segment` +-- + +DROP TABLE IF EXISTS `segment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `segment` ( + `segmentId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `segmentType` varchar(50) NOT NULL, + `enumeration` int(11) NOT NULL DEFAULT '0', + `tableName` varchar(50) NOT NULL, + `value` bigint(20) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`segmentId`), + KEY `segment_keys_index` (`segmentType`,`enumeration`,`tableName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlement` +-- + +DROP TABLE IF EXISTS `settlement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlement` ( + `settlementId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementId`), + KEY `settlement_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlement_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementStateChange` (`settlementstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrency` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementParticipantCurrency` ( + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `netAmount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementTransferId` varchar(36) DEFAULT NULL, + PRIMARY KEY (`settlementParticipantCurrencyId`), + KEY `settlementparticipantcurrency_settlementid_index` (`settlementId`), + KEY `settlementparticipantcurrency_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementparticipantcurrency_settlementtransferid_index` (`settlementTransferId`), + KEY `spc_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementparticipantcurrency_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementparticipantcurrency_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `spc_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementParticipantCurrencyStateChange` (`settlementparticipantcurrencystatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrencyStateChange` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrencyStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementParticipantCurrencyStateChange` ( + `settlementParticipantCurrencyStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `externalReference` varchar(50) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementParticipantCurrencyStateChangeId`), + KEY `spcsc_settlementparticipantcurrencyid_index` (`settlementParticipantCurrencyId`), + KEY `spcsc_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `spcsc_settlementparticipantcurrencyid_foreign` FOREIGN KEY (`settlementParticipantCurrencyId`) REFERENCES `settlementParticipantCurrency` (`settlementparticipantcurrencyid`), + CONSTRAINT `spcsc_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementSettlementWindow` +-- + +DROP TABLE IF EXISTS `settlementSettlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementSettlementWindow` ( + `settlementSettlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementSettlementWindowId`), + UNIQUE KEY `settlementsettlementwindow_unique` (`settlementId`,`settlementWindowId`), + KEY `settlementsettlementwindow_settlementid_index` (`settlementId`), + KEY `settlementsettlementwindow_settlementwindowid_index` (`settlementWindowId`), + CONSTRAINT `settlementsettlementwindow_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementsettlementwindow_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementState` +-- + +DROP TABLE IF EXISTS `settlementState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementState` ( + `settlementStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementStateChange` +-- + +DROP TABLE IF EXISTS `settlementStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementStateChange` ( + `settlementStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateChangeId`), + KEY `settlementstatechange_settlementid_index` (`settlementId`), + KEY `settlementstatechange_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `settlementstatechange_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementstatechange_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementTransferParticipant` +-- + +DROP TABLE IF EXISTS `settlementTransferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementTransferParticipant` ( + `settlementTransferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementTransferParticipantId`), + KEY `settlementtransferparticipant_settlementid_index` (`settlementId`), + KEY `settlementtransferparticipant_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementtransferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `stp_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementtransferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `settlementtransferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementtransferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementtransferparticipant_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementtransferparticipant_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `stp_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindow` +-- + +DROP TABLE IF EXISTS `settlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindow` ( + `settlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowId`), + KEY `settlementwindow_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementwindow_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowStateChange` (`settlementwindowstatechangeid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowState` +-- + +DROP TABLE IF EXISTS `settlementWindowState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindowState` ( + `settlementWindowStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindowStateChange` ( + `settlementWindowStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateChangeId`), + KEY `settlementwindowstatechange_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `settlementwindowstatechange_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `settlementwindowstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `token` +-- + +DROP TABLE IF EXISTS `token`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `token` ( + `tokenId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `expiration` bigint(20) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`tokenId`), + UNIQUE KEY `token_value_unique` (`value`), + KEY `token_participantid_index` (`participantId`), + CONSTRAINT `token_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiator` +-- + +DROP TABLE IF EXISTS `transactionInitiator`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionInitiator` ( + `transactionInitiatorId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorId`), + UNIQUE KEY `transactioninitiator_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiatorType` +-- + +DROP TABLE IF EXISTS `transactionInitiatorType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionInitiatorType` ( + `transactionInitiatorTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorTypeId`), + UNIQUE KEY `transactioninitiatortype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionReference` +-- + +DROP TABLE IF EXISTS `transactionReference`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionReference` ( + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `quoteId` varchar(36) DEFAULT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System row creation timestamp', + PRIMARY KEY (`transactionReferenceId`), + KEY `transactionreference_quoteid_index` (`quoteId`), + CONSTRAINT `transactionreference_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quoteDuplicateCheck` (`quoteid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionScenario` +-- + +DROP TABLE IF EXISTS `transactionScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionScenario` ( + `transactionScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionScenarioId`), + UNIQUE KEY `transactionscenario_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionSubScenario` +-- + +DROP TABLE IF EXISTS `transactionSubScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionSubScenario` ( + `transactionSubScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible sub-scenario, defined locally within the scheme', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionSubScenarioId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transfer` +-- + +DROP TABLE IF EXISTS `transfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transfer` ( + `transferId` varchar(36) NOT NULL, + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ilpCondition` varchar(256) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfer_currencyid_index` (`currencyId`), + CONSTRAINT `transfer_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `transfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferError` +-- + +DROP TABLE IF EXISTS `transferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferError` ( + `transferId` varchar(36) NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfererror_transferstatechangeid_foreign` (`transferStateChangeId`), + CONSTRAINT `transfererror_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferErrorDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferErrorDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferErrorDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transfererrorduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferExtension` +-- + +DROP TABLE IF EXISTS `transferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferExtension` ( + `transferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `isError` tinyint(1) NOT NULL DEFAULT '0', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferExtensionId`), + KEY `transferextension_transferid_foreign` (`transferId`), + CONSTRAINT `transferextension_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilment` +-- + +DROP TABLE IF EXISTS `transferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferFulfilment` ( + `transferId` varchar(36) NOT NULL, + `ilpFulfilment` varchar(256) DEFAULT NULL, + `completedDate` datetime NOT NULL, + `isValid` tinyint(1) DEFAULT NULL, + `settlementWindowId` bigint(20) unsigned DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transferfulfilment_settlementwindowid_foreign` (`settlementWindowId`), + CONSTRAINT `transferfulfilment_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `transferfulfilment_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferFulfilmentDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferFulfilmentDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transferfulfilmentduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipant` +-- + +DROP TABLE IF EXISTS `transferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferParticipant` ( + `transferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantId`), + KEY `transferparticipant_transferid_index` (`transferId`), + KEY `transferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `transferparticipant_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `transferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `transferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `transferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `transferparticipant_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferparticipant_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantRoleType` +-- + +DROP TABLE IF EXISTS `transferParticipantRoleType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferParticipantRoleType` ( + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantRoleTypeId`), + UNIQUE KEY `transferparticipantroletype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferRules` +-- + +DROP TABLE IF EXISTS `transferRules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferRules` ( + `transferRulesId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `rule` text NOT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferRulesId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferState` +-- + +DROP TABLE IF EXISTS `transferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferState` ( + `transferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'transferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferStateChange` +-- + +DROP TABLE IF EXISTS `transferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferStateChange` ( + `transferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `transferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateChangeId`), + KEY `transferstatechange_transferid_index` (`transferId`), + KEY `transferstatechange_transferstateid_index` (`transferStateId`), + CONSTRAINT `transferstatechange_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferstatechange_transferstateid_foreign` FOREIGN KEY (`transferStateId`) REFERENCES `transferState` (`transferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferTimeout` +-- + +DROP TABLE IF EXISTS `transferTimeout`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferTimeout` ( + `transferTimeoutId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferTimeoutId`), + UNIQUE KEY `transfertimeout_transferid_unique` (`transferId`), + CONSTRAINT `transfertimeout_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Final view structure for view `quotePartyView` +-- + +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quotePartyView` AS select `qp`.`quoteId` AS `quoteId`,`qp`.`quotePartyId` AS `quotePartyId`,`pt`.`name` AS `partyType`,`pit`.`name` AS `identifierType`,`qp`.`partyIdentifierValue` AS `partyIdentifierValue`,`spit`.`name` AS `partySubIdOrType`,`qp`.`fspId` AS `fspId`,`qp`.`merchantClassificationCode` AS `merchantClassificationCode`,`qp`.`partyName` AS `partyName`,`p`.`firstName` AS `firstName`,`p`.`lastName` AS `lastName`,`p`.`middleName` AS `middleName`,`p`.`dateOfBirth` AS `dateOfBirth`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from (((((`quoteParty` `qp` join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) join `partyIdentifierType` `pit` on((`pit`.`partyIdentifierTypeId` = `qp`.`partyIdentifierTypeId`))) left join `party` `p` on((`p`.`quotePartyId` = `qp`.`quotePartyId`))) left join `partyIdentifierType` `spit` on((`spit`.`partyIdentifierTypeId` = `qp`.`partySubIdOrTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteResponseView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteResponseView` AS select `qr`.`quoteResponseId` AS `quoteResponseId`,`qr`.`quoteId` AS `quoteId`,`qr`.`transferAmountCurrencyId` AS `transferAmountCurrencyId`,`qr`.`transferAmount` AS `transferAmount`,`qr`.`payeeReceiveAmountCurrencyId` AS `payeeReceiveAmountCurrencyId`,`qr`.`payeeReceiveAmount` AS `payeeReceiveAmount`,`qr`.`payeeFspFeeCurrencyId` AS `payeeFspFeeCurrencyId`,`qr`.`payeeFspFeeAmount` AS `payeeFspFeeAmount`,`qr`.`payeeFspCommissionCurrencyId` AS `payeeFspCommissionCurrencyId`,`qr`.`payeeFspCommissionAmount` AS `payeeFspCommissionAmount`,`qr`.`ilpCondition` AS `ilpCondition`,`qr`.`responseExpirationDate` AS `responseExpirationDate`,`qr`.`isValid` AS `isValid`,`qr`.`createdDate` AS `createdDate`,`qrilp`.`value` AS `ilpPacket`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from ((((`quoteResponse` `qr` join `quoteResponseIlpPacket` `qrilp` on((`qrilp`.`quoteResponseId` = `qr`.`quoteResponseId`))) join `quoteParty` `qp` on((`qp`.`quoteId` = `qr`.`quoteId`))) join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) where (`pt`.`name` = 'PAYEE') */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteView` AS select `q`.`quoteId` AS `quoteId`,`q`.`transactionReferenceId` AS `transactionReferenceId`,`q`.`transactionRequestId` AS `transactionRequestId`,`q`.`note` AS `note`,`q`.`expirationDate` AS `expirationDate`,`ti`.`name` AS `transactionInitiator`,`tit`.`name` AS `transactionInitiatorType`,`ts`.`name` AS `transactionScenario`,`q`.`balanceOfPaymentsId` AS `balanceOfPaymentsId`,`tss`.`name` AS `transactionSubScenario`,`amt`.`name` AS `amountType`,`q`.`amount` AS `amount`,`q`.`currencyId` AS `currency` from (((((`quote` `q` join `transactionInitiator` `ti` on((`ti`.`transactionInitiatorId` = `q`.`transactionInitiatorId`))) join `transactionInitiatorType` `tit` on((`tit`.`transactionInitiatorTypeId` = `q`.`transactionInitiatorTypeId`))) join `transactionScenario` `ts` on((`ts`.`transactionScenarioId` = `q`.`transactionScenarioId`))) join `amountType` `amt` on((`amt`.`amountTypeId` = `q`.`amountTypeId`))) left join `transactionSubScenario` `tss` on((`tss`.`transactionSubScenarioId` = `q`.`transactionSubScenarioId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-10-14 21:12:45 diff --git a/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd new file mode 100644 index 000000000..12059bab5 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + COLOR LEGEND: +Green - subject specific entity +Gray - transfer specific entity +Brown - bulk transfer entity +Red - settlement specific entity +Blue - lookup entity +Cyan - impl. specific +Yellow - tbd + + \ No newline at end of file diff --git a/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema.png b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema.png new file mode 100644 index 000000000..6afdaf2ea Binary files /dev/null and b/docs/technical/technical/central-bulk-transfers/assets/database/central-ledger-schema.png differ diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png b/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png new file mode 100644 index 000000000..aa361a64a Binary files /dev/null and b/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png differ diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg new file mode 100644 index 000000000..b22f23afe --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg @@ -0,0 +1,3 @@ + + +
    1.7 Increment Position (fsp1)
    [Not supported by viewer]
    1.6 Increment
    Position (fsp1)

    [Not supported by viewer]
    Fulfil
    Sucess
    [Not supported by viewer]
    2.6 Fulfil
    Success
    [Not supported by viewer]
    <alt> 2.6  Fulfil Reject
    [Not supported by viewer]
    Fulfil
    Reject
    [Not supported by viewer]
    <alt> 2.7 Decrement
    Position (fsp1)

    [Not supported by viewer]
    Central - Services
    <font style="font-size: 18px">Central - Services</font>
    3.0 Reject
    [Not supported by viewer]
    1.0 Bulk Transfer 
    Request

    [Not supported by viewer]
    3.1 Decrement
    Position (fsp1)

    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    Bulk Transfer
    Bulk Transfer<br>
    Notification
    Event Handler
    [Not supported by viewer]
    notifications
    notifications
    FSP1
    (Payer)

    [Not supported by viewer]
    FSP2
    (Payee)
    [Not supported by viewer]
    1.1
    Prepare Request
    [Not supported by viewer]
    1.2 Accpeted
    (202)
    [Not supported by viewer]
    Bulk Transfer
    Bulk Transfer<br>
    2.0 Bulk Fulfil 
    Success / 
    Reject

    [Not supported by viewer]
    bulk fulfil
    bulk fulfil
    2.7 Decrement
    Position (fsp2)

    [Not supported by viewer]
    2.1 Bulk Fulfil 
    Success / Reject

    [Not supported by viewer]
    2.2 OK
    (202)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    Transfer Timeout
    Handler
    [Not supported by viewer]
    2.12 Bulk Fulfil Notify Callback /
    <alt> 2.12 Bulk Reject Response (Fulfil reject) /
    3.6 Bulk Reject Response (Timeout) /
    <alt> 1.8 Bulk Prepare Failure 
    [Not supported by viewer]
    1.12 Bulk Prepare Notify /
    2.13 Bulk Fulfil Notify /
    <alt> 2.13 Bulk Reject Response (Fulfil reject)
    3.7 Bulk Reject Response (Timeout)

    [Not supported by viewer]
    positions
    positions<br>
    bulk processing
    bulk processing
    BulkFulfil
    Handler
    [Not supported by viewer]
    1.3 Bulk Prepare Consume
    [Not supported by viewer]
    BulkPrepare
    Handler
    BulkPrepare<br>Handler
     prepare
     prepare
    fulfil
    fulfil
    BulkProcessing Handler
    BulkProcessing Handler<br>
    1.4 Individual Prepare
    [Not supported by viewer]
    1.5 Individual Prepare
    [Not supported by viewer]
    1.5
     / 1.9 / 2.9 / 3.3
     Individual Notify
    [Not supported by viewer]
    1.8 / 2.8 / 3.2 Individual
    Notify
    [Not supported by viewer]
    1.6 / 1.10 / 2.10 / 3.4 Bulk Notify
    [Not supported by viewer]
    1.7 / 1.11 / 2.11 / 3.5 Bulk Notify
    [Not supported by viewer]
    2.3 Bulk Fulfil Consume
    [Not supported by viewer]
    2.4 Individual
    Fulfil
    [Not supported by viewer]
    2.5 Individual
    Fulfil
    [Not supported by viewer]
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    [Not supported by viewer]
    PositionHandler
    PositionHandler
    PrepareHandler
    PrepareHandler
    Object Store
    [Not supported by viewer]
    <alt> 1.4 Bulk Prepare Failure
    [Not supported by viewer]
    <alt> 1.6 Individual Prepare Failure
    [Not supported by viewer]
    <alt> 1.8 Individual
    Failure Notify

    [Not supported by viewer]
    <alt> 2.4 Bulk Fulfil Failure
    [Not supported by viewer]
    <alt> 2.6 Individual Fulfil Failure
    [Not supported by viewer]
    bulk prepare
    bulk prepare
    Object Store
    [Not supported by viewer]
    Object Store
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml new file mode 100644 index 000000000..5bdd8119f --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml @@ -0,0 +1,217 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULK_API +control "Bulk API Notification \nHandler" as NOTIFY_HANDLER +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +boundary "Central Service API" as CSAPI +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +control "Bulk Prepare\nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Handler" as PREP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULK_API + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant CSAPI + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_PREP_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +activate BULK_PROC_HANDLER +group DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - bulkTransferMessage: + { + bulkTransferId: , + bulkQuoteId: , + payeeFsp: , + payerFsp: , + individualTransfers: [ + { + transferId: , + transferAmount: + { + currency: , + amount: + }, + ilpPacket: , + condition: , + extensionList: { extension: [ + { key: , value: } + ] } + } + ], + extensionList: { extension: [ + { key: , value: } + ] }, + expiration: + } + end note + DFSP1 ->> BULK_API: POST - /bulkTransfers + activate BULK_API + BULK_API -> BULK_API: Validate incoming message\nError codes: 3000-3002, 3100-3107 + loop + BULK_API -> OBJECT_STORE: Persist individual transfers in the bulk to\nobject store: **MLOS.individualTransfers** + activate OBJECT_STORE + OBJECT_STORE --> BULK_API: Return messageId reference to the stored object(s) + deactivate OBJECT_STORE + end + note right of BULK_API #yellow + Message: + { + id: + to: , + from: , + type: "application/json" + content: { + headers: , + payload: { + bulkTransferId: , + bulkQuoteId": , + payerFsp: , + payeeFsp: , + expiration: , + hash: + } + }, + metadata: { + event: { + id: , + type: "bulk-prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_API -> TOPIC_BULK_PREPARE: Route & Publish Bulk Prepare event \nfor Payer\nError code: 2003 + activate TOPIC_BULK_PREPARE + TOPIC_BULK_PREPARE <-> TOPIC_BULK_PREPARE: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 + TOPIC_BULK_PREPARE --> BULK_API: Respond replication acknowledgements \nhave been received + deactivate TOPIC_BULK_PREPARE + BULK_API -->> DFSP1: Respond HTTP - 202 (Accepted) + deactivate BULK_API + ||| + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume message + ref over TOPIC_BULK_PREPARE, BULK_PREP_HANDLER, TOPIC_TRANSFER_PREPARE: Bulk Prepare Handler Consume \n + alt Success + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Produce (stream) single transfer message\nfor each individual transfer [loop] + else Failure + BULK_PREP_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk + end + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION: Prepare Handler Consume\n + alt Success + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + else Failure + PREP_HANDLER --> TOPIC_BULK_PROCESSING: Produce message + end + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER, TOPIC_BULK_PROCESSING: Position Handler Consume\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + ||| + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + ref over TOPIC_BULK_PROCESSING, BULK_PROC_HANDLER, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume\n + BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** + deactivate OBJECT_STORE + BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Prepare notification + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification(s) payload + deactivate OBJECT_STORE + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send Bulk Prepare notification to Payee + ||| +end +deactivate POS_HANDLER +deactivate BULK_PREP_HANDLER +deactivate PREP_HANDLER +deactivate BULK_PROC_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg new file mode 100644 index 000000000..9c52a416a --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg @@ -0,0 +1,405 @@ + + 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + Financial Service Providers + + Bulk API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification + Handler + + + Bulk API Notification + Handler + + + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + Central Service API + + + Central Service API + + + + + topic- + bulk-prepare + + + topic- + bulk-prepare + Bulk Prepare + Handler + + + Bulk Prepare + Handler + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + Prepare Handler + + + Prepare Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position Handler + + + Position Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + notifications + + + topic- + notifications + + + + + + + + + + + + + DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + Headers - transferHeaders: { + Content-Length: <int>, + Content-Type: <string>, + Date: <date>, + FSPIOP-Source: <string>, + FSPIOP-Destination: <string>, + FSPIOP-Encryption: <string>, + FSPIOP-Signature: <string>, + FSPIOP-URI: <uri>, + FSPIOP-HTTP-Method: <string> + } +   + Payload - bulkTransferMessage: + { + bulkTransferId: <uuid>, + bulkQuoteId: <uuid>, + payeeFsp: <string>, + payerFsp: <string>, + individualTransfers: [ + { + transferId: <uuid>, + transferAmount: + { + currency: <string>, + amount: <string> + }, + ilpPacket: <string>, + condition: <string>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + ], + extensionList: { extension: [ + { key: <string>, value: <string> } + ] }, + expiration: <string> + } + + + + 1 + POST - /bulkTransfers + + + + + 2 + Validate incoming message + Error codes: + 3000-3002, 3100-3107 + + + loop + + + 3 + Persist individual transfers in the bulk to + object store: + MLOS.individualTransfers + + + 4 + Return messageId reference to the stored object(s) + + + Message: + { + id: <messageId> + to: <payeeFspName>, + from: <payerFspName>, + type: "application/json" + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkQuoteId": <uuid>, + payerFsp: <string>, + payeeFsp: <string>, + expiration: <timestamp>, + hash: <string> + } + }, + metadata: { + event: { + id: <uuid>, + type: "bulk-prepare", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 5 + Route & Publish Bulk Prepare event + for Payer + Error code: + 2003 + + + + + + 6 + Ensure event is replicated + as configured (ACKS=all) + Error code: + 2003 + + + 7 + Respond replication acknowledgements + have been received + + + + 8 + Respond HTTP - 202 (Accepted) + + + 9 + Consume message + + + ref + Bulk Prepare Handler Consume +   + + + alt + [Success] + + + 10 + Produce (stream) single transfer message + for each individual transfer [loop] + + [Failure] + + + 11 + Produce single message for the entire bulk + + + 12 + Consume message + + + ref + Prepare Handler Consume +   + + + alt + [Success] + + + 13 + Produce message + + [Failure] + + + 14 + Produce message + + + 15 + Consume message + + + ref + Position Handler Consume +   + + + 16 + Produce message + + + 17 + Consume message + + + ref + Bulk Processing Handler Consume +   + + + 18 + Persist bulk message by destination to the + object store: + MLOS.bulkTransferResults + + + 19 + Return the reference to the stored + notification object(s): + messageId + + + 20 + Send Bulk Prepare notification + + + 21 + Consume message + + + 22 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 23 + Return notification(s) payload + + + ref + Send notification to Participant (Payee) +   + + + 24 + Send Bulk Prepare notification to Payee + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml new file mode 100644 index 000000000..a9c53292f --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml @@ -0,0 +1,320 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.1. Bulk Prepare Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +control "Bulk Prepare \nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +collections "topic-event" as TOPIC_EVENTS +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +entity "Bulk DAO" as BULK_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant BULK_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate BULK_PREP_HANDLER +group Bulk Prepare Handler Consume + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume Bulk Prepare message + activate TOPIC_BULK_PREPARE + deactivate TOPIC_BULK_PREPARE + group Validate Bulk Prepare Transfer + group Duplicate Check + note right of BULK_PREP_HANDLER #cyan + The Specification doesn't touch on the duplicate handling + of bulk transfers, so the current design mostly follows the + strategy used for individual transfers, except in two places: + + 1. For duplicate requests where hash matches, the current design + includes only the status of the bulk & timestamp (if completed), + but not the individual transfers (for which a GET should be used). + + 2. For duplicate requests where hash matches, but are not in a + finalized state, only the state of the bulkTransfer is sent. + end note + ||| + BULK_PREP_HANDLER -> DB: Request Duplicate Check + ref over BULK_PREP_HANDLER, DB: Request Duplicate Check (using message.content.payload)\n + DB --> BULK_PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break Return TRUE & Log ('Not implemented') + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of BULK_PREP_HANDLER #yellow + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: + } + ] + } + }, + uriParams: { + id: + } + } + }, + metadata: { + correlationId: , + event: { + id: , + type: "notification", + action: "bulk-prepare", + createdAt: , + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 3106 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else hasDuplicateId == FALSE + group Validate Bulk Transfer Prepare Request + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: FSPIOP Source matches Payer + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Check expiration + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Payer and Payee FSP's are different + group Validate Payer + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payee\nError codes: 3203 + end + end + ||| + alt Validate Bulk Transfer Prepare Request (success) + group Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + else Validate Bulk Transfer Prepare Request (failure) + group Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist transfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + bulkTransferError + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + end + end + end + alt Validate Bulk Prepare Transfer (success) + loop for each individual transfer in the bulk + BULK_PREP_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransfers.messageId** + activate OBJECT_STORE + note right of OBJECT_STORE #lightgrey + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + transfer to make their format similar to a single transfer + end note + OBJECT_STORE --> BULK_PREP_HANDLER: Stream bulk's individual transfers + deactivate OBJECT_STORE + + group Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Route & Publish Prepare event to the Payee for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + end + else Validate Bulk Prepare Transfer (failure) + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-abort", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + group Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + end +end +deactivate BULK_PREP_HANDLER +@enduml + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg new file mode 100644 index 000000000..ac272e017 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg @@ -0,0 +1,518 @@ + + 1.1.1. Bulk Prepare Handler Consume + + + 1.1.1. Bulk Prepare Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + + + topic- + bulk-prepare + + + topic- + bulk-prepare + Bulk Prepare + Handler + + + Bulk Prepare + Handler + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + + + topic-event + + + topic-event + + + topic- + notification + + + topic- + notification + + + topic-bulk- + processing + + + topic-bulk- + processing + Bulk DAO + + + Bulk DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + Bulk Prepare Handler Consume + + + 1 + Consume Bulk Prepare message + + + Validate Bulk Prepare Transfer + + + Duplicate Check + + + The Specification doesn't touch on the duplicate handling + of bulk transfers, so the current design mostly follows the + strategy used for individual transfers, except in two places: +   + 1. For duplicate requests where hash matches, the current design + includes only the status of the bulk & timestamp (if completed), + but not the individual transfers (for which a GET should be used). +   + 2. For duplicate requests where hash matches, but are not in a + finalized state, only the state of the bulkTransfer is sent. + + + 2 + Request Duplicate Check + + + ref + Request Duplicate Check (using message.content.payload) +   + + + 3 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + [Return TRUE & Log ('Not implemented')] + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + { + id: <messageId>, + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: <FSPIOPError> + } + ] + } + }, + uriParams: { + id: <bulkTransferId> + } + } + }, + metadata: { + correlationId: <uuid>, + event: { + id: <uuid>, + type: "notification", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: <uuid> + } + } + } + + + 4 + Publish Notification (failure) event for Payer + Error codes: + 3106 + + [hasDuplicateId == FALSE] + + + Validate Bulk Transfer Prepare Request + + + + + + 5 + FSPIOP Source matches Payer + + + + + + 6 + Check expiration + + + + + + 7 + Payer and Payee FSP's are different + + + Validate Payer + + + 8 + Request to retrieve Payer Participant details (if it exists) + + + 9 + Request Participant details + + participant + participantCurrency + + + 10 + Return Participant details if it exists + + + 11 + Return Participant details if it exists + + + + + + 12 + Validate Payer + Error codes: + 3202 + + + Validate Payee + + + 13 + Request to retrieve Payee Participant details (if it exists) + + + 14 + Request Participant details + + participant + participantCurrency + + + 15 + Return Participant details if it exists + + + 16 + Return Participant details if it exists + + + + + + 17 + Validate Payee + Error codes: + 3203 + + + alt + [Validate Bulk Transfer Prepare Request (success)] + + + Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + + + 18 + Request to persist bulk transfer + Error codes: + 2003 + + + 19 + Persist bulkTransfer + + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + + + 20 + Return state + + [Validate Bulk Transfer Prepare Request (failure)] + + + Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 21 + Request to persist bulk transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + + 22 + Persist transfer + + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + bulkTransferError + + + 23 + Return state + + + alt + [Validate Bulk Prepare Transfer (success)] + + + loop + [for each individual transfer in the bulk] + + + 24 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransfers.messageId + + + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + transfer to make their format similar to a single transfer + + + 25 + Stream bulk's individual transfers + + + Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + + + 26 + Request to persist bulk transfer association + Error codes: + 2003 + + + 27 + Insert bulkTransferAssociation + + bulkTransferAssociation + bulkTransferStateChange + + + 28 + Return state + + + Message: + { + id: <messageId> + from: <payerFspName>, + to: <payeeFspName>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "prepare", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + + + 29 + Route & Publish Prepare event to the Payee for the Individual Transfer + Error codes: + 2003 + + [Validate Bulk Prepare Transfer (failure)] + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <bulkTransferMessage.payerFsp>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 7.6 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-abort", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 30 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + + Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + + + 31 + Request to persist bulk transfer association + Error codes: + 2003 + + + 32 + Insert bulkTransferAssociation + + bulkTransferAssociation + bulkTransferStateChange + + + 33 + Return state + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml new file mode 100644 index 000000000..aee02560a --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml @@ -0,0 +1,324 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.2.1. Prepare Handler Consume individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Handler" as PREP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +collections "topic-\nevent" as TOPIC_EVENTS +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event message + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Validate Event + PREP_HANDLER <-> PREP_HANDLER: Validate event - Rule: type == 'prepare' && action == 'bulk-prepare'\nError codes: 2001 + end + end + + group Persist Event Information + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publish event information + ref over PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + group Validate Prepare Transfer + PREP_HANDLER <-> PREP_HANDLER: Schema validation of the incoming message + PREP_HANDLER <-> PREP_HANDLER: Verify the message's signature (to be confirmed in future requirement) + + group Validate Duplicate Check + ||| + PREP_HANDLER -> DB: Request Duplicate Check + ref over PREP_HANDLER, DB: Request Duplicate Check\n + DB --> PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + note right of PREP_HANDLER #lightgrey + In the context of a bulk (when compared to regular transfers), duplicate + individual transfers are now considered and reported with Modified Request, + because they could have already been handled for another bulk. + end note + break + note right of PREP_HANDLER #yellow + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request - Individual transfer prepare duplicate", + extensionList: { extension: [ { key: "_cause", value: } ] } + } + }, + uriParams: { id: } + }, + metadata: { + correlationId: , + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: , + state: { + code: "3106", + status: "error", + description: "Modified request - Individual transfer prepare duplicate" + }, + id: , + responseTo: + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + break + note right of PREP_HANDLER #yellow + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { extension: [ { key: "_cause", value: } ] } + } + }, + uriParams: { id: } + }, + metadata: { + correlationId: , + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: , + state: { + code: "3106", + status: "error", + description: "Modified request" + }, + id: , + responseTo: + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else hasDuplicateId == FALSE + note right of PREP_HANDLER #lightgrey + The validation of Payer, Payee can be skipped for individual transfers in Bulk + as they should've/would've been validated already in the bulk prepare part. + However, leaving it here for now, as in the future, this can be leveraged + when bulk transfers to multiple Payees are supported by the Specification. + end note + group Validate Payer + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee\nError codes: 3203 + end + + alt Validate Prepare Transfer (success) + group Persist Transfer State (with transferState='RECEIVED-PREPARE') + PREP_HANDLER -> POS_DAO: Request to persist transfer\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + else Validate Prepare Transfer (failure) + group Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + PREP_HANDLER -> POS_DAO: Request to persist transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + end + end + end + + alt Validate Prepare Transfer (success) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "position", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer\nError codes: 2003 + else Validate Prepare Transfer (failure) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "prepare", + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Prepare failure event to Bulk Processing Topic (for Payer) \nError codes: 2003 + end +end + +deactivate PREP_HANDLER +@enduml + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg new file mode 100644 index 000000000..210388650 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg @@ -0,0 +1,484 @@ + + 1.2.1. Prepare Handler Consume individual transfers from Bulk + + + 1.2.1. Prepare Handler Consume individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + transfer-prepare + + + topic- + transfer-prepare + Prepare Handler + + + Prepare Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Prepare Handler Consume + + + 1 + Consume Prepare event message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'prepare' && action == 'bulk-prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate Prepare Transfer + + + + + + 4 + Schema validation of the incoming message + + + + + + 5 + Verify the message's signature (to be confirmed in future requirement) + + + Validate Duplicate Check + + + 6 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 7 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + In the context of a bulk (when compared to regular transfers), duplicate + individual transfers are now considered and reported with Modified Request, + because they could have already been handled for another bulk. + + + break + + + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request - Individual transfer prepare duplicate", + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + } + }, + uriParams: { id: <transferId> } + }, + metadata: { + correlationId: <uuid>, + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: <timestamp>, + state: { + code: "3106", + status: "error", + description: "Modified request - Individual transfer prepare duplicate" + }, + id: <uuid>, + responseTo: <uuid> + } + } + + + 8 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + break + + + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + } + }, + uriParams: { id: <transferId> } + }, + metadata: { + correlationId: <uuid>, + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: <timestamp>, + state: { + code: "3106", + status: "error", + description: "Modified request" + }, + id: <uuid>, + responseTo: <uuid> + } + } + + + 9 + Publish Processing (failure) event for Payer + Error codes: + 2003 + + [hasDuplicateId == FALSE] + + + The validation of Payer, Payee can be skipped for individual transfers in Bulk + as they should've/would've been validated already in the bulk prepare part. + However, leaving it here for now, as in the future, this can be leveraged + when bulk transfers to multiple Payees are supported by the Specification. + + + Validate Payer + + + 10 + Request to retrieve Payer Participant details (if it exists) + + + 11 + Request Participant details + + participant + participantCurrency + + + 12 + Return Participant details if it exists + + + 13 + Return Participant details if it exists + + + + + + 14 + Validate Payer + Error codes: + 3202 + + + Validate Payee + + + 15 + Request to retrieve Payee Participant details (if it exists) + + + 16 + Request Participant details + + participant + participantCurrency + + + 17 + Return Participant details if it exists + + + 18 + Return Participant details if it exists + + + + + + 19 + Validate Payee + Error codes: + 3203 + + + alt + [Validate Prepare Transfer (success)] + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + 20 + Request to persist transfer + Error codes: + 2003 + + + 21 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + + + 22 + Return success + + [Validate Prepare Transfer (failure)] + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 23 + Request to persist transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + + 24 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + + + 25 + Return success + + + alt + [Validate Prepare Transfer (success)] + + + Message: + { + id: <messageId> + from: <payerFspName>, + to: <payeeFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "position", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + + + 26 + Route & Publish Position event for Payer + Error codes: + 2003 + + [Validate Prepare Transfer (failure)] + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 35.1.3 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "prepare", + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Prepare failure event to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml new file mode 100644 index 000000000..44d640284 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Position Handler Consume individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + alt Consume Prepare message for Payer + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'bulk-prepare'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS: Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Prepare Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Fulfil message for Payee + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'bulk-commit'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Fulfil Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Abort message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'timeout-reserved'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Abort Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg new file mode 100644 index 000000000..ee9d9ac7c --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg @@ -0,0 +1,187 @@ + + 1.3.0. Position Handler Consume individual transfers from Bulk + + + 1.3.0. Position Handler Consume individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Handler + + + Position Handler + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + + + + + + + Position Handler Consume + + + alt + [Consume Prepare message for Payer] + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'position' && action == 'bulk-prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Prepare Position Handler Consume +   + + + 4 + Produce message + + [Consume Fulfil message for Payee] + + + 5 + Consume Position event message for Payee + + + break + + + Validate Event + + + + + + 6 + Validate event - Rule: type == 'position' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 7 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Fulfil Position Handler Consume +   + + + 8 + Produce message + + [Consume Abort message] + + + 9 + Consume Position event message + + + break + + + Validate Event + + + + + + 10 + Validate event - Rule: type == 'position' && action == 'timeout-reserved' + Error codes: + 2001 + + + Persist Event Information + + + 11 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Abort Position Handler Consume +   + + + 12 + Produce message + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml new file mode 100644 index 000000000..370eaf388 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml @@ -0,0 +1,365 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER + +entity "Position\nManagement\nFacade" as POS_MGMT +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_MGMT + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Prepare Position Handler Consume + POS_HANDLER -> POS_MGMT: Request transfers to be processed + activate POS_MGMT + POS_MGMT -> POS_MGMT: Check 1st transfer to select the Participant and Currency + group DB TRANSACTION + ' DB Trans: This is where 1st DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT -> POS_MGMT: Loop through batch and build list of transferIds and calculate sumTransfersInBatch,\nchecking all in Batch are for the correct Paricipant and Currency\nError code: 2001, 3100 + POS_MGMT -> DB: Retrieve current state of all transfers in array from DB with select whereIn\n(FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_MGMT: Return current state of all selected transfers from DB + deactivate DB + POS_MGMT <-> POS_MGMT: Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nError code: 2001 against failing transfers\nBatch is not rejected as a whole. + + note right of POS_MGMT #lightgray + List of transfers used during processing + **reservedTransfers** is list of transfers to be processed in the batch + **abortedTransfers** is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + **processedTransfers** is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + Scalar intermidate values used in the algorithm + **transferAmount** = payload.amount.amount + **sumTransfersInBatch** = SUM amount against each Transfer in batch + **currentPosition** = participantPosition.value + **reservedPosition** = participantPosition.{original}reservedValue + **effectivePosition** = currentPosition + reservedPosition + **heldPosition** = effectivePosition + sumTransfersInBatch + **availablePosition** = participantLimit(NetDebitCap) - effectivePosition + **sumReserved** = SUM of transfers that have met rule criteria and processed + end note + note over POS_MGMT,DB + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + end note + POS_MGMT -> DB: Select effectivePosition FOR UPDATE from DB for Payer + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_MGMT: Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + deactivate DB + POS_MGMT -> POS_MGMT: Increment reservedValue to heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) + POS_MGMT -> DB: Persist reservedValue + activate DB + hnote over DB #lightyellow + UPDATE **participantPosition** + SET reservedValue += sumTransfersInBatch + end note + deactivate DB + ' DB Trans: This is where 1st DB Transaction would end in 2 DB transacation future model for horizontal scaling + + + POS_MGMT -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + FROM **participantLimit** + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + end note + DB --> POS_MGMT: Return position limits + deactivate DB + POS_MGMT <-> POS_MGMT: **availablePosition** = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) + note over POS_MGMT,DB + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + end note + POS_MGMT <-> POS_MGMT: Validate availablePosition for each tranfser (see algorithm below)\nError code: 4001 + note right of POS_MGMT #lightgray + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far **(NEED TO UPDATE IN CODE)** + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(NEED TO UPDATE IN CODE)** // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + end note + note over POS_MGMT,DB + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + end note + POS_MGMT->POS_MGMT: Assess any limit thresholds on the final position\nadding to alarm list if triggered + + ' DB Trans: This is where 2nd DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT->DB: Persist latest position **value** and **reservedValue** to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + end note + activate DB + deactivate DB + + POS_MGMT -> DB: Bulk persist transferStateChange for all processedTransfers + hnote over DB #lightyellow + batch INSERT **transferStateChange** + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch + + end note + activate DB + deactivate DB + + POS_MGMT->POS_MGMT: Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + note right of POS_MGMT #lightgray + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + end note + POS_MGMT -> DB: Bulk persist the participant position change for all processedTransfers + hnote over DB #lightyellow + batch INSERT **participantPositionChange** + end note + activate DB + deactivate DB + ' DB Trans: This is where 2nd DB Transaction would end in 2 DB transacation future model for horizontal scaling + end + POS_MGMT --> POS_HANDLER: Return a map of transferIds and their transferStateChanges + deactivate POS_MGMT + alt Calculate & Validate Latest Position Prepare (success) + POS_HANDLER -> POS_HANDLER: Notifications for Position Validation Success \nReference: Position Validation Success case (Prepare) + else Calculate & Validate Latest Position Prepare (failure) + note right of POS_HANDLER #red: Validation failure! + + group Persist Transfer State (with transferState='ABORTED' on position check fail) + POS_HANDLER -> POS_DAO: Request to persist transfer\nError code: 2003 + activate POS_DAO + note right of POS_HANDLER #lightgray + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + end note + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + POS_HANDLER -> POS_HANDLER: Notifications for failures\nReference: Failure in Position Validation (Prepare) + end +end + + +group Reference: Failure in Position Validation (Prepare) + alt If action == 'bulk-prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-prepare", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Position failure event (in Prepare) to Bulk Processing Topic (for Payer) \nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If action == 'prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "position", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + +end + +group Reference: Position Validation Success case (Prepare) + alt If action == 'bulk-prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Position Success event (in Prepare) to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If action == 'prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "abort", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg new file mode 100644 index 000000000..bbf658e1c --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg @@ -0,0 +1,522 @@ + + 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + + + 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position + Management + Facade + + + Position + Management + Facade + + + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + Prepare Position Handler Consume + + + 1 + Request transfers to be processed + + + + + 2 + Check 1st transfer to select the Participant and Currency + + + DB TRANSACTION + + + + + 3 + Loop through batch and build list of transferIds and calculate sumTransfersInBatch, + checking all in Batch are for the correct Paricipant and Currency + Error code: + 2001, 3100 + + + 4 + Retrieve current state of all transfers in array from DB with select whereIn + (FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + + transferStateChange + transferParticipant + + + 5 + Return current state of all selected transfers from DB + + + + + + 6 + Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + Error code: + 2001 + against failing transfers + Batch is not rejected as a whole. + + + List of transfers used during processing + reservedTransfers + is list of transfers to be processed in the batch + abortedTransfers + is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + processedTransfers + is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation +   + Scalar intermidate values used in the algorithm + transferAmount + = payload.amount.amount + sumTransfersInBatch + = SUM amount against each Transfer in batch + currentPosition + = participantPosition.value + reservedPosition + = participantPosition.{original}reservedValue + effectivePosition + = currentPosition + reservedPosition + heldPosition + = effectivePosition + sumTransfersInBatch + availablePosition + = participantLimit(NetDebitCap) - effectivePosition + sumReserved + = SUM of transfers that have met rule criteria and processed + + + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + + + 7 + Select effectivePosition FOR UPDATE from DB for Payer + + participantPosition + + + 8 + Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + + + + + 9 + Increment reservedValue to heldPosition + (reservedValue = reservedPosition + sumTransfersInBatch) + + + 10 + Persist reservedValue + + UPDATE + participantPosition + SET reservedValue += sumTransfersInBatch + + + 11 + Request position limits for Payer Participant + + FROM + participantLimit + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + + + 12 + Return position limits + + + + + + 13 + availablePosition + = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) + + + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + + + + + + 14 + Validate availablePosition for each tranfser (see algorithm below) + Error code: + 4001 + + + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far + (NEED TO UPDATE IN CODE) + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + (NEED TO UPDATE IN CODE) + // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + + + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + + + + + 15 + Assess any limit thresholds on the final position + adding to alarm list if triggered + + + 16 + Persist latest position + value + and + reservedValue + to DB for Payer + + UPDATE + participantPosition + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + + + 17 + Bulk persist transferStateChange for all processedTransfers + + batch INSERT + transferStateChange + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch +   + + + + + 18 + Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + + + 19 + Bulk persist the participant position change for all processedTransfers + + batch INSERT + participantPositionChange +              + + + 20 + Return a map of transferIds and their transferStateChanges + + + alt + [Calculate & Validate Latest Position Prepare (success)] + + + + + 21 + Notifications for Position Validation Success + Reference: Position Validation Success case (Prepare) + + [Calculate & Validate Latest Position Prepare (failure)] + + + Validation failure! + + + Persist Transfer State (with transferState='ABORTED' on position check fail) + + + 22 + Request to persist transfer + Error code: + 2003 + + + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 23 + Persist transfer state + + transferStateChange + + + 24 + Return success + + + + + 25 + Notifications for failures + Reference: Failure in Position Validation (Prepare) + + + Reference: Failure in Position Validation (Prepare) + + + alt + [If action == 'bulk-prepare'] + + + Message: + { + id: "<messageId>" + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 26 + Publish Position failure event (in Prepare) to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + [If action == 'prepare'] + + + Message: + { + id: "<messageId>" + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "position", + createdAt: <timestamp>, + state: { + status: "error", + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Notification (failure) event for Payer + Error code: + 2003 + + + Reference: Position Validation Success case (Prepare) + + + alt + [If action == 'bulk-prepare'] + + + Message: + { + id: "<messageId>" + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-prepare", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 28 + Publish Position Success event (in Prepare) to Bulk Processing Topic + Error codes: + 2003 + + [If action == 'prepare'] + + + Message: + { + id: "<messageId>" + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "abort", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Publish Notification event + Error code: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml new file mode 100644 index 000000000..19b2a9574 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml @@ -0,0 +1,347 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 1.4.0. Bulk Processing Handler Consume + +autonumber + +/'***** + Diagram notes + -------------- + RECEIVED/RECEIVED + from: prepare-handler , action: prepare-duplicate/success, result: PENDING_PREPARE/ACCEPTED & RECEIVED_DUPLICATE + from: prepare-handler , action: prepare-duplicate/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_DUPLICATE + from: prepare-handler , action: prepare/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_INVALID + from: position-handler, action: prepare/error , result: PENDING_PREPARE/ACCEPTED & RECEIVED_INVALID + from: position-handler, action: prepare/success , result: PENDING_PREPARE/ACCEPTED & ACCEPTED + from: timeout-handler , action: timeout-received/error , result: unchanged/COMPLETED & EXPIRED + -------------- + ACCEPTED/ACCEPTED + from: position-handler, action: timeout-reserved/error , result: unchanged/COMPLETED & EXPIRED + -------------- + PROCESSING/ACCEPTED + from: fulfil-handler , action: fulfil-duplicate/success , result: PENDING_FULFIL/COMPLETED & FULFIL_DUPLICATE + from: fulfil-handler , action: fulfil-duplicate/error , result: PENDING_FULFIL/COMPLETED & FULFIL_DUPLICATE + from: position-handler, action: commit/success , result: PENDING_FULFIL/COMPLETED & COMPLETED + from: position-handler, action: reject/success , result: PENDING_FULFIL/COMPLETED & REJECTED + from: position-handler, action: abort/error , result: PENDING_FULFIL/COMPLETED & FULFIL_INVALID + from: fulfil-handler , action: commit/error , result: PENDING_FULFIL/COMPLETED & FULFIL_INVALID + from: position-handler, action: timeout-reserved/error , result: unchanged/COMPLETED & EXPIRED + -------------- + COMPLETED/EXPIRED + -------------- + ******'/ + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-event" as TOPIC_EVENTS +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +collections "topic-notification" as TOPIC_NOTIFICATION +entity "Bulk DAO" as BULK_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_EVENTS + participant OBJECT_STORE + participant TOPIC_NOTIFICATION + participant BULK_DAO + participant DB +end box + +' start flow +activate BULK_PROC_HANDLER +group Bulk Processing Handler Consume + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + + break + group Validate Event + BULK_PROC_HANDLER <-> BULK_PROC_HANDLER: Validate event - Rule:\ntype == 'bulk-processing' && action IN\n['prepare-duplicate', 'bulk-prepare',\n'bulk-timeout-received', 'fulfil-duplicate',\n'bulk-commit', 'bulk-timeout-reserved']\nError codes: 2001 + end + end + + group Persist Event Information + ||| + BULK_PROC_HANDLER -> TOPIC_EVENTS: Publish event information + ref over BULK_PROC_HANDLER, TOPIC_EVENTS: Event Handler Consume\n + ||| + end + + group Process Message + BULK_PROC_HANDLER -> BULK_DAO: Retrieve current state of Bulk Transfer + activate BULK_DAO + BULK_DAO -> DB: Retrieve current state of Bulk Transfer + activate DB + hnote over DB #lightyellow + bulkTransfer + bulkTransferStateChange + end note + BULK_DAO <-- DB: Return **bulkTransferInfo** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **bulkTransferInfo** + deactivate BULK_DAO + + group Validate Bulk Transfer State + note right of BULK_PROC_HANDLER #lightgrey + **Initialize variables**: + let criteriaState + let incompleteBulkState + let completedBulkState + let bulkTransferState + let processingState + let errorCode, errorMessage + let produceNotification = false + end note + alt bulkTransferInfo.bulkTransferState IN ['RECEIVED', 'PENDING_PREPARE'] + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'RECEIVED' + incompleteBulkState = 'PENDING_PREPARE' + completedBulkState = 'ACCEPTED' + end note + alt action == 'prepare-duplicate' AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'RECEIVED_DUPLICATE' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else action == 'bulk-prepare' AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'RECEIVED_INVALID' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else action == 'bulk-prepare' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'ACCEPTED' + end note + else action IN ['bulk-timeout-received', 'bulk-timeout-reserved'] + note right of BULK_PROC_HANDLER #lightgrey + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['ACCEPTED'] + alt action == 'bulk-timeout-reserved' + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'ACCEPTED' + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['PROCESSING', 'PENDING_FULFIL', 'EXPIRING'] + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'PROCESSING' + incompleteBulkState = 'PENDING_FULFIL' + completedBulkState = 'COMPLETED' + end note + alt action == 'fulfil-duplicate' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'FULFIL_DUPLICATE' + end note + else action == 'bulk-commit' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'COMPLETED' + end note + else action == 'reject' AND state.status == 'success' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'REJECTED' + end note + else action IN ['commit', 'abort'] AND state.status == 'error' + note right of BULK_PROC_HANDLER #lightgrey + processingState = 'FULFIL_INVALID' + end note + else action == 'bulk-timeout-reserved' + note right of BULK_PROC_HANDLER #lightgrey + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else bulkTransferInfo.bulkTransferState IN ['ABORTING'] + alt action == 'bulk-abort' + note right of BULK_PROC_HANDLER #lightgrey + criteriaState = 'ABORTING' + processingState = 'FULFIL_INVALID' + completedBulkState = 'REJECTED' + incompleteBulkState = 'ABORTING' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + end note + else all other actions + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + else all other ['PENDING_INVALID', 'COMPLETED', 'REJECTED', 'INVALID'] + note right of BULK_PROC_HANDLER #lightgrey + throw ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + end note + end + end + + BULK_PROC_HANDLER -> BULK_DAO: Persist individual transfer processing state + activate BULK_DAO + BULK_DAO -> DB: Persist individual transfer processing state\n-- store errorCode/errorMessage when\nstate.status == 'error' + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end note + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return success + deactivate BULK_DAO + + BULK_PROC_HANDLER -> BULK_DAO: Check previously defined completion criteria + activate BULK_DAO + BULK_DAO -> DB: Select EXISTS (LIMIT 1) in criteriaState + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end note + BULK_DAO <-- DB: Return **existingIndividualTransfer** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **existingIndividualTransfer** + deactivate BULK_DAO + + alt individual transfer exists + note right of BULK_PROC_HANDLER #lightgrey + bulkTransferState = incompleteBulkState + end note + else no transfer in criteriaState exists + note right of BULK_PROC_HANDLER #lightgrey + bulkTransferState = completedBulkState + produceNotification = true + end note + end + + BULK_PROC_HANDLER -> BULK_DAO: Persist bulkTransferState from previous step + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransferState + activate DB + deactivate DB + hnote over DB #lightyellow + bulkTransferStateChange + end note + BULK_PROC_HANDLER <-- BULK_DAO: Return success + deactivate BULK_DAO + + + alt produceNotification == true + BULK_PROC_HANDLER -> BULK_DAO: Request to retrieve all bulk transfer and individual transfer results + activate BULK_DAO + BULK_DAO -> DB: Get bulkTransferResult + activate DB + hnote over DB #lightyellow + bulkTransfer + bulkTransferStateChange + bulkTransferAssociation + end note + BULK_DAO <-- DB: Return **bulkTransferResult** + deactivate DB + BULK_PROC_HANDLER <-- BULK_DAO: Return **bulkTransferResult** + deactivate BULK_DAO + + group Send Bulk Notification(s) + note right of BULK_PROC_HANDLER #lightgrey + Depending on the action decide where to + send notification: payer, payee OR both + end note + + BULK_PROC_HANDLER -> OBJECT_STORE: Generate & Persist bulk message to object store:\n**MLOS.bulkTransferResults** by destination + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return reference to the stored object(s)\n**MLOS.bulkTransferResults.messageId** + deactivate OBJECT_STORE + note right of BULK_PROC_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + bulkTransferId: , + bulkTransferState: + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "bulk-[prepare | commit | abort | processing]", + createdAt: , + state: { + status: state.status, + code: state.code + } + } + } + } + end note + + BULK_PROC_HANDLER -> TOPIC_NOTIFICATION: Publish Notification event for Payer/Payee\nError codes: 2003 + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + end + else produceNotification == false + note right of BULK_PROC_HANDLER #lightgrey + Do nothing (awaitAllTransfers) + end note + end + end +end +deactivate BULK_PROC_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg new file mode 100644 index 000000000..9d756ff45 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg @@ -0,0 +1,468 @@ + + 1.4.0. Bulk Processing Handler Consume + + + 1.4.0. Bulk Processing Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-bulk- + processing + + + topic-bulk- + processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic-event + + + topic-event + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + + + topic-notification + + + topic-notification + Bulk DAO + + + Bulk DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + Bulk Processing Handler Consume + + + 1 + Consume message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: + type == 'bulk-processing' && action IN + ['prepare-duplicate', 'bulk-prepare', + 'bulk-timeout-received', 'fulfil-duplicate', + 'bulk-commit', 'bulk-timeout-reserved'] + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Process Message + + + 4 + Retrieve current state of Bulk Transfer + + + 5 + Retrieve current state of Bulk Transfer + + bulkTransfer + bulkTransferStateChange + + + 6 + Return + bulkTransferInfo + + + 7 + Return + bulkTransferInfo + + + Validate Bulk Transfer State + + + Initialize variables + : + let criteriaState + let incompleteBulkState + let completedBulkState + let bulkTransferState + let processingState + let errorCode, errorMessage + let produceNotification = false + + + alt + [bulkTransferInfo.bulkTransferState IN ['RECEIVED', 'PENDING_PREPARE']] + + + criteriaState = 'RECEIVED' + incompleteBulkState = 'PENDING_PREPARE' + completedBulkState = 'ACCEPTED' + + + alt + [action == 'prepare-duplicate' AND state.status == 'error'] + + + processingState = 'RECEIVED_DUPLICATE' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [action == 'bulk-prepare' AND state.status == 'error'] + + + processingState = 'RECEIVED_INVALID' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [action == 'bulk-prepare' AND state.status == 'success'] + + + processingState = 'ACCEPTED' + + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['ACCEPTED']] + + + alt + [action == 'bulk-timeout-reserved'] + + + criteriaState = 'ACCEPTED' + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['PROCESSING', 'PENDING_FULFIL', 'EXPIRING']] + + + criteriaState = 'PROCESSING' + incompleteBulkState = 'PENDING_FULFIL' + completedBulkState = 'COMPLETED' + + + alt + [action == 'fulfil-duplicate'] + + + processingState = 'FULFIL_DUPLICATE' + + [action == 'bulk-commit' AND state.status == 'success'] + + + processingState = 'COMPLETED' + + [action == 'reject' AND state.status == 'success'] + + + processingState = 'REJECTED' + + [action IN ['commit', 'abort'] AND state.status == 'error'] + + + processingState = 'FULFIL_INVALID' + + [action == 'bulk-timeout-reserved'] + + + incompleteBulkState = 'EXPIRING' + completedBulkState = 'COMPLETED' + processingState = 'EXPIRED' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [bulkTransferInfo.bulkTransferState IN ['ABORTING']] + + + alt + [action == 'bulk-abort'] + + + criteriaState = 'ABORTING' + processingState = 'FULFIL_INVALID' + completedBulkState = 'REJECTED' + incompleteBulkState = 'ABORTING' + errorCode = payload.errorInformation.errorCode + errorDescription = payload.errorInformation.errorDescription + + [all other actions] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + [all other ['PENDING_INVALID', 'COMPLETED', 'REJECTED', 'INVALID']] + + + throw + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + 8 + Persist individual transfer processing state + + + 9 + Persist individual transfer processing state + -- store errorCode/errorMessage when + state.status == 'error' + + bulkTransferAssociation + + + 10 + Return success + + + 11 + Check previously defined completion criteria + + + 12 + Select EXISTS (LIMIT 1) in criteriaState + + bulkTransferAssociation + + + 13 + Return + existingIndividualTransfer + + + 14 + Return + existingIndividualTransfer + + + alt + [individual transfer exists] + + + bulkTransferState = incompleteBulkState + + [no transfer in criteriaState exists] + + + bulkTransferState = completedBulkState + produceNotification = true + + + 15 + Persist bulkTransferState from previous step + + + 16 + Persist bulkTransferState + + bulkTransferStateChange + + + 17 + Return success + + + alt + [produceNotification == true] + + + 18 + Request to retrieve all bulk transfer and individual transfer results + + + 19 + Get bulkTransferResult + + bulkTransfer + bulkTransferStateChange + bulkTransferAssociation + + + 20 + Return + bulkTransferResult + + + 21 + Return + bulkTransferResult + + + Send Bulk Notification(s) + + + Depending on the action decide where to + send notification: payer, payee OR both + + + 22 + Generate & Persist bulk message to object store: + MLOS.bulkTransferResults + by destination + + + 23 + Return reference to the stored object(s) + MLOS.bulkTransferResults.messageId + + + Message: + { + id: <messageId> + from: <source>, + to: <destination>, + type: "application/json" + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkTransferState: <string> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "bulk-[prepare | commit | abort | processing]", + createdAt: <timestamp>, + state: { + status: state.status, + code: state.code + } + } + } + } + + + 24 + Publish Notification event for Payer/Payee + Error codes: + 2003 + + [produceNotification == false] + + + Do nothing (awaitAllTransfers) + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml new file mode 100644 index 000000000..476d76354 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml @@ -0,0 +1,225 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API \nNotification Handler" as NOTIFY_HANDLER +collections "mongo-\nobject-store" as OBJECT_STORE +boundary "Central Service API" as CSAPI +collections "topic-\nbulk-fulfil" as TOPIC_BULK_FULFIL +control "Bulk Fulfil\nHandler" as BULK_FULFIL_HANDLER +collections "topic-\nfulfil" as TOPIC_FULFIL +control "Fulfil \nHandler" as FULF_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position \nHandler" as POS_HANDLER +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant CSAPI + participant TOPIC_BULK_FULFIL + participant BULK_FULFIL_HANDLER + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_FULFIL_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +activate BULK_PROC_HANDLER +group DFSP2 sends a Bulk Fulfil Success Transfer request to DFSP1 + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - bulkTransferMessage: + { + bulkTransferState: , + completedTimestamp: , + individualTransferResults: + [ + { + transferId: , + fulfilment: , + extensionList: { extension: [ + { key: , value: } + ] } + } + ], + extensionList: { extension: [ + { key: , value: } + ] } + } + end note + DFSP2 ->> MLAPI: PUT - /bulkTransfers/ + activate MLAPI + MLAPI -> OBJECT_STORE: Persist incoming bulk message to\nobject store: **MLOS.individualTransferFulfils** + activate OBJECT_STORE + OBJECT_STORE --> MLAPI: Return messageId reference to the stored object(s) + deactivate OBJECT_STORE + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + bulkTransferId: , + bulkTransferState: "COMPLETED", + completedTimestamp: , + extensionList: { extension: [ + { key: , value: } + ] }, + count: , + hash: + } + }, + metadata: { + event: { + id: , + type: "bulk-fulfil", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_BULK_FULFIL: Route & Publish Bulk Fulfil event for Payee\nError code: 2003 + activate TOPIC_BULK_FULFIL + TOPIC_BULK_FULFIL <-> TOPIC_BULK_FULFIL: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 + TOPIC_BULK_FULFIL --> MLAPI: Respond replication acknowledgements \nhave been received + deactivate TOPIC_BULK_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_BULK_FULFIL <- BULK_FULFIL_HANDLER: Consume message + BULK_FULFIL_HANDLER -> OBJECT_STORE: Retrieve individual transfers by key:\n**MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULFIL_HANDLER: Stream bulk's individual transfers + deactivate OBJECT_STORE + ref over TOPIC_BULK_FULFIL, TOPIC_FULFIL: Bulk Prepare Handler Consume \n + alt Success + BULK_FULFIL_HANDLER -> TOPIC_FULFIL: Produce (stream) single transfer message\nfor each individual transfer [loop] + else Failure + BULK_FULFIL_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk + end + ||| + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success)\n + alt Success + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + else Failure + FULF_HANDLER --> TOPIC_BULK_PROCESSING: Produce message + end + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_BULK_PROCESSING: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + ||| + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + ref over TOPIC_BULK_PROCESSING, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume (Success)\n + BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** + deactivate OBJECT_STORE + BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Commit notification + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification payload + deactivate OBJECT_STORE + opt action == 'bulk-commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification payload + deactivate OBJECT_STORE + opt action == 'bulk-commit' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +activate BULK_FULFIL_HANDLER +deactivate FULF_HANDLER +deactivate BULK_PROC_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg new file mode 100644 index 000000000..223109602 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg @@ -0,0 +1,429 @@ + + 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + + + 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API + Notification Handler + + + ML API + Notification Handler + + + + + mongo- + object-store + + + mongo- + object-store + Central Service API + + + Central Service API + + + + + topic- + bulk-fulfil + + + topic- + bulk-fulfil + Bulk Fulfil + Handler + + + Bulk Fulfil + Handler + + + + + topic- + fulfil + + + topic- + fulfil + Fulfil + Handler + + + Fulfil + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position + Handler + + + Position + Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + notification + + + topic- + notification + + + + + + + + + + + + + + + DFSP2 sends a Bulk Fulfil Success Transfer request to DFSP1 + + + Headers - transferHeaders: { + Content-Length: <int>, + Content-Type: <string>, + Date: <date>, + FSPIOP-Source: <string>, + FSPIOP-Destination: <string>, + FSPIOP-Encryption: <string>, + FSPIOP-Signature: <string>, + FSPIOP-URI: <uri>, + FSPIOP-HTTP-Method: <string> + } +   + Payload - bulkTransferMessage: + { + bulkTransferState: <bulkTransferState>, + completedTimestamp: <completedTimeStamp>, + individualTransferResults: + [ + { + transferId: <uuid>, + fulfilment: <ilpCondition>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + ], + extensionList: { extension: [ + { key: <string>, value: <string> } + ] } + } + + + + 1 + PUT - /bulkTransfers/<ID> + + + 2 + Persist incoming bulk message to + object store: + MLOS.individualTransferFulfils + + + 3 + Return messageId reference to the stored object(s) + + + Message: + { + id: <messageId>, + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferId: <uuid>, + bulkTransferState: "COMPLETED", + completedTimestamp: <timestamp>, + extensionList: { extension: [ + { key: <string>, value: <string> } + ] }, + count: <int>, + hash: <string> + } + }, + metadata: { + event: { + id: <uuid>, + type: "bulk-fulfil", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Bulk Fulfil event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated + as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements + have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + 9 + Retrieve individual transfers by key: + MLOS.individualTransferFulfils.messageId + + + 10 + Stream bulk's individual transfers + + + ref + Bulk Prepare Handler Consume +   + + + alt + [Success] + + + 11 + Produce (stream) single transfer message + for each individual transfer [loop] + + [Failure] + + + 12 + Produce single message for the entire bulk + + + 13 + Consume message + + + ref + Fulfil Handler Consume (Success) +   + + + alt + [Success] + + + 14 + Produce message + + [Failure] + + + 15 + Produce message + + + 16 + Consume message + + + ref + Position Handler Consume (Success) +   + + + 17 + Produce message + + + 18 + Consume message + + + ref + Bulk Processing Handler Consume (Success) +   + + + 19 + Persist bulk message by destination to the + object store: + MLOS.bulkTransferResults + + + 20 + Return the reference to the stored + notification object(s): + messageId + + + 21 + Send Bulk Commit notification + + + 22 + Consume message + + + 23 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 24 + Return notification payload + + + opt + [action == 'bulk-commit'] + + + ref + Send notification to Participant (Payer) +   + + + 25 + Send callback notification + + + 26 + Consume message + + + 27 + Retrieve bulk notification(s) by reference & destination: + MLOS.bulkTransferResults.messageId + destination + + + 28 + Return notification payload + + + opt + [action == 'bulk-commit'] + + + ref + Send notification to Participant (Payee) +   + + + 29 + Send callback notification + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml new file mode 100644 index 000000000..2da07f279 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml @@ -0,0 +1,324 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 2.1.1. Bulk Fulfil Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "mongo-\nobject-store" as OBJECT_STORE +collections "topic-bulk-\nfulfil" as TOPIC_BULK_FULFIL +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +control "Bulk Fulfil\nHandler" as BULK_FULF_HANDLER +collections "topic-transfer-\nfulfil" as TOPIC_TRANSFER_FULFIL +collections "topic-event" as TOPIC_EVENTS +collections "topic-notification" as TOPIC_NOTIFICATION +entity "Bulk DAO" as BULK_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant TOPIC_BULK_FULFIL + participant BULK_FULF_HANDLER + participant TOPIC_TRANSFER_FULFIL + participant TOPIC_BULK_PROCESSING + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATION + participant BULK_DAO + participant DB +end box + +' start flow +activate BULK_FULF_HANDLER +group Bulk Fulfil Handler Consume + TOPIC_BULK_FULFIL <- BULK_FULF_HANDLER: Consume message + activate TOPIC_BULK_FULFIL + deactivate TOPIC_BULK_FULFIL + + break + group Validate Event + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Validate event - Rule:\ntype == 'bulk-fulfil' && action == 'bulk-commit'\nError codes: 2001 + end + end + + group Persist Event Information + ||| + BULK_FULF_HANDLER -> TOPIC_EVENTS: Publish event information + ref over BULK_FULF_HANDLER, TOPIC_EVENTS: Event Handler Consume \n + ||| + end + + group Validate FSPIOP-Signature + ||| + ref over BULK_FULF_HANDLER, TOPIC_NOTIFICATION: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 3105/3106\n + ||| + end + + group Validate Bulk Fulfil Transfer + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Schema validation of the incoming message + BULK_FULF_HANDLER <-> BULK_FULF_HANDLER: Verify the message's signature\n(to be confirmed in future requirement) + note right of BULK_FULF_HANDLER #lightgrey + The above validation steps are already handled by the + Bulk-API-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + end note + + group Validate Duplicate Check + ||| + BULK_FULF_HANDLER -> DB: Request Duplicate Check + ref over BULK_FULF_HANDLER, DB: Request Duplicate Check\n + DB --> BULK_FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + BULK_FULF_HANDLER -> BULK_DAO: Request to retrieve Bulk Transfer state & completedTimestamp\nError code: 2003 + activate BULK_DAO + BULK_DAO -> DB: Query database + hnote over DB #lightyellow + bulkTransfer + bulkTransferFulfilment + bulkTransferStateChange + end note + activate DB + BULK_DAO <-- DB: Return resultset + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return **bulkTransferStateId** & **completedTimestamp** (not null when completed) + deactivate BULK_DAO + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + bulkTransferState: , + completedTimestamp: + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "bulk-fulfil-duplicate", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_NOTIFICATION: Publish Notification event for Payee + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of BULK_FULF_HANDLER #yellow + { + id: , + from: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: + } + ] + } + }, + uriParams: { + id: + } + } + }, + metadata: { + correlationId: , + event: { + id: , + type: "notification", + action: "bulk-commit", + createdAt: , + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_NOTIFICATION: Publish Notification (failure) event for Payer\nError codes: 3106 + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + else hasDuplicateId == FALSE + alt Validate Bulk Transfer Fulfil (success) + group Persist Bulk Transfer State (with bulktransferState='PROCESSING') + BULK_FULF_HANDLER -> BULK_DAO: Request to persist bulk transfer fulfil\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransferFulfilment + hnote over DB #lightyellow + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + end note + activate DB + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return success + deactivate BULK_DAO + end + else Validate Bulk Transfer Fulfil (failure) + group Persist Bulk Transfer State (with bulkTransferState='ABORTING') + BULK_FULF_HANDLER -> BULK_DAO: Request to persist bulk\ntransfer fulfil failure\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist transfer + hnote over DB #lightyellow + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + bulkTransferError + end note + activate DB + deactivate DB + BULK_DAO --> BULK_FULF_HANDLER: Return success + deactivate BULK_DAO + end + end + end + end + alt Validate Bulk Transfer Fulfil (success) + loop for every individual transfer in the bulk fulfil list + BULK_FULF_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Return stored bulk transfer containing individual transfers + deactivate OBJECT_STORE + + BULK_FULF_HANDLER --> OBJECT_STORE: Update bulk transfer association record to bulk transfer processing state 'PROCESSING' + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Bulk transfer association record commited + deactivate OBJECT_STORE + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "fulfil", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_TRANSFER_FULFIL: Route & Publish fulfil bulk commit events to the Payer for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_FULFIL + deactivate TOPIC_TRANSFER_FULFIL + end + else Validate Bulk Transfer Fulfil (failure) + loop for every individual transfer in the bulk fulfil list + BULK_FULF_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransferFulfils.messageId** + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Stream bulk's individual transfer fulfils + deactivate OBJECT_STORE + + BULK_FULF_HANDLER --> OBJECT_STORE: Update bulk transfer association record to bulk transfer processing state 'ABORTING' + activate OBJECT_STORE + OBJECT_STORE --> BULK_FULF_HANDLER: Bulk transfer association record commited + deactivate OBJECT_STORE + + note right of BULK_FULF_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: "errorInformation": { + "errorCode": + "errorDescription": "", + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "fulfil", + action: "bulk-abort", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_FULF_HANDLER -> TOPIC_TRANSFER_FULFIL: Route & Publish fulfil bulk abort events to the Payer for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_FULFIL + deactivate TOPIC_TRANSFER_FULFIL + end +end +deactivate BULK_FULF_HANDLER +@enduml + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg new file mode 100644 index 000000000..7ab28f05f --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg @@ -0,0 +1,496 @@ + + 2.1.1. Bulk Fulfil Handler Consume + + + 2.1.1. Bulk Fulfil Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mongo- + object-store + + + mongo- + object-store + + + topic-bulk- + fulfil + + + topic-bulk- + fulfil + Bulk Fulfil + Handler + + + Bulk Fulfil + Handler + + + + + topic-transfer- + fulfil + + + topic-transfer- + fulfil + + + topic-bulk- + processing + + + topic-bulk- + processing + + + topic-event + + + topic-event + + + topic-notification + + + topic-notification + Bulk DAO + + + Bulk DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + 1 + Consume message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: + type == 'bulk-fulfil' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 3105/3106 +   + + + Validate Bulk Fulfil Transfer + + + + + + 4 + Schema validation of the incoming message + + + + + + 5 + Verify the message's signature + (to be confirmed in future requirement) + + + The above validation steps are already handled by the + Bulk-API-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + + + Validate Duplicate Check + + + 6 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 7 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + 8 + Request to retrieve Bulk Transfer state & completedTimestamp + Error code: + 2003 + + + 9 + Query database + + bulkTransfer + bulkTransferFulfilment + bulkTransferStateChange + + + 10 + Return resultset + + + 11 + Return + bulkTransferStateId + & + completedTimestamp + (not null when completed) + + + Message: + { + id: <messageId> + from: <ledgerName>, + to: <payeeFspName>, + type: application/json + content: { + headers: <bulkTransferHeaders>, + payload: { + bulkTransferState: <string>, + completedTimestamp: <optional> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "notification", + action: "bulk-fulfil-duplicate", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 12 + Publish Notification event for Payee + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + { + id: <messageId>, + from: <ledgerName", + to: <payeeFspName>, + type: "application/json", + content: { + headers: <bulkTransferHeaders>, + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: <FSPIOPError> + } + ] + } + }, + uriParams: { + id: <bulkTransferId> + } + } + }, + metadata: { + correlationId: <uuid>, + event: { + id: <uuid>, + type: "notification", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: <uuid> + } + } + } + + + 13 + Publish Notification (failure) event for Payer + Error codes: + 3106 + + [hasDuplicateId == FALSE] + + + alt + [Validate Bulk Transfer Fulfil (success)] + + + Persist Bulk Transfer State (with bulktransferState='PROCESSING') + + + 14 + Request to persist bulk transfer fulfil + Error codes: + 2003 + + + 15 + Persist bulkTransferFulfilment + + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + + + 16 + Return success + + [Validate Bulk Transfer Fulfil (failure)] + + + Persist Bulk Transfer State (with bulkTransferState='ABORTING') + + + 17 + Request to persist bulk + transfer fulfil failure + Error codes: + 2003 + + + 18 + Persist transfer + + bulkTransferFulfilment + bulkTransferStateChange + bulkTransferExtension + bulkTransferError + + + 19 + Return success + + + alt + [Validate Bulk Transfer Fulfil (success)] + + + loop + [for every individual transfer in the bulk fulfil list] + + + 20 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransferFulfils.messageId + + + 21 + Return stored bulk transfer containing individual transfers + + + 22 + Update bulk transfer association record to bulk transfer processing state 'PROCESSING' + + + 23 + Bulk transfer association record commited + + + Message: + { + id: <messageId> + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "fulfil", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish fulfil bulk commit events to the Payer for the Individual Transfer + Error codes: + 2003 + + [Validate Bulk Transfer Fulfil (failure)] + + + loop + [for every individual transfer in the bulk fulfil list] + + + 25 + Retrieve individual transfers from the bulk using + reference: + MLOS.individualTransferFulfils.messageId + + + 26 + Stream bulk's individual transfer fulfils + + + 27 + Update bulk transfer association record to bulk transfer processing state 'ABORTING' + + + 28 + Bulk transfer association record commited + + + Message: + { + id: <messageId> + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json" + content: { + headers: <transferHeaders>, + payload: "errorInformation": { + "errorCode": <possible codes: [3100]> + "errorDescription": "<description>", + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "fulfil", + action: "bulk-abort", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Route & Publish fulfil bulk abort events to the Payer for the Individual Transfer + Error codes: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml new file mode 100644 index 000000000..b53afd2e5 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml @@ -0,0 +1,236 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Handler" as FULF_HANDLER +collections "topic-\nevent" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position DAO" as POS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_BULK_PROCESSING + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Success) + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && action == 'bulk-commit'\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 3105/3106\n + ||| + end + + group Validate Duplicate Check + ||| + FULF_HANDLER -> DB: Request Duplicate Check + ref over FULF_HANDLER, DB: Request Duplicate Check\n + DB --> FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of FULF_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + + end + + group Validate and persist Transfer Fulfilment + FULF_HANDLER -> POS_DAO: Request information for the validate checks\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return transfer + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + FULF_HANDLER -> FULF_HANDLER: Validate expirationDate\nError code: 3303 + + opt Transfer.ilpCondition validate successful + group Request current Settlement Window + FULF_HANDLER -> POS_DAO: Request to retrieve current/latest transfer settlement window\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return settlementWindowId to be appended during transferFulfilment insert\n**TODO**: During settlement design make sure transfers in 'RECEIVED-FULFIL'\nstate are updated to the next settlement window + deactivate POS_DAO + end + end + + group Persist fulfilment + FULF_HANDLER -> POS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Return success + deactivate POS_DAO + end + + alt Transfer.ilpCondition validate successful + group Persist Transfer State (with transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "position", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful + break + FULF_HANDLER -> FULF_HANDLER: Route & Publish Notification event for Payee\nReference: Failure in validation + end + end + end +end + +group Reference: Failure in validation + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-commit", + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING +end + +deactivate FULF_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg new file mode 100644 index 000000000..6dccfb80f --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg @@ -0,0 +1,401 @@ + + 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + + + 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Handler + + + Fulfil Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + bulk-processing + + + topic- + bulk-processing + + + topic- + notification + + + topic- + notification + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Success) + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && action == 'bulk-commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 3105/3106 +   + + + Validate Duplicate Check + + + 4 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 5 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + getTransfer callback +   + + + 7 + Produce message + + + + Ignore - resend in progress + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == FALSE] + + + Validate and persist Transfer Fulfilment + + + 8 + Request information for the validate checks + Error code: + 2003 + + + 9 + Fetch from database + + transfer + + + 10 +   + + + 11 + Return transfer + + + + + 12 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + + + 13 + Validate expirationDate + Error code: + 3303 + + + opt + [Transfer.ilpCondition validate successful] + + + Request current Settlement Window + + + 14 + Request to retrieve current/latest transfer settlement window + Error code: + 2003 + + + 15 + Fetch settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Return settlementWindowId to be appended during transferFulfilment insert + TODO + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + state are updated to the next settlement window + + + Persist fulfilment + + + 18 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 19 + Persist to database + + transferFulfilment + transferExtension + + + 20 + Return success + + + alt + [Transfer.ilpCondition validate successful] + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + 21 + Request to persist transfer state + Error code: + 2003 + + + 22 + Persist transfer state + + transferStateChange + + + 23 + Return success + + + Message: + { + id: <messageId>, + from: <payeeFspName>, + to: <payerFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "position", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish Position event for Payee + + [Validate Fulfil Transfer not successful] + + + break + + + + + 25 + Route & Publish Notification event for Payee + Reference: Failure in validation + + + Reference: Failure in validation + + + Message: + { + id: <messageId>, + from: <ledgerName>, + to: <payeeFspName>, + type: "application/json", + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: "bulk-processing", + action: "bulk-commit", + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 26 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml new file mode 100644 index 000000000..a90928354 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml @@ -0,0 +1,616 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-\nfulfil" as TOPIC_FULFIL +control "Fulfil Handler" as FULF_HANDLER +collections "topic-\nevent" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_BULK_PROCESSING + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Failure) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type IN ['fulfil','bulk-fulfil'] && ( action IN ['reject','abort'] )\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 2001 + end + group Validate Transfer Fulfil Duplicate Check + FULF_HANDLER -> FULF_HANDLER: Generate transferFulfilmentId uuid + FULF_HANDLER -> TRANS_DAO: Request to retrieve transfer fulfilment hashes by transferId\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request Transfer fulfilment \nduplicate message hashes + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Return existing hashes + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return (list of) transfer fulfil messages hash(es) + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Loop the list of returned hashes & compare \neach entry with the calculated message hash + alt Hash matched + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Request to retrieve Transfer Fulfilment & Transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request to retrieve \ntransferFulfilment & transferState + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Return transferFulfilment & \ntransferState + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return Transfer Fulfilment & Transfer state + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + alt If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: fulfil-duplicate, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event for Payee - Modified Request\nError codes: 3106 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee - Modified Request \n3106 to Bulk Processing Topic\nError codes: 3106 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + alt If type == 'fulfil' + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Reference: Failure in validation\nError code: 2001 + end + else + break + alt If type == 'fulfil' + FULF_HANDLER <-> FULF_HANDLER: Allow previous request to complete + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + end + else Hash not matched + FULF_HANDLER -> TRANS_DAO: Request to persist transfer hash\nError codes: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist hash + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + deactivate TRANS_DAO + end + end + alt action=='reject' call made on PUT /transfers/{ID} + FULF_HANDLER -> TRANS_DAO: Request information for the validate checks\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> TRANS_DAO + deactivate DB + FULF_HANDLER <-- TRANS_DAO: Return transfer + deactivate TRANS_DAO + + alt Fulfilment present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + + group Persist fulfilment + FULF_HANDLER -> TRANS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + else Fulfilment NOT present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that transfer fulfilment message to Abort is valid\nError code: 2001 + group Persist extensions + FULF_HANDLER -> TRANS_DAO: Persist extensionList elements\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + end + + alt Transfer.ilpCondition validate successful OR generic validation successful + group Persist Transfer State (with transferState='RECEIVED_REJECT') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + FULF_HANDLER -> FULF_HANDLER: Route & Publish Position event for Payer\nReference: Publish Position Reject event for Payer + + else Validate Fulfil Transfer not successful or Generic validation failed + break + FULF_HANDLER -> FULF_HANDLER: Publish event for Payee\nReference: Failure in validation + end + end + else action=='abort' Error callback + alt Validation successful + group Persist Transfer State (with transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state & Error\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state & Error + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + FULF_HANDLER -> FULF_HANDLER: Error callback validated\nReference: Produce message for validated error callback + + else Validate Transfer Error Message not successful + break + FULF_HANDLER -> FULF_HANDLER: Notifications for failures\nReference: Validate Transfer Error Message not successful + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end + +group Reference: Validate Transfer Error Message not successful + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +group Reference: Produce message for validated error callback + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end + +group Reference: Failure in validation + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish processing event to the Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +group Reference: Publish Position Reject event for Payer + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end + +deactivate FULF_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg new file mode 100644 index 000000000..6cb06df4e --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg @@ -0,0 +1,949 @@ + + 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + + + 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + fulfil + + + topic- + fulfil + Fulfil Handler + + + Fulfil Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + event + + + topic- + event + + + topic- + bulk-processing + + + topic- + bulk-processing + + + topic- + notification + + + topic- + notification + Transfer DAO + + + Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Failure) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type IN ['fulfil','bulk-fulfil'] && ( action IN ['reject','abort'] ) + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 2001 + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + Generate transferFulfilmentId uuid + + + 5 + Request to retrieve transfer fulfilment hashes by transferId + Error code: + 2003 + + + 6 + Request Transfer fulfilment + duplicate message hashes + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Return existing hashes + + + 8 + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + Loop the list of returned hashes & compare + each entry with the calculated message hash + + + alt + [Hash matched] + + + 10 + Request to retrieve Transfer Fulfilment & Transfer state + Error code: + 2003 + + + 11 + Request to retrieve + transferFulfilment & transferState + + transferFulfilment + transferStateChange + + + 12 + Return transferFulfilment & + transferState + + + 13 + Return Transfer Fulfilment & Transfer state + + + alt + [transferFulfilment.isValid == 0] + + + break + + + alt + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 14 + Publish Notification event for Payee - Modified Request + Error codes: + 3106 + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 15 + Publish Notification event for Payee - Modified Request + 3106 to Bulk Processing Topic + Error codes: + 3106 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + alt + [If type == 'fulfil'] + + + ref + Send notification to Participant (Payee) +   + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 16 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [transferState NOT 'RESERVED'] + + + break + + + + + + 17 + Reference: Failure in validation + Error code: + 2001 + + + + break + + + alt + [If type == 'fulfil'] + + + + + + 18 + Allow previous request to complete + + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: fulfil-duplicate, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 19 + Publish Notification event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [Hash not matched] + + + 20 + Request to persist transfer hash + Error codes: + 2003 + + + 21 + Persist hash + + transferFulfilmentDuplicateCheck + + + 22 + Return success + + + alt + [action=='reject' call made on PUT /transfers/{ID}] + + + 23 + Request information for the validate checks + Error code: + 2003 + + + 24 + Fetch from database + + transfer + + + 25 +   + + + 26 + Return transfer + + + alt + [Fulfilment present in the PUT /transfers/{ID} message] + + + + + 27 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + Persist fulfilment + + + 28 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 29 + Persist to database + + transferFulfilment + transferExtension + + + 30 + Return success + + [Fulfilment NOT present in the PUT /transfers/{ID} message] + + + + + 31 + Validate that transfer fulfilment message to Abort is valid + Error code: + 2001 + + + Persist extensions + + + 32 + Persist extensionList elements + Error code: + 2003 + + + 33 + Persist to database + + transferExtension + + + 34 + Return success + + + alt + [Transfer.ilpCondition validate successful OR generic validation successful] + + + Persist Transfer State (with transferState='RECEIVED_REJECT') + + + 35 + Request to persist transfer state + Error code: + 2003 + + + 36 + Persist transfer state + + transferStateChange + + + 37 + Return success + + + + + 38 + Route & Publish Position event for Payer + Reference: Publish Position Reject event for Payer + + [Validate Fulfil Transfer not successful or Generic validation failed] + + + break + + + + + 39 + Publish event for Payee + Reference: Failure in validation + + [action=='abort' Error callback] + + + alt + [Validation successful] + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + 40 + Request to persist transfer state & Error + Error code: + 2003 + + + 41 + Persist transfer state & Error + + transferStateChange + transferError + transferExtension + + + 42 + Return success + + + + + 43 + Error callback validated + Reference: Produce message for validated error callback + + [Validate Transfer Error Message not successful] + + + break + + + + + 44 + Notifications for failures + Reference: Validate Transfer Error Message not successful + + [Consume Batch Messages] + + + To be delivered by future story + + + Reference: Validate Transfer Error Message not successful + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 45 + Publish Processing event for Payee to Bulk Processing Topic + Error codes: + 2003 + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 46 + Route & Publish Notification event for Payee + + + Reference: Produce message for validated error callback + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 47 + Route & Publish Position event for Payer + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 48 + Route & Publish Position event for Payer + + + Reference: Failure in validation + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 49 + Publish processing event to the Bulk Processing Topic + Error codes: + 2003 + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 50 + Route & Publish Notification event for Payee + + + Reference: Publish Position Reject event for Payer + + + alt + [If type == 'bulk-fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 51 + Route & Publish Position event for Payer + + [If type == 'fulfil'] + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 52 + Route & Publish Position event for Payer + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml new file mode 100644 index 000000000..f992f9284 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml @@ -0,0 +1,176 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position Facade" as POS_FACADE +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Fulfil Position Handler Consume + POS_HANDLER -> POS_DAO: Request current state of transfer from DB \nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferState is 'RECEIVED-FULFIL')\nError code: 2001 + group Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + POS_HANDLER -> POS_FACADE: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION + activate POS_FACADE + POS_FACADE -> DB: Select participantPosition.value FOR UPDATE from DB for Payee + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Return participantPosition.value from DB for Payee + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persist latestPosition to DB for Payee + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persist transfer state and participant position change + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Return success + deactivate POS_FACADE + end + + alt If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: bulk-commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Transfer event to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'position' + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Transfer event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg new file mode 100644 index 000000000..750ea14e1 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg @@ -0,0 +1,238 @@ + + 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + + + 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notifications + + + topic- + notifications + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Position Facade + + + Position Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + + Fulfil Position Handler Consume + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state (transferState is 'RECEIVED-FULFIL') + Error code: + 2001 + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + 6 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION + + + 7 + Select participantPosition.value FOR UPDATE from DB for Payee + + participantPosition + + + 8 + Return participantPosition.value from DB for Payee + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persist latestPosition to DB for Payee + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persist transfer state and participant position change + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Return success + + + alt + [If type == 'bulk-position'] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: bulk-commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publish Transfer event to Bulk Processing Topic + Error codes: + 2003 + + [If type == 'position'] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 14 + Publish Transfer event + Error code: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml new file mode 100644 index 000000000..467666a01 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml @@ -0,0 +1,419 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + ------------- + ******'/ + +@startuml +' declate title +title 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +entity "Position DAO" as POS_DAO +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Abort Position Handler Consume + opt type IN ['position','bulk-position'] && action == 'timeout-reserved' + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state \n(transferStateChange.transferStateId == 'RESERVED_TIMEOUT')\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'EXPIRED_RESERVED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION IMPLEMENTATION + activate POS_DAO + POS_DAO -> DB: Select participantPosition.value FOR UPDATE for payerCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_DAO: Return participantPosition + deactivate DB + POS_DAO <-> POS_DAO: **latestPosition** = participantPosition - payload.amount.amount + POS_DAO->DB: Persist latestPosition to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_DAO -> DB: Persist participant position change and state change + hnote over DB #lightyellow + INSERT **transferStateChange** + VALUES (transferStateId) + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Transfer event to Bulk Processing Topic (for Payer) \nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + opt type IN ['position','bulk-position'] && (action IN ['reject', 'abort']) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state \n(transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR'])\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If action == 'reject' + alt If type == 'position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event\nError code: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else action == 'abort' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + + ' TODO: We do not see how this scenario will be triggered + opt type IN ['position','bulk-position'] && action == 'fail' (Unable to currently trigger this scenario) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferStateChange.transferStateId == 'FAILED') + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'FAILED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If type =='position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type =='bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event\nError code: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg new file mode 100644 index 000000000..038eaff5f --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg @@ -0,0 +1,613 @@ + + 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + + + 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + Abort Position Handler Consume + + + opt + [type IN ['position','bulk-position'] && action == 'timeout-reserved'] + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state + (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 6 + transferStateId + = 'EXPIRED_RESERVED' + + + 7 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION IMPLEMENTATION + + + 8 + Select participantPosition.value FOR UPDATE for payerCurrencyId + + participantPosition + + + 9 + Return participantPosition + + + + + + 10 + latestPosition + = participantPosition - payload.amount.amount + + + 11 + Persist latestPosition to DB for Payer + + UPDATE + participantPosition + SET value = latestPosition + + + 12 + Persist participant position change and state change + + INSERT + transferStateChange +   + VALUES (transferStateId) +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 13 + Return success + + + alt + [If type == 'bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Publish Transfer event to Bulk Processing Topic (for Payer) + Error codes: + 2003 + + [If type == 'position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 15 + Publish Notification event + Error code: + 2003 + + + opt + [type IN ['position','bulk-position'] && (action IN ['reject', 'abort'])] + + + 16 + Request current state of transfer from DB + Error code: + 2003 + + + 17 + Retrieve current state of transfer from DB + + transferStateChange + + + 18 + Return current state of transfer from DB + + + 19 + Return current state of transfer from DB + + + + + + 20 + Validate current state + (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 21 + transferStateId + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + 22 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 23 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 24 + Return success + + + alt + [If action == 'reject'] + + + alt + [If type == 'position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + + 25 + Publish Notification event + Error code: + 2003 + + [If type == 'bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + + 26 + Publish Notification event + Error code: + 2003 + + [action == 'abort'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <payload.errorInformation.errorCode || 5000> + description: <payload.errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Notification event + Error code: + 2003 + + + opt + [type IN ['position','bulk-position'] && action == 'fail' (Unable to currently trigger this scenario)] + + + 28 + Request current state of transfer from DB + Error code: + 2003 + + + 29 + Retrieve current state of transfer from DB + + transferStateChange + + + 30 + Return current state of transfer from DB + + + 31 + Return current state of transfer from DB + + + + + + 32 + Validate current state (transferStateChange.transferStateId == 'FAILED') + + + Persist Position change and Transfer state + + + + + 33 + transferStateId + = 'FAILED' + + + 34 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 35 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 36 + Return success + + + alt + [If type =='position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 37 + Publish Notification event + Error code: + 2003 + + [If type =='bulk-position'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: bulk-processing, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 38 + Publish Notification event + Error code: + 2003 + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml new file mode 100644 index 000000000..3f29d4657 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml @@ -0,0 +1,230 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 3.1.0. Transfer Timeout (incl. Bulk Transfer) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API\nAdapter" as MLAPI +control "ML API Notification\nEvent Handler" as NOTIFY_HANDLER +control "Transfer Timeout\nHandler" as EXP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event\nHandler" as POS_HANDLER +control "Bulk Processing\nHandler" as BULK_PROCESSING_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-event" as TOPIC_EVENT +collections "topic-\nbulk-processing" as BULK_PROCESSING_TOPIC + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant EXP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant BULK_PROCESSING_HANDLER + participant BULK_PROCESSING_TOPIC +end box + +' start flow +activate NOTIFY_HANDLER +activate EXP_HANDLER +activate POS_HANDLER +activate BULK_PROCESSING_HANDLER +group Transfer Expiry + ||| + ref over EXP_HANDLER, TOPIC_EVENT : Timeout Handler Consume\n + alt transferStateId == 'RECEIVED_PREPARE' + alt Regular Transfer + EXP_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Individual Transfer from a Bulk + EXP_HANDLER -> BULK_PROCESSING_TOPIC: Produce message + end + else transferStateId == 'RESERVED' + EXP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS : Position Hander Consume (Timeout)\n + alt Regular Transfer + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Individual Transfer from a Bulk + POS_HANDLER -> BULK_PROCESSING_TOPIC: Produce message + end + end + opt action IN ['bulk-timeout-received', 'bulk-timeout-reserved'] + ||| + BULK_PROCESSING_TOPIC <- BULK_PROCESSING_HANDLER: Consume message + ref over TOPIC_NOTIFICATIONS, BULK_PROCESSING_TOPIC : Bulk Processing Consume\n + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + ||| + opt action IN ['timeout-received', 'timeout-reserved', 'bulk-timeout-received', 'bulk-timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP1, TOPIC_NOTIFICATIONS : Send notification to Participant (Payer)\n + alt Timeout before any processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + else Timeout in middle of processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": , + "fulfilment": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + end + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + opt action IN ['timeout-reserved', 'bulk-timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP2, TOPIC_NOTIFICATIONS : Send notification to Participant (Payee)\n + alt Timeout before any processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + else Timeout in middle of processing + note left of NOTIFY_HANDLER #yellow + PUT /bulkTransfers/ + { + headers: , + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": , + "fulfilment": + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": + } + "transferId": + }, + ] + } + } + end note + end + NOTIFY_HANDLER -> DFSP2: Send callback notification + end +end +deactivate BULK_PROCESSING_HANDLER +deactivate POS_HANDLER +deactivate EXP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg new file mode 100644 index 000000000..e9424fc66 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg @@ -0,0 +1,349 @@ + + 3.1.0. Transfer Timeout (incl. Bulk Transfer) + + + 3.1.0. Transfer Timeout (incl. Bulk Transfer) + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API + Adapter + + + ML API + Adapter + + + ML API Notification + Event Handler + + + ML API Notification + Event Handler + + + Transfer Timeout + Handler + + + Transfer Timeout + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + Position Event + Handler + + + Position Event + Handler + + + + + topic- + notification + + + topic- + notification + Bulk Processing + Handler + + + Bulk Processing + Handler + + + + + topic- + bulk-processing + + + topic- + bulk-processing + + + + + + + Transfer Expiry + + + ref + Timeout Handler Consume +   + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + alt + [Regular Transfer] + + + 1 + Produce message + + [Individual Transfer from a Bulk] + + + 2 + Produce message + + [transferStateId == 'RESERVED'] + + + 3 + Produce message + + + 4 + Consume message + + + ref + Position Hander Consume (Timeout) +   + + + alt + [Regular Transfer] + + + 5 + Produce message + + [Individual Transfer from a Bulk] + + + 6 + Produce message + + + opt + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + 7 + Consume message + + + ref + Bulk Processing Consume +   + + + 8 + Produce message + + + opt + [action IN ['timeout-received', 'timeout-reserved', 'bulk-timeout-received', 'bulk-timeout-reserved']] + + + 9 + Consume message + + + ref + Send notification to Participant (Payer) +   + + + alt + [Timeout before any processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + [Timeout in middle of processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": <ID>, + "fulfilment": <fulfilment> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + + 10 + Send callback notification + + + opt + [action IN ['timeout-reserved', 'bulk-timeout-reserved']] + + + 11 + Consume message + + + ref + Send notification to Participant (Payee) +   + + + alt + [Timeout before any processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + [Timeout in middle of processing] + + + PUT /bulkTransfers/<ID> + { + headers: <bulkTransferHeaders>, + body: { + "bulkTransferState": "COMPLETED", + "completedTimestamp": "2022-08-18T01:00:24.407Z", + "individualTransferResults": [ + { + "transferId": <ID>, + "fulfilment": <fulfilment> + }, + { + "errorInformation": { + "errorCode": "3303", + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + "transferId": <ID> + }, + ] + } + } + + + 12 + Send callback notification + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml new file mode 100644 index 000000000..1c9343431 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml @@ -0,0 +1,420 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Transfer Timeout\nHandler" as TIMEOUT_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as NOTIFICATIONS_TOPIC +collections "topic-event" as EVENT_TOPIC +collections "topic-\nbulk-processing" as BULK_PROCESSING_TOPIC +entity "Segment DAO" as SEGMENT_DAO +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant NOTIFICATIONS_TOPIC + participant EVENT_TOPIC + participant BULK_PROCESSING_TOPIC + participant POS_DAO + participant SEGMENT_DAO + participant DB +end box + +' start flow + +group Timeout Handler Consume + activate TIMEOUT_HANDLER + group Persist Event Information + TIMEOUT_HANDLER -> EVENT_TOPIC: Publish event information + ref over TIMEOUT_HANDLER, EVENT_TOPIC : Event Handler Consume\n + end + + group Get previous checkpoint of last record processed (Lower limit for inclusion) + TIMEOUT_HANDLER -> SEGMENT_DAO: Get last segment as @intervalMin + activate SEGMENT_DAO + SEGMENT_DAO -> DB: Get last segment as @intervalMin + hnote over DB #lightyellow + SELECT value INTO @intervalMin + FROM **segment** + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + end note + activate DB + DB --> SEGMENT_DAO: Return @intervalMin + deactivate DB + SEGMENT_DAO --> TIMEOUT_HANDLER: Return @intervalMin + deactivate SEGMENT_DAO + opt @intervalMin IS NULL => segment record NOT FOUND + TIMEOUT_HANDLER->TIMEOUT_HANDLER: Set @intervalMin = 0 + end + end + + group Do Cleanup + TIMEOUT_HANDLER -> POS_DAO: Clean up transferTimeout from finalised transfers + activate POS_DAO + POS_DAO -> DB: Clean up transferTimeout from finalised transfers + hnote over DB #lightyellow + DELETE tt + FROM **transferTimeout** AS tt + JOIN (SELECT tsc.transferId, MAX(tsc.transferStateChangeId) maxTransferStateChangeId + FROM **transferTimeout** tt1 + JOIN **transferStateChange** tsc + ON tsc.transferId = tt1.transferId + GROUP BY transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_FULFIL', 'COMMITTED', 'FAILED' + , 'EXPIRED', 'REJECTED', 'EXPIRED_PREPARED', 'EXPIRED_RESERVED', 'ABORTED') + end note + activate DB + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return success + deactivate POS_DAO + end + + group Determine IntervalMax (Upper limit for inclusion) + TIMEOUT_HANDLER -> POS_DAO: Get last transferStateChangeId as @intervalMax + activate POS_DAO + POS_DAO -> DB: Get last transferStateChangeId as @intervalMax + hnote over DB #lightyellow + SELECT MAX(transferStateChangeId) INTO @intervalMax + FROM **transferStateChange** + end note + activate DB + DB --> POS_DAO: Return @intervalMax + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return @intervalMax + deactivate POS_DAO + end + + + group Prepare data and return the list for expiration + TIMEOUT_HANDLER -> POS_DAO: Prepare data and get transfers to be expired + activate POS_DAO + group DB TRANSACTION + POS_DAO <-> POS_DAO: **transactionTimestamp** = now() + POS_DAO -> DB: Insert all new transfers still in processing state + hnote over DB #lightyellow + INSERT INTO **transferTimeout**(transferId, expirationDate) + SELECT t.transferId, t.expirationDate + FROM **transfer** t + JOIN (SELECT transferId, MAX(transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** + WHERE transferStateChangeId > @intervalMin + AND transferStateChangeId <= @intervalMax + GROUP BY transferId) ts + ON ts.transferId = t.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_PREPARE', 'RESERVED') + end note + activate DB + deactivate DB + + POS_DAO -> DB: Insert transfer state ABORTED for\nexpired RECEIVED_PREPARE transfers + hnote over DB #lightyellow + INSERT INTO **transferStateChange** + SELECT tt.transferId, 'EXPIRED_PREPARED' AS transferStateId, 'Aborted by Timeout Handler' AS reason + FROM **transferTimeout** tt + JOIN ( -- Following subquery is reused 3 times and may be optimized if needed + SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RECEIVED_PREPARE' + end note + activate DB + deactivate DB + + POS_DAO -> DB: Insert transfer state EXPIRED for\nexpired RESERVED transfers + hnote over DB #lightyellow + INSERT INTO **transferStateChange** + SELECT tt.transferId, 'RESERVED_TIMEOUT' AS transferStateId, 'Expired by Timeout Handler' AS reason + FROM **transferTimeout** tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RESERVED' + end note + activate DB + deactivate DB + + POS_DAO -> DB: Update segment table to be used for the next run + hnote over DB #lightyellow + IF @intervalMin = 0 + INSERT + INTO **segment**(segmentType, enumeration, tableName, value) + VALUES ('timeout', 0, 'transferStateChange', @intervalMax) + ELSE + UPDATE **segment** + SET value = @intervalMax + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + end note + activate DB + deactivate DB + end + + POS_DAO -> DB: Get list of transfers to be expired with current state + hnote over DB #lightyellow + SELECT tt.*, tsc.transferStateId, tp1.participantCurrencyId payerParticipantId, + tp2.participantCurrencyId payeeParticipantId, bta.bulkTransferId + FROM **transferTimeout** tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM **transferStateChange** tsc1 + JOIN **transferTimeout** tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN **transferStateChange** tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + JOIN **transferParticipant** tp1 + ON tp1.transferId = tt.transferId + AND tp1.transferParticipantRoleTypeId = {PAYER_DFSP} + AND tp1.ledgerEntryTypeId = {PRINCIPLE_VALUE} + JOIN **transferParticipant** tp2 + ON tp2.transferId = tt.transferId + AND tp2.transferParticipantRoleTypeId = {PAYEE_DFSP} + AND tp2.ledgerEntryTypeId = {PRINCIPLE_VALUE} + LEFT JOIN **bulkTransferAssociation** bta + ON bta.transferId = tt.transferId + WHERE tt.expirationDate < {transactionTimestamp} + end note + activate DB + POS_DAO <-- DB: Return **transferTimeoutList** + deactivate DB + POS_DAO --> TIMEOUT_HANDLER: Return **transferTimeoutList** + deactivate POS_DAO + end + + loop for each transfer in the list + ||| + alt transferTimeoutList.bulkTransferId == NULL (Regular Transfer) + alt transferStateId == 'RECEIVED_PREPARE' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: notification, + action: timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> NOTIFICATIONS_TOPIC: Publish Notification event + activate NOTIFICATIONS_TOPIC + deactivate NOTIFICATIONS_TOPIC + else transferStateId == 'RESERVED' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + else Individual Transfer from a Bulk + alt transferStateId == 'RECEIVED_PREPARE' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + transferId: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: bulk-processing, + action: bulk-timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> BULK_PROCESSING_TOPIC: Publish to Bulk Processing topic + activate BULK_PROCESSING_TOPIC + deactivate BULK_PROCESSING_TOPIC + else transferStateId == 'RESERVED' + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + transferId: , + from: , + to: , + type: application/json, + content: { + headers: ,, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: bulk-timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + + deactivate TIMEOUT_HANDLER +end +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg new file mode 100644 index 000000000..5d241117d --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg @@ -0,0 +1,596 @@ + + 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + + + 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Transfer Timeout + Handler + + + Transfer Timeout + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + notification + + + topic- + notification + + + topic-event + + + topic-event + + + topic- + bulk-processing + + + topic- + bulk-processing + Position DAO + + + Position DAO + + + Segment DAO + + + Segment DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + Timeout Handler Consume + + + Persist Event Information + + + 1 + Publish event information + + + ref + Event Handler Consume +   + + + Get previous checkpoint of last record processed (Lower limit for inclusion) + + + 2 + Get last segment as @intervalMin + + + 3 + Get last segment as @intervalMin + + SELECT value INTO @intervalMin + FROM + segment + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + + + 4 + Return @intervalMin + + + 5 + Return @intervalMin + + + opt + [@intervalMin IS NULL => segment record NOT FOUND] + + + + + 6 + Set @intervalMin = 0 + + + Do Cleanup + + + 7 + Clean up transferTimeout from finalised transfers + + + 8 + Clean up transferTimeout from finalised transfers + + DELETE tt + FROM + transferTimeout + AS tt + JOIN (SELECT tsc.transferId, MAX(tsc.transferStateChangeId) maxTransferStateChangeId + FROM + transferTimeout + tt1 + JOIN + transferStateChange + tsc + ON tsc.transferId = tt1.transferId + GROUP BY transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_FULFIL', 'COMMITTED', 'FAILED' + , 'EXPIRED', 'REJECTED', 'EXPIRED_PREPARED', 'EXPIRED_RESERVED', 'ABORTED') + + + 9 + Return success + + + Determine IntervalMax (Upper limit for inclusion) + + + 10 + Get last transferStateChangeId as @intervalMax + + + 11 + Get last transferStateChangeId as @intervalMax + + SELECT MAX(transferStateChangeId) INTO @intervalMax + FROM + transferStateChange + + + 12 + Return @intervalMax + + + 13 + Return @intervalMax + + + Prepare data and return the list for expiration + + + 14 + Prepare data and get transfers to be expired + + + DB TRANSACTION + + + + + + 15 + transactionTimestamp + = now() + + + 16 + Insert all new transfers still in processing state + + INSERT INTO + transferTimeout + (transferId, expirationDate) + SELECT t.transferId, t.expirationDate + FROM + transfer + t + JOIN (SELECT transferId, MAX(transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + WHERE transferStateChangeId > @intervalMin + AND transferStateChangeId <= @intervalMax + GROUP BY transferId) ts + ON ts.transferId = t.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tsc.transferStateId IN ('RECEIVED_PREPARE', 'RESERVED') + + + 17 + Insert transfer state ABORTED for + expired RECEIVED_PREPARE transfers + + INSERT INTO + transferStateChange + SELECT tt.transferId, 'EXPIRED_PREPARED' AS transferStateId, 'Aborted by Timeout Handler' AS reason + FROM + transferTimeout + tt + JOIN ( + -- Following subquery is reused 3 times and may be optimized if needed + SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RECEIVED_PREPARE' + + + 18 + Insert transfer state EXPIRED for + expired RESERVED transfers + + INSERT INTO + transferStateChange + SELECT tt.transferId, 'RESERVED_TIMEOUT' AS transferStateId, 'Expired by Timeout Handler' AS reason + FROM + transferTimeout + tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + WHERE tt.expirationDate < {transactionTimestamp} + AND tsc.transferStateId = 'RESERVED' + + + 19 + Update segment table to be used for the next run + + IF @intervalMin = 0 + INSERT + INTO + segment + (segmentType, enumeration, tableName, value) + VALUES ('timeout', 0, 'transferStateChange', @intervalMax) + ELSE + UPDATE + segment + SET value = @intervalMax + WHERE segmentType = 'timeout' + AND enumeration = 0 + AND tableName = 'transferStateChange' + + + 20 + Get list of transfers to be expired with current state + + SELECT tt.*, tsc.transferStateId, tp1.participantCurrencyId payerParticipantId, + tp2.participantCurrencyId payeeParticipantId, bta.bulkTransferId + FROM + transferTimeout + tt + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + FROM + transferStateChange + tsc1 + JOIN + transferTimeout + tt1 + ON tt1.transferId = tsc1.transferId + GROUP BY tsc1.transferId) ts + ON ts.transferId = tt.transferId + JOIN + transferStateChange + tsc + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + JOIN + transferParticipant + tp1 + ON tp1.transferId = tt.transferId + AND tp1.transferParticipantRoleTypeId = {PAYER_DFSP} + AND tp1.ledgerEntryTypeId = {PRINCIPLE_VALUE} + JOIN + transferParticipant + tp2 + ON tp2.transferId = tt.transferId + AND tp2.transferParticipantRoleTypeId = {PAYEE_DFSP} + AND tp2.ledgerEntryTypeId = {PRINCIPLE_VALUE} + LEFT JOIN + bulkTransferAssociation + bta + ON bta.transferId = tt.transferId + WHERE tt.expirationDate < {transactionTimestamp} + + + 21 + Return + transferTimeoutList + + + 22 + Return + transferTimeoutList + + + loop + [for each transfer in the list] + + + alt + [transferTimeoutList.bulkTransferId == NULL (Regular Transfer)] + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: notification, + action: timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 23 + Publish Notification event + + [transferStateId == 'RESERVED'] + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 24 + Route & Publish Position event + + [Individual Transfer from a Bulk] + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + Message: + { +      + id + : <transferTimeoutList.bulkTransferId>, +      + transferId + : <transferTimeoutList.transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: <bulkTransferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: bulk-processing, + action: bulk-timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 25 + Publish to Bulk Processing topic + + [transferStateId == 'RESERVED'] + + + Message: + { +      + id + : <transferTimeoutList.bulkTransferId>, +      + transferId + : <transferTimeoutList.transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { + headers: <bulkTransferHeaders>,, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: bulk-timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 26 + Route & Publish Position event + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml new file mode 100644 index 000000000..e02a15142 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml @@ -0,0 +1,233 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declare title +title 4.1.0. Bulk Transfer Abort + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULKAPI +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Bulk-Fulfil-Topic" as TOPIC_BULK_FULFIL +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Bulk Fulfil Event Handler" as BULK_FULFIL_HANDLER +control "Fulfil Event Handler" as FULFIL_HANDLER +collections "topic-transfer-position" as TOPIC_POSITION +control "Position Event Handler" as POS_HANDLER +collections "topic-bulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing Event Handler" as BULK_PROCESSING_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +database "Central Services DB" as DB + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_BULK_FULFIL + participant TOPIC_FULFIL + participant BULK_FULFIL_HANDLER + participant FULFIL_HANDLER + participant TOPIC_POSITION + participant TOPIC_EVENTS + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROCESSING_HANDLER + participant TOPIC_NOTIFICATIONS + participant OBJECT_STORE + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_FULFIL_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate BULK_PROCESSING_HANDLER +activate POS_HANDLER + +group DFSP2 sends a Fulfil Abort Transfer request + note right of DFSP2 #lightblue + **Note**: In the payload for PUT /bulkTransfers//error + only the **errorInformation** field is **required** + end note + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + Payload - errorMessage: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> BULKAPI: **PUT - /bulkTransfers//error** + activate BULKAPI + + BULKAPI -> OBJECT_STORE: Persist request payload with messageId in cache + activate OBJECT_STORE + note right of BULKAPI #yellow + Message: { + messageId: , + bulkTransferId: , + payload: + } + end note + hnote over OBJECT_STORE #lightyellow + individualTransferFulfils + end hnote + BULKAPI <- OBJECT_STORE: Response of save operation + deactivate OBJECT_STORE + note right of BULKAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULKAPI -> TOPIC_BULK_FULFIL: Produce bulk-fulfil message + BULKAPI -->> DFSP2: Respond HTTP - 200 (OK) + TOPIC_BULK_FULFIL <- BULK_FULFIL_HANDLER: Consume bulk-fulfil message + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Perform duplicate check + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Validate request + loop n times, n = number of individual transfers + note right of BULK_FULFIL_HANDLER + Message: { + transferId: , + bulkTransferId< , + bulkTransferAssociationRecord: { + transferId: , + bulkTransferId: , + bulkProcessingStateId: , + errorCode: , + errorDescription: + } + } + end note + BULK_FULFIL_HANDLER -> DB: Update bulkTransferAssociation table + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end hnote + deactivate DB + BULK_FULFIL_HANDLER -> TOPIC_FULFIL: Produce fulfil message with action bulk-abort for each individual transfer + end + ||| + loop n times, n = number of individual transfers + TOPIC_FULFIL <- FULFIL_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_EVENTS: Fulfil Handler Consume (bulk-abort)\n + FULFIL_HANDLER -> TOPIC_POSITION: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_POSITION, BULK_PROCESSING_HANDLER: Position Handler Consume (bulk-abort)\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_BULK_PROCESSING <- BULK_PROCESSING_HANDLER: Consume individual transfer message + ref over TOPIC_BULK_PROCESSING, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume (bulk-abort)\n + end + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payer) + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payee) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payer) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payee) + opt action == 'bulk-abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Notification Handler (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + opt action == 'bulk-abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Notification Handler (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +activate POS_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate NOTIFY_HANDLER +@enduml + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg new file mode 100644 index 000000000..51eae9583 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg @@ -0,0 +1,397 @@ + + 4.1.0. Bulk Transfer Abort + + + 4.1.0. Bulk Transfer Abort + + Financial Service Providers + + Bulk API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification Event Handler + + + Bulk API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Bulk-Fulfil-Topic + + + Bulk-Fulfil-Topic + + + Fulfil-Topic + + + Fulfil-Topic + Bulk Fulfil Event Handler + + + Bulk Fulfil Event Handler + + + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + Position Event Handler + + + Position Event Handler + + + + + topic-bulk-processing + + + topic-bulk-processing + Bulk Processing Event Handler + + + Bulk Processing Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + mojaloop- + object-store + ( + MLOS + ) + + + mojaloop- + object-store + ( + MLOS + ) + Central Services DB + + + Central Services DB + + + + + + + + + + + + + + DFSP2 sends a Fulfil Abort Transfer request + + + Note + : In the payload for PUT /bulkTransfers/<ID>/error + only the + errorInformation + field is + required + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } + Payload - errorMessage: + { + "errorInformation": { + "errorCode": <string>, + "errorDescription": <string>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 1 + PUT - /bulkTransfers/<ID>/error + + + 2 + Persist request payload with messageId in cache + + + Message: { + messageId: <string>, + bulkTransferId: <string>, + payload: <object> + } + + individualTransferFulfils + + + 3 + Response of save operation + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Produce bulk-fulfil message + + + + 5 + Respond HTTP - 200 (OK) + + + 6 + Consume bulk-fulfil message + + + + + 7 + Perform duplicate check + + + + + 8 + Validate request + + + loop + [n times, n = number of individual transfers] + + + Message: { + transferId: <string>, + bulkTransferId< <string>, + bulkTransferAssociationRecord: { + transferId: <string>, + bulkTransferId: <string>, + bulkProcessingStateId: <string>, + errorCode: <string>, + errorDescription: <string> + } + } + + + 9 + Update bulkTransferAssociation table + + bulkTransferAssociation + + + 10 + Produce fulfil message with action bulk-abort for each individual transfer + + + loop + [n times, n = number of individual transfers] + + + 11 + Consume message + + + ref + Fulfil Handler Consume (bulk-abort) +   + + + 12 + Produce message + + + loop + [n times, n = number of individual transfers] + + + 13 + Consume message + + + ref + Position Handler Consume (bulk-abort) +   + + + 14 + Produce message + + + loop + [n times, n = number of individual transfers] + + + 15 + Consume individual transfer message + + + ref + Bulk Processing Handler Consume (bulk-abort) +   + + + 16 + Produce message (Payer) + + + 17 + Produce message (Payee) + + + 18 + Consume message (Payer) + + + 19 + Consume message (Payee) + + + opt + [action == 'bulk-abort'] + + + ref + Notification Handler (Payer) +   + + + 20 + Send callback notification + + + opt + [action == 'bulk-abort'] + + + ref + Notification Handler (Payee) +   + + + 21 + Send callback notification + + diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml new file mode 100644 index 000000000..e219f2465 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml @@ -0,0 +1,209 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declate title +title 5.1.0. Request Bulk Transfer Status + +autonumber + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Bulk API Adapter" as BULKAPI +collections "Topic-Transfer-Get" as TOPIC_GET +control "GET Event Handler" as GET_HANDLER +entity "Bulk Transfer DAO" as BULK_TRANSFER_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box +box "Central Ledger" #LightYellow + participant TOPIC_GET + participant GET_HANDLER + participant BULK_TRANSFER_DAO + participant DB +end box + +' start flow +group Request Bulk transfer status + activate DFSP + DFSP -> BULKAPI: Request bulk transfer status - GET - /bulkTransfers/{ID} + activate BULKAPI + ||| + BULKAPI -> TOPIC_GET: Publish event information + deactivate BULKAPI + activate TOPIC_GET + ||| + deactivate GET_HANDLER + + DFSP <-- BULKAPI: Respond HTTP - 200 (OK) + deactivate DFSP + deactivate BULKAPI + GET_HANDLER -> TOPIC_GET: Consume message + ||| + ref over TOPIC_GET, GET_HANDLER : GET Handler Consume\n + ||| + deactivate TOPIC_GET + + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer participants + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer participants + activate DB + hnote over DB #lightYellow + bulkTransfer + participant + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer participants + deactivate BULK_TRANSFER_DAO + alt Is request not from bulk transfer Payer or Payee FSP? + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer status + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer status + + activate DB + hnote over DB #lightyellow + bulkTransferStateChange + bulkTransferState + bulkTransferError + bulkTransferExtension + transferStateChange + transferState + transferFulfilment + transferError + transferExtension + ilpPacket + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer status + deactivate BULK_TRANSFER_DAO + + alt Is there a bulk transfer with the given ID recorded in the system? + alt Bulk Transfer state is **"PROCESSING"** + note left of GET_HANDLER #yellow + { + "bulkTransferState": "PROCESSING" + } + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> DFSP: Send callback - PUT /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + end + ||| + alt Request is from Payee FSP? + GET_HANDLER <-> GET_HANDLER: Exclude transfers with **transferStateId** not in \n [ **COMMITTED**, **ABORTED_REJECTED**, **EXPIRED_RESERVED** ] + activate GET_HANDLER + end + + note left of GET_HANDLER #yellow + { + "bulkTransferState": "", + "individualTransferResults": [ + { + "transferId": "", + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "errorInformation": , + "extensionList": { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + ], + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "extensionList": + { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + end note + note left of GET_HANDLER #lightGray + NOTE: If transfer is REJECTED, error information may be provided. + Either fulfilment or errorInformation should be set, not both. + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + note right of NOTIFY_HANDLER #lightgray + Log ERROR event + end note + else A bulk transfer with the given ID is not present in the System or this is an invalid request + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + + deactivate GET_HANDLER + deactivate NOTIFY_HANDLER +deactivate DFSP +end +@enduml diff --git a/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg new file mode 100644 index 000000000..9b520a21c --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg @@ -0,0 +1,295 @@ + + 5.1.0. Request Bulk Transfer Status + + + 5.1.0. Request Bulk Transfer Status + + Financial Service Provider + + Bulk API Adapter Service + + Central Ledger + + + + + + + + + + + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + Bulk API Adapter + + + Bulk API Adapter + + + Bulk API Notification Event Handler + + + Bulk API Notification Event Handler + + + + + Topic-Transfer-Get + + + Topic-Transfer-Get + GET Event Handler + + + GET Event Handler + + + Bulk Transfer DAO + + + Bulk Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + Request Bulk transfer status + + + 1 + Request bulk transfer status - GET - /bulkTransfers/{ID} + + + 2 + Publish event information + + + 3 + Respond HTTP - 200 (OK) + + + 4 + Consume message + + + ref + GET Handler Consume +   + + + 5 + Request bulk transfer participants + + + 6 + Fetch bulk transfer participants + + bulkTransfer + participant + + + 7 + Return query result + + + 8 + Return bulk transfer participants + + + alt + [Is request not from bulk transfer Payer or Payee FSP?] + + + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + + + 9 + Publish notification event (404) + + + 10 + callback PUT on /bulkTransfers/{ID}/error + + + 11 + Request bulk transfer status + + + 12 + Fetch bulk transfer status + + bulkTransferStateChange + bulkTransferState + bulkTransferError + bulkTransferExtension + transferStateChange + transferState + transferFulfilment + transferError + transferExtension + ilpPacket + + + 13 + Return query result + + + 14 + Return bulk transfer status + + + alt + [Is there a bulk transfer with the given ID recorded in the system?] + + + alt + [Bulk Transfer state is + "PROCESSING" + ] + + + { + "bulkTransferState": "PROCESSING" + } + + + 15 + Publish notification event + + + 16 + Send callback - PUT /bulkTransfers/{ID} + + + alt + [Request is from Payee FSP?] + + + + + + 17 + Exclude transfers with + transferStateId + not in + [ + COMMITTED + , + ABORTED_REJECTED + , + EXPIRED_RESERVED + ] + + + { + "bulkTransferState": "<BulkTransferState>", + "individualTransferResults": [ + { + "transferId": "<TransferId>", + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "errorInformation": <ErrorInformationObject>, + "extensionList": { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + ], + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "extensionList": + { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + + + NOTE: If transfer is REJECTED, error information may be provided. + Either fulfilment or errorInformation should be set, not both. + + + 18 + Publish notification event + + + 19 + callback PUT on /bulkTransfers/{ID} + + + Log ERROR event + + [A bulk transfer with the given ID is not present in the System or this is an invalid request] + + + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + + + 20 + Publish notification event (404) + + + 21 + callback PUT on /bulkTransfers/{ID}/error + + diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md b/docs/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md new file mode 100644 index 000000000..8ad8c6ce7 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Bulk Prepare Transfer Request [Overview] [includes individual transfers in a bulk] + +Sequence design diagram for Prepare Transfer Request process. + +## References within Sequence Diagram + +* [Bulk Prepare Handler Consume (1.1.1)](1.1.1-bulk-prepare-handler-consume.md) +* [Prepare Handler Consume (1.2.1)](1.2.1-prepare-handler-consume-for-bulk.md) +* [Position Handler Consume (1.3.0)](1.3.0-position-handler-consume-overview.md) +* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-1.1.0-bulk-prepare-overview.svg](../assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md b/docs/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md new file mode 100644 index 000000000..495a0fdaf --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Bulk Prepare handler consume + +Sequence design diagram for Bulk Prepare Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-1.1.1-bulk-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md new file mode 100644 index 000000000..aabde9fb1 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md @@ -0,0 +1,11 @@ +# Prepare handler consume [that includes individual transfers in a bulk] + +Sequence design diagram for Prepare Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-1.2.1-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md b/docs/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md new file mode 100644 index 000000000..aae066006 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md @@ -0,0 +1,14 @@ +# Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for Position Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fufil Position Handler Consume (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) +* [Abort Position Handler Consume (2.2.2)](2.2.2-fulfil-abort-for-bulk.md) + +## Sequence Diagram + +![seq-bulk-1.3.0-position-overview.svg](../assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md b/docs/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..460ab7350 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Prepare Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for Prepare Position Handler Consume process + +## Sequence Diagram + +![seq-bulk-1.3.1-position-prepare.svg](../assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md b/docs/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md new file mode 100644 index 000000000..53fe3c2b8 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md @@ -0,0 +1,7 @@ +# Bulk Processing Handler Consume + +Sequence design diagram for Bulk Processing Handler Consume process + +## Sequence Diagram + +![seq-bulk-1.4.1-bulk-processing-handler.svg](../assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md b/docs/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md new file mode 100644 index 000000000..f08b37d9e --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Bulk Fulfil Transfer Request Overview + +Sequence design diagram for the Bulk Fulfil Transfer request + +## References within Sequence Diagram + +* [Bulk Fulfil Handler Consume (Success) (2.1.1)](2.1.1-bulk-fulfil-handler-consume.md) +* [Fulfil Handler Consume (Success) (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) +* [Position Handler Consume (Success) (2.3.1)](2.3.1-fulfil-position-handler-consume.md) +* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.1.0-bulk-fulfil-overview.svg](../assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md b/docs/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md new file mode 100644 index 000000000..ea730d0b8 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Bulk Fulfil Handler Consume + +Sequence design diagram for the Bulk Fulfil Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.1.1-bulk-fulfil-handler.svg](../assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md new file mode 100644 index 000000000..7a2102201 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md @@ -0,0 +1,11 @@ +# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers + +Sequence design diagram for the Bulk Fulfil Transfer for the Commit option + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-2.2.1-fulfil-handler-commit.svg](../assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md new file mode 100644 index 000000000..6b32a71bc --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md @@ -0,0 +1,13 @@ +# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.2.2-fulfil-handler-abort.svg](../assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md b/docs/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md new file mode 100644 index 000000000..3b4d2877a --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md @@ -0,0 +1,11 @@ +# Fulfil Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for the Fulfil Position Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-2.3.1-position-fulfil.svg](../assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md b/docs/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md new file mode 100644 index 000000000..ed4d3f9f8 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md @@ -0,0 +1,7 @@ +# Position Handler Consume for Fulfil aborts at individual transfer level + +Sequence design diagram for Fulfil Position Handler Consume process + +## Sequence Diagram + +![seq-bulk-2.3.2-position-abort.svg](../assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md new file mode 100644 index 000000000..030f29281 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Transfer Timeout [includes individual transfers in a Bulk] + +Sequence design diagram for the Transfer Timeout process. + +## Sequence Diagram + +![seq-bulk-3.1.0-timeout-overview.svg](../assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md b/docs/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md new file mode 100644 index 000000000..d8fcefc23 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md @@ -0,0 +1,7 @@ +# TimeOut Handler + +Sequence design diagram for Timeout Handler process + +## Sequence Diagram + +![seq-bulk-3.1.1-timeout-handler.svg](../assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md new file mode 100644 index 000000000..25c4873e4 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Bulk Transfer Abort Overview [includes individual transfers in a Bulk] + +Sequence design diagram for the Bulk Transfer Abort process. + +## Sequence Diagram + +![seq-bulk-4.1.0-abort-overview.svg](../assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md b/docs/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md new file mode 100644 index 000000000..d4d05674a --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Get Bulk Transfer Overview + +Sequence design diagram for the Get Bulk Transfer process. + +## Sequence Diagram + +![seq-bulk-5.1.0-get-overview.svg](../assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg) diff --git a/docs/technical/technical/central-bulk-transfers/transfers/README.md b/docs/technical/technical/central-bulk-transfers/transfers/README.md new file mode 100644 index 000000000..36adeecc5 --- /dev/null +++ b/docs/technical/technical/central-bulk-transfers/transfers/README.md @@ -0,0 +1,11 @@ +# Mojaloop Bulk Transfer operations + +Operational processes that is the core of the transfer operational process; + +- Bulk Prepare Process at Bulk Transfer level +- Prepare process at a single transfer level +- Bulk Fulfil process at Bulk Transfer level +- Fulfil process at a single transfer level +- Notifications process at Bulk Transfer level +- Reject/Abort process +- Bulk Processing at a single transfer level to aggregate Bulks diff --git a/mojaloop-technical-overview/central-event-processor/README.md b/docs/technical/technical/central-event-processor/README.md similarity index 100% rename from mojaloop-technical-overview/central-event-processor/README.md rename to docs/technical/technical/central-event-processor/README.md diff --git a/docs/technical/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg b/docs/technical/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg new file mode 100644 index 000000000..40e9f3ae0 --- /dev/null +++ b/docs/technical/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg @@ -0,0 +1,2 @@ + +


    Notifiers
    /email, sms, etc./
    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    prepare 
    [Not supported by viewer]
    fulfil 
    [Not supported by viewer]
    notification 
    <b>notification </b>

    DB
    [Not supported by viewer]
    Central-Services
    Central-Services

    MangoDB
    [Not supported by viewer]
    Central Event
    Processor (CEP)

    [Not supported by viewer]
    RxJS
    RxJS
    json-rule-engine
    json-rule-engine

    Heading

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    [Not supported by viewer]
    REST admin API
    [Not supported by viewer]
    \ No newline at end of file diff --git a/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml rename to docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml diff --git a/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg new file mode 100644 index 000000000..37ea1f2bd --- /dev/null +++ b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg @@ -0,0 +1,83 @@ + + 9.1.0. Event Handler Placeholder + + + 9.1.0. Event Handler Placeholder + + Event Handler Placeholder + + + + + + Event Handler Placeholder + + + Event Handler Placeholder + + + + + Event-Topic + + + Event-Topic + + + + + Event Handler Placeholder + + + 1 + Consume Event message +   + Error code: + 2001 + + + Message: + { + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: INFO, + action: AUDIT, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + The type would be an ENUM with values: + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + Possible values for "action" would be + [AUDIT, EXCEPTION] + The event messages can be handled based on the values of these two variables + (when the placeholder is extended). + + + + + 2 + Auto-commit +   + Error code: + 2001 + + + Currently events to only be published as part of the placeholder. + This can be evolved to add relevant functionality. + + diff --git a/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml rename to docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml diff --git a/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg new file mode 100644 index 000000000..3dfc4a19f --- /dev/null +++ b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg @@ -0,0 +1,160 @@ + + 5.1.1. Notification Handler for Rejections + + + 5.1.1. Notification Handler for Rejections + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + + + + + + + DFSP Notified of Rejection + + + 1 + Consume Notification event message +   + Error code: + 2001 + + + Persist Event Information + + + 2 + Publish event information +   + Error code: + 3201 + + + ref + Event Handler + + + alt + [consume a single messages] + + + Validate Event + + + + + + 3 + Validate event - Rule: type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + + + 4 + Request Participant Callback details +   + Error code: + 3201 + + + ref + Get Participant Callback Details + + + 5 + Return Participant Callback details + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + payload: <transferMessage> + }, + } + + + 6 + Send Callback Notification +   + Error code: + 1000, 1001, 3002 + + [Validate rule type != 'notification' / Error] + + + Message: + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 7 + Invalid messages retrieved from the Notification Topic +   + Error code: + 3201 + + + ref + Event Handler + + + Log ERROR Messages + Update Event log upon ERROR notification + + diff --git a/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml similarity index 100% rename from mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml rename to docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml diff --git a/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg new file mode 100644 index 000000000..86939d30d --- /dev/null +++ b/docs/technical/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg @@ -0,0 +1,29 @@ + + Signature Validation + + + Signature Validation + + + + Alice + + Alice + + Bob + + Bob + + + Authentication Request + + + Authentication Response + + + Another authentication Request + + + another authentication Response + + diff --git a/docs/technical/technical/central-event-processor/event-handler-placeholder.md b/docs/technical/technical/central-event-processor/event-handler-placeholder.md new file mode 100644 index 000000000..e0b8a605b --- /dev/null +++ b/docs/technical/technical/central-event-processor/event-handler-placeholder.md @@ -0,0 +1,7 @@ +# Event Handler Placeholder + +Sequence design diagram for the Event Handler process. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-event-9.1.0.svg) diff --git a/docs/technical/technical/central-event-processor/notification-handler-for-rejections.md b/docs/technical/technical/central-event-processor/notification-handler-for-rejections.md new file mode 100644 index 000000000..e41bd68ea --- /dev/null +++ b/docs/technical/technical/central-event-processor/notification-handler-for-rejections.md @@ -0,0 +1,12 @@ +# Notification Handler for Rejections + +Sequence design diagram for the Notification Handler for Rejections process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](9.1.0-event-handler-placeholder.md) +* [Get Participant Callback Details (3.1.0)](../central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) + +## Sequence Diagram + +![](;./assets/diagrams/sequence/seq-notification-reject-5.1.1.svg) diff --git a/docs/technical/technical/central-event-processor/signature-validation.md b/docs/technical/technical/central-event-processor/signature-validation.md new file mode 100644 index 000000000..8ead8f91b --- /dev/null +++ b/docs/technical/technical/central-event-processor/signature-validation.md @@ -0,0 +1,7 @@ +# Signature Validation + +Sequence design diagram for the Signature Validation process. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-signature-validation.svg) diff --git a/docs/technical/technical/central-ledger/.gitkeep b/docs/technical/technical/central-ledger/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/technical/technical/central-ledger/README.md b/docs/technical/technical/central-ledger/README.md new file mode 100644 index 000000000..103a61da4 --- /dev/null +++ b/docs/technical/technical/central-ledger/README.md @@ -0,0 +1,52 @@ +# Central-Ledger Services + +The central ledger is a series of services that facilitate clearing and settlement of transfers between DFSPs, including the following functions: + +* Brokering real-time messaging for funds clearing +* Maintaining net positions for a deferred net settlement +* Propagating scheme-level and off-transfer fees + +## 1. Central Ledger Process Design + +### 1.1 Architecture overview + +![Central-Ledger Architecture](./assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg) + +## 2. Transfers End-to-End Architecture + + +### 2.1 Transfers End-to-End Architecture for v1.1 +![Transfers Architecture for Mojaloop FSP Interoperability API v1.1](./assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg) + +### 2.2 Transfers End-to-End Architecture for v1.0 +![Transfers Architecture for Mojaloop FSP Interoperability API v1.0](./assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg) + +## 3. Database Design + +### Note + +The grey-colored tables are specific to the transfer process. The blue- and green-colored tables are used for reference purposes during the transfer process. + +Summary of the tables specific to the transfer process; + +- `transfer` - stores data related to the transfer; +- `transferDuplicateCheck` - used to identify duplication during the transfer requests process; +- `transferError` - stores information on transfer errors encountered during the transfer process; +- `transferErrorDuplicateCheck` - used to identify duplication error transfer processes; +- `transferExtensions` - stores information on the transfer extension data; +- `transferFulfilment` - stores data for transfers that have completed the prepare transfer process; +- `transferFulfilmentDuplicateCheck` - used to identify duplicate transfer fulfilment requests; +- `transferParticipant` - participant information related to the transfer process; +- `transferStateChange` - used to track state changes of each individual transfer, creating an audit trail for a specific transfer request; +- `transferTimeout` - stores information of transfers that encountered a timeout exception during the process; +- `ilpPacket` - stores the ilp package for the transfer; + +The remaining tables in the below ERD are either lookup (blue) or settlement-specific (red) and are included as direct or indirect dependencies to depict the relation between the transfer specific entities and the transfer tables. + +The **Central Ledger** database schema definition [Central-Ledger Database Schema Definition](./assets/database/central-ledger-ddl-MySQLWorkbench.sql). + +![Central-Ledger Database Diagram](./assets/database/central-ledger-schema.png) + +## 4. API Specification + +Refer to **Central Ledger API** in the [API Specifications](../../api/README.md#central-ledger-api) section. diff --git a/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md b/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md new file mode 100644 index 000000000..021204219 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-health-check.md @@ -0,0 +1,265 @@ +# GET Health Check + +Design discussion for new Health Check implementation. + + +## Objectives + +The goal for this design is to implement a new Health check for mojaloop switch services that allows for a greater level of detail. + +It Features: +- Clear HTTP Statuses (no need to inspect the response to know there are no issues) +- ~Backwards compatibility with existing health checks~ - No longer a requirement. See [this discussion](https://github.com/mojaloop/project/issues/796#issuecomment-498350828). +- Information about the version of the API, and how long it has been running for +- Information about sub-service (kafka, logging sidecar and mysql) connections + +## Request Format +`/health` + +Uses the newly implemented health check. As discussed [here](https://github.com/mojaloop/project/issues/796#issuecomment-498350828) since there will be no added connection overhead (e.g. pinging a database) as part of implementing the health check, there is no need to complicate things with a simple and detailed version. + +Responses Codes: +- `200` - Success. The API is up and running, and is sucessfully connected to necessary services. +- `502` - Bad Gateway. The API is up and running, but the API cannot connect to necessary service (eg. `kafka`). +- `503` - Service Unavailable. This response is not implemented in this design, but will be the default if the api is not and running + +## Response Format + +| Name | Type | Description | Example | +| --- | --- | --- | --- | +| `status` | `statusEnum` | The status of the service. Options are `OK` and `DOWN`. _See `statusEnum` below_. | `"OK"` | +| `uptime` | `number` | How long (in seconds) the service has been alive for. | `123456` | +| `started` | `string` (ISO formatted date-time) | When the service was started (UTC) | `"2019-05-31T05:09:25.409Z"` | +| `versionNumber` | `string` (semver) | The current version of the service. | `"5.2.5"` | +| `services` | `Array` | A list of services this service depends on, and their connection status | _see below_ | + +### serviceHealth + +| Name | Type | Description | Example | +| --- | --- | --- | --- | +| `name` | `subServiceEnum` | The sub-service name. _See `subServiceEnum` below_. | `"broker"` | +| `status` | `enum` | The status of the service. Options are `OK` and `DOWN` | `"OK"` | + +### subServiceEnum + +The subServiceEnum enum describes a name of the subservice: + +Options: +- `datastore` -> The database for this service (typically a MySQL Database). +- `broker` -> The message broker for this service (typically Kafka). +- `sidecar` -> The logging sidecar sub-service this service attaches to. +- `cache` -> The caching sub-service this services attaches to. + + +### statusEnum + +The status enum represents status of the system or sub-service. + +It has two options: +- `OK` -> The service or sub-service is healthy. +- `DOWN` -> The service or sub-service is unhealthy. + +When a service is `OK`: the API is considered healthy, and all sub-services are also considered healthy. + +If __any__ sub-service is `DOWN`, then the entire health check will fail, and the API will be considered `DOWN`. + +## Defining Sub-Service health + +It is not enough to simply ping a sub-service to know if it is healthy, we want to go one step further. These criteria will change with each sub-service. + +### `datastore` + +For `datastore`, a status of `OK` means: +- An existing connection to the database +- The database is not empty (contains more than 1 table) + + +### `broker` + +For `broker`, a status of `OK` means: +- An existing connection to the kafka broker +- The necessary topics exist. This will change depending on which service the health check is running for. + +For example, for the `central-ledger` service to be considered healthy, the following topics need to be found: +``` +topic-admin-transfer +topic-transfer-prepare +topic-transfer-position +topic-transfer-fulfil +``` + +### `sidecar` + +For `sidecar`, a status of `OK` means: +- An existing connection to the sidecar + + +### `cache` + +For `cache`, a status of `OK` means: +- An existing connection to the cache + + +## Swagger Definition + +>_Note: These will be added to the existing swagger definitions for the following services:_ +> - `ml-api-adapter` +> - `central-ledger` +> - `central-settlement` +> - `central-event-processor` +> - `email-notifier` + +```json +{ + /// . . . + "/health": { + "get": { + "operationId": "getHealth", + "tags": [ + "health" + ], + "responses": { + "default": { + "schema": { + "$ref": "#/definitions/health" + }, + "description": "Successful" + } + } + } + }, + // . . . + "definitions": { + "health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + }, + "uptime": { + "description": "How long (in seconds) the service has been alive for.", + "type": "number", + }, + "started": { + "description": "When the service was started (UTC)", + "type": "string", + "format": "date-time" + }, + "versionNumber": { + "description": "The current version of the service.", + "type": "string", + "example": "5.2.3", + }, + "services": { + "description": "A list of services this service depends on, and their connection status", + "type": "array", + "items": { + "$ref": "#/definitions/serviceHealth" + } + }, + }, + }, + "serviceHealth": { + "type": "object", + "properties": { + "name": { + "description": "The sub-service name.", + "type": "string", + "enum": [ + "datastore", + "broker", + "sidecar", + "cache" + ] + }, + "status": { + "description": "The connection status with the service.", + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + } + } + } + } +} +``` + + +### Example Requests and Responses: + +__Successful Legacy Health Check:__ + +```bash +GET /health HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK" +} +``` + + +__Successful New Health Check:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "OK", + } + ] +} +``` + +__Failed Health Check, but API is up:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +502 BAD GATEWAY +{ + "status": "DOWN", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "DOWN", + } + ] +} +``` + +__Failed Health Check:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +503 SERVICE UNAVAILABLE +``` + + +## Sequence Diagram + +Sequence design diagram for the GET Health + +![seq-get-health-1.0.0.svg](../assets/diagrams/sequence/seq-get-health-1.0.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md b/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md new file mode 100644 index 000000000..7a1c5e933 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md @@ -0,0 +1,7 @@ +# GET Participant Limit Details For All Participants + +Sequence design diagram for the GET Participant Limit Details For All Participants process. + +## Sequence Diagram + +![seq-get-all-participant-limit-1.0.0.svg](../assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md b/docs/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md new file mode 100644 index 000000000..6fda674e3 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md @@ -0,0 +1,7 @@ +# Create initial position and limits for Participant + +Sequence design diagram for the POST (create) Participant Initial Position and Limit process. + +## Sequence Diagram + +![seq-participant-position-limits-1.0.0.svg](../assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md b/docs/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md new file mode 100644 index 000000000..2419df6fe --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md @@ -0,0 +1,7 @@ +# Request Participant Position and Limit Details + +Sequence design diagram for the Request Participant Position and Limit Details process. + +## Sequence Diagram + +![seq-get-participant-position-limit-1.1.0.svg](../assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md b/docs/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md new file mode 100644 index 000000000..99fb44d05 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.1.0-post-participant-limits.md @@ -0,0 +1,7 @@ +# Adjust Participant Limit for a certain Currency + +Sequence design diagram for the POST (manage) Participant Limit Details process. + +## Sequence Diagram + +![seq-manage-participant-limit-1.1.0.svg](../assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md b/docs/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md new file mode 100644 index 000000000..b5c1f6734 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/1.1.5-get-transfer-status.md @@ -0,0 +1,7 @@ +# Request transfer status + +Sequence design diagram for the GET Transfer Status process. + +## Sequence Diagram + +![seq-get-transfer-1.1.5-phase2.svg](../assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md b/docs/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md new file mode 100644 index 000000000..72020a489 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Get Participant Callback Details + +Sequence design diagram for the GET Participant Callback Details process. + +## Sequence Diagram + +![seq-callback-3.1.0.svg](../assets/diagrams/sequence/seq-callback-3.1.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md b/docs/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md new file mode 100644 index 000000000..2b9afae31 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Add Participant Callback Details + +Sequence design diagram for the POST (Add) Participant Callback Details process. + +## Sequence Diagram + +![seq-callback-add-3.1.0.svg](../assets/diagrams/sequence/seq-callback-add-3.1.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md b/docs/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md new file mode 100644 index 000000000..1153ef409 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/4.1.0-get-participant-position-details.md @@ -0,0 +1,7 @@ +# Get Participant Position Details + +Sequence design diagram for the GET Participant Position Details process. + +## Sequence Diagram + +![seq-participants-positions-query-4.1.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md b/docs/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md new file mode 100644 index 000000000..176494d61 --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md @@ -0,0 +1,7 @@ +# Get Position Details for all Participants + +Sequence design diagram for the Get Positions of all Participants process. + +## Sequence Diagram + +![seq-participants-positions-query-all-4.2.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg) diff --git a/docs/technical/technical/central-ledger/admin-operations/README.md b/docs/technical/technical/central-ledger/admin-operations/README.md new file mode 100644 index 000000000..ebdb6ac1d --- /dev/null +++ b/docs/technical/technical/central-ledger/admin-operations/README.md @@ -0,0 +1,3 @@ +# Mojaloop HUB/Switch operations + +Operational processes normally initiated by a HUB/Switch operator. diff --git a/docs/technical/technical/central-ledger/assets/database/README.md b/docs/technical/technical/central-ledger/assets/database/README.md new file mode 100644 index 000000000..77d71d79d --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/database/README.md @@ -0,0 +1,17 @@ +# How to EDIT the central-ledger-schema-DBeaver.erd file + +This is a basic guide on how to successfully view/update the central-ledger-schema-DBeaver.erd file. + +## Prerequisites +* Download and install the DBeaver Community DB Manager +* The Mojaloop Central-Ledger MySQL Database needs to be up and running, and connectable by the DBeaver +* You'll also need a text editor +## Steps to follow +* Create a new db connection in DBeaver under Database Navigator tab for the MySQL instance running. +* Under the Projects tab right click and create a New ER Diagram. +* Give the diagram a name and select central-ledger db in the wizard. + +* Copy the `central-ledger-schema-DBeaver.erd` file from the documentation module to `DBeaverData/workspace/General/Diagrams` in your DBeaver storage location +* Navigate to the newly created erd file using a text editor, search for `data-source id` and copy its value which looks like `mysql5-171ea991174-1218b6e1bf273693`. +* Navigate with a text editor to the `central-ledger-schema-DBeaver.erd` file in the ER Diagrams directory and replace its `data-source id` value with the one copied from the newly created erd file. +* The `central-ledger-schema-DBeaver.erd` should now show the tables as per the `central-ledger-schema.png` \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/docs/technical/technical/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..280962173 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql @@ -0,0 +1,1820 @@ +-- MySQL dump 10.13 Distrib 8.0.18, for macos10.14 (x86_64) +-- +-- Host: localhost Database: central_ledger +-- ------------------------------------------------------ +-- Server version 8.0.13 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `amountType` +-- + +DROP TABLE IF EXISTS `amountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `amountType` ( + `amountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`amountTypeId`), + UNIQUE KEY `amounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `balanceOfPayments` +-- + +DROP TABLE IF EXISTS `balanceOfPayments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `balanceOfPayments` ( + `balanceOfPaymentsId` int(10) unsigned NOT NULL, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible values and meaning are defined in https://www.imf.org/external/np/sta/bopcode/', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`balanceOfPaymentsId`), + UNIQUE KEY `balanceofpayments_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='See https://www.imf.org/external/np/sta/bopcode/guide.htm'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkProcessingState` +-- + +DROP TABLE IF EXISTS `bulkProcessingState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkProcessingState` ( + `bulkProcessingStateId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkProcessingStateId`), + UNIQUE KEY `bulkprocessingstate_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransfer` +-- + +DROP TABLE IF EXISTS `bulkTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransfer` ( + `bulkTransferId` varchar(36) NOT NULL, + `bulkQuoteId` varchar(36) DEFAULT NULL, + `payerParticipantId` int(10) unsigned DEFAULT NULL, + `payeeParticipantId` int(10) unsigned DEFAULT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + KEY `bulktransfer_payerparticipantid_index` (`payerParticipantId`), + KEY `bulktransfer_payeeparticipantid_index` (`payeeParticipantId`), + CONSTRAINT `bulktransfer_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferDuplicateCheck` (`bulktransferid`), + CONSTRAINT `bulktransfer_payeeparticipantid_foreign` FOREIGN KEY (`payeeParticipantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `bulktransfer_payerparticipantid_foreign` FOREIGN KEY (`payerParticipantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferAssociation` +-- + +DROP TABLE IF EXISTS `bulkTransferAssociation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferAssociation` ( + `bulkTransferAssociationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `bulkTransferId` varchar(36) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `bulkProcessingStateId` int(10) unsigned NOT NULL, + `lastProcessedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `errorCode` int(10) unsigned DEFAULT NULL, + `errorDescription` varchar(128) DEFAULT NULL, + PRIMARY KEY (`bulkTransferAssociationId`), + UNIQUE KEY `bulktransferassociation_transferid_bulktransferid_unique` (`transferId`,`bulkTransferId`), + KEY `bulktransferassociation_bulktransferid_foreign` (`bulkTransferId`), + KEY `bulktransferassociation_bulkprocessingstateid_foreign` (`bulkProcessingStateId`), + CONSTRAINT `bulktransferassociation_bulkprocessingstateid_foreign` FOREIGN KEY (`bulkProcessingStateId`) REFERENCES `bulkProcessingState` (`bulkprocessingstateid`), + CONSTRAINT `bulktransferassociation_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferError` +-- + +DROP TABLE IF EXISTS `bulkTransferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferError` ( + `bulkTransferErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferErrorId`), + KEY `bulktransfererror_bulktransferstatechangeid_index` (`bulkTransferStateChangeId`), + CONSTRAINT `bulktransfererror_bulktransferstatechangeid_foreign` FOREIGN KEY (`bulkTransferStateChangeId`) REFERENCES `bulkTransferStateChange` (`bulktransferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferExtension` +-- + +DROP TABLE IF EXISTS `bulkTransferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferExtension` ( + `bulkTransferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferExtensionId`), + KEY `bulktransferextension_bulktransferid_index` (`bulkTransferId`), + CONSTRAINT `bulktransferextension_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilment` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferFulfilment` ( + `bulkTransferId` varchar(36) NOT NULL, + `completedDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilment_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferFulfilmentDuplicateCheck` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferFulfilmentDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilmentduplicatecheck_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferState` +-- + +DROP TABLE IF EXISTS `bulkTransferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferState` ( + `bulkTransferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'bulkTransferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferStateChange` +-- + +DROP TABLE IF EXISTS `bulkTransferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferStateChange` ( + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `bulkTransferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateChangeId`), + KEY `bulktransferstatechange_bulktransferid_index` (`bulkTransferId`), + KEY `bulktransferstatechange_bulktransferstateid_index` (`bulkTransferStateId`), + CONSTRAINT `bulktransferstatechange_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`), + CONSTRAINT `bulktransferstatechange_bulktransferstateid_foreign` FOREIGN KEY (`bulkTransferStateId`) REFERENCES `bulkTransferState` (`bulktransferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `contactType` +-- + +DROP TABLE IF EXISTS `contactType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `contactType` ( + `contactTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`contactTypeId`), + UNIQUE KEY `contacttype_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `scale` int(10) unsigned NOT NULL DEFAULT '4', + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `event` +-- + +DROP TABLE IF EXISTS `event`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `event` ( + `eventId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`eventId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `expiringTransfer` +-- + +DROP TABLE IF EXISTS `expiringTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `expiringTransfer` ( + `expiringTransferId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`expiringTransferId`), + UNIQUE KEY `expiringtransfer_transferid_unique` (`transferId`), + KEY `expiringtransfer_expirationdate_index` (`expirationDate`), + CONSTRAINT `expiringtransfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `geoCode` +-- + +DROP TABLE IF EXISTS `geoCode`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `geoCode` ( + `geoCodeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL COMMENT 'Optionally the GeoCode for the Payer/Payee may have been provided. If the Quote Response has the GeoCode for the Payee, an additional row is added', + `latitude` varchar(50) NOT NULL COMMENT 'Latitude of the initiating Party', + `longitude` varchar(50) NOT NULL COMMENT 'Longitude of the initiating Party', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`geoCodeId`), + KEY `geocode_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `geocode_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ilpPacket` +-- + +DROP TABLE IF EXISTS `ilpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ilpPacket` ( + `transferId` varchar(36) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `ilppacket_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerAccountType` +-- + +DROP TABLE IF EXISTS `ledgerAccountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ledgerAccountType` ( + `ledgerAccountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `isSettleable` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`ledgerAccountTypeId`), + UNIQUE KEY `ledgeraccounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerEntryType` +-- + +DROP TABLE IF EXISTS `ledgerEntryType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ledgerEntryType` ( + `ledgerEntryTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ledgerAccountTypeId` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`ledgerEntryTypeId`), + UNIQUE KEY `ledgerentrytype_name_unique` (`name`), + KEY `ledgerentrytype_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + CONSTRAINT `ledgerentrytype_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participant` +-- + +DROP TABLE IF EXISTS `participant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participant` ( + `participantId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantId`), + UNIQUE KEY `participant_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantContact` +-- + +DROP TABLE IF EXISTS `participantContact`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantContact` ( + `participantContactId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `contactTypeId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `priorityPreference` int(11) NOT NULL DEFAULT '9', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantContactId`), + KEY `participantcontact_participantid_index` (`participantId`), + KEY `participantcontact_contacttypeid_index` (`contactTypeId`), + CONSTRAINT `participantcontact_contacttypeid_foreign` FOREIGN KEY (`contactTypeId`) REFERENCES `contactType` (`contacttypeid`), + CONSTRAINT `participantcontact_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantCurrency` +-- + +DROP TABLE IF EXISTS `participantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantCurrency` ( + `participantCurrencyId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantCurrencyId`), + UNIQUE KEY `participantcurrency_pcl_unique` (`participantId`,`currencyId`,`ledgerAccountTypeId`), + KEY `participantcurrency_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + KEY `participantcurrency_participantid_index` (`participantId`), + KEY `participantcurrency_currencyid_index` (`currencyId`), + CONSTRAINT `participantcurrency_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `participantcurrency_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `participantcurrency_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantEndpoint` +-- + +DROP TABLE IF EXISTS `participantEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantEndpoint` ( + `participantEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `value` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantEndpointId`), + KEY `participantendpoint_participantid_index` (`participantId`), + KEY `participantendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `participantendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `participantendpoint_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimit` +-- + +DROP TABLE IF EXISTS `participantLimit`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantLimit` ( + `participantLimitId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `participantLimitTypeId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL DEFAULT '0.0000', + `thresholdAlarmPercentage` decimal(5,2) NOT NULL DEFAULT '10.00', + `startAfterParticipantPositionChangeId` bigint(20) unsigned DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantLimitId`), + KEY `participantlimit_participantcurrencyid_index` (`participantCurrencyId`), + KEY `participantlimit_participantlimittypeid_index` (`participantLimitTypeId`), + KEY `participantlimit_startafterparticipantpositionchangeid_index` (`startAfterParticipantPositionChangeId`), + CONSTRAINT `participantlimit_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `participantlimit_participantlimittypeid_foreign` FOREIGN KEY (`participantLimitTypeId`) REFERENCES `participantLimitType` (`participantlimittypeid`), + CONSTRAINT `participantlimit_startafterparticipantpositionchangeid_foreign` FOREIGN KEY (`startAfterParticipantPositionChangeId`) REFERENCES `participantPositionChange` (`participantpositionchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimitType` +-- + +DROP TABLE IF EXISTS `participantLimitType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantLimitType` ( + `participantLimitTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantLimitTypeId`), + UNIQUE KEY `participantlimittype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantParty` +-- + +DROP TABLE IF EXISTS `participantParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantParty` ( + `participantPartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `partyId` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`participantPartyId`), + UNIQUE KEY `participantparty_participantid_partyid_unique` (`participantId`,`partyId`), + KEY `participantparty_participantid_index` (`participantId`), + CONSTRAINT `participantparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPosition` +-- + +DROP TABLE IF EXISTS `participantPosition`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantPosition` ( + `participantPositionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionId`), + KEY `participantposition_participantcurrencyid_index` (`participantCurrencyId`), + CONSTRAINT `participantposition_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPositionChange` +-- + +DROP TABLE IF EXISTS `participantPositionChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantPositionChange` ( + `participantPositionChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantPositionId` bigint(20) unsigned NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionChangeId`), + KEY `participantpositionchange_participantpositionid_index` (`participantPositionId`), + KEY `participantpositionchange_transferstatechangeid_index` (`transferStateChangeId`), + CONSTRAINT `participantpositionchange_participantpositionid_foreign` FOREIGN KEY (`participantPositionId`) REFERENCES `participantPosition` (`participantpositionid`), + CONSTRAINT `participantpositionchange_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `party` +-- + +DROP TABLE IF EXISTS `party`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `party` ( + `partyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL, + `firstName` varchar(128) DEFAULT NULL, + `middleName` varchar(128) DEFAULT NULL, + `lastName` varchar(128) DEFAULT NULL, + `dateOfBirth` datetime DEFAULT NULL, + PRIMARY KEY (`partyId`), + KEY `party_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `party_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Optional pers. data provided during Quote Request & Response'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyIdentifierType` +-- + +DROP TABLE IF EXISTS `partyIdentifierType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `partyIdentifierType` ( + `partyIdentifierTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) NOT NULL, + PRIMARY KEY (`partyIdentifierTypeId`), + UNIQUE KEY `partyidentifiertype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyType` +-- + +DROP TABLE IF EXISTS `partyType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `partyType` ( + `partyTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(256) NOT NULL, + PRIMARY KEY (`partyTypeId`), + UNIQUE KEY `partytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quote` +-- + +DROP TABLE IF EXISTS `quote`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quote` ( + `quoteId` varchar(36) NOT NULL, + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `transactionRequestId` varchar(36) DEFAULT NULL COMMENT 'Optional previously-sent transaction request', + `note` text COMMENT 'A memo that will be attached to the transaction', + `expirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `transactionInitiatorId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator', + `transactionInitiatorTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator type', + `transactionScenarioId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction scenario', + `balanceOfPaymentsId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type that contains the elements- balance of payment', + `transactionSubScenarioId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type sub scenario as defined by the local scheme', + `amountTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction type that contains valid elements for - Amount Type', + `amount` decimal(18,4) NOT NULL DEFAULT '0.0000' COMMENT 'The amount that the quote is being requested for. Need to be interpert in accordance with the amount type', + `currencyId` varchar(255) DEFAULT NULL COMMENT 'Trading currency pertaining to the Amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`), + KEY `quote_transactionreferenceid_foreign` (`transactionReferenceId`), + KEY `quote_transactionrequestid_foreign` (`transactionRequestId`), + KEY `quote_transactioninitiatorid_foreign` (`transactionInitiatorId`), + KEY `quote_transactioninitiatortypeid_foreign` (`transactionInitiatorTypeId`), + KEY `quote_transactionscenarioid_foreign` (`transactionScenarioId`), + KEY `quote_balanceofpaymentsid_foreign` (`balanceOfPaymentsId`), + KEY `quote_transactionsubscenarioid_foreign` (`transactionSubScenarioId`), + KEY `quote_amounttypeid_foreign` (`amountTypeId`), + KEY `quote_currencyid_foreign` (`currencyId`), + CONSTRAINT `quote_amounttypeid_foreign` FOREIGN KEY (`amountTypeId`) REFERENCES `amountType` (`amounttypeid`), + CONSTRAINT `quote_balanceofpaymentsid_foreign` FOREIGN KEY (`balanceOfPaymentsId`) REFERENCES `balanceOfPayments` (`balanceofpaymentsid`), + CONSTRAINT `quote_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quote_transactioninitiatorid_foreign` FOREIGN KEY (`transactionInitiatorId`) REFERENCES `transactionInitiator` (`transactioninitiatorid`), + CONSTRAINT `quote_transactioninitiatortypeid_foreign` FOREIGN KEY (`transactionInitiatorTypeId`) REFERENCES `transactionInitiatorType` (`transactioninitiatortypeid`), + CONSTRAINT `quote_transactionreferenceid_foreign` FOREIGN KEY (`transactionReferenceId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionrequestid_foreign` FOREIGN KEY (`transactionRequestId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionscenarioid_foreign` FOREIGN KEY (`transactionScenarioId`) REFERENCES `transactionScenario` (`transactionscenarioid`), + CONSTRAINT `quote_transactionsubscenarioid_foreign` FOREIGN KEY (`transactionSubScenarioId`) REFERENCES `transactionSubScenario` (`transactionsubscenarioid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteDuplicateCheck` ( + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(1024) DEFAULT NULL COMMENT 'hash value received for the quote request', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteError` +-- + +DROP TABLE IF EXISTS `quoteError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteError` ( + `quoteErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned DEFAULT NULL COMMENT 'The response to the intial quote', + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`quoteErrorId`), + KEY `quoteerror_quoteid_foreign` (`quoteId`), + KEY `quoteerror_quoteresponseid_foreign` (`quoteResponseId`), + CONSTRAINT `quoteerror_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteerror_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteExtension` +-- + +DROP TABLE IF EXISTS `quoteExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteExtension` ( + `quoteExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned NOT NULL COMMENT 'The response to the intial quote', + `transactionId` varchar(36) NOT NULL COMMENT 'The transaction reference that is part of the initial quote', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteExtensionId`), + KEY `quoteextension_quoteid_foreign` (`quoteId`), + KEY `quoteextension_quoteresponseid_foreign` (`quoteResponseId`), + KEY `quoteextension_transactionid_foreign` (`transactionId`), + CONSTRAINT `quoteextension_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteextension_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`), + CONSTRAINT `quoteextension_transactionid_foreign` FOREIGN KEY (`transactionId`) REFERENCES `transactionReference` (`transactionreferenceid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteParty` +-- + +DROP TABLE IF EXISTS `quoteParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteParty` ( + `quotePartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `partyTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of party this row relates to; typically PAYER or PAYEE', + `partyIdentifierTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of identifier used to identify this party e.g. MSISDN, IBAN etc...', + `partyIdentifierValue` varchar(128) NOT NULL COMMENT 'The value of the identifier used to identify this party', + `partySubIdOrTypeId` int(10) unsigned DEFAULT NULL COMMENT 'A sub-identifier or sub-type for the Party', + `fspId` varchar(255) DEFAULT NULL COMMENT 'This is the FSP ID as provided in the quote. For the switch between multi-parties it is required', + `participantId` int(10) unsigned DEFAULT NULL COMMENT 'Reference to the resolved FSP ID (if supplied/known). If not an error will be reported', + `merchantClassificationCode` varchar(4) DEFAULT NULL COMMENT 'Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments', + `partyName` varchar(128) DEFAULT NULL COMMENT 'Display name of the Party, could be a real name or a nick name', + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL COMMENT 'The role this Party is playing in the transaction', + `ledgerEntryTypeId` int(10) unsigned NOT NULL COMMENT 'The type of financial entry this Party is presenting', + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL COMMENT 'Trading currency pertaining to the party amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quotePartyId`), + KEY `quoteparty_quoteid_foreign` (`quoteId`), + KEY `quoteparty_partytypeid_foreign` (`partyTypeId`), + KEY `quoteparty_partyidentifiertypeid_foreign` (`partyIdentifierTypeId`), + KEY `quoteparty_partysubidortypeid_foreign` (`partySubIdOrTypeId`), + KEY `quoteparty_participantid_foreign` (`participantId`), + KEY `quoteparty_transferparticipantroletypeid_foreign` (`transferParticipantRoleTypeId`), + KEY `quoteparty_ledgerentrytypeid_foreign` (`ledgerEntryTypeId`), + KEY `quoteparty_currencyid_foreign` (`currencyId`), + CONSTRAINT `quoteparty_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteparty_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `quoteparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `quoteparty_partyidentifiertypeid_foreign` FOREIGN KEY (`partyIdentifierTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partysubidortypeid_foreign` FOREIGN KEY (`partySubIdOrTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partytypeid_foreign` FOREIGN KEY (`partyTypeId`) REFERENCES `partyType` (`partytypeid`), + CONSTRAINT `quoteparty_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteparty_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quotePartyView` +-- + +DROP TABLE IF EXISTS `quotePartyView`; +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quotePartyView` AS SELECT + 1 AS `quoteId`, + 1 AS `quotePartyId`, + 1 AS `partyType`, + 1 AS `identifierType`, + 1 AS `partyIdentifierValue`, + 1 AS `partySubIdOrType`, + 1 AS `fspId`, + 1 AS `merchantClassificationCode`, + 1 AS `partyName`, + 1 AS `firstName`, + 1 AS `lastName`, + 1 AS `middleName`, + 1 AS `dateOfBirth`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `quoteResponse` +-- + +DROP TABLE IF EXISTS `quoteResponse`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponse` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `transferAmountCurrencyId` varchar(3) NOT NULL COMMENT 'CurrencyId of the transfer amount', + `transferAmount` decimal(18,4) NOT NULL COMMENT 'The amount of money that the Payer FSP should transfer to the Payee FSP', + `payeeReceiveAmountCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee receive amount', + `payeeReceiveAmount` decimal(18,4) DEFAULT NULL COMMENT 'The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees', + `payeeFspFeeCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp fee amount', + `payeeFspFeeAmount` decimal(18,4) DEFAULT NULL COMMENT 'Payee FSP’s part of the transaction fee', + `payeeFspCommissionCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp commission amount', + `payeeFspCommissionAmount` decimal(18,4) DEFAULT NULL COMMENT 'Transaction commission from the Payee FSP', + `ilpCondition` varchar(256) NOT NULL, + `responseExpirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `isValid` tinyint(1) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponse_quoteid_foreign` (`quoteId`), + KEY `quoteresponse_transferamountcurrencyid_foreign` (`transferAmountCurrencyId`), + KEY `quoteresponse_payeereceiveamountcurrencyid_foreign` (`payeeReceiveAmountCurrencyId`), + KEY `quoteresponse_payeefspcommissioncurrencyid_foreign` (`payeeFspCommissionCurrencyId`), + CONSTRAINT `quoteresponse_payeefspcommissioncurrencyid_foreign` FOREIGN KEY (`payeeFspCommissionCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_payeereceiveamountcurrencyid_foreign` FOREIGN KEY (`payeeReceiveAmountCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponse_transferamountcurrencyid_foreign` FOREIGN KEY (`transferAmountCurrencyId`) REFERENCES `currency` (`currencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='This table is the primary store for quote responses'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteResponseDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponseDuplicateCheck` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'The response to the intial quote', + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(255) DEFAULT NULL COMMENT 'hash value received for the quote response', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponseduplicatecheck_quoteid_foreign` (`quoteId`), + CONSTRAINT `quoteresponseduplicatecheck_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponseduplicatecheck_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseIlpPacket` +-- + +DROP TABLE IF EXISTS `quoteResponseIlpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponseIlpPacket` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `value` text NOT NULL COMMENT 'ilpPacket returned from Payee in response to a quote request', + PRIMARY KEY (`quoteResponseId`), + CONSTRAINT `quoteresponseilppacket_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quoteResponseView` +-- + +DROP TABLE IF EXISTS `quoteResponseView`; +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quoteResponseView` AS SELECT + 1 AS `quoteResponseId`, + 1 AS `quoteId`, + 1 AS `transferAmountCurrencyId`, + 1 AS `transferAmount`, + 1 AS `payeeReceiveAmountCurrencyId`, + 1 AS `payeeReceiveAmount`, + 1 AS `payeeFspFeeCurrencyId`, + 1 AS `payeeFspFeeAmount`, + 1 AS `payeeFspCommissionCurrencyId`, + 1 AS `payeeFspCommissionAmount`, + 1 AS `ilpCondition`, + 1 AS `responseExpirationDate`, + 1 AS `isValid`, + 1 AS `createdDate`, + 1 AS `ilpPacket`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Temporary view structure for view `quoteView` +-- + +DROP TABLE IF EXISTS `quoteView`; +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quoteView` AS SELECT + 1 AS `quoteId`, + 1 AS `transactionReferenceId`, + 1 AS `transactionRequestId`, + 1 AS `note`, + 1 AS `expirationDate`, + 1 AS `transactionInitiator`, + 1 AS `transactionInitiatorType`, + 1 AS `transactionScenario`, + 1 AS `balanceOfPaymentsId`, + 1 AS `transactionSubScenario`, + 1 AS `amountType`, + 1 AS `amount`, + 1 AS `currency`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `segment` +-- + +DROP TABLE IF EXISTS `segment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `segment` ( + `segmentId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `segmentType` varchar(50) NOT NULL, + `enumeration` int(11) NOT NULL DEFAULT '0', + `tableName` varchar(50) NOT NULL, + `value` bigint(20) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`segmentId`), + KEY `segment_keys_index` (`segmentType`,`enumeration`,`tableName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlement` +-- + +DROP TABLE IF EXISTS `settlement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlement` ( + `settlementId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementModelId` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementId`), + KEY `settlement_currentstatechangeid_foreign` (`currentStateChangeId`), + KEY `settlement_settlementmodelid_foreign` (`settlementModelId`), + CONSTRAINT `settlement_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementStateChange` (`settlementstatechangeid`), + CONSTRAINT `settlement_settlementmodelid_foreign` FOREIGN KEY (`settlementModelId`) REFERENCES `settlementModel` (`settlementmodelid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementContentAggregation` +-- + +DROP TABLE IF EXISTS `settlementContentAggregation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementContentAggregation` ( + `settlementContentAggregationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowContentId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,2) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateId` varchar(50) NOT NULL, + `settlementId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementContentAggregationId`), + KEY `settlementcontentaggregation_settlementwindowcontentid_index` (`settlementWindowContentId`), + KEY `settlementcontentaggregation_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementcontentaggregation_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementcontentaggregation_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + KEY `settlementcontentaggregation_currentstateid_index` (`currentStateId`), + KEY `settlementcontentaggregation_settlementid_index` (`settlementId`), + CONSTRAINT `sca_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`), + CONSTRAINT `settlementcontentaggregation_currentstateid_foreign` FOREIGN KEY (`currentStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`), + CONSTRAINT `settlementcontentaggregation_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementcontentaggregation_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementcontentaggregation_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementcontentaggregation_settlementwindowcontentid_foreign` FOREIGN KEY (`settlementWindowContentId`) REFERENCES `settlementWindowContent` (`settlementwindowcontentid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementDelay` +-- + +DROP TABLE IF EXISTS `settlementDelay`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementDelay` ( + `settlementDelayId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementDelayId`), + UNIQUE KEY `settlementdelay_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementGranularity` +-- + +DROP TABLE IF EXISTS `settlementGranularity`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementGranularity` ( + `settlementGranularityId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementGranularityId`), + UNIQUE KEY `settlementgranularity_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementInterchange` +-- + +DROP TABLE IF EXISTS `settlementInterchange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementInterchange` ( + `settlementInterchangeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementInterchangeId`), + UNIQUE KEY `settlementinterchange_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementModel` +-- + +DROP TABLE IF EXISTS `settlementModel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementModel` ( + `settlementModelId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `settlementGranularityId` int(10) unsigned NOT NULL, + `settlementInterchangeId` int(10) unsigned NOT NULL, + `settlementDelayId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) DEFAULT NULL, + `requireLiquidityCheck` tinyint(1) NOT NULL DEFAULT '1', + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `autoPositionReset` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`settlementModelId`), + UNIQUE KEY `settlementmodel_name_unique` (`name`), + KEY `settlementmodel_settlementgranularityid_index` (`settlementGranularityId`), + KEY `settlementmodel_settlementinterchangeid_index` (`settlementInterchangeId`), + KEY `settlementmodel_settlementdelayid_index` (`settlementDelayId`), + KEY `settlementmodel_currencyid_index` (`currencyId`), + KEY `settlementmodel_ledgeraccounttypeid_index` (`ledgerAccountTypeId`), + CONSTRAINT `settlementmodel_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `settlementmodel_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `settlementmodel_settlementdelayid_foreign` FOREIGN KEY (`settlementDelayId`) REFERENCES `settlementDelay` (`settlementdelayid`), + CONSTRAINT `settlementmodel_settlementgranularityid_foreign` FOREIGN KEY (`settlementGranularityId`) REFERENCES `settlementGranularity` (`settlementgranularityid`), + CONSTRAINT `settlementmodel_settlementinterchangeid_foreign` FOREIGN KEY (`settlementInterchangeId`) REFERENCES `settlementInterchange` (`settlementinterchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrency` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementParticipantCurrency` ( + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `netAmount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementTransferId` varchar(36) DEFAULT NULL, + PRIMARY KEY (`settlementParticipantCurrencyId`), + KEY `settlementparticipantcurrency_settlementid_index` (`settlementId`), + KEY `settlementparticipantcurrency_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementparticipantcurrency_settlementtransferid_index` (`settlementTransferId`), + KEY `spc_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementparticipantcurrency_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementparticipantcurrency_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `spc_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementParticipantCurrencyStateChange` (`settlementparticipantcurrencystatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrencyStateChange` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrencyStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementParticipantCurrencyStateChange` ( + `settlementParticipantCurrencyStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `externalReference` varchar(50) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementParticipantCurrencyStateChangeId`), + KEY `spcsc_settlementparticipantcurrencyid_index` (`settlementParticipantCurrencyId`), + KEY `spcsc_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `spcsc_settlementparticipantcurrencyid_foreign` FOREIGN KEY (`settlementParticipantCurrencyId`) REFERENCES `settlementParticipantCurrency` (`settlementparticipantcurrencyid`), + CONSTRAINT `spcsc_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementSettlementWindow` +-- + +DROP TABLE IF EXISTS `settlementSettlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementSettlementWindow` ( + `settlementSettlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementSettlementWindowId`), + UNIQUE KEY `settlementsettlementwindow_unique` (`settlementId`,`settlementWindowId`), + KEY `settlementsettlementwindow_settlementid_index` (`settlementId`), + KEY `settlementsettlementwindow_settlementwindowid_index` (`settlementWindowId`), + CONSTRAINT `settlementsettlementwindow_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementsettlementwindow_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementState` +-- + +DROP TABLE IF EXISTS `settlementState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementState` ( + `settlementStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementStateChange` +-- + +DROP TABLE IF EXISTS `settlementStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementStateChange` ( + `settlementStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateChangeId`), + KEY `settlementstatechange_settlementid_index` (`settlementId`), + KEY `settlementstatechange_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `settlementstatechange_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementstatechange_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementTransferParticipant` +-- + +DROP TABLE IF EXISTS `settlementTransferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementTransferParticipant` ( + `settlementTransferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementTransferParticipantId`), + KEY `settlementtransferparticipant_settlementid_index` (`settlementId`), + KEY `settlementtransferparticipant_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementtransferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `stp_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementtransferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `settlementtransferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementtransferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementtransferparticipant_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementtransferparticipant_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `stp_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindow` +-- + +DROP TABLE IF EXISTS `settlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindow` ( + `settlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowId`), + KEY `settlementwindow_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementwindow_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowStateChange` (`settlementwindowstatechangeid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowContent` +-- + +DROP TABLE IF EXISTS `settlementWindowContent`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowContent` ( + `settlementWindowContentId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowContentId`), + KEY `settlementwindowcontent_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowcontent_ledgeraccounttypeid_index` (`ledgerAccountTypeId`), + KEY `settlementwindowcontent_currencyid_index` (`currencyId`), + KEY `settlementwindowcontent_currentstatechangeid_index` (`currentStateChangeId`), + KEY `settlementwindowcontent_settlementid_index` (`settlementId`), + CONSTRAINT `settlementwindowcontent_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `settlementwindowcontent_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowContentStateChange` (`settlementwindowcontentstatechangeid`), + CONSTRAINT `settlementwindowcontent_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `settlementwindowcontent_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementwindowcontent_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowContentStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowContentStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowContentStateChange` ( + `settlementWindowContentStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowContentId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowContentStateChangeId`), + KEY `swcsc_settlementwindowcontentid_index` (`settlementWindowContentId`), + KEY `swcsc_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `swc_settlementwindowcontentid_foreign` FOREIGN KEY (`settlementWindowContentId`) REFERENCES `settlementWindowContent` (`settlementwindowcontentid`), + CONSTRAINT `sws1_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowState` +-- + +DROP TABLE IF EXISTS `settlementWindowState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowState` ( + `settlementWindowStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowStateChange` ( + `settlementWindowStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateChangeId`), + KEY `settlementwindowstatechange_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `settlementwindowstatechange_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `settlementwindowstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `token` +-- + +DROP TABLE IF EXISTS `token`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `token` ( + `tokenId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `expiration` bigint(20) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`tokenId`), + UNIQUE KEY `token_value_unique` (`value`), + KEY `token_participantid_index` (`participantId`), + CONSTRAINT `token_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiator` +-- + +DROP TABLE IF EXISTS `transactionInitiator`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionInitiator` ( + `transactionInitiatorId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorId`), + UNIQUE KEY `transactioninitiator_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiatorType` +-- + +DROP TABLE IF EXISTS `transactionInitiatorType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionInitiatorType` ( + `transactionInitiatorTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorTypeId`), + UNIQUE KEY `transactioninitiatortype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionReference` +-- + +DROP TABLE IF EXISTS `transactionReference`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionReference` ( + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `quoteId` varchar(36) DEFAULT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System row creation timestamp', + PRIMARY KEY (`transactionReferenceId`), + KEY `transactionreference_quoteid_index` (`quoteId`), + CONSTRAINT `transactionreference_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quoteDuplicateCheck` (`quoteid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionScenario` +-- + +DROP TABLE IF EXISTS `transactionScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionScenario` ( + `transactionScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionScenarioId`), + UNIQUE KEY `transactionscenario_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionSubScenario` +-- + +DROP TABLE IF EXISTS `transactionSubScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionSubScenario` ( + `transactionSubScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible sub-scenario, defined locally within the scheme', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionSubScenarioId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transfer` +-- + +DROP TABLE IF EXISTS `transfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transfer` ( + `transferId` varchar(36) NOT NULL, + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ilpCondition` varchar(256) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfer_currencyid_index` (`currencyId`), + CONSTRAINT `transfer_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `transfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferError` +-- + +DROP TABLE IF EXISTS `transferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferError` ( + `transferId` varchar(36) NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfererror_transferstatechangeid_foreign` (`transferStateChangeId`), + CONSTRAINT `transfererror_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferErrorDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferErrorDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferErrorDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transfererrorduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferExtension` +-- + +DROP TABLE IF EXISTS `transferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferExtension` ( + `transferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `isError` tinyint(1) NOT NULL DEFAULT '0', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferExtensionId`), + KEY `transferextension_transferid_foreign` (`transferId`), + CONSTRAINT `transferextension_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilment` +-- + +DROP TABLE IF EXISTS `transferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferFulfilment` ( + `transferId` varchar(36) NOT NULL, + `ilpFulfilment` varchar(256) DEFAULT NULL, + `completedDate` datetime NOT NULL, + `isValid` tinyint(1) DEFAULT NULL, + `settlementWindowId` bigint(20) unsigned DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transferfulfilment_settlementwindowid_foreign` (`settlementWindowId`), + CONSTRAINT `transferfulfilment_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `transferfulfilment_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferFulfilmentDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferFulfilmentDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transferfulfilmentduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipant` +-- + +DROP TABLE IF EXISTS `transferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipant` ( + `transferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`transferParticipantId`), + KEY `transferparticipant_transferid_index` (`transferId`), + KEY `transferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `transferparticipant_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `transferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + KEY `transferparticipant_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `transferparticipant_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `transferParticipantStateChange` (`transferparticipantstatechangeid`), + CONSTRAINT `transferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `transferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `transferparticipant_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferparticipant_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantRoleType` +-- + +DROP TABLE IF EXISTS `transferParticipantRoleType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipantRoleType` ( + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantRoleTypeId`), + UNIQUE KEY `transferparticipantroletype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantStateChange` +-- + +DROP TABLE IF EXISTS `transferParticipantStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipantStateChange` ( + `transferParticipantStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferParticipantId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantStateChangeId`), + KEY `transferparticipantstatechange_transferparticipantid_index` (`transferParticipantId`), + KEY `transferparticipantstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `transferparticipantstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`), + CONSTRAINT `transferparticipantstatechange_transferparticipantid_foreign` FOREIGN KEY (`transferParticipantId`) REFERENCES `transferParticipant` (`transferparticipantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferRules` +-- + +DROP TABLE IF EXISTS `transferRules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferRules` ( + `transferRulesId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `rule` text NOT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferRulesId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferState` +-- + +DROP TABLE IF EXISTS `transferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferState` ( + `transferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'transferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferStateChange` +-- + +DROP TABLE IF EXISTS `transferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferStateChange` ( + `transferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `transferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateChangeId`), + KEY `transferstatechange_transferid_index` (`transferId`), + KEY `transferstatechange_transferstateid_index` (`transferStateId`), + CONSTRAINT `transferstatechange_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferstatechange_transferstateid_foreign` FOREIGN KEY (`transferStateId`) REFERENCES `transferState` (`transferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferTimeout` +-- + +DROP TABLE IF EXISTS `transferTimeout`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferTimeout` ( + `transferTimeoutId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferTimeoutId`), + UNIQUE KEY `transfertimeout_transferid_unique` (`transferId`), + CONSTRAINT `transfertimeout_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Final view structure for view `quotePartyView` +-- + +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quotePartyView` AS select `qp`.`quoteId` AS `quoteId`,`qp`.`quotePartyId` AS `quotePartyId`,`pt`.`name` AS `partyType`,`pit`.`name` AS `identifierType`,`qp`.`partyIdentifierValue` AS `partyIdentifierValue`,`spit`.`name` AS `partySubIdOrType`,`qp`.`fspId` AS `fspId`,`qp`.`merchantClassificationCode` AS `merchantClassificationCode`,`qp`.`partyName` AS `partyName`,`p`.`firstName` AS `firstName`,`p`.`lastName` AS `lastName`,`p`.`middleName` AS `middleName`,`p`.`dateOfBirth` AS `dateOfBirth`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from (((((`quoteParty` `qp` join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) join `partyIdentifierType` `pit` on((`pit`.`partyIdentifierTypeId` = `qp`.`partyIdentifierTypeId`))) left join `party` `p` on((`p`.`quotePartyId` = `qp`.`quotePartyId`))) left join `partyIdentifierType` `spit` on((`spit`.`partyIdentifierTypeId` = `qp`.`partySubIdOrTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteResponseView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteResponseView` AS select `qr`.`quoteResponseId` AS `quoteResponseId`,`qr`.`quoteId` AS `quoteId`,`qr`.`transferAmountCurrencyId` AS `transferAmountCurrencyId`,`qr`.`transferAmount` AS `transferAmount`,`qr`.`payeeReceiveAmountCurrencyId` AS `payeeReceiveAmountCurrencyId`,`qr`.`payeeReceiveAmount` AS `payeeReceiveAmount`,`qr`.`payeeFspFeeCurrencyId` AS `payeeFspFeeCurrencyId`,`qr`.`payeeFspFeeAmount` AS `payeeFspFeeAmount`,`qr`.`payeeFspCommissionCurrencyId` AS `payeeFspCommissionCurrencyId`,`qr`.`payeeFspCommissionAmount` AS `payeeFspCommissionAmount`,`qr`.`ilpCondition` AS `ilpCondition`,`qr`.`responseExpirationDate` AS `responseExpirationDate`,`qr`.`isValid` AS `isValid`,`qr`.`createdDate` AS `createdDate`,`qrilp`.`value` AS `ilpPacket`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from ((((`quoteResponse` `qr` join `quoteResponseIlpPacket` `qrilp` on((`qrilp`.`quoteResponseId` = `qr`.`quoteResponseId`))) join `quoteParty` `qp` on((`qp`.`quoteId` = `qr`.`quoteId`))) join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) where (`pt`.`name` = 'PAYEE') */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteView` AS select `q`.`quoteId` AS `quoteId`,`q`.`transactionReferenceId` AS `transactionReferenceId`,`q`.`transactionRequestId` AS `transactionRequestId`,`q`.`note` AS `note`,`q`.`expirationDate` AS `expirationDate`,`ti`.`name` AS `transactionInitiator`,`tit`.`name` AS `transactionInitiatorType`,`ts`.`name` AS `transactionScenario`,`q`.`balanceOfPaymentsId` AS `balanceOfPaymentsId`,`tss`.`name` AS `transactionSubScenario`,`amt`.`name` AS `amountType`,`q`.`amount` AS `amount`,`q`.`currencyId` AS `currency` from (((((`quote` `q` join `transactionInitiator` `ti` on((`ti`.`transactionInitiatorId` = `q`.`transactionInitiatorId`))) join `transactionInitiatorType` `tit` on((`tit`.`transactionInitiatorTypeId` = `q`.`transactionInitiatorTypeId`))) join `transactionScenario` `ts` on((`ts`.`transactionScenarioId` = `q`.`transactionScenarioId`))) join `amountType` `amt` on((`amt`.`amountTypeId` = `q`.`amountTypeId`))) left join `transactionSubScenario` `tss` on((`tss`.`transactionSubScenarioId` = `q`.`transactionSubScenarioId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-02-20 22:51:43 diff --git a/docs/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd b/docs/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd new file mode 100644 index 000000000..303fa1534 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/database/central-ledger-schema-DBeaver.erd @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/database/central-ledger-schema.png b/docs/technical/technical/central-ledger/assets/database/central-ledger-schema.png new file mode 100644 index 000000000..62b4a1a1e Binary files /dev/null and b/docs/technical/technical/central-ledger/assets/database/central-ledger-schema.png differ diff --git a/docs/technical/technical/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg new file mode 100644 index 000000000..d91178975 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Ledger
    Ledger
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Central Services
    [Not supported by viewer]
    positions
    positions
    Account-Lookup-Service
    [Not supported by viewer]
    Pathfinder
    Pathfinder
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Settlements
    Settlements
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg new file mode 100644 index 000000000..73c49765f --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    [Not supported by viewer]
    1.4 Increment
    Position (fsp1)

    [Not supported by viewer]
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    [Not supported by viewer]
    2.4 Fulfil
    Success
    [Not supported by viewer]
    <alt> 2.4 
    Fulfil Reject

    [Not supported by viewer]
    Fulfil
    Reject
    [Not supported by viewer]
    <alt> 2.5 Decrement
    Position (fsp1)

    [Not supported by viewer]
    <alt>1.6 Reject Notification
    (Not enough position)

    [Not supported by viewer]
    Central - Services
    <font style="font-size: 18px">Central - Services</font>
    3.0 Reject
    [Not supported by viewer]
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    [Not supported by viewer]
    1.0 Transfer 
    Request

    [Not supported by viewer]
    3.1 Decrement
    Position (fsp1)

    [Not supported by viewer]
    1.6 Prepare Notification
    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    Transfer
    API
    [Not supported by viewer]
    Notification
    Event Handler
    [Not supported by viewer]
    fsp prepare
    fsp prepare
    1.3 Prepare Consume
    [Not supported by viewer]
    notifications
    notifications
    FSP1
    (Payer)

    [Not supported by viewer]
    FSP2
    (Payee)
    [Not supported by viewer]
    1.1
    Prepare Request
    [Not supported by viewer]
    1.2 Accpeted
    (202)
    [Not supported by viewer]
    Transfer
    API
    [Not supported by viewer]
    2.0 Fulfil 
    Success / 
    Reject

    [Not supported by viewer]
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    [Not supported by viewer]
    2.5 Decrement
    Position (fsp2)

    [Not supported by viewer]
    2.1 Fulfil 
    Success / Reject

    [Not supported by viewer]
    2.2 OK
    (200)
    [Not supported by viewer]
    2.3 Fulfil
    Success /
    Reject
    Consume
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    Transfer Timeout
    Handler
    [Not supported by viewer]
    <alt> 1.4 Prepare Failure
    [Not supported by viewer]
    <alt> 2.4 Fulfil Failure
    [Not supported by viewer]
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    [Not supported by viewer]
    1.7 Prepare Notify /
    2.8 Fulfil Notify /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    [Not supported by viewer]
    position
    position<br>
    \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg new file mode 100644 index 000000000..02658b83d --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (optional) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg new file mode 100644 index 000000000..e9a1460c8 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (if transfer reserved) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg new file mode 100644 index 000000000..108afd9d1 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg @@ -0,0 +1,228 @@ + + 3.1.0 Get Participant Callback Details + + + 3.1.0 Get Participant Callback Details + + ML API Adapter Service + + Central Services + + + + + + + + + + + + + + + + + + + ML-API-ADAPTER + + + ML-API-ADAPTER + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + Get Callback Details + + + 1 + Request to get callback details - GET - /participants/{name}/endpoints?type={typeValue} + + + 2 + Fetch Callback details for Participant + + + 3 + Fetch Participant + Error code: + 3200 + + + 4 + Fetch Participant + + participant + + + 5 + Retrieved Participant + + + 6 + Return Participant + + + + + 7 + Validate DFSP + + + alt + [Validate participant (success)] + + + + + 8 + check if "type" parameter is sent + + + alt + [Check if "type" parameter is sent (Sent)] + + + 9 + Fetch Callback details for Participant and type + Error code: + 3000 + + + 10 + Fetch Callback details for Participant and type + + + Condition: + isActive = 1 + [endpointTypeId = <type>] + + participantEndpoint + + + 11 + Retrieved Callback details for Participant and type + + + 12 + Return Callback details for Participant and type + + + Message: + { + endpoints: {type: <type>, value: <value>} + } + + + 13 + Return Callback details for Participant + + + 14 + Return Callback details for Participant + + [Check if "type" parameter is sent (Not Sent)] + + + 15 + Fetch Callback details for Participant + Error code: + 3000 + + + 16 + Fetch Callback details for Participant + + + Condition: + isActive = 1 + + participantEndpoint + + + 17 + Retrieved Callback details for Participant + + + 18 + Return Callback details for Participant + + + Message: + { + endpoints: [ + {type: <type>, value: <value>}, + {type: <type>, value: <value>} + ] + } + + + 19 + Return Callback details for Participant + + + 20 + Return Callback details for Participant + + [Validate participant (failure)/ Error] + + + Validation failure/ Error! + + + Message: + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 21 + Return + Error code: + 3000, 3200 + + + 22 + Return + Error code: + 3000, 3200 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg new file mode 100644 index 000000000..e214ffafe --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg @@ -0,0 +1,215 @@ + + 3.1.0 Add Participant Callback Details + + + 3.1.0 Add Participant Callback Details + + Central Services + + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + Add Callback Details + + + 1 + Request to add callback details - POST - /paticipants/{name}/endpoints + + + Message: + { + payload: { + endpoint: { + type: <typeValue>, + value: <endpointValue> + } + } + } + + + 2 + Add Callback details for Participant + + + 3 + Fetch Participant + Error code: + 3200 + + + 4 + Fetch Participant + + participant + + + 5 + Retrieved Participant + + + 6 + Return Participant + + + + + 7 + Validate DFSP + + + alt + [Validate participant (success)] + + + 8 + Add Callback details for Participant + Error code: + 2003/ + Msg: + Service unavailable +   + Error code: + 2001/ + Msg: + Internal Server Error + + + 9 + Persist Participant Endpoint + + participantEndpoint + + + If (endpoint exists && isActive = 1) + oldEndpoint.isActive = 0 + insert endpoint + Else + insert endpoint + End +      + + + 10 + Return status + + + + + 11 + Validate status + + + alt + [Validate status (success)] + + + 12 + Return Status Code 201 + + + 13 + Return Status Code 201 + + [Validate status (failure) / Error] + + + Error! + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 14 + Return + Error code + + + 15 + Return + Error code + + [Validate participant (failure)] + + + Validation failure! + + + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + + + 16 + Return + Error code: + 3200 + + + 17 + Return + Error code: + 3200 + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml new file mode 100644 index 000000000..c24ae484b --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml @@ -0,0 +1,207 @@ +/' + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Valentin Genev + -------------- + '/ + + +@startuml +' declate title +title 2.1.0. DFSP2 sends a Fulfil Success Transfer request v1.1 + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Settlement Model\nHandler" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group DFSP2 sends a request for notification after tranfer is being committed in the Switch + DFSP2 <-> DFSP2: Retrieve fulfilment string generated during\nthe quoting process or regenerate it using\n**Local secret** and **ILP Packet** as inputs + alt Send back notification reserve request + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "transferState": "RESERVED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + else Send back commit request + + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "completedTimestamp": , + "transferState": "COMMITTED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + end + DFSP2 ->> MLAPI: PUT - /transfers/ + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reserve || commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg 2.1.1-v1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produce message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consume message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Settlement Model Handler Consume (Success)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'reserve' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg new file mode 100644 index 000000000..63ae6110e --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg @@ -0,0 +1,342 @@ + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request v1.1 + + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request v1.1 + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + topic-fulfil + + + topic-fulfil + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic- + settlement-model + + + topic- + settlement-model + Settlement Model + Handler + + + Settlement Model + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + + + + + + + DFSP2 sends a request for notification after tranfer is being committed in the Switch + + + + + + 1 + Retrieve fulfilment string generated during + the quoting process or regenerate it using + Local secret + and + ILP Packet + as inputs + + + alt + [Send back notification reserve request] + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "fulfilment": <IlpFulfilment>, + "transferState": "RESERVED" + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + [Send back commit request] + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "COMMITTED" + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Validate incoming token and originator matching Payee + Error codes: + 3000-3002, 3100-3107 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reserve || commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Fulfil event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + ref + Fulfil Handler Consume (Success) { + + 2.1.1-v1.1 + + } +   + + + 9 + Produce message + + + 10 + Produce message + + + 11 + Consume message + + + ref + Settlement Model Handler Consume (Success) +   + + + 12 + Consume message + + + ref + Position Handler Consume (Success) +   + + + 13 + Produce message + + + 14 + Consume message + + + opt + [action == 'commit'] + + + ref + Send notification to Participant (Payer) +   + + + 15 + Send callback notification + + + 16 + Consume message + + + opt + [action == 'reserve'] + + + ref + Send notification to Participant (Payee) +   + + + 17 + Send callback notification + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg new file mode 100644 index 000000000..abe0d547b --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg @@ -0,0 +1,307 @@ + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request + + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + topic-fulfil + + + topic-fulfil + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic- + settlement-model + + + topic- + settlement-model + Settlement Model + Handler + + + Settlement Model + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position Handler + + + Position Handler + + + + + topic- + notification + + + topic- + notification + + + + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + + 1 + Retrieve fulfilment string generated during + the quoting process or regenerate it using + Local secret + and + ILP Packet + as inputs + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "COMMITTED", + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Validate incoming token and originator matching Payee + Error codes: + 3000-3002, 3100-3107 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Fulfil event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + ref + Fulfil Handler Consume (Success) { + + 2.1.1 + + } +   + + + 9 + Produce message + + + 10 + Produce message + + + 11 + Consume message + + + ref + Settlement Model Handler Consume (Success) +   + + + 12 + Consume message + + + ref + Position Handler Consume (Success) +   + + + 13 + Produce message + + + 14 + Consume message + + + opt + [action == 'commit'] + + + ref + Send notification to Participant (Payer) +   + + + 15 + Send callback notification + + + 16 + Consume message + + + opt + [action == 'commit'] + + + ref + Send notification to Participant (Payee) +   + + + 17 + Send callback notification + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml new file mode 100644 index 000000000..9f2523d6d --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml @@ -0,0 +1,273 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.1. Fulfil Handler Consume (Success) v1.1 +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event\nHandler" as FULF_HANDLER +collections "topic-event" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +entity "Position DAO" as POS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_SETMODEL + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Success) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && action IN ['commit', 'reserve']\nError codes: 2001 + end + end + group Persist Event Information + ||| + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + ||| + end + + group Validate Duplicate Check + ||| + FULF_HANDLER -> DB: Request Duplicate Check + ref over FULF_HANDLER, DB: Request Duplicate Check\n + DB --> FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of FULF_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + group Validate and persist Transfer Fulfilment + FULF_HANDLER -> POS_DAO: Request information for the validate checks\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return transfer + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + FULF_HANDLER -> FULF_HANDLER: Validate expirationDate\nError code: 3303 + + opt Transfer.ilpCondition validate successful + group Request current Settlement Window + FULF_HANDLER -> POS_DAO: Request to retrieve current/latest transfer settlement window\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return settlementWindowId to be appended during transferFulfilment insert\n**TODO**: During settlement design make sure transfers in 'RECEIVED-FULFIL'\nstate are updated to the next settlement window + deactivate POS_DAO + end + end + + group Persist fulfilment + FULF_HANDLER -> POS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Return success + deactivate POS_DAO + end + + alt Transfer.ilpCondition validate successful + group Persist Transfer State (with transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: , + responseTo: , + type: setmodel, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_SETMODEL: Route & Publish settlement model event + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful + group Persist Transfer State (with transferState='ABORTED') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg new file mode 100644 index 000000000..ad91cb1e3 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg @@ -0,0 +1,439 @@ + + 2.1.1. Fulfil Handler Consume (Success) v1.1 + + + 2.1.1. Fulfil Handler Consume (Success) v1.1 + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + topic-fulfil + Fulfil Event + Handler + + + Fulfil Event + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + + + topic- + settlement-model + + + topic- + settlement-model + + + topic- + notification + + + topic- + notification + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Success) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && action IN ['commit', 'reserve'] + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate Duplicate Check + + + 4 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 5 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + getTransfer callback +   + + + 7 + Produce message + + + + Ignore - resend in progress + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == FALSE] + + + Validate and persist Transfer Fulfilment + + + 8 + Request information for the validate checks + Error code: + 2003 + + + 9 + Fetch from database + + transfer + + + 10 +   + + + 11 + Return transfer + + + + + 12 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + + + 13 + Validate expirationDate + Error code: + 3303 + + + opt + [Transfer.ilpCondition validate successful] + + + Request current Settlement Window + + + 14 + Request to retrieve current/latest transfer settlement window + Error code: + 2003 + + + 15 + Fetch settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Return settlementWindowId to be appended during transferFulfilment insert + TODO + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + state are updated to the next settlement window + + + Persist fulfilment + + + 18 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 19 + Persist to database + + transferFulfilment + transferExtension + + + 20 + Return success + + + alt + [Transfer.ilpCondition validate successful] + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + 21 + Request to persist transfer state + Error code: + 2003 + + + 22 + Persist transfer state + + transferStateChange + + + 23 + Return success + + + Message: + { + id: <id>, + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: setmodel, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish settlement model event + + + Message: + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: commit || reserve, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 25 + Route & Publish Position event for Payee + + [Validate Fulfil Transfer not successful] + + + Persist Transfer State (with transferState='ABORTED') + + + 26 + Request to persist transfer state + Error code: + 2003 + + + 27 + Persist transfer state + + transferStateChange + + + 28 + Return success + + + Message: + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 29 + Route & Publish Position event for Payer + + [Consume Batch Messages] + + + To be delivered by future story + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg new file mode 100644 index 000000000..aa745728d --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg @@ -0,0 +1,439 @@ + + 2.1.1. Fulfil Handler Consume (Success) + + + 2.1.1. Fulfil Handler Consume (Success) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + topic-fulfil + Fulfil Event + Handler + + + Fulfil Event + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic-event + + + topic-event + + + topic- + settlement-model + + + topic- + settlement-model + + + topic- + notification + + + topic- + notification + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Success) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && action == 'commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate Duplicate Check + + + 4 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 5 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 6 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + getTransfer callback +   + + + 7 + Produce message + + + + Ignore - resend in progress + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == FALSE] + + + Validate and persist Transfer Fulfilment + + + 8 + Request information for the validate checks + Error code: + 2003 + + + 9 + Fetch from database + + transfer + + + 10 +   + + + 11 + Return transfer + + + + + 12 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + + + 13 + Validate expirationDate + Error code: + 3303 + + + opt + [Transfer.ilpCondition validate successful] + + + Request current Settlement Window + + + 14 + Request to retrieve current/latest transfer settlement window + Error code: + 2003 + + + 15 + Fetch settlementWindowId + + settlementWindow + + + 16 +   + + + 17 + Return settlementWindowId to be appended during transferFulfilment insert + TODO + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + state are updated to the next settlement window + + + Persist fulfilment + + + 18 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 19 + Persist to database + + transferFulfilment + transferExtension + + + 20 + Return success + + + alt + [Transfer.ilpCondition validate successful] + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + 21 + Request to persist transfer state + Error code: + 2003 + + + 22 + Persist transfer state + + transferStateChange + + + 23 + Return success + + + Message: + { + id: <id>, + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: setmodel, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish settlement model event + + + Message: + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 25 + Route & Publish Position event for Payee + + [Validate Fulfil Transfer not successful] + + + Persist Transfer State (with transferState='ABORTED') + + + 26 + Request to persist transfer state + Error code: + 2003 + + + 27 + Persist transfer state + + transferStateChange + + + 28 + Return success + + + Message: + { + id: <id>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 29 + Route & Publish Position event for Payer + + [Consume Batch Messages] + + + To be delivered by future story + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg new file mode 100644 index 000000000..1e1d53096 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg @@ -0,0 +1,127 @@ + + 1.0.0 Get Participant Limit Details For All Participants + + + 1.0.0 Get Participant Limit Details For All Participants + + Central Services + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant Facade + + + Participant Facade + + + Central Store + + + Central Store + + + + + + + + + + Get Limits for all Participants + + + 1 + Request to get Limits - GET - /participants/limits?type={typeValue}&currency={currencyType} + + + 2 + Fetch Limits for all Participants + + + 3 + Fetch Limits for all participants with currency and type + Error code: + 3000 + + + 4 + Fetch Limits for currencyId and type(if passed) + + + Condition: + participantCurrency.participantCurrencyId = participant.participantCurrencyId + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + [ + participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimit.participantCurrencyId = <currencyId> + participantLimitType.name = <type> + ] + + participant + participantCurrency + participantLimit + participantLimitType + + + 5 + Retrieved Participant Limits for currencyId and type + + + 6 + Return Limits for all participants + + + Message: + [ + { + name: <fsp> + currency: <currencyId>, + limit: {type: <type>, value: <value>} + }, + { + name: <fsp> + currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 7 + Return Limits for all participants + Error code: + 3000 + + + 8 + Return Limits for all participants + Error code: + 3000 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg new file mode 100644 index 000000000..053316d82 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg @@ -0,0 +1,174 @@ + + 1.0.0 Get Health Check + + + 1.0.0 Get Health Check + + Central Services + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Metadata Handler + + + Metadata Handler + + + Central Store + + + Central Store + + + + + Kafka Store + + + Kafka Store + + + Logging Sidecar + + + Logging Sidecar + + + + + + + + + Get Detailed Health Check + + + 1 + Request to getHealth - GET /health?detailed=true + + + 2 + Fetch health status for all sub services + + + + + 3 + Fetch Service Metadata + + + - versionNumber + - uptime + - time service started + + + 4 + Check connection status + + + 5 + Report connection status + + + 6 + Check connection status + + + 7 + Report connection status + + + 8 + Check connection status + + + 9 + Report connection status + + + alt + [Validate Status (success)] + + + 10 + Return status response + + + Example Message: + 200 Success + { + "status": "UP", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "UP", + "latency": 10 + } + ] + } + + + 11 + Return + HTTP Status: + 200 + + + alt + [Validate Status (service failure)] + + + 12 + Return status response + + + Example Message: + 502 Bad Gateway + { + "status": "DOWN", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "DOWN", + "latency": 1111111 + } + ] + } + + + 13 + Return + HTTP Status: + 502 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg new file mode 100644 index 000000000..acbd9b098 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg @@ -0,0 +1,306 @@ + + 1.1.0 Request Participant Position and Limit Details + + + 1.1.0 Request Participant Position and Limit Details + + Central Services + + + + + + + + + + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant Facade + + + Participant Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + Get Callback Details + + + 1 + Request to get Limits - GET - /participants/{name}/limits?type={typeValue}&currency={currencyValue} + + + 2 + Fetch Limits for Participant + + + + + 3 + check if "currency" parameter is sent + + + alt + [Check if "currency" parameter is sent (Sent)] + + + 4 + Fetch Participant/currency id + Error code: + 3200 + + + 5 + Fetch Participant/currency id + + participant + participantCurrency + + + 6 + Retrieved Participant + + + 7 + Return Participant/currency id + + + + + 8 + Validate DFSP + + + alt + [Validate participant (success)] + + + 9 + Fetch Participant Limits for currency and type + Error code: + 3000 + + + 10 + Fetch Participant Limit for currencyId and type(if passed) + + + Condition: + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = <currencyId> + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = <type> + ] + + participantLimit + participantLimitType + + + 11 + Retrieved Participant Limits for currencyId and type + + + 12 + Return Participant Limits for currencyId and type + + + Message: + [ + { currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 13 + Return Participant Limits + + + 14 + Return Participant Limits + + [Validate participant (failure)/ Error] + + + Validation failure/ Error! + + + Message: + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 15 + Return + Error code: + 3000, 3200 + + + 16 + Return + Error code: + 3000, 3200 + + [Check if "currency" parameter is sent (Not Sent)] + + + 17 + Fetch Participant + Error code: + 3200 + + + 18 + Fetch Participant + + participant + + + 19 + Retrieved Participant + + + 20 + Return Participant + + + + + 21 + Validate DFSP + + + alt + [Validate participant (success)] + + + 22 + Fetch Participant Limits for all currencies and type + Error code: + 3000 + + + 23 + Fetch Participant Limit for all currencies and type(if passed) + + + Condition: + participantCurrency.participantId = <participantId> + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + participantLimit.isActive = 1 + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = <type> + ] + + participantCurrency + participantLimit + participantLimitType + + + 24 + Retrieved Participant Limits for all currencies and type + + + 25 + Return Participant Limits for all currencies and type + + + Message: + [ + { currency: <currencyId>, + limit: {type: <type>, value: <value>} + } + ] + + + 26 + Return Participant Limits + + + 27 + Return Participant Limits + + [Validate participant (failure)/ Error] + + + Validation failure/ Error! + + + Message: + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <ErrorMessage>, + } + } + + + 28 + Return + Error code: + 3000, 3200 + + + 29 + Return + Error code: + 3000, 3200 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg new file mode 100644 index 000000000..801226ab8 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg @@ -0,0 +1,208 @@ + + 1.1.5. Request transfer status (getTransferStatusById) - Phase2 version + + + 1.1.5. Request transfer status (getTransferStatusById) - Phase2 version + + Financial Service Provider + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Event-Topic + + + Event-Topic + Transfer-DAO + + + Transfer-DAO + + + Central Store + + + Central Store + + + + + + + + + + + Request transfer status + + + 1 + Callback transfer status request URL - GET - /transfers/{ID} + + + Persist Event Information + + + 2 + Request transfer information - GET - /transfers/{ID} + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + 4 + Return success + + + 5 + Return success + + + 6 + Respond HTTP - 200 (OK) + + + 7 + Request details for Transfer - GET - /transfers/{ID} + Error code: + 2003 + + + 8 + Request transfer status + Error code: + 2003 + + + 9 + Fetch transfer status + + SELECT transferId, transferStateId + FROM + transferStateChange + WHERE transferId = {ID} + ORDER BY transferStateChangeId desc limit 1 + + + 10 + Return transfer status + + + 11 + Return transfer status + Error codes: + 3202, 3203 + + + alt + [Is there a transfer with the given ID recorded in the system?] + + + alt + [Yes AND transferState is COMMITTED + This implies that a succesful transfer with the given ID is recorded in the system] + + + { + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "transferState": "COMMITTED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + + + 12 + callback PUT on /transfers/{ID} + + [transferState in [RECEIVED, RESERVED, ABORTED]] + + + { + "transferState": "RECEIVED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + + + 13 + callback PUT on /transfers/{ID} + + + Log ERROR event + + [A transfer with the given ID is not present in the System or this is an invalid request] + + + { + "errorInformation": { + "errorCode": <integer>, + "errorDescription": "Client error description" + } + } + + + 14 + callback PUT on /transfers/{ID}/error + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg new file mode 100644 index 000000000..7ed0d712a --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg @@ -0,0 +1,243 @@ + + 1.1.0 Manage Participant Limits + + + 1.1.0 Manage Participant Limits + + Central Services + + + + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + Manage Net Debit Cap + + + 1 + Request to adjust Participant Limit for a certain Currency - POST - /participants/{name}/limits + + + Message: + { + payload: { + currency: <string>, + limit: { + type: <string>, + value: <Id> + } + } + } + + + 2 + Adjust Limit for Participant + + + 3 + Fetch Participant/currency + Error code: + 3200 + + + 4 + Fetch Participant/currency + + participant + participantCurrency + + + 5 + Retrieved Participant/currency + + + 6 + Return Participant/currency + + + + + 7 + Validate DFSP + + + alt + [Validate participant (success)] + + + 8 + (for ParticipantCurrency) Fetch ParticipantLimit + Error code: + 3200 + + + 9 + Fetch ParticipantLimit + + participantLimit + + + 10 + Retrieved ParticipantLimit + + + 11 + Return ParticipantLimit + + + + + 12 + Validate ParticipantLimit + + + alt + [Validate participantLimit (success)] + + + DB TRANSACTION IMPLEMENTATION - Lock on ParticipantLimit table with UPDATE + + + If (record exists && isActive = 1) + oldIsActive.isActive = 0 + insert Record + Else + insert Record + End +   + + + 13 + (for ParticipantLimit) Insert new ParticipantLimit + Error code: + 3200 + + + 14 + Insert ParticipantLimit + + participantLimit + + + 15 + Inserted ParticipantLimit + + + 16 + Return ParticipantLimit + + [Validate participantLimit (failure)] + + + Validation failure! + + + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "ParticipantLimit Not Found", + } + } + + + 17 + Return new Limit values and status 200 + + + Message: + { + "currency": "EUR", + "limit": { + "participantLimitId": <number>, + "participantLimitTypeId": <number>, + "type": <string>, + "value": <string>, + "isActive": 1 + } + } + + + 18 + Return new Limit values and status 200 + + [Validate participant (failure)] + + + Validation failure! + + + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + + + 19 + Return + Error code: + 3200 + + + 20 + Return + Error code: + 3200 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg new file mode 100644 index 000000000..2b4da73f4 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg @@ -0,0 +1,283 @@ + + 1.0.0 Create initial position and limits for Participant + + + 1.0.0 Create initial position and limits for Participant + + Central Services + + + + + + + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant FACADE + + + Participant FACADE + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Create initial position and limits + + + 1 + Request to Create initial position and limits - POST - /paticipants/{name}/initialPositionAndLimits + + + Message: + { + currency: <currencyId>, + limit: { + type: <limitType>, + value: <limitValue> + }, + initialPosition: <positionValue> + } + + + 2 + Create initial position and limits for Participant + + + 3 + Fetch Participant/ Currency Id + Error code: + 3200 + + + 4 + Fetch Participant/Currency Id + + participant + participantCurrency + + + 5 + Retrieved Participant/Currency Id + + + 6 + Return Participant/Currency Id + + + + + 7 + Validate DFSP + + + alt + [Validate participant (success)] + + + 8 + Fetch limit for participantCurrencyId + + + 9 + Fetch limit for participantCurrencyId + + participantLimit + + + 10 + Retrieved participant limit + + + 11 + Return participant limit + + + 12 + Fetch position for participantCurrencyId + + + 13 + Fetch position for participantCurrencyId + + participantPosition + + + 14 + Retrieved participant position + + + 15 + Return participant position + + + + + 16 + Participant position or limit exists check + + + alt + [position or limit does not exist (success)] + + + 17 + create initial position and limits for Participantt + Error code: + 2003/ + Msg: + Service unavailable +   + Error code: + 2001/ + Msg: + Internal Server Error + + + 18 + Persist Participant limits/position + + participantPosition + participantLimit + + + 19 + Return status + + + alt + [Details persisted successfully] + + + 20 + Return Status Code 201 + + + 21 + Return Status Code 201 + + [Details not persisted/Error] + + + Error! + + + Message: + { + "errorInformation": { + "errorCode": <Error Code>, + "errorDescription": <Msg>, + } + } + + + 22 + Return + Error code + + + 23 + Return + Error code + + [position or limit exists (failure)] + + + Error! + + + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Participant Limit or Initial Position already set", + } + } + + + 24 + Return + Error code: + 3200 + + + 25 + Return + Error code: + 3200 + + [Validate participant (failure)] + + + Validation failure! + + + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + + + 26 + Return + Error code: + 3200 + + + 27 + Return + Error code: + 3200 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg new file mode 100644 index 000000000..effa45552 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg @@ -0,0 +1,240 @@ + + 4.1.0 Get Participant Position Details + + + 4.1.0 Get Participant Position Details + + HUB Operator + + Central Service + + + + + + + + + + + + + + + + + + + HUB OPERATOR + + + HUB OPERATOR + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant DAO + + + Participant DAO + + + Position Facade + + + Position Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + + Get Position Details + + + 1 + Request to get positions - GET - /participants/{name}/positions?currency={currencyId} + + + 2 + Fetch Positions for Participant + + + 3 + Fetch Participant + Error code: + 2003,3201 + + + 4 + Fetch Participant + + participant + + + 5 + Retrieved Participant + + + 6 + Return Participant + + + + + 7 + Validate DFSP + Error code: + 3201 + + + alt + [Validate participant (success)] + + + + + 8 + currency parameter passed ? + + + alt + [currency parameter passed] + + + 9 + Fetch Participant position for a currency id + Error code: + 2003 + + + 10 + Fetch Participant position for a currency id + + participantCurrency + participantPosition + + + 11 + Retrieved Participant position for a currency id + + + 12 + Return Positions for Participant + + + Message: + { + { + currency: <currencyId>, + value: <positionValue>, + updatedTime: <timeStamp1> + } + } + + + 13 + Return Participant position for a currency id + + + 14 + Return Participant position for a currency id + + [currency parameter not passed] + + + 15 + Fetch Participant Positions for all currencies + Error code: + 2003 + + + 16 + Fetch Participant Positions for all currencies + + participantCurrency + participantPosition + + + 17 + Retrieved Participant Positions for all currencies + + + 18 + Return Participant Positions for all currencies + + + Message: + { + [ + { + currency: <currencyId1>, + value: <positionValue1>, + updatedTime: <timeStamp1> + }, + { + currency: <currencyId2>, + value: <positionValue2>, + updatedTime: <timeStamp2> + } + ] + } + + + 19 + Return Participant Positions for all currencies + + + 20 + Return Participant Positions for all currencies + + [Validate participant (failure)] + + + Validation failure! + + + Message: + { + "errorInformation": { + "errorCode": 3201, + "errorDescription": "FSP id does not exist or not found", + } + } + + + 21 + Return + Error code: + 3201 + + + 22 + Return + Error code: + 3201 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg new file mode 100644 index 000000000..fc37d05c6 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg @@ -0,0 +1,153 @@ + + 4.2.0 Get Positions of all Participants + + + 4.2.0 Get Positions of all Participants + + ML API Adapter Service + + Central Service + + + + + + + + + + + + ML-API-ADAPTER + + + ML-API-ADAPTER + + + Central Service API + + + Central Service API + + + Participant Handler + + + Participant Handler + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + Get Position Details + + + 1 + Request to get positions - GET - /participants/positions + + + 2 + Fetch Positions for all Participants + + + 3 + Fetch Positions for all active Participants + Error code: + 2003,3200 + + + 4 + Fetch Positions for: + all active Participants + with all active Currencies for each Participant + + participant + participantPosition + participantCurrency + + + 5 + Retrieved Positions for Participants + + + 6 + Return Positions for Participants + + + Message: + { + snapshotAt: <timestamp0>, + positions: + [ + { + participantId: <dfsp1>, + participantPositions: + [ + { + currentPosition: { + currency: <currency1>, + value: <amount1>, + reservedValue: <amount2>, + lastUpdated: <timeStamp1> + } + }, + { + currentPosition: { + currency: <currency2>, + value: <amount3>, + reservedValue: <amount4>, + lastUpdated: <timeStamp2> + } + } + ] + }, + { + participantId: <dfsp2>, + participantPositions: + [ + { + currentPosition: { + currency: <currency1>, + value: <amount1>, + reservedValue: <amount2>, + lastUpdated: <timeStamp1> + } + }, + { + currentPosition: { + currency: <currency2>, + value: <amount3>, + reservedValue: <amount4>, + lastUpdated: <timeStamp2> + } + } + ] + } + ] + } + + + 7 + Return Positions for Participants + + + 8 + Return Positions for Participants + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml new file mode 100644 index 000000000..04d4356c9 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Position Handler Consume (single message) v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + alt Consume Prepare message for Payer + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'prepare'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Prepare Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Fulfil message for Payee + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action IN ['commit', 'reserve']\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Fulfil Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Abort message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' &&\naction IN ['timeout-reserved', 'reject', 'fail']\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Abort Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg new file mode 100644 index 000000000..d1915c8b0 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg @@ -0,0 +1,188 @@ + + 1.3.0. Position Handler Consume (single message) v1.1 + + + 1.3.0. Position Handler Consume (single message) v1.1 + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Handler + + + Position Handler + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + + + + + + + Position Handler Consume + + + alt + [Consume Prepare message for Payer] + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'position' && action == 'prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Prepare Position Handler Consume +   + + + 4 + Produce message + + [Consume Fulfil message for Payee] + + + 5 + Consume Position event message for Payee + + + break + + + Validate Event + + + + + + 6 + Validate event - Rule: type == 'position' && action IN ['commit', 'reserve'] + Error codes: + 2001 + + + Persist Event Information + + + 7 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Fulfil Position Handler Consume +   + + + 8 + Produce message + + [Consume Abort message] + + + 9 + Consume Position event message + + + break + + + Validate Event + + + + + + 10 + Validate event - Rule: type == 'position' && + action IN ['timeout-reserved', 'reject', 'fail'] + Error codes: + 2001 + + + Persist Event Information + + + 11 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Abort Position Handler Consume +   + + + 12 + Produce message + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg new file mode 100644 index 000000000..295295eda --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg @@ -0,0 +1,188 @@ + + 1.3.0. Position Handler Consume (single message) + + + 1.3.0. Position Handler Consume (single message) + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Handler + + + Position Handler + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + + + + + + + Position Handler Consume + + + alt + [Consume Prepare message for Payer] + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'position' && action == 'prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Prepare Position Handler Consume +   + + + 4 + Produce message + + [Consume Fulfil message for Payee] + + + 5 + Consume Position event message for Payee + + + break + + + Validate Event + + + + + + 6 + Validate event - Rule: type == 'position' && action == 'commit' + Error codes: + 2001 + + + Persist Event Information + + + 7 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Fulfil Position Handler Consume +   + + + 8 + Produce message + + [Consume Abort message] + + + 9 + Consume Position event message + + + break + + + Validate Event + + + + + + 10 + Validate event - Rule: type == 'position' && + action IN ['timeout-reserved', 'reject', 'fail'] + Error codes: + 2001 + + + Persist Event Information + + + 11 + Publish event information + + + ref + Event Handler Consume +   + + + ref + Abort Position Handler Consume +   + + + 12 + Produce message + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml new file mode 100644 index 000000000..2e420c3b3 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml @@ -0,0 +1,283 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.1. Prepare Position Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER + +entity "Position\nManagement\nFacade" as POS_MGMT +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_MGMT + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Prepare Position Handler Consume + POS_HANDLER -> POS_MGMT: Request transfers to be processed + activate POS_MGMT + POS_MGMT -> POS_MGMT: Check 1st transfer to select the Participant and Currency + group DB TRANSACTION + ' DB Trans: This is where 1st DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT -> POS_MGMT: Loop through batch and build list of transferIds and calculate sumTransfersInBatch,\nchecking all in Batch are for the correct Paricipant and Currency\nError code: 2001, 3100 + POS_MGMT -> DB: Retrieve current state of all transfers in array from DB with select whereIn\n(FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_MGMT: Return current state of all selected transfers from DB + deactivate DB + POS_MGMT <-> POS_MGMT: Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nError code: 2001 against failing transfers\nBatch is not rejected as a whole. + + note right of POS_MGMT #lightgray + List of transfers used during processing + **reservedTransfers** is list of transfers to be processed in the batch + **abortedTransfers** is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + **processedTransfers** is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + Scalar intermidate values used in the algorithm + **transferAmount** = payload.amount.amount + **sumTransfersInBatch** = SUM amount against each Transfer in batch + **currentPosition** = participantPosition.value + **reservedPosition** = participantPosition.{original}reservedValue + **effectivePosition** = currentPosition + reservedPosition + **heldPosition** = effectivePosition + sumTransfersInBatch + **availablePosition** = //if settlement model delay is IMMEDIATE then:// settlementBalance + participantLimit(NetDebitCap) - effectivePosition, //otherwise:// participantLimit(NetDebitCap) - effectivePosition + **sumReserved** = SUM of transfers that have met rule criteria and processed + end note + note over POS_MGMT,DB + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + end note + POS_MGMT -> DB: Select effectivePosition FOR UPDATE from DB for Payer + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_MGMT: Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + deactivate DB + POS_MGMT -> POS_MGMT: Increment reservedValue to heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) + POS_MGMT -> DB: Persist reservedValue + activate DB + hnote over DB #lightyellow + UPDATE **participantPosition** + SET reservedValue += sumTransfersInBatch + end note + deactivate DB + ' DB Trans: This is where 1st DB Transaction would end in 2 DB transacation future model for horizontal scaling + + + POS_MGMT -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + FROM **participantLimit** + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + end note + DB --> POS_MGMT: Return position limits + deactivate DB + POS_MGMT <-> POS_MGMT: **availablePosition** = //if settlement model delay is IMMEDIATE then://\n settlementBalance + participantLimit(NetDebitCap) - effectivePosition\n //otherwise://\n participantLimit(NetDebitCap) - effectivePosition\n(same as = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + note over POS_MGMT,DB + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + end note + POS_MGMT <-> POS_MGMT: Validate availablePosition for each tranfser (see algorithm below)\nError code: 4001 + note right of POS_MGMT #lightgray + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far **(NEED TO UPDATE IN CODE)** + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(NEED TO UPDATE IN CODE)** // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + end note + note over POS_MGMT,DB + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + end note + POS_MGMT->POS_MGMT: Assess any limit thresholds on the final position\nadding to alarm list if triggered + + ' DB Trans: This is where 2nd DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT->DB: Persist latest position **value** and **reservedValue** to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + end note + activate DB + deactivate DB + + POS_MGMT -> DB: Bulk persist transferStateChange for all processedTransfers + hnote over DB #lightyellow + batch INSERT **transferStateChange** + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch + + end note + activate DB + deactivate DB + + POS_MGMT->POS_MGMT: Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + note right of POS_MGMT #lightgray + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + end note + POS_MGMT -> DB: Bulk persist the participant position change for all processedTransfers + hnote over DB #lightyellow + batch INSERT **participantPositionChange** + end note + activate DB + deactivate DB + ' DB Trans: This is where 2nd DB Transaction would end in 2 DB transacation future model for horizontal scaling + end + POS_MGMT --> POS_HANDLER: Return a map of transferIds and their transferStateChanges + deactivate POS_MGMT + alt Calculate & Validate Latest Position Prepare (success) + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else Calculate & Validate Latest Position Prepare (failure) + note right of POS_HANDLER #red: Validation failure! + + group Persist Transfer State (with transferState='ABORTED' on position check fail) + POS_HANDLER -> POS_DAO: Request to persist transfer\nError code: 2003 + activate POS_DAO + note right of POS_HANDLER #lightgray + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + end note + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg new file mode 100644 index 000000000..83f1209b8 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg @@ -0,0 +1,410 @@ + + 1.3.1. Prepare Position Handler Consume + + + 1.3.1. Prepare Position Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + Notification-Topic + + + Notification-Topic + Position + Management + Facade + + + Position + Management + Facade + + + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + Prepare Position Handler Consume + + + 1 + Request transfers to be processed + + + + + 2 + Check 1st transfer to select the Participant and Currency + + + DB TRANSACTION + + + + + 3 + Loop through batch and build list of transferIds and calculate sumTransfersInBatch, + checking all in Batch are for the correct Paricipant and Currency + Error code: + 2001, 3100 + + + 4 + Retrieve current state of all transfers in array from DB with select whereIn + (FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + + transferStateChange + transferParticipant + + + 5 + Return current state of all selected transfers from DB + + + + + + 6 + Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + Error code: + 2001 + against failing transfers + Batch is not rejected as a whole. + + + List of transfers used during processing + reservedTransfers + is list of transfers to be processed in the batch + abortedTransfers + is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + processedTransfers + is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation +   + Scalar intermidate values used in the algorithm + transferAmount + = payload.amount.amount + sumTransfersInBatch + = SUM amount against each Transfer in batch + currentPosition + = participantPosition.value + reservedPosition + = participantPosition.{original}reservedValue + effectivePosition + = currentPosition + reservedPosition + heldPosition + = effectivePosition + sumTransfersInBatch + availablePosition + = + if settlement model delay is IMMEDIATE then: + settlementBalance + participantLimit(NetDebitCap) - effectivePosition, + otherwise: + participantLimit(NetDebitCap) - effectivePosition + sumReserved + = SUM of transfers that have met rule criteria and processed + + + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + + + 7 + Select effectivePosition FOR UPDATE from DB for Payer + + participantPosition + + + 8 + Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + + + + + 9 + Increment reservedValue to heldPosition + (reservedValue = reservedPosition + sumTransfersInBatch) + + + 10 + Persist reservedValue + + UPDATE + participantPosition + SET reservedValue += sumTransfersInBatch + + + 11 + Request position limits for Payer Participant + + FROM + participantLimit + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + + + 12 + Return position limits + + + + + + 13 + availablePosition + = + if settlement model delay is IMMEDIATE then: + settlementBalance + participantLimit(NetDebitCap) - effectivePosition +   + otherwise: + participantLimit(NetDebitCap) - effectivePosition + (same as = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + + + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + + + + + + 14 + Validate availablePosition for each tranfser (see algorithm below) + Error code: + 4001 + + + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far + (NEED TO UPDATE IN CODE) + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + (NEED TO UPDATE IN CODE) + // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + + + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + + + + + 15 + Assess any limit thresholds on the final position + adding to alarm list if triggered + + + 16 + Persist latest position + value + and + reservedValue + to DB for Payer + + UPDATE + participantPosition + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + + + 17 + Bulk persist transferStateChange for all processedTransfers + + batch INSERT + transferStateChange + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch +   + + + + + 18 + Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + + + 19 + Bulk persist the participant position change for all processedTransfers + + batch INSERT + participantPositionChange + + + 20 + Return a map of transferIds and their transferStateChanges + + + alt + [Calculate & Validate Latest Position Prepare (success)] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 21 + Publish Notification event + Error code: + 2003 + + [Calculate & Validate Latest Position Prepare (failure)] + + + Validation failure! + + + Persist Transfer State (with transferState='ABORTED' on position check fail) + + + 22 + Request to persist transfer + Error code: + 2003 + + + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 23 + Persist transfer state + + transferStateChange + + + 24 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 25 + Publish Notification (failure) event for Payer + Error code: + 2003 + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml new file mode 100644 index 000000000..fab0fbf38 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml @@ -0,0 +1,141 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.2. Fulfil Position Handler Consume v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +collections "Notifications-Topic" as TOPIC_NOTIFICATIONS +entity "Position Facade" as POS_FACADE +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Fulfil Position Handler Consume + POS_HANDLER -> POS_DAO: Request current state of transfer from DB \nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferState is 'RECEIVED-FULFIL')\nError code: 2001 + group Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + POS_HANDLER -> POS_FACADE: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION + activate POS_FACADE + POS_FACADE -> DB: Select participantPosition.value FOR UPDATE from DB for Payee + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Return participantPosition.value from DB for Payee + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persist latestPosition to DB for Payee + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persist transfer state and participant position change + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Return success + deactivate POS_FACADE + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Transfer event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg new file mode 100644 index 000000000..f7fc9c3cf --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg @@ -0,0 +1,186 @@ + + 1.3.2. Fulfil Position Handler Consume v1.1 + + + 1.3.2. Fulfil Position Handler Consume v1.1 + + Central Service + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + Notifications-Topic + + + Notifications-Topic + Position DAO + + + Position DAO + + + Position Facade + + + Position Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + Fulfil Position Handler Consume + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state (transferState is 'RECEIVED-FULFIL') + Error code: + 2001 + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + 6 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION + + + 7 + Select participantPosition.value FOR UPDATE from DB for Payee + + participantPosition + + + 8 + Return participantPosition.value from DB for Payee + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persist latestPosition to DB for Payee + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persist transfer state and participant position change + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: commit || reserve, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publish Transfer event + Error code: + 2003 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg new file mode 100644 index 000000000..d95894bd6 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg @@ -0,0 +1,186 @@ + + 1.3.2. Fulfil Position Handler Consume + + + 1.3.2. Fulfil Position Handler Consume + + Central Service + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + Notifications-Topic + + + Notifications-Topic + Position DAO + + + Position DAO + + + Position Facade + + + Position Facade + + + Central Store + + + Central Store + + + + + + + + + + + + + Fulfil Position Handler Consume + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state (transferState is 'RECEIVED-FULFIL') + Error code: + 2001 + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + 6 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION + + + 7 + Select participantPosition.value FOR UPDATE from DB for Payee + + participantPosition + + + 8 + Return participantPosition.value from DB for Payee + + + + + + 9 + latestPosition + = participantPosition.value - payload.amount.amount + + + 10 + Persist latestPosition to DB for Payee + + UPDATE + participantPosition + SET value = latestPosition + + + 11 + Persist transfer state and participant position change + + INSERT + transferStateChange + transferStateId = 'COMMITTED' +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 12 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: commit, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 13 + Publish Transfer event + Error code: + 2003 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg new file mode 100644 index 000000000..82d02319c --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg @@ -0,0 +1,457 @@ + + 1.3.3. Abort Position Handler Consume + + + 1.3.3. Abort Position Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Position Handler + + + Position Handler + + + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + Abort Position Handler Consume + + + opt + [type == 'position' && action == 'timeout-reserved'] + + + 1 + Request current state of transfer from DB + Error code: + 2003 + + + 2 + Retrieve current state of transfer from DB + + transferStateChange + transferParticipant + + + 3 + Return current state of transfer from DB + + + 4 + Return current state of transfer from DB + + + + + + 5 + Validate current state (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 6 + transferStateId + = 'EXPIRED_RESERVED' + + + 7 + Request to persist latest position and state to DB + Error code: + 2003 + + + DB TRANSACTION IMPLEMENTATION + + + 8 + Select participantPosition.value FOR UPDATE for payerCurrencyId + + participantPosition + + + 9 + Return participantPosition + + + + + + 10 + latestPosition + = participantPosition - payload.amount.amount + + + 11 + Persist latestPosition to DB for Payer + + UPDATE + participantPosition + SET value = latestPosition + + + 12 + Persist participant position change and state change + + INSERT + transferStateChange +   + VALUES (transferStateId) +   + INSERT + participantPositionChange + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + + + 13 + Return success + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Publish Notification event + Error code: + 2003 + + + opt + [type == 'position' && (action IN ['reject', 'abort'])] + + + 15 + Request current state of transfer from DB + Error code: + 2003 + + + 16 + Retrieve current state of transfer from DB + + transferStateChange + + + 17 + Return current state of transfer from DB + + + 18 + Return current state of transfer from DB + + + + + + 19 + Validate current state (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + Error code: + 2001 + + + Persist Position change and Transfer state + + + + + 20 + transferStateId + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + 21 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 22 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 23 + Return success + + + alt + [action == 'reject'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + + [action == 'abort'] + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <payload.errorInformation.errorCode || 5000> + description: <payload.errorInformation.errorDescription> + } + } + } + } + + + 24 + Publish Notification event + Error code: + 2003 + + + opt + [type == 'position' && action == 'fail' (Unable to currently trigger this scenario)] + + + 25 + Request current state of transfer from DB + Error code: + 2003 + + + 26 + Retrieve current state of transfer from DB + + transferStateChange + + + 27 + Return current state of transfer from DB + + + 28 + Return current state of transfer from DB + + + + + + 29 + Validate current state (transferStateChange.transferStateId == 'FAILED') + + + Persist Position change and Transfer state + + + + + 30 + transferStateId + = 'FAILED' + + + 31 + Request to persist latest position and state to DB + Error code: + 2003 + + + Refer to + DB TRANSACTION IMPLEMENTATION + above + + + 32 + Persist to database + + participantPosition + transferStateChange + participantPositionChange + + + 33 + Return success + + + Message: { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: abort, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 34 + Publish Notification event + Error code: + 2003 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg new file mode 100644 index 000000000..fb6c0955f --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg @@ -0,0 +1,238 @@ + + 1.1.0. DFSP1 sends a Prepare Transfer request to DFSP2 + + + 1.1.0. DFSP1 sends a Prepare Transfer request to DFSP2 + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Prepare Event Handler + + + Prepare Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP1 sends a Prepare Transfer request to DFSP2 + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "transferId": <uuid>, + "payeeFsp": dfsp2, + "payerFsp": dfsp1, + "amount": { + "currency": "AED", + "amount": "string" + }, + "ilpPacket": "string", + "condition": "string", + "expiration": "string", + "extensionList": { + "extension": [ + { + "key": "string", + "value": "string" + } + ] + } + } + + + + 1 + POST - /transfers + + + + + 2 + Validate incoming token and originator matching Payer + Error codes: + 3000-3002, 3100-3107 + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: prepare, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 3 + Route & Publish Prepare event for Payer + Error code: + 2003 + + + + + + 4 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 5 + Respond replication acknowledgements have been received + + + + 6 + Respond HTTP - 202 (Accepted) + + + 7 + Consume message + + + ref + Prepare Handler Consume +   + + + 8 + Produce message + + + 9 + Consume message + + + ref + Position Handler Consume +   + + + 10 + Produce message + + + 11 + Consume message + + + ref + Send notification to Participant (Payee) +   + + + 12 + Send callback notification + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg new file mode 100644 index 000000000..a5e14b378 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg @@ -0,0 +1,405 @@ + + 1.1.1.a. Prepare Handler Consume (single message) + + + 1.1.1.a. Prepare Handler Consume (single message) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Prepare Event Handler + + + Prepare Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Prepare Handler Consume + + + 1 + Consume Prepare event message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'prepare' && action == 'prepare' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + Validate Prepare Transfer + + + + + + 4 + Schema validation of the incoming message + + + + + + 5 + Verify the message's signature (to be confirmed in future requirement) + + + The above validation steps are already handled by + the ML-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + + + Validate Duplicate Check + + + 6 + Request Duplicate Check + + + ref + Request Duplicate Check +   + + + 7 + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + alt + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + break + + + + + 8 + stateRecord = await getTransferState(transferId) + + + alt + [endStateList.includes(stateRecord.transferStateId)] + + + ref + getTransfer callback +   + + + 9 + Produce message + + + + Ignore - resend in progress + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + Validate Prepare Transfer (failure) - Modified Request + + [hasDuplicateId == FALSE] + + + Validate Payer + + + 10 + Request to retrieve Payer Participant details (if it exists) + + + 11 + Request Participant details + + participant + participantCurrency + + + 12 + Return Participant details if it exists + + + 13 + Return Participant details if it exists + + + + + + 14 + Validate Payer + Error codes: + 3202 + + + Validate Payee + + + 15 + Request to retrieve Payee Participant details (if it exists) + + + 16 + Request Participant details + + participant + participantCurrency + + + 17 + Return Participant details if it exists + + + 18 + Return Participant details if it exists + + + + + + 19 + Validate Payee + Error codes: + 3203 + + + alt + [Validate Prepare Transfer (success)] + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + 20 + Request to persist transfer + Error codes: + 2003 + + + 21 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + + + 22 + Return success + + [Validate Prepare Transfer (failure)] + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + 23 + Request to persist transfer + (when Payee/Payer/crypto-condition validation fails) + Error codes: + 2003 + + + 24 + Persist transfer + + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + + + 25 + Return success + + + alt + [Validate Prepare Transfer (success)] + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 26 + Route & Publish Position event for Payer + Error codes: + 2003 + + [Validate Prepare Transfer (failure)] + + + Message: + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + "errorDescription": "<refer to section 35.1.3 for description>", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 27 + Publish Notification (failure) event for Payer + Error codes: + 2003 + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml new file mode 100644 index 000000000..1b01ef9c5 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml @@ -0,0 +1,186 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.1.b. Prepare Handler Consume (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + note over TOPIC_TRANSFER_PREPARE #LightSalmon + This flow has not been implemented + end note + + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event batch of messages for Payer + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + group Persist Event Information + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publish event information + ref over PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + group Fetch batch Payer information + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYER + end + + group Fetch batch Payee information + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYEE + end + + group Fetch batch of transfers + PREP_HANDLER -> POS_DAO: Request to retrieve batch of Transfers (if it exists) + activate POS_DAO + POS_DAO -> DB: Request batch of Transfers + hnote over DB #lightyellow + transfer + end note + activate DB + POS_DAO <-- DB: Return batch of Transfers (if it exists) + deactivate DB + POS_DAO --> PREP_HANDLER: Return batch of Transfer (if it exists) + deactivate POS_DAO + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_TRANSFERS + end + + loop for each message in batch + + group Validate Prepare Transfer + group Validate Payer + PREP_HANDLER <-> PREP_HANDLER: Validate Payer against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYER + end + group Validate Payee + PREP_HANDLER <-> PREP_HANDLER: Validate Payee against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYEE + end + group Duplicate check + PREP_HANDLER <-> PREP_HANDLER: Validate duplicate Check against in-memory var $LIST_TRANSFERS + end + PREP_HANDLER <-> PREP_HANDLER: Validate amount + PREP_HANDLER <-> PREP_HANDLER: Validate crypto-condition + PREP_HANDLER <-> PREP_HANDLER: Validate message signature (to be confirmed in future requirement) + end + + group Persist Transfer State (with transferState='RECEIVED' on validation pass) + PREP_HANDLER -> POS_DAO: Request to persist transfer + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end +deactivate PREP_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg new file mode 100644 index 000000000..548fbff89 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg @@ -0,0 +1,320 @@ + + 1.1.1.b. Prepare Handler Consume (batch messages) + + + 1.1.1.b. Prepare Handler Consume (batch messages) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + topic-transfer-prepare + Prepare Event Handler + + + Prepare Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + Prepare Handler Consume + + + This flow has not been implemented + + + 1 + Consume Prepare event batch of messages for Payer + + + Persist Event Information + + + 2 + Publish event information + + + ref + Event Handler Consume +   + + + Fetch batch Payer information + + + 3 + Request to retrieve batch of Payer Participant details (if it exists) + + + 4 + Request Participant details + + participant + + + 5 + Return Participant details if it exists + + + 6 + Return Participant details if it exists + + + + + + 7 + Validate Payer + + + + + 8 + store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYER + + + Fetch batch Payee information + + + 9 + Request to retrieve batch of Payee Participant details (if it exists) + + + 10 + Request Participant details + + participant + + + 11 + Return Participant details if it exists + + + 12 + Return Participant details if it exists + + + + + + 13 + Validate Payee + + + + + 14 + store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYEE + + + Fetch batch of transfers + + + 15 + Request to retrieve batch of Transfers (if it exists) + + + 16 + Request batch of Transfers + + transfer + + + 17 + Return batch of Transfers (if it exists) + + + 18 + Return batch of Transfer (if it exists) + + + + + 19 + store result set in var: $LIST_TRANSFERS + + + loop + [for each message in batch] + + + Validate Prepare Transfer + + + Validate Payer + + + + + + 20 + Validate Payer against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYER + + + Validate Payee + + + + + + 21 + Validate Payee against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYEE + + + Duplicate check + + + + + + 22 + Validate duplicate Check against in-memory var $LIST_TRANSFERS + + + + + + 23 + Validate amount + + + + + + 24 + Validate crypto-condition + + + + + + 25 + Validate message signature (to be confirmed in future requirement) + + + Persist Transfer State (with transferState='RECEIVED' on validation pass) + + + 26 + Request to persist transfer + + + 27 + Persist transfer + + transferStateChange + + + 28 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 29 + Route & Publish Position event for Payer + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg new file mode 100644 index 000000000..f6eae8d3e --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg @@ -0,0 +1,366 @@ + + 1.1.2.a. Position Handler Consume (single message) + + + 1.1.2.a. Position Handler Consume (single message) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + Position Handler Consume + + + 1 + Consume Position event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'position' && action == 'prepare' + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + alt + [Calulate & Validate Latest Position (success)] + + + Calculate position and persist change + + + 4 + Request latest position from DB for Payer + + + 5 + Retrieve latest position from DB for Payer + + transferPosition + + + 6 + Retrieve latest position from DB for Payer + + + 7 + Return latest position + + + 8 + Request position limits for Payer Participant + + + 9 + Request position limits for Payer Participant + + participant + participantLimit + + + 10 + Return position limits + + + 11 + Return position limits + + + + + + 12 + Calculate latest position (lpos) for prepare + + + + + + 13 + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + 14 + Request to persist latest position for Payer + + + 15 + Persist latest position to DB for Payer + + transferPosition + + + 16 + Return success + + + Persist Transfer State (with transferState='RESERVED' on position check pass) + + + 17 + Request to persist transfer + + + 18 + Persist transfer state + + transferStateChange + + + 19 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 20 + Publish Notification event to Payee + + [Calculate & Validate Latest Position (failure)] + + + Calculate position and persist change + + + 21 + Request latest position from DB for Payer + + + 22 + Retrieve latest position from DB for Payer + + transferPosition + + + 23 + Retrieve latest position from DB for Payer + + + 24 + Return latest position + + + 25 + Request position limits for Payer Participant + + + 26 + Request position limits for Payer Participant + + participant + participantLimit + + + 27 + Return position limits + + + 28 + Return position limits + + + + + + 29 + Calculate latest position (lpos) for prepare + + + + + + 30 + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + Validation failure! + + + Persist Transfer State (with transferState='ABORTED' on position check pass) + + + 31 + Request to persist transfer + + + 32 + Persist transfer state + + transferStateChange + + + 33 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <ledgerName>, + to: <transferMessage.payerFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": <transferMessage.extensionList> + } + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: notification, + action: prepare, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 34 + Publish Notification (failure) event for Payer + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml new file mode 100644 index 000000000..9e9bc1ff9 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml @@ -0,0 +1,148 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.2.b. Position Handler Consume (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Transfer-Topic" as TOPIC_TRANSFERS +entity "Position DAO" as POS_DAO +entity "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_TRANSFERS + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant TRANS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + note over TOPIC_TRANSFER_POSITION #LightSalmon + This flow has not been implemented + end note + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event batch of messages for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + loop for each message in batch + group Calculate position and persist change + POS_HANDLER -> POS_DAO: Request latest position from DB for Payer + activate POS_DAO + POS_DAO -> DB: Retrieve latest position from DB for Payer + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return latest position + deactivate POS_DAO + + POS_HANDLER <-> POS_HANDLER: Calculate latest position (lpos) by incrementing transfer for prepare + POS_HANDLER <-> POS_HANDLER: Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + POS_HANDLER -> POS_DAO: Request to persist latest position for Payer + activate POS_DAO + POS_DAO -> DB: Persist latest position to DB for Payer + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + group Persist Transfer State (with transferState='RESERVED' on position check pass) + POS_HANDLER -> TRANS_DAO: Request to persist batch transfer + activate TRANS_DAO + TRANS_DAO -> DB: Persist batch transfer + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + TRANS_DAO --> POS_HANDLER: Return success + deactivate TRANS_DAO + end + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_TRANSFERS: Publish Transfer event + activate TOPIC_TRANSFERS + deactivate TOPIC_TRANSFERS + end +end +deactivate POS_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg new file mode 100644 index 000000000..bba2e599a --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg @@ -0,0 +1,206 @@ + + 1.1.2.b. Position Handler Consume (batch messages) + + + 1.1.2.b. Position Handler Consume (batch messages) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Transfer-Topic + + + Transfer-Topic + Event-Topic + + + Event-Topic + + + + + Notification-Topic + + + Notification-Topic + Position DAO + + + Position DAO + + + Transfer DAO + + + Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + Position Handler Consume + + + This flow has not been implemented + + + 1 + Consume Position event batch of messages for Payer + + + Persist Event Information + + + 2 + Publish event information + + + ref + Event Handler Consume +   + + + loop + [for each message in batch] + + + Calculate position and persist change + + + 3 + Request latest position from DB for Payer + + + 4 + Retrieve latest position from DB for Payer + + transferPosition + + + 5 + Return latest position + + + + + + 6 + Calculate latest position (lpos) by incrementing transfer for prepare + + + + + + 7 + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + 8 + Request to persist latest position for Payer + + + 9 + Persist latest position to DB for Payer + + transferPosition + + + 10 + Return success + + + Persist Transfer State (with transferState='RESERVED' on position check pass) + + + 11 + Request to persist batch transfer + + + 12 + Persist batch transfer + + transferStateChange + + + 13 + Return success + + + Message: + { + id: <transferMessage.transferId> + from: <transferMessage.payerFsp>, + to: <transferMessage.payeeFsp>, + type: application/json + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: transfer, + action: prepare, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 14 + Publish Transfer event + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml new file mode 100644 index 000000000..fc35e5b8b --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml @@ -0,0 +1,123 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Shashikant Hirugade + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) v1.1 + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP\nParticipant" as PAYEE_DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "Event-Topic" as TOPIC_EVENTS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee)" #lightGray + participant PAYEE_DFSP +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participants + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume Notification event + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + group Persist Event Information + NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publish event information + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + TOPIC_EVENTS --> CSAPI: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + note right of NOTIFY_HANDLER #lightgray + The endpoint details are cached, when the cache + expires, the details are fetched again + end note + NOTIFY_HANDLER -> CSAPI: Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints\nError code: 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Fetch Endpoint details for Participant\nError code: 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Endpoint details for Participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Retrieved Endpoint details for Participant + deactivate DB + PARTICIPANT_DAO --> CSAPI: Return Endpoint details for Participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Return Endpoint details for Participant\nError codes: 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification with Prepare/fulfil result/error to \nPayer DFSP to specified Endpoint - PUT \nError code: 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt event.action === 'reserve' + alt event.status === 'success' + NOTIFY_HANDLER -> PAYEE_DFSP: Notification to with succesful fulfil result (committed) to Payee DFSP to specified Endpoint - PATCH \nError code: 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP: HTTP 200 OK + end + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg new file mode 100644 index 000000000..a6f26da77 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg @@ -0,0 +1,189 @@ + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) v1.1 + + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) v1.1 + + Financial Service Provider (Payer) + + ML API Adapter Service + + Central Service + + Financial Service Provider (Payee) + + + + + + + + + + + + + + + + + + + + Payer DFSP + Participant + + + Payer DFSP + Participant + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + + + Notification-Topic + + + Notification-Topic + Central Service API + + + Central Service API + + + + + Event-Topic + + + Event-Topic + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + Payee DFSP + Participant + + + Payee DFSP + Participant + + + + + + + + + + + + Send notification to Participants + + + 1 + Consume Notification event + + + Persist Event Information + + + 2 + Request to persist event information - POST - /events + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + 4 + Return success + + + 5 + Return success + + + The endpoint details are cached, when the cache + expires, the details are fetched again + + + 6 + Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints + Error code: + 2003 + + + 7 + Fetch Endpoint details for Participant + Error code: + 2003 + + + 8 + Fetch Endpoint details for Participant + + participantEndpoint + + + 9 + Retrieved Endpoint details for Participant + + + 10 + Return Endpoint details for Participant + + + 11 + Return Endpoint details for Participant + Error codes: + 3202, 3203 + + + 12 + Notification with Prepare/fulfil result/error to + Payer DFSP to specified Endpoint - PUT + Error code: + 1001 + + + 13 + HTTP 200 OK + + + alt + [event.action === 'reserve'] + + + alt + [event.status === 'success'] + + + 14 + Notification to with succesful fulfil result (committed) to Payee DFSP to specified Endpoint - PATCH + Error code: + 1001 + + + 15 + HTTP 200 OK + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg new file mode 100644 index 000000000..7f31b7361 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg @@ -0,0 +1,184 @@ + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) + + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) + + Financial Service Provider (Payer) + + ML API Adapter Service + + Central Service + + Financial Service Provider (Payee) + + + + + + + + + + + + + + + + + + + Payer DFSP + Participant + + + Payer DFSP + Participant + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + + + Notification-Topic + + + Notification-Topic + Central Service API + + + Central Service API + + + + + Event-Topic + + + Event-Topic + Participant DAO + + + Participant DAO + + + Central Store + + + Central Store + + + Payee DFSP + Participant + + + Payee DFSP + Participant + + + + + + + + + + + + Send notification to Participants + + + 1 + Consume Notification event + + + Persist Event Information + + + 2 + Request to persist event information - POST - /events + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + 4 + Return success + + + 5 + Return success + + + The endpoint details are cached, when the cache + expires, the details are fetched again + + + 6 + Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints + Error code: + 2003 + + + 7 + Fetch Endpoint details for Participant + Error code: + 2003 + + + 8 + Fetch Endpoint details for Participant + + participantEndpoint + + + 9 + Retrieved Endpoint details for Participant + + + 10 + Return Endpoint details for Participant + + + 11 + Return Endpoint details for Participant + Error codes: + 3202, 3203 + + + 12 + Notification with Prepare/fulfil result/error to + Payer DFSP to specified Endpoint - PUT + Error code: + 1001 + + + 13 + HTTP 200 OK + + + alt + [Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE === true] + + + 14 + Notification to with fulfil result (committed/aborted/rejected) to Payee DFSP to specified Endpoint - PUT + Error code: + 1001 + + + 15 + HTTP 200 OK + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml new file mode 100644 index 000000000..0c5c5fb5d --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml @@ -0,0 +1,108 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "Event-Topic" as TOPIC_EVENTS +entity "Notification DAO" as NOTIFY_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow +participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant EVENT_DAO + participant NOTIFY_DAO + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participant + note over DFSP #LightSalmon + This flow has not been implemented + end note + + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: **Consume Notifications event batch of messages for Participant** + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + loop for each message in batch + group Persist Event Information + NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publish event information + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + TOPIC_EVENTS --> CSAPI: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + NOTIFY_HANDLER -> CSAPI: Request Notifications details for Participant - GET - /notifications/DFPS(n) + activate CSAPI + CSAPI -> NOTIFY_DAO: Fetch Notifications details for Participant + activate NOTIFY_DAO + NOTIFY_DAO -> DB: Fetch Notifications details for Participant + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> NOTIFY_DAO: Retrieved Notification details for Participant + 'deactivate DB + NOTIFY_DAO --> CSAPI: Return Notifications details for Participant + deactivate NOTIFY_DAO + CSAPI --> NOTIFY_HANDLER: Return Notifications details for Participant + deactivate CSAPI + NOTIFY_HANDLER --> DFSP: Callback with Prepare result to Participant to specified URL - PUT - />/transfers + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg new file mode 100644 index 000000000..b7adfc723 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg @@ -0,0 +1,154 @@ + + 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) + + + 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) + + Financial Service Provider + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP(n) + Participant + + + DFSP(n) + Participant + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + + + Notification-Topic + + + Notification-Topic + Central Service API + + + Central Service API + + + + + Event-Topic + + + Event-Topic + + EVENT_DAO + + EVENT_DAO + Notification DAO + + + Notification DAO + + + Central Store + + + Central Store + + + + + + + + + + + + Send notification to Participant + + + This flow has not been implemented + + + 1 + Consume Notifications event batch of messages for Participant + + + loop + [for each message in batch] + + + Persist Event Information + + + 2 + Request to persist event information - POST - /events + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + 4 + Return success + + + 5 + Return success + + + 6 + Request Notifications details for Participant - GET - /notifications/DFPS(n) + + + 7 + Fetch Notifications details for Participant + + + 8 + Fetch Notifications details for Participant + + transferPosition + + + 9 + Retrieved Notification details for Participant + + + 10 + Return Notifications details for Participant + + + 11 + Return Notifications details for Participant + + + 12 + Callback with Prepare result to Participant to specified URL - PUT - /<dfsp-host>>/transfers + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml new file mode 100644 index 000000000..45f7fd524 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml @@ -0,0 +1,143 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER + +' collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +' control "Position Event Handler" as POS_HANDLER +' collections "Event-Topic" as TOPIC_EVENTS +' collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +group DFSP2 sends an error callback to reject a transfer with an errorCode and description + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: **PUT - /transfers//error** + + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all) + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + FULF_HANDLER -> FULF_HANDLER: Log error message + note right of FULF_HANDLER: (corresponding to a Fulfil message with transferState='ABORTED')\naction REJECT is not allowed into fulfil handler +end +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg new file mode 100644 index 000000000..5cbfe019e --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg @@ -0,0 +1,178 @@ + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + + + + + DFSP2 sends an error callback to reject a transfer with an errorCode and description + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "errorInformation": { + "errorCode": <errorCode>, + "errorDescription": <errorDescription>, + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 1 + PUT - /transfers/<ID>/error + + + + + 2 + Validate incoming token and originator matching Payee + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 3 + Route & Publish Fulfil event for Payee + + + + + + 4 + Ensure event is replicated as configured (ACKS=all) + + + 5 + Respond replication acknowledgements have been received + + + + 6 + Respond HTTP - 200 (OK) + + + 7 + Consume message + + + + + 8 + Log error message + + + (corresponding to a Fulfil message with transferState='ABORTED') + action REJECT is not allowed into fulfil handler + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml new file mode 100644 index 000000000..ec02b5318 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml @@ -0,0 +1,166 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +' declate title +title 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 sends a Fulfil Success Transfer request + DFSP2 <-> DFSP2: During processing of an incoming\nPOST /transfers request, some processing\nerror occurred and an Error callback is made + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage: + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers//error + activate MLAPI + MLAPI -> MLAPI: Validate incoming originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Abort event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Abort)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg new file mode 100644 index 000000000..fb382991c --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg @@ -0,0 +1,265 @@ + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + + 1 + During processing of an incoming + POST /transfers request, some processing + error occurred and an Error callback is made + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - errorMessage: + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /transfers/<ID>/error + + + + + 3 + Validate incoming originator matching Payee + Error codes: + 3000-3002, 3100-3107 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Abort event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + ref + Fulfil Handler Consume (Abort) +   + + + 9 + Produce message + + + 10 + Consume message + + + ref + Position Handler Consume (Abort) +   + + + 11 + Produce message + + + 12 + Consume message + + + opt + [action == 'abort'] + + + ref + Send notification to Participant (Payer) +   + + + 13 + Send callback notification + + + 14 + Consume message + + + opt + [action == 'abort'] + + + ref + Send notification to Participant (Payee) +   + + + 15 + Send callback notification + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg new file mode 100644 index 000000000..07a2af94f --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg @@ -0,0 +1,265 @@ + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + + 1 + During processing of an incoming + POST /transfers request, some processing + error occurred and an Error callback is made + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - errorMessage: + { + errorInformation + { + "errorCode": <errorCode>, + "errorDescription": <errorDescription> + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + } + + + + 2 + PUT - /transfers/<ID>/error + + + + + 3 + Validate incoming originator matching Payee + Error codes: + 3000-3002, 3100-3107 + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <errorMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Abort/Reject event for Payee + Error code: + 2003 + + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + Error code: + 2003 + + + 6 + Respond replication acknowledgements have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + ref + Fulfil Handler Consume (Reject/Abort) +   + + + 9 + Produce message + + + 10 + Consume message + + + ref + Position Handler Consume (Abort) +   + + + 11 + Produce message + + + 12 + Consume message + + + opt + [action == 'abort'] + + + ref + Send notification to Participant (Payer) +   + + + 13 + Send callback notification + + + 14 + Consume message + + + opt + [action == 'abort'] + + + ref + Send notification to Participant (Payee) +   + + + 15 + Send callback notification + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg new file mode 100644 index 000000000..10a77439b --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg @@ -0,0 +1,262 @@ + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API Adapter + + + ML API Adapter + + + ML API Notification Event Handler + + + ML API Notification Event Handler + + + Central Service API + + + Central Service API + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + Position Event Handler + + + Position Event Handler + + + + + Notification-Topic + + + Notification-Topic + + + + + + + + DFSP2 sends a Fulfil Reject Transfer request + + + + + + 1 + Retrieve fulfilment string generated during + the quoting process or regenerate it using + Local secret + and + ILP Packet + as inputs + + + Note + : In the payload for PUT /transfers/<ID> + only the + transferState + field is + required + + + Headers - transferHeaders: { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + } +   + Payload - transferMessage: + { + "fulfilment": <IlpFulfilment>, + "completedTimestamp": <DateTime>, + "transferState": "ABORTED", + "extensionList": { + "extension": [ + { + "key": <string>, + "value": <string> + } + ] + } + } + + + Note + : Payee rejection reason should be captured + in the extensionList within the payload. + + + + 2 + PUT - /transfers/<ID> + + + + + 3 + Validate incoming token and originator matching Payee + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + type: fulfil, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 4 + Route & Publish Fulfil event for Payee + + + + + + 5 + Ensure event is replicated as configured (ACKS=all) + + + 6 + Respond replication acknowledgements have been received + + + + 7 + Respond HTTP - 200 (OK) + + + 8 + Consume message + + + ref + Fulfil Handler Consume (Reject/Abort) +   + + + 9 + Produce message + + + 10 + Consume message + + + ref + Position Handler Consume (Reject) +   + + + 11 + Produce message + + + 12 + Consume message + + + opt + [action == 'reject'] + + + ref + Send notification to Participant (Payer) +   + + + 13 + Send callback notification + + diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml new file mode 100644 index 000000000..3c390db71 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml @@ -0,0 +1,225 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Fulfil Handler Consume (Abort/Reject) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "Event-Topic" as TOPIC_EVENT +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Failure) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] )\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 2001 + end + group Validate Transfer Fulfil Duplicate Check + FULF_HANDLER -> FULF_HANDLER: Generate transferFulfilmentId uuid + FULF_HANDLER -> TRANS_DAO: Request to retrieve transfer fulfilment hashes by transferId\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request Transfer fulfilment duplicate message hashes + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Return existing hashes + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return (list of) transfer fulfil messages hash(es) + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Loop the list of returned hashes and compare each entry with the calculated message hash + alt Hash matched + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Request to retrieve Transfer Fulfilment and Transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request to retrieve Transfer Fulfilment and Transfer state + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Return Transfer Fulfilment and Transfer state + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return Transfer Fulfilment and Transfer state + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + FULF_HANDLER <-> FULF_HANDLER: Error handling: 3105 + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Error code: 2001 + end + else + break + FULF_HANDLER <-> FULF_HANDLER: Allow previous request to complete + end + end + else Hash not matched + FULF_HANDLER -> TRANS_DAO: Request to persist transfer hash\nError codes: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist hash + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + deactivate TRANS_DAO + end + end + alt action=='reject' call made on PUT /transfers/{ID} + FULF_HANDLER -> FULF_HANDLER: Log error message + note right of FULF_HANDLER: action REJECT is not allowed into fulfil handler + else action=='abort' Error callback + alt Validation successful + group Persist Transfer State (with transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state and Error\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state and error information + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Transfer Error Message not successful + break + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg new file mode 100644 index 000000000..517355e0c --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg @@ -0,0 +1,386 @@ + + 2.2.1. Fulfil Handler Consume (Abort/Reject) + + + 2.2.1. Fulfil Handler Consume (Abort/Reject) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + Transfer DAO + + + Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Failure) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] ) + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 2001 + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + Generate transferFulfilmentId uuid + + + 5 + Request to retrieve transfer fulfilment hashes by transferId + Error code: + 2003 + + + 6 + Request Transfer fulfilment duplicate message hashes + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Return existing hashes + + + 8 + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + Loop the list of returned hashes and compare each entry with the calculated message hash + + + alt + [Hash matched] + + + 10 + Request to retrieve Transfer Fulfilment and Transfer state + Error code: + 2003 + + + 11 + Request to retrieve Transfer Fulfilment and Transfer state + + transferFulfilment + transferStateChange + + + 12 + Return Transfer Fulfilment and Transfer state + + + 13 + Return Transfer Fulfilment and Transfer state + + + alt + [transferFulfilment.isValid == 0] + + + break + + + + + + 14 + Error handling: + 3105 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + ref + Send notification to Participant (Payee) +   + + [transferState NOT 'RESERVED'] + + + break + + + + + + 15 + Error code: + 2001 + + + + break + + + + + + 16 + Allow previous request to complete + + [Hash not matched] + + + 17 + Request to persist transfer hash + Error codes: + 2003 + + + 18 + Persist hash + + transferFulfilmentDuplicateCheck + + + 19 + Return success + + + alt + [action=='reject' call made on PUT /transfers/{ID}] + + + + + 20 + Log error message + + + action REJECT is not allowed into fulfil handler + + [action=='abort' Error callback] + + + alt + [Validation successful] + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + 21 + Request to persist transfer state and Error + Error code: + 2003 + + + 22 + Persist transfer state and error information + + transferStateChange + transferError + transferExtension + + + 23 + Return success + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 24 + Route & Publish Position event for Payer + + [Validate Transfer Error Message not successful] + + + break + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 25 + Route & Publish Notification event for Payee + + [Consume Batch Messages] + + + To be delivered by future story + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg new file mode 100644 index 000000000..97665dece --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg @@ -0,0 +1,572 @@ + + 2.2.1. Fulfil Handler Consume (Reject/Abort) + + + 2.2.1. Fulfil Handler Consume (Reject/Abort) + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + Fulfil-Topic + Fulfil Event Handler + + + Fulfil Event Handler + + + + + topic-transfer-position + + + topic-transfer-position + + + Event-Topic + + + Event-Topic + + + Notification-Topic + + + Notification-Topic + Transfer DAO + + + Transfer DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil Handler Consume (Failure) + + + alt + [Consume Single Message] + + + 1 + Consume Fulfil event message for Payer + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] ) + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume + + + Validate FSPIOP-Signature + + + ref + Validate message.content.headers. + FSPIOP-Signature + Error codes: + 2001 + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + Generate transferFulfilmentId uuid + + + 5 + Request to retrieve transfer fulfilment hashes by transferId + Error code: + 2003 + + + 6 + Request Transfer fulfilment duplicate message hashes + + SELET transferId, hash + FROM + transferFulfilmentDuplicateCheck + WHERE transferId = request.params.id + + + 7 + Return existing hashes + + + 8 + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + Loop the list of returned hashes and compare each entry with the calculated message hash + + + alt + [Hash matched] + + + 10 + Request to retrieve Transfer Fulfilment and Transfer state + Error code: + 2003 + + + 11 + Request to retrieve Transfer Fulfilment and Transfer state + + transferFulfilment + transferStateChange + + + 12 + Return Transfer Fulfilment and Transfer state + + + 13 + Return Transfer Fulfilment and Transfer state + + + alt + [transferFulfilment.isValid == 0] + + + break + + + + + + 14 + Error handling: + 3105 + + [transferState IN ['COMMITTED', 'ABORTED']] + + + break + + + ref + Send notification to Participant (Payee) +   + + [transferState NOT 'RESERVED'] + + + break + + + + + + 15 + Error code: + 2001 + + + + break + + + + + + 16 + Allow previous request to complete + + [Hash not matched] + + + 17 + Request to persist transfer hash + Error codes: + 2003 + + + 18 + Persist hash + + transferFulfilmentDuplicateCheck + + + 19 + Return success + + + alt + [action=='reject' call made on PUT /transfers/{ID}] + + + 20 + Request information for the validate checks + Error code: + 2003 + + + 21 + Fetch from database + + transfer + + + 22 +   + + + 23 + Return transfer + + + alt + [Fulfilment present in the PUT /transfers/{ID} message] + + + + + 24 + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + Error code: + 2001 + + + Persist fulfilment + + + 25 + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + Error code: + 2003 + + + 26 + Persist to database + + transferFulfilment + transferExtension + + + 27 + Return success + + [Fulfilment NOT present in the PUT /transfers/{ID} message] + + + + + 28 + Validate that transfer fulfilment message to Abort is valid + Error code: + 2001 + + + Persist extensions + + + 29 + Persist extensionList elements + Error code: + 2003 + + + 30 + Persist to database + + transferExtension + + + 31 + Return success + + + alt + [Transfer.ilpCondition validate successful OR generic validation successful] + + + Persist Transfer State (with transferState='RECEIVED_REJECT') + + + 32 + Request to persist transfer state + Error code: + 2003 + + + 33 + Persist transfer state + + transferStateChange + + + 34 + Return success + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 35 + Route & Publish Position event for Payer + + [Validate Fulfil Transfer not successful or Generic validation failed] + + + break + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: reject, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 36 + Route & Publish Notification event for Payee + + [action=='abort' Error callback] + + + alt + [Validation successful] + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + 37 + Request to persist transfer state and Error + Error code: + 2003 + + + 38 + Persist transfer state and error information + + transferStateChange + transferError + transferExtension + + + 39 + Return success + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 40 + Route & Publish Position event for Payer + + [Validate Transfer Error Message not successful] + + + break + + + Message: + { + id: <ID>, + from: <transferHeaders.FSPIOP-Source>, + to: <transferHeaders.FSPIOP-Destination>, + type: application/json, + content: { + headers: <transferHeaders>, + payload: <transferMessage> + }, + metadata: { + event: { + id: <uuid>, + responseTo: <previous.uuid>, + type: position, + action: abort, + createdAt: <timestamp>, + state: { + status: "error", + code: 1 + } + } + } + } + + + 41 + Route & Publish Notification event for Payee + + [Consume Batch Messages] + + + To be delivered by future story + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg new file mode 100644 index 000000000..9799da8cd --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg @@ -0,0 +1,167 @@ + + 9.1.1. Request Duplicate Check (incl. Transfers, Quotes, Bulk Transfers, Bulk Quotes) + + + 9.1.1. Request Duplicate Check (incl. Transfers, Quotes, Bulk Transfers, Bulk Quotes) + + Central Service + + + + + + + + + + + + + + + + + + + + topic-source + + + topic-source + Processing + Handler + + + Processing + Handler + + + + + topic-event + + + topic-event + + + topic-notifcation + + + topic-notifcation + Request DAO + + + Request DAO + + + Central Store + + + Central Store + + + + + + + + + + + Request Duplicate Check + + + 1 + Consume message + + + + + 2 + Generate hash: + generatedHash + + + UUID Check (compareById) + + + 3 + Query hash using getDuplicateDataFuncOverride(id) + Error code: + 2003 + + + request + keyword to be replaced by + transfer + , + transferFulfilment + , + bulkTransfer + or other depending + on the override + + + 4 + getDuplicateDataFuncOverride + + request + DuplicateCheck + + + 5 + Return + duplicateHashRecord + + + 6 + Return + hasDuplicateId + + + alt + [hasDuplicateId == TRUE] + + + Hash Check (compareByHash) + + + generatedHash == duplicateHashRecord.hash + + + + + 7 + Return + hasDuplicateHash + + [hasDuplicateId == FALSE] + + + Store Message Hash + + + 8 + Persist hash using saveHashFuncOverride(id, generatedHash) + Error code: + 2003 + + + 9 + Persist + generatedHash + + request + DuplicateCheck + + + 10 + Return success + + + return { + hasDuplicateId: Boolean, + hasDuplicateHash: Boolean + } + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg new file mode 100644 index 000000000..a3e2de88c --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg @@ -0,0 +1,175 @@ + + 2.1.2. Settlement Model Handler Consume + + + 2.1.2. Settlement Model Handler Consume + + Central Service + + + + + + + + + + + + + + + + + + + + + + + topic- + settlement-model + + + topic- + settlement-model + Settlement Model + Handler + + + Settlement Model + Handler + + + + + topic-event + + + topic-event + Settlement DAO + + + Settlement DAO + + + Central Store + + + Central Store + + + + + + + + + + + + Settlement Model Handler Consume + + + alt + [Consume Single Message] + + + 1 + Consume settlement model + event message + + + break + + + Validate Event + + + + + + 2 + Validate event - Rule: type == 'setmodel' && action == 'commit' + Error codes: + 2001 + + + Persist Event Information + + + 3 + Publish event information + + + ref + Event Handler Consume +   + + + 4 + Assign transferParicipant state(s) + Error code: + 2003 + + + DB TRANSACTION + + + 5 + Fetch transfer participant entries + + transferParticipant + + + 6 + Return + transferParticipantRecords + + + loop + [for each transferParticipant] + + + Settlement models caching to be considered + + + 7 + Get settlement model by currency and ledger entry + + settlementModel + + + 8 + Return + settlementModel + + + opt + [settlementModel.delay == 'IMMEDIATE' && settlementModel.granularity == 'GROSS'] + + + 9 + Set states: CLOSED->PENDING_SETTLEMENT->SETTLED + + transferParticipantStateChange + transferParticipant + + + + 10 + Set state: OPEN + + transferParticipantStateChange + transferParticipant + + + 11 + Return success + + [Consume Batch Messages] + + + To be delivered by future story + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg new file mode 100644 index 000000000..e4440f48f --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg @@ -0,0 +1,195 @@ + + 2.3.0. Transfer Timeout + + + 2.3.0. Transfer Timeout + + Financial Service Providers + + ML API Adapter Service + + Central Service + + + + + + + + + + + + + + + + + + + DFSP1 + Payer + + + DFSP1 + Payer + + + DFSP2 + Payee + + + DFSP2 + Payee + + + ML API + Adapter + + + ML API + Adapter + + + Notification + Handler + + + Notification + Handler + + + Timeout Prepare + Handler + + + Timeout Prepare + Handler + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + Timeout + Handler + + + Timeout + Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + Position + Handler + + + Position + Handler + + + + + topic-notification + + + topic-notification + + + + + + + Transfer Expiry + + + ref + Timeout Processing Handler Consume +   + + + 1 + Produce message + + + 2 + Consume message + + + ref + Timeout Processing Handler Consume +   + + + alt + [transferStateId == 'RECEIVED_PREPARE'] + + + 3 + Produce message + + [transferStateId == 'RESERVED'] + + + 4 + Produce message + + + 5 + Consume message + + + ref + Position Hander Consume (Timeout) +   + + + 6 + Produce message + + + opt + [action IN ['timeout-received', 'timeout-reserved']] + + + 7 + Consume message + + + ref + Send notification to Participant (Payer) +   + + + 8 + Send callback notification + + + 9 + Consume message + + + opt + [action == 'timeout-reserved'] + + + ref + Send notification to Participant (Payee) +   + + + 10 + Send callback notification + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg new file mode 100644 index 000000000..7a554e868 --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg @@ -0,0 +1,169 @@ + + 2.3.1. Timeout Prepare Handler + + + 2.3.1. Timeout Prepare Handler + + Central Service + + + + + + + + + + + + + + + + + Timeout Prepare + Handler + + + Timeout Prepare + Handler + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + + + topic-event + + + topic-event + Timeout DAO + + + Timeout DAO + + + Central Store + + + Central Store + + + + + + + + + + + Timeout Prepare Handler + + + Persist Event Information + + + 1 + Publish event information + + + ref + Event Handler Consume +   + + + Cleanup + + + 2 + Cleanup Fulfilled Transfers + Error code: + 2003 + + + 3 + Delete fuflfilled transfers records + + DELETE et + FROM + expiringTransfer + et + JOIN + transferFulfilment + tf + ON tf.transferId = et.transferId + + + 4 + Return success + + + List Expired + + + 5 + Retrieve Expired Transfers + Error code: + 2003 + + + 6 + Select using index + + SELECT * + FROM + expiringTransfer + WHERE expirationDate < currentTimestamp + + + 7 + Return expired transfers + + + 8 + Return + expiredTransfersList + + + loop + [for each transfer in the list] + + + Message: + { + id: <uuid> + from: <switch>, + to: <payerFsp>, + type: application/json + content: { + headers: null, + payload: <transfer> + }, + metadata: { + event: { + id: <uuid>, + responseTo: null, + type: transfer, + action: timeout, + createdAt: <timestamp>, + state: { + status: "success", + code: 0 + } + } + } + } + + + 9 + Publish Timeout event + Error code: + 2003 + + diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml similarity index 100% rename from mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml rename to docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml diff --git a/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg new file mode 100644 index 000000000..8c79f9dfd --- /dev/null +++ b/docs/technical/technical/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg @@ -0,0 +1,302 @@ + + 2.3.2. Timeout Handler + + + 2.3.2. Timeout Handler + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + transfer-timeout + + + topic- + transfer-timeout + Transfer Timeout Handler + + + Transfer Timeout Handler + + + + + topic- + transfer-position + + + topic- + transfer-position + + + topic- + notification + + + topic- + notification + + + topic-event + + + topic-event + Timeout DAO + + + Timeout DAO + + + Central Store + + + Central Store + + + + + + + + + + + + + + + + + Timeout Handler Consume + + + 1 + Consume message + + + Persist Event Information + + + 2 + Publish event information + + + ref + Event Handler Consume +   + + + Get transfer info + + + 3 + Acquire transfer information + Error code: + 2003 + + + 4 + Get transfer data and state + + transfer + transferParticipant + participantCurrency + participant + transferStateChange + + + 5 + Return + transferInfo + + + 6 + Return + transferInfo + + + alt + [transferInfo.transferStateId == 'RECEIVED_PREPARE'] + + + 7 + Set EXPIRED_PREPARED state + Error code: + 2003 + + + 8 + Insert state change + + transferStateChange + + + 9 + Return success + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { +          + headers: + { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: notification, + action: timeout-received, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 10 + Publish Notification event + + [transferInfo.transferStateId == 'RESERVED'] + + + 11 + Set RESERVED_TIMEOUT state + Error code: + 2003 + + + 12 + Insert state change + + transferStateChange + + + 13 + Return success + + + Message: + { + id: <transferId>, + from: <payerParticipantId>, + to: <payeeParticipantId>, + type: application/json, + content: { +          + headers: + { + Content-Length: <Content-Length>, + Content-Type: <Content-Type>, + Date: <Date>, + X-Forwarded-For: <X-Forwarded-For>, + FSPIOP-Source: <FSPIOP-Source>, + FSPIOP-Destination: <FSPIOP-Destination>, + FSPIOP-Encryption: <FSPIOP-Encryption>, + FSPIOP-Signature: <FSPIOP-Signature>, + FSPIOP-URI: <FSPIOP-URI>, + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": <transferMessage.extensionList> + } + } + }, + metadata: { + event: { + id: <uuid>, + type: position, + action: timeout-reserved, + createdAt: <timestamp>, + state: { + status: 'error', + code: <errorInformation.errorCode> + description: <errorInformation.errorDescription> + } + } + } + } + + + 14 + Route & Publish Position event + Error code: + 2003 + + + + Any other state is ignored + + + Cleanup + + + 15 + Cleanup handled expiring transfer + Error code: + 2003 + + + 16 + Delete record + + expiringTransfer + + + 17 + Return success + + diff --git a/docs/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md b/docs/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md new file mode 100644 index 000000000..e98c606e8 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.0-prepare-transfer-request.md @@ -0,0 +1,16 @@ +# Prepare Transfer Request + +Sequence design diagram for Prepare Transfer Request process. + +## References within Sequence Diagram + +* [Prepare Handler Consume (1.1.1.a)](1.1.1.a-prepare-handler-consume.md) +* **Not Implemented** [Prepare Handler Consume (1.1.1.b)](1.1.1.b-prepare-handler-consume.md) +* [Position Handler Consume (1.1.2.a)](1.1.2.a-position-handler-consume.md) +* **Not Implemented** [Position Handler Consume (1.1.2.b)](1.1.2.b-position-handler-consume.md) +* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) +* **Not Implemented** [Send notification to Participant (1.1.4.b)](1.1.4.b-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-prepare-1.1.0.svg](../assets/diagrams/sequence/seq-prepare-1.1.0.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md new file mode 100644 index 000000000..b0a401b5f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Prepare handler consume + +Sequence design diagram for Prepare Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.1.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.a.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md new file mode 100644 index 000000000..72e6784d5 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Prepare handler consume + +Sequence design diagram for Prepare Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.1.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.b.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md new file mode 100644 index 000000000..8904fe97f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.2.a-position-handler-consume.md @@ -0,0 +1,11 @@ +# Position handler consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.2.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.a.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md new file mode 100644 index 000000000..161bea8d9 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.2.b-position-handler-consume.md @@ -0,0 +1,11 @@ +# Position handler consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.2.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.b.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md b/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md new file mode 100644 index 000000000..9fd4fb1c5 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md @@ -0,0 +1,11 @@ +# Send Notification to Participant v1.1 + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.a-v1.1.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md b/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md new file mode 100644 index 000000000..12b1972d6 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Send Notification to Participant + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md b/docs/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md new file mode 100644 index 000000000..c22b6c94f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Send Notification to Participant + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.b.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md b/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md new file mode 100644 index 000000000..3f12ab0b1 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md @@ -0,0 +1,14 @@ +# Position Handler Consume v1.1 + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fufil Position Handler Consume (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Abort Position Handler Consume (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Sequence Diagram + +![seq-position-1.3.0-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md new file mode 100644 index 000000000..6ec460a05 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.0-position-handler-consume.md @@ -0,0 +1,14 @@ +# Position Handler Consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fulfil Position Handler Consume (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Abort Position Handler Consume (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Sequence Diagram + +![seq-position-1.3.0.svg](../assets/diagrams/sequence/seq-position-1.3.0.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..2ab39456e --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Prepare Position Handler Consume + +Sequence design diagram for Prepare Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.1-prepare.svg](../assets/diagrams/sequence/seq-position-1.3.1-prepare.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md b/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md new file mode 100644 index 000000000..71799b0ea --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md @@ -0,0 +1,7 @@ +# Fulfil Position Handler Consume v1.1 + +Sequence design diagram for Fulfil Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.2-fulfil-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md new file mode 100644 index 000000000..25e5b2774 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md @@ -0,0 +1,7 @@ +# Fulfil Position Handler Consume + +Sequence design diagram for Fulfil Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.2-fulfil.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg) diff --git a/docs/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md b/docs/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md new file mode 100644 index 000000000..9ab80dc75 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/1.3.3-abort-position-handler-consume.md @@ -0,0 +1,7 @@ +# Abort Position Handler Consume + +Sequence design diagram for Abort Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.3-abort.svg](../assets/diagrams/sequence/seq-position-1.3.3-abort.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md b/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md new file mode 100644 index 000000000..d7a71954f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md @@ -0,0 +1,13 @@ +# Fulfil Transfer Request success v1.1 + +Sequence design diagram for the Fulfil Success Transfer request. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Success) (2.1.1)](2.1.1-fulfil-handler-consume-v1.1.md) +* [Position Handler Consume (Success) (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1-v1.1.md) + +## Sequence Diagram + +![seq-fulfil-2.1.0-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md b/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md new file mode 100644 index 000000000..c552a057a --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.1.0-fulfil-transfer-request.md @@ -0,0 +1,13 @@ +# Fulfil Transfer Request success + +Sequence design diagram for the Fulfil Success Transfer request. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Success) (2.1.1)](2.1.1-fulfil-handler-consume.md) +* [Position Handler Consume (Success) (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-fulfil-2.1.0.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md b/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md new file mode 100644 index 000000000..69f2afa87 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md @@ -0,0 +1,13 @@ +# Fulfil Handler Consume (Success) v1.1 + +Sequence design diagram for the Fulfil Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-fulfil-2.1.1-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md b/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md new file mode 100644 index 000000000..05f7e38f0 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.1.1-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Fulfil Handler Consume (Success) + +Sequence design diagram for the Fulfil Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-fulfil-2.1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md b/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md new file mode 100644 index 000000000..ede9acee1 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md @@ -0,0 +1,7 @@ +# Payee sends a Fulfil Abort Transfer request v1.1 + +Sequence design diagram for the Fulfil Reject Transfer process for version 1.1. of the API. + +## Sequence Diagram + +![seq-reject-2.2.0-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md b/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md new file mode 100644 index 000000000..fc193a59d --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md @@ -0,0 +1,13 @@ +# [Outdated] Payee sends a Fulfil Reject Transfer request + +Sequence design diagram for the Fulfil Reject Transfer process. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-reject-2.2.0.svg](../assets/diagrams/sequence/seq-reject-2.2.0.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md b/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md new file mode 100644 index 000000000..c50c356a0 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md @@ -0,0 +1,13 @@ +# Payee sends a PUT call on /error end-point for a Transfer request v1.1 + +Sequence design diagram for the Fulfil Reject Transfer process for version 1.1. of the API. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Abort)(2.2.1)](2.2.1-fulfil-reject-handler-v1.1.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-reject-2.2.0.a-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md b/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md new file mode 100644 index 000000000..0a1639855 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md @@ -0,0 +1,13 @@ +# Payee sends a PUT call on /error end-point for a Transfer request + +Sequence design diagram for the Fulfil Reject Transfer process. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-reject-2.2.0.a.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md b/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md new file mode 100644 index 000000000..1098c1c2f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md @@ -0,0 +1,7 @@ +# Fulfil Handler Consume (Reject/Abort) + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process for version 1.1. of the API. + +## Sequence Diagram + +![seq-reject-2.2.1-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md b/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md new file mode 100644 index 000000000..b4512e034 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.2.1-fulfil-reject-handler.md @@ -0,0 +1,13 @@ +# Fulfil Handler Consume (Reject/Abort) + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-reject-2.2.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md b/docs/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md new file mode 100644 index 000000000..03d9f36c1 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.3.0-transfer-timeout.md @@ -0,0 +1,13 @@ +# Transfer Timeout + +Sequence design diagram for the Transfer Timeout process. + +## References within Sequence Diagram + +* [Timeout Handler Consume (2.3.1)](2.3.1-timeout-handler-consume.md) +* [Position Handler Consume (Timeout)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-timeout-2.3.0.svg](../assets/diagrams/sequence/seq-timeout-2.3.0.svg) diff --git a/docs/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md b/docs/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md new file mode 100644 index 000000000..dd1415f1f --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/2.3.1-timeout-handler-consume.md @@ -0,0 +1,11 @@ +# Timeout Handler Consume + +Sequence design diagram for the Timeout Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-timeout-2.3.1.svg](../assets/diagrams/sequence/seq-timeout-2.3.1.svg) diff --git a/docs/technical/technical/central-ledger/transfers/README.md b/docs/technical/technical/central-ledger/transfers/README.md new file mode 100644 index 000000000..6dcad1ff8 --- /dev/null +++ b/docs/technical/technical/central-ledger/transfers/README.md @@ -0,0 +1,8 @@ +# Mojaloop Transfer operations + +Operational processes that are the core of the transfer operational process; + +- Prepare process +- Fulfil process +- Notifications process +- Reject/Abort process diff --git a/docs/technical/technical/deployment-guide/README.md b/docs/technical/technical/deployment-guide/README.md new file mode 100644 index 000000000..7e45a52f2 --- /dev/null +++ b/docs/technical/technical/deployment-guide/README.md @@ -0,0 +1,487 @@ +# Mojaloop Deployment + +The document is intended for an audience with a stable technical knowledge that would like to setup an environment for development, testing and contributing to the Mojaloop project. + +## Deployment and Setup + +- [Mojaloop Deployment](#mojaloop-deployment) + - [Deployment and Setup](#deployment-and-setup) + - [1. Pre-requisites](#_1-pre-requisites) + - [2. Deployment Recommendations](#_2-deployment-recommendations) + - [3. Kubernetes](#_3-kubernetes) + - [3.1. Kubernetes Ingress Controller](#_3-1-kubernetes-ingress-controller) + - [3.2. Kubernetes Admin Interfaces](#_3-2-kubernetes-admin-interfaces) + - [4. Helm](#_4-helm) + - [4.1. Helm configuration](#_4-1-helm-configuration) + - [5. Mojaloop](#_5-mojaloop) + - [5.1. Backend Helm Deployment](#_5-1-prerequisite-backend-helm-deployment) + - [5.2. Mojaloop Helm Deployment](#_5-2-mojaloop-helm-deployment) + - [5.3. Verifying Ingress Rules](#_5-3-verifying-ingress-rules) + - [5.4. Testing Mojaloop](#_5-4-testing-mojaloop) + - [5.5. Testing Mojaloop with Postman](#_5-5-testing-mojaloop-with-postman) + - [6. Overlay Services/3PPI](#_6-overlay-services-3ppi) + - [6.1 Configuring a deployment for Third Party API support](#_6-1-configuring-a-deployment-for-third-party-api-support) + - [6.2 Validating and Testing the Third Party API](#_6-2-validating-and-testing-the-third-party-api) + - [6.2.1 Deploying the Simulators](#_6-2-1-deploying-the-simulators) + - [6.2.2 Provisioning the Environment](#_6-2-2-provisioning-the-environment) + - [6.2.3 Run the Third Party API Test Collection](#_6-2-3-run-the-third-party-api-test-collection) + +### 1. Pre-requisites + +Take particular care when choosing the software versions, as a miss-match may cause issues or incompatibilities. + +A list of the pre-requisite tool set required for the deployment of Mojaloop: + +- **Kubernetes** An open-source system for automating deployment, scaling, and management of containerized applications. Find out more about [Kubernetes](https://kubernetes.io). + + - **Recommended Versions** + + | Mojaloop Helm Chart Release Version | Recommended Kubernetes Version | + | ---------------------------------------------------------------- | -------------------------- | + | [v16.0.0](https://github.com/mojaloop/helm/releases/tag/v16.0.0) | v1.29 | + | [v15.0.0](https://github.com/mojaloop/helm/releases/tag/v15.0.0) | v1.24 - v1.25 | + | [v14.1.1](https://github.com/mojaloop/helm/releases/tag/v14.1.1) | v1.20 - v1.24 | + | [v14.0.0](https://github.com/mojaloop/helm/releases/tag/v14.0.0) | v1.20 - v1.21 | + | [v13.x](https://github.com/mojaloop/helm/releases/tag/v13.1.1) | v1.13 - v1.21 | + | [v12.x](https://github.com/mojaloop/helm/releases/tag/v12.0.0) | v1.13 - v1.20 | + | [v11.x](https://github.com/mojaloop/helm/releases/tag/v11.0.0) | v1.13 - v1.17 | + | [v10.x](https://github.com/mojaloop/helm/releases/tag/v10.4.0) | v1.13 - v1.15 | + + > NOTES: + > + > - Links above are to the latest major version (E.g. v13.x --> v13.1.1). + > - Refer to [https://github.com/mojaloop/helm/releases](https://github.com/mojaloop/helm/releases) for details on interim version. + > - `Recommend Kubernetes Version` column is the Kubernetes versions that have been tested and verified to work as expected against the matching `Mojaloop Helm Chart Release Version` column. + + - **kubectl** - Kubernetes CLI for Kubernetes Management is required. Find out more about [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/): + - [Install-kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) + +- **Helm** A package manager for Kubernetes. Find out more about [Helm](https://helm.sh) + + **Recommended Versions** + + - [Helm v3](https://helm.sh/docs/intro/install) + + > NOTES: + > + > - Refer to [Migration from Helm v2 to v3](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-migration.html) guide to migrate from Helm v2.x to v3.x. + +### 2. Deployment Recommendations + +This provides environment resource recommendations with a view of the infrastructure architecture. + +**Resources Requirements:** + +- Control Plane (i.e. Master Node) + + [https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components](https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components) + + - 3x Master Nodes for future node scaling and HA (High Availability) + +- ETCd Plane: + + [https://etcd.io/docs/latest/op-guide/hardware/](https://etcd.io/docs/latest/op-guide/hardware/) + + - 3x ETCd nodes for HA (High Availability) + +- Compute Plane (i.e. Worker Node): + + To be confirmed once load testing has been concluded. However the current general recommended size: + + - 3x Worker nodes, each being: + - 4x vCPUs, 16GB of RAM, and 40gb storage + + **Note** that this would also depend on your underlying infrastructure, and it does NOT include requirements for persistent volumes/storage. + +![Mojaloop Deployment Recommendations - Infrastructure Architecture](./assets/diagrams/deployment/KubeInfrastructureArch.svg) + +### 3. Kubernetes + +If you are installing Kubernetes yourself, then we recommend using one of the following Kubernetes flavours ensuring you install the desired matching version as specified in section [1. Pre-requisites](#1-pre-requisites): + +- [k3s](https://docs.k3s.io/installation) - Flexible lightweight Kubernetes distribution that can be used for almost anything, spanning from local to Production grade environments. +- [Minikube](https://minikube.sigs.k8s.io/docs/start) - Simple platform agnostic single-node Kubernetes distribution that is useful for local or development environments. +- [Microk8s](https://microk8s.io/docs/install-alternatives) - Simple platform Kubernetes distribution that is useful for local or development environments. +- [Docker Desktop](https://docs.docker.com/desktop/kubernetes/) - Simple platform Kubernetes distribution that is useful for local or development environments (ensure you install applicable version that includes your target Kubernetes version by examining the [Docker Desktop release-notes](https://docs.docker.com/desktop/release-notes)). + +We do not specify a specific distribution of Kubernetes to be used, but rather any distribution of Kubernetes running on a [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/certification/software-conformance) certified distribution or managed solution (e.g. Azure, AWS, GCP) should be selected when testing new Mojaloop Releases. + +If you are new to Kubernetes it is strongly recommended to familiarize yourself with Kubernetes. [Kubernetes Concepts](https://kubernetes.io/docs/concepts/overview/) is a good place to start and will provide an overview. + +Insure **kubectl** is installed. A complete set of installation instruction are available [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + +#### 3.1. Kubernetes Ingress Controller + +Install your preferred Ingress Controller for load-balancing and external access. + +Refer to the following documentation to install the Nginx-Ingress Controller used for this guide: . + +List of alternative Ingress Controllers: . + +Insure you install a supported `Ingress Controller` version that matches your target `Kubernetes` version. + +> **DEPLOYMENT TROUBLESHOOTING - Updated March 2023** +> +> - If you are using Mojaloop `v13.x` - `v14.0.x`, see [Deployment Troubleshooting - 1.1. Nginx-Ingress Controller support for Mojaloop Helm release v13.x - v14.0x.x support for Kubernetes v1.20 - v1.21](./depoyment/../deployment-troubleshooting.md#11-nginx-ingress-controller-support-for-mojaloop-helm-release-v13x---v140xx-support-for-kubernetes-v120---v121). +> +> - If you are using Mojaloop `v12.x`, see [Deployment Troubleshooting - 1.2. Nginx-Ingress Controller support for Mojaloop Helm release v12.x](./depoyment/../deployment-troubleshooting.md#12-nginx-ingress-controller-support-for-mojaloop-helm-release-v12x). +> +> - If you are using Mojaloop `v10.x`, see [Deployment Troubleshooting - 1.4.Mojaloop Helm release v10.x or less does not support Kubernetes v1.16 or greater](./depoyment/../deployment-troubleshooting.md#14-mojaloop-helm-release-v10x-or-less-does-not-support-kubernetes-v116-or-greater). +> + +#### 3.2. Kubernetes Admin Interfaces (Optional) + +1. Kubernetes Dashboards + + The official Kubernetes Web UI Admin interface. + + Visit the following link for installation instructions (not needed if **MicroK8s** is installed): [Web UI (Dashboard) Installation Instructions](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/). + + **IMPORTANT:** Ensure (not needed if **MicroK8s** is installed) you configure RBAC roles and create an associated service account, refer to the following example on how to create a sample user for testing purposes only: [Creating sample user](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md). + + If you have installed MicroK8s, **enable the MicroK8s** dashboard: + + ```bash + microk8s.enable dashboard + ``` + + Refer to the following link for more information: [Add-on: dashboard](https://microk8s.io/docs/addon-dashboard). + + **Remember** to prefix all **kubectl** commands with **MicroK8s** if you opted not to create an alias. + +2. k8sLens + + A local desktop GUI based kubectl alternative which is easy to install and setup. + + Visit the following link for more information: . + +### 4. Helm + +Please review [Mojaloop Helm Chart](../repositories/helm.md) to understand the relationships between the deployed Mojaloop helm charts. + +Refer to the official documentation on how to install the latest version of Helm: . + +Refer to the following document if are using Helm v2: [Deployment with (Deprecated) Helm v2](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-deployment.html). + +Refer to the [Helm v2 to v3 Migration Guide](https://docs.mojaloop.io/legacy/deployment-guide/helm-legacy-migration.html) if you wish to migrate an existing Helm v2 deployment to v3. + +#### 4.1. Helm configuration + +1. Add mojaloop repo to your Helm config: + + ```bash + helm repo add mojaloop https://mojaloop.io/helm/repo/ + ``` + + If the repo already exists, substitute 'add' with 'apply' in the above command. + +2. Update helm repositories: + + ```bash + helm repo update + ``` + +### 5. Mojaloop + +#### 5.1. Prerequisite Backend Helm Deployment + +Mojaloop has several external backend dependencies. + +We recommend deploying these dependencies in a separate named deployment. + +This example backend chart is provided purely as an example and should only be used for PoC, development and testing purposes. + +Further reading can be found [here](https://github.com/mojaloop/helm/blob/master/README.md#deploying-backend-dependencies). + +1. Deploy backend + + ```bash + helm --namespace demo install backend mojaloop/example-mojaloop-backend --create-namespace + ``` + +#### 5.2. Mojaloop Helm Deployment + +1. Install Mojaloop: + + 1.1. Installing latest version: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace + ``` + + Or if you require a customized configuration: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace -f {custom-values.yaml} + ``` + + Further reading can be found [here](https://github.com/mojaloop/helm/blob/master/README.md#deploying-mojaloop-helm-charts). + + _Note: Download and customize the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml). Also ensure that you are using the value.yaml (i.e. `https://github.com/mojaloop/helm/blob/v/mojaloop/values.yaml`) from the correct version which can be found via [Helm Releases](https://github.com/mojaloop/helm/releases). You can confirm the installed version by using the following command: `helm --namespace demo list`. Under the **CHART** column, you should see something similar to 'mojaloop-**{version}**' with **{version}** being the deployed version._ + + ```bash + $ helm -n demo list + NAME NAMESPACE REVISION UPDATED STATUS CHART + moja demo 1 2021-06-11 15:06:04.533094 +0200 SAST deployed mojaloop-{version} + ``` + + _Note: The `--create-namespace` flag is only necessary if the `demo` namespace does not exist. You can alternatively create it using the following command: `kubectl create namespace demo`._ + + 1.2. Version specific installation: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace --version {version} + ``` + + 1.3. List of Mojaloop releases: + + ```bash + $ helm search repo mojaloop/mojaloop -l + NAME CHART VERSION APP VERSION DESCRIPTION + mojaloop/mojaloop {version} {list of app-versions} Mojaloop Helm chart for Kubernetes + ... ... ... ... + ``` + +#### 5.3. Verifying Ingress Rules + +1. Update your /etc/hosts for local deployment: + + _Note: This is only applicable for local deployments, and is not needed if custom DNS or ingress rules are configured in a customized [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml)_. + + ```bash + vi /etc/hosts + ``` + + _Windows the file can be updated in notepad - need to open with Administrative privileges. File location `C:\Windows\System32\drivers\etc\hosts`_. + + Include the following lines (_or alternatively combine them_) to the host config. + + The below required config is applicable to Helm release >= versions 6.2.2 for Mojaloop API Services; + + ```bash + # Mojaloop Demo + 127.0.0.1 ml-api-adapter.local central-ledger.local account-lookup-service.local account-lookup-service-admin.local quoting-service.local central-settlement-service.local transaction-request-service.local central-settlement.local bulk-api-adapter.local moja-simulator.local sim-payerfsp.local sim-payeefsp.local sim-testfsp1.local sim-testfsp2.local sim-testfsp3.local sim-testfsp4.local mojaloop-simulators.local finance-portal.local operator-settlement.local settlement-management.local testing-toolkit.local testing-toolkit-specapi.local + ``` + +2. Test system health in your browser after installation. This will only work if you have an active helm chart deployment running. + + _Note: The examples below are only applicable to a local deployment. The entries should match the DNS values or ingress rules as configured in the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) or otherwise matching any custom ingress rules configured_. + + **ml-api-adapter** health test: + + **central-ledger** health test: + +#### 5.4. Testing Mojaloop + +The [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) is used for testing deployments, and has been integrated into Helm utilizing its CLI to easily test any Mojaloop deployment. + +1. Validating Mojaloop using Helm + + ```bash + helm -n demo test moja + ``` + + Or with logs printed to console + + ```bash + helm -n demo test moja --logs + ``` + + This will automatically execute the following [test cases](https://github.com/mojaloop/testing-toolkit-test-cases) using the [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) CLI: + + - [TTK Hub setup and Simulator Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning). + + Use the following command to view the provisioning Collection logs: + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-setup + ``` + + - [TTK Golden Path Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path). + + Use the following command to view the Golden Path Collection logs: + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-validation + ``` + + Example of the finally summary being displayed from the Golden Path test collection log output: + + ```bash + Test Suite:GP Tests + Environment:Development + ┌───────────────────────────────────────────────────┐ + │ SUMMARY │ + ├───────────────────┬───────────────────────────────┤ + │ Total assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Failed assertions │ 0 │ + ├───────────────────┼───────────────────────────────┤ + │ Total requests │ 297 │ + ├───────────────────┼───────────────────────────────┤ + │ Total test cases │ 61 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed percentage │ 100.00% │ + ├───────────────────┼───────────────────────────────┤ + │ Started time │ Fri, 11 Jun 2021 15:45:53 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Completed time │ Fri, 11 Jun 2021 15:47:25 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Runtime duration │ 91934 ms │ + └───────────────────┴───────────────────────────────┘ + TTK-Assertion-Report-multi-2021-06-11T15:47:25.656Z.html was generated + ``` + +2. Accessing the Mojaloop Testing Toolkit UI + + Open the following link in a browser: . + + One is able to manually load and execute the Testing Toolkit Collections using the UI which allows one to visually inspect the requests, responses and assertions in more detail. This is a great way to learn more about Mojaloop. + + Refer to the [Mojaloop Testing Toolkit Documentation](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) for more information and guides. + +#### 5.5. Testing Mojaloop with Postman + +[Postman](https://www.postman.com/downloads) can be used as an alternative to the [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md). Refer to the [Automated Testing Guide](../contributors-guide/tools-and-technologies/automated-testing.md) for more information. + +The available [Mojaloop Postman Collections](https://github.com/mojaloop/postman) are similar to the [Mojaloop Testing Toolkit's Test Cases](https://github.com/mojaloop/testing-toolkit-test-cases)'s as follows: + +| Postman Collection | Mojaloop Testing Toolkit | Description | +|---------|----------|---------| +| [MojaloopHub_Setup Postman Collection](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) and [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) | [TTK Hub setup and Simulator Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning) | Hub Setup and Simulator Provisioning | +| [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) | [TTK Golden Path Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path) | Golden Path Tests | + +Pre-requisites: + +- The following postman environment file should be imported or customized as required when running the above listed Postman collections: [Mojaloop-Local-MojaSims.postman_environment.json](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local-MojaSims.postman_environment.json). +- Ensure you download the **latest patch release version** from the [Mojaloop Postman Git Repository Releases](https://github.com/mojaloop/postman/releases). For example if you install Mojaloop v12.0.**X**, ensure that you have the latest Postman collection patch version v12.0.**Y**. + +### 6. Overlay Services/3PPI + +As of [R.C. v13.1.0](https://github.com/mojaloop/helm/tree/release/v13.1.0) of Mojaloop, Third Party API is supported and will be published with the official release of Mojaloop v13.1.0. +which allows Third Party Payment Initiators (3PPIs) the ability to request an account link from a DFSP and initiate +payments on behalf of users. + +> Learn more about 3PPI: +> - Mojaloop's [Third Party API](https://github.com/mojaloop/mojaloop-specification/tree/master/thirdparty-api) +> - 3rd Party Use Cases: +> - [3rd Party Account Linking](https://sandbox.mojaloop.io/usecases/3ppi-account-linking.html) +> - [3rd Party Initiated Payments](https://sandbox.mojaloop.io/usecases/3ppi-transfer.html) + + +#### 6.1 Configuring a deployment for Third Party API support + +Third Party API support is **off** by default on the Mojaloop deployment. You can enable it by editing your `values.yaml` +file with the following settings: + +```yaml +... +account-lookup-service: + account-lookup-service: + config: + featureEnableExtendedPartyIdType: true # allows the ALS to support newer THIRD_PARTY_LINK PartyIdType + + account-lookup-service-admin: + config: + featureEnableExtendedPartyIdType: true # allows the ALS to support newer THIRD_PARTY_LINK PartyIdType + +... + +thirdparty: + enabled: true +... +``` + +In addition, the Third Party API has a number of dependencies that must be deployed manually for the thirdparty services +to run. [mojaloop/helm/thirdparty](https://github.com/mojaloop/helm/tree/master/thirdparty) contains details of these +dependencies, and also provides example k8s config files that install these dependencies for you. + +```bash +# install redis and mysql for the auth-service +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-auth-svc/example_dependencies.yaml +# install mysql for the consent oracle +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-consent-oracle/example_dependencies.yaml + +# apply the above changes to your values.yaml file, and update your mojaloop installation to deploy thirdparty services: +helm upgrade --install --namespace demo moja mojaloop/mojaloop -f values.yaml +``` + +Once the helm upgrade has completed, you can verify that the third party services are up and running: + +```bash +kubectl get po | grep tp-api +# tp-api-svc-b9bf78564-4g59d 1/1 Running 0 7m17s + +kubectl get po | grep auth-svc +# auth-svc-b75c954d4-9vq7w 1/1 Running 0 8m5s + +kubectl get po | grep consent-oracle +# consent-oracle-849cb69769-vq4rk 1/1 Running 0 8m31s + + +# and also make sure the ingress is exposed correctly +curl -H "Host: tp-api-svc.local" /health +# {"status":"OK","uptime":3545.77290063,"startTime":"2021-11-04T05:41:32.861Z","versionNumber":"11.21.0","services":[]} + +curl -H "Host: auth-service.local" /health + +# {"status":"OK","uptime":3682.48869561,"startTime":"2021-11-04T05:43:19.056Z","versionNumber":"11.10.1","services":[]} + +curl -H "Host: consent-oracle.local" /health +# {"status":"OK","uptime":3721.520096665,"startTime":"2021-11-04T05:43:48.382Z","versionNumber":"0.0.8","services":[]} +``` + +> You can also add the following entries to your `/etc/hosts` file to make it easy to talk to the thirdparty services +> +> ```bash +> tp-api-svc.local auth-service.local consent-oracle.local +> ``` + +#### 6.2 Validating and Testing the Third Party API + +Once you have deployed the Third Party services, you need to deploy some simulators that are capable of simulating +the Third Party scenarios. + +##### 6.2.1 Deploying the Simulators + +Once again, you can do this by modifying your `values.yaml` file, this time under the `mojaloop-simulator` entry: + +```yaml +... + +mojaloop-simulator: + simulators: + ... + pisp: + config: + thirdpartysdk: + enabled: true + dfspa: + config: + thirdpartysdk: + enabled: true + dfspb: {} +... +``` + +The above entry will create 3 new sets of mojaloop simulators: + +1. `pisp` - a PISP +2. `dfspa` - a DFSP that supports the Third Party API +3. `dfspb` - a normal DFSP simulator that doesn't support the Third Party API, but can receive payments + +##### 6.2.2 Provisioning the Environment + +Once the above simulators have been deployed and are up and running, it's time to configure the Mojaloop Hub +and simulators so we can test the Third Party API. + +Use the [Third Party Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-provisioning-collection) +from the mojaloop/testing-toolkit-test cases to provision the Third Party environment and the simulators +you set up in the last step. + +##### 6.2.3 Run the Third Party API Test Collection + +Once the provisioning steps are completed, you can run the [Third Party Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-test-collection) +to test that the Third Party services are deployed and configured correctly. diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg b/docs/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg new file mode 100644 index 000000000..26b8dcd92 --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg @@ -0,0 +1,2 @@ + + diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd b/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd new file mode 100644 index 000000000..71f8607d9 --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.mmd @@ -0,0 +1,30 @@ +graph TD + step1["Step 1: Base Libraries
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing"] + step2["Step 2: First-level Dependencies
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib"] + step3["Step 3: Second-level Dependencies
    event-sdk"] + step4["Step 4: Circular Dependency Group
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components"] + step5["Step 5: Database Layer
    central-services-db"] + step6["Step 6: Platform Libraries
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib"] + step7["Step 7: Core Services
    central-ledger
    central-settlement"] + step8["Step 8: API Services
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service"] + step9["Step 9: Remaining Services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator"] + note1["Note: The Step 4 repositories
    have circular dependencies.
    Update them as a unit."] + %% Clear update sequence arrows + step1 --> step2 + step2 --> step3 + step3 --> step4 + step4 --> step5 + %% Handle dependencies that can be updated in parallel + step5 --> step7 + step6 --> step8 + %% Platform libraries need special handling + step4 --> step6 + %% Final services depend on all previous updates + step7 --> step9 + step8 --> step9 + %% Connect notes + step4 --- note1 + %% Styling + classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; + classDef note fill:#ffffcc,stroke:#333,stroke-width:1px; + class note1 note; \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg b/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg new file mode 100644 index 000000000..6d55a9b6c --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/repositoryUpdate/repository-update-sequence.svg @@ -0,0 +1 @@ +

    Step 1: Base Libraries
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing

    Step 2: First-level Dependencies
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib

    Step 3: Second-level Dependencies
    event-sdk

    Step 4: Circular Dependency Group
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components

    Step 5: Database Layer
    central-services-db

    Step 6: Platform Libraries
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib

    Step 7: Core Services
    central-ledger
    central-settlement

    Step 8: API Services
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service

    Step 9: Remaining Services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator

    Note: The Step 4 repositories
    have circular dependencies.
    Update them as a unit.

    \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg b/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg new file mode 100644 index 000000000..a5e597d9c --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Target Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Target Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Sync & Data Migration

    (Transform data to new Schema)
    Sync & Data M...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment
    +
    Backed Dependencies
    (MySQL, Kafka, etc)

    (Old Release)
    Mojaloop Current...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg b/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg new file mode 100644 index 000000000..894431623 --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Shared Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Shared Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment

    (Old Release)
    Mojaloop Current...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png new file mode 100644 index 000000000..736a5190c Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png differ diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml new file mode 100644 index 000000000..a87421d97 --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml @@ -0,0 +1,107 @@ +@startuml dependency-vulnerability-management-process +!theme cerulean + +skinparam ActivityBackgroundColor #f0f0f0 +skinparam ActivityBorderColor #333333 +skinparam ArrowColor #333333 +skinparam backgroundColor white +skinparam ActivityFontColor black +skinparam ActivityFontSize 14 +skinparam noteFontColor black +skinparam ArrowFontColor black +skinparam PartitionFontColor #000000 +skinparam PartitionFontStyle bold +skinparam PartitionBorderColor #333333 +skinparam PartitionBackgroundColor #f8f8f8 + +title Dependency Vulnerability Management Process + +start + +partition "Vulnerability Detection Tools" { + :Identify Vulnerability; + fork + :GitHub Dependabot Alerts; + fork again + :npm run audit:check; + note right: audit-ci.jsonc with allowlist + fork again + :Grype Image Scan; + note right: .grype.yaml with ignore section + end fork +} + +partition "Triage Process" { + :Triage Vulnerability; + :Assess Severity Level; + fork + :Critical: 1-3 days; + note right #FF6666: Immediate attention + fork again + :High: 30 days; + note right #FFCC66: High priority + fork again + :Medium: 60 days; + note right #FFFF66: Medium priority + fork again + :Low: 90 days; + note right #99FF99: Low priority + end fork + :Take action based on severity level\nand fix date targets; +} + +partition "Update Process" { + :Select Single Module to Update; + :Update package.json; + :Run Tests; + if (Tests Pass?) then (Yes) + :Create Pull Request; + else (No) + if (Cannot Fix?) then (Yes) + fork + :Update audit-ci.jsonc; + note right #F9E0FF: For npm issues + fork again + :Update .grype.yaml; + note right #F9E0FF: For container issues + end fork + :Create Pull Request; + else (No) + :Adjust Update; + note right #F9E0FF + Consider Alternative Solutions + Contact Package Maintainer + end note + :Run Tests Again; + endif + endif + :Code Review Process; + if (Review Result) then (Approved) + :Merge PR; + else (Changes Requested) + :Update PR; + endif +} + +partition "CI/CD" { + :CI/CD Pipeline; + :Security Checks; + fork + :audit-ci Check; + fork again + :Grype Scan; + end fork + if (Checks Pass?) then (Yes) + :Release/Publish; + else (No) + :Fix Security Issues; + endif +} + +if (More Vulnerabilities?) then (Yes) + :Return to Select Module; +else (No) + stop +endif + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg new file mode 100644 index 000000000..0ef88f1e5 --- /dev/null +++ b/docs/technical/technical/deployment-guide/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg @@ -0,0 +1,305 @@ + + Dependency Vulnerability Management Process + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dependency Vulnerability Management Process + + + + Vulnerability Detection Tools + + Identify Vulnerability + + + GitHub Dependabot Alerts + + + audit-ci.jsonc with allowlist + + npm run audit:check + + + .grype.yaml with ignore section + + Grype Image Scan + + + + Triage Process + + Triage Vulnerability + + Assess Severity Level + + + + Immediate attention + + Critical: 1-3 days + + + High priority + + High: 30 days + + + Medium priority + + Medium: 60 days + + + Low priority + + Low: 90 days + + + Take action based on severity level + and fix date targets + + + Update Process + + Select Single Module to Update + + Update package.json + + Run Tests + + Tests Pass? + Yes + No + + Create Pull Request + + Cannot Fix? + Yes + No + + + + For npm issues + + Update audit-ci.jsonc + + + For container issues + + Update .grype.yaml + + + Create Pull Request + + + Consider Alternative Solutions + Contact Package Maintainer + + Adjust Update + + Run Tests Again + + + + Code Review Process + + Review Result + Approved + Changes Requested + + Merge PR + + Update PR + + + + CI/CD + + CI/CD Pipeline + + Security Checks + + + audit-ci Check + + Grype Scan + + + Checks Pass? + Yes + No + + Release/Publish + + Fix Security Issues + + + Return to Select Module + + Yes + More Vulnerabilities? + No + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png new file mode 100644 index 000000000..551ea6515 Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/audit-check-script.png differ diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png new file mode 100644 index 000000000..4c14b2661 Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png differ diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png new file mode 100644 index 000000000..a77a907b2 Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png differ diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png new file mode 100644 index 000000000..d9d3a289b Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png differ diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png new file mode 100644 index 000000000..3a35c25b3 Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png differ diff --git a/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png new file mode 100644 index 000000000..2c313578f Binary files /dev/null and b/docs/technical/technical/deployment-guide/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png differ diff --git a/docs/technical/technical/deployment-guide/deployment-troubleshooting.md b/docs/technical/technical/deployment-guide/deployment-troubleshooting.md new file mode 100644 index 000000000..80b6bd732 --- /dev/null +++ b/docs/technical/technical/deployment-guide/deployment-troubleshooting.md @@ -0,0 +1,158 @@ +# Deployment Troubleshooting + +## 1. Known issues + +Refer to the **Mojaloop Helm Chart Release** notes for more information on known issues: [https://github.com/mojaloop/helm/releases](https://github.com/mojaloop/helm/releases). + +### 1.1. Nginx-Ingress Controller support for Mojaloop Helm release v13.x - v14.0x.x support for Kubernetes v1.20 - v1.21 + +If you are using Mojaloop `v13.x` - `v14.0.x`, and want to install the `Nginx-Ingress` controller, then it is recommended that you install `Nginx-Ingress Controller v0.47.0` along with `Kubernetes v1.20 - v1.21` due to breaking changes introduce in `Kubernetes v1.22`. + +If you are using helm, this can be done as follows: + +```bash +helm install ingress-nginx ingress-nginx --version="3.33.0" --repo https://kubernetes.thub.io/ingress-nginx +``` + +### 1.2. Nginx-Ingress Controller support for Mojaloop Helm release v12.x + +If you are installing Mojaloop v12.x with an Nginx-Ingress controller version newer than `v0.22.0`, ensure you create a custom [Mojaloop v12.0.0 values config](https://github.com/jaloop/helm/blob/v12.0.0/mojaloop/values.yaml) with the following changes prior to stall:** + +```YAML +## **LOOK FOR THIS LINE IN mojaloop/values.yaml CONFIG FILE** +mojaloop-simulator: + ingress: + ## nginx ingress controller >= v0.22.0 <-- **COMMENT THE FOLLOWING THREE LINES BELOW:** + # annotations: <-- COMMENTED + # nginx.ingress.kubernetes.io/rewrite-target: '/$2' <-- COMMENTED + # ingressPathRewriteRegex: (/|$)(.*) <-- COMMENTED + ## nginx ingress controller < v0.22.0 <-- **UNCOMMENT THE FOLLOWING THREE LINES LOW:** + annotations: + nginx.ingress.kubernetes.io/rewrite-target: '/' + ingressPathRewriteRegex: "/" +``` + +**Note: This is NOT necessary if you are installing Mojaloop v13.x or newer.** + +### 1.3. Docker Desktop Kubernetes support for Mojaloop v13.x - v14.0.x + +If you are installing Mojaloop `v13.x` - `v14.0.x`, on Windows or MacOS, it is recommend that you install [Docker Desktop v4.2.0](https://docs.docker.com/desktop/release-notes/#420) version as it comes packaged with Kubernetes v1.21.5 which meets Mojaloop `v13.x` - `v14.0.x` version which matches [Deployment Guide (1. Pre-requisites)](README.md#1-pre-requisites) recommendations. + +### 1.4. Mojaloop Helm release v10.x or less does not support Kubernetes v1.16 or greater + +#### 1.4.1 Description + +_Note: This is only applicable to Mojaloop Helm v10.x or less release._ + +When installing mojaloop helm charts, the following error occurs: + +```log +Error: validation failed: [unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta2", unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta2", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta1"] +``` + +#### 1.4.2 Reason + +In version 1.16 of Kubernetes breaking change has been introduced (more about it [in "Deprecations and Removals" of Kubernetes release notes](https://kubernetes.io/docs/setup/release/notes/#deprecations-and-removals). The Kubernetes API versions `apps/v1beta1` and `apps/v1beta2`are no longer supported and and have been replaced by `apps/v1`. + +Mojaloop helm charts v10 or less refer to deprecated ids, therefore it's not possible to install v10- on Kubernetes version above 1.15 without manually modification. + +Refer to the following issue for more info: [mojaloop/helm#219](https://github.com/mojaloop/helm/issues/219) + +#### 1.4.3 Fixes + +Ensure that you are deploying Mojaloop Helm charts v10.x or less on v1.15 of Kubernetes. + +## 2. Deployment issues + +### 2.1. `ERR_NAME_NOT_RESOLVED` Error + +#### 2.1.1 Description + +The following error is displayed when attempting to access an end-point (e.g. central-ledger.local) via the Kubernetes Service directly in a browser: `ERR_NAME_NOT_RESOLVED` + +#### 2.1.2 Fixes + +1. Verify that Mojaloop was deployed correctly (by checking that the helm chart(s) was installed) by executing: + + ```bash + helm list + ``` + + If the helm charts are not listed, see the [Deployment Guide - 5.1. Mojaloop Helm Deployment](./README.md#51-mojaloop-helm-deployment) section to install a chart. + +2. Ensure that all the Mojaloop Pods/Containers have started up correctly and are available through the Kubernetes dashboard. + +3. Note that the Mojaloop deployment via Helm can take a few minutes to initially startup depending on the system's available resources and specification. Expect this to take anything between 2-10 minutes. + +### 2.3. MicroK8s - Connectivity Issues + +#### 2.3.1 Description + +My pods can’t reach the internet or each other (but my MicroK8s host machine can). + +An example of this is that the Central-Ledger logs indicate that there is an error with the Broker transport as per the following example: + +```log +2019-11-05T12:28:10.470Z - info: Server running at: +2019-11-05T12:28:10.474Z - info: Handler Setup - Registering {"type":"prepare","enabled":true}! +2019-11-05T12:28:10.476Z - info: CreateHandler::connect - creating Consumer for topics: [topic-transfer-prepare] +2019-11-05T12:28:10.515Z - info: CreateHandler::connect - successfully connected to topics: [topic-transfer-prepare] +2019-11-05T12:30:20.960Z - error: Consumer::onError()[topics='topic-transfer-prepare'] - Error: Local: Broker transport failure) +``` + +#### 2.3.2 Fixes + +Make sure packets to/from the pod network interface can be forwarded to/from the default interface on the host via the iptables tool. Such changes can be made persistent by installing the iptables-persistent package: + +```bash +sudo iptables -P FORWARD ACCEPT +sudo apt-get install iptables-persistent +``` + +or, if using ufw: + +```bash +sudo ufw default allow routed +``` + +The MicroK8s inspect command can be used to check the firewall configuration: + +```bash +microk8s.inspect +``` + +## 3. Ingress issues + +### 3.1. Ingress rules are not resolving for Nginx Ingress v0.22 or later when installing Mojaloop Helm v12.x or less + +#### 3.1.1 Description + +_Note: This is only applicable to Mojaloop Helm v12.x or less release._ + +Ingress rules are unable to resolve to the correct path based on the annotations specified in the [values.yaml](https://github.com/mojaloop/helm/blob/v12.0.0/mojaloop/values.yaml) configuration files when using Nginx Ingress controllers v0.22 or later. + +This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### 3.1.2 Fixes + +Make the following change to Ingress annotations (from --> to) in the values.yaml files: + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/$1' +``` + +### 3.2. Ingress rules are not resolving for Nginx Ingress earlier than v0.22 + +#### 3.2.1 Description + +Ingress rules are unable to resolve to the correct path based on the annotations specified in the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) configuration files when using Nginx Ingress controllers that are older than v0.22. + +This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### 3.2.2 Fixes + +Make the following change to all Ingress annotations (from --> to) in each of the values.yaml files: + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/$1'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/' +``` diff --git a/docs/technical/technical/deployment-guide/mojaloop-repository-update-guide.md b/docs/technical/technical/deployment-guide/mojaloop-repository-update-guide.md new file mode 100644 index 000000000..d4aa81c5d --- /dev/null +++ b/docs/technical/technical/deployment-guide/mojaloop-repository-update-guide.md @@ -0,0 +1,175 @@ +# Mojaloop Repository Update Sequence + +This document provides guidance on the order in which Mojaloop NodeJS repositories should be updated when releasing new features and/or maintaining Mojaloop. This is important to ensure that each of the services part of a Mojaloop Release use the correct Mojaloop repository dependency. This is the update as of Mojaloop RC v17; as Mojaloop evolves, this needs to be updated with new components (and clean up components that are removed). + +## Table of Contents + +- [NodeJS Repository Update Sequence](#nodejs-repository-update-sequence) + - [Table of Contents](#table-of-contents) + - [Repository Categories](#repository-categories) + - [Update Process](#update-process) + - [Testing Requirements](#testing-requirements) + - [Mojaloop Repo Sequence](#mojaloop-repo-sequence) + +## Repository Categories + +The following are the categories of Mojaloop NodeJS repositories: + +1. **Central Services libraries** + - `central-services-shared` + - `central-services-error-handling` + - `central-services-database` + - `central-services-stream` + - `central-services-metrics` + - `central-services-error` + - `central-services-logger` + - `sdk-standard-components` + +2. **Core Services** + - `account-lookup-service` + - `quoting-service` + - `central-ledger` + - `central-settlement` + - `central-bulk-transfers` + - `transaction-requests-service` + - `ml-api-adapter` + +3. **Event Components** + - `central-event-processor` + - `event-framework` + - `event-stream-processor` + - `elastic-apm-node` + - `elastic-apm-node-opentracing` + - `email-notifier` + - `event-sidecar` + +4. **Adapters, SDK and API** + - `sdk-scheme-adapter` + - `event-sdk` + - `thirdparty-sdk` + - `bulk-api-adapter` + - `thirdparty-api-svc` + - `als-consent-oracle` + - `als-oracle-pathfinder` + +5. **Testing** + - `ml-testing-toolkit` + - `ml-testing-toolkit-client-lib` + - `ml-testing-toolkit-ui` + - `ml-testing-toolkit-shared-lib` + - `mojaloop-simulator` + - `simulator` + +6. **Other libraries** + - `api-snippets` + - `auth-service` + - `ml-number` + - `object-store-lib` + - `inter-scheme-proxy-cache-lib` + - `database-lib` + +## Update Process + +1. **Identify Dependencies** + - Use `npm audit` to identify vulnerabilities + - Review `package.json` files for outdated dependencies + - Check for breaking changes in major version updates + +2. **Create Update Plan** + - Document all repositories that need updates + - Identify potential breaking changes + - Plan testing strategy for each component + +3. **Execute Updates** + - Start with core libraries + - Update one repository at a time + - Run tests after each update + - Document any issues or workarounds + +4. **Integration Testing** + - Test updated components together + - Verify end-to-end functionality + - Check for performance impacts (roadmap, post v17) + +## Testing Requirements + +For each repository, follow the testing instructions at README and run: + +1. **Unit Tests** + - Run existing test suite + - Add new tests for updated functionality + - Verify test coverage + +2. **Integration Tests** + - Test with dependent services + - Verify API compatibility + - Check event handling + +3. **End-to-End Tests** + - Run through Mojaloop testing toolkit + - Verify transaction flows + - Test error scenarios + + +## Mojaloop Repo Sequence + +The following table provides a detailed view of Mojaloop repositories and their dependencies. This information is crucial for understanding the correct order of updates when addressing dependency changes or vulnerabilities. + +| Sequence | Repo | Dependencies | +|---|---|---| +| 1 | api-snippets | | +| 2 | ml-number | | +| 3 | database-lib | | +| 4 | central-services-logger | | +| 5 | central-services-metrics | | +| 6 | central-services-error-handling | | +| 7 | ml-testing-toolkit-shared-lib | | +| 8 | logging-bc-public-types-lib | | +| 9 | platform-shared-lib-messaging-types-lib | | +| 10 | elastic-apm-node | | +| 11 | elastic-apm-node-opentracing | | +| 12 | object-store-libp | central-services-logger | +| 13 | central-services-stream | | +| 14 | central-services-health | central-services-error-handling, central-services-logger | +| 15 | event-sdk | central-services-stream, central-services-logger, central-services-stream | +| 16 | inter-scheme-proxy-cache-lib | central-services-logger, central-services-shared, inter-scheme-proxy-cache-lib, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 17 | ml-schema-transformer-lib | central-services-error-handling, central-services-logger, central-services-shared, sdk-standard-components, ml-schema-transformer-lib | +| 18 | sdk-standard-components | | +| 19 | central-services-shared | | +| 20 | platform-shared-lib-nodejs-kafka-client-lib | | +| 21 | logging-bc-client-lib | | +| 22 | **account-lookup-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, database-lib, event-sdk, inter-scheme-proxy-cache-lib, sdk-standard-components, sdk-standard-components, central-services-logger, central-services-shared, central-services-stream | +| 23 | **als-consent-oracle** | api-snippets, central-services-health, central-services-shared, sdk-standard-components, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 24 | **als-oracle-pathfinder** | central-services-logger, central-services-shared | +| 25 | **auth-service** | api-snippets, central-services-health, central-services-shared, event-sdk, sdk-standard-components, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 26 | **bulk-api-adapter** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, object-store-lib | +| 27 | **central-event-processor** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk | +| 28 | **central-ledger** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, database-lib, event-sdk, inter-scheme-proxy-cache-lib, ml-number, object-store-lib | +| 29 | **central-settlement** | central-ledger, central-services-database, central-services-error-handling, central-services-health, central-services-logger, central-services-shared, central-services-stream, event-sdk, ml-number | +| 30 | **email-notifier** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk | +| 31 | **event-sidecar** | central-services-logger, central-services-metrics, central-services-stream, event-sdk | +| 32 | **event-stream-processor** | central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, elastic-apm-node, elastic-apm-node-opentracing, event-sdk | +| 33 | **mojaloop-simulator** | central-services-logger | +| 34 | **ml-api-adapter** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, sdk-standard-components, database-lib, inter-scheme-proxy-cache-lib | +| 35 | **ml-testing-toolkit** | central-services-logger, central-services-metrics, ml-schema-transformer-lib, ml-testing-toolkit-shared-lib, sdk-standard-components | +| 36 | **ml-testing-toolkit-client-lib** | central-services-logger, ml-testing-toolkit-shared-lib, sdk-standard-components | +| 37 | **ml-testing-toolkit-ui** | ml-testing-toolkit-shared-lib | +| 38 | **quoting-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, central-services-stream, event-sdk, inter-scheme-proxy-cache-lib, ml-number, sdk-standard-components | +| 39 | **simulator** (legacy, ALS oracle) | central-services-error-handling, central-services-logger, central-services-metrics, central-services-shared, event-sdk, sdk-standard-components | +| 40 | **sdk-scheme-adapter** | api-snippets, central-services-error-handling, central-services-logger, central-services-metrics, central-services-shared, event-sdk, sdk-standard-components | +| 41 | **thirdparty-api-svc** | api-snippets, central-services-shared, central-services-stream, central-services-error-handling, central-services-logger, central-services-metrics, event-sdk | +| 42 | **thirdparty-sdk** | api-snippets, central-services-error-handling, central-services-metrics, central-services-shared, sdk-scheme-adapter, sdk-standard-components | +| 43 | **transaction-requests-service** | central-services-error-handling, central-services-health, central-services-logger, central-services-metrics, central-services-shared, event-sdk, ml-testing-toolkit-shared-lib | + +### Update Sequence Visualization + +The following diagram illustrates the recommended update sequence for Mojaloop repositories, taking into account their dependencies and relationships: + +![Repository Update Sequence](./assets/diagrams/repositoryUpdate/repository-update-sequence.svg) + +This diagram provides a visual representation of the update sequence, showing: +1. The logical grouping of repositories +2. Dependencies between different groups +3. Special cases like circular dependencies +4. Parallel update possibilities +5. Different types of dependencies to consider \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/nodejs-dependency-update-guide.md b/docs/technical/technical/deployment-guide/nodejs-dependency-update-guide.md new file mode 100644 index 000000000..53d368de3 --- /dev/null +++ b/docs/technical/technical/deployment-guide/nodejs-dependency-update-guide.md @@ -0,0 +1,41 @@ +The following diagram illustrates the recommended update sequence for Mojaloop repositories, taking into account their dependencies and relationships: + +```mermaid +graph TD + step1["Step 1: Base Libraries
    api-snippets
    ml-number
    central-services-logger
    central-services-metrics
    central-services-error-handling
    ml-testing-toolkit-shared-lib
    elastic-apm-node
    elastic-apm-node-opentracing"] + step2["Step 2: First-level Dependencies
    object-store-lib
    central-services-stream
    central-services-health
    inter-scheme-proxy-cache-lib"] + step3["Step 3: Second-level Dependencies
    event-sdk"] + step4["Step 4: Circular Dependency Group
    central-services-shared
    ml-schema-transformer-lib
    sdk-standard-components"] + step5["Step 5: Database Layer
    central-services-db"] + step6["Step 6: Platform Libraries
    logging-bc-public-types-lib
    platform-shared-lib-messaging-types-lib
    platform-shared-lib-nodejs-kafka-client-lib
    logging-bc-client-lib"] + step7["Step 7: Core Services
    central-ledger
    central-settlement"] + step8["Step 8: API Services
    sdk-scheme-adapter
    ml-api-adapter
    account-lookup-service
    auth-service"] + step9["Step 9: Remaining Services
    event-stream-processor
    event-sidecar
    central-event-processor
    bulk-api-adapter
    email-notifier
    ml-testing-toolkit
    ml-testing-toolkit-client-lib
    ml-testing-toolkit-ui
    quoting-service
    thirdparty-api-svc
    thirdparty-sdk
    transaction-requests-service
    als-oracle-pathfinder
    als-consent-oracle
    mojaloop-simulator
    simulator"] + note1["Note: The Step 4 repositories
    have circular dependencies.
    Update them as a unit."] + %% Clear update sequence arrows + step1 --> step2 + step2 --> step3 + step3 --> step4 + step4 --> step5 + %% Handle dependencies that can be updated in parallel + step5 --> step7 + step6 --> step8 + %% Platform libraries need special handling + step4 --> step6 + %% Final services depend on all previous updates + step7 --> step9 + step8 --> step9 + %% Connect notes + step4 --- note1 + %% Styling + classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; + classDef note fill:#ffffcc,stroke:#333,stroke-width:1px; + class note1 note; +``` + +This diagram provides a visual representation of the update sequence, showing: +1. The logical grouping of repositories +2. Dependencies between different groups +3. Special cases like circular dependencies +4. Parallel update possibilities +5. Different types of dependencies to consider \ No newline at end of file diff --git a/docs/technical/technical/deployment-guide/upgrade-strategy-guide.md b/docs/technical/technical/deployment-guide/upgrade-strategy-guide.md new file mode 100644 index 000000000..f7ee9a0df --- /dev/null +++ b/docs/technical/technical/deployment-guide/upgrade-strategy-guide.md @@ -0,0 +1,188 @@ +# Upgrade Strategy Guide + +This document provides instructions on how to upgrade existing Mojaloop installations. It assumes that Mojaloop is already installed using Helm, but these strategies can be applied in general. + +## Table of Contents + +- [Upgrade Strategy Guide](#upgrade-strategy-guide) + - [Table of Contents](#table-of-contents) + - [Helm Upgrades](#helm-upgrades) + - [Non-breaking Releases](#non-breaking-releases) + - [Breaking Releases](#breaking-releases) + - [Mojaloop installed without backend dependencies](#mojaloop-installed-without-backend-dependencies) + - [1. Target version has no datastore breaking changes](#1-target-version-has-no-datastore-breaking-changes) + - [Example Canary style deployment](#example-canary-style-deployment) + - [2. Target version has datastore breaking changes](#2-target-version-has-datastore-breaking-changes) + - [Mojaloop installed with backend dependencies](#mojaloop-installed-with-backend-dependencies) + - [Example Blue-green style deployment](#example-blue-green-style-deployment) + - [Upgrade Commands](#upgrade-commands) + - [Upgrade to v17.0.0](#upgrade-to-v1700) + - [Testing the upgrade scenario from v16.0.0 to v17.0.0](#testing-the-upgrade-scenario-from-v1600-to-v1700) + +## Helm Upgrades + +This section discusses the strategies of how upgrades could be applied to an existing Mojaloop Helm deployment that uses the [Mojaloop Helm Charts](https://github.com/mojaloop/helm). + +The scope of the breaking changes described below are applicable to the Switch Operator's Helm deployment with no direct impact (i.e. no functional changes such as a new Mojaloop API Specification version) to Participants (e.g. Financial Services Providers). Such functional changes may be part of a Helm release, but are out of scope for this section. + +Recommendations: + +1. All upgrades should be tested and verified in a pre-production (Test or QA) environment +2. Always consult the release notes as there may be some known issues, or useful notes that are applicable when upgrading +3. The [migrate:list command](https://knexjs.org/#Migrations) can be used to list pending datastore changes in the following repositories: + - + - + +### Non-breaking Releases + +Non-breaking changes will require no additional or special actions (unless otherwise stated in the release notes) to be taken other than running a standard [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade) command. + +Be aware of the following optional parameter flag(s) that will be useful when upgrading: + +``` + -i, --install if a release by this name doesn't already exist, run an install + --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +See the following example of how these parameters can be applied: + +```bash +helm --namespace ${NAMESPACE} ${RELEASE_NAME} upgrade --install mojaloop/mojaloop --reuse-values --version ${RELEASE_VERSION} +``` + +It is possible to rollback using the [Helm rollback](https://helm.sh/docs/helm/helm_rollback/) command if desired. + +### Breaking Releases + +There are several strategies that can be employed when upgrading between breaking releases depending on the following deployment topologies: + +1. Mojaloop installed without backend dependencies (e.g. Kafka, MySQL, MongoDB, etc), with backend dependencies managed separately. This is preferred and will provide the most flexibility in upgrading, especially when there are breaking changes + +2. Mojaloop installed with backend dependencies, with backend dependencies tightly coupled to the Helm installation + + > *NOTE: This process will be deprecated from Mojaloop v15.0.0 onwards (including v15) though example backend deployment support is provided for testing, QA. Refer to section [5. BREAKING CHANGES](https://github.com/mojaloop/helm/blob/master/.changelog/release-v15.0.0.md#5-breaking-changes) section in the [v15.0.0 Release Notes](https://github.com/mojaloop/helm/blob/master/.changelog/release-v15.0.0.md).* + + +#### Mojaloop installed without backend dependencies + +This is the preferred deployment topology as it will provide the most flexibility when upgrading. By separating out the backend dependencies, it will enable one to deploy the target version of Mojaloop as a new deployment. + +This new deployment can either point to the existing backend dependencies or will require new backend dependencies depending on the following: + +##### 1. Target version has no datastore breaking changes + +In this scenario, we can utilise a Canary style deployment strategy by configuring the new deployment to the existing backend dependencies. The new deployment will by default upgrade the datastore schemas as required by running the `migration` (see [Central-ledger](https://github.com/mojaloop/central-ledger/tree/master/migrations), [Account-lookup-service](https://github.com/mojaloop/account-lookup-service/tree/master/migrations)) scripts. Alternatively, the migration scripts can be disabled (e.g. [central-ledger](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml#L147), with Account-lookup-service similarly being configured) if required, and a manual upgrade SQL script can be prepared (see [migrate:list command](https://knexjs.org/#Migrations) to list pending changes) if preferred. + +There should be no disruption to the current Mojaloop deployment. + +As the backend dependencies are shared between the current and target deployments, it will also be possible to move a sub-set of users to the target Mojaloop deployment allowing for one to validate the new deployment with minimal impact, and also provide the ability for users to easily switch back to the current deployment. + +###### Example Canary style deployment + +![Helm Canary Upgrade Strategy](./assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg) + +1. Customize the [Mojaloop Chart values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) for the desired target Mojaloop release: + 1. Ensure backend-end configurations are set to the existing (shared) deployed Backend dependencies + 2. If applicable, ensure ingress-rules do not overwrite the current deployment configuration +2. Deploy the target Mojaloop release (Blue) + 1. Monitor the migration script logs for any upgrade errors via the `run-migration` containers: + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=centralledger-service -c run-migration` + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=account-lookup-service-admin -c run-migration` +3. Execute sanity tests on the Current Green deployment environment (verify impact of datastore changes, and allow for rollback, or partial switch-over for DFSPs, etc) +4. Execute sanity tests on the Target Blue deployment environment +5. Cut-over API Gateway (or upgrade target Ingress rules) to from Current Green to Target Blue deployment environment + +##### 2. Target version has datastore breaking changes + +#### Mojaloop installed without backend dependencies +In this scenario, we can utilise the inplace helm upgrade of backend dependencies. +A maintenance window need to be scheduled to stop "live" transaction on the current deployment to ensure data consistency, and allow for the switch-over to occur safely. This will cause a disruption, but can be somewhat mitigated by ensuring that the maintenance window is scheduled during the least busiest time. + +It is very important to take the backup of the database in case we need to rollback to previous version + +1. Schedule upgrade window +2. Backup the databases +3. Customize the [Mojaloop Chart values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) for the desired target Mojaloop release +4. Uninstall the mojaloop services +5. Upgrade the backend dependencies using +```bash +helm upgrade ${RELEASE_NAME} mojaloop/example-mojaloop-backend --namespace ${NAMESPACE} --version ${RELEASE_VERSION} +``` +6. Install mojaloop services +```bash +helm install ${RELEASE_NAME} mojaloop/mojaloop --namespace ${NAMESPACE} --version ${RELEASE_VERSION} -f {$VALUES_FILE} +``` +7. Execute sanity tests +8. If you need to rollback then (make sure database backup was taken before the upgrade) + 1. use `helm rollback` command to rollback to previous version of backend dependencies + 2. load the database from the backup ( to ensure the datastore is in correct state) + 3. install previous version of mojaloop services + +#### Mojaloop installed with backend dependencies (Version 15 or older) + +In this scenario, we can utilise a Blue-green style deployment strategy by deploying new backend dependencies, and deploying the target Mojaloop release separately (with the additional benefit of aligning your deployment to the recommending deployment topology). + +Manual data migrating from the existing datastores to the new target backend dependencies will be required. It will also be necessary to keep the current and new datastores in sync as long as live transactions are being processed through the existing Mojaloop deployment. A maintenance window need to be scheduled to stop "live" transaction on the current deployment to ensure data consistency, and allow for the switch-over to occur safely. This will cause a disruption, but can be somewhat mitigated by ensuring that the maintenance window is scheduled during the least busiest time. + +##### Example Blue-green style deployment + +![Helm Blue-green Upgrade Strategy](./assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg) + +1. Customize the [Mojaloop Chart values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) for the desired target Mojaloop release: + 1. Ensure backend-end configurations are set to the target deployed Backend dependencies + 2. If applicable, ensure ingress-rules do not overwrite the current deployment configuration +2. Deploy the target Mojaloop release (Blue) +3. Create Migration process to sync and transform data into target deployed Backend datastore dependencies from Green to Blue +4. Schedule cut-over window +5. Execute cut-over during window + 1. Set current Green Backend datastore dependencies to read-only (where possible) + 2. Drain any remaining connections from Green + 3. Ensure Migration process is fully in-sync from Green to Blue + 4. Execute sanity tests on the Blue Target deployment environment + 5. Cut-over API Gateway (or upgrade target Ingress rules) to from Green Current to Blue Target deployment environment + + +## Upgrade Commands + +This document provides commands to upgrade existing Mojaloop installations. It assumes that Mojaloop is already installed using Helm. + +### Upgrade to v17.0.0 + +1. Upgrade the backend dependencies +```bash +helm upgrade backend mojaloop/example-mojaloop-backend --namespace ${NAMESPACE} --version v17.0.0 -f ${VALUES_FILE} +``` +2. Install the mojaloop services +```bash +helm install moja mojaloop/mojaloop --namespace ${NAMESPACE} --version v17.0.0 -f ${VALUES_FILE} +``` + +#### Testing the upgrade scenario from v16.0.0 to v17.0.0 + +1. Install backend dependencies v16.0.0 with persistence enabled (need to create databases manually since the initDb scripts will not run) +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/example-mojaloop-backend --version 16.0.0 -f ${VALUES_FILE} +``` +2. Install the mojaloop services v16.0.0 and run tests to create data in databases +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/mojaloop --version 16.0.0 -f ${VALUES_FILE} +``` +3. Uninstall the mojaloop services +```bash +helm delete ${RELEASE} --namespace ${NAMESPACE} +``` +4. Upgrade the backend dependencies to v17.0.0 (This will upgrade mysql/Kafka/MongoDB versions) +```bash +helm --namespace ${NAMESPACE} upgrade ${RELEASE} mojaloop/example-mojaloop-backend --version 17.0.0 -f ${VALUES_FILE} +``` +5. Install the mojaloop services v17.0.0 (This will run the knex migrations to upgrade the database schemas) +```bash +helm --namespace ${NAMESPACE} install ${RELEASE} mojaloop/mojaloop --version 17.0.0 -f ${VALUES_FILE} +``` +6. Run the GP Tests +```bash +helm test ${RELEASE} --namespace=${NAMESPACE} --logs +``` + + diff --git a/docs/technical/technical/event-framework/README.md b/docs/technical/technical/event-framework/README.md new file mode 100644 index 000000000..d1a0f5ece --- /dev/null +++ b/docs/technical/technical/event-framework/README.md @@ -0,0 +1,233 @@ +# Event Framework + +The purpose of the Event Framework is to provide a standard unified architecture to capture all Mojaloop events. + +_Disclaimer: This is experimental and is being implemented as a PoC. As such the design may change based on the evolution of the PoC's implementation, and any lessons learned._ + + +## 1. Requirements + +- Events will be produced by utilising a standard common library that will publish events to a sidecar component utilising a light-weight highly performant protocol (e.g. gRPC). +- Sidecar module will publish events to a singular Kafka topic that will allow for multiple handlers to consume and process the events as required. +- Kafka partitions will be determined by the event-type (e.g. log, audit, trace, errors etc). +- Each Mojaloop component will have its own tightly coupled Sidecar. +- Event messages will be produced to Kafka using the Trace-Id as the message key. This will ensure that all the messages part of the same trace (transaction) are stored in the same partition in order. + + +## 2. Architecture + +### 2.1 Overview + +![Event Framework Architecture](./assets/diagrams/architecture/architecture-event-framework.svg) + +### 2.2 Micro Service Pods + +![Pod Architecture](./assets/diagrams/architecture/architecture-event-sidecar.svg) + +### 2.3 Event Flow + +![Tracing Architecture](./assets/diagrams/architecture/architecture-event-trace.svg) + + +## 3. Event Envelope Model + +## 3.1 JSON Example + +```JSON +{ + "from": "noresponsepayeefsp", + "to": "payerfsp", + "id": "aa398930-f210-4dcd-8af0-7c769cea1660", + "content": { + "headers": { + "content-type": "application/vnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "noresponsepayeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": "data:application/vnd.interoperability.transfers+json;version=1.0;base64,ewogICJmdWxmaWxtZW50IjogIlVObEo5OGhaVFlfZHN3MGNBcXc0aV9VTjN2NHV0dDdDWkZCNHlmTGJWRkEiLAogICJjb21wbGV0ZWRUaW1lc3RhbXAiOiAiMjAxOS0wNS0yOVQyMzoxODozMi44NTZaIiwKICAidHJhbnNmZXJTdGF0ZSI6ICJDT01NSVRURUQiCn0" + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7-3978-408e-ae2e-a13012c47739", + "parentSpanId": "4e3ce424-d611-417b-a7b3-44ba9bbc5840", + "spanId": "efeb5c22-689b-4d04-ac5a-2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } +} +``` + +## 3.2 Schema Definition + +### 3.2.1 Object Definition: EventMessage + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | The id references the related message. | | +| from | string | N | If the value is not present in the destination, it means that the notification was generated by the connected node (server). | | +| to | string | Y | Mandatory for the sender and optional in the destination. The sender can ommit the value of the domain. | | +| pp | string | N | Optional for the sender, when is considered the identity of the session. Is mandatory in the destination if the identity of the originator is different of the identity of the from property. | | +| metadata | object `` | N | The sender should avoid to use this property to transport any kind of content-related information, but merely data relevant to the context of the communication. Consider to define a new content type if there's a need to include more content information into the message. | | +| type | string | Y | `MIME` declaration of the content type of the message. | | +| content | object \ | Y | The representation of the content. | | + +##### 3.2.1.1 Object Definition: MessageMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| event | object `` | Y | Event information. | | +| trace | object `` | Y | Trace information. | | + +##### 3.2.1.2 Object Definition: EventMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | Generated UUIDv4 representing the event. | 3920382d-f78c-4023-adf9-0d7a4a2a3a2f | +| type | enum `` | Y | Type of event. | [`log`, `audit`, `error` `trace`] | +| action | enum `` | Y | Type of action. | [ `start`, `end` ] | +| createdAt | timestamp | Y | ISO Timestamp. | 2019-05-29T23:18:32.935Z | +| responseTo | string | N | UUIDv4 id link to the previous parent event. | 2019-05-29T23:18:32.935Z | +| state | object `` | Y | Object describing the state. | | + +##### 3.2.1.3 Object Definition: EventStateMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| status | enum `` | Y | The id references the related message. | success | +| code | number | N | The error code as per Mojaloop specification. | 2000 | +| description | string | N | Description for the status. Normally used to include an description for an error. | Generic server error to be used in order not to disclose information that may be considered private. | + +##### 3.2.1.4 Object Definition: EventTraceMetaData + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| service | string | Y | Name of service producing trace | central-ledger-prepare-handler | +| traceId | 32HEXDIGLC | Y | The end-to-end transaction identifier. | 664314d5b207d3ba722c6c0fdcd44c61 | +| spanId | 16HEXDIGLC | Y | Id for a processing leg identifier for a component or function. | 81fa25e8d66d2e88 | +| parentSpanId | 16HEXDIGLC | N | The id references the related message. | e457b5a2e4d86bd1 | +| sampled | number | N | Indicator if event message should be included in the trace `1`. If excluded it will be left the consumer to decide on sampling. | 1 | +| flags | number | N | Indicator if event message should be included in the trace flow. ( Debug `1` - this will override the sampled value ) | 0 | +| startTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the start timestamp of a span.| 2015-08-29T11:22:09.815479Z | +| finishTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the finish timestamp of a span | 2015-08-29T11:22:09.815479Z | +| tags | object `` | Y | The id references the related message. | success | + +_Note: HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lower case hex character. Ref: [WC3 standard for trace-context](https://www.w3.org/TR/trace-context/#field-value)._ + +##### 3.2.1.5 Object Definition: EventTraceMetaDataTags + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| transactionId | string | N | Transaction Id representing either a transfer, quote, etc | 659ee338-c8f8-4c06-8aff-944e6c5cd694 | +| transactionType | string | N | The transaction type represented by the transactionId. E.g. (transfer, quote, etc) | transfer | +| parentEventType | string | N | The event-type of the parent Span. | bulk-prepare | +| parentEventAction | string | N | The event-action of the parent Span. | prepare | +| tracestate | string | N | This tag is set if EventSDK environmental variable `EVENT_SDK_TRACESTATE_HEADER_ENABLED` is `true` or if parent span context has the `tracestate` header or tag included. The tag holds updated `tracestate` header value as per the W3C trace headers specification. [More here](#411-wc3-http-headers)| `congo=t61rcWkgMzE,rojo=00f067aa0ba902b7` | +| `` | string | N | Arbitary Key-value pair for additional meta-data to be added to the trace information. | n/a | + +##### 3.2.1.6 Enum: EventStatusType + +| Enum | Description | +| --- | --- | +| success | Event was processed successfully | +| fail | Event was processed with a failure or error | + +##### 3.2.1.7 Enum: EventType + +| Enum | Description | +| --- | --- | +| log | Event representing a general log entry. | +| audit | Event to be signed and persisted into the audit store. | +| trace | Event containing trace context information to be persisted into the tracing store. | + +##### 3.2.1.8 Enum: LogEventAction + +| Enum | Description | +| --- | --- | +| info | Event representing an `info` level log entry. | +| debug | Event representing a `debug` level log entry. | +| error | Event representing an `error` level log entry. | +| verbose | Event representing a `verbose` level log entry. | +| warning | Event representing a `warning` level log entry. | +| performance | Event representing a `performance` level log entry. | + +##### 3.2.1.9 Enum: AuditEventAction + +| Enum | Description | +| --- | --- | +| default | Standard audit action. | +| start | Audit action to represent the start of a process. | +| finish | Audit action to represent the end of a process. | +| ingress | Audit action to capture ingress activity. | +| egress | Audit action to capture egress activity. | + +##### 3.2.1.10 Enum: TraceEventAction + +| Enum | Description | +| --- | --- | +| span | Event action representing a span of a trace. | + + +## 4. Tracing Design + +### 4.1 HTTP Transports + +Below find the current proposed standard HTTP Transport headers for tracing. + +Mojaloop has yet to standardise on either standard, or if it will possible support both. + +#### 4.1.1 W3C Http Headers + +Refer to the following publication for more information: https://w3c.github.io/trace-context/ + +| Header | Description | Example | +| --- | --- | --- | +| traceparent | Dash delimited string of tracing information: \-\-\-\ | 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00 | +| tracestate | Comma delimited vendor specific format captured as follows: \=\| congo=t61rcWkgMzE,rojo=00f067aa0ba902b7 | + +Note: Before this specification was written, some tracers propagated X-B3-Sampled as true or false as opposed to 1 or 0. While you shouldn't encode X-B3-Sampled as true or false, a lenient implementation may accept them. + +Note: (Event-SDK)[https://github.com/mojaloop/event-sdk] since version v9.4.1 has methods to add key value tags in the tracestate, and since version v9.5.2 the tracestate is base64 encoded. To be able to use the tracestate consistently, use matching versions across all services in a system. + +#### 4.1.2 B3 HTTP Headers + +Refer to the following publication for more information: https://github.com/apache/incubator-zipkin-b3-propagation + +| Header | Description | Example | +| --- | --- | --- | +| X-B3-TraceId | Encoded as 32 or 16 lower-hex characters. | a 128-bit TraceId header might look like: X-B3-TraceId: 463ac35c9f6413ad48485a3953bb6124. Unless propagating only the Sampling State, the X-B3-TraceId header is required. | +| X-B3-SpanId | Encoded as 16 lower-hex characters. | a SpanId header might look like: X-B3-SpanId: a2fb4a1d1a96d312. Unless propagating only the Sampling State, the X-B3-SpanId header is required. | +| X-B3-ParentSpanId | header may be present on a child span and must be absent on the root span. It is encoded as 16 lower-hex characters. | A ParentSpanId header might look like: X-B3-ParentSpanId: 0020000000000001 | +| X-B3-Sampled | An accept sampling decision is encoded as `1` and a deny as `0`. Absent means defer the decision to the receiver of this header. | A Sampled header might look like: X-B3-Sampled: 1. | +| X-B3-Flags | Debug is encoded as `1`. Debug implies an accept decision, so don't also send the X-B3-Sampled header. | | + +### 4.2 Kafka Transports + +Refer to `Event Envelope Model` section. This defines the message that will be sent through the Kafka transport. + +Alternatively the tracing context could be stored in Kafka headers which are only supports v0.11 or later. Note that this would break support for older versions of Kafka. + +### 4.3 Known limitations + +- Transfer tracing would be limited to each of the transfer legs (i.e. Prepare and Fulfil) as a result of the Mojaloop API specification not catering for tracing information. The trace information will be send as part of the callbacks by the Switch, but the FSPs will not be required to respond appropriately with a reciprocal trace headers. diff --git a/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-framework.svg b/docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg similarity index 100% rename from mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-framework.svg rename to docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg diff --git a/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg b/docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg similarity index 100% rename from mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg rename to docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg diff --git a/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-trace.svg b/docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg similarity index 100% rename from mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-trace.svg rename to docs/technical/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg diff --git a/docs/technical/technical/event-stream-processor/README.md b/docs/technical/technical/event-stream-processor/README.md new file mode 100644 index 000000000..95db9223e --- /dev/null +++ b/docs/technical/technical/event-stream-processor/README.md @@ -0,0 +1,20 @@ +# Event Stream Processor Service + +Event Stream Processor consumes event messages from the `topic-events` topic as a result of messages published by the [event-sidecar](https://github.com/mojaloop/event-sidecar) service. Refer to [Event Framework](../event-framework/README.md) for more information on the overall architecture. + +The Service delivers logs, including audits, and traces to EFK stack with enabled APM plugin. Based on the event message type, the messages are delivered to different indexes in the Elasticsearch. + +## 1. Prerequisites + +The service logs all the events to Elasticsearch instance with enabled APM plugin. Sample docker-compose of the Elastic stack is available [here](https://github.com/mojaloop/event-stream-processor/blob/master/test/util/scripts/docker-efk/docker-compose.yml). The logs and audits are created under custom index template, while the trace data is stored to the default `apm-*` index. +Please, ensure that you have created the `mojatemplate` as it is described into the [event-stream-processor](https://github.com/mojaloop/event-stream-processor#111-create-template) service documentation. + +## 2. Architecture overview + +### 2.1. Flow overview +![Event Stream Processor flow overview](./assets/diagrams/architecture/event-stream-processor-overview.svg) + + +### 2.2 Trace processing flow sequence diagram +![](./assets/diagrams/sequence/process-flow.svg) + diff --git a/docs/technical/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg b/docs/technical/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg new file mode 100644 index 000000000..9deb189e9 --- /dev/null +++ b/docs/technical/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg @@ -0,0 +1,3 @@ + + +
    topic-event
    topic-event
    Event Stream Processor
    Send to Elasticsearch mojaloop custom schema via Elasticsearch API
    [Not supported by viewer]
    Yes
    Yes
    Is it trace?
    Is it trace?
    No
    No
    Should create master span?
    Should create master span?
    exit
    exit
    No
    No
    APM Agent
    APM Agent
    Create cache for the trace
    Create cache for the trace
    Yes
    Yes
    No
    No
    Is last span?
    Is last span?
    Recreate trace
    Recreate trace
    exit
    exit
    EFK Stack (Elasticsearch, Kibana, APM)
    EFK Stack (Elasticsearch, Kibana, APM)
    \ No newline at end of file diff --git a/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml b/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml new file mode 100644 index 000000000..9817a79d8 --- /dev/null +++ b/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml @@ -0,0 +1,280 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title Event Streaming Processor flow + +autonumber + +' Actor Keys: + +' declare actors + +collections "Notification topic" as TOPIC_NOTIFICATIONS +control "Topic Observable" as TOPIC_OBSERVABLE +control "Tracing Observable" as TRACING_OBSERVABLE +control "Caching Observable" as CACHING_OBSERVABLE +control "Check For Last Span Observable" as LASTSPAN_OBSERVABLE +control "Create Trace Observable" as CREATETRACE_OBSERVABLE +control "Cache Handler" as CACHE_HANDLER +control "Send Trace Handler" as TRACE_HANDLER +control "Send Span Handler" as SPAN_SENDER +database "Cache Storage" as CACHE +boundary "APM" as APM +boundary "Elasticsearch API" as ELASTIC + +box "Central Services" #lightGray + participant TOPIC_NOTIFICATIONS +end box + +box "Event Stream Processor" #LightBlue + participant TOPIC_OBSERVABLE + participant TRACING_OBSERVABLE + participant CACHING_OBSERVABLE + participant LASTSPAN_OBSERVABLE + participant CREATETRACE_OBSERVABLE + participant TRACE_HANDLER + participant SPAN_SENDER + participant CACHE_HANDLER +end box + +box "Cache" #LightSteelBlue + participant CACHE +end box + +box "Elasticsearch" #LightYellow + participant APM + participant ELASTIC +end box + +' start flow + +group New Event Message Received + TOPIC_NOTIFICATIONS -> TOPIC_OBSERVABLE: Consume Event Message + activate TOPIC_OBSERVABLE + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + note over TOPIC_OBSERVABLE #yellow + Message: + { + "from": "payeefsp", + "to": "payerfsp", + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "content": { + "headers": { + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "payeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": "44ba9bbc5840", + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } + } + end note + TOPIC_OBSERVABLE -> ELASTIC: Send message for log purposes to custom index + TOPIC_OBSERVABLE -> TOPIC_OBSERVABLE: Verify its tracing event Message + TOPIC_OBSERVABLE -> TRACING_OBSERVABLE: Send Message to Tracing Observable + deactivate TOPIC_OBSERVABLE + activate TRACING_OBSERVABLE + group Cache Span + TRACING_OBSERVABLE -> CACHING_OBSERVABLE: Send Span Context, \nmetadata.State and Content\nfrom Message + note right of TRACING_OBSERVABLE #yellow + { + spanContext: { + service: "central-ledger-prepare-handler", + traceId: "bbd7b2c7bbd7b2c7", + parentSpanId: "44ba9bbc5840", + spanId: "2aa9cd0a7e87", + startTimestamp: "2015-08-29T11:22:09.815479Z", + finishTimestamp: "2015-08-29T11:22:09.815479Z", + tags: { + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + transctionType: "transfer", + parentEventType: "bulk-prepare", + parentEventAction: "prepare" + }, + state: metadata.state, + content + } + end note + deactivate TRACING_OBSERVABLE + activate CACHING_OBSERVABLE + CACHING_OBSERVABLE <- CACHE: Get cachedTrace by traceId + alt the span should not be cached + CACHING_OBSERVABLE -> SPAN_SENDER: currentSpan + SPAN_SENDER -> APM: store to APM + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Complete + else + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + alt !cachedTrace + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Create new cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: {}, + masterSpan: null, + lastSpan: null + } + end note + end + alt !parentSpan + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Generate MasterSpanId + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Make received span child of masterSpan \nmerge({ parentSpanId: MasterSpanId }, { ...spanContext }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, \n{ ...spanContext }, \n{ spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Add masterSpan to cachedTrace + end + CACHING_OBSERVABLE <-> CACHE_HANDLER: Add span to cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: { + 2aa9cd0a7e87: { + state, + content + spanContext: { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": MasterSpanId, + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + }, + MasterSpanId: { + state, + content, + MasterSpanContext + } + }, + masterSpan: MasterSpanContext, + lastSpan: null + } + end note + CACHING_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + end + CACHING_OBSERVABLE -> LASTSPAN_OBSERVABLE: Send traceId to check if last span has been received\nand cached + deactivate CACHING_OBSERVABLE + activate LASTSPAN_OBSERVABLE + end + group Check for last span + LASTSPAN_OBSERVABLE <- CACHE: Get cachedTrace by traceId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Sort spans by startTimestamp + loop for currentSpan of SortedSpans + alt parentSpan + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: isError = (errorCode in parentSpan \nOR parentSpan status === failed \nOR status === failed) + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: apply masterSpan and error tags from parent to current span in cachedTrace + alt !isLastSpan + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + else + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Validate transactionType, TransactionAction, service and isError \nto match Config.START_CRITERIA && !parentSpandId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: cachedTrace.lastSpan = currentSpan.spanContext + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + LASTSPAN_OBSERVABLE -> CREATETRACE_OBSERVABLE: Send traceId + deactivate LASTSPAN_OBSERVABLE + activate CREATETRACE_OBSERVABLE + end + end + end + end + group Recreate Trace from Cached Trace + CREATETRACE_OBSERVABLE <- CACHE: get cachedTrace by TraceId + alt cachedTrace.lastSpan AND cachedTrace.masterSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: currentSpan = lastSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: resultTrace = [lastSpan] + loop for i = 0; i < cachedTrace.spans.length; i++ + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: get parentSpan of currentSpan + alt parentSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: insert parent span in resultTrace in front + else + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: break loop + end + end + alt cachedTrace.masterSpan === currentSpan.spanId + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + CREATETRACE_OBSERVABLE -> TRACE_HANDLER: send resultTrace + deactivate CREATETRACE_OBSERVABLE + activate TRACE_HANDLER + end + end + end + group send Trace + loop trace elements + TRACE_HANDLER -> SPAN_SENDER: send each span + SPAN_SENDER -> APM: send span to APM + end + TRACE_HANDLER -> TRACE_HANDLER: unsubscribe scheduler for traceId + TRACE_HANDLER -> CACHE: drop cachedTrace + + end + end +@enduml \ No newline at end of file diff --git a/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg b/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg new file mode 100644 index 000000000..a85cf2bb6 --- /dev/null +++ b/docs/technical/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg @@ -0,0 +1,577 @@ + + Event Streaming Processor flow + + + Event Streaming Processor flow + + Central Services + + Event Stream Processor + + Cache + + Elasticsearch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Notification topic + + + Notification topic + Topic Observable + + + Topic Observable + + + Tracing Observable + + + Tracing Observable + + + Caching Observable + + + Caching Observable + + + Check For Last Span Observable + + + Check For Last Span Observable + + + Create Trace Observable + + + Create Trace Observable + + + Send Trace Handler + + + Send Trace Handler + + + Send Span Handler + + + Send Span Handler + + + Cache Handler + + + Cache Handler + + + Cache Storage + + + Cache Storage + + + APM + + + APM + + + Elasticsearch API + + + Elasticsearch API + + + + + + + + + + + + New Event Message Received + + + 1 + Consume Event Message + + + Message: + { + "from": "payeefsp", + "to": "payerfsp", + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "content": { + "headers": { + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "payeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": <payload> + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": "44ba9bbc5840", + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } + } + + + 2 + Send message for log purposes to custom index + + + + + 3 + Verify its tracing event Message + + + 4 + Send Message to Tracing Observable + + + Cache Span + + + 5 + Send Span Context, + metadata.State and Content + from Message + + + { + spanContext: { + service: "central-ledger-prepare-handler", + traceId: "bbd7b2c7bbd7b2c7", + parentSpanId: "44ba9bbc5840", + spanId: "2aa9cd0a7e87", + startTimestamp: "2015-08-29T11:22:09.815479Z", + finishTimestamp: "2015-08-29T11:22:09.815479Z", + tags: { + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + transctionType: "transfer", + parentEventType: "bulk-prepare", + parentEventAction: "prepare" + }, + state: metadata.state, + content + } + + + 6 + Get cachedTrace by traceId + + + alt + [the span should not be cached] + + + 7 + currentSpan + + + 8 + store to APM + + + + + 9 + Complete + + + + + + + 10 + Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + + + alt + [!cachedTrace] + + + + + 11 + Create new cachedTrace + + + { + spans: {}, + masterSpan: null, + lastSpan: null + } + + + alt + [!parentSpan] + + + + + + 12 + Generate MasterSpanId + + + + + + 13 + Make received span child of masterSpan + merge({ parentSpanId: MasterSpanId }, { ...spanContext }) + + + + + + 14 + Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, + { ...spanContext }, + { spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + + + + + + 15 + Add masterSpan to cachedTrace + + + + 16 + Add span to cachedTrace + + + { + spans: { + 2aa9cd0a7e87: { + state, + content + spanContext: { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": + MasterSpanId + , + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + }, +    + MasterSpanId: + { + state, + content, + MasterSpanContext + } + }, + masterSpan: + MasterSpanContext + , + lastSpan: null + } + + + 17 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 18 + unsubscribe from Scheduler + + + 19 + record cachedTrace + + + + + + 20 + Reschedule scheduler for handling stale traces + + + 21 + Send traceId to check if last span has been received + and cached + + + Check for last span + + + 22 + Get cachedTrace by traceId + + + + + 23 + Sort spans by startTimestamp + + + loop + [for currentSpan of SortedSpans] + + + alt + [parentSpan] + + + + + 24 + isError = (errorCode in parentSpan + OR parentSpan status === failed + OR status === failed) + + + + + 25 + apply masterSpan and error tags from parent to current span in cachedTrace + + + alt + [!isLastSpan] + + + 26 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 27 + unsubscribe from Scheduler + + + 28 + record cachedTrace + + + + + + 29 + Reschedule scheduler for handling stale traces + + + + + + 30 + Validate transactionType, TransactionAction, service and isError + to match Config.START_CRITERIA && !parentSpandId + + + + + 31 + cachedTrace.lastSpan = currentSpan.spanContext + + + 32 + Update cachedTrace to Cache + + + alt + [cachedTrace not staled or expired] + + + + + 33 + unsubscribe from Scheduler + + + 34 + record cachedTrace + + + + + + 35 + Reschedule scheduler for handling stale traces + + + 36 + Send traceId + + + Recreate Trace from Cached Trace + + + 37 + get cachedTrace by TraceId + + + alt + [cachedTrace.lastSpan AND cachedTrace.masterSpan] + + + + + 38 + currentSpan = lastSpan + + + + + 39 + resultTrace = [lastSpan] + + + loop + [for i = 0; i < cachedTrace.spans.length; i++] + + + + + 40 + get parentSpan of currentSpan + + + alt + [parentSpan] + + + + + 41 + insert parent span in resultTrace in front + + + + + + 42 + break loop + + + alt + [cachedTrace.masterSpan === currentSpan.spanId] + + + + + 43 + masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + + + 44 + send resultTrace + + + send Trace + + + loop + [trace elements] + + + 45 + send each span + + + 46 + send span to APM + + + + + 47 + unsubscribe scheduler for traceId + + + 48 + drop cachedTrace + + diff --git a/docs/technical/technical/fraud-services/README.md b/docs/technical/technical/fraud-services/README.md new file mode 100644 index 000000000..d44482e5b --- /dev/null +++ b/docs/technical/technical/fraud-services/README.md @@ -0,0 +1,5 @@ +# Fraud Services + +Provides an overview of the monitoring and preventative measures in consideration to prevent and discourage fraudulent activities within a Mojaloop scheme. + +Relevant artefacts available for public consumption are shared within [related-documents](./related-documents/documentation.md) section. diff --git a/mojaloop-technical-overview/fraud-services/related-documents/documentation.md b/docs/technical/technical/fraud-services/related-documents/documentation.md similarity index 100% rename from mojaloop-technical-overview/fraud-services/related-documents/documentation.md rename to docs/technical/technical/fraud-services/related-documents/documentation.md diff --git a/docs/technical/technical/ml-testing-toolkit/README.md b/docs/technical/technical/ml-testing-toolkit/README.md new file mode 100644 index 000000000..0260e22a2 --- /dev/null +++ b/docs/technical/technical/ml-testing-toolkit/README.md @@ -0,0 +1,16 @@ +Mojaloop Testing Toolkit +============================= + +The **Mojaloop Testing Toolkit** was designed to help Mojaloop Schemes scale effectively by easing the DFSP Onboarding process. Schemes can provide a set of rules and tests on the toolkit and DFSPs can use it for self testing (or self-certification in some cases). This ensures that DFSPs are well and truly ready with their implementations to be integrated with the Scheme and allows for a quick and smooth onboarding process for the Mojaloop Hubs, thereby increasing their scalability. + +This was initially aimed at FSPs/Participants that would like to participate in a Mojaloop scheme. However, in its current form, this tool set can potentially be used by both DFSPs and _Mojaloop Hubs_ to verify integration between the 2 entities. Intentionally built as a standard integration testing tool between a _Digital Financial Service Provider (DFSP)_ and the _Mojaloop Switch_ (Hub), to facilitate testing. + +For additional background on the Self Testing Toolkit, please see [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md). It would be to the particpant's benefit to familiarise themselves with the understanding of the [Architecture Diagram](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md#7-architecture) that explains the various components and related flows. + +## Usage Guides + +For Web interface follow this [Usage Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide.md) + +For Command line tool follow this [CLI User Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide-CLI.md) + +**If you have your own DFSP implementation you can point the peer endpoint to Mojaloop Testing Toolkit on port 5000 and try to send requests from your implementation instead of using mojaloop-simulator.** diff --git a/docs/technical/technical/overview/README.md b/docs/technical/technical/overview/README.md new file mode 100644 index 000000000..c5c439207 --- /dev/null +++ b/docs/technical/technical/overview/README.md @@ -0,0 +1,24 @@ +# Mojaloop Hub + +There are several components that make up the Mojaloop ecosystem. The Mojaloop Hub is the primary container and reference we use to describe the core Mojaloop components. + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture: + +![Current Mojaloop Architecture Overview](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ + +These consist of: + +* The **Mojaloop API Adapters** (**ML-API-Adapter**) provide the standard set of interfaces a DFSP can implement to connect to the system for Transfers. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* The **Central Services** (**CS**) provide the set of components required to move money from one DFSP to another through the Mojaloop API Adapters. This is similar to how money moves through a central bank or clearing house in developed countries. The Central Services contains the core Central Ledger logic to move money but also will be extended to provide fraud management and enforce scheme rules. +* The **Account Lookup Service** (**ALS**) provides a mechanism to resolve FSP routing information through the Participant API or orchestrate a Party request based on an internal Participant look-up. The internal Participant look-up is handled by a number of standard Oracle adapter or services. Example Oracle adapter/service would be to look-up Participant information from Pathfinder or a Merchant Registry. These Oracle adapters or services can easily be added depending on the schema requirements. +* The **Quoting Service** (**QA**) provides Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. +* The **Simulator** (**SIM**) mocks several DFSP functions as follows: + * Oracle end-points for Oracle Participant CRUD operations using in-memory cache; + * Participant end-points for Oracles with support for parameterized partyIdTypes; + * Parties end-points for Payer and Payee FSPs with associated callback responses; + * Transfer end-points for Payer and Payee FSPs with associated callback responses; and + * Query APIs to verify transactions (requests, responses, callbacks, etc) to support QA testing and verification. + +On either side of the Mojaloop Hub there is sample open source code to show how a DFSP can send and receive payments and the client that an existing DFSP could host to connect to the network. diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg new file mode 100644 index 000000000..df9396cae --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg new file mode 100644 index 000000000..763c5697e --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Settlement Windows)
    Central-Settlements...
    Central-Settlements
    (Handler - Transfer Settlements)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg new file mode 100644 index 000000000..06680fbae --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg new file mode 100644 index 000000000..6e753c75d --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg @@ -0,0 +1,4 @@ + + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Infra management
    (IaC, Miniloop)
    Infra management...
    Mojaloop API Adapter
    (FSPIOP API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (FSPIOP API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (Functional
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Accelerators
    Software Accelerators
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (micro-frontends)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (3PPI - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (3PPI Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Business Operations Framework for 
    (Reporting
    )
    (Operations)
    (Monitoring)
    (self-service portals)
    Business Operations Frame...
    IAM, RBAC
    (Administration APIs; Ory - Keto, Kratos, Oathkeeper)
    IAM, RBAC...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg new file mode 100644 index 000000000..4a658b897 --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    Central-Directory
    (Participant Lookup)
    [Not supported by viewer]
    Central-End-User-Registry
    (Custom Participant Store)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Central-Hub
    (Retired - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg new file mode 100644 index 000000000..ac0b21621 --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Msisdn-Service
    (Pathfinder Lookup Adapter)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg new file mode 100644 index 000000000..9697dfc5b --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core
    <b>Core</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Persistence
    <b>Persistence</b>
    Scaffolding
    [Not supported by viewer]
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Event-Logging-Sidecar
    (POC - Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP, POCLogs, Error, Audits, Tracing)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational UI)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Deprecated - Auditing)
    [Not supported by viewer]
    Simulator
    (API - FSP Simulator /
    API - Oracle Simulator)

    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg new file mode 100644 index 000000000..2fedecbc1 --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core Components
    <b>Core Components</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Supporting Components
    <b style="line-height: 0%">Supporting Components</b>
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging
    (Future - Auditing)
    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Simulator
    (API - FSP & Oracle Simulator)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    Mojaloop-Simulator
    (SDK)
    [Not supported by viewer]
    License & Audit
    (Dependencies)
    [Not supported by viewer]
    Persistence
    <b>Persistence</b>
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Transaction Request Service
    (API - Transaction)
    <b>Transaction Request Service</b><br>(API - Transaction)
    Software Dev Kits
    <b>Software Dev Kits</b>
    Oracle SDK
    (Participant Store)
    [Not supported by viewer]
    Mojaloop SDK 
    (FSP Payer/Payee)
    [Not supported by viewer]
    Event SDK
    (Audit, Log, Trace - Client/Server)
    [Not supported by viewer]
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    <b>Event-Sidecar</b><br>(Logs, Error, Audits, Tracing)
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg new file mode 100644 index 000000000..3e5b75f13 --- /dev/null +++ b/docs/technical/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    \ No newline at end of file diff --git a/docs/technical/technical/overview/components-PI11.md b/docs/technical/technical/overview/components-PI11.md new file mode 100644 index 000000000..35b839657 --- /dev/null +++ b/docs/technical/technical/overview/components-PI11.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI11 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI11: + +![Mojaloop Architecture Overview PI11](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/docs/technical/technical/overview/components-PI12.md b/docs/technical/technical/overview/components-PI12.md new file mode 100644 index 000000000..d90d82eb9 --- /dev/null +++ b/docs/technical/technical/overview/components-PI12.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI12 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI12: + +![Mojaloop Architecture Overview PI12](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/docs/technical/technical/overview/components-PI14.md b/docs/technical/technical/overview/components-PI14.md new file mode 100644 index 000000000..d4c4e3887 --- /dev/null +++ b/docs/technical/technical/overview/components-PI14.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI14 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI14: + +![Mojaloop Architecture Overview PI14](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/docs/technical/technical/overview/components-PI18.md b/docs/technical/technical/overview/components-PI18.md new file mode 100644 index 000000000..d42df67ff --- /dev/null +++ b/docs/technical/technical/overview/components-PI18.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI18 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI18: + +![Mojaloop Architecture Overview PI18](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI18.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/mojaloop-technical-overview/overview/components-PI3.md b/docs/technical/technical/overview/components-PI3.md similarity index 100% rename from mojaloop-technical-overview/overview/components-PI3.md rename to docs/technical/technical/overview/components-PI3.md diff --git a/mojaloop-technical-overview/overview/components-PI5.md b/docs/technical/technical/overview/components-PI5.md similarity index 100% rename from mojaloop-technical-overview/overview/components-PI5.md rename to docs/technical/technical/overview/components-PI5.md diff --git a/mojaloop-technical-overview/overview/components-PI6.md b/docs/technical/technical/overview/components-PI6.md similarity index 100% rename from mojaloop-technical-overview/overview/components-PI6.md rename to docs/technical/technical/overview/components-PI6.md diff --git a/mojaloop-technical-overview/overview/components-PI7.md b/docs/technical/technical/overview/components-PI7.md similarity index 100% rename from mojaloop-technical-overview/overview/components-PI7.md rename to docs/technical/technical/overview/components-PI7.md diff --git a/docs/technical/technical/overview/components-PI8.md b/docs/technical/technical/overview/components-PI8.md new file mode 100644 index 000000000..3d18e7fac --- /dev/null +++ b/docs/technical/technical/overview/components-PI8.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI8 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI8: + +![Mojaloop Architecture Overview PI8](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/docs/technical/technical/quoting-service/README.md b/docs/technical/technical/quoting-service/README.md new file mode 100644 index 000000000..551f4c4b8 --- /dev/null +++ b/docs/technical/technical/quoting-service/README.md @@ -0,0 +1,22 @@ +--- +version: 1.1 +--- + +# Quoting Service Overview +The **Quoting Service** (**QS**) _(refer to section `5.1`) as per the [Mojaloop {{ $page.frontmatter.version }} Specification](/api) implements the quoting phase of the various use-cases. + +_Note: In addition to individual quotes, the quoting service supports bulk quotes as well._ + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-quotes-1.0.0.svg) + +## Individual Quotes + +- [GET: retrieve a quote by identifier](qs-get-quotes.md) +- [POST: quote request](qs-post-quotes.md) + +## Bulk Quotes + +- [GET: retrieve a bulk quote by identifier](qs-get-bulk-quotes.md) +- [POST: bulk quote request](qs-post-bulk-quotes.md) diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml new file mode 100644 index 000000000..0405a9868 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Retrieve Bulk Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP + +autonumber +note right of PayerFSP: Payer FSP sends request to get bulk quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /bulkQuotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve bulk quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode) + Switch -\ PayeeFSP: GET /bulkQuotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves bulk quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** + end note + Switch --/ PayeeFSP: 200 Ok + alt Response is ok + Switch -> Switch: Retrieve bulk quotes endpoint for the Payer FSP + alt Bulk Quotes callback endpoint found + note left of Switch: Switch forwards bulk quote response to Payer FSP + Switch -\ PayerFSP: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Bulk Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else bulkQuote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP Bulk quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg new file mode 100644 index 000000000..5048df7d9 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg @@ -0,0 +1,198 @@ + + Retrieve Bulk Quote Information + + + Retrieve Bulk Quote Information + + + + + + + + + Payer FSP + + Payer FSP + + Switch + [Quoting Service] + + Switch + [Quoting Service] + + Payee FSP + + Payee FSP + + + Payer FSP sends request to get bulk quote details + to Payee FSP via the Switch + + + 1 + GET /bulkQuotes/{ID} + + + Validate request against + Mojaloop interface specification + Error code: 300x, 310x + HTTP error response code: 4xx + + + + + 2 + Schema validation + + + 3 + 202 Accepted + + + + + 4 + Retrieve bulk quotes endpoint for Payee FSP + + + alt + [Payee FSP quotes endpoint is found] + + + Switch forwards request to Payee FSP (pass-through mode) + + + 5 + GET /bulkQuotes/{ID} + + + 6 + 202 Accepted + + + + + 7 + Payee FSP retireves bulk quote + + + alt + [Payee FSP successfully retieves quote] + + + Payee FSP responds to quote request + + + 8 + PUT /quotes/{ID} + + + Validate request against + Mojaloop interface specification + Error code: 300x, 310x + HTTP error response code: 4xx + + + 9 + 200 Ok + + + alt + [Response is ok] + + + + + 10 + Retrieve bulk quotes endpoint for the Payer FSP + + + alt + [Bulk Quotes callback endpoint found] + + + Switch forwards bulk quote response to Payer FSP + + + 11 + PUT /bulkQuotes/{ID} + + + 12 + 200 Ok + + [Bulk Quotes callback endpoint not found] + + + Switch returns error to Payee FSP + + + 13 + PUT /bulkQuotes/{ID}/error + + + 14 + 200 Ok + + [Response is invalid] + + + Switch returns error to Payee FSP + + + 15 + PUT /bulkQuotes/{ID}/error + + + 16 + 200 Ok + + + Note that under this + scenario the Payer FSP + may not receive a response + + [bulkQuote not found] + + + Payee FSP returns error to Switch +   + Error code: 3205 + + + 17 + PUT /bulkQuotes/{ID}/error + + + 18 + 200 OK + + + Switch returns error to Payer FSP +   + Error code: 3205 + + + 19 + PUT /bulkQuotes/{ID}/error + + + 20 + 200 OK + + [Payee FSP Bulk quotes endpoint is not found] + + + Switch returns error to Payer FSP + Error code: 3201 + + + 21 + PUT /bulkQuotes/{ID}error + + + 22 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml new file mode 100644 index 000000000..dfcb1918b --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml @@ -0,0 +1,86 @@ +@startuml +Title Retrieve Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber +note right of PayerFSP: Payer FSP sends request to get quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /quotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode)\n + Switch -\ PayeeFSP: GET /quotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 Ok + Switch -> Switch: Validate response (schema, headers (**Error code: 3100**)) + alt Response is ok + alt SimpleRoutingMode is FALSE + Switch -> Switch: Validate response (duplicate response check, handle resend scenario (**Error code: 3106**)) + alt Validation passed + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + end + alt SimpleRoutingMode is TRUE + Switch -> Switch: Retrieve quotes endpoint for the Payer FSP + else SimpleRoutingMode is FALSE + Switch -> Switch: Retrieve quote party endpoint (PAYER) + end + alt Quotes callback endpoint found + note left of Switch: Switch forwards quote response to Payer FSP\n + Switch -\ PayerFSP: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else Quote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode is FALSE + Switch -> Switch: Persist error data + end + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT quotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg new file mode 100644 index 000000000..d413d4496 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg @@ -0,0 +1,269 @@ + + Retrieve Quote Information + + + Retrieve Quote Information + + + + + + + + + + + + + + + Payer FSP + + Payer FSP + + Switch + [Quoting + Service] + + Switch + [Quoting + Service] + Central Store + + + Central Store + + + + Payee FSP + + Payee FSP + + + + Payer FSP sends request to get quote details + to Payee FSP via the Switch + + + 1 + GET /quotes/{ID} + + + Validate request against + Mojaloop interface specification + Error code: 300x, 310x + HTTP error response code: 4xx + + + + + 2 + Schema validation + + + 3 + 202 Accepted + + + + + 4 + Retrieve quotes endpoint for Payee FSP + + + alt + [Payee FSP quotes endpoint is found] + + + Switch forwards request to Payee FSP (pass-through mode) + <Payer based Rules> + + + 5 + GET /quotes/{ID} + + + 6 + 202 Accepted + + + + + 7 + Payee FSP retireves quote + + + alt + [Payee FSP successfully retieves quote] + + + Payee FSP responds to quote request + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Validate response (schema, headers ( + Error code: 3100 + )) + + + alt + [Response is ok] + + + alt + [SimpleRoutingMode is FALSE] + + + + + 11 + Validate response (duplicate response check, handle resend scenario ( + Error code: 3106 + )) + + + alt + [Validation passed] + + + 12 + Persist quote response + + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + + + 13 + Quote response saved + + + alt + [SimpleRoutingMode is TRUE] + + + + + 14 + Retrieve quotes endpoint for the Payer FSP + + [SimpleRoutingMode is FALSE] + + + + + 15 + Retrieve quote party endpoint (PAYER) + + + alt + [Quotes callback endpoint found] + + + Switch forwards quote response to Payer FSP + <Payee whole request Rule> + + + 16 + PUT /quotes/{ID} + + + 17 + 200 Ok + + [Quotes callback endpoint not found] + + + Switch returns error to Payee FSP + + + 18 + PUT /quotes/{ID}/error + + + 19 + 200 Ok + + [Response is invalid] + + + Switch returns error to Payee FSP + + + 20 + PUT /quotes/{ID}/error + + + 21 + 200 Ok + + + Note that under this + scenario the Payer FSP + may not receive a response + + [Quote not found] + + + Payee FSP returns error to Switch +   + Error code: 3205 + + + 22 + PUT quotes/{ID}/error + + + 23 + 200 OK + + + alt + [SimpleRoutingMode is FALSE] + + + + + 24 + Persist error data + + + Switch returns error to Payer FSP +   + Error code: 3205 + + + 25 + PUT quotes/{ID}/error + + + 26 + 200 OK + + [Payee FSP quotes endpoint is not found] + + + Switch returns error to Payer FSP + Error code: 3201 + + + 27 + PUT quotes/{ID}error + + + 28 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml new file mode 100644 index 000000000..ca4c1d30f --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml @@ -0,0 +1,99 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Request Bulk Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends bulk quote request\nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /bulkQuotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Bulk Quote request validation (rules engine etc.) +||| +Switch -> Switch: Duplicate check +||| +alt Request is a duplicate but not a resend +||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK +||| +else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario +end +||| +Switch -> Switch: Use fspiop-destination header to retrieve\n bulk quotes endpoint for Payee DFSP +alt Payee bulk quotes endpoint found + note right of Switch: Switch forwards bulk quote request to Payee FSP + Switch -\ PayeeFSP: POST /bulkQuotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP calculates individual quotes\nand responds with a bulk quote result + alt Payee bulkQuotes processing successful + note over PayeeFSP, Switch: Payee FSP sends bulk quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate bulk quote response + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects bulk quote or encounters an error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg new file mode 100644 index 000000000..d855d1f1f --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg @@ -0,0 +1,217 @@ + + Request Bulk Quote Creation + + + Request Bulk Quote Creation + + + + + + + + + + Payer FSP + + Payer FSP + + Switch + [Quoting Service] + + Switch + [Quoting Service] + + Payee FSP + + Payee FSP + + + Payer FSP sends bulk quote request + to Payee FSP via the Switch + + + 1 + POST /bulkQuotes + + + Validate request against + Mojaloop interface specification + Error code: 300x, 310x + HTTP error response code: 4xx + + + + + 2 + Schema validation + + + 3 + 202 Accepted + + + + + 4 + Bulk Quote request validation (rules engine etc.) + + + + + 5 + Duplicate check + + + alt + [Request is a duplicate but not a resend] + + + Switch returns error back to Payer FSP + Error code: 3106 + + + 6 + PUT /bulkQuotes/{ID}/error + + + 7 + 200 OK + + [Request is a duplicate and a resend] + + + + + 8 + Switch handles resend scenario + + + + + 9 + Use fspiop-destination header to retrieve + bulk quotes endpoint for Payee DFSP + + + alt + [Payee bulk quotes endpoint found] + + + Switch forwards bulk quote request to Payee FSP + + + 10 + POST /bulkQuotes + + + 11 + 202 OK + + + + + 12 + Payee FSP calculates individual quotes + and responds with a bulk quote result + + + alt + [Payee bulkQuotes processing successful] + + + Payee FSP sends bulk quote response back to Payer FSP via the Switch + + + 13 + PUT /bulkQuotes/{ID} + + + 14 + 200 OK + + + + + 15 + Validate bulk quote response + + + + + 16 + Duplicate check + + + alt + [Response is duplicate but not a resend] + + + 17 + PUT /bulkQuotes/{ID}/error + + + 18 + 200 OK + + + alt + [Response is a duplicate and a resend] + + + + + 19 + Switch handles resend scenario + + + Switch forwards quote response to Payer FSP + + + 20 + PUT /bulkQuotes/{ID} + + + 21 + 200 OK + + [Payee rejects bulk quote or encounters an error] + + + Payee FSP sends error callback to Payer FSP via the Switch + + + 22 + PUT /bulkQuotes/{ID}/error + + + 23 + 200 OK + + + Switch forwards error callback to Payer FSP + + + 24 + PUT /bulkQuotes/{ID}/error + + + 25 + 200 OK + + [Payee FSP quotes endpoint not found] + + + Switch sends an error callback to Payer FSP +   + Error code: 3201 + + + 26 + PUT /bulkQuotes/{ID}/error + + + 27 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml new file mode 100644 index 000000000..86fb8f8b6 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml @@ -0,0 +1,117 @@ +@startuml +Title Request Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends request for quote \nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /quotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Quote request validation (rules engine etc.) +||| +alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + ||| + alt Request is a duplicate but not a resend + ||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + ||| + else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + ||| + Switch -\ DB: Persist quote request + activate DB + hnote over DB + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + end hnote + Switch \-- DB: Quote request saved + deactivate DB +end +||| +alt SimpleRoutingMode === TRUE + Switch -> Switch: Use fspiop-destination header to retrieve quotes endpoint for Payee FSP +else SimpleRoutingMode === FALSE + Switch -> Switch: Retireve Payee FSP endpoint using quote party information +end +||| +alt Payee quotes endpoint found + note right of Switch: Switch forwards quote request to Payee FSP + Switch -\ PayeeFSP: POST /quotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP presists and calculates quote + alt Payee quotes processing successful + note left of PayeeFSP: Payee FSP sends quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate quote response + alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects quotes or encounters and error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode === FALSE + Switch -\ DB: Store quote error + activate DB + hnote over DB + quoteError + end hnote + Switch \-- DB: Quote error saved + deactivate DB + end + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg new file mode 100644 index 000000000..963594b46 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg @@ -0,0 +1,297 @@ + + Request Quote Creation + + + Request Quote Creation + + + + + + + + + + + + + + + + + + Payer FSP + + Payer FSP + + Switch + [Quoting + Service] + + Switch + [Quoting + Service] + Central Store + + + Central Store + + + + Payee FSP + + Payee FSP + + + + + + Payer FSP sends request for quote + to Payee FSP via the Switch + + + 1 + POST /quotes + + + Validate request against + Mojaloop interface specification + Error code: 300x, 310x + HTTP error response code: 4xx + + + + + 2 + Schema validation + + + 3 + 202 Accepted + + + + + 4 + Quote request validation (rules engine etc.) + + + alt + [SimpleRoutingMode === FALSE] + + + + + 5 + Duplicate check + + + alt + [Request is a duplicate but not a resend] + + + Switch returns error back to Payer FSP + Error code: 3106 + + + 6 + PUT /quotes/{ID}/error + + + 7 + 200 OK + + [Request is a duplicate and a resend] + + + + + 8 + Switch handles resend scenario + + + 9 + Persist quote request + + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + + + 10 + Quote request saved + + + alt + [SimpleRoutingMode === TRUE] + + + + + 11 + Use fspiop-destination header to retrieve quotes endpoint for Payee FSP + + [SimpleRoutingMode === FALSE] + + + + + 12 + Retireve Payee FSP endpoint using quote party information + + + alt + [Payee quotes endpoint found] + + + Switch forwards quote request to Payee FSP + + + 13 + POST /quotes + + + 14 + 202 OK + + + + + 15 + Payee FSP presists and calculates quote + + + alt + [Payee quotes processing successful] + + + Payee FSP sends quote response back to Payer FSP via the Switch + + + 16 + PUT /quotes/{ID} + + + 17 + 200 OK + + + + + 18 + Validate quote response + + + alt + [SimpleRoutingMode === FALSE] + + + + + 19 + Duplicate check + + + alt + [Response is duplicate but not a resend] + + + 20 + PUT /quotes/{ID}/error + + + 21 + 200 OK + + + alt + [Response is a duplicate and a resend] + + + + + 22 + Switch handles resend scenario + + + 23 + Persist quote response + + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + + + 24 + Quote response saved + + + Switch forwards quote response to Payer FSP + + + 25 + PUT /quotes/{ID} + + + 26 + 200 OK + + [Payee rejects quotes or encounters and error] + + + Payee FSP sends error callback to Payer FSP via the Switch + + + 27 + PUT /quotes/{ID}/error + + + 28 + 200 OK + + + alt + [SimpleRoutingMode === FALSE] + + + 29 + Store quote error + + quoteError + + + 30 + Quote error saved + + + Switch forwards error callback to Payer FSP + + + 31 + PUT /quotes/{ID}/error + + + 32 + 200 OK + + [Payee FSP quotes endpoint not found] + + + Switch sends an error callback to Payer FSP +   + Error code: 3201 + + + 33 + PUT /quotes/{ID}/error + + + 34 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml new file mode 100644 index 000000000..4f3405364 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml @@ -0,0 +1,68 @@ +@startuml +Title Quoting Service Sequences +participant "Payer DFSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee DFSP" + +autonumber +note over "Payer DFSP", Switch: Payer DFSP requests quote from Payee DFSP +"Payer DFSP" -\ Switch: POST /quotes +Switch --/ "Payer DFSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee DFSP": Switch forwards quote request to Payee DFSP\n + Switch -\ "Payee DFSP": POST /quotes + "Payee DFSP" --/ Switch: 202 Accepted + "Payee DFSP" -> "Payee DFSP": Calculate Fees/Charges + + alt Payee DFSP successfully calculates quote + + note over "Payee DFSP", Switch: Payee DFSP responds to quote request + "Payee DFSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee DFSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + + Switch -> Switch: Persist Response Data + + note over Switch, "Payer DFSP": Switch forwards quote response to Payer DFSP\n + + Switch -\ "Payer DFSP": PUT /quotes/{ID} + "Payer DFSP" --/ Switch: 200 Ok + + note over "Payer DFSP" #3498db: Payer DFSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee DFSP": Switch returns error to Payee DFSP + + Switch -\ "Payee DFSP": PUT /quotes/{ID}/error + "Payee DFSP" --/ Switch : 200 Ok + + note over Switch, "Payee DFSP" #ec7063: Note that under this\nscenario the Payer DFSP\nmay not receive a response + + end + else Payee DFSP calculation fails or rejects the request + + note over "Payee DFSP", Switch: Payee DFSP returns error to Switch + + "Payee DFSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee DFSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg new file mode 100644 index 000000000..bff0f162c --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg @@ -0,0 +1,183 @@ + + Quoting Service Sequences + + + Quoting Service Sequences + + + + + + + + Payer DFSP + + Payer DFSP + + Switch + Quoting + Service + + Switch + Quoting + Service + + Payee DFSP + + Payee DFSP + + + Payer DFSP requests quote from Payee DFSP + + + 1 + POST /quotes + + + 2 + 202 Accepted + + + + + 3 + Validate Quote Request + + + alt + [quote is valid] + + + + + 4 + Persist Quote Data + + + Switch forwards quote request to Payee DFSP + <Payer based Rules> + + + 5 + POST /quotes + + + 6 + 202 Accepted + + + + + 7 + Calculate Fees/Charges + + + alt + [Payee DFSP successfully calculates quote] + + + Payee DFSP responds to quote request + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Validate Quote Response + + + alt + [response is ok] + + + + + 11 + Persist Response Data + + + Switch forwards quote response to Payer DFSP + <Payee whole request Rule> + + + 12 + PUT /quotes/{ID} + + + 13 + 200 Ok + + + Payer DFSP continues + with transfer if quote + is acceptable... + + [response invalid] + + + Switch returns error to Payee DFSP + + + 14 + PUT /quotes/{ID}/error + + + 15 + 200 Ok + + + Note that under this + scenario the Payer DFSP + may not receive a response + + [Payee DFSP calculation fails or rejects the request] + + + Payee DFSP returns error to Switch + + + 16 + PUT quotes/{ID}/error + + + 17 + 200 OK + + + + + 18 + Persist error data + + + Switch returns error to Payer DFSP + + + 19 + PUT quotes/{ID}/error + + + 20 + 200 OK + + [quote invalid] + + + Switch returns error to Payer DFSP + + + 21 + PUT quotes/{ID}/error + + + 22 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml new file mode 100644 index 000000000..3275abff7 --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml @@ -0,0 +1,67 @@ +@startuml +Title Quoting Service Sequences +participant "Payer FSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee FSP" + +autonumber +note over "Payer FSP", Switch: Payer FSP requests quote from Payee FSP +"Payer FSP" -\ Switch: POST /quotes +Switch --/ "Payer FSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee FSP": Switch forwards quote request to Payee FSP\n + Switch -\ "Payee FSP": POST /quotes + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Calculate Fees/Charges + + alt Payee FSP successfully calculates quote + + note over "Payee FSP", Switch: Payee FSP responds to quote request + "Payee FSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee FSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + Switch -> Switch: Persist Response Data + + note over Switch, "Payer FSP": Switch forwards quote response to Payer FSP\n + + Switch -\ "Payer FSP": PUT /quotes/{ID} + "Payer FSP" --/ Switch: 200 Ok + + note over "Payer FSP" #3498db: Payer FSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee FSP": Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /quotes/{ID}/error + "Payee FSP" --/ Switch : 200 Ok + + note over Switch, "Payee FSP" #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + + end + else Payee FSP calculation fails or rejects the request + + note over "Payee FSP", Switch: Payee FSP returns error to Switch + + "Payee FSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee FSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer FSP", Switch: Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer FSP", Switch: Switch returns error to Payer FSP + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg new file mode 100644 index 000000000..43af29f8a --- /dev/null +++ b/docs/technical/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg @@ -0,0 +1,183 @@ + + Quoting Service Sequences + + + Quoting Service Sequences + + + + + + + + Payer FSP + + Payer FSP + + Switch + Quoting + Service + + Switch + Quoting + Service + + Payee FSP + + Payee FSP + + + Payer FSP requests quote from Payee FSP + + + 1 + POST /quotes + + + 2 + 202 Accepted + + + + + 3 + Validate Quote Request + + + alt + [quote is valid] + + + + + 4 + Persist Quote Data + + + Switch forwards quote request to Payee FSP + <Payer based Rules> + + + 5 + POST /quotes + + + 6 + 202 Accepted + + + + + 7 + Calculate Fees/Charges + + + alt + [Payee FSP successfully calculates quote] + + + Payee FSP responds to quote request + + + 8 + PUT /quotes/{ID} + + + 9 + 200 Ok + + + + + 10 + Validate Quote Response + + + alt + [response is ok] + + + + + 11 + Persist Response Data + + + Switch forwards quote response to Payer FSP + <Payee whole request Rule> + + + 12 + PUT /quotes/{ID} + + + 13 + 200 Ok + + + Payer FSP continues + with transfer if quote + is acceptable... + + [response invalid] + + + Switch returns error to Payee FSP + + + 14 + PUT /quotes/{ID}/error + + + 15 + 200 Ok + + + Note that under this + scenario the Payer FSP + may not receive a response + + [Payee FSP calculation fails or rejects the request] + + + Payee FSP returns error to Switch + + + 16 + PUT quotes/{ID}/error + + + 17 + 200 OK + + + + + 18 + Persist error data + + + Switch returns error to Payer FSP + + + 19 + PUT quotes/{ID}/error + + + 20 + 200 OK + + [quote invalid] + + + Switch returns error to Payer FSP + + + 21 + PUT quotes/{ID}/error + + + 22 + 200 OK + + diff --git a/docs/technical/technical/quoting-service/qs-get-bulk-quotes.md b/docs/technical/technical/quoting-service/qs-get-bulk-quotes.md new file mode 100644 index 000000000..a9479883a --- /dev/null +++ b/docs/technical/technical/quoting-service/qs-get-bulk-quotes.md @@ -0,0 +1,8 @@ +# GET Quote By ID + +Design for the retrieval of a Bulk Quote by an FSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg) + diff --git a/docs/technical/technical/quoting-service/qs-get-quotes.md b/docs/technical/technical/quoting-service/qs-get-quotes.md new file mode 100644 index 000000000..b9295912f --- /dev/null +++ b/docs/technical/technical/quoting-service/qs-get-quotes.md @@ -0,0 +1,8 @@ +# GET Quote By ID + +Design for the retrieval of a Quote by an FSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-get-quotes-1.1.0.svg) + diff --git a/docs/technical/technical/quoting-service/qs-post-bulk-quotes.md b/docs/technical/technical/quoting-service/qs-post-bulk-quotes.md new file mode 100644 index 000000000..bcaafa5fb --- /dev/null +++ b/docs/technical/technical/quoting-service/qs-post-bulk-quotes.md @@ -0,0 +1,8 @@ +# POST Quote + +Design for a Bulk Quote request by an FSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg) + diff --git a/docs/technical/technical/quoting-service/qs-post-quotes.md b/docs/technical/technical/quoting-service/qs-post-quotes.md new file mode 100644 index 000000000..6709b144a --- /dev/null +++ b/docs/technical/technical/quoting-service/qs-post-quotes.md @@ -0,0 +1,8 @@ +# POST Quote + +Design for a Quote request by an FSP. + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-post-quotes-1.2.0.svg) + diff --git a/docs/technical/technical/releases.md b/docs/technical/technical/releases.md new file mode 100644 index 000000000..6e245e478 --- /dev/null +++ b/docs/technical/technical/releases.md @@ -0,0 +1,195 @@ +# Mojaloop Release Process + +The Mojaloop Release process follows a community led approach, specifically technical work-stream led, in collaboration and consultation with the Product Council and the Design Authority (DA). + +The DA frames the policies, guidelines and technical criteria for the releases (such as quality metrics) while Product defines the feature and product requirements where such aspects are involved. This is executed by the relevant workstream(s). + +## 1. Mojaloop Release process +![YM8f9iPhGU1jAfr-dQUk4e34QMGPG1ZWnbmC4ERGpsqp70GJH2he2Nje4poq_dii642B82j-Cj-2-HuYTkEF4poIBg8rJSfWYagBVOMyt6PQs5_P2YRE9magU_jE](https://github.com/mojaloop/design-authority-project/assets/10507686/075e528c-d4b2-4100-a2b9-6d06d77155d0) + +Community event (PI level planning), workstreams, features, release quality, testing, checklist, release candidate, example epic, Release + +The Mojaloop Release process follows a +- community led approach +- specifically technical work-stream led +- in collaboration and consultation with the Product Council and +- the Design Authority (DA) + +Criteria, guidelines: +The DA frames policies, guidelines and technical criteria for the releases while Product defines the feature and product requirements +Example releases notes, criteria for v17.0.0, [v17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) + +Testing continues after the release is made as well and daily cron jobs run to test, until the next release is made, to ensure stability. + +**Current tasks and acceptance criteria for Mojaloop (helm) releases**: + +Example story: [3122](https://github.com/mojaloop/project/issues/3122) , [3847](https://github.com/mojaloop/project/issues/3847) + +The decisions on what features to include, which ones will be ready and included are not included as they happen during planning stages (and based on deliverables) + +- [x] Ensure all core services and services included in release follow standards for + - [x] Dependabot alerts + - [x] License files + - [x] License headers in source files + - [x] Snyk alerts + - [x] codeowners files + - [x] Branch protection rules on main branches verified + - [x] Review open issues + - [x] Review open pull requests + - [x] Review audit exceptions provided and clear / minimize the list +- [x] Update manifests for "release Pull Request (PR)" GH actions WF +- [x] Validate the PR released and the process +- [x] Deploy default values with RC on AWS moja* environment + - [x] Validate GP collection works with 100% + - [x] Validate FX, inter-scheme tests works with 100% +- [x] Deploy, validate RC on a second environment + - [x] Validate GP collection works with 100% + - [x] Validate FX, inter-scheme tests works with 100% +- [x] Identify issues with QA Scripts if any - fix them and retest +- [x] QA for bugs, regressions, log them +- [x] Fix bugs logged if critical +- [x] Validate with TTK GP collection +- [x] Test on-us configuration option (deploy time change) and verify on-us tests pass +- [x] TTK test-cases repo Release is published +- [x] Release notes for helm RC is drafted + - [x] Guidance for migration from Release (may have to be a separate story if sufficiently big / complex) +- [x] Update release notes with Upgrade Strategy Guide link +- [x] Helm Release is published +- [x] Deployment of released Helm on a dev envirnoment + - [x] Helm release is deployed on dev successfully + - [x] Regression testing on dev using TTK collections + - [x] GP collection + - [x] Core Bulk collection + - [x] Third-party collection + - [x] SDK Bulk collection + - [x] SDK R2P collection + - [x] ISO 20022 mode tests + - [x] FX collection (or tests) + - [x] Interscheme test collection + - [x] Validation using CGS Golden path regression tests + - [x] Test upgradability from previous release (v16.0.4 / v16.0.0) +- [x] Deployment of released Helm on a QA environment + - [x] Helm release is deployed on QA successfully + - [x] Validation using Golden path regression tests on QA + - [x] GP collection + - [x] Core Bulk collection + - [x] Third-party collection + - [x] SDK Bulk collection + - [x] SDK R2P collection + - [x] FX collection (or tests) + - [x] ISO 20022 mode tests + - [x] Interscheme test collection +- [x] Validate daily cronJobs on dev/qa for GP runs well and Cleanup scripts +- Validate that we can upgrade from the previous stable release, and this is also to pick up any "gotchas" that may need to be addressed as part of the release, or perhaps release notes need to be updated assuming that it would be up to the upgrader to deal with. + + +## 2. Mojaloop Release process - proposed updates: + +Propose release schedule and timelines + +1. Example: Feature freeze for a (major) release before six weeks prior to the next PI kick-off (or community event) +1. Freeze bug fixes (non critical) to be included four weeks prior to release date +1. RC to be validated by at least one downstream implementer such Mini-loop or IaC or Core-test-harness or another implementer +1. Release to move ahead on time if there are no high or medium priority bugs open in RC and validated on a dev environment and one downstream team / implementer +1. Streamline release numbers between various components of the Mojaloop platform, such as the Finance Portal +1. Include performance numbers with details on the setup on which the baselining was performed +1. Resource usage: capture resource footprint for a base release +1. Document support mechanisms for Mojaloop releases + +## 3. Mojaloop helm release contents + +Mojaloop services that support core functionality for the platform and other key services supporting them, along with tools needed for testing such as simulators + +Core Functionality with Configurability +1. Account Lookup + - Account Lookup Admin + - Oracles + - ALS (Account Lookup Service) +2. Quoting + - Support for persistent/pass-through modes (configurable) +3. Transfers (Clearing) + - Support for on-us transfers (configurable) +4. Settlement + - Support for various types, granularity, and frequency +5. Transaction Requests (Request-to-pay functionality) +6. 3PPI Services (Third-Party Provider Interface) +7. API Layer - For parties, quotes, transfers, and transaction requests +8. Notifications + - ML-API-Adapter +9. Currency Conversion +10. Extended Functionality + - Central Event Processor + - Email Notifier (prior to version 15) + - Traceability and Monitoring Support + - Instrumentation +11. Auditing + - Comprehensive auditing capabilities +12. Supporting Services & Tools for Testing + - ML TTK (Testing Toolkit) + - ML Simulator + - SDK-Scheme-Adapters + - Payment Manager Instances +13. Third-Party Scheme Adapters + - Integration with third-party schemes +14. Participant Life-Cycle Management + - Participant Creation + - Participant Updates +15. Participant Support + - Simple, Easily Usable Tools for Adopters (Example: [SDK-Scheme-Adapter](https://github.com/mojaloop/sdk-scheme-adapter), [Integration Toolkit](https://github.com/mojaloop/integration-toolkit/tree/main) ) + - Onboarding Functionality and Support + +## 4. Mojaloop Platform +1. Primary mojaloop (helm) release and config that supports + - Core clearing engine including support for Bulk + - Quoting + - Account lookup and supporting components + - Settlement engine + - API layer + - Support for request-to-pay (transaction requests) + - Participant life-cycle management + - Ref: Mojaloop helm release (example: v15.1.0) +2. PISP / 3PPI functionality +3. API Gateway(s) + - Provide a secure API layer + - Provide Ingress, Egress, IP filtering, firewalls + - Support security mechanisms: JWS, mTLS + - Reference: WSO2 +4. Security components: + - HSM where relevant / used + - Identity & access management + - Cert management + - Connection management +5. Finance Portal, Reporting + - Portals for Hub Operations, Business Operations teams + - Portals, capabilities for Technical Operations teams + - Ref: FP v3 based on Business Operations Framework +6. Monitoring Support: + - Operational support and tracing (example: EFK, Prometheus, Grafana, Loki) + - IaC uses Grafana, Prometheus and Loki +7. Use IaC as reference, example: https://github.com/mojaloop/iac-modules/releases/tag/v5.7.0 + + + +## Current Releases + +> *Note: The versions below are the latest published version for each distinct release artifact provided for reference. Consult the release notes for the respective Helm release to see which versions are included in the [Helm Charts Packaged Release](#helm-charts-packaged-releases) version.* + +* Helm: [![Git Releases](https://img.shields.io/github/release/mojaloop/helm.svg?style=flat)](https://github.com/mojaloop/helm/releases) +* Central-Ledger: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-ledger.svg?style=flat)](https://github.com/mojaloop/central-ledger/releases) +* Ml-API-Adapter: [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-api-adapter.svg?style=flat)](https://github.com/mojaloop/ml-api-adapter/releases) +* Account-Lookup-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/account-lookup-service.svg?style=flat)](https://github.com/mojaloop/account-lookup-service/releases) +* Quoting-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/quoting-service.svg?style=flat)](https://github.com/mojaloop/quoting-service/releases) +* Transaction-Request-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/transaction-requests-service.svg?style=flat)](https://github.com/mojaloop/transaction-requests-service/releases) +* Bulk-API-Adapter: [![Git Releases](https://img.shields.io/github/release/mojaloop/bulk-api-adapter.svg?style=flat)](https://github.com/mojaloop/bulk-api-adapter/releases) +* Central-Settlement: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-settlement.svg?style=flat)](https://github.com/mojaloop/central-settlement/releases) +* Central-Event-Processor: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-event-processor.svg?style=flat)](https://github.com/mojaloop/central-event-processor/releases) +* Email-Notifier: [![Git Releases](https://img.shields.io/github/release/mojaloop/email-notifier.svg?style=flat)](https://github.com/mojaloop/email-notifier/releases) +* SDK-Scheme-Adapter: [![Git Releases](https://img.shields.io/github/release/mojaloop/sdk-scheme-adapter.svg?style=flat)](https://github.com/mojaloop/sdk-scheme-adapter/releases) +* Thirdparty-SDK: [![Git Releases](https://img.shields.io/github/release/mojaloop/thirdparty-sdk.svg?style=flat)](https://github.com/mojaloop/thirdparty-sdk/releases) +* Thirdparty-Api-Svc: [![Git Releases](https://img.shields.io/github/release/mojaloop/thirdparty-api-svc.svg?style=flat)](https://github.com/mojaloop/thirdparty-api-svc/releases) +* Auth-Svc: [![Git Releases](https://img.shields.io/github/release/mojaloop/auth-service.svg?style=flat)](https://github.com/mojaloop/auth-service/releases) +* ML-Testing-Toolkit: [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-testing-toolkit.svg?style=flat)](https://github.com/mojaloop/ml-testing-toolkit/releases) +* ML-Testing-Toolkit-Ui: [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-testing-toolkit-ui.svg?style=flat)](https://github.com/mojaloop/ml-testing-toolkit-ui/releases) + + +For an exhaustive list of helm releases, please visit the [Helm release page](https://github.com/mojaloop/helm/releases). diff --git a/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md new file mode 100644 index 000000000..7555e33f5 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/Readme.md @@ -0,0 +1,65 @@ +# SDK Support for Bulk Transfers - Overview +This design document describes how the SDK Scheme Adapter has been enhanced to support the bulk transfers use case. + +## Why? - Mojaloop bulk transfer limitations overcome +The implementation of bulk transfers within Mojaloop have the following limitations that this SDK bulk enhancement is designed to overcome. +1. Only individual transfers that are addressed to the same Payer DFSP may be included in a bulk quotes and bulk transfers call. +1. The number of individual quotes and transfers in each bulkQuotes and bulkTransfers respectively are limited to a maximum of 1000. +1. In order to allow bulk functionality, all Payee DFSPs need to create integration support for bulk messaging. I.e. If the bulk use case were to be introduced into an existing scheme, then all connecting DFSPs would need to upgrade their connections and integrations into their core banking systems. +1. There is currently no bulk discovery call. + +## SDK Scheme Adapter bulk enhancement requirements +The enhancements enable: +1. Transfers where the discovery has not yet been called. +1. No limit on number of transfers (limited by infrastructure, network capabilities but > 1k that ML FSPIOP specifies) +1. Payee integration support for bulk being optional +1. Optionally support + - a single call that performs Discovery, Agreement and Transfer + - independently accepting of party lookups + - independently accepting of quotes + - setting a fee limit on the auto acceptance of quotes + - the skipping of the discovery phase + - running only the discovery phase + - setting an expiration for the bulk message + - home transaction IDs for both the bulk message and the individual transfers. + - both synchronous API calls and asynchronous API calls + +## Features Implemented +The current implementation does not include all the features. All the features that have been completed are functional and can be used. Additional features and enhancements can be added to the existing functionality as prioritized by Mojaloop product and the community. This aligns with the MVP (Minimum Viable Product) agile concept. +These are the features that are currently implemented: + +|Feature|Implementation Status|Release Version| +|---|---|---| +|Asynchronous Mode| released | v14.1.0 RC| +|Synchronous Mode| not started | | +|Auto Accept Party| not started | | +|Auto Accept Quote (with fee limit)| not started | | +|Only Validate Party| not started | | +|Skip Party Lookup| not started | | +|Bulk Expiration| not started | | +|Payee SDK - Demultiplexing bulk quotes| not started | | +|Payee SDK - Demultiplexing bulk transfers| not started | | +|Mojaloop - Bulk Patch Notification| not started | | +|Payee SDK - Demultiplexing bulk patch notification| not started | | + +### Functional Diagram +![Functional Diagram](../assets/BulkSDKEnhancements.drawio.svg) + +## Architectural Diagram +The Event Sourcing architecture has split the implementation into four components +1. **Backend API** : +The backend API receives API call and produces corresponding domain events, and monitors domain events to produce API callbacks. +1. **Domain Event Handler**: +The Domain Event Handler consumes Domain Events and produces Command events. +1. **Command Event Handler**: +The Command Event Handler consumes command events and produces domain events +1. **FSPIOP API**: +The FSPIOP API monitors domain events and produces corresponding FSPIOP calls, and monitors API Callbacks to produce corresponding domain events. + +![Architectural Diagram](../assets/BulkSDKEnhancements-Architecture.drawio.svg) + + +## Overview Sequence Diagram +Here is a sequence diagram that outlines the role that the SDK Scheme Adapter will play in a bulk call, both for a Payer DFSP and a Payee DFSP. +![Bulk Transfer Sequence Diagram Overview](../assets/sequence/SDKBulkSequenceDiagram.svg) + diff --git a/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md new file mode 100644 index 000000000..638edcb54 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-API-Design.md @@ -0,0 +1,154 @@ +# SDK Support for Bulk Transfers - API +The Payer SDK Scheme Adapter enhancements have been added to the API under the /BulkTransactions endpoint. +- **POST** /bulkTransactions +- **PUT** /bulkTransactions +- **PUT** /bulkTransactions callback + +The Outbound OpenAPI definition can be found [here](https://github.com/mojaloop/api-snippets/blob/master/sdk-scheme-adapter/v2_0_0/outbound/openapi.yaml). +The Inbound OpenAPI definition can be found [here](https://github.com/mojaloop/api-snippets/blob/master/sdk-scheme-adapter/v2_0_0/inbound/openapi.yaml). + + +## Technical Sequence Diagram +![Technical Bulk Transfer Sequence Diagram](https://raw.githubusercontent.com/mojaloop/sdk-scheme-adapter/master/docs/design-bulk-transfers/assets/api-sequence-diagram.svg) + +## Error Tables for bulk transfers +[Table of Error Codes](./assets/sequence/BULK-ERRORCODES.md) + +### Discovery Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Party Lookup Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Processing Error | +| Internal server error | 2001 | 503 | Processing Error | +| Timeout Resolving Party | 2004 | 503 | Processing Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Party not found | 3204 | 202 | Processing Error | + +### Agreement Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Quotes Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Technical Error | +| Internal server error | 2001 | 503 | Technical Error | +| Not implemented | 2002 | 501 | Processing Error | +| Service currently unavailable | 2003 | 503 | Processing Error | +| Server timed out | 2004 | 503 | Processing Error | +| Server busy | 2005 | 503 | Processing Error | +| Generic client error | 3000 | 400 | Request Validation Error | +| Unacceptable version requested | 3001 | 406 | Not acceptable Error | +| Unknown URI | 3002 | 404 | Not Found Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Malformed syntax | 3101 | 400 | Request Validation Error | +| Missing mandatory element | 3102 | 400 | Request Validation Error | +| Too many elements | 3103 | 400 | Request Validation Error | +| Too large payload | 3104 | 400 | Request Validation Error | +| Invalid signature | 3105 | 403 | Forbidden Error | +| Destination FSP Error | 3201 | 404 | Not Found Error | +| Payer FSP ID not found | 3202 | 404 | Not Found Error | +| Payee FSP ID not found | 3203 | 404 | Not Found Error | +| Quote ID not found | 3205 | 404 | Not Found Error | +| Bulk quote ID not found | 3209 | 404 | Not Found Error | +| Generic expired error | 3300 | 503 | Processing Error | +| Quote expired | 3302 | 503 | Processing Error | +| Generic Payer error | 4000 | 400 | Request Validation Error | +| Generic Payer rejection | 4100 | 403 | Forbidden Error | +| Payer limit error | 4200 | 400 | Request Validation Error | +| Payer permission error | 4300 | 403 | Forbidden Error | +| Generic Payer blocked error | 4400 | 403 | Forbidden Error | +| Generic Payee error | 5000 | 503 | Processing Error | +| Payee FSP insufficient liquidity | 5001 | 503 | Processing Error | +| Generic Payee rejection | 5100 | 403 | Forbidden Error | +| Payee rejected quote | 5101 | 503 | Processing Error | +| Payee FSP unsupported transaction type | 5102 | 503 | Processing Error | +| Payee rejected quote | 5103 | 503 | Processing Error | +| Payee unsupported currency | 5106 | 503 | Processing Error | +| Payee limit error | 5200 | 503 | Processing Error | +| Payee permission error | 5300 | 403 | Forbidden Error | +| Generic Payee blocked error | 5400 | 403 | Forbidden Error | + + + +### Transfer Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 404, + "mojaloopError": { + "errorInformation": { + "errorCode": "3210", + "errorDescription": "Bulk transfer ID not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Transfer Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Processing Error | +| Internal server error | 2001 | 503 | Processing Error | +| Server timed out | 2004 | 503 | Processing Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Bulk transfer ID not found | 3210 | 404 | Processing Error | +| Generic expired error | 3300 | 503 | Processing Error | +| Transaction request expired | 3301 | 503 | Processing Error | +| Transfer expired | 3303 | 503 | Processing Error | +| Generic Payee error | 5000 | 400 | Processing Error | +| Payee FSP insufficient liquidity | 5001 | 400 | Processing Error | +| Generic Payee rejection | 5100 | 400 | Processing Error | +| Payee rejected quote | 5101 | 400 | Processing Error | +| Payee FSP unsupported transaction type | 5102 | 400 | Processing Error | +| Payee FSP rejected quote | 5103 | 400 | Processing Error | +| Payee rejected transaction | 5104 | 400 | Processing Error | +| Payee FSP rejected transaction | 5105 | 400 | Processing Error | +| Payee unsupported currency | 5106 | 400 | Processing Error | +| Payee limit error | 5200 | 400 | Processing Error | +| Payee permission error | 5300 | 403 | Processing Error | +| Generic Payee blocked error | 5400 | 400 | Processing Error | diff --git a/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md new file mode 100644 index 000000000..4df1345f9 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-EventSourcing-Design.md @@ -0,0 +1,179 @@ +# SDK Support for Bulk Transfers - DDD and Event Sourcing Design +## Design overview +This diagram gives an overview of the SDK design. + +![Design Overview](../assets/overview-drawio.png) + +An http 202 response when posting an asynchronous request means that the SDK has accepted the request, and that the request will be processed and a response provided. Because of the potential long delays involved in processing large numbers of bulk payments in an asynchronous way, a new design approach in the SDK was necessary to meet the 202 response expectations. + +## DDD and Event sourcing design +An event sourcing and domain driven was chosen, as this solves all requirements of reliability and scalability while takeing advantage of the lib's and tools that have been built for the Mojaloop vNext architecture. + +## Bulk Payer DFSP SDK-Scheme-Adapter +### Outbound event sourcing sequence diagram +![Outbound sequence diagram](../assets/sequence/outbound-sequence.svg) + +## Payee DFSP SDK-Scheme-Adapter +### Inbound bulk quotes event sourcing sequence diagram +![Inbound bulk quotes sequence](../assets/sequence/inbound-bulk-quotes-sequence.svg) + +### Inbound bulk transfers event sourcing sequence diagram +![Inbound bulk transfers sequence](../assets/sequence/inbound-bulk-transfers-sequence.svg) + + +## Redis Store Data mapping for outbound bulk transfer +### 1. States (Global and individual) + +#### Command: +``` +HSET +``` +#### Key: +``` +outboundBulkTransaction_< bulkTransactionId > +``` + +#### Attributes: +- **bulkTransactionId**: bulkTransactionId +- **bulkHomeTransactionID**: Home transaction ID +- **request**: { + options: Options, + extensionList: Bulk Extension List +} +- **individualItem_< transactionId >**: Serialize ({ + id: transactionId + request: {} + state: Individual state + batchId: `` + partyRequest: {} + quotesRequest: {} + transfersRequest: {} + partyResponse: {} + quotesResponse: {} + transfersResponse: {} + lastError: {} + acceptParty: bool + acceptQuotes: bool +}) +- **state**: Global state + - RECEIVED + - DISCOVERY_PROCESSING +- **bulkBatch_< batchId >**: Serialize ({ + id: batchId + state: Individual state + - AGREEMENT_PROCESSING + - TRANSFER_PROCESSING + bulkQuoteId: `` + bulkTransferId: `` (Can be batchId) +}) +- **partyLookupTotalCount**: Total number of party lookup requests +- **partyLookupSuccessCount**: Total number of party lookup requests those are succeeded +- **partyLookupFailedCount**: Total number of party lookup requests those are failed +- **bulkQuotesTotalCount**: Total number of bulk quotes requests +- **bulkQuotesSuccessCount**: Total number of quotes requests those are succeeded +- **bulkQuotesFailedCount**: Total number of quotes requests those are failed +- **bulkTransfersTotalCount**: Total number of bulk transfers requests +- **bulkTransfersSuccessCount**: Total number of bulk transfers requests those are succeeded +- **bulkTransfersFailedCount**: Total number of bulk transfers requests those are failed + +::: tip Notes +- Kafka messages should contain bulkID. +- To update the global state use the command `HSET bulkTransaction_< bulkTransactionId > state < stateValue >` +::: + +### 2. For mapping individual callbacks with individual bulk items + +#### Command: +``` +HSET outboundBulkCorrelationMap +``` + +#### Attributes: +- partyLookup_``_``(_``): "{ bulkTransactionId: ``, transactionId: `` }" +- bulkQuotes_``: "{ bulkTransactionId: ``, batchId: `` }" +- bulkTransfers_``: "{ bulkTransactionId: ``, batchId: ``, bulkQuoteId: `` }" +- bulkHomeTransactionId_``: "{ bulkTransactionId: `` }" + +::: tip Notes: +- We can use `HKEYS` command to fetch all the individual transfer IDs in a bulk to iterate +::: + +## Redis message format for inbound bulk transfer +### 1. Bulk Quotes +#### Command: +``` +HSET +``` +#### Key: +``` +inboundBulkQuotes_< bulkQuotesId > +``` + +#### Attributes: +- **bulkQuotesId**: bulkQuotesId +- **individualItem_< quotesId >**: Serialize ({ + id: quotesId + request: {} + state: Individual state + quotesRequest: {} + quotesResponse: {} + lastError: {} +}) +- **state**: Global state + - RECEIVED + - PROCESSING +- **bulkQuotesTotalCount**: Total number of bulk quotes requests +- **bulkQuotesSuccessCount**: Total number of quotes requests those are succeeded +- **bulkQuotesFailedCount**: Total number of quotes requests those are failed + +::: tip Notes +- Kafka messages should contain bulkQuotesId. +- To update the global state use the command `HSET bulkQuotes_< bulkQuotesId > state < stateValue >` +::: + +### 2. Bulk Transfers +#### Command: +``` +HSET +``` +#### Key: +``` +inboundBulkTransfer_< bulkTransferId > +``` + +#### Attributes: +- **bulkTransferId**: bulkTransferId +- **individualItem_< transferId >**: Serialize ({ + id: transferId + request: {} + state: Individual state + transfersRequest: {} + transfersResponse: {} + lastError: {} +}) +- **state**: Global state + - RECEIVED + - PROCESSING +- **bulkTransferTotalCount**: Total number of bulk transfers requests +- **bulkTransferSuccessCount**: Total number of transfers requests those are succeeded +- **bulkTransferFailedCount**: Total number of transfers requests those are failed + +::: tip Notes +- Kafka messages should contain bulkTransferId. +- To update the global state use the command `HSET bulkTransfer_< bulkTransferId > state < stateValue >` +::: + +### 3. For mapping individual callbacks with individual bulk items + +#### Command: +``` +HSET inboundBulkCorrelationMap +``` + +#### Attributes: +- quotes_``: "{ bulkQuoteId: `` }" +- transfers_``: "{ bulkTransferId: ``, bulkQuoteId: `` }" + +::: tip Notes: +- We can use `HKEYS` command to fetch all the individual transfer IDs in a bulk to iterate +::: diff --git a/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md new file mode 100644 index 000000000..790c710c7 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/BulkEnhancements/SDKBulk-Tests.md @@ -0,0 +1,201 @@ +# SDK Support for Bulk Transfers - Tests +## Test Strategy +The quality of the delivered solution is as good as the quality of the tests and testing strategy adopted. The distributed nature of this event sourcing solution affected the testing strategy chosen. Multiple types of test were created, each supporting the others and designed to pick bugs as quickly as possible. + +The Command event handler and the domain event handler have both unit tests and narrow integration tests as the base testing. The FSPIOP API and backend API components have only unit tests. +Great emphasis was put on the functional tests which then tested the four components working together in both happy and unhappy path scenarios. + +### Narrow integration tests +These tests are written in jest and assert for example the updated state store and produced events based on a command event generated. + +**Command Handler Integration Test Harness** + +![Local Test Setup](../assets/CHIntegrationTestHarness.drawio.svg) + +### The functional test testharness +The functional test makes use of the TTK which simulates both the Payer and the Payee DFSP backends. + +:::tip Note +This test harness tests both the Payer SDK and the Payee SDK. +::: + +![Local Test Setup](../assets/bulk-functional-local-test-setup.drawio.svg) + +:::tip Note +These test can be run on the local checked out monorepo, and are run in the CI pipeline, and are included in the helm as helm tests used to confirm deployment. +::: + +## Payer DFSP Integration Test Matrix + +
    + +|Test Cases|C1|C2|C3|C4|C5|C6|C7|C8|C9|C10|C11|C12| +|---|---|---|---|---|---|---|---|---|---|---|---|---| +|INT D-1||||x||||||||| +|INT D-2||x||||||||||| +|INT D-3||x||||||||||| +|INT D-4|x|||||||||||| +|INT D-5|||x|||||||||| +|INT D-6|||x|||||||||| +|INT A-1||||||x||||||| +|INT A-2|||||x|||||||| +|INT T-1|||||||||||x|| +|INT T-2||||||||||x||| +|INT T-3|||||||||x|||| +|INT T-4|||||||||||x|| +|INT T-5|||||||x|||||| +|INT T-6||||||||||||x| + +
    + +## Payer DFSP Functional Test Matrix + +
    + +|Test Cases|B1|B2|B3|B4|B5|F1|F2|F3|F4|F5|F6|F7|F8|F9|D1|D2|D3|D4|D5|D6|D7|D8|D9|D10|D11|D12|D13|D14|D15|D16|D17|D18|D19|D20|C1|C2|C3|C4|C5|C6|C7|C8|C9|C10|C11|C12| +|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +|FUNC 1|x|x|x|x|x|x|x||x|x||x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x|x|x|x|x|x|x|x|x|x|x||x|x|x|x +|FUNC 2|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 3|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 4|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 5|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|FUNC 6|x|x||||x||x|||||||x|x|x|x|x||||||||||||||||x|x|x||||||||| +|TC-BQ1|x|x|x|||x|x||x||x||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x +|TC-BQ2|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x +|TC-BQ3|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ4|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ5|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ6|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ7|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ8|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ9|x|x|x|||x|x||x|x|x||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x|||||| +|TC-BQ10|x|x|x|||x|x||x||x||||x|x|x|x|x|x|x|x|x|x|||||||||||x|x|x|x|x|x|||||x|x| +|TC-BQ11|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x||||||| +|TC-BQ13|x|x|x|||x|x||x|x|||||x|x|x|x|x|x|x|x|x|x|x||||||||||x|x|x|x|x|x||||||| +|TC-BT1|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT2|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT3|x|x|x|x|x|x|x||x|x|x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT4|x|x|x|x|x|x|x||x|x|x|x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT5|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT6|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT7|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| +|TC-BT8|x|x|x|x|x|x|x||x|x||x||x|x|x|x|x|x|x|x|x|x|x|x|x|x|||x|x||||x|x|x|x|x|x|x||x|x|x|x| + +
    + +## Payer DFSP Features reference +|#|Outbound Features|Detail| +|---|---|---| +|B1|Backend API|POST /bulkTransactions SDKBulkRequest| +|B2|Backend API|Event SDKOutboundBulkAcceptPartyInfoRequested| +|B3|Backend API|PUT /bulkTransactions/{bulkTransactionId} Accept Party| +|B4|Backend API|PUT /bulkTransactions/{bulkTransactionId} Accept Quote| +|B5|Backend API|PUT /bulkTransactions/{bulkTransactionId} Results| +|F1|FSPIOP API|GET /parties| +|F2|FSPIOP API|PUT /parties/{Type}/{ID}| +|F3|FSPIOP API|PUT /parties/{Type}/{ID}/error| +|F4|FSPIOP API|POST /bulkQuotes| +|F5|FSPIOP API|PUT /bulkQuotes/{ID}| +|F6|FSPIOP API|PUT /bulkQuotes/{ID}/error| +|F7|FSPIOP API|POST /bulkTransfers| +|F8|FSPIOP API|PUT /bulkTransfers/{ID}| +|F9|FSPIOP API|PUT /bulkTransfers/{ID}/error| +|D1|Domain Event Handler|SDKOutboundBulkRequestReceived| +|D2|Domain Event Handler|SDKOutboundBulkPartyInfoRequested| +|D3|Domain Event Handler|PartyInfoCallbackReceived| +|D4|Domain Event Handler|PartyInfoCallbackProcessed| +|D5|Domain Event Handler|SDKOutboundBulkPartyInfoRequestProcessed| +|D6|Domain Event Handler|SDKOutboundBulkAcceptPartyInfoReceived| +|D7|Domain Event Handler|SDKOutboundBulkAutoAcceptPartyInfoRequested| +|D8|Domain Event Handler|SDKOutboundBulkAcceptPartyInfoProcessed| +|D9|Domain Event Handler|BulkQuotesCallbackReceived| +|D10|Domain Event Handler|BulkQuotesCallbackProcessed| +|D11|Domain Event Handler|SDKOutboundBulkQuotesRequestProcessed| +|D12|Domain Event Handler|SDKOutboundBulkAcceptQuoteReceived| +|D13|Domain Event Handler|SDKOutboundBulkAcceptQuoteProcessed| +|D14|Domain Event Handler|SDKOutboundBulkAutoAcceptQuoteRequested| +|D15|Domain Event Handler|SDKOutboundBulkAutoAcceptQuoteProcessed| +|D16|Domain Event Handler|BulkTransfersCallbackReceived| +|D17|Domain Event Handler|BulkTransfersCallbackProcessed| +|D18|Domain Event Handler|SDKOutboundBulkTransfersRequestProcessed| +|D19|Domain Event Handler|SDKOutboundBulkResponseSent| +|D20|Domain Event Handler|SDKOutboundBulkResponseSentProcessed| +|C1|Command Event Handler|ProcessSDKOutboundBulkRequest| +|C2|Command Event Handler|ProcessSDKOutboundBulkPartyInfoRequest| +|C3|Command Event Handler|ProcessPartyInfoCallback| +|C4|Command Event Handler|ProcessSDKOutboundBulkAcceptPartyInfo| +|C5|Command Event Handler|ProcessSDKOutboundBulkQuotesRequest| +|C6|Command Event Handler|ProcessBulkQuotesCallback| +|C7|Command Event Handler|ProcessSDKOutboundBulkAcceptQuote| +|C8|Command Event Handler|ProcessSDKOutboundBulkAutoAcceptQuote| +|C9|Command Event Handler|ProcessSDKOutboundBulkTransfersRequest| +|C10|Command Event Handler|ProcessBulkTransfersCallback| +|C11|Command Event Handler|PrepareSDKOutboundBulkResponse| +|C12|Command Event Handler|ProcessSDKOutboundBulkResponseSent| + +## Test Cases reference + +|Group|# test case|Test Type|Status|Detail| +|--- |--- |--- |--- |--- | +|**Discovery** - Command Handler Integration Tests||||| +|(process_bulk_accept_party_info.test.ts)|INT D-1|Integration|Pass|Given inbound command event ProcessSDKOutboundBulkAcceptPartyInfo is received Then the logic should loop through individual transfer in the bulk request And update the individual transfer state to DISCOVERY_ACCEPTED or DISCOVERY_REJECTED based on the value in the incoming event And update the overall global state to DISCOVERY_ACCEPTANCE_COMPLETED And outbound event SDKOutboundBulkAcceptPartyInfoProcessed should be published| +|(process_bulk_party_info_request.test.ts)|INT D-2|Integration|Pass|Given Party info does not already exist for none of the individual transfers. And Party Lookup is not skipped When inbound command event ProcessSDKOutboundBulkPartyInfoRequest is received Then the global state should be updated to DISCOVERY_PROCESSING And PartyInfoRequested kafka event should be published for each individual transfer. And State for individual transfer should be updated to DISCOVERY_PROCESSING| +|(process_bulk_party_info_request.test.ts)|INT D-3|Integration|Pass|Given Party info exists for individual transfers. And Party Lookup is not skipped When inbound command event ProcessSDKOutboundBulkPartyInfoRequest is received Then the global state should be updated to DISCOVERY_PROCESSING. And PartyInfoRequested outbound event should not be published for each individual transfer. And State for individual transfer should be updated to RECEIVED.| +|(process_bulk_request.test.ts)|INT D-4|Integration|Pass|When inbound command event ProcessSDKOutboundBulkRequest is received Then outbound event SDKOutboundBulkPartyInfoRequested should be published And Global state should be updated to RECEIVED.| +|(process_party_info_callback.test.ts)|INT D-5|Integration|Pass|Given receiving party info does not exist And receiving party lookup was successful When inbound command event ProcessPartyInfoCallback is received Then the state for individual successful party lookups should be updated to DISCOVERY_SUCCESS And the data in redis for individual transfer should be updated with received party info And outbound event PartyInfoCallbackProcessed event should be published And if all lookups are incomplete, outbound event ProcessSDKOutboundBulkPartyInfoRequestProcessed should not be published And neither outbound event SDKOutboundBulkAutoAcceptPartyInfoRequested/SDKOutboundBulkAutoAcceptPartyInfoRequested should be published| +|(process_party_info_callback.test.ts)|INT D-6|Integration|Pass|Given receiving party info does not exist And receiving party lookup was successful When inbound command event ProcessPartyInfoCallback is received Then the state for individual successful party lookups should be updated to DISCOVERY_SUCCESS And the data in redis for individual transfer should be updated with received party info And outbound event PartyInfoCallbackProcessed event should be published And if all lookups are complete, outbound event ProcessSDKOutboundBulkPartyInfoRequestProcessed should be published And if auto accept party is false, outbound event SDKOutboundBulkAcceptPartyInfoRequested should be published.| +|**Agreement** - Command Handler Integration Tests||||| +|(process_bulk_quotes_callback.test.ts)|INT A-1|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessBulkQuotesCallback is received Then the logic should update the individual batch state to AGREEMENT_COMPLETED or AGREEMENT_FAILED, And for each individual transfers in the batch, the state could be AGREEMENT_SUCCESS or AGREEMENT_FAILED accordingly And the individual quote data in redis should be updated with the response And the global BulkTransaction state should be AGREEMENT_ACCEPTANCE_PENDING And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published| +|(process_bulk_quotes_callback.test.ts)|INT A-2|Integration|Pass|When Inbound command event ProcessSDKOutboundBulkQuotesRequest is received Then the logic should update the global state to AGREEMENT_PROCESSING, And create batches based on FSP that has DISCOVERY_ACCEPTED state And also has config maxEntryConfigPerBatch And publish BulkQuotesRequested per each batch And update the state of each batch to AGREEMENT_PROCESSING.| +|**Transfers** - Command Handler Integration Tests||||| +|(prepare_sdk_outbound_bulk_response.test.ts)|INT T-1|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event PrepareSDKOutboundBulkResponseCmdEvt is received And SDKOutboundBulkResponsePreparedDmEvt should be published for each transfer batch And the Bulk Transaction global state should be updated to RESPONSE_PROCESSING| +|(process_bulk_transfers_callback.test.ts )|INT T-2|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event ProcessBulkTransfersCallbackCmdEvt is received Then the transfer batch state should be updated to TRANSFERS_COMPLETED States of failed quotes should remain AGREEMENT_FAILED And the logic should loop through individual transfers in the batch and update the state to TRANSFER_SUCCESS or TRANSFER_FAILED And BulkTransferProcessedDmEvt should be published for each transfer batch And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published And domain event BulkTransfersCallbackProcessed should be published And domain event SDKOutboundBulkTransfersRequestProcessed should be published| +|(process_bulk_transfers_request.test.ts)|INT T-3|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessSDKOutboundBulkTransfersRequestCmdEvt is received Then the global Bulk Transaction State should be updated to TRANSFERS_PROCESSING And the individual batch state should be equal to either TRANSFERS_PROCESSING or TRANSFERS_FAILED, And for each individual transfers in the batch, the state AGREEMENT_ACCEPTED or AGREEMENT_REJECTED depending on the acceptQuotes = TRUE/FALSE, And for each individual transfers in an AGREEMENT_FAILED state should not be altered, And the individual quote data in redis should be updated with the response And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published| +|(process_prepare_bulk_response.test.ts)|INT T-4|Integration|Pass|When inbound command event PrepareSDKOutboundBulkResponseCmdEvt is received Then SDKOutboundBulkResponsePreparedDmEvnt should be published| +|(process_sdk_outbound_bulk_accept_quote.test.ts)|INT T-5|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessSDKOutboundBulkAcceptQuote is received Then the global Bulk Transaction State should be updated to AGREEMENT_ACCEPTANCE_COMPLETED And the individual batch state should be equal to either AGREEMENT_COMPLETED or AGREEMENT_FAILED, And for each individual transfers in the batch, the state AGREEMENT_ACCEPTED or AGREEMENT_REJECTED depending on the acceptQuotes = TRUE/FALSE, And the individual quote data in redis should be updated with the response And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published| +|(process_sdk_outbound_bulk_response_sent.test.ts)#|INT T-6|Integration|Pass|Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event ProcessSDKOutboundBulkResponseSentCmdEvt is received And SDKOutboundBulkResponseSentProcessedDmEvt should be published for each transfer batch And the Bulk Transaction global state should be updated to RESPONSE_SENT | +|**Happy Path:** (bulk-happy-path.json)||||| +|- 1 transfer with acceptParty and acceptQuote set to true||||| +||TC-BHP1|Functional|Pass|4 transfers to 2 dfsps, with acceptParty and acceptQuote set to true| +||TC-BHP2|Validation|Pass|Bulk transaction having a format error| +|**Parties Errors:** (bulk-parties-error-cases.json)||||| +|- 1 transfer in the request||||| +||TC-BP1|Functional|Pass|Receiver sends error for in parties response| +||TC-BP2|Functional|Pass|Receiver timesout| +||TC-BP3|Functional|Pass|skipPartyLookup is false and receiver info exists in the request.| +|- 2 transfers in the request||||| +||TC-BP4|Functional|Pass|Receiver sends an error response for one of the transfers| +||TC-BP5|Functional|Pass|Receiver times out sending response for one of the transfers| +||TC-BP6|Functional|Pass|Do not get any response from the receiver for both the transfers| +|**Quotes Errors:** (bulk-quotes-error-cases.json)||||| +|- 2 transfers having the same receiver fsp id ||||| +|- acceptParty for all transfers||||| +||TC-BQ1|Functional|Pass|Receiver fsp fails the entire batch | +||TC-BQ2|Functional|Pass|Receiver fsp times out the entire batch| +||TC-BQ3|Functional|Pass|Receiver fsp sends only one response and skips the other| +||TC-BQ4|Functional|Out of scope for MVP|Receiver fsp sends one success response and one failure response (Not Implemented - Issue 3015)| +|- acceptParty varying||||| +||TC-BQ5|Functional|Pass|One true, one false| +||TC-BQ6|Functional|Out of scope for MVP| Accept party false for all responses - Then only party details and no quote response, final state to be COMPLETED (Not Implemented - Issue 3015)| +||TC-BQ7|Functional|Out of scope for MVP|True is sent only for one quote in PUT /bulkTxn acceptParty, ignoring second one (Not Implemented - Issue 3015)| +||TC-BQ8|Functional|Out of scope for MVP|false is sent only for one quote in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)| +|- 2 transfers having different receiver fsp ids - acceptParty for all transfers||||| +||TC-BQ9|Functional|Pass|One batch sends an error | +||TC-BQ10|Functional|Pass|Both batches sends error| +||TC-BQ11|Functional|Pass|One batch times out| +|- 3 transfers with 2 transfers having 1 receiver fsp id and the other having a different one||||| +||TC-BQ12|Functional|Out of scope for MVP|- The batch with 2 transfers sends only 1 transfer response and the other batch sends the success response (Not implemented - issue 3015)| +||TC-BQ13|Functional|Out of scope for MVP|Error in switch for unsupported currency - (issue - | +|**Transfers Errors:** (bulk-transfer-errors.json)||||| +|- One bulkTransfer with 2 transfers ||||| +|- acceptQuote for all transfers||||| +||TC-BT1|Functional|Pass|Receiver fails the entire batch | +||TC-BT2|Functional|Pass|Receiver times out for the entire batch| +||TC-BT3|Functional|Out of scope for MVP|Receiver fsp sends only one response and skips the other (Not Implemented - Issue 3015)| +||TC-BT4|Functional|Intermittent Failures|Receiver fsp sends one success response and one failure - ( Issue: 3019 )| +|- acceptQuote varying||||| +||TC-BT5|Functional|Out of scope for MVP|One true one false - TC2 - Bug 2958| +||TC-BT6|Functional|Out of scope for MVP|Accept quote - All false (Not Implemented - Issue 3015)| +||TC-BT7|Functional|Out of scope for MVP|True is sent only for one transfer in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)| +||TC-BT8|Functional|Out of scope for MVP|false is sent only for one transfer in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)| + diff --git a/docs/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md b/docs/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md new file mode 100644 index 000000000..6e70d5a21 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/IntegrationBulkFlowPatterns.md @@ -0,0 +1,29 @@ +# Integration Core Banking Systems using Bulk transfers +There are three patterns that can be used when building the Payer DFSP integrations for bulk transfers. +1. **Three phase** transfer integration. This aligns with the three Mojaloop transaction phases. I.e. Discovery, Agreement and Transfer. +1. **Double API Integration**. This pattern is described in detail in the sequence diagram below. It involves combining the Discovery and Agreement phases; as the first phase; the results are presented to the Payer for confirmation; following which the Transfer phase is executed as the second phase. +![Payer DFSP Double Integration API Flow Pattern](./assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg) +1. **Single API Integration**. This pattern is described in detail in the sequence diagram below. Here all three phases are combined to produce a single synchronous transfer call. +![Payer DFSP Single Integration API Flow Pattern](./assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg) + + +::: tip 2-Phased Commit +All Payer DFSP Integration Patterns support a 2 phased (reservation and commit phase) commit. +::: + +## Payee DFSP requirements +The updates to the SDK Scheme Adapter will ensure that DFSP that have built integrations into Mojaloop will not be required to make any change in order to support the receiving of bulk transfers. I.e. the SDK scheme adapter will receive bulk transfer messages and convert them to individual transfer messages. +If a Payee DFSP would like to take advantage of the bulk transfer message, integration for bulk messages can be implemented when it makes sense to do so for each Payee DFSP. + + +## Ideal Payee Integration Flow Pattern + +Here the AML checks and fees are calculated in the Agreement Phase, and the transfer phase is performed in two phases namely a reservation phase and a commit phase. + +![Payee DFSP Bulk Integration Ideal Pattern](./assets/sequence/PayeeDFSPBulkIdealPattern.svg) + +## Vendor API only supports Single API call +If the Core Banking Systems only support a single API call to perform all transfer related checks and phases. This is the pattern that is most commonly supported. +### Call Transfer on the Patch Notification +![Payee DFSP Integration during Patch Notification](./assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg) +A failure at anytime after the PATCH notification **[Step 19]** will result in a reconciliation error. This can be catered for by building in recompensation methods. E.g. initiate a refund transfer if an error occurs after step 19. diff --git a/docs/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md b/docs/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md new file mode 100644 index 000000000..b7814a1a1 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/IntegrationFlowPatterns.md @@ -0,0 +1,43 @@ +# Integrating Core Banking Systems to Mojaloop Patterns + +Integrating a core banking system into a modern, real-time, push-based transaction flow can come with some challenges. These are largely based on what vendor-provided integration APIs are on offer. This documents discusses what an ideal integration should look like, some of the typical limitations seen in vendor API's, and flow patterns that are used to overcome some of these limitations and a discussion on the risks. + +## Payer DFSP Integration Patterns + +There are three patterns that can be used when building the Payer DFSP integrations +1. **Three phase** transfer integration. This aligns with the three Mojaloop transaction phases. I.e. Discovery, Agreement and Transfer. +1. **Double API Integration**. This pattern is described in detail in the sequence diagram below. It involves combining the Discovery and Agreement phases; as the first phase; the results are presented to the Payer for confirmation; following which the Transfer phase is executed as the second phase. +![Payer DFSP Double Integration API Flow Pattern](./assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg) +1. **Single API Integration**. This pattern is described in detail in the sequence diagram below. Here all three phases are combined to produce a single synchronous transfer call. +![Payer DFSP Single Integration API Flow Pattern](./assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg) + +::: tip 2-Phased Commit +All Payer DFSP Integration Patterns support a 2 phased (reservation and commit phase) commit. +::: + +## Payee DFSP ideal integration pattern +Ideally a vendor's API's will provide the following. +1. To be able to perform AML checks ahead of and independent of the transfer. +1. To be able to calculate the fees of a transfer ahead of and independent of the transfer. +1. To be able to perform the transfer in two phases. I.e. A reserve phase, and then a committing phase. + +If these are available in the Vendor's API, then an ideal integration can be built that reduces reconciliation errors when unexpected errors occur, and has the lowest risk to the DFSP. + +### Ideal Payee Integration Flow Pattern + +Here the AML checks and fees are calculated in the Agreement Phase, and the transfer phase is performed in two phases namely a reservation phase and a commit phase. + +![Payee DFSP Integration Ideal Pattern](./assets/sequence/PayeeDFSPIdealPattern.svg) + +::: warning Common limitation +A common limitation in Vendor API's is that all these functions are combined into a single phase single API call to make a transfer. +::: + +## Vendor API only supports Single API call +If the Core Banking System only supports a single API call to perform all transfer related checks and phases, there are two patterns that should be considered. +1. Call Transfer on the Patch Notification +![Payee DFSP Integration during Patch Notification](./assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg) +A failure at anytime after the PATCH notification **[Step 17]** will result in a reconciliation error. This can be catered for by building in recompensation methods. E.g. initiate a refund transfer if an error occurs after step 17. +1. Call Transfer in the Transfer phase. +![Payee DFSP Integration during transfer phase](./assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg) +This pattern is usually not recommended as aborting a transfer is not normally possible. If the transfer is against an internal account e.g. for a loan repayment, then this pattern becomes favorable. diff --git a/docs/technical/technical/sdk-scheme-adapter/README.md b/docs/technical/technical/sdk-scheme-adapter/README.md new file mode 100644 index 000000000..eff17e54b --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/README.md @@ -0,0 +1,56 @@ +# SDK Scheme Adapter +A scheme adapter is a service that interfaces between a Mojaloop API compliant switch and a DFSP backend platform that does not natively implement the Mojaloop API. + +The API between the scheme adapter and the DFSP backend is synchronous HTTP while the interface between the scheme adapter and the switch is native Mojaloop API. There is one exception to this, and that is the bulk integrations that can be configured to either be synchronous or asynchronous. + +The SDK-Scheme-Adapter is supported by the Mojaloop Community, and is regarded as a reference for the best practice method for a DFSP to connect to a Mojaloop API. More commonly the SDK-Scheme-Adapter is used and deployed directly into the solution. Below is a summary of the different ways in which this can be done. + +## SDK Adoption Models +Depending on the Scheme Rules, there are four common modes in which DFSPs interact with the central Mojaloop Hub. This summary highlights the role that the SDK-Scheme-Adapter plays in each of the modes and provides a brief overview of each mode and highlights how the DFSPs benefit. + +### 1. DFSP using third party solution e.g. Payment Manager that makes use of the SDK Scheme Adapter + +There are a number of third party solutions that provide support, tooling and integrations into backend systems that makes use of the SDK-Scheme-Adapter in order to provide support for synchronous integration (using the Mojaloop best practice means) to connect to the Mojaloop API. + +Payment Manager an open sourced* tool is an example of this. Payment manager provides additional benefits to this, more information can be found [here](https://rtplex.io/). Payment Manager deployments can be either Saas or self hosted. + +![SDK-Scheme-Adapter Mode 1](./assets/SDKSchemeAdapterMode1.svg) + +- SDK Scheme Adapter is used directly in their custom integration implementation. +- As the SDK-Scheme-Adapter is maintained by the community, this tool provides an upgrade path for using new Mojaloop API versions. +- Standardised solution for rapid onboarding +- Core Connector developed jointly with System Integrators or Banking Software Vendors +- Payment Manager UX has supporting Business Operations and Security Onboarding and Maintenance automation + +:::tip Open Source Components +These are all Apache License v2.0. This was especially chosen as it would not violate many organizations' policies. Apache License v2.0 has no “copy-left” constraints, so adopters can customize elements, such as core connectors without having to share those private details back to the community. +::: + + +### 2. DFSP using their own Core Connector with SDK Scheme Adapter + +In this case the DFSP chooses to develop a custom Core Connector between their back-end and the Mojaloop SDK Scheme Adaptor. They are able to use the open source guidelines to develop the Core Connector . + +![SDK-Scheme-Adapter Mode 2](./assets/SDKSchemeAdapterMode2.svg) + +- SDK Scheme Adapter is used directly in their custom integration implementation. +- As the SDK-Scheme-Adapter is maintained by the community, this tool provides an upgrade path for using new Mojaloop API versions. +- Developed using the Open source Core Connector guidelines +- Mojaloop Community Support +- Operated by DFSPs Technical Operations + +### 3. DFSP Own built Mojaloop Connection Solution + +There is no standard Connection used and the DFSP chooses to develop their own connection to the Mojaloop Hub. + +![SDK-Scheme-Adapter Mode 3](./assets/SDKSchemeAdapterMode3.svg) + +- Developed using Open Source design documentation +- Mojaloop Community Support +- Operated by DFSP Tech Ops +- SDK Scheme Adapter is possibly used as a reference +- This implementation directly interacts with Mojaloop's asynchronous APIs + + + + diff --git a/docs/technical/technical/sdk-scheme-adapter/RequestToPay.md b/docs/technical/technical/sdk-scheme-adapter/RequestToPay.md new file mode 100644 index 000000000..88251e17d --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/RequestToPay.md @@ -0,0 +1,29 @@ +# Request To Pay (R2P) - use-case support + +This documentation describes how the SDK Scheme Adaptor supports the request to pay use case. The request to pay use case is the bases for all Payee initiated transfers. Support for this use-case requires every DFSP in a Mojaloop switch to automatically process a transfer once a request to perform a transfer is received and validated. Having support for this use-case in the SDK-scheme-adapter is important as it minimised the development effort that each DFSP needs to make if a Scheme mandates participant support for this use case. This use case is particularly interesting from a testing perspective, as it enables remote testing as both a Payer DFSP and a Payee DFSP. + +> Important: +> +> 1. Not all features have been fully tested and aligned to the FSPIOP Specification, please refer to the following epic for progress on this: [#3344 - Enhance SDK Scheme Adaptor to support the request to Pay use case](https://github.com/mojaloop/project/issues/3344); +> 2. There are currently no end-to-end tests verifying the full functionality which includes Authentication via OTP. See the following [Testing Toolkit Test Case collection release](https://github.com/mojaloop/testing-toolkit-test-cases/releases) for what is currently tested: [testing-toolkit-test-cases@v15.0.1](https://github.com/mojaloop/testing-toolkit-test-cases/releases/tag/v15.0.1); and +> 3. Not all failure cases may have been fully implemented. Once again refer to the epic [#3344](https://github.com/mojaloop/project/issues/3344). +> + +## Sequence Diagram + +1. The Payee DFSP initiates the R2P use case with **POST** /RequestToPay API call. +2. The Payee DFSP optionally can validate the Payer. +3. The Payer DFSP executes the R2P request with a **POST** /requestToPayTransfer API call. If the Authentication type is not provided in this call, then the flow assumes that the Payer will confirm the transfer and terms through a **PUT** /requestToPayTransfer, otherwise the appropriate authentication flow is executed. + +The following diagram summarises this flow. + + +![R2P Sequence Diagram](./assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg) + +## Detailed sequence diagram + +Below is a more detailed sequence diagram for the request to pay use case and the SDK Scheme Adapter API calls. + +![R2P Detailed Sequence Diagram](./assets/sequence/SDKrequestToPay.svg) + + diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg new file mode 100644 index 000000000..579441a56 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements-Architecture.drawio.svg @@ -0,0 +1,3 @@ + + +
    SDK-Scheme-Adapter with Bulk Enabled
    SDK-Scheme-Adapter with Bulk Enabled
    Payer DFSP

    Core banking system / Beneficiary Management System
    Payer DFSP...
    Mojaloop FSPIOP
    Mojaloop FSPIOP
    Backend API
    Backend API
    Domain Event Handler
    Domain Ev...
    Command Event Handler
    Command Event...
    FSPIOP API
    FSPIOP API
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    Producer
    Producer
    Consumer
    Consumer
    State
    Store
    State...
    State
    Store
    State...
    Infrastructure
    Infrastructure
    State
    Store
    State...
    Producer
    Producer
    Consumer
    Consumer
    Dependency Injection
    Dependency Injection
    Kafka
    Kafka
    Domain Events 
    Domain...
    Command Events 
    Command...
    Redis
    Redis
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio new file mode 100644 index 000000000..b308a656b --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio @@ -0,0 +1 @@ +7Vxtc6M2EP41nmk/xAMSrx+TOLnMtJmmzc302m8yCKMLRj4hkri/vhIIDAi/JdhxcsnNZZAQAvbZZ3e1KzKCl/PnLwwt4lsa4mQEjBkj4QhORgCY4r/oWKAZbnXIEffkv6rTUL05CXHWGsgpTThZtDsDmqY44K0+xBh9ag+LaKI/xn2AEqz1/k1CHpe9HnBX/TeYzOLqRqbjl2fmqBqsHjyLUUifGl3wagQvGaW8PJo/X+JESqaSS3nd9Zqz9YMxnPJdLsj/DazfEP6GF06ef7m8QR78ceaUszyiJFcvfIeWmImuyfX9nXpwvqykwWiehlhOaIzgxVNMOL5foECefRLgir6YzxPRMsVhiLK4GCsbEU25AtP0ZJskySVNKCsmhlEUgSAQ/Y+YcSLEf56QWSrOcbqorlaPIWfLOKMPuHF96Ewd2xFn1PuIWfDzWkGZtfiFUmI6x5wtxZD2Bcuy5Sj4nlboW6bCOG4gD301ECkFm9UTr0ARBwqXPTCqNL8B0i39jhIqRAOMm3z6OpikbK/RnCTyhW9w8oglAG3IgKlDFiLsRUEfGE7g4WnUA1s/uANAZpvuNtBgJcbjgAY1zLLw4SwLYjzHZyhECy5Z9hrcGOWIE5qq0bsRp0s7W/5T4xr95U8vtsVPh9DWMCgCt00909BhNK0+7tkH456t4fjl6utImtpr8WKcCFfURRGHwoOoZkpTXGDVBJYyHtMZTVHyu+Rwicx3zPlSCRTlnLbBFhJky2/q+qLxj2yM7ao5eW6enCxVq8Sv8lzOjnQ3y4nCc+kvRXua0OCh7LomSdKvS6GNvdDq0xkPTGGhMwma4uQCBQ+zQiDVECWkTKg6SWfqyUuxSlm+UJuMsQEMr61QVtlkOBHUeWzP3Kc7avI7SsQ965mhZ7Sndez2FBnNWYDVVU2X3JnIhm5nIjjuTMURm2G+YapqII2iDHNN4Wu5vJwDrkaBLYbrBfrdVD7Y1PczASO0O0pv+FvUfn/V1ImyVf/xM+EFJceGD1VbPqA5NjzVXD2ebCwbjTvMiAAGs+bzdzs382VXhgikCn3c5K0UpKW2bRhYxr1rOSfQMqvgSOk0NAbhnOm1fUO9HtiXcxBaY9fezN8TIJ3pHMevKB02G/qrvMpa9X2ZTwHmC3xKFGEn6I0xQ9efGvv4iR1Y4Pfr9is11+tENTUjtmjbUJrk95hvJxGiuRALB2cmDyYkC6gI3ZbVGXGj+mQ9mlU9f+GMCozlKxS3X1AuZE1QUggrIAsimpmM22ISxHItXIRqwJgW1xQESqVkaSRtTozVclNeIuLZqivD7JEIwLo8EAEmb2vxerO+zhEgFSUH4kmludXC5zkJQ3nD3ii8Tbum77IHWs90AwNQBwaNWBi4PUsa71ChcI/bf98WSawZ97dI2BQ65PbpnO+4EDnDWiRzjZoMbZK6SnNgk2Sa223S+YxhsVaWD7CLTbpChaUps1YGkaZkwegjkbpYGRS6WAiFzFPCpQyF4okxmEWUzcXR+e3v4rdYnwcPWWGg5HUolL8DmhXmjMq8WChtZV7at2IKXN6ZM5RmUc+ifgdzVavOOmV7Z+YKWPrC/cjGCn4aq53WPUMaK3AYY9WJ/OGR4ycTbDdWX2vyv9BWMfwjxxkvjRUtjVeAi+YT4XFtwiorMxbHIgzLk8IOCbAKM5UIQRfXlNZL3uCX7FdxlFJOIoLD8WcwJbOF9psHU6anKdXdH/cqsTjNk4c/cxFUHym3WOcxfKdlxxzobLRk7yApuUO4tjnJ0perGdBmAqUHWxMv6yLBVeLFcKsIvU6fj4bIvFhGO9upkWJr5uUI2RJ9kdumU2Wgj8soc2yAdmTggffOqFen+Q/MqCo62M6oNeFKXT4wLcNqE8oehFDQ1TKQNcdOiVN63l/uDaiSNRqRshgtCjoEXMK9rXzZjRGmlHM6H9VloAvVnpxZ3qr3a8FAy+oJjtulzteHDX5nIwCw9UWN1RMzHKwWWW0k2VSI+XAgdCp4fSvL44LQl7r44CB4/poM9puBoFflj+PXm1VJ0HHR1oGcNDyMkz5owXGr84XGRo2Tzhe2mV+vw1+bTmhHs3Bvz7u+jqh58ROoIwJLo8olTSPC5uXmIVWEkXtZpPxJKtOh6tQxGXXihHr9OrKPbgMSCjgbCSUMFtB2wwwTznYIBdx9N8McIZTVOCDwwBEJCCqEdItSNFPFBuM+n2bLjOP58fy6CzS/7nWU1tL0HRzA08OOo3/zaEvfnzxFvFVv6VnRJwlZZJJ0FWD5XHBZEJAm21HbeeHctBDVDjYNoEEw6RDM0pOXdh8o9qFA0ReGUVEa21YJ+2jAAF/bSQSdN8ZGzyu3sFHs+eDAOCfGGKiv3H9CVGAn8nbgG6OyfheC8MVpCwznR05VMW91VBTzOtH0muKdXh8sb1GVCDvQb6vKKZx6oBuyFtcfb+wUXzc+TgDGMPrjdqp4ph6b1N9atT4OONgnHmAI/bnIkwcxdEKyac6yKggtisKckdkMM6lIP5/anA1W/u18VOK9ud7skL068Q31O+zL/cAb6t9g+7vrjw3Tsmzg+Z7nGG4nKw6tse+ZruM4ru0b/gs/R4GgkyBw4NjvTnYCOS2orwo/P8oa9eatdiDq50dZ7/GjLNj3VdbJbuvfM05pquc6hX5nm84Ou4NfNFd/SKBUsdXfWoBX/wM=7V3blpu4Ev0aP7YXQkjAY1/SmT6ZrOlMP0xy3jDINmkMPhj35Xz9SIDMRcLQNhho21lJTCEEVG1tVRVWMYG3q7evobVefg8c4k1UZRG6zgTeTVQV0L9UsLYWpCBgLZ7c/3Ohkkq3rkM2hYZREHiRuy4K7cD3iR0VZFYYBq/FZvPAEy/jybY8Ikj/cZ1omUgNVc/kfxB3seQnAthM9qws3ji98M3ScoLXnAh+mcDbMAii5Nvq7ZZ4TDNcL8lx9xV7dxcWEj9qcoD+nx//De6dHw/fyOzX5ufXV/frjytDS7p5sbxtesdPd9+unuwlWZGra8daRySk+19dejeqcrP1nul/X3xr5hEnva/onSsrDLa+Q9j5lAm8eV26EXlaWzbb+0ptT2XLaOXRLUC/OtZmGbdlG5soDJ53Gqa6uZkHfpRaHyC6/ULCyKV2ufbchU+FUbDmrdILSDXCGpK3SiWBneopIEmwIlH4TpvwA4zUWu/Jtpluvma21/RUtszZHXGhlcJrses6Mwn9klrlIxbSBTUTh0I03QzCaBksAt/yvmTSm6IhsjZ/BkxrscZ/kyh6TxVsbaOgaBzy5kY/c99/sa6mKN26e0t7jjfe+YZP75cddKVMFQC4JDlUQyoXZEfHW4XDH0noUr1RzCXCIi6gBBebyAqjazawqWTmBfYzF9673u52fIc38QOfJJJ0PztNomKm1/24oWYItqFN9tiLc5IVLki0px2U4zAknhW5L8XraB1UfKhko36iYi9io9J9oV8XUayURMQ0zu6cUzH+35Zx1g3IvpYPmRUAy1uxjq6Sbq5pA4DXb8kxpV4erfeYdO7unx4njNXSTsPyaei9zySy5IIFseTWhnC3p7m92yAk9Cpmlv/s+gt2we+biKxi9d4zZic+mbu2a8Uo/G75dGJbkVgVT2lL+ZmOmQLmdATeBl4QxsfCOWJ/UtXl5Mlnxwa5PTj+7K7jKOrXiswPsEj9QJFQP+iM+tVBj9LvwW/LY/OJqtBx+vDXYwuwbRFMjkWMuS0FjW2Q2bwd0GBjcKgxjD4dBu4VJLO+3tBjAFMFFv0FA6NP4C8cMb+nhz4GbjyuU7ypilnAm6ozr6zQSeKhpMfl44FSV0CDQleKZmafUr+JRyP0S/VkveearVmDTfUd7EZIdtr9l7m/Pf2SXEE2YHbaPnwMQYF5byz7mWKACq8fH44kqhwisWQWnBNsS4nL0c2ZorRDXGUgASQSlynhrV0c3jpviZHoXbCyXJ/Fmy+JJ/KH5Tsecw07Vf9crVA/nmHUkrMB1Xr1y+LM7tSPBPXfBquVFUP+pPo3bCLX/8xAGmoJ/ho9dZ3+ATipAbBgAO5WdU45BDiI6DKdm1iHVkuYR7AB5sFJKUfkHEHPC6ro9SSfUmS5r0k+s3ccEavGVNVz065eUBKkuzUV6UBTDfYvFFSmaVPVyB2PNYkK4ZR3EP+L9a40qpxCo3uMKer5g6oCp1IVNOpVtVlaa/bVfvdcOtpDWD/UZwkv/DnbCajnsojZ4q9tRLshqTyNFDV6u9kNYwVJ6CIMIuq0BiztairdhVp7EFWdsC0OlyuApkjPhotqGiKvK1M+++YNz8BhdmVrU7D1Yxg4W1symVINRUWTFtWaBiR5G6QiK02N21SjLCIScuYr13HicE+GoeKEkoNAY/o/xH7a1DQhUk0NAB1rOlAFc0FmrnS3ggyDD5N9g1ZTu+I3Wea0X37js6nkScWQ6I6b5EJ3+61c83xqFHSnifHzbeBvtqszoLuauGNkdCcGJR3QXU2oDKmDbBRgPzanWO9v0sBy3Q52lrg4xY3Mqn+GWeKMneL99hvZLIF6DPor+G0kTjFqEE5c6C4F2MjpDokB0Lk4xTX2GxvdidFNB3RXE0fENFaA/cicYnSS3PseA47HKUbis7nLLFGFqLHPEmLEfS5OcY39xjZL9Bf0V/HbWJziSw6gkZU/Qw4AiTmAs3GKP1UOAJ8kB1DzAxNt7Jli3N/jRVwRow11lsBiOH2ZJaoQNfJZAosR97k4xTX2G9ss0V/QX8VvI3GK8SUH0MjKnyEHgMUcwLk4xTX2GxvdyXIAuRV89avvqhbfPdEhRhos/jzmDPGK0Ubr9E5APHhaMJgKDkRdzXSKwRQWVwaoJpjyXE6eFsxdqJGHFuxsdYAsKXKB0nChBJE2UCjpjYPM9ldod7OEorSWTZMsLNFki3l21T7aH65iXuvBn4cW1c/WjrZsOJQ0fuh6HrXsYqXTe5PyKrvCKVXlVQ6fyPUKk/VnEtEiktX0TclwkMQGZN54+ybko44vD01HnWTluyEzsNKVgbk32ENwWaMqqNdpCsgWe0LUlaYaJGv7wmuf0WOCoEozYp2vtefxYybJhyBIgvrOyj0AcTYfT27sSIaqsRcsEpTMVkCBorFU2JWtTvLLoRYYCkjSYcCQqEpTy+Un2lNWg1zhWZJUxdP9QZOUrLrAWDJax5LUfnsNjqR00Tm4I2tCdePb7Lof/N+UlBj4h2m5D9aVbJ9S95WCwhI3T+1q1BniqPtmzZ+tz2G4j5f+PGRiNNXC8ISiTWUm7S53I4tx8kk6bpAsC+eReSTm5Iq1dTZUbK2YSfzZJgn895dd3BfpisWzcsCqZlkkSTfVl0Iq4iQb0IfU5kpNfqVMDZ4jy9kZSezMZUdW9ULFOQCaJfg0LemlKzUdVdTwyjriDYP5fEMKbdoqraXL3LpDEFwqTzRQCDcorfMpIFyq0qaVJ7VDIawBc2rmP8MDdK8FmrOizL8muQqL8nKLdOPjBRNzY4GXS8yKIcqquDatX9dKueWkio44EI6EMyw9UmjKpK2Bqt8ingVQgW5BJS2w2ahKZ6/A0ypyT0cCD5g9A88cDvC6YLMCsFLo5XGlHMB4jcvntQO8bhhPKz9ELc/gHQOPPysaAvC6YLxW6g73yniom5LGEPTLeAYYDvDGwngnBh7qBHiIPzDuC3ji84wL8AYFPNyNj4f7Zjw4HOCNZao9rY+HOvLx1CLjndzHE3/Y/jdx3I0AxzN5IFGznBEUU2EIiBm9kz58MHqNDS+vIuv21SKYw4v/Wlk78MUiWDep0kt9aVMT5NdSNeKdj75bBJffFZLeQuWV7m8/6eTdIma/gW5hFF3ez9P2ICq9D+qI9/Ng/gOo076fB0NQPu3+y9zf/qNjiG5mr0RNmmdvjYVf/gU=5Vrdc+I2EP9reAxjSf58TAJcM3eZ0iG93j11HFsB94zl2uKA/vVd25KxJZMQaiBDH2Cs1Vof+/Hb1coDcr/cfMr8dPHIQhoPsDHPonBARgOMEfyAkPpz2iIUHLPoH0k0BHUVhTRvMXLGYh6lbWLAkoQGvEXzs4yt22wvLNaXMQv8mGrUP6KQLyqqi50d/RcazRdyImR7Vc/Sl8xi4fnCD9m6QSLjAbnPGOPV03JzT+NCMlIu1XuTPb31wjKa8ENecKbf53/dPnz98uckHbvh42NKnm7EKD/9eCU2PPW3NAPSbPRZrJtvpTAytkpCWoxnDMjdehFxOkv9oOhdg26BtuDLGFoIHl+iOL5nMcvKd8lkMrY8D+hiRppxutm7FVQLCMyGsiXl2RZYxAvYsapXtoJbyni9U1FNWzTVI4m+sIJ5PfZOcvAghPcOQeJOQdKTCPJ+7E36EaRlGB9NkEQTZK/SG9sjYzTuR3qEtM2QIF162D6r9My3pUeT8LbAQWglLKFtaVXcNJyr8PemTBp7tjq2LGkZjX0e/WwP3yUGMcOURTBxLXLTaRusSRRJ5myVBVS81UTDNwaqdScH4n42p1wbqNRKve3jFWXtB96HR01nYKO8raicZ+wHlYYtFNm0dUHy42ieQDMA/cHw5K6w+Aji263oWEZhWEzT6UdtT+vDZRTkJrbuMmaH+ZzMYez9uH3NejC9D6YHpwO47LgQ9jM8zHm57YrwwkpH3qnF/nvFZMdNXmaMt8CA3HSz65SjPD19lgPBQqux2uMDuTHn1VoAaluAaeoW4J7TAtx3ha4g9vM8CtqqoJuIf4PnG2NowPYqwvdCZkPXxKI92gghlo1tozGlWQR7KZRT0kI/X5Qif09khAWXIeitFOdSERQbSu7sGEMTIceGiGi5Lib4uICq5eSOsrQ9ARUU6m8bbGnBkO9fP7IUu0Xo1XWp/HJdO1OtVtBrdPc0W0ZDaE9/nT0NCgeaPK/iH0+b5HrhBeG22HEHvJw1wMj8rg98QUPDcFvwgiz3w8DLhRN0Re+qQg/FE+1oStyh5xHLMkzbsTwkw9eZ8nWkV0pw4dKfxsKjQVM8ovn1erSpBo6O065zVo/Way7v9uhD3e5S7mRjLVof6U5qwq8enHsKz7aWBhivrkvll+s6aXhGepGJ/L+c2Tb3wPSlsn/0vspVd3hOYCXfmo0qOBNLtnfBuWxtm62ewnPlRx82PCswgOwj031LBSb7MDzpzYX1AppZpti/qy48eRhdrx+rp3hkXTrN1gtqVksv9cnnqvWiXg3gDr10JUvEPZVeugpsRx5/5IGmQlcsCy17Tj4SlI02KDtvgfJJqy8fHafVKg1WryeOxmk1gewp78MKEBHz9bxP5ZcbPG3ep9cY7VfAyfCDlE/5tq5EZ7Is7AfQ89uKcXq9EIbV282Lp4h6Vc1fcXYbBBTUBOF+W9X9X/w4px06q3krxTV5r1WHRC2Wdlzvd6GYmsz195lEj1U4GUNEJEIHhqEhQl4zFBWXBficJ4TDCngHRKiL3iNohT6vpwhVG+mZThJYr+wdddNYXiAql413EE8KTdKcR8kcnm7g94UBHhTDUr5KBxhWbSQM/mbriAcLeHimfE1pUlrPlmYveVpIIwkFgZaEfVeY/rJAkuQ5Tw+7vswo7MN/LhkMAZPVzsruwwFNZAgwjXU3sEbd+NiJo23YK/YjPvtDrmyLHUhV/aebCfXIpGOi3fXJk2qWB2AiNHff91X2uvsEkoz/BQ==7Vpbd5s4EP41fkwOIMD4MXbSJtm0zTZ7afuyRwbZVg3IFXJs59evZCRAIN8S3/ZsHhKjYRAw8803oxEt0EvmHymcjD6RCMUtxxpSHLXAdctxbP7HBRM4RJpAaDzhFyW0pHSKI5RpioyQmOGJLgxJmqKQaTJIKZnpagMSNx/jKYQxakj/xhEb5dLAaZfyW4SHI3Uj2+/kZxKolOWDZyMYkVlFBG5aoEcJYflRMu+hWFhG2SW/7sOKs8WDUZSybS6YfOz+ShP848vt4CrLfo5/BJ27CznLM4yn8oXv0gGFGaPTkE0pko/OFsoelEzTCIkprRbozkaYoacJDMXZGXcvl41YEvORzQ8HJGXSg45QH+A47pGYUC5IScrl3Qhmo+V0Qp/flowLOztqBnl3ofGMKMPcO1cxHqZcxoi4pXwJfg7NV1rHLmzOkYhIghhdcBV5gWNJvy3ysetJt81Kr7sKg6OqxwMphBJYw2Lu0hn8QPrD7Jtf7t38MXpIX7qzC/j4D5xR9tdFAZzS+iji4JRDQtmIDEkK45tS2tX9U+o8EGGppQ1/IsYW0i1wyojuMzTH7Fvl+LucShxfz6sDYSngXHpy/Igo5i+OqNJJuRGKmcTge3VQzrUcLaqj+lQ6LoCOLNtbakDKrkR4l9Bayj5gYXQ5daQ0+jEJx7lIKtg1eLYcMAhCFIbF7Stn+oEn8KGAJ7yyHnbciWRKQ6l1/Xv46etn8OJ+/vP+no5Y79tkrCKRP/MQsTWoAGYYUxRDhp/15zBBcnkptwNcVBQmBKcsq8z8KARldPgqGmR0eC7QuWaDvoqcMhzyJyiDo3iVN8RLk8w40XFS4DKS8n9PDDK0/CWC2azeCKZDlBmj7AH2eZrSIgNKzgm5bwU0G2SU4CjKgxBl+AX2l/MJmEjz8sm9bsu7NuA3FrfrwnA8XAZwjSS1jCbnLRPLBt5bwy0r2dC6BG3fz+faDVkNKNgaEC7sGluSwSDjeK9z5W5wWBdQFTS0HD9mIufgZ344FIcSErmc36Zyyqi9BI5ZuwYinu4n4jBcxJgzMgWb02U/5+6HfiEoAPFlyvg0KgtmFeRUkeTvJxe6HT0XenYzFwamVGjtIRUafekYfFmzt7DT5E2BsqFAcF3dKJ5IfXWz2G2DXYB3ILOAzWY5FQwp4ZGFiaDFTr304xk0gigYGHOrHwaoP9gWyKvRstKRflv5TXFSKal4UjlNA3j7UAB3G558pCSahjzP1D3KzcF0h+k2lDnDUGtvn8BMCNEry1fRziu8BfRCwuQp2wJNVzngQJ7yzoGK/I38bAcGo7gFZe3dLP47Fa1Ey3+LitoNT/ZImk2T/wEVrffW2VFRp+GpryjCzfXMebhpm05PPYqLzs/bSbMgyYI07Yb7fFPxdqj2TnN98hscjOG798yxp68j3aCZ8o7rvaDhvrsUM8yXkzwArT9QxhqePEL37jSdsshDQeSaUmjg9IHvb9ng2LWPtkt/TOLowrr0PF9fyRU9iTd2Ohy3xjD1znDe25NXlfjbtRln+/p9QLvW+N+gr57L2Iwrr95rh8YcQ80EpjfsJCFaCcqyVY26Q7fDVRfbyhvdx+xjq9irhqeth6eMnzI6DQXuFn1s1fRXx8UbGpv+alB/vePGuN4rX70oWccFTsdf0Z88bD+dJys9ndnrQ7iu7znBeYRwswN1v8x8MgFaTyHFk2YmVEvBaRJfhYxUa5Nl4/2RZFgu2fqEMZIYipd8668SqiRfEfaKjd9myBlLlWbhtI+CJdCTDDDsJwJDweIfrGBxz4k+rSPQ576Km237A3uhNm9LajvJNqBbryTaayqJvVUJ3kmAqzLiZVttcK/fCX8HqGH77dgA9YC+c+WvK3X3BdBmR7hHkgSmERfe8p9YdM4sgUfxy0wrw52+qjlVSnNrm/q+YQ1uO4acto9WpZkawGmpYXtmMJXLZ7tWfx1brNsW2PhVy4rO64HTWVBLZ+uq6s1swYfl13y5evnBI7j5Fw==vVfbctowEP0aHtvxNcBjuCSZaUjpOJ2kecko9mIrCMsjCzD9+kpY8gWbQFInD8xoj1aLdHb3SO7Z41V2zVASzWgApGcZIcNBz570LMsUPwEkKIQaID08/FeDhkLXOIC05sgpJRwnddCncQw+r2GIMbqtuy0oaW7D8xGBBvqAAx7l6MDql/gN4DDSf2ReDPOZFdLOauNphAK6rUD2tGePGaU8H62yMRDJjObFvU+my2fr1+3iCe6oO/x992x/y4NdvWdJcQQGMe82tJWH3iCyVnxNrry5Oi/faRIZXccByEBmzx5tI8zBS5AvZ7eiJgQW8RVR0xtgHIsEXBIcxgLjVDosaMw9FfHcAyk/GRCySjrVAa+BroCznXBRs32Vqp0uOWVvy8w7jsKiatZ1jpEqrrAIXTIqBorUdoKHwfJ+Zv4c3D5la8/DlMUkVTmpEtyzLoj421GAN2IYyuEc7VaSCbmLfPKF6TmNiH+vrGgJMkOxqGV2zP9oRo3TGT2ShnMzeDRdtuHU82U382WaLfkadJCu1v3aDaIgEHKiTMp4REMaIzIt0VGdytLnlsrC3xP4CpzvlBSiNad1eiHD/LEy/iNDfXeVNclU5L2x00YsjvtYNSqrpFku21t6XcoR45dSRgXgE5Sm2NfwFSZ6SylndFkIplXUwLktm9I18+ENP5V4ye6bjc2AII43dTFvS7taOqd430iqwiz3QBH6B5Ujzh0CV6sOiqfYxsfryTmir8YI+UuIg0a5iUsmkcMIMiSqSBCfAMNiG6KzC3SuIet07y5wBvoWNt+dx/Old3hAtOOe18ruZ7Vyv0H9jL4iIpvSMm7WL81OJ0S8QeAMSr/iKnMP77I2bbS+UhsHLVfZkepdEMiUyAj9CY7oTROukFxX1eLttTeWwP2oELRDpfqoNH5EhjtWRfX0zEXpdG2fVM9qrRht7x4N/qfMuk69WAs10CHykzdkthHIOdBr2/havR42atyb/BCA50ewAjG4DFAitbiD91T3mmGfIcID93M0uPX1azboHFMmaRznH3e0EyK7f5g2ng0tRPa7ucyEWX5C5mVcfmXb038=3VjbcpswEP0aP7aDuTjOY2znMpOk4w6Tado3FdagRCAihI379ZWMuFngYI+TmfYhE/awWqOze46FR9Y8ym8ZSsJH6gMZmUbAsD+yFiPTHIs/ASQogBYgM1z8pwQNhWbYh7SVyCklHCdt0KNxDB5vYYgxummnrSjRH8P1EAEN/YF9Hhbo1Lyo8TvAQVh+0HhyWdyJUJmsHjwNkU83Dci6HllzRikvrqJ8DkQyU/IydfntNyOdrd/Qr8VYMLF0yZei2M0xS6otMIj5eUubRek1Ipnia3HjLtV++bYkkdEs9kEWGo+s2SbEHNwEefLuRsyEwEIeEXV7DYxj0YArgoNYYJzKhBWNuasqDt2QypMFIW+0U23wFmgEnG1Firp7oVq1LZup4k3dedtWWNjqugKRGq6gKl0zKi4UqUcQbGlcgi/mU4WU8ZAGNEbkukZnNduGiOqcByqZ3HH8ApxvlbZQxmm7A5Bj/ty4/ilLfXVUtMhV5V2wLYNYbPe5GTRWybBetovKdSlHjF9JXQrAIyhNsVfCN5iUj5RyRl8rBYoWzo6bgZRmzIMDebayEsQCOFTPKfJkFw5OFAOCOF63XeTs42H36M+YIe8VYl+bHmFCibwMIUdiKASPCTAsHgZYjS5LyHxfrSucQ+nS46PbMlyal3vStB1NmpUKm9J0zqDMh7URfyfrJ/fpjdzb7sSZvcTVYJ2uzPQVuBf+IzItv7yMTjEOVLGYSD1JgI2UTnmdUeeOrvPO9hrd0/g5snY0Wc+zlNNIYHPKYPdvd7qh7P9ReCXVQxI3PkjinVuYaG14pC+ISH2axl32W3cAQsQxFAZw+hmnGWf/OGPpx5mx2UHo9KMIvdAI7R3fFYFceUW3bfRYToPkPbdtOVjTenU7O9UlT3Hk0/2t37cGnGMmA88x74mvAgc7o/qMJcViw/Ww2u1hrb7wyxLFztWq5nvKXiF7z0YsY69QQY1WaDfQ1cZPPxcY2oy7i3sBuF4IkbTuKx8l0oz7X5KM9w2kxwuGDlKvZ1gDzllT5yweLML65bdgv/59wLr+Cw==1VZLc9owEP41HNsxFo/0GF5hJk2GKYekR8VebAVhMfIaTH9911jyEyhtSWd68Iz202q9+valDhtv0gfNt+GT8kF2XCfQwu+wScd1u/QRsOUB1IBMYyl+WNAxaCJ8iGuKqJREsa2Dnooi8LCGca3Vvq62UrLtxtLjElroi/AxzNE7d1jicxBBaH/UHXzJdzbcKhvH45D7al+B2LTDxlopzFebdAwyY8bykp+bndktHNMQ4TUHvu2fHx5XjzDnXff5hYvJ8N75ZKzsuEzMhSez5cI4jAfLglZJ5ENmqNtho30oEJZb7mW7ewoqYSFupNnegUZBDN5LEUSEocoUVirCpbFo/0qKkJ69TrcgiVIH1AZQH0jFHrC8HizzRt6XYWIDg4W1EBmQm0wICtsle7QwBP4Gmf0Wb+BTMhlRaQxVoCIupyU6Kpl1SCp1vqqMtSOf74B4MIXAE1R1tiEV+FpZf89Mfe4baZIay0fhYIWIrvtaFSqnMrE8dpTsuRi5xvusiAjwJI9j4Vl4JqR1KUat1kW5UAxHOTEZG5ejTeSpRHtwgWTX1DzXAeAFPXY6ezRIjmJX9+PmmeCeKStnxL01RH4rUag5bLNlCCmn+BNlW9CCnAFdogsLub8uwpVIwXbPbhGBv6u4fqPiev1WxRXFVa24/kcVHGvRPE5iVBvCntQ7l1kNuc44nwSCaHWdpZJJvvwPI8CaPe9UBNi/jECvFYEK8fPkrd0RpaRJDVfQd+N50R80uGPteVHMlCp3dx/F3bDF3dmkXElITd+lluyfacFtuMJnfdAUj5GjsAb0wqLHN5v3n06LGzZ9dmXT751OgWqInVNPAgtePR3MPxZK0FXK+mx0yJ7TyJ38ouZU9a3WMNRrGGJNQzkTLUPHPCwufio1SSyfnLl6+Spn058= \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg new file mode 100644 index 000000000..728a19418 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/BulkSDKEnhancements.drawio.svg @@ -0,0 +1,3 @@ + + +
    Payer DFSP
    Payer DFSP
    Mojaloop Hub
    Mojaloop Hub
    sdk-scheme-adapter
    sdk-scheme-adapter
    GET /parties
    GET /parties
    Discovery
    Resolve all potential recipients which might be at any of the DFSPs on the service
    Discovery...
    Agreement
    Each DFSP is provided the opportunity to perform AML checks and add costs or discounts to each transfer
    Agreement...
    Transfer
    Each DFSP is requested to proceed with the transfer. Results are collated and DFSP(s) notified.
    Transfer...
    POST /bulkQuotes
    POST /bulkQuotes
    POST /bulkTransfers
    POST /bulkTransfers
    Payee DFSP
    Payee...
    Confirmation of party information
    Confirmation of party information
    Beneficiary Management Subsystem
    Benefi...
    batch transfers
    batch tran...
    for each transfer
    for each t...
    for each batch
    for each b...
    for each batch
    for each b...
    Confirmation to proceed with transfer
    Confirmation to proceed with trans...
    Bulk Disbursement is triggered
    Bulk Disbursement is triggered
    GET /parties
    GET /parties
    Discovery
    Resolve all potential recipients which might be at any of the DFSPs
    Discovery...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg b/docs/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg new file mode 100644 index 000000000..d139c9f6c --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/CHIntegrationTestHarness.drawio.svg @@ -0,0 +1,3 @@ + + +
    Infrastructure
    Infrastructure
    Assert on State Store Changes
    Assert on State Store Changes
    State
    Store
    State...
    Producer
    Producer
    Consumer
    Consumer
    Redis
    Redis
    Kafka
    Kafka
    Initiates Test
    Initiates Test
    Assert on Kafka messges
    Assert on Kafka messges
    Jest Test Script
    Jest...
    Command Handler under test
    Command Handler...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg new file mode 100644 index 000000000..483b2dc7c --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode1.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    Payment
    Manager
    Payment...
    DFSP Backend
    DFSP Backend
    Mojaloop Hub
    Mojaloop Hub
    SDK Scheme Adapter
    SDK Scheme Ada...
    Core Connector
    Core Connec...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg new file mode 100644 index 000000000..b3143177b --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode2.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    DFSP Backend
    DFSP Backend
    Custom Core Connector
    Custom Core Conn...
    Mojaloop Hub
    Mojaloop Hub
    SDK Scheme Adapter
    SDK Scheme Ada...
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg new file mode 100644 index 000000000..814b57fa0 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/SDKSchemeAdapterMode3.svg @@ -0,0 +1,3 @@ + + +
    DFSP
    DFSP
    DFSP Backend
    DFSP Backend
    Custom Mojaloop Connection Solution
    Custom Mojaloop Conne...
    Mojaloop Hub
    Mojaloop Hub
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg b/docs/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg new file mode 100644 index 000000000..ab1c426df --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/bulk-functional-local-test-setup.drawio.svg @@ -0,0 +1,3 @@ + + +
    Payer SDK
    Payer SDK
    Payee SDK
    Payee SDK
    Payer SIM
    Payer...
    Payee SIM
    Payee...
    TTK
    TTK
    1. POST /bulkTxn
    1. POS...
    2. GET /parties
    2. GET /par...
    3. GET /parties
    3. GET /parti...
    4. PUT /parties/ID
    4. PUT...
    5. PUT /bulkTxn/ID
    5. PUT /bul...
    6. PUT /bulkTxn/ID acptPty
    accptQuote
    6. PUT /bulkT...
    autoAcceptParty: false
    autoAcceptQuote: false
    autoAcceptParty: false...
    Bulk testing - Local setup, no Switch between payerfsp and payeefsp 
    Bulk testing - Local setup, no Switch between payerfsp and payeefsp 
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png b/docs/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png new file mode 100644 index 000000000..855dcba55 Binary files /dev/null and b/docs/technical/technical/sdk-scheme-adapter/assets/overview-drawio.png differ diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md new file mode 100644 index 000000000..f03f6e0be --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/BULK-ERRORCODES.md @@ -0,0 +1,141 @@ +# Bulk Transfers + +## Error Cases +### Discovery Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Party Lookup Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Processing Error | +| Internal server error | 2001 | 503 | Processing Error | +| Timeout Resolving Party | 2004 | 503 | Processing Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Party not found | 3204 | 202 | Processing Error | + +### Agreement Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 202, + "mojaloopError": { + "errorInformation": { + "errorCode": "3204", + "errorDescription": "Party not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Quotes Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Technical Error | +| Internal server error | 2001 | 503 | Technical Error | +| Not implemented | 2002 | 501 | Processing Error | +| Service currently unavailable | 2003 | 503 | Processing Error | +| Server timed out | 2004 | 503 | Processing Error | +| Server busy | 2005 | 503 | Processing Error | +| Generic client error | 3000 | 400 | Request Validation Error | +| Unacceptable version requested | 3001 | 406 | Not acceptable Error | +| Unknown URI | 3002 | 404 | Not Found Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Malformed syntax | 3101 | 400 | Request Validation Error | +| Missing mandatory element | 3102 | 400 | Request Validation Error | +| Too many elements | 3103 | 400 | Request Validation Error | +| Too large payload | 3104 | 400 | Request Validation Error | +| Invalid signature | 3105 | 403 | Forbidden Error | +| Destination FSP Error | 3201 | 404 | Not Found Error | +| Payer FSP ID not found | 3202 | 404 | Not Found Error | +| Payee FSP ID not found | 3203 | 404 | Not Found Error | +| Quote ID not found | 3205 | 404 | Not Found Error | +| Bulk quote ID not found | 3209 | 404 | Not Found Error | +| Generic expired error | 3300 | 503 | Processing Error | +| Quote expired | 3302 | 503 | Processing Error | +| Generic Payer error | 4000 | 400 | Request Validation Error | +| Generic Payer rejection | 4100 | 403 | Forbidden Error | +| Payer limit error | 4200 | 400 | Request Validation Error | +| Payer permission error | 4300 | 403 | Forbidden Error | +| Generic Payer blocked error | 4400 | 403 | Forbidden Error | +| Generic Payee error | 5000 | 503 | Processing Error | +| Payee FSP insufficient liquidity | 5001 | 503 | Processing Error | +| Generic Payee rejection | 5100 | 403 | Forbidden Error | +| Payee rejected quote | 5101 | 503 | Processing Error | +| Payee FSP unsupported transaction type | 5102 | 503 | Processing Error | +| Payee rejected quote | 5103 | 503 | Processing Error | +| Payee unsupported currency | 5106 | 503 | Processing Error | +| Payee limit error | 5200 | 503 | Processing Error | +| Payee permission error | 5300 | 403 | Forbidden Error | +| Generic Payee blocked error | 5400 | 403 | Forbidden Error | + + + +### Transfer Phase +All the errors encountered during this phase will be accumulated in the mojaloop-connector and will be added to the `lastError` object and returned to the Payer FSP along with all other successful or failed transfers involved in the bulk transfer request. + +mojaloop-connector will act as a pass-through for all the errors returned by the switch + +``` + "lastError": { + "httpStatusCode": 404, + "mojaloopError": { + "errorInformation": { + "errorCode": "3210", + "errorDescription": "Bulk transfer ID not found", + "extensionList": {"extension": [{"key": "string","value": "string"}]} + } + } + } +``` + +**Transfer Error Codes** + +| Error Description | Error Code | HTTP Code | Category | +|------------------------------------------------------------------------|-------------|------------------|-----------------------------------------------------------| +| Communication error | 1000 | 503 | Technical Error | +| Destination communication error | 1001 | 503 | Technical Error | +| Generic server error | 2000 | 503 | Processing Error | +| Internal server error | 2001 | 503 | Processing Error | +| Server timed out | 2004 | 503 | Processing Error | +| Generic validation error | 3100 | 400 | Request Validation Error | +| Bulk transfer ID not found | 3210 | 404 | Processing Error | +| Generic expired error | 3300 | 503 | Processing Error | +| Transaction request expired | 3301 | 503 | Processing Error | +| Transfer expired | 3303 | 503 | Processing Error | +| Generic Payee error | 5000 | 400 | Processing Error | +| Payee FSP insufficient liquidity | 5001 | 400 | Processing Error | +| Generic Payee rejection | 5100 | 400 | Processing Error | +| Payee rejected quote | 5101 | 400 | Processing Error | +| Payee FSP unsupported transaction type | 5102 | 400 | Processing Error | +| Payee FSP rejected quote | 5103 | 400 | Processing Error | +| Payee rejected transaction | 5104 | 400 | Processing Error | +| Payee FSP rejected transaction | 5105 | 400 | Processing Error | +| Payee unsupported currency | 5106 | 400 | Processing Error | +| Payee limit error | 5200 | 400 | Processing Error | +| Payee permission error | 5300 | 403 | Processing Error | +| Generic Payee blocked error | 5400 | 400 | Processing Error | diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML new file mode 100644 index 000000000..8f7e09906 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.PlantUML @@ -0,0 +1,89 @@ +@startuml PayeeDFSPBulkIdealPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPBulkIdealPattern +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Discovery == + +Switch->MC: **GET** /parties/{Type}/{Id} +MC-->Switch: HTTP 202 Response +MC->CC: **GET** /parties/{Type}/{Id} +activate MC +CC->CBS: **GET** [account lookup] +CBS-->CC: Response +CC-->MC: Response +deactivate MC +alt If Success response +MC-->Switch: **PUT** /parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId}) +else if Error response +MC-->Switch: **PUT** /parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error) +end + +== Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check == + +Switch->MC: **POST** /bulkquotes +MC-->Switch: HTTP 202 Response +loop X times for each transfer in bulk message + MC->CC: **POST** /quoterequest + activate MC + CC->CBS: **AML** checks + CBS-->CC: Response + CC->CBS: **Calculate Fees** + CBS-->CC: Response + CC-->MC: Response + deactivate MC + MC->MC: Update transaction status \nand attach quote response +end Loop +MC-->Switch: **PUT** /bulkquotes/{Id} +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /bulktransfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds at indivial transfer level + Switch->MC: **POST** /bulktransfers + loop X times for each transfer in bulk message + MC->CC: Create & Reserve Transfer\n **POST** /transfers + activate MC + CC->CBS: Reserve funds + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC -> MC:Update transaction status \nand attach transfer response + end Loop + MC-->Switch: **PUT** /bulktransfers/{id} (BulkStatus='PROCESSING') + Switch-->Switch: Commit funds at indivial transfer level in DFSP ledgers + Switch -> MC: **PATCH** /bulktransfers/{id} (BulkStatus='COMPLETED') + loop X times for each transfer in bulk message + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} \n(TransferStatus='COMMITTED', homeTransactionId) + activate MC + CC->CBS: Commit funds + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + deactivate MC + end loop + + + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg new file mode 100644 index 000000000..f4c0069b0 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkIdealPattern.svg @@ -0,0 +1,183 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Discovery[1]GET/parties/{Type}/{Id}[2]HTTP 202 Response[3]GET/parties/{Type}/{Id}[4]GET[account lookup][5]Response[6]Responsealt[If Success response][7]PUT/parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId})[if Error response][8]PUT/parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error)Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check[9]POST/bulkquotes[10]HTTP 202 Responseloop[X times for each transfer in bulk message][11]POST/quoterequest[12]AMLchecks[13]Response[14]Calculate Fees[15]Response[16]Response[17]Update transaction statusand attach quote response[18]PUT/bulkquotes/{Id}[19]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/bulktransfers[20]Perform liquidity(NDC)check[21]Reserve Funds at indivial transfer level[22]POST/bulktransfersloop[X times for each transfer in bulk message][23]Create & Reserve Transfer POST/transfers[24]Reserve funds[25]response (homeTransactionId)[26]response (homeTransactionId)[27]Generate Fulfilment[28]Update transaction statusand attach transfer response[29]PUT/bulktransfers/{id} (BulkStatus='PROCESSING')[30]Commit funds at indivial transfer level in DFSP ledgers[31]PATCH/bulktransfers/{id} (BulkStatus='COMPLETED')loop[X times for each transfer in bulk message][32]Commit Transfer PATCH/transfers/{id}(TransferStatus='COMMITTED', homeTransactionId)[33]Commit funds[34]Release funds to Payee[35]response[36]response \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML new file mode 100644 index 000000000..438ef1779 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.PlantUML @@ -0,0 +1,84 @@ +@startuml PayeeDFSPBulkSingleIntegrationApiOnPatch +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPBulkSingleIntegrationApiOnPatch +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH == + +Switch->MC: **POST** /bulkquotes +MC-->Switch: HTTP 202 Response +loop X times for each transfer in bulk message + MC->CC: **POST** /quoterequest + activate MC + CC->CC: Do nothing + CC-->MC: Response + deactivate MC + MC->MC: Update transaction status \nand attach quote response +end Loop +MC-->Switch: **PUT** /bulkquotes/{Id} + +Switch->Switch: Pass Quote to Payer DFSP +note left +Obtain consent to +proceed with the transfer +Via **POST** /bulktransfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds at indivial transfer level + Switch->MC: **POST** /bulktransfers + loop X times for each transfer in bulk message + MC->CC: **POST** /transfers + activate MC + CC->CC: Do Nothing + CC-->MC: response + deactivate MC + MC->MC: Generate Fulfilment + MC -> MC:Update transaction status \nand attach transfer response + end Loop + MC-->Switch: **PUT** /bulktransfers/{id} (BulkStatus='PROCESSING') + Switch-->Switch: Commit funds at indivial transfer level in DFSP ledgers + Switch -> MC: **PATCH** /bulktransfers/{id} (BulkStatus='COMPLETED') + loop X times for each transfer in bulk message + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + activate MC + CC->CBS: Performn AML checks and transfer funds + alt if (AML checks pass) + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + else if (AML checks fail) + CBS->CBS: Compensation action for AML failure. \n Return error response. + CBS-->CC: response + CC-->MC: response + deactivate MC + rnote left MC + Payee DFSP AML checks / other errors result in: + + **Reconciliation Error** + Payer has sent funds + Payer DFSP has sent funds + Hub considers that the Payee DFSP has received funds + Payee DFSP has rejected the transaction + Payee has not received funds + endrnote + end + end Loop + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg new file mode 100644 index 000000000..5fe598782 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPBulkSingleIntegrationApiOnPatch.svg @@ -0,0 +1,173 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH[1]POST/bulkquotes[2]HTTP 202 Responseloop[X times for each transfer in bulk message][3]POST/quoterequest[4]Do nothing[5]Response[6]Update transaction statusand attach quote response[7]PUT/bulkquotes/{Id}[8]Pass Quote to Payer DFSPObtain consent toproceed with the transferViaPOST/bulktransfers[9]Perform liquidity(NDC)check[10]Reserve Funds at indivial transfer level[11]POST/bulktransfersloop[X times for each transfer in bulk message][12]POST/transfers[13]Do Nothing[14]response[15]Generate Fulfilment[16]Update transaction statusand attach transfer response[17]PUT/bulktransfers/{id} (BulkStatus='PROCESSING')[18]Commit funds at indivial transfer level in DFSP ledgers[19]PATCH/bulktransfers/{id} (BulkStatus='COMPLETED')loop[X times for each transfer in bulk message][20]Commit Transfer PATCH/transfers/{id} (TransferStatus='COMMITTED')[21]Performn AML checks and transfer fundsalt[if (AML checks pass)][22]Release funds to Payee[23]response[24]response[if (AML checks fail)][25]Compensation action for AML failure.Return error response.[26]response[27]responsePayee DFSP AML checks / other errors result in: Reconciliation ErrorPayer has sent fundsPayer DFSP has sent fundsHub considers that the Payee DFSP has received fundsPayee DFSP has rejected the transactionPayee has not received funds \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML new file mode 100644 index 000000000..dace0ab8b --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.PlantUML @@ -0,0 +1,80 @@ +@startuml PayeeDFSPIdealPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPIdealPattern +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Discovery == + +Switch->MC: **GET** /parties/{Type}/{Id} +MC-->Switch: HTTP 202 Response +MC->CC: **GET** /parties/{Type}/{Id} +activate MC +CC->CBS: **GET** [account lookup] +CBS-->CC: Response +CC-->MC: Response +deactivate MC +alt If Success response +MC-->Switch: **PUT** /parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId}) +else if Error response +MC-->Switch: **PUT** /parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error) +end + +== Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CBS: **AML** checks (velocity,etc...) +CBS-->CC: Response +CC->CBS: **Calculate Fees** +CBS-->CC: Response +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: Create & Reserve Transfer\n **POST** /transfers + activate MC + CC->CBS: Reserve funds + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch->Switch: Commit funds in DFSP ledgers + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} \n(TransferStatus='COMMITTED', homeTransactionId) + activate MC + CC->CBS: Commit funds + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + deactivate MC + + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg new file mode 100644 index 000000000..577ff3030 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPIdealPattern.svg @@ -0,0 +1,165 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Discovery[1]GET/parties/{Type}/{Id}[2]HTTP 202 Response[3]GET/parties/{Type}/{Id}[4]GET[account lookup][5]Response[6]Responsealt[If Success response][7]PUT/parties/{Type}/{Id} (or /parties/{Type}/{Id}/{SubId})[if Error response][8]PUT/parties/{Type}/{Id}/error (or /parties/{Type}/{Id}/{SubId}/error)Payee DFSP integration - Quote and Transfer - 2 phase commit with prior AML check[9]POST/quotes[10]HTTP 202 Response[11]POST/quoterequest[12]AMLchecks (velocity,etc...)[13]Response[14]Calculate Fees[15]Response[16]Response[17]PUT/quotes/{Id}[18]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[19]Perform liquidity(NDC)check[20]Reserve Funds[21]POST/transfers[22]Create & Reserve Transfer POST/transfers[23]Reserve funds[24]response (homeTransactionId)[25]response (homeTransactionId)[26]Generate Fulfilment[27]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[28]Commit funds in DFSP ledgers[29]PATCH/transfers/{id} (TransferStatus='COMMITTED')[30]Commit Transfer PATCH/transfers/{id}(TransferStatus='COMMITTED', homeTransactionId)[31]Commit funds[32]Release funds to Payee[33]response[34]response \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML new file mode 100644 index 000000000..1f12dce39 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatch.PlantUML @@ -0,0 +1,76 @@ +@startuml PayeeDFSPSingleIntegrationApiOnPatchPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPSingleIntegrationApiOnPatch +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CC: Do nothing +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} + +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: **POST** /transfers + activate MC + CC->CC: Do Nothing + CC-->MC: response + deactivate MC + MC->MC: Generate Fulfilment + MC-->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch-->Switch: Commit funds in DFSP ledgers + + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + MC->CC: Commit Transfer\n **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + activate MC + CC->CBS: Perform AML checks and transfer funds + alt if (AML checks pass) + CBS->CBS: Release funds to Payee + CBS-->CC: response + CC-->MC: response + else if (AML checks fail) + CBS->CBS: Compensation action for AML failure. \n Return error response. + CBS-->CC: response + CC-->MC: response + rnote left MC + Payee DFSP AML error checks (and other errors) result in: + + **Reconciliation Error** + Payer has sent funds + Payer DFSP has sent funds + Hub considers that the Payee DFSP has received funds + Payee DFSP has rejected the transaction + Payee has not received funds + endrnote + end + deactivate MC + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg new file mode 100644 index 000000000..ed8a23a77 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnPatchPattern.svg @@ -0,0 +1,157 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during PATCH[1]POST/quotes[2]HTTP 202 Response[3]POST/quoterequest[4]Do nothing[5]Response[6]PUT/quotes/{Id}[7]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[8]Perform liquidity(NDC)check[9]Reserve Funds[10]POST/transfers[11]POST/transfers[12]Do Nothing[13]response[14]Generate Fulfilment[15]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[16]Commit funds in DFSP ledgers[17]PATCH/transfers/{id} (TransferStatus='COMMITTED')[18]Commit Transfer PATCH/transfers/{id} (TransferStatus='COMMITTED')[19]Perform AML checks and transfer fundsalt[if (AML checks pass)][20]Release funds to Payee[21]response[22]response[if (AML checks fail)][23]Compensation action for AML failure.Return error response.[24]response[25]responsePayee DFSP AML error checks (and other errors) result in: Reconciliation ErrorPayer has sent fundsPayer DFSP has sent fundsHub considers that the Payee DFSP has received fundsPayee DFSP has rejected the transactionPayee has not received funds \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML new file mode 100644 index 000000000..c9e8b2a41 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransfer.PlantUML @@ -0,0 +1,67 @@ +@startuml PayeeDFSPSingleIntegrationApiOnTransferPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayeeDFSPSingleIntegrationApiOnTransfer +' declare actors +participant "Mojaloop\nSwitch" as Switch +box "Payment Manager\nPayee DFSP" #LightGrey +participant "SDK Scheme Adapter" as MC +participant "Core\nConnector" as CC +end box +participant "Core banking solution" as CBS +autonumber 1 1 "[0]" + +== Payee DFSP integration - Quote and Transfer - single AML check & transfer during POST transfer == + +Switch->MC: **POST** /quotes +MC-->Switch: HTTP 202 Response +MC->CC: **POST** /quoterequest +activate MC +CC->CC: Do nothing +CC-->MC: Response +deactivate MC +MC-->Switch: **PUT** /quotes/{Id} + +Switch->Switch: Pass Quote to Payer +note left +Obtain consent to +proceed with the transfer +Via **POST** /transfers +end note + Switch-> Switch: Perform liquidity(NDC)check + Switch->Switch: Reserve Funds + Switch->MC: **POST** /transfers + MC->CC: **POST** /transfers + activate MC + CC->CBS: Perform AML checks and transfer funds + CBS->CBS: Release of funds to Payee + CBS-->CC: response (homeTransactionId) + CC-->MC: response (homeTransactionId) + deactivate MC + MC->MC: Generate Fulfilment + MC-->Switch: **PUT** /transfers/{id} (TransferStatus='RESERVED', fulfullment) + Switch->Switch: Commit funds in DFSP ledgers + alt if (Transfer status == 'ABORTED') + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='ABORTED', homeTransactionId) + MC->CC: Abort Transfer\n **PATCH** /transfers/{id} (TransferStatus='ABORTED') + CC->CBS: Abort Transfer + CBS->CBS: Compensate action for abort + CBS-->CC: response + else if (Transfer status == 'COMMITTED') + Switch->MC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED', homeTransactionId) + MC->CC: **PATCH** /transfers/{id} (TransferStatus='COMMITTED') + CC->CC: Do nothing + CC-->MC: response + end + + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg new file mode 100644 index 000000000..811cbdc15 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayeeDFSPSingleIntegrationApiOnTransferPattern.svg @@ -0,0 +1,139 @@ +Payment ManagerPayee DFSPMojaloopSwitchMojaloopSwitchSDK Scheme AdapterSDK Scheme AdapterCoreConnectorCoreConnectorCore banking solutionCore banking solutionPayee DFSP integration - Quote and Transfer - single AML check & transfer during POST transfer[1]POST/quotes[2]HTTP 202 Response[3]POST/quoterequest[4]Do nothing[5]Response[6]PUT/quotes/{Id}[7]Pass Quote to PayerObtain consent toproceed with the transferViaPOST/transfers[8]Perform liquidity(NDC)check[9]Reserve Funds[10]POST/transfers[11]POST/transfers[12]Perform AML checks and transfer funds[13]Release of funds to Payee[14]response (homeTransactionId)[15]response (homeTransactionId)[16]Generate Fulfilment[17]PUT/transfers/{id} (TransferStatus='RESERVED', fulfullment)[18]Commit funds in DFSP ledgersalt[if (Transfer status == 'ABORTED')][19]PATCH/transfers/{id} (TransferStatus='ABORTED', homeTransactionId)[20]Abort Transfer PATCH/transfers/{id} (TransferStatus='ABORTED')[21]Abort Transfer[22]Compensate action for abort[23]response[if (Transfer status == 'COMMITTED')][24]PATCH/transfers/{id} (TransferStatus='COMMITTED', homeTransactionId)[25]PATCH/transfers/{id} (TransferStatus='COMMITTED')[26]Do nothing[27]response \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML new file mode 100644 index 000000000..7d193ae2c --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApi.PlantUML @@ -0,0 +1,100 @@ +@startuml PayerDFSPBulkDoubleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayerDFSPBulkDoubleIntegrationApi +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "Mojaloop\nConnector" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - with user confirmation == + +CBS->CC: **POST** /bulkTransactions\n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**, synchronous = false) +Loop n times (in parallel) + hnote left of CC + For each individual transfer + in bulk message + end hnote + CC -> CC: validate MSISDN & Prefix +end Loop +CC->MC: **POST** /bulkTransactions\n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**, synchronous = false) +activate MC +loop N times & within bulkExpiration timelimit (in parallel) +hnote left of MC + For each transfer + in bulk message +end hnote + activate MC + MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} + Switch-->MC: HTTP 202 response + Switch->Switch: Determine Payee DFSP using oracle + Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties + Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} + MC-->Switch: HTTP 200 Response +end Loop + +rnote left MC + Accept Party +endrnote + +loop Quote Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC->MC: Check bulkExpiration + MC->MC: Create bulkTransactionId + MC -> MC: Calculate bulk expiry \nbased on both expirySeconds config and \nbulkExpiration + MC->Switch: **POST** /bulkquotes + Switch-->MC: HTTP 202 response + Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /bulkquotes + Switch->MC: **PUT** /bulkquotes/{Id} + MC-->Switch: HTTP 200 Response +end loop + MC->CC: **PUT** /bulkTransactions/{Id} + + deactivate MC + CC->CBS: **PUT** /bulkTransactions/{Id} + + +CBS->CBS: Obtain concent from Payer on Fees and Payee Info +CBS->CBS: Reserve funds +CBS->CC: **PUT** /bulkTransactions/{bulkhometransferId} +CC->MC: **PUT** /bulkTransactions/{bulktransactionId} + +loop Transfer Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + + activate MC + MC->Switch: **POST** /bulktransfers + Switch-->MC: HTTP 202 response + Switch->Switch: Reserve Payer DFSP funds + Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /bulktransfers + Switch->Switch: Commit Payer DFSP funds + Switch->MC: **PUT** /bulktransfers/{Id} + MC-->Switch: HTTP 200 Response +end loop + +MC->CC: **PUT** /bulkTransactions/{Id} + +deactivate MC +CC->CBS: **PUT** /bulkTransactions/{Id} +CBS->CBS: Commit funds + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg new file mode 100644 index 000000000..19e336a0a --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkDoubleIntegrationApiPattern.svg @@ -0,0 +1,205 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorMojaloopConnectorMojaloopConnectorMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - with user confirmation[1]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false, synchronous = false)loop[n times (in parallel)]For each individual transferin bulk message[2]validate MSISDN & Prefix[3]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false, synchronous = false)loop[N times & within bulkExpiration timelimit (in parallel)]For each transferin bulk message[4]GET/parties/{Type}/{ID}/{SubId}[5]HTTP 202 response[6]Determine Payee DFSP using oracle[7]Lookup Payee Information from Payee DFSPusingGET/parties[8]PUT/parties/{Type}/{ID}/{SubId}[9]HTTP 200 ResponseAccept Partyloop[Quote Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[10]Check bulkExpiration[11]Create bulkTransactionId[12]Calculate bulk expirybased on both expirySeconds config andbulkExpiration[13]POST/bulkquotes[14]HTTP 202 response[15]Pass on quote to Payee DFSPusingPOST/bulkquotes[16]PUT/bulkquotes/{Id}[17]HTTP 200 Response[18]PUT/bulkTransactions/{Id}[19]PUT/bulkTransactions/{Id}[20]Obtain concent from Payer on Fees and Payee Info[21]Reserve funds[22]PUT/bulkTransactions/{bulkhometransferId}[23]PUT/bulkTransactions/{bulktransactionId}loop[Transfer Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[24]POST/bulktransfers[25]HTTP 202 response[26]Reserve Payer DFSP funds[27]Pass on transfer to Payee DFSPusingPOST/bulktransfers[28]Commit Payer DFSP funds[29]PUT/bulktransfers/{Id}[30]HTTP 200 Response[31]PUT/bulkTransactions/{Id}[32]PUT/bulkTransactions/{Id}[33]Commit funds \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML new file mode 100644 index 000000000..38e3d8d6c --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApi.PlantUML @@ -0,0 +1,95 @@ +@startuml PayerDFSPBulkSingleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title PayerDFSPBulkSingleIntegrationApi +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - single phase == + +CBS->CBS: Reserve funds +CBS->CC: **POST** /bulkTransactions \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false) +Loop n times (in parallel) + hnote left of CC + For each individual transfer + in bulk message + end hnote + CC -> CC: validate MSISDN & Prefix +end Loop +CC->MC: **POST** /bulkTransactions \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false) +activate MC +loop N times & within bulkExpiration timelimit (in parallel) +hnote left of MC + For each transfer + in bulk message +end hnote + MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} + Switch-->MC: HTTP 202 response + Switch->Switch: Determine Payee DFSP using oracle + Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties + Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} + MC-->Switch: HTTP 200 Response + MC -> MC: Update transaction status and\n attach get parties response + MC -> MC: Add to next phase FSP bulk call +end Loop + +rnote left MC + Accept Party +endrnote + +loop Quote Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC->MC: Check bulkExpiration + MC->MC: Create bulkTransactionId + MC -> MC: Calculate bulk expiry \nbased on both expirySeconds config and \nbulkExpiration + MC->Switch: **POST** /bulkquotes + Switch-->MC: HTTP 202 response + Switch->Switch: Pass on bulkquote to Payee DFSP\n using **POST** /bulkquotes + Switch->MC: **PUT** /bulkquotes/{Id} + MC-->Switch: HTTP 200 Response +end loop + +rnote left MC + Accept Quote +endrnote +loop Transfer Processing (M times & within bulkExpiration timelimit in parallel) + hnote left of MC + For each payee DFSP + in bulk message + end hnote + MC -> MC: Confirm Fees meets auto accept levels\n and bulkExpiration timelimit not reached \n-> Update Transfer Status + + MC->Switch: **POST** /bulktransfers + Switch-->MC: HTTP 202 response + Switch->Switch: Reserve Payer DFSP funds + Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /bulktransfers + Switch->Switch: Commit Payer DFSP funds + Switch->MC: **PUT** /bulktransfers/{Id} + MC-->Switch: HTTP 200 Response +end loop + +MC->CC: **PUT** /bulkTransactions/{Id} + +deactivate MC +CC->CBS: **PUT** /bulkTransactions/{Id} +CBS->CBS: Commit funds + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg new file mode 100644 index 000000000..e136c59bd --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPBulkSingleIntegrationApiPattern.svg @@ -0,0 +1,195 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - single phase[1]Reserve funds[2]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false)loop[n times (in parallel)]For each individual transferin bulk message[3]validate MSISDN & Prefix[4]POST/bulkTransactions(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true, synchronous = false)loop[N times & within bulkExpiration timelimit (in parallel)]For each transferin bulk message[5]GET/parties/{Type}/{ID}/{SubId}[6]HTTP 202 response[7]Determine Payee DFSP using oracle[8]Lookup Payee Information from Payee DFSPusingGET/parties[9]PUT/parties/{Type}/{ID}/{SubId}[10]HTTP 200 Response[11]Update transaction status andattach get parties response[12]Add to next phase FSP bulk callAccept Partyloop[Quote Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[13]Check bulkExpiration[14]Create bulkTransactionId[15]Calculate bulk expirybased on both expirySeconds config andbulkExpiration[16]POST/bulkquotes[17]HTTP 202 response[18]Pass on bulkquote to Payee DFSPusingPOST/bulkquotes[19]PUT/bulkquotes/{Id}[20]HTTP 200 ResponseAccept Quoteloop[Transfer Processing (M times & within bulkExpiration timelimit in parallel)]For each payee DFSPin bulk message[21]Confirm Fees meets auto accept levelsand bulkExpiration timelimit not reached-> Update Transfer Status[22]POST/bulktransfers[23]HTTP 202 response[24]Reserve Payer DFSP funds[25]Pass on transfer to Payee DFSPusingPOST/bulktransfers[26]Commit Payer DFSP funds[27]PUT/bulktransfers/{Id}[28]HTTP 200 Response[29]PUT/bulkTransactions/{Id}[30]PUT/bulkTransactions/{Id}[31]Commit funds \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML new file mode 100644 index 000000000..540789924 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.PlantUML @@ -0,0 +1,66 @@ +@startuml PayerDFSPDoubleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Core-Connector transactional flow patterns +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager\nPayer DFSP" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - with user confirmation == + +CBS->CC: **POST** /sendMoney \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = **false**) +CC->MC: **POST** /transfers +activate MC +MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} +Switch-->MC: HTTP 202 response +Switch->Switch: Determine Payee DFSP using oracle +Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties +Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Party +endrnote +MC->Switch: **POST** /quotes +Switch-->MC: HTTP 202 response +Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /quotes +Switch->MC: **PUT** /quotes/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: Response +deactivate MC +CC-->CBS: Response +CBS->CBS: Obtain concent from Payer on Fees and Payee Info +CBS->CBS: Reserve funds +CBS->CC: **PUT** /sendmoney/{transferId} +CC->MC: **PUT** /transfers + +activate MC +MC->Switch: **POST** /transfers +Switch-->MC: HTTP 202 response +Switch->Switch: Reserve Payer DFSP funds +Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /transfers +Switch->Switch: Commit Payer DFSP funds +Switch->MC: **PUT** /transfers/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: response +deactivate MC +CC-->CBS: response +alt if (transferStatus== 'COMMITTED') +CBS->CBS: Finalise transfer +else else +CBS->CBS: Rollback transfer +end +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg new file mode 100644 index 000000000..175a64e31 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPDoubleIntegrationApiPattern.svg @@ -0,0 +1,137 @@ +Payment ManagerPayer DFSPCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - with user confirmation[1]POST/sendMoney(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES =false)[2]POST/transfers[3]GET/parties/{Type}/{ID}/{SubId}[4]HTTP 202 response[5]Determine Payee DFSP using oracle[6]Lookup Payee Information from Payee DFSPusingGET/parties[7]PUT/parties/{Type}/{ID}/{SubId}[8]HTTP 200 ResponseAccept Party[9]POST/quotes[10]HTTP 202 response[11]Pass on quote to Payee DFSPusingPOST/quotes[12]PUT/quotes/{Id}[13]HTTP 200 Response[14]Response[15]Response[16]Obtain concent from Payer on Fees and Payee Info[17]Reserve funds[18]PUT/sendmoney/{transferId}[19]PUT/transfers[20]POST/transfers[21]HTTP 202 response[22]Reserve Payer DFSP funds[23]Pass on transfer to Payee DFSPusingPOST/transfers[24]Commit Payer DFSP funds[25]PUT/transfers/{Id}[26]HTTP 200 Response[27]response[28]responsealt[if (transferStatus== 'COMMITTED')][29]Finalise transfer[else][30]Rollback transfer \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML new file mode 100644 index 000000000..4884dec9c --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.PlantUML @@ -0,0 +1,63 @@ +@startuml PayerDFSPSingleIntegrationApiPattern +/'***** +-------------- +******'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Payer DFSP Single Phase Integration Pattern +' declare actors +participant "Core banking solution" as CBS +box "Payment Manager" #LightGrey +participant "Core\nConnector" as CC +participant "SDK Scheme Adapter" as MC +end box +participant "Mojaloop\nSwitch" as Switch +autonumber 1 1 "[0]" + +== Payer DFSP integration - 2 phase commit - single phase == + +CBS->CBS: Reserve funds +CBS->CC: **POST** /sendMoney \n(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true) +CC->MC: **POST** /transfers +activate MC +MC->Switch: **GET** /parties/{Type}/{ID}/{SubId} +Switch-->MC: HTTP 202 response +Switch->Switch: Determine Payee DFSP using oracle +Switch->Switch: Lookup Payee Information from Payee DFSP\n using **GET** /parties +Switch->MC: **PUT** /parties/{Type}/{ID}/{SubId} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Party +endrnote +MC->Switch: **POST** /quotes +Switch-->MC: HTTP 202 response +Switch->Switch: Pass on quote to Payee DFSP\n using **POST** /quotes +Switch->MC: **PUT** /quotes/{Id} +MC-->Switch: HTTP 200 Response +rnote left MC + Accept Quote +endrnote +MC->Switch: **POST** /transfers +Switch-->MC: HTTP 202 response +Switch->Switch: Reserve Payer DFSP funds +Switch->Switch: Pass on transfer to Payee DFSP\n using **POST** /transfers +Switch->Switch: Calculate fees +Switch->Switch: Commit Payer DFSP funds +Switch->MC: **PUT** /transfers/{Id} +MC-->Switch: HTTP 200 Response +MC-->CC: response +deactivate MC +CC-->CBS: response +alt if (transferStatus== 'COMMITTED') +CBS->CBS: Finalise transfer +else else +CBS->CBS: Rollback transfer +end + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg new file mode 100644 index 000000000..8c3b55365 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/PayerDFSPSingleIntegrationApiPattern.svg @@ -0,0 +1,131 @@ +Payment ManagerCore banking solutionCore banking solutionCoreConnectorCoreConnectorSDK Scheme AdapterSDK Scheme AdapterMojaloopSwitchMojaloopSwitchPayer DFSP integration - 2 phase commit - single phase[1]Reserve funds[2]POST/sendMoney(AUTO_ACCEPT_PARTY = true, AUTO_ACCEPT_QUOTES = true)[3]POST/transfers[4]GET/parties/{Type}/{ID}/{SubId}[5]HTTP 202 response[6]Determine Payee DFSP using oracle[7]Lookup Payee Information from Payee DFSPusingGET/parties[8]PUT/parties/{Type}/{ID}/{SubId}[9]HTTP 200 ResponseAccept Party[10]POST/quotes[11]HTTP 202 response[12]Pass on quote to Payee DFSPusingPOST/quotes[13]PUT/quotes/{Id}[14]HTTP 200 ResponseAccept Quote[15]POST/transfers[16]HTTP 202 response[17]Reserve Payer DFSP funds[18]Pass on transfer to Payee DFSPusingPOST/transfers[19]Calculate fees[20]Commit Payer DFSP funds[21]PUT/transfers/{Id}[22]HTTP 200 Response[23]response[24]responsealt[if (transferStatus== 'COMMITTED')][25]Finalise transfer[else][26]Rollback transfer \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml new file mode 100644 index 000000000..362d9c085 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.plantuml @@ -0,0 +1,132 @@ +@startuml +/'******** +-------------- +*********'/ + +skinparam activityFontSize 4 +skinparam activityDiamondFontSize 30 +skinparam activityArrowFontSize 22 +skinparam defaultFontSize 22 +skinparam noteFontSize 22 +skinparam monochrome true +' declare title +' title Bulk Transactions pattern using the Mojaloop Connector +' declare actors + +box "Payer DFSP" #LightGrey + participant "Backend System" as MFICC + participant "sdk-scheme-adapter" as MFIMC +end box +participant "Mojaloop\nSwitch" as MJW +box "Payee DFSP" #LightGrey + participant "sdk-scheme-adapter" as PayeeFSPMC + participant "Backend System" as PayeeFSPCC +end box + +== MVP Bulk Transfers using SDK-Scheme-Adapter == + +autonumber 1 1 "[0]" +MFICC->>MFIMC: **POST** /bulkTransactions +note left +Bulk Disbursement is triggerd +by beneficiary management sub-system +end note + +loop Discovery Processing: For each individualTransfer in bulk message +hnote left of MFIMC + Resolving all potential recipients + which might be at any of the DFSPs + on the service. +end hnote + MFIMC ->> MJW: **GET** /parties/* + activate MFIMC + MJW->MJW: query oracle to \ndetermine Payee DFSP + MJW->>PayeeFSPMC: **GET** /parties/* + PayeeFSPMC->PayeeFSPCC: **GET** /parties/* + note right + Lookup / validate party information + end note + PayeeFSPMC-->>MJW: **PUT** /parties/{type}/{id} + MJW-->>MFIMC: **PUT** /parties/{type}/{id} + deactivate MFIMC + +end Loop + MFIMC-->>MFICC: **PUT** /bulkTransactions/{bulkTransactionId} + MFICC->>MFIMC: **PUT** /bulkTransactions/{bulkTransactionId} + note left + Confirmation of party integration + end note + +MFIMC->MFIMC: Group Valid Transfers into batches +loop Agreement Processing: For each batch in bulk message +hnote left of MFIMC + Each DFSP is provided the opportunity to + perform AML checks and add costs + or discounts to each transfer. +end hnote + MFIMC ->> MJW: **POST** /bulkquotes + activate MFIMC + MJW->>PayeeFSPMC: **POST** /bulkquotes + alt if (HasSupportForBulkQuotes) + PayeeFSPMC->PayeeFSPCC: **POST** /bulkquotes + note right + Bulk AML checks + Bulk Fee calculations + end note + else if (!HasSupportForBulkQuotes) + loop X times for each transfer in bulk message + PayeeFSPMC->PayeeFSPCC: **POST** /quoterequests + note right + AML checks + Fee calculations + end note + end Loop + end + PayeeFSPMC-->>MJW: **PUT** /bulkquotes/{id) + MJW-->>MFIMC: **PUT** /bulkquotes/{id) + deactivate MFIMC +end loop + + MFIMC-->>MFICC: **PUT** /bulkTransactions/{bulkTransactionId} + MFICC->>MFIMC: **PUT** /bulkTransactions/{bulkTransactionId} + note left + confirmation of quote integration + end note + +loop Transfer Processing: For each batch in bulk message + hnote left of MFIMC + Each DFSP is messaged to proceed + with the transfer. Results + are captured and returned. + end hnote + MFIMC ->> MJW: **POST** /bulktransfers + activate MFIMC + MJW-> MJW: Perform liquidity(NDC) check\n at individual transfer level + MJW->MJW: Reserve Funds + MJW ->> PayeeFSPMC: **POST** /bulktransfers + alt if (HasSupportForBulkTransfers) + PayeeFSPMC->PayeeFSPCC: **POST** /bulktransfers + note right + Bulk Transfer integration + end note + else if (!HasSupportForBulkTransfers) + loop X times for each transfer in bulk message + PayeeFSPMC->PayeeFSPCC: **POST** /transfers + note right + Single Transfer integration + end note + end Loop + end + PayeeFSPMC -->> MJW: **PUT** /bulktransfers/{id} (BulkStatus) + MJW->MJW: Commit funds at indivial transfer level + MJW-->>MFIMC:**PUT** /bulktransfers/{id} + + deactivate MFIMC +end loop +MFIMC-->>MFICC:Callback Response \n**PUT** /bulkTransactions/{bulkTransactionId}\nTransfer Response (success & fail) +note left + Result of bulk disbursement received. +end note + + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg new file mode 100644 index 000000000..a6fc96ca3 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKBulkSequenceDiagram.svg @@ -0,0 +1,295 @@ + + + + + Payer DFSP + + Payee DFSP + + + + + + + + + + + + + + + + + Backend System + + Backend System + + sdk-scheme-adapter + + sdk-scheme-adapter + + Mojaloop + Switch + + Mojaloop + Switch + + sdk-scheme-adapter + + sdk-scheme-adapter + + Backend System + + Backend System + + + + + + + + MVP Bulk Transfers using SDK-Scheme-Adapter + + + + [1] + POST + /bulkTransactions + + + Bulk Disbursement is triggerd + by beneficiary management sub-system + + + loop + [Discovery Processing: For each individualTransfer in bulk message] + + Resolving all potential recipients + which might be at any of the DFSPs + on the service. + + + + [2] + GET + /parties/* + + + + + [3] + query oracle to + determine Payee DFSP + + + + [4] + GET + /parties/* + + + [5] + GET + /parties/* + + + Lookup / validate party information + + + + [6] + PUT + /parties/{type}/{id} + + + + [7] + PUT + /parties/{type}/{id} + + + + [8] + PUT + /bulkTransactions/{bulkTransactionId} + + + + [9] + PUT + /bulkTransactions/{bulkTransactionId} + + + Confirmation of party integration + + + + + [10] + Group Valid Transfers into batches + + + loop + [Agreement Processing: For each batch in bulk message] + + Each DFSP is provided the opportunity to + perform AML checks and add costs + or discounts to each transfer. + + + + [11] + POST + /bulkquotes + + + + [12] + POST + /bulkquotes + + + alt + [if (HasSupportForBulkQuotes)] + + + [13] + POST + /bulkquotes + + + Bulk AML checks + Bulk Fee calculations + + [if (!HasSupportForBulkQuotes)] + + + loop + [X times for each transfer in bulk message] + + + [14] + POST + /quoterequests + + + AML checks + Fee calculations + + + + [15] + PUT + /bulkquotes/{id) + + + + [16] + PUT + /bulkquotes/{id) + + + + [17] + PUT + /bulkTransactions/{bulkTransactionId} + + + + [18] + PUT + /bulkTransactions/{bulkTransactionId} + + + confirmation of quote integration + + + loop + [Transfer Processing: For each batch in bulk message] + + Each DFSP is messaged to proceed + with the transfer. Results + are captured and returned. + + + + [19] + POST + /bulktransfers + + + + + [20] + Perform liquidity(NDC) check + at individual transfer level + + + + + [21] + Reserve Funds + + + + [22] + POST + /bulktransfers + + + alt + [if (HasSupportForBulkTransfers)] + + + [23] + POST + /bulktransfers + + + Bulk Transfer integration + + [if (!HasSupportForBulkTransfers)] + + + loop + [X times for each transfer in bulk message] + + + [24] + POST + /transfers + + + Single Transfer integration + + + + [25] + PUT + /bulktransfers/{id} (BulkStatus) + + + + + [26] + Commit funds at indivial transfer level + + + + [27] + PUT + /bulktransfers/{id} + + + + [28] + Callback Response + PUT + /bulkTransactions/{bulkTransactionId} + Transfer Response (success & fail) + + + Result of bulk disbursement received. + + diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml new file mode 100644 index 000000000..2485c6f54 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml @@ -0,0 +1,195 @@ +@startuml + +actor "Payer" as Payer +box Payer DFSP +participant "Core Banking System" as PayerDFSP +participant "SDK" as PayerSDK +end box +participant "Mojaloop" as Mojaloop #d4f2f9 + +box Payee DFSP +participant "SDK" as PayeeSDK +participant "Core Banking System" as PayeeDFSP +end box +actor "Payee" as Payee +autonumber 1 "[0]" + +alt if (User Initiated OTP) +Payer->PayerDFSP: Generate an OTP for me +PayerDFSP->PayerDFSP:Generate +PayerDFSP-->Payer: Here is your OTP +end +=== Payee initiated request to pay (R2P) == +Payee->PayeeDFSP: I would like \nto receive 1000 TZS\n from +1234567890 +PayeeDFSP->PayeeDFSP: Payer not within Payee System + +PayeeDFSP->PayeeSDK: **POST** /requestToPayTransfer +note right +{ + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "+1234567890", + "idSubValue": "string" + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "scenario": {...}, + "initiator": "PAYEE", + "initiatorType": "CONSUMER", + "note": "Note sent to Payee." +} +end note +activate PayeeSDK + +PayeeSDK->>Mojaloop: **GET** /parties +Mojaloop->>PayerSDK: **GET** /parties +PayerSDK->PayerDFSP: **GET** /parties +PayerDFSP->PayerDFSP: Lookup Validate Payer Account +PayerDFSP-->PayerSDK: return Payer information +note left +Payer information +end note +PayerSDK->>Mojaloop: **PUT** /parties +Mojaloop->>PayeeSDK: **PUT** /parties + +alt If AutoAcceptParty = false + PayeeSDK-->PayeeDFSP: **POST**\n /requestToPayTransfer \n(synchronous return) + note left +{ + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "1234567890", + "idSubValue": "string", + "displayName": "ryZ037pWP'lHu,Tu9,Tjl MRMbdMSpRGAHt4m6 2jk5L4'ePRWT", + "firstName": "Henrik", + "middleName": "Johannes", + "lastName": "Karlsson", + "dateOfBirth": "1966-06-16", + "fspId": "string", + "extensionList": [] + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "transactionType": "TRANSFER", + "note": "Note sent to Payee.", + "currentState": "WAITING_FOR_PARTY_ACCEPTANCE", +} + end note +PayeeDFSP->PayeeSDK: **PUT** /requestToPay/\n{requestToPayId} +note right + { + acceptParty: true + } +end note +else +PayeeSDK->PayeeSDK: Automatically \nAcceptParty by updating\n status +end + +PayeeSDK->>Mojaloop: **POST** /transactionRequests +Mojaloop->>PayerSDK: **POST** /transactionRequests +PayerSDK->PayerDFSP: **POST** /transactionRequests +PayerDFSP->PayerDFSP: Validate request\n to pay request +PayerDFSP-->PayerSDK: return +PayerSDK->>Mojaloop: **PUT** /transactionRequests/{ID} +note left +{ + "transactionId": "b51ec534-ee48-4575-b6a9-ead2955b8069", + "transactionRequestState": "RECEIVED", + "AuthenticationType": {} + "extensionList": {extension:[]} +} +end note +Mojaloop->>PayeeSDK: **PUT** /transactionRequests +PayeeSDK-->PayeeDFSP: return +deactivate PayeeSDK + +=== Payer DFSP executes R2P request == + +PayerDFSP->PayerSDK: **POST** /RequestToPayTransfer +note left +Initiate R2P with AuthType +end note +activate PayerSDK +PayerSDK->>Mojaloop: **POST** /quotes +Mojaloop->>PayeeSDK: **POST** /quotes +PayeeSDK->PayeeDFSP: **POST** /quoterequest +PayeeDFSP->PayeeSDK: return quote +PayeeSDK->>Mojaloop: **PUT** /quotes +Mojaloop->>PayerSDK: **PUT** /quotes + +PayerSDK-->PayerDFSP: return \n(**POST** /RequestToPayTransfer) +deactivate PayerSDK + +alt if AuthenticateType is null +PayerDFSP->Payer: Present payment terms\n to Payer for acceptance +Payer->PayerDFSP: I accept the payment terms +else if AuthenticateType is OTP +alt if (Automatic generated OTP) + +PayerDFSP->PayerDFSP: Generate OTP +PayerDFSP->Payer: Present OTP to Payer +end + +loop x retries +PayerDFSP->PayerSDK: **PUT** /RequestToPayTransfer +note left + accept quote = true + retries left = x +end note + +PayerSDK->>Mojaloop: **GET** \n/authorizations/\n{transactionRequestID} +Mojaloop->>PayeeSDK: **GET** \n/authorizations/\n{transactionRequestID} +PayeeSDK->PayeeDFSP: **GET** \n/auth/{authtype}/{requestToPayId} +PayeeDFSP->Payee: Get Payee to get\n Payer to enter OTP\n on POS +Payer->PayeeDFSP: Enter OTP +PayeeDFSP-->PayeeSDK: return OTP +note right +{ + "otpValue": "string" +} +end note +PayeeSDK->>Mojaloop: **PUT** /authorizations/{ID} +Mojaloop->>PayerSDK: **PUT** /authorizations/{ID} +PayerSDK-->PayerDFSP: synchronous return \n **POST** /requestToPayTransfer/\n{requestToPayTransactionId} +PayerDFSP->PayerDFSP: Validate OTP + +end loop + +end + + + +alt if can proceed with transfer +PayerDFSP->PayerDFSP: Reserve funds against \nPayer's account +PayerDFSP-->PayerSDK: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId} + +PayerSDK->>Mojaloop: **POST** /transfers +activate PayerSDK +Mojaloop->>PayeeSDK: **POST** /transfers +PayeeSDK-->PayeeDFSP: **PUT** / **POST**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n return +PayeeDFSP->Payee: Notify user +PayeeSDK->>Mojaloop: **PUT** /transfers \nreturn fulfilment +Mojaloop->>PayerSDK: **PUT** /transfers +deactivate PayerSDK +PayerSDK->PayerDFSP: **POST** \n/newAPI \nNotify payer of transfer +PayerDFSP->PayerDFSP: Commit transfer \nto Payer's account +PayerDFSP->Payer: Notify Payer + +else if rejected + +PayerDFSP-->PayerSDK: return +PayerSDK->>Mojaloop: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId}\n rejected +Mojaloop->>PayeeSDK: **PUT**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n rejected +PayeeSDK-->X PayeeDFSP: return rejected +end + + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg new file mode 100644 index 000000000..f734170e5 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg @@ -0,0 +1,532 @@ + + + + + Payer DFSP + + Payee DFSP + + + + + + + + + + + + + + + + + Payer + + + Payer + + + + Core Banking System + + Core Banking System + + SDK + + SDK + + Mojaloop + + Mojaloop + + SDK + + SDK + + Core Banking System + + Core Banking System + Payee + + + Payee + + + + + + + + alt + [if (User Initiated OTP)] + + + [1] + Generate an OTP for me + + + + + [2] + Generate + + + [3] + Here is your OTP + + + + + Payee initiated request to pay (R2P) + + + [4] + I would like + to receive 1000 TZS + from +1234567890 + + + + + [5] + Payer not within Payee System + + + [6] + POST + /requestToPayTransfer + + + { + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "+1234567890", + "idSubValue": "string" + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "scenario": {...}, + "initiator": "PAYEE", + "initiatorType": "CONSUMER", + "note": "Note sent to Payee." + } + + + + [7] + GET + /parties + + + + [8] + GET + /parties + + + [9] + GET + /parties + + + + + [10] + Lookup Validate Payer Account + + + [11] + return Payer information + + + Payer information + + + + [12] + PUT + /parties + + + + [13] + PUT + /parties + + + alt + [If AutoAcceptParty = false] + + + [14] + POST + /requestToPayTransfer + (synchronous return) + + + { + "requestToPayTransactionId": "string", + "from": { + "type": "CONSUMER", + "idType": "MSISDN", + "idValue": "1234567890", + "idSubValue": "string", + "displayName": "ryZ037pWP'lHu,Tu9,Tjl MRMbdMSpRGAHt4m6 2jk5L4'ePRWT", + "firstName": "Henrik", + "middleName": "Johannes", + "lastName": "Karlsson", + "dateOfBirth": "1966-06-16", + "fspId": "string", + "extensionList": [] + }, + "to": {...}, + "amountType": "RECEIVE", + "currency": "TZS", + "amount": "1000.0", + "transactionType": "TRANSFER", + "note": "Note sent to Payee.", + "currentState": "WAITING_FOR_PARTY_ACCEPTANCE", + } + + + [15] + PUT + /requestToPay/ + {requestToPayId} + + + { + acceptParty: true + } + + + + + + [16] + Automatically + AcceptParty by updating + status + + + + [17] + POST + /transactionRequests + + + + [18] + POST + /transactionRequests + + + [19] + POST + /transactionRequests + + + + + [20] + Validate request + to pay request + + + [21] + return + + + + [22] + PUT + /transactionRequests/{ID} + + + { + "transactionId": "b51ec534-ee48-4575-b6a9-ead2955b8069", + "transactionRequestState": "RECEIVED", + "AuthenticationType": {} + "extensionList": {extension:[]} + } + + + + [23] + PUT + /transactionRequests + + + [24] + return + + + + + Payer DFSP executes R2P request + + + [25] + POST + /RequestToPayTransfer + + + Initiate R2P with AuthType + + + + [26] + POST + /quotes + + + + [27] + POST + /quotes + + + [28] + POST + /quoterequest + + + [29] + return quote + + + + [30] + PUT + /quotes + + + + [31] + PUT + /quotes + + + [32] + return + ( + POST + /RequestToPayTransfer) + + + alt + [if AuthenticateType is null] + + + [33] + Present payment terms + to Payer for acceptance + + + [34] + I accept the payment terms + + [if AuthenticateType is OTP] + + + alt + [if (Automatic generated OTP)] + + + + + [35] + Generate OTP + + + [36] + Present OTP to Payer + + + loop + [x retries] + + + [37] + PUT + /RequestToPayTransfer + + + accept quote = true + retries left = x + + + + [38] + GET +   + /authorizations/ + {transactionRequestID} + + + + [39] + GET +   + /authorizations/ + {transactionRequestID} + + + [40] + GET +   + /auth/{authtype}/{requestToPayId} + + + [41] + Get Payee to get + Payer to enter OTP + on POS + + + [42] + Enter OTP + + + [43] + return OTP + + + { + "otpValue": "string" + } + + + + [44] + PUT + /authorizations/{ID} + + + + [45] + PUT + /authorizations/{ID} + + + [46] + synchronous return +   + POST + /requestToPayTransfer/ + {requestToPayTransactionId} + + + + + [47] + Validate OTP + + + alt + [if can proceed with transfer] + + + + + [48] + Reserve funds against + Payer's account + + + [49] + PUT +   + /requestToPayTransfer/ + {requestToPayTransactionId} + + + + [50] + POST + /transfers + + + + [51] + POST + /transfers + + + [52] + PUT + / + POST + /requestToPayTransfer/ + {requestToPayTransactionId} + return + + + [53] + Notify user + + + + [54] + PUT + /transfers + return fulfilment + + + + [55] + PUT + /transfers + + + [56] + POST +   + /newAPI + Notify payer of transfer + + + + + [57] + Commit transfer + to Payer's account + + + [58] + Notify Payer + + [if rejected] + + + [59] + return + + + + [60] + PUT +   + /requestToPayTransfer/ + {requestToPayTransactionId} + rejected + + + + [61] + PUT + /requestToPayTransfer/ + {requestToPayTransactionId} + rejected + + + + [62] + return rejected + + diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg new file mode 100644 index 000000000..c395e3caa --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-quotes-sequence.svg @@ -0,0 +1 @@ +Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payeetopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventsloop[for each transfer in bulk]alt[Bulk quotes supported][Bulk quotes NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventsPOST /bulkquotesProcess Trace HeadersInboundBulkQuotesRequestReceivedAcceptedProcessInboundBulkQuotesRequestUpdate the bulk state: RECEIVEDCheck if bulkQuotes supported by payeeSDKBulkQuotesRequestedUpdate the bulk state: PROCESSINGProcess outbound Trace HeadersPOST /bulkQuotesAcceptedPUT /bulkQuotesProcess inbound Trace HeadersSDKBulkQuotesCallbackReceivedAcceptedQuoteRequestedUpdate the individual state: QUOTES_PROCESSINGProcess outbound Trace HeadersPOST /quotesSynchronous responseProcess Inbound Trace HeadersQuotesResponseReceivedProcessQuotesResponseUpdate the individual state: QUOTES_SUCCESS / QUOTES_FAILEDQuotesResponseProcessedCheck the status of the remaining items in the bulkProcessInboundBulkQuotesRequestCompleteUpdate the bulk state: COMPLETEDInboundBulkQuotesRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkQuotes/{bulkQuoteId}AcceptedInboundBulkQuotesReponseSentProcessInboundBulkQuotesReponseSentUpdate bulk state "RESPONSE_SENT"Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payee \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg new file mode 100644 index 000000000..6deaf1f7a --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/inbound-bulk-transfers-sequence.svg @@ -0,0 +1 @@ +Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payeetopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-command-eventstopic-sdk-domain-eventsloop[for each transfer in bulk]alt[Bulk transfers supported][Bulk transfers NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-command-eventstopic-sdk-domain-eventsloop[for each transfer in bulk]alt[Bulk transfers supported][Bulk transfers NOT supported]topic-sdk-inbound-command-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-domain-eventstopic-sdk-inbound-command-eventsalt[bulkStatus == 'ACCEPTED']POST /bulkTransfersProcess Trace HeadersInboundBulkTransfersRequestReceivedAcceptedProcessInboundBulkTransfersRequestUpdate the bulk state: RECEIVEDCheck if bulkQuotes supported by payeeSDKBulkTransfersRequestedUpdate the bulk state: PROCESSINGProcess outbound Trace HeadersPOST /bulkTransfersAcceptedPUT /bulkTransfersProcess inbound Trace HeadersSDKBulkTransfersCallbackReceivedAcceptedTransferRequestedUpdate the individual state: TRANSFERS_PROCESSINGProcess outbound Trace HeadersPOST /transfersSynchronous ResponseProcess Inbound Trace HeadersTransfersCallbackReceivedProcessTransfersCallbackUpdate the individual state: TRANSFERS_SUCCESS / TRANSFERS_FAILEDTransfersCallbackProcessedCheck the status of the remaining items in the bulkProcessInboundBulkTransfersRequestCompleteUpdate the bulk state: COMPLETED?InboundBulkTransfersRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkTransfers/{bulkTransferId}AcceptedInboundBulkTransfersResponseSentProcessInboundBulkTransfersResponseSentUpdate bulk state "RESPONSE_SENT"Check bulkStatusPATCH /bulkTransfers/{bulkTransferId}AcceptedProcess Trace HeadersInboundBulkTransfersPatchRequestReceivedAcceptedProcessInboundBulkTransfersPatchRequestUpdate the bulk state: PATCH_RECEIVEDCheck if bulkTransfers supported by payeeSDKBulkTransfersPatchRequestedUpdate the bulk state: PATCH_PROCESSINGProcess outbound Trace HeadersPATCH /bulkTransfers/{bulkTransferId}AcceptedResponse to Patch /bulkTransfersProcess inbound Trace HeadersSDKBulkTransfersPatchCallbackReceivedAcceptedTransfersPatchRequestedUpdate the individual state: TRANSFERS_PATCH_PROCESSINGProcess outbound Trace HeadersPATCH /transfers/{transferId}AcceptedProcess Inbound Trace HeadersTransfersPatchCallbackReceivedAcceptedProcessTransfersPatchCallbackUpdate the individual state: TRANSFERS_PATCH_SUCCESS / TRANSFERS_PATCH_FAILEDTransfersPatchCallbackProcessedCheck the status of the remaining items in the bulkProcessInboundBulkTransfersPatchRequestCompleteUpdate the bulk state: COMPLETEDInboundBulkTransfersPatchRequestProcessedUpdate the bulk state: RESPONSE_PROCESSINGProcess Outbound Trace HeadersPUT /bulkTransfers/{bulkTransferId}AcceptedInboundBulkTransfersPatchResponseSentProcessInboundBulkTransfersPatchResponseSentUpdate bulk state "PATCH_RESPONSE_SENT"Mojaloop SwitchSDK FSPIOP APISDK Inbound Domain Event HandlerSDK Inbound Command Event HandlerSDK Backend APICore Connector Payee \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg new file mode 100644 index 000000000..d611c2057 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/outbound-sequence.svg @@ -0,0 +1 @@ +Core ConnectorSDK Backend APISDK Outbound Domain Event HandlerSDK Outbound Command Event HandlerSDK FSPIOP APIMojaloop Switchtopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventsalt[party info already exists][party info doesn't exist]topic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventsloop[Party Lookup per transfer]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsalt[autoAcceptParty == false][autoAcceptParty == true (In future we can make this optional and an external service can handle this)]loop[for each transfer in bulk]topic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[through items in batch]topic-sdk-outbound-domain-eventsloop[BulkQuotes requests per batch]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[for each individual transfer in bulk]topic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[for each individual transfer in bulk]topic-sdk-outbound-domain-eventsalt[autoAcceptQuote == false][autoAcceptQuote == true]topic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsloop[through items in batch]topic-sdk-outbound-domain-eventsloop[BulkTransfers requests per each batch and include only items with AGREEMENT_ACCEPTED]topic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-domain-eventstopic-sdk-outbound-command-eventsSDKBulkRequest1Scheme Validation2Process Trace Headers3SDKOutboundBulkRequestReceived4Accepted5ProcessSDKOutboundBulkRequest6Store initial data into redis (Generate UUIDs and map to persistent model, break the JSON into smaller parts)7Update global state "RECEIVED"8SDKOutboundBulkPartyInfoRequested9ProcessSDKOutboundBulkPartyInfoRequest10Update global state "DISCOVERY_PROCESSING"11Update the global state to DISCOVERY_RECEIVED12PartyInfoCallbackReceived13Update the party request14PartyInfoRequested (includes info for SDK for making a party call)15Set individual state: DISCOVERY_PROCESSING16Process outbound Trace Headers17GET /parties18PUT /parties19Process Inbound Trace Headers20PartyInfoCallbackReceived21ProcessPartyInfoCallback22Update the individual state: DISCOVERY_SUCCESS / DISCOVERY_FAILED23Update the party response24PartyInfoCallbackProcessed25Check the status of the remaining items in the bulk26Update global state "DISCOVERY_COMPLETED"27SDKOutboundBulkPartyInfoRequestProcessed28check options.autoAcceptParty in redis29SDKOutboundBulkAcceptPartyInfoRequested30Update global state "DISCOVERY_ACCEPTANCE_PENDING"31Process outbound Trace Headers32PUT /bulkTransactions/{bulkTransactionId}33Accepted34PUT /bulkTransactions/{bulkTransactionId}35Process inbound Trace Headers36SDKOutboundBulkAcceptPartyInfoReceived37Accepted38ProcessSDKOutboundBulkAcceptPartyInfo39SDKOutboundBulkAutoAcceptPartyInfoRequested40Create SDKOutboundBulkAcceptPartyInfo with acceptParty=true for individual items with DISCOVERY_SUCCESS state41ProcessSDKOutboundBulkAcceptPartyInfo42Update the individual state: DISCOVERY_ACCEPTED / DISCOVERY_REJECTED43Update global state "DISCOVERY_ACCEPTANCE_COMPLETED"44SDKOutboundBulkAcceptPartyInfoProcessed45ProcessSDKOutboundBulkQuotesRequest46Update global state "AGREEMENT_PROCESSING"47Create bulkQuotes batches from individual items with DISCOVERY_ACCEPTED state per FSP and maxEntryConfigPerBatch48Update bulkQuotes request49BulkQuotesRequested50Update the batch state: AGREEMENT_PROCESSING51Process outbound Trace Headers52POST /bulkQuotes53Accepted54PUT /bulkQuotes55Process inbound Trace Headers56BulkQuotesCallbackReceived57Accepted58ProcessBulkQuotesCallback59Update the batch state: AGREEMENT_COMPLETED / AGREEMENT_FAILED60Update the individual state: AGREEMENT_SUCCESS / AGREEMENT_FAILED61Update the quote response62BulkQuotesCallbackProcessed63Check the status of the remaining items in the bulk64Update global state "AGREEMENT_COMPLETED"65SDKOutboundBulkQuotesRequestProcessed66check autoAcceptQuote67SDKOutboundBulkAcceptQuoteRequested68Update global state "AGREEMENT_ACCEPTANCE_PENDING"69Process outbound Trace Headers70PUT /bulkTransactions/{bulkTransactionId}71Accepted72PUT /bulkTransactions/{bulkTransactionId}73Process inbound Trace Headers74SDKOutboundBulkAcceptQuoteReceived75Accepted76ProcessSDKOutboundBulkAcceptQuote77Update the individual state: AGREEMENT_ACCEPTED / AGREEMENT_REJECTED78Update global state "AGREEMENT_ACCEPTANCE_COMPLETED"79SDKOutboundBulkAcceptQuoteProcessed80SDKOutboundBulkAutoAcceptQuoteRequested81ProcessSDKOutboundBulkAutoAcceptQuote82Check fee limits83Update the individual state: AGREEMENT_ACCEPTED / AGREEMENT_REJECTED84Update global state "AGREEMENT_ACCEPTANCE_COMPLETED"85SDKOutboundBulkAutoAcceptQuoteProcessed86ProcessSDKOutboundBulkTransfersRequest87Update global state "TRANSFERS_PROCESSING"88Update the request89BulkTransfersRequested90Update the batch state: TRANSFERS_PROCESSING91Process outbound Trace Headers92POST /bulkTransfers93Accepted94PUT /bulkTransfers95Process inbound Trace Headers96BulkTransfersCallbackReceived97Accepted98ProcessBulkTransfersCallback99Update the batch state: TRANSFERS_COMPLETED / TRANSFERS_FAILED100Update the individual state: TRANSFERS_SUCCESS / TRANSFERS_FAILED101Update the transfer response102BulkTransfersCallbackProcessed103Check the status of the remaining items in the bulk104Update global state "TRANSFERS_COMPLETED"105SDKOutboundBulkTransfersRequestProcessed106PrepareSDKOutboundBulkResponse107Build response from redis state108SDKOutboundBulkResponsePrepared109Update global state "RESPONSE_PROCESSING"110Process outbound Trace Headers111Send the response as callback112Accepted113SDKOutboundBulkResponseSent114ProcessSDKOutboundBulkResponseSent115Update global state "RESPONSE_SENT"116SDKOutboundBulkResponseSentProcessed117Core ConnectorSDK Backend APISDK Outbound Domain Event HandlerSDK Outbound Command Event HandlerSDK FSPIOP APIMojaloop Switch \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg new file mode 100644 index 000000000..998a7145b --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg @@ -0,0 +1,4 @@ + + + +
    Payee
    Core
    Payee...
    POST /transactionRequest
    POST /transactionRequest
    (Add authenticationType)
    (Add authenticationType)
    PUT /transactionRequest
    PUT /transactionRequest
    Payer SDK
    Payer...
    Payee SDK
    Payee...
    POST /transactionRequest
    POST /transactionRequest
    PUT /transactionRequest
    PUT /transactionRequest
    Switch
    Switch
    Payer
    Core
    Payer...
    POST /RequestToPay
    POST /RequestToPay
    (Add authenticationType,
    rename homeTxId to homeR2PTrxId
    )
    (Add authenticationType,...
    POST /transactionRequest
    POST /transactionRequest
    RES: POST /RequestToPay
    RES: POST /RequestToPay
    POST /quotes
    POST /quotes
    POST /quotes
    POST /quotes
    POST /quotesrequest
    POST /quotesrequest
    (Add homeR2PTrxId)
    (Add homeR2PTrxId)
    PUT /quotes
    PUT /quotes
    PUT /quotes
    PUT /quotes
    PUT /RequestToPay
    PUT /RequestToPay
    RES: PUT /RequestToPay
    RES: PUT /RequestToPay
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    (Add authResponse)
    (Add authResponse)
    RES: POST /transactionRequest
    RES: POST /transactionRequest
    (Add homeR2PTxId (optional),
    rename transferAmount to 
    transactionRequestState 
    )
    (Add homeR2PTxId (optional),...
    POST /requestToPayTransfer
    POST /requestToPayTransfer
    (Add homeR2PTxId,
    Add authenticationType,
    Rename rTPayTrxId to tReqId)
    (Add homeR2PTxId,...
    GET /authorizations
    GET /authorizations
    (authenticationType hardcoded,
    retriesLeft hardcoded
    )
    (authenticationType hardcoded,...
    Accept payment and terms
    and generate OTP
    Accept pay...
    GET /authorizations
    GET /authorizations
    GET /otp
    GET /otp
    (rename rtpId to
    tRequestId,
    Add homeR2PTrxId,
    Add retriesLeft
    )
    (rename rtpId to...
    PUT /authorizations
    PUT /authorizations
    PUT /authorizations
    PUT /authorizations
    If OTP
    If OTP
    RES: POST /requestToPayTransfer
    RES: POST /requestToPayTransfer
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (accept quote,
    Add retriesLeft)
    (accept quote,...
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (accept quote/auth)
    (accept quote/auth)
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    Payer
    Payer
    POST /transfers
    POST /transfers
    POST /transfers
    POST /transfers
    PUT /transfers
    PUT /transfers
    PUT /transfers
    PUT /transfers
    Payer provides OTP
    Payer prov...
    Payer
    Payer
    POST /transfers
    POST /transfers
    (Add transactionRequestId, 
    Add homeR2PTrxId
    )
    (Add transactionRequestId,...
    Validate Payer Details
    Validate P...
    Payer
    Payer
    Calculate fees and set terms.
    Present to Payer to validate.
    Calculate...
    Payer
    Payer
    PoS - Point of Sale device at Merchant
    PoS - Point of Sale devic...
    Payee PoS
    Payee PoS
    Payee Pos
    Payee Pos
    Payee PoS
    Payee PoS
    PUT /parties
    PUT /parties
    GET /parties
    GET /parties
    PUT /Parties
    PUT /Parties
    GET /parties
    GET /parties
    GET /parties
    GET /parties
    PoS displays
    Payment Confirmation
    PoS displa...
    Payer
    Payer
    Payee PoS
    Payee PoS
    Validate RTP
    Validate R...
    Initiate RTP with
    AuthType
    Initiate R...
    Validate OTP
    Validate O...
    Retry on
    OTP Failure
    Retry...
    PUT /requestToPayTransfer
    PUT /requestToPayTransfer
    (reject)
    (reject)
    RES: PUT /requestToPayTransfer
    RES: PUT /requestToPayTransfer
    PUT /transactionRequest
    PUT /transactionRequest
    (rejected state)
    (rejected state)
    PUT /RequestToPay
    PUT /RequestToPay
    (rejected state)
    (rejected state)
    If Rejected
    If Rejected
    PUT /transactionRequest
    PUT /transactionRequest
    (rejected state)
    (rejected state)
    If Accepted
    If Accepted
    Payer Receives
    Payment Confirmation
    Payer Rece...
    Payer
    Payer
    Payer Receives
    Rejection Notification
    Payer Rece...
    Payer
    Payer
    PoS displays
    Rejection Notification
    PoS displa...
    Payer
    Payer
    Payee PoS
    Payee PoS
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/README.md b/docs/technical/technical/sdk-scheme-adapter/usage/README.md new file mode 100644 index 000000000..46eca6c75 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/usage/README.md @@ -0,0 +1,44 @@ +# Overview of tested SDK usage scenarios +A scheme adapter is a service that interfaces between a Mojaloop API compliant switch and a DFSP backend platform that does not natively implement the Mojaloop API. + +The API between the scheme adapter and the DFSP backend is synchronous HTTP while the interface between the scheme adapter and the switch is the native Mojaloop API. + +This document provides different ways of setups that a DFSP can test using the scheme adapter. + +# Scenarios +There are number of scenarios those we tested and documented as follows. + +* [[Scheme Adapter + Mock DFSP Backend] -> [Scheme Adapter + Mojaloop Simulator]](./scheme-adapter-to-scheme-adapter/README.md) +* [[Scheme Adapter + Mock DFSP Backend] -> [Local K8S cluster]](./scheme-adapter-and-local-k8s/README.md) +* [[Scheme Adapter + Mojaloop Simulator] -> [Public hosted WSO2 enabled Mojaloop Switch]](./scheme-adapter-and-wso2-api-gateway/README.md) + +## [Scheme Adapter + Mock DFSP Backend] -> [Scheme Adapter + Mojaloop Simulator] + +The scheme adapter can be used in combination with the already implemented mock backends "Mock DFSP Backend" and "Mojaloop Simulator". The below are the links for the repositories. + +https://github.com/mojaloop/sdk-mock-dfsp-backend.git + +https://github.com/mojaloop/mojaloop-simulator.git + +The idea is to combine scheme adapter with mock DFSP backend on oneside and with mojaloop simulator on another side. Consider one side is payer dfsp and another side is payee dfsp. By following this example, you can send and receive funds from one DFSP to another. + +Please [click here](./scheme-adapter-to-scheme-adapter/README.md) for the documentation. + +![SchemeAdapterToSchemeAdapter](./scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png) + +## [Scheme Adapter + Mock DFSP Backend] -> [Local K8S cluster] + +Then if we want to include a switch in between the DFSPs, we can simulate that environment using a local K8S cluster. Please follow the onboarding documentation of local K8S cluster here (https://mojaloop.io/documentation/deployment-guide/). + +Please [click here](./scheme-adapter-and-local-k8s/README.md) for the documentation. + +![SchemeAdapterAndK8S](./scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png) + +## [Scheme Adapter + Mojaloop Simulator] -> [Public hosted WSO2 enabled Mojaloop Switch] + +If you have access to the WSO2 Mojaloop API, you can test that by the following documentation. In the above two scenarios, we didn't use token authentication and SSL encryption capabilities of scheme adapter. We are going to use those capabilities in this section. + +Please [click here](./scheme-adapter-and-wso2-api-gateway/README.md) for the documentation. + + +![SchemeAdapterAndWSO2APIGateway](./scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png) diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md rename to docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json new file mode 100644 index 000000000..eddcac266 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json @@ -0,0 +1,1012 @@ +{ + "id": "a9937c8b-0281-4128-8b53-1f1f913ff2aa", + "name": "Mojaloop-Local", + "values": [ + { + "key": "payeefsp", + "value": "payeefsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfsp", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiration", + "value": "2019-05-27T15:44:53.292Z", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transactionRequestId", + "value": "25a00155-c777-4629-a6b7-61cf0d16f499", + "enabled": true + }, + { + "key": "transferDate", + "value": "Fri, 21 Dec 2018 12:17:01 GMT", + "enabled": true + }, + { + "key": "currentTimestamp", + "value": "2018-12-06T17:09:56.386Z", + "enabled": true + }, + { + "key": "quoteDate", + "value": "Fri, 21 Dec 2018 12:19:49 GMT", + "enabled": true + }, + { + "key": "quoteExpiration", + "value": "2018-11-08T21:31:00.534+01:00", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_MOJALOOP", + "value": "localhost:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_MOJALOOP", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_LEDGER", + "value": "http://central-ledger.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_ADMIN", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ML_API", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_ML_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_SETTLEMENT", + "value": "http://central-settlement.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_SETTLEMENT", + "value": "/v1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_PREPARE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_QUOTE\n", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TIMESTAMP", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_PREPARE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSACTION_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiredExpiration", + "value": "2018-08-31T15:26:01.870Z", + "enabled": true + }, + { + "key": "condition", + "value": "HOr22-H3AfTDHrSkPjJtVPRdKouuMkDXTR4ejlQa8Ks", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "fulfilment", + "value": "uU0nuZNNPgilLlLX2n2r-sSE7-N6U4DukIj3rOLvzek", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR", + "value": "http://moja-simulator.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "SCHEME_ADAPTER_ENDPOINT", + "value": "http://host.docker.internal:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "quoteId", + "value": "ddaa67b3-5bf8-45c1-bfcf-1e8781177c37", + "enabled": true + }, + { + "key": "ilpPacket", + "value": "AQAAAAAAAADIEHByaXZhdGUucGF5ZWVmc3CCAiB7InRyYW5zYWN0aW9uSWQiOiIyZGY3NzRlMi1mMWRiLTRmZjctYTQ5NS0yZGRkMzdhZjdjMmMiLCJxdW90ZUlkIjoiMDNhNjA1NTAtNmYyZi00NTU2LThlMDQtMDcwM2UzOWI4N2ZmIiwicGF5ZWUiOnsicGFydHlJZEluZm8iOnsicGFydHlJZFR5cGUiOiJNU0lTRE4iLCJwYXJ0eUlkZW50aWZpZXIiOiIyNzcxMzgwMzkxMyIsImZzcElkIjoicGF5ZWVmc3AifSwicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7fX19LCJwYXllciI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjI3NzEzODAzOTExIiwiZnNwSWQiOiJwYXllcmZzcCJ9LCJwZXJzb25hbEluZm8iOnsiY29tcGxleE5hbWUiOnt9fX0sImFtb3VudCI6eyJjdXJyZW5jeSI6IlVTRCIsImFtb3VudCI6IjIwMCJ9LCJ0cmFuc2FjdGlvblR5cGUiOnsic2NlbmFyaW8iOiJERVBPU0lUIiwic3ViU2NlbmFyaW8iOiJERVBPU0lUIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJpbml0aWF0b3JUeXBlIjoiQ09OU1VNRVIiLCJyZWZ1bmRJbmZvIjp7fX19", + "enabled": true + }, + { + "key": "payerFspId", + "value": "3", + "enabled": true + }, + { + "key": "payerFspAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspId", + "value": "4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspAccountId", + "value": "5", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "openWindowID", + "value": 1, + "enabled": true + }, + { + "key": "newOpenWindowID", + "value": 2, + "enabled": true + }, + { + "key": "closedWindowID", + "value": 1, + "enabled": true + }, + { + "key": "settlementId", + "value": 1, + "enabled": true + }, + { + "key": "expectedFullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "expectedFirstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "expectedLastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "expectedDOB", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "pathfinderMSISDN", + "value": "27713803912", + "enabled": true + }, + { + "key": "fullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "firstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "lastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "dob", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "HOST_ML_API_ADAPTER", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "dateHeader", + "value": "Thu, 24 Jan 2019 10:22:12 GMT", + "enabled": true + }, + { + "key": "participant", + "value": "testfsp4", + "enabled": true + }, + { + "key": "payerfspBeforePosition", + "value": -1782, + "enabled": true + }, + { + "key": "HOST_SWITCH_TRANSFERS", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_PATH_SWITCH_TRANSFERS", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR_K8S_CLUSTER", + "value": "http://moja-simulator", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payeefspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "blockTransferAmount", + "value": 7494, + "enabled": true + }, + { + "key": "payeeNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "transferAmount", + "value": "99", + "enabled": true + }, + { + "key": "payeefspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransferBeforeExpiry", + "value": 1596, + "enabled": true + }, + { + "key": "fspName", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "settlementAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "reportEndDate", + "value": "2018-10-31", + "enabled": true + }, + { + "key": "reportFSPID", + "value": "payerfsp", + "enabled": true + }, + { + "key": "reportStartDate", + "value": "2018-10-01", + "enabled": true + }, + { + "key": "transactionId", + "value": "97f3f215-37a0-4755-a17c-c39313aa2f98", + "enabled": true + }, + { + "key": "payerfspSettlementAccountId", + "value": 8, + "enabled": true + }, + { + "key": "payeefspSettlementAccountId", + "value": 4, + "enabled": true + }, + { + "key": "fundsInPrepareTransferId", + "value": "b79a979e-9605-4db4-a052-85bc948be414", + "enabled": true + }, + { + "key": "HUBOPERATOR_BEARER_TOKEN", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hub_operator", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefspNetSettlementAmount", + "value": -198, + "enabled": true + }, + { + "key": "payerfspNetSettlementAmount", + "value": 198, + "enabled": true + }, + { + "key": "fundsInPrepareAmount", + "value": 500, + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalance", + "value": -4800, + "enabled": true + }, + { + "key": "hubReconAccountBalance", + "value": 4800, + "enabled": true + }, + { + "key": "payerfspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "payeefspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "fundsOutPrepareTransferId", + "value": "f60c555f-72a7-44c7-a3a8-1f4a4df4b100", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareAmount", + "value": "", + "enabled": true + }, + { + "key": "payerfspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionAccountId", + "value": 3, + "enabled": true + }, + { + "key": "payerfspPositionAccountId", + "value": 7, + "enabled": true + }, + { + "key": "testfsp1", + "value": "testfsp1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2", + "value": "testfsp2", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountId", + "value": 25, + "enabled": true + }, + { + "key": "testfsp1SettlementAccountId", + "value": 26, + "enabled": true + }, + { + "key": "testfsp2PositionAccountId", + "value": 29, + "enabled": true + }, + { + "key": "testfsp2SettlementAccountId", + "value": 30, + "enabled": true + }, + { + "key": "testfsp1Id", + "value": "13", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2Id", + "value": "14", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitTransferId", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "transfer_ID", + "value": "e7b43799-e69e-4578-bd26-2a4b9a22e92e", + "enabled": true + }, + { + "key": "get_transfer_ID", + "value": "7e19ae5f-7db6-4612-ab99-7538a56b4c25", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "env_prefix", + "value": "test", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "validCondition", + "value": "GRzLaTP7DJ9t4P-a_BA0WA9wzzlsugf00-Tn6kESAfM", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "validFulfillment", + "value": "UNlJ98hZTY_dsw0cAqw4i_UN3v4utt7CZFB4yfLbVFA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "currency", + "value": "USD", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfspId3", + "value": "15", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfspId4", + "value": "16", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "invalidFulfillment", + "value": "_3cco-YN5OGpRKVWV3n6x6uNpBTH9tYUdOYmHA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "completedTimestamp", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionAfterPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveTransferId", + "value": "", + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "fspiop-signature", + "value": "{\"signature\":\"iU4GBXSfY8twZMj1zXX1CTe3LDO8Zvgui53icrriBxCUF_wltQmnjgWLWI4ZUEueVeOeTbDPBZazpBWYvBYpl5WJSUoXi14nVlangcsmu2vYkQUPmHtjOW-yb2ng6_aPfwd7oHLWrWzcsjTF-S4dW7GZRPHEbY_qCOhEwmmMOnE1FWF1OLvP0dM0r4y7FlnrZNhmuVIFhk_pMbEC44rtQmMFv4pm4EVGqmIm3eyXz0GkX8q_O1kGBoyIeV_P6RRcZ0nL6YUVMhPFSLJo6CIhL2zPm54Qdl2nVzDFWn_shVyV0Cl5vpcMJxJ--O_Zcbmpv6lxqDdygTC782Ob3CNMvg\\\",\\\"protectedHeader\\\":\\\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1VUkkiOiIvdHJhbnNmZXJzIiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUE9TVCIsIkZTUElPUC1Tb3VyY2UiOiJPTUwiLCJGU1BJT1AtRGVzdGluYXRpb24iOiJNVE5Nb2JpbGVNb25leSIsIkRhdGUiOiIifQ\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3", + "value": "testfsp3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4", + "value": "testfsp4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payeefsp_fspiop_signature", + "value": "{\"signature\":\"abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess\",\"protectedHeader\":\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1Tb3VyY2UiOiJwYXllZWZzcCIsIkZTUElPUC1EZXN0aW5hdGlvbiI6InBheWVyZnNwIiwiRlNQSU9QLVVSSSI6Ii90cmFuc2ZlcnMvZDY3MGI1OTAtZjc5ZC00YWU5LThjNmUtMTVjZjZjNWMzODk5IiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUFVUIiwiRGF0ZSI6IiJ9\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_SERVICE", + "value": "http://account-lookup-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_ADMIN", + "value": "http://account-lookup-service-admin.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_QUOTING_SERVICE", + "value": "http://quoting-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefsp_signature", + "value": "abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess", + "type": "text", + "description": "", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2019-05-30T00:29:41.827Z", + "_postman_exported_using": "Postman/6.7.4" +} diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json new file mode 100644 index 000000000..70e2b3599 --- /dev/null +++ b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json @@ -0,0 +1,1072 @@ +{ + "info": { + "_postman_id": "52f405c0-bec3-4915-8c43-c250208623aa", + "name": "OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup", + "description": "Author: Sridevi Miriyala\nPurpose: Used to add new FSP and relevant Callback Information", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "FSP Onboarding", + "item": [ + { + "name": "safsp (p2p transfers)", + "item": [ + { + "name": "Add payerfsp - TRANSFERS", + "event": [ + { + "listen": "test", + "script": { + "id": "76c222f4-969b-4081-b4d7-133ebe48f50f", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\": \"safsp\",\"currency\": \"{{currency}}\"}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants" + ] + } + }, + "response": [] + }, + { + "name": "Add initial position and limits - payerfsp", + "event": [ + { + "listen": "test", + "script": { + "id": "d767079d-a9dd-401a-8d6a-5f94654c4259", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"currency\": \"{{currency}}\",\n\t\"limit\": {\n\t \"type\": \"NET_DEBIT_CAP\",\n\t \"value\": 1000000\n\t},\n\t\"initialPosition\": 0\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/initialPositionAndLimits", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "initialPositionAndLimits" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES GET", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_GET\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - QUOTES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_QUOTES\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER POST", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_POST\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER ERROR", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "9. Set Endpoint-NET_DEBIT_CAP_ADJUSTMENT_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "83984619-0430-4a4c-87ec-671bf97894de", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_ADJUSTMENT_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Set Endpoint-SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "16f8d261-3f2d-470b-986b-c8e23602605b", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "DFSP Endpoint-NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "67082524-b658-4f1c-90c4-af6fc24adb3e", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Record Funds In - payerfsp ", + "event": [ + { + "listen": "test", + "script": { + "id": "802139ed-ec95-40f8-99a7-d88f0e77e49d", + "exec": [ + "pm.test(\"Status code is 202\", function () {", + " pm.response.to.have.status(202);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "461d34bc-33f6-4031-bbc4-b26489ff1953", + "exec": [ + "var uuid = require('uuid');", + "var generatedUUID = uuid.v4();", + "pm.environment.set('fundsInPrepareTransferId', generatedUUID);", + "pm.environment.set('fundsInPrepareAmount', 5000);", + "", + "", + "const payerfspGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/'+pm.environment.get(\"payerfsp\")+'/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"hub_operator\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(payerfspGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'SETTLEMENT') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"payerfspSettlementAccountId\",jsonData[i].id)", + " pm.environment.set(\"payerfspSettlementAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "", + "const hubGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/hub/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"payerfsp\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(hubGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'HUB_RECONCILIATION') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"hubReconAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{payerfsp}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"transferId\": \"{{fundsInPrepareTransferId}}\",\n \"externalReference\": \"string\",\n \"action\": \"recordFundsIn\",\n \"reason\": \"string\",\n \"amount\": {\n \"amount\":\"{{fundsInPrepareAmount}}\" ,\n \"currency\": \"{{currency}}\"\n },\n \"extensionList\": {\n \"extension\": [\n {\n \"key\": \"string\",\n \"value\": \"string\"\n }\n ]\n }\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/accounts/{{payerfspSettlementAccountId}}", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "accounts", + "{{payerfspSettlementAccountId}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "e5ffaeb6-241f-4b10-af63-b52b064ff44f", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "efb91eb5-c6c5-460c-89b0-a424f39dcf9a", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "a29d64a2-7a89-4cc9-ac33-2a630283471d", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "7bcf1b8c-ce85-4b11-ac83-899cc81ce501", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "402cb439-04ee-4add-9a65-f4b3f9dafa58", + "type": "text/javascript", + "exec": [ + "", + "// Ensure that the following variables are not set in the environment", + "// This is a fix for the following issue: https://github.com/mojaloop/project/issues/903", + "// This will ensure that templates are not replaced in the endpoint configs:", + "pm.environment.unset('partyIdType')", + "pm.environment.unset('partyIdentifier')", + "pm.environment.unset('requestId')", + "pm.environment.unset('transferId')", + "", + "pm.globals.unset('partyIdType')", + "pm.globals.unset('partyIdentifier')", + "pm.globals.unset('requestId')", + "pm.globals.unset('transferId')" + ] + } + }, + { + "listen": "test", + "script": { + "id": "e73fb24a-c94a-4551-ac31-fb7ceb250579", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png new file mode 100644 index 000000000..4d6282c3c Binary files /dev/null and b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png differ diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md rename to docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png new file mode 100644 index 000000000..206d31d45 Binary files /dev/null and b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png differ diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md rename to docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md diff --git a/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png new file mode 100644 index 000000000..35702294c Binary files /dev/null and b/docs/technical/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png differ diff --git a/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png new file mode 100644 index 000000000..736a5190c Binary files /dev/null and b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png differ diff --git a/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml new file mode 100644 index 000000000..a87421d97 --- /dev/null +++ b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.puml @@ -0,0 +1,107 @@ +@startuml dependency-vulnerability-management-process +!theme cerulean + +skinparam ActivityBackgroundColor #f0f0f0 +skinparam ActivityBorderColor #333333 +skinparam ArrowColor #333333 +skinparam backgroundColor white +skinparam ActivityFontColor black +skinparam ActivityFontSize 14 +skinparam noteFontColor black +skinparam ArrowFontColor black +skinparam PartitionFontColor #000000 +skinparam PartitionFontStyle bold +skinparam PartitionBorderColor #333333 +skinparam PartitionBackgroundColor #f8f8f8 + +title Dependency Vulnerability Management Process + +start + +partition "Vulnerability Detection Tools" { + :Identify Vulnerability; + fork + :GitHub Dependabot Alerts; + fork again + :npm run audit:check; + note right: audit-ci.jsonc with allowlist + fork again + :Grype Image Scan; + note right: .grype.yaml with ignore section + end fork +} + +partition "Triage Process" { + :Triage Vulnerability; + :Assess Severity Level; + fork + :Critical: 1-3 days; + note right #FF6666: Immediate attention + fork again + :High: 30 days; + note right #FFCC66: High priority + fork again + :Medium: 60 days; + note right #FFFF66: Medium priority + fork again + :Low: 90 days; + note right #99FF99: Low priority + end fork + :Take action based on severity level\nand fix date targets; +} + +partition "Update Process" { + :Select Single Module to Update; + :Update package.json; + :Run Tests; + if (Tests Pass?) then (Yes) + :Create Pull Request; + else (No) + if (Cannot Fix?) then (Yes) + fork + :Update audit-ci.jsonc; + note right #F9E0FF: For npm issues + fork again + :Update .grype.yaml; + note right #F9E0FF: For container issues + end fork + :Create Pull Request; + else (No) + :Adjust Update; + note right #F9E0FF + Consider Alternative Solutions + Contact Package Maintainer + end note + :Run Tests Again; + endif + endif + :Code Review Process; + if (Review Result) then (Approved) + :Merge PR; + else (Changes Requested) + :Update PR; + endif +} + +partition "CI/CD" { + :CI/CD Pipeline; + :Security Checks; + fork + :audit-ci Check; + fork again + :Grype Scan; + end fork + if (Checks Pass?) then (Yes) + :Release/Publish; + else (No) + :Fix Security Issues; + endif +} + +if (More Vulnerabilities?) then (Yes) + :Return to Select Module; +else (No) + stop +endif + +@enduml \ No newline at end of file diff --git a/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg new file mode 100644 index 000000000..0ef88f1e5 --- /dev/null +++ b/docs/technical/technical/security/assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.svg @@ -0,0 +1,305 @@ + + Dependency Vulnerability Management Process + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dependency Vulnerability Management Process + + + + Vulnerability Detection Tools + + Identify Vulnerability + + + GitHub Dependabot Alerts + + + audit-ci.jsonc with allowlist + + npm run audit:check + + + .grype.yaml with ignore section + + Grype Image Scan + + + + Triage Process + + Triage Vulnerability + + Assess Severity Level + + + + Immediate attention + + Critical: 1-3 days + + + High priority + + High: 30 days + + + Medium priority + + Medium: 60 days + + + Low priority + + Low: 90 days + + + Take action based on severity level + and fix date targets + + + Update Process + + Select Single Module to Update + + Update package.json + + Run Tests + + Tests Pass? + Yes + No + + Create Pull Request + + Cannot Fix? + Yes + No + + + + For npm issues + + Update audit-ci.jsonc + + + For container issues + + Update .grype.yaml + + + Create Pull Request + + + Consider Alternative Solutions + Contact Package Maintainer + + Adjust Update + + Run Tests Again + + + + Code Review Process + + Review Result + Approved + Changes Requested + + Merge PR + + Update PR + + + + CI/CD + + CI/CD Pipeline + + Security Checks + + + audit-ci Check + + Grype Scan + + + Checks Pass? + Yes + No + + Release/Publish + + Fix Security Issues + + + Return to Select Module + + Yes + More Vulnerabilities? + No + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png new file mode 100644 index 000000000..551ea6515 Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/audit-check-script.png differ diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png new file mode 100644 index 000000000..4c14b2661 Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png differ diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png new file mode 100644 index 000000000..a77a907b2 Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png differ diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png new file mode 100644 index 000000000..d9d3a289b Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png differ diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png new file mode 100644 index 000000000..3a35c25b3 Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-id-allowed.png differ diff --git a/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png new file mode 100644 index 000000000..2c313578f Binary files /dev/null and b/docs/technical/technical/security/assets/screenshots/vulnerabilityManagement/severity-level-allowed.png differ diff --git a/docs/technical/technical/security/dependency-vulnerability-management.md b/docs/technical/technical/security/dependency-vulnerability-management.md new file mode 100644 index 000000000..268e697e3 --- /dev/null +++ b/docs/technical/technical/security/dependency-vulnerability-management.md @@ -0,0 +1,613 @@ +# Mojaloop Dependency Vulnerability Management Guide + +This guide outlines the process for managing security vulnerabilities in dependencies of Mojaloop organization GitHub repositories . + +This guide focuses primarily on dependency vulnerabilities. For vulnerabilities discovered in Mojaloop's own code (rather than in dependencies), please email detailed information to security@mojaloop.io and follow the Coordinated Vulnerability Disclosure (CVD) policy. + +The Mojaloop CVD policy provides a structured process for reporting, validating, and remediating security vulnerabilities in Mojaloop code. It ensures responsible disclosure that balances the need to protect users while providing transparent information about security issues. The policy includes clear timelines for response, validation, remediation, and public disclosure, allowing the Mojaloop Security team to address vulnerabilities in a coordinated manner that minimizes risk to adopters and users of the software. + +## Table of Contents + +- [Executive Summary](#executive-summary) +- [Overview](#overview) +- [Quickstart Guide](#quickstart-guide) +- [Detailed Guide](#detailed-guide) + - [1. Understanding what is a Vulnerability and where to find them](#1-understanding-what-is-a-vulnerability-and-where-to-find-them) + - [2. ProcessFlow for Handling Dependency Vulnerability Updates](#2-processflow-for-handling-dependency-vulnerability-updates) + - [3. Practical Guide to package.json Updates](#3-practical-guide-to-packagejson-updates) + - [4. Code Review Best Practices for Security PRs](#4-code-review-best-practices-for-security-prs) + - [5. Developer Onboarding and Dependency Vulnerability Management Education](#5-developer-onboarding-and-dependency-vulnerability-management-education) + - [6. Continuous Improvement](#6-continuous-improvement) + - [7. Conclusion](#7-conclusion) +- [Tools and Resources](#tools-and-resources) +- [Related Documentation](#related-documentation) + +## Executive Summary + +This guide provides a structured approach for handling security vulnerabilities in dependencies of Mojaloop repositories. It addresses the current need for a standardized process that can help developers understand vulnerability reports (namely GitHub Dependabot alerts, results on npx audit and grype scans), implement proper fixes, and prioritize security updates across the codebase. + +## Overview + +Mojaloop's dependency vulnerability management process is designed to: +- Identify security vulnerabilities in dependencies and code +- Assess the impact and severity of vulnerabilities +- Prioritize remediation efforts +- Track and verify fixes +- Maintain security compliance + +## Quickstart Guide + +This quickstart provides essential steps for managing vulnerabilities in Mojaloop repositories without background information. For detailed explanations, see the comprehensive sections that follow. + +### 1. Detect Vulnerabilities + +- Run `npm run audit:check` to identify npm package vulnerabilities +- Check GitHub Dependabot alerts in the Security tab of your repository(if you have access to Security tab) +- Use Grype to scan container images, triggered automatically if using Mojaloop orb for CircleCI and report can be reviewed in CircleCI (if you have access to CircleCI) + +### 2. Assess and Prioritize + +- **Critical**: Fix within 1-3 business days +- **High**: Fix within 30 days +- **Medium**: Fix within 60 days +- **Low**: Fix within 90 days + +### 3. Fix Process + +1. Take action based on severity level and fix date targets +2. Select a single module to update +3. Update the vulnerable dependency in package.json +4. Run tests as intructed in repo's README to verify functionality +5. If tests pass, create a pull request +6. If tests fail and you cannot fix: + - Add to allowlist in audit-ci.jsonc (for npm packages) + - Add to ignore section in .grype.yaml (for container vulnerabilities) +7. Include complete fix vulnerability details in the PR + +### 4. PR Template + +```markdown +## Security Fix: [GHSA-ID or CVE-ID] + +### Vulnerability Details +- Severity: [Critical/High/Medium/Low] +- Affected Package: [package-name] +- Vulnerable Versions: [version range] +- Fixed Version: [version number] + +### Description +Brief description of the vulnerability and its potential impact. + +### Changes +- Updated [package-name] from [old-version] to [new-version] + +### Testing +- [X] Unit tests pass +- [X] Integration tests pass +- [X] Manual testing performed +``` + +### 5. Review and Merge + +- Ensure version update properly fixes the vulnerability +- Verify minimum changes to package.json +- Confirm all tests pass +- Check for unintended side effects +- Merge after approval + +## Detailed Guide + +The following sections provide comprehensive explanations, background information, and detailed procedures for vulnerability management in Mojaloop repositories. + +## 1. Understanding what is a Vulnerability and where to find them + +A vulnerability is identified by a Common Vulnerabilities and Exposures (CVE) id, which is a standardized identifier for publicly known security vulnerabilities. + +### Vulnerability Identifier Systems: CVE and GHSA + +#### CVE (Common Vulnerabilities and Exposures) +CVEs are standardized identifiers for publicly known cybersecurity vulnerabilities, maintained by the MITRE Corporation and funded by the U.S. Department of Homeland Security. Each CVE has a unique identifier in the format CVE-YYYY-NNNNN (year-number). + +#### GHSA (GitHub Security Advisory) +GHSA identifiers are GitHub-specific vulnerability identifiers used in the GitHub Advisory Database. They follow the format GHSA-XXXX-YYYY-ZZZZ, where X, Y, and Z are alphanumeric characters. + +#### Relationship Between CVE and GHSA +- A GHSA may reference one or more CVEs, as GitHub may consolidate multiple related vulnerabilities +- Not all GHSAs have corresponding CVEs, especially for newly discovered vulnerabilities +- GitHub often assigns a GHSA identifier before a CVE is assigned by MITRE +- Both systems describe the same vulnerabilities but may contain slightly different information: + - CVEs are the industry standard used across security tools and databases + - GHSAs often contain more ecosystem-specific information and may include remediation advice for GitHub users + +#### How Identifiers Appear Across Tools + +- **GitHub Dependabot Alerts**: Display both the GHSA and CVE identifiers (when a CVE is assigned) + + ![GitHub Dependabot Alerts List](./assets/screenshots/vulnerabilityManagement/gh-dependabot-alerts.png) + *Dependabot alerts view at GitHub Security* + + ![GitHub Dependabot Alert Details](./assets/screenshots/vulnerabilityManagement/gh-dependabot-alert.png) + *Detailed dependabot alert* + +- **npm run audit:check**: Results show GHSA identifiers for vulnerabilities + + ![Audit Check Script](./assets/screenshots/vulnerabilityManagement/audit-check-script.png) + *Execution of npm run audit:check script* + + ![Severity Level Allowed](./assets/screenshots/vulnerabilityManagement/severity-level-allowed.png) + *Increase vulnerability passing level to low, previous was moderate* + + ![Severity ID Allowed](./assets/screenshots/vulnerabilityManagement/severity-id-allowed.png) + *Allowlist vulnerability ID provided to ignore when running npm run audit:check* + +- **Grype Scan**: Displays vulnerabilities with GHSA identifiers + + ![Grype Scan Vulnerabilities](./assets/screenshots/vulnerabilityManagement/grype-scan-vulnerabilities-ci.png) + *Grype Scan vulnerabilities detected in CircleCI* + +#### Accessing Detailed Vulnerability Information + +GHSA identifiers can be used as direct URLs to access detailed vulnerability information. Simply append the GHSA ID to the GitHub security advisory base URL: + +``` +https://github.com/[owner]/[repo]/security/advisories/[GHSA-ID] +``` + +or use the generic GitHub Advisory Database URL: + +``` +https://github.com/advisories/[GHSA-ID] +``` + +For example, a vulnerability in the multer package can be accessed at: +https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5 + +Similarly, when a CVE has been assigned to a vulnerability, you can access the official CVE record using the CVE ID in the following URL format: + +``` +https://www.cve.org/CVERecord?id=[CVE-ID] +``` + +For the same multer vulnerability example, corresponding CVE information can be found at: +https://www.cve.org/CVERecord?id=CVE-2025-47935 + +#### Vulnerability Information Sources + +**GitHub Security Advisory pages include:** +- Detailed vulnerability descriptions +- Affected and patched versions +- CVE IDs (when assigned) +- Severity scores (typically CVSS) +- Remediation guidance +- References to related issues and commits + +**CVE Record pages include:** +- Official vulnerability descriptions +- References to related resources +- Affected products and versions +- Standardized severity information +- Attribution information + +When investigating vulnerabilities, it's often valuable to check both sources as they may contain complementary information. + +When working with Mojaloop vulnerabilities, you may encounter both types of identifiers: +- CVEs in general security bulletins and tools like npm audit +- GHSAs in GitHub Dependabot alerts and in .grype.yaml configuration files + +GitHub Dependabot alerts section in a GitHub repo can be found by navigating to the Security tab on the top menu and then under Vulnerability alerts, click on Dependabot. Here you will find a list of alerts. Finally, click one of the alerts to review details. + +Note: Please notice that your GitHub account must have granted permission to access Security tab. Also, Dependabot must be enabled for the given repo. Please contact Mojaloop GitHub Admin if need help with these. + +### 1.1 Vulnerability Severity Levels + +Vulnerabilities are classified using the following four severity levels: + +- **Critical**: Vulnerabilities that require immediate attention. These typically include remote code execution, authentication bypasses, or other severe flaws that could lead to a complete system compromise. +- **High**: Serious vulnerabilities that should be addressed before the end of a Program Increment (PI), with a target of 30 days. These may include injection vulnerabilities, insecure deserialization, or cross-site scripting issues that could lead to significant data exposure. +- **Medium**: Moderate risk vulnerabilities that should be addressed within the current PI if possible, with a target of 60 days. These may include information disclosure, cross-site request forgery, or other vulnerabilities with mitigating factors. +- **Low**: Minor issues that pose minimal risk. These should still be addressed but at a lower priority, with a target of 90 days. + +**Note on CVE IDs**: When a vulnerability report does not include a CVE, it may mean: +1. The vulnerability is newly discovered and hasn't yet been assigned a CVE +2. The issue is specifically related to the way code is implemented in your project +3. The vulnerability is in a development dependency that doesn't affect production environments + +A missing CVE doesn't mean the vulnerability isn't important - it should still be assessed based on its severity and potential impact. + +### 1.2 Understanding Package/Dependency Version Ranges in Dependabot alerts + +Version ranges in Dependabot alerts define which versions of a package/dependency are affected. Please noticed how in a Dependabot alert the what is refer to as package corresponds to a dependency in the package.json of the NodeJS project. Dependencies and there pacakges follwong Semantic Versioning. Understanding these notations is crucial: + +- **`<=M.m.p`**: All versions less than or equal to the specified version are vulnerable. + - Example: `<=1.2.3` means all versions up to and including 1.2.3 are vulnerable. + +- **Range using `>M.m.p 1.0.0 <1.2.0` means all versions after 1.0.0 and before 1.2.0 are vulnerable. + +Other common version specifiers you'll encounter include: + +- **Caret (`^`)**: Allows changes that don't modify the leftmost non-zero digit. + - Example: `^1.2.3` allows updates to any version from 1.2.3 up to but not including 2.0.0. + - For `^0.2.3`, allows updates to any version from 0.2.3 up to but not including 0.3.0. + - For `^0.0.3`, allows updates to any version from 0.0.3 up to but not including 0.0.4. + +- **Tilde (`~`)**: Allows patch-level changes if a minor version is specified. + - Example: `~1.2.3` allows updates to any version from 1.2.3 up to but not including 1.3.0. + +## Vulnerability Sources + +Vulnerabilities can be introduced through: +1. Direct dependencies +2. Transitive dependencies +3. Runtime environments +4. Infrastructure components +5. Custom code + +## Detection and Assessment + +### Vulnerability Detection Tools + +Mojaloop employs multiple tools to detect vulnerabilities: + +1. **GitHub Dependabot Alerts** + - Automatic detection of vulnerabilities in GitHub repositories + - Provides detailed information about affected versions and available fixes + - Available in the Security tab of GitHub repositories + - **Assets Scanned**: NodeJS application dependencies declared in package.json files within GitHub repositories + +2. **npm audit via audit-ci** + - Run locally using `npm run audit:check` + - Configurable via `audit-ci.jsonc` with allowlist for known issues + - Integrated in CI/CD pipelines to prevent vulnerable code from being deployed + - **Assets Scanned**: Direct and transitive NodeJS dependencies in package.json and package-lock.json files + +3. **Grype Image Scanning** + - Container image vulnerability scanner + - Configurable through `.grype.yaml` with an ignore section for known issues + - Scans for vulnerabilities in container images and dependencies + - **Assets Scanned**: Docker container images, including base images, installed OS packages, and application dependencies + - NOTE: Please notice that grype also scans Docker image if the given repo produces one and vulnerabilities can be found in images, if so, please be aware that an update to base image at Mojaloop CircleCI orb is needed. + +### Configuration Files for Vulnerability Management + +1. **audit-ci.jsonc** + - Contains an allowlist of vulnerabilities that can be temporarily ignored + - Used when a vulnerability cannot be fixed immediately + - Uses GHSA IDs to identify vulnerabilities to ignore + - Should include justification and tracking information for each allowed vulnerability + - Example format: + ```json + { + "allowlist": [ + { + "id": "GHSA-XXXX-YYYY-ZZZZ", + "reason": "No patch available yet, workaround implemented, tracking in issue #123" + } + ] + } + ``` + +2. **.grype.yaml** + - Configuration file for Grype container scanning + - Contains ignore section with GHSA vulnerability IDs + - Uses GHSA IDs to specify which vulnerabilities should be ignored + - Used for container-specific vulnerabilities that cannot be immediately addressed + - Example format: + ```yaml + ignore: + - vulnerability: GHSA-XXXX-YYYY-ZZZZ + package: + name: package-name + version: 1.2.3 + until: "2023-12-31" + reason: "Investigating alternative solutions, not exploitable in our context" + ``` + +### Automated Scanning +- Regular dependency scanning using npm audit +- Container image scanning +- Infrastructure vulnerability scanning +- Static code analysis + +### Manual Review +- Security code reviews +- Penetration testing +- Threat modeling +- Compliance audits + +## 2. ProcessFlow for Handling Dependency Vulnerability Updates + +The following diagram illustrates the dependency vulnerability management process for Mojaloop repositories: + +![Dependency Vulnerability Management Process](./assets/diagrams/vulnerabilityManagement/dependency-vulnerability-management-process.png) + +### 2.1 Standard Process + +1. **Triage** + - Regularly review GitHub Dependabot alerts. + - Classify/Review based on severity (Critical, High, Medium, Low). + - Track vulnerabilities in the existing private GitHub project repository dedicated to security vulnerabilities. Access to this repository is restricted and granted only on a need-to-know basis. Contact the Mojaloop Security Committee if you need access. + +2. **Update Process** + - **Step 1**: Choose a single module(a mojaloop service or library) with a reported vulnerability. + - **Step 2**: Make the required dependency update in the package.json. + - **Step 3**: Perform smoke tests to ensure functionality is not broken. Please follow details on this on the given repo README file. + - **Step 4**: If tests pass, proceed create a pull request. + - **Step 5**: Create Pull Requests for each module with the single security patch. + - **Step 6**: Include detailed information in the PR about the vulnerability being fixed, including its CVE ID and the dependencies being updated in the package.json along with any details as needed. + +3. **Important Principles** + - **Isolation**: Handle one vulnerability fix at a time. + - **No Bundling**: Don't bundle multiple unrelated security patches together. + - **Clean History**: Rebase commits for a clean history. + - **Thorough Testing**: Always run tests after making changes as instructed in README file for the given repo. + +### 2.2 Prioritization Framework + +- **Critical Severity**: Immediate attention required; aim to fix within 1-3 business days. +- **High Severity**: Fix before the end of the current Program Increment (PI), target 30 days. +- **Medium Severity**: Fix before the end of the current PI if possible, target 60 days. +- **Low Severity**: Address during regular maintenance cycles, target 90 days. + +### 2.3 Vulnerability Assessment Criteria + +Mojaloop follows OpenSSF and OWASP practices when assessing vulnerabilities. The ultimate decisions regarding vulnerability management are taken by the Mojaloop Security Committee. + +When determining whether to fix or allowlist/ignore a vulnerability: +- When a vulnerability fix exists, it should be applied. +- A vulnerability should only be allowlisted or ignored if the fix breaks existing functionality, which must be confirmed by either automated tests (as descrcribed on the given repo README) failing or through manual testing. +- For zero-day vulnerabilities, the Mojaloop Security Committee will provide guidance on handling procedures as necessary on a case by case basis. + +## 3. Practical Guide to package.json Updates + +### 3.1 Recommended Tools + +- **npm run audit:check**: To scan for vulnerabilities the audit:check script should help you identify vulnerabilities and should match those listed in GitHub Dependabot + ```bash + npm run audit:check + ``` + +- **npm run dep:check & npm run dep:update**: To help manage dependency updates, can be used, be mindful of making changes in bulk as it will be harder to track what breaks functionality. NOTE: Updating dependencies needs its own management guide. + +- **.ncurc.yaml**: To declare which dependencies should reject upgrade as it might break functionality. Used as last resource. + + +### 3.2 Step-by-Step Process + +1. **Identify the vulnerable package**: + ```bash + npm audit + ``` + +2. **Update a single package**: + ```bash + # For direct dependencies + npm update [package-name] + + # For fixing specific vulnerabilities + npm run audit:fix + + # For more complex cases with breaking changes + npm audit fix --force # Use with caution + ``` + +3. **Test the update**: + ```bash + npm test + # Run other project-specific tests + ``` + +4. **Commit changes and create a PR**: + ```bash + git checkout -b fix/security-vulnerability-[CVE-ID] + git add package.json package-lock.json + git commit -m "fix: update [package] to fix [CVE-ID]" + git push origin fix/security-vulnerability-[CVE-ID] + ``` + +### 3.3 Handling Challenging Cases + +When `npm run audit:fix` doesn't resolve the issue: + +1. **For dependencies without patches available**: + - Check if the vulnerability is actually exploitable in your specific use case. + - Consider alternative packages. + - Contact the package maintainer to report the issue. + - Document the vulnerability with a detailed explanation of risk assessment. + +2. **When fixes break functionality**: + - If tests fail after dependency updates and no immediate solution is available: + - For npm package vulnerabilities: Add to the allowlist in `audit-ci.jsonc` + - For container vulnerabilities: Add to the ignore section in `.grype.yaml` + - Document the reasons for allowlisting/ignoring and include: + - Issue tracking number + - Detailed explanation of the risk + - Target date for resolution + - Any mitigating controls implemented + +3. **CI/CD Integration**: + - Security checks are integrated into CI/CD pipelines + - Critical vulnerabilities will fail the pipeline unless properly allowlisted/ignored + - All allowlisted/ignored vulnerabilities should be regularly reviewed + - Regular scanning should be performed to detect new vulnerabilities + +### 3.4 Container Vulnerability Management + +When working with Docker containers: + +1. **Grype Configuration**: + - Grype is used for scanning container images for vulnerabilities + - For detailed guidance on configuring Grype, use Mojaloop CircleCI Orb and refer to the [Mojaloop CI Config Orb documentation](https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration) + +2. **Base Image Security**: + - Mojaloop services typically use Node.js Alpine images + - The current base image used can be found at: [node:22.15.1-alpine3.21](https://hub.docker.com/layers/library/node/22.15.1-alpine3.21/images/sha256-d1068d8b737ffed2b8e9d0e9313177a2e2786c36780c5467ac818232e603ccd0) + - This page lists any vulnerabilities present in the base image, and the grype image scan also detect any vulnerabilities. + +## Update Strategy + +When addressing vulnerabilities: +1. Follow the repository update sequence as outlined in the [Mojaloop Repository Update Guide](./mojaloop-repository-update-guide.md) +2. Prioritize critical and high-severity vulnerabilities +3. Consider the impact on dependent services +4. Test thoroughly in non-production environments +5. Plan for coordinated updates across affected services + +## 4. Code Review Best Practices for Security PRs + +1. **Focused PRs**: PRs should address a single vulnerability. + +2. **Required Information in PRs**: + - CVE ID or vulnerability identifier + - Severity level + - Description of the vulnerability + - Description of the fix + - Testing performed + - Potential impact assessment + +3. **Review Checklist**: + - Verify the version update actually fixes the vulnerability + - Check for minimum changes to package.json + - Ensure tests still pass + - Verify smoke tests were performed per README and leverage test code harness + - Check for unintended side effects + +4. **Example PR Description Template**: + ```markdown + ## Security Fix: [CVE-ID] + + ### Vulnerability Details + - Severity: [Critical/High/Medium/Low] + - Affected Package: [package-name] + - Vulnerable Versions: [version range] + - Fixed Version: [version number] + + ### Description + Brief description of the vulnerability and its potential impact. + + ### Changes + - Updated [package-name] from [old-version] to [new-version] + + ### Testing + - [X] Unit tests pass + - [X] Integration tests pass + - [X] Manual testing performed + - [X] Leverage test code harness on the developer's workstation + - [X] CI/CD test code harness and/or Golden Path tests + + ### Additional Notes + Any other relevant information. + ``` + +## Reporting and Communication + +- Centralize vulnerability tracking and control access +- Document all identified issues +- Track remediation status +- Communicate updates to stakeholders +- Follow responsible disclosure practices + +## 5. Developer Onboarding and Dependency Vulnerability Management Education + +To use vulnerability management as an entry point for new Mojaloop developers: + +### 5.1 Educational Resources + +- Create a dedicated section in documentation about vulnerability management +- Include practical examples and walkthroughs +- Provide links to external resources about Node.js security + +### 5.2 Mentoring Process + +1. **Assign Simple Vulnerabilities**: Start new developers with low-priority vulnerability fixes. +2. **Paired Reviews**: Have experienced developers review PRs from newcomers. +3. **Progressive Responsibility**: Gradually assign more complex security issues. + +### 5.3 Documentation Updates + +- Maintain a knowledge base of common vulnerability patterns in the codebase +- Document lessons learned from previous vulnerability fixes +- Update this dependency vulnerability management guide as processes evolve + +### 5.4 Security in Daily Development + +During the developer onboarding process, this dependency vulnerability management document will be shared with all developers and adherence will be enforced through code reviews during PRs. Several open source security scanning tools for IDE integration are currently under investigation to further improve developer workflow. + +## Best Practices + +1. **Prevention** + - Regular dependency updates + - Security-focused development practices + - Automated security testing + - Secure coding guidelines + +2. **Response** + - Clear escalation paths + - Defined response timelines + - Regular security reviews + - Continuous monitoring + +3. **Documentation** + - Vulnerability tracking + - Remediation procedures + - Security incident reports + - Lessons learned + +## 6. Continuous Improvement + +### 6.1 Regular Security Reviews + +- Conduct weekly reviews of new vulnerability reports +- Track metrics on time-to-fix by severity level +- Compare performance against industry standards + +### 6.2 Automation Opportunities + +- Explore adoption of open source DefectDojo to centralize and automate vulnerability lifecycle management + - [DefectDojo Community](https://defectdojo.com/community) + - [DefectDojo GitHub Repository](https://github.com/DefectDojo/django-DefectDojo) + - [OWASP DefectDojo Project](https://owasp.org/www-project-defectdojo/) + - [DefectDojo Documentation](https://docs.defectdojo.com/en/about_defectdojo/about_docs/) +- Implement pre-commit hooks for dependency checking +- Set up scheduled jobs for regular security audits + +### 6.3 Knowledge Sharing + +- Create and maintain documentation and training on vulnerability management +- Create walkthrough videos for common vulnerability fixes +- Establish a security champions program within the community + +## 7. Conclusion + +By implementing this structured approach to dependency vulnerability management, the Mojaloop community can ensure consistent, timely, and effective responses to security issues. This process not only improves the security posture of the codebase but also provides an excellent opportunity to onboard new developers and build security awareness throughout the community. + +Dependency vulnerability management is not just about fixing issues, it's about building a security mindset. + +## Tools and Resources + +- [What is a CVE (Common Vulnerabilities and Exposures)?](https://www.ibm.com/think/topics/cve) +- [Mojaloop Documentation](https://docs.mojaloop.io/) +- [Node.js Security Best Practices](https://nodejs.org/en/learn/getting-started/security-best-practices) +- [npm Audit Documentation](https://docs.npmjs.com/cli/v10/commands/npm-audit) +- [Semantic Versioning Specification](https://semver.org/) +- [npm Semver Calculator](https://semver.npmjs.com/) +- [GitHub Security Features](https://docs.github.com/en/code-security) +- [GitHub Dependabot quickstart guide](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide) +- [Mojaloop CI Config - Vulnerability Image Scan Configuration](https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration) +- [DefectDojo Community](https://defectdojo.com/community) +- [DefectDojo GitHub Repository](https://github.com/DefectDojo/django-DefectDojo) +- [OWASP DefectDojo Project](https://owasp.org/www-project-defectdojo/) +- [DefectDojo Documentation](https://docs.defectdojo.com/en/about_defectdojo/about_docs/) +- npm audit +- GitHub Security Advisories +- Container scanning tools +- Static analysis tools +- Security monitoring systems + +## Related Documentation + +- [Upgrade Strategy Guide](./upgrade-strategy-guide.md) +- [Mojaloop Repository Update Guide](./mojaloop-repository-update-guide.md) +- [Deployment Troubleshooting](./deployment-troubleshooting.md) +- [Mojaloop Coordinated Vulnerability Disclosure Policy](https://docs.mojaloop.io/community/contributing/cvd.html) + \ No newline at end of file diff --git a/docs/technical/technical/security/security-overview.md b/docs/technical/technical/security/security-overview.md new file mode 100644 index 000000000..9971c0d3a --- /dev/null +++ b/docs/technical/technical/security/security-overview.md @@ -0,0 +1,179 @@ + +

    Mojaloop Vulnerability Management Process

    + +Contents: +1. [Introduction](#1-introduction) +2. [Security committee](#2-security-committee) +3. [Handling a possible vulnerability](#3-handling-a-possible-vulnerability) +4. [Mojaloop Vulnerability Management Processes in Place](#4-mojaloop-vulnerability-management-processes-in-place) +5. [Scope](#5-scope) + +

    1. Introduction

    + +This document outlines the Mojaloop Vulnerability Management Process, providing guidelines for the Mojaloop community on identifying, reporting, assessing, and addressing security vulnerabilities within Mojaloop software. By adhering to recognized security standards, such as ISO 27001, Mojaloop ensures a consistent approach to maintaining security and resilience. + +This process is based on Mojaloop's established processes, ensuring a well-defined scope and guidelines that adopters of the software can rely on. It emphasizes responsible handling of vulnerabilities until verified fixes are available and properly communicated. + +A structured, transparent, and effective vulnerability management process is essential for maintaining trust and safeguarding the Mojaloop ecosystem. + +

    2. Security Committee

    + +Mojaloop's vulnerability management process is supported by a designated "Security Committee," a core group responsible for coordinating all aspects of vulnerability management. This committee oversees the process, including: + +1. Reviewing and validating vulnerability reports. +2. Deciding on the acceptance or rejection of reported vulnerabilities. +3. Defining appropriate fixes and planning announcements. +4. Coordinating releases that include security patches. + +The Security Committee is composed of core contributors and community leaders who ensure the efficient and secure handling of vulnerabilities within Mojaloop. Its structure and responsibilities are designed to maintain the security and integrity of the Mojaloop ecosystem. + +

    3. Handling a Possible Vulnerability

    + +Mojaloop vulnerability disclosure (CVD) policy: [https://docs.mojaloop.io/community/contributing/cvd.html](https://docs.mojaloop.io/community/contributing/cvd.html) + +The default process for managing a possible security vulnerability in Mojaloop is outlined in the above link. Projects that require a different process must document it clearly and publicly. + +The process for general third-party dependencies and other open source modules is outlined in the [dependency vulnerability management](dependency-vulnerability-management.md) guide. + +

    Security for Mojaloop Community Members

    + +Mojaloop community members and member organizations play a vital role in the vulnerability management process, particularly in handling potential vulnerabilities according to defined procedures. The following guidance outlines the expected steps: + +* Avoid entering details of security vulnerabilities in public bug trackers, unless access is strictly limited. +* Security communications should be limited to private channels designated for this purpose. These channels are not notification systems for the general public. + +

    Work in Private

    + +Information about a vulnerability should not be made public until a formal announcement is issued at the end of the process. This means: + +* **Do not create public issue tracker tickets (e.g. GitHub/Zenhub) to track the issue**, as this would make it public. +* **Messages associated with code commits should not reference the security nature of the commit.** +* **Discussions regarding the vulnerability, potential fixes, and announcements should occur on private channels**, such as a project-specific security mailing list or a private channel for maintainers. +* Work with Mojaloop security team (security at mojaloop dot io) to follow the CVD process: https://docs.mojaloop.io/community/contributing/cvd.html + +

    Report

    + +The person discovering the issue (the reporter) should report the vulnerability by completing the report and emailing it to: **[security@mojaloop.io](mailto:security@mojaloop.io)** . Report templates can be follow the bug template here: https://github.com/mojaloop/project/issues . + +List of issues that are deemed relevant: +1. Security issues / vulnerabilities in Mojaloop core services (application codebase) +2. Security issues / vulnerabilities in Mojaloop supporting services +3. Wide-spread or day-zero issues in latest versions of critical dependencies Mojaloop's core and supporting services use (such as nodejs, kafka, mysql) + +List of issues that are not deemed critical or of low priority and responses may be delayed: + +1. Vulnerabilities regarding [mojaloop.io](mojaloop.io) website +2. Vulnerabilities regarding [docs.mojaloop.io](docs.mojaloop.io) website + +

    Acknowledge

    + +The Mojaloop security team should send an email to the original reporter to acknowledge receipt of the report. This acknowledgment should ideally include a copy to the relevant private security mailing list. + +

    Investigate and Respond

    + +The team investigates the report and either rejects or accepts it. + +1. Information may be shared with domain experts privately, provided they understand it is not for public disclosure. +2. If rejected, the team explains the decision to the reporter, with a copy to the relevant security mailing list. +3. If accepted, the team notifies the reporter that the report is being addressed. + +

    Resolve

    + +* The team agrees on a fix, typically on a private list. +* Details of the vulnerability and the fix should be documented to generate draft announcements. +* The reporter may be provided with a copy of the fix and the draft announcement for comment. +* The fix is committed without any reference in the commit message that it relates to a security vulnerability. +* A release that includes the fix is created. More details are included in the Mojaloop CVD policy. + +

    Announce

    + +* After the release, the vulnerability and fix are publicly announced. +* The announcement should be sent to relevant destinations, including the vulnerability reporter, project security lists, and possibly public security lists. + +

    Complete

    + +The project's public security pages should be updated with information about the vulnerability, ensuring transparency for users. + +

    4. Mojaloop Vulnerability Management Processes in Place

    + +Mojaloop has established a series of robust processes and tools to manage vulnerabilities throughout the software development lifecycle, ensuring alignment with industry best practices, including ISO 27001 standards for vulnerability identification and mitigation. + +

    Vulnerability Management

    + +Continuous monitoring of open-source components for vulnerabilities is integrated into the CI/CD pipeline. This process is automated to assess each release, commit, and pull request, leveraging Node Package Manager (NPM) for dependency vulnerability assessments. + +

    Static Application Security Testing (SAST)

    + +Mojaloop uses multiple tools for SAST, providing detailed insights into code-level vulnerabilities by leveraging public vulnerability databases, including: + +1. **GitHub Security Tools:** Including Dependabot for dependency scanning (relying on GitHub’s Advisory Database), CodeQL for code analysis, and Secret Scanning to prevent the inclusion of sensitive information. +2. **SonarCloud:** Analyzes every commit, pull request, and release for code quality and security issues, utilizing vulnerability data from public databases such as CVE (Common Vulnerabilities and Exposures). + +

    Software Bill of Materials (SBOM) and Dependency Management

    + +An SBOM tool is used to generate an inventory of third-party dependencies, allowing for: + +1. Identification of vulnerabilities and license compliance issues. +2. Regular reporting for regulatory and security assessments. +3. Ongoing monitoring of library versions across all repositories. +4. Ensuring well maintained and managed packages / dependencies are used and outdated ones are managed accordingly. + +Here's more information about SBOM in Mojaloop: https://github.com/mojaloop/ml-depcheck-utility?tab=readme-ov-file#sbom-generation-tool-for-mojaloop-repositories + +

    Container Security

    + +Container images are scanned for vulnerabilities using Grype before release. Grype is configured following best practices and stricter configurations are recommended for adopters. Grype configuration from the CI Orb Mojaloop uses: https://github.com/mojaloop/ci-config-orb-build?tab=readme-ov-file#vulnerability-image-scan-configuration . + +

    License Compliance

    + +An automated license scanner ensures that only components with compatible licenses are used. Compliance checks are integrated into the CI/CD processes, blocking non-compliant code from being merged or deployed. + +

    Provenance of Images

    + +Following Mojaloop Release (v17.1.0), Mojaloop's helm charts are signed at publishing and can be verified at install / deploy time (This feature has native helm support in helm), to ensure provenance of artefacts related to charts. In the future this can be extended to other artefacts such as images. + +

    Mojaloop CI/CD Security Process

    + +Mojaloop employs a CI/CD pipeline that automatically integrates security checks throughout the software development process. This ensures consistent security application without manual oversight. Branch protection rules enforce continuous checks on every commit, pull request, and release. + +CI/CD Security Integration: + +1. **Container Security: **… +2. **License Compliance:** … +3. **Dependency Vulnerability Scanning:** … + +All critical vulnerabilities are logged, and the CI/CD pipeline will block publishing images or packages until these issues are resolved. These automated security measures in the CI/CD pipeline guarantee that code is continuously tested, secure, and compliant, maintaining high security standards across the development process. + +

    Coordinated Vulnerability Disclosure (CVD)

    + +Mojaloop operates a CVD process, ensuring responsible parties have adequate time to address and remedy vulnerabilities before public disclosure. + +Mojaloop vulnerability disclosure (CVD) policy: [https://docs.mojaloop.io/community/contributing/cvd.html](https://docs.mojaloop.io/community/contributing/cvd.html) + +

    Reporting and Compliance

    + +Comprehensive reports are generated after each scan, detailing outcomes, remediation actions, and their effectiveness. + +All reports are stored for auditing and compliance, ensuring transparency and accountability. + +Report from license scanning at helm level is provided with Mojaloop release notes (also confirms that license scanning step has passed and only includes allowed licenses). The license summary file is attached to the release notes (present at the bottom): [https://github.com/mojaloop/helm/releases/tag/v17.0.0](https://github.com/mojaloop/helm/releases/tag/v17.0.0) provides an example. + +Image scanning reports are present for review in the CI tool (circleCI) to record either failure or pass result (but the workflow moves forward only if this step passes). For example / reference, a sample Grype scanning result here: [https://app.circleci.com/pipelines/github/mojaloop/account-lookup-service/2165/workflows/d420ef53-85a7-46d3-af1e-1527baf3a207/jobs/16509/artifacts](https://app.circleci.com/pipelines/github/mojaloop/account-lookup-service/2165/workflows/d420ef53-85a7-46d3-af1e-1527baf3a207/jobs/16509/artifacts) (though this might go out-of-date with time, it is given as an example) + +

    5. Scope

    + +The Mojaloop vulnerability management process applies to all components that are part of the Mojaloop Helm release. + +This includes: + +1. All core components and services are explicitly defined in the Mojaloop Helm charts. +2. Dependencies included within the Mojaloop Helm release, which are automatically scanned as part of the vulnerability management process. + +Exclusions: + +1. Repositories that are not part of the Mojaloop core release are considered non-production and are excluded from the vulnerability management process. +2. External components required for a typical Mojaloop deployment (e.g., MySQL, Redis, MongoDB, Kafka) are not maintained by the Mojaloop Foundation and are excluded from this vulnerability management process meant for Mojaloop's application codebase, though they are part of the general vulnerability management (as third-party OSS dependencies). + +This approach ensures that the Mojaloop core components are consistently secured, while also clarifying the boundary of responsibility regarding external dependencies and providing guidance regarding other (or third-party) OSS packages, dependencies and tools. + +

    diff --git a/docs/technical/technical/transaction-requests-service/README.md b/docs/technical/technical/transaction-requests-service/README.md new file mode 100644 index 000000000..aafe06e92 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/README.md @@ -0,0 +1,9 @@ +# Transaction Requests Service + +## Sequence Diagram + +![](./assets/diagrams/sequence/trx-service-overview-spec.svg) + + +* The transaction-requests-service is a Mojaloop core service that enables Payee initiated use cases such as "Merchant Request to Pay". +* This is a pass through service which also includes Authorizations. diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml new file mode 100644 index 000000000..0d4005e68 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml @@ -0,0 +1,64 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Authorizations +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" --\ "Payee FSP": Lookup, Transaction request,\nprocessing not shown here +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payer FSP" --> "Payer FSP": Do quote, generate OTP\nnotify user (not shown here) +"Payer FSP" -\ Switch: GET /authorizations/{TransactionRequestID} +Switch --/ "Payer FSP": 202 Accepted + +alt authorization request is valid + + Switch -> Switch: Validate GET /authorizations/{TransactionRequestID} (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + note over Switch, "Payee FSP": Switch forwards GET /authorizations request to Payee FSP + Switch -\ "Payee FSP": GET /authorizations/{TransactionRequestID} + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Process authorization request\n(Payer approves/rejects transaction\nusing OTP) + + note over Switch, "Payee FSP": Payee FSP responds with PUT /authorizations//{TransactionRequestID} + "Payee FSP" -\ Switch: PUT /authorizations//{TransactionRequestID} + Switch --/ "Payee FSP": 200 Ok + + note over "Payer FSP", Switch: Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + Switch -\ "Payer FSP": PUT /authorizations//{TransactionRequestID} + "Payer FSP" --/ Switch: 200 Ok + + +else authorization request is invalid + note over "Payer FSP", Switch: Switch returns error callback to Payer FSP + Switch -\ "Payer FSP": PUT /authorizations/{TransactionRequestID}/error + "Payer FSP" --/ Switch: 200 OK + "Payer FSP" --> "Payer FSP": Validate OTP sent by Payee FSP +end +@enduml diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg new file mode 100644 index 000000000..58173614d --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg @@ -0,0 +1,132 @@ + + Transaction Requests Service - Authorizations + + + Transaction Requests Service - Authorizations + + + + + + Payer FSP + + Payer FSP + + Switch + transaction-requests-service + + Switch + transaction-requests-service + + Payee FSP + + Payee FSP + + + + + 1 + Lookup, Transaction request, + processing not shown here + + + Payee FSP generates a transaction-request to the Payer FSP + + + + + 2 + Do quote, generate OTP + notify user (not shown here) + + + 3 + GET /authorizations/{TransactionRequestID} + + + 4 + 202 Accepted + + + alt + [authorization request is valid] + + + + + 5 + Validate GET /authorizations/{TransactionRequestID} (internal validation) + + + + + 6 + Retrieve corresponding end-points for Payee FSP + + + Switch forwards GET /authorizations request to Payee FSP + + + 7 + GET /authorizations/{TransactionRequestID} + + + 8 + 202 Accepted + + + + + 9 + Process authorization request + (Payer approves/rejects transaction + using OTP) + + + Payee FSP responds with PUT /authorizations//{TransactionRequestID} + + + 10 + PUT /authorizations//{TransactionRequestID} + + + 11 + 200 Ok + + + Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + + + + + 12 + Retrieve corresponding end-points for Payer FSP + + + 13 + PUT /authorizations//{TransactionRequestID} + + + 14 + 200 Ok + + [authorization request is invalid] + + + Switch returns error callback to Payer FSP + + + 15 + PUT /authorizations/{TransactionRequestID}/error + + + 16 + 200 OK + + + + + 17 + Validate OTP sent by Payee FSP + + diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml new file mode 100644 index 000000000..655cf6e07 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml @@ -0,0 +1,93 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Create +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" -\ "Payee FSP": Lookup process\n(not shown here) +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payee FSP" -\ Switch: POST /transactionRequests +Switch -> Switch: Validate POST /transactionRequests schema +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request is valid + + Switch -> Switch: Validate POST /transactionRequests (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards POST /transactionRequests request to Payer FSP + Switch -\ "Payer FSP": POST /transactionRequests + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Process transaction-request + + alt Payer FSP successfully processes transaction-request + + note over "Payer FSP", Switch: Payer FSP responds to POST /transactionRequests + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + note over "Payee FSP" #3498db: Wait for a quote, transfer by Payer FSP\nor a rejected transaction-request + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP calculation fails or rejects the request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg new file mode 100644 index 000000000..c602dd78a --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg @@ -0,0 +1,185 @@ + + Transaction Requests Service - Create + + + Transaction Requests Service - Create + + + + + + + + Payer FSP + + Payer FSP + + Switch + transaction-requests-service + + Switch + transaction-requests-service + + Payee FSP + + Payee FSP + + + + + 1 + Lookup process + (not shown here) + + + Payee FSP generates a transaction-request to the Payer FSP + + + 2 + POST /transactionRequests + + + + + 3 + Validate POST /transactionRequests schema + + + 4 + 202 Accepted + + + alt + [transaction-request is valid] + + + + + 5 + Validate POST /transactionRequests (internal validation) + + + + + 6 + Retrieve corresponding end-points for Payer FSP + + + Switch forwards POST /transactionRequests request to Payer FSP + + + 7 + POST /transactionRequests + + + 8 + 202 Accepted + + + + + 9 + Process transaction-request + + + alt + [Payer FSP successfully processes transaction-request] + + + Payer FSP responds to POST /transactionRequests + + + 10 + PUT /transactionRequests/{ID} + + + 11 + 200 Ok + + + + + 12 + Validate PUT /transactionRequests/{ID} + + + alt + [response is ok] + + + Switch forwards transaction-request response to Payee FSP + + + + + 13 + Retrieve corresponding end-points for Payee FSP + + + 14 + PUT /transactionRequests/{ID} + + + 15 + 200 Ok + + + Wait for a quote, transfer by Payer FSP + or a rejected transaction-request + + [response invalid] + + + Switch returns error to Payer FSP + + + 16 + PUT /transactionRequests/{ID}/error + + + 17 + 200 Ok + + + Note that under this + scenario the Payee FSP + may not receive a response + + [Payer FSP calculation fails or rejects the request] + + + Payer FSP returns error to Switch + + + 18 + PUT /transactionRequests/{ID}/error + + + 19 + 200 OK + + + Switch returns error to Payee FSP + + + 20 + PUT /transactionRequests/{ID}/error + + + 21 + 200 OK + + [transaction-request is invalid] + + + Switch returns error to Payee FSP + + + 22 + PUT /transactionRequests/{ID}/error + + + 23 + 200 OK + + diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml new file mode 100644 index 000000000..17262a24a --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml @@ -0,0 +1,90 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Query +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +note over "Payee FSP", Switch: Payee FSP requests the status of a transaction-request at the Payer FSP.\nID here is the ID of prevoiusly created transaction-request +"Payee FSP" -\ Switch: GET /transactionRequests/{ID} +Switch -> Switch: Validate GET /transactionRequests/{ID} +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request query is valid + + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards GET /transactionRequests/{ID} request to Payer FSP + Switch -\ "Payer FSP": GET /transactionRequests/{ID} + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Retrieve transaction-request + + alt Payer FSP successfully retrieves transaction-request + + note over "Payer FSP", Switch: Payer FSP responds with the\nPUT /transactionRequests/{ID} callback + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP is unable to retrieve the transaction-request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg new file mode 100644 index 000000000..c2f12614b --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg @@ -0,0 +1,170 @@ + + Transaction Requests Service - Query + + + Transaction Requests Service - Query + + + + + + + + Payer FSP + + Payer FSP + + Switch + transaction-requests-service + + Switch + transaction-requests-service + + Payee FSP + + Payee FSP + + + Payee FSP requests the status of a transaction-request at the Payer FSP. + ID here is the ID of prevoiusly created transaction-request + + + 1 + GET /transactionRequests/{ID} + + + + + 2 + Validate GET /transactionRequests/{ID} + + + 3 + 202 Accepted + + + alt + [transaction-request query is valid] + + + + + 4 + Retrieve corresponding end-points for Payer FSP + + + Switch forwards GET /transactionRequests/{ID} request to Payer FSP + + + 5 + GET /transactionRequests/{ID} + + + 6 + 202 Accepted + + + + + 7 + Retrieve transaction-request + + + alt + [Payer FSP successfully retrieves transaction-request] + + + Payer FSP responds with the + PUT /transactionRequests/{ID} callback + + + 8 + PUT /transactionRequests/{ID} + + + 9 + 200 Ok + + + + + 10 + Validate PUT /transactionRequests/{ID} + + + alt + [response is ok] + + + Switch forwards transaction-request response to Payee FSP + + + + + 11 + Retrieve corresponding end-points for Payee FSP + + + 12 + PUT /transactionRequests/{ID} + + + 13 + 200 Ok + + [response invalid] + + + Switch returns error to Payer FSP + + + 14 + PUT /transactionRequests/{ID}/error + + + 15 + 200 Ok + + + Note that under this + scenario the Payee FSP + may not receive a response + + [Payer FSP is unable to retrieve the transaction-request] + + + Payer FSP returns error to Switch + + + 16 + PUT /transactionRequests/{ID}/error + + + 17 + 200 OK + + + Switch returns error to Payee FSP + + + 18 + PUT /transactionRequests/{ID}/error + + + 19 + 200 OK + + [transaction-request is invalid] + + + Switch returns error to Payee FSP + + + 20 + PUT /transactionRequests/{ID}/error + + + 21 + 200 OK + + diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml new file mode 100644 index 000000000..d88913d33 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation +- Name Surname + +* Henk Kodde +-------------- +******'/ + +@startuml transactionRequests + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +payeefsp <- Payee: I would like to receive\nfunds from +123456789 +activate payeefsp +payeefsp <- payeefsp: Lookup +123456789\n(process not shown here) +Switch <<- payeefsp: **POST /transactionRequest/**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepted) +payerfsp <<- Switch: **POST /transactionRequests/**\n(Payee information,\ntransaction details) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepted) +payeefsp -> payeefsp: Perform optional validation +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Received status) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Received status) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Wait for either quote and\ntransfer, or rejected\ntransaction request by Payer +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg new file mode 100644 index 000000000..81ddcf167 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + Payer + FSP + + Optional + Switch + + Payee + FSP + + Payee + + + + + + + + I would like to receive + funds from +123456789 + + + + + Lookup +123456789 + (process not shown here) + + + + POST /transactionRequest/ + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + POST /transactionRequests/ + (Payee information, + transaction details) + + + + HTTP 202 + (Accepted) + + + + + Perform optional validation + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + PUT /transactionRequests/ + <ID> + (Received status) + + + + HTTP 200 + (OK) + + + + + Wait for either quote and + transfer, or rejected + transaction request by Payer + + diff --git a/docs/technical/technical/transaction-requests-service/authorizations.md b/docs/technical/technical/transaction-requests-service/authorizations.md new file mode 100644 index 000000000..6617f1780 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/authorizations.md @@ -0,0 +1,8 @@ +# Transaction Requests + +GET /authorizations/{TransactionRequestID} and PUT /authorizations/{TransactionRequestID} to support authorizations in "Merchant Request to Pay" and other Payee initiated use cases + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg) + diff --git a/docs/technical/technical/transaction-requests-service/transaction-requests-get.md b/docs/technical/technical/transaction-requests-service/transaction-requests-get.md new file mode 100644 index 000000000..c8bbe7815 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/transaction-requests-get.md @@ -0,0 +1,8 @@ +# Transaction Requests - Query + +GET /transactionRequests and PUT /transactionRequests to support "Merchant Request to Pay" + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg) + diff --git a/docs/technical/technical/transaction-requests-service/transaction-requests-post.md b/docs/technical/technical/transaction-requests-service/transaction-requests-post.md new file mode 100644 index 000000000..956bc9150 --- /dev/null +++ b/docs/technical/technical/transaction-requests-service/transaction-requests-post.md @@ -0,0 +1,8 @@ +# Transaction Requests + +POST /transactionRequests and PUT /transactionRequests to support "Merchant Request to Pay" + +## Sequence Diagram + +![](./assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg) + diff --git a/glossary.md b/glossary.md deleted file mode 100644 index 65b9763a1..000000000 --- a/glossary.md +++ /dev/null @@ -1,8 +0,0 @@ -# Glossary of Terms - -| Term | Definition | Notes | -| --- | --- | --- | -| DFSP | Digital Financial Service Provider | | -| FSP | Financial Service Provider | | -| K8s | Short name for [Kubernetes](https://kubernetes.io/) | Read more here [https://kubernetes.io](https://kubernetes.io) | -| ALS | [Account-Lookup Service](mojaloop-technical-overview/account-lookup-service/README.md) | Refer to [Documentation](mojaloop-technical-overview/account-lookup-service/README.md) | diff --git a/index.js b/index.js deleted file mode 100644 index b248afdbc..000000000 --- a/index.js +++ /dev/null @@ -1,34 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - - * Gates Foundation - - Name Surname - - * Miguel de Barros - - -------------- - ******/ - -const express = require('express') -const app = express() -app.use(express.static(__dirname + '/_book')) - -app.listen(process.env.PORT || 8989) diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 000000000..70953e512 --- /dev/null +++ b/infra/README.md @@ -0,0 +1,89 @@ +# infra + +Mojaloop Documentation Site is hosted on AWS CloudFront, with Terraform to automate the creation and management +of the site. + +This document is for maintainers of Mojaloop's documentation site, but this repo can also serve as a good template + for automating the deployment of static hosting with cloudfront functions. + +## Requirements + +- `terraform` +- AWS credentials and necessary IAM permissions to create, update destroy s3 buckets, dynamodb tables, CloudFront CDNs + +## Deploy + +```bash +# sign in with MFA +aws-mfa + +# initialize the shared terraform state (if not done already) +cd ./state + +terraform init + +# for some reason I need to set this env var for tf 0.14+ +AWS_SHARED_CREDENTIALS_FILE=$HOME/.aws/credentials +terraform plan +terraform apply + + + +cd ../src +# first time only +terraform init \ + -backend-config="bucket=docs.mojaloop.io-state" \ + -backend-config="region=eu-west-2" \ + -backend-config="dynamodb_table=docs.mojaloop.io-lock" + + +# see what changes are needed +terraform plan + +# apply the terraform +terraform apply +``` + +## Manual Steps: + +It's up to you to configure the DNS and SSL Certificates. I didn't want to add this here +because the `docs.mojaloop.io` domain is not configured by us, so there is no point in +automating it. + +Additionally, domains are slow moving and tend to often need manual intervention at some point. + +### Configure the DNS: + +1. Log in to Route53 > Hosted Zones > select your domain (for example `moja-lab.live`) +2. "Create Record" with the following details: +- Record Name: `docs-preview2` +- Type: `CNAME` +- Value: `d1n6mdji42j0gb.cloudfront.net` - value from terraform output: `website_cdn_root_domain_name` +3. "Create Records" + +### Attach the CI user to the IAM groups + +In order to use this tooling in CI/CD, you need to manually attach a CI user to the groups +created by terraform, in this case `docs-preview2.moja-lab.live-infra-group` and +`docs-preview2.moja-lab.live-infra-infra` + +### Upload your site! + +Build and upload the site to your terraform-managed s3 bucket: + +```bash +AWS_REGION=us-east-2 BUCKET_NAME=docs-preview.moja-lab.live-root DOMAIN=docs-preview.moja-lab.live ../scripts/_deploy_preview_s3.sh +``` + + +## Configure Redirects + +In order to support the gradual migration to docs 2.0, we need to be able to configure the CDN +to fall back to legacy docs that haven't yet been migrated, also be able to redirect legacy +links to updated pages in order to avoid broken links once we switch over to docs 2.0. + + +For this, we use cloudfront functions, which are lightweight Javascript functions that allow you +to control the behaviour of requests and responses of the CDN. + +The redirect behaviour can be configured in `./src/redirect/index.js` \ No newline at end of file diff --git a/infra/src/.terraform.lock.hcl b/infra/src/.terraform.lock.hcl new file mode 100755 index 000000000..0e7cea3fa --- /dev/null +++ b/infra/src/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "3.64.2" + constraints = "~> 3.64.2" + hashes = [ + "h1:oFsgTmmt/eJ8KLo59PSmYu/irUHJiPnQEey0VqaOOck=", + "zh:0b029a2282beabfe410eb2969e18ca773d3473415e442be4dc8ce0eb6d1cd8c5", + "zh:3209de3266a1138f1ccb09f094fdd98b6f55afc06e291db0abe092ec5dbe7640", + "zh:40648266551631cbc15f8a76e80faf300510e3b38c2544d43fc25e37e6802727", + "zh:483c8af92ae70146f2790a70c1a810251e7135aa912b66e769c934eddceebe32", + "zh:4d106d8d415d8df342f3f85e58c35418e6c55e3cb7f02897f832cefac4dca68c", + "zh:972626a6ddb31d5216606d12ab5c30fbf8d51ed2bbe0efcdd7cffa68c1141557", + "zh:a230d55ec52b1695148d40296877ee23e0b302e817154f9b838eb117c87b13fa", + "zh:c95fddfbd7f870db949da0601323e866e0f0fb0d4a93e96725ae5b88029e84d5", + "zh:ea0c7f568074f835f22273c8e7e61e87f5277e32004c72122915fd3c8df49ccc", + "zh:f96d25887e6e2d2ae47659e2c586efea2167995b59a479ae65a02b097da86474", + "zh:fe7502d8e52d3b5ccb2b3c178e7ea894344783093aa71ffb20e978914c976182", + ] +} diff --git a/infra/src/cloudfront.tf b/infra/src/cloudfront.tf new file mode 100644 index 000000000..1e130f8e9 --- /dev/null +++ b/infra/src/cloudfront.tf @@ -0,0 +1,169 @@ +# Shared cache behaviors for both main and preview distributions +locals { + shared_cache_behaviors = [ + { + path_pattern = "/business-operations-framework-docs/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/business-operations-framework-docs" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/mojaloop-business-docs/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/mojaloop-business-docs" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/reference-architecture-doc/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/reference-architecture-doc" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/charts/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/helm/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/wso2-helm-charts-simple/*" + target_origin_id = "mojaloop.github.io" + }, + { + path_pattern = "/finance-portal-v2-ui/*" + target_origin_id = "mojaloop.github.io" + } + ] +} + +# CloudFront +# Creates the CloudFront distribution to serve the static website +resource "aws_cloudfront_distribution" "website_cdn_root" { + provider = aws.custom + enabled = true + price_class = "PriceClass_All" + + depends_on = [ + aws_s3_bucket.website_root + ] + + aliases = [var.website-domain-main] + + // base docs.mojaloop.io origin + origin { + origin_id = "origin-bucket-${aws_s3_bucket.website_root.id}" + domain_name = aws_s3_bucket.website_root.website_endpoint + + custom_origin_config { + origin_protocol_policy = "http-only" + http_port = 80 + https_port = 443 + origin_ssl_protocols = ["TLSv1.2", "TLSv1.1", "TLSv1"] + } + } + + // other origins for sites hosted at docs.mojaloop.io/ + origin { + origin_id = "mojaloop.github.io" + domain_name = "mojaloop.github.io" + custom_origin_config { + origin_protocol_policy = "match-viewer" + http_port = 80 + https_port = 443 + origin_ssl_protocols = ["TLSv1.2", "TLSv1.1", "TLSv1"] + } + } + + default_root_object = "index.html" + + logging_config { + bucket = aws_s3_bucket.website_logs.bucket_domain_name + prefix = "${var.website-domain-main}/" + } + + # Shared cache behaviors for main distribution + dynamic "ordered_cache_behavior" { + for_each = local.shared_cache_behaviors + content { + path_pattern = ordered_cache_behavior.value.path_pattern + target_origin_id = ordered_cache_behavior.value.target_origin_id + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + viewer_protocol_policy = "allow-all" + forwarded_values { + query_string = false + cookies { + forward = "none" + } + } + } + } + + default_cache_behavior { + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = "origin-bucket-${aws_s3_bucket.website_root.id}" + min_ttl = "0" + default_ttl = "300" + max_ttl = "1200" + + viewer_protocol_policy = "redirect-to-https" + compress = true + forwarded_values { + query_string = false + cookies { + forward = "none" + } + } + + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.docs-redirects.arn + } + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + viewer_certificate { + acm_certificate_arn = var.cloudfront-certificate-arn + ssl_support_method = "sni-only" + } + custom_error_response { + error_caching_min_ttl = 300 + error_code = 404 + response_page_path = "/404.html" + response_code = 404 + } + + tags = merge(var.tags, { + ManagedBy = "terraform" + Changed = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp()) + }) + + lifecycle { + ignore_changes = [ + tags["Changed"], + viewer_certificate, + ] + } +} + +resource "aws_cloudfront_function" "docs-redirects" { + provider = aws.custom + name = "${replace(var.website-domain-main, ".", "-")}-docs-redirects" + runtime = "cloudfront-js-1.0" + comment = "main" + publish = true + code = file("${path.module}/redirect/index.js") +} diff --git a/infra/src/iam.tf b/infra/src/iam.tf new file mode 100644 index 000000000..7493166a6 --- /dev/null +++ b/infra/src/iam.tf @@ -0,0 +1,52 @@ + +resource "aws_iam_group_policy" "infa_group_policy" { + provider = aws.custom + name = "${var.website-domain-main}-infra" + group = aws_iam_group.infra_group.name + policy = < { + if (uri.endsWith(m.from)) { + var newurl = uri.replace(m.from, m.to) + response = { + statusCode: 301, + statusDescription: 'Moved Permanently', + headers: { "location": { "value": newurl } } + } + } + }) + if (response) { + return response + } + + // fallthrough + return request +} diff --git a/infra/src/redirect/link_list.md b/infra/src/redirect/link_list.md new file mode 100644 index 000000000..9989f4c52 --- /dev/null +++ b/infra/src/redirect/link_list.md @@ -0,0 +1,196 @@ + + +## migrated already - has a new location +/mojaloop-specification/;/api/ +/mojaloop-specification/fspiop-api/documents/Logical-Data-Model.html;/api/fspiop/logical-data-model.html +/mojaloop-specification/fspiop-api/documents/Generic-Transaction-Patterns.html;/api/fspiop/generic-transaction-patterns.html +/mojaloop-specification/fspiop-api/documents/Use-Cases.html;/api/fspiop/use-cases.html +/mojaloop-specification/admin-api/admin-api-specification-v1.0.html;/api/administration/ +/mojaloop-specification/fspiop-api/documents/Scheme-Rules.html;/api/fspiop/scheme-rules.html +/mojaloop-specification/fspiop-api/documents/JSON-Binding-Rules.html;/api/fspiop/json-binding-rules.html +/mojaloop-specification/fspiop-api/documents/PKI-Best-Practices.html;/api/fspiop/pki-best-practices.html +/mojaloop-specification/fspiop-api/documents/Signature_v1.1.html;/api/fspiop/v1.1/signature.html +/mojaloop-specification/fspiop-api/documents/Encryption_v1.1.html;/api/fspiop/v1.1/encryption.html +/mojaloop-specification/ccb-meetings/;https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings +/mojaloop-specification/ccb-meetings/Issue-and-Decision-Log.html;https://github.com/mojaloop/mojaloop-specification/issues +/documentation/;/ +/documentation/mojaloop-background/;/not_found.html +/documentation/mojaloop-background/core-scenarios.html;/not_found.html +/documentation/mojaloop-background/level-one-principles.html;/not_found.html +/documentation/onboarding.html;/not_found.html +/documentation/deployment-guide/;/legacy/deployment-guide/ +/documentation/deployment-guide/releases.html;/legacy/deployment-guide/releases.html +/documentation/deployment-guide/local-setup-linux.html;/legacy/deployment-guide/local-setup-linux.html +/documentation/deployment-guide/local-setup-mac.html;/legacy/deployment-guide/local-setup-mac.html +/documentation/deployment-guide/local-setup-windows.html;/legacy/deployment-guide/local-setup-windows.html +/documentation/deployment-guide/deployment-troubleshooting.html;/legacy/deployment-guide/deployment-troubleshooting.html +/documentation/deployment-guide/upgrade-strategy-guide.html;/legacy/deployment-guide/upgrade-strategy-guide.html +/documentation/deployment-guide/helm-legacy-migration.html;/legacy/deployment-guide/helm-legacy-migration.html +/documentation/deployment-guide/helm-legacy-deployment.html;/legacy/deployment-guide/helm-legacy-deployment.html +/documentation/contributors-guide/;/community/contributing/contributors-guide.html +/documentation/contributors-guide/new-contributor-checklist.html;/community/contributing/new-contributor-checklist.html +/documentation/contributors-guide/code-of-conduct.html;/community/contributing/code-of-conduct.html +/documentation/contributors-guide/signing-the-cla.html;/community/contributing/signing-the-cla.html +/documentation/contributors-guide/frequently-asked-questions.html;/getting-started/faqs.html +/documentation/contributors-guide/standards/;/community/standards/guide.html +/documentation/contributors-guide/standards/versioning.html;/community/standards/versioning.html +/documentation/contributors-guide/standards/creating-new-features.html;/community/standards/creating-new-features.html +/documentation/contributors-guide/standards/triaging-ml-oss-bugs.html;/community/standards/triaging-bugs.html +/documentation/contributors-guide/tools-and-technologies/;/community/tools/tools-and-technologies.html +/documentation/contributors-guide/tools-and-technologies/pragmatic-rest.html;/community/tools/pragmatic-rest.html +/documentation/contributors-guide/tools-and-technologies/code-quality-metrics.html;/community/tools/code-quality-metrics.html +/documentation/contributors-guide/tools-and-technologies/automated-testing.html;/community/tools/automated-testing.html +/documentation/contributors-guide/documentation/;/community/documentation/standards.html +/documentation/contributors-guide/documentation/api-documentation.html;/community/documentation/api-documentation.html +/documentation/contributors-guide/documentation/documentation-style-guide.html;/community/documentation/style-guide.html +/documentation/mojaloop-roadmap.html;/community/mojaloop-roadmap.html +/documentation/mojaloop-publications.html;/community/mojaloop-publications.html +/documentation/discussions/readme.html;/community/archive/discussion-docs/ +/documentation/discussions/ISO_Integration.html;/community/archive/discussion-docs/ +/documentation/discussions/decimal.html;/community/archive/discussion-docs/ +/documentation/discussions/workbench.html;/community/archive/discussion-docs/ +/documentation/discussions/cross_border_day_1.html;/community/archive/discussion-docs/ +/documentation/discussions/cross_border_day_2.html;/community/archive/discussion-docs/ +/documentation/meeting-notes/readme.html;/not_found.html +/documentation/meeting-notes/scrum-of-scrum-notes.html;/not_found.html +/documentation/meeting-notes/da-notes.html;/not_found.html +/documentation/meeting-notes/ccb-notes.html;/not_found.html +/documentation/quality-security/readme.html;/legacy/quality-security/readme.html +/documentation/quality-security/program-management/readme.html;/legacy/quality-security/program-management/readme.html +/documentation/quality-security/program-management/vulnerability-disclosure-procedure.html;/legacy/quality-security/program-management/vulnerability-disclosure-procedure.html +/documentation/quality-security/program-management/scheme-rules-guidelines.html;/legacy/quality-security/program-management/scheme-rules-guidelines.html +/documentation/quality-security/standards-guidelines/readme.html;/legacy/quality-security/standards-guidelines/readme.html +/documentation/quality-security/reference-implementation.html;/legacy/quality-security/reference-implementation.html +/documentation/api/;/api/ +/documentation/api/central-ledger-api-specification.html;/api/administration/ +/documentation/api/central-settlements-api-specification.html;/api/settlement/ +/documentation/api/als-oracle-api-specification.html;/legacy/api/als-oracle-api-specification.html +/documentation/mojaloop-technical-overview/;/legacy/mojaloop-technical-overview/ +/documentation/mojaloop-technical-overview/overview/;/legacy/mojaloop-technical-overview/overview/ +/documentation/mojaloop-technical-overview/overview/components-PI14.html;/legacy/mojaloop-technical-overview/overview/components-PI14.html +/documentation/mojaloop-technical-overview/overview/components-PI12.html;/legacy/mojaloop-technical-overview/overview/components-PI12.html +/documentation/mojaloop-technical-overview/overview/components-PI11.html;/legacy/mojaloop-technical-overview/overview/components-PI11.html +/documentation/mojaloop-technical-overview/overview/components-PI8.html;/legacy/mojaloop-technical-overview/overview/components-PI8.html +/documentation/mojaloop-technical-overview/overview/components-PI7.html;/legacy/mojaloop-technical-overview/overview/components-PI7.html +/documentation/mojaloop-technical-overview/overview/components-PI6.html;/legacy/mojaloop-technical-overview/overview/components-PI6.html +/documentation/mojaloop-technical-overview/overview/components-PI5.html;/legacy/mojaloop-technical-overview/overview/components-PI5.html +/documentation/mojaloop-technical-overview/overview/components-PI3.html;/legacy/mojaloop-technical-overview/overview/components-PI3.html +/documentation/mojaloop-technical-overview/account-lookup-service/;/legacy/mojaloop-technical-overview/account-lookup-service/ +/documentation/mojaloop-technical-overview/account-lookup-service/als-get-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-get-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-post-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-del-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-del-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-get-parties.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-get-parties.html +/documentation/mojaloop-technical-overview/quoting-service/;/legacy/mojaloop-technical-overview/quoting-service/ +/documentation/mojaloop-technical-overview/quoting-service/qs-get-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-get-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-post-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-post-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.html +/documentation/mojaloop-technical-overview/central-ledger/;/legacy/mojaloop-technical-overview/central-ledger/ +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/ +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/;/legacy/mojaloop-technical-overview/central-ledger/transfers/ +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/;/legacy/mojaloop-technical-overview/central-bulk-transfers/ +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-settlements/;/legacy/mojaloop-technical-overview/central-settlements/ +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/ +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/ +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.html +/documentation/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.html;/legacy/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.html +/documentation/mojaloop-technical-overview/transaction-requests-service/;/legacy/mojaloop-technical-overview/transaction-requests-service/ +/documentation/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.html;/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.html +/documentation/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.html;/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.html +/documentation/mojaloop-technical-overview/transaction-requests-service/authorizations.html;/legacy/mojaloop-technical-overview/transaction-requests-service/authorizations.html +/documentation/mojaloop-technical-overview/central-event-processor/;/legacy/mojaloop-technical-overview/central-event-processor/ +/documentation/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.html;/legacy/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.html +/documentation/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.html;/legacy/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.html +/documentation/mojaloop-technical-overview/central-event-processor/signature-validation.html;/legacy/mojaloop-technical-overview/central-event-processor/signature-validation.html +/documentation/mojaloop-technical-overview/event-framework/;/legacy/mojaloop-technical-overview/event-framework/ +/documentation/mojaloop-technical-overview/event-stream-processor/;/legacy/mojaloop-technical-overview/event-stream-processor/ +/documentation/mojaloop-technical-overview/fraud-services/;/legacy/mojaloop-technical-overview/fraud-services/ +/documentation/mojaloop-technical-overview/fraud-services/related-documents/documentation.html;/legacy/mojaloop-technical-overview/fraud-services/related-documents/documentation.html +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/ +/documentation/mojaloop-technical-overview/ml-testing-toolkit/;/legacy/mojaloop-technical-overview/ml-testing-toolkit/ +/documentation/repositories/;/legacy/repositories/ +/documentation/repositories/helm.html;/legacy/repositories/helm.html +/documentation/repositories/project.html;/legacy/repositories/project.html +/documentation/glossary.html;/legacy/glossary.html +/documentation/discussions/Mojaloop%20Performance%202020.pdf;/legacy/discussions/Mojaloop%20Performance%202020.pdf + + + + +## not yet migrated + +/mojaloop-specification/fspiop-api/documents/Glossary.html +/mojaloop-specification/fspiop-api/documents/API-Definition_v1.1.html +/documentation/api/mojaloop-api-specification.html + + diff --git a/infra/src/redirect/link_list.txt b/infra/src/redirect/link_list.txt new file mode 100644 index 000000000..e92fb9247 --- /dev/null +++ b/infra/src/redirect/link_list.txt @@ -0,0 +1,182 @@ +/mojaloop-specification/;/api/ +/mojaloop-specification/fspiop-api/documents/Logical-Data-Model.html;/api/fspiop/logical-data-model.html +/mojaloop-specification/fspiop-api/documents/Generic-Transaction-Patterns.html;/api/fspiop/generic-transaction-patterns.html +/mojaloop-specification/fspiop-api/documents/Use-Cases.html;/api/fspiop/use-cases.html +/mojaloop-specification/admin-api/admin-api-specification-v1.0.html;/api/administration/ +/mojaloop-specification/fspiop-api/documents/Scheme-Rules.html;/api/fspiop/scheme-rules.html +/mojaloop-specification/fspiop-api/documents/JSON-Binding-Rules.html;/api/fspiop/json-binding-rules.html +/mojaloop-specification/fspiop-api/documents/PKI-Best-Practices.html;/api/fspiop/pki-best-practices.html +/mojaloop-specification/fspiop-api/documents/Signature_v1.1.html;/api/fspiop/v1.1/signature.html +/mojaloop-specification/fspiop-api/documents/Encryption_v1.1.html;/api/fspiop/v1.1/encryption.html +/mojaloop-specification/ccb-meetings/;https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings +/mojaloop-specification/ccb-meetings/Issue-and-Decision-Log.html;https://github.com/mojaloop/mojaloop-specification/issues +/documentation/;/ +/documentation/mojaloop-background/;/not_found.html +/documentation/mojaloop-background/core-scenarios.html;/not_found.html +/documentation/mojaloop-background/level-one-principles.html;/not_found.html +/documentation/onboarding.html;/not_found.html +/documentation/deployment-guide/;/legacy/deployment-guide/ +/documentation/deployment-guide/releases.html;/legacy/deployment-guide/releases.html +/documentation/deployment-guide/local-setup-linux.html;/legacy/deployment-guide/local-setup-linux.html +/documentation/deployment-guide/local-setup-mac.html;/legacy/deployment-guide/local-setup-mac.html +/documentation/deployment-guide/local-setup-windows.html;/legacy/deployment-guide/local-setup-windows.html +/documentation/deployment-guide/deployment-troubleshooting.html;/legacy/deployment-guide/deployment-troubleshooting.html +/documentation/deployment-guide/upgrade-strategy-guide.html;/legacy/deployment-guide/upgrade-strategy-guide.html +/documentation/deployment-guide/helm-legacy-migration.html;/legacy/deployment-guide/helm-legacy-migration.html +/documentation/deployment-guide/helm-legacy-deployment.html;/legacy/deployment-guide/helm-legacy-deployment.html +/documentation/contributors-guide/;/community/contributing/contributors-guide.html +/documentation/contributors-guide/new-contributor-checklist.html;/community/contributing/new-contributor-checklist.html +/documentation/contributors-guide/code-of-conduct.html;/community/contributing/code-of-conduct.html +/documentation/contributors-guide/signing-the-cla.html;/community/contributing/signing-the-cla.html +/documentation/contributors-guide/frequently-asked-questions.html;/getting-started/faqs.html +/documentation/contributors-guide/standards/;/community/standards/guide.html +/documentation/contributors-guide/standards/versioning.html;/community/standards/versioning.html +/documentation/contributors-guide/standards/creating-new-features.html;/community/standards/creating-new-features.html +/documentation/contributors-guide/standards/triaging-ml-oss-bugs.html;/community/standards/triaging-bugs.html +/documentation/contributors-guide/tools-and-technologies/;/community/tools/tools-and-technologies.html +/documentation/contributors-guide/tools-and-technologies/pragmatic-rest.html;/community/tools/pragmatic-rest.html +/documentation/contributors-guide/tools-and-technologies/code-quality-metrics.html;/community/tools/code-quality-metrics.html +/documentation/contributors-guide/tools-and-technologies/automated-testing.html;/community/tools/automated-testing.html +/documentation/contributors-guide/documentation/;/community/documentation/standards.html +/documentation/contributors-guide/documentation/api-documentation.html;/community/documentation/api-documentation.html +/documentation/contributors-guide/documentation/documentation-style-guide.html;/community/documentation/style-guide.html +/documentation/mojaloop-roadmap.html;/community/mojaloop-roadmap.html +/documentation/mojaloop-publications.html;/community/mojaloop-publications.html +/documentation/discussions/readme.html;/community/archive/discussion-docs/ +/documentation/discussions/ISO_Integration.html;/community/archive/discussion-docs/ +/documentation/discussions/decimal.html;/community/archive/discussion-docs/ +/documentation/discussions/workbench.html;/community/archive/discussion-docs/ +/documentation/discussions/cross_border_day_1.html;/community/archive/discussion-docs/ +/documentation/discussions/cross_border_day_2.html;/community/archive/discussion-docs/ +/documentation/meeting-notes/readme.html;/not_found.html +/documentation/meeting-notes/scrum-of-scrum-notes.html;/not_found.html +/documentation/meeting-notes/da-notes.html;/not_found.html +/documentation/meeting-notes/ccb-notes.html;/not_found.html +/documentation/quality-security/readme.html;/legacy/quality-security/readme.html +/documentation/quality-security/program-management/readme.html;/legacy/quality-security/program-management/readme.html +/documentation/quality-security/program-management/vulnerability-disclosure-procedure.html;/legacy/quality-security/program-management/vulnerability-disclosure-procedure.html +/documentation/quality-security/program-management/scheme-rules-guidelines.html;/legacy/quality-security/program-management/scheme-rules-guidelines.html +/documentation/quality-security/standards-guidelines/readme.html;/legacy/quality-security/standards-guidelines/readme.html +/documentation/quality-security/reference-implementation.html;/legacy/quality-security/reference-implementation.html +/documentation/api/;/api/ +/documentation/api/central-ledger-api-specification.html;/api/administration/ +/documentation/api/central-settlements-api-specification.html;/api/settlement/ +/documentation/api/als-oracle-api-specification.html;/legacy/api/als-oracle-api-specification.html +/documentation/mojaloop-technical-overview/;/legacy/mojaloop-technical-overview/ +/documentation/mojaloop-technical-overview/overview/;/legacy/mojaloop-technical-overview/overview/ +/documentation/mojaloop-technical-overview/overview/components-PI14.html;/legacy/mojaloop-technical-overview/overview/components-PI14.html +/documentation/mojaloop-technical-overview/overview/components-PI12.html;/legacy/mojaloop-technical-overview/overview/components-PI12.html +/documentation/mojaloop-technical-overview/overview/components-PI11.html;/legacy/mojaloop-technical-overview/overview/components-PI11.html +/documentation/mojaloop-technical-overview/overview/components-PI8.html;/legacy/mojaloop-technical-overview/overview/components-PI8.html +/documentation/mojaloop-technical-overview/overview/components-PI7.html;/legacy/mojaloop-technical-overview/overview/components-PI7.html +/documentation/mojaloop-technical-overview/overview/components-PI6.html;/legacy/mojaloop-technical-overview/overview/components-PI6.html +/documentation/mojaloop-technical-overview/overview/components-PI5.html;/legacy/mojaloop-technical-overview/overview/components-PI5.html +/documentation/mojaloop-technical-overview/overview/components-PI3.html;/legacy/mojaloop-technical-overview/overview/components-PI3.html +/documentation/mojaloop-technical-overview/account-lookup-service/;/legacy/mojaloop-technical-overview/account-lookup-service/ +/documentation/mojaloop-technical-overview/account-lookup-service/als-get-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-get-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-post-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-del-participants.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-del-participants.html +/documentation/mojaloop-technical-overview/account-lookup-service/als-get-parties.html;/legacy/mojaloop-technical-overview/account-lookup-service/als-get-parties.html +/documentation/mojaloop-technical-overview/quoting-service/;/legacy/mojaloop-technical-overview/quoting-service/ +/documentation/mojaloop-technical-overview/quoting-service/qs-get-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-get-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-post-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-post-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.html +/documentation/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.html;/legacy/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.html +/documentation/mojaloop-technical-overview/central-ledger/;/legacy/mojaloop-technical-overview/central-ledger/ +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/ +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.html +/documentation/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.html;/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/;/legacy/mojaloop-technical-overview/central-ledger/transfers/ +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.html +/documentation/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.html;/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/;/legacy/mojaloop-technical-overview/central-bulk-transfers/ +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.html;/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.html +/documentation/mojaloop-technical-overview/central-settlements/;/legacy/mojaloop-technical-overview/central-settlements/ +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/ +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.html +/documentation/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.html;/legacy/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/ +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.html +/documentation/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.html;/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.html +/documentation/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.html;/legacy/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.html +/documentation/mojaloop-technical-overview/transaction-requests-service/;/legacy/mojaloop-technical-overview/transaction-requests-service/ +/documentation/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.html;/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.html +/documentation/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.html;/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.html +/documentation/mojaloop-technical-overview/transaction-requests-service/authorizations.html;/legacy/mojaloop-technical-overview/transaction-requests-service/authorizations.html +/documentation/mojaloop-technical-overview/central-event-processor/;/legacy/mojaloop-technical-overview/central-event-processor/ +/documentation/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.html;/legacy/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.html +/documentation/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.html;/legacy/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.html +/documentation/mojaloop-technical-overview/central-event-processor/signature-validation.html;/legacy/mojaloop-technical-overview/central-event-processor/signature-validation.html +/documentation/mojaloop-technical-overview/event-framework/;/legacy/mojaloop-technical-overview/event-framework/ +/documentation/mojaloop-technical-overview/event-stream-processor/;/legacy/mojaloop-technical-overview/event-stream-processor/ +/documentation/mojaloop-technical-overview/fraud-services/;/legacy/mojaloop-technical-overview/fraud-services/ +/documentation/mojaloop-technical-overview/fraud-services/related-documents/documentation.html;/legacy/mojaloop-technical-overview/fraud-services/related-documents/documentation.html +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/ +/documentation/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/;/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/ +/documentation/mojaloop-technical-overview/ml-testing-toolkit/;/legacy/mojaloop-technical-overview/ml-testing-toolkit/ +/documentation/repositories/;/legacy/repositories/ +/documentation/repositories/helm.html;/legacy/repositories/helm.html +/documentation/repositories/project.html;/legacy/repositories/project.html +/documentation/glossary.html;/legacy/glossary.html +/documentation/discussions/Mojaloop%20Performance%202020.pdf;/legacy/discussions/Mojaloop%20Performance%202020.pdf \ No newline at end of file diff --git a/infra/src/s3.tf b/infra/src/s3.tf new file mode 100644 index 000000000..4221a5704 --- /dev/null +++ b/infra/src/s3.tf @@ -0,0 +1,74 @@ +# Creates bucket to store logs +resource "aws_s3_bucket" "website_logs" { + provider = aws.custom + bucket = "${var.website-domain-main}-logs" + acl = "log-delivery-write" + + # Comment the following line if you are uncomfortable with Terraform destroying the bucket even if this one is not empty + force_destroy = true + + tags = merge(var.tags, { + ManagedBy = "terraform" + Changed = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp()) + }) + + lifecycle { + ignore_changes = [tags["Changed"]] + } +} + +# Creates bucket to store the static website +resource "aws_s3_bucket" "website_root" { + provider = aws.custom + bucket = "${var.website-domain-main}-root" + acl = "public-read" + + # Comment the following line if you are uncomfortable with Terraform destroying the bucket even if not empty + force_destroy = true + + logging { + target_bucket = aws_s3_bucket.website_logs.bucket + target_prefix = "${var.website-domain-main}/" + } + + website { + index_document = "index.html" + error_document = "404.html" + } + + tags = merge(var.tags, { + ManagedBy = "mojaloop/documentation" + Changed = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp()) + }) + + lifecycle { + ignore_changes = [tags["Changed"]] + } +} + +# Creates policy to allow public access to the S3 bucket +resource "aws_s3_bucket_policy" "update_website_root_bucket_policy" { + provider = aws.custom + bucket = aws_s3_bucket.website_root.id + policy = < git.log + + echo "Checking out $GITBOOK_TARGET_BRANCH" + git checkout -b $GITBOOK_TARGET_BRANCH $GITHUB_PROJECT_USERNAME/$GITBOOK_TARGET_BRANCH &> git.log + + echo "Pulling latest code from $GITBOOK_TARGET_BRANCH branch..." + git pull -q $GITHUB_PROJECT_USERNAME $GITBOOK_TARGET_BRANCH --rebase &> git.log + + echo "Copying contents of _book to root..." + cp -R _book/* . + + echo "Staging general changes..." + git add . + + echo "Staging generated UML..." + git add -f assets/images/uml/*.* + + echo "Commiting changes..." + git commit -a -m "Updating release to $GITHUB_TAG" + + echo "Publishing $GITHUB_TAG release to $GITBOOK_TARGET_BRANCH on github..." + git push -q $GITHUB_PROJECT_USERNAME $GITBOOK_TARGET_BRANCH &> git.log +## +# Executors +# +# CircleCI Executors +## +executors: + default-docker: + working_directory: /home/circleci/project + docker: + - image: node:10.15-alpine + + default-machine: + machine: + image: ubuntu-1604:201903-01 + +## +# Jobs +# +# A map of CircleCI jobs +## +jobs: + setup: + executor: default-docker + steps: + - checkout + - run: + <<: *defaults_Dependencies + - run: + name: Access npm folder as root + command: cd $(npm root -g)/npm + - run: + name: Update NPM install + command: npm ci + - run: + name: Delete build dependencies + command: apk del build-dependencies + - save_cache: + key: dependency-cache-{{ checksum "package-lock.json" }} + paths: + - node_modules + + build: + executor: default-docker + steps: + - checkout + - run: + <<: *defaults_Dependencies + - run: + name: Installing build dependencies + command: | + echo 'Installing build dependencies via APK' + apk add --no-cache -t gitbook-build-dependencies openjdk8-jre graphviz ttf-droid ttf-droid-nonlatin + + echo 'Setting env vars' + echo 'export PLANTUML_VERSION=$PLANTUML_VERSION' >> $BASH_ENV + echo 'export LANG=$PLANTUML_LANG' >> $BASH_ENV + + echo 'Downloading plantuml jar' + curl -L https://sourceforge.net/projects/plantuml/files/plantuml.${PLANTUML_VERSION}.jar/download -o plantuml.jar + - restore_cache: + keys: + - dependency-cache-{{ checksum "package-lock.json" }} + - run: + name: Build Gitbooks + command: | + npm run gitbook:build + - save_cache: + key: build-cache-{{ checksum "package-lock.json" }} + paths: + - _book + + test-svg: + executor: default-machine + steps: + - checkout + - run: + name: Set up NVM + command: | + echo ${NVM_DIR} + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + nvm install v10.15.3 + nvm alias default v10.15.3 + node --version + npm ci + - run: + name: Check if plantuml has been updated correctly + command: | + set +o pipefail + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + npm run build:plantuml:all + FILE_COUNT=$(git diff --name-only | grep .svg | wc -l) + if [ ${FILE_COUNT} -ne "0" ]; then + echo "${FILE_COUNT} plantuml files are out of sync. Please run npm run build:plantuml and try again."; + exit 1; + else + echo 'Plantuml files are up to date'; + fi + + deploy: + executor: default-docker + steps: + - checkout + - run: + <<: *defaults_Dependencies + - run: + name: setup environment vars + command: | + echo 'export GITBOOK_TARGET_BRANCH=$GITBOOK_TARGET_BRANCH' >> $BASH_ENV + echo 'export GITHUB_TOKEN=$GITHUB_TOKEN' >> $BASH_ENV + echo 'export GITHUB_PROJECT_USERNAME=$CIRCLE_PROJECT_USERNAME' >> $BASH_ENV + echo 'export GITHUB_PROJECT_REPONAME=$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV + echo 'export GITHUB_TAG=$CIRCLE_TAG' >> $BASH_ENV + echo 'export GIT_CI_USER=$GIT_CI_USER' >> $BASH_ENV + echo 'export GIT_CI_EMAIL=$GIT_CI_EMAIL' >> $BASH_ENV + - restore_cache: + keys: + - build-cache-{{ checksum "package-lock.json" }} + - run: + <<: *defaults_git_identity_setup + - run: + <<: *defaults_publish_to_gh_pages + - run: + <<: *defaults_slack_announcement + +## +# Workflows +# +# CircleCI Workflow config +## +workflows: + version: 2 + build_and_test: + jobs: + - pr-tools/pr-title-check: + context: org-global + - setup: + context: org-global + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature.*/ + - /bugfix.*/ + - gh-pages + - test-svg: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature*/ + - /bugfix*/ + - build: + context: org-global + requires: + - setup + filters: + tags: + only: /.*/ + branches: + ignore: + - /feature.*/ + - /bugfix.*/ + - gh-pages + - deploy: + context: org-global + requires: + - build + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*/ + branches: + ignore: + - /.*/ diff --git a/.dockerignore b/legacy/.dockerignore similarity index 100% rename from .dockerignore rename to legacy/.dockerignore diff --git a/.gitbook.md b/legacy/.gitbook.md similarity index 100% rename from .gitbook.md rename to legacy/.gitbook.md diff --git a/legacy/.gitignore b/legacy/.gitignore new file mode 100644 index 000000000..5f1920278 --- /dev/null +++ b/legacy/.gitignore @@ -0,0 +1,24 @@ +# --------------- # +# IntelliJ # +# --------------- # +.idea/ +**/*.iml + +# VSCode directory +.vscode + +# Node +node_modules + +# Gitbook +_book + +# Gitbook UML +**/uml + +# MacOs +.DS_Store + +*.log + +*.jar diff --git a/.ncurc.json b/legacy/.ncurc.json similarity index 100% rename from .ncurc.json rename to legacy/.ncurc.json diff --git a/legacy/.nvmrc b/legacy/.nvmrc new file mode 100644 index 000000000..95abd2ac4 --- /dev/null +++ b/legacy/.nvmrc @@ -0,0 +1 @@ +10.15.2 diff --git a/legacy/CODEOWNERS b/legacy/CODEOWNERS new file mode 100644 index 000000000..8d2572104 --- /dev/null +++ b/legacy/CODEOWNERS @@ -0,0 +1,38 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +## These owners will be the default owners for everything in +## the repo. Unless a later match takes precedence, +## @global-owner1 and @global-owner2 will be requested for +## review when someone opens a pull request. +#* @global-owner1 @global-owner2 +* @millerabel @mdebarros @kjw000 @elnyry-sam-k @lewisdaly @simeonoriko + +## Order is important; the last matching pattern takes the most +## precedence. When someone opens a pull request that only +## modifies JS files, only @js-owner and not the global +## owner(s) will be requested for a review. +# *.js @js-owner + +## You can also use email addresses if you prefer. They'll be +## used to look up users just like we do for commit author +## emails. +#*.go docs@example.com + +# In this example, @doctocat owns any files in the build/logs +# directory at the root of the repository and any of its +# subdirectories. +# /build/logs/ @doctocat + +## The `docs/*` pattern will match files like +## `docs/getting-started.md` but not further nested files like +## `docs/build-app/troubleshooting.md`. +# docs/* docs@example.com + +## In this example, @octocat owns any file in an apps directory +## anywhere in your repository. +#apps/ @octocat + +## In this example, @doctocat owns any file in the `/docs` +## directory in the root of your repository. +#/docs/ @doctocat diff --git a/Dockerfile b/legacy/Dockerfile similarity index 100% rename from Dockerfile rename to legacy/Dockerfile diff --git a/legacy/LICENSE.md b/legacy/LICENSE.md new file mode 100644 index 000000000..40350591c --- /dev/null +++ b/legacy/LICENSE.md @@ -0,0 +1,10 @@ +# LICENSE + +Copyright © 2020 Mojaloop Foundation + +The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 +(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). + +You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/legacy/NOTES.md b/legacy/NOTES.md new file mode 100644 index 000000000..5f37bea56 --- /dev/null +++ b/legacy/NOTES.md @@ -0,0 +1,51 @@ +# Documentation Notes + +Helpers and notes for building and working on these docs. + + +## Building `.svg`s from plantuml sources + +We use a git commit hook to automatically rebuild `.svg` files from plantuml +sources. The magic of git hooks means that no extra work is required by you +after creating or editing a `.puml` file + +Behind the scenes, this hook spins up a docker container to run the PUML server +and calls `./scripts/_render_svg.mjs` for each file that has changed. We use the +docker version instead of the public puml server to (1) get around rate limits, and +(2) ensure deterministic SVG output that is git diffable. + +### Creating a new PUML + +1. Create a new `*.puml/plantuml` file +2. Add the file and generate the `.svg` + +```bash +git add . #(or the specific file you are working on) +npm run build:plantuml:diff +``` +3. Update your `.md` file to refer to the newly created `.svg` file +4. Git add/commit +### Updating an existing PUML + +1. Make changes to an existing `*.puml/plantuml` file +2. `git add` + `git commit` +3. The pre-commit hook rebuilds the changed SVG files, and adds them before the commit + +### Building all `.puml` sources manually + +You can also force a complete rebuild of all `.puml` and `.plantuml` sources like so: + +```bash +npm install +npm run build:plantuml:all +``` + +### `test-svg` CI/CD Step + +This is a ci/cd step that ensures that the `.svg` files have been updated +correctly, just in case something got out of sync on your branch before +merging a pull request. + +It runs `npm run build:plantuml:all` to build all of the plantuml sources +and if it detects file changes, it means something went wrong with the +commit hook (or you skipped it with `git commit -n`). diff --git a/legacy/README.md b/legacy/README.md new file mode 100644 index 000000000..a7a7247cb --- /dev/null +++ b/legacy/README.md @@ -0,0 +1,18 @@ +# Mojaloop Overview +[![Git Commit](https://img.shields.io/github/last-commit/mojaloop/documentation.svg?style=flat)](https://github.com/mojaloop/documentation/commits/master) +[![Git Releases](https://img.shields.io/github/release/mojaloop/documentation.svg?style=flat)](https://github.com/mojaloop/documentation/releases) +[![CircleCI](https://circleci.com/gh/mojaloop/documentation.svg?style=svg)](https://circleci.com/gh/mojaloop/documentation) + +Mojaloop is open source software for creating digital payments platforms that connect all customers, merchants, banks, and other financial providers in a country's economy. Rather than a financial product or application in itself, Mojaloop establishes a blueprint for technology that bridges all the financial products and applications in any given market. + +The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers \(DFSPs\) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. + +![Mojaloop Solution](./mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg) + +Our model addresses these issues in several key ways: + +* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. +* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. + +The intention for the Mojaloop project is for financial institutions and commercial providers to use the open-source software to help build digital, interoperable payments platforms that drive financial inclusion on a national scale. Specifically, the platforms will enable seamless, low-cost transactions between individual users, merchants, banks, providers, and even government offices - helping connect poor customers with everyone else in the digital economy. diff --git a/legacy/SUMMARY.md b/legacy/SUMMARY.md new file mode 100644 index 000000000..dbe3f67d4 --- /dev/null +++ b/legacy/SUMMARY.md @@ -0,0 +1,181 @@ +# Table of contents + +* [Mojaloop Overview](README.md) +* [Mojaloop Background](mojaloop-background/README.md) + * [Core Scenarios](mojaloop-background/core-scenarios.md) + * [Level One Principles](mojaloop-background/level-one-principles.md) +* [Onboarding](onboarding.md) +* [Deployment Guide](deployment-guide/README.md) + * [Releases](deployment-guide/releases.md) + * [Local Setup Linux](deployment-guide/local-setup-linux.md) + * [Local Setup Mac](deployment-guide/local-setup-mac.md) + * [Local Setup Windows](deployment-guide/local-setup-windows.md) + * [Troubleshooting](deployment-guide/deployment-troubleshooting.md) + * [Upgrade Strategy Guide](deployment-guide/upgrade-strategy-guide.md) + * [Helm v2 to v3 Migration Guide](deployment-guide/helm-legacy-migration.md) + * [Deployment with (Deprecated) Helm v2](deployment-guide/helm-legacy-deployment.md) +* [Contributors Guide](contributors-guide/README.md) + * [New Contributor Checklist](contributors-guide/new-contributor-checklist.md) + * [Code Of Conduct](contributors-guide/code-of-conduct.md) + * [Signing the CLA](contributors-guide/signing-the-cla.md) + * [FAQ](contributors-guide/frequently-asked-questions.md) + * [Standards](contributors-guide/standards/README.md) + * [Versioning](contributors-guide/standards/versioning.md) + * [Creating new Features](contributors-guide/standards/creating-new-features.md) + * [ML OSS Bug Triage](contributors-guide/standards/triaging-ml-oss-bugs.md) + * [Tools and Technologies](contributors-guide/tools-and-technologies/README.md) + * [Pragmatic REST](contributors-guide/tools-and-technologies/pragmatic-rest.md) + * [Code Quality Metrics](contributors-guide/tools-and-technologies/code-quality-metrics.md) + * [Automated Testing](contributors-guide/tools-and-technologies/automated-testing.md) + * [Documentation](contributors-guide/documentation/README.md) + * [API Documentation](contributors-guide/documentation/api-documentation.md) + * [Documentation Style Guide](contributors-guide/documentation/documentation-style-guide.md) +* [Mojaloop Technical Overview](mojaloop-technical-overview/README.md) + * [Mojaloop Hub](mojaloop-technical-overview/overview/README.md) + * [Current Architecture - PI14](mojaloop-technical-overview/overview/components-PI14.md) + * [Current Architecture - PI12](mojaloop-technical-overview/overview/components-PI12.md) + * [Legacy Architecture - PI11](mojaloop-technical-overview/overview/components-PI11.md) + * [Legacy Architecture - PI8](mojaloop-technical-overview/overview/components-PI8.md) + * [Legacy Architecture - PI7](mojaloop-technical-overview/overview/components-PI7.md) + * [Legacy Architecture - PI6](mojaloop-technical-overview/overview/components-PI6.md) + * [Legacy Architecture - PI5](mojaloop-technical-overview/overview/components-PI5.md) + * [Legacy Architecture - PI3](mojaloop-technical-overview/overview/components-PI3.md) + * [Account-Lookup Service](mojaloop-technical-overview/account-lookup-service/README.md) + * [GET Participants](mojaloop-technical-overview/account-lookup-service/als-get-participants.md) + * [POST Participants](mojaloop-technical-overview/account-lookup-service/als-post-participants.md) + * [POST Participants (batch)](mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md) + * [DEL Participants](mojaloop-technical-overview/account-lookup-service/als-del-participants.md) + * [GET Parties](mojaloop-technical-overview/account-lookup-service/als-get-parties.md) + * [Quoting Service Overview](mojaloop-technical-overview/quoting-service/README.md) + * [GET Quote](mojaloop-technical-overview/quoting-service/qs-get-quotes.md) + * [POST Quote](mojaloop-technical-overview/quoting-service/qs-post-quotes.md) + * [GET Bulk Quote](mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.md) + * [POST Bulk Quote](mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.md) + * [Central-Ledger Services](mojaloop-technical-overview/central-ledger/README.md) + * [Admin Operations](mojaloop-technical-overview/central-ledger/admin-operations/README.md) + * [POST Participant Limit](mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md) + * [GET Participant Limit Details](mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md) + * [GET All Participant Limits](mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md) + * [POST Participant limits](mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md) + * [GET Transfer Status](mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md) + * [POST Participant Callback](mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) + * [GET Participant Callback](mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md) + * [GET Participant Position](mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md) + * [GET All Participants Positions](mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md) + * [Transfer Operations](mojaloop-technical-overview/central-ledger/transfers/README.md) + * [Prepare Handler](mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md) + * [Prepare Handler Consume](mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md) + * [Prepare Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md) + * [Prepare Position Handler v1.1](mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md) + * [Prepare Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md) + * [Position Handler Consume](mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md) + * [Fulfil Handler](mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md) + * [Fulfil Handler v1.1](mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md) + * [Fulfil Handler Consume](mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md) + * [Fulfil Handler Consume v1.1](mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md) + * [Fulfil Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md) + * [Fulfil Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md) + * [Fulfil Position Handler v1.1](mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md) + * [Fulfil Reject Transfer](mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md) + * [Fulfil Reject Transfer (a)](mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md) + * [Fulfil Handler (Reject-Abort)](mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md) + * [Fulfil Reject Transfer v1.1](mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md) + * [Fulfil Reject Transfer (a) v1.1](mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md) + * [Fulfil Handler (Reject-Abort) v1.1](mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md) + * [Notifications]() + * [Notification to Participant (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md) + * [Notification to Participant (a) - v1.1](mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md) + * [Notification to Participant (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md) + * [Reject/Abort]() + * [Abort Position Handler](mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md) + * [Timeout]() + * [Transfer Timeout](mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md) + * [Timeout Handler Consume](mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md) + * [Bulk Transfer Operations](mojaloop-technical-overview/central-bulk-transfers/README.md) + * [Bulk Prepare Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md) + * [Bulk Prepare Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md) + * [Prepare Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md) + * [Position Handler Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md) + * [Prepare Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md) + * [Fulfil Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md) + * [Fulfil Abort Position Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md) + * [Bulk Fulfil Handler Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md) + * [Bulk Fulfil Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md) + * [Fulfil Handler - Commit](mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md) + * [Fulfil Handler - Reject/Abort](mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md) + * [Bulk Processing Handler](mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md) + * [Notifications]() + * [Notification to Participant (a)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md) + * [Notification to Participant (b)](mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md) + * [Timeout Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md) + * [Timeout Handler Consume](mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md) + * [Bulk Abort Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md) + * [Get Bulk Transfer Overview](mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md) + * [Central-Settlements Service](mojaloop-technical-overview/central-settlements/README.md) + * [Settlement Process](mojaloop-technical-overview/central-settlements/settlement-process/README.md) + * [Settlement Windows By Params](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md) + * [Request Settlement Window](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md) + * [Close Settlement Window](mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md) + * [Create Settlement](mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md) + * [Request Settlement](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md) + * [Settlement Transfer Acknowledgement](mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md) + * [Settlement Abort](mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md) + * [Request Settlement By SPA](mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md) + * [Request Settlements By Params](mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md) + * [Gross Settlement Handler](mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.md) + * [Rules Handler](mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.md) + * [Funds In/Out](mojaloop-technical-overview/central-settlements/funds-in-out/README.md) + * [Reconciliation Transfer Prepare](mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md) + * [Transfer State and Position Change](mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md) + * [Funds In](mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md) + * [Funds Out - Prepare & Reserve](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md) + * [Funds Out - Commit](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md) + * [Funds Out - Abort](mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md) + * [OSS Settlement FSD](mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md) + * [Transaction-requests-service Service](mojaloop-technical-overview/transaction-requests-service/README.md) + * [Transaction Requests Create](mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.md) + * [Transaction Requests Query](mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.md) + * [Authorizations](mojaloop-technical-overview/transaction-requests-service/authorizations.md) + * [Central-Event-Processor Services](mojaloop-technical-overview/central-event-processor/README.md) + * [Event Handler (Placeholder)](mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md) + * [Notification Handler For Rejections](mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md) + * [Signature Validation](mojaloop-technical-overview/central-event-processor/signature-validation.md) + * [Event Framework](mojaloop-technical-overview/event-framework/README.md) + * [Event Stream Processor](mojaloop-technical-overview/event-stream-processor/README.md) + * [Fraud Services](mojaloop-technical-overview/fraud-services/README.md) + * [Ecosystem Fraud Documentation](mojaloop-technical-overview/fraud-services/related-documents/documentation.md) + * [SDK Scheme Adapter](mojaloop-technical-overview/sdk-scheme-adapter/README.md) + * [Usage](mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md) + * [Scheme Adapter to Scheme Adapter](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md) + * [Scheme Adapter to Local ML Cluster](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md) + * [Scheme Adapter to WSO2 API Gateway](mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md) + * [ML Testing Toolkit](mojaloop-technical-overview/ml-testing-toolkit/README.md) +* [API Specifications](api/README.md) + * [Mojaloop](api/mojaloop-api-specification.md) + * [Central Ledger API](api/central-ledger-api-specification.md) + * [Central Settlements](api/central-settlements-api-specification.md) + * [ALS Oracle](api/als-oracle-api-specification.md) +* [Repo Details](repositories/README.md) + * [Helm](repositories/helm.md) + * [Project](repositories/project.md) +* [Mojaloop Roadmap](mojaloop-roadmap.md) +* [Mojaloop Publications](mojaloop-publications.md) +* [Discussion Documents](discussions/readme.md) + * [ISO integration Overivew](discussions/ISO_Integration.md) + * [Mojaloop Decimal Type; Based on XML Schema Decimal Type](discussions/decimal.md) + * [Workbench Workstream](discussions/workbench.md) + * [Cross Border Meeting Notes Day 1](discussions/cross_border_day_1.md) + * [Cross Border Meeting Notes Day 2](discussions/cross_border_day_2.md) +* [Mojaloop DA, CCB, Scrum-of-scrum Notes](meeting-notes/readme.md) + * [Scrum-of-scrum meeting notes](meeting-notes/scrum-of-scrum-notes.md) + * [DA meeting notes](meeting-notes/da-notes.md) + * [CCB Notes](meeting-notes/ccb-notes.md) +* [Code Quality and Security](quality-security/readme.md) + * [Program Management](quality-security/program-management/readme.md) + * [Vulnerability Reporting](quality-security/program-management/vulnerability-disclosure-procedure.md) + * [Scheme Rules Guidelines](quality-security/program-management/scheme-rules-guidelines.md) + * [Standards + Guidelines](quality-security/standards-guidelines/readme.md) + * [Reference Implementation](quality-security/reference-implementation.md) +* [Frequently Asked Questions](contributors-guide/frequently-asked-questions.md) +* [Glossary of Terms](glossary.md) + diff --git a/api/README.md b/legacy/api/README.md similarity index 100% rename from api/README.md rename to legacy/api/README.md diff --git a/api/als-oracle-api-specification.md b/legacy/api/als-oracle-api-specification.md similarity index 100% rename from api/als-oracle-api-specification.md rename to legacy/api/als-oracle-api-specification.md diff --git a/legacy/api/assets/interface-contracts/oracle-service-swagger-v1.yaml b/legacy/api/assets/interface-contracts/oracle-service-swagger-v1.yaml new file mode 100644 index 000000000..6851ebcc1 --- /dev/null +++ b/legacy/api/assets/interface-contracts/oracle-service-swagger-v1.yaml @@ -0,0 +1,1131 @@ +openapi: 3.0.0 +info: + version: '1.0' + title: >- + Interface for interaction between Mojaloop's Account Lookup Service(ALS) and + an Oracle Registry Service + description: >- + Based on Mojaloop [API + Definition](https://github.com/mojaloop/mojaloop-specification/blob/main/API%20Definition%20v1.1.pdf). + More information can be found at [mojaloop.io](http://mojaloop.io/) + contact: {} +paths: + /health: + get: + tags: + - health + responses: + '200': + $ref: '#/components/responses/200' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + operationId: HealthGet + summary: Get Server + description: >- + The HTTP request GET /health is used to return the current status of the + API. + /metrics: + get: + tags: + - metrics + responses: + '200': + $ref: '#/components/responses/200' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + operationId: MetricsGet + summary: Prometheus metrics endpoint + description: The HTTP request GET /metrics is used to return metrics for the API. + /participants/{Type}/{ID}: + parameters: + - $ref: '#/components/parameters/Type' + - $ref: '#/components/parameters/ID' + post: + description: > + The HTTP request `POST /participants/{Type}/{ID}` + + (or `POST /participants/{Type}/{ID}/{SubId}`) + + is used to create information in the server regarding the provided + identity, + + defined by `{Type}`, `{ID}`, and optionally `{SubId}` + + (for example, `POST /participants/MSISDN/123456789` or + + `POST /participants/BUSINESS/shoecompany/employee1`). + + An ExtensionList element has been added to this request in version v1.1 + summary: Create participant information + tags: + - participants + operationId: ParticipantsByTypeAndIDPost + requestBody: + description: Participant information to be created. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDPostPutRequest' + responses: + '201': + description: Created + headers: {} + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + get: + description: > + The HTTP request `GET /participants/{Type}/{ID}` (or `GET + /participants/{Type}/{ID}/{SubId}`) + + is used to find out in which FSP the requested Party, defined by + `{Type}`, `{ID}` and optionally `{SubId}`, + is located (for example, `GET /participants/MSISDN/123456789`, or + `GET /participants/BUSINESS/shoecompany/employee1`). + This HTTP request should support a query string for filtering of currency. + To use filtering of currency, the HTTP request `GET /participants/{Type}/{ID}?currency=XYZ` + should be used, where `XYZ` is the requested currency. + summary: Look up participant information + tags: + - participants + operationId: ParticipantsByTypeAndIDGet + parameters: + - $ref: '#/components/parameters/partySubIdOrType' + responses: + '200': + description: OK + headers: + Content-Length: + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDGetResponse' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + put: + description: | + The PUT /participants/{Type}/{ID} is used to update information in the + server regarding the provided identity, defined by {Type} and {ID} + (for example, PUT /participants/MSISDN/123456789). + summary: Update participant information + tags: + - participants + operationId: ParticipantsByTypeAndIDPut + requestBody: + description: Participant information returned. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDPostPutRequest' + responses: + '200': + $ref: '#/components/responses/200' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + delete: + description: > + The HTTP request `DELETE /participants/{Type}/{ID}` + + (or `DELETE /participants/{Type}/{ID}/{SubId}`) is used to delete + + information in the server regarding the provided identity, + + defined by `{Type}` and `{ID}`) (for example, `DELETE + /participants/MSISDN/123456789`), + + and optionally `{SubId}`. This HTTP request should support a query + + string to delete FSP information regarding a specific currency only. + + To delete a specific currency only, the HTTP request + + `DELETE /participants/{Type}/{ID}?currency=XYZ` + + should be used, where `XYZ` is the requested currency. + + + + **Note:** The Account Lookup System should verify that it is the Party’s + current FSP that is deleting the FSP information. + summary: Delete participant information + tags: + - participants + operationId: ParticipantsByTypeAndIDDelete + responses: + '204': + description: No Content + headers: {} + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + /participants/{Type}/{ID}/{SubId}: + parameters: + - $ref: '#/components/parameters/Type' + - $ref: '#/components/parameters/ID' + - $ref: '#/components/parameters/SubId' + post: + description: > + The HTTP request `POST /participants/{Type}/{ID}` + + (or `POST /participants/{Type}/{ID}/{SubId}`) + + is used to create information in the server regarding the provided + identity, + + defined by `{Type}`, `{ID}`, and optionally `{SubId}` + + (for example, `POST /participants/MSISDN/123456789` or + + `POST /participants/BUSINESS/shoecompany/employee1`). + + An ExtensionList element has been added to this request in version v1.1 + summary: Create participant information + tags: + - participants + operationId: ParticipantsSubIdByTypeAndIDPost + requestBody: + description: Participant information to be created. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDSubIDPostRequest' + responses: + '201': + description: Created + headers: {} + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + get: + description: > + The HTTP request `GET /participants/{Type}/{ID}` (or `GET + /participants/{Type}/{ID}/{SubId}`) + + is used to find out in which FSP the requested Party, defined by + `{Type}`, `{ID}` and optionally `{SubId}`, + is located (for example, `GET /participants/MSISDN/123456789`, or + `GET /participants/BUSINESS/shoecompany/employee1`). + This HTTP request should support a query string for filtering of currency. + To use filtering of currency, the HTTP request `GET /participants/{Type}/{ID}?currency=XYZ` + should be used, where `XYZ` is the requested currency. + summary: Look up participant information + tags: + - participants + operationId: ParticipantsSubIdByTypeAndIDGet + responses: + '200': + description: OK + headers: + Content-Length: + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDGetResponse' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + put: + description: > + The PUT /participants/{Type}/{ID}/{SubId} is used to update information + in the + + server regarding the provided identity, defined by {Type}, {ID} and + {SubId} + + (for example, PUT /participants/MSISDN/123456789/PERSONAL). + summary: Update participant information + tags: + - participants + operationId: ParticipantsSubIdByTypeAndIDPut + requestBody: + description: Participant information returned. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsTypeIDPostPutRequest' + responses: + '200': + $ref: '#/components/responses/200' + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + delete: + description: > + The HTTP request `DELETE /participants/{Type}/{ID}` + + (or `DELETE /participants/{Type}/{ID}/{SubId}`) is used to delete + + information in the server regarding the provided identity, + + defined by `{Type}` and `{ID}`) (for example, `DELETE + /participants/MSISDN/123456789`), + + and optionally `{SubId}`. This HTTP request should support a query + + string to delete FSP information regarding a specific currency only. + + To delete a specific currency only, the HTTP request + + `DELETE /participants/{Type}/{ID}?currency=XYZ` + + should be used, where `XYZ` is the requested currency. + + + + **Note:** The Account Lookup System should verify that it is the Party’s + current FSP that is deleting the FSP information. + summary: Delete participant information + tags: + - participants + operationId: ParticipantsSubIdByTypeAndIDDelete + responses: + '204': + description: No Content + headers: {} + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' + /participants: + post: + description: >- + The HTTP request `POST /participants` is used to create information in + the server regarding the provided list of identities. This request + should be used for bulk creation of FSP information for more than one + Party. The optional currency parameter should indicate that each + provided Party supports the currency. + summary: Create bulk participant information + tags: + - participants + operationId: ParticipantsPost + requestBody: + description: Participant information to be created. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ParticipantsPostRequest' + responses: + '201': + description: Created + headers: {} + '400': + $ref: '#/components/responses/400' + '401': + $ref: '#/components/responses/401' + '403': + $ref: '#/components/responses/403' + '404': + $ref: '#/components/responses/404' + '405': + $ref: '#/components/responses/405' + '406': + $ref: '#/components/responses/406' + '501': + $ref: '#/components/responses/501' + '503': + $ref: '#/components/responses/503' +tags: + - name: participants + description: '' +servers: + - url: / +components: + parameters: + partySubIdOrType: + name: partySubIdOrType + in: query + required: false + schema: + type: string + description: >- + A sub-identifier of the party identifier, or a sub-type of the party + identifier's type. For example, `PASSPORT`, `DRIVING_LICENSE`. + Type: + name: Type + in: path + required: true + schema: + type: string + description: The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`. + ID: + name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + SubId: + name: SubId + in: path + required: true + schema: + type: string + description: >- + A sub-identifier of the party identifier, or a sub-type of the party + identifier's type. For example, `PASSPORT`, `DRIVING_LICENSE`. + schemas: + ParticipantsTypeIDPostPutRequest: + title: ParticipantsTypeIDPostPutRequest + description: PUT /participants/{Type}/{ID} object + type: object + properties: + fspId: + description: FSP Identifier that the Party belongs to. + type: string + currency: + description: >- + Indicate that the provided Currency was set to be supported by each + successfully added PartyIdInfo. + type: string + partySubIdOrType: + description: A sub-identifier or sub-type for the Party. + type: string + required: + - fspId + ParticipantsTypeIDGetResponse: + title: ParticipantsTypeIDGetResponse + description: OK + type: object + properties: + partyList: + description: >- + List of PartyTypeIdInfo elements that were either created or failed + to be created. + type: array + items: + $ref: '#/components/schemas/PartyTypeIdInfo' + minItems: 1 + maxItems: 10000 + PartyTypeIdInfo: + title: PartyTypeIdInfo + description: Data model for the complex type PartyIdInfo. + type: object + properties: + fspId: + $ref: '#/components/schemas/FspId' + partySubIdOrType: + $ref: '#/components/schemas/PartySubIdOrType' + required: + - fspId + ErrorCode: + title: ErrorCode + type: string + pattern: ^[1-9]\d{3}$ + description: >- + The API data type ErrorCode is a JSON String of four characters, + consisting of digits only. Negative numbers are not allowed. A leading + zero is not allowed. Each error code in the API is a four-digit number, + for example, 1234, where the first number (1 in the example) represents + the high-level error category, the second number (2 in the example) + represents the low-level error category, and the last two numbers (34 in + the example) represent the specific error. + example: '5100' + ErrorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + ExtensionKey: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + ExtensionValue: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + Extension: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + $ref: '#/components/schemas/ExtensionKey' + value: + $ref: '#/components/schemas/ExtensionValue' + required: + - key + - value + ExtensionList: + title: ExtensionList + type: object + description: >- + Data model for the complex type ExtensionList. An optional list of + extensions, specific to deployment. + properties: + extension: + type: array + items: + $ref: '#/components/schemas/Extension' + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + ErrorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + $ref: '#/components/schemas/ErrorCode' + errorDescription: + $ref: '#/components/schemas/ErrorDescription' + extensionList: + $ref: '#/components/schemas/ExtensionList' + required: + - errorCode + - errorDescription + ErrorInformationResponse: + title: ErrorInformationResponse + type: object + description: >- + Data model for the complex type object that contains an optional element + ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/components/schemas/ErrorInformation' + FspId: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + PartySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: >- + Either a sub-identifier of a PartyIdentifier, or a sub-type of the + PartyIdType, normally a PersonalIdentifierType. + Currency: + title: Currency + description: >- + The currency codes defined in [ISO + 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter + alphabetic codes are used as the standard naming representation for + currencies. + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + ParticipantsTypeIDSubIDPostRequest: + title: ParticipantsTypeIDSubIDPostRequest + type: object + description: >- + The object sent in the POST /participants/{Type}/{ID}/{SubId} and + /participants/{Type}/{ID} requests. An additional optional ExtensionList + element has been added as part of v1.1 changes. + properties: + fspId: + $ref: '#/components/schemas/FspId' + currency: + $ref: '#/components/schemas/Currency' + extensionList: + $ref: '#/components/schemas/ExtensionList' + required: + - fspId + CorrelationId: + title: CorrelationId + type: string + pattern: >- + ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ + description: >- + Identifier that correlates all messages of the same sequence. The API + data type UUID (Universally Unique Identifier) is a JSON String in + canonical format, conforming to [RFC + 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a + regular expression for interoperability reasons. A UUID is always 36 + characters long, 32 hexadecimal symbols and 4 dashes (‘-‘). + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + PartyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: > + Below are the allowed values for the enumeration. + + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + + Number, that is, the phone number) is used as reference to a + participant. + + The MSISDN identifier should be in international format according to the + + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + + Optionally, the MSISDN may be prefixed by a single plus sign, indicating + the + + international prefix. + + - EMAIL - An email is used as reference to a + + participant. The format of the email should be according to the + informational + + [RFC 3696](https://tools.ietf.org/html/rfc3696). + + - PERSONAL_ID - A personal identifier is used as reference to a + participant. + + Examples of personal identification are passport number, birth + certificate + + number, and national registration number. The identifier number is added + in + + the PartyIdentifier element. The personal identifier type is added in + the + + PartySubIdOrType element. + + - BUSINESS - A specific Business (for example, an organization or a + company) + + is used as reference to a participant. The BUSINESS identifier can be in + any + + format. To make a transaction connected to a specific username or bill + number + + in a Business, the PartySubIdOrType element should be used. + + - DEVICE - A specific device (for example, a POS or ATM) ID connected to + a + + specific business or organization is used as reference to a Party. + + For referencing a specific device under a specific business or + organization, + + use the PartySubIdOrType element. + + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + + reference to a participant. The ACCOUNT_ID identifier can be in any + format, + + as formats can greatly differ depending on country and FSP. + + - IBAN - A bank account number or FSP account ID is used as reference to + a + + participant. The IBAN identifier can consist of up to 34 alphanumeric + + characters and should be entered without whitespace. + + - ALIAS An alias is used as reference to a participant. The alias should + be + + created in the FSP as an alternative reference to an account owner. + + Another example of an alias is a username in the FSP system. + + The ALIAS identifier can be in any format. It is also possible to use + the + + PartySubIdOrType element for identifying an account under an Alias + defined + + by the PartyIdentifier. + + - CONSENT - A Consent represents an agreement between a PISP, a Customer + and + + a DFSP which allows the PISP permission to perform actions on behalf of + the + + customer. A Consent has an authoritative source: either the DFSP who + issued + + the Consent, or an Auth Service which administers the Consent. + + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between + a PISP, + + a DFSP, and a specific Customer's account at the DFSP. The content of + the link + + is created by the DFSP at the time when it gives permission to the PISP + for + + specific access to a given account. + example: PERSONAL_ID + PartyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + PartyIdInfo: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + $ref: '#/components/schemas/PartyIdType' + partyIdentifier: + $ref: '#/components/schemas/PartyIdentifier' + partySubIdOrType: + $ref: '#/components/schemas/PartySubIdOrType' + fspId: + $ref: '#/components/schemas/FspId' + extensionList: + $ref: '#/components/schemas/ExtensionList' + required: + - partyIdType + - partyIdentifier + ParticipantsPostRequest: + title: ParticipantsPostRequest + type: object + description: The object sent in the POST /participants request. + properties: + requestId: + $ref: '#/components/schemas/CorrelationId' + partyList: + type: array + items: + $ref: '#/components/schemas/PartyIdInfo' + minItems: 1 + maxItems: 10000 + description: | + List of PartyIdInfo elements that the client would like to update + or create FSP information about. + currency: + $ref: '#/components/schemas/Currency' + required: + - requestId + - partyList + responses: + '200': + description: OK + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInformationResponse' + headers: + Content-Length: + $ref: '#/components/headers/Content-Length' + Content-Type: + $ref: '#/components/headers/Content-Type' + headers: + Content-Length: + required: false + schema: + type: integer + description: >- + The `Content-Length` header field indicates the anticipated size of the + payload body. Only sent if there is a body. + + + **Note:** The API supports a maximum size of 5242880 bytes (5 + Megabytes). + Content-Type: + schema: + type: string + required: true + description: >- + The `Content-Type` header indicates the specific version of the API used + to send the payload body. diff --git a/api/central-ledger-api-specification.md b/legacy/api/central-ledger-api-specification.md similarity index 100% rename from api/central-ledger-api-specification.md rename to legacy/api/central-ledger-api-specification.md diff --git a/api/central-settlements-api-specification.md b/legacy/api/central-settlements-api-specification.md similarity index 100% rename from api/central-settlements-api-specification.md rename to legacy/api/central-settlements-api-specification.md diff --git a/legacy/api/mojaloop-api-specification.md b/legacy/api/mojaloop-api-specification.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/legacy/api/mojaloop-api-specification.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/legacy/assets/.gitkeep b/legacy/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/legacy/assets/diagrams/.gitkeep b/legacy/assets/diagrams/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/book.json b/legacy/book.json similarity index 84% rename from book.json rename to legacy/book.json index 6a11e685e..0028a0338 100644 --- a/book.json +++ b/legacy/book.json @@ -3,8 +3,8 @@ "plugins": ["swagger", "editlink", "include", "insert-logo", "plantuml-svg", "collapsible-chapters", "back-to-top-button", "theme-api", "variables", "changelog", "page-toc" ], "pluginsConfig": { "theme-gestalt": { - "logo": "https://mojaloop.io/images/logo.png", - "favicon": "https://mojaloop.io/images/logo.png", + "logo": "https://docs.mojaloop.io/mojaloop_logo_med.png", + "favicon": "https://docs.mojaloop.io/mojaloop_logo_med.png", "baseUrl": null, "excludeDefaultStyles": false, "doNotHideChildrenChapters" : false @@ -15,7 +15,7 @@ "multilingual": true }, "insert-logo": { - "url": "https://mojaloop.io/images/logo.png", + "url": "https://docs.mojaloop.io/mojaloop_logo_med.png", "style": "background: none; max-height: 140px; max-width: 140px;" }, "theme-api": { diff --git a/book_variables.yml b/legacy/book_variables.yml similarity index 85% rename from book_variables.yml rename to legacy/book_variables.yml index 7e4ca6a02..9b232a7ba 100644 --- a/book_variables.yml +++ b/legacy/book_variables.yml @@ -12,8 +12,8 @@ mojaloop: spec: version: v1.0 uri: - doc: https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf - api: https://github.com/mojaloop/mojaloop-specification/blob/master/Supporting%20Files/fspiop-rest-v1.0-OpenAPI-implementation.yaml + doc: https://mojaloop.io/mojaloop-specification/ + api: https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml central_ledger: spec: version: v2.0 diff --git a/changelog.md b/legacy/changelog.md similarity index 100% rename from changelog.md rename to legacy/changelog.md diff --git a/legacy/contributors-guide/README.md b/legacy/contributors-guide/README.md new file mode 100644 index 000000000..c22389122 --- /dev/null +++ b/legacy/contributors-guide/README.md @@ -0,0 +1,63 @@ +# Contributors Guide + +## How do I contribute? + +* Review the [Mojaloop Deployment](../deployment-guide/) Guide and the [Onboarding Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) +* Browse through the [Repository Overview](../repositories/) to understand how the Mojaloop code is managed across multiple Github Repositories +* Get familiar with our [Standards](standards/) on contributing to this project +* Go through the [New Contributor Checklist](./new-contributor-checklist.md), and browse through the project board and work on your [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) +* Review the [Roadmap](../mojaloop-roadmap.md) and contribute to future opportunities +* Familiarize yourself with our Community [Code of Conduct](../code-of-conduct.md) + +## What work is needed? + +Work is tracked as issues in the [mojaloop/project](https://github.com/mojaloop/project) repository GitHub. You'll see issues there that are open and marked as bugs, stories, or epics. An epic is larger work that contains multiple stories. Start with any stories that are marked with "[good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)". In addition, anything that is in the backlog and not assigned to someone are things we could use help with. Stories that have owners are in someone's backlog already, though you can always ask about them in the issue or on Slack. + +There's a [roadmap](../mojaloop-roadmap.md) that shows larger work that people could do or are working on. It has some main initiatives and epics and the order, but lacks dates as this work is community driven. Work is broken down from there into issues in GitHub. + +In general, we are looking for example implementations and bug fixes, and project enhancements. + +### Where do I get help? + +Join the [Mojaloop Slack Discussions](https://mojaloop-slack.herokuapp.com/) to connect with other developers. + +Also checkout the [FAQ](https://github.com/mojaloop/documentation/blob/master/contributors-guide/frequently-asked-questions.md) + +### What is the current release? + +See the [Mojaloop Slack Announcements](https://mojaloop.slack.com/messages/CG3MAJZ5J) to find out information on the latest release. + +### What's here and what's not? + +This is free code provided under an [Apache 2.0 license](https://github.com/mojaloop/mojaloop/blob/master/LICENSE.md). + +The code is released with an Apache 2.0 license but the Specification documents under the 'mojaloop-specification' documents are published with CC BY-ND 4.0 License + +We don't provide production servers to run it on. That's up to you. You are free \(and encouraged!\) to clone these repositories, participate in the community of developers, and contribute back to the code. + +We are not trying to replace any mobile wallet or financial providers. We provide code to link together new and existing financial providers using a common scheme. There are central services for identifying a customer's provider, quoting, fulfillment, deferred net settlement, and shared fraud management. Each provider can take advantage of these services to send and receive money with others on the system and there's no cost to them to onboard new providers. We provide code for a simple example mobile money provider to show how integration can be done, but our example DFSP is not meant to be a production mobile money provider. + +## Where do I send bugs, questions, and feedback? + +For bugs, see [Reporting bugs](https://github.com/mojaloop/mojaloop/blob/master/contribute/Reporting-Bugs.md). + +### Related Projects + +The [Interledger Protocol Suite](https://interledger.org/) \(ILP\) is an open and secure standard that enables DFSPs to settle payments with minimal _counter-party risk_ \(the risk you incur when someone else is holding your money\). With ILP, you can transact across different systems with no chance that someone in the middle disappears with your money. Mojaloop uses the Interledger Protocol Suite for the clearing layer. + +## Types of Contributors + +There are three types of contributors that we are targeting for this phase of the Mojaloop project. + +### Developers or General Contributors + +These individuals are those that want to start contributing to the Mojaloop community. This could be a developer or quality assurance person that wants to write new code or fix a bug. This could also be a business, compliance or risk specialist that wants to help provide rules, write documentation or participate in requirements gathering. + +### Hub Operators + +Typically these or organizations or individuals or government agencies that are interested in setting up their own Mojaloop Switch to become part of the ecosystem. + +### Implementation Teams + +Implementation teams can assist banks, government offices, mobile operators or credit unions in deploying Mojaloop. + diff --git a/legacy/contributors-guide/code-of-conduct.md b/legacy/contributors-guide/code-of-conduct.md new file mode 100644 index 000000000..641649471 --- /dev/null +++ b/legacy/contributors-guide/code-of-conduct.md @@ -0,0 +1,94 @@ +# Mojaloop Code of Conduct + + +## Vision and Mission + +Mojaloop is a portmanteau derived from the Swahili word "Moja" meaning "one" and the English word loop. Mojaloop's vision is to loop digital financial providers and customers together in one inclusive ecosystem. + +The Mojaloop open source project mission is to increase financial inclusion by empowering organizations creating trusted and interoperable payments systems to enable digital financial services for all. We believe an economy that includes everyone, benefits everyone and we are building software that will accelerate full financial inclusion. Succeeding in our mission will require diverse opinions and contributions from people reflecting differing experiences and who come from culturally diverse backgrounds. + +## Community Foundation and Values + +Our goal is a strong and diverse community that welcomes new ideas in a complex field and fosters collaboration between groups and individuals with very different needs, interests, and skills. + +We build a strong and diverse community by actively seeking participation from those who add value to it. + +We treat each other openly and respectfully, we evaluate contributions with fairness and equity, and we seek to create a project that includes everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, and orientation. + +*This code of conduct exists to ensure that diverse groups collaborate to mutual advantage and enjoyment.* + +The Code of Conduct governs how we behave in public or in private, virtually or in person. We expect it to be honoured by everyone who represents the project officially or informally, claims affiliation with the project, or participates directly. + +### We strive to: + +- **Be Considerate**\ + Our work will be used by other people, and we in turn will depend on the work of others. Any decision we take will affect everyone involved in our ecosystem, and we should consider all relevant aspects when making decisions. + +- **Be Respectful**\ + We work together to resolve conflict, assume good intentions, and do our best to act in an empathic fashion. We believe a community where people are respected and feel comfortable is a productive one. + +- **Be Accountable**\ + We are accountable for our words and actions. We all can make mistakes; when we do, we take responsibility for them. If someone has been harmed or offended, we listen carefully and respectfully and work to right the wrong. + +- **Be Collaborative**\ + What we produce is a complex whole made of many parts. Collaboration between teams that each have their own goal and vision is essential; for the whole to be more than the sum of its parts, each part must make an effort to understand the whole.\ + Collaboration reduces redundancy and improves the quality of our work. Internally and externally, we celebrate good collaboration. Wherever possible, we work closely with upstream projects and others in the open-source software community to coordinate our efforts. We prefer to work transparently and involve interested parties as early as possible. + +- **Value Decisiveness, Clarity, and Consensus**\ + Disagreements, social and technical, are normal, but we do not allow them to persist and fester leaving others uncertain of the agreed direction.\ + We expect community members to resolve disagreements constructively. When they face obstacles in doing so, we escalate the matter to structures with designated leaders to arbitrate and provide clarity and direction. + +- **Ask for help when unsure**\ + Nobody is expected to be perfect in this community. Asking questions early avoids many problems later, so questions are encouraged, though they may be directed to the appropriate forum. Those who are asked should be responsive and helpful. + +- **Step Down Considerately**\ + When somebody leaves or disengages from the project, we ask that they do so in a way that minimises disruption to the project. They should tell people they are leaving and take the proper steps to ensure that others can pick up where they left off. + +- **Open Meritocracy**\ +We invite anybody, from any company or organization, to participate in any aspect of the project. Our community is open, and any responsibility can be carried by any contributor who demonstrates the required capacity and competence. + +- **Value Diversity and Inclusion**\ +This is a community that wants to make a real difference to people's lives across the globe; and, in particular, in developing societies and economies. We value our members, first of all, for themselves; and, second, for the help they can give each of us as we work together to transform the world. Each of us will strive never to allow any other considerations to weigh with us, either consciously or unconsciously. In particular, considerations of gender identity or expression, sexual orientation, religion, ethnicity, age, neurodiversity, disability status, language, and citizenship have no place in our collaboration and we will work to eradicate them where we find them: first of all, in ourselves; but after that, and with respect and affection, in those we work with. + +- **Be Transparent**\ +We believe community members will have personal and professional interests in the development of the Mojaloop Open Source Software. These interests will, directly and indirectly, influence perceptions about the best direction of the community. Community members should make every reasonable effort to be transparent about their interests within the limits of confidentiality.  Community members who hold permanent or temporary governance roles should not use those roles in the advancement of personal or professional interests but should base their influence on the best interests of the success of the community. + +This Code of Conduct is not exhaustive or complete. It is not a rulebook; it serves to distill our common understanding of a collaborative, shared environment, and goals. We expect it to be followed in spirit as much as in the letter. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language + +- Being respectful of differing viewpoints and experiences + +- Gracefully accepting constructive criticism + +- Focusing on what is best for the community + +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances + +- Trolling, insulting/derogatory comments, and personal or political attacks + +- Public or private harassment + +- Publishing others' private information, such as a physical or electronic address, without explicit permission + +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Reporting and Resolution + +If you see someone violating the code of conduct, you are encouraged to address the behavior directly with those involved. Many issues can be resolved quickly and easily, and this gives people more control over the outcome of their dispute. If you are unable to resolve the matter for any reason, or if the behavior is threatening or harassing, report it. We are dedicated to providing an environment where participants feel welcome and safe. + +Reports should be directed to the Community Leadership Committee via an email sent to . This email goes to the Mojaloop Foundation Community Manager whose duty it is to receive and address reported violations of the code of conduct. They will then work with the Community Leadership Committee to address and resolve the report. + +We will investigate every complaint, but you may not receive a direct response. Whether we respond to you directly or not, you will always be able to enquire after the status of a complaint by contacting a member of the Community Leadership Committee. We will use our discretion in determining when and how to follow up on reported incidents, which may range from not taking action to permanent expulsion from the community and foundation-sponsored spaces. We will notify the accused of the report and provide them an opportunity to discuss it before any action is taken. The identity of the reporter will be omitted from the details of the report supplied to the accused. In potentially harmful situations, such as ongoing harassment or threats to anyone's safety, we may take action without notice. + +### Attribution + +This Code of Conduct is adapted from the Ubuntu Code of Conduct v2.0, available at diff --git a/contributors-guide/documentation/README.md b/legacy/contributors-guide/documentation/README.md similarity index 100% rename from contributors-guide/documentation/README.md rename to legacy/contributors-guide/documentation/README.md diff --git a/contributors-guide/documentation/api-documentation.md b/legacy/contributors-guide/documentation/api-documentation.md similarity index 100% rename from contributors-guide/documentation/api-documentation.md rename to legacy/contributors-guide/documentation/api-documentation.md diff --git a/contributors-guide/documentation/documentation-style-guide.md b/legacy/contributors-guide/documentation/documentation-style-guide.md similarity index 100% rename from contributors-guide/documentation/documentation-style-guide.md rename to legacy/contributors-guide/documentation/documentation-style-guide.md diff --git a/contributors-guide/frequently-asked-questions.md b/legacy/contributors-guide/frequently-asked-questions.md similarity index 77% rename from contributors-guide/frequently-asked-questions.md rename to legacy/contributors-guide/frequently-asked-questions.md index edf79bc54..58ac80757 100644 --- a/contributors-guide/frequently-asked-questions.md +++ b/legacy/contributors-guide/frequently-asked-questions.md @@ -8,43 +8,46 @@ This document contains some of the most frequently asked questions from the comm ### Table of Content -* [What is Mojaloop](#1-what-is-mojaloop) -* [How does it work](#2-how-does-it-work) -* [Who is it for](#3-who-is-it-for) -* [Why does it exist](#4-why-does-it-exist) -* [Who's behind it](#5-whos-behind-it) -* [What platforms does Mojaloop run on](#6-what-platforms-does-mojaloop-run-on) -* [Is it really open-source](#7-is-it-really-open-source) -* [How can I contribute to Mojaloop](#8-how-can-i-contribute-to-mojaloop) -* [What is supported](#9-what-is-supported) -* [Can we connect directly to Pathfinder in a development environment](#10-can-we-connect-directly-to-pathfinder-in-a-development-environment) -* [Should i register DFSP via url or update configuration in default.json](#11-should-i-register-dfsp-via-urlhttpcentral-directorycommandsregisteror-i-need-to-update-configuration-in-defaultjson) -* [Status of the pod pi3-kafka-0 is still on CrashLoopBackOff](#12-status-of-the-pod-pi3-kafka-0-is-still-on-crashloopbackoff) -* [Why am I getting an error when we try to create new DFSP using Admin](#13-why-am-i-getting-an-error-when-we-try-to-create-new-dfsp-using-admin) -* [Using Mojaloop to do payment using crypto-currency](#14-using-mojaloop-to-do-payment-using-crypto-currency) -* [Can I spread Mojaloop components over different physical machines and VM's](#15--can-i-spread-mojaloop-components-over-different-physical-machines-and-vms) -* [Can we expect all the endpoints defined in the API document are implemented in Mojaloop](#16-can-we-expect-all-the-endpoints-defined-in-the-api-document-are-implemented-in-mojaloop) -* [Does Mojaloop store the payment initiator FSP’s quote/status info](#17-does-mojaloop-store-the-payment-initiator-fsps-quotestatus-info) -* [Does Mojaloop handle workflow validation](#18-does-mojaloop-handle-workflow-validation) -* [How is the Mojaloop source accessible](#19-how-is-the-mojaloop-source-accessible) -* [How to register a new party in Mojaloop](#20-how-to-register-a-new-party-in-mojaloop) -* [Does the participant represent an account of a customer in a bank](#21-does-the-participant-represent-an-account-of-a-customer-in-a-bank) -* [How to register _trusted_ payee to a payer, to skip OTP](#22-how-to-register-trusted-payee-to-a-payer-to-skip-otp) -* [Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file](#23-receiving-a-404-error-when-attempting-to-access-or-load-kubernetes-dashboardyaml-file) -* [When installing nginx-ingress for load balancing & external access - Error: no available release name found](#24-when-installing-nginx-ingress-for-load-balancing--external-access---error-no-available-release-name-found) -* [Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command](#25-received-importerror-librdkafkaso1-cannot-open-shared-object-file-no-such-file-or-directory-when-running-npm-start-command) -* [Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only](#26-can-we-use-mojaloop-as-open-source-mobile-wallet-software-or-mojaloop-does-interoperability-only) -* [Describe companies that helps to deploy & support for mojaloop](#27-describe-companies-that-helps-to-deploy--support-for-mojaloop) -* [Can you say something about mojaloop & security](#28-can-you-say-something-about-mojaloop--security) -* [What are the benefit(s) from using mojaloop as interoperabilty platform](#29-what-are-the-benefits-from-using-mojaloop-as-interoperabilty-platform) -* [What are the main challenges that companies face using mojaloop](#30-what-are-the-main-challenges-that-companies-face-using-mojaloop) -* [Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform](#31-is-forensic-loggingaudit-in-mojaloop--is-it-related-with-securing-the-inter-operability-platform) -* [How do the financial service providers connect with mojaloop](#32-how-do-the-financial-service-providers-connect-with-mojaloop) -* [Is there any open source ISO8583-OpenAPI converter/connector available](#33-is-there-any-open-source-iso8583-openapi-converterconnector-available) -* [How do I know the end points to setup postman for testing the deployment](#34-how-do-i-know-the-end-points-to-setup-postman-for-testing-the-deployment) -* [Why are there no reversals allowed on a Mojaloop](#35-why-are-there-no-reversals-allowed-on-a-mojaloop) -* [ffg. error with microk8s installation "MountVolume.SetUp failed"](#36-ffg-error-with-microk8s-installation-mountvolumesetup-failed) -* [Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"?](#37-why-am-i-getting-this-error-when-trying-to-create-a-participant-hub-reconciliation-account-for-the-specified-currency-does-not-exist) +- [Frequently Asked Questions](#frequently-asked-questions) + - [Table of Content](#table-of-content) + - [1. What is Mojaloop?](#1-what-is-mojaloop) + - [2. How does it work?](#2-how-does-it-work) + - [3. Who is it for?](#3-who-is-it-for) + - [4. Why does it exist?](#4-why-does-it-exist) + - [5. Who's behind it?](#5-whos-behind-it) + - [6. What platforms does Mojaloop run on?](#6-what-platforms-does-mojaloop-run-on) + - [7. Is it really open-source?](#7-is-it-really-open-source) + - [8. How can I contribute to Mojaloop?](#8-how-can-i-contribute-to-mojaloop) + - [9. What is supported?](#9-what-is-supported) + - [10. Can we connect directly to Pathfinder in a development environment?](#10-can-we-connect-directly-to-pathfinder-in-a-development-environment) + - [11. Should i register DFSP via url http://central-directory/commands/register or i need to update configuration in default.json?](#11-should-i-register-dfsp-via-urlhttpcentral-directorycommandsregisteror-i-need-to-update-configuration-in-defaultjson) + - [12. Status of the pod pi3-kafka-0 is still on CrashLoopBackOff?](#12-status-of-the-pod-pi3-kafka-0-is-still-on-crashloopbackoff) + - [13. Why am I getting an error when we try to create new DFSP using Admin?](#13-why-am-i-getting-an-error-when-we-try-to-create-new-dfsp-using-admin) + - [14. Using Mojaloop to do payment using crypto-currency?](#14-using-mojaloop-to-do-payment-using-crypto-currency) + - [15. Can I spread Mojaloop components over different physical machines and VM's?](#15--can-i-spread-mojaloop-components-over-different-physical-machines-and-vms) + - [16. Can we expect all the endpoints defined in the API document are implemented in Mojaloop?](#16-can-we-expect-all-the-endpoints-defined-in-the-api-document-are-implemented-in-mojaloop) + - [17. Does Mojaloop store the payment initiator FSP’s quote/status info?](#17-does-mojaloop-store-the-payment-initiator-fsps-quotestatus-info) + - [18. Does Mojaloop handle workflow validation?](#18-does-mojaloop-handle-workflow-validation) + - [19. How is the Mojaloop source accessible?](#19-how-is-the-mojaloop-source-accessible) + - [20. How to register a new party in Mojaloop?](#20-how-to-register-a-new-party-in-mojaloop) + - [21. Does the participant represent an account of a customer in a bank?](#21-does-the-participant-represent-an-account-of-a-customer-in-a-bank) + - [22. How to register _trusted_ payee to a payer, to skip OTP?](#22-how-to-register-trusted-payee-to-a-payer-to-skip-otp) + - [23. Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file?](#23-receiving-a-404-error-when-attempting-to-access-or-load-kubernetes-dashboardyaml-file) + - [24. When installing nginx-ingress for load balancing & external access - Error: no available release name found?](#24-when-installing-nginx-ingress-for-load-balancing--external-access---error-no-available-release-name-found) + - [25. Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command.](#25-received-importerror-librdkafkaso1-cannot-open-shared-object-file-no-such-file-or-directory-when-running-npm-start-command) + - [26. Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only?](#26-can-we-use-mojaloop-as-open-source-mobile-wallet-software-or-mojaloop-does-interoperability-only) + - [27. Describe companies that helps to deploy & support for mojaloop?](#27-describe-companies-that-helps-to-deploy--support-for-mojaloop) + - [28. Can you say something about mojaloop & security?](#28-can-you-say-something-about-mojaloop--security) + - [29. What are the benefit(s) from using mojaloop as interoperabilty platform?](#29-what-are-the-benefits-from-using-mojaloop-as-interoperabilty-platform) + - [30. What are the main challenges that companies face using mojaloop?](#30-what-are-the-main-challenges-that-companies-face-using-mojaloop) + - [31. Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform?](#31-is-forensic-loggingaudit-in-mojaloop--is-it-related-with-securing-the-inter-operability-platform) + - [32. How do the financial service providers connect with mojaloop?](#32-how-do-the-financial-service-providers-connect-with-mojaloop) + - [33. Is there any open source ISO8583-OpenAPI converter/connector available?](#33-is-there-any-open-source-iso8583-openapi-converterconnector-available) + - [34. How do I know the end points to setup postman for testing the deployment?](#34-how-do-i-know-the-end-points-to-setup-postman-for-testing-the-deployment) + - [35. Why are there no reversals allowed on a Mojaloop?](#35-why-are-there-no-reversals-allowed-on-a-mojaloop) + - [36. ffg. error with microk8s installation "MountVolume.SetUp failed"?](#36-ffg-error-with-microk8s-installation-mountvolumesetup-failed) + - [37. Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"?](#37-why-am-i-getting-this-error-when-trying-to-create-a-participant-hub-reconciliation-account-for-the-specified-currency-does-not-exist) + - [38. Resolve problems with VSCode and kafka on ubuntu 18.04. To make the code work with VSCode debugger, added the following into the launch.json](#38-resolve-problems-with-vscode-and-kafka-on-ubuntu-1804-to-make-the-code-work-with-vscode-debugger-added-the-following-into-the-launchjson) #### 1. What is Mojaloop? @@ -139,7 +142,7 @@ Not at the moment, but this may happen in the future. Regarding correlating requ #### 19. How is the Mojaloop source accessible? Here are some resources to start with: -1. Docs: https://github.com/mojaloop/documents. Note we are in the process to migrate from https://github.com/mojaloop/docs to https://github.com/mojaloop/documents. +1. Docs: https://github.com/mojaloop/documentation. 2. Look at the repos that have “CORE COMPONENT (Mojaloop)” in the description and these are core components. “CORE RELATED (Mojaloop)” repos are the ones that are needed to support the current Mojaloop Switch implementation/deployment. 3. As a generic point of note, for latest code, please use the ‘develop’ branch for the time-being. 4. Current architecture: https://github.com/mojaloop/docs/tree/master/Diagrams/ArchitectureDiagrams. Please note that these are currently being migrated to https://github.com/mojaloop/documents. @@ -252,3 +255,12 @@ You need to create the corresponding Hub accounts (HUB_MULTILATERAL_SETTLEMENT a In this Postman collection you can find the requests to perform the operation in the "Hub Account" folder: https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json Find also the related environments in the Postman repo: https://github.com/mojaloop/postman + +#### 38. Resolve problems with VSCode and kafka on ubuntu 18.04. To make the code work with VSCode debugger, added the following into the launch.json + + ```json + "env": { + "LD_LIBRARY_PATH": "${workspaceFolder}/node_modules/node-rdkafka/build/deps", + "WITH_SASL": 0 + } + ``` diff --git a/legacy/contributors-guide/images/cla/admin_configure.png b/legacy/contributors-guide/images/cla/admin_configure.png new file mode 100644 index 000000000..1d8281bb4 Binary files /dev/null and b/legacy/contributors-guide/images/cla/admin_configure.png differ diff --git a/legacy/contributors-guide/images/cla/admin_sign_in.png b/legacy/contributors-guide/images/cla/admin_sign_in.png new file mode 100644 index 000000000..a960e2dcd Binary files /dev/null and b/legacy/contributors-guide/images/cla/admin_sign_in.png differ diff --git a/legacy/contributors-guide/images/cla/cla_1.png b/legacy/contributors-guide/images/cla/cla_1.png new file mode 100644 index 000000000..46718fc66 Binary files /dev/null and b/legacy/contributors-guide/images/cla/cla_1.png differ diff --git a/legacy/contributors-guide/images/cla/cla_2_1.png b/legacy/contributors-guide/images/cla/cla_2_1.png new file mode 100644 index 000000000..18ae1809c Binary files /dev/null and b/legacy/contributors-guide/images/cla/cla_2_1.png differ diff --git a/legacy/contributors-guide/images/cla/cla_2_2.png b/legacy/contributors-guide/images/cla/cla_2_2.png new file mode 100644 index 000000000..2e60fb762 Binary files /dev/null and b/legacy/contributors-guide/images/cla/cla_2_2.png differ diff --git a/legacy/contributors-guide/images/cla/cla_3.png b/legacy/contributors-guide/images/cla/cla_3.png new file mode 100644 index 000000000..5e2ddc46d Binary files /dev/null and b/legacy/contributors-guide/images/cla/cla_3.png differ diff --git a/legacy/contributors-guide/new-contributor-checklist.md b/legacy/contributors-guide/new-contributor-checklist.md new file mode 100644 index 000000000..b189457d2 --- /dev/null +++ b/legacy/contributors-guide/new-contributor-checklist.md @@ -0,0 +1,67 @@ +# New Contributor Checklist + +This guide summarizes the steps needed to get up and running as a contributor to Mojaloop. They needn't be completed all in one sitting, but by the end of the checklist, you should have learned a good deal about Mojaloop, and be prepared to contribute to the community. + + +## 1. Tools & Documentation + +- Make sure you have a GitHub account already, or sign up for an account [here](https://github.com/join) + +- Join the slack community at the [self-invite link](https://mojaloop-slack.herokuapp.com/), and join the following channels: + - `#announcements` - Announcements for new Releases and QA Status + - `#design-authority` - Questions + Discussion around Mojaloop Design + - `#general` - General discussion about Mojaloop + - `#help-mojaloop` - Ask for help with installing or running Mojaloop + - `#ml-oss-bug-triage` - Discussion and triage for new bugs and issues + +- Say hi! Feel free to give a short introduction of yourself to the community on the `#general` channel. + +- Review the [Git workflow guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) and ensure you are familiar with git. + - Further reading: [Introduction to Github workflow](https://www.atlassian.com/git/tutorials/comparing-workflows) + +- Familiarize yourself with our standard coding style: https://standardjs.com/ + +- Browse through the [Mojaloop Documentation](https://mojaloop.io/documentation/) and get a basic understanding of how the technology works. + +- Go through the [Developer Tools Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) to get the necessary developer tools up and running on your local environment. + +- (Optional) Get the Central-Ledger up and running on local machines: + - https://github.com/mojaloop/central-ledger/blob/master/Onboarding.md + - https://github.com/mojaloop/ml-api-adapter/blob/master/Onboarding.md + +- (Optional:) Run an entire switch yourself with Kubernetes https://mojaloop.io/documentation/deployment-guide/ _(note: if running locally, your Kubernetes cluster will need 8gb or more of RAM)_ + +## 2. Finding an Issue + +- Review the [good-first-issue](https://github.com/mojaloop/project/labels/good%20first%20issue) list on [`mojaloop/project`](https://github.com/mojaloop/project), to find a good issue to start working on. Alternatively, reach out to the community on Slack at `#general` to ask for help to find an issue. + +- Leave a comment on the issue asking for it to be assigned to you -- this helps make sure we don't duplicate work. As always, reach out to us on Slack if you have any questions or concerns. + +- Fork the relevant repos for the issue, clone and create a new branch for the issue + - Refer to our [git user guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) if you get lost + + +## 3. Opening your First PR + +> _Complete this part of the guide once you have been added to the Mojaloop GitHub organization. If you don't have access, reach out to us on the `#general` or `#help-mojaloop` + +- Sign up for [Zenhub](https://www.zenhub.com/), and connect it to the Mojaloop Organisation, Search for the _'project'_ workspace +- Install the [Zenhub Browser extension](https://www.zenhub.com/extension) for Chrome or Firefox, and browse the (Mojaloop Project Kanban board](https://github.com/mojaloop/project#zenhub) + +- When your branch is ready for review, open a new pull request from your repository back into the mojaloop project. + >_Note: if the CI/CD pipelines don't run, this may be because your Github account isn't added to the Mojaloop repo_ +- Ensure the following: + - A good description of the feature/bugfix you implemented + - The PR is _assigned_ to yourself + - You have assigned two or more _reviewers_. GitHub often has suggested reviewers, but if you don't know who to assign, feel free to ask whoever created the issue. + +- (Optional) Post a link to your PR on the `#ml-oss-devs` channel in Slack so everyone can share in the fun + + +## 4. Signing the CLA + +After you open your first PR, our CI/CD pipelines will ask you to sign the CLA. For more information on what the CLA is and how to sign it, see [signing the cla](./signing-the-cla.html) + +## FAQs: + +> None as of yet. If you have problems getting through this list, or need more help, reach out to us on Slack! diff --git a/legacy/contributors-guide/personas.md b/legacy/contributors-guide/personas.md new file mode 100644 index 000000000..5443d3ec9 --- /dev/null +++ b/legacy/contributors-guide/personas.md @@ -0,0 +1,46 @@ +# Mojaloop OSS/Community Personas + +# Document Purpose + +To specify the different types of personas/roles that will need access to the Mojaloop portal and documentation. + +## Contributor + +A contributor is someone that is actively involved in contributing to the Mojaloop project code, tests, and documentation. Some scenarios could include a developer, technical writer, or product manager. These people might be brand new to the project or someone that is well versed with the project. + +## Hub Operator + +A hub operator is someone who would be responsible for deploying a Mojaloop hub; they might already have a payments hub. A payment hub operator would need to know how the technical components work (ex how payments and messaging work, API flows, etc). They would also have to have operational control and participate in regulatory forums. + +## Digital Financial Service Provider (DFSP) + +A digital financial service provider, bank, mobile money operator is anyone that will have to talk/communicate directly with a Mojaloop hub. They will need to be familiar with the Mojaloop APIs and participate in scheme agreements with the other Mojaloop hub participants. + +## Systems Integrator + +This person would be responsible for deploying and customizing the Mojaloop components to work with an existing or new payment hub, DFSP or banking system. They would need equal access as the contributor but not necessarily have the system's full details, just those required for integration. + +## Business Owner, Decision Maker or Stakeholder + +A stakeholder is typically someone evaluating Mojaloop, potentially a new pilot customer or collaborator. Documentation for this individual needs to be at a higher level and explain the systems' value proposition, overview, integration points and technology drill-downs. + +## End-User (USSD user) + +The end-user documentation would be minimal for someone using the USSD interface to interact on their flip phone. Some issues that might arise for the end-user would be pin reset and trouble adding new accounts. + +## Customer Service + +Customer service or support personnel included in this category needs to understand the system's user interfaces and operational hubs. Advanced (tier 2 or 3) personnel might also need access to the network overview, API's and logs to help troubleshoot issues. + +End-User (merchant/bulk payment) + +The documentation required for an end-user in using the bulk payment system would need to include an onboarding guide, have some integration information to potentially contact to a merchant's accounts payable system, and have some info regarding bulk payment status accounts. This documentation would also need to include the ability to set different thresholds. + +## Auditor + +The auditor role represents the board of directors and shareholders of a given institution. An example would be an auditor for a financial provider. This role will require a high-level knowledge of the system and access to foresic logs. This role might have access to the different operational hubs and might represent a specific function, and have different access levels for the various components. + +## Regulator + +The regulator ensures the safety and soundness of the financial systems. Like the auditor role, will require a high level of knowledge of the system and access to forensic logs. This role might have access to the different operational hubs and might represent a specific function, and have different access levels for the various components. + diff --git a/legacy/contributors-guide/signing-the-cla.md b/legacy/contributors-guide/signing-the-cla.md new file mode 100644 index 000000000..edb75e520 --- /dev/null +++ b/legacy/contributors-guide/signing-the-cla.md @@ -0,0 +1,99 @@ +# Signing the CLA + +Mojaloop has a [Contributor License Agreement (CLA)](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) which clarifies the intellectual property rights for contributions from individuals or entities. + +To ensure every developer has signed the CLA, we use [CLA Assistant](https://cla-assistant.io/), a well maintained, open source tool which checks to make sure that a contributor has signed the CLA before allowing a pull request to be merged. + +## How to sign the CLA + +1. Open a pull request to any Mojaloop repository +2. When the pull request performs the standard checks, you will see the `license/cla` check has run, and requests users to sign the CLA: + + + + + +3. Click 'Details', and you will be directed to the CLA Assistant tool, where you can read the CLA, fill out some personal details, and sign it. + + +
    + + + +4. Once you have clicked "I agree", navigate back to the Pull request, and see that the CLA Assistant check has passed. + + + + + +### Signing For A Company + +Section 3 of the [Mojaloop CLA](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) covers contributions both from individuals and contributions made by individuals on behalf of their employer. If you are contributing to the Mojaloop Community on behalf of your employer, please enter your employer's name in the "Company or Organization" field. If not, feel free to write "OSS Contributor" and leave the "role" field blank. + + +## Administering the CLA tool + +The CLA Tool is easy to install, any GitHub admin can link it with the Mojaloop organization. + +1. Create a new GitHub Gist and enter in the text of the CLA in a new file. +> Since Github doesn't allow Gists to be owned my organizations, [our gist](https://gist.github.com/mojaloopci/9b7133e1ac153a097ae4ff893add8974) is owned by the 'mojaloopci' user. + +2. Go to [CLA Assistant](https://cla-assistant.io/) and click "Sign in with GitHub" + + + +3. You can add a CLA to either a Repo or Organization. Select "Mojaloop", and then select the gist you just created + + + +4. Hit "Link" and that's it! + + +### Requesting Additional Information: + +> Reference: [request-more-information-from-the-cla-signer](https://github.com/cla-assistant/cla-assistant#request-more-information-from-the-cla-signer) + +You can also add a `metadata` file to the CLA gist, to build a custom form for the CLA tool: + +```json +{ + "name": { + "title": "Full Name", + "type": "string", + "githubKey": "name" + }, + "email": { + "title": "E-Mail", + "type": "string", + "githubKey": "email", + "required": true + }, + "country": { + "title": "Country you are based in", + "type": "string", + "required": true + }, + "company": { + "title": "Company or Organization", + "description": "If you're not affiliated with any, please write 'OSS Contributor'", + "type": "string", + "required": true + }, + "role": { + "title": "Your Role", + "description": "What is your role in your company/organization? Skip this if you're not affiliated with any", + "type": "string", + "required": false + }, + "agreement": { + "title": "I have read and agree to the CLA", + "type": "boolean", + "required": true + } +} +``` + +Produces the following form: + + + diff --git a/legacy/contributors-guide/standards/README.md b/legacy/contributors-guide/standards/README.md new file mode 100644 index 000000000..34723d218 --- /dev/null +++ b/legacy/contributors-guide/standards/README.md @@ -0,0 +1,355 @@ +# Standards + +> *Note:* These standards are by no means set in stone, and as a community, we always want to be iterating and improving Mojaloop. If you want to propose a change to these standards, or suggest further improvements, please reach out to the Design Authority Channel on the Mojaloop Slack (#design-authority) + +## Style Guide + +The Mojaloop Community provides a set of guidelines for the style of code we write. These standards help ensure that the Mojaloop codebase remains high quality, maintainable and consistent. + +These style guides are chosen because they can be easily enforced and checked using popular tools with minimal customisation. While we recognise that developers will have personal preferences that may conflict with these guidelines we favour consistency over [bike-shedding](https://en.wikipedia.org/wiki/Law_of_triviality) these rules. + +The goal of these guides is to ensure an easy developer workflow and reduce code commits that contain changes for the sake of style over content. By reducing the noise in diffs we make the job of reviewers easier. + +### Code Style + +#### Javascript + +Mojaloop uses the Javascript code style dictated by [StandardJS](https://standardjs.com/). For a full set of rules, refer to the [Standard Rules](https://standardjs.com/rules.html), but as a brief set of highlights: + +- Use *2 spaces* for indentation + +```js +function helloWorld (name) { + console.log('hi', name) +} +``` + +- Use *single quotes* for strings except to avoid escaping. + +```js +console.log('hello there') // ✓ ok +console.log("hello there") // ✗ avoid +console.log(`hello there`) // ✗ avoid +``` + +- No semicolons. (see: 1, 2, 3) + +```js +window.alert('hi') // ✓ ok +window.alert('hi'); // ✗ avoid +``` + +#### Typescript + +>*Note: Standard and Typescript* +> +>As we start to introduce more Typescript into the codebase, Standard becomes less useful, and can even be detrimental +>to our development workflow if we try to run standard across the Javascript compiled from Typescript. +>We need to evaluate other options for Standard in Typescript, such as a combination of Prettier + ESLint + +Refer to the [template-typescript-public](https://github.com/mojaloop/template-typescript-public) for the standard typescript configuration. + + +#### YAML + +While YAML deserializers can vary from one to another, we follow the following rules when writing YAML: +> Credit: these examples were taken from the [flathub style guide](https://github.com/flathub/flathub/wiki/YAML-Style-Guide) + +- 2 space indents +- Always indent child elements + +```yaml +# GOOD: +modules: + - name: foo + sources: + - type: bar + +# BAD: +modules: +- name: foo + sources: + - type: bar +``` + +- Do not align values + +```yaml +# BAD: +id: org.example.Foo +modules: + - name: foo + sources: + - type: git +``` +#### sh + bash + +- The Shebang should respect the user's local environment: + +```bash +#!/usr/bin/env bash +``` + +This ensures that the script will match the `bash` that is defined in the user's environment, instead of hardcoding to a specific bash at `/usr/bin/bash`. + +- When referring to other files, don't use relative paths: + +This is because your script will likely break if somebody runs it from a different directory from where the script is located + +```bash +# BAD: +cat ../Dockerfile | wc -l + +# GOOD: +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cat ${DIR}/../Dockerfile | wc -l +``` + +For other recommended bash conventions, refer to this blog post: [Best Practices for Writing Shell Scripts](https://kvz.io/bash-best-practices.html) + +### Documentation + +Documentation should be written in Mark Down format. +All discusison documents should be placed in /documentation/discussions +The use of Google Docs and other tools should not be used. + +### Directory Structure + +Along with guidelines for coding styles, the Mojaloop Community recommends the following directory structure. This ensures that developers can easily switch from one project to another, and also ensures that our tools and configs (such as `.circleci/config.yml` and `Dockerfile`s) can be ported easily from one project to another with minor changes. + +The directory structure guide requires: + +```bash +├── package.json # at the root of the project +├── src # directory containing project source files +├── dist # directory containing compiled javascript files (see tsconfig below) +├── test # directory for tests, containing at least: +│  ├── unit # unit tests, matching the directory structure in `./src` +│  └── integration # integration tests, matching the directory structure in `./src` +└── config + └── default.json # RC config file +``` + +### Config Files + +The following Config files help to enforce the code styles outlined above: + + +#### EditorConfig +> EditorConfig is supported out of the box in many IDEs and Text editors. For more information, refer to the [EditorConfig guide](https://editorconfig.org/). + +`.editorconfig` +```ini +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[{*.js,*.ts,package.json,*.yml,*.cjson}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false +``` + +#### NYC (code coverage tool) + +`.nycrc.yml` +```yml +temp-directory: "./.nyc_output" +check-coverage: true +per-file: true +lines: 90 +statements: 90 +functions: 90 +branches: 90 +all: true +include: [ + "src/**/*.js" +] +reporter: [ + "lcov", + "text-summary" +] +exclude: [ + "**/node_modules/**", + '**/migrations/**' +] +``` + +### Typescript + +`.tsconfig.json` +```json +{ + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "lib", + "coverage" + ], + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": [ + "esnext" + ], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "outDir": "./dist", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "baseUrl": "./", + "paths": { + "*": [ + "src/*", + "node_modules/*" + ] + }, + "esModuleInterop": true + } +} +``` + +`.eslintrc.js` +```js +module.exports = { + parser: '@typescript-eslint/parser', // Specifies the ESLint parser + extends: [ + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier + 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. + // Enforces ES6+ import/export syntax + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', + ], + parserOptions: { + ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off' + }, + overrides: [ + { + // Disable some rules that we abuse in unit tests. + files: ['test/**/*.ts'], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + }, + }, + ], +}; +``` + +For a more detailed list of the recommended typescript configuration, including `package.json`, `jest.config.js` and more, refer to the [Typescript Template Project](https://github.com/mojaloop/template-typescript-public) + +### Design + Implementation Guidelines + +These guidelines are meant as recommendations for writing code in the Mojaloop community (or code that will be adopted into the community). If you are writing code that you wish to donate code to the community, we ask that you follow these guidelines as much as possible to aid with the consistency and maintainability of the codebase. Donations that adhere to these guidelines will be adopted more easily and swiftly. + +For more information, refer to the FAQ [below](#faqs). + +#### Tools + Frameworks + +In the Mojaloop OSS Community, we are prefer the following tools and frameworks: + +- **Web Server:** [`HapiJS`](https://github.com/hapijs/hapi) +- **Web UI Framework:** [`ReactJS`](https://reactjs.org/) +- **Runtime Configuration:** [`rc`](https://www.npmjs.com/package/rc) (both from env variables and config files) +- **Package Management:** `npm` +- **Logging:** [`@mojaloop/central-services-logger`](https://github.com/mojaloop/central-services-logger#readme) library, built on top of Winston +- **Containers and Orchestration:** [`docker`](https://www.docker.com/) and [`kubernetes`](https://kubernetes.io/) +- **Unit Testing:** For existing tests, [`Tape`](https://github.com/substack/tape), but we are currently moving over to [`Jest`](https://jestjs.io/) for new codebases. +- **Test Coverage:** [`nyc`](https://github.com/istanbuljs/nyc) +- **CI:** [`CircleCI`](https://circleci.com/) + +By using these tools and frameworks, we maintain a high level of consistency and maintainability across the codebase, which keeps our developers productive and happy. While we don't mandate that donated codebases use these same tools and frameworks, we would like to stress that adoptions that use different tools could create an undue maintenance burden on the Community. + +### Adopting Open Source Contributions into Mojaloop + +This section provides guidelines regarding the adoption of a contribution to the Mojaloop Open Source repositories. Adoption is the process where we as the community work with a contributor to bring a contribution into alignment with our standards and guidelines to be a part of the Mojaloop OSS Codebase. + +>*Note:* Code Contributions are evaluated on a **case-by-case** basis. Contributions that don't align to these guidelines will need to go through the incubation phase as described below. Other misalignments to these standards (for example, framework choices) may be added to a roadmap for further improvement and OSS Standardization in the future. + +#### Step 0: Prerequisites + +Before a contribution is to be considered for adoption, it: + +1. Should be in-line with the [Level One Project Principles](https://leveloneproject.org/) +1. Should adhere to the above Style and Design + Implementation Guides +1. Should contain documentation to get started: the more, the better +1. Contain tests with a high level of coverage. At a minimum, a contribution should contain unit tests, but a test suite with unit, integration and functional tests is preferred. Refer to the [contributors guide](./tools-and-technologies/automated-testing) for more information. + +#### Step 1: Incubation + +1. Create a private repo within the Mojaloop GitHub organization for the adopted code +1. Have a sub-team of the DA take a look to make sure its portable \(to OSS\) - aligns with L1P principles, etc, and ensure design is in line with standards +1. Check Licensing of the contribution and any new dependencies it requires, and add the standard Mojaloop License with attribution to donor/contributors +1. Assess the current state of the codebase, including documentation, tests, code quality, and address any shortfalls +1. Assess Performance impact +1. Create action items \(stories\) to update naming, remove/sanitize any items that are not generic +1. Inspect and discuss any framework and tooling choices. + - If a decision is made to make any changes, add them to the roadmap + +#### Step 2: Public Adoption + +1. Make the project public on Mojaloop GitHub +1. Announce on the slack `#announcements` channel +1. Enable CI/CD Pipelines and publish any relevant artifacts, such as Docker Images or npm modules +1. Review and recommend a module or course for the Mojaloop Training Program if needed and relevant for this contribution. + +### Versioning + +Review the information on [versioning](versioning.md) for Mojaloop. + +### Creating new Features + +Process for creating new [features and branches](creating-new-features.md) in Mojaloop. + +### Pull Request Process + +It's a good idea to ask about major changes on [Slack](https://mojaloop.slack.com). Submit pull requests which include both the change and the reason for the change. Feel free to use GitHub's "Draft Pull Request" feature to open up your changes for comments and review from the community. + +Pull requests will be denied if they violate the [Level One Principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf) + +### Code of conduct + +We use the [Mojaloop Foundation Code of Conduct](https://github.com/mojaloop/mojaloop/blob/master/CODE_OF_CONDUCT.md) + +### Licensing + +See [License](https://github.com/mojaloop/mojaloop/blob/master/contribute/License.md) policy + +### FAQs + +__1. What if I want to contribute code, but it doesn't align with the code style and framework/tool recommendations in this guide?__ + +Contributions are accepted on a _case by case_ basis. If your contribution is not yet ready to be fully adopted, we can go through the incubation phase described above, where the code is refactored with our help and brought into alignment with the code and documentation requirements. + + +__2. These standards are outdated, and a newer, cooler tool (or framework, method or language) has come along that will solve problem _x_ for us. How can I update the standards?__ + +Writing high quality, functional code is a moving target, and we always want to be on the lookout for new tools that will improve the Mojaloop OSS codebase. So please talk to us in the design authority slack channel (`#design-authority`) if you have a recommendation. diff --git a/legacy/contributors-guide/standards/creating-new-features.md b/legacy/contributors-guide/standards/creating-new-features.md new file mode 100644 index 000000000..a5a3ea3af --- /dev/null +++ b/legacy/contributors-guide/standards/creating-new-features.md @@ -0,0 +1,63 @@ +# Creating new Features + +### Fork + +Fork the Mojaloop repository into your own personal space. Ensure that you keep the `master` branch in sync. + +Refer to the following documentation for more information: [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/) + +1. Clone repo using Git Fork button \(refer to the above documentation for more information\) +2. Clone your forked repo: `git clone https://github.com//.git` +3. Synchronise your forked repo with Mojaloop + + Add a new upstream repo for Mojaloop `$ git remote add mojaloop https://github.com/mojaloop/.git` + + You should now see that you have two remotes: + + ```bash + git remote -v + origin https://github.com//.git (fetch) + origin https://github.com//.git (push) + mojaloop https://github.com/mojaloop/.git (fetch) + mojaloop https://github.com/mojaloop/.git (push) + ``` + +4. To sync to your current branch: `git pull mojaloop ` This will merge any changes from Mojaloop's repo into your forked repo. +5. Push the changes back to your remote fork: `git push origin ` + +### Creating a Branch + +Create a new branch from the `master` branch with the following format: `/` where `issue#` can be attained from the Github issue, and the `issueDescription` is the issue description formatted in CamelCase. + +1. Create and checkout the branch: `git checkout -b /` +2. Push the branch to your remote: `git push origin /` + +Where `` can be one of the following: + +| branchType | Description | +| :--- | :--- | +| feature | Any new or maintenance features that are in active development. | +| hotfix | A hotfix branch is for any urgent fixes. | +| release | A release branch containing a snapshot of a release. | +| backup | A temporary backup branch. Used normally during repo maintenance. | + +### Open a Pull Request (PR) + +Once your feature is ready for review, create a Pull Request from you feature branch back into the `master` branch on the Mojaloop Repository. If you're new to GitHub or Pull Requests, take a look at [this guide](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) for more information. + +#### Pull Request Titles + +Mojaloop uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to help our automated tooling manage releases and deployments. Your Pull Request title _must_conform to the conventional commits specification to pass the CI/CD checks in CircleCI. + +By adopting Conventional Commits + Semantic Versioning we can automatically release a new version for a given component and increment the `MAJOR`, `MINOR` and `BUGFIX` versions based soley on the PR titles, and auto generate rich changelogs. (See [this example](https://github.com/mojaloop/thirdparty-scheme-adapter/releases/tag/v11.20.0) of an auto generated changelog) + +> **Note**: +> When merging (and squashing) a PR, GitHub uses the _title_ of the PR for the git commit message. This means that to specify a breaking change, you must use the `!` format: +> "If included in the type/scope prefix, breaking changes MUST be indicated by a ! immediately before the :. If ! is used, BREAKING CHANGE: MAY be omitted from the footer section, and the commit description SHALL be used to describe the breaking change." + +**Examples of good PR titles** +- feat(api): add ability to handle `PUT /thirdpartyRequests/trasactions/{ID}` endpoint +- fix: update outdated node modules +- feat(models)!: change database schema +- chore: tidy up readme + diff --git a/contributors-guide/standards/triaging-ml-oss-bugs.md b/legacy/contributors-guide/standards/triaging-ml-oss-bugs.md similarity index 92% rename from contributors-guide/standards/triaging-ml-oss-bugs.md rename to legacy/contributors-guide/standards/triaging-ml-oss-bugs.md index 7c8a43ff3..92d140af8 100644 --- a/contributors-guide/standards/triaging-ml-oss-bugs.md +++ b/legacy/contributors-guide/standards/triaging-ml-oss-bugs.md @@ -21,18 +21,13 @@ There is a bug [template](https://github.com/mojaloop/project/issues/new?assigne 3. Based on the discussions, a final call on the priority and severity of the issue is made by the Program Manager. 4. If you think you need a vote, please reach out to Kim or Sam. 5. Here are the voting members [14] for triaging bugs to start with. - 1. Adrian Hope-Bailie - 1. James Bush 1. Kim Walters 1. Lewis Daly 1. Miguel deBarros - 1. Matt Bohan - 1. Miller Abel - 1. Neal Donnan - 1. Nico Duvenage - 1. Rajiv Mothilal - 1. Rob Reeve 1. Sam Kummary 1. Sri Miryala 1. Warren Carew + 1. Vijay Guthi + 1. Valentin Genev + 1. Shashi Hirugade 6. The list and the process will be updated as it evolves, this is a proposal to start with do a Pilot on. diff --git a/legacy/contributors-guide/standards/versioning.md b/legacy/contributors-guide/standards/versioning.md new file mode 100644 index 000000000..8ea82358e --- /dev/null +++ b/legacy/contributors-guide/standards/versioning.md @@ -0,0 +1,126 @@ +# Versioning + +## Versioning of releases made for core Switch services + +This document provides guidelines regarding the versioning strategy used for the releases of Mojaloop Open Source repositories corresponding to the Switch services. + +### Versioning Strategy + + +#### Standard for PI-11 and beyond +1. Starting PI-11 (27th July, 2020) the Versioning guidance is to move to a versioning system that is closely aligned with Semantic versioning by removing the PI/Sprint dependency. So starting 11.x.x, the proposal is to move to pure [SemVer](https://semver.org/). +2. At a high-level, we will still follow the vX.Y.Z format, but X represents ‘Major’ version, Y represents ‘Minor’ version and Z represents ‘patch’ version. Minor fixes, patches affect increments to ‘Z’, whereas non-breaking functionality changes affect changes to ‘Y; breaking changes affect the ‘X’ version. +3. Along with these, suffixes such as “-snapshot”, “-patch”, “-hotfix” are used as relevant and on need basis (supported by CI config). +4. So starting with 11.0.0 (primarily for Helm, but for individual services as well) for PI-11, the proposal is to move to pure [SemVer](https://semver.org/). +5. This implies that for any new release of a package/service below X=11 (for existing repositories and not new ones) will first be baselined to v11.0.0 and from then on follow standard SemVer guidelines as discussed above. For new projects or repositories, versioning can start from v1.0.0 (after they reach release status) + + +#### Versioning Strategy used until PI-10 +1. The Mojaloop (up to PI-10) versioning system is inspired by the [Semantic Versioning](https://semver.org/) numbering system for releases. +2. However, this is customized to depict the timelines of the Mojaloop project, based on the Program Increment \(PI\) and Sprint numbers +3. For example, the release number v5.1.0 implies that this release was the first one made during a Sprint 5.1, where Sprint5.1 is the first Sprint in PI-5. So for a version vX.Y.Z, X.Y is the Sprint number where X is the PI number and Z represents the number of release for this specific repository. Example v4.4.4 implies that the current release is the fourth of four releases made in Sprint 4.4 \(of PI-4\) + + + +### Current Version + +The currrent version information for Mojaloop can be found [here](../../deployment-guide/releases.md). + +### Sprint schedule for PI-13 + +Below is the Sprint schedule for Program Increment 13 which ends with the PI-14 Community event in April 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-5 Kick-off On-site**|1/25/2021|1/29/2021|5 days| Virtual Zoom Webinars| +|**Sprint 13.1**|02/01/2021|02/14/2021|2 weeks | | +|**Sprint 13.2**|02/15/2021|02/28/2021|2 weeks | | +|**Sprint 13.3**|03/01/2021|03/14/2021|2 weeks | | +|**Sprint 13.4**|03/15/2021|03/28/2021|2 weeks | | +|**Sprint 13.5**|03/29/2021|04/11/2021|2 weeks | | +|**Sprint 13.6**|04/12/2021|04/25/2021|2 weeks | | +|**Phase-5 PI-14**|04/26/2021|04/30/2021|5 days| Virtual meetings | + +### Sprint schedule for PI-12 + +Below is the Sprint schedule for Program Increment 12 which ends with the PI-13 Community event in January 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-12 Virtual**|10/19/2020|10/23/2020|5 days| Virtual Zoom Webinars| +|**Sprint 12.1**|10/26/2020|11/15/2020|3 weeks | | +|**Sprint 12.2**|11/16/2020|11/29/2020|2 weeks | | +|**Sprint 12.3**|11/30/2020|12/13/2020|2 weeks | | +|**Sprint 12.4**|12/14/2020|12/27/2020|2 weeks | | +|**Sprint 12.5**|12/28/2020|01/10/2021|2 weeks | | +|**Sprint 12.6**|01/11/2020|01/24/2020|2 weeks | | +|**Phase-5 Kick-off / PI-13**|01/25/2021|01/29/2021|5 days| TBD | + +### Previous Sprint Schedules: + +### Sprint schedule for PI-11 + +Below is the Sprint schedule for Program Increment 11 which ends with the PI 12 Event. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars | +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars | +|**Sprint 11.1**|7/27/2020|8/9/2020|2 weeks| | +|**Sprint 11.2**|8/10/2020|8/23/2020|2 weeks| | +|**Sprint 11.3**|8/24/2020|9/6/2020|2 weeks| | +|**Sprint 11.4**|9/7/2020|9/20/2020|2 weeks| | +|**Sprint 11.5**|9/21/2020|10/4/2020|2 weeks| | +|**Sprint 11.6**|10/5/2020|10/18/2020|2 weeks | | +|**Phase-4 PI-12**|10/20/2020|10/23/2020|4 days| TBD | + +#### Sprint schedule for PI-10 + +Below is the Sprint schedule for Program Increment 10 which ends with the PI 11 Event. Please use this as guidance during the versioning and release processes. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-3 PI6 On-site**|4/16/2019|4/18/2019|3 days| Johannesburg| +|**Phase-3 PI7 On-site**|6/25/2019|6/27/2019|3 days| Arusha| +|**Phase-3 PI8 On-site**|9/10/2019|9/12/2019|3 days| Abidjan| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI 10 Virtual**|4/21/2020|4/24/2020|5 days| Virtual Zoom Webinars | +|**Sprint 10.1**|4/27/2020|5/10/2020|2 weeks| | +|**Sprint 10.2**|5/11/2020|5/24/2020|2 weeks| | +|**Sprint 10.3**|5/25/2020|6/7/2020|2 weeks| | +|**Sprint 10.4**|6/8/2020|6/21/2020|2 weeks| | +|**Sprint 10.5**|6/22/2020|7/5/2020|2 weeks| | +|**Sprint 10.6**|7/6/2020|7/19/2020|2 weeks | | +|**Phase-4 PI 11 On-Site**|7/21/2020|7/23/2020|3 days| Kenya (Tentative) | + +#### PI-9 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 9.1**|2/3/2020|2/16/2020|2 weeks| | +|**Sprint 9.2**|2/17/2020|3/1/2020|2 weeks| | +|**Sprint 9.3**|3/2/2020|3/15/2020|2 weeks| | +|**Sprint 9.4**|3/16/2020|3/29/2020|2 weeks| | +|**Sprint 9.5**|3/30/2020|4/12/2020|2 weeks| | +|**Sprint 9.6**|3/13/2020|4/19/2020|1 week | | +|**Phase-4 PI 10 Virtual**|4/21/2020|4/23/2020|5 days| Virtual Zoom Webinars | + +#### PI-8 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 8.1**|9/16/2019|9/29/2019|2 weeks| | +|**Sprint 8.2**|9/30/2019|10/13/2019|2 weeks| | +|**Sprint 8.3**|10/14/2019|10/27/2019|2 weeks| | +|**Sprint 8.4**|10/28/2019|11/10/2019|2 weeks| | +|**Sprint 8.5**|11/11/2019|11/24/2019|2 weeks| | +|**Sprint 8.6**|11/25/2019|12/8/2019|2 weeks| | +|**Sprint 8.7**|12/9/2019|1/5/2020|4 weeks| Christmas Break| +|**Sprint 8.8**|1/6/2020|1/26/2020|3 weeks| 1 week prep| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| + +### Notes + +1. A new release for **helm** repo is made based on the feature and configuration changes made to core services and requirements from thhe Community. diff --git a/contributors-guide/tools-and-technologies/README.md b/legacy/contributors-guide/tools-and-technologies/README.md similarity index 100% rename from contributors-guide/tools-and-technologies/README.md rename to legacy/contributors-guide/tools-and-technologies/README.md diff --git a/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-build.svg b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-build.svg similarity index 100% rename from contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-build.svg rename to legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-build.svg diff --git a/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-pr.svg b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-pr.svg similarity index 100% rename from contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-pr.svg rename to legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-license-scanning/audit-licenses-pr.svg diff --git a/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml new file mode 100644 index 000000000..0aaf61dbe --- /dev/null +++ b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml @@ -0,0 +1,70 @@ +@startuml + +skinparam TitleFontColor #819FF7 +skinparam TitleFontSize 23 + +title Regression Test Life Cycle\n(Self-contained Test Server on EC2) + +skinparam backgroundColor #353B42 +skinparam activity { + StartColor #40FF00 + EndColor #FF0000 + BackgroundColor #2E9AFE + BorderColor #A9D0F5 + LineColor #AAAAAA +} + +skinparam Arrow{ + Color #BFA350 + FontSize 10 + FontColor #6CBF50 +} + +start + +:Test is triggered; +note right: This could be a manual trigger, \nscheduler timer or \nan external action like a Pull Request \nfrom the Source Control System + +if (Validate run parameters as expected?) then (yes) + :Prepare environment for required run; + note left: Set Timestamp\nPostmanCollection to execute\nList of email recipients\nEnvironment Variables\nExecution Timestamp\nOutput FileName +else (no) + -[#red]-> + :Abort run with Note stating incorrect Run Parameters; + -[#red]-> + stop +endif + +:Create Simulator Docker Container; +:Create Regression Test Docker Container; +note left: This container has node\nNewman\email SMTP Server + +while (More Postman Requests to run?) is (Yes) + :Perform Pre-Request Script; + note right: Set up any variables for\npreparation of the request to follow + :Execute Postman Request; + :Perform Test; + :Log Results; + note right: Inspect the response \nagainst variables set previously during\nthe run to determine if expected results are obtained + if (Assertion Test Failed?) then (yes) + if (Run Parameter requested 'Abort at First Error'?) then (yes) + -[#red]-> + (A) + detach + else (no) + endif + else (no) + endif +endwhile (No) + +(A) +:Destroy Simulator Docker Container; +:Finalise Report; +:Prepare Notification(s); +:Attach Reports; +:Send out Notification(s); +note right: The Attachment (Generated Report) \nis sent as an attachment \nto the different notification channels. +:Destroy Regression Test Docker Container; +stop + +@enduml \ No newline at end of file diff --git a/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.svg b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.svg new file mode 100644 index 000000000..c5a3bd917 --- /dev/null +++ b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.svg @@ -0,0 +1,255 @@ + + + + + + + + + + + Regression Test Life Cycle + + + (Self-contained Test Server on EC2) + + + + + + This could be a manual trigger, + + + scheduler timer or + + + an external action like a Pull Request + + + from the Source Control System + + + + Test is triggered + + + + Validate run parameters as expected? + + + yes + + + no + + + + + Set Timestamp + + + PostmanCollection to execute + + + List of email recipients + + + Environment Variables + + + Execution Timestamp + + + Output FileName + + + + Prepare environment for required run + + + + Abort run with Note stating incorrect Run Parameters + + + + + + Create Simulator Docker Container + + + + + This container has node + + + Newman\email SMTP Server + + + + Create Regression Test Docker Container + + + + + Set up any variables for + + + preparation of the request to follow + + + + Perform Pre-Request Script + + + + Execute Postman Request + + + + Perform Test + + + + + Inspect the response + + + against variables set previously during + + + the run to determine if expected results are obtained + + + + Log Results + + + + no + + + Run Parameter requested 'Abort at First Error'? + + + yes + + + + + + yes + + + Assertion Test Failed? + + + no + + + + Yes + + + More Postman Requests to run? + + + No + + + + + + Destroy Simulator Docker Container + + + + Finalise Report + + + + Prepare Notification(s) + + + + Attach Reports + + + + + The Attachment (Generated Report) + + + is sent as an attachment + + + to the different notification channels. + + + + Send out Notification(s) + + + + Destroy Regression Test Docker Container + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contributors-guide/tools-and-technologies/assets/diagrams/rest/glory-of-rest.png b/legacy/contributors-guide/tools-and-technologies/assets/diagrams/rest/glory-of-rest.png similarity index 100% rename from contributors-guide/tools-and-technologies/assets/diagrams/rest/glory-of-rest.png rename to legacy/contributors-guide/tools-and-technologies/assets/diagrams/rest/glory-of-rest.png diff --git a/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-pr-build.png b/legacy/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-pr-build.png similarity index 100% rename from contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-pr-build.png rename to legacy/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-pr-build.png diff --git a/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-release-build.png b/legacy/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-release-build.png similarity index 100% rename from contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-release-build.png rename to legacy/contributors-guide/tools-and-technologies/assets/images/automated-license-scanning/circle-release-build.png diff --git a/contributors-guide/tools-and-technologies/automated-license-scanning.md b/legacy/contributors-guide/tools-and-technologies/automated-license-scanning.md similarity index 89% rename from contributors-guide/tools-and-technologies/automated-license-scanning.md rename to legacy/contributors-guide/tools-and-technologies/automated-license-scanning.md index 62a958165..1640fb5bc 100644 --- a/contributors-guide/tools-and-technologies/automated-license-scanning.md +++ b/legacy/contributors-guide/tools-and-technologies/automated-license-scanning.md @@ -5,22 +5,21 @@ For Mojaloop to maintain its open source nature and compatibility with the [Moja ## Mojaloop License Scanner We have a suite of tools bundled under the [license-scanner](https://github.com/mojaloop/license-scanner) project on the Mojaloop Github account. The license-scanner allows us to: + - Perform a license scan across one to many Mojaloop github repositories - Integrate with FossaCLI to run mass license audits across the entire codebase - Run inside of a CI process - Run a license scan against a pre-built docker image - For more information, refer to the [readme](https://github.com/mojaloop/license-scanner) in the license-scanner repository. +## Blocking and Allowing Licenses -## Blacklisting and Whitelisting - -The license-scanner works by blacklisting unwanted licenses, and whitelisting packages which have been manually audited, and we are comfortable with using. +The license-scanner works by blocklisting unwanted licenses, and allowlisting packages which have been manually audited, and we are comfortable with using. In the [`config.toml`](https://github.com/mojaloop/license-scanner/blob/master/config.toml) file, we configure two arrays of strings. -__Adding a new License identifier to the blacklist:__ +__Adding a new License identifier to the blocklist:__ Edit `config.tml`, and add the license string into the `failList` array: ```toml @@ -33,14 +32,14 @@ failList = [ ] ``` -The license-scanner will pick out licenses that it finds in the `node_modules` folder, and if the license string is in the `failList` (using a fuzzy string search), the license-scanner will fail, unless the package is found in the whitelist. +The license-scanner will pick out licenses that it finds in the `node_modules` folder, and if the license string is in the `failList` (using a fuzzy string search), the license-scanner will fail, unless the package is found in the allowlist. -__Adding a new package to the whitelist:__ +__Adding a new package to the allowlist:__ -In addition to maintaining a blacklist of licenses, we whitelist packages that we have manually audited and are happy to include. +In addition to maintaining a blocklist of licenses, we allowlist packages that we have manually audited and are happy to include. The most common case for this is packages that don't have a license entry in the `package.json` file, which the npm license scan tool lists as `UNKNOWN`. -To add a package to the whitelist, simply add an entry to the `excludeList` in `config.toml`. For example: +To add a package to the allowlist, simply add an entry to the `excludeList` in `config.toml`. For example: ```toml excludeList = [ "taffydb@2.6.2", @@ -51,11 +50,11 @@ excludeList = [ ] ``` ->___FAQ:__ Why keep a whitelist?_ +>___FAQ:__ Why keep a allowlist?_ > >The license-scanner is not perfect, and sometimes there are packages that have been incorrectly identified, or contain no license entry in the `package.json` file, but do contain a valid license in the package's git repository. > ->By maintaining a whitelist of packages we have manually audited, we can get around incorrectly labelled packages. +>By maintaining a allowlist of packages we have manually audited, we can get around incorrectly labelled packages. ## Running Inside CI/CD @@ -63,7 +62,7 @@ excludeList = [ ### PR Flow When a new Pull Request is opened for a Mojaloop project, the license scanner runs as a part of the CI/CD workflow. The step in CircleCI is called 'audit-licenses' - +
    Example CircleCI Build Overview PR The license-scanner does the following: @@ -78,7 +77,7 @@ The license-scanner does the following: * 4. Uploads the results as a `.csv` artifact -Should the license scanner pass (i.e. find no licenses that are blacklisted), the build will succeed. +Should the license scanner pass (i.e. find no licenses that are blocklisted), the build will succeed. CircleCI license scanning for PR diff --git a/legacy/contributors-guide/tools-and-technologies/automated-testing.md b/legacy/contributors-guide/tools-and-technologies/automated-testing.md new file mode 100644 index 000000000..b7f005913 --- /dev/null +++ b/legacy/contributors-guide/tools-and-technologies/automated-testing.md @@ -0,0 +1,166 @@ +# QA and Regression Testing in Mojaloop + +An overview of the testing framework set up in Mojaloop + +Contents: + +- [QA and Regression Testing in Mojaloop](#qa-and-regression-testing-in-mojaloop) + - [Regression Topics](#regression-topics) + - [Developer Testing](#developer-testing) + - [The section below is deprecated. Mojaloop Releases now use test collections that run on the Mojaloop Testing Toolkit (TTK). Please use the readme page on the repository until this document is properly updated](#the-section-below-is-deprecated-mojaloop-releases-now-use-test-collections-that-run-on-the-mojaloop-testing-toolkit-ttk-please-use-the-readme-page-on-the-httpsgithubcommojalooptesting-toolkit-test-cases-repository-until-this-document-is-properly-updated) + - [[DEPRECATED] Postman and Newman Testing](#deprecated-postman-and-newman-testing) + - [Postman Collections](#postman-collections) + - [Environment Configuration](#environment-configuration) + - [Executing regression test](#executing-regression-test) + - [Steps to execute the script via Postman UI](#steps-to-execute-the-script-via-postman-ui) + - [Steps to execute the bash script to run the Newman / Postman test via CLI](#steps-to-execute-the-bash-script-to-run-the-newman--postman-test-via-cli) + - [Process flow of a typical Scheduled Test](#process-flow-of-a-typical-scheduled-test) + - [Newman Commands](#newman-commands) + +## Regression Topics + + In order for a deployed system to be robust, one of the last checkpoints is to determine if the environment it is deployed in, is in a healthy state and all exposed functionality works exactly the way as intended. + + Prior to that though, there are quite a number of disciplines one must put in place to ensure maximum control. + + To illustrate how the Mojaloop project reaches this goal, we are going to show you the various checkpoints put in place. + +### Developer Testing + + Looking at each component and module, inside the code base, you will find a folder named "*test*" which contain three types of tests. + +- Firstly, the *coverage test* which alerts one if there are unreachable or redundant code +- Unit Tests, which determines if the intended functionality works as expected +- Integration Tests, which does not test end-to-end functionality, but the immediate neighboring interaction +- Automated code-standard checks implemented by means of packages that form part of the code base + + These tests are executed by running the command line instructions, by the developer, during the coding process. Also, the tests are automatically executed every time a *check-in* is done and a Github Pull-Request issued for the code to be integrated into the project. + + The procedure described above, falls outside the realm of Quality Assurance (QA) and Regression testing, which this document addresses. + + Once a developer has written new functionality or extended existing functionality, by having to go through the above rigorous tests, one can assume the functionality in question is executing as intended. How does one then ensure that this new portion of code does not negatively affect the project or product as a whole? + + When the code has passed all of the above and is deployed as part of the CI/CD processes implemented by our workflow, the new component(s) are accepted onto the various hosts, cloud-based or on-premise implementations. These hosts ranges from development platforms through to production environments. + +### The section below is deprecated. Mojaloop Releases now use test collections that run on the Mojaloop Testing Toolkit (TTK). Please use the readme page on the repository until this document is properly updated + +### [DEPRECATED] Postman and Newman Testing + +Parallel to the deployment process is the upkeep and maintenance of the [Postman](https://github.com/mojaloop/postman.git "Postman") Collection testing Framework. When a new release is done, as part of the workflow, Release Notes are published listing all of the new and/or enhanced functionality implemented as part of the release. These notes are used by the QA team to extend and enhance the existing Postman Collections where tests are written behind the request/response scripts to test both positive as well as negative scenarios against the intended behaviour. These tests are then run in the following manner: + +- Manually to determine if the tests cover all aspects and angles of the functionality, positive to assert intended behaviour and negative tests to determine if the correct alternate flows work as intended when something unexpected goes wrong +- Scheduled - as part of the Regression regime, to do exactly the same as the manual intent, but fully automated (with the *Newman Package*) with reports and logs produced to highlight any unintended behaviour and to also warn where known behaviour changed from a previous run. + +In order to facilitate the automated and scheduled testing of a Postman Collection, there are various methods one can follow and the one implemented for Mojaloop use is explained further down in this document. + +There is a complete repository containing all of the scripts, setup procedures and anything required in order to set up an automated [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"). This framework allows one to target any Postman Collection, specifying your intended Environment to execute against, as well as a comma-separated list of intended email recipients to receive the generated report. This framework is in daily use by Mojaloop and exists on an EC2 instance on AWS, hosting the required components like Node, Docker, Email Server and Newman, as well as various Bash Scripts and Templates for use by the framework to automatically run the intended collections every day. Using this guide will allow anyone to set up their own Framework. + +#### Postman Collections + +There are a number of Postman collections in use throughout the different processes: + +For Mojaloop Simulator: + +- [MojaloopHub_Setup](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) : This collection needs to be executed once after a new deployment, normally by the Release Manager. It sets up an empty Mojaloop hub, including things such as the Hub's currency, the settlement accounts. +- [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) : MojaloopSims_Onboarding sets up the DFSP simulators, and configures things such as the endpoint urls so that the Mojaloop hub knows where to send request callbacks. +- [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + - Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. +- [Bulk_API_Transfers_MojaSims](https://github.com/mojaloop/postman/blob/master/Bulk_API_Transfers_MojaSims.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Mojaloop Simulator. + +For Legacy Simulator (encouraged to use Mojaloop Simulator, as this will not be supported starting PI-12 (Oct 2020) ): + +- [ML_OSS_Setup_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Setup_LegacySim.postman_collection.json) : This collection needs to be executed once after a new deployment (if it uses Legacy Simulator), normally by the Release Manager. It sets up the Mojaloop hub, including things such as the Hub's currency, the settlement accounts along with the Legacy Simulator(s) as FSP(s). +- [ML_OSS_Golden_Path_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Golden_Path_LegacySim.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + - Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. +- [Bulk API Transfers.postman_collection](https://github.com/mojaloop/postman/blob/master/Bulk%20API%20Transfers.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Legacy Simulator. + +#### Environment Configuration + +You will need to customize the following environment config file to match your deployment environment: + +- [Local Environment Config](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local.postman_environment.json) + +> Tips: +> +> - The host configurations will be the most likely changes required to match your environment. e.g. `HOST_CENTRAL_LEDGER: http://central-ledger.local`_ +> - Refer to the ingress hosts that have been configured in your `values.yaml` as part of your Helm deployment. +> + +### Executing regression test + +For the Mojaloop QA and Regression Testing Framework specifically, Postman regression test can be executed by going into the EC2 instance via SSH, for which you need the PEM file, and then by running a script(s). + +Following the requirements and instructions as set out in the detail in [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"), everyone will be able to create their own Framework and gain access to their instance to execute tests against any Postman Collection targeting any Environment they have control over. + +#### Steps to execute the script via Postman UI + +- Import the desired collection into your Postman UI. You can either download the collection from the repo or alternatively use the `RAW` link and import it directly via the **import link** option. +- Import the environment config into your Postman UI via the Environmental Config setup. Note that you will need to download the environmental config to your machine and customize it to your environment. +- Ensure that you have pre-loaded all prerequisite test data before executing transactions (party, quotes, transfers) as per the example collection [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json): + - Hub Accounts + - FSP onboarding + - Add any test data to Simulator (if applicable) + - Oracle onboarding +- The `p2p_money_transfer` test cases from the [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) collection are a good place to start. + +#### Steps to execute the bash script to run the Newman / Postman test via CLI + +- To run a test via this method, you will have to be in posession of the PEM-file of the server on which the Mojaloop QA and Regression Framework was deployed on an EC2 instance on Amazon Cloud. + +- SSH into the specific EC2 instance and when running the script, it will in turn run the commands via an instantiated Docker container. + +- You will notice that by using this approach where both the URLs for the Postman-Collection and Environment File are required as input parameters (together with a comma-delimited email recipient list for the report) you have total freedom of executing any Postman Collection you choose. + +- Also, by having an Environment File, the specific Mojaloop services targeted can be on any server. This means you can execute any Postman test against any Mojaloop installation on any server of your choice. + +- The EC2 instance we execute these tests from are merely containing all the tools and processes in order to execute your required test and does not host any Mojaloop Services as such. + +```bash +./testMojaloop.sh +``` + +## Process flow of a typical Scheduled Test + +![QARegressionTestingMojaloop-Complete.svg](./assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.svg) + +## Newman Commands + +The following section is a reference, obtained from the Newman Package site itself, highlighting the different commands that may be used in order to have access to the Postman environment by specifying some commands via the CLI. + +```bash +Example: +- newman run -e -n 1 -- + +Usage: run [options] + + URL or path to a Postman Collection. + + Options: + + -e, --environment Specify a URL or Path to a Postman Environment. + -g, --globals Specify a URL or Path to a file containing Postman Globals. + --folder Specify folder to run from a collection. Can be specified multiple times to run multiple folders (default: ) + -r, --reporters [reporters] Specify the reporters to use for this run. (default: cli) + -n, --iteration-count Define the number of iterations to run. + -d, --iteration-data Specify a data file to use for iterations (either json or csv). + --export-environment Exports the environment to a file after completing the run. + --export-globals Specify an output file to dump Globals before exiting. + --export-collection Specify an output file to save the executed collection + --postman-api-key API Key used to load the resources from the Postman API. + --delay-request [n] Specify the extent of delay between requests (milliseconds) (default: 0) + --bail [modifiers] Specify whether or not to gracefully stop a collection run on encountering an errorand whether to end the run with an error based on the optional modifier. + -x , --suppress-exit-code Specify whether or not to override the default exit code for the current run. + --silent Prevents newman from showing output to CLI. + --disable-unicode Forces unicode compliant symbols to be replaced by their plain text equivalents + --global-var Allows the specification of global variables via the command line, in a key=value format (default: ) + --color Enable/Disable colored output. (auto|on|off) (default: auto) + --timeout [n] Specify a timeout for collection run (in milliseconds) (default: 0) + --timeout-request [n] Specify a timeout for requests (in milliseconds). (default: 0) + --timeout-script [n] Specify a timeout for script (in milliseconds). (default: 0) + --ignore-redirects If present, Newman will not follow HTTP Redirects. + -k, --insecure Disables SSL validations. + --ssl-client-cert Specify the path to the Client SSL certificate. Supports .cert and .pfx files. + --ssl-client-key Specify the path to the Client SSL key (not needed for .pfx files) + --ssl-client-passphrase Specify the Client SSL passphrase (optional, needed for passphrase protected keys). + -h, --help output usage information +``` diff --git a/contributors-guide/tools-and-technologies/aws-cli.md b/legacy/contributors-guide/tools-and-technologies/aws-cli.md similarity index 100% rename from contributors-guide/tools-and-technologies/aws-cli.md rename to legacy/contributors-guide/tools-and-technologies/aws-cli.md diff --git a/contributors-guide/tools-and-technologies/code-quality-metrics.md b/legacy/contributors-guide/tools-and-technologies/code-quality-metrics.md similarity index 100% rename from contributors-guide/tools-and-technologies/code-quality-metrics.md rename to legacy/contributors-guide/tools-and-technologies/code-quality-metrics.md diff --git a/contributors-guide/tools-and-technologies/pragmatic-rest.md b/legacy/contributors-guide/tools-and-technologies/pragmatic-rest.md similarity index 100% rename from contributors-guide/tools-and-technologies/pragmatic-rest.md rename to legacy/contributors-guide/tools-and-technologies/pragmatic-rest.md diff --git a/cover.jpg b/legacy/cover.jpg similarity index 100% rename from cover.jpg rename to legacy/cover.jpg diff --git a/legacy/deployment-guide/README.md b/legacy/deployment-guide/README.md new file mode 100644 index 000000000..6eddbe3a3 --- /dev/null +++ b/legacy/deployment-guide/README.md @@ -0,0 +1,493 @@ +# Mojaloop Deployment + +The document is intended for an audience with a stable technical knowledge that would like to setup an environment for development, testing and contributing to the Mojaloop project. + +## Deployment and Setup + +- [Mojaloop Deployment](#mojaloop-deployment) + - [Deployment and Setup](#deployment-and-setup) + - [1. Pre-requisites](#1-pre-requisites) + - [2. Deployment Recommendations](#2-deployment-recommendations) + - [3. Kubernetes](#3-kubernetes) + - [3.1. Kubernetes Ingress Controller](#31-kubernetes-ingress-controller) + - [3.2. Kubernetes Admin Interfaces](#32-kubernetes-admin-interfaces) + - [4. Helm](#4-helm) + - [4.1. Helm configuration](#41-helm-configuration) + - [5. Mojaloop](#5-mojaloop) + - [5.1. Mojaloop Helm Deployment](#51-mojaloop-helm-deployment) + - [5.2. Verifying Ingress Rules](#52-verifying-ingress-rules) + - [5.3. Testing Mojaloop](#53-testing-mojaloop) + - [5.4. Testing Mojaloop with Postman](#54-testing-mojaloop-with-postman) + - [6. Overlay Services/3PPI](#6-overlay-services3ppi) + - [6.1 Configuring a deployment for Third Party API support](#61-configuring-a-deployment-for-third-party-api-support) + - [6.2 Validating and Testing the Third Party API](#62-validating-and-testing-the-third-party-api) + - [6.2.1 Deploying the Simulators](#621-deploying-the-simulators) + - [6.2.2 Provisioning the Environment](#622-provisioning-the-environment) + - [6.2.3 Run the Third Party API Test Collection](#623-run-the-third-party-api-test-collection) +### 1. Pre-requisites + +Versions numbers below are hard requirements, not just recommendations (more recent versions are known not to work). + +A list of the pre-requisite tool set required for the deployment of Mojaloop: + +- **Kubernetes** An open-source system for automating deployment, scaling, and management of containerized applications. Find out more about [Kubernetes](https://kubernetes.io). + - Recommended Versions: + > + > **Mojaloop Helm Chart release v14.1.x** supports **Kubernetes v1.20 - v1.24**. + > + > **Mojaloop Helm Chart release v14.0.x** supports **Kubernetes v1.20 - v1.21**. + > + > **Mojaloop Helm Chart release v13.x** supports **Kubernetes v1.13 - v1.21**. + > + > **Mojaloop Helm Chart release v12.x** supports **Kubernetes v1.13 - v1.20**. + > + > **Mojaloop Helm Chart release v11.x** supports **Kubernetes v1.13 - v1.17**. + > + > **Mojaloop Helm Chart release v10.x** supports **Kubernetes v1.13 - v1.15**, it will fail on Kubernetes v1.16+ onwards due deprecated APIs ([ref: Helm Issue #219](https://github.com/mojaloop/helm/issues/219)). + > + + - kubectl - Kubernetes CLI for Kubernetes Management is required. Find out more about [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/): + - [Install-kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/), + - microk8s - MicroK8s installs a barebones upstream Kubernetes for a single node deployment generally used for local development. We recommend this installation on Linux (ubuntu) OS. Find out more about [microk8s](https://microk8s.io/) and [microk8s documents](https://microk8s.io/docs/): + - [Install-microk8s](https://microk8s.io/docs/), + - kubectx - Not required but useful. Find out more about [kubectx](https://github.com/ahmetb/kubectx), + - kubetail - Not required but useful. Bash script that enables you to aggregate (tail/follow) logs from multiple pods into one stream. Find out more about [kubetail](https://github.com/johanhaleby/kubetail), +- **Docker** Provides containerized environment to host the application. Find out more about [Docker](https://docker.com), +- **Helm** A package manager for Kubernetes. Find out more about [Helm](https://helm.sh), +
    _Recommended Versions:_ +
        _**Helm v3.x** ([ref: Design Auth Issue #52](https://github.com/mojaloop/design-authority/issues/52))._ +- **Postman** Postman is a Google Chrome application for the interacting with HTTP API's. It presents you with a friendly GUI for the construction requests and reading responces. . Find out more about [Postman](https://postman.com). + +For **local guides** on how to setup the pre-requisites on your laptop or desktop, refer to the appropriate link document below; + +- [Local Setup for Mac](local-setup-mac.md) +- [Local Setup for Linux](local-setup-linux.md) +- [Local Setup for Windows](local-setup-windows.md) + +### 2. Deployment Recommendations + +This provides environment resource recommendations with a view of the infrastructure architecture. + +**Resources Requirements:** + +- Control Plane (i.e. Master Node) + + [https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components](https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components) + + - 3x Master Nodes for future node scaling and HA (High Availability) + +- ETCd Plane: + + [https://etcd.io/docs/v3.3.12/op-guide/hardware](https://etcd.io/docs/v3.3.12/op-guide/hardware) + + - 3x ETCd nodes for HA (High Availability) + +- Compute Plane (i.e. Worker Node): + + TBC once load testing has been concluded. However the current general recommended size: + + - 3x Worker nodes, each being: + - 4x vCPUs, 16GB of RAM, and 40gb storage + + **Note** that this would also depend on your underlying infrastructure, and it does NOT include requirements for persistent volumes/storage. + +![Mojaloop Deployment Recommendations - Infrastructure Architecture](./assets/diagrams/deployment/KubeInfrastructureArch.svg) + +### 3. Kubernetes + +This section will guide the reader through the deployment process to setup Kubernetes. + +If you are new to Kubernetes it is strongly recommended to familiarize yourself with Kubernetes. [Kubernetes Concepts](https://kubernetes.io/docs/concepts/overview/) is a good place to start and will provide an overview. + +The following are Kubernetes concepts used within the project. An understanding of these concepts is imperative before attempting the deployment; + +- Deployment +- Pod +- ReplicaSets +- Service +- Ingress +- StatefulSet +- DaemonSet +- Ingress Controller +- ConfigMap +- Secret + +Insure **kubectl** is installed. A complete set of installation instruction are available [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + +#### 3.1. Kubernetes Ingress Controller + +Install your preferred Ingress Controller for load-balancing and external access. + +Refer to the following documentation to install the Nginx-Ingress Controller used for this guide: . It is recommended that you install **v0.47.0** of the Nginx-Ingress Controller due to recent changes being made to support Kubernetes v1.22. + +If you are using helm, this can be done as follows: + +```bash +helm install ingress-nginx ingress-nginx --version="3.33.0" --repo https://kubernetes.github.io/ingress-nginx +``` + +> **NOTE: If you are installing Mojaloop v12.x with an Nginx-Ingress controller version newer than v0.22.0, ensure you create a custom [Mojaloop values config](https://github.com/mojaloop/helm/blob/v12.0.0/mojaloop/values.yaml) with the following changes prior to install:** +> +> ```YAML +> ## **LOOK FOR THIS LINE IN mojaloop/values.yaml CONFIG FILE** +> mojaloop-simulator: +> ingress: +> ## nginx ingress controller >= v0.22.0 <-- **COMMENT THE FOLLOWING THREE LINES BELOW:** +> # annotations: <-- COMMENTED +> # nginx.ingress.kubernetes.io/rewrite-target: '/$2' <-- COMMENTED +> # ingressPathRewriteRegex: (/|$)(.*) <-- COMMENTED +> +> ## nginx ingress controller < v0.22.0 <-- **UNCOMMENT THE FOLLOWING THREE LINES BELOW:** +> annotations: +> nginx.ingress.kubernetes.io/rewrite-target: '/' +> ingressPathRewriteRegex: "/" +> ``` +> +> **This is NOT necessary if you are installing Mojaloop v13.x or newer.** + +List of alternative Ingress Controllers: . + +#### 3.2. Kubernetes Admin Interfaces + +1. Kubernetes Dashboards + + The official Kubernetes Web UI Admin interface. + + Visit the following link for installation instructions (not needed if **MicroK8s** is installed): [Web UI (Dashboard) Installation Instructions](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/). + + **IMPORTANT:** Ensure (not needed if **MicroK8s** is installed) you configure RBAC roles and create an associated service account, refer to the following example on how to create a sample user for testing purposes only: [Creating sample user](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md). + + If you have installed MicroK8s, **enable the MicroK8s** dashboard: + + ```bash + microk8s.enable dashboard + ``` + + Refer to the following link for more information: [Add-on: dashboard](https://microk8s.io/docs/addon-dashboard). + + **Remember** to prefix all **kubectl** commands with **microk8s** if you opted not to create an alias. + +2. k8sLens + + A local desktop GUI based kubectl alternative which is easy to install and setup. + + Visit the following link for more information: . + +### 4. Helm + +Please review [Mojaloop Helm Chart](../repositories/helm.md) to understand the relationships between the deployed Mojaloop helm charts. + +Refer to the official documentation on how to install the latest version of Helm: . + +Refer to the following document if are using Helm v2: [Deployment with (Deprecated) Helm v2](./helm-legacy-deployment.md). + +Refer to the [Helm v2 to v3 Migration Guide](./helm-legacy-migration.md) if you wish to migrate an existing Helm v2 deployment to v3. + +#### 4.1. Helm configuration + +1. Add mojaloop repo to your Helm config: + + ```bash + helm repo add mojaloop https://mojaloop.io/helm/repo/ + ``` + + If the repo already exists, substitute 'add' with 'apply' in the above command. + +2. Update helm repositories: + + ```bash + helm repo update + ``` + +### 5. Mojaloop + +#### 5.1. Mojaloop Helm Deployment + +1. Install Mojaloop: + + 1.1. Installing latest version: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace + ``` + + Or if you require a customized configuration: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace -f {custom-values.yaml} + ``` + + _Note: Download and customize the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml). Also ensure that you are using the value.yaml from the correct version which can be found via [Helm Releases](https://github.com/mojaloop/helm/releases). You can confirm the installed version by using the following command: `helm --namespace demo list`. Under the **CHART** column, you should see something similar to 'mojaloop-**{version}**' with **{version}** being the deployed version._ + + ```bash + $ helm -n demo list + NAME NAMESPACE REVISION UPDATED STATUS CHART + moja demo 1 2021-06-11 15:06:04.533094 +0200 SAST deployed mojaloop-{version} + ``` + + _Note: The `--create-namespace` flag is only necessary if the `demo` namespace does not exist. You can alternatively create it using the following command: `kubectl create namespace demo`._ + + 1.2. Version specific installation: + + ```bash + helm --namespace demo install moja mojaloop/mojaloop --create-namespace --version {version} + ``` + + 1.3. List of Mojaloop releases: + + ```bash + $ helm search repo mojaloop/mojaloop -l + NAME CHART VERSION APP VERSION DESCRIPTION + mojaloop/mojaloop {version} {list of app-versions} Mojaloop Helm chart for Kubernetes + ... ... ... ... + ``` + +#### 5.2. Verifying Ingress Rules + +1. Update your /etc/hosts for local deployment: + + _Note: This is only applicable for local deployments, and is not needed if custom DNS or ingress rules are configured in a customized [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml)_. + + ```bash + vi /etc/hosts + ``` + + _Windows the file can be updated in notepad - need to open with Administrative privileges. File location `C:\Windows\System32\drivers\etc\hosts`_. + + Include the following lines (_or alternatively combine them_) to the host config. + + The below required config is applicable to Helm release >= versions 6.2.2 for Mojaloop API Services; + + ``` + # Mojaloop Demo + 127.0.0.1 ml-api-adapter.local central-ledger.local account-lookup-service.local account-lookup-service-admin.local quoting-service.local central-settlement-service.local transaction-request-service.local central-settlement.local bulk-api-adapter.local moja-simulator.local sim-payerfsp.local sim-payeefsp.local sim-testfsp1.local sim-testfsp2.local sim-testfsp3.local sim-testfsp4.local mojaloop-simulators.local finance-portal.local operator-settlement.local settlement-management.local testing-toolkit.local testing-toolkit-specapi.local + ``` + +2. Test system health in your browser after installation. This will only work if you have an active helm chart deployment running. + + _Note: The examples below are only applicable to a local deployment. The entries should match the DNS values or ingress rules as configured in the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) or otherwise matching any custom ingress rules configured_. + + **ml-api-adapter** health test: + + **central-ledger** health test: + +#### 5.3. Testing Mojaloop + +The [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) is used for testing deployments, and has been integrated into Helm utilizing its CLI to easily test any Mojaloop deployment. + +1. Validating Mojaloop using Helm + + ```bash + helm -n demo test moja + ``` + + Or with logs printed to console + + ```bash + helm -n demo test moja --logs + ``` + + This will automatically execute the following [test cases](https://github.com/mojaloop/testing-toolkit-test-cases) using the [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) (**TTK**) CLI: + + - [TTK Hub setup and Simulator Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning). + + Use the following command to view the provisioning Collection logs: + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-setup + ``` + + - [TTK Golden Path Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path). + + Use the following command to view the Golden Path Collection logs: + + ```bash + kubectl -n demo logs pod/moja-ml-ttk-test-validation + ``` + + Example of the finally summary being displayed from the Golden Path test collection log output: + + ``` + Test Suite:GP Tests + Environment:Development + ┌───────────────────────────────────────────────────┐ + │ SUMMARY │ + ├───────────────────┬───────────────────────────────┤ + │ Total assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed assertions │ 1557 │ + ├───────────────────┼───────────────────────────────┤ + │ Failed assertions │ 0 │ + ├───────────────────┼───────────────────────────────┤ + │ Total requests │ 297 │ + ├───────────────────┼───────────────────────────────┤ + │ Total test cases │ 61 │ + ├───────────────────┼───────────────────────────────┤ + │ Passed percentage │ 100.00% │ + ├───────────────────┼───────────────────────────────┤ + │ Started time │ Fri, 11 Jun 2021 15:45:53 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Completed time │ Fri, 11 Jun 2021 15:47:25 GMT │ + ├───────────────────┼───────────────────────────────┤ + │ Runtime duration │ 91934 ms │ + └───────────────────┴───────────────────────────────┘ + TTK-Assertion-Report-multi-2021-06-11T15:47:25.656Z.html was generated + ``` + +2. Accessing the Mojaloop Testing Toolkit UI + + Open the following link in a browser: . + + One is able to manually load and execute the Testing Toolkit Collections using the UI which allows one to visually inspect the requests, responses and assertions in more detail. This is a great way to learn more about Mojaloop. + + Refer to the [Mojaloop Testing Toolkit Documentation](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md) for more information and guides. + +#### 5.4. Testing Mojaloop with Postman + +[Postman](https://www.postman.com/downloads) can be used as an alternative to the [Mojaloop Testing Toolkit](../../documentation/mojaloop-technical-overview/ml-testing-toolkit/README.md). Refer to the [Automated Testing Guide](../contributors-guide/tools-and-technologies/automated-testing.md) for more information. + +The available [Mojaloop Postman Collections](https://github.com/mojaloop/postman) are similar to the [Mojaloop Testing Toolkit's Test Cases](https://github.com/mojaloop/testing-toolkit-test-cases)'s as follows: + +| Postman Collection | Mojaloop Testing Toolkit | Description | +|---------|----------|---------| +| [MojaloopHub_Setup Postman Collection](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) and [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) | [TTK Hub setup and Simulator Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/provisioning) | Hub Setup and Simulator Provisioning | +| [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) | [TTK Golden Path Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases/tree/master/collections/hub/golden_path) | Golden Path Tests | + +Pre-requisites: + +- The following postman environment file should be imported or customized as required when running the above listed Postman collections: [Mojaloop-Local-MojaSims.postman_environment.json](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local-MojaSims.postman_environment.json). +- Ensure you download the **latest patch release version** from the [Mojaloop Postman Git Repository Releases](https://github.com/mojaloop/postman/releases). For example if you install Mojaloop v12.0.**X**, ensure that you have the latest Postman collection patch version v12.0.**Y**. + + +### 6. Overlay Services/3PPI + +As of [R.C. v13.1.0](https://github.com/mojaloop/helm/tree/release/v13.1.0) of Mojaloop, Third Party API is supported and will be published with the official release of Mojaloop v13.1.0. +which allows Third Party Payment Initiators (3PPIs) the ability to request an account link from a DFSP and initiate +payments on behalf of users. + +> Learn more about 3PPI: +> - Mojaloop's [Third Party API](https://github.com/mojaloop/mojaloop-specification/tree/master/thirdparty-api) +> - 3rd Party Use Cases: +> - [3rd Party Account Linking](https://sandbox.mojaloop.io/usecases/3ppi-account-linking.html) +> - [3rd Party Initiated Payments](https://sandbox.mojaloop.io/usecases/3ppi-transfer.html) + + +#### 6.1 Configuring a deployment for Third Party API support + +Third Party API support is **off** by default on the Mojaloop deployment. You can enable it by editing your `values.yaml` +file with the following settings: + +```yaml +... +account-lookup-service: + account-lookup-service: + config: + featureEnableExtendedPartyIdType: true # allows the ALS to support newer THIRD_PARTY_LINK PartyIdType + + account-lookup-service-admin: + config: + featureEnableExtendedPartyIdType: true # allows the ALS to support newer THIRD_PARTY_LINK PartyIdType + +... + +thirdparty: + enabled: true +... +``` + +In addition, the Third Party API has a number of dependencies that must be deployed manually for the thirdparty services +to run. [mojaloop/helm/thirdparty](https://github.com/mojaloop/helm/tree/master/thirdparty) contains details of these +dependencies, and also provides example k8s config files that install these dependencies for you. + + + + +```bash +# install redis and mysql for the auth-service +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-auth-svc/example_dependencies.yaml +# install mysql for the consent oracle +kubectl apply --namespace demo -f https://raw.githubusercontent.com/mojaloop/helm/master/thirdparty/chart-consent-oracle/example_dependencies.yaml + +# apply the above changes to your values.yaml file, and update your mojaloop installation to deploy thirdparty services: +helm upgrade --install --namespace demo moja mojaloop/mojaloop -f values.yaml +``` + +Once the helm upgrade has completed, you can verify that the third party services are up and running: + + +```bash +kubectl get po | grep tp-api +# tp-api-svc-b9bf78564-4g59d 1/1 Running 0 7m17s + +kubectl get po | grep auth-svc +# auth-svc-b75c954d4-9vq7w 1/1 Running 0 8m5s + +kubectl get po | grep consent-oracle +# consent-oracle-849cb69769-vq4rk 1/1 Running 0 8m31s + + +# and also make sure the ingress is exposed correctly +curl -H "Host: tp-api-svc.local" /health +# {"status":"OK","uptime":3545.77290063,"startTime":"2021-11-04T05:41:32.861Z","versionNumber":"11.21.0","services":[]} + +curl -H "Host: auth-service.local" /health + +# {"status":"OK","uptime":3682.48869561,"startTime":"2021-11-04T05:43:19.056Z","versionNumber":"11.10.1","services":[]} + +curl -H "Host: consent-oracle.local" /health +# {"status":"OK","uptime":3721.520096665,"startTime":"2021-11-04T05:43:48.382Z","versionNumber":"0.0.8","services":[]} +``` + +> You can also add the following entries to your `/etc/hosts` file to make it easy to talk to the thirdparty services +> ``` +> tp-api-svc.local auth-service.local consent-oracle.local +> ``` + +#### 6.2 Validating and Testing the Third Party API + +Once you have deployed the Third Party services, you need to deploy some simulators that are capable of simulating +the Third Party scenarios. + + +##### 6.2.1 Deploying the Simulators + +Once again, you can do this by modifying your `values.yaml` file, this time under the `mojaloop-simulator` entry: + +```yaml +... + +mojaloop-simulator: + simulators: + ... + pisp: + config: + thirdpartysdk: + enabled: true + dfspa: + config: + thirdpartysdk: + enabled: true + dfspb: {} +... +``` + +The above entry will create 3 new sets of mojaloop simulators: + +1. `pisp` - a PISP +2. `dfspa` - a DFSP that supports the Third Party API +3. `dfspb` - a normal DFSP simulator that doesn't support the Third Party API, but can receive payments + + +##### 6.2.2 Provisioning the Environment + +Once the above simulators have been deployed and are up and running, it's time to configure the Mojaloop Hub +and simulators so we can test the Third Party API. + +Use the [Third Party Provisioning Collection](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-provisioning-collection) +from the mojaloop/testing-toolkit-test cases to provision the Third Party environment and the simulators +you set up in the last step. + +##### 6.2.3 Run the Third Party API Test Collection + +Once the provisioning steps are completed, you can run the [Third Party Test Collection](https://github.com/mojaloop/testing-toolkit-test-cases#third-party-test-collection) +to test that the Third Party services are deployed and configured correctly. diff --git a/deployment-guide/assets/diagrams/deployment/DockerAdvanceSettings.png b/legacy/deployment-guide/assets/diagrams/deployment/DockerAdvanceSettings.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/DockerAdvanceSettings.png rename to legacy/deployment-guide/assets/diagrams/deployment/DockerAdvanceSettings.png diff --git a/deployment-guide/assets/diagrams/deployment/DockerForDesktop.png b/legacy/deployment-guide/assets/diagrams/deployment/DockerForDesktop.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/DockerForDesktop.png rename to legacy/deployment-guide/assets/diagrams/deployment/DockerForDesktop.png diff --git a/deployment-guide/assets/diagrams/deployment/DockerIsRunning.png b/legacy/deployment-guide/assets/diagrams/deployment/DockerIsRunning.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/DockerIsRunning.png rename to legacy/deployment-guide/assets/diagrams/deployment/DockerIsRunning.png diff --git a/deployment-guide/assets/diagrams/deployment/EnableKubernetes.png b/legacy/deployment-guide/assets/diagrams/deployment/EnableKubernetes.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/EnableKubernetes.png rename to legacy/deployment-guide/assets/diagrams/deployment/EnableKubernetes.png diff --git a/legacy/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg b/legacy/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg new file mode 100644 index 000000000..26b8dcd92 --- /dev/null +++ b/legacy/deployment-guide/assets/diagrams/deployment/KubeInfrastructureArch.svg @@ -0,0 +1,2 @@ + + diff --git a/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-1.png b/legacy/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-1.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-1.png rename to legacy/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-1.png diff --git a/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-2.png b/legacy/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-2.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-2.png rename to legacy/deployment-guide/assets/diagrams/deployment/KubernetesInstallWithDocker-2.png diff --git a/deployment-guide/assets/diagrams/deployment/kubernetesDashboard.png b/legacy/deployment-guide/assets/diagrams/deployment/kubernetesDashboard.png similarity index 100% rename from deployment-guide/assets/diagrams/deployment/kubernetesDashboard.png rename to legacy/deployment-guide/assets/diagrams/deployment/kubernetesDashboard.png diff --git a/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg b/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg new file mode 100644 index 000000000..a5e597d9c --- /dev/null +++ b/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Target Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Target Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Sync & Data Migration

    (Transform data to new Schema)
    Sync & Data M...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment
    +
    Backed Dependencies
    (MySQL, Kafka, etc)

    (Old Release)
    Mojaloop Current...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg b/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg new file mode 100644 index 000000000..894431623 --- /dev/null +++ b/legacy/deployment-guide/assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg @@ -0,0 +1,3 @@ + + +
    Shared Data-layer Runtime Environment
    Kubernetes Cluster(s)
    Shared Data-layer Runtime Environment...
    Mojaloop Runtime Environment
    Kubernetes Cluster(s)
    Mojaloop Runtime Environment...
    Backend Dependencies

    (MySQL, Kafka, etc)
    Backend Dependencies...
    Mojaloop Current
    Deployment

    (Old Release)
    Mojaloop Current...
    Mojaloop Target
    Deployment

    (New Release)
    Mojaloop Target...
    Mojaloop DMZ
    Mojaloop DMZ
    API
    Gateway
    API...
    DFSP(s)
    DFSP(...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/deployment-guide/deployment-troubleshooting.md b/legacy/deployment-guide/deployment-troubleshooting.md new file mode 100644 index 000000000..cc26c8f3d --- /dev/null +++ b/legacy/deployment-guide/deployment-troubleshooting.md @@ -0,0 +1,126 @@ +# Deployment Troubleshooting + +## 1. Known issues + +### 1.1. Mojaloop Helm release v10.x or less does not support Kubernetes v1.16 or greater + +#### Description + +_Note: This is only applicable to Mojaloop Helm v10.x or less release._ + +When installing mojaloop helm charts, the following error occurs: + +```log +Error: validation failed: [unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta2", unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta2", unable to recognize "": no matches for kind "StatefulSet" in version "apps/v1beta1"] +``` + +#### Reason + +In version 1.16 of Kubernetes breaking change has been introduced (more about it [in "Deprecations and Removals" of Kubernetes release notes](https://kubernetes.io/docs/setup/release/notes/#deprecations-and-removals). The Kubernetes API versions `apps/v1beta1` and `apps/v1beta2`are no longer supported and and have been replaced by `apps/v1`. + +Mojaloop helm charts v10 or less refer to deprecated ids, therefore it's not possible to install v10- on Kubernetes version above 1.15 without manually modification. + +Refer to the following issue for more info: [mojaloop/helm#219](https://github.com/mojaloop/helm/issues/219) + +#### Fixes + +Ensure that you are deploying Mojaloop Helm charts v10.x or less on v1.15 of Kubernetes. + +#### Additional details for `microk8s` fix + +Refer to the following section for more information on how to install the desired Kubernetes version: [Mojaloop Setup for Linux (Ubuntu) - 2.1. MicroK8S](./local-setup-linux.md#21-microk8s). + +## 2. Deployment issues + +### 2.1. `ERR_NAME_NOT_RESOLVED` Error + +#### Description + +The following error is displayed when attempting to access an end-point (e.g. central-ledger.local) via the Kubernetes Service directly in a browser: `ERR_NAME_NOT_RESOLVED` + +#### Fixes + +1. Verify that that Mojaloop was deployed by checking that the helm chart(s) was installed by executing: + + ```bash + helm list + ``` + + If the helm charts are not listed, see the [Deployment Guide - 5.1. Mojaloop Helm Deployment](./README.md#51-mojaloop-helm-deployment) section to install a chart. + +2. Ensure that all the Mojaloop Pods/Containers have started up correctly and are available through the Kubernetes dashboard. + +3. Note that the Mojaloop deployment via Helm can take a few minutes to initially startup depending on the system's available resources and specification. It is recommended that you wait at least 10m for all Pods/Containers to self heal before troubleshooting. + +### 2.3. MicroK8s - Connectivity Issues + +#### Description + +My pods can’t reach the internet or each other (but my MicroK8s host machine can). + +An example of this is that the Central-Ledger logs indicate that there is an error with the Broker transport as per the following example: + +```log +2019-11-05T12:28:10.470Z - info: Server running at: +2019-11-05T12:28:10.474Z - info: Handler Setup - Registering {"type":"prepare","enabled":true}! +2019-11-05T12:28:10.476Z - info: CreateHandler::connect - creating Consumer for topics: [topic-transfer-prepare] +2019-11-05T12:28:10.515Z - info: CreateHandler::connect - successfully connected to topics: [topic-transfer-prepare] +2019-11-05T12:30:20.960Z - error: Consumer::onError()[topics='topic-transfer-prepare'] - Error: Local: Broker transport failure) +``` + +#### Fixes + +Make sure packets to/from the pod network interface can be forwarded to/from the default interface on the host via the iptables tool. Such changes can be made persistent by installing the iptables-persistent package: + +```bash +sudo iptables -P FORWARD ACCEPT +sudo apt-get install iptables-persistent +``` + +or, if using ufw: + +```bash +sudo ufw default allow routed +``` + +The MicroK8s inspect command can be used to check the firewall configuration: + +```bash +microk8s.inspect +``` + +## 3. Ingress issues + +### 3.1. Ingress rules are not resolving for Nginx Ingress v0.22 or later when installing Mojaloop Helm v12.x or less + +#### Description + +_Note: This is only applicable to Mojaloop Helm v12.x or less release._ + +Ingress rules are unable to resolve to the correct path based on the annotations specified in the [values.yaml](https://github.com/mojaloop/helm/blob/v12.0.0/mojaloop/values.yaml) configuration files when using Nginx Ingress controllers v0.22 or later. + +This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### Fixes + +Make the following change to Ingress annotations (from --> to) in the values.yaml files: + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/$1' +``` + +### 3.2. Ingress rules are not resolving for Nginx Ingress earlier than v0.22 + +#### Description + +Ingress rules are unable to resolve to the correct path based on the annotations specified in the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) configuration files when using Nginx Ingress controllers that are older than v0.22. + +This is due to the changes introduced in Nginx Ingress controllers that are v0.22 or later as per the following link: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target. + +#### Fixes + +Make the following change to all Ingress annotations (from --> to) in each of the values.yaml files: + +```yaml +nginx.ingress.kubernetes.io/rewrite-target: '/$1'` --> `nginx.ingress.kubernetes.io/rewrite-target: '/' +``` diff --git a/legacy/deployment-guide/helm-legacy-deployment.md b/legacy/deployment-guide/helm-legacy-deployment.md new file mode 100644 index 000000000..c3978fb9a --- /dev/null +++ b/legacy/deployment-guide/helm-legacy-deployment.md @@ -0,0 +1,65 @@ +# Mojaloop Deployment with (Deprecated) Helm v2 + +_Note: It is recommended that you upgrate from Helm v2 to v3 as v2 is at end-of-life. Refer to legacy instruction for [Helm v2](./helm-legacy-deployment.md). Please refer to the [Helm v2 to v3 Migration Guide](./helm-legacy-migration.md)._ + +This document exists for legacy purposes and describes how to install Mojaloop using Helm v2. Refer to the [Design Authority issue #52](https://github.com/mojaloop/design-authority/issues/52) for more information. + +## Deployment and Setup + +#### 4.1. Helm v2 configuration + +1. Config Helm CLI and install Helm Tiller on K8s cluster: + ```bash + helm init + ``` + _Note: if `helm init` fails with `connection refused error`, refer to [troubleshooting](./deployment-troubleshooting.md#helm_init_connection_refused)_ + +2. Validate Helm Tiller is up and running. _Windows replace `grep` with `findstr`_: + ```bash + kubectl -n kube-system get po | grep tiller + ``` + +3. Add mojaloop repo to your Helm config (optional): + ```bash + helm repo add mojaloop http://mojaloop.io/helm/repo/ + ``` + If the repo already exists, substitute 'add' with 'apply' in the above command. + +4. Add the additional dependency Helm repositories. This is needed to resolve Helm Chart dependencies required by Mojaloop charts. Linux use with sudo; + ```bash + helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator + helm repo add kiwigrid https://kiwigrid.github.io + helm repo add elastic https://helm.elastic.co + ``` + +5. Update helm repositories: + ```bash + helm repo update + ``` + +### 5. Mojaloop + +#### 5.1. Mojaloop Helm v2 Deployment + +1. Install Mojaloop: + + Default installation: + ```bash + helm --namespace demo --name moja install mojaloop/mojaloop + ``` + + Version specific installation: + ```bash + helm --namespace demo --name moja install mojaloop/mojaloop --version {version} + ``` + + List of available versions: + ```bash + helm search -l mojaloop/mojaloop + ``` + + Custom configured installation: + ```bash + helm --namespace demo --name moja install mojaloop/mojaloop -f {custom-values.yaml} + ``` + _Note: Download and customize the [values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml). Also ensure that you are using the value.yaml from the correct version which can be found via [Helm Releases](https://github.com/mojaloop/helm/releases)._ diff --git a/legacy/deployment-guide/helm-legacy-migration.md b/legacy/deployment-guide/helm-legacy-migration.md new file mode 100644 index 000000000..586b26539 --- /dev/null +++ b/legacy/deployment-guide/helm-legacy-migration.md @@ -0,0 +1,147 @@ +# Migration from Helm v2 to v3 + +_Note: It is recommended that you upgrate from Helm v2 to v3 as v2 is at end-of-life. Refer to [Deployment with (Deprecated) Helm v2](./helm-legacy-deployment.md) if you still require information on using Helm v2._ + +This document provides instructions on how to migrate existing Mojaloop installations from Helm v2 to v3, and is based of the official Helm ([Migrating Helm v2 to v3](https://helm.sh/docs/topics/v2_v3_migration/)) document. + +## Deployment and Setup + +#### 1. Helm configuration + +1. Install Helm v3 + + Follow the [Installation Helm](https://helm.sh/docs/intro/install/) documentation to download and install Helm v3, but ensure to rename to binary as `helm3` before storing it in your path (i.e. on linux moving it to the `usr/local/bin` folder). This will ensure that the existing Helm v2 binary is still accessible. + +2. Validate that Helm3 has been installed correctly + Run the following command to ensure that it is functioning: + ```bash + $ helm3 repo list + Error: no repositories to show + ``` + You should receive the following response `Error: no repositories to show` which is expected, and indicates that the Helm3 binary is working. + +3. Install the `helm-2to3` plugin + ```bash + helm3 plugin install https://github.com/helm/helm-2to3 + ``` + + Run the following command to confirm the plugin installation: + ```bash + $ helm3 plugin list + NAME VERSION DESCRIPTION + 2to3 0.2.0 migrate and cleanup Helm v2 configuration and releases in-place to Helm v3 + ``` + +4. Backup your exisitng Helm v2 data + + Make a copy of your existing `~/.helm` directory as the next (`move`) command will cause your Helm v2 configuration to be no longer available. + +5. Run the following commands to migrate your existing local configuration + + Try run a `dry-run` to ensure that everything looks fine: + ```bash + helm3 2to3 move config --dry-run + ``` + + Assuming that there are no errors, you can proceed with the following command: + ```bash + helm3 2to3 move config + ``` + + Run the following to ensure that the configuration was properly migrated, and your prviously Helm v2 configured repo config is shown: + ```bash + $ helm3 repo list + NAME URL + stable https://kubernetes-charts.storage.googleapis.com + local http://127.0.0.1:8879/charts + incubator http://storage.googleapis.com/kubernetes-charts-incubator + kiwigrid https://kiwigrid.github.io + elastic https://helm.elastic.co + kiwigrid https://kiwigrid.github.io + bitnami https://charts.bitnami.com/bitnami + mojaloop http://mojaloop.io/helm/repo/ + ``` + +#### 2. Migrating Helm Installations + + + ```bash + $ helm list + + NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE + moja 1 Thu Nov 14 15:01:00 2019 DEPLOYED mojaloop-10.4.0 v10.4.0 demo + ``` + + Dry-run the migration command to validate that everything looks fine: + ```bash + $ helm3 2to3 convert --dry-run moja + 2019/11/14 15:03:17 NOTE: This is in dry-run mode, the following actions will not be executed. + 2019/11/14 15:03:17 Run without --dry-run to take the actions described below: + 2019/11/14 15:03:17 + 2019/11/14 15:03:17 Release "moja" will be converted from Helm v2 to Helm v3. + 2019/11/14 15:03:17 [Helm 3] Release "moja" will be created. + 2019/11/14 15:03:17 [Helm 3] ReleaseVersion "moja.v1" will be created. + ``` + + Run the migration command: + ```bash + $ helm3 2to3 convert moja + 2019/11/14 15:03:57 Release "moja" will be converted from Helm v2 to Helm v3. + 2019/11/14 15:03:57 [Helm 3] Release "moja" will be created. + 2019/11/14 15:03:57 [Helm 3] ReleaseVersion "moja.v1" will be created. + 2019/11/14 15:03:57 [Helm 3] ReleaseVersion "moja.v1" created. + 2019/11/14 15:03:57 [Helm 3] Release "moja" created. + 2019/11/14 15:03:57 Release "moja" was converted successfully from Helm v2 to Helm v3. + 2019/11/14 15:03:57 Note: The v2 release information still remains and should be removed to avoid conflicts with the migrated v3 release. + 2019/11/14 15:03:57 v2 release information should only be removed using `helm 2to3` cleanup and when all releases have been migrated over. + ``` + + Optionaly add `--delete-v2-releases` to the above command if you do not wish to retain the release information for the existing Helm v2 installation. This can be cleaned up later using the `helm3 2to3 cleanup`. + + Validate that the migration was successful: + ```bash + $ helm list + NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE + moja 1 Thu Nov 14 15:01:00 2019 DEPLOYED mojaloop-10.4.0 v10.4.0 demo + + $ helm3 list -n demo + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + moja demo 1 2019-11-14 13:01:00.188487 +0000 UTC deployed mojaloop-10.4.0 10.4.0 + ``` + +#### 3. Cleanup + + This section will show you how to remove Tiller and any existing configuration or metadata from existing Helm v2 deployments. + + _NOTE: This may impact any Helm v2 deployments that have not been migrated. It is recommended that you only run these commands if you have migrated all existing Helm v2 to v3 deployments!_ + + ```bash + $ helm3 2to3 cleanup --dry-run + 2019/11/14 15:06:59 NOTE: This is in dry-run mode, the following actions will not be executed. + 2019/11/14 15:06:59 Run without --dry-run to take the actions described below: + 2019/11/14 15:06:59 + WARNING: "Helm v2 Configuration" "Release Data" "Release Data" will be removed. + This will clean up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases. + Helm v2 may not be usable afterwards. + + [Cleanup/confirm] Are you sure you want to cleanup Helm v2 data? [y/N]: y + 2019/11/14 15:07:01 + Helm v2 data will be cleaned up. + 2019/11/14 15:07:01 [Helm 2] Releases will be deleted. + 2019/11/14 15:07:01 [Helm 2] ReleaseVersion "moja.v1" will be deleted. + 2019/11/14 15:07:01 [Helm 2] Home folder "/Users/user/.helm" will be deleted. + ``` + + This will show a list of all what will be removed & deleted during the cleanup process: + - Tiller service to be removed from kube-system namespace + - Remote Helm v2 deployments + - Local Helm v2 home configuration folder will be deleted + + If you are happy to proceed run the following command: + ```bash + helm3 2to3 cleanup + ``` + + If you no longer require Helm v2: + - Uninstall Helm v2 from your local system + - Rename the `helm3` binary to `helm` diff --git a/legacy/deployment-guide/local-setup-linux.md b/legacy/deployment-guide/local-setup-linux.md new file mode 100644 index 000000000..92bc0ef67 --- /dev/null +++ b/legacy/deployment-guide/local-setup-linux.md @@ -0,0 +1,143 @@ +# Mojaloop Setup for Linux (Ubuntu) + +Local setup on a Laptop or Desktop to run the Mojaloop project. + +## Setup Introduction + +This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. + +At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. + +- [Mojaloop Setup for Linux (Ubuntu)](#mojaloop-setup-for-linux-ubuntu) + - [Setup Introduction](#setup-introduction) + - [1. Environment recommendations](#1-environment-recommendations) + - [2. Kubernetes](#2-kubernetes) + - [2.1. MicroK8S](#21-microk8s) + - [2.2. Docker](#22-docker) + - [3. Continue with Deployment](#3-continue-with-deployment) + +## 1. Environment recommendations + +This environment setup was validated on: + +- 64-bit version of Ubuntu Bionic 18.04(LTS). +- This guide is based on Ubuntu 18.04.2 (bionic) on a x86_64 desktop with 8 CPU's and 16GB RAM. + +## 2. Kubernetes + +Kubernetes installation for a local environment. + +### 2.1. MicroK8S + +We recommend install directly from the snap store, refer to [microk8s.io/docs](https://microk8s.io/docs) for more information. + +Don't have the snap command? [Installing snapd](https://snapcraft.io/docs/installing-snapd). + +1. Installing MicroK8s from snap. + + ```bash + sudo snap install microk8s --classic --channel=1.20/stable + ``` + + _Note: Please check the [release notes of your target Mojaloop Helm deployment](https://github.com/mojaloop/helm/releases) to see if there are any recommended Kubernetes version prior to installing MicroK8s. The channel parameter specifies the version of Kubernetes to be installed. More information can be found at [microk8s.io/docs/setting-snap-channel](https://microk8s.io/docs/setting-snap-channel)._ + +2. Configure user permission + + ```bash + sudo usermod -a -G microk8s $USER + sudo chown -f -R $USER ~/.kube + ``` + + You will also need to re-enter the session for the group update to take place: + + ```bash + su - $USER + ``` + +3. Verify MicroK8s is installed and available. + + ```bash + microk8s.status + ``` + +4. During installation you can use the --wait-ready flag to wait for the kubernetes services to initialize. + + ```bash + microk8s.status --wait -ready + ``` + +5. To avoid colliding with a **kubectl** already installed and to avoid overwriting any existing Kubernetes configuration file, MicroK8s adds a **microk8s.kubectl** command, configured to exclusively access the new **MicroK8s** install. + + ```bash + microk8s.kubectl get services + ``` + +6. This step is only necessary if you require **microk8s.kubectl** to function as a standard **kubectl** command. This **DOES NOT** mean that you can then use **kubectl** to access **OTHER** k8s clusters. + + An example of why you would use this: You have a bash script or 3rd party tool that expects **kubectl** to be available. E.g. If you want to use Helm, it will not work against **microk8s.kubectl**, thus one **MUST** setup the alias for Helm to function correctly. + + ```bash + snap alias microk8s.kubectl kubectl + ``` + + Reverting it at any time; + + ```bash + snap unalias kubectl + ``` + + We will stick with the standard command of prefixing with **microk8s.** for this guide. + +7. If you already have **kubectl** installed and would like to use it to access the **MicroK8s** deployment. + + ```bash + microk8s.kubectl config view --raw > $HOME/.kube/config + ``` + +8. View the current context. + + ```bash + microk8s.kubectl config get-contexts + ``` + +9. Make sure the current context is **microk8s**. If not, set it as the current context. + + ```bash + microk8s.kubectl config use-context microk8s + ``` + +10. Install an Ingress Controller + + Install an Nginx Ingress Controller for MicroK8s by running the command: + + ```bash + microk8s enable ingress + ``` + + Alternatively refer to [Deployment Guide - 3.2. Kubernetes Ingress Controller](./README.md#32-kubernetes-ingress-controller) for manual installation. + +### 2.2. Docker + +Docker is deployed as part of the MicroK8s installation. The docker daemon used by MicroK8s is listening on unix:///var/snap/microk8s/current/docker.sock. You can access it with the **microk8s.docker** command. + +1. If you require **microk8s.docker** to function as a standard **docker** command, you set an alias + + ```bash + sudo snap alias microk8s.docker docker + ``` + + Undo the alias: + + ```bash + sudo snap unalias docker + ``` + +2. Otherwise you can apply the native microK8s commands by prefixing the docker command with `microk8s.` + + ```bash + microk8s.docker ps + ``` + +## 3. Continue with Deployment + +1. Continue setup and configuration from the [Mojaloop's deployment guide - 3.2. Kubernetes Admin Interfaces](./README.md#32-kubernetes-admin-interfaces) document. diff --git a/legacy/deployment-guide/local-setup-mac.md b/legacy/deployment-guide/local-setup-mac.md new file mode 100644 index 000000000..718f69e2c --- /dev/null +++ b/legacy/deployment-guide/local-setup-mac.md @@ -0,0 +1,84 @@ +# Mojaloop local environment setup for Mac + +Local setup on a Laptop or Desktop to run the Mojaloop project. + +## Setup Introduction + +This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. + +At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. + +- [Mojaloop local environment setup for Mac](#mojaloop-local-environment-setup-for-mac) + - [Setup Introduction](#setup-introduction) + - [1. Kubernetes](#1-kubernetes) + - [1.1. Kubernetes Installation with Docker](#11-kubernetes-installation-with-docker) + - [2. Continue with Deployment](#2-continue-with-deployment) + +## 1. Kubernetes + +This section will guide the reader through the deployment process to setup Kubernetes within Docker. + +> RECOMMENDATIONS - Aug 2022 +> +> We recommend installing Kubernetes using either [minikube](https://minikube.sigs.k8s.io/docs/start) or [microk8s](https://microk8s.io/docs/install-alternatives) instead, as this will allow you to easily specify your desired Kubernetes version (i.e. either v1.20 or v1.21). +> +> Alternatively, a specific version of Docker-desktop that includes a supported target Kubernetes version as specified in the [Deployment Guide (1. Pre-requisites)](README.md#1-pre-requisites) can be installed. See [Installing Docker for Windows](#11-kubernetes-installation-with-docker) section for more information. +> + +### 1.1. Kubernetes Installation with Docker + +1. Kubectl + + Complete set of **kubectl** installation instruction are available [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + + ```bash + brew install kubernetes-cli + ``` + + To verify if the installation was successful, check the version; + + ```bash + kubectl version + ``` + +2. To install Kubernetes with Docker, follow the steps below; + + > RECOMMENDATIONS - Aug 2022 + > + > For Windows/MacOS, version [Docker Desktop v4.2.0](https://docs.docker.com/desktop/release-notes/#docker-desktop-420) comes packaged with Kubernetes v1.21.5 which meets the current requirements. + > + + * Click on the Docker icon on the status barr + * Select **Preferences** + * Go to **Advanced** + * Increase the CPU allocation to at least 4 + * Increase the Memory allocation to at least 8.0 GiB + + ![Kubernetes Install with Docker 1](./assets/diagrams/deployment/KubernetesInstallWithDocker-1.png) + + * Go to **Kubernetes** + * Select **Enable Kubernetes** tick box + * Make sure **Kubernetes** is selected + * Click **Apply** + * Click **Install** on the confirmation tab. + * The option is available to wait for completion or run as a background task. + + ![Kubernetes Install with Docker 2](./assets/diagrams/deployment/KubernetesInstallWithDocker-2.png) + +### 1.2. Kubernetes environment setup + +1. List the current Kubernetes context; + + ```bash + kubectl config get-contexts + ``` + +2. Change your Contexts; + + ```bash + kubectl config use-context docker-desktop + ``` + +## 2. Continue with Deployment + +1. Continue setup and configuration from the [Mojaloop's deployment guide - 3.1. Kubernetes Ingress Controller](./README.md#31-kubernetes-ingress-controller) document. diff --git a/legacy/deployment-guide/local-setup-windows.md b/legacy/deployment-guide/local-setup-windows.md new file mode 100644 index 000000000..94698b26b --- /dev/null +++ b/legacy/deployment-guide/local-setup-windows.md @@ -0,0 +1,129 @@ +# Mojaloop local environment setup for Windows + +Local setup on a Laptop or Desktop to run the Mojaloop project. + +## Setup Introduction + +This document will provide guidelines to a technical capable resources to setup, deploy and configure the Mojaloop applications on a local environment, utilizing Docker, Kubernetes and HELM charts. + +At this point the reader/implementer should be familiar with [Mojaloop's deployment guide](./README.md). Imported information is contained in that document and as such a prerequisite to this document. + +- [Mojaloop local environment setup for Windows](#mojaloop-local-environment-setup-for-windows) + - [Setup Introduction](#setup-introduction) + - [1. Kubernetes](#1-kubernetes) + - [1.1 Kubernetes Installation with Docker](#11-kubernetes-installation-with-docker) + - [1.2 Kubernetes environment setup](#12-kubernetes-environment-setup) + - [2. Continue with Deployment](#2-continue-with-deployment) + +## 1. Kubernetes + +This section will guide the reader through the deployment process to setup Kubernetes within Docker. + +> +> RECOMMENDATIONS - Aug 2022 +> +> We recommend installing Kubernetes using either [minikube](https://minikube.sigs.k8s.io/docs/start) or [microk8s](https://microk8s.io/docs/install-alternatives) instead, as this will allow you to easily specify your desired Kubernetes version (i.e. either v1.20 or v1.21). +> +> Alternatively, a specific version of Docker-desktop that includes a supported target Kubernetes version as specified in the [Deployment Guide (1. Pre-requisites)](README.md#1-pre-requisites) can be installed. See [Installing Docker for Windows](#11-kubernetes-installation-with-docker) section for more information. +> + +### 1.1 Kubernetes Installation with Docker + +- **kubectl** is part of the installation package when installing Docker Desktop for Windows. + + Please note the minimum system and operation requirements; + - Docker Desktop for Windows require Microsoft Hyper-V to run. Hyper-V will be enable as part of the installation process, + - Windows 10 64bit: Pro, Enterprise, Education (1607 Anniversary Update, Build 14393 or later), + - CPU SLAT-capable feature, + - At least 4GB of RAM. (At least 16GB will be required to run the Mojaloop project). + +1. Installing Docker for Windows: + + > + > RECOMMENDATIONS - Aug 2022 + > + > For Windows/MacOS, version [Docker Desktop v4.2.0](https://docs.docker.com/desktop/release-notes/#docker-desktop-420) comes packaged with Kubernetes v1.21.5 which meets the current requirements. + > + + You will require Docker Desktop for Windows 18.02 Edge (win50) and higher, or 18.06 Stable (win 70) and higher. Kubernetes on Docker Desktop for Windows is available on these versions and higher. They are downloadable from: + + ```url + https://docs.docker.com/docker-for-windows/install/ + ``` + + Once download is completed, the downloaded file can normally be found in your Download folder. Installation is as per normal installations for windows. A restart will be required after this step. + +2. Enable visualization: + + Docker Desktop for Windows requires Microsoft Hyper-V to run. The Docker Desktop installer enables Hyper-V for you. + + If Hyper-V is not enabled, A pop-up messages will request if you would like to turn this on. Read the messages and select 'Ok' if appropriate. + + You need to insure that **VT-X/AMD-v** is enabled from `cmd.exe`: + + ```bash + systeminfo + ``` + + If not, from `cmd.exe` run as Administrator and execute: + + ```bash + bcdedit /set hypervisorlaunchtype auto + ``` + + A reboot would be required again for the updates to take effect. + +3. Start Docker Desktop for Windows: + + Docker does not start automatically after installation. To start it, select **Docker Desktop** and click on it (or hit Enter). + + When the _whale_ in the status bar stays steady, **Docker Desktop** is up-and-running, and accessible from any terminal window. Note - if the _whale_ is not on the status bar, it will be in the **hidden icon** notifications area, click the up arrow on the taskbar to show it. + + ![Docker is Running](./assets/diagrams/deployment/DockerIsRunning.png) + +### 1.2 Kubernetes environment setup + +1. Setting up the Kubernetes runtime environment within Docker Desktop: + + - Open the Docker Desktop for Windows menu by right-clicking the Docker icon. + - Select **Settings** to open the settings dialog. + - Under the **General** tab you can configure when to start and update Docker. + + - Go to **Advanced** tab + - Increase the CPU allocation to at least 4 + - Increase the Memory allocation to at least 8.0 GiB + + (If your system resource allow, more can be allocated as indicated below.) + + ![Docker Advance Settings](./assets/diagrams/deployment/DockerAdvanceSettings.png) + + Kubernetes on Docker Desktop for Windows is available in 18.02 Edge (win50) and higher, and in 18.06 Stable (win 70) and higher. + + - go to **Kubernetes** tab + - Select **Enable Kubernetes** + - Select **Show system container (advanced)** + + ![Enable Kubernetes](./assets/diagrams/deployment/EnableKubernetes.png) + +2. Set the context to be used. + + As mentioned, the Kubernetes client command, `kubectl` is included and configured to connect to the local Kubernetes server. If you have `kubectl` already installed, be sure to change context to point to **docker-for-desktop**; + + Through `cmd.exe`: + + ```bash + kubectl config get-contexts + kubectl config use-context docker-for-desktop + ``` + + Or through the Docker Desktop for Windows menu: + + - right-clicking the Docker icon + - Select **Kubernetes** + - Select **docker-for-desktop** + + ![Docker For Desktop](./assets/diagrams/deployment/DockerForDesktop.png) + +## 2. Continue with Deployment + +1. Continue setup and configuration from the [Mojaloop's deployment guide - 3.1. Kubernetes Ingress Controller](./README.md#31-kubernetes-ingress-controller) document. diff --git a/legacy/deployment-guide/releases.md b/legacy/deployment-guide/releases.md new file mode 100644 index 000000000..d47f799bf --- /dev/null +++ b/legacy/deployment-guide/releases.md @@ -0,0 +1,41 @@ +# Mojaloop Releases + +Below you will find more information on the current and historical releases for Mojaloop. + +Refer to [Versioning Documentation](../contributors-guide/standards/versioning.md) for more information on the release strategy and standards. + +## Current Releases +* Helm: [![Git Releases](https://img.shields.io/github/release/mojaloop/helm.svg?style=flat)](https://github.com/mojaloop/helm/releases) +* Central-Ledger: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-ledger.svg?style=flat)](https://github.com/mojaloop/central-ledger/releases) +* Ml-API-Adapter: [![Git Releases](https://img.shields.io/github/release/mojaloop/ml-api-adapter.svg?style=flat)](https://github.com/mojaloop/ml-api-adapter/releases) +* Central-Settlement: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-settlement.svg?style=flat)](https://github.com/mojaloop/central-settlement/releases) +* Central-Event-Processor: [![Git Releases](https://img.shields.io/github/release/mojaloop/central-event-processor.svg?style=flat)](https://github.com/mojaloop/central-event-processor/releases) +* Email-Notifier: [![Git Releases](https://img.shields.io/github/release/mojaloop/email-notifier.svg?style=flat)](https://github.com/mojaloop/email-notifier/releases) +* Account-Lookup-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/account-lookup-service.svg?style=flat)](https://github.com/mojaloop/account-lookup-service/releases) +* Quoting-Service: [![Git Releases](https://img.shields.io/github/release/mojaloop/quoting-service.svg?style=flat)](https://github.com/mojaloop/quoting-service/releases) + + +## Helm Charts Packaged Releases + +Refer to [Mojaloop Helm Repository](../repositories/helm.md) documentation to find out more information about Helm. Below are some of the Helm releases made and timelines. Please note that this is not an exhaustive list. For an exhaustive list, please visit the [Helm releases page](https://github.com/mojaloop/helm/releases). + +| Version | Release Date | Tested | Notes | +| --- | :---: | :---: | --- | +| [9.2.0](https://github.com/mojaloop/helm/releases/tag/v9.2.0) | 2019/03/04 | ✓ | Sprint release | +| [8.8.0](https://github.com/mojaloop/helm/releases/tag/v8.8.0) | 2020/02/12 | ✓ | Sprint release | +| [8.7.0](https://github.com/mojaloop/helm/releases/tag/v8.7.0) | 2019/12/12 | ✓ | Sprint release | +| [8.4.0](https://github.com/mojaloop/helm/releases/tag/v8.4.0) | 2019/11/12 | ✓ | Sprint release | +| [8.1.0](https://github.com/mojaloop/helm/releases/tag/v8.1.0) | 2019/10/08 | ✓ | Sprint release | +| [7.4.3](https://github.com/mojaloop/helm/releases/tag/v7.4.3) | 2019/08/30 | ✓ | Sprint release | +| [7.4.1](https://github.com/mojaloop/helm/releases/tag/v7.4.1) | 2019/08/23 | ✓ | Sprint release | +| [6.3.1](https://github.com/mojaloop/helm/releases/tag/v6.3.1) | 2019/05/31 | ✓ | Sprint release | +| [5.5.0](https://github.com/mojaloop/helm/releases/tag/v5.5.0) | 2019/04/02 | - | Sprint release | +| [5.4.2](https://github.com/mojaloop/helm/releases/tag/v5.4.2) | 2019/03/29 | ✓ | Sprint release | +| [5.4.1](https://github.com/mojaloop/helm/releases/tag/v5.4.1) | 2019/03/21 | ✓ | Sprint release | +| [5.4.0](https://github.com/mojaloop/helm/releases/tag/v5.4.0) | 2019/03/19 | ✓ | Sprint release | +| [5.2.0](https://github.com/mojaloop/helm/releases/tag/v5.2.0) | 2019/02/20 | ✓ | Sprint release | +| [5.1.3](https://github.com/mojaloop/helm/releases/tag/v5.1.3) | 2019/02/14 | ✓ | Sprint release | +| [5.1.2](https://github.com/mojaloop/helm/releases/tag/v5.1.2) | 2019/02/11 | ✓ | Sprint release | +| [5.1.1](https://github.com/mojaloop/helm/releases/tag/v5.1.1) | 2019/02/08 | ✓ | Sprint release | +| [5.1.0](https://github.com/mojaloop/helm/releases/tag/v5.1.0) | 2019/02/06 | ✓ | Sprint release | +| [4.4.1](https://github.com/mojaloop/helm/releases/tag/v4.4.1) | 2019/01/31 | ✓ | Released at PI4 Convening in Jan 2019 | diff --git a/legacy/deployment-guide/upgrade-strategy-guide.md b/legacy/deployment-guide/upgrade-strategy-guide.md new file mode 100644 index 000000000..ef2e2b09e --- /dev/null +++ b/legacy/deployment-guide/upgrade-strategy-guide.md @@ -0,0 +1,115 @@ +# Upgrade Strategy Guide + +This document provides instructions on how to upgrade existing Mojaloop installations. It assumes that Mojaloop is currently installed using Helm, but these strategies can be applied in general. + +## Table of Contents + +- [Upgrade Strategy Guide](#upgrade-strategy-guide) + - [Table of Contents](#table-of-contents) + - [Helm Upgrades](#helm-upgrades) + - [Non-breaking Releases](#non-breaking-releases) + - [Breaking Releases](#breaking-releases) + - [Mojaloop installed without backend dependencies](#mojaloop-installed-without-backend-dependencies) + - [1. Target version has no datastore breaking changes](#1-target-version-has-no-datastore-breaking-changes) + - [Example Canary style deployment](#example-canary-style-deployment) + - [2. Target version has datastore breaking changes](#2-target-version-has-datastore-breaking-changes) + - [Mojaloop installed with backend dependencies](#mojaloop-installed-with-backend-dependencies) + - [Example Blue-green style deployment](#example-blue-green-style-deployment) + +## Helm Upgrades + +This section discusses the strategies of how upgrades could be applied to an existing Mojaloop Helm deployment that uses the [Mojaloop Helm Charts](https://github.com/mojaloop/helm). + +The scope of the breaking changes described below are applicable to the Switch Operator's Helm deployment with no direct impact (i.e. no functional changes such as a new Mojaloop API Specification version) to Participants (e.g. Financial Services Providers). Such functional changes may be part of a Helm release, but are out of scope for this section. + +Recommendations: + +1. all upgrades should be tested and verified in a pre-production environment +2. always consult the release notes as there may be some known issues, or useful notes that are applicable when upgrading +3. the [migrate:list command](https://knexjs.org/#Migrations) can be used to list pending datastore changes in the following repositories: + - + - + +### Non-breaking Releases + +Non-breaking changes will require no additional or special actions (unless otherwise stated in the release notes) to be taken other than running a standard [Helm upgrade](https://helm.sh/docs/helm/helm_upgrade) command. + +Be aware of the following optional parameter flag(s) that will be useful when upgrading: + +``` + -i, --install if a release by this name doesn't already exist, run an install + --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +See the following example of how these parameters can be applied: + +```bash +helm --namespace ${NAMESPACE} ${RELEASE_NAME} upgrade --install mojaloop/mojaloop --reuse-values --version ${RELEASE_VERSION} +``` + +It is possible to rollback using the [Helm rollback](https://helm.sh/docs/helm/helm_rollback/) command if desired. + +### Breaking Releases + +There are several strategies that can be employed when upgrading between breaking releases depending on the following deployment topologies: + +1. Mojaloop installed without backend dependencies (e.g. Kafka, MySQL, MongoDB, etc), with backend dependencies managed separately. This is preferred and will provide the most flexibility in upgrading, especially when there are breaking changes + +2. Mojaloop installed with backend dependencies, with backend dependencies tightly coupled to the Helm installation + +#### Mojaloop installed without backend dependencies + +This is the preferred deployment topology as it will provide the most flexibility when upgrading. By separating out the backend dependencies, it will enable one to deploy the target version of Mojaloop as a new deployment. + +This new deployment can either point to the existing backend dependencies or will require new backend dependencies depending on the following: + +##### 1. Target version has no datastore breaking changes + +In this scenario, we can utilise a Canary style deployment strategy by configuring the new deployment to the existing backend dependencies. The new deployment will by default upgrade the datastore schemas as required by running the `migration` (see [Central-ledger](https://github.com/mojaloop/central-ledger/tree/master/migrations), [Account-lookup-service](https://github.com/mojaloop/account-lookup-service/tree/master/migrations)) scripts. Alternatively, the migration scripts can be disabled (e.g. [central-ledger](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml#L147), with Account-lookup-service similarly being configured) if required, and a manual upgrade SQL script can be prepared (see [migrate:list command](https://knexjs.org/#Migrations) to list pending changes) if preferred. + +There should be no disruption to the current Mojaloop deployment. + +As the backend dependencies are shared between the current and target deployments, it will also be possible to move a sub-set of users to the target Mojaloop deployment allowing for one to validate the new deployment with minimal impact, and also provide the ability for users to easily switch back to the current deployment. + +###### Example Canary style deployment + +![Helm Canary Upgrade Strategy](./assets/diagrams/upgradeStrategies/helm-canary-upgrade-strategy.svg) + +1. Customize the [Mojaloop Chart values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) for the desired target Mojaloop release: + 1. Ensure backend-end configurations are set to the existing (shared) deployed Backend dependencies + 2. If applicable, ensure ingress-rules do not overwrite the current deployment configuration +2. Deploy the target Mojaloop release (Blue) + 1. Monitor the migration script logs for any upgrade errors via the `run-migration` containers: + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=centralledger-service -c run-migration` + - `kubectl -n ${NAMESPACE} logs -l app.kubernetes.io/name=account-lookup-service-admin -c run-migration` +3. Execute sanity tests on the Current Green deployment environment (verify impact of datastore changes, and allow for rollback, or partial switch-over for DFSPs, etc) +4. Execute sanity tests on the Target Blue deployment environment +5. Cut-over API Gateway (or upgrade target Ingress rules) to from Current Green to Target Blue deployment environment + +##### 2. Target version has datastore breaking changes + +See [Mojaloop installed with backend dependencies](#mojaloop-installed-with-backend-dependencies). + +#### Mojaloop installed with backend dependencies + +In this scenario, we can utilise a Blue-green style deployment strategy by deploying new backend dependencies, and deploying the target Mojaloop release separately (with the additional benefit of aligning your deployment to the recommending deployment topology). + +Manual data migrating from the existing datastores to the new target backend dependencies will be required. It will also be necessary to keep the current and new datastores in sync as long as live transactions are being processed through the existing Mojaloop deployment. A maintenance window need to be scheduled to stop "live" transaction on the current deployment to ensure data consistency, and allow for the switch-over to occur safely. This will cause a disruption, but can be somewhat mitigated by ensuring that the maintenance window is scheduled during the least busiest time. + +##### Example Blue-green style deployment + +![Helm Blue-green Upgrade Strategy](./assets/diagrams/upgradeStrategies/helm-blue-green-upgrade-strategy.svg) + +1. Customize the [Mojaloop Chart values.yaml](https://github.com/mojaloop/helm/blob/master/mojaloop/values.yaml) for the desired target Mojaloop release: + 1. Ensure backend-end configurations are set to the target deployed Backend dependencies + 2. If applicable, ensure ingress-rules do not overwrite the current deployment configuration +2. Deploy the target Mojaloop release (Blue) +3. Create Migration process to sync and transform data into target deployed Backend datastore dependencies from Green to Blue +4. Schedule cut-over window +5. Execute cut-over during window + 1. Set current Green Backend datastore dependencies to read-only (where possible) + 2. Drain any remaining connections from Green + 3. Ensure Migration process is fully in-sync from Green to Blue + 4. Execute sanity tests on the Blue Target deployment environment + 5. Cut-over API Gateway (or upgrade target Ingress rules) to from Green Current to Blue Target deployment environment diff --git a/legacy/discussions/ISO_Integration.md b/legacy/discussions/ISO_Integration.md new file mode 100644 index 000000000..333ed8729 --- /dev/null +++ b/legacy/discussions/ISO_Integration.md @@ -0,0 +1,61 @@ +Mojaloop ISO Integration discussions + +# Mojaloop-ISO integration + +The proposed solution would be able to handle ISO to Open API translation and vice versa, by making use of an ISO-OPEN API converter/connecter plug-in or interface, similar to the Scheme Adapter in the Mojaloop system. As the Scheme adapter performs Mojaloop API to FSP API conversion, the custom plug-in/interface would function as a protocol and message translator between the ISO interface and the ML API or the Scheme Adapter. + +## Scope + +Define message flows in both and ISO and Open API networks and mappings between messages. + - Document failure scenarios and message flows for these. + - Define a mechanism for routing that is MSISDN-based . + - Mojaloop Transactions could be sent through existing payment rails conforming to their standards(such as ISO) + - Develop a scheme adapter/plug-ins that could perform ISO-Open API and vice versa. + - To be able to send Mojaloop transactions originating from ATM and POS over ISO networks, across Mojaloop systems + + ## ISO 8583 - Mojaloop - An Inter-network case study + +Africa is a great continent with a multitude of Financial Service providers who focuses on region based financial inclusion and services provision. The continent boasts of a vast network of Payment service providers and financial institutions. Some of the most prominent networks are listed below: + +- InterSwitch ( Nigeria) +- eProcess ( Ghana) +- Umoja Switch ( Tanzania) +- KenSwitch ( Kenya) +- ZimSwitch ( ZImbabwe) +- RSwitch ( Rwanda) + +Almost all of these networks make use of an ISO 8583 based Payments processing platform ( Postilion Switch) to drive ATM’s, POS & Mobile channels, process card based and non card based transactions for both acquiring and issuing verticals. + +As such, the proposition is to create a solution, where by the existing Payment networks could integrate with a Mojaloop based system like Mowali, without having to make any development or design changes to their existing infrastructure. + +In this case study, we are considering the case of Umoja Switch in Tanzania and provide them with a solution whereby, Umoja could provide Mojaloop transactions through their existing ATM deployments. + +### Umoja Switch + +UmojaSwitch was established in the year 2006 by six banks in Tanzania with the main purpose being able to establish a joint shared infrastructure for financial services and enjoying the economies of scale. + +The aim of establishment was to create a shared platform where financial institutions can integrate and interpolate through a shared switch. + +Eventually, the number of members joining the UmojaSwitch network continued to increase and as of now there are around 27 banks who has joined the Umoja Switch consortium. + +## ISO Networks to Open API + +The goal of the PoC would be to showcase how a Mojaloop transaction would be sent over a standard ISO switch/Network through to a Mojaloop system such as Mowali. + +As a part of this an ISO-Open API Adapter would be implemented which would process ISO messages originating from an ISO network like InterSwitch and send it through to an Open API network like Mowali. + +## Proposed Solution + +The proposed solution will consist of an interface or adapter/plugin that could process transactions between ISO networks and Mojaloop systems. + +The ISO payments platform makes use of an ISO interface which uses standard TCP/IP connection to send and respond to ISO messages to and from the various channels. In order to accept and process connections from the interface, our solution would have a TCP/IP listener, which would receive and process transactions from ISO network and then map it to Open API , after which the transactions will be sent over to a Mojaloop system like Mowali on a URL. + +In this case the payment networks are largely dependent on their respective (i.e. Visa/ MasterCard/Verve/etc) card or account number, which is used to define the BIN look up table for routing purposes . One of the options would be to predefine a Bin range (eg: 757575) that would identify a Mojaloop transaction and then let the payment network implement a routing logic that would send all Moja transactions through to the Open API network. + +The ISO-Open API adapter would process the ISO message received from the ISO switch and send it through to the Mojaloop system in Open API format. + +However, such changes would imply configurational changes to download applications on ATM and other terminal devices, but this could be handled as a standard operational change similar to the existing configurational changes performed as per the business requirements. + + + + diff --git a/legacy/discussions/Mojaloop Performance 2020.pdf b/legacy/discussions/Mojaloop Performance 2020.pdf new file mode 100644 index 000000000..719dec47e Binary files /dev/null and b/legacy/discussions/Mojaloop Performance 2020.pdf differ diff --git a/legacy/discussions/aws_tagging.md b/legacy/discussions/aws_tagging.md new file mode 100644 index 000000000..a50c7b2ef --- /dev/null +++ b/legacy/discussions/aws_tagging.md @@ -0,0 +1,127 @@ +# AWS Tagging Guidelines + Policies + +> **Note:** These guidelines are specific to the Mojaloop Community's AWS Environment for testing and validating Mojaloop installations, and are primarily for internal purposes. They may, however, be a useful reference to others wishing to implement similar tagging strategies in their own organizations. + +To better manage and understand our AWS usage and spending, we are implementing the following tagging guidelines. + +## Contents +- [Proposed tags and their meanings](#proposed-tags-and-their-meanings) + - [mojaloop/cost_center](#mojaloopcost_center) + - [mojaloop/owner](#mojaloopowner) +- [Manual Tagging](#manual-tagging) +- [Automated Tagging](#automated-tagging) +- [AWS Tagging Policies](#aws-tagging-policies) + - [Viewing Tag Reports + Compliance](#viewing-tag-reports--compliance) + - [Editing Tag Policies](#editing-tag-policies) + - [Attaching/Detaching Tag Policies](#attachingdetaching-tag-policies) + +## Proposed tags and their meanings + +We propose the following 2 tag _keys_: + +- `mojaloop/cost_center` +- `mojaloop/owner` + +### `mojaloop/cost_center` + +`mojaloop/cost_center` is a breakdown of different resources in AWS by the workstream or project that is incurring the associated costs. + +It loosely follows the format of `-[-subpurpose]`, where account is something like `oss`, `tips`, or `woccu`. +> Note: It's likely that most of the resources will be under the `oss` "account", but I managed to find some older resources that fall under the `tips` and `woccu` categories. We also want to plan for future types of resources that might be launched in the future. + +Some potential values for `mojaloop/cost_center` are: + +- `oss-qa`: Open source QA work, such as the existing dev1 and dev2 environments +- `oss-perf`: Open source performance work, such as the ongoing performance workstream +- `oss-perf-poc`: Performance/Architecture POC + +We also reserve some special values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/cost_center:unknown` tags and produce a report +- `n/a`: This resource incurrs no cost, so we're not really worried about assigning a `cost_center` to it + - This can be useful for mass tagging resources that are hard to figure out where the belong, such as EC2 Security Groups + +### `mojaloop/owner` + +`mojaloop/owner` is a person who is responsible for the managing and shutdown of a given resource. + +The goal of this tag is to prevent long running resources that everybody else thinks _someone else_ knows about, but we no longer need. By applying this tag, we will be able to have a list of _who to go to_ in order to ask questions about the resource. + +The value can simply be a person's name, all lowercase: +- `lewis` +- `miguel` +- etc. + +Once again, we will reserve the following values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/owner:unknown` tags and see what resources are 'orphaned' + + +## Manual Tagging + +We can use the "Tag Editor" in the AWS console to search for untagged resources. + +1. Log into the AWS Console +2. Under Resource Groups, select "Tag Editor" +![](./images/tagging_01.png) +3. From the tag editor, select a Region (I typically use "All regions"), and Resource Type (I also typically use "All resource types") +4. Now select "Search Resources", and wait for the resources to appear + +You can also search by tags, or the absense of tags to see what resources have not been tagged yet. +![](./images/tagging_02.png) + +5. Once you have a list of the resources, you can select and edit tags for many resources at once! +6. You can also export a `.csv` file of resources found in your search + + +## Automated Tagging + +We currently automate tagging on the following + +As we have a firmer grasp of our tagging guidelines, we need to introduce them into our tooling so that all of the grunt work of manual tagging. + +At the moment, this will look like introducing tags into: +1. Rancher - which currently manages our Kubernetes clusters for both QA and Performance purposes +2. IAC - The upcoming IAC code that will eventually be running our dev environments + + +## AWS Tagging Policies + +As of August 3, 2020, we have started introducing [AWS Tagging Policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) to better enforce tags and monitor our resources (especially with respect to costs). + + +### Viewing Tag Reports + Compliance + +1. Log in to the AWS Console +2. "Resource Groups" > "Tag Editor" +3. On the left sidebar, select "Tag Policies" + +From here you can see the tag policies "compliance report" + +![](./images/tagging_03.png) + + +### Editing Tag Policies + +> Note: This may require special admin priviledges to access these pages + +1. Log in to the AWS Console +2. Select "username@mojaloop" in the top right > "My Organization" +3. Select "Policies" > "Tag Policies" + +![](./images/tagging_04.png) + +4. From here, you can view the current tag policies + +![](./images/tagging_05.png) + +5. In the sidebar, you can click "View details" > "Edit policy" to edit the policy + + +### Attaching/Detaching Tag Policies + +1. Go to the "My Organization" page +2. Select the relevant account > "Tag policies" in the sidebar +3. From here you can Attach + Detach tag policies + +![](./images/tagging_06.png) diff --git a/discussions/code_improvement.md b/legacy/discussions/code_improvement.md similarity index 100% rename from discussions/code_improvement.md rename to legacy/discussions/code_improvement.md diff --git a/legacy/discussions/cross_border_day_1.md b/legacy/discussions/cross_border_day_1.md new file mode 100644 index 000000000..5c5d51d79 --- /dev/null +++ b/legacy/discussions/cross_border_day_1.md @@ -0,0 +1,270 @@ +# Cross Border Discussion Day 1 + +>**Links** +>- [Day 2 Notes](./cross_border_day_2.md) +>- [Relevant Issue on DA Board](https://github.com/mojaloop/design-authority/issues/32) +>- [Mojaloop Spec Pull Request](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Attendees: + +In person +- Lewis, Crosslake +- Adrian, Coil +- Nico, MB +- Sam, MB +- Miguel, MB +- Carol Benson, Glenbrook +- Michael Richards, MB +- Henrik Karlsson, Ericsson +- Rob Reeve, MB +- Vanburn, Terra Pay +- Razin, Terra Pay +- Ram, Terra Pay +- JJ, Google +- Matt Bohan, Gates Foundation +- David Power, EY +- James Bush, MB +- Warren, MB +- Judit, MB +- Bart-Jan and Bruno from GSMA - Day #2 + +Phone +- Kim Walters, Crosslake +- Istvan Molnar, DPC +- Innocent Ephraim, MB + +## Session 1 + +**Goal: Update the API definitions** + +- Privacy: + - Can I send USD? _yes/no_ + - What can I send? _list of currencies_ + +Business agreements: there are a few ways this can happen +- Global scheme, made up of scheme to scheme agreements +- bilateral scheme agreements +- scheme to scheme +- region + + +Definitions: +- Gateway FSP: An FSP that 'bridges' across 2 networks +e.g. Mowali + - 2 logical networks (USD,XOF?) + - a single mojaloop network + +- Cross Network Provider (CNP) + - FXP, same thing? + +Michael: +- there is a reason for that assumption +- other legal implications here... + +- single entity, legally in 2 different jurisdictions + - a close analogy of a scheme without jurisdiction + +- participant: + - has a tx account that can be debited or credited + - bank, fxp etc. + +>Q: Can we have a participant that doesn't settle? Or would this be covered by CNP that is a party +>e.g. Visa, doesn't always settle in a given market, but holds an account + +- Resident vs. Non-resident + - reporting requirements are different + +- what are the technical requirements for reporters? + +- settlement + - not too worried about it at this stage (our focus is on the API changes) + - we assume that settlement is possible, but need to narrow scope witht the api first + +- Not only mojaloop + - need to allow for non-mojaloop -> mojaloop transfers and vice versa (both inbound and outbound) + - must still be interoperable + + +- who provides routing? + - switch? + - ALS? + - CNP? + + +>*Follow Up:* Need a formal definition of FXP and CNP roles, along with requirements and responsibilities + + +At a scheme level + - should the sceheme maintain a list of other schemes it allows its FSPs to connect with? + - or should the CNP take care of this? + +- not scheme -> scheme, but part of the onboarding CNP process +- but the scheme can/should still maintain rules + +- how will quoting work? Should an FSP send multiple quotes, one addressed to each CNP? Or should the switch have some rules engine that helps it determine who to send quotes to? + +James: We want to be flexible. Can see instances where we would want both to happen, so we shouldn't assume too much at this stage. + +Simplest option: The switch talks to the ALS, determines a transfer is not in our network, and then finds a list of CNPs + +CNP + FXP -> essentially the same thing +- they are *Roles*, and a DFSP can assume more than 1 role +- fxps can also exist in more than 1 zone (e.g. Mowali case) + - single network fxp is just an fxp, + - multi-network fxp is likely also a CNP + + +## Session 2 + +- debate about single or multiple lookups + - we should never return "empty result" + +- are wallets addressable by MSISDN? + - only 1 account at the moment + - but this is internal to the switch + - the oracle's job is to convert MSIDN -> Mojaloop Address + +- in the future: MSISDN + accounts will be less related + - this topic is adjacently related to addressing + +- 'going outisde' mojaloop with addressing will be a little tricky +- Standardize addressing? + - not something we want to do + +Ram: There are existing tools (no need to reinvent the wheel), outside the mojaloop scheme + +- sending to unknown currency + - currently: 1 routing table answer + - future: multiple answers + +- privacy: + - no real need for hard rules at the moment (at least not at the API level, rules come along with schemes) + - we do need a method for mediating information that one switch requires from another (and rejecting quotes should these prerequesites not be met) + +--- +- Domestic vs. Cross border: USer has/needs different information + - e.g. do we only want to support discovery in domestic case? +--- + +Adrian: A lot of this stuff is business rule and scheme specific +- maintains competitive space +- How much information is in the: + - lookup? + - Quote? + +--- +- Proposal: Address lookup -> Returns multiple responses? +- MSISDN -> ID, not an address. Someone, not an account + +- there should be only 1 response from the ALS +- Michael disagrees + +- need to separate out *addressing* from *routing* + +- we need to think about the downstream affects this will have on testing + - need to find a clear way to test these lookups + + +For example, airtel UPI issue (where existing MSIDSNs were replaced when they grandfathered in their mobile customers to become mobile money customers) + - we need to avoid a situation like that + +--- + +Bring it back to first (L1P) principles +- transfers should clear immediately +- no such thing as a future + +- For domestic: we can guarantee delivery, but cross-border is much harder +- need to maintain transparency requirement on CNPs + - this comes down to business rules + +- Reversible tx's or rules abour downstream issues + - ILP takes care of *most* of this for us + +- in TIPS case: 1 ID maps to 1 account +- as always, there needs to be a compromise between privacy and features (and that's ok!) + +--- + +At the end of a quote: +- ValueDate +- how much will be received +- what are the fees? (broken down, by step and currency) + +--- + +How do we support protocols that don't support quotes (this is a question for moja to non-moja systems) + +Risk: CNP: they hold the risk in this type of transaction + +CNP as a participant? + - holds an account with a participant + - direct vs indirect approach + - this doesn't affect the technical requirements (so out of scope for this discussion) + + +--- + +- fixed send and receive: + - What direction does data need to be appended to the quote? It depends on if it is fixed receive vs fixed send + +- Either: `A send 20 USD to B` OR `B receives 1000 PHP` + +- translating fees back for user: FXP __must__ apply the same rate for fees as the principal transfer + +- From L1P Perspective: __the goal is transparency__ + +- how about quotes outside of Mojaloop? + - CNP should take care of this - it is the last bastion of Mojaloopyness + +--- + +- Participant Object + - Attached to the Quotes, one entry per hop? + - So multi-hop quotes hold _n_ participant objects, where _n_ = number of hops + 1 + +As part of this we need: +- interoperable bits of data (common defs) +- scheme for encryption +- a place to put the data (in the quotes object) + +Should we worry about encryption for now? +- perhaps not, but still should allow for it in the API + +Encryption adds extra integration challenge +- what is the need to get data in the clear? + - from a techincal perspective: just use a blank encryption key + +Do we need to encrypt to ensure the switch(es) can't see the data? + - perhaps not at this stage + + +>### Decision: +>- No encryption for now +>- in outbound quote request: have a list of data requirements +>- for inbound quote request: participants fill out those requirements +>- if requirements are not met: abort the quote +>- Don't hardcode the data requirements, we should use existing standards + + +- we need to specify whether or not fields _have_ been verified + - ties in with tiered KYC processes + +- need a common dictionary of data that can/should be requested + + +## Boards: + +_board 1: Fixed send flows_ +![board_1](./images/cb_board_1.jpg) + +_board 2: Fixed receive flows_ +![board_2](./images/cb_board_2.jpg) + + + + + + + + diff --git a/legacy/discussions/cross_border_day_2.md b/legacy/discussions/cross_border_day_2.md new file mode 100644 index 000000000..fbbbfd799 --- /dev/null +++ b/legacy/discussions/cross_border_day_2.md @@ -0,0 +1,124 @@ +# Cross Border Discussion Day 2 + +>**Links** +>- [Day 1 Notes](./cross_border_day_1.md) +>- [Relevant Issue on DA Board](https://github.com/mojaloop/design-authority/issues/32) +>- [Mojaloop Spec Pull Request](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Next Steps: + +- Updated the proposal APIs +- Present the consolidated change to the CCB in writing +- Couple of weeks to put together the changes (Michael/Adrian to split up the work) +- Mid-November CCB call + + +## Session 1 + +Unanswered Questions: +- addressing + - break it down? + - cross-mojaloop + - what does a PayerFSP do with an address? + +- ALS + routing + - what optimizations does the API need to do/allow? + +- local vs. remote DFSP ids + +- Downstream failures + - When paymnet does clear, does the payer receive a notification (esp. with 'delayed' payments that may interface with non-mojaloop systems) + - Can a CNP send a `PATCH` of the tx to update the Payee somehow? + +--- + +- multiple quotes and route responses: + - how do display to the user? + - We need to establish rules for filtering routes + - hard to do: e.g. blacklisting a switch? or express a preference for certain routes + +- how will Sender DFSP discover the scheme rules for a receiver? +- does the Sender DFSP need to 'know' the final switch? Or can it just 'know' the next one? + +--- + +Running up against ML + non-ML assumptions +- does this mean CNP needs to do more work when connecting to non-ML? + - e.g. knowing the resulting scheme/switch? + - why? Failure handling + - based on yesterday's decision: Should the CNP do the work here? + +- Take a lesson from SWIFT: + - bank doesn't know where the money is going + - can we avoid this in ML? + +--- + +CNP: Goal is to 'act like' a normal member of the network + - This minimizes the responsibilities that the scheme assumes + +When is the TX considered completed? + - There might be cases where the scheme considers it done, but it is not techincally finished end to end + +How do we deal with service deteroriation? + - Scheme rules + +--- + +Back to quotes: + +- how to express quote information? + - are quotes and routes separate? Presumably, yes + +- The quote is the most expensive step + - Can we provide QOS information here as part of the lookup? + +Addressing: +- Need for a globally unique address + - Allow an address space for DFSPs and unique persons/accounts +- sheme says "this isn't in my space" +- CNP figures out the routes to get to that space + +--- + +### Michael's Tangent: + +- did we make the wrong assumptions about the CNP? + +**switch:** Knows CNPs + FXPs +**CNPs:** holds routing table and lookup + +- if the sender or receiver is an FXP, the the tx is *not* a cross-currency tx + +--- + +## Session 2 + +*Decision:* +- header value is CNP id +- partId object is the final FSP + +valueDate +- implied that funds are expected to clear before the valueDate +- can still have short expiry times on tx + +- CNP: + - returns an obfuscated set of fees + - fits into our current model + + +- condition: + - existing object cryptographically tied to the tx object + - but for multi-hop, we don't only know this + - fixed receive makes this tricker (which is what echo data hopes to solve) + + - We want **only 1 condition for all hops** + - the idea of a multi-condition is a "perversion" (according to some) + + +## Boards: + +_board 3: Cross Network lookup and quotes flow, fixed receive of 1000 PHP from USD_ +![board_3](./images/cb_board_3.jpg) + + diff --git a/legacy/discussions/crossborder.md b/legacy/discussions/crossborder.md new file mode 100644 index 000000000..4deec6f8d --- /dev/null +++ b/legacy/discussions/crossborder.md @@ -0,0 +1,396 @@ +**Cross-border Workstream Meeting** + +March 10th & 11th (London/remote) + +**Next Steps for PI:** + +• Proposal for how the CNP query and host oracle services and global goals - Adrian, Michael + +• Compound identifiers, ways in which this is captured in the system or expressed in apis - open + +• What information is captured in the data model or the extension list - Michael + +• Follow-up w/ SWIFT to discuss requirements - Matt + +**Open Items:** + +• Finalize CNP Requirements + +• Has to aggregate information and put them together into a single request & they will need to sign separately + +• Finalize FXP has to manage FX rates, the settlements and what expires when + +• CNPs can extend this and determine additional scheme rules + +• FXP handles rounding errors + +• FXP Guarantee a given rate + +• How do you get non-Mojaloop folks in the schema? + +• How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + +• How do we manage requests for regulatory reasons + +• Investigate identifier mappings (Map pathfinder accounts/mobile accounts to DFSP unique IDs) + +• Investigate Certification (Hash and PKKI) + + +Detailed Meeting Notes: +Day #1: + - Quote response + + ○ How do we code the SLA into the response + + ○ Ask a 2nd CNP to route + + ○ In the API - need to package up how to get it there + + ○ As a CMP in Mowali if I return a quote response the scheme has implications + + ○ Follow the whole route from payer to payee + + ○ Limiting the participation of CNP - they need to be the last hop + + § How to define the requirements of a CNP? + + - Message format + + ○ Http syntax + + ○ Started from the mojaloop scheme + + § Move towards the CNP should manage the conversion + + ○ SWIFT version + + ○ Security - TLS + + ○ Header/content encrypted in JWS + + - Retail system + + ○ Off network - remit to someone hub + + - Data Model + + ○ Structure: Ways in which we added new information, different routes, etc. + + ○ Privacy: Visibility and Security - only accessible to the people that can see it + + ○ Content of the data model + + - Transfer is done through the switch (movement of money) + + ○ In mowali - the amounts are expressed but the rate is important because it impacts settlements + + § Data flow - we add the rate when we send the quote back + + § Added in the extension list - should it be part of the standard? + + § Send and receive amount (differ currency) + + - Data element + + ○ Fee for each participant + + ○ Payer DFSP adds it up + + ○ Fee element for the transaction + + - Proposal + + ○ Account lookup service + + § List of local FSP + + ○ Switch - need to maintain state and lookup requests + + § Should look like a domestic transfer to the sender + + § Collect the information and send it back - + + ○ CNP - making assumptions to meet requirements + + § Do you need to see the route + + § Collecting different information downstream + + § Sending FSPs needs to know who is the receiver + + ○ CNP has to aggregate information and put them together into a single request & they will need to sign separately + + § Condition and fulfillment is part of a PKI structure + + § If there is more than one CNP - there needs to ensure the DFSP payee has to be certain the DFSP payer - connections + + § CNP needs to know everything, regulatory reporting - + + ○ Do we need to duplicate the structure in a Cross-network transfer? + + § Trying to prevent a rouge partner from joining + + § Trust the CNP to meet their SLAs + + ○ Mojaloop to another scheme - we don’t have control + + § Require they confirm receipt + + § How can I tell + + § How can I tell the person at the end got the money + + ○ External signing authority to confirm the money was received + + § If your scheme wants to participate in x-border then all the participants need to get signed + + § Public key - need to join a mojaloop network have to issue public keys + + § Central certificate issuing authority + + § Need a PKI structure in place + + ○ How do you get non-Mojaloop folks in the schema? + + § How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + + § Identify the participants - FSP, DFSP - all have signed + + § Parties - end users (Bob/Alice) + + § Single transaction (with multiple transfers) + + § No one commits their funds to everyone is satisfied + + § How to extend mojaloop and non-mojaloop scheme + + ○ Certification + + § Hash and PKKI + + § Gold and silver network + + § New partner - live on the network + + § Scheme decides requirement on the network + + § Self-signing cert + + ○ Liquidity + + § FXP does position mgmt + + § What requirements do we put on a FXP + + § Mobile money has less flexibility + + § Rules that happened across schemes + + ○ FXP has to manage the settlements, what expires when, etc.. + + § FXP has to manage the shortage of quote validity + + § Allow FXP to reject the requests + + ○ How do we manage requests for regulatory reasons + + § There is a dictionary + + □ Is the a requirement to share KYC? + + □ You can ask for many things - up to the participant + + □ Need to agree on the baseline scheme + +**Day #2:** + + - Switch data + + ○ Account numbers + + ○ Blacklist, white list (oversight and blocking) + + ○ Keeping it simple + + ○ Hub + + ○ Side service for folks that can do this + + § Mobile data capture + + § Side car + + § Digital process + + § Value added services for the hub (managed service) + + - Switch - need to maintain state and lookup requests + + - CNP can be an ordinary DFSP + + ○ All DFSP supports all the use cases + + ○ Full participants (might just provide a CNP or FXP service) + + - FXP definition and requirements + + ○ FXP - require rates/fees as part of the Quoting service - need standard industry rate + + § CNPs can extend this and determine additional scheme rules + + ○ FXP handles rounding errors + + ○ Guarantee a given rate + + ○ Manage settlement across schemas + + ○ FX rates + + ○ Should allow people that just do FX + + ○ Edge cases for failure + + § Details in the error messages to find the errors + + ○ FXP needs to point back the right information + + § How messages passed work + + § Edge cases - share what is done too date + + § Jo owns got a working API - identified + + § Changed the quote (intercepted the quote) -- + + § KYC extension list - extended the quote for this + + § Rates are in the extended list (are the list) + + § Where the FXP is applied ? + + § What do we do with fees downstream + + □ (payee DFSP takes place of the aggregation) + + - How to manage identifier resolution + + ○ 2 types of Identifiers + + § Global ones (pass to CNP) - to get a response + + § Local ones - expect the user to provide + + ○ Mojaloop we use identifiers as proxy + + ○ Merchant numbers might be specific to a scheme + + ○ Multiple identifiers for a single account + + ○ How do we uniquely identify the account? + + ○ Rely on CNP (restrict each identifiers in this scheme) + + ○ What sort of structures in place + + ○ Passport identification - place holders + + ○ Map pathfinder accounts/mobile accounts to DFSP unique IDs + + § Service - primary account is X + + § Each country has a service they provide + + § Each CNP understands the address scheme + + § Global one - need to know which ways to use + + ○ Sends a get parties to the switch + + § ALS never heard of them + + § 2 ways + + □ Global way (path finder and conversion to BIC) + - CNP + + ○ Not hosting anything + + ○ Route through the CNP - ask others + + ○ Constructing the alternative routes + + - Global registry does not exist + + ○ Ultimate beneficiary + + ○ Established communication + + ○ Challenge will we able to have 2 DFSPs share direct communication and will be a stretch? + + - Switch has schemes + + ○ A Hub operator following Scheme Rules may allow names of FSPs as decided by those Rules + + ○ The technology or the Admin API itself doesn’t restrict the names (apart from restrictions on length, type or characters, etc) + + ○ BGP: Border Gateway Protocol  + + - Query each CNP and then come up with optimizations, matrix that provides global route - goal would be not to query the CNP directly + +• How to connect with Mojaloop? + + - Any financial service can connect to Mowali + + - Scheme rules, technical + + - Regulatory + + - How do I assign stuff? - no one knows the steps + + - Mojaloop API - understand this. + + - 2 instances Mojaloop instances - TIPs and Mowali + + ○ WOCCU, Asia, US - applied for instance + + ○ Still pushing the boundries + + - What dos an integration look like + + ○ Need sandbox, simulators + + ○ Standard approach + +• Instance payment service + + - Get the flows flowing in a timely manner + + - Need real-time ledgers; what happens if they are offline? + + - Exception for off network (banks take advantage of float) + +• Discovery process (sending FSP) + + - Switch determines if they need to contact a FXP + + - What currency the receiving account can receive in + + - Multiple lookups + + - Data model - set of accounts, w/ one currency at a DFSP + + +Attendees: + + - Mike, Patricia - Thume + + - Michael R, Rob R, Sam - Modusbox + + - Kim, Lewis - Crosslake + + - Rolland, Greg, Phillip - Sybrin + + - Vanburn -- Terrapay + + - Megan, Simeon - Virtual diff --git a/discussions/decimal.md b/legacy/discussions/decimal.md similarity index 98% rename from discussions/decimal.md rename to legacy/discussions/decimal.md index be968f724..119e51501 100644 --- a/discussions/decimal.md +++ b/legacy/discussions/decimal.md @@ -1,4 +1,4 @@ -# Moajoop Decimal Type; Based on XML Schema Decimal Type +# Mojaloop Decimal Type; Based on XML Schema Decimal Type ## Decimal value type diff --git a/legacy/discussions/dicussion-docs.md b/legacy/discussions/dicussion-docs.md new file mode 100644 index 000000000..7b8efb24b --- /dev/null +++ b/legacy/discussions/dicussion-docs.md @@ -0,0 +1,30 @@ +# Discussion Documents + +## PI 10 +- [Performance Project](./Mojaloop%20Performance%202020.pdf) +- [Code Improvement Project](./code_improvement.md) +- [Cross Border Project](./crossborder.md) +- [PSIP Project](./pisp.md) + +## PI 9 + +- [Versioning Draft Proposal](./versioning_draft_proposal.md) +- [Code Improvement Project](./code_improvement.md) +- [Performance Project](./performance.md) +- [Cross Border Project](./crossborder.md) +- [PSIP Project](./pisp.md) + +## PI 8 + +- [Cross Border Meeting Notes Day 1](./cross_border_day_1.md) + +- [Cross Border Meeting Notes Day 2](./cross_border_day_2.md) + +- [ISO integration Overivew](./ISO_Integration.md) + +- [Mojaoop Decimal Type; Based on XML Schema Decimal Type](./decimal.md) + +## PI 7 + +- [Workbench Workstream](./workbench.md) + diff --git a/legacy/discussions/images/cb_board_1.jpg b/legacy/discussions/images/cb_board_1.jpg new file mode 100644 index 000000000..e53cad0b9 Binary files /dev/null and b/legacy/discussions/images/cb_board_1.jpg differ diff --git a/legacy/discussions/images/cb_board_2.jpg b/legacy/discussions/images/cb_board_2.jpg new file mode 100644 index 000000000..8afa47d94 Binary files /dev/null and b/legacy/discussions/images/cb_board_2.jpg differ diff --git a/legacy/discussions/images/cb_board_3.jpg b/legacy/discussions/images/cb_board_3.jpg new file mode 100644 index 000000000..7cce85870 Binary files /dev/null and b/legacy/discussions/images/cb_board_3.jpg differ diff --git a/legacy/discussions/images/mojaloop_spokes.png b/legacy/discussions/images/mojaloop_spokes.png new file mode 100644 index 000000000..b0c67eb08 Binary files /dev/null and b/legacy/discussions/images/mojaloop_spokes.png differ diff --git a/legacy/discussions/images/tagging_01.png b/legacy/discussions/images/tagging_01.png new file mode 100644 index 000000000..4379443ce Binary files /dev/null and b/legacy/discussions/images/tagging_01.png differ diff --git a/legacy/discussions/images/tagging_02.png b/legacy/discussions/images/tagging_02.png new file mode 100644 index 000000000..b86ac0a91 Binary files /dev/null and b/legacy/discussions/images/tagging_02.png differ diff --git a/legacy/discussions/images/tagging_03.png b/legacy/discussions/images/tagging_03.png new file mode 100644 index 000000000..d8ab17646 Binary files /dev/null and b/legacy/discussions/images/tagging_03.png differ diff --git a/legacy/discussions/images/tagging_04.png b/legacy/discussions/images/tagging_04.png new file mode 100644 index 000000000..a2913b226 Binary files /dev/null and b/legacy/discussions/images/tagging_04.png differ diff --git a/legacy/discussions/images/tagging_05.png b/legacy/discussions/images/tagging_05.png new file mode 100644 index 000000000..ba54dbf64 Binary files /dev/null and b/legacy/discussions/images/tagging_05.png differ diff --git a/legacy/discussions/images/tagging_06.png b/legacy/discussions/images/tagging_06.png new file mode 100644 index 000000000..8c4eb717f Binary files /dev/null and b/legacy/discussions/images/tagging_06.png differ diff --git a/legacy/discussions/performance.md b/legacy/discussions/performance.md new file mode 100644 index 000000000..a554f6610 --- /dev/null +++ b/legacy/discussions/performance.md @@ -0,0 +1,175 @@ +# Performance Workstream + +Wednesday, March 11, 2020 + +## Performance Goals: + +- Current HW system achieving stable 1k TPS, peak 5k and proven horizontal scalability + 1. More instances = more performance in almost linear fashion. + 1. Validate the minimum infrastructure to do 1K TPS (fin TPS) + 1. Determine the entry level configuration and cost (AWS and on-premise) + +## POCs: + +Test the impact or a direct replace of the mysql DB with an shared memory network service like redis (using redlock alg if locks are required) + +Test a different method of sharing state, using a light version of event-drive with some CQRS + +## Resources: + +- Slack Channel: `#perf-engineering` +- [Mid-PI performance presentation](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/March2020-PI9-MidPI-Review) +- [Setting up the monitoring components](https://github.com/mojaloop/helm/tree/master/monitoring) + +## Action/Follow-up Items: + +- What Kafka metrics (client & server side) should we be reviewing? - Confluent to assist +- Explore Locking and position settlement - Sybrin to assist + 1. Review RedLock - pessimistic locking vs automatic locking + 2. Remove the shared DB in the middle (automatic locking on Reddis) + +- Combine prepare/position handler w/ distributed DB +- Review node.js client and how it impact kafka, configuration of Node and ultimate Kafka client - Nakul +- Turn back on tracing to see how latency and applications are behaving +- Ensure the call counts have been rationalized (at a deeper level) +- Validate the processing times on the handlers and we are hitting the cache +- Async patterns in Node + 1. Missing someone who is excellent on mysql and percona + 2. Are we leveraging this correctly + +- What cache layer are we using (in memory) +- Review the event modeling implementation - identify the domain events +- Node.js/kubernetes - +- Focus on application issues not as much as arch issues +- How we are doing async technology - review this (Node.JS - larger issue) threaded models need to be optimize - Nakul + +## Meeting Notes/Details + +### History + +1. Technology has been put in place, hoped the design solves an enterprise problem + +2. Community effort did not prioritize on making the slices of the system enterprise grade or cheap to run + +3. OSS technology choices + +### Goals + +1. Optimize current system +2. Make it cheaper to run +3. Make it scalable to 5K TPS +4. Ensure value added services can effectively and securely access transaction data + +### Testing Constraints + +1. Only done the golden transfer - transfer leg +2. Flow of transfer +3. Simulators (legacy and advance) - using the legacy one for continuity +4. Disabled the timeout handler +5. 8 DFSP (participant organizations) w/ more DFSPs we would be able to scale + +### Process + +1. Jmeter initiates payer request +2. Legacy simulator Receives fulfill notify callback +3. Legacy simulator Handles Payee processing, initiatives Fulfillment Callback +4. Record in the positions table for each DFSP + - a. Partial algorithm where the locking is done to reserve the funds, do calculations and do the final commits + - b. Position handler is Processing one record at a time + +5. Future algorithm would do a bulk + +- One transfer is handler by one position handler + - Transfers are all pre-funded + +1. Reduced settlement costs +2. Can control how fast DFSPs respond to the fulfill request (complete the transfers committed first before handling new requests) +- System need to timeout transfers that go longer then 30 seconds + - Any redesign of the DBs + - Test Cases + +- Financial transaction + - End-to-end + - Prepare-only + - Fulfil only + +- Individual Mojaloop Characterization + - Services & Handlers + - Streaming Arch & Libraries + - Database + - What changed: 150 to 300 TPS? + +- How we process the messages +- Position handler (run in mixed mode, random + - Latency Measurement + +1. 5 sec for DB to process, X sec for Kafka to process +2. How to measure this? + +### Targets + +1. High enough the system has to function well +2. Crank the system up to add scale (x DFSPs addition) +3. Suspicious cases for investigations +4. Observing contentions around the DB +5. Shared DB, 600MS w/ out any errors + - Contention is fully on the DB + - Bottleneck is the DB (distribute systems so they run independently + + + +- 16 databases run end to end +- GSMA - 500 TPS +- What is the optimal design? + +### Contentions + +1. System handler contention + - Where the system can be scaled +1. If there are arch changes that we need to make we can explore this + - Consistency for each DFSP + - Threading of info flows - open question + +1. Sku'ed results of single DB for all DFSPs +1. Challenge is where get to with additional HW + - What are the limits of the application design +1. Financial transfers (in and out of the system) + - Audit systems + - Settlement activity + - Grouped into DB solves some issues + - Confluent feedback + +1. Shared DB issues, multiple DBs + +1. Application design level issues + +1. Seen situations where we ran a bunch of simulators/sandboxes + - Need to rely on tracers and scans once this gets in productions + - Miguel states we disable tracing for now + +### Known Issues + +1. Load CPU resources on boxes (node waiting around) - reoptimize code +2. Processing times increase over time + +## Optimization + 1. Distributed monolithic - PRISM - getting rid of redundant reads + 2. Combine the handlers - Prepare+Position & Fulfil+Position + +### What are we trying to fix? + 1. Can we scale the system? + 2. What does this cost to do this? (scale unit cost) + 3. Need to understand - how to do this from a small and large scale + 3. Optimized the resources + 4. 2.5 sprints + 5. Need to scale horizontal + 6. Add audit and repeatability - + +### Attendees: + +- Don, Joran (newly hired perf expert) - Coil +- Sam, Miguel, Roman, Valentine, Warren, Bryan, Rajiv - ModusBox +- Pedro - Crosslake +- Rhys, Nakul Mishra - Confluent +- Miller - Gates Foundation +- In-person: Lewis (CL), Rob (MB), Roland (Sybrin), Greg (Sybrin), Megan (V), Simeon (V), Kim (CL) diff --git a/legacy/discussions/pisp.md b/legacy/discussions/pisp.md new file mode 100644 index 000000000..d517d6f10 --- /dev/null +++ b/legacy/discussions/pisp.md @@ -0,0 +1,21 @@ +# PISP (3rd party payment initiation) + +## Goal: + +Updated Mojaloop specification documents, and POC implementation of a PISP + + +## Action Items: + +- Revisit /authorizaitons resource: [Michael] and raise with CCB +- Identity provider research and follow-up: [Matt de Haast] +- Share all sequence diagrams: [JJ] +- Outline proposal at high level including new API calls - Unassigned +- Mapping account information (info about accounts for PISP) - [Lewis] + +## Links: + +- [London Meeting Notes](./pisp_meeting_march_2020.md) +- [WIP Separate Docs Repo with sequence diagrams](https://github.com/jgeewax/mojaloop-pisp) +- [End to End Sequence Diagram](https://plantuml-server.kkeisuke.app/svg/xLhhRnkv4V--VmKX571iI8eaEx4Z875aoyu9Tt44hz8WWFg1sgMaFQz87ScreXRvtpl3nxuaEx7H5bVW0kJXvN1cE9pvpODvhpILEbkbWKvqoiXu58w9bfIhEPDa9MAMJlcBJ2LyGJuo6Iqfr-IM_P4nfOaMP4otv2DI7GOqqaAImPQf9ILKaSj1i0RUIPIiSLF3i1wirmrSXB_th8PCtZC90eVNuVZG40wxLRfma-XeQPR2wihWjz2o9ZNET0j7GOwECHaurhrTGbOXl724n-vmZOiblOVpmVh5-r2is6R99BD4bnS15veH0IS0rIRBH96r56kXQ4fYmHI1PIB1T8ba10svW6zWmi5uH82tCWTh1oXOaSrIa5mvu9fmefUCg6Z9LeniaZGbdB4Ozw_e7IDw8ppFVj0z9AEveSzl4fH9UA8Ju1MJsPPGSzDD4edrrb3-aQ7oagcru8eXN_oAH47l6UnoohqSVnEB9C8lCqOoPOz1LSIafd1GC2fGIZGAcko7WiV04RwhfTXmD5IQSDOEHXg9gLBP2WKigUu7hNU4WkMYJ6cuF4be1imv69dgH72aZwYK2T2BJ1DXRUwf3nI9sNqICMHZt2FETC9G8JXbQbbWI9H323I0suxP77IAQxSeinHsKmxIrap2VeYnHPP0C06n2XWie4S5Rz-IOQ8YTAmjUVisk1oqta7yz4Ta8x8qXlFUMVCwcLF-jswdWrzAJeeUdDoZAs7emU_Mks6txwBrMNmWCeVTbbNb0znJejj1p2fYO1sbV07Zet6jDB3ZseJa7TkUJ_b8muV1-wjKEG6uAOGzIRIqPePhhL30fXT7Hn-k9kIb2H6cZeuE2xr24eGj8xVNwVN9w01kVC4qcT7e3W-p5LbPJpX628TuL639U2GOj50_exP5aygfaHc8jYj4hHczKsIEm5WwueuDGz2rGpxzsYGBOyaoIpXF0IomOUAYY2Y3bWPR-87EyU2EYqrWvE1F2jq8dGvilW9VxyCFS1M880547q16dC8-gWpS454BzBaKgy0TqpiaUU2AIbxob2jwzWsLvJrwGnUxDtJS7nevzeRC1Urd1zW_F7Otz6DLGoH6xhTC0uxS5-W1iGz2LXObZ3YRIio6iFyBI0LrtKSC4S0EmI5rbFRj6l3u4Ry1pH_onT9HftooB6kPw_149pK-WL0GRfLcAq34jP1QJNdEcbF0l7tySq2w7FGd01M57Pf49ekbFaV8izo_CjK4qS0dnx3BakvBkZO92F16BS6WKux-Zy3gqe_X1yf1MaqW6kg0LGcqK82xRyZ8H1IP2RqqB6131lVY_BhleWEbkp1prOPTk2WlsEeYk35SVRnALqqvFdb6BsAsI0KsyCOfev1HgRehRQgXDWQkByOGmUj6_t48abeCLgiRvWeMj2LBxZ6HaHLJYYwOjNyg17YRpIb0BJY3R9-A3MRc0wI6ofF7LCPGF_vEWNhjzmVZJo40XpaGAY2uApWL-MKo6R_ijhi177lqQTmAHIOZrhTLXVis1Cg4cu3fU_i4_me8_6hiyXp5ZJvfdCN79_CttRWLTqxFMYUTqzFMMU_rSQiNTKvEpqvVpwFvwqRJyZ0N2PiiI_T9wkqe7a6eLXRAYvFj6dT1cJeQX8vNdGPhaNd29DALOhJH95NokLfRlQsBDVBLx-PVtqkQofgc3bRsgng9rJfbtsuWKdSMhU14AksM6zQxQaSnP2ajg2RqBg6D2ittGj_cVzU8fQHRfwxQSF2G3UbAP5nxkRTNbrUZlryrAejL2-VV6X269Q6DA9EIyMYBIv_3OQCYfkIOJbQ99LJ6dCf467FU3cx2wwlRCcTN4GjpvF7WwmEh_X2Ndsx2pn-1gA81XdTng-G-iJMzFohxjawa2Iea0ipej3gzLlVLfDVhTq_xlRFscxDNhKwt3uSsE_uHV2zL327YLWXAC5j_ED0p6Qht7m4qwEQ6lQSawfuHlKSdgBS72yaOGYyPBr4pgBgHFeTUQEpkeL0dfXU3l41D_rGaTyFF7w04kXPpUpzNzlGga3jOG6_Kj9oniI4sM3LBjmMK-YxE7kG6Vp1WZ1cJHsaMCrNKTpKSj1OsM0rPCi7QmpEgeQsh1n_4smiFjqOT6sMdKU-OdNMYdq7OadOEdb_DmIwzUUlupQpNEddJdRNEkgUiTK8xnxtESNmoxvxisVn_1V5_8VnV2FyaX2TFXlWdONWDlQ7LSDXdCSOCH_8H5rQoEsZtpDPf3Aq3bIoVIjdMfsYJV45Th3srBIh3AjRY6rOTfb4tIiCFIrY7W_85zCn2tc57q0w-i5BrZdsEW-LIYrSQTpK39N8OZYZl1_IGVEOn12hYjgtqfO2KerIz0GzcX-JMYd3ZACtaQeUCl63jHPlC6LE7NhHll8hkmIRRkWsBgT_-PFf8osTJw4ZPurFRuxIA0PrXZxE0fCtQTWXQICK43dlsuVNvOK1JJMw4w_NuWVR2XjYKcGi960G-AHh2jYUvJfnHpLJEkwOLaQUqikxbvimEwB1LfSenCHjSKtTk5DiZT9BdvReH_1srfxok_Cu1m_wra1lCv3-OoUuhAIeNjJEBnWdfbclS6D4KYePiaMwRq9D5D0FcPXQon3aWpfAmQmueEJeQVvuS7H7sBM9hRGUTXJBKswPDBZ8DKOGH3a4Yjm6TuG3Lze6WfMotsrKtxFg9Ht5Er00gGB0OHD6JHsH-r3YvFlV__hHi0dqRMcq8EZYIguMA2ieVPihDQKepQtSiWrdOo99iNHzhEpUoedmLwSzYYiAz6wezTQMenFAt7BXeutkQ9Z7LhC9iojri3UVNKApzqq2EUhalb8wEdbz-selwNsbNlkYVIXVMz1-0PbMsFIX4TulmoetX9Cd0eCyp5bHn4uYHvP7_Rbhpuwh7vvT-eFMOc18oU2CN3n8c8AHYwTmy4KI2Gscs0bT57uQb0ydyk4jW-eWW8ULF0owuLbio1x1XSYqJRlnvjRjdPuu67Gy18cXnM5oetIwc_Gy7eX_wXrLkJddFBdSKyp3WqWBSbPyVcOZ3oH6aZh4KCpe3kFezKte7dFqECm_Vm4S0BjsSSYY2uPpADsSp1ZU07dl7J6PsdgaOub8zFBgF5GzTbqH_udZFpAO5bDHTb_1iDSDNA-m4bKPNg7HoVdsHt3FktvfCJBHnokkc_kxDRPwb-D36gvAWFO3BC7wCRV34Vy-xuDA0jES7fFcppepoEpCiLVa8jcgV8F-yeLoRrq_VnLRrADSwWPZ39_lSLyp7CHct2SuXZLH4-0LSx99HI5mGBzvcPRRcKR1mDsSXZZKR68D2DiITK0skayY27LmoP3C0VsFpmc0gYo9mFJHYyLZkVD5C4inCD0v0vThZIQcE6LLAeF95KwL4PAg7ANUfn4EPlUhpwaLyOOW6xZnVyGR5joPHK5qmsIHmFUsg_6gPyVXRxGyhZOT75iRdj11_vje3Id2TxTRJVxvYPCftgf5AhL5r438QJhbnPpHmOlwlnjpNnG_cn3pU3PJcFhx_gUOhfh1vncF05Kno1JrSi1SXRPVauhPTFEHCbXYsQ6RphBtAyFy-r3995NZHBV3tU_WZMwN_1W00.svg) +- [Initial PISP Design Doc, v5](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/January%202020%20OSS%20Community%20Session/%5BEXTERNAL%5D%20Mojaloop_%20PISP%20Credit%20Transactions(3).pdf) diff --git a/legacy/discussions/versioning_draft_proposal.md b/legacy/discussions/versioning_draft_proposal.md new file mode 100644 index 000000000..790dd4452 --- /dev/null +++ b/legacy/discussions/versioning_draft_proposal.md @@ -0,0 +1,281 @@ +--- +Authors: Lewis Daly, Matthew De Haast, Samuel Kummary +Proposal Name: Mojaloop Versioning Proposal +Solution Proposal Status: Draft +Created: 26-Feb-2020 +Last Updated: 17-Mar-2020 +Approved/Rejected Date: N/A +--- + +# Mojaloop Versioning, A Proposal + +_Note: This document is a living draft of a proposal for versioning within Mojaloop. Once the proposal is ready, it will be submitted to the CCB for approval._ + +## Overview + +The aim is to produce a proposal that keeps the versioning Scheme simple to use and clear regarding compatibility issues. However, it needs to include all the details needed for a Mojaloop ecosystem as well. + +Goal: +Propose a standard for a new 'Mojaloop Version', which embodies: +1. Helm: Individual Service Versions, Monitoring Component Versions +2. API Versions: FSPIOP API, Hub Operations / Admin API, Settlement API +3. Internal Schema Versions: Database Schema and Internal Messaging Versions + +## Versioning Strategies/Background (Literature Review) + +How do current systems handle versioning? Give a brief overview of the current space. +* Most best practices follow semantic versioning for APIs, this will be covered more in [#1198](https://github.com/mojaloop/project/issues/1198) + +### Demonstrates zero-downtime deployment approaches with Kubernetes [5] + +Key observations: +* in order to support rollbacks, the services must be both forward and backwards compatible. +consecutive app versions must be schema compatible +* 'Never deploy any breaking schema changes', separate into multiple deployments instead + +For example, start with a PERSON table: +``` +PK ID + NAME + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +And we want to break this down (normalize) into 2 tables, PERSON and ADDRESS: + +``` +#person +PK ID + NAME + +#address +PK ID +FK PERSON_ID + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +If this change were made in one migration, 2 different versions of our application won't be compatible. Instead, the schema changes must be broken down: +1. Create ADDRESS table + * App use the PERSON table data as previously + * Trigger a copy of data to the ADDRESS table +2. The ADDRESS now becomes the 'source of truth' + * App now uses the ADDRESS table data + * Trigger a copy of new added to address to the PERSON table +3. Stop copying data +4. Remove extra columns from PERSON table + +This means for any one change of the database schema, multiple application versions will need to be created, and multiple deployments must be made in succession for this change to be made. +* [5] also notes how simple Kubernetes makes deploying such a change + * rolling upgrade deployments + * Tip: make sure your health endpoint waits for the migrations to finish! +* Q: so how do we make big changes that touch both the database schema and the API? + * this seems really hard, and would need a lot of coordination + * If we don't design it correctly, it could mean that a single schema change could require all DFSPs to be on board + * This is why I think the API version and Service version should be unrelated. We should be able to + deploy a new version of a service (which runs a migration), and supports an old API version + + +### Using a schema registry for Kafka Messages [6] + +* [6] suggests some approaches, such as using a schema registry for kafka messages, such as [Apache Arvo](https://docs.confluent.io/current/schema-registry/index.html) +* This adds a certain level of 'strictness' to the messages we produce, and will help enforce versioning +* Adds a separate 'schema registry' component, which ensures messages conform to a given schema. This doesn't really + help enforce versioning, and leaves the work up to us still, but does give more guarantees about the message formats. + +### Backwards and Forwards Compatibility [3], [4] + +* "The Robustness principle states that you should be “liberal in what you accept and conservative in what you send +”. In terms of APIs this implies a certain tolerance in consuming services." [3] +* Backwards Compatibility vs Backwards Incompatibility [4]: + * Generally, additions are considered backwards compatible + * Removing or changing names is backwards incompatible + * It's more something to assess on a case-by-case basis, but [Google's API Design Doc](https://cloud.google.com/apis/design/compatibility) helps lay out the cases. + +## Mojaloop Ecosystem +When discussing versioning we need to be clear that we are versioning interfaces for various parties. + +# Proposal +The following section will outline the versioning proposal. + +## A “Mojaloop Version” +A Mojaloop Version **x.y**.z can be defined that can encompass the versions of all the three APIs included (detailed below). +In the version **x.y**.z, ‘x’ indicates the Major version and ‘y’ a minor version, similar to the Mojaloop FSPIOP API versioning standards; ‘z’ represents the ‘hotfix’ version or a version released with the same major, minor version x.y but to keep things simple, there is a need to bundle all the components included in the Mojaloop ecosystem indicating what all items are included there. + +In effect we may say Mojaloop version **x.y** includes +1. Mojaloop FSPIOP API + * Maintained by the CCB (Change Control Board) + * Uses x.y format + * Currently version v1.0, v1.1 and v2.0 are in the pipeline +2. Settlement API + * Maintained by the CCB + * To use x.y format + * Currently version v1.1 and v2.0 is in the pipeline +3. Admin / Operations API + * Maintained by the CCB + * To use x.y format + * Can use version v1.0 +4. Helm + * Maintained by the Design Authority + * Uses x.y.z format + * PI (Program Increment) + Sprint based versioning. + > *Note:* _PI + Sprint based versioning_ make sense in the context of the current Mojaloop Program Increments, but will need to be revised at a later date. + * Bundles compatible versions of individual services together +5. Internal Schemas + * Maintained by the Design Authority + * DB Schema x.y + * Internal messaging Schema (Kafka) x.y + +| **Mojaloop** | x.y | | | +|---|---|---|--- +| | Owner/Maintainer | Format | Meaning | +| **APIs** | | | | +| - FSPIOP API | CCB | *x.y* | Major.Minor | +| - Settlement API | CCB | *x.y* | Major.Minor | +| - Admin/Operations API | CCB | *x.y* | Major.Minor | +| Helm | Design Authority | *x.y.z* | PI.Sprint.Increment | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *x.y* | Major.Minor | +| - Internal Messaging | Design Authority | *x.y* | Major.Minor | + + + +For example: Mojaloop 1.0 includes +1. APIs + * FSPIOP API v1.0 + * Settlements API v1.1 + * Admin API v1.0 +2. Helm v9.1.0 + * Individual services' versions + * Monitoring components versions +3. Internal Schemas + * DB Schema v1.0 + * Internal messaging version v1.0 + +| **Mojaloop** | v1.0 | | | +|---|---|---|--- +| | Owner/Maintainer | Version | +| **APIs** | | | | +| - FSPIOP API | CCB | *1.0* | +| - Settlement API | CCB | *1.1* | +| - Admin/Operations API | CCB | *1.0* | +| Helm | Design Authority | *9.1.0* | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *1.0* | +| - Internal Messaging | Design Authority | *1.0* | + +### Advantages + +1. The advantage of this strategy is primarily simplicity. A given version say - Mojaloop v1.0 can just be used in + discussions which then refers to specific versions of the three APIs - FSPIOP, Settlements, Admin APIs, along with the Helm version that is a bundle of the individual services which are compatible with each other and can be deployed together. +Along with these, the Schema versions for the DB and Internal messaging to communicate whether any changes have been made to these or not since the previously released version. +2. The other advantage, obviously, is that it caters for everyone who may be interested in differing levels of details +, whether high level or detailed. Because of the nature of the major and minor versions, it should be easy for Users and adopters to understand compatibility issues as well. + +### Compatibility +As described in [section 3.3 of the API Definition v1.0](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning), whether or not a version is backwards compatible is + indicated by the **Major** version. All versions with the same major version must be compatible while those having different major versions, will most likely not be compatible. + +_Important Note: Hub operators will likely need to support multiple versions of the FSPIOP API at the same time, in order to cater for different participants as they can't all be expected to upgrade at the same time._ + +## Breaking down the “Mojaloop Version” +This section aims to break down the above proposed mojaloop version into its constituent parts, and provide support for the above proposed versioning strategy + +### APIs + +The [Mojaloop Spec](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning) already outlines many of the decisions made around versioning APIs. + +In terms of common best practices, there are many approaches for requesting different versions, including adding in a + version in the url, but let's not worry about this because the spec already lays this out for us, using the HTML vendor extension: [3.3.4.1 Http Accept Header](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3341-http-accept-header) + +As for version negotiation, the spec also states that in the event of an unsupported version being requested by a + client, a HTTP status 406 can be returned, along with an error message which describes the supported versions. [3.3.4.3 Non-Acceptable Version Requested by Client](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3343-non-acceptable-version-requested-by-client) + +Another best practice around versioning is specifying to what level clients may request specific apis. +* In a development environment, many APIs will allow specificy up to the BUGFIX version, i.e. vX.X.X +* In production however, this is limited to Major versions only, e.g. v1, v2 +* e.g. The Google API Platform supports only major versions, not minor and patch versions +* Given the new features that may become available with v1.1 of the Mojaloop API, we might want to allow participants + to specify MAJOR and MINOR versions, i.e. vX.X. This practice should be avoided however, since minor versions should be backwards compatible + +Participants using the same MAJOR version of the API should be able to interact. Participants on different MAJOR +versions are not able to interact. For example, a participant on API v1.1 can send transfers to another participant on v1.0, but not to a different participant on v2.0. + +### Helm +This section deals with how Mojaloop services interact within a given deployment. Here, we attempt to propose questions such as "should an instance of central-ledger:v10.0.1 be able to talk to ml-api-adapter:v10.1.0? How about ml-api-adapter:v11.0.0?"? or "how do we make sure both central-ledger:v10.0.1 and central-ledger:v10.1.0 talk to the database at the same time?" + +There are two places where this happens: +1. Where services interact with saved state - MySQL Percona Databases +2. Where services interact with each other - Apache Kakfa and (some) internal APIs + +This implies we need to version: +* the database schema +* messages within Apache kafka + * need to make sure the right services can appropriately read the right messages. E.g. Can mojaloop/ml-api-adapter:v10 +.1.0 publish messages to kafka that mojaloop/central-ledger:v10.0.1 can understand? + * Q: If we decide to make breaking changes to the message format, how can we ensure that messages in the kafka streams + don't get picked up by the wong services? + +### Internal Schemas + +#### Database + +todo: anything to be said here? + +#### Kafka/Messaging +Currently, we use the lime protocol for our kafka message formats: https://limeprotocol.org/ + +Also refer to the mojaloop/central-services-stream readme for more information about the message format. + +The lime protocol provides for a type, field, which supports MIME type declarations. So we could potentially handle messages in a manner similar to the API above (e.g. application/vnd.specific+json). Versioning messages in this manner means that consumers reading these messages would need to be backwards and fowards compatible (consecutive message versions must be schema compatible). +* Q. does it make sense to put the version in the Kafka topic? + * One example, ml-api-adapter publishes messages to the prepare topic + * If we add versioning to this, ml-api-adapter:v10.0.0 publishes messages to a prepare_v10.0 topic, and a new instance + of the ml-api-adapter:v10.1.0 will publish to the prepare_v10.1 topic. + * subscribers can subscribe to whichever prepare topic they want, or both, depending on their own tolerance to such + messages + * This may have some serious performance side effects +* Another potential option would be to allow for a message 'adapter' in the deployment. Say the ml-api-adapter:v10.1.0 is producing messages to a prepare_v10.1 topic, and there is no corresponding central-ledger in the deployment to read such messages, we could have an adapter, which subscribes to prepare_v10.1, reformats them to be backwards compatible, and publishes them to prepare_v10.0 in the old format. + +Such an approach would allow for incremental schema changes to the messaging format as services are gradually upgraded. + +All in all, I didn't see too much about this subject, so we'll likely need to return later down the line. + +## Version Negotiation +todo: @sam Discuss how to deal with version negotiation strategy + +## Long Term Support +todo: Discuss how long term support fits into the versioning proposal. I don’t think we want to get into too much detail, but more outline what it might look like + +Mention current (lack of) lts support, current PI cadence + +## Appendix A: Definitions + +* **service**: Mojaloop follows a microservices oriented approach, where a large application is broken down into smaller + micro services. In this instance, Service refers to a containerized application running as part of a Mojaloop deployment. At the moment, this takes the form of a Docker container running inside of a Kubernetes cluster. e.g. mojaloop/central-ledger is the central-ledger service +* **service version**: The version of the given service. This currently doesn't follow semantic versioning, but may in the + future e.g. mojaloop/central-ledger:v10.0.1. The current approach is described in more detail in the [standards + /Versioning doc](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/versioning.md). +* **helm**: Helm is an application package manager that runs on top of Kubernetes. It may also be referred to as the + "deployment". A single helm deployment runs many different services, and MAY run multiple versions of the same service simultaneously. We also refer to the deployment as it's repo, mojaloop/helm interchangeably. +* **helm version**: A helm version is the version of the packaged helm charts, e.g.mojaloop/helm:v1.1.0 +* **interface**: An interface is the protocol by which a Mojaloop switch interacts with the outside world. This includes + interactions with Participants (DFSPs) who transfer funds through the switch, hub operators running a Mojaloop switch, and admins performing administrative functions. +* **api**: Application Programming Interface - in most cases referring to the FSPIOP-API a.k.a. Open API for FSP + Interoperability defined [here](https://github.com/mojaloop/mojaloop-specification). +* **api version**: The Version of the FSPIOP-API, e.g. FSPIOP-API v1. For the purposes of this document, it refers to the + contract between a Mojaloop Switch and Participants (DFSPs) who implement the FSPIOP-API + +## References + +[1] LTS versioning within nodejs. This is a great example of an LTS strategy, and how to clearly communicate such a strategy. +[2] Semantic Versioning Reference +[3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ +[4] https://cloud.google.com/apis/design/compatibility +[5] Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway +[6] Stackoverflow - Kafka Topic Message Versioning + diff --git a/discussions/workbench.md b/legacy/discussions/workbench.md similarity index 100% rename from discussions/workbench.md rename to legacy/discussions/workbench.md diff --git a/gitbook.Dockerfile b/legacy/gitbook.Dockerfile similarity index 100% rename from gitbook.Dockerfile rename to legacy/gitbook.Dockerfile diff --git a/legacy/glossary.md b/legacy/glossary.md new file mode 100644 index 000000000..f2063b83a --- /dev/null +++ b/legacy/glossary.md @@ -0,0 +1,12 @@ +# Glossary of Terms + +| Term | Definition | Notes | +| --- | --- | --- | +| DFSP | Digital Financial Service Provider | | +| FSP | Financial Service Provider | | +| K8s | Short name for [Kubernetes](https://kubernetes.io/) | Read more here [https://kubernetes.io](https://kubernetes.io) | +| ALS | [Account-Lookup Service](mojaloop-technical-overview/account-lookup-service/README.md) | Refer to [Documentation](mojaloop-technical-overview/account-lookup-service/README.md) | +| CS | Central Services | | +| ALS | Account Lookup Services | | +| QS | Quoting Service | | +| SIM | Simulator | | diff --git a/legacy/hackathon-materials/README.md b/legacy/hackathon-materials/README.md new file mode 100644 index 000000000..99e95c391 --- /dev/null +++ b/legacy/hackathon-materials/README.md @@ -0,0 +1,7 @@ +# Hackathon Materials + +A set of documentation from past hackathons. In the future, we may spin this folder off into it's own fully fledged "Mojaloop Hackathon Guide". For now, it's a place to put reference material. + +Most of this initial material comes from The Include Everyone Mojaloop Hackathon in Kampala, Uganda late 2019. + +If you have additional material you want to add, or changes you want to make, please go ahead and raise a pull request. \ No newline at end of file diff --git a/legacy/hackathon-materials/images/lab_onboarding_01.png b/legacy/hackathon-materials/images/lab_onboarding_01.png new file mode 100644 index 000000000..3ff3c9558 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_01.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_02.png b/legacy/hackathon-materials/images/lab_onboarding_02.png new file mode 100644 index 000000000..9f587dd0b Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_02.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_04.png b/legacy/hackathon-materials/images/lab_onboarding_04.png new file mode 100644 index 000000000..3a048003f Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_04.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_05.png b/legacy/hackathon-materials/images/lab_onboarding_05.png new file mode 100644 index 000000000..7d2b805ff Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_05.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_06.png b/legacy/hackathon-materials/images/lab_onboarding_06.png new file mode 100644 index 000000000..d690a7f36 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_06.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_07.png b/legacy/hackathon-materials/images/lab_onboarding_07.png new file mode 100644 index 000000000..4446f55f1 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_07.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_08.png b/legacy/hackathon-materials/images/lab_onboarding_08.png new file mode 100644 index 000000000..a15a27f21 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_08.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_09.png b/legacy/hackathon-materials/images/lab_onboarding_09.png new file mode 100644 index 000000000..6a8e3e877 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_09.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_10.png b/legacy/hackathon-materials/images/lab_onboarding_10.png new file mode 100644 index 000000000..b699f92fc Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_10.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_11.png b/legacy/hackathon-materials/images/lab_onboarding_11.png new file mode 100644 index 000000000..40af4b86d Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_11.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_12.png b/legacy/hackathon-materials/images/lab_onboarding_12.png new file mode 100644 index 000000000..71fb2e738 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_12.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_13.png b/legacy/hackathon-materials/images/lab_onboarding_13.png new file mode 100644 index 000000000..3acbbd1f9 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_13.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_14.png b/legacy/hackathon-materials/images/lab_onboarding_14.png new file mode 100644 index 000000000..e132b02f6 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_14.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_15.png b/legacy/hackathon-materials/images/lab_onboarding_15.png new file mode 100644 index 000000000..d10967224 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_15.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_16.png b/legacy/hackathon-materials/images/lab_onboarding_16.png new file mode 100644 index 000000000..0b2341a04 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_16.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_17.png b/legacy/hackathon-materials/images/lab_onboarding_17.png new file mode 100644 index 000000000..3cbe498fe Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_17.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_18.png b/legacy/hackathon-materials/images/lab_onboarding_18.png new file mode 100644 index 000000000..9f7f274f3 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_18.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_19.png b/legacy/hackathon-materials/images/lab_onboarding_19.png new file mode 100644 index 000000000..eeaa8b422 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_19.png differ diff --git a/legacy/hackathon-materials/images/lab_onboarding_20.png b/legacy/hackathon-materials/images/lab_onboarding_20.png new file mode 100644 index 000000000..4848b3af4 Binary files /dev/null and b/legacy/hackathon-materials/images/lab_onboarding_20.png differ diff --git a/legacy/hackathon-materials/images/postman_01.png b/legacy/hackathon-materials/images/postman_01.png new file mode 100644 index 000000000..6164d22f3 Binary files /dev/null and b/legacy/hackathon-materials/images/postman_01.png differ diff --git a/legacy/hackathon-materials/images/postman_02.png b/legacy/hackathon-materials/images/postman_02.png new file mode 100644 index 000000000..ffcfa218f Binary files /dev/null and b/legacy/hackathon-materials/images/postman_02.png differ diff --git a/legacy/hackathon-materials/lab_onboarding.md b/legacy/hackathon-materials/lab_onboarding.md new file mode 100644 index 000000000..dd108d77c --- /dev/null +++ b/legacy/hackathon-materials/lab_onboarding.md @@ -0,0 +1,91 @@ +# ModusBox Mojaloop Lab +## Getting started with the Lab + +>***Note:** This document is specific to the ModusBox lab provided for the Include Everyone hackathon, but may generalize well in the future* + + +## 1.0 Obtaining an Access Token + +- 1.1 Go to the public gateway (the link has been removed as this environment is not public). + +- 1.2 Click “Sign Up”, and go through the steps to create a new account + + + + +- 1.3 Click “Sign Up” > follow the dialog box to the sign in page > Enter your details and “Sign In” + +
    + + + +- 1.4 In the top left, select “Applications” + + + + +- 1.5 Select “Default Application” from the list + + + +- 1.6 Navigate to “Production Keys” > set the validity of the key to “-1” > “Generate Keys” + +
    + + +- 1.7 Your access key along with a token will be created. Click “Show keys” + + + +- 1.8 Observe that your access token has been created. You can copy this for later reference + + + +- 1.9 Navigate to APIs in the top left menu + + + +- 1.10 From the list of APIs, select “CentralLedgerApi…” + + + + +- 1.11 You now need to subscribe the DefaultApplication to this api. You can do this in the top right > “Subscribe” + +
    + + + +- 1.12 Navigate to “Api Console”. Your access token should already be pre-filled for you. + + + +- 1.13 Now we can test out the `/health` endpoint of the central-ledger service. Browse down the list of endpoints > “Try it out” > “Execute” + +
    +
    +
    + + + +1.14 You should see a response similar to the following: + + +```json +{ + "status": "OK", + "uptime": 535767.333, + "startTime": "2019-09-17T15:11:37.794Z", + "versionNumber": "7.3.1", + "services": [ + { + "name": "datastore", + "status": "OK" + }, + { + "name": "broker", + "status": "OK" + } + ] +} +``` \ No newline at end of file diff --git a/legacy/hackathon-materials/preread.md b/legacy/hackathon-materials/preread.md new file mode 100644 index 000000000..97bf3d959 --- /dev/null +++ b/legacy/hackathon-materials/preread.md @@ -0,0 +1,67 @@ +# Hackathon Pre-Read: +> Goal: A simple reading and todo list for hackathon participants + +## Compulsory Reading +>Time to complete: 15-30 minutes + +- [Mojaloop Project Website](https://mojaloop.io/ ) + - Basic into the project + - Intro video +- [Mojaloop Documentation](https://mojaloop.io/documentation/) + - Overview + - Onboarding doc [todo: this needs work] + - Repo Details (get a lay of the land from the services) +- [Onboarding to the ModusBox Lab Environment](./lab_onboarding.md) + - Logging in and using the environment + - getting an access token and talking to the Lab from postman/curl + + +## Hackathon Onboarding Checklist +>Time to complete: 15-30 minutes + +### Slack: +> The Mojaloop OSS Community uses Slack for all of its communications and announcements. + + +1. Go to [mojaloop-slack.herokuapp.com](mojaloop-slack.herokuapp.com) > Enter your Email address and press "Join" +2. Follow the steps in the email to set up your Slack account +3. Go [here](https://slack.com/intl/en-gm/downloads/) to download slack for your computer +_Optional: You can also go to the Play Store or App Store and install Slack on your phone as well_ +4. Once Slack is installed, select "Channels" in the left bar and search for the `#this-hackathon-name` channel +_[todo: update this doc and replace `#this-hackathon-name` with a channel name specific for the hackathon]_ + + +### Postman +>Postman is a REST API testing and automation tool which we use to interact with the Lab environment and Mojaloop itself + +1. Go to [Postman Downloads](https://www.getpostman.com/downloads/) to download Postman for your machine +2. Clone or Download the [mojaloop/postman](https://github.com/mojaloop/postman) repository. This contains a number of postman 'Collections' which will help you to interact with Mojaloop and the Lab environment +3. Open Postman, and select "Import" from the top left and navigate to where you cloned the Postman repo + +![postman_01.png](./images/postman_01.png) + +4. Drag and drop all of the `collection.json` files into the dialog, and they will be imported into your environment +![postman_02.png](./images/postman_02.png) + +5. Do the same as above with the files in `./environment`. These files specify the environment variables for the collections +6. Now that the collections and environment are set up, we will use the Collection Runner to run one of the test collections. The Collection Runner will run through a list of HTTP requests inside of a collection, which we use to automate or test different processes. +7. Select "Runner" from the top left (next to import), and select the +_[todo: fill this section in after getting the Lab environment test runner]_ + + +## Extended Reading + +- Mojaloop API Specification + Use Cases. For a better understanding of the API and how the API can be used to implement various interoperable payment use cases + - [Mojaloop API Spec v1.0](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) + - [Mojaloop Use Cases](https://github.com/mojaloop/mojaloop-specification/blob/master/Use%20Cases.pdf) + +- Getting a local Mojaloop Environment up and Running On Kubernetes. For running Mojaloop yourself, either on a local machine, or cloud server + - [Mojaloop Deployment Guide](https://mojaloop.io/documentation/deployment-guide/) + +- Getting started with contributing to Mojaloop: + - [Mojaloop Contributor's Guide](https://mojaloop.io/documentation/contributors-guide/) + - _[todo: Github + Zenhub setup]_ + +- Digging into the code: + - [central-ledger service](https://github.com/mojaloop/central-ledger) + - [ml-api-adpater service](https://github.com/mojaloop/ml-api-adapter) \ No newline at end of file diff --git a/legacy/index.js b/legacy/index.js new file mode 100644 index 000000000..90159aa25 --- /dev/null +++ b/legacy/index.js @@ -0,0 +1,32 @@ +/***** + License + -------------- + Copyright © 2020-2025 Mojaloop Foundation + The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Mojaloop Foundation for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + + * Mojaloop Foundation + - Name Surname + + * Miguel de Barros +*****/ + +const express = require('express') +const app = express() +app.use(express.static(__dirname + '/_book')) + +app.listen(process.env.PORT || 8989) diff --git a/legacy/meeting-notes/ccb-notes.md b/legacy/meeting-notes/ccb-notes.md new file mode 100644 index 000000000..b8c49a9df --- /dev/null +++ b/legacy/meeting-notes/ccb-notes.md @@ -0,0 +1,6 @@ +## CCB meetings: Overview +The Change Control Board meets every two weeks. + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have Change Requests or Solution Proposals to discuss. + +More details can be found here: https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings . \ No newline at end of file diff --git a/legacy/meeting-notes/da-notes.md b/legacy/meeting-notes/da-notes.md new file mode 100644 index 000000000..2e04a1be9 --- /dev/null +++ b/legacy/meeting-notes/da-notes.md @@ -0,0 +1,125 @@ +## DA meetings: Overview +The Design Authority meets every week for a weekly update and has ad-hoc or detailed sessions for Specific topics + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have designs to be reviewed or proposals for changes. + +More details can be found [here](https://github.com/mojaloop/design-authority/issues/42#workspaces/da-issue-log-5cdd507422733779191866e9/board?notFullScreen=false&repos=186592307) + +# DA Meeting - 30 September 2020 +Discussion around the topics mentioned started - the newly implemented "patch" in version 1.1 of the API spec was discussed and the majority of the meeting was spent on how to promote wider adoption of this new pattern. + +Concerns about the implementation and use of the "patch" command was raised, stating that further discussion is required to determine if we are not trying to patch a design flaw with another potential implementation flaw. + +See: https://github.com/mojaloop/design-authority/issues/68 + + +# DA Meeting - 2 September 2020 +First we discussed the topic about the "models" folder from being excluded from the unit test coverage checks. The decision taken was that if the folder contains business logic (which generally should not be the case), it must be refactored and moved out. Once at that "business logic isolated" state, coverage testing for that folder can be ignored. See: https://github.com/mojaloop/design-authority/issues/64 + +We concluded discussions on the separate scheme-adapter for a PISP - see issue on board: https://github.com/mojaloop/design-authority/issues/51 +Please have a look at the draft document at this location: https://github.com/mojaloop/pisp/blob/scratch/api-collision/docs/api-collision.md +The above link has a detailed discussion regarding the latest thinking and some examples of mitigations. +The decision has been taken to block this topic until further development on the PoC has been done, in order for the DA to assess if the designs are still aligned with the recommended approach. + +# DA Meeting - 26 August 2020 +We discussed https://github.com/mojaloop/design-authority/issues/51 further on our DA Meeting on 26/08/2020. + +Some of the key points were noted: + +In order to take advantage of Typescript, and to help speed up development, the PISP workstream has gone ahead and separated out the thirdparty-scheme-adapter already. + +One of the challenges identified with the "multi-scheme-adapter" approach was for cases where there are shared resources between the APIs, such as GET /parties/{type}/{id}. + +Our decision to break the Thirdparty API into it's own API (and not extend the FSPIOP-API) was predicated on the idea that "not all participants will want thirdparty functions", and therefore shouldn't have to worry about them. As a part of the decision to keep a separate Thirdparty API, we decided that some resources would be duplicated between the two. + +This could lead to problems down the line, where callbacks to some resources might not be able to reach their desired destination: for example if a DFSP needs to listen for PUT /parties/{type}/{id} callbacks for both the FSPIOP API and the Thirdparty API, it may not be possible for DFSPs to route such callbacks to the right place. + +Lewis Daly will spend more time working on some diagrams and design documents, and come back to the DA shortly + +# DA Meeting (Ad-Hoc) - 24 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/65 +The Ad-Hoc meeting was conducted with a wider issue being addressed relating to recommendations required to be taken to the CCB for consideration to change/enhance the API spec. + +Many valid points were raised and discussed and Michael and Adrian suggested some collaboration on this platform to consolidate the ideas put forward in order to formulate a recommendation to the CCB. + +# DA Meeting - 19 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/61 +The group agreed that there needs to be a balance between the need to eliminate reconciliation and liquidity management of (Payer) FSPs by not holding/reserving funds for longer than necessary. In addition, It was proposed to use 'grace time period' before timing out transfers to compensate for differences in clocks. It was also suggested that for risky transactions, the final notification in the form of a PATCH call that was introduced with FSPIOP API v1.1 can be used to mitigate risk to the Payee FSPs. + +One point made was that after the timeout period (plus the grace period to account for clock difference), a transfer status cannot be changed - it is either finalized or it isn't, but it cannot be changed. For example, if a timeout period (expressed as a time in future and not duration) is 10 seconds, then a Payer FSP (or Switch), may add a grace period of 1second and after waiting for 11seconds can query the downstream entity to find the transfer's status; At this point, if a transfer is finalized (Committed or Aborted), then the Payer FSP can take action accordingly; however if it is in an intermediate state, then the transfer has to be timed-out since the time-out period is done. + +The group agreed on the need to revisit the topic of implementing 'telescopic timeouts', which is not currently supported in favor of end-to-end encryption of (most) messages. + +# DA Meeting - 12 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/63 +The DA discussed the topic of where and how to create and work on issue tickets. With over 50 repositories, it makes sense to create a ticket in the repo where it originated and keep working on it there until it is resolved. The Product Owner and Scrum Master would have context and should replicate a ticket in the Design Autority Repo with a link to the originating ticket. Please have a look at the DA Board for the decisions made here: https://github.com/mojaloop/design-authority#workspaces/da-issue-log-5cdd507422733779191866e9/board?repos=186592307 + +# DA Meeting - 5 August 2020 +The topic for discussion was: https://github.com/mojaloop/project/issues/852 +The "HSM Integration Approach" was touched on a few times, and the workgroup taking care of the design and implementation, tabled this for discussion at this week's DA meeting to answer a few questions arising from the last PI-Planning session where progress on this was again presented. + +As we have not completed the discussion, an ad-hoc DA meeting has been arranged for this Friday with a sub-section of the DA Members. The reason for that was because there were a few specific questions we did not have time to go into detail for, which will be clarified with the individuals who raised those questions. Please drop me a note if you would like to participate in that meeting. + +# DA Meeting - 29 July 2020 +Issue discussed: https://github.com/mojaloop/design-authority/issues/60 +Claudio noted three observations regarding usage of best practices in the Mojaloop Core codebase. One of the issues has an active issue and will be used for tracking it; the other two will be followed up as separate stories/bugs as well (standards). Claudio will provide examples and in some cases sample snippets that can be used. + +Istvan and Michael discussed the usage of a unique ID for lookup requests and proposed to have a follow-up meeting the upcoming week for those interested. The current trace headers (optional) usage for traceability (APM) was brought up as a solution, which after the DA review can be proposed to the CCB (if accepted by the DA). + +# DA Meeting - 22 July 2020 +Canceled as a result of the PI-11 Mojaloop Convening taking place + +# DA Meeting - 15 July 2020 +Sam walked through some of the high-level changes being introduced with Helm v10.4.0 release and various sections from the release notes: https://github.com/mojaloop/helm/releases/tag/v10.4.0 +Please have a look on the DA Topic board: https://github.com/mojaloop/design-authority/issues/56 + +Neal and Michael discussed the issue of shared DB, code between central-settlement and central-ledger; they’re going to continue with the current work on Continuous Gross Settlement but after the convening will get the inputs from the Perf/Arch PoC (Event sourcing / CQRS) and then align. https://github.com/mojaloop/design-authority/issues/58 + +# DA Meeting - 8 July 2020 +The TIPS team did a presentation of the design and implementation of a **Rules Engine** satisfying their requirements of interpretation in the **Settlements Portion**, to extend fees levied as part of a transfer. The implementation allows for rules to be interpreted at any stage during a transaction. A formal presentation will be made at the convening during the week of the 20th July 2020 after which more informed decisions as to the adaption of this implementation into the Core OSS codebase can be considered as a generic approach to implementation of a rules engine. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/53 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting - 1 July 2020 +As part of the "Versioning" workstream, a "zero down-time deployment proposal" PoC is being conducted and feedback from that project has been presented in the form of a problem statement, solution and a demo. The team currently working on that is Lewis Daly, Mat de Haast and Sam Kummary. The feedback was well received and as this work is ongoing, the DA will follow up with any action items to come out of the upcoming presentation for this workstream at the PI 11 Meeting. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/54 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 29 June 2020 +KNEX Discussion - continued. The KNEX discussion extended into talking about the possible use of third-party tools to assist in the generation of queries to help migration efforts. This has no direct bearing on the use of KNEX itself and after exploring a bit deeper, it was decided that there was no compelling reason to continue further investigation into the use of KNEX itself, but to keep an open mind and look out for alternative solutions out there as and when they are introduced. Those libraries will be measured against the current implementation to ensure we deploy the right tools for the right purpose. This issue is now closed. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 25 June 2020 +KNEX Discussion - initiated +Conversations have been started, highlighting the problem statement of difficulty in generating or creating migration scripts when database changes occur, as well as the scenario of having to perform these upgrades on a database which is online at the time. +With this context in place, continued design sessions have been scheduled to determine if KNEX would be capable of handling the above scenario and if there are alternate libraries or tools out there to replace or supplement the current implementation, which may help alleviate this difficult task. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + + +# DA Meeting - 24 June 2020 +Discussion today started with: Deprecation of Helm2 support - Issue #52, where it was agreed that migration to Helm3 should continue. Documentation to assist in the use of tools available to help in the migration should be provided. Find the link to this document at https://github.com/mojaloop/design-authority/issues/52 + +The topic of having a design approach of implementing a generic rules-based system was discussed with some specific reference first, to a requirement of having the capability to interrogate completed or in-flight transactions (either in the transfer stage or even as early in the quoting stage) in order to apply "interchange fees" for that transaction, depending on the transaction type, as interpreted by certain rules. +Various design decisions are going to be discussed around this topic as the requirement is the facility to attach rules at various points of the transaction path. +The current implementation of a Rules Engine in the TIPS project was discussed and a request to demonstrate the capabilities of that solution in order for the DA to see if it was generic anough to incorporate into the core Switch will be made in a follow-up discussion. +Please track the progression of the design decisions surrounding this issue on the board at https://github.com/mojaloop/design-authority/issues/53 + + +# DA Meeting - 17 June 2020 +Topic under discussion was: Understand and Define Mojaloop Roles for PISP, x-network, etc. use cases +The DA is happy for workstreams to go ahead and split out new APIs and Role definitions (e.g. Thirdparty API, CNP API etc.) +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/44 for a detailed problem statement and subsequent decision. + +# DA Meeting - 10 June 2020 +This week, the DA discussed: Discuss the PISP Simulator: https://github.com/mojaloop/design-authority/issues/46 +The decision was made that for the time being, the PISP workstream will work on it's own branch in the sdk-scheme-adapter, and such a division/abstraction of the sdk-scheme-adapter will be revisited at a later date (see #51) + +# DA Meeting - 3 June 2020 +We continued the discussion started last week regarding the separate API for PISP and decided to go with option 4: maximum API Separation, with common swagger/open api files for definition and data model reuse: +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/47 for a detailed problem statement and subsequent decision. + +# DA Meeting - 27 May 2020 +Consensus relating to the issue raised and discussed some time ago, as queried by Adrian, was reached amongst the attendees. The outcome is that the Switch development will not be restrictive and prescriptive but as far as recommendation for new contributions and modules are concerned, it will be preferred if those could be done in TypeScript. + +A new discussion topic was tabled: https://github.com/mojaloop/design-authority/issues/47 seeking to answer the question of whether to have a separate API for PISP, or simply extend the existing Open API. A position statement was prepared and added as a comment. All attendees were brought up to speed with the decision to be made and Issue-#47 will be the topic for the next DA meeting. + +Another, PISP related topic was tabled and will be scheduled for another DA meeting: https://github.com/mojaloop/design-authority/issues/48 - Answer the question of how to manage notifications so that a PISP can be registered as an interested party for notification of the success of a transfer + diff --git a/legacy/meeting-notes/readme.md b/legacy/meeting-notes/readme.md new file mode 100644 index 000000000..3051b0cf9 --- /dev/null +++ b/legacy/meeting-notes/readme.md @@ -0,0 +1,5 @@ +# Mojaloop OSS meeting Groups + +- Change Control Board +- Design Authority +- Scrum-of-scrum calls diff --git a/legacy/meeting-notes/scrum-of-scrum-notes.md b/legacy/meeting-notes/scrum-of-scrum-notes.md new file mode 100644 index 000000000..648d833d3 --- /dev/null +++ b/legacy/meeting-notes/scrum-of-scrum-notes.md @@ -0,0 +1,154 @@ +# Meeting Notes from Weekly Scrum-of-scrum meetings + +## OSS Scrum or scrum calls Thu **May 7th** 2020 + +1. Coil - Don: + a Performance: 'Big Gap' problem; changes to cs-stream; changed results; putting together a doc with changes for review; Joran's work on concurrent message processing on Kafka topics -> try to test it; seeing 40-50% throughput; + b LPS adapter: Working with Renjith (Applied Payments); putting together a lab / envt for partner teams to use it; Exploring collaboration with GSMA lab +2. Crosslake - Lewis: + a. Performance: Had report out with Confluent with Nakul, engagement wrapping up; Disseminating docs Nakul produced + b. PISP: Design discussions going on along with Implementation + c. Versioning: Figuring scope for ZDD deployments + d. Official launch related issues: DNS issues - worked on and were resolved +3. ModusBox - Sam: + a. Performance: Moving / standardizing Perf changes from PI-9 into master (not all PoCs); Working on goals, strategy for PI10 + b. Core-team: Bulk transfers - getting started by providing support in sdk-scheme-adapter + c. Maintenance (Bug Fixes): + i) Accents in names - Ongoing + ii) Mojaloop simulator on AWS deployments - almost done, working on QA scripts (on 'dev2' - second environment) + d. Testing toolkit: Currently available for testing - all resources in ML FSPIOP API Supported. Reports can be generated. Working on providing Command line options and more portability + e. CCB: Publishing v1.1 Spec this week - API Definition and corresponding Swagger (Open API) +4. Virtual / Mojaloop Foundation - Megan: + a. Launch of Mojaloop Foundation + b. Paula H - Executive Director of the Mojaloop Foundation. +5. Mojaloop Foundation - Simeon: + a. Provide feedback on the Community Survey + b. Hackathon possible in early June time-frame in collaboration with Google + c. Mojaloop Newsletter with interesting items such as ML FSPIOP v1.1 Spec, Helm v10.1.0 release, etc. to be launched next week. + +## OSS Scrum or scrum calls Thu **April 16th** 2020 + +1. Coil: + a. Don C: Perf - preliminary results - got some numbers - got individual handler numbers, to compare with individual handlers - focusing on DB - a thrid of time for one leg spent on perf + b. Don C: HSM: Renjit's team demo'ed the demo for next week - event prep +2. Crosslake: + a. Lewis D: PISP - Sprint planning - iterating designs + b. Lewis D: Hackathons - Discussed a few concepts with Innocent K (HiPiPo) + c. Lewis D: Has access to GSMA lab - will play around + d. Lewis D: Versioning: working on deck for PI10 + e. Kim W: Performance stream overall update - workshop with Confluent + f. Kim W: Performance stream update - Pedro putting together a proposal, presentation +3. Mifos: + a. Ed C: Demo Prep for PI10 meetings +4. Virtual: + a. Megan : Getting ready for the PI10 event and Logistics +5. DA: + a. Nico: Discussing PISP issue which Michael will be the owner of +6. Core team: + a. Sam K: Performance: Preparing Metrics; Doing performance runs to baseline master branches after moving some enhancements to master + b. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing - QA done for current iteration + g. Sam K: Testing toolkit: Improving unit test coverage. Assertions added for various endpoints + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, Reviews in progress +7. Mojaloop Community: + a. Community update by Simeon + +## OSS Scrum or scrum calls Thu **April 9th** 2020 + +1. Coil: + a. Don C: perf testing - Under utilization of resources - more tweaking to be done + b. Don C: HSM integration - demo prep + c. Don C: Legacy adapter - docs update - looking for feedback +2. Crosslake: + a. Kim W: FRMS meeting earlier today - proposals made + b. Kim W: PI10 meetings update, registrations - questions + c. Lewis D: PISP: more planning - working on stories, items, but discussing designs on Oauth, Fido + d. Lewis D: Performance: discussion with Pedro about PoC for arch changes, for Event Sourcing, CQRS, etc + e. Lewis D: Code standards - updated + f. Lewis D: Code quality & Security stream: HSM usage, demo, Security in the OSS community + g. Lewis D: Container scans working - will work with Victor, early benchmarks + h. Lewis D: Finally - versioning update +3. Mifos: + a. Ed C: Work on Payment Hub, integrating with Kafka, ML transactions going through, usiing Elastic Search, for backoffice ops moniring + b. Ed C: Demo Prep for PI10 meetings +4. Core team: + a. Sam K: Performance: Drafting reports, Moving metrics, other enhancements to master branches + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Provide tests and validate Merchant "Request to Pay" use case, standardization on-going + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS done, mTLS being added + h. Sam K: Testing toolkit: Usage guide in progress along with adding Golden path related tests + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, waiting for review + +## OSS Scrum or scrum calls Thu **April 2nd** 2020 + +1. Mifos: + a. Ed C: Team continuing work on Payment Hub EE, Focus on Operational UI , capabilities for DFSP backends, Error event handling framework +2. Coil: + a. Don C: Performance - setup done and got started - on GCP - getting high latency times - need to troubleshoot and will probably get support from other contributors + b. Don C: ATM - OTP - Encryption +3. Crosslake: + a. Kim W: Agenda for PI10 drafted - email should good out soon + b. Kim W: Schedule for PI10: Tue - Fri; 11am - 4pm GMT - Remote / Virtual event + c. Lewis D: Perf meeting later today - architecture deep dive + d. Lewis D: Versioning - In progress + e. Lewis D: Code quality & Security - Overall Security architecture, HSM covered by Coil + f. Lewis D: Mojaloop in a Vagrant box - in progress +4. Core team: + a. Miguel dB: Performance: Wrapping up Perf work - nearing 900 TPS end-to-end; Currently attempting to identify / understand a single unit that needs this perf + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Fixing issues in /authorizations + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum of scrum call Thu **March 26th** 2020 + +1. DA: Nico - Versioning topic discussed by Lewis, Matt, Sam +2. Crosslake: + a. Kim W: Finalizing Agenda - Monday to Friday + b. Kim W: Reach out if you want to present / speak + c. Kim W: Preparing pre-reads + d. Kim W: Fraud & AML workshop: Justus to post summary and notes to GitHub after the workshops + e. Lewis D: Performance workshop / deep-dive possibly Monday + f. Lewis D: PISP Design discussions ongoing + g: Lewis D: Code quality and security stream: i. Docker container security recommendations. ii. GDPR Scope for Mojaloop +3. Mifos: + a. Ed C / Istvan M: Continue creating Lab + b. Ed C / Istvan M: Fineract , new instance of Payment Hub - good progress + c. Ed C / Istvan M: Working on operational monitoring of backend part (back-office debugging, monitoring, etc) +4. Simeon O - Community Manager in attendance +5. Core team: + a. Sam K: Performance: Finalized phase-3 work. Get to immediate goals for logical conclusion - still ongoing - Phase4 roadmap and kickoff + b. Sam K: Community Support: Fixing bugs, providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Metrics being added, event framework added + e. Sam K: Accents in names issue - Discussing issue, designing solution + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress. Usage guide in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum or scrum call Thu **March 19th** 2020 + +1. Coil: + a. Don C: Looking at performance, network hops (avoid dup checks etc) + b. Adrian hB: Renjith & Matt working on translation ISO20022, (to JWEs, etc) - demo by the time we meet on how to use HSM +2. Crosslake: + a. Kim W: Finishing action items from the Mid-PI Workshop, follow-up items + b. Kim W: April Community event is happening but will be a Virtual event. Kim has a planning event and will confirm details: Suggestions welcome + c. Lewis D: Performance - to include Don in other discussions + d. Lewis D: Code quality - GDPR requirements proposal + e: Lewis D: Versioning - iinitial draft made as PR - will be presented to DA next week +3. Mifos: + a. Ed C, Istvan M: Payment Hub, envt in Azure, + b. Ed C, Istvan M: Transactions now going through + c. Ed C, Istvan M: Next phase: to implement back office screens to see screens for business users + d. Ed C, Istvan M: Workshop with Google on PISP +4. Core team: + a. Sam K: Perf - Combining prepare+position handler and fulfil+position handlers, characterization work ongoing + b. Sam K: Perf - Working on gaining an understanding of how 1 unit of Infrastructure looks like for a Mojaloop deployment + c. Sam K: Transaction requests service standardization: Added event framework, Adding metrics now + d. Sam K: Community Support: Fixing issues, upgrade issues, issue for allowing accents in names, etc,. diff --git a/mojaloop-background.md b/legacy/mojaloop-background.md similarity index 100% rename from mojaloop-background.md rename to legacy/mojaloop-background.md diff --git a/mojaloop-background/README.md b/legacy/mojaloop-background/README.md similarity index 100% rename from mojaloop-background/README.md rename to legacy/mojaloop-background/README.md diff --git a/mojaloop-background/core-scenarios.md b/legacy/mojaloop-background/core-scenarios.md similarity index 99% rename from mojaloop-background/core-scenarios.md rename to legacy/mojaloop-background/core-scenarios.md index 856716930..47fddaa2b 100644 --- a/mojaloop-background/core-scenarios.md +++ b/legacy/mojaloop-background/core-scenarios.md @@ -18,7 +18,7 @@ Mojaloop addresses a number of scenarios in which this software might help the p Hamim is working on his farm in Northern Uganda when he receives an urgent phone call from his brother, Kani. Kani is low on money and will not get paid until next week. Kani has no money to pay for food for his family and asks Hamim to help him out. Hamim and Kani have no means of transportation and it would take several days for Hamim to get to his Kani's home in Southern Uganda. While they both have mobile flip phones, they use different financial service providers. Kani tells Hamim that he needs 5,000 shillings to buy food until he gets paid next week for his job working in a local field. Hamin agrees to send Kani the money. -```text +``` *** Mojaloop technology does its job *** ``` @@ -28,7 +28,7 @@ Because Hamim has sent money to Kani before he has his information on his phone. Venya is waiting in line to buy plantains at her local market. She is corralling her elder child with one hand and has her baby in a sling. She often comes to this seller and she knows he has a good price. She also knows that even though she carries no money and he is not on her financial network, she can buy from him. As she approaches the head of the line she juggles the children and pulls out a simple flip phone. She tells him 1.5 kilograms and he tells her the price, which she agrees to. -```text +``` *** Mojaloop technology does its job *** ``` @@ -38,7 +38,7 @@ Because she's been here before the merchant already has her information on his p Nikisha is the accountant for one of the largest manufacturing companies in Johannesburg and employs over 250 workers. Their company uses a time and attendance system to track the number of hours that each employee works along with their hourly rate and employee ID. On a weekly basis Nikisha gets an update on her bulk payment system that shows all the employees, their user ID along and amount to be paid. Since the companies employees all have different financial service providers this system makes it really easy for Nikisha to confirm and distribute their pay with a couple of clicks. The company has a high turnover rate so new employees who get their first paycheck are automatically prompted to open an account as long as they provided a valid mobile number when they started. As Nikisha gets ready to send out this week's payments she opens up a bulk payment report. -```text +``` *** Mojaloop technology does its job *** ``` @@ -48,7 +48,7 @@ The bulk report for payments comes up by date range and, since Nikisha does this Salem works as an auditor for a large bank in Kampala, Uganda. His job is to monitor, manage and reduce risk for the company. order to do so each new user ID in the system is assigned a default tier level which means they can only transfer a small number and amount of funds in and out of the system over specific periods of time. As users acquire greater balances in their accounts and hold their accounts for longer periods of time their tier levels improve. Tier levels are handled automatically by the system so Salem does not need to worry about assigning or changing these levels under normal circumstances. Part of Salem's job as an auditor is to review the daily reports to ensure that everyone's funds are safe and secure and he kicks off his daily report to review the accounts. -```text +``` *** Mojaloop technology does its job *** ``` @@ -58,7 +58,7 @@ This morning when Salem reviews these reports he notices that one specific user Salem works as an auditor for a large bank in Kampala, Uganda. His job is to monitor and stop any fraudulent activity for the company. While the company has a set of rules that might flag individuals for Salem to investigate, he also has the authority to screen any user ID for fraudulent activities at any time. Each time Salem performs a fraud check on a user ID, the system records the date of the last check along with any comments that Salem might have made. This makes it very easy for Salem to search for IDs that might have never been checked for fraud or have not been checked in a very long time. Salem has been monitoring one particular ID that seems to have had an increased amount of incoming funds deposited into their account on a daily basis. Today he does a search of the user ID to investigate further. -```text +``` *** Mojaloop technology does its job *** ``` @@ -68,7 +68,7 @@ When the user ID is retrieved Salem is able to see the customer's name, birthdat Tadeo just bought his first mobile flip phone for him and his family to share. He is happy that he finally has a phone that he can use in emergencies, but he can also finally keep his money secure by opening up a bank account. Tadeo has never had a bank account since he lives in a very remote part of Africa with no personal means of transportation. Tadeo and his family have to rely on bartering or cash to buy any goods they need at the market. Although Tadeo is not proficient in reading, he is able to easily use his phone to setup and account for him and his family by following a couple of easy to read menu steps. -```text +``` *** Mojaloop technology does its job *** ``` @@ -78,13 +78,13 @@ Tadeo was able to use his phone to create an mWallet account using his National Jahari has a flip phone that all the family uses and he has setup different user numbers for each family member. Jahari is at the local market and needs to buy some meat for his family. Before he does, he wants to make sure he has enough funds in his account to purchase the goods and still have enough left over to set aside for future medical expenses and education. Jahari is happy that his money is secure and he is able to check his account balance anytime he needs to by simply entering his secure pin on his phone. Once he confirms his balance he will buy some goat and cow meat at the market. -```text +``` *** Mojaloop technology does its job *** ``` After Jahari has entered his pin on his phone he is able to see his account balance. He is also able to see any of his recent transactions as well as any fees that were associated with these transactions. After confirming his available funds he picks out his meat and brings it up to the merchant for payment. The merchant does a lot of business in this market and has a point of sales device. This is very helpful for Jahari and his family since they only have one phone and many times his wife or his children go to the market and do not have the phone with them. Jahari can generate a one time pin for family to use in these cases. The merchant is able to enter the purchase amount on the POS device and Jahari or any of his family members securely enters their user number and reviews the transaction. He confirms that the amount on the POS machine matches what the merchant verbally told him and he enters his one-time pin to approve the transaction. -```text +``` *** Mojaloop technology does its job *** ``` diff --git a/mojaloop-background/level-one-principles.md b/legacy/mojaloop-background/level-one-principles.md similarity index 100% rename from mojaloop-background/level-one-principles.md rename to legacy/mojaloop-background/level-one-principles.md diff --git a/mojaloop-publications.md b/legacy/mojaloop-publications.md similarity index 100% rename from mojaloop-publications.md rename to legacy/mojaloop-publications.md diff --git a/legacy/mojaloop-roadmap.md b/legacy/mojaloop-roadmap.md new file mode 100644 index 000000000..3ab842449 --- /dev/null +++ b/legacy/mojaloop-roadmap.md @@ -0,0 +1,75 @@ +# Mojaloop Roadmap + +The roadmap is built around the concept of three pillars, which are: + +1. Make it easier to deploy Mojaloop +2. Make sure deployments have every opportunity to make themselves profitable +3. Connect to other payments services in the ecosystem + +These three pillars are underpinned by a fourth workstream, that of continuous development of a quality +product. +* Make Adoption Easier +* Achieve Scale +* Connect to Other Systems +* Quality Product + +## Make Adoption Easier +(Promote a better understanding of Mojaloop) +* Develop “Mojaloop Journey” – a manual to take adopters from concept to live service +* Better portals for both Hub and Payment Manager + * Develop Configuration support + * Showcase extensions using Biz Ops Framework + * Bootcamp +* Easier Deployment + * Make IaC more accessible + * Pre-configs for different deployment types + * On-Prem + * Azure +* Better Showcase +* Capitalise on MiniLoop + * Demos etc as part of deployment + * Testing support (Quality Product) +* Fintech sandbox +* Integration with FRMS, demonstrate with a live deployment (PoC) + +## Achieve Scale +Drive scale through: +* Merchant Payments + * QR-based Push + * Merchant acquiring + * Mobile wallets, MFIs +* PISP + * MRTP + * Bill Payments + * Aggregators + * Salaries etc + * Support for bulk through PISP interface +* Bulk + * Partially complete – needs completing for older CBS + +## Connect to Other Systems +* Cross-Border + * Next Generation Settlement (part of TigerBeetle, vNext, “Quality Product”) + * Integrated Forex services & API + * Payments addressing solutions for international transactions +* Integrations into emerging DPG ecosystem + * Payments addressing using MOSIP national ID + * Integration with MOSIP, Mifos, OpenG2P + * Oracle/ALS development + * Opportunity for thought leadership on the integration of DPGs +* Working within international ecosystems +* Wholesale CBDC +* Compatibility with Interledger developments +* Development of an Interledger Cross Network Provider (CNP) + +## Maintain and Develop the Ecosystem +Continuous: +* Ongoing maintenance +* Adopt MiniLoop for testing etc + +In order to support the scale we want to achieve under Pillar 2: +* Continue the development of vNext, work towards a migration +* Adoption of TigerBeetle for vNext + +In order to support the interconnections we want to achieve under Pillar 3: +* Accelerate TigerBeetle, vNext for agile deployment of next gen settlement engine diff --git a/legacy/mojaloop-technical-overview/README.md b/legacy/mojaloop-technical-overview/README.md new file mode 100644 index 000000000..8aadf39ae --- /dev/null +++ b/legacy/mojaloop-technical-overview/README.md @@ -0,0 +1,16 @@ +# Mojaloop Technical Overview + +## Mojaloop Services + +The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers (DFSPs) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. The following diagrams shows the Mojaloop interconnects between DFSPs and the Mojaloop Hub (schema implementation example) for a Peer-to-Peer (P2P) Transfer: + +Mojaloop addresses these issues in several key ways: +* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. +* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. + +![Mojaloop End-to-end Architecture Flow PI5](./assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg) + +The Mojaloop Hub is the primary container and reference we use to describe the Mojaloop ecosystem which is split in to the following domains: +* Mojaloop Open Source Services - Core Mojaloop Open Source Software (OSS) that has been supported by the Bill & Melinda Gates Foundation in partnership with the Open Source Community. +* Mojaloop Hub - Overall Mojaloop reference (and customizable) implementation for Hub Operators is based on the above OSS solution. diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/README.md b/legacy/mojaloop-technical-overview/account-lookup-service/README.md new file mode 100644 index 000000000..f0ff84f03 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/README.md @@ -0,0 +1,123 @@ +# Account Lookup Service + +The **Account Lookup Service** (**ALS**) _(refer to section `6.2.1.2`)_ as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) implements the following use-cases: + +* Participant Look-up +* Party Look-up +* Manage Participants Registry information + * Adding Participant Registry information + * Deleting Participant Registry information + +Use-cases that have been implemented over and above for Hub Operational use: +* Admin Operations + * Manage Oracle End-point Routing information + * Manage Switch End-point Routing information + +## 1. Design Considerations + +### 1.1. Account Lookup Service (ALS) +The ALS design provides a generic Central-Service component as part of the core Mojaloop. The purpose of this component is to provide routing and alignment to the Mojaloop API Specification. This component will support multiple Look-up registries (Oracles). This ALS will provide an Admin API to configure routing/config for each of the Oracles similiar to the Central-Service API for the End-point configuration for DFSP routing by the Notification-Handler (ML-API-Adapter Component). The ALS will in all intense purpose be a switch with a persistence store for the storage/management of the routing rules/config. + +#### 1.1.1. Assumptions + +* The ALS design will only cater for a single switch for the time being. +* Support for multiple switches will utilise the same DNS resolution mechanism that is being developed for the Cross Border/Network design. + +#### 1.1.2. Routing + +The routing configuration will be based on the following: +* PartyIdType - See section `7.5.6` of the Mojaloop Specification +* Currency - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, however `isDefault` indicator must be set to `true` if the `Currency` is not provided. +* isDefault - Indicator that a specific Oracle is the default provider for a specific PartyIdType. Note that there can be many default Oracles, but there can only be a single Oracle default for a specific PartyIdType. The default Oracle for a specific PartyIdType will only be selected if the originating request does not include a Currency filter. + + +### 1.2. ALS Oracle +The ALS Oracle be implemented as either a **Service** or **Adapter** (semantic dependant on use - Mediation = Adapter, Service = Implementation) will provide a look-up registry component with similar functionality of the `/participants` Mojaloop API resources. It has however loosely based on the ML API specification as it's interface implements a sync pattern which reduces the correlation/persistence requirements of the Async Callback pattern implemented directly by the ML API Spec. This will provide all ALS Oracle Services/Adapters with a standard interface which will be mediated by the ALS based on its routing configuration. +This component (or back-end systems) will also be responsible for the persistence & defaulting of the Participant details. + +## 2. Participant Lookup Design + +### 2.1. Architecture overview +![Architecture Flow Account-Lookup for Participants](./assets/diagrams/architecture/arch-flow-account-lookup-participants.svg) + +_Note: The Participant Lookup use-case similarly applies to for a Payee Initiated use-case such as transactionRequests. The difference being that the Payee is the initiation in the above diagram._ + +### 2.2. Sequence diagrams + +#### 2.2.1. GET Participants + +- [Sequence Diagram for GET Participants](als-get-participants.md) + +#### 2.2.2. POST Participants + +- [Sequence Diagram for POST Participants](als-post-participants.md) + +#### 2.2.3. POST Participants (Batch) + +- [Sequence Diagram for POST Participants (Batch)](als-post-participants-batch.md) + +#### 2.2.4. DEL Participants + +- [Sequence Diagram for DEL Participants](als-del-participants.md) + +## 3. Party Lookup Design + +### 3.1. Architecture overview +![Architecture Flow Account-Lookup for Parties](./assets/diagrams/architecture/arch-flow-account-lookup-parties.svg) + +### 3.2. Sequence diagram + +#### 3.2.1. GET Parties + +- [Sequence Diagram for GET Parties](als-get-parties.md) + +## 4. ALS Admin Design + +### 4.1. Architecture overview +![Architecture Flow Account-Lookup for Admin Get Oracles](./assets/diagrams/architecture/arch-flow-account-lookup-admin.svg) + +### 4.2. Sequence diagram + +#### 4.2.1 GET Oracles + +- [Sequence Diagram for GET Oracles](als-admin-get-oracles.md) + +#### 4.2.2 POST Oracle + +- [Sequence Diagram for POST Oracle](als-admin-post-oracles.md) + +#### 4.2.3 PUT Oracle + +- [Sequence Diagram for PUT Oracle](als-admin-put-oracles.md) + +#### 4.2.4 DELETE Oracle + +- [Sequence Diagram for DELETE Oracle](als-admin-del-oracles.md) + +#### 4.2.5 DELETE Endpoint Cache + +- [Sequence Diagram for DELETE Endpoint Cache](als-del-endpoint.md) + +## 5. Database Design + +### 5.1. ALS Database Schema + +#### Notes +- `partyIdType` - Values are currently seeded as per section _`7.5.6`_ [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}). +- `currency` - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, and must provide a "default" config if no Currency is either provided or provide a default if the Currency is provided, but only the "default" End-point config exists. +- `endPointType` - Type identifier for the end-point (e.g. `URL`) which provides flexibility for future transport support. +- `migration*` - Meta-data tables used by Knex Framework engine. +- A `centralSwitchEndpoint` must be associated to the `OracleEndpoint` by the Admin API upon insertion of a new `OracleEndpoint` record. If the `centralSwitchEndpoint` is not provided as part of the API Request, then it must be defaulted. + +![Acount Lookup Service ERD](./assets/entities/AccountLookupService-schema.png) + +* [Acount Lookup Service DBeaver ERD](./assets/entities/AccountLookupDB-schema-DBeaver.erd) +* [Acount Lookup Service MySQL Workbench Export](./assets/entities/AccountLookup-ddl-MySQLWorkbench.sql) + +## 6. ALS Oracle Design + +Detail design for the Oracle is out of scope for this document. The Oracle design and implementation is specific to each Oracle's requirements. + +### 6.1. API Specification + +Refer to **ALS Oracle API** in the [API Specifications](../../api/README.md#als-oracle-api) section. diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-del-oracles.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-del-oracles.md new file mode 100644 index 000000000..b02a6c44d --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-del-oracles.md @@ -0,0 +1,7 @@ +# DELETE Oracles + +Design for the Deletion of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-del-oracle-7.3.4.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-del-oracle-7.3.4.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-get-oracles.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-get-oracles.md new file mode 100644 index 000000000..63ff4cefe --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-get-oracles.md @@ -0,0 +1,7 @@ +# GET Oracles + +Design for getting a list of all Oracle Endpoints by the Hub Operator with the option of querying but currency and/or type. + +## Sequence Diagram + +![seq-acct-lookup-admin-get-oracle-7.3.1](./assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-post-oracles.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-post-oracles.md new file mode 100644 index 000000000..9f2b210e0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-post-oracles.md @@ -0,0 +1,7 @@ +# POST Oracles + +Design for the creation of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-post-oracle-7.3.2.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-put-oracles.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-put-oracles.md new file mode 100644 index 000000000..46446c731 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-admin-put-oracles.md @@ -0,0 +1,7 @@ +# PUT Oracles + +Design for the Update of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-put-oracle-7.3.3.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-del-endpoint.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-del-endpoint.md new file mode 100644 index 000000000..5f8ed7d52 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-del-endpoint.md @@ -0,0 +1,7 @@ +# DELETE Endpoint Cache + +Design for the disabling of an Oracle by the Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-del-endpoint-cache-7.3.0](./assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-del-participants.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-del-participants.md new file mode 100644 index 000000000..7e2621e74 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-del-participants.md @@ -0,0 +1,11 @@ +# DEL Participants + +Design for the deletion of a Participant by a DFSP. + +## Notes + +- Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. ~ This has been addressed in the design by insuring that the Party currently belongs to the FSPs requesting the deletion of the record. Any other validations are out of scope for the Switch and should be addressed at the schema level. + +## Sequence Diagram + +![seq-acct-lookup-del-participants-7.1.2.svg](./assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-get-participants.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-get-participants.md new file mode 100644 index 000000000..8844c37c2 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-get-participants.md @@ -0,0 +1,7 @@ +# GET Participants + +Design for the retrieval of a Participant by a DFSP. + +## Sequence Diagram + +![seq-acct-lookup-get-participants-7.1.0.svg](./assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-get-parties.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-get-parties.md new file mode 100644 index 000000000..4d1b87249 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-get-parties.md @@ -0,0 +1,7 @@ +# GET Parties + +Design for the retrieval of a Party by a DFSP. + +## Sequence Diagram + +![seq-acct-lookup-get-parties-7.2.0.svg](./assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md new file mode 100644 index 000000000..0bad74bc8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md @@ -0,0 +1,14 @@ +# Sequence Diagram for POST Participants (Batch) + +Design for the creation of a Participant by a DFSP via a batch request. + +## Notes + +- Operation only supports requests which contain: + - All Participant's FSPs match the FSPIOP-Source + - All Participant's will be of the same Currency as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) +- Duplicate POST Requests with matching TYPE and optional CURRENCY will be considered an __update__ operation. The existing record must be completely __replaced__ in its entirety. + +## Sequence Diagram + +![seq-acct-lookup-post-participants-batch-7.1.1.svg](./assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants.md b/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants.md new file mode 100644 index 000000000..088171ce8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/als-post-participants.md @@ -0,0 +1,7 @@ +# POST Participant + +Design for the creation of a Participant by a DFSP via a request. + +## Sequence Diagram + +![seq-acct-lookup-post-participants-7.1.3.svg](./assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg) diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/.gitkeep b/legacy/mojaloop-technical-overview/account-lookup-service/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg new file mode 100644 index 000000000..d46ffa284 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service Admin
    (ALS)
    Account Lookup Service Adm...
    HUB
    Backend



    HUB...
    Account Lookup Admin
    Account Lookup Admin
    HUB Operator
    HUB Operator
    A1. Request Oracle Endpoints 
    GET /oracles
    A1. Requ...
    A1.3. Return List of Oracles
    A1.3. Re...
    ALS
    DB
    ALS...
    Key
    Key
    A1.2. Lookup All Oracle Registry Service End-points 
    API
    Internal Use-Only
    API...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg new file mode 100644 index 000000000..2bb5d7029 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Participants Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A5. Retrieve Participant End-points GET /participants/<participantId>/endpoints
    A1. Request Participant Lookup
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A3. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A4. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A7. User Lookup
    PUT /participants/<idType>/<id>
    A7. User Lookup <br>PUT /participants/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A6. Retrieve Participant End-point Data
    A6. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    A2. Lookup Oracle Adapter/Service End-points based on <idType>
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg new file mode 100644 index 000000000..0dd8b76e6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Parties Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    A10. Get 
    receiver 
    details
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A7. Retrieve PayeeFSP Participant End-pointsGET /participants/<participantId>/endpoints
    A1. Request Party Lookup
    GET /parties/<idType>/<id>
    [Not supported by viewer]
    A4. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A9. User Lookup
    GET /parties/<idType>/<id>
    A9. User Lookup <br>GET /parties/<idType>/<id>
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A5. Alt
    [Not supported by viewer]

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A5. Alt
    A5. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A5. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A11. User Lookup
    PUT /parties/<idType>/<id>
    A11. User Lookup <br>PUT /parties/<idType>/<id>
    A14. User Lookup
    PUT /parties/<idType>/<id>
    A14. User Lookup <br>PUT /parties/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A8. Retrieve Participant End-point Data
    A8. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    A3. Lookup Oracle Registry ServiceEnd-points based on <idType>A12. Retrieve PayerFSP Participant End-pointsGET /participants/<participantId>/endpointsA6. Retrieve PayeeFSP Data for ValidationGET /participants/<participantId>(retrieve FSP Data)
    A13. Retrieve Participant End-point Data
    <font style="font-size: 13px">A13. Retrieve Participant End-point Data</font>
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml new file mode 100644 index 000000000..3a6a6eecb --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.4 Delete Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "DELETE Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Delete Oracle Endpoint -\nDELETE /oracles/{ID} + activate ALSADM + + ALSADM -> ORC_HANDLER: Delete Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Update existing Oracle Endpoint By ID + hnote over DB #lightyellow + Update isActive = false + end note + alt Delete existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Success + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + alt Delete existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Throws Error (Not Found) + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg new file mode 100644 index 000000000..6cbc84f40 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + 7.3.4 Delete Oracle Endpoint + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + DELETE Oracle Handler + + + + + DELETE Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Delete Oracle Endpoint - + + + DELETE /oracles/{ID} + + + + + 2 + + + Delete Oracle Endpoint + + + + + 3 + + + Update existing Oracle Endpoint By ID + + + + Update isActive = false + + + + + alt + + + [Delete existing Oracle Endpoint (success)] + + + + + 4 + + + Return Success + + + + + 5 + + + Return success response + + + + + 6 + + + Return + + + HTTP Status: + + + 204 + + + + + alt + + + [Delete existing Oracle Endpoint (failure)] + + + + + 7 + + + Throws Error (Not Found) + + + + + 8 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 9 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml new file mode 100644 index 000000000..b800d83f9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.1 Get All Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "Get Oracles Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoints + OPERATOR -> ALSADM: Request to GET all Oracle Endpoints -\nGET /oracles?currency=USD&type=MSISDN + activate ALSADM + + ALSADM -> ORC_HANDLER: Get Oracle Endpoints + activate ORC_HANDLER + ORC_HANDLER -> DB: Get oracle endpoints + activate DB + + alt Get Oracle Endpoints (success) + DB --> ORC_HANDLER: Return Oracle Endpoints + deactivate DB + + deactivate DB + ORC_HANDLER -> ALSADM: Return Oracle Endpoints + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + [ + { + "oracleId": , + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + ] + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 200 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Get Oracle Endpoints (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg new file mode 100644 index 000000000..7447557a3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + 7.3.1 Get All Oracle Endpoints + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + Get Oracles Handler + + + + + Get Oracles Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoints + + + + + 1 + + + Request to GET all Oracle Endpoints - + + + GET /oracles?currency=USD&type=MSISDN + + + + + 2 + + + Get Oracle Endpoints + + + + + 3 + + + Get oracle endpoints + + + + + alt + + + [Get Oracle Endpoints (success)] + + + + + 4 + + + Return Oracle Endpoints + + + + + 5 + + + Return Oracle Endpoints + + + + + Message: + + + { + + + [ + + + { + + + "oracleId": <string>, + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + ] + + + } + + + + + 6 + + + Return + + + HTTP Status: + + + 200 + + + + + alt + + + [Get Oracle Endpoints (failure)] + + + + + 7 + + + Throw Error + + + + + 8 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 9 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml new file mode 100644 index 000000000..083b0fac2 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml @@ -0,0 +1,112 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.2 Create Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "POST Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Create Oracle Endpoint -\nPOST /oracles + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Create Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> ORC_HANDLER: Build Oracle Endpoint Data Object + ORC_HANDLER -> DB: Insert Oracle Endpoint Data Object + activate DB + + alt Create Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 201 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Create Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg new file mode 100644 index 000000000..0638bdb48 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + 7.3.2 Create Oracle Endpoints + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + POST Oracle Handler + + + + + POST Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Create Oracle Endpoint - + + + POST /oracles + + + + + Message: + + + { + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + + + 2 + + + Create Oracle Endpoint + + + + + 3 + + + Build Oracle Endpoint Data Object + + + + + 4 + + + Insert Oracle Endpoint Data Object + + + + + alt + + + [Create Oracle Entry (success)] + + + + + 5 + + + Return success response + + + + + 6 + + + Return success response + + + + + 7 + + + Return + + + HTTP Status: + + + 201 + + + + + alt + + + [Create Oracle Entry (failure)] + + + + + 8 + + + Throw Error + + + + + 9 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 10 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml new file mode 100644 index 000000000..142eae685 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml @@ -0,0 +1,131 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.3 Update Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "PUT Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Update Oracle Endpoint -\nPUT /oracles/{ID} + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Update Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Find existing Oracle Endpoint + alt Find existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Oracle Endpoint Result + deactivate DB + ORC_HANDLER -> ORC_HANDLER: Update Returned Oracle Data Object + ORC_HANDLER -> DB: Update Oracle Data Object + activate DB + alt Update Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Update Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end + end + alt Find existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Returns Empty Object + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg new file mode 100644 index 000000000..98da55c5c --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + 7.3.3 Update Oracle Endpoint + + + + Account Lookup Service + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + PUT Oracle Handler + + + + + PUT Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Update Oracle Endpoint - + + + PUT /oracles/{ID} + + + + + Message: + + + { + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + + + 2 + + + Update Oracle Endpoint + + + + + 3 + + + Find existing Oracle Endpoint + + + + + alt + + + [Find existing Oracle Endpoint (success)] + + + + + 4 + + + Return Oracle Endpoint Result + + + + + 5 + + + Update Returned Oracle Data Object + + + + + 6 + + + Update Oracle Data Object + + + + + alt + + + [Update Oracle Entry (success)] + + + + + 7 + + + Return success response + + + + + 8 + + + Return success response + + + + + 9 + + + Return + + + HTTP Status: + + + 204 + + + + + alt + + + [Update Oracle Entry (failure)] + + + + + 10 + + + Throw Error + + + + + 11 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 12 + + + Return + + + HTTP Status: + + + 502 + + + + + alt + + + [Find existing Oracle Endpoint (failure)] + + + + + 13 + + + Returns Empty Object + + + + + 14 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 15 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml new file mode 100644 index 000000000..3095e7bad --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml @@ -0,0 +1,104 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.0 Delete Endpoint Cache + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS API Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service API" as ALSAPI +control "Delete Endpoint Cache Handler" as DEL_HANDLER +database "Cache" as Cache + +box "Account Lookup Service" #LightYellow +participant ALSAPI +participant DEL_HANDLER +participant Cache +end box + +' start flow + +activate OPERATOR +group Delete Endpoint Cache + OPERATOR -> ALSAPI: Request to DELETE Endpoint Cache - DELETE /endpointcache + activate ALSAPI + activate ALSAPI + + ALSAPI -> DEL_HANDLER: Delete Cache + activate DEL_HANDLER + DEL_HANDLER -> Cache: Stop Cache + activate Cache + + + alt Stop Cache Status (success) + Cache --> DEL_HANDLER: Return status + deactivate Cache + + DEL_HANDLER -> Cache: Initialize Cache + activate Cache + Cache -> DEL_HANDLER: Return Status + deactivate Cache + DEL_HANDLER -> ALSAPI: Return Status + deactivate DEL_HANDLER + ALSAPI --> OPERATOR: Return HTTP Status: 202 + + deactivate ALSAPI + deactivate OPERATOR + end + + alt Validate Status (service failure) + Cache --> DEL_HANDLER: Throw Error + deactivate Cache + DEL_HANDLER -> ALSAPI: Throw Error + deactivate DEL_HANDLER + note left of ALSAPI #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSAPI --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSAPI + deactivate OPERATOR + + + end +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg new file mode 100644 index 000000000..ab60d1d1b --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + 7.3.0 Delete Endpoint Cache + + + + Account Lookup Service + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service API + + + + + Account Lookup Service API + + + + + Delete Endpoint Cache Handler + + + + + Delete Endpoint Cache Handler + + + + + Cache + + + + + Cache + + + + + + + + + Delete Endpoint Cache + + + + + 1 + + + Request to DELETE Endpoint Cache - DELETE /endpointcache + + + + + 2 + + + Delete Cache + + + + + 3 + + + Stop Cache + + + + + alt + + + [Stop Cache Status (success)] + + + + + 4 + + + Return status + + + + + 5 + + + Initialize Cache + + + + + 6 + + + Return Status + + + + + 7 + + + Return Status + + + + + 8 + + + Return + + + HTTP Status: + + + 202 + + + + + alt + + + [Validate Status (service failure)] + + + + + 9 + + + Throw Error + + + + + 10 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 11 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml new file mode 100644 index 000000000..978a1e303 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.2. Delete Participant Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +actor "Payee FSP" as PAYEE_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +entity "ALS Participant Endpoint\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +box "Financial Service Provider" #LightGrey +participant PAYEE_FSP +end box + +' START OF FLOW + +group Get Party Details + PAYER_FSP ->> ALS_API: Request to delete Participant details\nDEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to delete Participant details + + alt oracleEndpoint match found & parties information retrieved + activate ALS_PARTICIPANT_HANDLER + '********************* Retrieve Oracle Routing Information - START ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + '********************* Retrieve Oracle Routing Information - END ************************ + ||| + '********************* Retrieve Switch Routing Information - START ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref + '********************* Retrieve Switch Routing Information - END ************************ + + ||| + + '********************* Validate FSPIOP-Source Participant - START ************************ + group Validate FSPIOP-Source Participant + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request FSPIOP-Source participant information\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return FSPIOP-Source participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return FSPIOP-Source participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate FSPIOP-Source participant\nError code: 320x + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + end group + '********************* Validate Participant - END ************************ + + ||| + + '********************* Request Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Get Participant Information for PayerFSP\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Request Participant Information from Oracle Sequence]] + ||| + end ref + + '********************* Request Oracle Participant Information - END ************************ + + ||| + + '********************* Validate Participant Ownership - START ************************ + ' Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. Is this adequate? + group Validate Participant Ownership + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId matches Participant Information retrieved from Oracle.\nError code: 3100 + end group + '********************* Validate Participant - END ************************ + + ||| + + '********************* Delete Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Delete Oracle Participant Information - END ************************ + ||| + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return delete request result + ALS_API ->> PAYER_FSP: Callback indiciating success:\nPUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + else Validation failure or Oracle was unable process delete request + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + + else Empty list of switchEndpoint results returned + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg new file mode 100644 index 000000000..4612fee5f --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg @@ -0,0 +1,632 @@ + + + + + + + + + + + 7.1.2. Delete Participant Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + Financial Service Provider + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant Endpoint + + + Oracle DAO + + + + + ALS Participant Endpoint + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS Parties + + + FSP DAO + + + + + ALS Parties + + + FSP DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + Payee FSP + + + + + Payee FSP + + + + + + + + Get Party Details + + + + 1 + + + Request to delete Participant details + + + DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to delete Participant details + + + + + alt + + + [oracleEndpoint match found & parties information retrieved] + + + + + 3 + + + Get Oracle Routing Config + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + + + 4 + + + Request FSPIOP-Source participant information + + + Error code: + + + 200x + + + + + 5 + + + GET - /participants/{FSPIOP-Source} + + + Error code: + + + 200x, 310x, 320x + + + + + 6 + + + Return FSPIOP-Source participant information + + + + + 7 + + + Return FSPIOP-Source participant information + + + + + 8 + + + Validate FSPIOP-Source participant + + + Error code: + + + 320x + + + + + 9 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + 10 + + + Get Participant Information for PayerFSP + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Request Participant Information from Oracle Sequence + + + + + + + Validate Participant Ownership + + + + + 11 + + + Validate that PARTICIPANT.fspId matches Participant Information retrieved from Oracle. + + + Error code: + + + 3100 + + + + + 12 + + + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 14 + + + Return result + + + + + 15 + + + Return result + + + + + 16 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x + + + + + 17 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Error code: + + + 200x, 310x, 320x + + + + + 18 + + + List of PayerFSP Participant Callback Endpoints + + + + + 19 + + + List of PayerFSP Participant Callback Endpoints + + + + + 20 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 21 + + + Return delete request result + + + + 22 + + + Callback indiciating success: + + + PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + + [Validation failure or Oracle was unable process delete request] + + + + + 23 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 24 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 25 + + + List of PayerFSP Participant Callback Endpoints + + + + + 26 + + + List of PayerFSP Participant Callback Endpoints + + + + + 27 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 28 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 29 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of switchEndpoint results returned] + + + + + 30 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml new file mode 100644 index 000000000..09be5f1df --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml @@ -0,0 +1,180 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.0. Get Participant Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS Endpoint Type\nConfig DAO" as ALS_TYPE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Participant Endpoint\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_TYPE_ENDPOINT_CONFIG_DAO +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Get Participant's FSP Details + + + PAYER_FSP ->> ALS_API: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to get participant's FSP details + + alt oracleEndpoint match found + group #lightskyblue IMPLEMENTATION: Get Oracle Routing Config Sequence [CACHED] + activate ALS_PARTICIPANT_HANDLER + ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Fetch Oracle Routing information based on\n{TYPE} and {CURRENCY} if provided\nError code: 200x + activate ALS_TYPE_ENDPOINT_CONFIG_DAO + ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Retrieve oracleEndpoint\nError code: 200x + activate ALS_DB + hnote over ALS_DB #lightyellow + oracleEndpoint + endpointType + partyIdType + currency (optional) + end note + ALS_DB --> ALS_TYPE_ENDPOINT_CONFIG_DAO: Return oracleEndpoint result set + deactivate ALS_DB + ALS_TYPE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of **oracleEndpoint** for the Participant + deactivate ALS_TYPE_ENDPOINT_CONFIG_DAO + opt #lightskyblue oracleEndpoint IS NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Error code: 3200 + end + end group + + group #lightskyblue IMPLEMENTATION: Request Participant Information from Oracle Sequence + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return list of Participant information + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return list of Participant information + deactivate ALS_PARTICIPANT_ORACLE_DAO + end group + +' group #lightskyblue IMPLEMENTATION: Get Switch Routing Config Sequence [CACHED] +' note right of ALS_PARTICIPANT_HANDLER #lightgray +' **REFERENCE**: Get Oracle Routing Config Sequence: oracleEndpoint +' end note +' alt #lightskyblue oracleEndpoint IS NOT NULL +' ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Fetch Switch Routing information\nError code: 200x +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Retrieve switchEndpoint\nError code: 200x +' activate ALS_DB +' hnote over ALS_DB #lightyellow +' switchEndpoint +' endpointType +' end note +' ALS_DB -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Return switchEndpoint result set +' deactivate ALS_DB +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_PARTICIPANT_HANDLER: Return **switchEndpoint** +' else +' ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Error code: 2000 +' end alt +' end group + + '********************* Get PayerFSP Participant End-point Information - START ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + else oracleEndpoint IS NULL OR error occurred + + '********************* Get PayerFSP Participant End-point Information - START ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints. \nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else switchEndpoint IS NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + deactivate ALS_API + + deactivate ALS_PARTICIPANT_HANDLER + +end +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg new file mode 100644 index 000000000..74687dae8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg @@ -0,0 +1,558 @@ + + + + + + + + + + + 7.1.0. Get Participant Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Endpoint Type + + + Config DAO + + + + + ALS Endpoint Type + + + Config DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Get Participant's FSP Details + + + + 1 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to get participant's FSP details + + + + + alt + + + [oracleEndpoint match found] + + + + + IMPLEMENTATION: Get Oracle Routing Config Sequence + + + [CACHED] + + + + + 3 + + + Fetch Oracle Routing information based on + + + {TYPE} and {CURRENCY} if provided + + + Error code: + + + 200x + + + + + 4 + + + Retrieve oracleEndpoint + + + Error code: + + + 200x + + + + oracleEndpoint + + + endpointType + + + partyIdType + + + currency (optional) + + + + + 5 + + + Return oracleEndpoint result set + + + + + 6 + + + List of + + + oracleEndpoint + + + for the Participant + + + + + opt + + + [oracleEndpoint IS NULL] + + + + + 7 + + + Error code: + + + 3200 + + + + + IMPLEMENTATION: Request Participant Information from Oracle Sequence + + + + + 8 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 310x, 320x + + + + + 9 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 10 + + + Return list of Participant information + + + + + 11 + + + Return list of Participant information + + + + + 12 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 14 + + + List of PayerFSP Participant Callback Endpoints + + + + + 15 + + + List of PayerFSP Participant Callback Endpoints + + + + + 16 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 17 + + + Return list of Participant information + + + + 18 + + + Callback: PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + + [oracleEndpoint IS NULL OR error occurred] + + + + + 19 + + + Retrieve the Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 20 + + + Retrieve the Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints. + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 21 + + + List of Participant Callback Endpoints + + + + + 22 + + + List of Participant Callback Endpoints + + + + + 23 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 24 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 25 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [switchEndpoint IS NULL] + + + + + 26 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml new file mode 100644 index 000000000..776445cc5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml @@ -0,0 +1,215 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.2.0. Get Party Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +actor "Payee FSP" as PAYEE_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +box "Financial Service Provider" #LightGrey +participant PAYEE_FSP +end box + +' START OF FLOW + +group Get Party Details + PAYER_FSP ->> ALS_API: Request to get parties's FSP details\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to get parties's FSP details + + alt oracleEndpoint match found & parties information retrieved + activate ALS_PARTICIPANT_HANDLER + '********************* Retrieve Oracle Routing Information - START ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + '********************* Retrieve Oracle Routing Information - END ************************ + ||| + '********************* Retrieve Switch Routing Information - START ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref + '********************* Retrieve Switch Routing Information - END ************************ + ||| + group Validate FSPIOP-Source Participant + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request FSPIOP-Source participant information\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return FSPIOP-Source participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return FSPIOP-Source participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate FSPIOP-Source participant\nError code: 320x + end group + ||| + + '********************* Request Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Get Participant Information for PayeeFSP\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Request Participant Information from Oracle Sequence]] + ||| + end ref + + '********************* Request Oracle Participant Information - END ************************ + ||| + '********************* Request Parties Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTIES_FSP_DAO: Request Parties information from FSP.\nError code: 200x + + activate ALS_PARTIES_FSP_DAO + ALS_PARTIES_FSP_DAO ->> PAYEE_FSP: Parties Callback to Destination:\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 310x, 320x + deactivate ALS_PARTIES_FSP_DAO + activate PAYEE_FSP + + PAYEE_FSP ->> ALS_API: Callback with Participant Information:\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 300x, 310x, 320x + deactivate PAYEE_FSP + + ALS_API -> ALS_API: Validate request against\nMojaloop Interface Specification\nError code: 300x, 310x + ALS_API -> ALS_PARTICIPANT_HANDLER: Process Participant Callback Information for PUT + + '********************* Request Parties Information - END ************************ + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return Participant Information to PayerFSP + ALS_API ->> PAYER_FSP: Callback with Parties Information:\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + else Empty list of End-Points returned for either (PayeeFSP or Oracle) config information or Error occurred for PayerFSP + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else Empty list of End-Points returned for PayerFSP config information or Error occurred for PayeeFSP + + '********************* Get PayeeFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayeeFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayeeFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayeeFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayeeFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayeeFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYEE_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else Empty list of switchEndpoint results returned + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg new file mode 100644 index 000000000..7b3342d7b --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg @@ -0,0 +1,699 @@ + + + + + + + + + + + 7.2.0. Get Party Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + Financial Service Provider + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS Parties + + + FSP DAO + + + + + ALS Parties + + + FSP DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + Payee FSP + + + + + Payee FSP + + + + + + + + Get Party Details + + + + 1 + + + Request to get parties's FSP details + + + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to get parties's FSP details + + + + + alt + + + [oracleEndpoint match found & parties information retrieved] + + + + + 3 + + + Get Oracle Routing Config + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + + + 4 + + + Request FSPIOP-Source participant information + + + Error code: + + + 200x + + + + + 5 + + + GET - /participants/{FSPIOP-Source} + + + Error code: + + + 200x, 310x, 320x + + + + + 6 + + + Return FSPIOP-Source participant information + + + + + 7 + + + Return FSPIOP-Source participant information + + + + + 8 + + + Validate FSPIOP-Source participant + + + Error code: + + + 320x + + + + + 9 + + + Get Participant Information for PayeeFSP + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Request Participant Information from Oracle Sequence + + + + + + + 10 + + + Request Parties information from FSP. + + + Error code: + + + 200x + + + + 11 + + + Parties Callback to Destination: + + + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 310x, 320x + + + + 12 + + + Callback with Participant Information: + + + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + 13 + + + Validate request against + + + Mojaloop Interface Specification + + + Error code: + + + 300x, 310x + + + + + 14 + + + Process Participant Callback Information for PUT + + + + + 15 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x + + + + + 16 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Error code: + + + 200x, 310x, 320x + + + + + 17 + + + List of PayerFSP Participant Callback Endpoints + + + + + 18 + + + List of PayerFSP Participant Callback Endpoints + + + + + 19 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT + + + + + 20 + + + Return Participant Information to PayerFSP + + + + 21 + + + Callback with Parties Information: + + + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + + [Empty list of End-Points returned for either (PayeeFSP or Oracle) config information or Error occurred for PayerFSP] + + + + + 22 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 23 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 24 + + + List of PayerFSP Participant Callback Endpoints + + + + + 25 + + + List of PayerFSP Participant Callback Endpoints + + + + + 26 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + + + 27 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 28 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of End-Points returned for PayerFSP config information or Error occurred for PayeeFSP] + + + + + 29 + + + Retrieve the PayeeFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 30 + + + Retrieve the PayeeFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 31 + + + List of PayeeFSP Participant Callback Endpoints + + + + + 32 + + + List of PayeeFSP Participant Callback Endpoints + + + + + 33 + + + Match PayeeFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + + + 34 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 35 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of switchEndpoint results returned] + + + + + 36 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml new file mode 100644 index 000000000..7769e3a8d --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.3 Post Participant Details by Type and ID + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Post Participant's FSP Details + note right of PAYER_FSP #yellow + Headers - postParticipantsByTypeIDHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - postParticipantsByTypeIDMessage: + { + "fspId": "string" + } + end note + PAYER_FSP ->> ALS_API: Request to add participant's FSP details\nPOST - /participants/{Type}/{ID}\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Process create participant's FSP details + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + + '********************* Sort into Participant buckets based on {TYPE} - END ************************ + + alt Validation passed + + + '********************* Fetch Oracle Routing Information - START ************************ + + '********************* Retrieve Oracle Routing Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config based on Type (and optional Currency)\nError code: 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + + '********************* Retrieve Oracle Routing Information - END ************************ + + ||| + +' '********************* Fetch Oracle Routing Information - END ************************ +' +' '********************* Retrieve Switch Routing Information - START ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref +' +' '********************* Retrieve Switch Routing Information - END ************************ +' ||| + + '********************* Validate Participant - START ************************ + group Validate Participant's FSP + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request participant (PARTICIPANT.fspId) information for {Type}\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate participant\nError code: 320x + end group + '********************* Validate Participant - END ************************ + + '********************* Create Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Create participant's FSP details\nPOST - /participants\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Create participant's FSP details\nPOST - /participants\nResponse code: 204 \nError code: 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result of Participant Create request + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result of Participant Create request + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Create Participant Information - END ************************ + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information from ParticipantResult + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID} + + else Validation failure + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg new file mode 100644 index 000000000..07a5a256d --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg @@ -0,0 +1,598 @@ + + + + + + + + + + + 7.1.3 Post Participant Details by Type and ID + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Post Participant's FSP Details + + + + + Headers - postParticipantsByTypeIDHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - postParticipantsByTypeIDMessage: + + + { + + + "fspId": "string" + + + } + + + + 1 + + + Request to add participant's FSP details + + + POST - /participants/{Type}/{ID} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Process create participant's FSP details + + + + + 3 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + alt + + + [Validation passed] + + + + + 4 + + + Get Oracle Routing Config based on Type (and optional Currency) + + + Error code: + + + 300x, 310x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + + + 5 + + + Request participant (PARTICIPANT.fspId) information for {Type} + + + Error code: + + + 200x + + + + + 6 + + + GET - /participants/{PARTICIPANT.fspId} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 7 + + + Return participant information + + + + + 8 + + + Return participant information + + + + + 9 + + + Validate participant + + + Error code: + + + 320x + + + + + 10 + + + Create participant's FSP details + + + POST - /participants + + + Error code: + + + 200x, 310x, 320x + + + + + 11 + + + Create participant's FSP details + + + POST - /participants + + + Response code: + + + 204 + + + Error code: + + + 200x, 310x, 320x + + + + + 12 + + + Return result of Participant Create request + + + + + 13 + + + Return result of Participant Create request + + + + + 14 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 15 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 16 + + + List of PayerFSP Participant Callback Endpoints + + + + + 17 + + + List of PayerFSP Participant Callback Endpoints + + + + + 18 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 19 + + + Return list of Participant information from ParticipantResult + + + + 20 + + + Callback: PUT - /participants/{Type}/{ID} + + + + [Validation failure] + + + + + 21 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 22 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 23 + + + List of PayerFSP Participant Callback Endpoints + + + + + 24 + + + List of PayerFSP Participant Callback Endpoints + + + + + 25 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 26 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 27 + + + Callback: PUT - /participants/{Type}/{ID}/error + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml new file mode 100644 index 000000000..c92838dc9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml @@ -0,0 +1,238 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.1. Post Participant (Batch) Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Post Participant's FSP Details + note right of PAYER_FSP #yellow + Headers - postParticipantsHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - postParticipantsMessage: + { + "requestId": "string", + "partyList": [ + { + "partyIdType": "string", + "partyIdentifier": "string", + "partySubIdOrType": "string", + "fspId": "string" + } + ], + "currency": "string" + } + end note + PAYER_FSP ->> ALS_API: Request to add participant's FSP details\nPOST - /participants\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Process create participant's FSP details + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + '********************* Sort into Participant buckets based on {TYPE} - START ************************ + loop for Participant in ParticipantList + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Group Participant lists into a Map (ParticipantMap) based on {TYPE} + + end loop + + '********************* Sort into Participant buckets based on {TYPE} - END ************************ + + alt Validation passed and the ParticipantMap was created successfully + + loop for keys in ParticipantMap -> TypeKey + + '********************* Fetch Oracle Routing Information - START ************************ + + '********************* Retrieve Oracle Routing Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config based on TypeKey (and optional Currency)\nError code: 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + + '********************* Retrieve Oracle Routing Information - END ************************ + + ||| + +' '********************* Fetch Oracle Routing Information - END ************************ +' +' '********************* Retrieve Switch Routing Information - START ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref +' +' '********************* Retrieve Switch Routing Information - END ************************ +' ||| + + '********************* Validate Participant - START ************************ + group Validate Participant's FSP + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request participant (PARTICIPANT.fspId) information for {TypeKey}\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate participant\nError code: 320x + end group + '********************* Validate Participant - END ************************ + + '********************* Create Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Create participant's FSP details\nPOST - /participants\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Create participant's FSP details\nPOST - /participants\nResponse code: 204 \nError code: 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result of Participant Create request + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result of Participant Create request + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Create Participant Information - END ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Store results in ParticipantResultMap[TypeKey] + + end loop + + loop for keys in ParticipantResultMap -> TypeKey + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Combine ParticipantResultMap[TypeKey] results into ParticipantResult + end loop + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information from ParticipantResult + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{requestId} + + else Validation failure and/or the ParticipantMap was not created successfully + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{requestId}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg new file mode 100644 index 000000000..e3883aba0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg @@ -0,0 +1,674 @@ + + + + + + + + + + + 7.1.1. Post Participant (Batch) Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Post Participant's FSP Details + + + + + Headers - postParticipantsHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - postParticipantsMessage: + + + { + + + "requestId": "string", + + + "partyList": [ + + + { + + + "partyIdType": "string", + + + "partyIdentifier": "string", + + + "partySubIdOrType": "string", + + + "fspId": "string" + + + } + + + ], + + + "currency": "string" + + + } + + + + 1 + + + Request to add participant's FSP details + + + POST - /participants + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Process create participant's FSP details + + + + + loop + + + [for Participant in ParticipantList] + + + + + 3 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + 4 + + + Group Participant lists into a Map (ParticipantMap) based on {TYPE} + + + + + alt + + + [Validation passed and the ParticipantMap was created successfully] + + + + + loop + + + [for keys in ParticipantMap -> TypeKey] + + + + + 5 + + + Get Oracle Routing Config based on TypeKey (and optional Currency) + + + Error code: + + + 300x, 310x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + + + 6 + + + Request participant (PARTICIPANT.fspId) information for {TypeKey} + + + Error code: + + + 200x + + + + + 7 + + + GET - /participants/{PARTICIPANT.fspId} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 8 + + + Return participant information + + + + + 9 + + + Return participant information + + + + + 10 + + + Validate participant + + + Error code: + + + 320x + + + + + 11 + + + Create participant's FSP details + + + POST - /participants + + + Error code: + + + 200x, 310x, 320x + + + + + 12 + + + Create participant's FSP details + + + POST - /participants + + + Response code: + + + 204 + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Return result of Participant Create request + + + + + 14 + + + Return result of Participant Create request + + + + + 15 + + + Store results in ParticipantResultMap[TypeKey] + + + + + loop + + + [for keys in ParticipantResultMap -> TypeKey] + + + + + 16 + + + Combine ParticipantResultMap[TypeKey] results into ParticipantResult + + + + + 17 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 18 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 19 + + + List of PayerFSP Participant Callback Endpoints + + + + + 20 + + + List of PayerFSP Participant Callback Endpoints + + + + + 21 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + + + + 22 + + + Return list of Participant information from ParticipantResult + + + + 23 + + + Callback: PUT - /participants/{requestId} + + + + [Validation failure and/or the ParticipantMap was not created successfully] + + + + + 24 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 25 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 26 + + + List of PayerFSP Participant Callback Endpoints + + + + + 27 + + + List of PayerFSP Participant Callback Endpoints + + + + + 28 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + + + + 29 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 30 + + + Callback: PUT - /participants/{requestId}/error + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..e538b6351 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql @@ -0,0 +1,195 @@ +-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64) +-- +-- Host: 127.0.0.1 Database: account_lookup +-- ------------------------------------------------------ +-- Server version 8.0.12 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `currency` +-- + +LOCK TABLES `currency` WRITE; +/*!40000 ALTER TABLE `currency` DISABLE KEYS */; +INSERT INTO `currency` VALUES ('AED','UAE dirham',1,'2019-03-28 09:07:47'),('AFA','Afghanistan afghani (obsolete)',1,'2019-03-28 09:07:47'),('AFN','Afghanistan afghani',1,'2019-03-28 09:07:47'),('ALL','Albanian lek',1,'2019-03-28 09:07:47'),('AMD','Armenian dram',1,'2019-03-28 09:07:47'),('ANG','Netherlands Antillian guilder',1,'2019-03-28 09:07:47'),('AOA','Angolan kwanza',1,'2019-03-28 09:07:47'),('AOR','Angolan kwanza reajustado',1,'2019-03-28 09:07:47'),('ARS','Argentine peso',1,'2019-03-28 09:07:47'),('AUD','Australian dollar',1,'2019-03-28 09:07:47'),('AWG','Aruban guilder',1,'2019-03-28 09:07:47'),('AZN','Azerbaijanian new manat',1,'2019-03-28 09:07:47'),('BAM','Bosnia-Herzegovina convertible mark',1,'2019-03-28 09:07:47'),('BBD','Barbados dollar',1,'2019-03-28 09:07:47'),('BDT','Bangladeshi taka',1,'2019-03-28 09:07:47'),('BGN','Bulgarian lev',1,'2019-03-28 09:07:47'),('BHD','Bahraini dinar',1,'2019-03-28 09:07:47'),('BIF','Burundi franc',1,'2019-03-28 09:07:47'),('BMD','Bermudian dollar',1,'2019-03-28 09:07:47'),('BND','Brunei dollar',1,'2019-03-28 09:07:47'),('BOB','Bolivian boliviano',1,'2019-03-28 09:07:47'),('BRL','Brazilian real',1,'2019-03-28 09:07:47'),('BSD','Bahamian dollar',1,'2019-03-28 09:07:47'),('BTN','Bhutan ngultrum',1,'2019-03-28 09:07:47'),('BWP','Botswana pula',1,'2019-03-28 09:07:47'),('BYN','Belarusian ruble',1,'2019-03-28 09:07:47'),('BZD','Belize dollar',1,'2019-03-28 09:07:47'),('CAD','Canadian dollar',1,'2019-03-28 09:07:47'),('CDF','Congolese franc',1,'2019-03-28 09:07:47'),('CHF','Swiss franc',1,'2019-03-28 09:07:47'),('CLP','Chilean peso',1,'2019-03-28 09:07:47'),('CNY','Chinese yuan renminbi',1,'2019-03-28 09:07:47'),('COP','Colombian peso',1,'2019-03-28 09:07:47'),('CRC','Costa Rican colon',1,'2019-03-28 09:07:47'),('CUC','Cuban convertible peso',1,'2019-03-28 09:07:47'),('CUP','Cuban peso',1,'2019-03-28 09:07:47'),('CVE','Cape Verde escudo',1,'2019-03-28 09:07:47'),('CZK','Czech koruna',1,'2019-03-28 09:07:47'),('DJF','Djibouti franc',1,'2019-03-28 09:07:47'),('DKK','Danish krone',1,'2019-03-28 09:07:47'),('DOP','Dominican peso',1,'2019-03-28 09:07:47'),('DZD','Algerian dinar',1,'2019-03-28 09:07:47'),('EEK','Estonian kroon',1,'2019-03-28 09:07:47'),('EGP','Egyptian pound',1,'2019-03-28 09:07:47'),('ERN','Eritrean nakfa',1,'2019-03-28 09:07:47'),('ETB','Ethiopian birr',1,'2019-03-28 09:07:47'),('EUR','EU euro',1,'2019-03-28 09:07:47'),('FJD','Fiji dollar',1,'2019-03-28 09:07:47'),('FKP','Falkland Islands pound',1,'2019-03-28 09:07:47'),('GBP','British pound',1,'2019-03-28 09:07:47'),('GEL','Georgian lari',1,'2019-03-28 09:07:47'),('GGP','Guernsey pound',1,'2019-03-28 09:07:47'),('GHS','Ghanaian new cedi',1,'2019-03-28 09:07:47'),('GIP','Gibraltar pound',1,'2019-03-28 09:07:47'),('GMD','Gambian dalasi',1,'2019-03-28 09:07:47'),('GNF','Guinean franc',1,'2019-03-28 09:07:47'),('GTQ','Guatemalan quetzal',1,'2019-03-28 09:07:47'),('GYD','Guyana dollar',1,'2019-03-28 09:07:47'),('HKD','Hong Kong SAR dollar',1,'2019-03-28 09:07:47'),('HNL','Honduran lempira',1,'2019-03-28 09:07:47'),('HRK','Croatian kuna',1,'2019-03-28 09:07:47'),('HTG','Haitian gourde',1,'2019-03-28 09:07:47'),('HUF','Hungarian forint',1,'2019-03-28 09:07:47'),('IDR','Indonesian rupiah',1,'2019-03-28 09:07:47'),('ILS','Israeli new shekel',1,'2019-03-28 09:07:47'),('IMP','Isle of Man pound',1,'2019-03-28 09:07:47'),('INR','Indian rupee',1,'2019-03-28 09:07:47'),('IQD','Iraqi dinar',1,'2019-03-28 09:07:47'),('IRR','Iranian rial',1,'2019-03-28 09:07:47'),('ISK','Icelandic krona',1,'2019-03-28 09:07:47'),('JEP','Jersey pound',1,'2019-03-28 09:07:47'),('JMD','Jamaican dollar',1,'2019-03-28 09:07:47'),('JOD','Jordanian dinar',1,'2019-03-28 09:07:47'),('JPY','Japanese yen',1,'2019-03-28 09:07:47'),('KES','Kenyan shilling',1,'2019-03-28 09:07:47'),('KGS','Kyrgyz som',1,'2019-03-28 09:07:47'),('KHR','Cambodian riel',1,'2019-03-28 09:07:47'),('KMF','Comoros franc',1,'2019-03-28 09:07:47'),('KPW','North Korean won',1,'2019-03-28 09:07:47'),('KRW','South Korean won',1,'2019-03-28 09:07:47'),('KWD','Kuwaiti dinar',1,'2019-03-28 09:07:47'),('KYD','Cayman Islands dollar',1,'2019-03-28 09:07:47'),('KZT','Kazakh tenge',1,'2019-03-28 09:07:47'),('LAK','Lao kip',1,'2019-03-28 09:07:47'),('LBP','Lebanese pound',1,'2019-03-28 09:07:47'),('LKR','Sri Lanka rupee',1,'2019-03-28 09:07:47'),('LRD','Liberian dollar',1,'2019-03-28 09:07:47'),('LSL','Lesotho loti',1,'2019-03-28 09:07:47'),('LTL','Lithuanian litas',1,'2019-03-28 09:07:47'),('LVL','Latvian lats',1,'2019-03-28 09:07:47'),('LYD','Libyan dinar',1,'2019-03-28 09:07:47'),('MAD','Moroccan dirham',1,'2019-03-28 09:07:47'),('MDL','Moldovan leu',1,'2019-03-28 09:07:47'),('MGA','Malagasy ariary',1,'2019-03-28 09:07:47'),('MKD','Macedonian denar',1,'2019-03-28 09:07:47'),('MMK','Myanmar kyat',1,'2019-03-28 09:07:47'),('MNT','Mongolian tugrik',1,'2019-03-28 09:07:47'),('MOP','Macao SAR pataca',1,'2019-03-28 09:07:47'),('MRO','Mauritanian ouguiya',1,'2019-03-28 09:07:47'),('MUR','Mauritius rupee',1,'2019-03-28 09:07:47'),('MVR','Maldivian rufiyaa',1,'2019-03-28 09:07:47'),('MWK','Malawi kwacha',1,'2019-03-28 09:07:47'),('MXN','Mexican peso',1,'2019-03-28 09:07:47'),('MYR','Malaysian ringgit',1,'2019-03-28 09:07:47'),('MZN','Mozambique new metical',1,'2019-03-28 09:07:47'),('NAD','Namibian dollar',1,'2019-03-28 09:07:47'),('NGN','Nigerian naira',1,'2019-03-28 09:07:47'),('NIO','Nicaraguan cordoba oro',1,'2019-03-28 09:07:47'),('NOK','Norwegian krone',1,'2019-03-28 09:07:47'),('NPR','Nepalese rupee',1,'2019-03-28 09:07:47'),('NZD','New Zealand dollar',1,'2019-03-28 09:07:47'),('OMR','Omani rial',1,'2019-03-28 09:07:47'),('PAB','Panamanian balboa',1,'2019-03-28 09:07:47'),('PEN','Peruvian nuevo sol',1,'2019-03-28 09:07:47'),('PGK','Papua New Guinea kina',1,'2019-03-28 09:07:47'),('PHP','Philippine peso',1,'2019-03-28 09:07:47'),('PKR','Pakistani rupee',1,'2019-03-28 09:07:47'),('PLN','Polish zloty',1,'2019-03-28 09:07:47'),('PYG','Paraguayan guarani',1,'2019-03-28 09:07:47'),('QAR','Qatari rial',1,'2019-03-28 09:07:47'),('RON','Romanian new leu',1,'2019-03-28 09:07:47'),('RSD','Serbian dinar',1,'2019-03-28 09:07:47'),('RUB','Russian ruble',1,'2019-03-28 09:07:47'),('RWF','Rwandan franc',1,'2019-03-28 09:07:47'),('SAR','Saudi riyal',1,'2019-03-28 09:07:47'),('SBD','Solomon Islands dollar',1,'2019-03-28 09:07:47'),('SCR','Seychelles rupee',1,'2019-03-28 09:07:47'),('SDG','Sudanese pound',1,'2019-03-28 09:07:47'),('SEK','Swedish krona',1,'2019-03-28 09:07:47'),('SGD','Singapore dollar',1,'2019-03-28 09:07:47'),('SHP','Saint Helena pound',1,'2019-03-28 09:07:47'),('SLL','Sierra Leone leone',1,'2019-03-28 09:07:47'),('SOS','Somali shilling',1,'2019-03-28 09:07:47'),('SPL','Seborgan luigino',1,'2019-03-28 09:07:47'),('SRD','Suriname dollar',1,'2019-03-28 09:07:47'),('STD','Sao Tome and Principe dobra',1,'2019-03-28 09:07:47'),('SVC','El Salvador colon',1,'2019-03-28 09:07:47'),('SYP','Syrian pound',1,'2019-03-28 09:07:47'),('SZL','Swaziland lilangeni',1,'2019-03-28 09:07:47'),('THB','Thai baht',1,'2019-03-28 09:07:47'),('TJS','Tajik somoni',1,'2019-03-28 09:07:47'),('TMT','Turkmen new manat',1,'2019-03-28 09:07:47'),('TND','Tunisian dinar',1,'2019-03-28 09:07:47'),('TOP','Tongan pa\'anga',1,'2019-03-28 09:07:47'),('TRY','Turkish lira',1,'2019-03-28 09:07:47'),('TTD','Trinidad and Tobago dollar',1,'2019-03-28 09:07:47'),('TVD','Tuvaluan dollar',1,'2019-03-28 09:07:47'),('TWD','Taiwan New dollar',1,'2019-03-28 09:07:47'),('TZS','Tanzanian shilling',1,'2019-03-28 09:07:47'),('UAH','Ukrainian hryvnia',1,'2019-03-28 09:07:47'),('UGX','Uganda new shilling',1,'2019-03-28 09:07:47'),('USD','US dollar',1,'2019-03-28 09:07:47'),('UYU','Uruguayan peso uruguayo',1,'2019-03-28 09:07:47'),('UZS','Uzbekistani sum',1,'2019-03-28 09:07:47'),('VEF','Venezuelan bolivar fuerte',1,'2019-03-28 09:07:47'),('VND','Vietnamese dong',1,'2019-03-28 09:07:47'),('VUV','Vanuatu vatu',1,'2019-03-28 09:07:47'),('WST','Samoan tala',1,'2019-03-28 09:07:47'),('XAF','CFA franc BEAC',1,'2019-03-28 09:07:47'),('XAG','Silver (ounce)',1,'2019-03-28 09:07:47'),('XAU','Gold (ounce)',1,'2019-03-28 09:07:47'),('XCD','East Caribbean dollar',1,'2019-03-28 09:07:47'),('XDR','IMF special drawing right',1,'2019-03-28 09:07:47'),('XFO','Gold franc',1,'2019-03-28 09:07:47'),('XFU','UIC franc',1,'2019-03-28 09:07:47'),('XOF','CFA franc BCEAO',1,'2019-03-28 09:07:47'),('XPD','Palladium (ounce)',1,'2019-03-28 09:07:47'),('XPF','CFP franc',1,'2019-03-28 09:07:47'),('XPT','Platinum (ounce)',1,'2019-03-28 09:07:47'),('YER','Yemeni rial',1,'2019-03-28 09:07:47'),('ZAR','South African rand',1,'2019-03-28 09:07:47'),('ZMK','Zambian kwacha (obsolete)',1,'2019-03-28 09:07:47'),('ZMW','Zambian kwacha',1,'2019-03-28 09:07:47'),('ZWD','Zimbabwe dollar (initial)',1,'2019-03-28 09:07:47'),('ZWL','Zimbabwe dollar (3rd denomination)',1,'2019-03-28 09:07:47'),('ZWN','Zimbabwe dollar (1st denomination)',1,'2019-03-28 09:07:47'),('ZWR','Zimbabwe dollar (2nd denomination)',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `currency` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_type_unique` (`type`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `endpointType` +-- + +LOCK TABLES `endpointType` WRITE; +/*!40000 ALTER TABLE `endpointType` DISABLE KEYS */; +INSERT INTO `endpointType` VALUES (1,'URL','REST URLs',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `endpointType` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration` +-- + +LOCK TABLES `migration` WRITE; +/*!40000 ALTER TABLE `migration` DISABLE KEYS */; +INSERT INTO `migration` VALUES (1,'01_currency.js',1,'2019-03-28 11:07:46'),(2,'02_endpointType.js',1,'2019-03-28 11:07:46'),(3,'03_endpointType-indexes.js',1,'2019-03-28 11:07:46'),(4,'04_partyIdType.js',1,'2019-03-28 11:07:46'),(5,'05_partyIdType-indexes.js',1,'2019-03-28 11:07:46'),(6,'08_oracleEndpoint.js',1,'2019-03-28 11:07:47'),(7,'09_oracleEndpoint-indexes.js',1,'2019-03-28 11:07:47'); +/*!40000 ALTER TABLE `migration` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration_lock` +-- + +LOCK TABLES `migration_lock` WRITE; +/*!40000 ALTER TABLE `migration_lock` DISABLE KEYS */; +INSERT INTO `migration_lock` VALUES (1,0); +/*!40000 ALTER TABLE `migration_lock` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `oracleEndpoint` +-- + +DROP TABLE IF EXISTS `oracleEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `oracleEndpoint` ( + `oracleEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `partyIdTypeId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `currencyId` varchar(255) DEFAULT NULL, + `value` varchar(512) NOT NULL, + `isDefault` tinyint(1) NOT NULL DEFAULT '0', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`oracleEndpointId`), + KEY `oracleendpoint_currencyid_foreign` (`currencyId`), + KEY `oracleendpoint_partyidtypeid_index` (`partyIdTypeId`), + KEY `oracleendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `oracleendpoint_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `oracleendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `oracleendpoint_partyidtypeid_foreign` FOREIGN KEY (`partyIdTypeId`) REFERENCES `partyIdType` (`partyidtypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `oracleEndpoint` +-- + +LOCK TABLES `oracleEndpoint` WRITE; +/*!40000 ALTER TABLE `oracleEndpoint` DISABLE KEYS */; +/*!40000 ALTER TABLE `oracleEndpoint` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `partyIdType` +-- + +DROP TABLE IF EXISTS `partyIdType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `partyIdType` ( + `partyIdTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`partyIdTypeId`), + UNIQUE KEY `partyidtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `partyIdType` +-- + +LOCK TABLES `partyIdType` WRITE; +/*!40000 ALTER TABLE `partyIdType` DISABLE KEYS */; +INSERT INTO `partyIdType` VALUES (1,'MSISDN','A MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.',1,'2019-03-28 09:07:47'),(2,'EMAIL','An email is used as reference to a participant. The format of the email should be according to the informational RFC 3696.',1,'2019-03-28 09:07:47'),(3,'PERSONAL_ID','A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(4,'BUSINESS','A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.',1,'2019-03-28 09:07:47'),(5,'DEVICE','A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(6,'ACCOUNT_ID','A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.',1,'2019-03-28 09:07:47'),(7,'IBAN','A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.',1,'2019-03-28 09:07:47'),(8,'ALIAS','An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `partyIdType` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-03-28 11:09:54 diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd new file mode 100644 index 000000000..ea177ae89 --- /dev/null +++ b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupService-schema.png b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupService-schema.png new file mode 100644 index 000000000..bdca208cd Binary files /dev/null and b/legacy/mojaloop-technical-overview/account-lookup-service/assets/entities/AccountLookupService-schema.png differ diff --git a/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg new file mode 100644 index 000000000..d87484a3c --- /dev/null +++ b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Ledger
    Central-Ledger
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg new file mode 100644 index 000000000..f75130984 --- /dev/null +++ b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Services
    (Ledger - API, Handlers)
    Central-Services<br>(Ledger - API, Handlers)<br>
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    Quoting-Service
    Quoting-Service
    ALS Oracle Simulator
    [Not supported by viewer]
    A 2. *ID based
    lookup
    A 2. *ID based <br>lookup
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg new file mode 100644 index 000000000..a2fbbe512 --- /dev/null +++ b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg @@ -0,0 +1,3 @@ + + +
    C 4. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Account Lookup Services
    [Not supported by viewer]
    Pathfinder
    Pathfinder
    FSP
    Backend


    (Does not natively speak Mojaloop API)








    [Not supported by viewer]
    S
    c
    h
    e
    m
    e

    A
    d
    a
    p
    t
    e
    r

    [Not supported by viewer]
    A 2. MSISDN based lookup
    A 2. MSISDN based lookup
    FSP
    Backend
      

    (Natively speaks Mojaloop API)









    [Not supported by viewer]
    A
    A
    A 1. User
    Lookup
    A 1. User <br>Lookup
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based lookup
    A 2. mID based lookup
    Mojaloop Hub
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    C 1. Transfer
        Prepare
    [Not supported by viewer]
    A 3. Receiver
    Details
    A 3. Receiver<br>Details<br>
     Fee /
    Comm
    [Not supported by viewer]
    Get Receiver
    Details
    [Not supported by viewer]
     C 2. Transfer
    Prepare
    [Not supported by viewer]
    C 5. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Transfer
    Prepare
    [Not supported by viewer]
    C 3. Transfer
    Fulfil
    C 3. Transfer<br>Fulfil<br>
    Transfer
    Fulfil
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    Central Services
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote<br>
    Settlement Provider
    Settlement Provider
    Hub Operator
    Hub Operator
    D 1. Create Settlement
    D 1. Create Settlement
    D
    D
    D 2. Query Settlement Report
    (Pull)
    D 2. Query Settlement Report<br>(Pull)<br>
    D 3. Send Acknowledgements
    (Push)
    D 3. Send Acknowledgements<br>(Push)<br>
    Quoting Service
    <font style="font-size: 18px">Quoting Service</font>
    Central Services
    • Transfers
    • Settlements
    • Auditing
    • Notifications
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/assets/diagrams/architecture/central_ledger_block_diagram.png b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/central_ledger_block_diagram.png new file mode 100644 index 000000000..48199cf3e Binary files /dev/null and b/legacy/mojaloop-technical-overview/assets/diagrams/architecture/central_ledger_block_diagram.png differ diff --git a/mojaloop-technical-overview/central-bulk-transfers/README.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/README.md similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/README.md rename to legacy/mojaloop-technical-overview/central-bulk-transfers/README.md diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..f6995bc85 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-ddl-MySQLWorkbench.sql @@ -0,0 +1,1600 @@ +-- MySQL dump 10.13 Distrib 8.0.16, for macos10.14 (x86_64) +-- +-- Host: 127.0.0.1 Database: central_ledger +-- ------------------------------------------------------ +-- Server version 8.0.13 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; + SET NAMES utf8 ; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `amountType` +-- + +DROP TABLE IF EXISTS `amountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `amountType` ( + `amountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`amountTypeId`), + UNIQUE KEY `amounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `balanceOfPayments` +-- + +DROP TABLE IF EXISTS `balanceOfPayments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `balanceOfPayments` ( + `balanceOfPaymentsId` int(10) unsigned NOT NULL, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible values and meaning are defined in https://www.imf.org/external/np/sta/bopcode/', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`balanceOfPaymentsId`), + UNIQUE KEY `balanceofpayments_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='See https://www.imf.org/external/np/sta/bopcode/guide.htm'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkProcessingState` +-- + +DROP TABLE IF EXISTS `bulkProcessingState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkProcessingState` ( + `bulkProcessingStateId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkProcessingStateId`), + UNIQUE KEY `bulkprocessingstate_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransfer` +-- + +DROP TABLE IF EXISTS `bulkTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransfer` ( + `bulkTransferId` varchar(36) NOT NULL, + `bulkQuoteId` varchar(36) DEFAULT NULL, + `payerParticipantId` int(10) unsigned DEFAULT NULL, + `payeeParticipantId` int(10) unsigned DEFAULT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + KEY `bulktransfer_payerparticipantid_index` (`payerParticipantId`), + KEY `bulktransfer_payeeparticipantid_index` (`payeeParticipantId`), + CONSTRAINT `bulktransfer_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferDuplicateCheck` (`bulktransferid`), + CONSTRAINT `bulktransfer_payeeparticipantid_foreign` FOREIGN KEY (`payeeParticipantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `bulktransfer_payerparticipantid_foreign` FOREIGN KEY (`payerParticipantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferAssociation` +-- + +DROP TABLE IF EXISTS `bulkTransferAssociation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferAssociation` ( + `bulkTransferAssociationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `bulkTransferId` varchar(36) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `bulkProcessingStateId` int(10) unsigned NOT NULL, + `lastProcessedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `errorCode` int(10) unsigned DEFAULT NULL, + `errorDescription` varchar(128) DEFAULT NULL, + PRIMARY KEY (`bulkTransferAssociationId`), + UNIQUE KEY `bulktransferassociation_transferid_bulktransferid_unique` (`transferId`,`bulkTransferId`), + KEY `bulktransferassociation_bulktransferid_foreign` (`bulkTransferId`), + KEY `bulktransferassociation_bulkprocessingstateid_foreign` (`bulkProcessingStateId`), + CONSTRAINT `bulktransferassociation_bulkprocessingstateid_foreign` FOREIGN KEY (`bulkProcessingStateId`) REFERENCES `bulkProcessingState` (`bulkprocessingstateid`), + CONSTRAINT `bulktransferassociation_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferError` +-- + +DROP TABLE IF EXISTS `bulkTransferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferError` ( + `bulkTransferErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferErrorId`), + KEY `bulktransfererror_bulktransferstatechangeid_index` (`bulkTransferStateChangeId`), + CONSTRAINT `bulktransfererror_bulktransferstatechangeid_foreign` FOREIGN KEY (`bulkTransferStateChangeId`) REFERENCES `bulkTransferStateChange` (`bulktransferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferExtension` +-- + +DROP TABLE IF EXISTS `bulkTransferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferExtension` ( + `bulkTransferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferExtensionId`), + KEY `bulktransferextension_bulktransferid_index` (`bulkTransferId`), + CONSTRAINT `bulktransferextension_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilment` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferFulfilment` ( + `bulkTransferId` varchar(36) NOT NULL, + `completedDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilment_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferFulfilmentDuplicateCheck` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferFulfilmentDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilmentduplicatecheck_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferState` +-- + +DROP TABLE IF EXISTS `bulkTransferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferState` ( + `bulkTransferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'bulkTransferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferStateChange` +-- + +DROP TABLE IF EXISTS `bulkTransferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `bulkTransferStateChange` ( + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `bulkTransferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateChangeId`), + KEY `bulktransferstatechange_bulktransferid_index` (`bulkTransferId`), + KEY `bulktransferstatechange_bulktransferstateid_index` (`bulkTransferStateId`), + CONSTRAINT `bulktransferstatechange_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`), + CONSTRAINT `bulktransferstatechange_bulktransferstateid_foreign` FOREIGN KEY (`bulkTransferStateId`) REFERENCES `bulkTransferState` (`bulktransferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `contactType` +-- + +DROP TABLE IF EXISTS `contactType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `contactType` ( + `contactTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`contactTypeId`), + UNIQUE KEY `contacttype_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `scale` int(10) unsigned NOT NULL DEFAULT '4', + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `event` +-- + +DROP TABLE IF EXISTS `event`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `event` ( + `eventId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`eventId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `geoCode` +-- + +DROP TABLE IF EXISTS `geoCode`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `geoCode` ( + `geoCodeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL COMMENT 'Optionally the GeoCode for the Payer/Payee may have been provided. If the Quote Response has the GeoCode for the Payee, an additional row is added', + `latitude` varchar(50) NOT NULL COMMENT 'Latitude of the initiating Party', + `longitude` varchar(50) NOT NULL COMMENT 'Longitude of the initiating Party', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`geoCodeId`), + KEY `geocode_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `geocode_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ilpPacket` +-- + +DROP TABLE IF EXISTS `ilpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ilpPacket` ( + `transferId` varchar(36) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `ilppacket_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerAccountType` +-- + +DROP TABLE IF EXISTS `ledgerAccountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ledgerAccountType` ( + `ledgerAccountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ledgerAccountTypeId`), + UNIQUE KEY `ledgeraccounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerEntryType` +-- + +DROP TABLE IF EXISTS `ledgerEntryType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `ledgerEntryType` ( + `ledgerEntryTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ledgerEntryTypeId`), + UNIQUE KEY `ledgerentrytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=138 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participant` +-- + +DROP TABLE IF EXISTS `participant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participant` ( + `participantId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantId`), + UNIQUE KEY `participant_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantContact` +-- + +DROP TABLE IF EXISTS `participantContact`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantContact` ( + `participantContactId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `contactTypeId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `priorityPreference` int(11) NOT NULL DEFAULT '9', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantContactId`), + KEY `participantcontact_participantid_index` (`participantId`), + KEY `participantcontact_contacttypeid_index` (`contactTypeId`), + CONSTRAINT `participantcontact_contacttypeid_foreign` FOREIGN KEY (`contactTypeId`) REFERENCES `contactType` (`contacttypeid`), + CONSTRAINT `participantcontact_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantCurrency` +-- + +DROP TABLE IF EXISTS `participantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantCurrency` ( + `participantCurrencyId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantCurrencyId`), + UNIQUE KEY `participantcurrency_pcl_unique` (`participantId`,`currencyId`,`ledgerAccountTypeId`), + KEY `participantcurrency_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + KEY `participantcurrency_participantid_index` (`participantId`), + KEY `participantcurrency_currencyid_index` (`currencyId`), + CONSTRAINT `participantcurrency_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `participantcurrency_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `participantcurrency_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantEndpoint` +-- + +DROP TABLE IF EXISTS `participantEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantEndpoint` ( + `participantEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `value` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantEndpointId`), + KEY `participantendpoint_participantid_index` (`participantId`), + KEY `participantendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `participantendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `participantendpoint_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimit` +-- + +DROP TABLE IF EXISTS `participantLimit`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantLimit` ( + `participantLimitId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `participantLimitTypeId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL DEFAULT '0.0000', + `thresholdAlarmPercentage` decimal(5,2) NOT NULL DEFAULT '10.00', + `startAfterParticipantPositionChangeId` bigint(20) unsigned DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantLimitId`), + KEY `participantlimit_participantcurrencyid_index` (`participantCurrencyId`), + KEY `participantlimit_participantlimittypeid_index` (`participantLimitTypeId`), + KEY `participantlimit_startafterparticipantpositionchangeid_index` (`startAfterParticipantPositionChangeId`), + CONSTRAINT `participantlimit_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `participantlimit_participantlimittypeid_foreign` FOREIGN KEY (`participantLimitTypeId`) REFERENCES `participantLimitType` (`participantlimittypeid`), + CONSTRAINT `participantlimit_startafterparticipantpositionchangeid_foreign` FOREIGN KEY (`startAfterParticipantPositionChangeId`) REFERENCES `participantPositionChange` (`participantpositionchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimitType` +-- + +DROP TABLE IF EXISTS `participantLimitType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantLimitType` ( + `participantLimitTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantLimitTypeId`), + UNIQUE KEY `participantlimittype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantParty` +-- + +DROP TABLE IF EXISTS `participantParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantParty` ( + `participantPartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `partyId` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`participantPartyId`), + UNIQUE KEY `participantparty_participantid_partyid_unique` (`participantId`,`partyId`), + KEY `participantparty_participantid_index` (`participantId`), + CONSTRAINT `participantparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPosition` +-- + +DROP TABLE IF EXISTS `participantPosition`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantPosition` ( + `participantPositionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionId`), + KEY `participantposition_participantcurrencyid_index` (`participantCurrencyId`), + CONSTRAINT `participantposition_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPositionChange` +-- + +DROP TABLE IF EXISTS `participantPositionChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `participantPositionChange` ( + `participantPositionChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantPositionId` bigint(20) unsigned NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionChangeId`), + KEY `participantpositionchange_participantpositionid_index` (`participantPositionId`), + KEY `participantpositionchange_transferstatechangeid_index` (`transferStateChangeId`), + CONSTRAINT `participantpositionchange_participantpositionid_foreign` FOREIGN KEY (`participantPositionId`) REFERENCES `participantPosition` (`participantpositionid`), + CONSTRAINT `participantpositionchange_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `party` +-- + +DROP TABLE IF EXISTS `party`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `party` ( + `partyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL, + `firstName` varchar(128) DEFAULT NULL, + `middleName` varchar(128) DEFAULT NULL, + `lastName` varchar(128) DEFAULT NULL, + `dateOfBirth` datetime DEFAULT NULL, + PRIMARY KEY (`partyId`), + KEY `party_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `party_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Optional pers. data provided during Quote Request & Response'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyIdentifierType` +-- + +DROP TABLE IF EXISTS `partyIdentifierType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `partyIdentifierType` ( + `partyIdentifierTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) NOT NULL, + PRIMARY KEY (`partyIdentifierTypeId`), + UNIQUE KEY `partyidentifiertype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyType` +-- + +DROP TABLE IF EXISTS `partyType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `partyType` ( + `partyTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(256) NOT NULL, + PRIMARY KEY (`partyTypeId`), + UNIQUE KEY `partytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quote` +-- + +DROP TABLE IF EXISTS `quote`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quote` ( + `quoteId` varchar(36) NOT NULL, + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `transactionRequestId` varchar(36) DEFAULT NULL COMMENT 'Optional previously-sent transaction request', + `note` text COMMENT 'A memo that will be attached to the transaction', + `expirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `transactionInitiatorId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator', + `transactionInitiatorTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator type', + `transactionScenarioId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction scenario', + `balanceOfPaymentsId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type that contains the elements- balance of payment', + `transactionSubScenarioId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type sub scenario as defined by the local scheme', + `amountTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction type that contains valid elements for - Amount Type', + `amount` decimal(18,4) NOT NULL DEFAULT '0.0000' COMMENT 'The amount that the quote is being requested for. Need to be interpert in accordance with the amount type', + `currencyId` varchar(255) DEFAULT NULL COMMENT 'Trading currency pertaining to the Amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`), + KEY `quote_transactionreferenceid_foreign` (`transactionReferenceId`), + KEY `quote_transactionrequestid_foreign` (`transactionRequestId`), + KEY `quote_transactioninitiatorid_foreign` (`transactionInitiatorId`), + KEY `quote_transactioninitiatortypeid_foreign` (`transactionInitiatorTypeId`), + KEY `quote_transactionscenarioid_foreign` (`transactionScenarioId`), + KEY `quote_balanceofpaymentsid_foreign` (`balanceOfPaymentsId`), + KEY `quote_transactionsubscenarioid_foreign` (`transactionSubScenarioId`), + KEY `quote_amounttypeid_foreign` (`amountTypeId`), + KEY `quote_currencyid_foreign` (`currencyId`), + CONSTRAINT `quote_amounttypeid_foreign` FOREIGN KEY (`amountTypeId`) REFERENCES `amountType` (`amounttypeid`), + CONSTRAINT `quote_balanceofpaymentsid_foreign` FOREIGN KEY (`balanceOfPaymentsId`) REFERENCES `balanceOfPayments` (`balanceofpaymentsid`), + CONSTRAINT `quote_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quote_transactioninitiatorid_foreign` FOREIGN KEY (`transactionInitiatorId`) REFERENCES `transactionInitiator` (`transactioninitiatorid`), + CONSTRAINT `quote_transactioninitiatortypeid_foreign` FOREIGN KEY (`transactionInitiatorTypeId`) REFERENCES `transactionInitiatorType` (`transactioninitiatortypeid`), + CONSTRAINT `quote_transactionreferenceid_foreign` FOREIGN KEY (`transactionReferenceId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionrequestid_foreign` FOREIGN KEY (`transactionRequestId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionscenarioid_foreign` FOREIGN KEY (`transactionScenarioId`) REFERENCES `transactionScenario` (`transactionscenarioid`), + CONSTRAINT `quote_transactionsubscenarioid_foreign` FOREIGN KEY (`transactionSubScenarioId`) REFERENCES `transactionSubScenario` (`transactionsubscenarioid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteDuplicateCheck` ( + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(1024) DEFAULT NULL COMMENT 'hash value received for the quote request', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteError` +-- + +DROP TABLE IF EXISTS `quoteError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteError` ( + `quoteErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned DEFAULT NULL COMMENT 'The response to the intial quote', + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`quoteErrorId`), + KEY `quoteerror_quoteid_foreign` (`quoteId`), + KEY `quoteerror_quoteresponseid_foreign` (`quoteResponseId`), + CONSTRAINT `quoteerror_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteerror_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteExtension` +-- + +DROP TABLE IF EXISTS `quoteExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteExtension` ( + `quoteExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned NOT NULL COMMENT 'The response to the intial quote', + `transactionId` varchar(36) NOT NULL COMMENT 'The transaction reference that is part of the initial quote', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteExtensionId`), + KEY `quoteextension_quoteid_foreign` (`quoteId`), + KEY `quoteextension_quoteresponseid_foreign` (`quoteResponseId`), + KEY `quoteextension_transactionid_foreign` (`transactionId`), + CONSTRAINT `quoteextension_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteextension_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`), + CONSTRAINT `quoteextension_transactionid_foreign` FOREIGN KEY (`transactionId`) REFERENCES `transactionReference` (`transactionreferenceid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteParty` +-- + +DROP TABLE IF EXISTS `quoteParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteParty` ( + `quotePartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `partyTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of party this row relates to; typically PAYER or PAYEE', + `partyIdentifierTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of identifier used to identify this party e.g. MSISDN, IBAN etc...', + `partyIdentifierValue` varchar(128) NOT NULL COMMENT 'The value of the identifier used to identify this party', + `partySubIdOrTypeId` int(10) unsigned DEFAULT NULL COMMENT 'A sub-identifier or sub-type for the Party', + `fspId` varchar(255) DEFAULT NULL COMMENT 'This is the FSP ID as provided in the quote. For the switch between multi-parties it is required', + `participantId` int(10) unsigned DEFAULT NULL COMMENT 'Reference to the resolved FSP ID (if supplied/known). If not an error will be reported', + `merchantClassificationCode` varchar(4) DEFAULT NULL COMMENT 'Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments', + `partyName` varchar(128) DEFAULT NULL COMMENT 'Display name of the Party, could be a real name or a nick name', + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL COMMENT 'The role this Party is playing in the transaction', + `ledgerEntryTypeId` int(10) unsigned NOT NULL COMMENT 'The type of financial entry this Party is presenting', + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL COMMENT 'Trading currency pertaining to the party amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quotePartyId`), + KEY `quoteparty_quoteid_foreign` (`quoteId`), + KEY `quoteparty_partytypeid_foreign` (`partyTypeId`), + KEY `quoteparty_partyidentifiertypeid_foreign` (`partyIdentifierTypeId`), + KEY `quoteparty_partysubidortypeid_foreign` (`partySubIdOrTypeId`), + KEY `quoteparty_participantid_foreign` (`participantId`), + KEY `quoteparty_transferparticipantroletypeid_foreign` (`transferParticipantRoleTypeId`), + KEY `quoteparty_ledgerentrytypeid_foreign` (`ledgerEntryTypeId`), + KEY `quoteparty_currencyid_foreign` (`currencyId`), + CONSTRAINT `quoteparty_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteparty_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `quoteparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `quoteparty_partyidentifiertypeid_foreign` FOREIGN KEY (`partyIdentifierTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partysubidortypeid_foreign` FOREIGN KEY (`partySubIdOrTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partytypeid_foreign` FOREIGN KEY (`partyTypeId`) REFERENCES `partyType` (`partytypeid`), + CONSTRAINT `quoteparty_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteparty_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quotePartyView` +-- + +DROP TABLE IF EXISTS `quotePartyView`; +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quotePartyView` AS SELECT + 1 AS `quoteId`, + 1 AS `quotePartyId`, + 1 AS `partyType`, + 1 AS `identifierType`, + 1 AS `partyIdentifierValue`, + 1 AS `partySubIdOrType`, + 1 AS `fspId`, + 1 AS `merchantClassificationCode`, + 1 AS `partyName`, + 1 AS `firstName`, + 1 AS `lastName`, + 1 AS `middleName`, + 1 AS `dateOfBirth`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `quoteResponse` +-- + +DROP TABLE IF EXISTS `quoteResponse`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponse` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `transferAmountCurrencyId` varchar(3) NOT NULL COMMENT 'CurrencyId of the transfer amount', + `transferAmount` decimal(18,4) NOT NULL COMMENT 'The amount of money that the Payer FSP should transfer to the Payee FSP', + `payeeReceiveAmountCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee receive amount', + `payeeReceiveAmount` decimal(18,4) DEFAULT NULL COMMENT 'The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees', + `payeeFspFeeCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp fee amount', + `payeeFspFeeAmount` decimal(18,4) DEFAULT NULL COMMENT 'Payee FSP’s part of the transaction fee', + `payeeFspCommissionCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp commission amount', + `payeeFspCommissionAmount` decimal(18,4) DEFAULT NULL COMMENT 'Transaction commission from the Payee FSP', + `ilpCondition` varchar(256) NOT NULL, + `responseExpirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `isValid` tinyint(1) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponse_quoteid_foreign` (`quoteId`), + KEY `quoteresponse_transferamountcurrencyid_foreign` (`transferAmountCurrencyId`), + KEY `quoteresponse_payeereceiveamountcurrencyid_foreign` (`payeeReceiveAmountCurrencyId`), + KEY `quoteresponse_payeefspcommissioncurrencyid_foreign` (`payeeFspCommissionCurrencyId`), + CONSTRAINT `quoteresponse_payeefspcommissioncurrencyid_foreign` FOREIGN KEY (`payeeFspCommissionCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_payeereceiveamountcurrencyid_foreign` FOREIGN KEY (`payeeReceiveAmountCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponse_transferamountcurrencyid_foreign` FOREIGN KEY (`transferAmountCurrencyId`) REFERENCES `currency` (`currencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='This table is the primary store for quote responses'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteResponseDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponseDuplicateCheck` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'The response to the intial quote', + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(255) DEFAULT NULL COMMENT 'hash value received for the quote response', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponseduplicatecheck_quoteid_foreign` (`quoteId`), + CONSTRAINT `quoteresponseduplicatecheck_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponseduplicatecheck_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseIlpPacket` +-- + +DROP TABLE IF EXISTS `quoteResponseIlpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `quoteResponseIlpPacket` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `value` text NOT NULL COMMENT 'ilpPacket returned from Payee in response to a quote request', + PRIMARY KEY (`quoteResponseId`), + CONSTRAINT `quoteresponseilppacket_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quoteResponseView` +-- + +DROP TABLE IF EXISTS `quoteResponseView`; +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quoteResponseView` AS SELECT + 1 AS `quoteResponseId`, + 1 AS `quoteId`, + 1 AS `transferAmountCurrencyId`, + 1 AS `transferAmount`, + 1 AS `payeeReceiveAmountCurrencyId`, + 1 AS `payeeReceiveAmount`, + 1 AS `payeeFspFeeCurrencyId`, + 1 AS `payeeFspFeeAmount`, + 1 AS `payeeFspCommissionCurrencyId`, + 1 AS `payeeFspCommissionAmount`, + 1 AS `ilpCondition`, + 1 AS `responseExpirationDate`, + 1 AS `isValid`, + 1 AS `createdDate`, + 1 AS `ilpPacket`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Temporary view structure for view `quoteView` +-- + +DROP TABLE IF EXISTS `quoteView`; +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8mb4; +/*!50001 CREATE VIEW `quoteView` AS SELECT + 1 AS `quoteId`, + 1 AS `transactionReferenceId`, + 1 AS `transactionRequestId`, + 1 AS `note`, + 1 AS `expirationDate`, + 1 AS `transactionInitiator`, + 1 AS `transactionInitiatorType`, + 1 AS `transactionScenario`, + 1 AS `balanceOfPaymentsId`, + 1 AS `transactionSubScenario`, + 1 AS `amountType`, + 1 AS `amount`, + 1 AS `currency`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `segment` +-- + +DROP TABLE IF EXISTS `segment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `segment` ( + `segmentId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `segmentType` varchar(50) NOT NULL, + `enumeration` int(11) NOT NULL DEFAULT '0', + `tableName` varchar(50) NOT NULL, + `value` bigint(20) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`segmentId`), + KEY `segment_keys_index` (`segmentType`,`enumeration`,`tableName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlement` +-- + +DROP TABLE IF EXISTS `settlement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlement` ( + `settlementId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementId`), + KEY `settlement_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlement_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementStateChange` (`settlementstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrency` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementParticipantCurrency` ( + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `netAmount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementTransferId` varchar(36) DEFAULT NULL, + PRIMARY KEY (`settlementParticipantCurrencyId`), + KEY `settlementparticipantcurrency_settlementid_index` (`settlementId`), + KEY `settlementparticipantcurrency_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementparticipantcurrency_settlementtransferid_index` (`settlementTransferId`), + KEY `spc_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementparticipantcurrency_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementparticipantcurrency_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `spc_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementParticipantCurrencyStateChange` (`settlementparticipantcurrencystatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrencyStateChange` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrencyStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementParticipantCurrencyStateChange` ( + `settlementParticipantCurrencyStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `externalReference` varchar(50) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementParticipantCurrencyStateChangeId`), + KEY `spcsc_settlementparticipantcurrencyid_index` (`settlementParticipantCurrencyId`), + KEY `spcsc_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `spcsc_settlementparticipantcurrencyid_foreign` FOREIGN KEY (`settlementParticipantCurrencyId`) REFERENCES `settlementParticipantCurrency` (`settlementparticipantcurrencyid`), + CONSTRAINT `spcsc_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementSettlementWindow` +-- + +DROP TABLE IF EXISTS `settlementSettlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementSettlementWindow` ( + `settlementSettlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementSettlementWindowId`), + UNIQUE KEY `settlementsettlementwindow_unique` (`settlementId`,`settlementWindowId`), + KEY `settlementsettlementwindow_settlementid_index` (`settlementId`), + KEY `settlementsettlementwindow_settlementwindowid_index` (`settlementWindowId`), + CONSTRAINT `settlementsettlementwindow_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementsettlementwindow_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementState` +-- + +DROP TABLE IF EXISTS `settlementState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementState` ( + `settlementStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementStateChange` +-- + +DROP TABLE IF EXISTS `settlementStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementStateChange` ( + `settlementStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateChangeId`), + KEY `settlementstatechange_settlementid_index` (`settlementId`), + KEY `settlementstatechange_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `settlementstatechange_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementstatechange_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementTransferParticipant` +-- + +DROP TABLE IF EXISTS `settlementTransferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementTransferParticipant` ( + `settlementTransferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementTransferParticipantId`), + KEY `settlementtransferparticipant_settlementid_index` (`settlementId`), + KEY `settlementtransferparticipant_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementtransferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `stp_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementtransferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `settlementtransferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementtransferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementtransferparticipant_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementtransferparticipant_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `stp_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindow` +-- + +DROP TABLE IF EXISTS `settlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindow` ( + `settlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowId`), + KEY `settlementwindow_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementwindow_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowStateChange` (`settlementwindowstatechangeid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowState` +-- + +DROP TABLE IF EXISTS `settlementWindowState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindowState` ( + `settlementWindowStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `settlementWindowStateChange` ( + `settlementWindowStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateChangeId`), + KEY `settlementwindowstatechange_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `settlementwindowstatechange_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `settlementwindowstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `token` +-- + +DROP TABLE IF EXISTS `token`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `token` ( + `tokenId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `expiration` bigint(20) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`tokenId`), + UNIQUE KEY `token_value_unique` (`value`), + KEY `token_participantid_index` (`participantId`), + CONSTRAINT `token_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiator` +-- + +DROP TABLE IF EXISTS `transactionInitiator`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionInitiator` ( + `transactionInitiatorId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorId`), + UNIQUE KEY `transactioninitiator_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiatorType` +-- + +DROP TABLE IF EXISTS `transactionInitiatorType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionInitiatorType` ( + `transactionInitiatorTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorTypeId`), + UNIQUE KEY `transactioninitiatortype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionReference` +-- + +DROP TABLE IF EXISTS `transactionReference`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionReference` ( + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `quoteId` varchar(36) DEFAULT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System row creation timestamp', + PRIMARY KEY (`transactionReferenceId`), + KEY `transactionreference_quoteid_index` (`quoteId`), + CONSTRAINT `transactionreference_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quoteDuplicateCheck` (`quoteid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionScenario` +-- + +DROP TABLE IF EXISTS `transactionScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionScenario` ( + `transactionScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionScenarioId`), + UNIQUE KEY `transactionscenario_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionSubScenario` +-- + +DROP TABLE IF EXISTS `transactionSubScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transactionSubScenario` ( + `transactionSubScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible sub-scenario, defined locally within the scheme', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionSubScenarioId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transfer` +-- + +DROP TABLE IF EXISTS `transfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transfer` ( + `transferId` varchar(36) NOT NULL, + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ilpCondition` varchar(256) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfer_currencyid_index` (`currencyId`), + CONSTRAINT `transfer_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `transfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferError` +-- + +DROP TABLE IF EXISTS `transferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferError` ( + `transferId` varchar(36) NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfererror_transferstatechangeid_foreign` (`transferStateChangeId`), + CONSTRAINT `transfererror_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferErrorDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferErrorDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferErrorDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transfererrorduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferExtension` +-- + +DROP TABLE IF EXISTS `transferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferExtension` ( + `transferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `isError` tinyint(1) NOT NULL DEFAULT '0', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferExtensionId`), + KEY `transferextension_transferid_foreign` (`transferId`), + CONSTRAINT `transferextension_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilment` +-- + +DROP TABLE IF EXISTS `transferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferFulfilment` ( + `transferId` varchar(36) NOT NULL, + `ilpFulfilment` varchar(256) DEFAULT NULL, + `completedDate` datetime NOT NULL, + `isValid` tinyint(1) DEFAULT NULL, + `settlementWindowId` bigint(20) unsigned DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transferfulfilment_settlementwindowid_foreign` (`settlementWindowId`), + CONSTRAINT `transferfulfilment_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `transferfulfilment_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferFulfilmentDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferFulfilmentDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transferfulfilmentduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipant` +-- + +DROP TABLE IF EXISTS `transferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferParticipant` ( + `transferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantId`), + KEY `transferparticipant_transferid_index` (`transferId`), + KEY `transferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `transferparticipant_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `transferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `transferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `transferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `transferparticipant_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferparticipant_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantRoleType` +-- + +DROP TABLE IF EXISTS `transferParticipantRoleType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferParticipantRoleType` ( + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantRoleTypeId`), + UNIQUE KEY `transferparticipantroletype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferRules` +-- + +DROP TABLE IF EXISTS `transferRules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferRules` ( + `transferRulesId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `rule` text NOT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferRulesId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferState` +-- + +DROP TABLE IF EXISTS `transferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferState` ( + `transferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'transferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferStateChange` +-- + +DROP TABLE IF EXISTS `transferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferStateChange` ( + `transferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `transferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateChangeId`), + KEY `transferstatechange_transferid_index` (`transferId`), + KEY `transferstatechange_transferstateid_index` (`transferStateId`), + CONSTRAINT `transferstatechange_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferstatechange_transferstateid_foreign` FOREIGN KEY (`transferStateId`) REFERENCES `transferState` (`transferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferTimeout` +-- + +DROP TABLE IF EXISTS `transferTimeout`; +/*!40101 SET @saved_cs_client = @@character_set_client */; + SET character_set_client = utf8mb4 ; +CREATE TABLE `transferTimeout` ( + `transferTimeoutId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferTimeoutId`), + UNIQUE KEY `transfertimeout_transferid_unique` (`transferId`), + CONSTRAINT `transfertimeout_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Final view structure for view `quotePartyView` +-- + +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quotePartyView` AS select `qp`.`quoteId` AS `quoteId`,`qp`.`quotePartyId` AS `quotePartyId`,`pt`.`name` AS `partyType`,`pit`.`name` AS `identifierType`,`qp`.`partyIdentifierValue` AS `partyIdentifierValue`,`spit`.`name` AS `partySubIdOrType`,`qp`.`fspId` AS `fspId`,`qp`.`merchantClassificationCode` AS `merchantClassificationCode`,`qp`.`partyName` AS `partyName`,`p`.`firstName` AS `firstName`,`p`.`lastName` AS `lastName`,`p`.`middleName` AS `middleName`,`p`.`dateOfBirth` AS `dateOfBirth`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from (((((`quoteParty` `qp` join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) join `partyIdentifierType` `pit` on((`pit`.`partyIdentifierTypeId` = `qp`.`partyIdentifierTypeId`))) left join `party` `p` on((`p`.`quotePartyId` = `qp`.`quotePartyId`))) left join `partyIdentifierType` `spit` on((`spit`.`partyIdentifierTypeId` = `qp`.`partySubIdOrTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteResponseView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteResponseView` AS select `qr`.`quoteResponseId` AS `quoteResponseId`,`qr`.`quoteId` AS `quoteId`,`qr`.`transferAmountCurrencyId` AS `transferAmountCurrencyId`,`qr`.`transferAmount` AS `transferAmount`,`qr`.`payeeReceiveAmountCurrencyId` AS `payeeReceiveAmountCurrencyId`,`qr`.`payeeReceiveAmount` AS `payeeReceiveAmount`,`qr`.`payeeFspFeeCurrencyId` AS `payeeFspFeeCurrencyId`,`qr`.`payeeFspFeeAmount` AS `payeeFspFeeAmount`,`qr`.`payeeFspCommissionCurrencyId` AS `payeeFspCommissionCurrencyId`,`qr`.`payeeFspCommissionAmount` AS `payeeFspCommissionAmount`,`qr`.`ilpCondition` AS `ilpCondition`,`qr`.`responseExpirationDate` AS `responseExpirationDate`,`qr`.`isValid` AS `isValid`,`qr`.`createdDate` AS `createdDate`,`qrilp`.`value` AS `ilpPacket`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from ((((`quoteResponse` `qr` join `quoteResponseIlpPacket` `qrilp` on((`qrilp`.`quoteResponseId` = `qr`.`quoteResponseId`))) join `quoteParty` `qp` on((`qp`.`quoteId` = `qr`.`quoteId`))) join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) where (`pt`.`name` = 'PAYEE') */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteView` AS select `q`.`quoteId` AS `quoteId`,`q`.`transactionReferenceId` AS `transactionReferenceId`,`q`.`transactionRequestId` AS `transactionRequestId`,`q`.`note` AS `note`,`q`.`expirationDate` AS `expirationDate`,`ti`.`name` AS `transactionInitiator`,`tit`.`name` AS `transactionInitiatorType`,`ts`.`name` AS `transactionScenario`,`q`.`balanceOfPaymentsId` AS `balanceOfPaymentsId`,`tss`.`name` AS `transactionSubScenario`,`amt`.`name` AS `amountType`,`q`.`amount` AS `amount`,`q`.`currencyId` AS `currency` from (((((`quote` `q` join `transactionInitiator` `ti` on((`ti`.`transactionInitiatorId` = `q`.`transactionInitiatorId`))) join `transactionInitiatorType` `tit` on((`tit`.`transactionInitiatorTypeId` = `q`.`transactionInitiatorTypeId`))) join `transactionScenario` `ts` on((`ts`.`transactionScenarioId` = `q`.`transactionScenarioId`))) join `amountType` `amt` on((`amt`.`amountTypeId` = `q`.`amountTypeId`))) left join `transactionSubScenario` `tss` on((`tss`.`transactionSubScenarioId` = `q`.`transactionSubScenarioId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-10-14 21:12:45 diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd new file mode 100644 index 000000000..12059bab5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema-DBeaver.erd @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + COLOR LEGEND: +Green - subject specific entity +Gray - transfer specific entity +Brown - bulk transfer entity +Red - settlement specific entity +Blue - lookup entity +Cyan - impl. specific +Yellow - tbd + + \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema.png b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema.png new file mode 100644 index 000000000..6afdaf2ea Binary files /dev/null and b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/database/central-ledger-schema.png differ diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png new file mode 100644 index 000000000..aa361a64a Binary files /dev/null and b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/Figure60-Example-Bulk-Transfer-Process-Spec1.0.png differ diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg new file mode 100644 index 000000000..b22f23afe --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/architecture/bulk-transfer-arch-flows.svg @@ -0,0 +1,3 @@ + + +
    1.7 Increment Position (fsp1)
    [Not supported by viewer]
    1.6 Increment
    Position (fsp1)

    [Not supported by viewer]
    Fulfil
    Sucess
    [Not supported by viewer]
    2.6 Fulfil
    Success
    [Not supported by viewer]
    <alt> 2.6  Fulfil Reject
    [Not supported by viewer]
    Fulfil
    Reject
    [Not supported by viewer]
    <alt> 2.7 Decrement
    Position (fsp1)

    [Not supported by viewer]
    Central - Services
    <font style="font-size: 18px">Central - Services</font>
    3.0 Reject
    [Not supported by viewer]
    1.0 Bulk Transfer 
    Request

    [Not supported by viewer]
    3.1 Decrement
    Position (fsp1)

    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    Bulk Transfer
    Bulk Transfer<br>
    Notification
    Event Handler
    [Not supported by viewer]
    notifications
    notifications
    FSP1
    (Payer)

    [Not supported by viewer]
    FSP2
    (Payee)
    [Not supported by viewer]
    1.1
    Prepare Request
    [Not supported by viewer]
    1.2 Accpeted
    (202)
    [Not supported by viewer]
    Bulk Transfer
    Bulk Transfer<br>
    2.0 Bulk Fulfil 
    Success / 
    Reject

    [Not supported by viewer]
    bulk fulfil
    bulk fulfil
    2.7 Decrement
    Position (fsp2)

    [Not supported by viewer]
    2.1 Bulk Fulfil 
    Success / Reject

    [Not supported by viewer]
    2.2 OK
    (202)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    Transfer Timeout
    Handler
    [Not supported by viewer]
    2.12 Bulk Fulfil Notify Callback /
    <alt> 2.12 Bulk Reject Response (Fulfil reject) /
    3.6 Bulk Reject Response (Timeout) /
    <alt> 1.8 Bulk Prepare Failure 
    [Not supported by viewer]
    1.12 Bulk Prepare Notify /
    2.13 Bulk Fulfil Notify /
    <alt> 2.13 Bulk Reject Response (Fulfil reject)
    3.7 Bulk Reject Response (Timeout)

    [Not supported by viewer]
    positions
    positions<br>
    bulk processing
    bulk processing
    BulkFulfil
    Handler
    [Not supported by viewer]
    1.3 Bulk Prepare Consume
    [Not supported by viewer]
    BulkPrepare
    Handler
    BulkPrepare<br>Handler
     prepare
     prepare
    fulfil
    fulfil
    BulkProcessing Handler
    BulkProcessing Handler<br>
    1.4 Individual Prepare
    [Not supported by viewer]
    1.5 Individual Prepare
    [Not supported by viewer]
    1.5
     / 1.9 / 2.9 / 3.3
     Individual Notify
    [Not supported by viewer]
    1.8 / 2.8 / 3.2 Individual
    Notify
    [Not supported by viewer]
    1.6 / 1.10 / 2.10 / 3.4 Bulk Notify
    [Not supported by viewer]
    1.7 / 1.11 / 2.11 / 3.5 Bulk Notify
    [Not supported by viewer]
    2.3 Bulk Fulfil Consume
    [Not supported by viewer]
    2.4 Individual
    Fulfil
    [Not supported by viewer]
    2.5 Individual
    Fulfil
    [Not supported by viewer]
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    [Not supported by viewer]
    PositionHandler
    PositionHandler
    PrepareHandler
    PrepareHandler
    Object Store
    [Not supported by viewer]
    <alt> 1.4 Bulk Prepare Failure
    [Not supported by viewer]
    <alt> 1.6 Individual Prepare Failure
    [Not supported by viewer]
    <alt> 1.8 Individual
    Failure Notify

    [Not supported by viewer]
    <alt> 2.4 Bulk Fulfil Failure
    [Not supported by viewer]
    <alt> 2.6 Individual Fulfil Failure
    [Not supported by viewer]
    bulk prepare
    bulk prepare
    Object Store
    [Not supported by viewer]
    Object Store
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml new file mode 100644 index 000000000..5bdd8119f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml @@ -0,0 +1,217 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULK_API +control "Bulk API Notification \nHandler" as NOTIFY_HANDLER +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +boundary "Central Service API" as CSAPI +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +control "Bulk Prepare\nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Handler" as PREP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing\nHandler" as BULK_PROC_HANDLER +collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULK_API + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant CSAPI + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROC_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_PREP_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +activate BULK_PROC_HANDLER +group DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - bulkTransferMessage: + { + bulkTransferId: , + bulkQuoteId: , + payeeFsp: , + payerFsp: , + individualTransfers: [ + { + transferId: , + transferAmount: + { + currency: , + amount: + }, + ilpPacket: , + condition: , + extensionList: { extension: [ + { key: , value: } + ] } + } + ], + extensionList: { extension: [ + { key: , value: } + ] }, + expiration: + } + end note + DFSP1 ->> BULK_API: POST - /bulkTransfers + activate BULK_API + BULK_API -> BULK_API: Validate incoming message\nError codes: 3000-3002, 3100-3107 + loop + BULK_API -> OBJECT_STORE: Persist individual transfers in the bulk to\nobject store: **MLOS.individualTransfers** + activate OBJECT_STORE + OBJECT_STORE --> BULK_API: Return messageId reference to the stored object(s) + deactivate OBJECT_STORE + end + note right of BULK_API #yellow + Message: + { + id: + to: , + from: , + type: "application/json" + content: { + headers: , + payload: { + bulkTransferId: , + bulkQuoteId": , + payerFsp: , + payeeFsp: , + expiration: , + hash: + } + }, + metadata: { + event: { + id: , + type: "bulk-prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULK_API -> TOPIC_BULK_PREPARE: Route & Publish Bulk Prepare event \nfor Payer\nError code: 2003 + activate TOPIC_BULK_PREPARE + TOPIC_BULK_PREPARE <-> TOPIC_BULK_PREPARE: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 + TOPIC_BULK_PREPARE --> BULK_API: Respond replication acknowledgements \nhave been received + deactivate TOPIC_BULK_PREPARE + BULK_API -->> DFSP1: Respond HTTP - 202 (Accepted) + deactivate BULK_API + ||| + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume message + ref over TOPIC_BULK_PREPARE, BULK_PREP_HANDLER, TOPIC_TRANSFER_PREPARE: Bulk Prepare Handler Consume \n + alt Success + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Produce (stream) single transfer message\nfor each individual transfer [loop] + else Failure + BULK_PREP_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk + end + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION: Prepare Handler Consume\n + alt Success + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + else Failure + PREP_HANDLER --> TOPIC_BULK_PROCESSING: Produce message + end + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER, TOPIC_BULK_PROCESSING: Position Handler Consume\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + ||| + TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message + ref over TOPIC_BULK_PROCESSING, BULK_PROC_HANDLER, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume\n + BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** + activate OBJECT_STORE + OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** + deactivate OBJECT_STORE + BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Prepare notification + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** + activate OBJECT_STORE + OBJECT_STORE --> NOTIFY_HANDLER: Return notification(s) payload + deactivate OBJECT_STORE + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send Bulk Prepare notification to Payee + ||| +end +deactivate POS_HANDLER +deactivate BULK_PREP_HANDLER +deactivate PREP_HANDLER +deactivate BULK_PROC_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg new file mode 100644 index 000000000..b24804c17 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg @@ -0,0 +1,788 @@ + + + + + + + + + + + 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + + Financial Service Providers + + + + Bulk API Adapter Service + + + + Central Service + + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + Bulk API Adapter + + + + + Bulk API Adapter + + + + + Bulk API Notification + + + Handler + + + + + Bulk API Notification + + + Handler + + + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + Central Service API + + + + + Central Service API + + + + + + + topic- + + + bulk-prepare + + + + + topic- + + + bulk-prepare + + + Bulk Prepare + + + Handler + + + + + Bulk Prepare + + + Handler + + + + + + + topic- + + + transfer-prepare + + + + + topic- + + + transfer-prepare + + + Prepare Handler + + + + + Prepare Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Bulk Processing + + + Handler + + + + + Bulk Processing + + + Handler + + + + + + + topic- + + + notifications + + + + + topic- + + + notifications + + + + + + DFSP1 sends a Bulk Prepare Transfer request to DFSP2 + + + + + Headers - transferHeaders: { + + + Content-Length: <int>, + + + Content-Type: <string>, + + + Date: <date>, + + + FSPIOP-Source: <string>, + + + FSPIOP-Destination: <string>, + + + FSPIOP-Encryption: <string>, + + + FSPIOP-Signature: <string>, + + + FSPIOP-URI: <uri>, + + + FSPIOP-HTTP-Method: <string> + + + } + + + Payload - bulkTransferMessage: + + + { + + + bulkTransferId: <uuid>, + + + bulkQuoteId: <uuid>, + + + payeeFsp: <string>, + + + payerFsp: <string>, + + + individualTransfers: [ + + + { + + + transferId: <uuid>, + + + transferAmount: + + + { + + + currency: <string>, + + + amount: <string> + + + }, + + + ilpPacket: <string>, + + + condition: <string>, + + + extensionList: { extension: [ + + + { key: <string>, value: <string> } + + + ] } + + + } + + + ], + + + extensionList: { extension: [ + + + { key: <string>, value: <string> } + + + ] }, + + + expiration: <string> + + + } + + + + 1 + + + POST - /bulkTransfers + + + + + 2 + + + Validate incoming message + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + loop + + + + + 3 + + + Persist individual transfers in the bulk to + + + object store: + + + MLOS.individualTransfers + + + + + 4 + + + Return messageId reference to the stored object(s) + + + + + Message: + + + { + + + id: <messageId> + + + to: <payeeFspName>, + + + from: <payerFspName>, + + + type: "application/json" + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + bulkTransferId: <uuid>, + + + bulkQuoteId": <uuid>, + + + payerFsp: <string>, + + + payeeFsp: <string>, + + + expiration: <timestamp>, + + + hash: <string> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: "bulk-prepare", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 5 + + + Route & Publish Bulk Prepare event + + + for Payer + + + Error code: + + + 2003 + + + + + 6 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 7 + + + Respond replication acknowledgements + + + have been received + + + + + 8 + + + Respond HTTP - 202 (Accepted) + + + + + 9 + + + Consume message + + + + + ref + + + Bulk Prepare Handler Consume + + + + + alt + + + [Success] + + + + + 10 + + + Produce (stream) single transfer message + + + for each individual transfer [loop] + + + + [Failure] + + + + + 11 + + + Produce single message for the entire bulk + + + + + 12 + + + Consume message + + + + + ref + + + Prepare Handler Consume + + + + + alt + + + [Success] + + + + + 13 + + + Produce message + + + + [Failure] + + + + + 14 + + + Produce message + + + + + 15 + + + Consume message + + + + + ref + + + Position Handler Consume + + + + + 16 + + + Produce message + + + + + 17 + + + Consume message + + + + + ref + + + Bulk Processing Handler Consume + + + + + 18 + + + Persist bulk message by destination to the + + + object store: + + + MLOS.bulkTransferResults + + + + + 19 + + + Return the reference to the stored + + + notification object(s): + + + messageId + + + + + 20 + + + Send Bulk Prepare notification + + + + + 21 + + + Consume message + + + + + 22 + + + Retrieve bulk notification(s) by reference & destination: + + + MLOS.bulkTransferResults.messageId + destination + + + + + 23 + + + Return notification(s) payload + + + + + ref + + + Send notification to Participant (Payee) + + + + + 24 + + + Send Bulk Prepare notification to Payee + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml new file mode 100644 index 000000000..a9c53292f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml @@ -0,0 +1,320 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declare title +title 1.1.1. Bulk Prepare Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +control "Bulk Prepare \nHandler" as BULK_PREP_HANDLER +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +collections "topic-event" as TOPIC_EVENTS +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING +entity "Bulk DAO" as BULK_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant OBJECT_STORE + participant TOPIC_BULK_PREPARE + participant BULK_PREP_HANDLER + participant TOPIC_TRANSFER_PREPARE + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant BULK_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate BULK_PREP_HANDLER +group Bulk Prepare Handler Consume + TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume Bulk Prepare message + activate TOPIC_BULK_PREPARE + deactivate TOPIC_BULK_PREPARE + group Validate Bulk Prepare Transfer + group Duplicate Check + note right of BULK_PREP_HANDLER #cyan + The Specification doesn't touch on the duplicate handling + of bulk transfers, so the current design mostly follows the + strategy used for individual transfers, except in two places: + + 1. For duplicate requests where hash matches, the current design + includes only the status of the bulk & timestamp (if completed), + but not the individual transfers (for which a GET should be used). + + 2. For duplicate requests where hash matches, but are not in a + finalized state, only the state of the bulkTransfer is sent. + end note + ||| + BULK_PREP_HANDLER -> DB: Request Duplicate Check + ref over BULK_PREP_HANDLER, DB: Request Duplicate Check (using message.content.payload)\n + DB --> BULK_PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break Return TRUE & Log ('Not implemented') + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of BULK_PREP_HANDLER #yellow + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { + extension: [ + { + key: "_cause", + value: + } + ] + } + }, + uriParams: { + id: + } + } + }, + metadata: { + correlationId: , + event: { + id: , + type: "notification", + action: "bulk-prepare", + createdAt: , + state: { + status: "error", + code: "3106", + description: "Modified request" + }, + responseTo: + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 3106 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else hasDuplicateId == FALSE + group Validate Bulk Transfer Prepare Request + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: FSPIOP Source matches Payer + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Check expiration + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Payer and Payee FSP's are different + group Validate Payer + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payee\nError codes: 3203 + end + end + ||| + alt Validate Bulk Transfer Prepare Request (success) + group Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist bulkTransfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + else Validate Bulk Transfer Prepare Request (failure) + group Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Persist transfer + hnote over DB #lightyellow + bulkTransfer + bulkTransferExtension + bulkTransferStateChange + bulkTransferError + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + end + end + end + alt Validate Bulk Prepare Transfer (success) + loop for each individual transfer in the bulk + BULK_PREP_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransfers.messageId** + activate OBJECT_STORE + note right of OBJECT_STORE #lightgrey + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + transfer to make their format similar to a single transfer + end note + OBJECT_STORE --> BULK_PREP_HANDLER: Stream bulk's individual transfers + deactivate OBJECT_STORE + + group Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "prepare", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Route & Publish Prepare event to the Payee for the Individual Transfer\nError codes: 2003 + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + end + else Validate Bulk Prepare Transfer (failure) + note right of BULK_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-abort", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + BULK_PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + group Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 + activate BULK_DAO + BULK_DAO -> DB: Insert bulkTransferAssociation + hnote over DB #lightyellow + bulkTransferAssociation + bulkTransferStateChange + end note + activate DB + deactivate DB + BULK_DAO --> BULK_PREP_HANDLER: Return state + deactivate BULK_DAO + end + + end +end +deactivate BULK_PREP_HANDLER +@enduml + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg new file mode 100644 index 000000000..eb4b20b44 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg @@ -0,0 +1,1009 @@ + + + + + + + + + + + 1.1.1. Bulk Prepare Handler Consume + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + topic- + + + bulk-prepare + + + + + topic- + + + bulk-prepare + + + Bulk Prepare + + + Handler + + + + + Bulk Prepare + + + Handler + + + + + + + topic- + + + transfer-prepare + + + + + topic- + + + transfer-prepare + + + + + topic-event + + + + + topic-event + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic-bulk- + + + processing + + + + + topic-bulk- + + + processing + + + Bulk DAO + + + + + Bulk DAO + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Bulk Prepare Handler Consume + + + + + 1 + + + Consume Bulk Prepare message + + + + + Validate Bulk Prepare Transfer + + + + + Duplicate Check + + + + + The Specification doesn't touch on the duplicate handling + + + of bulk transfers, so the current design mostly follows the + + + strategy used for individual transfers, except in two places: + + + 1. For duplicate requests where hash matches, the current design + + + includes only the status of the bulk & timestamp (if completed), + + + but not the individual transfers (for which a GET should be used). + + + 2. For duplicate requests where hash matches, but are not in a + + + finalized state, only the state of the bulkTransfer is sent. + + + + + 2 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check (using message.content.payload) + + + + + 3 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + [Return TRUE & Log ('Not implemented')] + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + { + + + id: <messageId>, + + + from: <ledgerName>, + + + to: <payerFspName>, + + + type: "application/json", + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + errorInformation: { + + + errorCode: "3106", + + + errorDescription: "Modified request", + + + extensionList: { + + + extension: [ + + + { + + + key: "_cause", + + + value: <FSPIOPError> + + + } + + + ] + + + } + + + }, + + + uriParams: { + + + id: <bulkTransferId> + + + } + + + } + + + }, + + + metadata: { + + + correlationId: <uuid>, + + + event: { + + + id: <uuid>, + + + type: "notification", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: "3106", + + + description: "Modified request" + + + }, + + + responseTo: <uuid> + + + } + + + } + + + } + + + + + 4 + + + Publish Notification (failure) event for Payer + + + Error codes: + + + 3106 + + + + [hasDuplicateId == FALSE] + + + + + Validate Bulk Transfer Prepare Request + + + + + 5 + + + FSPIOP Source matches Payer + + + + + 6 + + + Check expiration + + + + + 7 + + + Payer and Payee FSP's are different + + + + + Validate Payer + + + + + 8 + + + Request to retrieve Payer Participant details (if it exists) + + + + + 9 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 10 + + + Return Participant details if it exists + + + + + 11 + + + Return Participant details if it exists + + + + + 12 + + + Validate Payer + + + Error codes: + + + 3202 + + + + + Validate Payee + + + + + 13 + + + Request to retrieve Payee Participant details (if it exists) + + + + + 14 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 15 + + + Return Participant details if it exists + + + + + 16 + + + Return Participant details if it exists + + + + + 17 + + + Validate Payee + + + Error codes: + + + 3203 + + + + + alt + + + [Validate Bulk Transfer Prepare Request (success)] + + + + + Persist Bulk Transfer State (with bulkTransferState='RECEIVED') + + + + + 18 + + + Request to persist bulk transfer + + + Error codes: + + + 2003 + + + + + 19 + + + Persist bulkTransfer + + + + bulkTransfer + + + bulkTransferExtension + + + bulkTransferStateChange + + + + + 20 + + + Return state + + + + [Validate Bulk Transfer Prepare Request (failure)] + + + + + Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + + + 21 + + + Request to persist bulk transfer + + + (when Payee/Payer/crypto-condition validation fails) + + + Error codes: + + + 2003 + + + + + 22 + + + Persist transfer + + + + bulkTransfer + + + bulkTransferExtension + + + bulkTransferStateChange + + + bulkTransferError + + + + + 23 + + + Return state + + + + + alt + + + [Validate Bulk Prepare Transfer (success)] + + + + + loop + + + [for each individual transfer in the bulk] + + + + + 24 + + + Retrieve individual transfers from the bulk using + + + reference: + + + MLOS.individualTransfers.messageId + + + + + Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each + + + transfer to make their format similar to a single transfer + + + + + 25 + + + Stream bulk's individual transfers + + + + + Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') + + + + + 26 + + + Request to persist bulk transfer association + + + Error codes: + + + 2003 + + + + + 27 + + + Insert bulkTransferAssociation + + + + bulkTransferAssociation + + + bulkTransferStateChange + + + + + 28 + + + Return state + + + + + Message: + + + { + + + id: <messageId> + + + from: <payerFspName>, + + + to: <payeeFspName>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "prepare", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0, + + + description:"action successful" + + + } + + + } + + + } + + + } + + + + + 29 + + + Route & Publish Prepare event to the Payee for the Individual Transfer + + + Error codes: + + + 2003 + + + + [Validate Bulk Prepare Transfer (failure)] + + + + + Message: + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <bulkTransferMessage.payerFsp>, + + + type: "application/json", + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + + + "errorDescription": "<refer to section 7.6 for description>", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "bulk-processing", + + + action: "bulk-abort", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 30 + + + Publish Processing (failure) event for Payer + + + Error codes: + + + 2003 + + + + + Insert Bulk Transfer Association (with bulkProcessingState='INVALID') + + + + + 31 + + + Request to persist bulk transfer association + + + Error codes: + + + 2003 + + + + + 32 + + + Insert bulkTransferAssociation + + + + bulkTransferAssociation + + + bulkTransferStateChange + + + + + 33 + + + Return state + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml new file mode 100644 index 000000000..aee02560a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml @@ -0,0 +1,324 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.2.1. Prepare Handler Consume individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Handler" as PREP_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +collections "topic-\nevent" as TOPIC_EVENTS +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event message + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Validate Event + PREP_HANDLER <-> PREP_HANDLER: Validate event - Rule: type == 'prepare' && action == 'bulk-prepare'\nError codes: 2001 + end + end + + group Persist Event Information + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publish event information + ref over PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + group Validate Prepare Transfer + PREP_HANDLER <-> PREP_HANDLER: Schema validation of the incoming message + PREP_HANDLER <-> PREP_HANDLER: Verify the message's signature (to be confirmed in future requirement) + + group Validate Duplicate Check + ||| + PREP_HANDLER -> DB: Request Duplicate Check + ref over PREP_HANDLER, DB: Request Duplicate Check\n + DB --> PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + note right of PREP_HANDLER #lightgrey + In the context of a bulk (when compared to regular transfers), duplicate + individual transfers are now considered and reported with Modified Request, + because they could have already been handled for another bulk. + end note + break + note right of PREP_HANDLER #yellow + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request - Individual transfer prepare duplicate", + extensionList: { extension: [ { key: "_cause", value: } ] } + } + }, + uriParams: { id: } + }, + metadata: { + correlationId: , + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: , + state: { + code: "3106", + status: "error", + description: "Modified request - Individual transfer prepare duplicate" + }, + id: , + responseTo: + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + break + note right of PREP_HANDLER #yellow + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: { + errorInformation: { + errorCode: "3106", + errorDescription: "Modified request", + extensionList: { extension: [ { key: "_cause", value: } ] } + } + }, + uriParams: { id: } + }, + metadata: { + correlationId: , + event: { + type: "bulk-processing", + action: "prepare-duplicate", + createdAt: , + state: { + code: "3106", + status: "error", + description: "Modified request" + }, + id: , + responseTo: + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else hasDuplicateId == FALSE + note right of PREP_HANDLER #lightgrey + The validation of Payer, Payee can be skipped for individual transfers in Bulk + as they should've/would've been validated already in the bulk prepare part. + However, leaving it here for now, as in the future, this can be leveraged + when bulk transfers to multiple Payees are supported by the Specification. + end note + group Validate Payer + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee\nError codes: 3203 + end + + alt Validate Prepare Transfer (success) + group Persist Transfer State (with transferState='RECEIVED-PREPARE') + PREP_HANDLER -> POS_DAO: Request to persist transfer\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + else Validate Prepare Transfer (failure) + group Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + PREP_HANDLER -> POS_DAO: Request to persist transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + end + end + end + + alt Validate Prepare Transfer (success) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "position", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0, + description:"action successful" + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer\nError codes: 2003 + else Validate Prepare Transfer (failure) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "prepare", + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Prepare failure event to Bulk Processing Topic (for Payer) \nError codes: 2003 + end +end + +deactivate PREP_HANDLER +@enduml + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg new file mode 100644 index 000000000..af0e4479c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg @@ -0,0 +1,975 @@ + + + + + + + + + + + 1.2.1. Prepare Handler Consume individual transfers from Bulk + + + + Central Service + + + + + + + + + + + + + + + + + + + + topic- + + + transfer-prepare + + + + + topic- + + + transfer-prepare + + + Prepare Handler + + + + + Prepare Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic- + + + event + + + + + topic- + + + event + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Position DAO + + + + + Position DAO + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Prepare Handler Consume + + + + + 1 + + + Consume Prepare event message + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'prepare' && action == 'bulk-prepare' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate Prepare Transfer + + + + + 4 + + + Schema validation of the incoming message + + + + + 5 + + + Verify the message's signature (to be confirmed in future requirement) + + + + + Validate Duplicate Check + + + + + 6 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 7 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + In the context of a bulk (when compared to regular transfers), duplicate + + + individual transfers are now considered and reported with Modified Request, + + + because they could have already been handled for another bulk. + + + + + break + + + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <payerFspName>, + + + type: "application/json", + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + errorInformation: { + + + errorCode: "3106", + + + errorDescription: "Modified request - Individual transfer prepare duplicate", + + + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + + + } + + + }, + + + uriParams: { id: <transferId> } + + + }, + + + metadata: { + + + correlationId: <uuid>, + + + event: { + + + type: "bulk-processing", + + + action: "prepare-duplicate", + + + createdAt: <timestamp>, + + + state: { + + + code: "3106", + + + status: "error", + + + description: "Modified request - Individual transfer prepare duplicate" + + + }, + + + id: <uuid>, + + + responseTo: <uuid> + + + } + + + } + + + + + 8 + + + Publish Processing (failure) event for Payer + + + Error codes: + + + 2003 + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + break + + + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <payerFspName>, + + + type: "application/json", + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + errorInformation: { + + + errorCode: "3106", + + + errorDescription: "Modified request", + + + extensionList: { extension: [ { key: "_cause", value: <FSPIOPError> } ] } + + + } + + + }, + + + uriParams: { id: <transferId> } + + + }, + + + metadata: { + + + correlationId: <uuid>, + + + event: { + + + type: "bulk-processing", + + + action: "prepare-duplicate", + + + createdAt: <timestamp>, + + + state: { + + + code: "3106", + + + status: "error", + + + description: "Modified request" + + + }, + + + id: <uuid>, + + + responseTo: <uuid> + + + } + + + } + + + + + 9 + + + Publish Processing (failure) event for Payer + + + Error codes: + + + 2003 + + + + [hasDuplicateId == FALSE] + + + + + The validation of Payer, Payee can be skipped for individual transfers in Bulk + + + as they should've/would've been validated already in the bulk prepare part. + + + However, leaving it here for now, as in the future, this can be leveraged + + + when bulk transfers to multiple Payees are supported by the Specification. + + + + + Validate Payer + + + + + 10 + + + Request to retrieve Payer Participant details (if it exists) + + + + + 11 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 12 + + + Return Participant details if it exists + + + + + 13 + + + Return Participant details if it exists + + + + + 14 + + + Validate Payer + + + Error codes: + + + 3202 + + + + + Validate Payee + + + + + 15 + + + Request to retrieve Payee Participant details (if it exists) + + + + + 16 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 17 + + + Return Participant details if it exists + + + + + 18 + + + Return Participant details if it exists + + + + + 19 + + + Validate Payee + + + Error codes: + + + 3203 + + + + + alt + + + [Validate Prepare Transfer (success)] + + + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + + + 20 + + + Request to persist transfer + + + Error codes: + + + 2003 + + + + + 21 + + + Persist transfer + + + + transfer + + + transferParticipant + + + transferStateChange + + + transferExtension + + + ilpPacket + + + + + 22 + + + Return success + + + + [Validate Prepare Transfer (failure)] + + + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + + + 23 + + + Request to persist transfer + + + (when Payee/Payer/crypto-condition validation fails) + + + Error codes: + + + 2003 + + + + + 24 + + + Persist transfer + + + + transfer + + + transferParticipant + + + transferStateChange + + + transferExtension + + + transferError + + + ilpPacket + + + + + 25 + + + Return success + + + + + alt + + + [Validate Prepare Transfer (success)] + + + + + Message: + + + { + + + id: <messageId> + + + from: <payerFspName>, + + + to: <payeeFspName>, + + + type: "application/json", + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "position", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0, + + + description:"action successful" + + + } + + + } + + + } + + + } + + + + + 26 + + + Route & Publish Position event for Payer + + + Error codes: + + + 2003 + + + + [Validate Prepare Transfer (failure)] + + + + + Message: + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <payerFspName>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + + + "errorDescription": "<refer to section 35.1.3 for description>", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "bulk-processing", + + + action: "prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 27 + + + Publish Prepare failure event to Bulk Processing Topic (for Payer) + + + Error codes: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml new file mode 100644 index 000000000..44d640284 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Position Handler Consume individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + alt Consume Prepare message for Payer + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'bulk-prepare'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS: Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Prepare Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Fulfil message for Payee + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'bulk-commit'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Fulfil Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Abort message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'timeout-reserved'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Abort Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg new file mode 100644 index 000000000..a6c1ce040 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg @@ -0,0 +1,298 @@ + + + + + + + + + + + 1.3.0. Position Handler Consume individual transfers from Bulk + + + + Central Service + + + + + + + + + + + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + Position Handler Consume + + + + + alt + + + [Consume Prepare message for Payer] + + + + + 1 + + + Consume Position event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'position' && action == 'bulk-prepare' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Prepare Position Handler Consume + + + + + 4 + + + Produce message + + + + [Consume Fulfil message for Payee] + + + + + 5 + + + Consume Position event message for Payee + + + + + break + + + + + Validate Event + + + + + 6 + + + Validate event - Rule: type == 'position' && action == 'bulk-commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 7 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Fulfil Position Handler Consume + + + + + 8 + + + Produce message + + + + [Consume Abort message] + + + + + 9 + + + Consume Position event message + + + + + break + + + + + Validate Event + + + + + 10 + + + Validate event - Rule: type == 'position' && action == 'timeout-reserved' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 11 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Abort Position Handler Consume + + + + + 12 + + + Produce message + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml new file mode 100644 index 000000000..370eaf388 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml @@ -0,0 +1,365 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER + +entity "Position\nManagement\nFacade" as POS_MGMT +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_MGMT + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Prepare Position Handler Consume + POS_HANDLER -> POS_MGMT: Request transfers to be processed + activate POS_MGMT + POS_MGMT -> POS_MGMT: Check 1st transfer to select the Participant and Currency + group DB TRANSACTION + ' DB Trans: This is where 1st DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT -> POS_MGMT: Loop through batch and build list of transferIds and calculate sumTransfersInBatch,\nchecking all in Batch are for the correct Paricipant and Currency\nError code: 2001, 3100 + POS_MGMT -> DB: Retrieve current state of all transfers in array from DB with select whereIn\n(FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_MGMT: Return current state of all selected transfers from DB + deactivate DB + POS_MGMT <-> POS_MGMT: Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nError code: 2001 against failing transfers\nBatch is not rejected as a whole. + + note right of POS_MGMT #lightgray + List of transfers used during processing + **reservedTransfers** is list of transfers to be processed in the batch + **abortedTransfers** is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + **processedTransfers** is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + Scalar intermidate values used in the algorithm + **transferAmount** = payload.amount.amount + **sumTransfersInBatch** = SUM amount against each Transfer in batch + **currentPosition** = participantPosition.value + **reservedPosition** = participantPosition.{original}reservedValue + **effectivePosition** = currentPosition + reservedPosition + **heldPosition** = effectivePosition + sumTransfersInBatch + **availablePosition** = participantLimit(NetDebitCap) - effectivePosition + **sumReserved** = SUM of transfers that have met rule criteria and processed + end note + note over POS_MGMT,DB + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + end note + POS_MGMT -> DB: Select effectivePosition FOR UPDATE from DB for Payer + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_MGMT: Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + deactivate DB + POS_MGMT -> POS_MGMT: Increment reservedValue to heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) + POS_MGMT -> DB: Persist reservedValue + activate DB + hnote over DB #lightyellow + UPDATE **participantPosition** + SET reservedValue += sumTransfersInBatch + end note + deactivate DB + ' DB Trans: This is where 1st DB Transaction would end in 2 DB transacation future model for horizontal scaling + + + POS_MGMT -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + FROM **participantLimit** + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + end note + DB --> POS_MGMT: Return position limits + deactivate DB + POS_MGMT <-> POS_MGMT: **availablePosition** = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) + note over POS_MGMT,DB + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + end note + POS_MGMT <-> POS_MGMT: Validate availablePosition for each tranfser (see algorithm below)\nError code: 4001 + note right of POS_MGMT #lightgray + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far **(NEED TO UPDATE IN CODE)** + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(NEED TO UPDATE IN CODE)** // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + end note + note over POS_MGMT,DB + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + end note + POS_MGMT->POS_MGMT: Assess any limit thresholds on the final position\nadding to alarm list if triggered + + ' DB Trans: This is where 2nd DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT->DB: Persist latest position **value** and **reservedValue** to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + end note + activate DB + deactivate DB + + POS_MGMT -> DB: Bulk persist transferStateChange for all processedTransfers + hnote over DB #lightyellow + batch INSERT **transferStateChange** + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch + + end note + activate DB + deactivate DB + + POS_MGMT->POS_MGMT: Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + note right of POS_MGMT #lightgray + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + end note + POS_MGMT -> DB: Bulk persist the participant position change for all processedTransfers + hnote over DB #lightyellow + batch INSERT **participantPositionChange** + end note + activate DB + deactivate DB + ' DB Trans: This is where 2nd DB Transaction would end in 2 DB transacation future model for horizontal scaling + end + POS_MGMT --> POS_HANDLER: Return a map of transferIds and their transferStateChanges + deactivate POS_MGMT + alt Calculate & Validate Latest Position Prepare (success) + POS_HANDLER -> POS_HANDLER: Notifications for Position Validation Success \nReference: Position Validation Success case (Prepare) + else Calculate & Validate Latest Position Prepare (failure) + note right of POS_HANDLER #red: Validation failure! + + group Persist Transfer State (with transferState='ABORTED' on position check fail) + POS_HANDLER -> POS_DAO: Request to persist transfer\nError code: 2003 + activate POS_DAO + note right of POS_HANDLER #lightgray + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + end note + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + POS_HANDLER -> POS_HANDLER: Notifications for failures\nReference: Failure in Position Validation (Prepare) + end +end + + +group Reference: Failure in Position Validation (Prepare) + alt If action == 'bulk-prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-prepare", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Position failure event (in Prepare) to Bulk Processing Topic (for Payer) \nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If action == 'prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "position", + createdAt: , + state: { + status: "error", + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + +end + +group Reference: Position Validation Success case (Prepare) + alt If action == 'bulk-prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-prepare", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Position Success event (in Prepare) to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If action == 'prepare' + note right of POS_HANDLER #yellow + Message: + { + id: "" + from: , + to: , + type: "application/json" + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "notification", + action: "abort", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg new file mode 100644 index 000000000..1403dc6ab --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg @@ -0,0 +1,1092 @@ + + + + + + + + + + + 1.3.1. Prepare Position Handler Consume (single message, includes individual transfers from Bulk) + + + + Central Service + + + + + + + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Position + + + Management + + + Facade + + + + + Position + + + Management + + + Facade + + + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Prepare Position Handler Consume + + + + + 1 + + + Request transfers to be processed + + + + + 2 + + + Check 1st transfer to select the Participant and Currency + + + + + DB TRANSACTION + + + + + 3 + + + Loop through batch and build list of transferIds and calculate sumTransfersInBatch, + + + checking all in Batch are for the correct Paricipant and Currency + + + Error code: + + + 2001, 3100 + + + + + 4 + + + Retrieve current state of all transfers in array from DB with select whereIn + + + (FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + + + + transferStateChange + + + transferParticipant + + + + + 5 + + + Return current state of all selected transfers from DB + + + + + 6 + + + Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + + + Error code: + + + 2001 + + + against failing transfers + + + Batch is not rejected as a whole. + + + + + List of transfers used during processing + + + reservedTransfers + + + is list of transfers to be processed in the batch + + + abortedTransfers + + + is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + + + processedTransfers + + + is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + + Scalar intermidate values used in the algorithm + + + transferAmount + + + = payload.amount.amount + + + sumTransfersInBatch + + + = SUM amount against each Transfer in batch + + + currentPosition + + + = participantPosition.value + + + reservedPosition + + + = participantPosition.{original}reservedValue + + + effectivePosition + + + = currentPosition + reservedPosition + + + heldPosition + + + = effectivePosition + sumTransfersInBatch + + + availablePosition + + + = participantLimit(NetDebitCap) - effectivePosition + + + sumReserved + + + = SUM of transfers that have met rule criteria and processed + + + + + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + + + and calculate the available position for the Participant to use + + + + + 7 + + + Select effectivePosition FOR UPDATE from DB for Payer + + + + participantPosition + + + + + 8 + + + Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + + + + + 9 + + + Increment reservedValue to heldPosition + + + (reservedValue = reservedPosition + sumTransfersInBatch) + + + + + 10 + + + Persist reservedValue + + + + UPDATE + + + participantPosition + + + SET reservedValue += sumTransfersInBatch + + + + + 11 + + + Request position limits for Payer Participant + + + + FROM + + + participantLimit + + + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + + + AND participantLimit.participantId = payload.payerFsp + + + AND participantLimit.currencyId = payload.amount.currency + + + + + 12 + + + Return position limits + + + + + 13 + + + availablePosition + + + = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) + + + + + For each transfer in the batch, validate the availablility of position to meet the transfer amount + + + this will be as per the position algorithm documented below + + + + + 14 + + + Validate availablePosition for each tranfser (see algorithm below) + + + Error code: + + + 4001 + + + + + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + + + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + + + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + + + 04: foreach transfer in reservedTransfers + + + 05: sumProcessed += transfer.amount // the total processed so far + + + (NEED TO UPDATE IN CODE) + + + 06: if availablePosition >= transfer.amount + + + 07: transfer.state = "RESERVED" + + + 08: availablePosition -= preparedTransfer.amount + + + 09: sumRESERVED += preparedTransfer.amount + + + 10: else + + + 11: preparedTransfer.state = "ABORTED" + + + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 13: end if + + + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + + + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + + + (NEED TO UPDATE IN CODE) + + + // the running down of the total reserved value at the begining of the batch. + + + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + + + 16: end foreach + + + + + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + + + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + + + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + + + + + 15 + + + Assess any limit thresholds on the final position + + + adding to alarm list if triggered + + + + + 16 + + + Persist latest position + + + value + + + and + + + reservedValue + + + to DB for Payer + + + + UPDATE + + + participantPosition + + + SET value += sumRESERVED, + + + reservedValue -= sumTransfersInBatch + + + + + 17 + + + Bulk persist transferStateChange for all processedTransfers + + + + batch INSERT + + + transferStateChange + + + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + + + build list of transferStateChanges from transferBatch + + + + + 18 + + + Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + + + + Effectively: + + + SET transferStateChangeId = processedTransfer.transferStateChangeId, + + + participantPositionId = preparedTransfer.participantPositionId, + + + value = preparedTransfer.positionValue, + + + reservedValue = preparedTransfer.positionReservedValue + + + + + 19 + + + Bulk persist the participant position change for all processedTransfers + + + + batch INSERT + + + participantPositionChange + + + + + 20 + + + Return a map of transferIds and their transferStateChanges + + + + + alt + + + [Calculate & Validate Latest Position Prepare (success)] + + + + + 21 + + + Notifications for Position Validation Success + + + Reference: Position Validation Success case (Prepare) + + + + [Calculate & Validate Latest Position Prepare (failure)] + + + + + Validation failure! + + + + + Persist Transfer State (with transferState='ABORTED' on position check fail) + + + + + 22 + + + Request to persist transfer + + + Error code: + + + 2003 + + + + + transferStateChange.state = "ABORTED", + + + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + + + 23 + + + Persist transfer state + + + + transferStateChange + + + + + 24 + + + Return success + + + + + 25 + + + Notifications for failures + + + Reference: Failure in Position Validation (Prepare) + + + + + Reference: Failure in Position Validation (Prepare) + + + + + alt + + + [If action == 'bulk-prepare'] + + + + + Message: + + + { + + + id: "<messageId>" + + + from: <ledgerName>, + + + to: <transferMessage.payerFsp>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 4001, + + + "errorDescription": "Payer FSP insufficient liquidity", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "bulk-processing", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 26 + + + Publish Position failure event (in Prepare) to Bulk Processing Topic (for Payer) + + + Error codes: + + + 2003 + + + + [If action == 'prepare'] + + + + + Message: + + + { + + + id: "<messageId>" + + + from: <ledgerName>, + + + to: <transferMessage.payerFsp>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 4001, + + + "errorDescription": "Payer FSP insufficient liquidity", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "notification", + + + action: "position", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 27 + + + Publish Notification (failure) event for Payer + + + Error code: + + + 2003 + + + + + Reference: Position Validation Success case (Prepare) + + + + + alt + + + [If action == 'bulk-prepare'] + + + + + Message: + + + { + + + id: "<messageId>" + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "bulk-processing", + + + action: "bulk-prepare", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 28 + + + Publish Position Success event (in Prepare) to Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [If action == 'prepare'] + + + + + Message: + + + { + + + id: "<messageId>" + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "notification", + + + action: "abort", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 29 + + + Publish Notification event + + + Error code: + + + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml rename to legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg new file mode 100644 index 000000000..fa4186d7d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg @@ -0,0 +1,860 @@ + + + + + + + + + + + 1.4.0. Bulk Processing Handler Consume + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + topic-bulk- + + + processing + + + + + topic-bulk- + + + processing + + + Bulk Processing + + + Handler + + + + + Bulk Processing + + + Handler + + + + + + + topic-event + + + + + topic-event + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + topic-notification + + + + + topic-notification + + + Bulk DAO + + + + + Bulk DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Bulk Processing Handler Consume + + + + + 1 + + + Consume message + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: + + + type == 'bulk-processing' && action IN + + + ['prepare-duplicate', 'bulk-prepare', + + + 'bulk-timeout-received', 'fulfil-duplicate', + + + 'bulk-commit', 'bulk-timeout-reserved'] + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Process Message + + + + + 4 + + + Retrieve current state of Bulk Transfer + + + + + 5 + + + Retrieve current state of Bulk Transfer + + + + bulkTransfer + + + bulkTransferStateChange + + + + + 6 + + + Return + + + bulkTransferInfo + + + + + 7 + + + Return + + + bulkTransferInfo + + + + + Validate Bulk Transfer State + + + + + Initialize variables + + + : + + + let criteriaState + + + let incompleteBulkState + + + let completedBulkState + + + let bulkTransferState + + + let processingState + + + let errorCode, errorMessage + + + let produceNotification = false + + + + + alt + + + [bulkTransferInfo.bulkTransferState IN ['RECEIVED', 'PENDING_PREPARE']] + + + + + criteriaState = 'RECEIVED' + + + incompleteBulkState = 'PENDING_PREPARE' + + + completedBulkState = 'ACCEPTED' + + + + + alt + + + [action == 'prepare-duplicate' AND state.status == 'error'] + + + + + processingState = 'RECEIVED_DUPLICATE' + + + errorCode = payload.errorInformation.errorCode + + + errorDescription = payload.errorInformation.errorDescription + + + + [action == 'bulk-prepare' AND state.status == 'error'] + + + + + processingState = 'RECEIVED_INVALID' + + + errorCode = payload.errorInformation.errorCode + + + errorDescription = payload.errorInformation.errorDescription + + + + [action == 'bulk-prepare' AND state.status == 'success'] + + + + + processingState = 'ACCEPTED' + + + + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + + + incompleteBulkState = 'EXPIRING' + + + completedBulkState = 'COMPLETED' + + + processingState = 'EXPIRED' + + + errorCode = payload.errorInformation.errorCode + + + errorDescription = payload.errorInformation.errorDescription + + + + [all other actions] + + + + + throw + + + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + + [bulkTransferInfo.bulkTransferState IN ['ACCEPTED']] + + + + + alt + + + [action == 'bulk-timeout-reserved'] + + + + + criteriaState = 'ACCEPTED' + + + incompleteBulkState = 'EXPIRING' + + + completedBulkState = 'COMPLETED' + + + processingState = 'EXPIRED' + + + + [all other actions] + + + + + throw + + + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + + [bulkTransferInfo.bulkTransferState IN ['PROCESSING', 'PENDING_FULFIL', 'EXPIRING']] + + + + + criteriaState = 'PROCESSING' + + + incompleteBulkState = 'PENDING_FULFIL' + + + completedBulkState = 'COMPLETED' + + + + + alt + + + [action == 'fulfil-duplicate'] + + + + + processingState = 'FULFIL_DUPLICATE' + + + + [action == 'bulk-commit' AND state.status == 'success'] + + + + + processingState = 'COMPLETED' + + + + [action == 'reject' AND state.status == 'success'] + + + + + processingState = 'REJECTED' + + + + [action IN ['commit', 'abort'] AND state.status == 'error'] + + + + + processingState = 'FULFIL_INVALID' + + + + [action == 'bulk-timeout-reserved'] + + + + + incompleteBulkState = 'EXPIRING' + + + completedBulkState = 'COMPLETED' + + + processingState = 'EXPIRED' + + + errorCode = payload.errorInformation.errorCode + + + errorDescription = payload.errorInformation.errorDescription + + + + [all other actions] + + + + + throw + + + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + + [all other ['PENDING_INVALID', 'COMPLETED', 'REJECTED', 'INVALID']] + + + + + throw + + + ErrorHandler.Factory.createFSPIOPError(INTERNAL_SERVER_ERROR) + + + + + 8 + + + Persist individual transfer processing state + + + + + 9 + + + Persist individual transfer processing state + + + -- store errorCode/errorMessage when + + + state.status == 'error' + + + + bulkTransferAssociation + + + + + 10 + + + Return success + + + + + 11 + + + Check previously defined completion criteria + + + + + 12 + + + Select EXISTS (LIMIT 1) in criteriaState + + + + bulkTransferAssociation + + + + + 13 + + + Return + + + existingIndividualTransfer + + + + + 14 + + + Return + + + existingIndividualTransfer + + + + + alt + + + [individual transfer exists] + + + + + bulkTransferState = incompleteBulkState + + + + [no transfer in criteriaState exists] + + + + + bulkTransferState = completedBulkState + + + produceNotification = true + + + + + 15 + + + Persist bulkTransferState from previous step + + + + + 16 + + + Persist bulkTransferState + + + + bulkTransferStateChange + + + + + 17 + + + Return success + + + + + alt + + + [produceNotification == true] + + + + + 18 + + + Request to retrieve all bulk transfer and individual transfer results + + + + + 19 + + + Get bulkTransferResult + + + + bulkTransfer + + + bulkTransferStateChange + + + bulkTransferAssociation + + + + + 20 + + + Return + + + bulkTransferResult + + + + + 21 + + + Return + + + bulkTransferResult + + + + + Send Bulk Notification(s) + + + + + Depending on the action decide where to + + + send notification: payer, payee OR both + + + + + 22 + + + Generate & Persist bulk message to object store: + + + MLOS.bulkTransferResults + + + by destination + + + + + 23 + + + Return reference to the stored object(s) + + + MLOS.bulkTransferResults.messageId + + + + + Message: + + + { + + + id: <messageId> + + + from: <source>, + + + to: <destination>, + + + type: "application/json" + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + bulkTransferId: <uuid>, + + + bulkTransferState: <string> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "notification", + + + action: "bulk-[prepare | commit | abort | processing]", + + + createdAt: <timestamp>, + + + state: { + + + status: state.status, + + + code: state.code + + + } + + + } + + + } + + + } + + + + + 24 + + + Publish Notification event for Payer/Payee + + + Error codes: + + + 2003 + + + + [produceNotification == false] + + + + + Do nothing (awaitAllTransfers) + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml rename to legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg new file mode 100644 index 000000000..90d6889fc --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg @@ -0,0 +1,835 @@ + + + + + + + + + + + 2.1.0. DFSP2 sends a Bulk Fulfil Success Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API + + + Notification Handler + + + + + ML API + + + Notification Handler + + + + + + + mongo- + + + object-store + + + + + mongo- + + + object-store + + + Central Service API + + + + + Central Service API + + + + + + + topic- + + + bulk-fulfil + + + + + topic- + + + bulk-fulfil + + + Bulk Fulfil + + + Handler + + + + + Bulk Fulfil + + + Handler + + + + + + + topic- + + + fulfil + + + + + topic- + + + fulfil + + + Fulfil + + + Handler + + + + + Fulfil + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + Position + + + Handler + + + + + Position + + + Handler + + + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Bulk Processing + + + Handler + + + + + Bulk Processing + + + Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + + DFSP2 sends a Bulk Fulfil Success Transfer request to DFSP1 + + + + + Headers - transferHeaders: { + + + Content-Length: <int>, + + + Content-Type: <string>, + + + Date: <date>, + + + FSPIOP-Source: <string>, + + + FSPIOP-Destination: <string>, + + + FSPIOP-Encryption: <string>, + + + FSPIOP-Signature: <string>, + + + FSPIOP-URI: <uri>, + + + FSPIOP-HTTP-Method: <string> + + + } + + + Payload - bulkTransferMessage: + + + { + + + bulkTransferState: <bulkTransferState>, + + + completedTimestamp: <completedTimeStamp>, + + + individualTransferResults: + + + [ + + + { + + + transferId: <uuid>, + + + fulfilment: <ilpCondition>, + + + extensionList: { extension: [ + + + { key: <string>, value: <string> } + + + ] } + + + } + + + ], + + + extensionList: { extension: [ + + + { key: <string>, value: <string> } + + + ] } + + + } + + + + 1 + + + PUT - /bulkTransfers/<ID> + + + + + 2 + + + Validate incoming message + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + 3 + + + Persist incoming bulk message to + + + object store: + + + MLOS.individualTransferFulfils + + + + + 4 + + + Return messageId reference to the stored object(s) + + + + + Message: + + + { + + + id: <messageId>, + + + from: <payeeFspName>, + + + to: <payerFspName>, + + + type: "application/json", + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + bulkTransferId: <uuid>, + + + bulkTransferState: "COMPLETED", + + + completedTimestamp: <timestamp>, + + + extensionList: { extension: [ + + + { key: <string>, value: <string> } + + + ] }, + + + count: <int>, + + + hash: <string> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: "bulk-fulfil", + + + action: "bulk-commit", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 5 + + + Route & Publish Bulk Fulfil event for Payee + + + Error code: + + + 2003 + + + + + 6 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 7 + + + Respond replication acknowledgements + + + have been received + + + + + 8 + + + Respond HTTP - 200 (OK) + + + + + 9 + + + Consume message + + + + + 10 + + + Retrieve individual transfers by key: + + + MLOS.individualTransferFulfils.messageId + + + + + 11 + + + Stream bulk's individual transfers + + + + + ref + + + Bulk Prepare Handler Consume + + + + + alt + + + [Success] + + + + + 12 + + + Produce (stream) single transfer message + + + for each individual transfer [loop] + + + + [Failure] + + + + + 13 + + + Produce single message for the entire bulk + + + + + 14 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Success) + + + + + alt + + + [Success] + + + + + 15 + + + Produce message + + + + [Failure] + + + + + 16 + + + Produce message + + + + + 17 + + + Consume message + + + + + ref + + + Position Handler Consume (Success) + + + + + 18 + + + Produce message + + + + + 19 + + + Consume message + + + + + ref + + + Bulk Processing Handler Consume (Success) + + + + + 20 + + + Persist bulk message by destination to the + + + object store: + + + MLOS.bulkTransferResults + + + + + 21 + + + Return the reference to the stored + + + notification object(s): + + + messageId + + + + + 22 + + + Send Bulk Commit notification + + + + + 23 + + + Consume message + + + + + 24 + + + Retrieve bulk notification(s) by reference & destination: + + + MLOS.bulkTransferResults.messageId + destination + + + + + 25 + + + Return notification payload + + + + + opt + + + [action == 'bulk-commit'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 26 + + + Send callback notification + + + + + 27 + + + Consume message + + + + + 28 + + + Retrieve bulk notification(s) by reference & destination: + + + MLOS.bulkTransferResults.messageId + destination + + + + + 29 + + + Return notification payload + + + + + opt + + + [action == 'bulk-commit'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 30 + + + Send callback notification + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml rename to legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg new file mode 100644 index 000000000..bb328dce5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg @@ -0,0 +1,954 @@ + + + + + + + + + + + 2.1.1. Bulk Fulfil Handler Consume + + + + Central Service + + + + + + + + + + + + + + + + + + + mongo- + + + object-store + + + + + mongo- + + + object-store + + + + + topic-bulk- + + + fulfil + + + + + topic-bulk- + + + fulfil + + + Bulk Fulfil + + + Handler + + + + + Bulk Fulfil + + + Handler + + + + + + + topic-transfer- + + + fulfil + + + + + topic-transfer- + + + fulfil + + + + + topic-bulk- + + + processing + + + + + topic-bulk- + + + processing + + + + + topic-event + + + + + topic-event + + + + + topic-notification + + + + + topic-notification + + + Bulk DAO + + + + + Bulk DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Bulk Fulfil Handler Consume + + + + + 1 + + + Consume message + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: + + + type == 'bulk-fulfil' && action == 'bulk-commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate FSPIOP-Signature + + + + + ref + + + Validate message.content.headers. + + + FSPIOP-Signature + + + Error codes: + + + 3105/3106 + + + + + Validate Bulk Fulfil Transfer + + + + + 4 + + + Schema validation of the incoming message + + + + + 5 + + + Verify the message's signature + + + (to be confirmed in future requirement) + + + + + The above validation steps are already handled by the + + + Bulk-API-Adapter for the open source implementation. + + + It may need to be added in future for custom adapters. + + + + + Validate Duplicate Check + + + + + 6 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 7 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + + + 8 + + + Request to retrieve Bulk Transfer state & completedTimestamp + + + Error code: + + + 2003 + + + + + 9 + + + Query database + + + + bulkTransfer + + + bulkTransferFulfilment + + + bulkTransferStateChange + + + + + 10 + + + Return resultset + + + + + 11 + + + Return + + + bulkTransferStateId + + + & + + + completedTimestamp + + + (not null when completed) + + + + + Message: + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <payeeFspName>, + + + type: application/json + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + bulkTransferState: <string>, + + + completedTimestamp: <optional> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "notification", + + + action: "bulk-fulfil-duplicate", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 12 + + + Publish Notification event for Payee + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + { + + + id: <messageId>, + + + from: <ledgerName", + + + to: <payeeFspName>, + + + type: "application/json", + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + errorInformation: { + + + errorCode: "3106", + + + errorDescription: "Modified request", + + + extensionList: { + + + extension: [ + + + { + + + key: "_cause", + + + value: <FSPIOPError> + + + } + + + ] + + + } + + + }, + + + uriParams: { + + + id: <bulkTransferId> + + + } + + + } + + + }, + + + metadata: { + + + correlationId: <uuid>, + + + event: { + + + id: <uuid>, + + + type: "notification", + + + action: "bulk-commit", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: "3106", + + + description: "Modified request" + + + }, + + + responseTo: <uuid> + + + } + + + } + + + } + + + + + 13 + + + Publish Notification (failure) event for Payer + + + Error codes: + + + 3106 + + + + [hasDuplicateId == FALSE] + + + + + alt + + + [Validate Bulk Transfer Fulfil (success)] + + + + + Persist Bulk Transfer State (with bulktransferState='PROCESSING') + + + + + 14 + + + Request to persist bulk transfer fulfil + + + Error codes: + + + 2003 + + + + + 15 + + + Persist bulkTransferFulfilment + + + + bulkTransferFulfilment + + + bulkTransferStateChange + + + bulkTransferExtension + + + + + 16 + + + Return success + + + + [Validate Bulk Transfer Fulfil (failure)] + + + + + Persist Bulk Transfer State (with bulkTransferState='INVALID/REJECTED') + + + + + 17 + + + Request to persist bulk + + + transfer fulfil failure + + + Error codes: + + + 2003 + + + + + 18 + + + Persist transfer + + + + bulkTransferFulfilment + + + bulkTransferStateChange + + + bulkTransferExtension + + + bulkTransferError + + + + + 19 + + + Return success + + + + + alt + + + [Validate Bulk Transfer Fulfil (success)] + + + + + loop + + + [for every individual transfer in the bulk fulfil list] + + + + + 20 + + + Retrieve individual transfers from the bulk using + + + reference: + + + MLOS.individualTransferFulfils.messageId + + + + + 21 + + + Stream bulk's individual transfer fulfils + + + + + Message: + + + { + + + id: <messageId> + + + from: <payeeFspName>, + + + to: <payerFspName>, + + + type: "application/json" + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "fulfil", + + + action: "bulk-commit", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 22 + + + Route & Publish Prepare event to the Payer for the Individual Transfer + + + Error codes: + + + 2003 + + + + [Validate Bulk Transfer Fulfil (failure)] + + + + + Message: + + + { + + + id: <messageId> + + + from: <ledgerName>, + + + to: <payerFspName>, + + + type: "application/json" + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + + + "errorDescription": "<refer to section 35.1.3 for description>", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "notification", + + + action: "bulk-abort", + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 23 + + + Publish Notification (failure) event for Payer + + + Error codes: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml new file mode 100644 index 000000000..b53afd2e5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml @@ -0,0 +1,236 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Handler" as FULF_HANDLER +collections "topic-\nevent" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position DAO" as POS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_BULK_PROCESSING + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Success) + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && action == 'bulk-commit'\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 3105/3106\n + ||| + end + + group Validate Duplicate Check + ||| + FULF_HANDLER -> DB: Request Duplicate Check + ref over FULF_HANDLER, DB: Request Duplicate Check\n + DB --> FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of FULF_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + + end + + group Validate and persist Transfer Fulfilment + FULF_HANDLER -> POS_DAO: Request information for the validate checks\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return transfer + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + FULF_HANDLER -> FULF_HANDLER: Validate expirationDate\nError code: 3303 + + opt Transfer.ilpCondition validate successful + group Request current Settlement Window + FULF_HANDLER -> POS_DAO: Request to retrieve current/latest transfer settlement window\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return settlementWindowId to be appended during transferFulfilment insert\n**TODO**: During settlement design make sure transfers in 'RECEIVED-FULFIL'\nstate are updated to the next settlement window + deactivate POS_DAO + end + end + + group Persist fulfilment + FULF_HANDLER -> POS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Return success + deactivate POS_DAO + end + + alt Transfer.ilpCondition validate successful + group Persist Transfer State (with transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "position", + action: "bulk-commit", + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful + break + FULF_HANDLER -> FULF_HANDLER: Route & Publish Notification event for Payee\nReference: Failure in validation + end + end + end +end + +group Reference: Failure in validation + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: "application/json", + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: "bulk-processing", + action: "bulk-commit", + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING +end + +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg new file mode 100644 index 000000000..b89824971 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg @@ -0,0 +1,726 @@ + + + + + + + + + + + 2.2.1. Fulfil Handler Consume (Success) individual transfers from Bulk + + + + Central Service + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Handler + + + + + Fulfil Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic- + + + event + + + + + topic- + + + event + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + + + topic- + + + notification + + + + + topic- + + + notification + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Handler Consume (Success) + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'fulfil' && action == 'bulk-commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate FSPIOP-Signature + + + + + ref + + + Validate message.content.headers. + + + FSPIOP-Signature + + + Error codes: + + + 3105/3106 + + + + + Validate Duplicate Check + + + + + 4 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 5 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + + + 6 + + + stateRecord = await getTransferState(transferId) + + + + + alt + + + [endStateList.includes(stateRecord.transferStateId)] + + + + + ref + + + getTransfer callback + + + + + 7 + + + Produce message + + + + + + Ignore - resend in progress + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + Validate Prepare Transfer (failure) - Modified Request + + + + [hasDuplicateId == FALSE] + + + + + Validate and persist Transfer Fulfilment + + + + + 8 + + + Request information for the validate checks + + + Error code: + + + 2003 + + + + + 9 + + + Fetch from database + + + + transfer + + + + + 10 + + + + + 11 + + + Return transfer + + + + + 12 + + + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + + + Error code: + + + 2001 + + + + + 13 + + + Validate expirationDate + + + Error code: + + + 3303 + + + + + opt + + + [Transfer.ilpCondition validate successful] + + + + + Request current Settlement Window + + + + + 14 + + + Request to retrieve current/latest transfer settlement window + + + Error code: + + + 2003 + + + + + 15 + + + Fetch settlementWindowId + + + + settlementWindow + + + + + 16 + + + + + 17 + + + Return settlementWindowId to be appended during transferFulfilment insert + + + TODO + + + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + + + state are updated to the next settlement window + + + + + Persist fulfilment + + + + + 18 + + + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + + + Error code: + + + 2003 + + + + + 19 + + + Persist to database + + + + transferFulfilment + + + transferExtension + + + + + 20 + + + Return success + + + + + alt + + + [Transfer.ilpCondition validate successful] + + + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + + + 21 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 22 + + + Persist transfer state + + + + transferStateChange + + + + + 23 + + + Return success + + + + + Message: + + + { + + + id: <messageId>, + + + from: <payeeFspName>, + + + to: <payerFspName>, + + + type: "application/json", + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "position", + + + action: "bulk-commit", + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 24 + + + Route & Publish Position event for Payee + + + + [Validate Fulfil Transfer not successful] + + + + + break + + + + + 25 + + + Route & Publish Notification event for Payee + + + Reference: Failure in validation + + + + + Reference: Failure in validation + + + + + Message: + + + { + + + id: <messageId>, + + + from: <ledgerName>, + + + to: <payeeFspName>, + + + type: "application/json", + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: "bulk-processing", + + + action: "bulk-commit", + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 26 + + + Publish Notification event for Payee to Bulk Processing Topic + + + Error codes: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml new file mode 100644 index 000000000..a90928354 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml @@ -0,0 +1,616 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-\nfulfil" as TOPIC_FULFIL +control "Fulfil Handler" as FULF_HANDLER +collections "topic-\nevent" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_BULK_PROCESSING + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Failure) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type IN ['fulfil','bulk-fulfil'] && ( action IN ['reject','abort'] )\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 2001 + end + group Validate Transfer Fulfil Duplicate Check + FULF_HANDLER -> FULF_HANDLER: Generate transferFulfilmentId uuid + FULF_HANDLER -> TRANS_DAO: Request to retrieve transfer fulfilment hashes by transferId\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request Transfer fulfilment \nduplicate message hashes + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Return existing hashes + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return (list of) transfer fulfil messages hash(es) + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Loop the list of returned hashes & compare \neach entry with the calculated message hash + alt Hash matched + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Request to retrieve Transfer Fulfilment & Transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request to retrieve \ntransferFulfilment & transferState + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Return transferFulfilment & \ntransferState + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return Transfer Fulfilment & Transfer state + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + alt If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: fulfil-duplicate, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event for Payee - Modified Request\nError codes: 3106 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee - Modified Request \n3106 to Bulk Processing Topic\nError codes: 3106 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + alt If type == 'fulfil' + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Reference: Failure in validation\nError code: 2001 + end + else + break + alt If type == 'fulfil' + FULF_HANDLER <-> FULF_HANDLER: Allow previous request to complete + else If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: fulfil-duplicate, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end + end + else Hash not matched + FULF_HANDLER -> TRANS_DAO: Request to persist transfer hash\nError codes: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist hash + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + deactivate TRANS_DAO + end + end + alt action=='reject' call made on PUT /transfers/{ID} + FULF_HANDLER -> TRANS_DAO: Request information for the validate checks\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> TRANS_DAO + deactivate DB + FULF_HANDLER <-- TRANS_DAO: Return transfer + deactivate TRANS_DAO + + alt Fulfilment present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + + group Persist fulfilment + FULF_HANDLER -> TRANS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + else Fulfilment NOT present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that transfer fulfilment message to Abort is valid\nError code: 2001 + group Persist extensions + FULF_HANDLER -> TRANS_DAO: Persist extensionList elements\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + end + + alt Transfer.ilpCondition validate successful OR generic validation successful + group Persist Transfer State (with transferState='RECEIVED_REJECT') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + FULF_HANDLER -> FULF_HANDLER: Route & Publish Position event for Payer\nReference: Publish Position Reject event for Payer + + else Validate Fulfil Transfer not successful or Generic validation failed + break + FULF_HANDLER -> FULF_HANDLER: Publish event for Payee\nReference: Failure in validation + end + end + else action=='abort' Error callback + alt Validation successful + group Persist Transfer State (with transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state & Error\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state & Error + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + FULF_HANDLER -> FULF_HANDLER: Error callback validated\nReference: Produce message for validated error callback + + else Validate Transfer Error Message not successful + break + FULF_HANDLER -> FULF_HANDLER: Notifications for failures\nReference: Validate Transfer Error Message not successful + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end + +group Reference: Validate Transfer Error Message not successful + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing event for Payee to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +group Reference: Produce message for validated error callback + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end + +group Reference: Failure in validation + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_BULK_PROCESSING: Publish processing event to the Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end + +group Reference: Publish Position Reject event for Payer + alt If type == 'bulk-fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else If type == 'fulfil' + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end + +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg new file mode 100644 index 000000000..1b64285dd --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg @@ -0,0 +1,1975 @@ + + + + + + + + + + + 2.2.2. Fulfil Handler Consume (Reject/Abort) (single message, includes individual transfers from Bulk) + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + topic- + + + fulfil + + + + + topic- + + + fulfil + + + Fulfil Handler + + + + + Fulfil Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic- + + + event + + + + + topic- + + + event + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + + + topic- + + + notification + + + + + topic- + + + notification + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + + Fulfil Handler Consume (Failure) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type IN ['fulfil','bulk-fulfil'] && ( action IN ['reject','abort'] ) + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate FSPIOP-Signature + + + + + ref + + + Validate message.content.headers. + + + FSPIOP-Signature + + + Error codes: + + + 2001 + + + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + + + Generate transferFulfilmentId uuid + + + + + 5 + + + Request to retrieve transfer fulfilment hashes by transferId + + + Error code: + + + 2003 + + + + + 6 + + + Request Transfer fulfilment + + + duplicate message hashes + + + + SELET transferId, hash + + + FROM + + + transferFulfilmentDuplicateCheck + + + WHERE transferId = request.params.id + + + + + 7 + + + Return existing hashes + + + + + 8 + + + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + + + Loop the list of returned hashes & compare + + + each entry with the calculated message hash + + + + + alt + + + [Hash matched] + + + + + 10 + + + Request to retrieve Transfer Fulfilment & Transfer state + + + Error code: + + + 2003 + + + + + 11 + + + Request to retrieve + + + transferFulfilment & transferState + + + + transferFulfilment + + + transferStateChange + + + + + 12 + + + Return transferFulfilment & + + + transferState + + + + + 13 + + + Return Transfer Fulfilment & Transfer state + + + + + alt + + + [transferFulfilment.isValid == 0] + + + + + break + + + + + alt + + + [If type == 'fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: fulfil-duplicate, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 14 + + + Publish Notification event for Payee - Modified Request + + + Error codes: + + + 3106 + + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: fulfil-duplicate, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 15 + + + Publish Notification event for Payee - Modified Request + + + 3106 to Bulk Processing Topic + + + Error codes: + + + 3106 + + + + [transferState IN ['COMMITTED', 'ABORTED']] + + + + + break + + + + + alt + + + [If type == 'fulfil'] + + + + + ref + + + Send notification to Participant (Payee) + + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: fulfil-duplicate, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 16 + + + Publish Notification event for Payee to Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [transferState NOT 'RESERVED'] + + + + + break + + + + + 17 + + + Reference: Failure in validation + + + Error code: + + + 2001 + + + + + + break + + + + + alt + + + [If type == 'fulfil'] + + + + + 18 + + + Allow previous request to complete + + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: fulfil-duplicate, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 19 + + + Publish Notification event for Payee to Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [Hash not matched] + + + + + 20 + + + Request to persist transfer hash + + + Error codes: + + + 2003 + + + + + 21 + + + Persist hash + + + + transferFulfilmentDuplicateCheck + + + + + 22 + + + Return success + + + + + alt + + + [action=='reject' call made on PUT /transfers/{ID}] + + + + + 23 + + + Request information for the validate checks + + + Error code: + + + 2003 + + + + + 24 + + + Fetch from database + + + + transfer + + + + + 25 + + + + + 26 + + + Return transfer + + + + + alt + + + [Fulfilment present in the PUT /transfers/{ID} message] + + + + + 27 + + + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + + + Error code: + + + 2001 + + + + + Persist fulfilment + + + + + 28 + + + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + + + Error code: + + + 2003 + + + + + 29 + + + Persist to database + + + + transferFulfilment + + + transferExtension + + + + + 30 + + + Return success + + + + [Fulfilment NOT present in the PUT /transfers/{ID} message] + + + + + 31 + + + Validate that transfer fulfilment message to Abort is valid + + + Error code: + + + 2001 + + + + + Persist extensions + + + + + 32 + + + Persist extensionList elements + + + Error code: + + + 2003 + + + + + 33 + + + Persist to database + + + + transferExtension + + + + + 34 + + + Return success + + + + + alt + + + [Transfer.ilpCondition validate successful OR generic validation successful] + + + + + Persist Transfer State (with transferState='RECEIVED_REJECT') + + + + + 35 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 36 + + + Persist transfer state + + + + transferStateChange + + + + + 37 + + + Return success + + + + + 38 + + + Route & Publish Position event for Payer + + + Reference: Publish Position Reject event for Payer + + + + [Validate Fulfil Transfer not successful or Generic validation failed] + + + + + break + + + + + 39 + + + Publish event for Payee + + + Reference: Failure in validation + + + + [action=='abort' Error callback] + + + + + alt + + + [Validation successful] + + + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + + + 40 + + + Request to persist transfer state & Error + + + Error code: + + + 2003 + + + + + 41 + + + Persist transfer state & Error + + + + transferStateChange + + + transferError + + + transferExtension + + + + + 42 + + + Return success + + + + + 43 + + + Error callback validated + + + Reference: Produce message for validated error callback + + + + [Validate Transfer Error Message not successful] + + + + + break + + + + + 44 + + + Notifications for failures + + + Reference: Validate Transfer Error Message not successful + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + + + + Reference: Validate Transfer Error Message not successful + + + + + alt + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 45 + + + Publish Processing event for Payee to Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [If type == 'fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: fulfil, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 46 + + + Route & Publish Notification event for Payee + + + + + Reference: Produce message for validated error callback + + + + + alt + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 47 + + + Route & Publish Position event for Payer + + + + [If type == 'fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 48 + + + Route & Publish Position event for Payer + + + + + Reference: Failure in validation + + + + + alt + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 49 + + + Publish processing event to the Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [If type == 'fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: fulfil, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 50 + + + Route & Publish Notification event for Payee + + + + + Reference: Publish Position Reject event for Payer + + + + + alt + + + [If type == 'bulk-fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-position, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 51 + + + Route & Publish Position event for Payer + + + + [If type == 'fulfil'] + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 52 + + + Route & Publish Position event for Payer + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml new file mode 100644 index 000000000..f992f9284 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml @@ -0,0 +1,176 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Rajiv Mothilal + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +entity "Position Facade" as POS_FACADE +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Fulfil Position Handler Consume + POS_HANDLER -> POS_DAO: Request current state of transfer from DB \nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferState is 'RECEIVED-FULFIL')\nError code: 2001 + group Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + POS_HANDLER -> POS_FACADE: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION + activate POS_FACADE + POS_FACADE -> DB: Select participantPosition.value FOR UPDATE from DB for Payee + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Return participantPosition.value from DB for Payee + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persist latestPosition to DB for Payee + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persist transfer state and participant position change + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Return success + deactivate POS_FACADE + end + + alt If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: bulk-commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Transfer event to Bulk Processing Topic\nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'position' + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Transfer event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg new file mode 100644 index 000000000..a50bd3d57 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg @@ -0,0 +1,468 @@ + + + + + + + + + + + 2.3.1. Fulfil Position Handler Consume (single message, includes individual transfers from Bulk) + + + + Central Service + + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + notifications + + + + + topic- + + + notifications + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Position DAO + + + + + Position DAO + + + + + Position Facade + + + + + Position Facade + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Position Handler Consume + + + + + 1 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 2 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + transferParticipant + + + + + 3 + + + Return current state of transfer from DB + + + + + 4 + + + Return current state of transfer from DB + + + + + 5 + + + Validate current state (transferState is 'RECEIVED-FULFIL') + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + + + 6 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + DB TRANSACTION + + + + + 7 + + + Select participantPosition.value FOR UPDATE from DB for Payee + + + + participantPosition + + + + + 8 + + + Return participantPosition.value from DB for Payee + + + + + 9 + + + latestPosition + + + = participantPosition.value - payload.amount.amount + + + + + 10 + + + Persist latestPosition to DB for Payee + + + + UPDATE + + + participantPosition + + + SET value = latestPosition + + + + + 11 + + + Persist transfer state and participant position change + + + + INSERT + + + transferStateChange + + + transferStateId = 'COMMITTED' + + + INSERT + + + participantPositionChange + + + SET participantPositionId = participantPosition.participantPositionId, + + + transferStateChangeId = transferStateChange.transferStateChangeId, + + + value = latestPosition, + + + reservedValue = participantPosition.reservedValue + + + createdDate = new Date() + + + + + 12 + + + Return success + + + + + alt + + + [If type == 'bulk-position'] + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: bulk-commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 13 + + + Publish Transfer event to Bulk Processing Topic + + + Error codes: + + + 2003 + + + + [If type == 'position'] + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 14 + + + Publish Transfer event + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml new file mode 100644 index 000000000..467666a01 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml @@ -0,0 +1,419 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Sam Kummary + ------------- + ******'/ + +@startuml +' declate title +title 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +entity "Position DAO" as POS_DAO +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS +collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant TOPIC_BULK_PROCESSING + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Abort Position Handler Consume + opt type IN ['position','bulk-position'] && action == 'timeout-reserved' + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state \n(transferStateChange.transferStateId == 'RESERVED_TIMEOUT')\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'EXPIRED_RESERVED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION IMPLEMENTATION + activate POS_DAO + POS_DAO -> DB: Select participantPosition.value FOR UPDATE for payerCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_DAO: Return participantPosition + deactivate DB + POS_DAO <-> POS_DAO: **latestPosition** = participantPosition - payload.amount.amount + POS_DAO->DB: Persist latestPosition to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_DAO -> DB: Persist participant position change and state change + hnote over DB #lightyellow + INSERT **transferStateChange** + VALUES (transferStateId) + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Transfer event to Bulk Processing Topic (for Payer) \nError codes: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + else If type == 'position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + opt type IN ['position','bulk-position'] && (action IN ['reject', 'abort']) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state \n(transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR'])\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If action == 'reject' + alt If type == 'position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type == 'bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event\nError code: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + else action == 'abort' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + + ' TODO: We do not see how this scenario will be triggered + opt type IN ['position','bulk-position'] && action == 'fail' (Unable to currently trigger this scenario) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferStateChange.transferStateId == 'FAILED') + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'FAILED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt If type =='position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else If type =='bulk-position' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: bulk-processing, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_BULK_PROCESSING: Publish Notification event\nError code: 2003 + activate TOPIC_BULK_PROCESSING + deactivate TOPIC_BULK_PROCESSING + end + end +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg new file mode 100644 index 000000000..9ebfd3c26 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg @@ -0,0 +1,1297 @@ + + + + + + + + + + + 2.3.2. Abort Position Handler Consume (single message, includes individual transfers from Bulk) + + + + Central Service + + + + + + + + + + + + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Abort Position Handler Consume + + + + + opt + + + [type IN ['position','bulk-position'] && action == 'timeout-reserved'] + + + + + 1 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 2 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + transferParticipant + + + + + 3 + + + Return current state of transfer from DB + + + + + 4 + + + Return current state of transfer from DB + + + + + 5 + + + Validate current state + + + (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer state + + + + + 6 + + + transferStateId + + + = 'EXPIRED_RESERVED' + + + + + 7 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + DB TRANSACTION IMPLEMENTATION + + + + + 8 + + + Select participantPosition.value FOR UPDATE for payerCurrencyId + + + + participantPosition + + + + + 9 + + + Return participantPosition + + + + + 10 + + + latestPosition + + + = participantPosition - payload.amount.amount + + + + + 11 + + + Persist latestPosition to DB for Payer + + + + UPDATE + + + participantPosition + + + SET value = latestPosition + + + + + 12 + + + Persist participant position change and state change + + + + INSERT + + + transferStateChange + + + VALUES (transferStateId) + + + INSERT + + + participantPositionChange + + + SET participantPositionId = participantPosition.participantPositionId, + + + transferStateChangeId = transferStateChange.transferStateChangeId, + + + value = latestPosition, + + + reservedValue = participantPosition.reservedValue + + + createdDate = new Date() + + + + + 13 + + + Return success + + + + + alt + + + [If type == 'bulk-position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Transfer expired", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 14 + + + Publish Transfer event to Bulk Processing Topic (for Payer) + + + Error codes: + + + 2003 + + + + [If type == 'position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Transfer expired", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 15 + + + Publish Notification event + + + Error code: + + + 2003 + + + + + opt + + + [type IN ['position','bulk-position'] && (action IN ['reject', 'abort'])] + + + + + 16 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 17 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + + + 18 + + + Return current state of transfer from DB + + + + + 19 + + + Return current state of transfer from DB + + + + + 20 + + + Validate current state + + + (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer state + + + + + 21 + + + transferStateId + + + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + + + 22 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + Refer to + + + DB TRANSACTION IMPLEMENTATION + + + above + + + + + 23 + + + Persist to database + + + + participantPosition + + + transferStateChange + + + participantPositionChange + + + + + 24 + + + Return success + + + + + alt + + + [If action == 'reject'] + + + + + alt + + + [If type == 'position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0, + + + description: "action successful" + + + } + + + } + + + } + + + } + + + + + 25 + + + Publish Notification event + + + Error code: + + + 2003 + + + + [If type == 'bulk-position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0, + + + description: "action successful" + + + } + + + } + + + } + + + } + + + + + 26 + + + Publish Notification event + + + Error code: + + + 2003 + + + + [action == 'abort'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <payload.errorInformation.errorCode || 5000> + + + description: <payload.errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 27 + + + Publish Notification event + + + Error code: + + + 2003 + + + + + opt + + + [type IN ['position','bulk-position'] && action == 'fail' (Unable to currently trigger this scenario)] + + + + + 28 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 29 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + + + 30 + + + Return current state of transfer from DB + + + + + 31 + + + Return current state of transfer from DB + + + + + 32 + + + Validate current state (transferStateChange.transferStateId == 'FAILED') + + + + + Persist Position change and Transfer state + + + + + 33 + + + transferStateId + + + = 'FAILED' + + + + + 34 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + Refer to + + + DB TRANSACTION IMPLEMENTATION + + + above + + + + + 35 + + + Persist to database + + + + participantPosition + + + transferStateChange + + + participantPositionChange + + + + + 36 + + + Return success + + + + + alt + + + [If type =='position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3100, + + + "errorDescription": "Transfer failed", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 37 + + + Publish Notification event + + + Error code: + + + 2003 + + + + [If type =='bulk-position'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3100, + + + "errorDescription": "Transfer failed", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: bulk-processing, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 38 + + + Publish Notification event + + + Error code: + + + 2003 + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml rename to legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg new file mode 100644 index 000000000..20faf4b81 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg @@ -0,0 +1,406 @@ + + + + + + + + + + + 3.1.0. Transfer Timeout (incl. Bulk Transfer) + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API + + + Adapter + + + + + ML API + + + Adapter + + + + + ML API Notification + + + Event Handler + + + + + ML API Notification + + + Event Handler + + + + + Transfer Timeout + + + Handler + + + + + Transfer Timeout + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic-event + + + + + topic-event + + + Position Event + + + Handler + + + + + Position Event + + + Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + Bulk Processing + + + Handler + + + + + Bulk Processing + + + Handler + + + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + + + + Transfer Expiry + + + + + ref + + + Timeout Handler Consume + + + + + alt + + + [transferStateId == 'RECEIVED_PREPARE'] + + + + + alt + + + [Regular Transfer] + + + + + 1 + + + Produce message + + + + [Individual Transfer from a Bulk] + + + + + 2 + + + Produce message + + + + [transferStateId == 'RESERVED'] + + + + + 3 + + + Produce message + + + + + 4 + + + Consume message + + + + + ref + + + Position Hander Consume (Timeout) + + + + + alt + + + [Regular Transfer] + + + + + 5 + + + Produce message + + + + [Individual Transfer from a Bulk] + + + + + 6 + + + Produce message + + + + + opt + + + [action IN ['bulk-timeout-received', 'bulk-timeout-reserved']] + + + + + 7 + + + Consume message + + + + + ref + + + Bulk Processing Consume + + + + + 8 + + + Produce message + + + + + opt + + + [action IN ['timeout-received', 'timeout-reserved', 'bulk-timeout-received', 'bulk-timeout-reserved']] + + + + + 9 + + + Consume message + + + + + ref + + + Send notification to Participant (Payer) + + + + + 10 + + + Send callback notification + + + + + opt + + + [action IN ['timeout-reserved', 'bulk-timeout-reserved']] + + + + + 11 + + + Consume message + + + + + ref + + + Send notification to Participant (Payee) + + + + + 12 + + + Send callback notification + + diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml rename to legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg new file mode 100644 index 000000000..4f687da29 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg @@ -0,0 +1,1340 @@ + + + + + + + + + + + 3.1.1. Timeout Handler Consume (incl. Bulk Transfer) + + + + Central Service + + + + + + + + + + + + + + Transfer Timeout + + + Handler + + + + + Transfer Timeout + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic-event + + + + + topic-event + + + + + topic- + + + bulk-processing + + + + + topic- + + + bulk-processing + + + Position DAO + + + + + Position DAO + + + + + Segment DAO + + + + + Segment DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Timeout Handler Consume + + + + + Persist Event Information + + + + + 1 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Get previous checkpoint of last record processed (Lower limit for inclusion) + + + + + 2 + + + Get last segment as @intervalMin + + + + + 3 + + + Get last segment as @intervalMin + + + + SELECT value INTO @intervalMin + + + FROM + + + segment + + + WHERE segmentType = 'timeout' + + + AND enumeration = 0 + + + AND tableName = 'transferStateChange' + + + + + 4 + + + Return @intervalMin + + + + + 5 + + + Return @intervalMin + + + + + opt + + + [@intervalMin IS NULL => segment record NOT FOUND] + + + + + 6 + + + Set @intervalMin = 0 + + + + + Do Cleanup + + + + + 7 + + + Clean up transferTimeout from finalised transfers + + + + + 8 + + + Clean up transferTimeout from finalised transfers + + + + DELETE tt + + + FROM + + + transferTimeout + + + AS tt + + + JOIN (SELECT tsc.transferId, MAX(tsc.transferStateChangeId) maxTransferStateChangeId + + + FROM + + + transferTimeout + + + tt1 + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferId = tt1.transferId + + + GROUP BY transferId) ts + + + ON ts.transferId = tt.transferId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + + + WHERE tsc.transferStateId IN ('RECEIVED_FULFIL', 'COMMITTED', 'FAILED' + + + , 'EXPIRED', 'REJECTED', 'EXPIRED_PREPARED', 'EXPIRED_RESERVED', 'ABORTED') + + + + + 9 + + + Return success + + + + + Determine IntervalMax (Upper limit for inclusion) + + + + + 10 + + + Get last transferStateChangeId as @intervalMax + + + + + 11 + + + Get last transferStateChangeId as @intervalMax + + + + SELECT MAX(transferStateChangeId) INTO @intervalMax + + + FROM + + + transferStateChange + + + + + 12 + + + Return @intervalMax + + + + + 13 + + + Return @intervalMax + + + + + Prepare data and return the list for expiration + + + + + 14 + + + Prepare data and get transfers to be expired + + + + + DB TRANSACTION + + + + + 15 + + + transactionTimestamp + + + = now() + + + + + 16 + + + Insert all new transfers still in processing state + + + + INSERT INTO + + + transferTimeout + + + (transferId, expirationDate) + + + SELECT t.transferId, t.expirationDate + + + FROM + + + transfer + + + t + + + JOIN (SELECT transferId, MAX(transferStateChangeId) maxTransferStateChangeId + + + FROM + + + transferStateChange + + + WHERE transferStateChangeId > @intervalMin + + + AND transferStateChangeId <= @intervalMax + + + GROUP BY transferId) ts + + + ON ts.transferId = t.transferId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + + + WHERE tsc.transferStateId IN ('RECEIVED_PREPARE', 'RESERVED') + + + + + 17 + + + Insert transfer state ABORTED for + + + expired RECEIVED_PREPARE transfers + + + + INSERT INTO + + + transferStateChange + + + SELECT tt.transferId, 'EXPIRED_PREPARED' AS transferStateId, 'Aborted by Timeout Handler' AS reason + + + FROM + + + transferTimeout + + + tt + + + JOIN ( + + + -- Following subquery is reused 3 times and may be optimized if needed + + + SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + + + FROM + + + transferStateChange + + + tsc1 + + + JOIN + + + transferTimeout + + + tt1 + + + ON tt1.transferId = tsc1.transferId + + + GROUP BY tsc1.transferId) ts + + + ON ts.transferId = tt.transferId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + + + WHERE tt.expirationDate < {transactionTimestamp} + + + AND tsc.transferStateId = 'RECEIVED_PREPARE' + + + + + 18 + + + Insert transfer state EXPIRED for + + + expired RESERVED transfers + + + + INSERT INTO + + + transferStateChange + + + SELECT tt.transferId, 'RESERVED_TIMEOUT' AS transferStateId, 'Expired by Timeout Handler' AS reason + + + FROM + + + transferTimeout + + + tt + + + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + + + FROM + + + transferStateChange + + + tsc1 + + + JOIN + + + transferTimeout + + + tt1 + + + ON tt1.transferId = tsc1.transferId + + + GROUP BY tsc1.transferId) ts + + + ON ts.transferId = tt.transferId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + + + WHERE tt.expirationDate < {transactionTimestamp} + + + AND tsc.transferStateId = 'RESERVED' + + + + + 19 + + + Update segment table to be used for the next run + + + + IF @intervalMin = 0 + + + INSERT + + + INTO + + + segment + + + (segmentType, enumeration, tableName, value) + + + VALUES ('timeout', 0, 'transferStateChange', @intervalMax) + + + ELSE + + + UPDATE + + + segment + + + SET value = @intervalMax + + + WHERE segmentType = 'timeout' + + + AND enumeration = 0 + + + AND tableName = 'transferStateChange' + + + + + 20 + + + Get list of transfers to be expired with current state + + + + SELECT tt.*, tsc.transferStateId, tp1.participantCurrencyId payerParticipantId, + + + tp2.participantCurrencyId payeeParticipantId, bta.bulkTransferId + + + FROM + + + transferTimeout + + + tt + + + JOIN (SELECT tsc1.transferId, MAX(tsc1.transferStateChangeId) maxTransferStateChangeId + + + FROM + + + transferStateChange + + + tsc1 + + + JOIN + + + transferTimeout + + + tt1 + + + ON tt1.transferId = tsc1.transferId + + + GROUP BY tsc1.transferId) ts + + + ON ts.transferId = tt.transferId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferStateChangeId = ts.maxTransferStateChangeId + + + JOIN + + + transferParticipant + + + tp1 + + + ON tp1.transferId = tt.transferId + + + AND tp1.transferParticipantRoleTypeId = {PAYER_DFSP} + + + AND tp1.ledgerEntryTypeId = {PRINCIPLE_VALUE} + + + JOIN + + + transferParticipant + + + tp2 + + + ON tp2.transferId = tt.transferId + + + AND tp2.transferParticipantRoleTypeId = {PAYEE_DFSP} + + + AND tp2.ledgerEntryTypeId = {PRINCIPLE_VALUE} + + + LEFT JOIN + + + bulkTransferAssociation + + + bta + + + ON bta.transferId = tt.transferId + + + WHERE tt.expirationDate < {transactionTimestamp} + + + + + 21 + + + Return + + + transferTimeoutList + + + + + 22 + + + Return + + + transferTimeoutList + + + + + loop + + + [for each transfer in the list] + + + + + alt + + + [transferTimeoutList.bulkTransferId == NULL (Regular Transfer)] + + + + + alt + + + [transferStateId == 'RECEIVED_PREPARE'] + + + + + Message: + + + { + + + id: <transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + }, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Generic expired error", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: notification, + + + action: timeout-received, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 23 + + + Publish Notification event + + + + [transferStateId == 'RESERVED'] + + + + + Message: + + + { + + + id: <transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + }, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Generic expired error", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: position, + + + action: timeout-reserved, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 24 + + + Route & Publish Position event + + + + [Individual Transfer from a Bulk] + + + + + alt + + + [transferStateId == 'RECEIVED_PREPARE'] + + + + + Message: + + + { + + + id + + + : <transferTimeoutList.bulkTransferId>, + + + transferId + + + : <transferTimeoutList.transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: <bulkTransferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Generic expired error", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: bulk-processing, + + + action: bulk-timeout-received, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 25 + + + Publish to Bulk Processing topic + + + + [transferStateId == 'RESERVED'] + + + + + Message: + + + { + + + id + + + : <transferTimeoutList.bulkTransferId>, + + + transferId + + + : <transferTimeoutList.transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: <bulkTransferHeaders>,, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Generic expired error", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: position, + + + action: bulk-timeout-reserved, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 26 + + + Route & Publish Position event + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml new file mode 100644 index 000000000..e02a15142 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.plantuml @@ -0,0 +1,233 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declare title +title 4.1.0. Bulk Transfer Abort + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "Bulk API Adapter" as BULKAPI +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Bulk-Fulfil-Topic" as TOPIC_BULK_FULFIL +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Bulk Fulfil Event Handler" as BULK_FULFIL_HANDLER +control "Fulfil Event Handler" as FULFIL_HANDLER +collections "topic-transfer-position" as TOPIC_POSITION +control "Position Event Handler" as POS_HANDLER +collections "topic-bulk-processing" as TOPIC_BULK_PROCESSING +control "Bulk Processing Event Handler" as BULK_PROCESSING_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE +database "Central Services DB" as DB + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_BULK_FULFIL + participant TOPIC_FULFIL + participant BULK_FULFIL_HANDLER + participant FULFIL_HANDLER + participant TOPIC_POSITION + participant TOPIC_EVENTS + participant POS_HANDLER + participant TOPIC_BULK_PROCESSING + participant BULK_PROCESSING_HANDLER + participant TOPIC_NOTIFICATIONS + participant OBJECT_STORE + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +activate BULK_FULFIL_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate BULK_PROCESSING_HANDLER +activate POS_HANDLER + +group DFSP2 sends a Fulfil Abort Transfer request + note right of DFSP2 #lightblue + **Note**: In the payload for PUT /bulkTransfers//error + only the **errorInformation** field is **required** + end note + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + Payload - errorMessage: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> BULKAPI: **PUT - /bulkTransfers//error** + activate BULKAPI + + BULKAPI -> OBJECT_STORE: Persist request payload with messageId in cache + activate OBJECT_STORE + note right of BULKAPI #yellow + Message: { + messageId: , + bulkTransferId: , + payload: + } + end note + hnote over OBJECT_STORE #lightyellow + individualTransferFulfils + end hnote + BULKAPI <- OBJECT_STORE: Response of save operation + deactivate OBJECT_STORE + note right of BULKAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + BULKAPI -> TOPIC_BULK_FULFIL: Produce bulk-fulfil message + BULKAPI -->> DFSP2: Respond HTTP - 200 (OK) + TOPIC_BULK_FULFIL <- BULK_FULFIL_HANDLER: Consume bulk-fulfil message + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Perform duplicate check + BULK_FULFIL_HANDLER -> BULK_FULFIL_HANDLER: Validate request + loop n times, n = number of individual transfers + note right of BULK_FULFIL_HANDLER + Message: { + transferId: , + bulkTransferId< , + bulkTransferAssociationRecord: { + transferId: , + bulkTransferId: , + bulkProcessingStateId: , + errorCode: , + errorDescription: + } + } + end note + BULK_FULFIL_HANDLER -> DB: Update bulkTransferAssociation table + activate DB + hnote over DB #lightyellow + bulkTransferAssociation + end hnote + deactivate DB + BULK_FULFIL_HANDLER -> TOPIC_FULFIL: Produce fulfil message with action bulk-abort for each individual transfer + end + ||| + loop n times, n = number of individual transfers + TOPIC_FULFIL <- FULFIL_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_EVENTS: Fulfil Handler Consume (bulk-abort)\n + FULFIL_HANDLER -> TOPIC_POSITION: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_POSITION, BULK_PROCESSING_HANDLER: Position Handler Consume (bulk-abort)\n + POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message + end + ||| + loop n times, n = number of individual transfers + TOPIC_BULK_PROCESSING <- BULK_PROCESSING_HANDLER: Consume individual transfer message + ref over TOPIC_BULK_PROCESSING, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume (bulk-abort)\n + end + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payer) + BULK_PROCESSING_HANDLER -> TOPIC_NOTIFICATIONS: Produce message (Payee) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payer) + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message (Payee) + opt action == 'bulk-abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Notification Handler (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + opt action == 'bulk-abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Notification Handler (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +activate POS_HANDLER +activate FULFIL_HANDLER +activate FULFIL_HANDLER +activate NOTIFY_HANDLER +@enduml + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg new file mode 100644 index 000000000..65d6a65a7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg @@ -0,0 +1,732 @@ + + + + + + + + + + + 4.1.0. Bulk Transfer Abort + + + + Financial Service Providers + + + + Bulk API Adapter Service + + + + Central Service + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + Bulk API Adapter + + + + + Bulk API Adapter + + + + + Bulk API Notification Event Handler + + + + + Bulk API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Bulk-Fulfil-Topic + + + + + Bulk-Fulfil-Topic + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Bulk Fulfil Event Handler + + + + + Bulk Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + Position Event Handler + + + + + Position Event Handler + + + + + + + topic-bulk-processing + + + + + topic-bulk-processing + + + Bulk Processing Event Handler + + + + + Bulk Processing Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + + + mojaloop- + + + object-store + + + ( + + + MLOS + + + ) + + + Central Services DB + + + + + Central Services DB + + + + + + + + + DFSP2 sends a Fulfil Abort Transfer request + + + + + Note + + + : In the payload for PUT /bulkTransfers/<ID>/error + + + only the + + + errorInformation + + + field is + + + required + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - errorMessage: + + + { + + + "errorInformation": { + + + "errorCode": <string>, + + + "errorDescription": <string>, + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + } + + + + 1 + + + PUT - /bulkTransfers/<ID>/error + + + + + 2 + + + Persist request payload with messageId in cache + + + + + Message: { + + + messageId: <string>, + + + bulkTransferId: <string>, + + + payload: <object> + + + } + + + + individualTransferFulfils + + + + + 3 + + + Response of save operation + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Produce bulk-fulfil message + + + + + 5 + + + Respond HTTP - 200 (OK) + + + + + 6 + + + Consume bulk-fulfil message + + + + + 7 + + + Perform duplicate check + + + + + 8 + + + Validate request + + + + + loop + + + [n times, n = number of individual transfers] + + + + + Message: { + + + transferId: <string>, + + + bulkTransferId< <string>, + + + bulkTransferAssociationRecord: { + + + transferId: <string>, + + + bulkTransferId: <string>, + + + bulkProcessingStateId: <string>, + + + errorCode: <string>, + + + errorDescription: <string> + + + } + + + } + + + + + 9 + + + Update bulkTransferAssociation table + + + + bulkTransferAssociation + + + + + 10 + + + Produce fulfil message with action bulk-abort for each individual transfer + + + + + loop + + + [n times, n = number of individual transfers] + + + + + 11 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (bulk-abort) + + + + + 12 + + + Produce message + + + + + loop + + + [n times, n = number of individual transfers] + + + + + 13 + + + Consume message + + + + + ref + + + Position Handler Consume (bulk-abort) + + + + + 14 + + + Produce message + + + + + loop + + + [n times, n = number of individual transfers] + + + + + 15 + + + Consume individual transfer message + + + + + ref + + + Bulk Processing Handler Consume (bulk-abort) + + + + + 16 + + + Produce message (Payer) + + + + + 17 + + + Produce message (Payee) + + + + + 18 + + + Consume message (Payer) + + + + + 19 + + + Consume message (Payee) + + + + + opt + + + [action == 'bulk-abort'] + + + + + ref + + + Notification Handler (Payer) + + + + + 20 + + + Send callback notification + + + + + opt + + + [action == 'bulk-abort'] + + + + + ref + + + Notification Handler (Payee) + + + + + 21 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml new file mode 100644 index 000000000..e219f2465 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.plantuml @@ -0,0 +1,209 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Steven Oderayi + -------------- + ******'/ + +@startuml +' declate title +title 5.1.0. Request Bulk Transfer Status + +autonumber + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "Bulk API Notification Event Handler" as NOTIFY_HANDLER +boundary "Bulk API Adapter" as BULKAPI +collections "Topic-Transfer-Get" as TOPIC_GET +control "GET Event Handler" as GET_HANDLER +entity "Bulk Transfer DAO" as BULK_TRANSFER_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box +box "Bulk API Adapter Service" #LightBlue + participant BULKAPI + participant NOTIFY_HANDLER +end box +box "Central Ledger" #LightYellow + participant TOPIC_GET + participant GET_HANDLER + participant BULK_TRANSFER_DAO + participant DB +end box + +' start flow +group Request Bulk transfer status + activate DFSP + DFSP -> BULKAPI: Request bulk transfer status - GET - /bulkTransfers/{ID} + activate BULKAPI + ||| + BULKAPI -> TOPIC_GET: Publish event information + deactivate BULKAPI + activate TOPIC_GET + ||| + deactivate GET_HANDLER + + DFSP <-- BULKAPI: Respond HTTP - 200 (OK) + deactivate DFSP + deactivate BULKAPI + GET_HANDLER -> TOPIC_GET: Consume message + ||| + ref over TOPIC_GET, GET_HANDLER : GET Handler Consume\n + ||| + deactivate TOPIC_GET + + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer participants + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer participants + activate DB + hnote over DB #lightYellow + bulkTransfer + participant + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer participants + deactivate BULK_TRANSFER_DAO + alt Is request not from bulk transfer Payer or Payee FSP? + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + GET_HANDLER -> BULK_TRANSFER_DAO: Request bulk transfer status + activate GET_HANDLER + activate BULK_TRANSFER_DAO + BULK_TRANSFER_DAO -> DB: Fetch bulk transfer status + + activate DB + hnote over DB #lightyellow + bulkTransferStateChange + bulkTransferState + bulkTransferError + bulkTransferExtension + transferStateChange + transferState + transferFulfilment + transferError + transferExtension + ilpPacket + end hnote + BULK_TRANSFER_DAO <-- DB: Return query result + deactivate DB + + GET_HANDLER <-- BULK_TRANSFER_DAO: Return bulk transfer status + deactivate BULK_TRANSFER_DAO + + alt Is there a bulk transfer with the given ID recorded in the system? + alt Bulk Transfer state is **"PROCESSING"** + note left of GET_HANDLER #yellow + { + "bulkTransferState": "PROCESSING" + } + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> DFSP: Send callback - PUT /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + end + ||| + alt Request is from Payee FSP? + GET_HANDLER <-> GET_HANDLER: Exclude transfers with **transferStateId** not in \n [ **COMMITTED**, **ABORTED_REJECTED**, **EXPIRED_RESERVED** ] + activate GET_HANDLER + end + + note left of GET_HANDLER #yellow + { + "bulkTransferState": "", + "individualTransferResults": [ + { + "transferId": "", + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "errorInformation": , + "extensionList": { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + ], + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "extensionList": + { + "extension": + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + end note + note left of GET_HANDLER #lightGray + NOTE: If transfer is REJECTED, error information may be provided. + Either fulfilment or errorInformation should be set, not both. + end note + NOTIFY_HANDLER <- GET_HANDLER: Publish notification event + deactivate GET_HANDLER + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID} + deactivate NOTIFY_HANDLER + note right of NOTIFY_HANDLER #lightgray + Log ERROR event + end note + else A bulk transfer with the given ID is not present in the System or this is an invalid request + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": 3210, + "errorDescription": "Bulk transfer ID not found" + } + } + end note + GET_HANDLER -> NOTIFY_HANDLER: Publish notification event (404) + activate NOTIFY_HANDLER + DFSP <- NOTIFY_HANDLER: callback PUT on /bulkTransfers/{ID}/error + deactivate NOTIFY_HANDLER + end + + deactivate GET_HANDLER + deactivate NOTIFY_HANDLER +deactivate DFSP +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg new file mode 100644 index 000000000..0c0bb5959 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg @@ -0,0 +1,552 @@ + + + + + + + + + + + 5.1.0. Request Bulk Transfer Status + + + + Financial Service Provider + + + + Bulk API Adapter Service + + + + Central Ledger + + + + + + + + + DFSP(n) + + + Participant + + + + + DFSP(n) + + + Participant + + + + + Bulk API Adapter + + + + + Bulk API Adapter + + + + + Bulk API Notification Event Handler + + + + + Bulk API Notification Event Handler + + + + + + + Topic-Transfer-Get + + + + + Topic-Transfer-Get + + + GET Event Handler + + + + + GET Event Handler + + + + + Bulk Transfer DAO + + + + + Bulk Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Request Bulk transfer status + + + + + 1 + + + Request bulk transfer status - GET - /bulkTransfers/{ID} + + + + + 2 + + + Publish event information + + + + + 3 + + + Respond HTTP - 200 (OK) + + + + + 4 + + + Consume message + + + + + ref + + + GET Handler Consume + + + + + 5 + + + Request bulk transfer participants + + + + + 6 + + + Fetch bulk transfer participants + + + + bulkTransfer + + + participant + + + + + 7 + + + Return query result + + + + + 8 + + + Return bulk transfer participants + + + + + alt + + + [Is request not from bulk transfer Payer or Payee FSP?] + + + + + { + + + "errorInformation": { + + + "errorCode": 3210, + + + "errorDescription": "Bulk transfer ID not found" + + + } + + + } + + + + + 9 + + + Publish notification event (404) + + + + + 10 + + + callback PUT on /bulkTransfers/{ID}/error + + + + + 11 + + + Request bulk transfer status + + + + + 12 + + + Fetch bulk transfer status + + + + bulkTransferStateChange + + + bulkTransferState + + + bulkTransferError + + + bulkTransferExtension + + + transferStateChange + + + transferState + + + transferFulfilment + + + transferError + + + transferExtension + + + ilpPacket + + + + + 13 + + + Return query result + + + + + 14 + + + Return bulk transfer status + + + + + alt + + + [Is there a bulk transfer with the given ID recorded in the system?] + + + + + alt + + + [Bulk Transfer state is + + + "PROCESSING" + + + ] + + + + + { + + + "bulkTransferState": "PROCESSING" + + + } + + + + + 15 + + + Publish notification event + + + + + 16 + + + Send callback - PUT /bulkTransfers/{ID} + + + + + alt + + + [Request is from Payee FSP?] + + + + + 17 + + + Exclude transfers with + + + transferStateId + + + not in + + + [ + + + COMMITTED + + + , + + + ABORTED_REJECTED + + + , + + + EXPIRED_RESERVED + + + ] + + + + + { + + + "bulkTransferState": "<BulkTransferState>", + + + "individualTransferResults": [ + + + { + + + "transferId": "<TransferId>", + + + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + + + "errorInformation": <ErrorInformationObject>, + + + "extensionList": { + + + "extension": + + + [ + + + { + + + "key": "Description", + + + "value": "This is a more detailed description" + + + } + + + ] + + + } + + + } + + + ], + + + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + + + "extensionList": + + + { + + + "extension": + + + [ + + + { + + + "key": "Description", + + + "value": "This is a more detailed description" + + + } + + + ] + + + } + + + } + + + + + NOTE: If transfer is REJECTED, error information may be provided. + + + Either fulfilment or errorInformation should be set, not both. + + + + + 18 + + + Publish notification event + + + + + 19 + + + callback PUT on /bulkTransfers/{ID} + + + + + Log ERROR event + + + + [A bulk transfer with the given ID is not present in the System or this is an invalid request] + + + + + { + + + "errorInformation": { + + + "errorCode": 3210, + + + "errorDescription": "Bulk transfer ID not found" + + + } + + + } + + + + + 20 + + + Publish notification event (404) + + + + + 21 + + + callback PUT on /bulkTransfers/{ID}/error + + diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md new file mode 100644 index 000000000..8ad8c6ce7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Bulk Prepare Transfer Request [Overview] [includes individual transfers in a bulk] + +Sequence design diagram for Prepare Transfer Request process. + +## References within Sequence Diagram + +* [Bulk Prepare Handler Consume (1.1.1)](1.1.1-bulk-prepare-handler-consume.md) +* [Prepare Handler Consume (1.2.1)](1.2.1-prepare-handler-consume-for-bulk.md) +* [Position Handler Consume (1.3.0)](1.3.0-position-handler-consume-overview.md) +* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-1.1.0-bulk-prepare-overview.svg](../assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md new file mode 100644 index 000000000..148656326 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Bulk Prepare handler consume + +Sequence design diagram for Bulk Prepare Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-1.1.1-bulk-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md new file mode 100644 index 000000000..56740e2e3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md @@ -0,0 +1,11 @@ +# Prepare handler consume [that includes individual transfers in a bulk] + +Sequence design diagram for Prepare Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-1.2.1-prepare-handler.svg](../assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md new file mode 100644 index 000000000..bcd5bf1e1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md @@ -0,0 +1,14 @@ +# Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for Position Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fufil Position Handler Consume (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) +* [Abort Position Handler Consume (2.2.2)](2.2.2-fulfil-abort-for-bulk.md) + +## Sequence Diagram + +![seq-bulk-1.3.0-position-overview.svg](../assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..31c4c05a4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Prepare Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for Prepare Position Handler Consume process + +## Sequence Diagram + +![seq-bulk-1.3.1-position-prepare.svg](../assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md new file mode 100644 index 000000000..086bfb8b6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md @@ -0,0 +1,7 @@ +# Bulk Processing Handler Consume + +Sequence design diagram for Bulk Processing Handler Consume process + +## Sequence Diagram + +![seq-bulk-1.4.1-bulk-processing-handler.svg](../assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md new file mode 100644 index 000000000..f08b37d9e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md @@ -0,0 +1,15 @@ +# Bulk Fulfil Transfer Request Overview + +Sequence design diagram for the Bulk Fulfil Transfer request + +## References within Sequence Diagram + +* [Bulk Fulfil Handler Consume (Success) (2.1.1)](2.1.1-bulk-fulfil-handler-consume.md) +* [Fulfil Handler Consume (Success) (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) +* [Position Handler Consume (Success) (2.3.1)](2.3.1-fulfil-position-handler-consume.md) +* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.1.0-bulk-fulfil-overview.svg](../assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md new file mode 100644 index 000000000..ea730d0b8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Bulk Fulfil Handler Consume + +Sequence design diagram for the Bulk Fulfil Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.1.1-bulk-fulfil-handler.svg](../assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md new file mode 100644 index 000000000..7a2102201 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md @@ -0,0 +1,11 @@ +# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers + +Sequence design diagram for the Bulk Fulfil Transfer for the Commit option + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-2.2.1-fulfil-handler-commit.svg](../assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md new file mode 100644 index 000000000..ab1c78b39 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md @@ -0,0 +1,13 @@ +# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-bulk-2.2.2-fulfil-handler-abort.svg](../assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md new file mode 100644 index 000000000..c869282ab --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md @@ -0,0 +1,11 @@ +# Fulfil Position Handler Consume [that includes individual transfers in a bulk] + +Sequence design diagram for the Fulfil Position Handler Consume process + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-bulk-2.3.1-position-fulfil.svg](../assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md new file mode 100644 index 000000000..ed4d3f9f8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md @@ -0,0 +1,7 @@ +# Position Handler Consume for Fulfil aborts at individual transfer level + +Sequence design diagram for Fulfil Position Handler Consume process + +## Sequence Diagram + +![seq-bulk-2.3.2-position-abort.svg](../assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md new file mode 100644 index 000000000..e2e982791 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Transfer Timeout [includes individual transfers in a Bulk] + +Sequence design diagram for the Transfer Timeout process. + +## Sequence Diagram + +![seq-bulk-3.1.0-timeout-overview.svg](../assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md new file mode 100644 index 000000000..d8fcefc23 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md @@ -0,0 +1,7 @@ +# TimeOut Handler + +Sequence design diagram for Timeout Handler process + +## Sequence Diagram + +![seq-bulk-3.1.1-timeout-handler.svg](../assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.svg) diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md new file mode 100644 index 000000000..9a3c04a1d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/4.1.0-transfer-abort-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Bulk Transfer Abort Overview [includes individual transfers in a Bulk] + +Sequence design diagram for the Bulk Transfer Abort process. + +## Sequence Diagram + +![seq-bulk-4.1.0-abort-overview.svg](../assets/diagrams/sequence/seq-bulk-4.1.0-abort-overview.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md new file mode 100644 index 000000000..f178b7b30 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/5.1.0-transfer-get-overview-for-bulk.md @@ -0,0 +1,7 @@ +# Get Bulk Transfer Overview + +Sequence design diagram for the Get Bulk Transfer process. + +## Sequence Diagram + +![seq-bulk-5.1.0-get-overview.svg](../assets/diagrams/sequence/seq-bulk-5.1.0-get-overview.svg) \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/README.md b/legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/README.md similarity index 100% rename from mojaloop-technical-overview/central-bulk-transfers/transfers/README.md rename to legacy/mojaloop-technical-overview/central-bulk-transfers/transfers/README.md diff --git a/legacy/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md b/legacy/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md new file mode 100644 index 000000000..258ef5fb7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md @@ -0,0 +1,12 @@ +# Notification Handler for Rejections + +Sequence design diagram for the Notification Handler for Rejections process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](9.1.0-event-handler-placeholder.md) +* [Get Participant Callback Details (3.1.0)](../central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) + +## Sequence Diagram + +![seq-notification-reject-5.1.1.svg](./assets/diagrams/sequence/seq-notification-reject-5.1.1.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md b/legacy/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md new file mode 100644 index 000000000..38904e3d2 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md @@ -0,0 +1,7 @@ +# Event Handler Placeholder + +Sequence design diagram for the Event Handler process. + +## Sequence Diagram + +![seq-event-9.1.0.svg](./assets/diagrams/sequence/seq-event-9.1.0.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/README.md b/legacy/mojaloop-technical-overview/central-event-processor/README.md new file mode 100644 index 000000000..45b2203f8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/README.md @@ -0,0 +1,13 @@ +# Central Event Processor Service + +The Central Event Processor (CEP) service provides the capability to monitor for a pre-defined/configured set of business rules or patterns. + +In the current iteration, the rules are set to monitor for three criteria: + + 1. Breaching of a threshold on the Limit of Net Debit Cap (which may be set as part of on-boarding), + 2. Adjustment of the limit - Net Debit Cap, + 3. Adjust of position based on a Settlement. + +The CEP can then be integrated with a notifier service, to send out notifications or alerts. In this instance, it integrates with the email-notifier to send out alerts based on the aforementioned criteria. + +![Central Event Processor Architecture](./assets/diagrams/architecture/CEPArchTechOverview.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg new file mode 100644 index 000000000..40e9f3ae0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg @@ -0,0 +1,2 @@ + +


    Notifiers
    /email, sms, etc./
    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    prepare 
    [Not supported by viewer]
    fulfil 
    [Not supported by viewer]
    notification 
    <b>notification </b>

    DB
    [Not supported by viewer]
    Central-Services
    Central-Services

    MangoDB
    [Not supported by viewer]
    Central Event
    Processor (CEP)

    [Not supported by viewer]
    RxJS
    RxJS
    json-rule-engine
    json-rule-engine

    Heading

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    [Not supported by viewer]
    REST admin API
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml new file mode 100644 index 000000000..d01340e1f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml @@ -0,0 +1,94 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 9.1.0. Event Handler Placeholder + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Event Handler Placeholder" as EVENT_HANDLER + +box "Event Handler Placeholder" #LightGray + participant EVENT_HANDLER +end box + +collections "Event-Topic" as TOPIC_EVENTS + +' start flow +activate EVENT_HANDLER + +group Event Handler Placeholder + EVENT_HANDLER -> TOPIC_EVENTS: Consume Event message \n Error code: 2001 + note right of EVENT_HANDLER #yellow + Message: + { + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: INFO, + action: AUDIT, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + note right of EVENT_HANDLER #LightGray + The type would be an ENUM with values: + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + Possible values for "action" would be + [AUDIT, EXCEPTION] + The event messages can be handled based on the values of these two variables + (when the placeholder is extended). + end note + EVENT_HANDLER -> EVENT_HANDLER: Auto-commit \n Error code: 2001 + note right of EVENT_HANDLER #lightBlue + Currently events to only be published as part of the placeholder. + This can be evolved to add relevant functionality. + end note + activate TOPIC_EVENTS + deactivate TOPIC_EVENTS +end +deactivate EVENT_HANDLER + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg new file mode 100644 index 000000000..3f48ce80a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + 9.1.0. Event Handler Placeholder + + + + Event Handler Placeholder + + + + + + Event Handler Placeholder + + + + + Event Handler Placeholder + + + + + + + Event-Topic + + + + + Event-Topic + + + + + + Event Handler Placeholder + + + + + 1 + + + Consume Event message + + + Error code: + + + 2001 + + + + + Message: + + + { + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: INFO, + + + action: AUDIT, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + The type would be an ENUM with values: + + + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + + + Possible values for "action" would be + + + [AUDIT, EXCEPTION] + + + The event messages can be handled based on the values of these two variables + + + (when the placeholder is extended). + + + + + 2 + + + Auto-commit + + + Error code: + + + 2001 + + + + + Currently events to only be published as part of the placeholder. + + + This can be evolved to add relevant functionality. + + diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml new file mode 100644 index 000000000..38e5e7dd3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml @@ -0,0 +1,111 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Henk Kodde + -------------- + ******'/ + +@startuml +' declate title +title 5.1.1. Notification Handler for Rejections + +autonumber + +' Actor Keys: + +' declare actors + +actor "DFSP1\nPayer" as DFSP1 +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Event-Topic" as TOPIC_EVENT +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS +end box + +' start flow + +group DFSP Notified of Rejection + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> TOPIC_NOTIFICATIONS: Consume Notification event message \n Error code: 2001 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + group Persist Event Information + NOTIFY_HANDLER -> TOPIC_EVENT: Publish event information \n Error code: 3201 + activate TOPIC_EVENT + ref over TOPIC_EVENT : Event Handler + deactivate TOPIC_EVENT + end + + alt consume a single messages + group Validate Event + NOTIFY_HANDLER <-> NOTIFY_HANDLER: Validate event - Rule: type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + end + NOTIFY_HANDLER -> CSAPI: Request Participant Callback details \n Error code: 3201 + ref over NOTIFY_HANDLER, CSAPI: Get Participant Callback Details + NOTIFY_HANDLER <-- CSAPI: Return Participant Callback details + note left of NOTIFY_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + payload: + }, + } + end note + NOTIFY_HANDLER --> DFSP1: Send Callback Notification \n Error code: 1000, 1001, 3002 + else Validate rule type != 'notification' / Error + note right of NOTIFY_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + NOTIFY_HANDLER -> TOPIC_EVENT: Invalid messages retrieved from the Notification Topic \n Error code: 3201 + activate TOPIC_EVENT + deactivate TOPIC_EVENT + ref over TOPIC_EVENT: Event Handler + note right of NOTIFY_HANDLER #lightblue + Log ERROR Messages + Update Event log upon ERROR notification + end note +' deactivate TOPIC_NOTIFICATIONS + end +end +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg new file mode 100644 index 000000000..6eb610b07 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + 5.1.1. Notification Handler for Rejections + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP Notified of Rejection + + + + + 1 + + + Consume Notification event message + + + Error code: + + + 2001 + + + + + Persist Event Information + + + + + 2 + + + Publish event information + + + Error code: + + + 3201 + + + + + ref + + + Event Handler + + + + + alt + + + [consume a single messages] + + + + + Validate Event + + + + + 3 + + + Validate event - Rule: type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + + + + + 4 + + + Request Participant Callback details + + + Error code: + + + 3201 + + + + + ref + + + Get Participant Callback Details + + + + + 5 + + + Return Participant Callback details + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + payload: <transferMessage> + + + }, + + + } + + + + + 6 + + + Send Callback Notification + + + Error code: + + + 1000, 1001, 3002 + + + + [Validate rule type != 'notification' / Error] + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <ErrorMessage>, + + + } + + + } + + + + + 7 + + + Invalid messages retrieved from the Notification Topic + + + Error code: + + + 3201 + + + + + ref + + + Event Handler + + + + + Log ERROR Messages + + + Update Event log upon ERROR notification + + diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml new file mode 100644 index 000000000..03a932865 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml @@ -0,0 +1,35 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + * Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title Signature Validation + +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: another authentication Response +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg new file mode 100644 index 000000000..4e80c45ca --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + Signature Validation + + + + + Alice + + + + Alice + + + + Bob + + + + Bob + + + + + Authentication Request + + + + + Authentication Response + + + + + Another authentication Request + + + + + another authentication Response + + diff --git a/legacy/mojaloop-technical-overview/central-event-processor/signature-validation.md b/legacy/mojaloop-technical-overview/central-event-processor/signature-validation.md new file mode 100644 index 000000000..e4aabbbe7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-event-processor/signature-validation.md @@ -0,0 +1,7 @@ +# Signature Validation + +Sequence design diagram for the Signature Validation process. + +## Sequence Diagram + +![seq-signature-validation.svg](./assets/diagrams/sequence/seq-signature-validation.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/.gitkeep b/legacy/mojaloop-technical-overview/central-ledger/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/legacy/mojaloop-technical-overview/central-ledger/README.md b/legacy/mojaloop-technical-overview/central-ledger/README.md new file mode 100644 index 000000000..4d5089388 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/README.md @@ -0,0 +1,52 @@ +# Central-Ledger Services + +The central ledger is a series of services that facilitate clearing and settlement of transfers between DFSPs, including the following functions: + +* Brokering real-time messaging for funds clearing +* Maintaining net positions for a deferred net settlement +* Propagating scheme-level and off-transfer fees + +## 1. Central Ledger Process Design + +### 1.1 Architecture overview + +![Central-Ledger Architecture](assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg) + +## 2. Transfers End-to-End Architecture + + +### 2.1 Transfers End-to-End Architecture for v1.1 +![Transfers Architecture for Mojaloop FSP Interoperability API v1.1](assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg) + +### 2.2 Transfers End-to-End Architecture for v1.0 +![Transfers Architecture for Mojaloop FSP Interoperability API v1.0](assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg) + +## 3. Database Design + +### Note + +The tables *Grey* colored tables are specific to the transfer process. The *Blue* and *Green* color tables are used for reference purposes during the Transfer process. + +Summary of the tables specific to the transfer process; + +- `transfer` - stores data related to the transfer; +- `transferDuplicateCheck` - used to identify duplication during the transfer requests process; +- `transferError` - stores information on transfer errors encountered during the transfer process; +- `transferErrorDuplicateCheck` - used to identify duplication error transfer processes; +- `transferExtensions` - stores information on the transfer extension data; +- `transferFulfilment` - stores data for transfers that have completed the prepare transfer process; +- `transferFulfilmentDuplicateCheck` - used the identify duplicate transfer fulfil requests; +- `transferParticipant` - participant information related to the transfer process; +- `transferStateChange` - use to track state changes of each individual transfer, creating and audit trail for a specific transfer request; +- `transferTimeout` - stores information of transfers that encountered a timeout exception during the process; +- `ilpPacket` - stores the ilp package for the transfer; + +The remaining tables in the below ERD are either lookup (blue) or settlement-specific (red) and are included as direct or indirect dependencies to depict the relation between the transfer specific entities and the transfer tables. + +The **Central Ledger** database schema definition [Central-Ledger Database Schema Definition](assets/database/central-ledger-ddl-MySQLWorkbench.sql). + +![Central-Ledger Database Diagram](assets/database/central-ledger-schema.png) + +## 4. API Specification + +Refer to **Central Ledger API** in the [API Specifications](../../api/README.md#central-ledger-api) section. diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md new file mode 100644 index 000000000..021204219 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md @@ -0,0 +1,265 @@ +# GET Health Check + +Design discussion for new Health Check implementation. + + +## Objectives + +The goal for this design is to implement a new Health check for mojaloop switch services that allows for a greater level of detail. + +It Features: +- Clear HTTP Statuses (no need to inspect the response to know there are no issues) +- ~Backwards compatibility with existing health checks~ - No longer a requirement. See [this discussion](https://github.com/mojaloop/project/issues/796#issuecomment-498350828). +- Information about the version of the API, and how long it has been running for +- Information about sub-service (kafka, logging sidecar and mysql) connections + +## Request Format +`/health` + +Uses the newly implemented health check. As discussed [here](https://github.com/mojaloop/project/issues/796#issuecomment-498350828) since there will be no added connection overhead (e.g. pinging a database) as part of implementing the health check, there is no need to complicate things with a simple and detailed version. + +Responses Codes: +- `200` - Success. The API is up and running, and is sucessfully connected to necessary services. +- `502` - Bad Gateway. The API is up and running, but the API cannot connect to necessary service (eg. `kafka`). +- `503` - Service Unavailable. This response is not implemented in this design, but will be the default if the api is not and running + +## Response Format + +| Name | Type | Description | Example | +| --- | --- | --- | --- | +| `status` | `statusEnum` | The status of the service. Options are `OK` and `DOWN`. _See `statusEnum` below_. | `"OK"` | +| `uptime` | `number` | How long (in seconds) the service has been alive for. | `123456` | +| `started` | `string` (ISO formatted date-time) | When the service was started (UTC) | `"2019-05-31T05:09:25.409Z"` | +| `versionNumber` | `string` (semver) | The current version of the service. | `"5.2.5"` | +| `services` | `Array` | A list of services this service depends on, and their connection status | _see below_ | + +### serviceHealth + +| Name | Type | Description | Example | +| --- | --- | --- | --- | +| `name` | `subServiceEnum` | The sub-service name. _See `subServiceEnum` below_. | `"broker"` | +| `status` | `enum` | The status of the service. Options are `OK` and `DOWN` | `"OK"` | + +### subServiceEnum + +The subServiceEnum enum describes a name of the subservice: + +Options: +- `datastore` -> The database for this service (typically a MySQL Database). +- `broker` -> The message broker for this service (typically Kafka). +- `sidecar` -> The logging sidecar sub-service this service attaches to. +- `cache` -> The caching sub-service this services attaches to. + + +### statusEnum + +The status enum represents status of the system or sub-service. + +It has two options: +- `OK` -> The service or sub-service is healthy. +- `DOWN` -> The service or sub-service is unhealthy. + +When a service is `OK`: the API is considered healthy, and all sub-services are also considered healthy. + +If __any__ sub-service is `DOWN`, then the entire health check will fail, and the API will be considered `DOWN`. + +## Defining Sub-Service health + +It is not enough to simply ping a sub-service to know if it is healthy, we want to go one step further. These criteria will change with each sub-service. + +### `datastore` + +For `datastore`, a status of `OK` means: +- An existing connection to the database +- The database is not empty (contains more than 1 table) + + +### `broker` + +For `broker`, a status of `OK` means: +- An existing connection to the kafka broker +- The necessary topics exist. This will change depending on which service the health check is running for. + +For example, for the `central-ledger` service to be considered healthy, the following topics need to be found: +``` +topic-admin-transfer +topic-transfer-prepare +topic-transfer-position +topic-transfer-fulfil +``` + +### `sidecar` + +For `sidecar`, a status of `OK` means: +- An existing connection to the sidecar + + +### `cache` + +For `cache`, a status of `OK` means: +- An existing connection to the cache + + +## Swagger Definition + +>_Note: These will be added to the existing swagger definitions for the following services:_ +> - `ml-api-adapter` +> - `central-ledger` +> - `central-settlement` +> - `central-event-processor` +> - `email-notifier` + +```json +{ + /// . . . + "/health": { + "get": { + "operationId": "getHealth", + "tags": [ + "health" + ], + "responses": { + "default": { + "schema": { + "$ref": "#/definitions/health" + }, + "description": "Successful" + } + } + } + }, + // . . . + "definitions": { + "health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + }, + "uptime": { + "description": "How long (in seconds) the service has been alive for.", + "type": "number", + }, + "started": { + "description": "When the service was started (UTC)", + "type": "string", + "format": "date-time" + }, + "versionNumber": { + "description": "The current version of the service.", + "type": "string", + "example": "5.2.3", + }, + "services": { + "description": "A list of services this service depends on, and their connection status", + "type": "array", + "items": { + "$ref": "#/definitions/serviceHealth" + } + }, + }, + }, + "serviceHealth": { + "type": "object", + "properties": { + "name": { + "description": "The sub-service name.", + "type": "string", + "enum": [ + "datastore", + "broker", + "sidecar", + "cache" + ] + }, + "status": { + "description": "The connection status with the service.", + "type": "string", + "enum": [ + "OK", + "DOWN" + ] + } + } + } + } +} +``` + + +### Example Requests and Responses: + +__Successful Legacy Health Check:__ + +```bash +GET /health HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK" +} +``` + + +__Successful New Health Check:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +200 SUCCESS +{ + "status": "OK", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "OK", + } + ] +} +``` + +__Failed Health Check, but API is up:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +502 BAD GATEWAY +{ + "status": "DOWN", + "uptime": 0, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "broker", + "status": "DOWN", + } + ] +} +``` + +__Failed Health Check:__ + +``` +GET /health?detailed=true HTTP/1.1 +Content-Type: application/json + +503 SERVICE UNAVAILABLE +``` + + +## Sequence Diagram + +Sequence design diagram for the GET Health + +![seq-get-health-1.0.0.svg](../assets/diagrams/sequence/seq-get-health-1.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md new file mode 100644 index 000000000..7a1c5e933 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md @@ -0,0 +1,7 @@ +# GET Participant Limit Details For All Participants + +Sequence design diagram for the GET Participant Limit Details For All Participants process. + +## Sequence Diagram + +![seq-get-all-participant-limit-1.0.0.svg](../assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md new file mode 100644 index 000000000..6fda674e3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md @@ -0,0 +1,7 @@ +# Create initial position and limits for Participant + +Sequence design diagram for the POST (create) Participant Initial Position and Limit process. + +## Sequence Diagram + +![seq-participant-position-limits-1.0.0.svg](../assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md new file mode 100644 index 000000000..2419df6fe --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md @@ -0,0 +1,7 @@ +# Request Participant Position and Limit Details + +Sequence design diagram for the Request Participant Position and Limit Details process. + +## Sequence Diagram + +![seq-get-participant-position-limit-1.1.0.svg](../assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md new file mode 100644 index 000000000..99fb44d05 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md @@ -0,0 +1,7 @@ +# Adjust Participant Limit for a certain Currency + +Sequence design diagram for the POST (manage) Participant Limit Details process. + +## Sequence Diagram + +![seq-manage-participant-limit-1.1.0.svg](../assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md new file mode 100644 index 000000000..b5c1f6734 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md @@ -0,0 +1,7 @@ +# Request transfer status + +Sequence design diagram for the GET Transfer Status process. + +## Sequence Diagram + +![seq-get-transfer-1.1.5-phase2.svg](../assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md new file mode 100644 index 000000000..72020a489 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Get Participant Callback Details + +Sequence design diagram for the GET Participant Callback Details process. + +## Sequence Diagram + +![seq-callback-3.1.0.svg](../assets/diagrams/sequence/seq-callback-3.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md new file mode 100644 index 000000000..2b9afae31 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md @@ -0,0 +1,7 @@ +# 3.1.0 Add Participant Callback Details + +Sequence design diagram for the POST (Add) Participant Callback Details process. + +## Sequence Diagram + +![seq-callback-add-3.1.0.svg](../assets/diagrams/sequence/seq-callback-add-3.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md new file mode 100644 index 000000000..1153ef409 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md @@ -0,0 +1,7 @@ +# Get Participant Position Details + +Sequence design diagram for the GET Participant Position Details process. + +## Sequence Diagram + +![seq-participants-positions-query-4.1.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md new file mode 100644 index 000000000..176494d61 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md @@ -0,0 +1,7 @@ +# Get Position Details for all Participants + +Sequence design diagram for the Get Positions of all Participants process. + +## Sequence Diagram + +![seq-participants-positions-query-all-4.2.0.svg](../assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/admin-operations/README.md b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/README.md new file mode 100644 index 000000000..ebdb6ac1d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/admin-operations/README.md @@ -0,0 +1,3 @@ +# Mojaloop HUB/Switch operations + +Operational processes normally initiated by a HUB/Switch operator. diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/database/README.md b/legacy/mojaloop-technical-overview/central-ledger/assets/database/README.md new file mode 100644 index 000000000..77d71d79d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/database/README.md @@ -0,0 +1,17 @@ +# How to EDIT the central-ledger-schema-DBeaver.erd file + +This is a basic guide on how to successfully view/update the central-ledger-schema-DBeaver.erd file. + +## Prerequisites +* Download and install the DBeaver Community DB Manager +* The Mojaloop Central-Ledger MySQL Database needs to be up and running, and connectable by the DBeaver +* You'll also need a text editor +## Steps to follow +* Create a new db connection in DBeaver under Database Navigator tab for the MySQL instance running. +* Under the Projects tab right click and create a New ER Diagram. +* Give the diagram a name and select central-ledger db in the wizard. + +* Copy the `central-ledger-schema-DBeaver.erd` file from the documentation module to `DBeaverData/workspace/General/Diagrams` in your DBeaver storage location +* Navigate to the newly created erd file using a text editor, search for `data-source id` and copy its value which looks like `mysql5-171ea991174-1218b6e1bf273693`. +* Navigate with a text editor to the `central-ledger-schema-DBeaver.erd` file in the ER Diagrams directory and replace its `data-source id` value with the one copied from the newly created erd file. +* The `central-ledger-schema-DBeaver.erd` should now show the tables as per the `central-ledger-schema.png` \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..280962173 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-ddl-MySQLWorkbench.sql @@ -0,0 +1,1820 @@ +-- MySQL dump 10.13 Distrib 8.0.18, for macos10.14 (x86_64) +-- +-- Host: localhost Database: central_ledger +-- ------------------------------------------------------ +-- Server version 8.0.13 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `amountType` +-- + +DROP TABLE IF EXISTS `amountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `amountType` ( + `amountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`amountTypeId`), + UNIQUE KEY `amounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `balanceOfPayments` +-- + +DROP TABLE IF EXISTS `balanceOfPayments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `balanceOfPayments` ( + `balanceOfPaymentsId` int(10) unsigned NOT NULL, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible values and meaning are defined in https://www.imf.org/external/np/sta/bopcode/', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`balanceOfPaymentsId`), + UNIQUE KEY `balanceofpayments_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='See https://www.imf.org/external/np/sta/bopcode/guide.htm'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkProcessingState` +-- + +DROP TABLE IF EXISTS `bulkProcessingState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkProcessingState` ( + `bulkProcessingStateId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkProcessingStateId`), + UNIQUE KEY `bulkprocessingstate_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransfer` +-- + +DROP TABLE IF EXISTS `bulkTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransfer` ( + `bulkTransferId` varchar(36) NOT NULL, + `bulkQuoteId` varchar(36) DEFAULT NULL, + `payerParticipantId` int(10) unsigned DEFAULT NULL, + `payeeParticipantId` int(10) unsigned DEFAULT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + KEY `bulktransfer_payerparticipantid_index` (`payerParticipantId`), + KEY `bulktransfer_payeeparticipantid_index` (`payeeParticipantId`), + CONSTRAINT `bulktransfer_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferDuplicateCheck` (`bulktransferid`), + CONSTRAINT `bulktransfer_payeeparticipantid_foreign` FOREIGN KEY (`payeeParticipantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `bulktransfer_payerparticipantid_foreign` FOREIGN KEY (`payerParticipantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferAssociation` +-- + +DROP TABLE IF EXISTS `bulkTransferAssociation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferAssociation` ( + `bulkTransferAssociationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `bulkTransferId` varchar(36) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `bulkProcessingStateId` int(10) unsigned NOT NULL, + `lastProcessedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `errorCode` int(10) unsigned DEFAULT NULL, + `errorDescription` varchar(128) DEFAULT NULL, + PRIMARY KEY (`bulkTransferAssociationId`), + UNIQUE KEY `bulktransferassociation_transferid_bulktransferid_unique` (`transferId`,`bulkTransferId`), + KEY `bulktransferassociation_bulktransferid_foreign` (`bulkTransferId`), + KEY `bulktransferassociation_bulkprocessingstateid_foreign` (`bulkProcessingStateId`), + CONSTRAINT `bulktransferassociation_bulkprocessingstateid_foreign` FOREIGN KEY (`bulkProcessingStateId`) REFERENCES `bulkProcessingState` (`bulkprocessingstateid`), + CONSTRAINT `bulktransferassociation_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferError` +-- + +DROP TABLE IF EXISTS `bulkTransferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferError` ( + `bulkTransferErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferErrorId`), + KEY `bulktransfererror_bulktransferstatechangeid_index` (`bulkTransferStateChangeId`), + CONSTRAINT `bulktransfererror_bulktransferstatechangeid_foreign` FOREIGN KEY (`bulkTransferStateChangeId`) REFERENCES `bulkTransferStateChange` (`bulktransferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferExtension` +-- + +DROP TABLE IF EXISTS `bulkTransferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferExtension` ( + `bulkTransferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferExtensionId`), + KEY `bulktransferextension_bulktransferid_index` (`bulkTransferId`), + CONSTRAINT `bulktransferextension_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilment` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferFulfilment` ( + `bulkTransferId` varchar(36) NOT NULL, + `completedDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilment_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransferFulfilmentDuplicateCheck` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `bulkTransferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferFulfilmentDuplicateCheck` ( + `bulkTransferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferId`), + CONSTRAINT `bulktransferfulfilmentduplicatecheck_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferState` +-- + +DROP TABLE IF EXISTS `bulkTransferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferState` ( + `bulkTransferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'bulkTransferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `bulkTransferStateChange` +-- + +DROP TABLE IF EXISTS `bulkTransferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bulkTransferStateChange` ( + `bulkTransferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `bulkTransferId` varchar(36) NOT NULL, + `bulkTransferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`bulkTransferStateChangeId`), + KEY `bulktransferstatechange_bulktransferid_index` (`bulkTransferId`), + KEY `bulktransferstatechange_bulktransferstateid_index` (`bulkTransferStateId`), + CONSTRAINT `bulktransferstatechange_bulktransferid_foreign` FOREIGN KEY (`bulkTransferId`) REFERENCES `bulkTransfer` (`bulktransferid`), + CONSTRAINT `bulktransferstatechange_bulktransferstateid_foreign` FOREIGN KEY (`bulkTransferStateId`) REFERENCES `bulkTransferState` (`bulktransferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `contactType` +-- + +DROP TABLE IF EXISTS `contactType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `contactType` ( + `contactTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`contactTypeId`), + UNIQUE KEY `contacttype_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `scale` int(10) unsigned NOT NULL DEFAULT '4', + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `event` +-- + +DROP TABLE IF EXISTS `event`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `event` ( + `eventId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`eventId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `expiringTransfer` +-- + +DROP TABLE IF EXISTS `expiringTransfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `expiringTransfer` ( + `expiringTransferId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`expiringTransferId`), + UNIQUE KEY `expiringtransfer_transferid_unique` (`transferId`), + KEY `expiringtransfer_expirationdate_index` (`expirationDate`), + CONSTRAINT `expiringtransfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `geoCode` +-- + +DROP TABLE IF EXISTS `geoCode`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `geoCode` ( + `geoCodeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL COMMENT 'Optionally the GeoCode for the Payer/Payee may have been provided. If the Quote Response has the GeoCode for the Payee, an additional row is added', + `latitude` varchar(50) NOT NULL COMMENT 'Latitude of the initiating Party', + `longitude` varchar(50) NOT NULL COMMENT 'Longitude of the initiating Party', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`geoCodeId`), + KEY `geocode_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `geocode_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ilpPacket` +-- + +DROP TABLE IF EXISTS `ilpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ilpPacket` ( + `transferId` varchar(36) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `ilppacket_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerAccountType` +-- + +DROP TABLE IF EXISTS `ledgerAccountType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ledgerAccountType` ( + `ledgerAccountTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `isSettleable` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`ledgerAccountTypeId`), + UNIQUE KEY `ledgeraccounttype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `ledgerEntryType` +-- + +DROP TABLE IF EXISTS `ledgerEntryType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ledgerEntryType` ( + `ledgerEntryTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ledgerAccountTypeId` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`ledgerEntryTypeId`), + UNIQUE KEY `ledgerentrytype_name_unique` (`name`), + KEY `ledgerentrytype_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + CONSTRAINT `ledgerentrytype_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participant` +-- + +DROP TABLE IF EXISTS `participant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participant` ( + `participantId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantId`), + UNIQUE KEY `participant_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantContact` +-- + +DROP TABLE IF EXISTS `participantContact`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantContact` ( + `participantContactId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `contactTypeId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `priorityPreference` int(11) NOT NULL DEFAULT '9', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantContactId`), + KEY `participantcontact_participantid_index` (`participantId`), + KEY `participantcontact_contacttypeid_index` (`contactTypeId`), + CONSTRAINT `participantcontact_contacttypeid_foreign` FOREIGN KEY (`contactTypeId`) REFERENCES `contactType` (`contacttypeid`), + CONSTRAINT `participantcontact_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantCurrency` +-- + +DROP TABLE IF EXISTS `participantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantCurrency` ( + `participantCurrencyId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantCurrencyId`), + UNIQUE KEY `participantcurrency_pcl_unique` (`participantId`,`currencyId`,`ledgerAccountTypeId`), + KEY `participantcurrency_ledgeraccounttypeid_foreign` (`ledgerAccountTypeId`), + KEY `participantcurrency_participantid_index` (`participantId`), + KEY `participantcurrency_currencyid_index` (`currencyId`), + CONSTRAINT `participantcurrency_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `participantcurrency_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `participantcurrency_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantEndpoint` +-- + +DROP TABLE IF EXISTS `participantEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantEndpoint` ( + `participantEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `value` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantEndpointId`), + KEY `participantendpoint_participantid_index` (`participantId`), + KEY `participantendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `participantendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `participantendpoint_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimit` +-- + +DROP TABLE IF EXISTS `participantLimit`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantLimit` ( + `participantLimitId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `participantLimitTypeId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL DEFAULT '0.0000', + `thresholdAlarmPercentage` decimal(5,2) NOT NULL DEFAULT '10.00', + `startAfterParticipantPositionChangeId` bigint(20) unsigned DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`participantLimitId`), + KEY `participantlimit_participantcurrencyid_index` (`participantCurrencyId`), + KEY `participantlimit_participantlimittypeid_index` (`participantLimitTypeId`), + KEY `participantlimit_startafterparticipantpositionchangeid_index` (`startAfterParticipantPositionChangeId`), + CONSTRAINT `participantlimit_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `participantlimit_participantlimittypeid_foreign` FOREIGN KEY (`participantLimitTypeId`) REFERENCES `participantLimitType` (`participantlimittypeid`), + CONSTRAINT `participantlimit_startafterparticipantpositionchangeid_foreign` FOREIGN KEY (`startAfterParticipantPositionChangeId`) REFERENCES `participantPositionChange` (`participantpositionchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantLimitType` +-- + +DROP TABLE IF EXISTS `participantLimitType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantLimitType` ( + `participantLimitTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantLimitTypeId`), + UNIQUE KEY `participantlimittype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantParty` +-- + +DROP TABLE IF EXISTS `participantParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantParty` ( + `participantPartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `partyId` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`participantPartyId`), + UNIQUE KEY `participantparty_participantid_partyid_unique` (`participantId`,`partyId`), + KEY `participantparty_participantid_index` (`participantId`), + CONSTRAINT `participantparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPosition` +-- + +DROP TABLE IF EXISTS `participantPosition`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantPosition` ( + `participantPositionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantCurrencyId` int(10) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionId`), + KEY `participantposition_participantcurrencyid_index` (`participantCurrencyId`), + CONSTRAINT `participantposition_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `participantPositionChange` +-- + +DROP TABLE IF EXISTS `participantPositionChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `participantPositionChange` ( + `participantPositionChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `participantPositionId` bigint(20) unsigned NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `value` decimal(18,4) NOT NULL, + `reservedValue` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`participantPositionChangeId`), + KEY `participantpositionchange_participantpositionid_index` (`participantPositionId`), + KEY `participantpositionchange_transferstatechangeid_index` (`transferStateChangeId`), + CONSTRAINT `participantpositionchange_participantpositionid_foreign` FOREIGN KEY (`participantPositionId`) REFERENCES `participantPosition` (`participantpositionid`), + CONSTRAINT `participantpositionchange_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `party` +-- + +DROP TABLE IF EXISTS `party`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `party` ( + `partyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quotePartyId` bigint(20) unsigned NOT NULL, + `firstName` varchar(128) DEFAULT NULL, + `middleName` varchar(128) DEFAULT NULL, + `lastName` varchar(128) DEFAULT NULL, + `dateOfBirth` datetime DEFAULT NULL, + PRIMARY KEY (`partyId`), + KEY `party_quotepartyid_foreign` (`quotePartyId`), + CONSTRAINT `party_quotepartyid_foreign` FOREIGN KEY (`quotePartyId`) REFERENCES `quoteParty` (`quotepartyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Optional pers. data provided during Quote Request & Response'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyIdentifierType` +-- + +DROP TABLE IF EXISTS `partyIdentifierType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `partyIdentifierType` ( + `partyIdentifierTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) NOT NULL, + PRIMARY KEY (`partyIdentifierTypeId`), + UNIQUE KEY `partyidentifiertype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `partyType` +-- + +DROP TABLE IF EXISTS `partyType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `partyType` ( + `partyTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(256) NOT NULL, + PRIMARY KEY (`partyTypeId`), + UNIQUE KEY `partytype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quote` +-- + +DROP TABLE IF EXISTS `quote`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quote` ( + `quoteId` varchar(36) NOT NULL, + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `transactionRequestId` varchar(36) DEFAULT NULL COMMENT 'Optional previously-sent transaction request', + `note` text COMMENT 'A memo that will be attached to the transaction', + `expirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `transactionInitiatorId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator', + `transactionInitiatorTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction initiator type', + `transactionScenarioId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction scenario', + `balanceOfPaymentsId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type that contains the elements- balance of payment', + `transactionSubScenarioId` int(10) unsigned DEFAULT NULL COMMENT 'This is part of the transaction type sub scenario as defined by the local scheme', + `amountTypeId` int(10) unsigned NOT NULL COMMENT 'This is part of the transaction type that contains valid elements for - Amount Type', + `amount` decimal(18,4) NOT NULL DEFAULT '0.0000' COMMENT 'The amount that the quote is being requested for. Need to be interpert in accordance with the amount type', + `currencyId` varchar(255) DEFAULT NULL COMMENT 'Trading currency pertaining to the Amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`), + KEY `quote_transactionreferenceid_foreign` (`transactionReferenceId`), + KEY `quote_transactionrequestid_foreign` (`transactionRequestId`), + KEY `quote_transactioninitiatorid_foreign` (`transactionInitiatorId`), + KEY `quote_transactioninitiatortypeid_foreign` (`transactionInitiatorTypeId`), + KEY `quote_transactionscenarioid_foreign` (`transactionScenarioId`), + KEY `quote_balanceofpaymentsid_foreign` (`balanceOfPaymentsId`), + KEY `quote_transactionsubscenarioid_foreign` (`transactionSubScenarioId`), + KEY `quote_amounttypeid_foreign` (`amountTypeId`), + KEY `quote_currencyid_foreign` (`currencyId`), + CONSTRAINT `quote_amounttypeid_foreign` FOREIGN KEY (`amountTypeId`) REFERENCES `amountType` (`amounttypeid`), + CONSTRAINT `quote_balanceofpaymentsid_foreign` FOREIGN KEY (`balanceOfPaymentsId`) REFERENCES `balanceOfPayments` (`balanceofpaymentsid`), + CONSTRAINT `quote_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quote_transactioninitiatorid_foreign` FOREIGN KEY (`transactionInitiatorId`) REFERENCES `transactionInitiator` (`transactioninitiatorid`), + CONSTRAINT `quote_transactioninitiatortypeid_foreign` FOREIGN KEY (`transactionInitiatorTypeId`) REFERENCES `transactionInitiatorType` (`transactioninitiatortypeid`), + CONSTRAINT `quote_transactionreferenceid_foreign` FOREIGN KEY (`transactionReferenceId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionrequestid_foreign` FOREIGN KEY (`transactionRequestId`) REFERENCES `transactionReference` (`transactionreferenceid`), + CONSTRAINT `quote_transactionscenarioid_foreign` FOREIGN KEY (`transactionScenarioId`) REFERENCES `transactionScenario` (`transactionscenarioid`), + CONSTRAINT `quote_transactionsubscenarioid_foreign` FOREIGN KEY (`transactionSubScenarioId`) REFERENCES `transactionSubScenario` (`transactionsubscenarioid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteDuplicateCheck` ( + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(1024) DEFAULT NULL COMMENT 'hash value received for the quote request', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteError` +-- + +DROP TABLE IF EXISTS `quoteError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteError` ( + `quoteErrorId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned DEFAULT NULL COMMENT 'The response to the intial quote', + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`quoteErrorId`), + KEY `quoteerror_quoteid_foreign` (`quoteId`), + KEY `quoteerror_quoteresponseid_foreign` (`quoteResponseId`), + CONSTRAINT `quoteerror_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteerror_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteExtension` +-- + +DROP TABLE IF EXISTS `quoteExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteExtension` ( + `quoteExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `quoteResponseId` bigint(20) unsigned NOT NULL COMMENT 'The response to the intial quote', + `transactionId` varchar(36) NOT NULL COMMENT 'The transaction reference that is part of the initial quote', + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteExtensionId`), + KEY `quoteextension_quoteid_foreign` (`quoteId`), + KEY `quoteextension_quoteresponseid_foreign` (`quoteResponseId`), + KEY `quoteextension_transactionid_foreign` (`transactionId`), + CONSTRAINT `quoteextension_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteextension_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`), + CONSTRAINT `quoteextension_transactionid_foreign` FOREIGN KEY (`transactionId`) REFERENCES `transactionReference` (`transactionreferenceid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteParty` +-- + +DROP TABLE IF EXISTS `quoteParty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteParty` ( + `quotePartyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `partyTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of party this row relates to; typically PAYER or PAYEE', + `partyIdentifierTypeId` int(10) unsigned NOT NULL COMMENT 'Specifies the type of identifier used to identify this party e.g. MSISDN, IBAN etc...', + `partyIdentifierValue` varchar(128) NOT NULL COMMENT 'The value of the identifier used to identify this party', + `partySubIdOrTypeId` int(10) unsigned DEFAULT NULL COMMENT 'A sub-identifier or sub-type for the Party', + `fspId` varchar(255) DEFAULT NULL COMMENT 'This is the FSP ID as provided in the quote. For the switch between multi-parties it is required', + `participantId` int(10) unsigned DEFAULT NULL COMMENT 'Reference to the resolved FSP ID (if supplied/known). If not an error will be reported', + `merchantClassificationCode` varchar(4) DEFAULT NULL COMMENT 'Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments', + `partyName` varchar(128) DEFAULT NULL COMMENT 'Display name of the Party, could be a real name or a nick name', + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL COMMENT 'The role this Party is playing in the transaction', + `ledgerEntryTypeId` int(10) unsigned NOT NULL COMMENT 'The type of financial entry this Party is presenting', + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL COMMENT 'Trading currency pertaining to the party amount', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quotePartyId`), + KEY `quoteparty_quoteid_foreign` (`quoteId`), + KEY `quoteparty_partytypeid_foreign` (`partyTypeId`), + KEY `quoteparty_partyidentifiertypeid_foreign` (`partyIdentifierTypeId`), + KEY `quoteparty_partysubidortypeid_foreign` (`partySubIdOrTypeId`), + KEY `quoteparty_participantid_foreign` (`participantId`), + KEY `quoteparty_transferparticipantroletypeid_foreign` (`transferParticipantRoleTypeId`), + KEY `quoteparty_ledgerentrytypeid_foreign` (`ledgerEntryTypeId`), + KEY `quoteparty_currencyid_foreign` (`currencyId`), + CONSTRAINT `quoteparty_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteparty_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `quoteparty_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`), + CONSTRAINT `quoteparty_partyidentifiertypeid_foreign` FOREIGN KEY (`partyIdentifierTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partysubidortypeid_foreign` FOREIGN KEY (`partySubIdOrTypeId`) REFERENCES `partyIdentifierType` (`partyidentifiertypeid`), + CONSTRAINT `quoteparty_partytypeid_foreign` FOREIGN KEY (`partyTypeId`) REFERENCES `partyType` (`partytypeid`), + CONSTRAINT `quoteparty_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteparty_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quotePartyView` +-- + +DROP TABLE IF EXISTS `quotePartyView`; +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quotePartyView` AS SELECT + 1 AS `quoteId`, + 1 AS `quotePartyId`, + 1 AS `partyType`, + 1 AS `identifierType`, + 1 AS `partyIdentifierValue`, + 1 AS `partySubIdOrType`, + 1 AS `fspId`, + 1 AS `merchantClassificationCode`, + 1 AS `partyName`, + 1 AS `firstName`, + 1 AS `lastName`, + 1 AS `middleName`, + 1 AS `dateOfBirth`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `quoteResponse` +-- + +DROP TABLE IF EXISTS `quoteResponse`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponse` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `transferAmountCurrencyId` varchar(3) NOT NULL COMMENT 'CurrencyId of the transfer amount', + `transferAmount` decimal(18,4) NOT NULL COMMENT 'The amount of money that the Payer FSP should transfer to the Payee FSP', + `payeeReceiveAmountCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee receive amount', + `payeeReceiveAmount` decimal(18,4) DEFAULT NULL COMMENT 'The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees', + `payeeFspFeeCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp fee amount', + `payeeFspFeeAmount` decimal(18,4) DEFAULT NULL COMMENT 'Payee FSP’s part of the transaction fee', + `payeeFspCommissionCurrencyId` varchar(3) DEFAULT NULL COMMENT 'CurrencyId of the payee fsp commission amount', + `payeeFspCommissionAmount` decimal(18,4) DEFAULT NULL COMMENT 'Transaction commission from the Payee FSP', + `ilpCondition` varchar(256) NOT NULL, + `responseExpirationDate` datetime DEFAULT NULL COMMENT 'Optional expiration for the requested transaction', + `isValid` tinyint(1) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponse_quoteid_foreign` (`quoteId`), + KEY `quoteresponse_transferamountcurrencyid_foreign` (`transferAmountCurrencyId`), + KEY `quoteresponse_payeereceiveamountcurrencyid_foreign` (`payeeReceiveAmountCurrencyId`), + KEY `quoteresponse_payeefspcommissioncurrencyid_foreign` (`payeeFspCommissionCurrencyId`), + CONSTRAINT `quoteresponse_payeefspcommissioncurrencyid_foreign` FOREIGN KEY (`payeeFspCommissionCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_payeereceiveamountcurrencyid_foreign` FOREIGN KEY (`payeeReceiveAmountCurrencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `quoteresponse_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponse_transferamountcurrencyid_foreign` FOREIGN KEY (`transferAmountCurrencyId`) REFERENCES `currency` (`currencyid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='This table is the primary store for quote responses'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseDuplicateCheck` +-- + +DROP TABLE IF EXISTS `quoteResponseDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponseDuplicateCheck` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'The response to the intial quote', + `quoteId` varchar(36) NOT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `hash` varchar(255) DEFAULT NULL COMMENT 'hash value received for the quote response', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`quoteResponseId`), + KEY `quoteresponseduplicatecheck_quoteid_foreign` (`quoteId`), + CONSTRAINT `quoteresponseduplicatecheck_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quote` (`quoteid`), + CONSTRAINT `quoteresponseduplicatecheck_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quoteResponseIlpPacket` +-- + +DROP TABLE IF EXISTS `quoteResponseIlpPacket`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `quoteResponseIlpPacket` ( + `quoteResponseId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `value` text NOT NULL COMMENT 'ilpPacket returned from Payee in response to a quote request', + PRIMARY KEY (`quoteResponseId`), + CONSTRAINT `quoteresponseilppacket_quoteresponseid_foreign` FOREIGN KEY (`quoteResponseId`) REFERENCES `quoteResponse` (`quoteresponseid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Temporary view structure for view `quoteResponseView` +-- + +DROP TABLE IF EXISTS `quoteResponseView`; +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quoteResponseView` AS SELECT + 1 AS `quoteResponseId`, + 1 AS `quoteId`, + 1 AS `transferAmountCurrencyId`, + 1 AS `transferAmount`, + 1 AS `payeeReceiveAmountCurrencyId`, + 1 AS `payeeReceiveAmount`, + 1 AS `payeeFspFeeCurrencyId`, + 1 AS `payeeFspFeeAmount`, + 1 AS `payeeFspCommissionCurrencyId`, + 1 AS `payeeFspCommissionAmount`, + 1 AS `ilpCondition`, + 1 AS `responseExpirationDate`, + 1 AS `isValid`, + 1 AS `createdDate`, + 1 AS `ilpPacket`, + 1 AS `longitude`, + 1 AS `latitude`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Temporary view structure for view `quoteView` +-- + +DROP TABLE IF EXISTS `quoteView`; +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +SET @saved_cs_client = @@character_set_client; +/*!50503 SET character_set_client = utf8mb4 */; +/*!50001 CREATE VIEW `quoteView` AS SELECT + 1 AS `quoteId`, + 1 AS `transactionReferenceId`, + 1 AS `transactionRequestId`, + 1 AS `note`, + 1 AS `expirationDate`, + 1 AS `transactionInitiator`, + 1 AS `transactionInitiatorType`, + 1 AS `transactionScenario`, + 1 AS `balanceOfPaymentsId`, + 1 AS `transactionSubScenario`, + 1 AS `amountType`, + 1 AS `amount`, + 1 AS `currency`*/; +SET character_set_client = @saved_cs_client; + +-- +-- Table structure for table `segment` +-- + +DROP TABLE IF EXISTS `segment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `segment` ( + `segmentId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `segmentType` varchar(50) NOT NULL, + `enumeration` int(11) NOT NULL DEFAULT '0', + `tableName` varchar(50) NOT NULL, + `value` bigint(20) NOT NULL, + `changedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`segmentId`), + KEY `segment_keys_index` (`segmentType`,`enumeration`,`tableName`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlement` +-- + +DROP TABLE IF EXISTS `settlement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlement` ( + `settlementId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementModelId` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementId`), + KEY `settlement_currentstatechangeid_foreign` (`currentStateChangeId`), + KEY `settlement_settlementmodelid_foreign` (`settlementModelId`), + CONSTRAINT `settlement_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementStateChange` (`settlementstatechangeid`), + CONSTRAINT `settlement_settlementmodelid_foreign` FOREIGN KEY (`settlementModelId`) REFERENCES `settlementModel` (`settlementmodelid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementContentAggregation` +-- + +DROP TABLE IF EXISTS `settlementContentAggregation`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementContentAggregation` ( + `settlementContentAggregationId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowContentId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,2) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateId` varchar(50) NOT NULL, + `settlementId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementContentAggregationId`), + KEY `settlementcontentaggregation_settlementwindowcontentid_index` (`settlementWindowContentId`), + KEY `settlementcontentaggregation_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementcontentaggregation_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementcontentaggregation_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + KEY `settlementcontentaggregation_currentstateid_index` (`currentStateId`), + KEY `settlementcontentaggregation_settlementid_index` (`settlementId`), + CONSTRAINT `sca_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`), + CONSTRAINT `settlementcontentaggregation_currentstateid_foreign` FOREIGN KEY (`currentStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`), + CONSTRAINT `settlementcontentaggregation_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementcontentaggregation_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementcontentaggregation_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementcontentaggregation_settlementwindowcontentid_foreign` FOREIGN KEY (`settlementWindowContentId`) REFERENCES `settlementWindowContent` (`settlementwindowcontentid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementDelay` +-- + +DROP TABLE IF EXISTS `settlementDelay`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementDelay` ( + `settlementDelayId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementDelayId`), + UNIQUE KEY `settlementdelay_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementGranularity` +-- + +DROP TABLE IF EXISTS `settlementGranularity`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementGranularity` ( + `settlementGranularityId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementGranularityId`), + UNIQUE KEY `settlementgranularity_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementInterchange` +-- + +DROP TABLE IF EXISTS `settlementInterchange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementInterchange` ( + `settlementInterchangeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`settlementInterchangeId`), + UNIQUE KEY `settlementinterchange_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementModel` +-- + +DROP TABLE IF EXISTS `settlementModel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementModel` ( + `settlementModelId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `settlementGranularityId` int(10) unsigned NOT NULL, + `settlementInterchangeId` int(10) unsigned NOT NULL, + `settlementDelayId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) DEFAULT NULL, + `requireLiquidityCheck` tinyint(1) NOT NULL DEFAULT '1', + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `autoPositionReset` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`settlementModelId`), + UNIQUE KEY `settlementmodel_name_unique` (`name`), + KEY `settlementmodel_settlementgranularityid_index` (`settlementGranularityId`), + KEY `settlementmodel_settlementinterchangeid_index` (`settlementInterchangeId`), + KEY `settlementmodel_settlementdelayid_index` (`settlementDelayId`), + KEY `settlementmodel_currencyid_index` (`currencyId`), + KEY `settlementmodel_ledgeraccounttypeid_index` (`ledgerAccountTypeId`), + CONSTRAINT `settlementmodel_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `settlementmodel_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `settlementmodel_settlementdelayid_foreign` FOREIGN KEY (`settlementDelayId`) REFERENCES `settlementDelay` (`settlementdelayid`), + CONSTRAINT `settlementmodel_settlementgranularityid_foreign` FOREIGN KEY (`settlementGranularityId`) REFERENCES `settlementGranularity` (`settlementgranularityid`), + CONSTRAINT `settlementmodel_settlementinterchangeid_foreign` FOREIGN KEY (`settlementInterchangeId`) REFERENCES `settlementInterchange` (`settlementinterchangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrency` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementParticipantCurrency` ( + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `netAmount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementTransferId` varchar(36) DEFAULT NULL, + PRIMARY KEY (`settlementParticipantCurrencyId`), + KEY `settlementparticipantcurrency_settlementid_index` (`settlementId`), + KEY `settlementparticipantcurrency_participantcurrencyid_index` (`participantCurrencyId`), + KEY `settlementparticipantcurrency_settlementtransferid_index` (`settlementTransferId`), + KEY `spc_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementparticipantcurrency_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementparticipantcurrency_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `spc_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementParticipantCurrencyStateChange` (`settlementparticipantcurrencystatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementParticipantCurrencyStateChange` +-- + +DROP TABLE IF EXISTS `settlementParticipantCurrencyStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementParticipantCurrencyStateChange` ( + `settlementParticipantCurrencyStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementParticipantCurrencyId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `externalReference` varchar(50) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementParticipantCurrencyStateChangeId`), + KEY `spcsc_settlementparticipantcurrencyid_index` (`settlementParticipantCurrencyId`), + KEY `spcsc_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `spcsc_settlementparticipantcurrencyid_foreign` FOREIGN KEY (`settlementParticipantCurrencyId`) REFERENCES `settlementParticipantCurrency` (`settlementparticipantcurrencyid`), + CONSTRAINT `spcsc_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementSettlementWindow` +-- + +DROP TABLE IF EXISTS `settlementSettlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementSettlementWindow` ( + `settlementSettlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementSettlementWindowId`), + UNIQUE KEY `settlementsettlementwindow_unique` (`settlementId`,`settlementWindowId`), + KEY `settlementsettlementwindow_settlementid_index` (`settlementId`), + KEY `settlementsettlementwindow_settlementwindowid_index` (`settlementWindowId`), + CONSTRAINT `settlementsettlementwindow_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementsettlementwindow_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementState` +-- + +DROP TABLE IF EXISTS `settlementState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementState` ( + `settlementStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementStateChange` +-- + +DROP TABLE IF EXISTS `settlementStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementStateChange` ( + `settlementStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementStateChangeId`), + KEY `settlementstatechange_settlementid_index` (`settlementId`), + KEY `settlementstatechange_settlementstateid_index` (`settlementStateId`), + CONSTRAINT `settlementstatechange_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementstatechange_settlementstateid_foreign` FOREIGN KEY (`settlementStateId`) REFERENCES `settlementState` (`settlementstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementTransferParticipant` +-- + +DROP TABLE IF EXISTS `settlementTransferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementTransferParticipant` ( + `settlementTransferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementId` bigint(20) unsigned NOT NULL, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementTransferParticipantId`), + KEY `settlementtransferparticipant_settlementid_index` (`settlementId`), + KEY `settlementtransferparticipant_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementtransferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `stp_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `settlementtransferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + CONSTRAINT `settlementtransferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `settlementtransferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `settlementtransferparticipant_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementtransferparticipant_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `stp_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindow` +-- + +DROP TABLE IF EXISTS `settlementWindow`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindow` ( + `settlementWindowId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowId`), + KEY `settlementwindow_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `settlementwindow_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowStateChange` (`settlementwindowstatechangeid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowContent` +-- + +DROP TABLE IF EXISTS `settlementWindowContent`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowContent` ( + `settlementWindowContentId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `ledgerAccountTypeId` int(10) unsigned NOT NULL, + `currencyId` varchar(3) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + `settlementId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`settlementWindowContentId`), + KEY `settlementwindowcontent_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowcontent_ledgeraccounttypeid_index` (`ledgerAccountTypeId`), + KEY `settlementwindowcontent_currencyid_index` (`currencyId`), + KEY `settlementwindowcontent_currentstatechangeid_index` (`currentStateChangeId`), + KEY `settlementwindowcontent_settlementid_index` (`settlementId`), + CONSTRAINT `settlementwindowcontent_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `settlementwindowcontent_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `settlementWindowContentStateChange` (`settlementwindowcontentstatechangeid`), + CONSTRAINT `settlementwindowcontent_ledgeraccounttypeid_foreign` FOREIGN KEY (`ledgerAccountTypeId`) REFERENCES `ledgerAccountType` (`ledgeraccounttypeid`), + CONSTRAINT `settlementwindowcontent_settlementid_foreign` FOREIGN KEY (`settlementId`) REFERENCES `settlement` (`settlementid`), + CONSTRAINT `settlementwindowcontent_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowContentStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowContentStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowContentStateChange` ( + `settlementWindowContentStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowContentId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowContentStateChangeId`), + KEY `swcsc_settlementwindowcontentid_index` (`settlementWindowContentId`), + KEY `swcsc_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `swc_settlementwindowcontentid_foreign` FOREIGN KEY (`settlementWindowContentId`) REFERENCES `settlementWindowContent` (`settlementwindowcontentid`), + CONSTRAINT `sws1_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowState` +-- + +DROP TABLE IF EXISTS `settlementWindowState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowState` ( + `settlementWindowStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `settlementWindowStateChange` +-- + +DROP TABLE IF EXISTS `settlementWindowStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `settlementWindowStateChange` ( + `settlementWindowStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `settlementWindowId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`settlementWindowStateChangeId`), + KEY `settlementwindowstatechange_settlementwindowid_index` (`settlementWindowId`), + KEY `settlementwindowstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `settlementwindowstatechange_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `settlementwindowstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `token` +-- + +DROP TABLE IF EXISTS `token`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `token` ( + `tokenId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `participantId` int(10) unsigned NOT NULL, + `value` varchar(256) NOT NULL, + `expiration` bigint(20) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`tokenId`), + UNIQUE KEY `token_value_unique` (`value`), + KEY `token_participantid_index` (`participantId`), + CONSTRAINT `token_participantid_foreign` FOREIGN KEY (`participantId`) REFERENCES `participant` (`participantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiator` +-- + +DROP TABLE IF EXISTS `transactionInitiator`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionInitiator` ( + `transactionInitiatorId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorId`), + UNIQUE KEY `transactioninitiator_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionInitiatorType` +-- + +DROP TABLE IF EXISTS `transactionInitiatorType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionInitiatorType` ( + `transactionInitiatorTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionInitiatorTypeId`), + UNIQUE KEY `transactioninitiatortype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionReference` +-- + +DROP TABLE IF EXISTS `transactionReference`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionReference` ( + `transactionReferenceId` varchar(36) NOT NULL COMMENT 'Common ID (decided by the Payer FSP) between the FSPs for the future transaction object', + `quoteId` varchar(36) DEFAULT NULL COMMENT 'Common ID between the FSPs for the quote object, decided by the Payer FSP', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System row creation timestamp', + PRIMARY KEY (`transactionReferenceId`), + KEY `transactionreference_quoteid_index` (`quoteId`), + CONSTRAINT `transactionreference_quoteid_foreign` FOREIGN KEY (`quoteId`) REFERENCES `quoteDuplicateCheck` (`quoteid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionScenario` +-- + +DROP TABLE IF EXISTS `transactionScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionScenario` ( + `transactionScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionScenarioId`), + UNIQUE KEY `transactionscenario_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transactionSubScenario` +-- + +DROP TABLE IF EXISTS `transactionSubScenario`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactionSubScenario` ( + `transactionSubScenarioId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) NOT NULL, + `description` varchar(1024) DEFAULT NULL COMMENT 'Possible sub-scenario, defined locally within the scheme', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'System dateTime stamp pertaining to the inserted record', + PRIMARY KEY (`transactionSubScenarioId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transfer` +-- + +DROP TABLE IF EXISTS `transfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transfer` ( + `transferId` varchar(36) NOT NULL, + `amount` decimal(18,4) NOT NULL, + `currencyId` varchar(3) NOT NULL, + `ilpCondition` varchar(256) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfer_currencyid_index` (`currencyId`), + CONSTRAINT `transfer_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `transfer_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferError` +-- + +DROP TABLE IF EXISTS `transferError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferError` ( + `transferId` varchar(36) NOT NULL, + `transferStateChangeId` bigint(20) unsigned NOT NULL, + `errorCode` int(10) unsigned NOT NULL, + `errorDescription` varchar(128) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transfererror_transferstatechangeid_foreign` (`transferStateChangeId`), + CONSTRAINT `transfererror_transferstatechangeid_foreign` FOREIGN KEY (`transferStateChangeId`) REFERENCES `transferStateChange` (`transferstatechangeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferErrorDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferErrorDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferErrorDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transfererrorduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferExtension` +-- + +DROP TABLE IF EXISTS `transferExtension`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferExtension` ( + `transferExtensionId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `key` varchar(128) NOT NULL, + `value` text NOT NULL, + `isFulfilment` tinyint(1) NOT NULL DEFAULT '0', + `isError` tinyint(1) NOT NULL DEFAULT '0', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferExtensionId`), + KEY `transferextension_transferid_foreign` (`transferId`), + CONSTRAINT `transferextension_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilment` +-- + +DROP TABLE IF EXISTS `transferFulfilment`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferFulfilment` ( + `transferId` varchar(36) NOT NULL, + `ilpFulfilment` varchar(256) DEFAULT NULL, + `completedDate` datetime NOT NULL, + `isValid` tinyint(1) DEFAULT NULL, + `settlementWindowId` bigint(20) unsigned DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + KEY `transferfulfilment_settlementwindowid_foreign` (`settlementWindowId`), + CONSTRAINT `transferfulfilment_settlementwindowid_foreign` FOREIGN KEY (`settlementWindowId`) REFERENCES `settlementWindow` (`settlementwindowid`), + CONSTRAINT `transferfulfilment_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transferFulfilmentDuplicateCheck` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferFulfilmentDuplicateCheck` +-- + +DROP TABLE IF EXISTS `transferFulfilmentDuplicateCheck`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferFulfilmentDuplicateCheck` ( + `transferId` varchar(36) NOT NULL, + `hash` varchar(256) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferId`), + CONSTRAINT `transferfulfilmentduplicatecheck_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipant` +-- + +DROP TABLE IF EXISTS `transferParticipant`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipant` ( + `transferParticipantId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `participantCurrencyId` int(10) unsigned NOT NULL, + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL, + `ledgerEntryTypeId` int(10) unsigned NOT NULL, + `amount` decimal(18,4) NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `currentStateChangeId` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`transferParticipantId`), + KEY `transferparticipant_transferid_index` (`transferId`), + KEY `transferparticipant_participantcurrencyid_index` (`participantCurrencyId`), + KEY `transferparticipant_transferparticipantroletypeid_index` (`transferParticipantRoleTypeId`), + KEY `transferparticipant_ledgerentrytypeid_index` (`ledgerEntryTypeId`), + KEY `transferparticipant_currentstatechangeid_foreign` (`currentStateChangeId`), + CONSTRAINT `transferparticipant_currentstatechangeid_foreign` FOREIGN KEY (`currentStateChangeId`) REFERENCES `transferParticipantStateChange` (`transferparticipantstatechangeid`), + CONSTRAINT `transferparticipant_ledgerentrytypeid_foreign` FOREIGN KEY (`ledgerEntryTypeId`) REFERENCES `ledgerEntryType` (`ledgerentrytypeid`), + CONSTRAINT `transferparticipant_participantcurrencyid_foreign` FOREIGN KEY (`participantCurrencyId`) REFERENCES `participantCurrency` (`participantcurrencyid`), + CONSTRAINT `transferparticipant_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferparticipant_transferparticipantroletypeid_foreign` FOREIGN KEY (`transferParticipantRoleTypeId`) REFERENCES `transferParticipantRoleType` (`transferparticipantroletypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantRoleType` +-- + +DROP TABLE IF EXISTS `transferParticipantRoleType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipantRoleType` ( + `transferParticipantRoleTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantRoleTypeId`), + UNIQUE KEY `transferparticipantroletype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferParticipantStateChange` +-- + +DROP TABLE IF EXISTS `transferParticipantStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferParticipantStateChange` ( + `transferParticipantStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferParticipantId` bigint(20) unsigned NOT NULL, + `settlementWindowStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferParticipantStateChangeId`), + KEY `transferparticipantstatechange_transferparticipantid_index` (`transferParticipantId`), + KEY `transferparticipantstatechange_settlementwindowstateid_index` (`settlementWindowStateId`), + CONSTRAINT `transferparticipantstatechange_settlementwindowstateid_foreign` FOREIGN KEY (`settlementWindowStateId`) REFERENCES `settlementWindowState` (`settlementwindowstateid`), + CONSTRAINT `transferparticipantstatechange_transferparticipantid_foreign` FOREIGN KEY (`transferParticipantId`) REFERENCES `transferParticipant` (`transferparticipantid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferRules` +-- + +DROP TABLE IF EXISTS `transferRules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferRules` ( + `transferRulesId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `rule` text NOT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferRulesId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferState` +-- + +DROP TABLE IF EXISTS `transferState`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferState` ( + `transferStateId` varchar(50) NOT NULL, + `enumeration` varchar(50) NOT NULL COMMENT 'transferState associated to the Mojaloop API', + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferStateChange` +-- + +DROP TABLE IF EXISTS `transferStateChange`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferStateChange` ( + `transferStateChangeId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `transferStateId` varchar(50) NOT NULL, + `reason` varchar(512) DEFAULT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferStateChangeId`), + KEY `transferstatechange_transferid_index` (`transferId`), + KEY `transferstatechange_transferstateid_index` (`transferStateId`), + CONSTRAINT `transferstatechange_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`), + CONSTRAINT `transferstatechange_transferstateid_foreign` FOREIGN KEY (`transferStateId`) REFERENCES `transferState` (`transferstateid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `transferTimeout` +-- + +DROP TABLE IF EXISTS `transferTimeout`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transferTimeout` ( + `transferTimeoutId` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `transferId` varchar(36) NOT NULL, + `expirationDate` datetime NOT NULL, + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`transferTimeoutId`), + UNIQUE KEY `transfertimeout_transferid_unique` (`transferId`), + CONSTRAINT `transfertimeout_transferid_foreign` FOREIGN KEY (`transferId`) REFERENCES `transfer` (`transferid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Final view structure for view `quotePartyView` +-- + +/*!50001 DROP VIEW IF EXISTS `quotePartyView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quotePartyView` AS select `qp`.`quoteId` AS `quoteId`,`qp`.`quotePartyId` AS `quotePartyId`,`pt`.`name` AS `partyType`,`pit`.`name` AS `identifierType`,`qp`.`partyIdentifierValue` AS `partyIdentifierValue`,`spit`.`name` AS `partySubIdOrType`,`qp`.`fspId` AS `fspId`,`qp`.`merchantClassificationCode` AS `merchantClassificationCode`,`qp`.`partyName` AS `partyName`,`p`.`firstName` AS `firstName`,`p`.`lastName` AS `lastName`,`p`.`middleName` AS `middleName`,`p`.`dateOfBirth` AS `dateOfBirth`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from (((((`quoteParty` `qp` join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) join `partyIdentifierType` `pit` on((`pit`.`partyIdentifierTypeId` = `qp`.`partyIdentifierTypeId`))) left join `party` `p` on((`p`.`quotePartyId` = `qp`.`quotePartyId`))) left join `partyIdentifierType` `spit` on((`spit`.`partyIdentifierTypeId` = `qp`.`partySubIdOrTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteResponseView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteResponseView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteResponseView` AS select `qr`.`quoteResponseId` AS `quoteResponseId`,`qr`.`quoteId` AS `quoteId`,`qr`.`transferAmountCurrencyId` AS `transferAmountCurrencyId`,`qr`.`transferAmount` AS `transferAmount`,`qr`.`payeeReceiveAmountCurrencyId` AS `payeeReceiveAmountCurrencyId`,`qr`.`payeeReceiveAmount` AS `payeeReceiveAmount`,`qr`.`payeeFspFeeCurrencyId` AS `payeeFspFeeCurrencyId`,`qr`.`payeeFspFeeAmount` AS `payeeFspFeeAmount`,`qr`.`payeeFspCommissionCurrencyId` AS `payeeFspCommissionCurrencyId`,`qr`.`payeeFspCommissionAmount` AS `payeeFspCommissionAmount`,`qr`.`ilpCondition` AS `ilpCondition`,`qr`.`responseExpirationDate` AS `responseExpirationDate`,`qr`.`isValid` AS `isValid`,`qr`.`createdDate` AS `createdDate`,`qrilp`.`value` AS `ilpPacket`,`gc`.`longitude` AS `longitude`,`gc`.`latitude` AS `latitude` from ((((`quoteResponse` `qr` join `quoteResponseIlpPacket` `qrilp` on((`qrilp`.`quoteResponseId` = `qr`.`quoteResponseId`))) join `quoteParty` `qp` on((`qp`.`quoteId` = `qr`.`quoteId`))) join `partyType` `pt` on((`pt`.`partyTypeId` = `qp`.`partyTypeId`))) left join `geoCode` `gc` on((`gc`.`quotePartyId` = `qp`.`quotePartyId`))) where (`pt`.`name` = 'PAYEE') */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +-- +-- Final view structure for view `quoteView` +-- + +/*!50001 DROP VIEW IF EXISTS `quoteView`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = utf8 */; +/*!50001 SET character_set_results = utf8 */; +/*!50001 SET collation_connection = utf8_general_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`central_ledger`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `quoteView` AS select `q`.`quoteId` AS `quoteId`,`q`.`transactionReferenceId` AS `transactionReferenceId`,`q`.`transactionRequestId` AS `transactionRequestId`,`q`.`note` AS `note`,`q`.`expirationDate` AS `expirationDate`,`ti`.`name` AS `transactionInitiator`,`tit`.`name` AS `transactionInitiatorType`,`ts`.`name` AS `transactionScenario`,`q`.`balanceOfPaymentsId` AS `balanceOfPaymentsId`,`tss`.`name` AS `transactionSubScenario`,`amt`.`name` AS `amountType`,`q`.`amount` AS `amount`,`q`.`currencyId` AS `currency` from (((((`quote` `q` join `transactionInitiator` `ti` on((`ti`.`transactionInitiatorId` = `q`.`transactionInitiatorId`))) join `transactionInitiatorType` `tit` on((`tit`.`transactionInitiatorTypeId` = `q`.`transactionInitiatorTypeId`))) join `transactionScenario` `ts` on((`ts`.`transactionScenarioId` = `q`.`transactionScenarioId`))) join `amountType` `amt` on((`amt`.`amountTypeId` = `q`.`amountTypeId`))) left join `transactionSubScenario` `tss` on((`tss`.`transactionSubScenarioId` = `q`.`transactionSubScenarioId`))) */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-02-20 22:51:43 diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd new file mode 100644 index 000000000..303fa1534 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png new file mode 100644 index 000000000..62b4a1a1e Binary files /dev/null and b/legacy/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png differ diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg new file mode 100644 index 000000000..d91178975 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Ledger
    Ledger
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Central Services
    [Not supported by viewer]
    positions
    positions
    Account-Lookup-Service
    [Not supported by viewer]
    Pathfinder
    Pathfinder
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Settlements
    Settlements
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg new file mode 100644 index 000000000..73c49765f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0-old.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    [Not supported by viewer]
    1.4 Increment
    Position (fsp1)

    [Not supported by viewer]
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    [Not supported by viewer]
    2.4 Fulfil
    Success
    [Not supported by viewer]
    <alt> 2.4 
    Fulfil Reject

    [Not supported by viewer]
    Fulfil
    Reject
    [Not supported by viewer]
    <alt> 2.5 Decrement
    Position (fsp1)

    [Not supported by viewer]
    <alt>1.6 Reject Notification
    (Not enough position)

    [Not supported by viewer]
    Central - Services
    <font style="font-size: 18px">Central - Services</font>
    3.0 Reject
    [Not supported by viewer]
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    [Not supported by viewer]
    1.0 Transfer 
    Request

    [Not supported by viewer]
    3.1 Decrement
    Position (fsp1)

    [Not supported by viewer]
    1.6 Prepare Notification
    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    Transfer
    API
    [Not supported by viewer]
    Notification
    Event Handler
    [Not supported by viewer]
    fsp prepare
    fsp prepare
    1.3 Prepare Consume
    [Not supported by viewer]
    notifications
    notifications
    FSP1
    (Payer)

    [Not supported by viewer]
    FSP2
    (Payee)
    [Not supported by viewer]
    1.1
    Prepare Request
    [Not supported by viewer]
    1.2 Accpeted
    (202)
    [Not supported by viewer]
    Transfer
    API
    [Not supported by viewer]
    2.0 Fulfil 
    Success / 
    Reject

    [Not supported by viewer]
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    [Not supported by viewer]
    2.5 Decrement
    Position (fsp2)

    [Not supported by viewer]
    2.1 Fulfil 
    Success / Reject

    [Not supported by viewer]
    2.2 OK
    (200)
    [Not supported by viewer]
    2.3 Fulfil
    Success /
    Reject
    Consume
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    OK (200)
    [Not supported by viewer]
    Transfer Timeout
    Handler
    [Not supported by viewer]
    <alt> 1.4 Prepare Failure
    [Not supported by viewer]
    <alt> 2.4 Fulfil Failure
    [Not supported by viewer]
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    [Not supported by viewer]
    1.7 Prepare Notify /
    2.8 Fulfil Notify /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    [Not supported by viewer]
    position
    position<br>
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg new file mode 100644 index 000000000..02658b83d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.0.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (optional) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg new file mode 100644 index 000000000..e9a1460c8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/architecture/Transfers-Arch-End-to-End-v1.1.svg @@ -0,0 +1,3 @@ + + +
    1.5 Increment Position (fsp1)
    1.5 Increment Position (fsp1)
    1.4 Increment
    Position (fsp1)

    1.4 Increment...
    PrepareHandler
    PrepareHandler
    PositionHandler
    PositionHandler
    Fulfil
    Sucess
    Fulfil...
    2.4 Fulfil
    Success
    2.4 Fulfil...
    <alt> 2.4 
    Fulfil Reject

    <alt> 2.4...
    Fulfil
    Reject
    Fulfil...
    <alt> 2.5 Decrement
    Position (fsp1)

    <alt> 2.5 Decrement...
    <alt>1.6 Reject Notification
    (Not enough position)

    <alt>1.6...
    Central - Services
    Central - Services
    3.0 Reject
    3.0 Reject
    2.6 Fulfil Notification /
     <alt> 2.6 Reject Notification (Fulfil) /
    3.2 Reject Notification (Timeout)

    2.6 Fulfil Notification /...
    1.0 Transfer 
    Request

    1.0 Transfer...
    3.1 Decrement
    Position (fsp1)

    3.1 Decrement...
    1.6 Prepare Notification
    1.6 Prepare Notification
    ML-Adapter
    ML-Adapter
    Transfer
    API
    Transfer...
    Notification
    Event Handler
    Notification...
    fsp prepare
    fsp prep...
    1.3 Prepare Consume
    1.3 Prepare Consume
    notifications
    notificati...
    FSP1
    (Payer)

    FSP1...
    FSP2
    (Payee)
    FSP2...
    1.1
    Prepare Request
    1.1...
    1.2 Accpeted
    (202)
    1.2 Accpeted...
    Transfer
    API
    Transfer...
    2.0 Fulfil 
    Success / 
    Reject

    2...
    fulfils
    fulfils
    FulfilHandler
    FulfilHandler
    Success/
    Reject
    Success/...
    2.5 Decrement
    Position (fsp2)

    2.5 Decrement...
    2.1 Fulfil 
    Success / Reject

    2.1 Fulfil...
    2.2 OK
    (200)
    2.2 OK...
    2.3 Fulfil
    Success /
    Reject
    Consume
    2.3 Fulfil...
    OK (200)
    OK (200)
    OK (200)
    OK (200)
    Transfer Timeout
    Handler
    Transfer Timeout...
    <alt> 1.4 Prepare Failure
    <alt> 1.4 Prepare Failure
    <alt> 2.4 Fulfil Failure
    <alt>...
    2.7 Fulfil Notify Callback /
    <alt> 2.7 Reject Response (Fulfil reject) /
    3.1, 3.3 Reject Response (Timeout) /
    <alt> 1.7 Reject Response (Not enough position)
    <alt> 1.5 Prepare Failure 

    2.7 Fulfil Notify Callback /...
    1.7 Prepare Notify /
    2.8 Commit Notify (if transfer reserved) /
    <alt> 2.7 Reject Response (Fulfil reject)
    3.3 Reject Response (Timeout)
    <alt> 2.5 Fulfil Failure

    1.7 Prepare Notify /...
    position
    position
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml new file mode 100644 index 000000000..461a64c23 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml @@ -0,0 +1,160 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 3.1.0 Get Participant Callback Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "ML-API-ADAPTER" as MLAPI +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB +box "ML API Adapter Service" #LightBlue +participant MLAPI +end box + +box "Central Services" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate MLAPI +group Get Callback Details + MLAPI -> CSAPI: Request to get callback details - GET - /participants/{name}/endpoints?type={typeValue} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Fetch Callback details for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant \nError code: 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Retrieved Participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: check if "type" parameter is sent + alt Check if "type" parameter is sent (Sent) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Callback details for Participant and type \nError code: 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Callback details for Participant and type + note right of PARTICIPANT_DAO #lightgrey + Condition: + isActive = 1 + [endpointTypeId = ] + end note + + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB --> PARTICIPANT_DAO: Retrieved Callback details for Participant and type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Callback details for Participant and type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + { + endpoints: {type: , value: } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Callback details for Participant + deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Return Callback details for Participant + else Check if "type" parameter is sent (Not Sent) + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Callback details for Participant \nError code: 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Callback details for Participant + note right of PARTICIPANT_DAO #lightgrey + Condition: + isActive = 1 + end note + + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB --> PARTICIPANT_DAO: Retrieved Callback details for Participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Callback details for Participant + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + { + endpoints: [ + {type: , value: }, + {type: , value: } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Callback details for Participant + ' deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Return Callback details for Participant + end + + + else Validate participant (failure)/ Error + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Validation failure/ Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->MLAPI: Return Error code: 3000, 3200 + + end + deactivate CSAPI + deactivate MLAPI +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg new file mode 100644 index 000000000..c7acd7bd0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.svg @@ -0,0 +1,409 @@ + + + + + + + + + + + 3.1.0 Get Participant Callback Details + + + + ML API Adapter Service + + + + Central Services + + + + + + + + + ML-API-ADAPTER + + + + + ML-API-ADAPTER + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Get Callback Details + + + + + 1 + + + Request to get callback details - GET - /participants/{name}/endpoints?type={typeValue} + + + + + 2 + + + Fetch Callback details for Participant + + + + + 3 + + + Fetch Participant + + + Error code: + + + 3200 + + + + + 4 + + + Fetch Participant + + + + participant + + + + + 5 + + + Retrieved Participant + + + + + 6 + + + Return Participant + + + + + 7 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 8 + + + check if "type" parameter is sent + + + + + alt + + + [Check if "type" parameter is sent (Sent)] + + + + + 9 + + + Fetch Callback details for Participant and type + + + Error code: + + + 3000 + + + + + 10 + + + Fetch Callback details for Participant and type + + + + + Condition: + + + isActive = 1 + + + [endpointTypeId = <type>] + + + + participantEndpoint + + + + + 11 + + + Retrieved Callback details for Participant and type + + + + + 12 + + + Return Callback details for Participant and type + + + + + Message: + + + { + + + endpoints: {type: <type>, value: <value>} + + + } + + + + + 13 + + + Return Callback details for Participant + + + + + 14 + + + Return Callback details for Participant + + + + [Check if "type" parameter is sent (Not Sent)] + + + + + 15 + + + Fetch Callback details for Participant + + + Error code: + + + 3000 + + + + + 16 + + + Fetch Callback details for Participant + + + + + Condition: + + + isActive = 1 + + + + participantEndpoint + + + + + 17 + + + Retrieved Callback details for Participant + + + + + 18 + + + Return Callback details for Participant + + + + + Message: + + + { + + + endpoints: [ + + + {type: <type>, value: <value>}, + + + {type: <type>, value: <value>} + + + ] + + + } + + + + + 19 + + + Return Callback details for Participant + + + + + 20 + + + Return Callback details for Participant + + + + [Validate participant (failure)/ Error] + + + + + Validation failure/ Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <ErrorMessage>, + + + } + + + } + + + + + 21 + + + Return + + + Error code: + + + 3000, 3200 + + + + + 22 + + + Return + + + Error code: + + + 3000, 3200 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml new file mode 100644 index 000000000..dd4849343 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml @@ -0,0 +1,149 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + + +@startuml +' declate title +title 3.1.0 Add Participant Callback Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Services" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Add Callback Details + OPERATOR -> CSAPI: Request to add callback details - POST - /paticipants/{name}/endpoints + note right of OPERATOR #yellow + Message: + { + payload: { + endpoint: { + type: , + value: + } + } + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Add Callback details for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant \nError code: 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Retrieved Participant + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return Participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Add Callback details for Participant \nError code: 2003/Msg: Service unavailable \nError code: 2001/Msg: Internal Server Error + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Persist Participant Endpoint + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + deactivate DB + note right of PARTICIPANT_DAO #lightgrey + If (endpoint exists && isActive = 1) + oldEndpoint.isActive = 0 + insert endpoint + Else + insert endpoint + End + + end note + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return status + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Validate status + alt Validate status (success) + PARTICIPANT_HANDLER -->CSAPI: Return Status Code 201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Status Code 201 + else Validate status (failure) / Error + note right of PARTICIPANT_HANDLER #red: Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code + + end + + else Validate participant (failure) + note right of PARTICIPANT_HANDLER #red: Validation failure! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3200 + + end + deactivate CSAPI + deactivate OPERATOR +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg new file mode 100644 index 000000000..975978ddb --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.svg @@ -0,0 +1,400 @@ + + + + + + + + + + + 3.1.0 Add Participant Callback Details + + + + Central Services + + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Add Callback Details + + + + + 1 + + + Request to add callback details - POST - /paticipants/{name}/endpoints + + + + + Message: + + + { + + + payload: { + + + endpoint: { + + + type: <typeValue>, + + + value: <endpointValue> + + + } + + + } + + + } + + + + + 2 + + + Add Callback details for Participant + + + + + 3 + + + Fetch Participant + + + Error code: + + + 3200 + + + + + 4 + + + Fetch Participant + + + + participant + + + + + 5 + + + Retrieved Participant + + + + + 6 + + + Return Participant + + + + + 7 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 8 + + + Add Callback details for Participant + + + Error code: + + + 2003/ + + + Msg: + + + Service unavailable + + + Error code: + + + 2001/ + + + Msg: + + + Internal Server Error + + + + + 9 + + + Persist Participant Endpoint + + + + participantEndpoint + + + + + If (endpoint exists && isActive = 1) + + + oldEndpoint.isActive = 0 + + + insert endpoint + + + Else + + + insert endpoint + + + End + + + + + 10 + + + Return status + + + + + 11 + + + Validate status + + + + + alt + + + [Validate status (success)] + + + + + 12 + + + Return Status Code 201 + + + + + 13 + + + Return Status Code 201 + + + + [Validate status (failure) / Error] + + + + + Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 14 + + + Return + + + Error code + + + + + 15 + + + Return + + + Error code + + + + [Validate participant (failure)] + + + + + Validation failure! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3200, + + + "errorDescription": "FSP id Not Found", + + + } + + + } + + + + + 16 + + + Return + + + Error code: + + + 3200 + + + + + 17 + + + Return + + + Error code: + + + 3200 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml new file mode 100644 index 000000000..c24ae484b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.plantuml @@ -0,0 +1,207 @@ +/' + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Valentin Genev + -------------- + '/ + + +@startuml +' declate title +title 2.1.0. DFSP2 sends a Fulfil Success Transfer request v1.1 + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Settlement Model\nHandler" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group DFSP2 sends a request for notification after tranfer is being committed in the Switch + DFSP2 <-> DFSP2: Retrieve fulfilment string generated during\nthe quoting process or regenerate it using\n**Local secret** and **ILP Packet** as inputs + alt Send back notification reserve request + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "transferState": "RESERVED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + else Send back commit request + + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "completedTimestamp": , + "transferState": "COMMITTED" + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + end + DFSP2 ->> MLAPI: PUT - /transfers/ + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reserve || commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg 2.1.1-v1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produce message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consume message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Settlement Model Handler Consume (Success)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'reserve' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg new file mode 100644 index 000000000..1a04bdb4a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg @@ -0,0 +1,665 @@ + + + + + + + + + + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request v1.1 + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + topic-fulfil + + + + + topic-fulfil + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic- + + + settlement-model + + + + + topic- + + + settlement-model + + + Settlement Model + + + Handler + + + + + Settlement Model + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + + DFSP2 sends a request for notification after tranfer is being committed in the Switch + + + + + 1 + + + Retrieve fulfilment string generated during + + + the quoting process or regenerate it using + + + Local secret + + + and + + + ILP Packet + + + as inputs + + + + + alt + + + [Send back notification reserve request] + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "fulfilment": <IlpFulfilment>, + + + "transferState": "RESERVED" + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + + [Send back commit request] + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "fulfilment": <IlpFulfilment>, + + + "completedTimestamp": <DateTime>, + + + "transferState": "COMMITTED" + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + + 2 + + + PUT - /transfers/<ID> + + + + + 3 + + + Validate incoming token and originator matching Payee + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: reserve || commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Route & Publish Fulfil event for Payee + + + Error code: + + + 2003 + + + + + 5 + + + Ensure event is replicated as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 6 + + + Respond replication acknowledgements have been received + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + 8 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Success) { + + + + 2.1.1-v1.1 + + + + } + + + + + 9 + + + Produce message + + + + + 10 + + + Produce message + + + + + 11 + + + Consume message + + + + + ref + + + Settlement Model Handler Consume (Success) + + + + + 12 + + + Consume message + + + + + ref + + + Position Handler Consume (Success) + + + + + 13 + + + Produce message + + + + + 14 + + + Consume message + + + + + opt + + + [action == 'commit'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 15 + + + Send callback notification + + + + + 16 + + + Consume message + + + + + opt + + + [action == 'reserve'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 17 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml new file mode 100644 index 000000000..08c71eb9f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml @@ -0,0 +1,174 @@ +/' + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + '/ + + +@startuml +' declate title +title 2.1.0. DFSP2 sends a Fulfil Success Transfer request + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Settlement Model\nHandler" as SETMODEL_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate SETMODEL_HANDLER +activate POS_HANDLER +group DFSP2 sends a Fulfil Success Transfer request + DFSP2 <-> DFSP2: Retrieve fulfilment string generated during\nthe quoting process or regenerate it using\n**Local secret** and **ILP Packet** as inputs + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "completedTimestamp": , + "transferState": "COMMITTED", + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers/ + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Success) {[[https://github.com/mojaloop/documentation/tree/master/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg 2.1.1]]} \n + FULF_HANDLER -> TOPIC_SETMODEL: Produce message + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consume message + ref over TOPIC_SETMODEL, SETMODEL_HANDLER: Settlement Model Handler Consume (Success)\n + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Success)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'commit' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'commit' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg new file mode 100644 index 000000000..052c40891 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.svg @@ -0,0 +1,574 @@ + + + + + + + + + + + 2.1.0. DFSP2 sends a Fulfil Success Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + topic-fulfil + + + + + topic-fulfil + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic- + + + settlement-model + + + + + topic- + + + settlement-model + + + Settlement Model + + + Handler + + + + + Settlement Model + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + 1 + + + Retrieve fulfilment string generated during + + + the quoting process or regenerate it using + + + Local secret + + + and + + + ILP Packet + + + as inputs + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "fulfilment": <IlpFulfilment>, + + + "completedTimestamp": <DateTime>, + + + "transferState": "COMMITTED", + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + + 2 + + + PUT - /transfers/<ID> + + + + + 3 + + + Validate incoming token and originator matching Payee + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Route & Publish Fulfil event for Payee + + + Error code: + + + 2003 + + + + + 5 + + + Ensure event is replicated as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 6 + + + Respond replication acknowledgements have been received + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + 8 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Success) { + + + + 2.1.1 + + + + } + + + + + 9 + + + Produce message + + + + + 10 + + + Produce message + + + + + 11 + + + Consume message + + + + + ref + + + Settlement Model Handler Consume (Success) + + + + + 12 + + + Consume message + + + + + ref + + + Position Handler Consume (Success) + + + + + 13 + + + Produce message + + + + + 14 + + + Consume message + + + + + opt + + + [action == 'commit'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 15 + + + Send callback notification + + + + + 16 + + + Consume message + + + + + opt + + + [action == 'commit'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 17 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml new file mode 100644 index 000000000..9f2523d6d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.plantuml @@ -0,0 +1,273 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.1. Fulfil Handler Consume (Success) v1.1 +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event\nHandler" as FULF_HANDLER +collections "topic-event" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +entity "Position DAO" as POS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_SETMODEL + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Success) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && action IN ['commit', 'reserve']\nError codes: 2001 + end + end + group Persist Event Information + ||| + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + ||| + end + + group Validate Duplicate Check + ||| + FULF_HANDLER -> DB: Request Duplicate Check + ref over FULF_HANDLER, DB: Request Duplicate Check\n + DB --> FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of FULF_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + group Validate and persist Transfer Fulfilment + FULF_HANDLER -> POS_DAO: Request information for the validate checks\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return transfer + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + FULF_HANDLER -> FULF_HANDLER: Validate expirationDate\nError code: 3303 + + opt Transfer.ilpCondition validate successful + group Request current Settlement Window + FULF_HANDLER -> POS_DAO: Request to retrieve current/latest transfer settlement window\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return settlementWindowId to be appended during transferFulfilment insert\n**TODO**: During settlement design make sure transfers in 'RECEIVED-FULFIL'\nstate are updated to the next settlement window + deactivate POS_DAO + end + end + + group Persist fulfilment + FULF_HANDLER -> POS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Return success + deactivate POS_DAO + end + + alt Transfer.ilpCondition validate successful + group Persist Transfer State (with transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: , + responseTo: , + type: setmodel, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_SETMODEL: Route & Publish settlement model event + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful + group Persist Transfer State (with transferState='ABORTED') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg new file mode 100644 index 000000000..9d931dc0c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg @@ -0,0 +1,821 @@ + + + + + + + + + + + 2.1.1. Fulfil Handler Consume (Success) v1.1 + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + + + topic-fulfil + + + Fulfil Event + + + Handler + + + + + Fulfil Event + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic-event + + + + + topic-event + + + + + topic- + + + settlement-model + + + + + topic- + + + settlement-model + + + + + topic- + + + notification + + + + + topic- + + + notification + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Handler Consume (Success) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'fulfil' && action IN ['commit', 'reserve'] + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate Duplicate Check + + + + + 4 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 5 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + + + 6 + + + stateRecord = await getTransferState(transferId) + + + + + alt + + + [endStateList.includes(stateRecord.transferStateId)] + + + + + ref + + + getTransfer callback + + + + + 7 + + + Produce message + + + + + + Ignore - resend in progress + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + Validate Prepare Transfer (failure) - Modified Request + + + + [hasDuplicateId == FALSE] + + + + + Validate and persist Transfer Fulfilment + + + + + 8 + + + Request information for the validate checks + + + Error code: + + + 2003 + + + + + 9 + + + Fetch from database + + + + transfer + + + + + 10 + + + + + 11 + + + Return transfer + + + + + 12 + + + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + + + Error code: + + + 2001 + + + + + 13 + + + Validate expirationDate + + + Error code: + + + 3303 + + + + + opt + + + [Transfer.ilpCondition validate successful] + + + + + Request current Settlement Window + + + + + 14 + + + Request to retrieve current/latest transfer settlement window + + + Error code: + + + 2003 + + + + + 15 + + + Fetch settlementWindowId + + + + settlementWindow + + + + + 16 + + + + + 17 + + + Return settlementWindowId to be appended during transferFulfilment insert + + + TODO + + + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + + + state are updated to the next settlement window + + + + + Persist fulfilment + + + + + 18 + + + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + + + Error code: + + + 2003 + + + + + 19 + + + Persist to database + + + + transferFulfilment + + + transferExtension + + + + + 20 + + + Return success + + + + + alt + + + [Transfer.ilpCondition validate successful] + + + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + + + 21 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 22 + + + Persist transfer state + + + + transferStateChange + + + + + 23 + + + Return success + + + + + Message: + + + { + + + id: <id>, + + + from: switch, + + + to: switch, + + + type: application/json + + + content: { + + + payload: { + + + transferId: {id} + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: setmodel, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 24 + + + Route & Publish settlement model event + + + + + Message: + + + { + + + id: <id>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: commit || reserve, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 25 + + + Route & Publish Position event for Payee + + + + [Validate Fulfil Transfer not successful] + + + + + Persist Transfer State (with transferState='ABORTED') + + + + + 26 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 27 + + + Persist transfer state + + + + transferStateChange + + + + + 28 + + + Return success + + + + + Message: + + + { + + + id: <id>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 29 + + + Route & Publish Position event for Payer + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml new file mode 100644 index 000000000..42f281ef6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml @@ -0,0 +1,272 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.1. Fulfil Handler Consume (Success) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-fulfil" as TOPIC_FULFIL +control "Fulfil Event\nHandler" as FULF_HANDLER +collections "topic-event" as TOPIC_EVENT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +collections "topic-\nnotification" as TOPIC_NOTIFICATIONS + +entity "Position DAO" as POS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_SETMODEL + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Success) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && action == 'commit'\nError codes: 2001 + end + end + group Persist Event Information + ||| + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume\n + ||| + end + + group Validate Duplicate Check + ||| + FULF_HANDLER -> DB: Request Duplicate Check + ref over FULF_HANDLER, DB: Request Duplicate Check\n + DB --> FULF_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + FULF_HANDLER -> FULF_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of FULF_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of FULF_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + group Validate and persist Transfer Fulfilment + FULF_HANDLER -> POS_DAO: Request information for the validate checks\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return transfer + deactivate POS_DAO + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + FULF_HANDLER -> FULF_HANDLER: Validate expirationDate\nError code: 3303 + + opt Transfer.ilpCondition validate successful + group Request current Settlement Window + FULF_HANDLER -> POS_DAO: Request to retrieve current/latest transfer settlement window\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Fetch settlementWindowId + activate DB + hnote over DB #lightyellow + settlementWindow + end note + DB --> POS_DAO + deactivate DB + FULF_HANDLER <-- POS_DAO: Return settlementWindowId to be appended during transferFulfilment insert\n**TODO**: During settlement design make sure transfers in 'RECEIVED-FULFIL'\nstate are updated to the next settlement window + deactivate POS_DAO + end + end + + group Persist fulfilment + FULF_HANDLER -> POS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- POS_DAO: Return success + deactivate POS_DAO + end + + alt Transfer.ilpCondition validate successful + group Persist Transfer State (with transferState='RECEIVED-FULFIL') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: switch, + to: switch, + type: application/json + content: { + payload: { + transferId: {id} + } + }, + metadata: { + event: { + id: , + responseTo: , + type: setmodel, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_SETMODEL: Route & Publish settlement model event + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful + group Persist Transfer State (with transferState='ABORTED') + FULF_HANDLER -> POS_DAO: Request to persist transfer state\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + POS_DAO --> FULF_HANDLER: Return success + deactivate POS_DAO + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg new file mode 100644 index 000000000..de1888f4f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.svg @@ -0,0 +1,821 @@ + + + + + + + + + + + 2.1.1. Fulfil Handler Consume (Success) + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + topic-fulfil + + + + + topic-fulfil + + + Fulfil Event + + + Handler + + + + + Fulfil Event + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic-event + + + + + topic-event + + + + + topic- + + + settlement-model + + + + + topic- + + + settlement-model + + + + + topic- + + + notification + + + + + topic- + + + notification + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Handler Consume (Success) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'fulfil' && action == 'commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate Duplicate Check + + + + + 4 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 5 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + + + 6 + + + stateRecord = await getTransferState(transferId) + + + + + alt + + + [endStateList.includes(stateRecord.transferStateId)] + + + + + ref + + + getTransfer callback + + + + + 7 + + + Produce message + + + + + + Ignore - resend in progress + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + Validate Prepare Transfer (failure) - Modified Request + + + + [hasDuplicateId == FALSE] + + + + + Validate and persist Transfer Fulfilment + + + + + 8 + + + Request information for the validate checks + + + Error code: + + + 2003 + + + + + 9 + + + Fetch from database + + + + transfer + + + + + 10 + + + + + 11 + + + Return transfer + + + + + 12 + + + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + + + Error code: + + + 2001 + + + + + 13 + + + Validate expirationDate + + + Error code: + + + 3303 + + + + + opt + + + [Transfer.ilpCondition validate successful] + + + + + Request current Settlement Window + + + + + 14 + + + Request to retrieve current/latest transfer settlement window + + + Error code: + + + 2003 + + + + + 15 + + + Fetch settlementWindowId + + + + settlementWindow + + + + + 16 + + + + + 17 + + + Return settlementWindowId to be appended during transferFulfilment insert + + + TODO + + + : During settlement design make sure transfers in 'RECEIVED-FULFIL' + + + state are updated to the next settlement window + + + + + Persist fulfilment + + + + + 18 + + + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + + + Error code: + + + 2003 + + + + + 19 + + + Persist to database + + + + transferFulfilment + + + transferExtension + + + + + 20 + + + Return success + + + + + alt + + + [Transfer.ilpCondition validate successful] + + + + + Persist Transfer State (with transferState='RECEIVED-FULFIL') + + + + + 21 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 22 + + + Persist transfer state + + + + transferStateChange + + + + + 23 + + + Return success + + + + + Message: + + + { + + + id: <id>, + + + from: switch, + + + to: switch, + + + type: application/json + + + content: { + + + payload: { + + + transferId: {id} + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: setmodel, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 24 + + + Route & Publish settlement model event + + + + + Message: + + + { + + + id: <id>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 25 + + + Route & Publish Position event for Payee + + + + [Validate Fulfil Transfer not successful] + + + + + Persist Transfer State (with transferState='ABORTED') + + + + + 26 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 27 + + + Persist transfer state + + + + transferStateChange + + + + + 28 + + + Return success + + + + + Message: + + + { + + + id: <id>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 29 + + + Route & Publish Position event for Payer + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml new file mode 100644 index 000000000..d3d86084c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml @@ -0,0 +1,111 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.0.0 Get Participant Limit Details For All Participants + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant Facade" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Services" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Get Limits for all Participants + OPERATOR -> CSAPI: Request to get Limits - GET - /participants/limits?type={typeValue}¤cy={currencyType} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Fetch Limits for all Participants + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Limits for all participants with currency and type \nError code: 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Limits for currencyId and type(if passed) + note right of PARTICIPANT_DAO #lightgrey + Condition: + participantCurrency.participantCurrencyId = participant.participantCurrencyId + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + [ + participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimit.participantCurrencyId = + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participant + participantCurrency + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Retrieved Participant Limits for currencyId and type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Limits for all participants + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + [ + { + name: + currency: , + limit: {type: , value: } + }, + { + name: + currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Return Limits for all participants \nError code: 3000 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Limits for all participants \nError code: 3000 + + deactivate CSAPI + deactivate OPERATOR +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg new file mode 100644 index 000000000..3f24665cc --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.svg @@ -0,0 +1,241 @@ + + + + + + + + + + + 1.0.0 Get Participant Limit Details For All Participants + + + + Central Services + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant Facade + + + + + Participant Facade + + + + + Central Store + + + + + Central Store + + + + + + + + Get Limits for all Participants + + + + + 1 + + + Request to get Limits - GET - /participants/limits?type={typeValue}&currency={currencyType} + + + + + 2 + + + Fetch Limits for all Participants + + + + + 3 + + + Fetch Limits for all participants with currency and type + + + Error code: + + + 3000 + + + + + 4 + + + Fetch Limits for currencyId and type(if passed) + + + + + Condition: + + + participantCurrency.participantCurrencyId = participant.participantCurrencyId + + + participantLimit.isActive = 1 + + + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + + + [ + + + participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + + + participantLimit.participantCurrencyId = <currencyId> + + + participantLimitType.name = <type> + + + ] + + + + participant + + + participantCurrency + + + participantLimit + + + participantLimitType + + + + + 5 + + + Retrieved Participant Limits for currencyId and type + + + + + 6 + + + Return Limits for all participants + + + + + Message: + + + [ + + + { + + + name: <fsp> + + + currency: <currencyId>, + + + limit: {type: <type>, value: <value>} + + + }, + + + { + + + name: <fsp> + + + currency: <currencyId>, + + + limit: {type: <type>, value: <value>} + + + } + + + ] + + + + + 7 + + + Return Limits for all participants + + + Error code: + + + 3000 + + + + + 8 + + + Return Limits for all participants + + + Error code: + + + 3000 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml new file mode 100644 index 000000000..b8a7ba51b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml @@ -0,0 +1,203 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Lewis Daly + -------------- + ******'/ + + +@startuml +' declare title +title 1.0.0 Get Health Check + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Metadata Handler" as METADATA_HANDLER +entity "Central Service API" as CSAPI +database "Central Store" as DB +collections "Kafka Store" as KAFKA +collections "Logging Sidecar" as SIDECAR + +box "Central Services" #LightYellow +participant CSAPI +participant METADATA_HANDLER +participant DB +participant KAFKA +participant SIDECAR +end box + +' start flow + +activate OPERATOR +group Get Detailed Health Check + OPERATOR -> CSAPI: Request to getHealth - GET /health?detailed=true + activate CSAPI + + CSAPI -> METADATA_HANDLER: Fetch health status for all sub services + activate METADATA_HANDLER + + METADATA_HANDLER -> METADATA_HANDLER: Fetch Service Metadata + note right of METADATA_HANDLER #yellow + - versionNumber + - uptime + - time service started + end note + + + METADATA_HANDLER -> DB: Check connection status + activate DB + DB --> METADATA_HANDLER: Report connection status + deactivate DB + + + METADATA_HANDLER -> KAFKA: Check connection status + activate KAFKA + KAFKA --> METADATA_HANDLER: Report connection status + deactivate KAFKA + + + METADATA_HANDLER -> SIDECAR: Check connection status + activate SIDECAR + SIDECAR --> METADATA_HANDLER: Report connection status + deactivate SIDECAR + + alt Validate Status (success) + METADATA_HANDLER --> CSAPI: Return status response + deactivate METADATA_HANDLER + note right of OPERATOR #yellow + **Example Message:** + ""200 Success"" + { + "status": "UP", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "UP", + "latency": 10 + } + ] + } + end note + + CSAPI --> OPERATOR: Return HTTP Status: 200 + + deactivate CSAPI + deactivate OPERATOR + end + + alt Validate Status (service failure) + METADATA_HANDLER --> CSAPI: Return status response + deactivate METADATA_HANDLER + note right of OPERATOR #yellow + **Example Message:** + ""502 Bad Gateway"" + { + "status": "DOWN", + "uptime": 1234, + "started": "2019-05-31T05:09:25.409Z", + "versionNumber": "5.2.3", + "services": [ + { + "name": "kafka", + "status": "DOWN", + "latency": 1111111 + } + ] + } + end note + + CSAPI --> OPERATOR: Return HTTP Status: 502 + + deactivate CSAPI + deactivate OPERATOR + + + end + + +' group Get Limits for all Participants +' OPERATOR -> CSAPI: Request to get Limits - GET - /participants/limits?type={typeValue}¤cy={currencyType} +' activate CSAPI +' CSAPI -> PARTICIPANT_HANDLER: Fetch Limits for all Participants +' activate PARTICIPANT_HANDLER +' PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Limits for all participants with currency and type \nError code: 3000 +' activate PARTICIPANT_DAO +' PARTICIPANT_DAO ->DB: Fetch Limits for currencyId and type(if passed) +' note right of PARTICIPANT_DAO #lightgrey +' Condition: +' participantCurrency.participantCurrencyId = participant.participantCurrencyId +' participantLimit.isActive = 1 +' participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId +' [ +' participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId +' participantLimit.participantCurrencyId = +' participantLimitType.name = +' ] +' end note + +' activate DB +' hnote over DB #lightyellow +' participant +' participantCurrency +' participantLimit +' participantLimitType +' end note +' DB --> PARTICIPANT_DAO: Retrieved Participant Limits for currencyId and type +' deactivate DB +' PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Limits for all participants +' deactivate PARTICIPANT_DAO +' note right of PARTICIPANT_HANDLER #yellow +' Message: +' [ +' { +' name: +' currency: , +' limit: {type: , value: } +' }, +' { +' name: +' currency: , +' limit: {type: , value: } +' } +' ] +' end note +' PARTICIPANT_HANDLER -->CSAPI: Return Limits for all participants \nError code: 3000 +' deactivate PARTICIPANT_HANDLER +' CSAPI -->OPERATOR: Return Limits for all participants \nError code: 3000 + +' deactivate CSAPI +' deactivate OPERATOR +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg new file mode 100644 index 000000000..aff440cd5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.svg @@ -0,0 +1,324 @@ + + + + + + + + + + + 1.0.0 Get Health Check + + + + Central Services + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Metadata Handler + + + + + Metadata Handler + + + + + Central Store + + + + + Central Store + + + + + + + Kafka Store + + + + + Kafka Store + + + + + Logging Sidecar + + + + + Logging Sidecar + + + + + + Get Detailed Health Check + + + + + 1 + + + Request to getHealth - GET /health?detailed=true + + + + + 2 + + + Fetch health status for all sub services + + + + + 3 + + + Fetch Service Metadata + + + + + - versionNumber + + + - uptime + + + - time service started + + + + + 4 + + + Check connection status + + + + + 5 + + + Report connection status + + + + + 6 + + + Check connection status + + + + + 7 + + + Report connection status + + + + + 8 + + + Check connection status + + + + + 9 + + + Report connection status + + + + + alt + + + [Validate Status (success)] + + + + + 10 + + + Return status response + + + + + Example Message: + + + 200 Success + + + { + + + "status": "UP", + + + "uptime": 1234, + + + "started": "2019-05-31T05:09:25.409Z", + + + "versionNumber": "5.2.3", + + + "services": [ + + + { + + + "name": "kafka", + + + "status": "UP", + + + "latency": 10 + + + } + + + ] + + + } + + + + + 11 + + + Return + + + HTTP Status: + + + 200 + + + + + alt + + + [Validate Status (service failure)] + + + + + 12 + + + Return status response + + + + + Example Message: + + + 502 Bad Gateway + + + { + + + "status": "DOWN", + + + "uptime": 1234, + + + "started": "2019-05-31T05:09:25.409Z", + + + "versionNumber": "5.2.3", + + + "services": [ + + + { + + + "name": "kafka", + + + "status": "DOWN", + + + "latency": 1111111 + + + } + + + ] + + + } + + + + + 13 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml new file mode 100644 index 000000000..0c0fbfff9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml @@ -0,0 +1,206 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.1.0 Request Participant Position and Limit Details + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant Facade" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Services" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Get Callback Details + OPERATOR -> CSAPI: Request to get Limits - GET - /participants/{name}/limits?type={typeValue}¤cy={currencyValue} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Fetch Limits for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: check if "currency" parameter is sent + alt Check if "currency" parameter is sent (Sent) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant/currency id \nError code: 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant/currency id + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Retrieved Participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant/currency id + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant Limits for currency and type \nError code: 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant Limit for currencyId and type(if passed) + note right of PARTICIPANT_DAO #lightgrey + Condition: + participantLimit.isActive = 1 + participantLimit.participantCurrencyId = + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Retrieved Participant Limits for currencyId and type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant Limits for currencyId and type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + [ + { currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Return Participant Limits + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Participant Limits + + + else Validate participant (failure)/ Error + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Validation failure/ Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3000, 3200 + end + + else Check if "currency" parameter is sent (Not Sent) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant \nError code: 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Retrieved Participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant Limits for all currencies and type \nError code: 3000 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant Limit for all currencies and type(if passed) + note right of PARTICIPANT_DAO #lightgrey + Condition: + participantCurrency.participantId = + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + participantLimit.isActive = 1 + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + participantLimitType.name = + ] + end note + + activate DB + hnote over DB #lightyellow + participantCurrency + participantLimit + participantLimitType + end note + DB --> PARTICIPANT_DAO: Retrieved Participant Limits for all currencies and type + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant Limits for all currencies and type + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + [ + { currency: , + limit: {type: , value: } + } + ] + end note + PARTICIPANT_HANDLER -->CSAPI: Return Participant Limits + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Participant Limits + + + else Validate participant (failure)/ Error + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #red: Validation failure/ Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3000, 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3000, 3200 + end + end + + + deactivate CSAPI + deactivate OPERATOR +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg new file mode 100644 index 000000000..e017a501e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.svg @@ -0,0 +1,568 @@ + + + + + + + + + + + 1.1.0 Request Participant Position and Limit Details + + + + Central Services + + + + + + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant Facade + + + + + Participant Facade + + + + + Central Store + + + + + Central Store + + + + + + + + + + Get Callback Details + + + + + 1 + + + Request to get Limits - GET - /participants/{name}/limits?type={typeValue}&currency={currencyValue} + + + + + 2 + + + Fetch Limits for Participant + + + + + 3 + + + check if "currency" parameter is sent + + + + + alt + + + [Check if "currency" parameter is sent (Sent)] + + + + + 4 + + + Fetch Participant/currency id + + + Error code: + + + 3200 + + + + + 5 + + + Fetch Participant/currency id + + + + participant + + + participantCurrency + + + + + 6 + + + Retrieved Participant + + + + + 7 + + + Return Participant/currency id + + + + + 8 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 9 + + + Fetch Participant Limits for currency and type + + + Error code: + + + 3000 + + + + + 10 + + + Fetch Participant Limit for currencyId and type(if passed) + + + + + Condition: + + + participantLimit.isActive = 1 + + + participantLimit.participantCurrencyId = <currencyId> + + + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + + + participantLimitType.name = <type> + + + ] + + + + participantLimit + + + participantLimitType + + + + + 11 + + + Retrieved Participant Limits for currencyId and type + + + + + 12 + + + Return Participant Limits for currencyId and type + + + + + Message: + + + [ + + + { currency: <currencyId>, + + + limit: {type: <type>, value: <value>} + + + } + + + ] + + + + + 13 + + + Return Participant Limits + + + + + 14 + + + Return Participant Limits + + + + [Validate participant (failure)/ Error] + + + + + Validation failure/ Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <ErrorMessage>, + + + } + + + } + + + + + 15 + + + Return + + + Error code: + + + 3000, 3200 + + + + + 16 + + + Return + + + Error code: + + + 3000, 3200 + + + + [Check if "currency" parameter is sent (Not Sent)] + + + + + 17 + + + Fetch Participant + + + Error code: + + + 3200 + + + + + 18 + + + Fetch Participant + + + + participant + + + + + 19 + + + Retrieved Participant + + + + + 20 + + + Return Participant + + + + + 21 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 22 + + + Fetch Participant Limits for all currencies and type + + + Error code: + + + 3000 + + + + + 23 + + + Fetch Participant Limit for all currencies and type(if passed) + + + + + Condition: + + + participantCurrency.participantId = <participantId> + + + participantLimit.participantCurrencyId = participantCurrency.participantCurrencyId + + + participantLimit.isActive = 1 + + + [ participantLimit.participantLimitTypeId = participantLimitType.participantLimitTypeId + + + participantLimitType.name = <type> + + + ] + + + + participantCurrency + + + participantLimit + + + participantLimitType + + + + + 24 + + + Retrieved Participant Limits for all currencies and type + + + + + 25 + + + Return Participant Limits for all currencies and type + + + + + Message: + + + [ + + + { currency: <currencyId>, + + + limit: {type: <type>, value: <value>} + + + } + + + ] + + + + + 26 + + + Return Participant Limits + + + + + 27 + + + Return Participant Limits + + + + [Validate participant (failure)/ Error] + + + + + Validation failure/ Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <ErrorMessage>, + + + } + + + } + + + + + 28 + + + Return + + + Error code: + + + 3000, 3200 + + + + + 29 + + + Return + + + Error code: + + + 3000, 3200 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml new file mode 100644 index 000000000..06f4689fb --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml @@ -0,0 +1,167 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 1.1.5. Request transfer status (getTransferStatusById) - Phase2 version + +autonumber + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Event-Topic" as TOPIC_EVENTS +entity "Transfer-DAO" as TRANSFER_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_EVENTS + participant TRANSFER_DAO + participant DB +end box + +' start flow +group Request transfer status + activate DFSP + DFSP -> NOTIFY_HANDLER: Callback transfer status request URL - GET - /transfers/{ID} +'alt invalid tansferId +' activate NOTIFY_HANDLER +' NOTIFY_HANDLER -> NOTIFY_HANDLER: Validate TransferId +' break +' note right of NOTIFY_HANDLER #yellow +' { +' "errorInformation": { +' "errorCode": , +' "errorDescription": "Invalid payload or state" +' } +' } +' end note +' DFSP <-- NOTIFY_HANDLER: Respond HTTP - 4xx (Bad Request) +' end +'else valid transfer + ||| + group Persist Event Information +' hnote over NOTIFY_HANDLER #Pink +' Do we need to write the event to the Event-Topic? +' Not transaction related. +' end hnote + NOTIFY_HANDLER -> CSAPI: Request transfer information - GET - /transfers/{ID} + activate CSAPI + + activate TOPIC_EVENTS + CSAPI -> TOPIC_EVENTS: Publish event information + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + CSAPI <-- TOPIC_EVENTS: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + DFSP <-- NOTIFY_HANDLER: Respond HTTP - 200 (OK) +'end + NOTIFY_HANDLER -> CSAPI: Request details for Transfer - GET - /transfers/{ID}\nError code: 2003 + activate CSAPI + CSAPI -> TRANSFER_DAO: Request transfer status\nError code: 2003 + activate TRANSFER_DAO + TRANSFER_DAO -> DB: Fetch transfer status + activate DB + hnote over DB #lightyellow + SELECT transferId, transferStateId + FROM **transferStateChange** + WHERE transferId = {ID} + ORDER BY transferStateChangeId desc limit 1 + end note + deactivate DB + CSAPI <-- TRANSFER_DAO: Return transfer status + deactivate TRANSFER_DAO + NOTIFY_HANDLER <-- CSAPI: Return transfer status\nError codes: 3202, 3203 + deactivate CSAPI + + alt Is there a transfer with the given ID recorded in the system? + alt Yes AND transferState is COMMITTED \nThis implies that a succesful transfer with the given ID is recorded in the system + note left of NOTIFY_HANDLER #yellow + { + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + "transferState": "COMMITTED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT on /transfers/{ID} + else transferState in [RECEIVED, RESERVED, ABORTED] + note left of NOTIFY_HANDLER #yellow + { + "transferState": "RECEIVED", + extensionList: + { + extension: + [ + { + "key": "Description", + "value": "This is a more detailed description" + } + ] + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT on /transfers/{ID} + end + note right of NOTIFY_HANDLER #lightgray + Log ERROR event + end note + else A transfer with the given ID is not present in the System or this is an invalid request + note left of NOTIFY_HANDLER #yellow + { + "errorInformation": { + "errorCode": , + "errorDescription": "Client error description" + } + } + end note + DFSP <- NOTIFY_HANDLER: callback PUT on /transfers/{ID}/error + end + deactivate NOTIFY_HANDLER +deactivate DFSP +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg new file mode 100644 index 000000000..8ad873bd3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.svg @@ -0,0 +1,402 @@ + + + + + + + + + + + 1.1.5. Request transfer status (getTransferStatusById) - Phase2 version + + + + Financial Service Provider + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + DFSP(n) + + + Participant + + + + + DFSP(n) + + + Participant + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + Transfer-DAO + + + + + Transfer-DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Request transfer status + + + + + 1 + + + Callback transfer status request URL - GET - /transfers/{ID} + + + + + Persist Event Information + + + + + 2 + + + Request transfer information - GET - /transfers/{ID} + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + 4 + + + Return success + + + + + 5 + + + Return success + + + + + 6 + + + Respond HTTP - 200 (OK) + + + + + 7 + + + Request details for Transfer - GET - /transfers/{ID} + + + Error code: + + + 2003 + + + + + 8 + + + Request transfer status + + + Error code: + + + 2003 + + + + + 9 + + + Fetch transfer status + + + + SELECT transferId, transferStateId + + + FROM + + + transferStateChange + + + WHERE transferId = {ID} + + + ORDER BY transferStateChangeId desc limit 1 + + + + + 10 + + + Return transfer status + + + + + 11 + + + Return transfer status + + + Error codes: + + + 3202, 3203 + + + + + alt + + + [Is there a transfer with the given ID recorded in the system?] + + + + + alt + + + [Yes AND transferState is COMMITTED + + + This implies that a succesful transfer with the given ID is recorded in the system] + + + + + { + + + "fulfilment": "WLctttbu2HvTsa1XWvUoGRcQozHsqeu9Ahl2JW9Bsu8", + + + "completedTimestamp": "2018-09-24T08:38:08.699-04:00", + + + "transferState": "COMMITTED", + + + extensionList: + + + { + + + extension: + + + [ + + + { + + + "key": "Description", + + + "value": "This is a more detailed description" + + + } + + + ] + + + } + + + } + + + + + 12 + + + callback PUT on /transfers/{ID} + + + + [transferState in [RECEIVED, RESERVED, ABORTED]] + + + + + { + + + "transferState": "RECEIVED", + + + extensionList: + + + { + + + extension: + + + [ + + + { + + + "key": "Description", + + + "value": "This is a more detailed description" + + + } + + + ] + + + } + + + } + + + + + 13 + + + callback PUT on /transfers/{ID} + + + + + Log ERROR event + + + + [A transfer with the given ID is not present in the System or this is an invalid request] + + + + + { + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 14 + + + callback PUT on /transfers/{ID}/error + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml new file mode 100644 index 000000000..0d42f4d94 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml @@ -0,0 +1,174 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declare title +title 1.1.0 Manage Participant Limits + +autonumber + +' declare actors +actor "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Services" #LightYellow +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Manage Net Debit Cap + OPERATOR -> CSAPI: Request to adjust Participant Limit for a certain Currency - POST - /participants/{name}/limits + note right of OPERATOR #yellow + Message: + { + payload: { + currency: , + limit: { + type: , + value: + } + } + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Adjust Limit for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant/currency \nError code: 3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Participant/currency + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Retrieved Participant/currency + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return Participant/currency + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: (for ParticipantCurrency) Fetch ParticipantLimit \nError code: 3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch ParticipantLimit + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: Retrieved ParticipantLimit + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return ParticipantLimit + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER -> PARTICIPANT_HANDLER: Validate ParticipantLimit + alt Validate participantLimit (success) + Group DB TRANSACTION IMPLEMENTATION - Lock on ParticipantLimit table with UPDATE + note right of PARTICIPANT_DAO #lightgrey + If (record exists && isActive = 1) + oldIsActive.isActive = 0 + insert Record + Else + insert Record + End + + end note + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: (for ParticipantLimit) Insert new ParticipantLimit \nError code: 3200 + + activate PARTICIPANT_DAO + + PARTICIPANT_DAO -> DB: Insert ParticipantLimit + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: Inserted ParticipantLimit + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return ParticipantLimit + + + deactivate PARTICIPANT_DAO + ' Release Lock on ParticipantLimit table + End + + else Validate participantLimit (failure) + note right of PARTICIPANT_HANDLER #red: Validation failure! + + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "ParticipantLimit Not Found", + } + } + end note + end + PARTICIPANT_HANDLER --> CSAPI: Return new Limit values and status 200 + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "currency": "EUR", + "limit": { + "participantLimitId": , + "participantLimitTypeId": , + "type": , + "value": , + "isActive": 1 + } + } + end note + CSAPI --> OPERATOR: Return new Limit values and status 200 + + else Validate participant (failure) + note right of PARTICIPANT_HANDLER #red: Validation failure! + + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + end note + + end + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3200 + + deactivate PARTICIPANT_HANDLER + deactivate CSAPI + deactivate OPERATOR +end +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg new file mode 100644 index 000000000..a640cdb01 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.svg @@ -0,0 +1,457 @@ + + + + + + + + + + + 1.1.0 Manage Participant Limits + + + + Central Services + + + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Manage Net Debit Cap + + + + + 1 + + + Request to adjust Participant Limit for a certain Currency - POST - /participants/{name}/limits + + + + + Message: + + + { + + + payload: { + + + currency: <string>, + + + limit: { + + + type: <string>, + + + value: <Id> + + + } + + + } + + + } + + + + + 2 + + + Adjust Limit for Participant + + + + + 3 + + + Fetch Participant/currency + + + Error code: + + + 3200 + + + + + 4 + + + Fetch Participant/currency + + + + participant + + + participantCurrency + + + + + 5 + + + Retrieved Participant/currency + + + + + 6 + + + Return Participant/currency + + + + + 7 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 8 + + + (for ParticipantCurrency) Fetch ParticipantLimit + + + Error code: + + + 3200 + + + + + 9 + + + Fetch ParticipantLimit + + + + participantLimit + + + + + 10 + + + Retrieved ParticipantLimit + + + + + 11 + + + Return ParticipantLimit + + + + + 12 + + + Validate ParticipantLimit + + + + + alt + + + [Validate participantLimit (success)] + + + + + DB TRANSACTION IMPLEMENTATION - Lock on ParticipantLimit table with UPDATE + + + + + If (record exists && isActive = 1) + + + oldIsActive.isActive = 0 + + + insert Record + + + Else + + + insert Record + + + End + + + + + 13 + + + (for ParticipantLimit) Insert new ParticipantLimit + + + Error code: + + + 3200 + + + + + 14 + + + Insert ParticipantLimit + + + + participantLimit + + + + + 15 + + + Inserted ParticipantLimit + + + + + 16 + + + Return ParticipantLimit + + + + [Validate participantLimit (failure)] + + + + + Validation failure! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3200, + + + "errorDescription": "ParticipantLimit Not Found", + + + } + + + } + + + + + 17 + + + Return new Limit values and status 200 + + + + + Message: + + + { + + + "currency": "EUR", + + + "limit": { + + + "participantLimitId": <number>, + + + "participantLimitTypeId": <number>, + + + "type": <string>, + + + "value": <string>, + + + "isActive": 1 + + + } + + + } + + + + + 18 + + + Return new Limit values and status 200 + + + + [Validate participant (failure)] + + + + + Validation failure! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3200, + + + "errorDescription": "FSP id Not Found", + + + } + + + } + + + + + 19 + + + Return + + + Error code: + + + 3200 + + + + + 20 + + + Return + + + Error code: + + + 3200 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml new file mode 100644 index 000000000..79bb20553 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml @@ -0,0 +1,187 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.0.0 Create initial position and limits for Participant + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant FACADE" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Services" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Create initial position and limits + OPERATOR -> CSAPI: Request to Create initial position and limits - POST - /paticipants/{name}/initialPositionAndLimits + note right of OPERATOR #yellow + Message: + { + currency: , + limit: { + type: , + value: + }, + initialPosition: + } + end note + + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Create initial position and limits for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant/ Currency Id \nError code: 3200 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Participant/Currency Id + activate DB + hnote over DB #lightyellow + participant + participantCurrency + end note + DB --> PARTICIPANT_DAO: Retrieved Participant/Currency Id + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return Participant/Currency Id + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch limit for participantCurrencyId + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch limit for participantCurrencyId + activate DB + hnote over DB #lightyellow + participantLimit + end note + DB --> PARTICIPANT_DAO: Retrieved participant limit + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return participant limit + deactivate PARTICIPANT_DAO + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch position for participantCurrencyId + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch position for participantCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> PARTICIPANT_DAO: Retrieved participant position + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return participant position + deactivate PARTICIPANT_DAO + + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Participant position or limit exists check + + alt position or limit does not exist (success) + + + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: create initial position and limits for Participantt \nError code: 2003/Msg: Service unavailable \nError code: 2001/Msg: Internal Server Error + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Persist Participant limits/position + activate DB + hnote over DB #lightyellow + participantPosition + participantLimit + end note + deactivate DB + PARTICIPANT_DAO --> PARTICIPANT_HANDLER: Return status + deactivate PARTICIPANT_DAO + alt Details persisted successfully + PARTICIPANT_HANDLER -->CSAPI: Return Status Code 201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Status Code 201 + else Details not persisted/Error + note right of PARTICIPANT_HANDLER #red: Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code + + end + + else position or limit exists (failure) + note right of PARTICIPANT_HANDLER #red: Error! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "Participant Limit or Initial Position already set", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3200 + ' deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3200 + + end + + else Validate participant (failure) + note right of PARTICIPANT_HANDLER #red: Validation failure! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3200, + "errorDescription": "FSP id Not Found", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3200 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3200 + + end + deactivate CSAPI + deactivate OPERATOR +end +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg new file mode 100644 index 000000000..fcfca97c7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.svg @@ -0,0 +1,527 @@ + + + + + + + + + + + 1.0.0 Create initial position and limits for Participant + + + + Central Services + + + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant FACADE + + + + + Participant FACADE + + + + + Central Store + + + + + Central Store + + + + + + + + Create initial position and limits + + + + + 1 + + + Request to Create initial position and limits - POST - /paticipants/{name}/initialPositionAndLimits + + + + + Message: + + + { + + + currency: <currencyId>, + + + limit: { + + + type: <limitType>, + + + value: <limitValue> + + + }, + + + initialPosition: <positionValue> + + + } + + + + + 2 + + + Create initial position and limits for Participant + + + + + 3 + + + Fetch Participant/ Currency Id + + + Error code: + + + 3200 + + + + + 4 + + + Fetch Participant/Currency Id + + + + participant + + + participantCurrency + + + + + 5 + + + Retrieved Participant/Currency Id + + + + + 6 + + + Return Participant/Currency Id + + + + + 7 + + + Validate DFSP + + + + + alt + + + [Validate participant (success)] + + + + + 8 + + + Fetch limit for participantCurrencyId + + + + + 9 + + + Fetch limit for participantCurrencyId + + + + participantLimit + + + + + 10 + + + Retrieved participant limit + + + + + 11 + + + Return participant limit + + + + + 12 + + + Fetch position for participantCurrencyId + + + + + 13 + + + Fetch position for participantCurrencyId + + + + participantPosition + + + + + 14 + + + Retrieved participant position + + + + + 15 + + + Return participant position + + + + + 16 + + + Participant position or limit exists check + + + + + alt + + + [position or limit does not exist (success)] + + + + + 17 + + + create initial position and limits for Participantt + + + Error code: + + + 2003/ + + + Msg: + + + Service unavailable + + + Error code: + + + 2001/ + + + Msg: + + + Internal Server Error + + + + + 18 + + + Persist Participant limits/position + + + + participantPosition + + + participantLimit + + + + + 19 + + + Return status + + + + + alt + + + [Details persisted successfully] + + + + + 20 + + + Return Status Code 201 + + + + + 21 + + + Return Status Code 201 + + + + [Details not persisted/Error] + + + + + Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 22 + + + Return + + + Error code + + + + + 23 + + + Return + + + Error code + + + + [position or limit exists (failure)] + + + + + Error! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3200, + + + "errorDescription": "Participant Limit or Initial Position already set", + + + } + + + } + + + + + 24 + + + Return + + + Error code: + + + 3200 + + + + + 25 + + + Return + + + Error code: + + + 3200 + + + + [Validate participant (failure)] + + + + + Validation failure! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3200, + + + "errorDescription": "FSP id Not Found", + + + } + + + } + + + + + 26 + + + Return + + + Error code: + + + 3200 + + + + + 27 + + + Return + + + Error code: + + + 3200 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml new file mode 100644 index 000000000..2bab529fe --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml @@ -0,0 +1,164 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 4.1.0 Get Participant Position Details + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant DAO" as PARTICIPANT_DAO +entity "Position Facade" as POSITION_DAO +database "Central Store" as DB +box "HUB Operator" #LightBlue +participant OPERATOR +end box + +box "Central Service" #LightYellow +participant CSAPI +participant PARTICIPANT_HANDLER +participant PARTICIPANT_DAO +participant POSITION_DAO +participant DB +end box + +' start flow + +activate OPERATOR +group Get Position Details + OPERATOR -> CSAPI: Request to get positions - GET - /participants/{name}/positions?currency={currencyId} + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Fetch Positions for Participant + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Participant \nError code: 2003,3201 + + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Participant + activate DB + hnote over DB #lightyellow + participant + end note + DB --> PARTICIPANT_DAO: Retrieved Participant + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Participant + deactivate PARTICIPANT_DAO + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: Validate DFSP \nError code: 3201 + alt Validate participant (success) + PARTICIPANT_HANDLER ->PARTICIPANT_HANDLER: currency parameter passed ? + + alt currency parameter passed + + PARTICIPANT_HANDLER ->POSITION_DAO: Fetch Participant position for a currency id\nError code: 2003 + activate POSITION_DAO + POSITION_DAO ->DB: Fetch Participant position for a currency id + activate DB + hnote over DB #lightyellow + participantCurrency + participantPosition + end note + DB --> POSITION_DAO: Retrieved Participant position for a currency id + deactivate DB + POSITION_DAO -->PARTICIPANT_HANDLER: Return Positions for Participant + deactivate POSITION_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + { + { + currency: , + value: , + updatedTime: + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Participant position for a currency id + CSAPI -->OPERATOR: Return Participant position for a currency id + else currency parameter not passed + PARTICIPANT_HANDLER ->POSITION_DAO: Fetch Participant Positions for all currencies\nError code: 2003 + activate POSITION_DAO + POSITION_DAO ->DB: Fetch Participant Positions for all currencies + activate DB + hnote over DB #lightyellow + participantCurrency + participantPosition + end note + DB --> POSITION_DAO: Retrieved Participant Positions for all currencies + deactivate DB + POSITION_DAO -->PARTICIPANT_HANDLER: Return Participant Positions for all currencies + deactivate POSITION_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + { + [ + { + currency: , + value: , + updatedTime: + }, + { + currency: , + value: , + updatedTime: + } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Participant Positions for all currencies + CSAPI -->OPERATOR: Return Participant Positions for all currencies + end + else Validate participant (failure) + note right of PARTICIPANT_HANDLER #red: Validation failure! + activate PARTICIPANT_HANDLER + note right of PARTICIPANT_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": 3201, + "errorDescription": "FSP id does not exist or not found", + } + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Error code: 3201 + deactivate PARTICIPANT_HANDLER + CSAPI -->OPERATOR: Return Error code: 3201 + end + +end + +deactivate CSAPI +deactivate OPERATOR + +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg new file mode 100644 index 000000000..b623ef955 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.svg @@ -0,0 +1,448 @@ + + + + + + + + + + + 4.1.0 Get Participant Position Details + + + + HUB Operator + + + + Central Service + + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant DAO + + + + + Participant DAO + + + + + Position Facade + + + + + Position Facade + + + + + Central Store + + + + + Central Store + + + + + + + + Get Position Details + + + + + 1 + + + Request to get positions - GET - /participants/{name}/positions?currency={currencyId} + + + + + 2 + + + Fetch Positions for Participant + + + + + 3 + + + Fetch Participant + + + Error code: + + + 2003,3201 + + + + + 4 + + + Fetch Participant + + + + participant + + + + + 5 + + + Retrieved Participant + + + + + 6 + + + Return Participant + + + + + 7 + + + Validate DFSP + + + Error code: + + + 3201 + + + + + alt + + + [Validate participant (success)] + + + + + 8 + + + currency parameter passed ? + + + + + alt + + + [currency parameter passed] + + + + + 9 + + + Fetch Participant position for a currency id + + + Error code: + + + 2003 + + + + + 10 + + + Fetch Participant position for a currency id + + + + participantCurrency + + + participantPosition + + + + + 11 + + + Retrieved Participant position for a currency id + + + + + 12 + + + Return Positions for Participant + + + + + Message: + + + { + + + { + + + currency: <currencyId>, + + + value: <positionValue>, + + + updatedTime: <timeStamp1> + + + } + + + } + + + + + 13 + + + Return Participant position for a currency id + + + + + 14 + + + Return Participant position for a currency id + + + + [currency parameter not passed] + + + + + 15 + + + Fetch Participant Positions for all currencies + + + Error code: + + + 2003 + + + + + 16 + + + Fetch Participant Positions for all currencies + + + + participantCurrency + + + participantPosition + + + + + 17 + + + Retrieved Participant Positions for all currencies + + + + + 18 + + + Return Participant Positions for all currencies + + + + + Message: + + + { + + + [ + + + { + + + currency: <currencyId1>, + + + value: <positionValue1>, + + + updatedTime: <timeStamp1> + + + }, + + + { + + + currency: <currencyId2>, + + + value: <positionValue2>, + + + updatedTime: <timeStamp2> + + + } + + + ] + + + } + + + + + 19 + + + Return Participant Positions for all currencies + + + + + 20 + + + Return Participant Positions for all currencies + + + + [Validate participant (failure)] + + + + + Validation failure! + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": 3201, + + + "errorDescription": "FSP id does not exist or not found", + + + } + + + } + + + + + 21 + + + Return + + + Error code: + + + 3201 + + + + + 22 + + + Return + + + Error code: + + + 3201 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml new file mode 100644 index 000000000..753a7e850 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml @@ -0,0 +1,139 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 4.2.0 Get Positions of all Participants + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +entity "ML-API-ADAPTER" as MLAPI +boundary "Central Service API" as CSAPI +control "Participant Handler" as PARTICIPANT_HANDLER +entity "Central Service API" as CSAPI +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB +box "ML API Adapter Service" #LightBlue + participant MLAPI +end box + +box "Central Service" #LightYellow + participant CSAPI + participant PARTICIPANT_HANDLER + participant PARTICIPANT_DAO + participant DB +end box + +' start flow + +activate MLAPI +group Get Position Details +MLAPI -> CSAPI: Request to get positions - GET - /participants/positions + activate CSAPI + CSAPI -> PARTICIPANT_HANDLER: Fetch Positions for all Participants + activate PARTICIPANT_HANDLER + PARTICIPANT_HANDLER ->PARTICIPANT_DAO: Fetch Positions for all active Participants \nError code: 2003,3200 + activate PARTICIPANT_DAO + PARTICIPANT_DAO ->DB: Fetch Positions for: \n all active Participants \n with all active Currencies for each Participant + activate DB + hnote over DB #lightyellow + participant + participantPosition + participantCurrency + end note + DB --> PARTICIPANT_DAO: Retrieved Positions for Participants + deactivate DB + PARTICIPANT_DAO -->PARTICIPANT_HANDLER: Return Positions for Participants + deactivate PARTICIPANT_DAO + note right of PARTICIPANT_HANDLER #yellow + Message: + { + snapshotAt: , + positions: + [ + { + participantId: , + participantPositions: + [ + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + }, + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + } + ] + }, + { + participantId: , + participantPositions: + [ + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + }, + { + currentPosition: { + currency: , + value: , + reservedValue: , + lastUpdated: + } + } + ] + } + ] + } + end note + PARTICIPANT_HANDLER -->CSAPI: Return Positions for Participants + deactivate PARTICIPANT_HANDLER +CSAPI -->MLAPI: Return Positions for Participants + +end + deactivate CSAPI +deactivate MLAPI + +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg new file mode 100644 index 000000000..76b9e95a5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.svg @@ -0,0 +1,321 @@ + + + + + + + + + + + 4.2.0 Get Positions of all Participants + + + + ML API Adapter Service + + + + Central Service + + + + + + ML-API-ADAPTER + + + + + ML-API-ADAPTER + + + + + Central Service API + + + + + Central Service API + + + + + Participant Handler + + + + + Participant Handler + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Get Position Details + + + + + 1 + + + Request to get positions - GET - /participants/positions + + + + + 2 + + + Fetch Positions for all Participants + + + + + 3 + + + Fetch Positions for all active Participants + + + Error code: + + + 2003,3200 + + + + + 4 + + + Fetch Positions for: + + + all active Participants + + + with all active Currencies for each Participant + + + + participant + + + participantPosition + + + participantCurrency + + + + + 5 + + + Retrieved Positions for Participants + + + + + 6 + + + Return Positions for Participants + + + + + Message: + + + { + + + snapshotAt: <timestamp0>, + + + positions: + + + [ + + + { + + + participantId: <dfsp1>, + + + participantPositions: + + + [ + + + { + + + currentPosition: { + + + currency: <currency1>, + + + value: <amount1>, + + + reservedValue: <amount2>, + + + lastUpdated: <timeStamp1> + + + } + + + }, + + + { + + + currentPosition: { + + + currency: <currency2>, + + + value: <amount3>, + + + reservedValue: <amount4>, + + + lastUpdated: <timeStamp2> + + + } + + + } + + + ] + + + }, + + + { + + + participantId: <dfsp2>, + + + participantPositions: + + + [ + + + { + + + currentPosition: { + + + currency: <currency1>, + + + value: <amount1>, + + + reservedValue: <amount2>, + + + lastUpdated: <timeStamp1> + + + } + + + }, + + + { + + + currentPosition: { + + + currency: <currency2>, + + + value: <amount3>, + + + reservedValue: <amount4>, + + + lastUpdated: <timeStamp2> + + + } + + + } + + + ] + + + } + + + ] + + + } + + + + + 7 + + + Return Positions for Participants + + + + + 8 + + + Return Positions for Participants + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml new file mode 100644 index 000000000..04d4356c9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.plantuml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Position Handler Consume (single message) v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + alt Consume Prepare message for Payer + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'prepare'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Prepare Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Fulfil message for Payee + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action IN ['commit', 'reserve']\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Fulfil Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Abort message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' &&\naction IN ['timeout-reserved', 'reject', 'fail']\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Abort Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg new file mode 100644 index 000000000..6829d68ff --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + 1.3.0. Position Handler Consume (single message) v1.1 + + + + Central Service + + + + + + + + + + + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + Position Handler Consume + + + + + alt + + + [Consume Prepare message for Payer] + + + + + 1 + + + Consume Position event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'position' && action == 'prepare' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Prepare Position Handler Consume + + + + + 4 + + + Produce message + + + + [Consume Fulfil message for Payee] + + + + + 5 + + + Consume Position event message for Payee + + + + + break + + + + + Validate Event + + + + + 6 + + + Validate event - Rule: type == 'position' && action IN ['commit', 'reserve'] + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 7 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Fulfil Position Handler Consume + + + + + 8 + + + Produce message + + + + [Consume Abort message] + + + + + 9 + + + Consume Position event message + + + + + break + + + + + Validate Event + + + + + 10 + + + Validate event - Rule: type == 'position' && + + + action IN ['timeout-reserved', 'reject', 'fail'] + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 11 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Abort Position Handler Consume + + + + + 12 + + + Produce message + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml new file mode 100644 index 000000000..963700067 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml @@ -0,0 +1,115 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.0. Position Handler Consume (single message) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + alt Consume Prepare message for Payer + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'prepare'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Prepare Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Fulfil message for Payee + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payee + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'commit'\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Fulfil Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else Consume Abort message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' &&\naction IN ['timeout-reserved', 'reject', 'fail']\nError codes: 2001 + end + end + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + ||| + ref over POS_HANDLER: Abort Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg new file mode 100644 index 000000000..f03e043a8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + 1.3.0. Position Handler Consume (single message) + + + + Central Service + + + + + + + + + + + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Handler + + + + + Position Handler + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + Position Handler Consume + + + + + alt + + + [Consume Prepare message for Payer] + + + + + 1 + + + Consume Position event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'position' && action == 'prepare' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Prepare Position Handler Consume + + + + + 4 + + + Produce message + + + + [Consume Fulfil message for Payee] + + + + + 5 + + + Consume Position event message for Payee + + + + + break + + + + + Validate Event + + + + + 6 + + + Validate event - Rule: type == 'position' && action == 'commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 7 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Fulfil Position Handler Consume + + + + + 8 + + + Produce message + + + + [Consume Abort message] + + + + + 9 + + + Consume Position event message + + + + + break + + + + + Validate Event + + + + + 10 + + + Validate event - Rule: type == 'position' && + + + action IN ['timeout-reserved', 'reject', 'fail'] + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 11 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + ref + + + Abort Position Handler Consume + + + + + 12 + + + Produce message + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml new file mode 100644 index 000000000..2e420c3b3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml @@ -0,0 +1,283 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.1. Prepare Position Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER + +entity "Position\nManagement\nFacade" as POS_MGMT +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_MGMT + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Prepare Position Handler Consume + POS_HANDLER -> POS_MGMT: Request transfers to be processed + activate POS_MGMT + POS_MGMT -> POS_MGMT: Check 1st transfer to select the Participant and Currency + group DB TRANSACTION + ' DB Trans: This is where 1st DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT -> POS_MGMT: Loop through batch and build list of transferIds and calculate sumTransfersInBatch,\nchecking all in Batch are for the correct Paricipant and Currency\nError code: 2001, 3100 + POS_MGMT -> DB: Retrieve current state of all transfers in array from DB with select whereIn\n(FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_MGMT: Return current state of all selected transfers from DB + deactivate DB + POS_MGMT <-> POS_MGMT: Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nError code: 2001 against failing transfers\nBatch is not rejected as a whole. + + note right of POS_MGMT #lightgray + List of transfers used during processing + **reservedTransfers** is list of transfers to be processed in the batch + **abortedTransfers** is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + **processedTransfers** is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + Scalar intermidate values used in the algorithm + **transferAmount** = payload.amount.amount + **sumTransfersInBatch** = SUM amount against each Transfer in batch + **currentPosition** = participantPosition.value + **reservedPosition** = participantPosition.{original}reservedValue + **effectivePosition** = currentPosition + reservedPosition + **heldPosition** = effectivePosition + sumTransfersInBatch + **availablePosition** = //if settlement model delay is IMMEDIATE then:// settlementBalance + participantLimit(NetDebitCap) - effectivePosition, //otherwise:// participantLimit(NetDebitCap) - effectivePosition + **sumReserved** = SUM of transfers that have met rule criteria and processed + end note + note over POS_MGMT,DB + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + and calculate the available position for the Participant to use + end note + POS_MGMT -> DB: Select effectivePosition FOR UPDATE from DB for Payer + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_MGMT: Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + deactivate DB + POS_MGMT -> POS_MGMT: Increment reservedValue to heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) + POS_MGMT -> DB: Persist reservedValue + activate DB + hnote over DB #lightyellow + UPDATE **participantPosition** + SET reservedValue += sumTransfersInBatch + end note + deactivate DB + ' DB Trans: This is where 1st DB Transaction would end in 2 DB transacation future model for horizontal scaling + + + POS_MGMT -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + FROM **participantLimit** + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + AND participantLimit.participantId = payload.payerFsp + AND participantLimit.currencyId = payload.amount.currency + end note + DB --> POS_MGMT: Return position limits + deactivate DB + POS_MGMT <-> POS_MGMT: **availablePosition** = //if settlement model delay is IMMEDIATE then://\n settlementBalance + participantLimit(NetDebitCap) - effectivePosition\n //otherwise://\n participantLimit(NetDebitCap) - effectivePosition\n(same as = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + note over POS_MGMT,DB + For each transfer in the batch, validate the availablility of position to meet the transfer amount + this will be as per the position algorithm documented below + end note + POS_MGMT <-> POS_MGMT: Validate availablePosition for each tranfser (see algorithm below)\nError code: 4001 + note right of POS_MGMT #lightgray + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + 04: foreach transfer in reservedTransfers + 05: sumProcessed += transfer.amount // the total processed so far **(NEED TO UPDATE IN CODE)** + 06: if availablePosition >= transfer.amount + 07: transfer.state = "RESERVED" + 08: availablePosition -= preparedTransfer.amount + 09: sumRESERVED += preparedTransfer.amount + 10: else + 11: preparedTransfer.state = "ABORTED" + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + 13: end if + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(NEED TO UPDATE IN CODE)** // the running down of the total reserved value at the begining of the batch. + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + 16: end foreach + end note + note over POS_MGMT,DB + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + end note + POS_MGMT->POS_MGMT: Assess any limit thresholds on the final position\nadding to alarm list if triggered + + ' DB Trans: This is where 2nd DB Transaction would start in 2 DB transacation future model for horizontal scaling + POS_MGMT->DB: Persist latest position **value** and **reservedValue** to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value += sumRESERVED, + reservedValue -= sumTransfersInBatch + end note + activate DB + deactivate DB + + POS_MGMT -> DB: Bulk persist transferStateChange for all processedTransfers + hnote over DB #lightyellow + batch INSERT **transferStateChange** + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + build list of transferStateChanges from transferBatch + + end note + activate DB + deactivate DB + + POS_MGMT->POS_MGMT: Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + note right of POS_MGMT #lightgray + Effectively: + SET transferStateChangeId = processedTransfer.transferStateChangeId, + participantPositionId = preparedTransfer.participantPositionId, + value = preparedTransfer.positionValue, + reservedValue = preparedTransfer.positionReservedValue + end note + POS_MGMT -> DB: Bulk persist the participant position change for all processedTransfers + hnote over DB #lightyellow + batch INSERT **participantPositionChange** + end note + activate DB + deactivate DB + ' DB Trans: This is where 2nd DB Transaction would end in 2 DB transacation future model for horizontal scaling + end + POS_MGMT --> POS_HANDLER: Return a map of transferIds and their transferStateChanges + deactivate POS_MGMT + alt Calculate & Validate Latest Position Prepare (success) + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else Calculate & Validate Latest Position Prepare (failure) + note right of POS_HANDLER #red: Validation failure! + + group Persist Transfer State (with transferState='ABORTED' on position check fail) + POS_HANDLER -> POS_DAO: Request to persist transfer\nError code: 2003 + activate POS_DAO + note right of POS_HANDLER #lightgray + transferStateChange.state = "ABORTED", + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + end note + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg new file mode 100644 index 000000000..0e6b46ec3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.svg @@ -0,0 +1,842 @@ + + + + + + + + + + + 1.3.1. Prepare Position Handler Consume + + + + Central Service + + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Position + + + Management + + + Facade + + + + + Position + + + Management + + + Facade + + + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Prepare Position Handler Consume + + + + + 1 + + + Request transfers to be processed + + + + + 2 + + + Check 1st transfer to select the Participant and Currency + + + + + DB TRANSACTION + + + + + 3 + + + Loop through batch and build list of transferIds and calculate sumTransfersInBatch, + + + checking all in Batch are for the correct Paricipant and Currency + + + Error code: + + + 2001, 3100 + + + + + 4 + + + Retrieve current state of all transfers in array from DB with select whereIn + + + (FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) + + + + transferStateChange + + + transferParticipant + + + + + 5 + + + Return current state of all selected transfers from DB + + + + + 6 + + + Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE') + + + Error code: + + + 2001 + + + against failing transfers + + + Batch is not rejected as a whole. + + + + + List of transfers used during processing + + + reservedTransfers + + + is list of transfers to be processed in the batch + + + abortedTransfers + + + is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) + + + processedTransfers + + + is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation + + + Scalar intermidate values used in the algorithm + + + transferAmount + + + = payload.amount.amount + + + sumTransfersInBatch + + + = SUM amount against each Transfer in batch + + + currentPosition + + + = participantPosition.value + + + reservedPosition + + + = participantPosition.{original}reservedValue + + + effectivePosition + + + = currentPosition + reservedPosition + + + heldPosition + + + = effectivePosition + sumTransfersInBatch + + + availablePosition + + + = + + + if settlement model delay is IMMEDIATE then: + + + settlementBalance + participantLimit(NetDebitCap) - effectivePosition, + + + otherwise: + + + participantLimit(NetDebitCap) - effectivePosition + + + sumReserved + + + = SUM of transfers that have met rule criteria and processed + + + + + Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch + + + and calculate the available position for the Participant to use + + + + + 7 + + + Select effectivePosition FOR UPDATE from DB for Payer + + + + participantPosition + + + + + 8 + + + Return effectivePosition (currentPosition and reservedPosition) from DB for Payer + + + + + 9 + + + Increment reservedValue to heldPosition + + + (reservedValue = reservedPosition + sumTransfersInBatch) + + + + + 10 + + + Persist reservedValue + + + + UPDATE + + + participantPosition + + + SET reservedValue += sumTransfersInBatch + + + + + 11 + + + Request position limits for Payer Participant + + + + FROM + + + participantLimit + + + WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' + + + AND participantLimit.participantId = payload.payerFsp + + + AND participantLimit.currencyId = payload.amount.currency + + + + + 12 + + + Return position limits + + + + + 13 + + + availablePosition + + + = + + + if settlement model delay is IMMEDIATE then: + + + settlementBalance + participantLimit(NetDebitCap) - effectivePosition + + + otherwise: + + + participantLimit(NetDebitCap) - effectivePosition + + + (same as = (settlementBalance?) + netDebitCap - currentPosition - reservedPosition) + + + + + For each transfer in the batch, validate the availablility of position to meet the transfer amount + + + this will be as per the position algorithm documented below + + + + + 14 + + + Validate availablePosition for each tranfser (see algorithm below) + + + Error code: + + + 4001 + + + + + 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED + + + 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch + + + 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position + + + 04: foreach transfer in reservedTransfers + + + 05: sumProcessed += transfer.amount // the total processed so far + + + (NEED TO UPDATE IN CODE) + + + 06: if availablePosition >= transfer.amount + + + 07: transfer.state = "RESERVED" + + + 08: availablePosition -= preparedTransfer.amount + + + 09: sumRESERVED += preparedTransfer.amount + + + 10: else + + + 11: preparedTransfer.state = "ABORTED" + + + 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + 13: end if + + + 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far + + + 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition + + + (NEED TO UPDATE IN CODE) + + + // the running down of the total reserved value at the begining of the batch. + + + 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } + + + 16: end foreach + + + + + Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch + + + (If there are any alarm limits, process those returning limits in which the threshold has been breached) + + + Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position + + + + + 15 + + + Assess any limit thresholds on the final position + + + adding to alarm list if triggered + + + + + 16 + + + Persist latest position + + + value + + + and + + + reservedValue + + + to DB for Payer + + + + UPDATE + + + participantPosition + + + SET value += sumRESERVED, + + + reservedValue -= sumTransfersInBatch + + + + + 17 + + + Bulk persist transferStateChange for all processedTransfers + + + + batch INSERT + + + transferStateChange + + + select for update from transfer table where transferId in ([transferBatch.transferId,...]) + + + build list of transferStateChanges from transferBatch + + + + + 18 + + + Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list + + + + + Effectively: + + + SET transferStateChangeId = processedTransfer.transferStateChangeId, + + + participantPositionId = preparedTransfer.participantPositionId, + + + value = preparedTransfer.positionValue, + + + reservedValue = preparedTransfer.positionReservedValue + + + + + 19 + + + Bulk persist the participant position change for all processedTransfers + + + + batch INSERT + + + participantPositionChange + + + + + 20 + + + Return a map of transferIds and their transferStateChanges + + + + + alt + + + [Calculate & Validate Latest Position Prepare (success)] + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: transfer, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 21 + + + Publish Notification event + + + Error code: + + + 2003 + + + + [Calculate & Validate Latest Position Prepare (failure)] + + + + + Validation failure! + + + + + Persist Transfer State (with transferState='ABORTED' on position check fail) + + + + + 22 + + + Request to persist transfer + + + Error code: + + + 2003 + + + + + transferStateChange.state = "ABORTED", + + + transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" + + + + + 23 + + + Persist transfer state + + + + transferStateChange + + + + + 24 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <ledgerName>, + + + to: <transferMessage.payerFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 4001, + + + "errorDescription": "Payer FSP insufficient liquidity", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 25 + + + Publish Notification (failure) event for Payer + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml new file mode 100644 index 000000000..fab0fbf38 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.plantuml @@ -0,0 +1,141 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.3.2. Fulfil Position Handler Consume v1.1 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +collections "Notifications-Topic" as TOPIC_NOTIFICATIONS +entity "Position Facade" as POS_FACADE +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Fulfil Position Handler Consume + POS_HANDLER -> POS_DAO: Request current state of transfer from DB \nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferState is 'RECEIVED-FULFIL')\nError code: 2001 + group Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + POS_HANDLER -> POS_FACADE: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION + activate POS_FACADE + POS_FACADE -> DB: Select participantPosition.value FOR UPDATE from DB for Payee + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Return participantPosition.value from DB for Payee + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persist latestPosition to DB for Payee + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persist transfer state and participant position change + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Return success + deactivate POS_FACADE + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: commit || reserve, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Transfer event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg new file mode 100644 index 000000000..de29ad2c9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg @@ -0,0 +1,345 @@ + + + + + + + + + + + 1.3.2. Fulfil Position Handler Consume v1.1 + + + + Central Service + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + Notifications-Topic + + + + + Notifications-Topic + + + Position DAO + + + + + Position DAO + + + + + Position Facade + + + + + Position Facade + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Position Handler Consume + + + + + 1 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 2 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + transferParticipant + + + + + 3 + + + Return current state of transfer from DB + + + + + 4 + + + Return current state of transfer from DB + + + + + 5 + + + Validate current state (transferState is 'RECEIVED-FULFIL') + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + + + 6 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + DB TRANSACTION + + + + + 7 + + + Select participantPosition.value FOR UPDATE from DB for Payee + + + + participantPosition + + + + + 8 + + + Return participantPosition.value from DB for Payee + + + + + 9 + + + latestPosition + + + = participantPosition.value - payload.amount.amount + + + + + 10 + + + Persist latestPosition to DB for Payee + + + + UPDATE + + + participantPosition + + + SET value = latestPosition + + + + + 11 + + + Persist transfer state and participant position change + + + + INSERT + + + transferStateChange + + + transferStateId = 'COMMITTED' + + + INSERT + + + participantPositionChange + + + SET participantPositionId = participantPosition.participantPositionId, + + + transferStateChangeId = transferStateChange.transferStateChangeId, + + + value = latestPosition, + + + reservedValue = participantPosition.reservedValue + + + createdDate = new Date() + + + + + 12 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: transfer, + + + action: commit || reserve, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 13 + + + Publish Transfer event + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml new file mode 100644 index 000000000..091fd6adf --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml @@ -0,0 +1,140 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.3.2. Fulfil Position Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +collections "Notifications-Topic" as TOPIC_NOTIFICATIONS +entity "Position Facade" as POS_FACADE +entity "Position DAO" as POS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant POS_FACADE + participant DB +end box + +' start flow +activate POS_HANDLER +group Fulfil Position Handler Consume + POS_HANDLER -> POS_DAO: Request current state of transfer from DB \nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferState is 'RECEIVED-FULFIL')\nError code: 2001 + group Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + POS_HANDLER -> POS_FACADE: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION + activate POS_FACADE + POS_FACADE -> DB: Select participantPosition.value FOR UPDATE from DB for Payee + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_FACADE: Return participantPosition.value from DB for Payee + deactivate DB + POS_FACADE <-> POS_FACADE: **latestPosition** = participantPosition.value - payload.amount.amount + POS_FACADE->DB: Persist latestPosition to DB for Payee + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_FACADE -> DB: Persist transfer state and participant position change + hnote over DB #lightyellow + INSERT **transferStateChange** transferStateId = 'COMMITTED' + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + deactivate POS_DAO + end + POS_FACADE --> POS_HANDLER: Return success + deactivate POS_FACADE + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: commit, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Transfer event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg new file mode 100644 index 000000000..89ddaffd3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg @@ -0,0 +1,345 @@ + + + + + + + + + + + 1.3.2. Fulfil Position Handler Consume + + + + Central Service + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + Notifications-Topic + + + + + Notifications-Topic + + + Position DAO + + + + + Position DAO + + + + + Position Facade + + + + + Position Facade + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Position Handler Consume + + + + + 1 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 2 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + transferParticipant + + + + + 3 + + + Return current state of transfer from DB + + + + + 4 + + + Return current state of transfer from DB + + + + + 5 + + + Validate current state (transferState is 'RECEIVED-FULFIL') + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer State (with transferState='COMMITTED' on position check pass) + + + + + 6 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + DB TRANSACTION + + + + + 7 + + + Select participantPosition.value FOR UPDATE from DB for Payee + + + + participantPosition + + + + + 8 + + + Return participantPosition.value from DB for Payee + + + + + 9 + + + latestPosition + + + = participantPosition.value - payload.amount.amount + + + + + 10 + + + Persist latestPosition to DB for Payee + + + + UPDATE + + + participantPosition + + + SET value = latestPosition + + + + + 11 + + + Persist transfer state and participant position change + + + + INSERT + + + transferStateChange + + + transferStateId = 'COMMITTED' + + + INSERT + + + participantPositionChange + + + SET participantPositionId = participantPosition.participantPositionId, + + + transferStateChangeId = transferStateChange.transferStateChangeId, + + + value = latestPosition, + + + reservedValue = participantPosition.reservedValue + + + createdDate = new Date() + + + + + 12 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: transfer, + + + action: commit, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 13 + + + Publish Transfer event + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml new file mode 100644 index 000000000..3301874a4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml @@ -0,0 +1,306 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + ------------- + ******'/ + +@startuml +' declate title +title 1.3.3. Abort Position Handler Consume + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +control "Position Handler" as POS_HANDLER +entity "Position DAO" as POS_DAO +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +database "Central Store" as DB + +box "Central Service" #LightYellow + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Abort Position Handler Consume + opt type == 'position' && action == 'timeout-reserved' + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + transferParticipant + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferStateChange.transferStateId == 'RESERVED_TIMEOUT')\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'EXPIRED_RESERVED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group DB TRANSACTION IMPLEMENTATION + activate POS_DAO + POS_DAO -> DB: Select participantPosition.value FOR UPDATE for payerCurrencyId + activate DB + hnote over DB #lightyellow + participantPosition + end note + DB --> POS_DAO: Return participantPosition + deactivate DB + POS_DAO <-> POS_DAO: **latestPosition** = participantPosition - payload.amount.amount + POS_DAO->DB: Persist latestPosition to DB for Payer + hnote over DB #lightyellow + UPDATE **participantPosition** + SET value = latestPosition + end note + activate DB + deactivate DB + POS_DAO -> DB: Persist participant position change and state change + hnote over DB #lightyellow + INSERT **transferStateChange** + VALUES (transferStateId) + + INSERT **participantPositionChange** + SET participantPositionId = participantPosition.participantPositionId, + transferStateChangeId = transferStateChange.transferStateChangeId, + value = latestPosition, + reservedValue = participantPosition.reservedValue + createdDate = new Date() + end note + activate DB + deactivate DB + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3300, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + opt type == 'position' && (action IN ['reject', 'abort']) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR'])\nError code: 2001 + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + alt action == 'reject' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: reject, + createdAt: , + state: { + status: "success", + code: 0, + description: "action successful" + } + } + } + } + end note + else action == 'abort' + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + end + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + + ' TODO: We do not see how this scenario will be triggered + opt type == 'position' && action == 'fail' (Unable to currently trigger this scenario) + POS_HANDLER -> POS_DAO: Request current state of transfer from DB\nError code: 2003 + activate POS_DAO + POS_DAO -> DB: Retrieve current state of transfer from DB + activate DB + hnote over DB #lightyellow + transferStateChange + end note + DB --> POS_DAO: Return current state of transfer from DB + deactivate DB + POS_DAO --> POS_HANDLER: Return current state of transfer from DB + deactivate POS_DAO + POS_HANDLER <-> POS_HANDLER: Validate current state (transferStateChange.transferStateId == 'FAILED') + + group Persist Position change and Transfer state + POS_HANDLER -> POS_HANDLER: **transferStateId** = 'FAILED' + POS_HANDLER -> POS_DAO: Request to persist latest position and state to DB\nError code: 2003 + group Refer to DB TRANSACTION IMPLEMENTATION above + activate POS_DAO + POS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + participantPosition + transferStateChange + participantPositionChange + end note + end + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + note right of POS_HANDLER #yellow + Message: { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 3100, + "errorDescription": "Transfer failed", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: abort, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg new file mode 100644 index 000000000..57c541a8c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.svg @@ -0,0 +1,915 @@ + + + + + + + + + + + 1.3.3. Abort Position Handler Consume + + + + Central Service + + + + + + + + + + + + + + + Position Handler + + + + + Position Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Position DAO + + + + + Position DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Abort Position Handler Consume + + + + + opt + + + [type == 'position' && action == 'timeout-reserved'] + + + + + 1 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 2 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + transferParticipant + + + + + 3 + + + Return current state of transfer from DB + + + + + 4 + + + Return current state of transfer from DB + + + + + 5 + + + Validate current state (transferStateChange.transferStateId == 'RESERVED_TIMEOUT') + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer state + + + + + 6 + + + transferStateId + + + = 'EXPIRED_RESERVED' + + + + + 7 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + DB TRANSACTION IMPLEMENTATION + + + + + 8 + + + Select participantPosition.value FOR UPDATE for payerCurrencyId + + + + participantPosition + + + + + 9 + + + Return participantPosition + + + + + 10 + + + latestPosition + + + = participantPosition - payload.amount.amount + + + + + 11 + + + Persist latestPosition to DB for Payer + + + + UPDATE + + + participantPosition + + + SET value = latestPosition + + + + + 12 + + + Persist participant position change and state change + + + + INSERT + + + transferStateChange + + + VALUES (transferStateId) + + + INSERT + + + participantPositionChange + + + SET participantPositionId = participantPosition.participantPositionId, + + + transferStateChangeId = transferStateChange.transferStateChangeId, + + + value = latestPosition, + + + reservedValue = participantPosition.reservedValue + + + createdDate = new Date() + + + + + 13 + + + Return success + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3300, + + + "errorDescription": "Transfer expired", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 14 + + + Publish Notification event + + + Error code: + + + 2003 + + + + + opt + + + [type == 'position' && (action IN ['reject', 'abort'])] + + + + + 15 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 16 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + + + 17 + + + Return current state of transfer from DB + + + + + 18 + + + Return current state of transfer from DB + + + + + 19 + + + Validate current state (transferStateChange.transferStateId IN ['RECEIVED_REJECT', 'RECEIVED_ERROR']) + + + Error code: + + + 2001 + + + + + Persist Position change and Transfer state + + + + + 20 + + + transferStateId + + + = (action == 'reject' ? 'ABORTED_REJECTED' : 'ABORTED_ERROR' ) + + + + + 21 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + Refer to + + + DB TRANSACTION IMPLEMENTATION + + + above + + + + + 22 + + + Persist to database + + + + participantPosition + + + transferStateChange + + + participantPositionChange + + + + + 23 + + + Return success + + + + + alt + + + [action == 'reject'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0, + + + description: "action successful" + + + } + + + } + + + } + + + } + + + + [action == 'abort'] + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <payload.errorInformation.errorCode || 5000> + + + description: <payload.errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 24 + + + Publish Notification event + + + Error code: + + + 2003 + + + + + opt + + + [type == 'position' && action == 'fail' (Unable to currently trigger this scenario)] + + + + + 25 + + + Request current state of transfer from DB + + + Error code: + + + 2003 + + + + + 26 + + + Retrieve current state of transfer from DB + + + + transferStateChange + + + + + 27 + + + Return current state of transfer from DB + + + + + 28 + + + Return current state of transfer from DB + + + + + 29 + + + Validate current state (transferStateChange.transferStateId == 'FAILED') + + + + + Persist Position change and Transfer state + + + + + 30 + + + transferStateId + + + = 'FAILED' + + + + + 31 + + + Request to persist latest position and state to DB + + + Error code: + + + 2003 + + + + + Refer to + + + DB TRANSACTION IMPLEMENTATION + + + above + + + + + 32 + + + Persist to database + + + + participantPosition + + + transferStateChange + + + participantPositionChange + + + + + 33 + + + Return success + + + + + Message: { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3100, + + + "errorDescription": "Transfer failed", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 34 + + + Publish Notification event + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml new file mode 100644 index 000000000..5b530af7b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml @@ -0,0 +1,163 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.0. DFSP1 sends a Prepare Transfer request to DFSP2 + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate PREP_HANDLER +activate POS_HANDLER +group DFSP1 sends a Prepare Transfer request to DFSP2 + note right of DFSP1 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "transferId": , + "payeeFsp": dfsp2, + "payerFsp": dfsp1, + "amount": { + "currency": "AED", + "amount": "string" + }, + "ilpPacket": "string", + "condition": "string", + "expiration": "string", + "extensionList": { + "extension": [ + { + "key": "string", + "value": "string" + } + ] + } + } + end note + DFSP1 ->> MLAPI: POST - /transfers + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payer\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: prepare, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_TRANSFER_PREPARE: Route & Publish Prepare event for Payer\nError code: 2003 + activate TOPIC_TRANSFER_PREPARE + TOPIC_TRANSFER_PREPARE <-> TOPIC_TRANSFER_PREPARE: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_TRANSFER_PREPARE --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_TRANSFER_PREPARE + MLAPI -->> DFSP1: Respond HTTP - 202 (Accepted) + deactivate MLAPI + ||| + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message + ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION : Prepare Handler Consume\n + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, POS_HANDLER : Position Handler Consume\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP2, TOPIC_NOTIFICATIONS : Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + ||| +end +deactivate POS_HANDLER +deactivate PREP_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg new file mode 100644 index 000000000..597c20f74 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.svg @@ -0,0 +1,455 @@ + + + + + + + + + + + 1.1.0. DFSP1 sends a Prepare Transfer request to DFSP2 + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + topic-transfer-prepare + + + + + topic-transfer-prepare + + + Prepare Event Handler + + + + + Prepare Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP1 sends a Prepare Transfer request to DFSP2 + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "transferId": <uuid>, + + + "payeeFsp": dfsp2, + + + "payerFsp": dfsp1, + + + "amount": { + + + "currency": "AED", + + + "amount": "string" + + + }, + + + "ilpPacket": "string", + + + "condition": "string", + + + "expiration": "string", + + + "extensionList": { + + + "extension": [ + + + { + + + "key": "string", + + + "value": "string" + + + } + + + ] + + + } + + + } + + + + 1 + + + POST - /transfers + + + + + 2 + + + Validate incoming token and originator matching Payer + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: prepare, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 3 + + + Route & Publish Prepare event for Payer + + + Error code: + + + 2003 + + + + + 4 + + + Ensure event is replicated as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 5 + + + Respond replication acknowledgements have been received + + + + + 6 + + + Respond HTTP - 202 (Accepted) + + + + + 7 + + + Consume message + + + + + ref + + + Prepare Handler Consume + + + + + 8 + + + Produce message + + + + + 9 + + + Consume message + + + + + ref + + + Position Handler Consume + + + + + 10 + + + Produce message + + + + + 11 + + + Consume message + + + + + ref + + + Send notification to Participant (Payee) + + + + + 12 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml new file mode 100644 index 000000000..4df26eef9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml @@ -0,0 +1,257 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Shashikant Hirugade + * Georgi Georgiev + * Rajiv Mothilal + * Samuel Kummary + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.1.a. Prepare Handler Consume (single message) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event message + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + + break + group Validate Event + PREP_HANDLER <-> PREP_HANDLER: Validate event - Rule: type == 'prepare' && action == 'prepare'\nError codes: 2001 + end + end + + group Persist Event Information + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publish event information + ref over PREP_HANDLER, TOPIC_EVENTS: Event Handler Consume\n + ||| + end + + group Validate Prepare Transfer + PREP_HANDLER <-> PREP_HANDLER: Schema validation of the incoming message + PREP_HANDLER <-> PREP_HANDLER: Verify the message's signature (to be confirmed in future requirement) + note right of PREP_HANDLER #lightgrey + The above validation steps are already handled by + the ML-Adapter for the open source implementation. + It may need to be added in future for custom adapters. + end note + + group Validate Duplicate Check + ||| + PREP_HANDLER -> DB: Request Duplicate Check + ref over PREP_HANDLER, DB: Request Duplicate Check\n + DB --> PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + end + + alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE + break + PREP_HANDLER -> PREP_HANDLER: stateRecord = await getTransferState(transferId) + alt endStateList.includes(stateRecord.transferStateId) + ||| + ref over PREP_HANDLER, TOPIC_NOTIFICATIONS: getTransfer callback\n + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else + note right of PREP_HANDLER #lightgrey + Ignore - resend in progress + end note + end + end + else hasDuplicateId == TRUE && hasDuplicateHash == FALSE + note right of PREP_HANDLER #lightgrey + Validate Prepare Transfer (failure) - Modified Request + end note + else hasDuplicateId == FALSE + group Validate Payer + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer\nError codes: 3202 + end + group Validate Payee + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + participantCurrency + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee\nError codes: 3203 + end + + alt Validate Prepare Transfer (success) + group Persist Transfer State (with transferState='RECEIVED-PREPARE') + PREP_HANDLER -> POS_DAO: Request to persist transfer\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + else Validate Prepare Transfer (failure) + group Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + PREP_HANDLER -> POS_DAO: Request to persist transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transfer + transferParticipant + transferStateChange + transferExtension + transferError + ilpPacket + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + end + end + end + + alt Validate Prepare Transfer (success) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer\nError codes: 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Prepare Transfer (failure) + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": + "errorDescription": "", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 2003 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end +end +deactivate PREP_HANDLER +@enduml + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg new file mode 100644 index 000000000..65895c97b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.svg @@ -0,0 +1,738 @@ + + + + + + + + + + + 1.1.1.a. Prepare Handler Consume (single message) + + + + Central Service + + + + + + + + + + + + + + + + + + + + topic-transfer-prepare + + + + + topic-transfer-prepare + + + Prepare Event Handler + + + + + Prepare Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + Position DAO + + + + + Position DAO + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Prepare Handler Consume + + + + + 1 + + + Consume Prepare event message + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'prepare' && action == 'prepare' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate Prepare Transfer + + + + + 4 + + + Schema validation of the incoming message + + + + + 5 + + + Verify the message's signature (to be confirmed in future requirement) + + + + + The above validation steps are already handled by + + + the ML-Adapter for the open source implementation. + + + It may need to be added in future for custom adapters. + + + + + Validate Duplicate Check + + + + + 6 + + + Request Duplicate Check + + + + + ref + + + Request Duplicate Check + + + + + 7 + + + Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } + + + + + alt + + + [hasDuplicateId == TRUE && hasDuplicateHash == TRUE] + + + + + break + + + + + 8 + + + stateRecord = await getTransferState(transferId) + + + + + alt + + + [endStateList.includes(stateRecord.transferStateId)] + + + + + ref + + + getTransfer callback + + + + + 9 + + + Produce message + + + + + + Ignore - resend in progress + + + + [hasDuplicateId == TRUE && hasDuplicateHash == FALSE] + + + + + Validate Prepare Transfer (failure) - Modified Request + + + + [hasDuplicateId == FALSE] + + + + + Validate Payer + + + + + 10 + + + Request to retrieve Payer Participant details (if it exists) + + + + + 11 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 12 + + + Return Participant details if it exists + + + + + 13 + + + Return Participant details if it exists + + + + + 14 + + + Validate Payer + + + Error codes: + + + 3202 + + + + + Validate Payee + + + + + 15 + + + Request to retrieve Payee Participant details (if it exists) + + + + + 16 + + + Request Participant details + + + + participant + + + participantCurrency + + + + + 17 + + + Return Participant details if it exists + + + + + 18 + + + Return Participant details if it exists + + + + + 19 + + + Validate Payee + + + Error codes: + + + 3203 + + + + + alt + + + [Validate Prepare Transfer (success)] + + + + + Persist Transfer State (with transferState='RECEIVED-PREPARE') + + + + + 20 + + + Request to persist transfer + + + Error codes: + + + 2003 + + + + + 21 + + + Persist transfer + + + + transfer + + + transferParticipant + + + transferStateChange + + + transferExtension + + + ilpPacket + + + + + 22 + + + Return success + + + + [Validate Prepare Transfer (failure)] + + + + + Persist Transfer State (with transferState='INVALID') (Introducing a new status INVALID to mark these entries) + + + + + 23 + + + Request to persist transfer + + + (when Payee/Payer/crypto-condition validation fails) + + + Error codes: + + + 2003 + + + + + 24 + + + Persist transfer + + + + transfer + + + transferParticipant + + + transferStateChange + + + transferExtension + + + transferError + + + ilpPacket + + + + + 25 + + + Return success + + + + + alt + + + [Validate Prepare Transfer (success)] + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 26 + + + Route & Publish Position event for Payer + + + Error codes: + + + 2003 + + + + [Validate Prepare Transfer (failure)] + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <ledgerName>, + + + to: <transferMessage.payerFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": <possible codes: [2003, 3100, 3105, 3106, 3202, 3203, 3300, 3301]> + + + "errorDescription": "<refer to section 35.1.3 for description>", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 27 + + + Publish Notification (failure) event for Payer + + + Error codes: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml new file mode 100644 index 000000000..1b01ef9c5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml @@ -0,0 +1,186 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.1.b. Prepare Handler Consume (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE +control "Prepare Event Handler" as PREP_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Position DAO" as POS_DAO +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_PREPARE + participant PREP_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate PREP_HANDLER +group Prepare Handler Consume + note over TOPIC_TRANSFER_PREPARE #LightSalmon + This flow has not been implemented + end note + + TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event batch of messages for Payer + activate TOPIC_TRANSFER_PREPARE + deactivate TOPIC_TRANSFER_PREPARE + group Persist Event Information + ||| + PREP_HANDLER -> TOPIC_EVENTS: Publish event information + ref over PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + group Fetch batch Payer information + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payer Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payer + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYER + end + + group Fetch batch Payee information + PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payee Participant details (if it exists) + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request Participant details + hnote over DB #lightyellow + participant + end note + activate DB + PARTICIPANT_DAO <-- DB: Return Participant details if it exists + deactivate DB + PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists + deactivate PARTICIPANT_DAO + PREP_HANDLER <-> PREP_HANDLER: Validate Payee + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYEE + end + + group Fetch batch of transfers + PREP_HANDLER -> POS_DAO: Request to retrieve batch of Transfers (if it exists) + activate POS_DAO + POS_DAO -> DB: Request batch of Transfers + hnote over DB #lightyellow + transfer + end note + activate DB + POS_DAO <-- DB: Return batch of Transfers (if it exists) + deactivate DB + POS_DAO --> PREP_HANDLER: Return batch of Transfer (if it exists) + deactivate POS_DAO + PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_TRANSFERS + end + + loop for each message in batch + + group Validate Prepare Transfer + group Validate Payer + PREP_HANDLER <-> PREP_HANDLER: Validate Payer against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYER + end + group Validate Payee + PREP_HANDLER <-> PREP_HANDLER: Validate Payee against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYEE + end + group Duplicate check + PREP_HANDLER <-> PREP_HANDLER: Validate duplicate Check against in-memory var $LIST_TRANSFERS + end + PREP_HANDLER <-> PREP_HANDLER: Validate amount + PREP_HANDLER <-> PREP_HANDLER: Validate crypto-condition + PREP_HANDLER <-> PREP_HANDLER: Validate message signature (to be confirmed in future requirement) + end + + group Persist Transfer State (with transferState='RECEIVED' on validation pass) + PREP_HANDLER -> POS_DAO: Request to persist transfer + activate POS_DAO + POS_DAO -> DB: Persist transfer + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> PREP_HANDLER: Return success + deactivate POS_DAO + end + + note right of PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + end +end +deactivate PREP_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg new file mode 100644 index 000000000..13489faa8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.svg @@ -0,0 +1,497 @@ + + + + + + + + + + + 1.1.1.b. Prepare Handler Consume (batch messages) + + + + Central Service + + + + + + + + + + + topic-transfer-prepare + + + + + topic-transfer-prepare + + + Prepare Event Handler + + + + + Prepare Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + Position DAO + + + + + Position DAO + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Prepare Handler Consume + + + + + This flow has not been implemented + + + + + 1 + + + Consume Prepare event batch of messages for Payer + + + + + Persist Event Information + + + + + 2 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Fetch batch Payer information + + + + + 3 + + + Request to retrieve batch of Payer Participant details (if it exists) + + + + + 4 + + + Request Participant details + + + + participant + + + + + 5 + + + Return Participant details if it exists + + + + + 6 + + + Return Participant details if it exists + + + + + 7 + + + Validate Payer + + + + + 8 + + + store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYER + + + + + Fetch batch Payee information + + + + + 9 + + + Request to retrieve batch of Payee Participant details (if it exists) + + + + + 10 + + + Request Participant details + + + + participant + + + + + 11 + + + Return Participant details if it exists + + + + + 12 + + + Return Participant details if it exists + + + + + 13 + + + Validate Payee + + + + + 14 + + + store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYEE + + + + + Fetch batch of transfers + + + + + 15 + + + Request to retrieve batch of Transfers (if it exists) + + + + + 16 + + + Request batch of Transfers + + + + transfer + + + + + 17 + + + Return batch of Transfers (if it exists) + + + + + 18 + + + Return batch of Transfer (if it exists) + + + + + 19 + + + store result set in var: $LIST_TRANSFERS + + + + + loop + + + [for each message in batch] + + + + + Validate Prepare Transfer + + + + + Validate Payer + + + + + 20 + + + Validate Payer against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYER + + + + + Validate Payee + + + + + 21 + + + Validate Payee against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYEE + + + + + Duplicate check + + + + + 22 + + + Validate duplicate Check against in-memory var $LIST_TRANSFERS + + + + + 23 + + + Validate amount + + + + + 24 + + + Validate crypto-condition + + + + + 25 + + + Validate message signature (to be confirmed in future requirement) + + + + + Persist Transfer State (with transferState='RECEIVED' on validation pass) + + + + + 26 + + + Request to persist transfer + + + + + 27 + + + Persist transfer + + + + transferStateChange + + + + + 28 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 29 + + + Route & Publish Position event for Payer + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml new file mode 100644 index 000000000..abec38aa9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml @@ -0,0 +1,249 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.2.a. Position Handler Consume (single message) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +entity "Position DAO" as POS_DAO +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant PARTICIPANT_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event message for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + break + group Validate Event + POS_HANDLER <-> POS_HANDLER: Validate event - Rule: type == 'position' && action == 'prepare' + end + end + + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + alt Calulate & Validate Latest Position (success) + group Calculate position and persist change + POS_HANDLER -> POS_DAO: Request latest position from DB for Payer + activate POS_DAO + POS_DAO -> DB: Retrieve latest position from DB for Payer + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> POS_DAO: Retrieve latest position from DB for Payer + deactivate DB + POS_DAO --> POS_HANDLER: Return latest position + deactivate POS_DAO + + POS_HANDLER -> PARTICIPANT_DAO: Request position limits for Payer Participant + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Return position limits + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Return position limits + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculate latest position (lpos) for prepare + POS_HANDLER <-> POS_HANDLER: Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + POS_HANDLER -> POS_DAO: Request to persist latest position for Payer + activate POS_DAO + POS_DAO -> DB: Persist latest position to DB for Payer + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + + group Persist Transfer State (with transferState='RESERVED' on position check pass) + POS_HANDLER -> POS_DAO: Request to persist transfer + activate POS_DAO + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event to Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + else Calculate & Validate Latest Position (failure) + group Calculate position and persist change + POS_HANDLER -> POS_DAO: Request latest position from DB for Payer + activate POS_DAO + POS_DAO -> DB: Retrieve latest position from DB for Payer + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> POS_DAO: Retrieve latest position from DB for Payer + deactivate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return latest position + deactivate POS_DAO + + POS_HANDLER -> PARTICIPANT_DAO: Request position limits for Payer Participant + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Request position limits for Payer Participant + activate DB + hnote over DB #lightyellow + participant + participantLimit + end note + DB --> PARTICIPANT_DAO: Return position limits + deactivate DB + deactivate DB + PARTICIPANT_DAO --> POS_HANDLER: Return position limits + deactivate PARTICIPANT_DAO + + POS_HANDLER <-> POS_HANDLER: Calculate latest position (lpos) for prepare + POS_HANDLER <-> POS_HANDLER: Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + note right of POS_HANDLER #red: Validation failure! + end + + group Persist Transfer State (with transferState='ABORTED' on position check pass) + POS_HANDLER -> POS_DAO: Request to persist transfer + activate POS_DAO + POS_DAO -> DB: Persist transfer state + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: { + "errorInformation": { + "errorCode": 4001, + "errorDescription": "Payer FSP insufficient liquidity", + "extensionList": + } + }, + metadata: { + event: { + id: , + responseTo: , + type: notification, + action: prepare, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + deactivate POS_HANDLER + end +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg new file mode 100644 index 000000000..2a0857acf --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.svg @@ -0,0 +1,633 @@ + + + + + + + + + + + 1.1.2.a. Position Handler Consume (single message) + + + + Central Service + + + + + + + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + Position DAO + + + + + Position DAO + + + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Position Handler Consume + + + + + 1 + + + Consume Position event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'position' && action == 'prepare' + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + alt + + + [Calulate & Validate Latest Position (success)] + + + + + Calculate position and persist change + + + + + 4 + + + Request latest position from DB for Payer + + + + + 5 + + + Retrieve latest position from DB for Payer + + + + transferPosition + + + + + 6 + + + Retrieve latest position from DB for Payer + + + + + 7 + + + Return latest position + + + + + 8 + + + Request position limits for Payer Participant + + + + + 9 + + + Request position limits for Payer Participant + + + + participant + + + participantLimit + + + + + 10 + + + Return position limits + + + + + 11 + + + Return position limits + + + + + 12 + + + Calculate latest position (lpos) for prepare + + + + + 13 + + + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + + + 14 + + + Request to persist latest position for Payer + + + + + 15 + + + Persist latest position to DB for Payer + + + + transferPosition + + + + + 16 + + + Return success + + + + + Persist Transfer State (with transferState='RESERVED' on position check pass) + + + + + 17 + + + Request to persist transfer + + + + + 18 + + + Persist transfer state + + + + transferStateChange + + + + + 19 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: transfer, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 20 + + + Publish Notification event to Payee + + + + [Calculate & Validate Latest Position (failure)] + + + + + Calculate position and persist change + + + + + 21 + + + Request latest position from DB for Payer + + + + + 22 + + + Retrieve latest position from DB for Payer + + + + transferPosition + + + + + 23 + + + Retrieve latest position from DB for Payer + + + + + 24 + + + Return latest position + + + + + 25 + + + Request position limits for Payer Participant + + + + + 26 + + + Request position limits for Payer Participant + + + + participant + + + participantLimit + + + + + 27 + + + Return position limits + + + + + 28 + + + Return position limits + + + + + 29 + + + Calculate latest position (lpos) for prepare + + + + + 30 + + + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + + + Validation failure! + + + + + Persist Transfer State (with transferState='ABORTED' on position check pass) + + + + + 31 + + + Request to persist transfer + + + + + 32 + + + Persist transfer state + + + + transferStateChange + + + + + 33 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <ledgerName>, + + + to: <transferMessage.payerFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: { + + + "errorInformation": { + + + "errorCode": 4001, + + + "errorDescription": "Payer FSP insufficient liquidity", + + + "extensionList": <transferMessage.extensionList> + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: notification, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 34 + + + Publish Notification (failure) event for Payer + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml new file mode 100644 index 000000000..9e9bc1ff9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml @@ -0,0 +1,148 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.2.b. Position Handler Consume (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Transfer-Topic" as TOPIC_TRANSFERS +entity "Position DAO" as POS_DAO +entity "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_TRANSFERS + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATIONS + participant POS_DAO + participant TRANS_DAO + participant DB +end box + +' start flow +activate POS_HANDLER +group Position Handler Consume + note over TOPIC_TRANSFER_POSITION #LightSalmon + This flow has not been implemented + end note + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event batch of messages for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + + group Persist Event Information + ||| + POS_HANDLER -> TOPIC_EVENTS: Publish event information + ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n + ||| + end + + loop for each message in batch + group Calculate position and persist change + POS_HANDLER -> POS_DAO: Request latest position from DB for Payer + activate POS_DAO + POS_DAO -> DB: Retrieve latest position from DB for Payer + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return latest position + deactivate POS_DAO + + POS_HANDLER <-> POS_HANDLER: Calculate latest position (lpos) by incrementing transfer for prepare + POS_HANDLER <-> POS_HANDLER: Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + POS_HANDLER -> POS_DAO: Request to persist latest position for Payer + activate POS_DAO + POS_DAO -> DB: Persist latest position to DB for Payer + hnote over DB #lightyellow + transferPosition + end note + activate DB + deactivate DB + POS_DAO --> POS_HANDLER: Return success + deactivate POS_DAO + end + group Persist Transfer State (with transferState='RESERVED' on position check pass) + POS_HANDLER -> TRANS_DAO: Request to persist batch transfer + activate TRANS_DAO + TRANS_DAO -> DB: Persist batch transfer + hnote over DB #lightyellow + transferStateChange + end note + activate DB + deactivate DB + TRANS_DAO --> POS_HANDLER: Return success + deactivate TRANS_DAO + end + note right of POS_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: transfer, + action: prepare, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + POS_HANDLER -> TOPIC_TRANSFERS: Publish Transfer event + activate TOPIC_TRANSFERS + deactivate TOPIC_TRANSFERS + end +end +deactivate POS_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg new file mode 100644 index 000000000..3b1dd63b4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + 1.1.2.b. Position Handler Consume (batch messages) + + + + Central Service + + + + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Transfer-Topic + + + + + Transfer-Topic + + + Event-Topic + + + + + Event-Topic + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Position DAO + + + + + Position DAO + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Position Handler Consume + + + + + This flow has not been implemented + + + + + 1 + + + Consume Position event batch of messages for Payer + + + + + Persist Event Information + + + + + 2 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + loop + + + [for each message in batch] + + + + + Calculate position and persist change + + + + + 3 + + + Request latest position from DB for Payer + + + + + 4 + + + Retrieve latest position from DB for Payer + + + + transferPosition + + + + + 5 + + + Return latest position + + + + + 6 + + + Calculate latest position (lpos) by incrementing transfer for prepare + + + + + 7 + + + Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap + + + + + 8 + + + Request to persist latest position for Payer + + + + + 9 + + + Persist latest position to DB for Payer + + + + transferPosition + + + + + 10 + + + Return success + + + + + Persist Transfer State (with transferState='RESERVED' on position check pass) + + + + + 11 + + + Request to persist batch transfer + + + + + 12 + + + Persist batch transfer + + + + transferStateChange + + + + + 13 + + + Return success + + + + + Message: + + + { + + + id: <transferMessage.transferId> + + + from: <transferMessage.payerFsp>, + + + to: <transferMessage.payeeFsp>, + + + type: application/json + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: transfer, + + + action: prepare, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 14 + + + Publish Transfer event + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml new file mode 100644 index 000000000..fc35e5b8b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.plantuml @@ -0,0 +1,123 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Shashikant Hirugade + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) v1.1 + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP\nParticipant" as PAYEE_DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "Event-Topic" as TOPIC_EVENTS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee)" #lightGray + participant PAYEE_DFSP +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participants + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume Notification event + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + group Persist Event Information + NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publish event information + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + TOPIC_EVENTS --> CSAPI: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + note right of NOTIFY_HANDLER #lightgray + The endpoint details are cached, when the cache + expires, the details are fetched again + end note + NOTIFY_HANDLER -> CSAPI: Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints\nError code: 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Fetch Endpoint details for Participant\nError code: 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Endpoint details for Participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Retrieved Endpoint details for Participant + deactivate DB + PARTICIPANT_DAO --> CSAPI: Return Endpoint details for Participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Return Endpoint details for Participant\nError codes: 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification with Prepare/fulfil result/error to \nPayer DFSP to specified Endpoint - PUT \nError code: 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt event.action === 'reserve' + alt event.status === 'success' + NOTIFY_HANDLER -> PAYEE_DFSP: Notification to with succesful fulfil result (committed) to Payee DFSP to specified Endpoint - PATCH \nError code: 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP: HTTP 200 OK + end + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg new file mode 100644 index 000000000..7461e0ab9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg @@ -0,0 +1,326 @@ + + + + + + + + + + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) v1.1 + + + + Financial Service Provider (Payer) + + + + ML API Adapter Service + + + + Central Service + + + + Financial Service Provider (Payee) + + + + + + + + Payer DFSP + + + Participant + + + + + Payer DFSP + + + Participant + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + Payee DFSP + + + Participant + + + + + Payee DFSP + + + Participant + + + + + + + + Send notification to Participants + + + + + 1 + + + Consume Notification event + + + + + Persist Event Information + + + + + 2 + + + Request to persist event information - POST - /events + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + 4 + + + Return success + + + + + 5 + + + Return success + + + + + The endpoint details are cached, when the cache + + + expires, the details are fetched again + + + + + 6 + + + Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints + + + Error code: + + + 2003 + + + + + 7 + + + Fetch Endpoint details for Participant + + + Error code: + + + 2003 + + + + + 8 + + + Fetch Endpoint details for Participant + + + + participantEndpoint + + + + + 9 + + + Retrieved Endpoint details for Participant + + + + + 10 + + + Return Endpoint details for Participant + + + + + 11 + + + Return Endpoint details for Participant + + + Error codes: + + + 3202, 3203 + + + + + 12 + + + Notification with Prepare/fulfil result/error to + + + Payer DFSP to specified Endpoint - PUT + + + Error code: + + + 1001 + + + + + 13 + + + HTTP 200 OK + + + + + alt + + + [event.action === 'reserve'] + + + + + alt + + + [event.status === 'success'] + + + + + 14 + + + Notification to with succesful fulfil result (committed) to Payee DFSP to specified Endpoint - PATCH + + + Error code: + + + 1001 + + + + + 15 + + + HTTP 200 OK + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml new file mode 100644 index 000000000..b96130bf1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml @@ -0,0 +1,120 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) + +autonumber + +' Actor Keys: +' actor - Payer DFSP, Payee DFSP +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "Payer DFSP\nParticipant" as PAYER_DFSP +actor "Payee DFSP\nParticipant" as PAYEE_DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "Event-Topic" as TOPIC_EVENTS +entity "Participant DAO" as PARTICIPANT_DAO +database "Central Store" as DB + +box "Financial Service Provider (Payer)" #lightGray + participant PAYER_DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant PARTICIPANT_DAO + participant DB +end box + +box "Financial Service Provider (Payee)" #lightGray + participant PAYEE_DFSP +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participants + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume Notification event + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + + group Persist Event Information + NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publish event information + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + TOPIC_EVENTS --> CSAPI: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + note right of NOTIFY_HANDLER #lightgray + The endpoint details are cached, when the cache + expires, the details are fetched again + end note + NOTIFY_HANDLER -> CSAPI: Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints\nError code: 2003 + + activate CSAPI + CSAPI -> PARTICIPANT_DAO: Fetch Endpoint details for Participant\nError code: 2003 + activate PARTICIPANT_DAO + PARTICIPANT_DAO -> DB: Fetch Endpoint details for Participant + activate DB + hnote over DB #lightyellow + participantEndpoint + end note + DB -> PARTICIPANT_DAO: Retrieved Endpoint details for Participant + deactivate DB + PARTICIPANT_DAO --> CSAPI: Return Endpoint details for Participant + deactivate PARTICIPANT_DAO + CSAPI --> NOTIFY_HANDLER: Return Endpoint details for Participant\nError codes: 3202, 3203 + deactivate CSAPI + NOTIFY_HANDLER -> PAYER_DFSP: Notification with Prepare/fulfil result/error to \nPayer DFSP to specified Endpoint - PUT \nError code: 1001 + NOTIFY_HANDLER <-- PAYER_DFSP: HTTP 200 OK + alt Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE === true + NOTIFY_HANDLER -> PAYEE_DFSP: Notification to with fulfil result (committed/aborted/rejected) to Payee DFSP to specified Endpoint - PUT \nError code: 1001 + ||| + NOTIFY_HANDLER <-- PAYEE_DFSP: HTTP 200 OK + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg new file mode 100644 index 000000000..de654e47e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + 1.1.4.a. Send notification to Participant (Payer/Payee) (single message) + + + + Financial Service Provider (Payer) + + + + ML API Adapter Service + + + + Central Service + + + + Financial Service Provider (Payee) + + + + + + + Payer DFSP + + + Participant + + + + + Payer DFSP + + + Participant + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + Participant DAO + + + + + Participant DAO + + + + + Central Store + + + + + Central Store + + + + + Payee DFSP + + + Participant + + + + + Payee DFSP + + + Participant + + + + + + + + Send notification to Participants + + + + + 1 + + + Consume Notification event + + + + + Persist Event Information + + + + + 2 + + + Request to persist event information - POST - /events + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + 4 + + + Return success + + + + + 5 + + + Return success + + + + + The endpoint details are cached, when the cache + + + expires, the details are fetched again + + + + + 6 + + + Request Endpoint details for Participant - GET - /participants/{{fsp}}/endpoints + + + Error code: + + + 2003 + + + + + 7 + + + Fetch Endpoint details for Participant + + + Error code: + + + 2003 + + + + + 8 + + + Fetch Endpoint details for Participant + + + + participantEndpoint + + + + + 9 + + + Retrieved Endpoint details for Participant + + + + + 10 + + + Return Endpoint details for Participant + + + + + 11 + + + Return Endpoint details for Participant + + + Error codes: + + + 3202, 3203 + + + + + 12 + + + Notification with Prepare/fulfil result/error to + + + Payer DFSP to specified Endpoint - PUT + + + Error code: + + + 1001 + + + + + 13 + + + HTTP 200 OK + + + + + alt + + + [Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE === true] + + + + + 14 + + + Notification to with fulfil result (committed/aborted/rejected) to Payee DFSP to specified Endpoint - PUT + + + Error code: + + + 1001 + + + + + 15 + + + HTTP 200 OK + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml new file mode 100644 index 000000000..0c5c5fb5d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml @@ -0,0 +1,108 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Miguel de Barros + -------------- + ******'/ + +@startuml +' declate title +title 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP(n)\nParticipant" as DFSP +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +collections "Event-Topic" as TOPIC_EVENTS +entity "Notification DAO" as NOTIFY_DAO +database "Central Store" as DB + +box "Financial Service Provider" #lightGray + participant DFSP +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow +participant TOPIC_NOTIFICATIONS + participant CSAPI + participant TOPIC_EVENTS + participant EVENT_DAO + participant NOTIFY_DAO + participant DB +end box + +' start flow +activate NOTIFY_HANDLER +group Send notification to Participant + note over DFSP #LightSalmon + This flow has not been implemented + end note + + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: **Consume Notifications event batch of messages for Participant** + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + loop for each message in batch + group Persist Event Information + NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events + activate CSAPI + CSAPI -> TOPIC_EVENTS: Publish event information + activate TOPIC_EVENTS + ||| + ref over TOPIC_EVENTS : Event Handler Consume\n + ||| + TOPIC_EVENTS --> CSAPI: Return success + deactivate TOPIC_EVENTS + CSAPI --> NOTIFY_HANDLER: Return success + deactivate CSAPI + end + NOTIFY_HANDLER -> CSAPI: Request Notifications details for Participant - GET - /notifications/DFPS(n) + activate CSAPI + CSAPI -> NOTIFY_DAO: Fetch Notifications details for Participant + activate NOTIFY_DAO + NOTIFY_DAO -> DB: Fetch Notifications details for Participant + activate DB + hnote over DB #lightyellow + transferPosition + end note + DB --> NOTIFY_DAO: Retrieved Notification details for Participant + 'deactivate DB + NOTIFY_DAO --> CSAPI: Return Notifications details for Participant + deactivate NOTIFY_DAO + CSAPI --> NOTIFY_HANDLER: Return Notifications details for Participant + deactivate CSAPI + NOTIFY_HANDLER --> DFSP: Callback with Prepare result to Participant to specified URL - PUT - />/transfers + end +end +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg new file mode 100644 index 000000000..6e972084c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) + + + + Financial Service Provider + + + + ML API Adapter Service + + + + Central Service + + + + + + + + DFSP(n) + + + Participant + + + + + DFSP(n) + + + Participant + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + + EVENT_DAO + + + + EVENT_DAO + + + Notification DAO + + + + + Notification DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Send notification to Participant + + + + + This flow has not been implemented + + + + + 1 + + + Consume Notifications event batch of messages for Participant + + + + + loop + + + [for each message in batch] + + + + + Persist Event Information + + + + + 2 + + + Request to persist event information - POST - /events + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + 4 + + + Return success + + + + + 5 + + + Return success + + + + + 6 + + + Request Notifications details for Participant - GET - /notifications/DFPS(n) + + + + + 7 + + + Fetch Notifications details for Participant + + + + + 8 + + + Fetch Notifications details for Participant + + + + transferPosition + + + + + 9 + + + Retrieved Notification details for Participant + + + + + 10 + + + Return Notifications details for Participant + + + + + 11 + + + Return Notifications details for Participant + + + + + 12 + + + Callback with Prepare result to Participant to specified URL - PUT - /<dfsp-host>>/transfers + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml new file mode 100644 index 000000000..45f7fd524 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.plantuml @@ -0,0 +1,143 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER + +' collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +' control "Position Event Handler" as POS_HANDLER +' collections "Event-Topic" as TOPIC_EVENTS +' collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +group DFSP2 sends an error callback to reject a transfer with an errorCode and description + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: **PUT - /transfers//error** + + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all) + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + FULF_HANDLER -> FULF_HANDLER: Log error message + note right of FULF_HANDLER: (corresponding to a Fulfil message with transferState='ABORTED')\naction REJECT is not allowed into fulfil handler +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg new file mode 100644 index 000000000..d00bef23e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + + DFSP2 sends an error callback to reject a transfer with an errorCode and description + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <errorDescription>, + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + } + + + + 1 + + + PUT - /transfers/<ID>/error + + + + + 2 + + + Validate incoming token and originator matching Payee + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 3 + + + Route & Publish Fulfil event for Payee + + + + + 4 + + + Ensure event is replicated as configured (ACKS=all) + + + + + 5 + + + Respond replication acknowledgements have been received + + + + + 6 + + + Respond HTTP - 200 (OK) + + + + + 7 + + + Consume message + + + + + 8 + + + Log error message + + + + + (corresponding to a Fulfil message with transferState='ABORTED') + + + action REJECT is not allowed into fulfil handler + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml new file mode 100644 index 000000000..ec02b5318 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.plantuml @@ -0,0 +1,166 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +' declate title +title 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 sends a Fulfil Success Transfer request + DFSP2 <-> DFSP2: During processing of an incoming\nPOST /transfers request, some processing\nerror occurred and an Error callback is made + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage: + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers//error + activate MLAPI + MLAPI -> MLAPI: Validate incoming originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Abort event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Abort)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg new file mode 100644 index 000000000..dd1fc3063 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg @@ -0,0 +1,495 @@ + + + + + + + + + + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + 1 + + + During processing of an incoming + + + POST /transfers request, some processing + + + error occurred and an Error callback is made + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - errorMessage: + + + { + + + errorInformation + + + { + + + "errorCode": <errorCode>, + + + "errorDescription": <errorDescription> + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + } + + + + 2 + + + PUT - /transfers/<ID>/error + + + + + 3 + + + Validate incoming originator matching Payee + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <errorMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Route & Publish Abort event for Payee + + + Error code: + + + 2003 + + + + + 5 + + + Ensure event is replicated as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 6 + + + Respond replication acknowledgements have been received + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + 8 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Abort) + + + + + 9 + + + Produce message + + + + + 10 + + + Consume message + + + + + ref + + + Position Handler Consume (Abort) + + + + + 11 + + + Produce message + + + + + 12 + + + Consume message + + + + + opt + + + [action == 'abort'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 13 + + + Send callback notification + + + + + 14 + + + Consume message + + + + + opt + + + [action == 'abort'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 15 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml new file mode 100644 index 000000000..f7c9c3c06 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml @@ -0,0 +1,166 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +' declate title +title 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 sends a Fulfil Success Transfer request + DFSP2 <-> DFSP2: During processing of an incoming\nPOST /transfers request, some processing\nerror occurred and an Error callback is made + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - errorMessage: + { + errorInformation + { + "errorCode": , + "errorDescription": + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + } + end note + DFSP2 ->> MLAPI: PUT - /transfers//error + activate MLAPI + MLAPI -> MLAPI: Validate incoming originator matching Payee\nError codes: 3000-3002, 3100-3107 + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Abort/Reject event for Payee\nError code: 2003 + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all)\nError code: 2003 + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_TRANSFER_POSITION: Fulfil Handler Consume (Reject/Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Abort)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'abort' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end + ||| +end +deactivate POS_HANDLER +deactivate FULF_HANDLER +deactivate NOTIFY_HANDLER +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg new file mode 100644 index 000000000..7ac9606f1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.svg @@ -0,0 +1,495 @@ + + + + + + + + + + + 2.2.0.a. DFSP2 sends a PUT call on /error end-point for a Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP2 sends a Fulfil Success Transfer request + + + + + 1 + + + During processing of an incoming + + + POST /transfers request, some processing + + + error occurred and an Error callback is made + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - errorMessage: + + + { + + + errorInformation + + + { + + + "errorCode": <errorCode>, + + + "errorDescription": <errorDescription> + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + } + + + + 2 + + + PUT - /transfers/<ID>/error + + + + + 3 + + + Validate incoming originator matching Payee + + + Error codes: + + + 3000-3002, 3100-3107 + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <errorMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Route & Publish Abort/Reject event for Payee + + + Error code: + + + 2003 + + + + + 5 + + + Ensure event is replicated as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 6 + + + Respond replication acknowledgements have been received + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + 8 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Reject/Abort) + + + + + 9 + + + Produce message + + + + + 10 + + + Consume message + + + + + ref + + + Position Handler Consume (Abort) + + + + + 11 + + + Produce message + + + + + 12 + + + Consume message + + + + + opt + + + [action == 'abort'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 13 + + + Send callback notification + + + + + 14 + + + Consume message + + + + + opt + + + [action == 'abort'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 15 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml new file mode 100644 index 000000000..9c88eb8cb --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml @@ -0,0 +1,170 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API Adapter" as MLAPI +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +control "Position Event Handler" as POS_HANDLER +collections "Event-Topic" as TOPIC_EVENTS +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #LightBlue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENTS + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate NOTIFY_HANDLER +activate FULF_HANDLER +activate POS_HANDLER +group DFSP2 sends a Fulfil Reject Transfer request + DFSP2 <-> DFSP2: Retrieve fulfilment string generated during\nthe quoting process or regenerate it using\n**Local secret** and **ILP Packet** as inputs + note right of DFSP2 #lightblue + **Note**: In the payload for PUT /transfers/ + only the **transferState** field is **required** + end note + note right of DFSP2 #yellow + Headers - transferHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - transferMessage: + { + "fulfilment": , + "completedTimestamp": , + "transferState": "ABORTED", + "extensionList": { + "extension": [ + { + "key": , + "value": + } + ] + } + } + end note + note right of DFSP2 #lightgray + **Note**: Payee rejection reason should be captured + in the extensionList within the payload. + end note + DFSP2 ->> MLAPI: **PUT - /transfers/** + + activate MLAPI + MLAPI -> MLAPI: Validate incoming token and originator matching Payee + note right of MLAPI #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: fulfil, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + MLAPI -> TOPIC_FULFIL: Route & Publish Fulfil event for Payee + activate TOPIC_FULFIL + TOPIC_FULFIL <-> TOPIC_FULFIL: Ensure event is replicated as configured (ACKS=all) + TOPIC_FULFIL --> MLAPI: Respond replication acknowledgements have been received + deactivate TOPIC_FULFIL + MLAPI -->> DFSP2: Respond HTTP - 200 (OK) + deactivate MLAPI + TOPIC_FULFIL <- FULF_HANDLER: Consume message + ref over TOPIC_FULFIL, TOPIC_EVENTS: Fulfil Handler Consume (Reject/Abort)\n + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + ||| + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Handler Consume (Reject)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'reject' + ||| + ref over DFSP1, TOPIC_NOTIFICATIONS: Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| +end +activate POS_HANDLER +activate FULF_HANDLER +activate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg new file mode 100644 index 000000000..a2cbf7626 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.svg @@ -0,0 +1,489 @@ + + + + + + + + + + + 2.2.0. DFSP2 sends a Fulfil Reject Transfer request + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API Adapter + + + + + ML API Adapter + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + Position Event Handler + + + + + Position Event Handler + + + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP2 sends a Fulfil Reject Transfer request + + + + + 1 + + + Retrieve fulfilment string generated during + + + the quoting process or regenerate it using + + + Local secret + + + and + + + ILP Packet + + + as inputs + + + + + Note + + + : In the payload for PUT /transfers/<ID> + + + only the + + + transferState + + + field is + + + required + + + + + Headers - transferHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - transferMessage: + + + { + + + "fulfilment": <IlpFulfilment>, + + + "completedTimestamp": <DateTime>, + + + "transferState": "ABORTED", + + + "extensionList": { + + + "extension": [ + + + { + + + "key": <string>, + + + "value": <string> + + + } + + + ] + + + } + + + } + + + + + Note + + + : Payee rejection reason should be captured + + + in the extensionList within the payload. + + + + 2 + + + PUT - /transfers/<ID> + + + + + 3 + + + Validate incoming token and originator matching Payee + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: fulfil, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 4 + + + Route & Publish Fulfil event for Payee + + + + + 5 + + + Ensure event is replicated as configured (ACKS=all) + + + + + 6 + + + Respond replication acknowledgements have been received + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + 8 + + + Consume message + + + + + ref + + + Fulfil Handler Consume (Reject/Abort) + + + + + 9 + + + Produce message + + + + + 10 + + + Consume message + + + + + ref + + + Position Handler Consume (Reject) + + + + + 11 + + + Produce message + + + + + 12 + + + Consume message + + + + + opt + + + [action == 'reject'] + + + + + ref + + + Send notification to Participant (Payer) + + + + + 13 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml new file mode 100644 index 000000000..3c390db71 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.plantuml @@ -0,0 +1,225 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Fulfil Handler Consume (Abort/Reject) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "Event-Topic" as TOPIC_EVENT +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Failure) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] )\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 2001 + end + group Validate Transfer Fulfil Duplicate Check + FULF_HANDLER -> FULF_HANDLER: Generate transferFulfilmentId uuid + FULF_HANDLER -> TRANS_DAO: Request to retrieve transfer fulfilment hashes by transferId\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request Transfer fulfilment duplicate message hashes + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Return existing hashes + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return (list of) transfer fulfil messages hash(es) + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Loop the list of returned hashes and compare each entry with the calculated message hash + alt Hash matched + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Request to retrieve Transfer Fulfilment and Transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request to retrieve Transfer Fulfilment and Transfer state + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Return Transfer Fulfilment and Transfer state + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return Transfer Fulfilment and Transfer state + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + FULF_HANDLER <-> FULF_HANDLER: Error handling: 3105 + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Error code: 2001 + end + else + break + FULF_HANDLER <-> FULF_HANDLER: Allow previous request to complete + end + end + else Hash not matched + FULF_HANDLER -> TRANS_DAO: Request to persist transfer hash\nError codes: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist hash + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + deactivate TRANS_DAO + end + end + alt action=='reject' call made on PUT /transfers/{ID} + FULF_HANDLER -> FULF_HANDLER: Log error message + note right of FULF_HANDLER: action REJECT is not allowed into fulfil handler + else action=='abort' Error callback + alt Validation successful + group Persist Transfer State (with transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state and Error\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state and error information + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Transfer Error Message not successful + break + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg new file mode 100644 index 000000000..7b61b6711 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + 2.2.1. Fulfil Handler Consume (Abort/Reject) + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Fulfil Handler Consume (Failure) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] ) + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate FSPIOP-Signature + + + + + ref + + + Validate message.content.headers. + + + FSPIOP-Signature + + + Error codes: + + + 2001 + + + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + + + Generate transferFulfilmentId uuid + + + + + 5 + + + Request to retrieve transfer fulfilment hashes by transferId + + + Error code: + + + 2003 + + + + + 6 + + + Request Transfer fulfilment duplicate message hashes + + + + SELET transferId, hash + + + FROM + + + transferFulfilmentDuplicateCheck + + + WHERE transferId = request.params.id + + + + + 7 + + + Return existing hashes + + + + + 8 + + + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + + + Loop the list of returned hashes and compare each entry with the calculated message hash + + + + + alt + + + [Hash matched] + + + + + 10 + + + Request to retrieve Transfer Fulfilment and Transfer state + + + Error code: + + + 2003 + + + + + 11 + + + Request to retrieve Transfer Fulfilment and Transfer state + + + + transferFulfilment + + + transferStateChange + + + + + 12 + + + Return Transfer Fulfilment and Transfer state + + + + + 13 + + + Return Transfer Fulfilment and Transfer state + + + + + alt + + + [transferFulfilment.isValid == 0] + + + + + break + + + + + 14 + + + Error handling: + + + 3105 + + + + [transferState IN ['COMMITTED', 'ABORTED']] + + + + + break + + + + + ref + + + Send notification to Participant (Payee) + + + + [transferState NOT 'RESERVED'] + + + + + break + + + + + 15 + + + Error code: + + + 2001 + + + + + + break + + + + + 16 + + + Allow previous request to complete + + + + [Hash not matched] + + + + + 17 + + + Request to persist transfer hash + + + Error codes: + + + 2003 + + + + + 18 + + + Persist hash + + + + transferFulfilmentDuplicateCheck + + + + + 19 + + + Return success + + + + + alt + + + [action=='reject' call made on PUT /transfers/{ID}] + + + + + 20 + + + Log error message + + + + + action REJECT is not allowed into fulfil handler + + + + [action=='abort' Error callback] + + + + + alt + + + [Validation successful] + + + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + + + 21 + + + Request to persist transfer state and Error + + + Error code: + + + 2003 + + + + + 22 + + + Persist transfer state and error information + + + + transferStateChange + + + transferError + + + transferExtension + + + + + 23 + + + Return success + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 24 + + + Route & Publish Position event for Payer + + + + [Validate Transfer Error Message not successful] + + + + + break + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 25 + + + Route & Publish Notification event for Payee + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml new file mode 100644 index 000000000..1cd1e4b68 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml @@ -0,0 +1,343 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + * Georgi Georgiev + * Sam Kummary + -------------- + ******'/ + +@startuml +' declate title +title 2.2.1. Fulfil Handler Consume (Reject/Abort) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "Fulfil-Topic" as TOPIC_FULFIL +control "Fulfil Event Handler" as FULF_HANDLER +collections "Event-Topic" as TOPIC_EVENT +collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION +collections "Notification-Topic" as TOPIC_NOTIFICATIONS +'entity "Transfer Duplicate Facade" as DUP_FACADE +entity "Transfer DAO" as TRANS_DAO +database "Central Store" as DB +box "Central Service" #LightYellow + participant TOPIC_FULFIL + participant FULF_HANDLER + participant TOPIC_TRANSFER_POSITION + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS + participant TRANS_DAO + participant DB +end box +' start flow +activate FULF_HANDLER +group Fulfil Handler Consume (Failure) + alt Consume Single Message + TOPIC_FULFIL <- FULF_HANDLER: Consume Fulfil event message for Payer + activate TOPIC_FULFIL + deactivate TOPIC_FULFIL + break + group Validate Event + FULF_HANDLER <-> FULF_HANDLER: Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] )\nError codes: 2001 + end + end + group Persist Event Information + FULF_HANDLER -> TOPIC_EVENT: Publish event information + ref over FULF_HANDLER, TOPIC_EVENT: Event Handler Consume + end + group Validate FSPIOP-Signature + ||| + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Validate message.content.headers.**FSPIOP-Signature**\nError codes: 2001 + end + group Validate Transfer Fulfil Duplicate Check + FULF_HANDLER -> FULF_HANDLER: Generate transferFulfilmentId uuid + FULF_HANDLER -> TRANS_DAO: Request to retrieve transfer fulfilment hashes by transferId\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request Transfer fulfilment duplicate message hashes + hnote over DB #lightyellow + SELET transferId, hash + FROM **transferFulfilmentDuplicateCheck** + WHERE transferId = request.params.id + end note + activate DB + TRANS_DAO <-- DB: Return existing hashes + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return (list of) transfer fulfil messages hash(es) + deactivate TRANS_DAO + FULF_HANDLER -> FULF_HANDLER: Loop the list of returned hashes and compare each entry with the calculated message hash + alt Hash matched + ' Need to check what respond with same results if finalised then resend, else ignore and wait for response + FULF_HANDLER -> TRANS_DAO: Request to retrieve Transfer Fulfilment and Transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Request to retrieve Transfer Fulfilment and Transfer state + hnote over DB #lightyellow + transferFulfilment + transferStateChange + end note + activate DB + TRANS_DAO <-- DB: Return Transfer Fulfilment and Transfer state + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return Transfer Fulfilment and Transfer state + deactivate TRANS_DAO + alt transferFulfilment.isValid == 0 + break + FULF_HANDLER <-> FULF_HANDLER: Error handling: 3105 + end + else transferState IN ['COMMITTED', 'ABORTED'] + break + ref over FULF_HANDLER, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n + end + else transferState NOT 'RESERVED' + break + FULF_HANDLER <-> FULF_HANDLER: Error code: 2001 + end + else + break + FULF_HANDLER <-> FULF_HANDLER: Allow previous request to complete + end + end + else Hash not matched + FULF_HANDLER -> TRANS_DAO: Request to persist transfer hash\nError codes: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist hash + hnote over DB #lightyellow + transferFulfilmentDuplicateCheck + end note + activate DB + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + deactivate TRANS_DAO + end + end + alt action=='reject' call made on PUT /transfers/{ID} + FULF_HANDLER -> TRANS_DAO: Request information for the validate checks\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Fetch from database + activate DB + hnote over DB #lightyellow + transfer + end note + DB --> TRANS_DAO + deactivate DB + FULF_HANDLER <-- TRANS_DAO: Return transfer + deactivate TRANS_DAO + + alt Fulfilment present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment)\nError code: 2001 + + group Persist fulfilment + FULF_HANDLER -> TRANS_DAO: Persist fulfilment with the result of the above check (transferFulfilment.isValid)\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferFulfilment + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + else Fulfilment NOT present in the PUT /transfers/{ID} message + FULF_HANDLER ->FULF_HANDLER: Validate that transfer fulfilment message to Abort is valid\nError code: 2001 + group Persist extensions + FULF_HANDLER -> TRANS_DAO: Persist extensionList elements\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist to database + activate DB + deactivate DB + hnote over DB #lightyellow + transferExtension + end note + FULF_HANDLER <-- TRANS_DAO: Return success + deactivate TRANS_DAO + end + end + + alt Transfer.ilpCondition validate successful OR generic validation successful + group Persist Transfer State (with transferState='RECEIVED_REJECT') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state + activate DB + hnote over DB #lightyellow + transferStateChange + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Fulfil Transfer not successful or Generic validation failed + break + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: reject, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + else action=='abort' Error callback + alt Validation successful + group Persist Transfer State (with transferState='RECEIVED_ERROR') + FULF_HANDLER -> TRANS_DAO: Request to persist transfer state and Error\nError code: 2003 + activate TRANS_DAO + TRANS_DAO -> DB: Persist transfer state and error information + activate DB + hnote over DB #lightyellow + transferStateChange + transferError + transferExtension + end note + deactivate DB + TRANS_DAO --> FULF_HANDLER: Return success + end + + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + + FULF_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else Validate Transfer Error Message not successful + break + note right of FULF_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + responseTo: , + type: position, + action: abort, + createdAt: , + state: { + status: "error", + code: 1 + } + } + } + } + end note + FULF_HANDLER -> TOPIC_NOTIFICATIONS: Route & Publish Notification event for Payee + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + end + end + end + else Consume Batch Messages + note left of FULF_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate FULF_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg new file mode 100644 index 000000000..ad8d40a03 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.svg @@ -0,0 +1,1073 @@ + + + + + + + + + + + 2.2.1. Fulfil Handler Consume (Reject/Abort) + + + + Central Service + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fulfil-Topic + + + + + Fulfil-Topic + + + Fulfil Event Handler + + + + + Fulfil Event Handler + + + + + + + topic-transfer-position + + + + + topic-transfer-position + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + + Fulfil Handler Consume (Failure) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume Fulfil event message for Payer + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'fulfil' && ( action IN ['reject','abort'] ) + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Validate FSPIOP-Signature + + + + + ref + + + Validate message.content.headers. + + + FSPIOP-Signature + + + Error codes: + + + 2001 + + + + + Validate Transfer Fulfil Duplicate Check + + + + + 4 + + + Generate transferFulfilmentId uuid + + + + + 5 + + + Request to retrieve transfer fulfilment hashes by transferId + + + Error code: + + + 2003 + + + + + 6 + + + Request Transfer fulfilment duplicate message hashes + + + + SELET transferId, hash + + + FROM + + + transferFulfilmentDuplicateCheck + + + WHERE transferId = request.params.id + + + + + 7 + + + Return existing hashes + + + + + 8 + + + Return (list of) transfer fulfil messages hash(es) + + + + + 9 + + + Loop the list of returned hashes and compare each entry with the calculated message hash + + + + + alt + + + [Hash matched] + + + + + 10 + + + Request to retrieve Transfer Fulfilment and Transfer state + + + Error code: + + + 2003 + + + + + 11 + + + Request to retrieve Transfer Fulfilment and Transfer state + + + + transferFulfilment + + + transferStateChange + + + + + 12 + + + Return Transfer Fulfilment and Transfer state + + + + + 13 + + + Return Transfer Fulfilment and Transfer state + + + + + alt + + + [transferFulfilment.isValid == 0] + + + + + break + + + + + 14 + + + Error handling: + + + 3105 + + + + [transferState IN ['COMMITTED', 'ABORTED']] + + + + + break + + + + + ref + + + Send notification to Participant (Payee) + + + + [transferState NOT 'RESERVED'] + + + + + break + + + + + 15 + + + Error code: + + + 2001 + + + + + + break + + + + + 16 + + + Allow previous request to complete + + + + [Hash not matched] + + + + + 17 + + + Request to persist transfer hash + + + Error codes: + + + 2003 + + + + + 18 + + + Persist hash + + + + transferFulfilmentDuplicateCheck + + + + + 19 + + + Return success + + + + + alt + + + [action=='reject' call made on PUT /transfers/{ID}] + + + + + 20 + + + Request information for the validate checks + + + Error code: + + + 2003 + + + + + 21 + + + Fetch from database + + + + transfer + + + + + 22 + + + + + 23 + + + Return transfer + + + + + alt + + + [Fulfilment present in the PUT /transfers/{ID} message] + + + + + 24 + + + Validate that Transfer.ilpCondition = SHA-256 (content.payload.fulfilment) + + + Error code: + + + 2001 + + + + + Persist fulfilment + + + + + 25 + + + Persist fulfilment with the result of the above check (transferFulfilment.isValid) + + + Error code: + + + 2003 + + + + + 26 + + + Persist to database + + + + transferFulfilment + + + transferExtension + + + + + 27 + + + Return success + + + + [Fulfilment NOT present in the PUT /transfers/{ID} message] + + + + + 28 + + + Validate that transfer fulfilment message to Abort is valid + + + Error code: + + + 2001 + + + + + Persist extensions + + + + + 29 + + + Persist extensionList elements + + + Error code: + + + 2003 + + + + + 30 + + + Persist to database + + + + transferExtension + + + + + 31 + + + Return success + + + + + alt + + + [Transfer.ilpCondition validate successful OR generic validation successful] + + + + + Persist Transfer State (with transferState='RECEIVED_REJECT') + + + + + 32 + + + Request to persist transfer state + + + Error code: + + + 2003 + + + + + 33 + + + Persist transfer state + + + + transferStateChange + + + + + 34 + + + Return success + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 35 + + + Route & Publish Position event for Payer + + + + [Validate Fulfil Transfer not successful or Generic validation failed] + + + + + break + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: reject, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 36 + + + Route & Publish Notification event for Payee + + + + [action=='abort' Error callback] + + + + + alt + + + [Validation successful] + + + + + Persist Transfer State (with transferState='RECEIVED_ERROR') + + + + + 37 + + + Request to persist transfer state and Error + + + Error code: + + + 2003 + + + + + 38 + + + Persist transfer state and error information + + + + transferStateChange + + + transferError + + + transferExtension + + + + + 39 + + + Return success + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 40 + + + Route & Publish Position event for Payer + + + + [Validate Transfer Error Message not successful] + + + + + break + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: <previous.uuid>, + + + type: position, + + + action: abort, + + + createdAt: <timestamp>, + + + state: { + + + status: "error", + + + code: 1 + + + } + + + } + + + } + + + } + + + + + 41 + + + Route & Publish Notification event for Payee + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml new file mode 100644 index 000000000..99fd990f9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.plantuml @@ -0,0 +1,114 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 9.1.1. Request Duplicate Check (incl. Transfers, Quotes, Bulk Transfers, Bulk Quotes) + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +collections "topic-source" as TOPIC_SOURCE +control "Processing\nHandler" as HANDLER +collections "topic-event" as TOPIC_EVENTS +collections "topic-notifcation" as TOPIC_NOTIFICATION +entity "Request DAO" as DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_SOURCE + participant HANDLER + participant TOPIC_EVENTS + participant TOPIC_NOTIFICATION + participant DAO + participant DB +end box + +' start flow +activate HANDLER + +group Request Duplicate Check + TOPIC_SOURCE <- HANDLER: Consume message + activate TOPIC_SOURCE + deactivate TOPIC_SOURCE + + HANDLER -> HANDLER: Generate hash: **generatedHash** + group UUID Check (compareById) + HANDLER -> DAO: Query hash using getDuplicateDataFuncOverride(id)\nError code: 2003 + activate DAO + note right of DAO #lightgrey + //request// keyword to be replaced by + **transfer**, **transferFulfilment**, + **bulkTransfer** or other depending + on the override + end note + DAO -> DB: getDuplicateDataFuncOverride + hnote over DB #lightyellow + //request//DuplicateCheck + end note + activate DB + DB --> DAO: Return **duplicateHashRecord** + deactivate DB + DAO --> HANDLER: Return **hasDuplicateId** + deactivate DAO + end + + alt hasDuplicateId == TRUE + group Hash Check (compareByHash) + note right of HANDLER #lightgrey + generatedHash == duplicateHashRecord.hash + end note + HANDLER -> HANDLER: Return **hasDuplicateHash** + end + else hasDuplicateId == FALSE + group Store Message Hash + HANDLER -> DAO: Persist hash using saveHashFuncOverride(id, generatedHash)\nError code: 2003 + activate DAO + DAO -> DB: Persist **generatedHash** + activate DB + deactivate DB + hnote over DB #lightyellow + //request//DuplicateCheck + end note + DAO --> HANDLER: Return success + deactivate DAO + end + end + + note right of HANDLER #yellow + return { + hasDuplicateId: Boolean, + hasDuplicateHash: Boolean + } + end note +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg new file mode 100644 index 000000000..988ffd39a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-request-dup-check-9.1.1.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + 9.1.1. Request Duplicate Check (incl. Transfers, Quotes, Bulk Transfers, Bulk Quotes) + + + + Central Service + + + + + + + + + + + + topic-source + + + + + topic-source + + + Processing + + + Handler + + + + + Processing + + + Handler + + + + + + + topic-event + + + + + topic-event + + + + + topic-notifcation + + + + + topic-notifcation + + + Request DAO + + + + + Request DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Request Duplicate Check + + + + + 1 + + + Consume message + + + + + 2 + + + Generate hash: + + + generatedHash + + + + + UUID Check (compareById) + + + + + 3 + + + Query hash using getDuplicateDataFuncOverride(id) + + + Error code: + + + 2003 + + + + + request + + + keyword to be replaced by + + + transfer + + + , + + + transferFulfilment + + + , + + + bulkTransfer + + + or other depending + + + on the override + + + + + 4 + + + getDuplicateDataFuncOverride + + + + request + + + DuplicateCheck + + + + + 5 + + + Return + + + duplicateHashRecord + + + + + 6 + + + Return + + + hasDuplicateId + + + + + alt + + + [hasDuplicateId == TRUE] + + + + + Hash Check (compareByHash) + + + + + generatedHash == duplicateHashRecord.hash + + + + + 7 + + + Return + + + hasDuplicateHash + + + + [hasDuplicateId == FALSE] + + + + + Store Message Hash + + + + + 8 + + + Persist hash using saveHashFuncOverride(id, generatedHash) + + + Error code: + + + 2003 + + + + + 9 + + + Persist + + + generatedHash + + + + request + + + DuplicateCheck + + + + + 10 + + + Return success + + + + + return { + + + hasDuplicateId: Boolean, + + + hasDuplicateHash: Boolean + + + } + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml new file mode 100644 index 000000000..3d8209299 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.plantuml @@ -0,0 +1,122 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.1.2. Settlement Model Handler Consume +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store +' declare actors +collections "topic-\nsettlement-model" as TOPIC_SETMODEL +control "Settlement Model\nHandler" as SETMODEL_HANDLER +collections "topic-event" as TOPIC_EVENT +entity "Settlement DAO" as SET_DAO +database "Central Store" as DB + +box "Central Service" #LightYellow + participant TOPIC_SETMODEL + participant SETMODEL_HANDLER + participant TOPIC_EVENT + participant SET_DAO + participant DB +end box + +' start flow +activate SETMODEL_HANDLER +group Settlement Model Handler Consume + alt Consume Single Message + TOPIC_SETMODEL <- SETMODEL_HANDLER: Consume settlement model\nevent message + activate TOPIC_SETMODEL + deactivate TOPIC_SETMODEL + break + group Validate Event + SETMODEL_HANDLER <-> SETMODEL_HANDLER: Validate event - Rule: type == 'setmodel' && action == 'commit'\nError codes: 2001 + end + end + group Persist Event Information + ||| + SETMODEL_HANDLER -> TOPIC_EVENT: Publish event information + ref over SETMODEL_HANDLER, TOPIC_EVENT: Event Handler Consume\n + ||| + end + + SETMODEL_HANDLER -> SET_DAO: Assign transferParicipant state(s)\nError code: 2003 + activate SET_DAO + group DB TRANSACTION + SET_DAO -> DB: Fetch transfer participant entries + activate DB + hnote over DB #lightyellow + transferParticipant + end note + DB --> SET_DAO: Return **transferParticipantRecords** + deactivate DB + + loop for each transferParticipant + note right of SET_DAO #lightgrey + Settlement models caching to be considered + end note + SET_DAO -> DB: Get settlement model by currency and ledger entry + activate DB + hnote over DB #lightyellow + settlementModel + end note + DB --> SET_DAO: Return **settlementModel** + deactivate DB + + opt settlementModel.delay == 'IMMEDIATE' && settlementModel.granularity == 'GROSS' + SET_DAO -> DB: Set states: CLOSED->PENDING_SETTLEMENT->SETTLED + activate DB + hnote over DB #lightyellow + transferParticipantStateChange + transferParticipant + end note + deactivate DB + else + SET_DAO -> DB: Set state: OPEN + activate DB + hnote over DB #lightyellow + transferParticipantStateChange + transferParticipant + end note + deactivate DB + end + + end + end + SETMODEL_HANDLER <-- SET_DAO: Return success + deactivate SET_DAO + else Consume Batch Messages + note left of SETMODEL_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate SETMODEL_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg new file mode 100644 index 000000000..50323963f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-setmodel-2.1.2.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + 2.1.2. Settlement Model Handler Consume + + + + Central Service + + + + + + + + + + + + + + topic- + + + settlement-model + + + + + topic- + + + settlement-model + + + Settlement Model + + + Handler + + + + + Settlement Model + + + Handler + + + + + + + topic-event + + + + + topic-event + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Settlement Model Handler Consume + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume settlement model + + + event message + + + + + break + + + + + Validate Event + + + + + 2 + + + Validate event - Rule: type == 'setmodel' && action == 'commit' + + + Error codes: + + + 2001 + + + + + Persist Event Information + + + + + 3 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + 4 + + + Assign transferParicipant state(s) + + + Error code: + + + 2003 + + + + + DB TRANSACTION + + + + + 5 + + + Fetch transfer participant entries + + + + transferParticipant + + + + + 6 + + + Return + + + transferParticipantRecords + + + + + loop + + + [for each transferParticipant] + + + + + Settlement models caching to be considered + + + + + 7 + + + Get settlement model by currency and ledger entry + + + + settlementModel + + + + + 8 + + + Return + + + settlementModel + + + + + opt + + + [settlementModel.delay == 'IMMEDIATE' && settlementModel.granularity == 'GROSS'] + + + + + 9 + + + Set states: CLOSED->PENDING_SETTLEMENT->SETTLED + + + + transferParticipantStateChange + + + transferParticipant + + + + + + 10 + + + Set state: OPEN + + + + transferParticipantStateChange + + + transferParticipant + + + + + 11 + + + Return success + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml new file mode 100644 index 000000000..a1ee95a55 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml @@ -0,0 +1,107 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declate title +title 2.3.0. Transfer Timeout + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +actor "DFSP1\nPayer" as DFSP1 +actor "DFSP2\nPayee" as DFSP2 +boundary "ML API\nAdapter" as MLAPI +control "Notification\nHandler" as NOTIFY_HANDLER +control "Timeout Prepare\nHandler" as TIMEOUT_PREP_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +control "Timeout\nHandler" as TIMEOUT_HANDLER +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +control "Position\nHandler" as POS_HANDLER +collections "topic-notification" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightgray + participant DFSP1 + participant DFSP2 +end box + +box "ML API Adapter Service" #lightblue + participant MLAPI + participant NOTIFY_HANDLER +end box + +box "Central Service" #lightyellow + participant TIMEOUT_PREP_HANDLER + participant TOPIC_TRANSFER_TIMEOUT + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant POS_HANDLER + participant TOPIC_NOTIFICATIONS +end box + +' start flow +activate TIMEOUT_PREP_HANDLER +activate NOTIFY_HANDLER +activate TIMEOUT_HANDLER +activate POS_HANDLER +group Transfer Expiry + ||| + ref over TIMEOUT_PREP_HANDLER, TOPIC_TRANSFER_TIMEOUT: Timeout Processing Handler Consume\n + TIMEOUT_PREP_HANDLER -> TOPIC_TRANSFER_TIMEOUT: Produce message + ||| + TOPIC_TRANSFER_TIMEOUT <- TIMEOUT_HANDLER: Consume message + ref over TOPIC_TRANSFER_TIMEOUT, TIMEOUT_HANDLER: Timeout Processing Handler Consume\n + alt transferStateId == 'RECEIVED_PREPARE' + TIMEOUT_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + else transferStateId == 'RESERVED' + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message + TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message + ref over TOPIC_TRANSFER_POSITION, TOPIC_NOTIFICATIONS: Position Hander Consume (Timeout)\n + POS_HANDLER -> TOPIC_NOTIFICATIONS: Produce message + end + opt action IN ['timeout-received', 'timeout-reserved'] + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + ref over DFSP1, TOPIC_NOTIFICATIONS : Send notification to Participant (Payer)\n + NOTIFY_HANDLER -> DFSP1: Send callback notification + end + ||| + TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message + opt action == 'timeout-reserved' + ||| + ref over DFSP2, TOPIC_NOTIFICATIONS : Send notification to Participant (Payee)\n + NOTIFY_HANDLER -> DFSP2: Send callback notification + end +end +deactivate POS_HANDLER +deactivate TIMEOUT_HANDLER +deactivate NOTIFY_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg new file mode 100644 index 000000000..b35a96686 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + 2.3.0. Transfer Timeout + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + DFSP2 + + + Payee + + + + + DFSP2 + + + Payee + + + + + ML API + + + Adapter + + + + + ML API + + + Adapter + + + + + Notification + + + Handler + + + + + Notification + + + Handler + + + + + Timeout Prepare + + + Handler + + + + + Timeout Prepare + + + Handler + + + + + + + topic- + + + transfer-timeout + + + + + topic- + + + transfer-timeout + + + Timeout + + + Handler + + + + + Timeout + + + Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + Position + + + Handler + + + + + Position + + + Handler + + + + + + + topic-notification + + + + + topic-notification + + + + + + Transfer Expiry + + + + + ref + + + Timeout Processing Handler Consume + + + + + 1 + + + Produce message + + + + + 2 + + + Consume message + + + + + ref + + + Timeout Processing Handler Consume + + + + + alt + + + [transferStateId == 'RECEIVED_PREPARE'] + + + + + 3 + + + Produce message + + + + [transferStateId == 'RESERVED'] + + + + + 4 + + + Produce message + + + + + 5 + + + Consume message + + + + + ref + + + Position Hander Consume (Timeout) + + + + + 6 + + + Produce message + + + + + opt + + + [action IN ['timeout-received', 'timeout-reserved']] + + + + + 7 + + + Consume message + + + + + ref + + + Send notification to Participant (Payer) + + + + + 8 + + + Send callback notification + + + + + 9 + + + Consume message + + + + + opt + + + [action == 'timeout-reserved'] + + + + + ref + + + Send notification to Participant (Payee) + + + + + 10 + + + Send callback notification + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml new file mode 100644 index 000000000..c51976758 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml @@ -0,0 +1,132 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + -------------- + ******'/ + +@startuml +' declare title +title 2.3.1. Timeout Prepare Handler + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Timeout Prepare\nHandler" as TIMEOUT_PREP_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +collections "topic-event" as EVENT_TOPIC +entity "Timeout DAO" as TIMEOUT_DAO +database "Central Store" as DB + +box "Central Service" #lightyellow + participant TIMEOUT_PREP_HANDLER + participant TOPIC_TRANSFER_TIMEOUT + participant EVENT_TOPIC + participant TIMEOUT_DAO + participant DB +end box + +' start flow + +group Timeout Prepare Handler + activate TIMEOUT_PREP_HANDLER + group Persist Event Information + TIMEOUT_PREP_HANDLER -> EVENT_TOPIC: Publish event information + ref over TIMEOUT_PREP_HANDLER, EVENT_TOPIC : Event Handler Consume\n + end + + group Cleanup + TIMEOUT_PREP_HANDLER -> TIMEOUT_DAO: Cleanup Fulfilled Transfers\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Delete fuflfilled transfers records + activate DB + deactivate DB + hnote over DB #lightyellow + DELETE et + FROM **expiringTransfer** et + JOIN **transferFulfilment** tf + ON tf.transferId = et.transferId + end note + TIMEOUT_DAO --> TIMEOUT_PREP_HANDLER: Return success + deactivate TIMEOUT_DAO + end + + group List Expired + TIMEOUT_PREP_HANDLER -> TIMEOUT_DAO: Retrieve Expired Transfers\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Select using index + activate DB + hnote over DB #lightyellow + SELECT * + FROM **expiringTransfer** + WHERE expirationDate < currentTimestamp + end note + TIMEOUT_DAO <-- DB: Return expired transfers + deactivate DB + TIMEOUT_DAO --> TIMEOUT_PREP_HANDLER: Return **expiredTransfersList** + deactivate TIMEOUT_DAO + end + + + + loop for each transfer in the list + ||| + note right of TIMEOUT_PREP_HANDLER #yellow + Message: + { + id: + from: , + to: , + type: application/json + content: { + headers: null, + payload: + }, + metadata: { + event: { + id: , + responseTo: null, + type: transfer, + action: timeout, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + TIMEOUT_PREP_HANDLER -> TOPIC_TRANSFER_TIMEOUT: Publish Timeout event\nError code: 2003 + activate TOPIC_TRANSFER_TIMEOUT + deactivate TOPIC_TRANSFER_TIMEOUT + end + + deactivate TIMEOUT_PREP_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg new file mode 100644 index 000000000..08083d7e3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 2.3.1. Timeout Prepare Handler + + + + Central Service + + + + + + + Timeout Prepare + + + Handler + + + + + Timeout Prepare + + + Handler + + + + + + + topic- + + + transfer-timeout + + + + + topic- + + + transfer-timeout + + + + + topic-event + + + + + topic-event + + + Timeout DAO + + + + + Timeout DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Timeout Prepare Handler + + + + + Persist Event Information + + + + + 1 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Cleanup + + + + + 2 + + + Cleanup Fulfilled Transfers + + + Error code: + + + 2003 + + + + + 3 + + + Delete fuflfilled transfers records + + + + DELETE et + + + FROM + + + expiringTransfer + + + et + + + JOIN + + + transferFulfilment + + + tf + + + ON tf.transferId = et.transferId + + + + + 4 + + + Return success + + + + + List Expired + + + + + 5 + + + Retrieve Expired Transfers + + + Error code: + + + 2003 + + + + + 6 + + + Select using index + + + + SELECT * + + + FROM + + + expiringTransfer + + + WHERE expirationDate < currentTimestamp + + + + + 7 + + + Return expired transfers + + + + + 8 + + + Return + + + expiredTransfersList + + + + + loop + + + [for each transfer in the list] + + + + + Message: + + + { + + + id: <uuid> + + + from: <switch>, + + + to: <payerFsp>, + + + type: application/json + + + content: { + + + headers: null, + + + payload: <transfer> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: null, + + + type: transfer, + + + action: timeout, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 9 + + + Publish Timeout event + + + Error code: + + + 2003 + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml new file mode 100644 index 000000000..42132c116 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.plantuml @@ -0,0 +1,227 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * ModusBox + - Georgi Georgiev + - Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title 2.3.2. Timeout Handler + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Transfer Timeout Handler" as TIMEOUT_HANDLER +collections "topic-\ntransfer-timeout" as TOPIC_TRANSFER_TIMEOUT +collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION +collections "topic-\nnotification" as NOTIFICATIONS_TOPIC +collections "topic-event" as EVENT_TOPIC +entity "Timeout DAO" as TIMEOUT_DAO +database "Central Store" as DB + +box "Central Service" #lightyellow + participant TOPIC_TRANSFER_TIMEOUT + participant TIMEOUT_HANDLER + participant TOPIC_TRANSFER_POSITION + participant NOTIFICATIONS_TOPIC + participant EVENT_TOPIC + participant TIMEOUT_DAO + participant DB +end box + +' start flow + +group Timeout Handler Consume + activate TIMEOUT_HANDLER + TOPIC_TRANSFER_TIMEOUT <- TIMEOUT_HANDLER: Consume message + activate TOPIC_TRANSFER_TIMEOUT + deactivate TOPIC_TRANSFER_TIMEOUT + + group Persist Event Information + TIMEOUT_HANDLER -> EVENT_TOPIC: Publish event information + ref over TIMEOUT_HANDLER, EVENT_TOPIC: Event Handler Consume\n + end + + group Get transfer info + TIMEOUT_HANDLER -> TIMEOUT_DAO: Acquire transfer information\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Get transfer data and state + activate DB + hnote over DB #lightyellow + transfer + transferParticipant + participantCurrency + participant + transferStateChange + end note + TIMEOUT_DAO <-- DB: Return **transferInfo** + deactivate DB + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Return **transferInfo** + deactivate TIMEOUT_DAO + end + + alt transferInfo.transferStateId == 'RECEIVED_PREPARE' + TIMEOUT_HANDLER -> TIMEOUT_DAO: Set EXPIRED_PREPARED state\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Insert state change + activate DB + deactivate DB + hnote over DB #lightyellow + transferStateChange + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Return success + deactivate TIMEOUT_DAO + + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: notification, + action: timeout-received, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> NOTIFICATIONS_TOPIC: Publish Notification event + activate NOTIFICATIONS_TOPIC + deactivate NOTIFICATIONS_TOPIC + else transferInfo.transferStateId == 'RESERVED' + TIMEOUT_HANDLER -> TIMEOUT_DAO: Set RESERVED_TIMEOUT state\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Insert state change + activate DB + deactivate DB + hnote over DB #lightyellow + transferStateChange + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Return success + deactivate TIMEOUT_DAO + + note right of TIMEOUT_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + headers: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + }, + payload: { + "errorInformation": { + "errorCode": 3303, + "errorDescription": "Transfer expired", + "extensionList": + } + } + }, + metadata: { + event: { + id: , + type: position, + action: timeout-reserved, + createdAt: , + state: { + status: 'error', + code: + description: + } + } + } + } + end note + TIMEOUT_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event\nError code: 2003 + activate TOPIC_TRANSFER_POSITION + deactivate TOPIC_TRANSFER_POSITION + else + note right of TIMEOUT_HANDLER #lightgrey + Any other state is ignored + end note + end + + group Cleanup + TIMEOUT_HANDLER -> TIMEOUT_DAO: Cleanup handled expiring transfer\nError code: 2003 + activate TIMEOUT_DAO + TIMEOUT_DAO -> DB: Delete record + activate DB + deactivate DB + hnote over DB #lightyellow + expiringTransfer + end note + TIMEOUT_HANDLER <-- TIMEOUT_DAO: Return success + deactivate TIMEOUT_DAO + end + + deactivate TIMEOUT_HANDLER +end +@enduml diff --git a/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg new file mode 100644 index 000000000..0103f7ba9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.2.svg @@ -0,0 +1,614 @@ + + + + + + + + + + + 2.3.2. Timeout Handler + + + + Central Service + + + + + + + + + + + topic- + + + transfer-timeout + + + + + topic- + + + transfer-timeout + + + Transfer Timeout Handler + + + + + Transfer Timeout Handler + + + + + + + topic- + + + transfer-position + + + + + topic- + + + transfer-position + + + + + topic- + + + notification + + + + + topic- + + + notification + + + + + topic-event + + + + + topic-event + + + Timeout DAO + + + + + Timeout DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Timeout Handler Consume + + + + + 1 + + + Consume message + + + + + Persist Event Information + + + + + 2 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + Get transfer info + + + + + 3 + + + Acquire transfer information + + + Error code: + + + 2003 + + + + + 4 + + + Get transfer data and state + + + + transfer + + + transferParticipant + + + participantCurrency + + + participant + + + transferStateChange + + + + + 5 + + + Return + + + transferInfo + + + + + 6 + + + Return + + + transferInfo + + + + + alt + + + [transferInfo.transferStateId == 'RECEIVED_PREPARE'] + + + + + 7 + + + Set EXPIRED_PREPARED state + + + Error code: + + + 2003 + + + + + 8 + + + Insert state change + + + + transferStateChange + + + + + 9 + + + Return success + + + + + Message: + + + { + + + id: <transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: + + + { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + }, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3303, + + + "errorDescription": "Transfer expired", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: notification, + + + action: timeout-received, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 10 + + + Publish Notification event + + + + [transferInfo.transferStateId == 'RESERVED'] + + + + + 11 + + + Set RESERVED_TIMEOUT state + + + Error code: + + + 2003 + + + + + 12 + + + Insert state change + + + + transferStateChange + + + + + 13 + + + Return success + + + + + Message: + + + { + + + id: <transferId>, + + + from: <payerParticipantId>, + + + to: <payeeParticipantId>, + + + type: application/json, + + + content: { + + + headers: + + + { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + }, + + + payload: { + + + "errorInformation": { + + + "errorCode": 3303, + + + "errorDescription": "Transfer expired", + + + "extensionList": <transferMessage.extensionList> + + + } + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: position, + + + action: timeout-reserved, + + + createdAt: <timestamp>, + + + state: { + + + status: 'error', + + + code: <errorInformation.errorCode> + + + description: <errorInformation.errorDescription> + + + } + + + } + + + } + + + } + + + + + 14 + + + Route & Publish Position event + + + Error code: + + + 2003 + + + + + + Any other state is ignored + + + + + Cleanup + + + + + 15 + + + Cleanup handled expiring transfer + + + Error code: + + + 2003 + + + + + 16 + + + Delete record + + + + expiringTransfer + + + + + 17 + + + Return success + + diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md new file mode 100644 index 000000000..e98c606e8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md @@ -0,0 +1,16 @@ +# Prepare Transfer Request + +Sequence design diagram for Prepare Transfer Request process. + +## References within Sequence Diagram + +* [Prepare Handler Consume (1.1.1.a)](1.1.1.a-prepare-handler-consume.md) +* **Not Implemented** [Prepare Handler Consume (1.1.1.b)](1.1.1.b-prepare-handler-consume.md) +* [Position Handler Consume (1.1.2.a)](1.1.2.a-position-handler-consume.md) +* **Not Implemented** [Position Handler Consume (1.1.2.b)](1.1.2.b-position-handler-consume.md) +* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) +* **Not Implemented** [Send notification to Participant (1.1.4.b)](1.1.4.b-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-prepare-1.1.0.svg](../assets/diagrams/sequence/seq-prepare-1.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md new file mode 100644 index 000000000..b0a401b5f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Prepare handler consume + +Sequence design diagram for Prepare Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.1.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.a.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md new file mode 100644 index 000000000..72e6784d5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md @@ -0,0 +1,11 @@ +# Prepare handler consume + +Sequence design diagram for Prepare Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.1.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.1.b.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md new file mode 100644 index 000000000..d091e6223 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md @@ -0,0 +1,11 @@ +# Position handler consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.2.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.a.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md new file mode 100644 index 000000000..161bea8d9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md @@ -0,0 +1,11 @@ +# Position handler consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.2.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.2.b.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md new file mode 100644 index 000000000..9fd4fb1c5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant-v1.1.md @@ -0,0 +1,11 @@ +# Send Notification to Participant v1.1 + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.a-v1.1.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a-v1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md new file mode 100644 index 000000000..12b1972d6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Send Notification to Participant + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.a.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.a.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md new file mode 100644 index 000000000..c22b6c94f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md @@ -0,0 +1,11 @@ +# Send Notification to Participant + +Sequence design diagram for the Send Notification to Participant request. + +## References within Sequence Diagram + +* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-prepare-1.1.4.b.svg](../assets/diagrams/sequence/seq-prepare-1.1.4.b.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md new file mode 100644 index 000000000..3f12ab0b1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume-v1.1.md @@ -0,0 +1,14 @@ +# Position Handler Consume v1.1 + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fufil Position Handler Consume (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Abort Position Handler Consume (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Sequence Diagram + +![seq-position-1.3.0-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.0-v1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md new file mode 100644 index 000000000..a3942172f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md @@ -0,0 +1,14 @@ +# Position Handler Consume + +Sequence design diagram for Position Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) +* [Fufil Position Handler Consume (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Abort Position Handler Consume (1.3.3)](1.3.3-abort-position-handler-consume.md) + +## Sequence Diagram + +![seq-position-1.3.0.svg](../assets/diagrams/sequence/seq-position-1.3.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md new file mode 100644 index 000000000..2ab39456e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md @@ -0,0 +1,7 @@ +# Prepare Position Handler Consume + +Sequence design diagram for Prepare Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.1-prepare.svg](../assets/diagrams/sequence/seq-position-1.3.1-prepare.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md new file mode 100644 index 000000000..fff28f156 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume-v1.1.md @@ -0,0 +1,8 @@ +# Fulfil Position Handler Consume v1.1 + +Sequence design diagram for Fulfil Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.2-fulfil-v1.1.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil-v1.1.svg) + diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md new file mode 100644 index 000000000..25e5b2774 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md @@ -0,0 +1,7 @@ +# Fulfil Position Handler Consume + +Sequence design diagram for Fulfil Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.2-fulfil.svg](../assets/diagrams/sequence/seq-position-1.3.2-fulfil.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md new file mode 100644 index 000000000..9ab80dc75 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md @@ -0,0 +1,7 @@ +# Abort Position Handler Consume + +Sequence design diagram for Abort Position Handler Consume process. + +## Sequence Diagram + +![seq-position-1.3.3-abort.svg](../assets/diagrams/sequence/seq-position-1.3.3-abort.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md new file mode 100644 index 000000000..d7a71954f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request-v1.1.md @@ -0,0 +1,13 @@ +# Fulfil Transfer Request success v1.1 + +Sequence design diagram for the Fulfil Success Transfer request. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Success) (2.1.1)](2.1.1-fulfil-handler-consume-v1.1.md) +* [Position Handler Consume (Success) (1.3.2)](1.3.2-fulfil-position-handler-consume-v1.1.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1-v1.1.md) + +## Sequence Diagram + +![seq-fulfil-2.1.0-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0-v1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md new file mode 100644 index 000000000..c552a057a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md @@ -0,0 +1,13 @@ +# Fulfil Transfer Request success + +Sequence design diagram for the Fulfil Success Transfer request. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Success) (2.1.1)](2.1.1-fulfil-handler-consume.md) +* [Position Handler Consume (Success) (1.3.2)](1.3.2-fulfil-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-fulfil-2.1.0.svg](../assets/diagrams/sequence/seq-fulfil-2.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md new file mode 100644 index 000000000..69f2afa87 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume-v1.1.md @@ -0,0 +1,13 @@ +# Fulfil Handler Consume (Success) v1.1 + +Sequence design diagram for the Fulfil Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-fulfil-2.1.1-v1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1-v1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md new file mode 100644 index 000000000..05f7e38f0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md @@ -0,0 +1,13 @@ +# Fulfil Handler Consume (Success) + +Sequence design diagram for the Fulfil Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-fulfil-2.1.1.svg](../assets/diagrams/sequence/seq-fulfil-2.1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md new file mode 100644 index 000000000..ede9acee1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer-v1.1.md @@ -0,0 +1,7 @@ +# Payee sends a Fulfil Abort Transfer request v1.1 + +Sequence design diagram for the Fulfil Reject Transfer process for version 1.1. of the API. + +## Sequence Diagram + +![seq-reject-2.2.0-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0-v1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md new file mode 100644 index 000000000..fc193a59d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md @@ -0,0 +1,13 @@ +# [Outdated] Payee sends a Fulfil Reject Transfer request + +Sequence design diagram for the Fulfil Reject Transfer process. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-reject-2.2.0.svg](../assets/diagrams/sequence/seq-reject-2.2.0.svg) diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md new file mode 100644 index 000000000..74303e5e5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer-v1.1.md @@ -0,0 +1,13 @@ +# Payee sends a PUT call on /error end-point for a Transfer request v1.1 + +Sequence design diagram for the Fulfil Reject Transfer process for version 1.1. of the API. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Abort)(2.2.1)](2.2.1-fulfil-reject-handler-v1.1.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant-v1.1.md) + +## Sequence Diagram + +![seq-reject-2.2.0.a-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a-v1.1.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md new file mode 100644 index 000000000..91d635f5e --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md @@ -0,0 +1,13 @@ +# Payee sends a PUT call on /error end-point for a Transfer request + +Sequence design diagram for the Fulfil Reject Transfer process. + +## References within Sequence Diagram + +* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) +* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-reject-2.2.0.a.svg](../assets/diagrams/sequence/seq-reject-2.2.0.a.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md new file mode 100644 index 000000000..c3b5939f2 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler-v1.1.md @@ -0,0 +1,7 @@ +## Fulfil Handler Consume (Reject/Abort) + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process for version 1.1. of the API. + +## Sequence Diagram + +![seq-reject-2.2.1-v1.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1-v1.1.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md new file mode 100644 index 000000000..c83982b0d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md @@ -0,0 +1,13 @@ +## Fulfil Handler Consume (Reject/Abort) + +Sequence design diagram for the Fulfil Handler Consume Reject/Abort process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) +* [seq-signature-validation](../../central-event-processor/signature-validation.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-reject-2.2.1.svg](../assets/diagrams/sequence/seq-reject-2.2.1.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md new file mode 100644 index 000000000..874561f3d --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md @@ -0,0 +1,13 @@ +## Transfer Timeout + +Sequence design diagram for the Transfer Timeout process. + +## References within Sequence Diagram + +* [Timeout Handler Consume (2.3.1)](2.3.1-timeout-handler-consume.md) +* [Position Handler Consume (Timeout)(1.3.3)](1.3.3-abort-position-handler-consume.md) +* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) + +## Sequence Diagram + +![seq-timeout-2.3.0.svg](../assets/diagrams/sequence/seq-timeout-2.3.0.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md new file mode 100644 index 000000000..9d96ccf69 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md @@ -0,0 +1,11 @@ +## Timeout Handler Consume + +Sequence design diagram for the Timeout Handler Consume process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) + +## Sequence Diagram + +![seq-timeout-2.3.1.svg](../assets/diagrams/sequence/seq-timeout-2.3.1.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-ledger/transfers/README.md b/legacy/mojaloop-technical-overview/central-ledger/transfers/README.md new file mode 100644 index 000000000..ba8fc02cf --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-ledger/transfers/README.md @@ -0,0 +1,8 @@ +# Mojaloop Transfer operations + +Operational processes that is the core of the transfer operational process; + +- Prepare process +- Fulfil process +- Notifications process +- Reject/Abort process diff --git a/legacy/mojaloop-technical-overview/central-settlements/.gitkeep b/legacy/mojaloop-technical-overview/central-settlements/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/legacy/mojaloop-technical-overview/central-settlements/README.md b/legacy/mojaloop-technical-overview/central-settlements/README.md new file mode 100644 index 000000000..596744601 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/README.md @@ -0,0 +1,24 @@ +# Central-Settlements Service + +The Central Settlements service is part of the Mojaloop project and deployment. + +* The central settlements service exposes Settlement API to manage the settlements between FSPs and the Central Hub. +* The service manages Settlement Windows and Settlements Event Triggers and provides information about FSPs accounts and settlements. + +## 1. Settlement Process Design + +### 1.1. Architecture overview + +![The Settlements Architecture](./assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg) + +## 2. Funds In/Out + +Record Funds In and Record Funds Out operations are used respectively to deposit and withdraw funds into participant SETTLEMENT ledgers. The balance of the SETTLEMENT account relates to the NET_DEBIT_CAP set by the switch for every participant of the scheme. NET_DEBIT_CAP value is always lower or equal to the SETTLEMENT value. On the other side, the balance of the participant's POSITION account is limited to the value of the NET_DEBIT_CAP. + +## 3. API Specification + +Refer to **Central Settlements API** in the [API Specifications](../../api/README.md#central-settlements-api) section. + +## 4. Rules Engine + +The rules engine is separate handler within the Central-Settlement handler, that can be deployed if needed. Rules format and way of operation can be found on [Rules Handler . Interchange fees example. File format.](./settlement-process/rules-handler-consume.md) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-settlements/assets/.gitkeep b/legacy/mojaloop-technical-overview/central-settlements/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png b/legacy/mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png similarity index 100% rename from mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png rename to legacy/mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png diff --git a/mojaloop-technical-overview/central-settlements/assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg b/legacy/mojaloop-technical-overview/central-settlements/assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg similarity index 100% rename from mojaloop-technical-overview/central-settlements/assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg rename to legacy/mojaloop-technical-overview/central-settlements/assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/README.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/README.md similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/README.md rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/README.md diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.svg new file mode 100644 index 000000000..56512040f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.svg @@ -0,0 +1,267 @@ + + + + + + + + + + + 5.1.0.a. Reconciliation transfer prepare (reconciliationTransferPrepare) + + + + Central Service + + + + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + reconciliationTransferPrepare (payload, trx) + + + + + 1 + + + Insert transferDuplicateCheck + + + + INSERT INTO + + + transferDuplicateCheck + + + (transferId, hash, createdDate) + + + VALUES ({payload.transferId}, hashCode({payload.transferId}), {transactionTimestamp}) + + + + + 2 + + + Insert transfer + + + + INSERT INTO + + + transfer + + + (transferId, amount, currencyId, + + + ilpCondition, expirationDate, createdDate) + + + VALUES ({payload.transferId}, {payload.amount.amount}, + + + {payload.amount.curency}, 0, + + + {new Date()+Config.INTERNAL_TRANSFER_VALIDITY_SECONDS}, + + + {transactionTimestamp}) + + + + + 3 + + + Retrieve hub reconciliation account + + + + SELECT participantCurrencyId AS reconciliationAccountId + + + FROM + + + participantCurrency + + + WHERE participantId = 1 + + + AND currencyId = {payload.amount.currency} + + + LIMIT 1 + + + + + 4 + + + Return + + + reconciliationAccountId + + + + + alt + + + [payload.action == 'RECORD_FUNDS_IN'] + + + + + ledgerEntryTypeId + + + = 'RECORD_FUNDS_IN' + + + amount + + + = + + + payload.amount.amount + + + + [payload.action == 'RECORD_FUNDS_OUT_PREPARE'] + + + + + ledgerEntryTypeId + + + = 'RECORD_FUNDS_OUT' + + + amount + + + = + + + -payload.amount.amount + + + + + 5 + + + Insert transferParticipant records + + + + INSERT INTO + + + transferParticipant + + + (transferId, participantCurrencyId, transferParticipantRoleTypeId, + + + ledgerEntryTypeId, amount, createdDate) + + + VALUES (payload.transferId, reconciliationAccountId, 'HUB', + + + {ledgerEntryTypeId}, {amount}, {transactionTimestamp}) + + + INSERT INTO + + + transferParticipant + + + (transferId, participantCurrencyId, transferParticipantRoleTypeId, + + + ledgerEntryTypeId, amount, createdDate) + + + VALUES ({payload.transferId}, {payload.participantCurrencyId}, 'DFSP_SETTLEMENT', + + + {ledgerEntryTypeId}, {-amount}, {transactionTimestamp}) + + + + + 6 + + + Insert transferStateChange record + + + + INSERT INTO + + + transferStateChange + + + (transferId, transferStateId, reason, createdDate) + + + VALUES ({payload.transferId}, 'RECEIVED_PREPARE', + + + {payload.reason}, {transactionTimestamp}) + + + + + 7 + + + Save externalReference and extensions + + + + transferExtension + + diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.svg new file mode 100644 index 000000000..57ab88b3f --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + 5.1.0.b. Transfer state and position change (transferStateAndPositionChange) + + + + Central Service + + + + + + + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + transferStateAndPositionUpdate (param1, trx) + + + + + param1 + + + = { + + + transferId: {payload.transferId}, + + + transferStateId: "enum", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: "boolean", + + + crUpdated: "boolean" + + + } + + + + + 1 + + + Select all required info + + + + SELECT dr.participantCurrencyId AS drAccountId, + + + dr.amount AS drAmount, drp.participantPositionId AS drPositionId, + + + drp.value AS drPositionValue, drp.reservedValue AS drReservedValue, + + + cr.participantCurrencyId AS crAccountId, + + + cr.amount AS crAmount, crp.participantPositionId AS crPositionId, + + + crp.value AS crPositionValue, crp.reservedValue AS crReservedValue, + + + tsc.transferStateId + + + FROM + + + transfer + + + t + + + JOIN + + + transferParticipant + + + dr + + + ON dr.transferId = t.transferId + + + AND dr.amount > 0 + + + JOIN + + + participantCurrency + + + drpc + + + ON drpc.participantCurrencyId = dr.participantCurrencyId + + + JOIN + + + participantPosition + + + drp + + + ON drp.participantCurrencyId = dr.participantCurrencyId + + + JOIN + + + transferParticipant + + + cr + + + ON cr.transferId = t.transferId + + + AND cr.amount < 0 + + + JOIN + + + participantCurrency + + + crpc + + + ON crpc.participantCurrencyId = dr.participantCurrencyId + + + JOIN + + + participantPosition + + + crp + + + ON crp.participantCurrencyId = cr.participantCurrencyId + + + JOIN + + + transferStateChange + + + tsc + + + ON tsc.transferId = t.transferId + + + WHERE t.transferId = param1.tranferId + + + AND drpc.ledgerAccountTypeId IN('POSITION', 'SETTLEMENT', ' + + + HUB_RECONCILIATION', 'HUB_MULTILATERAL_SETTLEMENT') + + + AND crpc.ledgerAccountTypeId IN('POSITION', 'SETTLEMENT', ' + + + HUB_RECONCILIATION', 'HUB_MULTILATERAL_SETTLEMENT') + + + ORDER BY transferStateChangeId DESC + + + LIMIT 1 + + + + + 2 + + + Return + + + info + + + + + opt + + + [param1.transferStateId == 'COMMITTED'] + + + + + 3 + + + Change transfer state + + + + INSERT INTO + + + transferStateChange + + + (transferId, transferStateId, reason, createdDate) + + + VALUES ({param1.transferId, 'RECEIVED_FULFIL', {param1.reason}, {param1.createdDate}) + + + + [param1.transferStateId == 'ABORTED'] + + + + + 4 + + + Change transfer state + + + + INSERT INTO + + + transferStateChange + + + (transferId, transferStateId, reason, createdDate) + + + VALUES ({param1.transferId, 'REJECTED', {param1.reason}, {param1.createdDate}) + + + + + 5 + + + Change transfer state + + + + INSERT INTO + + + transferStateChange + + + (transferId, transferStateId, reason, createdDate) + + + VALUES ({param1.transferId, {param1.transferStateId}, {param1.reason}, {param1.createdDate}) + + + + + 6 + + + Return + + + transferStateChangeId + + + + + opt + + + [param1.drUpdated == true] + + + + + opt + + + [param1.transferStateId == 'ABORTED'] + + + + + info.drAmount = -info.drAmount + + + + + 7 + + + Change DR position + + + + UPDATE + + + participantPosition + + + SET value = {info.drPositionValue + info.drAmount} + + + WHERE participantPositionId = {info.drPositionId} + + + INSERT INTO + + + participantPositionChange + + + (participantPositionId, + + + transferStateChangeId, value, reservedValue, createdDate) + + + VALUES ({info.drPositionId}, {transferStateChangeId}, + + + {info.drPositionValue + info.drAmount}, {info.drReservedValue}, + + + {param1.createdDate}) + + + + + opt + + + [param1.crUpdated == true] + + + + + opt + + + [param1.transferStateId == 'ABORTED'] + + + + + info.crAmount = -info.crAmount + + + + + 8 + + + Change CR position + + + + UPDATE + + + participantPosition + + + SET value = {info.crPositionValue + info.crAmount} + + + WHERE participantPositionId = {info.crPositionId} + + + INSERT INTO + + + participantPositionChange + + + (participantPositionId, + + + transferStateChangeId, value, reservedValue, createdDate) + + + VALUES ({info.crPositionId}, {transferStateChangeId}, + + + {info.crPositionValue + info.crAmount}, {info.crReservedValue}, + + + {param1.createdDate}) + + + + + return + + + { + + + transferStateChangeId, + + + drPositionValue: {info.drPositionValue + info.drAmount} + + + crPositionValue: {info.crPositionValue + info.crAmount} + + + } + + diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.svg new file mode 100644 index 000000000..c83a1ab9b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + 5.1.1. Record Funds In (recordFundsIn) + + + + Central HUB + + + + Central Service + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Central Service + + + Admin API + + + + + Central Service + + + Admin API + + + + + + + Admin-Transfer-Topic + + + + + Admin-Transfer-Topic + + + Admin Event Handler + + + + + Admin Event Handler + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Record Funds In + + + + + { + + + "transferId": <uuid>, + + + "externalReference": "string", + + + "action": "recordFundsIn", + + + "amount": { + + + "amount": <decimal>, + + + "currency": "string" + + + }, + + + "reason": "string", + + + "extensionList": { + + + "extension": [ + + + { + + + "key": "string", + + + "value": "string" + + + } + + + ] + + + } + + + } + + + + + 1 + + + POST - /participants/{name}/accounts/{id} + + + + + Message: + + + { + + + id: <payload.transferId> + + + from: "dfspName", + + + to: "Hub", + + + type: "application/json" + + + content: { + + + headers: <payloadHeaders>, + + + payload: <payloadMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: "", + + + type: "transfer", + + + action: "recordFundsIn", + + + createdAt: <timestamp>, + + + state: "" + + + } + + + }, + + + pp: "" + + + } + + + + + 2 + + + Route & Publish Prepare event + + + Error code: + + + 2003 + + + + + 3 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 4 + + + Respond replication acks + + + have been received + + + + + 5 + + + Respond HTTP - 202 (Accepted) + + + + + 6 + + + Consume message + + + + + 7 + + + Prepare transfer + + + + + DB TRANSACTION + + + + + Reconciliation Transfer Prepare + + + + + ref + + + reconciliationTransferPrepare + + + (payload, trx) + + + + + Reconciliation Transfer Reserve + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "RESERVED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: true, + + + crUpdated: false + + + }, trx) + + + + + Reconciliation Transfer Commit + + + + + 8 + + + Insert transferFulfilment record + + + + INSERT INTO + + + transferFulfilment + + + (transferFulfilmentId, transferId, ilpFulfilment, + + + completedDate, isValid, settlementWindowId, createdDate) + + + VALUES ({Uuid()}, {payload.transferId}, 0, {transactionTimestamp}, + + + 1, NULL, {transactionTimestamp}) + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "COMMITTED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: false, + + + crUpdated: true + + + }, trx) + + + + + 9 + + + Finished await + + diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.svg new file mode 100644 index 000000000..a22743415 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.svg @@ -0,0 +1,443 @@ + + + + + + + + + + + 5.2.1. Record Funds Out - Prepare & Reserve (recordFundsOutPrepareReserve) + + + + Central HUB + + + + Central Service + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Central Service + + + Admin API + + + + + Central Service + + + Admin API + + + + + + + Admin-Transfer-Topic + + + + + Admin-Transfer-Topic + + + Admin Event Handler + + + + + Admin Event Handler + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Record Funds Out - Prepare & Reserve + + + + + { + + + "transferId": <uuid>, + + + "externalReference": "string", + + + "action": "recordFundsOutPrepareReserve", + + + "amount": { + + + "amount": <decimal>, + + + "currency": "string" + + + }, + + + "reason": "string", + + + "extensionList": { + + + "extension": [ + + + { + + + "key": "string", + + + "value": "string" + + + } + + + ] + + + } + + + } + + + + + 1 + + + POST - /participants/{name}/accounts/{id} + + + + + Message: + + + { + + + id: <payload.transferId> + + + from: "Hub", + + + to: "dfspName", + + + type: "application/json" + + + content: { + + + headers: <payloadHeaders>, + + + payload: <payloadMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: "", + + + type: "transfer", + + + action: "recordFundsOutPrepareReserve", + + + createdAt: <timestamp>, + + + state: "" + + + } + + + }, + + + pp: "" + + + } + + + + + 2 + + + Route & Publish Prepare event + + + Error code: + + + 2003 + + + + + 3 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 4 + + + Respond replication acks + + + have been received + + + + + 5 + + + Respond HTTP - 202 (Accepted) + + + + + 6 + + + Consume message + + + + + 7 + + + Prepare transfer + + + and reserve + + + + + DB TRANSACTION + + + + + Reconciliation Transfer Prepare + + + + + ref + + + reconciliationTransferPrepare + + + (payload, trx) + + + + + Reconciliation Transfer Reserve + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "RESERVED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: true, + + + crUpdated: false + + + }, trx) + + + + + opt + + + [transferStateAndPositionUpdate.crPositionValue > 0] + + + + + payload.reason = 'Aborted due to insufficient funds' + + + + + Reconciliation Transfer Abort + + + + + 8 + + + Insert transferFulfilment record + + + + INSERT INTO + + + transferFulfilment + + + (transferFulfilmentId, transferId, ilpFulfilment, + + + completedDate, isValid, settlementWindowId, createdDate) + + + VALUES ({Uuid()}, {payload.transferId}, 0, {transactionTimestamp}, + + + 1, NULL, {transactionTimestamp}) + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "ABORTED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: true, + + + crUpdated: false + + + }, trx) + + + + + 9 + + + Finished await + + diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.svg new file mode 100644 index 000000000..fd276ff59 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + 5.2.2. Record Funds Out Commit (recordFundsOutCommit) + + + + Central HUB + + + + Central Service + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Central Service + + + Admin API + + + + + Central Service + + + Admin API + + + + + + + Admin-Transfer-Topic + + + + + Admin-Transfer-Topic + + + Admin Event Handler + + + + + Admin Event Handler + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Record Funds Out Commit + + + + + { + + + "action": "recordFundsOutCommit", + + + "reason": "string" + + + } + + + + + 1 + + + PUT - /participants/{name}/accounts/ + + + {id}/transfers/{transferId} + + + + + Message: + + + { + + + id: <payload.transferId> + + + from: "Hub", + + + to: "dfspName", + + + type: "application/json" + + + content: { + + + headers: <payloadHeaders>, + + + payload: <payloadMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: "", + + + type: "transfer", + + + action: "recordFundsOutCommit", + + + createdAt: <timestamp>, + + + state: "" + + + } + + + }, + + + pp: "" + + + } + + + + + 2 + + + Route & Publish Prepare event + + + Error code: + + + 2003 + + + + + 3 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 4 + + + Respond replication acks + + + have been received + + + + + 5 + + + Respond HTTP - 202 (Accepted) + + + + + 6 + + + Consume message + + + + + 7 + + + Commit transfer + + + + + DB TRANSACTION + + + + + Reconciliation Transfer Commit + + + + + 8 + + + Insert transferFulfilment record + + + + INSERT INTO + + + transferFulfilment + + + (transferFulfilmentId, transferId, ilpFulfilment, + + + completedDate, isValid, settlementWindowId, createdDate) + + + VALUES ({transferFulfilmentId}, {payload.transferId}, 0, {transactionTimestamp}, + + + 1, NULL, {transactionTimestamp}) + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "COMMITTED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: false, + + + crUpdated: true + + + }, trx) + + + + + 9 + + + Finished await + + diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.plantuml b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.svg b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.svg new file mode 100644 index 000000000..8db2df0c4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + 5.2.3. Record Funds Out Abort (recordFundsOutAbort) + + + + Central HUB + + + + Central Service + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Central Service + + + Admin API + + + + + Central Service + + + Admin API + + + + + + + Admin-Transfer-Topic + + + + + Admin-Transfer-Topic + + + Admin Event Handler + + + + + Admin Event Handler + + + + + Transfer DAO + + + + + Transfer DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Record Funds Out Abort + + + + + { + + + "action": "recordFundsOutAbort", + + + "reason": "string" + + + } + + + + + 1 + + + PUT - /participants/{name}/accounts/ + + + {id}/transfers/{transferId} + + + + + Message: + + + { + + + id: <payload.transferId> + + + from: "Hub", + + + to: "dfspName", + + + type: "application/json" + + + content: { + + + headers: <payloadHeaders>, + + + payload: <payloadMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: "", + + + type: "transfer", + + + action: "recordFundsOutAbort", + + + createdAt: <timestamp>, + + + state: "" + + + } + + + }, + + + pp: "" + + + } + + + + + 2 + + + Route & Publish Prepare event + + + Error code: + + + 2003 + + + + + 3 + + + Ensure event is replicated + + + as configured (ACKS=all) + + + Error code: + + + 2003 + + + + + 4 + + + Respond replication acks + + + have been received + + + + + 5 + + + Respond HTTP - 202 (Accepted) + + + + + 6 + + + Consume message + + + + + 7 + + + Abort transfer + + + + + DB TRANSACTION + + + + + Reconciliation Transfer Abort + + + + + 8 + + + Insert transferFulfilment record + + + + INSERT INTO + + + transferFulfilment + + + (transferFulfilmentId, transferId, ilpFulfilment, + + + completedDate, isValid, settlementWindowId, createdDate) + + + VALUES ({transferFulfilmentId}, {payload.transferId}, 0, {transactionTimestamp}, + + + 1, NULL, {transactionTimestamp}) + + + + + ref + + + transferStateAndPositionUpdate + + + ({ + + + transferId: {payload.transferId}, + + + transferStateId: "ABORTED", + + + reason: {payload.reason}, + + + createdDate: {transactionTimestamp}, + + + drUpdated: true, + + + crUpdated: false + + + }, trx) + + + + + 9 + + + Finished await + + diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md new file mode 100644 index 000000000..4e4ff79a3 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md @@ -0,0 +1,7 @@ +# Funds In - Prepare, Reserve, Commit + +Funds In operation performs all the stages of the transfer (prepare, reserve and commit) at once. + +## Sequence Diagram + +![seq-recfunds-5.1.1-in.svg](./assets/diagrams/sequence/seq-recfunds-5.1.1-in.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md new file mode 100644 index 000000000..9e59dd187 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md @@ -0,0 +1,7 @@ +# Funds Out - Abort + +Funds out abort of a prepared reconciliation transfer. + +## Sequence Diagram + +![seq-recfunds-5.2.3-out-abort.svg](./assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md new file mode 100644 index 000000000..113b0c44b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md @@ -0,0 +1,7 @@ +# Funds Out - Commit + +Funds out commit of a prepared reconciliation transfer. + +## Sequence Diagram + +![seq-recfunds-5.2.2-out-commit.svg](./assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md new file mode 100644 index 000000000..0b55913fd --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md @@ -0,0 +1,8 @@ +# Funds Out - Prepare & Reserve + +Funds Out operation performs the prepare and reserve stages of the transfer at once. But the commit of the transfer or the abort operation are separate processes. + +## Sequence Diagram + + +![seq-recfunds-5.2.1-out-prepare-reserve.svg](./assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.svg) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md new file mode 100644 index 000000000..e257ead28 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md @@ -0,0 +1,7 @@ +# Reconciliation Transfer Prepare + +Design for Reconciliation Transfer Prepare sub-process. + +## Sequence Diagram + +![seq-recfunds-5.1.0.a-reconciliationTransferPrepare.svg](./assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md new file mode 100644 index 000000000..a711df784 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md @@ -0,0 +1,7 @@ +# Transfer State and Position Change + +Design for Transfer State and Position Change sub-process. + +## Sequence Diagram + +![seq-recfunds-5.1.0.b-transferStateAndPositionChange.svg](./assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.svg) diff --git a/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md b/legacy/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md similarity index 93% rename from mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md rename to legacy/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md index 707daeb0a..938a506fa 100644 --- a/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md +++ b/legacy/mojaloop-technical-overview/central-settlements/oss-settlement-fsd.md @@ -1,1703 +1,1723 @@ ---- -title: "OSS Settlement \n \nBusiness Requirements Document" ---- - -Introduction -============ - -This document describes the requirements for changes to the functionality of the -OSS Mojaloop switch to support: - -1. The immediate requirement for Mowali of being able to settle according to - different timetables for different currencies. - -2. The requirement for TIPS to be able to settle gross via a pooled account. - -3. The requirement for TIPS to use the settlement process for interchange fees. - -4. The requirement for Mojaloop to support the evolving Settlement API - -References -========== - -The following external references are used in this document: - -| Reference | Document | -| :--- | :--- | -| 1 | [Open API for FSP Interoperability Specification](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html) | -| 2 | [Settlement API Interface Definition](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json)| -| 3 | [Current administration API definition](https://mojaloop.io/documentation/api/central-ledger-api-specification.html)| -| | | - -Versions -======== - -| Version | Description | Author | Date | Changes tracked | -|:---------|:------------------|:------------------|:------------|:-----------------| -| 1.0 | Baseline version | Michael Richards | 2 Dec 2019 | No | -| | | | | | - -Definition of terms -=================== - -Settlement model ----------------- - -A settlement model defines a kind of settlement within the scheme. Settlement -models can be defined by scheme administrators, and have the following -characteristics: - -1. They can support settlement either gross or net settlements. If gross, then - a settlement is executed after each transfer is completed. If net, a group - of transfers is settled together. - -2. They can support either multilateral or bilateral settlements. If - settlements are multilateral, each participant settles with the scheme for - the net of its transfers which are included in the settlement. If they are - multilateral, each participant settles separately with each of the other - participants and the scheme is not a party to the settlement. - -3. They can support either deferred or immediate settlements. If settlements - are immediate, they are actioned immediately they are completed. If they are - deferred, they are actioned after a period of delay. - -4. They can support continuous or discontinuous settlements. Discontinuous - settlements require a formal approval from a resource outside the system to - confirm that they have been completed. Continuous settlements can be - approved from within the switch, provided that the criteria for approval are - met. - -5. They can require liquidity support or not. - -Ledger account type -------------------- - -A ledger account type defines a type of internal account. Current values are: - -1. POSITION. Accounts of this type are used for provisioning transfers - -2. SETTLEMENT. Accounts of this type are intended to be reflections of - Settlement Accounts held at the Settlement Bank - -3. HUB_RECONCILIATION. Each implementation of the switch has one account of - this type for each currency supported by the switch, owned by the virtual - DFSP which represents the Hub in the implementation. The account is used - during FUNDS IN/OUT operations to represent movements in participants’ - SETTLEMENT accounts. - -4. HUB_MULTILATERAL_SETTLEMENT. Each implementation of the switch has one - account of this type for each currency supported by the switch, owned by the - virtual DFSP which represents the Hub in the implementation. This account - type is used to record counterparty information for net amounts paid to or - from participants as part of settlements. Entries in this account represent - balancing values corresponding with the net value in a participant’s - POSITION account for a given settlement. - -5. HUB_FEE. Accounts of this type represent accounts into which fees are - collected, or from which they are disbursed. (Not implemented) - -Ledger entry type ------------------ - -A ledger entry type categorises the type of funds which are the content of a -transfer and which are due to or from a participant as a consequence of that -transfer. The current values are: - -1. PRINCIPLE_VALUE. This designates the funds moved as the content of a - transfer in the Interoperability API Specification sense of that term (i.e. - the **amount.amount** item in the **Transaction** object described in - [Section 7.4.17](https://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#7317-ilpcondition) of the Interoperability API specification[1](https://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html).) It should be - spelt “principal.” - -2. INTERCHANGE_FEE. This designates fees paid between participants in the - system. (Not implemented) - -3. HUB_FEE. This designates fees paid between participants and the scheme. (Not - implemented) - -4. POSITION_DEPOSIT. This is used to designate funds transfers which are - intended to increase the value of the position in a particular ledger - account. (Not implemented) - -5. POSITION_WITHDRAWAL. This is used to designate funds transfers which are - intended to reduce the value of the position in a particular ledger account. - (Not implemented) - -6. SETTLEMENT_NET_RECIPIENT. This is used to designate funds which a - participant is owed by the counterparty as part of a settlement (in a - multilateral settlement model, the counterparty will be the hub; in a - bilateral settlement model, it will be another party.) - -7. SETTLEMENT_NET_SENDER. This is used to designate funds which a participant - owes to the counterparty as part of a settlement (in a multilateral - settlement model, the counterparty will be the hub; in a bilateral - settlement model, it will be another party.) - -8. SETTLEMENT_NET_ZERO. This is used to generate formal records where a - participant’s net position in a settlement is zero. - -9. RECORD_FUNDS_IN. This is used to record funds deposited by a participant to - the SETTLEMENT account. - -10. RECORD_FUNDS_OUT. This is used to record funds withdrawn by a participant - from the SETTLEMENT account. - -The last seven of these types relate to the internal structure of the switch and -should be neither visible to nor modifiable by a scheme. The first three fall -into a category which is expected to be extensible by the scheme. The table does -not currently have an indicator to mark this distinction, but one is proposed in -Section TODO. - -Participant role types ----------------------- - -A participant role type defines the role that a particular participant is -playing in a given transaction. The current values of this table are: - -1. PAYER_DFSP. The participant is the debtor in a transfer. - -2. PAYEE_DFSP. The participant is a creditor in a transfer. - -3. HUB. The participant is representing the scheme, and may be either the - creditor or the debtor in a transaction. - -4. DFSP_SETTLEMENT. The participant represents the settlement account of a - participant in the scheme. It may be either the creditor or the debtor in a - transaction. It is used during FUNDS IN/OUT operations. This is used for - entries whose counterparty is an entry in the HUB account. - -5. DFSP_POSITION. The participant represents the position of a participant in - the scheme. It may be either the creditor or the debtor in a transaction. It - is used during the settlement process. This is used for entries whose - counterparty is an entry in the HUB account. - -Settlement states ------------------ - -A settlement may be in a number of possible states. The states currently -supported are: - -1. PENDING_SETTLEMENT. A new settlement consisting of one or more settlement - windows has been created. The net amounts due to or from each participant - have been calculated and a report detailing these net amounts has been - produced. - -2. PS_TRANSFERS_RECORDED: all the calculated net amounts for the settlement - have been converted into transfers between the creditor and debtor accounts. - It is applied for each settlement entry and at settlement level, when all - entries are recorded. This state is not applied to settlement windows. - -3. PS_TRANSFERS_RESERVED: all the funds required for settlement have been - reserved (debit amounts only.) It is applied for each settlement entry and - at settlement level, when all entries are reserved. - -4. PS_TRANSFERS_COMMITTED: all the credit amounts required as part of the - settlement have been committed. It is applied for each settlement entry and - at settlement level, when all entries are committed. - -5. SETTLING: It is used only at settlement level if all accounts are not yet - settled. - -6. SETTLED: This state is applied to settlement accounts in - PS_TRANSFERS_COMMITTED state. When applied to even one account, the - settlement will transit to SETTLING state. When all accounts in a window are - SETTLED, the settlement window will change from PENDING_SETTLEMENT to - SETTLED, while the settlement is still in SETTLING state. When all accounts - from all windows are SETTLED, the settlement will be changed to SETTLED. It - is possible for a settlement to change directly from PS_TRANSFERS_COMMITTED - to SETTLED if all accounts are settled with one request. - -7. ABORTED: the settlement could not be completed and should be rolled back. It - is currently only possible to abort a settlement if the state is one of: - PENDING_SETTLEMENT, PS_TRANSFERS_RECORDED or PS_TRANSFERS_RESERVED. After - having even one account in PS_TRANSFERS_COMMITTED state (even if the - settlement as a whole is still in PS_TRANSFERS_RESERVED), a request to abort - the settlement is rejected. It should be noted that this prevents abortion - in cases such as the default of a participant midway through the settlement - process. - -The present data model contains a foreign key to the enumeration table -containing settlement states from the -**settlementParticipantCurrencyStateChange** table, which maps onto a table -which contains a record for each participant/currency/account type combination. - -Assumption: this means that the states appropriate to a settlement are also to -be applied to the individual elements of a settlement. As a consequence, the -descriptions should be taken to refer to individual settlement amounts as well -as to the settlement as a whole. - -Settlement window states ------------------------- - -A settlement is made up of one or more settlement windows. Each settlement -window has a state associated with it. The current values of this table are as -follows: - -1. OPEN: the settlement window can have ledger movements added to it. - -2. CLOSED: the settlement window cannot have any additional ledger movements - added to it. It is available for settlement. - -3. PENDING_SETTLEMENT: the settlement window’s contents have been included in a - settlement request, but this request is a request for deferred settlement - which has not yet been completed. - -4. SETTLED: the scheme has confirmed that the obligations incurred by - participants as a consequence of the settlement to which this settlement - window belongs have been met by those participants and the settlement is - therefore complete. - -5. ABORTED: the settlement to which this settlement window belongs did not - complete. The settlement window is available to be included in another - settlement. - -Transfer states ---------------- - -Each transaction which passes through the system can be assigned one of a fixed -number of states. The current values of this state are: - -1. RECEIVED_PREPARE: the switch has received the transaction request. - -2. RESERVED: the switch has reserved the funds required to cover the - transaction. - -3. RECEIVED_FULFIL: the switch has received the fulfilment request, and the - transaction has been assigned to a settlement window - -4. COMMITTED: the transaction has been committed. - -5. FAILED: the transaction has failed in some unspecified way and has been - aborted. (Not implemented) - -6. RESERVED_TIMEOUT: the transaction has timed out while in the reserved state - and has been aborted. - -7. RECEIVED_REJECT: the transaction has been rejected by the payee DFSP and - should be aborted. - -8. ABORTED_REJECTED: the transaction has been aborted by the switch as a - consequence of its having been rejected by the payee DFSP. - -9. RECEIVED_ERROR: the transaction was not received correctly by the payee DFSP - and should be aborted. - -10. ABORTED_ERROR: the transaction has been aborted by the switch as a - consequence of its not having been received correctly. - -11. EXPIRED_PREPARED: the transaction has expired during the prepare process and - has been aborted. - -12. EXPIRED_RESERVED: the transaction has timed out during the reservation - process and has been aborted. - -13. INVALID: the transaction has failed the switch’s internal validation process - and has been aborted. - -Transfers and transactions --------------------------- - -Transfers define a movement of funds in the system. There is a table in the -switch which has this name. Some entries in this table are the consequence of -external movements which are generated by scheme participants and processed by -the switch; others are internally generated by the switch (e.g. to record net -movements of funds associated with settlements.) - -It may be a source of confusion that, although “transfers” is a term used e.g. -in the Interoperability API specification to designate the movement of funds -between participants, it is used as the name of a table in the switch which -stores other types of funds movement as well. - -This document will therefore adopt the following convention: - -- “Transfers” refers to the content of instructions issued using the - **/transfers** resource of the Interoperability API definition[1](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html). (see [Section 6.7](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#67-api-resource-transfers) of the Interoperability API definition[1](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html).) - -- “Transactions” refers to all movements of funds which are tracked by the - switch. - -In scope and out of scope -========================== - -In scope --------- - -The following functional items are in scope: - -1. Requesting a settlement by currency - -2. Requesting a settlement by currency and settlement model - -Out of scope ------------- - -Business rules -============== - -How do things happen now? -------------------------- - -This section describes how the current settlement process works. - -### Categorisation - -The process leading to settlement is initially defined by entries in the -*participantCurrency* table. This table holds a record for each combination of: - -1. Participant - -2. Currency - -3. Ledger account type (see Section 2.2 above.) - -### Recording positions - -Each entry in this table has a corresponding entry in the *participantPosition* -table. This table stores the current committed and reserved positions for each -of the combinations described above. Each change to the positions in this table -is documented by an entry in the *participantPositionChange* table, which refers -the change back to the *transfer* table and thence to the authoritative record -of transactions. - -### Assigning transactions to settlement windows - -As each transfer is fulfilled, a record is created for it in the -**transferFulfilment** table. This record contains a link to the currently open -settlement window. - -Records may be created for transactions which are not transfers. Non-transfer -transactions have their ilpFulfilment set to 0. - -The settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) contains a resource -(**closeSettlementWindow**) to allow an administrator to close a settlement -window and create a new one. The resource takes a settlement window ID as part -of the query string, together with a string describing the status to be assigned -and a string describing the reason for the change of status. In-line -documentation for the resource states: “If the settlementWindow is open, it can -be closed and a new window is created. If it is already closed, return an error -message. Returns the new settlement window.” - -Settlement windows can only be passed a status of CLOSED using this resource. - -### Initiating a settlement - -The initiation of a settlement is initiated by making a call triggered by the -scheme making a **POST** to the **/settlements** resource in the settlement API. -The caller gives a reason for the settlement request. This is a synchronous -call, whose return is described in Section 4.1.5 below. Internally, the -initiation is marked by the creation of a record in the **settlement** table and -the association of a number of settlement window records in the -**settlementWindow** table with the settlement created. This says: I want this -settlement to contain these settlement windows. Each of the settlement windows -selected to form part of this settlement must have the status CLOSED or ABORTED. -When selected to form part of a settlement, the status of each window should be -changed to PENDING_SETTLEMENT. The status of the settlement itself should also -be set to PENDING_SETTLEMENT. - -### Calculating the content of a settlement - -When a settlement has been requested and the windows which it will contain have -been selected, the switch produces an aggregation of the content of the proposed -settlement at the following levels: - -1. Settlement window (from **settlementWindow**) - -2. Participant (from **participantCurrency**) - -3. Currency (from **participantCurrency**) - -4. Account type (from **participantCurrency**) - -5. Participant role type (from **transferParticipant**) - -6. Ledger entry type (from **transferParticipant**) - -This query can be provisioned from the database FK links from **settlement** to -**settlementwindow**, to **transferFulfilment** (all fulfilled transfers), to -**transfer**, to **transferParticipant**. The amount is taken from the -**transferParticipant** table. Correct! - -Only transfers are included in a settlement. This is implied by the first -aggregation criterion above (Settlement window) and the fact that only transfers -are assigned to the current OPEN window when a **transferFulfilment** record is -created. All COMMITTED transactions should have an entry in the -**transferFulfilment** table. - -The results of this query are used to construct a number of records in the -**settlementParticipantCurrency** table, representing the net amount due to or -from each participant and currency in the settlement as a consequence of the -settlement. For a given settlement, these records are segmented by: Correct! - -1. Participant (from **participantCurrency**) - -2. Currency (from **participantCurrency**) - -3. Account type (from **participantCurrency)** - -This report is used as the basis of the information returned from the initial -**POST** to the **/createSettlement** resource of the settlement API (see -Section 4.1.4 above.) - -Bilateral settlements are not currently implemented. - -### Creating position records for the settlement - -A record is inserted in the **transfer** table for each net amount calculated in -the previous step when the settlement account transitions from -PENDING_SETTLEMENT to PS_TRANSFERS_RECORDED. Please note that PS stands for -PENDING_SETTLEMENT. Each of these records will have the account type SETTLEMENT. -The ledger entry type will be SETTLEMENT_NET_SENDER, SETTLEMENT_NET_RECIPIENT or -SETTLEMENT_NET_ZERO depending on whether the participant owes money to the -scheme, is owed money by the scheme or is neutral in the settlement, -respectively. The transfer participant type is HUB for the Hub participant and -DFSP_POSITION for the DFSP participant. The account type is imposed by the -participant currency – for the Hub participant it is the -HUB_MULTILATERAL_SETTLEMENT and for the DFSP participant it is the POSITION -account. This enables the switch to reset the participant’s position when the -window enters the PS_TRANSFERS_COMMITTED state. - -### Progress of the settlement - -As the scheme verifies that participants have settled the amounts due from them, -the scheme administrator can update the switch with this information. - -#### Updating the status of settlement windows - -Three methods of performing this update are supported. Each of these methods is -discussed in more detail below. - -##### **updateSettlementById** - -An administrator may issue a **PUT** to the **/updateSettlementById** resource -on the settlement API, giving the settlement ID of the settlement they wish to -update as part of the query (e.g. **PUT -/updateSettlementById/settlements/123.**) The content of the request is as -follows: - -1. A state to be assigned to the participants required. The state is - constrained to be either ABORTED or INVALID - -2. A reason for the change of state. - -3. An external reference for the change. - -4. An array of participants to which the status is to be applied. The following - information is given for each participant: - - 1. The ID of the participant. This is the internal Mojaloop ID of the - participant. - - 2. An array of *accounts*. The content of each account is as follows: - - 1. An ID. The description characterises this as the participant’s - currency ID QUESTION: Is this correct? It is an integer, where a - VARCHAR(3) would be expected. - - 2. A reason. A string which presumably can contain anything. - - 3. The state of the settlement for the account. This is not constrained - by an enum, but is a simple string. It is not clear how this status - relates to the overall state given in Item 1 above. - - 4. An external reference for the change in state. - -> A call to this API resource may contain *either* items 1-3 above *or* an -> array of accounts as specified in item 4 above, but not both. If it contains -> items 1-3 above, then all the items must be present. If these rules are -> breached, then the switch will reject the request. - -##### **updateSettlementBySettlementParticipant** - -An administrator may issue a **PUT** to the -**/updateSettlementBySettlementParticipant** resource on the settlement API, -giving the settlement ID and the participant ID of the parts of the settlement -they wish to update as part of the query (e.g. **PUT -/updateSettlementByParticipant/settlements/123/participants/56789.**) The -content of the request is as follows: - -1. An array of state changes, whose content is as follows: - - 1. The currency ID whose status is to be changed. This is an integer, where - a VARCHAR(3) would be expected. - - 2. A reason for the state change. - - 3. The state requested. This is a string, where an enumeration would be - expected. - - 4. An external reference for the change in state. - -Note that this is an array with the same structure as that described in item 4 -of Section 5.1.7.1 above, although it is defined separately in the API -definition. - -##### **updateSettlementBySettlementParticipantAccount** - -An administrator may issue a **PUT** to the -**/updateSettlementBySettlementParticipantAccount** resource on the settlement -API, giving the settlement ID, the participant ID and the account ID of the part -of the settlement they wish to update as part of the query (e.g. **PUT -/updateSettlementByParticipant/settlements/123/participants/56789/accounts/1.**) -The content of the request is as follows: - -1. The state requested. This is a string, where an enumeration would be - expected. - -2. A reason. A string which presumably can contain anything. - -3. An external reference for the change in state. - -Note that this is a structure with most of the same members as the structure -defined in Item 1 of Section 5.1.7.2 above, although the items appear in a -different order. - -#### How changes in settlement window state are processed - -The action taken in response to these calls depends on the status assigned to -the account. In any case, a record is created in the -**settlementParticipantCurrencyStateChange** table, giving the state identifier, -the reason and an external reference for the change. - -There is a sequence of steps defined for a settlement. Each step must be -followed in order, and no steps may be omitted. The sequence of steps is -hard-coded into the application and is as follows: - -1. PENDING_SETTLEMENT - -2. PS_TRANSFERS_RECORDED - -3. PS_TRANSFERS_RESERVED - -4. PS_TRANSFERS_COMMITTED - -5. SETTLED - -A settlement can be aborted provided no account in the settlement has reached a -status of PS_TRANSFERS_COMMITTED. - -The following actions are taken on each change of status: - -##### PENDING_SETTLEMENT to PS_TRANSFERS_RECORDED - -A record is generated in the **transfer** table to record the change in state. -The parties to this transfer are the POSITION account type and the -HUB_MULTILATERAL_SETTLEMENT type. If the participant account is a net creditor -for the settlement, then the ledger entry type will be set to -SETTLEMENT_NET_RECIPIENT. If the participant account is a net debtor for the -settlement, then the ledger entry type will be set to SETTLEMENT_NET_SENDER. If -the participant account is neutral for the settlement, then the ledger entry -type will be set to SETTLEMENT_NET_ZERO. - -A record is also created in the **transferstatechange** table with the -RECEIVED_PREPARE state, which means that no positions have been changed. - -When the last participating account is changed to PS_TRANSFERS_RECORDED, then -the settlement’s status is also changed to PS_TRANSFERS_RECORDED. - -If an administrator attempts to change an account’s state to -PS_TRANSFERS_RECORDED and either the settlement’s state or the settlement -account’s state is not PENDING_SETTLEMENT or PS_TRANSFERS_RECORDED, then the -request will be rejected. - -##### PS_TRANSFERS_RECORDED to PS_TRANSFERS_RESERVED - -A new record is created in the **transferstatechange** table for the transfer -that was created in section 5.1.7.2 above. This record will have a status of -RESERVED. If the participant is a net creditor as a result of the settlement, -then a record will also be created in the participantPositionChange table if the -account being reserved is for a net creditor in the settlement, as defined in -Section 5.1.7.2 above. The Net Debit Cap is checked at this point, and if the -current position exceeds the Net Debit Cap, then the Net Debit Cap is -automatically adjusted by the amount of the net credit due to the account as -part of the settlement and the participant is sent a notification of the new Net -Debit Cap value and its currency. - -When the last participating account is changed to PS_TRANSFERS_RESERVED, then -the settlement’s status is also changed to PS_TRANSFERS_RESERVED. - -If an administrator attempts to change an account’s state to -PS_TRANSFERS_RESERVED and either the settlement’s state or the settlement -account’s state is not PS_TRANSFERS_RECORDED or PS_TRANSFERS_RESERVED, then the -request will be rejected. - -##### PS_TRANSFERS_RESERVED to PS_TRANSFERS_COMMITTED - -A new record is created in the **transferstatechange** table for the transfer -that was created in section 5.1.7.2 above. This record will have a status of -COMMITTED. If the participant is a net debtor as a result of the settlement, -then a record will also be created in the participantPositionChange table if the -account being reserved is for a net debtor in the settlement, as defined in -Section 5.1.7.2 above. - -When the last participating account is changed to PS_TRANSFERS_COMMITTED, then -the settlement’s status is also changed to PS_TRANSFERS_COMMITTED. - -If an administrator attempts to change an account’s state to -PS_TRANSFERS_COMMITTED and either the settlement’s state or the settlement -account’s state is not to PS_TRANSFERS_RESERVED or PS_TRANSFERS_COMMITTED, then -the request will be rejected. - -##### PS_TRANSFERS_COMMITTED to SETTLED - -When the first account is changed to a status of SETTLED, the settlement’s state -is changed to SETTLING. - -When the last participating account is changed to SETTLED, then the settlement’s -status is also changed to SETTLED. - -If an administrator attempts to change an account’s state to SETTLED and either -the settlement’s state or the settlement account’s state is not to -PS_TRANSFERS_COMMITTED or SETTLED, then the request will be rejected. - -### Aborting the settlement - -If there is any failure in the scheme’s process for recovering the amounts due -from participants in a settlement, the scheme can update the switch with this -information by issuing a **PUT** to the **/updateSettlementById** resource of -the settlement API and setting the **state** value of the content of the message -to ABORTED. A **PUT** call on the **/updateSettlementById** resource is the only -method which may be used for ABORTING a settlement. If any account information -is given in the call, then neither the **state** nor the **reason** nor the -**externalReference** fields may be set. if the **state** value is set at the -top level of the call, then the **reason** field must also be set, and the -request will be rejected if any account information is given in the call. - -If an attempt is made to abort a settlement, and any of the accounts in the -settlement have the status PS_TRANSFERS_COMMITTED or SETTLED, then the request -will be rejected. - -When a call is received, a new record is created in the -**settlementParticipantCurrencyStateChange** table, and is given the appropriate -status based on the status reported by the caller. Depending on the update that -was received, this may also require the status of the transaction and that of -the participant position to be updated. No, it is done at settlement level for -the entire settlement and all entries in settlementParticipantCurrency are -affected. - -Note: if the settlement is bilateral, then there is no obvious reason to abort -the entire settlement if one interchange fails. We should think about this use -case and how we would want to represent it. This document does not consider this -use case. - -Aborting a settlement comprises the following steps: - -1. The status of the transfers created in Section 5.1.6 above should be changed - to ABORTED. - -2. A new record is added to the **settlementParticipantCurrencyStateChange** - table for each of the participant records in the settlement. This record has - a status of ABORTED, and the **currentStateChangeId** column in the - **settlementParticipantCurrency** table for that participant record is - changed to point to this new record. - -3. A new record is added to the **settlementWindowStateChange** table for each - settlement window in the settlement. This record has a status of ABORTED, - and the **currentStateChangeId** column in the settlementWindow table for - that window is changed to point to this new record. - -4. A new record is added to the **settlementStateChange** table for the - settlement. This record has a status of ABORTED, and the - **currentStateChangeId** column in the **settlement** table is changed to - point to this new record. - -5. If positions have been reserved for net creditors as a result of the - settlement (see Section 5.1.7.3 above,) then a balancing entry will be - created in the **participantPositionChange** table to reverse the - reservation of funds. This action does not at present reverse any change to - the account’s Net Debit Cap that may have been made as a consequence of this - reservation. - -6. Any records created in the **transfers** table (see Section 5.1.7.2 above) - will have their state changed in two steps by adding records to the - **transferStateChange** table. The first step will change the transfer state - to REJECTED. The second step will change the state to ABORTED. - -Question: should there be/is there a time-out after which a settlement will be -aborted if it has not completed? If there is, how is it set? No, there isn’t -timeout on a settlement level. But when transfers are prepared (for -PS_TRANSFERS_RECORED) expiration is set on a transfer level. Its value is -controlled by a Config.TRANSFER_VALIDITY_SECONDS, which currently defaults to -432000 seconds, which equals 5 days. It is big enough to avoid expiration. -Still, if that happens, it would leave the data in an unrecoverable by the API -state. This is very good point and should be certainly addressed with the next -increment! - -Recording the deposit of funds ------------------------------- - -As participants are informed of their liabilities under the settlement, it is -expected that they will deposit funds in their settlement account to cover those -liabilities. These activities are recorded via the central ledger administration -interface resource **recordFundsIn**. - -This action is called through a POST to the administration interface, giving the -name of the participant and the account to be credited in the form POST -/participants/{participantName}/accounts/{accountId} (e.g. **POST -/participants/myDfsp/accounts/1234**) The content of this message is as follows. - -1. transferId: a UUID to be used to identify the transfer in the switch. - -2. externalReference: a reference used to identify the transfer for the - administrator - -3. action: this should be set to “recordFundsIn” for recording funds in. - -4. reason: the reason why the transfer is being made. - -5. amount: the amount of the transfer. - - 1. amount: the actual amount being transferred - - 2. currency: the ISO 4217 code of the currency of the deposit. - -6. extensionList: a series of key/value pairs which are used to carry - additional information - -When an administrator records that a participant has deposited funds to an -account, the amount deposited is recorded in an entry in the **transfer** table. -The parties to the transfer are recorded by entries in the -**transferParticipant** table, with a ledger account type of the type requested -in the POST for the participant and HUB_RECONCILIATION for the balancing entry. -For deposits, the participant account will be the creditor and the -HUB_RECONCILIATION account the debtor. The application will currently reject -requests to this interface which do not have a ledger account type of -SETTLEMENT. - -A deposit goes through the following changes of state: - -1. A record is created for the transfer in the **transferStateChange** table - with a state of RECEIVED_PREPARE. - -2. Next, a record is created in the **transferStateChange** table with the - state RESERVED. This also creates a record in the - **participantPositionChange** table to record the reservation of funds in - the HUB_RECONCILIATION account, and the **participantPosition** table’s - value for that account is updated. - -3. Finally, a record is created in the **transferStateChange** table with the - state COMMITTED. After this act, records are created in the - **participantPositionChange** table for the creditor account to record the - completion of the deposit, and the appropriate record in the - **participantPosition** table has its balance updated. - -These changes of state are simply chained together in sequence. There is no -interval or trigger between the steps. - -This activity has no direct effect on the settlement process or on the Net Debit -Cap. - -Recording the withdrawal of funds ---------------------------------- - -At various times, participants may wish to withdraw funds from their settlement -accounts: for instance, if they are long-term net beneficiaries of transfers and -are building up a surplus of liquidity. These activities are recorded via a -two-phase process. In the first phase, the funds for the proposed withdrawal are -reserved via the central ledger administration interface resource -**recordFundsOutPrepareReserve**. In the second phase, the withdrawal is -committed via the **recprdFundsOutCommit** resource or aborted through the -**recordFundsOutAbort** resource. - -These activities are defined below. - -### **recordFundsOutPrepareReserve** - -This action is called through a POST to the administration interface, giving the -name of the participant and the account to be credited (e.g. **POST -/participants/myDfsp/accounts/1234**) The content of this message is as follows. - -1. transferId: a UUID to be used to identify the transfer in the switch. - -2. externalReference: a reference used to identify the transfer for the - administrator - -3. action: this should be set to “recordFundsOutPrepareReserve” for recording - funds withdrawals. - -4. reason: the reason why the transfer is being made. - -5. amount: the amount of the transfer. - - 1. amount: the actual amount being transferred - - 2. currency: the ISO 4217 code of the currency of the deposit. - -6. extensionList: a series of key/value pairs which are used to carry - additional information - -When an administrator records that a participant has requested the withdrawal of -funds from an account, the amount to be withdrawn is recorded in an entry in the -**transfer** table. The parties to the transfer are recorded by entries in the -**transferParticipant** table, with a ledger account type of the type requested -in the POST for the participant and HUB_RECONCILIATION for the balancing entry. -For withdrawals, the participant account will be the debtor and the -HUB_RECONCILIATION account the creditor. The application will currently reject -requests to this interface which do not have a ledger account type of -SETTLEMENT. - -Reservation of a withdrawal goes through the following changes of state: - -1. A record is created for the transfer in the **transferStateChange** table - with a state of RECEIVED_PREPARE. - -2. Next, a record is created in the **transferStateChange** table with the - state RESERVED. This also creates a record in the - **participantPositionChange** table to record the reservation of funds in - the participant’s settlement account, and the **participantPosition** - table’s value for that account is updated. - -These changes of state are simply chained together in sequence. There is no -interval or trigger between the steps.**recordFundsOutCommit** - -This action is called through a POST to the administration interface, giving the -name of the participant and the account to be credited (e.g. **POST -/participants/myDfsp/accounts/1234**) The content of this message is as follows. - -1. transferId: a UUID to be used to tie the commit to the preceding reservation - in the switch. - -2. externalReference: a reference used to identify the transfer for the - administrator - -3. action: this should be set to “recordFundsOutCommit” for recording funds - commitments. - -4. reason: the reason why the transfer is being made. - -5. amount: the amount of the transfer. - - 1. amount: the actual amount being transferred - - 2. currency: the ISO 4217 code of the currency of the deposit. - -6. extensionList: a series of key/value pairs which are used to carry - additional information - -When an administrator records that a participant wants to commit the withdrawal -of funds from an account, the original entry in the **transfer** table is -identified. The parties to the transfer are recorded by entries in the -**transferParticipant** table, with a ledger account type of the type requested -in the POST for the participant and HUB_RECONCILIATION for the balancing entry. -For withdrawals, the participant account will be the debtor and the -HUB_RECONCILIATION account the creditor. The application will currently reject -requests to this interface which do not have a ledger account type of -SETTLEMENT. - -Commitment of a withdrawal goes through the following changes of state: a record -is created in the **transferStateChange** table with the state COMMITTED. After -this act, records are created in the **participantPositionChange** table for the -creditor account to record the completion of the deposit, and the appropriate -record in the **participantPosition** table has its balance updated. These -changes of state are simply chained together in sequence. There is no interval -or trigger between the steps. - -This activity has no direct effect on the settlement process or on the Net Debit -Cap. - -Proposed enhancements -===================== - -This section describes the enhancements to the existing OSS settlement process -(described in Section 4.1 above) which are proposed. Each enhancement is shown -in a separate section and, where there are dependencies between enhancements, -these are listed in the enhancement’s description. - -Request settlement by currency [EPIC] -------------------------------------- - -The following changes are required to support settling separately for different -currencies. - -### Database changes - -The following changes are required to support multi-currency settlement. - -#### Addition of a settlementWindowContent table [Story \#1] - -A new table will be added to the database. The name of this table will be -**settlementWindowContent**. The table will contain an entry for each item of -content in a given settlement window, broken down by ledger account type and -currency. The full column structure of the table is as follows: - -| **Column name** | **Description** | **Attributes** | -|-----------------------------------------|---------------------------------------------------|---------------------------------------------------------------------------------------| -| **settlementWindowContentId** | Auto-generated key for the record. | BIGINT(20). Unsigned, not null, primary key, autoincrement | -| **settlementWindowId** | The settlement window that the record belongs to. | BIGINT(20). Unsigned, not null. Foreign Key to **settlementWindow** | -| **ledgerAccountTypeId** | The ledger account that the record refers to. | INT(10). Unsigned, not null. Foreign key to **ledgerAccountType** | -| **currencyId** | The currency that the record refers to. | VARCHAR(3). Not null. Foreign key to **currency**. | -| **createdDate** | The date and time when the record was created. | DATETIME. Not null. Defaults to CURRENT_TIMESTAMP. | -| **currentStateChangeId** | The current state of this entry. | BIGINT(20). Unsigned. Foreign key to **settlementWindowContentStateChange** | - -  - -#### Addition of a settlementWindowContentStateChange table [Story \#2] - -A new table will be added to the database. The name of this table will be -**settlementWindowContentStateChange**. The table will track changes to the -status of entries in the **settlementWindowContent** table. The full column -structure of the table is as follows: - -| **Column name** | **Description** | **Attributes** | -|------------------------------------------|---------------------------------------------------------------------|----------------------------------------------------------------------------| -| **settlementWindowContentStateChangeId** | Auto-generated key for the record. | BIGINT(20). Unsigned, not null, primary key, autoincrement | -| **settlementWindowContentId** | The settlement window content record whose status is being tracked. | BIGINT(20). Unsigned, not null. Foreign Key to **settlementWindowContent** | -| **settlementWindowStateId** | The record’s status. | VARCHAR(50). Not null. Foreign key to **settlementWindowState** | -| **reason** | An optional field giving the reason for the state being set. | VARCHAR(512). | -| **createdDate** | The date and time when the record was created | DATETIME. Not null. Defaults to CURRENT_TIMESTAMP | - -  - -#### Changes to the settlementTransferParticipant table [Story \#3] - -The name of the **settlementTransferParticipant** table should be changed to -**settlementContentAggregation**. - -The column structure of the **settlementContentAggregation** table should be -modified as follows: - -1. Remove the following foreign keys from the table: - 1. settlementtransferparticipant_settlementid_foreign - 2. settlementtransferparticipant_settlementwindowid_foreign -2. Remove the following columns from the table: - 1. settlementId - 2. settlementWindowId -3. Add the following column to the table: - 1. Column name: **settlementWindowContentId** - 2. Attributes: BIGINT(20), unsigned, not null -4. Add the following foreign key to the table: - 1. Name: settlementContentAggregation_settlementwindowcontent_foreign - 2. Child column **settlementWindowContentId** - 3. Refers to table: **settlementWindowContent** - 4. Refers to column: **settlementWindowContentId** - -All database scripts which use the **settlementTransferParticipant** table will -be changed to accommodate the new name and structure of the table. [Story \#8] - -Queries to filter the records in the **settlementContentAggregation** table -required for a settlement in a particular currency will need to join across from -that table to the **participantCurrency** table using the -**participantCurrencyId** column to ascertain the currency to which a particular -row refers. The **currencyId** column is held in the **participantCurrency** -table. [Story \#9] - -#### Add structures relating to settlement models [Story \#4] - -In order to support the specification of settlement models, which will include -currencies, the database changes specified in Section 6.2.1.1 below should be -added to the database. - -Settlement models describing the settlement types required for a given -implementation will be developed and tested.**[Story \#4a]** - -#### Change to settlement table [Story \#5] - -The **settlement** table in the central ledger database needs to be modified to -add a *settlementModel* column. This column should have the following -characteristics: - -- The column should be required (NOT NULL) and unsigned. -- The column’s data type should be integer(10) -- The column should be defined as a foreign key reference to the -*settlementModelId* field of the **settlementModel** table. - -When this change is applied to an existing database, a settlement model to -describe the default settlement should be created. The settlementCurrencyId -column in this model should be left blank (= all currencies.) The -settlementModel column in all existing records in the settlement table should be -set to point to this model’s ID. A script to apply this change should be -created, tested and stored in the repository. - -### Changes to processing - -The following changes to the processing code are required to support -multi-currency settlement. - -#### Change to code supporting closeSettlementWindow resource - -The existing API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) provides a single function -(**closeSettlementWindow**) to manage settlement windows. This function allows -its user to select a settlement window by ID number and to input a new status -for the window and a reason for that status. - -When a settlement window is closed, the code supporting this activity should -perform two functions, as follows. These functions should be performed in the -background and without impacting system performance. - -##### Generate records in the settlementWindowContent table [Story \#1095] - -The code should generate a record in the **settlementWindowContent** table for -each ledger entry type/currency combination found in the transfers in the -settlement window. This information can be obtained from the following query: -``` -SELECT DISTINCT - @mySettlementWindowId, pc.ledgerAccountTypeId, pc.currencyId -FROM transferFulfilment tf -INNER JOIN transferParticipant tp - ON tp.transferId = tf.transferId -INNER JOIN participantCurrency pc - ON pc.participantCurrencyId = tp.participantCurrencyId -WHERE tf.settlementWindowId = @mySettlementWindowId; -``` - -##### Generate records in the settlementContentAggregation table [Story \#1095] - -The code should calculate the aggregate values for all transfers which form part -of that settlement window and store them in the **settlementContentAggregation** -table. Aggregates should be produced for the following segmentation: - -1. Participant -2. Currency -3. Ledger account type -4. Participant role type -5. Ledger entry type - -The following query will perform this function for a given settlement window: - -``` -INSERT INTO settlementContentAggregation - (settlementWindowContentId, participantCurrencyId, - transferParticipantRoleTypeId, ledgerEntryTypeId, amount) -SELECT swc.settlementWindowContentId, pc.participantCurrencyId, - tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId, SUM(tp.amount) -FROM transferFulfilment tf -INNER JOIN transferParticipant tp - ON tf.transferId = tp.transferId -INNER JOIN participantCurrency pc - ON pc.participantCurrencyId = tp.participantCurrencyId -INNER JOIN settlementWindowContent swc - ON swc.settlementWindowId = tf.settlementWindowId -  AND swc.ledgerAccountTypeId = pc.ledgerAccountTypeId - AND swc.currencyId = pc.currencyId -WHERE tf.settlementWindowId = @mySettlementWindowId -GROUP BY swc.settlementWindowContentId, pc.participantCurrencyId, - tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId; -``` - -#### createSettlement - -The parameters for the **createSettlement** resource should be extended to -include the settlement model for which the settlement is required. - -When the settlement is created, the settlement model for which the settlement is -required should be added to the new row in the **settlement** table. [Story \#1097] - -When a settlement is requested, the switch should check that the settlement -model for which settlement is being requested requires NET settlement and not -GROSS settlement. If the requested settlement model requires GROSS settlement, -then the request should be rejected with an error. - -The verification procedures associated with the **createSettlement** resource -should be changed to check that some of the settlement windows associated with -the proposed settlement contain entries for the settlement model requested. If -there are no entries for the settlement model requested for any of the -settlement windows requested, then an error should be returned and the -settlement request rejected. [Story \#1096] - -#### Updating the progress of a settlement - -When the status for a settlement participant is changed to SETTLED, this will result in -changes to the status of all the records in the **settlementContentAggregation** -table for the given participant, identified by the compound key: settlementId + participantCurrencyId. - -[Story \#16] - -The code should then check to see if, as a result of the updates to the records -in **settlementContentAggregation**, all records for a given combination of -settlement window, ledger account type and currency have the same status. If -they have, then the appropriate record in the **settlementWindowContent** table -should be updated to have that status. - -The code should then check to see if all records in the -**settlementWindowContent** table for a given settlement window have the same -status. If they have, then the appropriate record in the **settlementWindow** - -Support continuous gross settlement ------------------------------------ - -Continuous Gross Settlement is a settlement model in which each transaction is -settled as soon as it is fulfilled. The following changes are required to -implement this change. - -### Database changes - -The database changes shown in Section 8 below should be implemented. These can -be summarised as follows: - -#### Changes to support the settlement model - -A number of new tables are required to define a settlement model and to store -the enumerations for its definition types. This comprises the following tables -in the ERD: - -- settlementDelay - -- settlementInterchange - -- settlementModel - -In addition, the **settlementmodel** table has foreign keys to two existing -tables, as follows: - -1. A foreign key to the **currency** table to enable the settlement model to - settle only scheme accounts in a particular currency. If this entry is - blank, this should be interpreted as saying that the settlement model - settles all currencies that are not specified as being settled by other - settlement models for the same account type. - -2. A foreign key to the **ledgerAccountType** table. This specifies that the - settlement model settles accounts of this type. - -#### Changes to the **ledgeraccounttype** table - -The current **ledgeraccounttype** table stores a number of entries for account -types which should not be used for settlements – for instance, -HUB_MULTILATERAL_SETTLEMENT. A column should therefore be added to the -**ledgeraccounttype** table to indicate whether the account type can be attached -to a settlement model or not. This column is called **settleable**, and is -specified as a Boolean value, NOT NULL and with a default of FALSE. - -Of the existing ledger account types, PRINCIPAL_VALUE, INTERCHANGE_FEE and -HUB_FEE should be marked as capable of being attached to settlement models (this -value should be TRUE.) For all other ledger account types, the column should be -set to FALSE. If new ledger account types are added to this table via the -eventual settlement API, then they should have a value of TRUE. - -#### Changes to the **ledgerentrytype** table - -Implementation of the TIPS settlement model requires an explicit association -between ledger entry types and the account types in which they should appear. -Since each ledger entry type should only appear in a single account type, though -multiple ledger entry types may appear in a given account type, this is modelled -by including a foreign key reference to the **ledgeraccounttype** table as a -column in the **ledgerentrytype** table. It should be noted that this applies -only to ledger entry types which are associated with a settlement model, as -described in Section 6.2.1.2 above. The assignment of existing entries in the -database would be as follows: - -| Ledger Entry Type | Ledger Account Type | -|-------------------|---------------------------| -| PRINCIPAL_VALUE | POSITION | -| INTERCHANGE_FEE | INTERCHANGE_FEE | -| HUB_FEE | HUB_FEE | -| | | - -#### Changes to the **settlement** table - -The **settlement** table should have a column added to it to allow the -settlement model to be used in settling it to be specified. The column should be -called *settlementModelId*. It should have the same data type as the equivalent -field in the **settlementModel** table, and should be a foreign key into that -table. It should be defined as not null. - -#### Changes to the **settlementWindow** table - -As well as settlements, individual settlement windows will need to be assigned -to settlement models. The **settlementWindow** table should therefore have a -column added to it to allow the settlement model to be used in settling it to be -specified. The column should be called *settlementModelId*. It should have the -same data type as the equivalent field in the **settlementModel** table, and -should be a foreign key into that table. It should be defined as not null. - -This concludes the list of schema changes required to support the TIPS -settlement models - -### API changes - -API Support for the settlement functionality required for TIPS will include the -following functions: - -#### Close a settlement window - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a -**closeSettlementWindow** resource. This function allows its user to select a -settlement window by ID number and to input a new status for the window and a -reason for that status. This resource will retain its current signature, but the -code supporting it needs to change as follows. - -When a settlement window is closed, the system should create a new settlement -window with the same settlement model as the newly closed settlement window, and -should make this the active window. - -When a settlement window is closed, the code supporting this activity should -calculate the aggregate values for all transfers which form part of that -settlement window and store them in the **settlementTransferParticipant** table. -Aggregates should be produced for the following segmentation: - -1. Participant - -2. Currency - -3. Ledger account type - -4. Participant role type - -5. Ledger entry type - -The following example code will produce the aggregations required for a given -settlement window (identified as \@MyWindow in the example): - -SELECT - -S.settlementId - -, W.settlementWindowId - -, P.participantCurrencyId - -, P.transferParticipantRoleTypeId - -, P.ledgerEntryTypeId - -, SUM(P.amount) - -, CURRENT_TIMESTAMP AS createdDate - -FROM - -settlementWindow W INNER JOIN settlementModel M ON W.settlementModelId = -M.idsettlementModel - -INNER JOIN settlementSettlementWindow S ON W.settlementWindowId = -S.settlementWindowId - -INNER JOIN ledgerAccountType L ON M.idsettlementModel = L.settlementModelId - -INNER JOIN transferFulfilment F ON W.settlementWindowId = F.settlementWindowId - -INNER JOIN transferParticipant P ON F.transferId = P.TransferId - -INNER JOIN participantCurrency PC ON P.participantCurrencyId = -PC.participantCurrencyId - -AND PC.ledgerAccountTypeId = L.ledgerAccountTypeId - -WHERE - -W.settlementWindowId = \@MyWindow - -AND - -(PC.currencyId = M.settlementcurrencyId OR M.settlementcurrencyId IS NULL) - -GROUP BY - -S.settlementId - -, W.settlementWindowId - -, P.participantCurrencyId - -, P.transferParticipantRoleTypeId - -, P.ledgerEntryTypeId; - -#### Getting information about a settlement window - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a -**getSettlementWindowById** resource. This function allows its user to obtain -information about a settlement window by giving the ID that was returned when -the settlement window was created. - -This call returns a **SettlementWindow** object. This object will need to be -extended to include the name of the settlement model to which the settlement -window belongs. - -#### Getting information about settlement windows using parameters - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a -**getSettlementWindowsByParams** resource. This function allows its user to -obtain information about all settlement windows which meet the criteria -specified by the user. The following changes will need to be made to this call: - -1. The parameters supported by the call will need to be extended to allow a - user to request settlement windows by settlement model. The user should be - able to enter the name of a settlement model. - -2. This call returns an array of **SettlementWindow** objects. It is assumed - that these objects will have been changed by the changes specified in - Section 6.2.2.2 above, and that no further processing will be required for - this call. - -#### Requesting a settlement - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a **createSettlement** -resource. This function allows its user to request a settlement for a given set -of settlement windows, which are passed to the resource as parameters. The -following changes will need to be made to this call: - -The parameters for the **createSettlement** resource are defined in the -**SettlementEventPayload** object. This object will need to have a parameter -added to specify the settlement model which is to be settled. The parameter -should be called *settlementModel*, and it should be a string. It should be -required. - -The following validation should be performed on this parameter when the request -is received via the API: - -1. The content of the parameter is a case-insensitive match for an active entry - in the **settlementmodel** table, ignoring whitespace. - -2. The *settlementtypeid* column in the record in the selected settlement model - should not point to a record in the **settlementdelay** table whose - *settlementDelayName* value is “IMMEDIATE”. If it does, the request should - be rejected and an error message returned to the caller. - -The id of the settlement model requested should be stored in the -settlementModelId column of the row created in the **settlement** table to -describe the settlement. - -#### Returning the status of a settlement - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a **getSettlementById** -resource. This function allows its user to obtain information about a settlement -by giving the ID that was returned when the settlement was created. - -Information about settlements is returned in a **Settlement** object. A -parameter should be added to the Settlement object to record the settlement -model which is being settled by the settlement. - -The parameter should be called *settlementModel*, and it should be a string. It -should be required. - -**Note**: when a settlement is requested, a reason is given; but the -**Settlement** object does not contain the reason. It might be worth including -this in the definition of the **Settlement** object. - -#### Getting information about settlements using parameters - -The existing API definition[2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a -**getSettlementsByParams** resource. This function allows its user to obtain -information about all settlements by giving the ID that was returned when the -settlement was created. The following changes will need to be made to this call: - -1. This call returns an array of **Settlement** objects. It is assumed that - these objects will have been changed by the changes specified in Section - 6.2.2.5 above, and that no further processing will be required for this - call. - -#### Getting information about a specific participant in a settlement - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a -**getSettlementBySettlementParticipant** resource. This function allows its user -to obtain information about a settlement which meet the criteria specified by -the user. The following changes will need to be made to this call: - -1. This call returns a **Settlement** object. It is assumed that this object - will have been changed by the changes specified in Section 6.2.2.5 above, - and that no further processing will be required for this call. - -#### Updating a specific settlement - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an -**updateSettlementById** resource. This function allows its user to update -information about a settlement by giving the ID that was returned when the -settlement was created. - -This call returns a **Settlement** object. It is assumed that this object will -have been changed by the changes specified in Section 6.2.2.5 above, and that no -further processing will be required for this call. - -#### Updating a settlement for a specific participant - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an -**updateSettlementBySettlementParticipant** resource. This function allows its -user to update information about a settlement by giving the ID that was returned -when the settlement was created, and the participant whose information is to be -updated. - -This call returns a **Settlement** object. It is assumed that this object will -have been changed by the changes specified in Section 6.2.2.5 above, and that no -further processing will be required for this call. - -#### Updating a settlement for a specific participant and account - -The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an -**updateSettlementBySettlementParticipantAccount** resource. This function -allows its user to update information about a settlement by giving the ID that -was returned when the settlement was created, and the participant and account -whose information is to be updated. - -This call returns a **Settlement** object. It is assumed that this object will -have been changed by the changes specified in Section 6.2.2.5 above, and that no -further processing will be required for this call. - -#### Recording the deposit of funds by a participant - -The existing administration API [3](https://mojaloop.io/documentation/api/central-ledger-api-specification.html) contains functions to enable -an administrator to record a deposit made by a participant to an account. This -process is described in Section 5.2 above. The API should be changed to align it -with the structures used in the existing settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json). In addition, the signature of the API should be extended to allow the -administrator to specify the account type that will be updated by the deposit. - -#### Recording the withdrawal of funds by a participant - -The existing administration API [3](https://mojaloop.io/documentation/api/central-ledger-api-specification.html) contains functions to enable -an administrator to record a withdrawal made by a participant from an account. -This process is described in Section 5.3 above. The API should be changed to -align it with the structures used in the existing settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json). In addition, the signature of the API should be extended to allow -the administrator to specify the account type that will be updated by the -withdrawal. - -#### New resource: openSettlementWindow - -In the current architecture, an instance of each settlement window is created -when the instance is set up, and subsequent settlement windows are created by -closing the current settlement window. In the new settlement management -structure, we will need the ability to create new settlement windows where no -predecessors exist: for instance, when an administrator decides to settle a -particular currency using a different settlement model. - -### Processing changes - -The following processing changes are required to implement the changes required -to support continuous gross settlement. - -#### Attributing ledger entries to the correct ledger account type - -When a ledger entry is created, it should be assigned to the ledger account type -specified in the *ledgeraccounttypeid* column of the row in the -**ledgerentrytype** table appropriate to the ledger entry type which is being -created. - -For example: if a normal entry representing a transfer is being created, it will -have a ledger entry type of PRINCIPAL_VALUE. It should be assigned to the -POSITION account type (the default position at present.) This implies that the -match described in Section 6.2.1.3 above has been implemented. - -Question: how does the switch decide whether or when to construct a record in -the **participantPositionChange** table? How would it be possible to select the -ledger account type to which the position refers? - -Processing interchange fees ----------------------------- - -In order to support the scheme model implemented by TIPS, we need to generate -and settle liabilities incurred as a consequence of making transfers between -particular types of customer. The general form of this rule is as follows: - -- If the transaction is a wallet-to-wallet P2P transaction, then the receiver - DFSP pays the sender DFSP 0.6% of the amount of the transaction. - -- No interchange fees are levied for on-us transactions. - -The business decisions around this requirement are: - -1. The definition of whether or not a payee account is a wallet will be - returned by the payee DFSP as part of customer discovery. The mechanism by - which this is implemented is outside the scope of this document. - -2. Interchange fees will be captured by the switch when the transfers which - incur them are completed. - -3. Interchange fees will have the ledger entry type INTERCHANGE_FEE and will be - recorded in accounts whose type is INTERCHANGE_FEE. - -4. Interchange fees will be settled multilaterally, net and deferred. It is - expected that this settlement will take place monthly. - -5. Interchange fees do not require liability cover by participants. - -This functionality will be implemented as a partial instance of a general -process for defining and executing rules, and for taking actions based on the -outcome of evaluation of a rule. For this particular case, we propose the -changes described in the following sections. - -### Part 1: Run script for batch update of interchange fees when settlement window is closed. - -Include stories to manage account type definition - -### Part 2: Add reservation on prepare using script and modify fulfilment to fulfil all ledger types for which an entry has been made - -### Evaluating a rule - -The process of evaluating a rule is based on the following assumptions: - -1. There will be a standard form of rule evaluation with the following - structure: - - 1. A transaction object will be passed as the parameter to the rule - evaluation function. - - 2. The rule evaluation itself will use a complex if statement. - - 3. If the rule evaluates to TRUE, then an action should be executed as - described in Section 6.3.2 below. - -An example of a rule function to evaluate a TIPS interchange fee rule could be: - -function evaluateInterchangeFee (transaction) { - -if( - -(transaction.payee.fspId.toLowerCase() != transaction.payer.fspId.toLowerCase()) - -&& (transaction.extensionList[“payerAccountType”].toLowerCase() == -"Wallet".toLowerCase() - -&& transaction.extensionList[“payeeAccountType”].toLowerCase() == -"Wallet".toLowerCase()) - -&& (transaction.transactionType.scenario.toLowerCase() == -"TRANSFER".toLowerCase() - -&& transaction.transactionType.initiator.toLowerCase() == "PAYER".toLowerCase() - -&& transaction.transactionType.initiatorType.toLowerCase() == -"CONSUMER".toLowerCase()) - -) { - -// Do some good stuff - -}; - -}; - -### Taking action after evaluating a rule - -If a rule evaluates to TRUE as described in Section 6.3.1 above, then -appropriate action should be taken. In the case of the immediate example of -interchange fees, the action taken should be to add two entries to the -participants’ interchange fee accounts, on recording the debit from the payee of -the interchange fee amount and the other recording the credit to the payer of -the interchange fee amount. - -A simple yet general way of supporting actions of this type is to define a class -(which might be called ruleAction) and adding methods to it to represent the -actions to be taken. The rule evaluation function can then instantiate the class -and call the appropriate function. - -In the case of the interchange fees, we would define an action called -addLedgerEntry, with the following parameters: - -1. The transfer ID for which the ledger entry is being created - -2. The ledger entry type to be used - -3. The currency in which the amount is denominated - -4. The amount of the fee - -5. The FSP ID of the credit party - -6. The FSP ID of the debit party - -This might appear in the rule evaluation function as: - -myAction.addLedgerEntry(transaction.transactionId, - -transaction.transactionId, - -"INTERCHANGE_FEE“, - -transaction.currency, - -transaction.amount\*0.006, - -transaction.payer.fspId, - -transaction.payee.fspId); - -### Providing a generic framework for rule evaluation - -Finally, we will need to provide a generic framework to trigger the evaluation -of rules. This should be an array of evaluation functions, which are triggered -when the status of a transfer changes to FULFILLED. - -Process transfers for continuous gross settlement [EPIC] -------------------------------------------------- - -When a settlement model specifies that an account is to be settled immediate gross, then each ledger entry which is of a type belonging to that scheme account should be settled immediately. This immediate settlement should have the following characteristics: - -- It should be performed by a process which is logged. -- It should be performed immediately, so that participants can check their current position against the transfers that comprise it. -- It should be aggregated to settlement window level, so that the checks which are currently performed on the overall status of a settlement window will continue to work. - -The following sections describe the changes that are required to process transfers for accounts which are settled immediate gross. - -### Database changes - -The following changes are required to the database to implement transfer processing for continuous gross settlement - -#### Addition of a new table to store changes in state - -A new table should be added to store changes in state for individual transfers. The name of this table should be **transferParticipantStateChange**. Its column structure should be as follows: - -1. The unique key to the record. Column name: **transferParticipantStateChangeId**; type: unsigned BIGINT; not nullable; primary key -2. The record in **TransferParticipant** whose state change this record marks. Column name: **transferParticipantId**; type: unsigned BIGINT; not nullable; foreign key to the **transferParticipantId** column of the **transferParticipant** table. -3. The current state of the record in **transferParticipant** to which this state record refers. Column name: **settlementWindowStateId**; data type VARCHAR(50); not nullable; foreign key to the **settlementWindowStateId** column of the **settlementWindowState** table. -4. An explanation of the state change. Column name: **reason**; type: VARCHAR(512); nullable. -5. The date and time when the change was recorded. Column name: **createdDate**; type DATETIME; not nullable; default value **CURRENT_TIMESTAMP**. - -#### Changes to the TransferParticipant table - -The **transferParticipant** table should have a new column added to store the current state of the transaction. The name of the column should be **currentStateChangeId** and its data type should be UNSIGNED BIGINT. The column should be nullable, and it should have a foreign key reference to the **transferParticipantStateChangeId** column of the **transferParticipantStateChange** table. - -### Processing changes - -The following changes to processing are required to support immediate settlement of gross ledger entries. - -#### Generating entries in settlementTransferParticipant - -When a new row is inserted in the **transferParticipant** table, the value of the **currentStateChangeId** column for that row should be set to NULL. - - - -#### Generating entries in settlementContentAggregation - -The following changes to the process that creates aggregation records in the **settlementContentAggregation** table are required. - -1. The aggregation process for a settlement window may not be performed if there are any records in the **transferParticipant** table which belong to the settlement window to be aggregated (as defined by joining the **transferParticipant** records to the matching records in the **transferFulfilment** table on the **transferId** column in both tables) and which have their **currentStateChangeId** column set to NULL. -2. When there are no records in **transferParticipant** which meet the blocking criteria described in step 1 above, then all records belonging to the settlement window which has just been closed, and which currently have the status OPEN, should have their status set to CLOSED. This means: a record should be added to the **transferParticipantStateChange** table for the qualifying **transferParticipant** record whose status is CLOSED, and the **currentStateChangeId** column for the qualifying **transferParticipant** record should be set to point to the newly created record. -2. When aggregating records for insertion into the **settlementContentAggregation** table, if all the records in the **transferParticipant** table which are to be aggregated into a single record in the **settlementContentAggregation** table have the same value in their **currentStateChangeId** column, then the value of the **currentStateId** column in the newly created record in the **settlementContentAggregation** table should be set as follows. The value of the **currentStateId** column in the newly created record in the **settlementContentAggregation** table should be set to the shared value in the constituent records from the **transferParticipant** table, except in the following case: if the shared value in the constituent records from the **transferParticipant** table is OPEN, then the value of the **currentStateId** column should be set to the value CLOSED. - -#### Marking transfers as settled - -The following additional processes are required in order to mark ledger entries which are settled immediate gross as having been settled. - -##### Queueing transfers for settlement processing - -When a transfer is completed, a record is generated in the **transferFulfilment** table. As part of the process that generates this record, the transfer should be placed on a Kafka stream for immediate settlement processing. - -##### Processing settlements - -A new service should be developed for processing settlements. The characteristics of the service should be as follows: - -1. Pick a transfer from the Kafka stream holding transfers awaiting settlement processing. There is no requirement for sequence preservation, so this service can pick up multiple transfer entries if this would accelerate processing. -2 For each record in the **transferParticipant** table which belongs to the transfer *and* whose **ledgerEntryType** column specifies a ledger entry type which belongs to a settlement model which is settled both GROSS and IMMEDIATE, the service should generate consecutive records in the **transferParticipantStateChange** table with the values: CLOSED, PENDING_SETTLEMENT, and SETTLED, in that order. The **currentStateChangeId** column for the record in the **transferParticipant** table should be set to point to the record in the **transferParticipantStateChange** table whose value is SETTLED. -3 For all other records in the **transferParticipant** table which belong to the transfer, the service should generate a record in the **transferParticipantStateChange** table with a value of OPEN. The **currentStateChangeId** column for the record in the **transferParticipant** table should be set to point to the record in the **transferParticipantStateChange** table which was created. - -#### Updating status values for net settlements - -When the status is updated for a participant in a settlement which belongs to a settlement model which is not settled both GROSS and IMMEDIATE, then the constituent records for that participant in the settlement in the **transferParticipant** table need to be updated. The rules for this are: - -1. When the settlement is created, all the records in **transferParticipant** which belong to a transfer which belongs to a window which belongs to the settlement being created (i.e. which are contained in the inner join between **transferParticipant**, **transferfulfilment** (on **transferId**) and **settlementSettlementWindow** (on **settlementWindowId**) for the settlement Id which is being created) should have a record created in **settlementContentAggregationStateChange** with the **settlementWindowStateId** column set to PENDING_SETTLEMENT. -2. When a participant's settlement status is updated to SETTLED in **settlementParticipantCurrency**, then all the records in **transferParticipant** for settlement windows which belong to that settlement, and whose participant and currency IDs match the participant and currency of the records in **settlementParticipantCurrency** which have been updated, shoul have their status set to SETTLED. - -Domain class diagram -==================== - -ERD -=== - -The following ERD describes the new data structures required to model settlements. - -![](/mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png) - -Enumerations ------------- - -The following enumerations are required to support the new ERD: -``` -DELETE FROM settlementGranularity; -INSERT INTO settlementGranularity (name) -VALUES ('GROSS'), ('NET'); - -DELETE FROM settlementInterchange; -INSERT INTO settlementInterchange (name) -VALUES ('BILATERAL'), ('MULTILATERAL'); - -DELETE FROM settlementDelay; -INSERT INTO settlementDelay(name) -VALUES ('IMMEDIATE'), ('DEFERRED'); -``` +--- +title: "OSS Settlement \n \nBusiness Requirements Document" +--- + +Introduction +============ + +This document describes the requirements for changes to the functionality of the +OSS Mojaloop switch to support: + +1. The immediate requirement for Mowali of being able to settle according to + different timetables for different currencies. + +2. The requirement for TIPS to be able to settle gross via a pooled account. + +3. The requirement for TIPS to use the settlement process for interchange fees. + +4. The requirement for Mojaloop to support the evolving Settlement API + +References +========== + +The following external references are used in this document: + +| Reference | Document | +| :--- | :--- | +| 1 | [Open API for FSP Interoperability Specification](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html) | +| 2 | [Settlement API Interface Definition](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json)| +| 3 | [Current administration API definition](https://mojaloop.io/documentation/api/central-ledger-api-specification.html)| +| | | + +Versions +======== + +| Version | Description | Author | Date | Changes tracked | +|:---------|:------------------|:------------------|:------------|:-----------------| +| 1.0 | Baseline version | Michael Richards | 2 Dec 2019 | No | +| | | | | | + +Definition of terms +=================== + +Settlement model +---------------- + +A settlement model defines a kind of settlement within the scheme. Settlement +models can be defined by scheme administrators, and have the following +characteristics: + +1. They can support settlement either gross or net settlements. If gross, then + a settlement is executed after each transfer is completed. If net, a group + of transfers is settled together. + +2. They can support either multilateral or bilateral settlements. If + settlements are multilateral, each participant settles with the scheme for + the net of its transfers which are included in the settlement. If they are + multilateral, each participant settles separately with each of the other + participants and the scheme is not a party to the settlement. + +3. They can support either deferred or immediate settlements. If settlements + are immediate, they are actioned immediately they are completed. If they are + deferred, they are actioned after a period of delay. + +4. They can support continuous or discontinuous settlements. Discontinuous + settlements require a formal approval from a resource outside the system to + confirm that they have been completed. Continuous settlements can be + approved from within the switch, provided that the criteria for approval are + met. + +5. They can require liquidity support or not. + +Ledger account type +------------------- + +A ledger account type defines a type of internal account. Current values are: + +1. POSITION. Accounts of this type are used for provisioning transfers + +2. SETTLEMENT. Accounts of this type are intended to be reflections of + Settlement Accounts held at the Settlement Bank + +3. HUB_RECONCILIATION. Each implementation of the switch has one account of + this type for each currency supported by the switch, owned by the virtual + DFSP which represents the Hub in the implementation. The account is used + during FUNDS IN/OUT operations to represent movements in participants’ + SETTLEMENT accounts. + +4. HUB_MULTILATERAL_SETTLEMENT. Each implementation of the switch has one + account of this type for each currency supported by the switch, owned by the + virtual DFSP which represents the Hub in the implementation. This account + type is used to record counterparty information for net amounts paid to or + from participants as part of settlements. Entries in this account represent + balancing values corresponding with the net value in a participant’s + POSITION account for a given settlement. + +5. HUB_FEE. Accounts of this type represent accounts into which fees are + collected, or from which they are disbursed. (Not implemented) + +Ledger entry type +----------------- + +A ledger entry type categorises the type of funds which are the content of a +transfer and which are due to or from a participant as a consequence of that +transfer. The current values are: + +1. PRINCIPLE_VALUE. This designates the funds moved as the content of a + transfer in the Interoperability API Specification sense of that term (i.e. + the **amount.amount** item in the **Transaction** object described in + [Section 7.4.17](https://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#7317-ilpcondition) of the Interoperability API specification[1](https://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html).) It should be + spelt “principal.” + +2. INTERCHANGE_FEE. This designates fees paid between participants in the + system. (Not implemented) + +3. HUB_FEE. This designates fees paid between participants and the scheme. (Not + implemented) + +4. POSITION_DEPOSIT. This is used to designate funds transfers which are + intended to increase the value of the position in a particular ledger + account. (Not implemented) + +5. POSITION_WITHDRAWAL. This is used to designate funds transfers which are + intended to reduce the value of the position in a particular ledger account. + (Not implemented) + +6. SETTLEMENT_NET_RECIPIENT. This is used to designate funds which a + participant is owed by the counterparty as part of a settlement (in a + multilateral settlement model, the counterparty will be the hub; in a + bilateral settlement model, it will be another party.) + +7. SETTLEMENT_NET_SENDER. This is used to designate funds which a participant + owes to the counterparty as part of a settlement (in a multilateral + settlement model, the counterparty will be the hub; in a bilateral + settlement model, it will be another party.) + +8. SETTLEMENT_NET_ZERO. This is used to generate formal records where a + participant’s net position in a settlement is zero. + +9. RECORD_FUNDS_IN. This is used to record funds deposited by a participant to + the SETTLEMENT account. + +10. RECORD_FUNDS_OUT. This is used to record funds withdrawn by a participant + from the SETTLEMENT account. + +The last seven of these types relate to the internal structure of the switch and +should be neither visible to nor modifiable by a scheme. The first three fall +into a category which is expected to be extensible by the scheme. The table does +not currently have an indicator to mark this distinction, but one is proposed in +Section TODO. + +Participant role types +---------------------- + +A participant role type defines the role that a particular participant is +playing in a given transaction. The current values of this table are: + +1. PAYER_DFSP. The participant is the debtor in a transfer. + +2. PAYEE_DFSP. The participant is a creditor in a transfer. + +3. HUB. The participant is representing the scheme, and may be either the + creditor or the debtor in a transaction. + +4. DFSP_SETTLEMENT. The participant represents the settlement account of a + participant in the scheme. It may be either the creditor or the debtor in a + transaction. It is used during FUNDS IN/OUT operations. This is used for + entries whose counterparty is an entry in the HUB account. + +5. DFSP_POSITION. The participant represents the position of a participant in + the scheme. It may be either the creditor or the debtor in a transaction. It + is used during the settlement process. This is used for entries whose + counterparty is an entry in the HUB account. + +Settlement states +----------------- + +A settlement may be in a number of possible states. The states currently +supported are: + +1. PENDING_SETTLEMENT. A new settlement consisting of one or more settlement + windows has been created. The net amounts due to or from each participant + have been calculated and a report detailing these net amounts has been + produced. + +2. PS_TRANSFERS_RECORDED: all the calculated net amounts for the settlement + have been converted into transfers between the creditor and debtor accounts. + It is applied for each settlement entry and at settlement level, when all + entries are recorded. This state is not applied to settlement windows. + +3. PS_TRANSFERS_RESERVED: all the funds required for settlement have been + reserved (debit amounts only.) It is applied for each settlement entry and + at settlement level, when all entries are reserved. + +4. PS_TRANSFERS_COMMITTED: all the credit amounts required as part of the + settlement have been committed. It is applied for each settlement entry and + at settlement level, when all entries are committed. + +5. SETTLING: It is used only at settlement level if all accounts are not yet + settled. + +6. SETTLED: This state is applied to settlement accounts in + PS_TRANSFERS_COMMITTED state. When applied to even one account, the + settlement will transit to SETTLING state. When all accounts in a window are + SETTLED, the settlement window will change from PENDING_SETTLEMENT to + SETTLED, while the settlement is still in SETTLING state. When all accounts + from all windows are SETTLED, the settlement will be changed to SETTLED. It + is possible for a settlement to change directly from PS_TRANSFERS_COMMITTED + to SETTLED if all accounts are settled with one request. + +7. ABORTED: the settlement could not be completed and should be rolled back. It + is currently only possible to abort a settlement if the state is one of: + PENDING_SETTLEMENT, PS_TRANSFERS_RECORDED or PS_TRANSFERS_RESERVED. After + having even one account in PS_TRANSFERS_COMMITTED state (even if the + settlement as a whole is still in PS_TRANSFERS_RESERVED), a request to abort + the settlement is rejected. It should be noted that this prevents abortion + in cases such as the default of a participant midway through the settlement + process. + +The present data model contains a foreign key to the enumeration table +containing settlement states from the +**settlementParticipantCurrencyStateChange** table, which maps onto a table +which contains a record for each participant/currency/account type combination. + +Assumption: this means that the states appropriate to a settlement are also to +be applied to the individual elements of a settlement. As a consequence, the +descriptions should be taken to refer to individual settlement amounts as well +as to the settlement as a whole. + +Settlement window states +------------------------ + +A settlement is made up of one or more settlement windows. Each settlement +window has a state associated with it. The current values of this table are as +follows: + +1. OPEN: the settlement window can have ledger movements added to it. + +2. CLOSED: the settlement window cannot have any additional ledger movements + added to it. It is available for settlement. + +3. PENDING_SETTLEMENT: the settlement window’s contents have been included in a + settlement request, but this request is a request for deferred settlement + which has not yet been completed. + +4. SETTLED: the scheme has confirmed that the obligations incurred by + participants as a consequence of the settlement to which this settlement + window belongs have been met by those participants and the settlement is + therefore complete. + +5. ABORTED: the settlement to which this settlement window belongs did not + complete. The settlement window is available to be included in another + settlement. + +Transfer states +--------------- + +Each transaction which passes through the system can be assigned one of a fixed +number of states. The current values of this state are: + +1. RECEIVED_PREPARE: the switch has received the transaction request. + +2. RESERVED: the switch has reserved the funds required to cover the + transaction. + +3. RECEIVED_FULFIL: the switch has received the fulfilment request, and the + transaction has been assigned to a settlement window + +4. COMMITTED: the transaction has been committed. + +5. FAILED: the transaction has failed in some unspecified way and has been + aborted. (Not implemented) + +6. RESERVED_TIMEOUT: the transaction has timed out while in the reserved state + and has been aborted. + +7. RECEIVED_REJECT: the transaction has been rejected by the payee DFSP and + should be aborted. + +8. ABORTED_REJECTED: the transaction has been aborted by the switch as a + consequence of its having been rejected by the payee DFSP. + +9. RECEIVED_ERROR: the transaction was not received correctly by the payee DFSP + and should be aborted. + +10. ABORTED_ERROR: the transaction has been aborted by the switch as a + consequence of its not having been received correctly. + +11. EXPIRED_PREPARED: the transaction has expired during the prepare process and + has been aborted. + +12. EXPIRED_RESERVED: the transaction has timed out during the reservation + process and has been aborted. + +13. INVALID: the transaction has failed the switch’s internal validation process + and has been aborted. + +Transfers and transactions +-------------------------- + +Transfers define a movement of funds in the system. There is a table in the +switch which has this name. Some entries in this table are the consequence of +external movements which are generated by scheme participants and processed by +the switch; others are internally generated by the switch (e.g. to record net +movements of funds associated with settlements.) + +It may be a source of confusion that, although “transfers” is a term used e.g. +in the Interoperability API specification to designate the movement of funds +between participants, it is used as the name of a table in the switch which +stores other types of funds movement as well. + +This document will therefore adopt the following convention: + +- “Transfers” refers to the content of instructions issued using the + **/transfers** resource of the Interoperability API definition[1](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html). (see [Section 6.7](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#67-api-resource-transfers) of the Interoperability API definition[1](http://mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html).) + +- “Transactions” refers to all movements of funds which are tracked by the + switch. + +In scope and out of scope +========================== + +In scope +-------- + +The following functional items are in scope: + +1. Requesting a settlement by currency + +2. Requesting a settlement by currency and settlement model + +Out of scope +------------ + +Business rules +============== + +How do things happen now? +------------------------- + +This section describes how the current settlement process works. + +### Categorisation + +The process leading to settlement is initially defined by entries in the +*participantCurrency* table. This table holds a record for each combination of: + +1. Participant + +2. Currency + +3. Ledger account type (see Section 2.2 above.) + +### Recording positions + +Each entry in this table has a corresponding entry in the *participantPosition* +table. This table stores the current committed and reserved positions for each +of the combinations described above. Each change to the positions in this table +is documented by an entry in the *participantPositionChange* table, which refers +the change back to the *transfer* table and thence to the authoritative record +of transactions. + +### Assigning transactions to settlement windows + +As each transfer is fulfilled, a record is created for it in the +**transferFulfilment** table. This record contains a link to the currently open +settlement window. + +Records may be created for transactions which are not transfers. Non-transfer +transactions have their ilpFulfilment set to 0. + +The settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) contains a resource +(**closeSettlementWindow**) to allow an administrator to close a settlement +window and create a new one. The resource takes a settlement window ID as part +of the query string, together with a string describing the status to be assigned +and a string describing the reason for the change of status. In-line +documentation for the resource states: “If the settlementWindow is open, it can +be closed and a new window is created. If it is already closed, return an error +message. Returns the new settlement window.” + +Settlement windows can only be passed a status of CLOSED using this resource. + +### Initiating a settlement + +The initiation of a settlement is initiated by making a call triggered by the +scheme making a **POST** to the **/settlements** resource in the settlement API. +The caller gives a reason for the settlement request. This is a synchronous +call, whose return is described in Section 4.1.5 below. Internally, the +initiation is marked by the creation of a record in the **settlement** table and +the association of a number of settlement window records in the +**settlementWindow** table with the settlement created. This says: I want this +settlement to contain these settlement windows. Each of the settlement windows +selected to form part of this settlement must have the status CLOSED or ABORTED. +When selected to form part of a settlement, the status of each window should be +changed to PENDING_SETTLEMENT. The status of the settlement itself should also +be set to PENDING_SETTLEMENT. + +### Calculating the content of a settlement + +When a settlement has been requested and the windows which it will contain have +been selected, the switch produces an aggregation of the content of the proposed +settlement at the following levels: + +1. Settlement window (from **settlementWindow**) + +2. Participant (from **participantCurrency**) + +3. Currency (from **participantCurrency**) + +4. Account type (from **participantCurrency**) + +5. Participant role type (from **transferParticipant**) + +6. Ledger entry type (from **transferParticipant**) + +This query can be provisioned from the database FK links from **settlement** to +**settlementwindow**, to **transferFulfilment** (all fulfilled transfers), to +**transfer**, to **transferParticipant**. The amount is taken from the +**transferParticipant** table. Correct! + +Only transfers are included in a settlement. This is implied by the first +aggregation criterion above (Settlement window) and the fact that only transfers +are assigned to the current OPEN window when a **transferFulfilment** record is +created. All COMMITTED transactions should have an entry in the +**transferFulfilment** table. + +The results of this query are used to construct a number of records in the +**settlementParticipantCurrency** table, representing the net amount due to or +from each participant and currency in the settlement as a consequence of the +settlement. For a given settlement, these records are segmented by: Correct! + +1. Participant (from **participantCurrency**) + +2. Currency (from **participantCurrency**) + +3. Account type (from **participantCurrency)** + +This report is used as the basis of the information returned from the initial +**POST** to the **/createSettlement** resource of the settlement API (see +Section 4.1.4 above.) + +Bilateral settlements are not currently implemented. + +### Creating position records for the settlement + +A record is inserted in the **transfer** table for each net amount calculated in +the previous step when the settlement account transitions from +PENDING_SETTLEMENT to PS_TRANSFERS_RECORDED. Please note that PS stands for +PENDING_SETTLEMENT. Each of these records will have the account type SETTLEMENT. +The ledger entry type will be SETTLEMENT_NET_SENDER, SETTLEMENT_NET_RECIPIENT or +SETTLEMENT_NET_ZERO depending on whether the participant owes money to the +scheme, is owed money by the scheme or is neutral in the settlement, +respectively. The transfer participant type is HUB for the Hub participant and +DFSP_POSITION for the DFSP participant. The account type is imposed by the +participant currency – for the Hub participant it is the +HUB_MULTILATERAL_SETTLEMENT and for the DFSP participant it is the POSITION +account. This enables the switch to reset the participant’s position when the +window enters the PS_TRANSFERS_COMMITTED state. + +### Progress of the settlement + +As the scheme verifies that participants have settled the amounts due from them, +the scheme administrator can update the switch with this information. + +#### Updating the status of settlement windows + +Three methods of performing this update are supported. Each of these methods is +discussed in more detail below. + +##### **updateSettlementById** + +An administrator may issue a **PUT** to the **/updateSettlementById** resource +on the settlement API, giving the settlement ID of the settlement they wish to +update as part of the query (e.g. **PUT +/updateSettlementById/settlements/123.**) The content of the request is as +follows: + +1. A state to be assigned to the participants required. The state is + constrained to be either ABORTED or INVALID + +2. A reason for the change of state. + +3. An external reference for the change. + +4. An array of participants to which the status is to be applied. The following + information is given for each participant: + + 1. The ID of the participant. This is the internal Mojaloop ID of the + participant. + + 2. An array of *accounts*. The content of each account is as follows: + + 1. An ID. The description characterises this as the participant’s + currency ID QUESTION: Is this correct? It is an integer, where a + VARCHAR(3) would be expected. + + 2. A reason. A string which presumably can contain anything. + + 3. The state of the settlement for the account. This is not constrained + by an enum, but is a simple string. It is not clear how this status + relates to the overall state given in Item 1 above. + + 4. An external reference for the change in state. + +> A call to this API resource may contain *either* items 1-3 above *or* an +> array of accounts as specified in item 4 above, but not both. If it contains +> items 1-3 above, then all the items must be present. If these rules are +> breached, then the switch will reject the request. + +##### **updateSettlementBySettlementParticipant** + +An administrator may issue a **PUT** to the +**/updateSettlementBySettlementParticipant** resource on the settlement API, +giving the settlement ID and the participant ID of the parts of the settlement +they wish to update as part of the query (e.g. **PUT +/updateSettlementByParticipant/settlements/123/participants/56789.**) The +content of the request is as follows: + +1. An array of state changes, whose content is as follows: + + 1. The currency ID whose status is to be changed. This is an integer, where + a VARCHAR(3) would be expected. + + 2. A reason for the state change. + + 3. The state requested. This is a string, where an enumeration would be + expected. + + 4. An external reference for the change in state. + +Note that this is an array with the same structure as that described in item 4 +of Section 5.1.7.1 above, although it is defined separately in the API +definition. + +##### **updateSettlementBySettlementParticipantAccount** + +An administrator may issue a **PUT** to the +**/updateSettlementBySettlementParticipantAccount** resource on the settlement +API, giving the settlement ID, the participant ID and the account ID of the part +of the settlement they wish to update as part of the query (e.g. **PUT +/updateSettlementByParticipant/settlements/123/participants/56789/accounts/1.**) +The content of the request is as follows: + +1. The state requested. This is a string, where an enumeration would be + expected. + +2. A reason. A string which presumably can contain anything. + +3. An external reference for the change in state. + +Note that this is a structure with most of the same members as the structure +defined in Item 1 of Section 5.1.7.2 above, although the items appear in a +different order. + +#### How changes in settlement window state are processed + +The action taken in response to these calls depends on the status assigned to +the account. In any case, a record is created in the +**settlementParticipantCurrencyStateChange** table, giving the state identifier, +the reason and an external reference for the change. + +There is a sequence of steps defined for a settlement. Each step must be +followed in order, and no steps may be omitted. The sequence of steps is +hard-coded into the application and is as follows: + +1. PENDING_SETTLEMENT + +2. PS_TRANSFERS_RECORDED + +3. PS_TRANSFERS_RESERVED + +4. PS_TRANSFERS_COMMITTED + +5. SETTLED + +A settlement can be aborted provided no account in the settlement has reached a +status of PS_TRANSFERS_COMMITTED. + +The following actions are taken on each change of status: + +##### PENDING_SETTLEMENT to PS_TRANSFERS_RECORDED + +A record is generated in the **transfer** table to record the change in state. +The parties to this transfer are the POSITION account type and the +HUB_MULTILATERAL_SETTLEMENT type. If the participant account is a net creditor +for the settlement, then the ledger entry type will be set to +SETTLEMENT_NET_RECIPIENT. If the participant account is a net debtor for the +settlement, then the ledger entry type will be set to SETTLEMENT_NET_SENDER. If +the participant account is neutral for the settlement, then the ledger entry +type will be set to SETTLEMENT_NET_ZERO. + +A record is also created in the **transferstatechange** table with the +RECEIVED_PREPARE state, which means that no positions have been changed. + +When the last participating account is changed to PS_TRANSFERS_RECORDED, then +the settlement’s status is also changed to PS_TRANSFERS_RECORDED. + +If an administrator attempts to change an account’s state to +PS_TRANSFERS_RECORDED and either the settlement’s state or the settlement +account’s state is not PENDING_SETTLEMENT or PS_TRANSFERS_RECORDED, then the +request will be rejected. + +##### PS_TRANSFERS_RECORDED to PS_TRANSFERS_RESERVED + +A new record is created in the **transferstatechange** table for the transfer +that was created in section 5.1.7.2 above. This record will have a status of +RESERVED. If the participant is a net creditor as a result of the settlement, +then a record will also be created in the participantPositionChange table if the +account being reserved is for a net creditor in the settlement, as defined in +Section 5.1.7.2 above. The Net Debit Cap is checked at this point, and if the +current position exceeds the Net Debit Cap, then the Net Debit Cap is +automatically adjusted by the amount of the net credit due to the account as +part of the settlement and the participant is sent a notification of the new Net +Debit Cap value and its currency. + +When the last participating account is changed to PS_TRANSFERS_RESERVED, then +the settlement’s status is also changed to PS_TRANSFERS_RESERVED. + +If an administrator attempts to change an account’s state to +PS_TRANSFERS_RESERVED and either the settlement’s state or the settlement +account’s state is not PS_TRANSFERS_RECORDED or PS_TRANSFERS_RESERVED, then the +request will be rejected. + +##### PS_TRANSFERS_RESERVED to PS_TRANSFERS_COMMITTED + +A new record is created in the **transferstatechange** table for the transfer +that was created in section 5.1.7.2 above. This record will have a status of +COMMITTED. If the participant is a net debtor as a result of the settlement, +then a record will also be created in the participantPositionChange table if the +account being reserved is for a net debtor in the settlement, as defined in +Section 5.1.7.2 above. + +When the last participating account is changed to PS_TRANSFERS_COMMITTED, then +the settlement’s status is also changed to PS_TRANSFERS_COMMITTED. + +If an administrator attempts to change an account’s state to +PS_TRANSFERS_COMMITTED and either the settlement’s state or the settlement +account’s state is not to PS_TRANSFERS_RESERVED or PS_TRANSFERS_COMMITTED, then +the request will be rejected. + +##### PS_TRANSFERS_COMMITTED to SETTLED + +When the first account is changed to a status of SETTLED, the settlement’s state +is changed to SETTLING. + +When the last participating account is changed to SETTLED, then the settlement’s +status is also changed to SETTLED. + +If an administrator attempts to change an account’s state to SETTLED and either +the settlement’s state or the settlement account’s state is not to +PS_TRANSFERS_COMMITTED or SETTLED, then the request will be rejected. + +### Aborting the settlement + +If there is any failure in the scheme’s process for recovering the amounts due +from participants in a settlement, the scheme can update the switch with this +information by issuing a **PUT** to the **/updateSettlementById** resource of +the settlement API and setting the **state** value of the content of the message +to ABORTED. A **PUT** call on the **/updateSettlementById** resource is the only +method which may be used for ABORTING a settlement. If any account information +is given in the call, then neither the **state** nor the **reason** nor the +**externalReference** fields may be set. if the **state** value is set at the +top level of the call, then the **reason** field must also be set, and the +request will be rejected if any account information is given in the call. + +If an attempt is made to abort a settlement, and any of the accounts in the +settlement have the status PS_TRANSFERS_COMMITTED or SETTLED, then the request +will be rejected. + +When a call is received, a new record is created in the +**settlementParticipantCurrencyStateChange** table, and is given the appropriate +status based on the status reported by the caller. Depending on the update that +was received, this may also require the status of the transaction and that of +the participant position to be updated. No, it is done at settlement level for +the entire settlement and all entries in settlementParticipantCurrency are +affected. + +Note: if the settlement is bilateral, then there is no obvious reason to abort +the entire settlement if one interchange fails. We should think about this use +case and how we would want to represent it. This document does not consider this +use case. + +Aborting a settlement comprises the following steps: + +1. The status of the transfers created in Section 5.1.6 above should be changed + to ABORTED. + +2. A new record is added to the **settlementParticipantCurrencyStateChange** + table for each of the participant records in the settlement. This record has + a status of ABORTED, and the **currentStateChangeId** column in the + **settlementParticipantCurrency** table for that participant record is + changed to point to this new record. + +3. A new record is added to the **settlementWindowStateChange** table for each + settlement window in the settlement. This record has a status of ABORTED, + and the **currentStateChangeId** column in the settlementWindow table for + that window is changed to point to this new record. + +4. A new record is added to the **settlementStateChange** table for the + settlement. This record has a status of ABORTED, and the + **currentStateChangeId** column in the **settlement** table is changed to + point to this new record. + +5. If positions have been reserved for net creditors as a result of the + settlement (see Section 5.1.7.3 above,) then a balancing entry will be + created in the **participantPositionChange** table to reverse the + reservation of funds. This action does not at present reverse any change to + the account’s Net Debit Cap that may have been made as a consequence of this + reservation. + +6. Any records created in the **transfers** table (see Section 5.1.7.2 above) + will have their state changed in two steps by adding records to the + **transferStateChange** table. The first step will change the transfer state + to REJECTED. The second step will change the state to ABORTED. + +Question: should there be/is there a time-out after which a settlement will be +aborted if it has not completed? If there is, how is it set? No, there isn’t +timeout on a settlement level. But when transfers are prepared (for +PS_TRANSFERS_RECORED) expiration is set on a transfer level. Its value is +controlled by a Config.TRANSFER_VALIDITY_SECONDS, which currently defaults to +432000 seconds, which equals 5 days. It is big enough to avoid expiration. +Still, if that happens, it would leave the data in an unrecoverable by the API +state. This is very good point and should be certainly addressed with the next +increment! + +Recording the deposit of funds +------------------------------ + +As participants are informed of their liabilities under the settlement, it is +expected that they will deposit funds in their settlement account to cover those +liabilities. These activities are recorded via the central ledger administration +interface resource **recordFundsIn**. + +This action is called through a POST to the administration interface, giving the +name of the participant and the account to be credited in the form POST +/participants/{participantName}/accounts/{accountId} (e.g. **POST +/participants/myDfsp/accounts/1234**) The content of this message is as follows. + +1. transferId: a UUID to be used to identify the transfer in the switch. + +2. externalReference: a reference used to identify the transfer for the + administrator + +3. action: this should be set to “recordFundsIn” for recording funds in. + +4. reason: the reason why the transfer is being made. + +5. amount: the amount of the transfer. + + 1. amount: the actual amount being transferred + + 2. currency: the ISO 4217 code of the currency of the deposit. + +6. extensionList: a series of key/value pairs which are used to carry + additional information + +When an administrator records that a participant has deposited funds to an +account, the amount deposited is recorded in an entry in the **transfer** table. +The parties to the transfer are recorded by entries in the +**transferParticipant** table, with a ledger account type of the type requested +in the POST for the participant and HUB_RECONCILIATION for the balancing entry. +For deposits, the participant account will be the creditor and the +HUB_RECONCILIATION account the debtor. The application will currently reject +requests to this interface which do not have a ledger account type of +SETTLEMENT. + +A deposit goes through the following changes of state: + +1. A record is created for the transfer in the **transferStateChange** table + with a state of RECEIVED_PREPARE. + +2. Next, a record is created in the **transferStateChange** table with the + state RESERVED. This also creates a record in the + **participantPositionChange** table to record the reservation of funds in + the HUB_RECONCILIATION account, and the **participantPosition** table’s + value for that account is updated. + +3. Finally, a record is created in the **transferStateChange** table with the + state COMMITTED. After this act, records are created in the + **participantPositionChange** table for the creditor account to record the + completion of the deposit, and the appropriate record in the + **participantPosition** table has its balance updated. + +These changes of state are simply chained together in sequence. There is no +interval or trigger between the steps. + +This activity has no direct effect on the settlement process or on the Net Debit +Cap. + +Recording the withdrawal of funds +--------------------------------- + +At various times, participants may wish to withdraw funds from their settlement +accounts: for instance, if they are long-term net beneficiaries of transfers and +are building up a surplus of liquidity. These activities are recorded via a +two-phase process. In the first phase, the funds for the proposed withdrawal are +reserved via the central ledger administration interface resource +**recordFundsOutPrepareReserve**. In the second phase, the withdrawal is +committed via the **recprdFundsOutCommit** resource or aborted through the +**recordFundsOutAbort** resource. + +These activities are defined below. + +### **recordFundsOutPrepareReserve** + +This action is called through a POST to the administration interface, giving the +name of the participant and the account to be credited (e.g. **POST +/participants/myDfsp/accounts/1234**) The content of this message is as follows. + +1. transferId: a UUID to be used to identify the transfer in the switch. + +2. externalReference: a reference used to identify the transfer for the + administrator + +3. action: this should be set to “recordFundsOutPrepareReserve” for recording + funds withdrawals. + +4. reason: the reason why the transfer is being made. + +5. amount: the amount of the transfer. + + 1. amount: the actual amount being transferred + + 2. currency: the ISO 4217 code of the currency of the deposit. + +6. extensionList: a series of key/value pairs which are used to carry + additional information + +When an administrator records that a participant has requested the withdrawal of +funds from an account, the amount to be withdrawn is recorded in an entry in the +**transfer** table. The parties to the transfer are recorded by entries in the +**transferParticipant** table, with a ledger account type of the type requested +in the POST for the participant and HUB_RECONCILIATION for the balancing entry. +For withdrawals, the participant account will be the debtor and the +HUB_RECONCILIATION account the creditor. The application will currently reject +requests to this interface which do not have a ledger account type of +SETTLEMENT. + +Reservation of a withdrawal goes through the following changes of state: + +1. A record is created for the transfer in the **transferStateChange** table + with a state of RECEIVED_PREPARE. + +2. Next, a record is created in the **transferStateChange** table with the + state RESERVED. This also creates a record in the + **participantPositionChange** table to record the reservation of funds in + the participant’s settlement account, and the **participantPosition** + table’s value for that account is updated. + +These changes of state are simply chained together in sequence. There is no +interval or trigger between the steps.**recordFundsOutCommit** + +This action is called through a POST to the administration interface, giving the +name of the participant and the account to be credited (e.g. **POST +/participants/myDfsp/accounts/1234**) The content of this message is as follows. + +1. transferId: a UUID to be used to tie the commit to the preceding reservation + in the switch. + +2. externalReference: a reference used to identify the transfer for the + administrator + +3. action: this should be set to “recordFundsOutCommit” for recording funds + commitments. + +4. reason: the reason why the transfer is being made. + +5. amount: the amount of the transfer. + + 1. amount: the actual amount being transferred + + 2. currency: the ISO 4217 code of the currency of the deposit. + +6. extensionList: a series of key/value pairs which are used to carry + additional information + +When an administrator records that a participant wants to commit the withdrawal +of funds from an account, the original entry in the **transfer** table is +identified. The parties to the transfer are recorded by entries in the +**transferParticipant** table, with a ledger account type of the type requested +in the POST for the participant and HUB_RECONCILIATION for the balancing entry. +For withdrawals, the participant account will be the debtor and the +HUB_RECONCILIATION account the creditor. The application will currently reject +requests to this interface which do not have a ledger account type of +SETTLEMENT. + +Commitment of a withdrawal goes through the following changes of state: a record +is created in the **transferStateChange** table with the state COMMITTED. After +this act, records are created in the **participantPositionChange** table for the +creditor account to record the completion of the deposit, and the appropriate +record in the **participantPosition** table has its balance updated. These +changes of state are simply chained together in sequence. There is no interval +or trigger between the steps. + +This activity has no direct effect on the settlement process or on the Net Debit +Cap. + +Proposed enhancements +===================== + +This section describes the enhancements to the existing OSS settlement process +(described in Section 4.1 above) which are proposed. Each enhancement is shown +in a separate section and, where there are dependencies between enhancements, +these are listed in the enhancement’s description. + +Request settlement by currency [EPIC] +------------------------------------- + +The following changes are required to support settling separately for different +currencies. + +### Database changes + +The following changes are required to support multi-currency settlement. + +#### Addition of a settlementWindowContent table [Story \#1] + +A new table will be added to the database. The name of this table will be +**settlementWindowContent**. The table will contain an entry for each item of +content in a given settlement window, broken down by ledger account type and +currency. The full column structure of the table is as follows: + +| **Column name** | **Description** | **Attributes** | +|-----------------------------------------|---------------------------------------------------|---------------------------------------------------------------------------------------| +| **settlementWindowContentId** | Auto-generated key for the record. | BIGINT(20). Unsigned, not null, primary key, autoincrement | +| **settlementWindowId** | The settlement window that the record belongs to. | BIGINT(20). Unsigned, not null. Foreign Key to **settlementWindow** | +| **ledgerAccountTypeId** | The ledger account that the record refers to. | INT(10). Unsigned, not null. Foreign key to **ledgerAccountType** | +| **currencyId** | The currency that the record refers to. | VARCHAR(3). Not null. Foreign key to **currency**. | +| **createdDate** | The date and time when the record was created. | DATETIME. Not null. Defaults to CURRENT_TIMESTAMP. | +| **currentStateChangeId** | The current state of this entry. | BIGINT(20). Unsigned. Foreign key to **settlementWindowContentStateChange** | + +  + +#### Addition of a settlementWindowContentStateChange table [Story \#2] + +A new table will be added to the database. The name of this table will be +**settlementWindowContentStateChange**. The table will track changes to the +status of entries in the **settlementWindowContent** table. The full column +structure of the table is as follows: + +| **Column name** | **Description** | **Attributes** | +|------------------------------------------|---------------------------------------------------------------------|----------------------------------------------------------------------------| +| **settlementWindowContentStateChangeId** | Auto-generated key for the record. | BIGINT(20). Unsigned, not null, primary key, autoincrement | +| **settlementWindowContentId** | The settlement window content record whose status is being tracked. | BIGINT(20). Unsigned, not null. Foreign Key to **settlementWindowContent** | +| **settlementWindowStateId** | The record’s status. | VARCHAR(50). Not null. Foreign key to **settlementWindowState** | +| **reason** | An optional field giving the reason for the state being set. | VARCHAR(512). | +| **createdDate** | The date and time when the record was created | DATETIME. Not null. Defaults to CURRENT_TIMESTAMP | + +  + +#### Changes to the settlementTransferParticipant table [Story \#3] + +The name of the **settlementTransferParticipant** table should be changed to +**settlementContentAggregation**. + +The column structure of the **settlementContentAggregation** table should be +modified as follows: + +1. Remove the following foreign keys from the table: + 1. settlementtransferparticipant_settlementid_foreign + 2. settlementtransferparticipant_settlementwindowid_foreign +2. Remove the following columns from the table: + 1. settlementId + 2. settlementWindowId +3. Add the following column to the table: + 1. Column name: **settlementWindowContentId** + 2. Attributes: BIGINT(20), unsigned, not null +4. Add the following foreign key to the table: + 1. Name: settlementContentAggregation_settlementwindowcontent_foreign + 2. Child column **settlementWindowContentId** + 3. Refers to table: **settlementWindowContent** + 4. Refers to column: **settlementWindowContentId** + +All database scripts which use the **settlementTransferParticipant** table will +be changed to accommodate the new name and structure of the table. [Story \#8] + +Queries to filter the records in the **settlementContentAggregation** table +required for a settlement in a particular currency will need to join across from +that table to the **participantCurrency** table using the +**participantCurrencyId** column to ascertain the currency to which a particular +row refers. The **currencyId** column is held in the **participantCurrency** +table. [Story \#9] + +#### Add structures relating to settlement models [Story \#4] + +In order to support the specification of settlement models, which will include +currencies, the database changes specified in Section 6.2.1.1 below should be +added to the database. + +Settlement models describing the settlement types required for a given +implementation will be developed and tested.**[Story \#4a]** + +#### Change to settlement table [Story \#5] + +The **settlement** table in the central ledger database needs to be modified to +add a *settlementModel* column. This column should have the following +characteristics: + +- The column should be required (NOT NULL) and unsigned. +- The column’s data type should be integer(10) +- The column should be defined as a foreign key reference to the +*settlementModelId* field of the **settlementModel** table. + +When this change is applied to an existing database, a settlement model to +describe the default settlement should be created. The settlementCurrencyId +column in this model should be left blank (= all currencies.) The +settlementModel column in all existing records in the settlement table should be +set to point to this model’s ID. A script to apply this change should be +created, tested and stored in the repository. + +### Changes to processing + +The following changes to the processing code are required to support +multi-currency settlement. + +#### Change to code supporting closeSettlementWindow resource + +The existing API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) provides a single function +(**closeSettlementWindow**) to manage settlement windows. This function allows +its user to select a settlement window by ID number and to input a new status +for the window and a reason for that status. + +When a settlement window is closed, the code supporting this activity should +perform two functions, as follows. These functions should be performed in the +background and without impacting system performance. + +##### Generate records in the settlementWindowContent table [Story \#1095] + +The code should generate a record in the **settlementWindowContent** table for +each ledger entry type/currency combination found in the transfers in the +settlement window. This information can be obtained from the following query: +``` +SELECT DISTINCT + @mySettlementWindowId, pc.ledgerAccountTypeId, pc.currencyId +FROM transferFulfilment tf +INNER JOIN transferParticipant tp + ON tp.transferId = tf.transferId +INNER JOIN participantCurrency pc + ON pc.participantCurrencyId = tp.participantCurrencyId +WHERE tf.settlementWindowId = @mySettlementWindowId; +``` + +##### Generate records in the settlementContentAggregation table [Story \#1095] + +The code should calculate the aggregate values for all transfers which form part +of that settlement window and store them in the **settlementContentAggregation** +table. Aggregates should be produced for the following segmentation: + +1. Participant +2. Currency +3. Ledger account type +4. Participant role type +5. Ledger entry type + +The following query will perform this function for a given settlement window: + +``` +INSERT INTO settlementContentAggregation + (settlementWindowContentId, participantCurrencyId, + transferParticipantRoleTypeId, ledgerEntryTypeId, amount) +SELECT swc.settlementWindowContentId, pc.participantCurrencyId, + tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId, SUM(tp.amount) +FROM transferFulfilment tf +INNER JOIN transferParticipant tp + ON tf.transferId = tp.transferId +INNER JOIN participantCurrency pc + ON pc.participantCurrencyId = tp.participantCurrencyId +INNER JOIN settlementWindowContent swc + ON swc.settlementWindowId = tf.settlementWindowId +  AND swc.ledgerAccountTypeId = pc.ledgerAccountTypeId + AND swc.currencyId = pc.currencyId +WHERE tf.settlementWindowId = @mySettlementWindowId +GROUP BY swc.settlementWindowContentId, pc.participantCurrencyId, + tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId; +``` + +#### createSettlement + +The parameters for the **createSettlement** resource should be extended to +include the settlement model for which the settlement is required. + +When the settlement is created, the settlement model for which the settlement is +required should be added to the new row in the **settlement** table. [Story \#1097] + +When a settlement is requested, the switch should check that the settlement +model for which settlement is being requested requires NET settlement and not +GROSS settlement. If the requested settlement model requires GROSS settlement, +then the request should be rejected with an error. + +The verification procedures associated with the **createSettlement** resource +should be changed to check that some of the settlement windows associated with +the proposed settlement contain entries for the settlement model requested. If +there are no entries for the settlement model requested for any of the +settlement windows requested, then an error should be returned and the +settlement request rejected. [Story \#1096] + +#### Updating the progress of a settlement + +When the status for a settlement participant is changed to SETTLED, this will result in +changes to the status of all the records in the **settlementContentAggregation** +table for the given participant, identified by the compound key: settlementId + participantCurrencyId. + +[Story \#16] + +The code should then check to see if, as a result of the updates to the records +in **settlementContentAggregation**, all records for a given combination of +settlement window, ledger account type and currency have the same status. If +they have, then the appropriate record in the **settlementWindowContent** table +should be updated to have that status. + +The code should then check to see if all records in the +**settlementWindowContent** table for a given settlement window have the same +status. If they have, then the appropriate record in the **settlementWindow** + +Support continuous gross settlement +----------------------------------- + +Continuous Gross Settlement is a settlement model in which each transaction is +settled as soon as it is fulfilled. The following changes are required to +implement this change. + +### Database changes + +The database changes shown in Section 8 below should be implemented. These can +be summarised as follows: + +#### Changes to support the settlement model + +A number of new tables are required to define a settlement model and to store +the enumerations for its definition types. This comprises the following tables +in the ERD: + +- settlementDelay + +- settlementInterchange + +- settlementModel + +In addition, the **settlementmodel** table has foreign keys to two existing +tables, as follows: + +1. A foreign key to the **currency** table to enable the settlement model to + settle only scheme accounts in a particular currency. If this entry is + blank, this should be interpreted as saying that the settlement model + settles all currencies that are not specified as being settled by other + settlement models for the same account type. + +2. A foreign key to the **ledgerAccountType** table. This specifies that the + settlement model settles accounts of this type. + +#### Changes to the **ledgeraccounttype** table + +The current **ledgeraccounttype** table stores a number of entries for account +types which should not be used for settlements – for instance, +HUB_MULTILATERAL_SETTLEMENT. A column should therefore be added to the +**ledgeraccounttype** table to indicate whether the account type can be attached +to a settlement model or not. This column is called **settleable**, and is +specified as a Boolean value, NOT NULL and with a default of FALSE. + +Of the existing ledger account types, PRINCIPAL_VALUE, INTERCHANGE_FEE and +HUB_FEE should be marked as capable of being attached to settlement models (this +value should be TRUE.) For all other ledger account types, the column should be +set to FALSE. If new ledger account types are added to this table via the +eventual settlement API, then they should have a value of TRUE. + +#### Changes to the **ledgerentrytype** table + +Implementation of the TIPS settlement model requires an explicit association +between ledger entry types and the account types in which they should appear. +Since each ledger entry type should only appear in a single account type, though +multiple ledger entry types may appear in a given account type, this is modelled +by including a foreign key reference to the **ledgeraccounttype** table as a +column in the **ledgerentrytype** table. It should be noted that this applies +only to ledger entry types which are associated with a settlement model, as +described in Section 6.2.1.2 above. The assignment of existing entries in the +database would be as follows: + +| Ledger Entry Type | Ledger Account Type | +|-------------------|---------------------------| +| PRINCIPAL_VALUE | POSITION | +| INTERCHANGE_FEE | INTERCHANGE_FEE | +| HUB_FEE | HUB_FEE | +| | | + +#### Changes to the **settlement** table + +The **settlement** table should have a column added to it to allow the +settlement model to be used in settling it to be specified. The column should be +called *settlementModelId*. It should have the same data type as the equivalent +field in the **settlementModel** table, and should be a foreign key into that +table. It should be defined as not null. + +#### Changes to the **settlementWindow** table + +As well as settlements, individual settlement windows will need to be assigned +to settlement models. The **settlementWindow** table should therefore have a +column added to it to allow the settlement model to be used in settling it to be +specified. The column should be called *settlementModelId*. It should have the +same data type as the equivalent field in the **settlementModel** table, and +should be a foreign key into that table. It should be defined as not null. + +This concludes the list of schema changes required to support the TIPS +settlement models + +### API changes + +API Support for the settlement functionality required for TIPS will include the +following functions: + +#### Close a settlement window + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a +**closeSettlementWindow** resource. This function allows its user to select a +settlement window by ID number and to input a new status for the window and a +reason for that status. This resource will retain its current signature, but the +code supporting it needs to change as follows. + +When a settlement window is closed, the system should create a new settlement +window with the same settlement model as the newly closed settlement window, and +should make this the active window. + +When a settlement window is closed, the code supporting this activity should +calculate the aggregate values for all transfers which form part of that +settlement window and store them in the **settlementTransferParticipant** table. +Aggregates should be produced for the following segmentation: + +1. Participant + +2. Currency + +3. Ledger account type + +4. Participant role type + +5. Ledger entry type + +The following example code will produce the aggregations required for a given +settlement window (identified as \@MyWindow in the example): + +SELECT + +S.settlementId + +, W.settlementWindowId + +, P.participantCurrencyId + +, P.transferParticipantRoleTypeId + +, P.ledgerEntryTypeId + +, SUM(P.amount) + +, CURRENT_TIMESTAMP AS createdDate + +FROM + +settlementWindow W INNER JOIN settlementModel M ON W.settlementModelId = +M.idsettlementModel + +INNER JOIN settlementSettlementWindow S ON W.settlementWindowId = +S.settlementWindowId + +INNER JOIN ledgerAccountType L ON M.idsettlementModel = L.settlementModelId + +INNER JOIN transferFulfilment F ON W.settlementWindowId = F.settlementWindowId + +INNER JOIN transferParticipant P ON F.transferId = P.TransferId + +INNER JOIN participantCurrency PC ON P.participantCurrencyId = +PC.participantCurrencyId + +AND PC.ledgerAccountTypeId = L.ledgerAccountTypeId + +WHERE + +W.settlementWindowId = \@MyWindow + +AND + +(PC.currencyId = M.settlementcurrencyId OR M.settlementcurrencyId IS NULL) + +GROUP BY + +S.settlementId + +, W.settlementWindowId + +, P.participantCurrencyId + +, P.transferParticipantRoleTypeId + +, P.ledgerEntryTypeId; + +#### Getting information about a settlement window + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a +**getSettlementWindowById** resource. This function allows its user to obtain +information about a settlement window by giving the ID that was returned when +the settlement window was created. + +This call returns a **SettlementWindow** object. This object will need to be +extended to include the name of the settlement model to which the settlement +window belongs. + +#### Getting information about settlement windows using parameters + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a +**getSettlementWindowsByParams** resource. This function allows its user to +obtain information about all settlement windows which meet the criteria +specified by the user. The following changes will need to be made to this call: + +1. The parameters supported by the call will need to be extended to allow a + user to request settlement windows by settlement model. The user should be + able to enter the name of a settlement model. + +2. This call returns an array of **SettlementWindow** objects. It is assumed + that these objects will have been changed by the changes specified in + Section 6.2.2.2 above, and that no further processing will be required for + this call. + +#### Requesting a settlement + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a **createSettlement** +resource. This function allows its user to request a settlement for a given set +of settlement windows, which are passed to the resource as parameters. The +following changes will need to be made to this call: + +The parameters for the **createSettlement** resource are defined in the +**SettlementEventPayload** object. This object will need to have a parameter +added to specify the settlement model which is to be settled. The parameter +should be called *settlementModel*, and it should be a string. It should be +required. + +The following validation should be performed on this parameter when the request +is received via the API: + +1. The content of the parameter is a case-insensitive match for an active entry + in the **settlementmodel** table, ignoring whitespace. + +2. The *settlementtypeid* column in the record in the selected settlement model + should not point to a record in the **settlementdelay** table whose + *settlementDelayName* value is “IMMEDIATE”. If it does, the request should + be rejected and an error message returned to the caller. + +The id of the settlement model requested should be stored in the +settlementModelId column of the row created in the **settlement** table to +describe the settlement. + +#### Returning the status of a settlement + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a **getSettlementById** +resource. This function allows its user to obtain information about a settlement +by giving the ID that was returned when the settlement was created. + +Information about settlements is returned in a **Settlement** object. A +parameter should be added to the Settlement object to record the settlement +model which is being settled by the settlement. + +The parameter should be called *settlementModel*, and it should be a string. It +should be required. + +**Note**: when a settlement is requested, a reason is given; but the +**Settlement** object does not contain the reason. It might be worth including +this in the definition of the **Settlement** object. + +#### Getting information about settlements using parameters + +The existing API definition[2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a +**getSettlementsByParams** resource. This function allows its user to obtain +information about all settlements by giving the ID that was returned when the +settlement was created. The following changes will need to be made to this call: + +1. This call returns an array of **Settlement** objects. It is assumed that + these objects will have been changed by the changes specified in Section + 6.2.2.5 above, and that no further processing will be required for this + call. + +#### Getting information about a specific participant in a settlement + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports a +**getSettlementBySettlementParticipant** resource. This function allows its user +to obtain information about a settlement which meet the criteria specified by +the user. The following changes will need to be made to this call: + +1. This call returns a **Settlement** object. It is assumed that this object + will have been changed by the changes specified in Section 6.2.2.5 above, + and that no further processing will be required for this call. + +#### Updating a specific settlement + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an +**updateSettlementById** resource. This function allows its user to update +information about a settlement by giving the ID that was returned when the +settlement was created. + +This call returns a **Settlement** object. It is assumed that this object will +have been changed by the changes specified in Section 6.2.2.5 above, and that no +further processing will be required for this call. + +#### Updating a settlement for a specific participant + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an +**updateSettlementBySettlementParticipant** resource. This function allows its +user to update information about a settlement by giving the ID that was returned +when the settlement was created, and the participant whose information is to be +updated. + +This call returns a **Settlement** object. It is assumed that this object will +have been changed by the changes specified in Section 6.2.2.5 above, and that no +further processing will be required for this call. + +#### Updating a settlement for a specific participant and account + +The existing API definition [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json) supports an +**updateSettlementBySettlementParticipantAccount** resource. This function +allows its user to update information about a settlement by giving the ID that +was returned when the settlement was created, and the participant and account +whose information is to be updated. + +This call returns a **Settlement** object. It is assumed that this object will +have been changed by the changes specified in Section 6.2.2.5 above, and that no +further processing will be required for this call. + +#### Recording the deposit of funds by a participant + +The existing administration API [3](https://mojaloop.io/documentation/api/central-ledger-api-specification.html) contains functions to enable +an administrator to record a deposit made by a participant to an account. This +process is described in Section 5.2 above. The API should be changed to align it +with the structures used in the existing settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json). In addition, the signature of the API should be extended to allow the +administrator to specify the account type that will be updated by the deposit. + +#### Recording the withdrawal of funds by a participant + +The existing administration API [3](https://mojaloop.io/documentation/api/central-ledger-api-specification.html) contains functions to enable +an administrator to record a withdrawal made by a participant from an account. +This process is described in Section 5.3 above. The API should be changed to +align it with the structures used in the existing settlement API [2](https://github.com/mojaloop/central-settlement/blob/master/src/interface/swagger.json). In addition, the signature of the API should be extended to allow +the administrator to specify the account type that will be updated by the +withdrawal. + +#### New resource: openSettlementWindow + +In the current architecture, an instance of each settlement window is created +when the instance is set up, and subsequent settlement windows are created by +closing the current settlement window. In the new settlement management +structure, we will need the ability to create new settlement windows where no +predecessors exist: for instance, when an administrator decides to settle a +particular currency using a different settlement model. + +### Processing changes + +The following processing changes are required to implement the changes required +to support continuous gross settlement. + +#### Attributing ledger entries to the correct ledger account type + +When a ledger entry is created, it should be assigned to the ledger account type +specified in the *ledgeraccounttypeid* column of the row in the +**ledgerentrytype** table appropriate to the ledger entry type which is being +created. + +For example: if a normal entry representing a transfer is being created, it will +have a ledger entry type of PRINCIPAL_VALUE. It should be assigned to the +POSITION account type (the default position at present.) This implies that the +match described in Section 6.2.1.3 above has been implemented. + +Question: how does the switch decide whether or when to construct a record in +the **participantPositionChange** table? How would it be possible to select the +ledger account type to which the position refers? + +Processing interchange fees +---------------------------- + +In order to support the scheme model implemented by TIPS, we need to generate +and settle liabilities incurred as a consequence of making transfers between +particular types of customer. The general form of this rule is as follows: + +- If the transaction is a wallet-to-wallet P2P transaction, then the receiver + DFSP pays the sender DFSP 0.6% of the amount of the transaction. + +- No interchange fees are levied for on-us transactions. + +The business decisions around this requirement are: + +1. The definition of whether or not a payee account is a wallet will be + returned by the payee DFSP as part of customer discovery. The mechanism by + which this is implemented is outside the scope of this document. + +2. Interchange fees will be captured by the switch when the transfers which + incur them are completed. + +3. Interchange fees will have the ledger entry type INTERCHANGE_FEE and will be + recorded in accounts whose type is INTERCHANGE_FEE. + +4. Interchange fees will be settled multilaterally, net and deferred. It is + expected that this settlement will take place monthly. + +5. Interchange fees do not require liability cover by participants. + +This functionality will be implemented as a partial instance of a general +process for defining and executing rules, and for taking actions based on the +outcome of evaluation of a rule. For this particular case, we propose the +changes described in the following sections. + +### Part 1: Run script for batch update of interchange fees when settlement window is closed. + +Include stories to manage account type definition + +### Part 2: Add reservation on prepare using script and modify fulfilment to fulfil all ledger types for which an entry has been made + +### Evaluating a rule + +The process of evaluating a rule is based on the following assumptions: + +1. There will be a standard form of rule evaluation with the following + structure: + + 1. A transaction object will be passed as the parameter to the rule + evaluation function. + + 2. The rule evaluation itself will use a complex if statement. + + 3. If the rule evaluates to TRUE, then an action should be executed as + described in Section 6.3.2 below. + +An example of a rule function to evaluate a TIPS interchange fee rule could be: + +function evaluateInterchangeFee (transaction) { + +if( + +(transaction.payee.fspId.toLowerCase() != transaction.payer.fspId.toLowerCase()) + +&& (transaction.extensionList[“payerAccountType”].toLowerCase() == +"Wallet".toLowerCase() + +&& transaction.extensionList[“payeeAccountType”].toLowerCase() == +"Wallet".toLowerCase()) + +&& (transaction.transactionType.scenario.toLowerCase() == +"TRANSFER".toLowerCase() + +&& transaction.transactionType.initiator.toLowerCase() == "PAYER".toLowerCase() + +&& transaction.transactionType.initiatorType.toLowerCase() == +"CONSUMER".toLowerCase()) + +) { + +// Do some good stuff + +}; + +}; + +### Taking action after evaluating a rule + +If a rule evaluates to TRUE as described in Section 6.3.1 above, then +appropriate action should be taken. In the case of the immediate example of +interchange fees, the action taken should be to add two entries to the +participants’ interchange fee accounts, on recording the debit from the payee of +the interchange fee amount and the other recording the credit to the payer of +the interchange fee amount. + +A simple yet general way of supporting actions of this type is to define a class +(which might be called ruleAction) and adding methods to it to represent the +actions to be taken. The rule evaluation function can then instantiate the class +and call the appropriate function. + +In the case of the interchange fees, we would define an action called +addLedgerEntry, with the following parameters: + +1. The transfer ID for which the ledger entry is being created + +2. The ledger entry type to be used + +3. The currency in which the amount is denominated + +4. The amount of the fee + +5. The FSP ID of the credit party + +6. The FSP ID of the debit party + +This might appear in the rule evaluation function as: + +myAction.addLedgerEntry(transaction.transactionId, + +transaction.transactionId, + +"INTERCHANGE_FEE“, + +transaction.currency, + +transaction.amount\*0.006, + +transaction.payer.fspId, + +transaction.payee.fspId); + +### Providing a generic framework for rule evaluation + +Finally, we will need to provide a generic framework to trigger the evaluation +of rules. This should be an array of evaluation functions, which are triggered +when the status of a transfer changes to FULFILLED. + +Process transfers for continuous gross settlement [EPIC] +------------------------------------------------- + +When a settlement model specifies that an account is to be settled immediate gross, then each ledger entry which is of a type belonging to that scheme account should be settled immediately. This immediate settlement should have the following characteristics: + +- It should be performed by a process which is forensically logged. +- It should be performed immediately, so that participants can check their current position against the transfers that comprise it. +- It should be aggregated to settlement window level, so that the checks which are currently performed on the overall status of a settlement window will continue to work. + +The following sections describe the changes that are required to process transfers for accounts which are settled immediate gross. + +### Database changes + +The following changes are required to the database to implement transfer processing for continuous gross settlement + +#### Addition of a new table to store changes in state + +A new table should be added to store changes in state for ledger entries for individual transfers. The name of this table should be **transferParticipantStateChange**. Its column structure should be as follows: + +1. The unique key to the record. Column name: **transferParticipantStateChangeId**; type: unsigned BIGINT; not nullable; primary key +2. The record in **TransferParticipant** whose state change this record marks. Column name: **transferParticipantId**; type: unsigned BIGINT; not nullable; foreign key to the **transferParticipantId** column of the **transferParticipant** table. +3. The current state of the record in **transferParticipant** to which this state record refers. Column name: **settlementWindowStateId**; data type VARCHAR(50); not nullable; foreign key to the **settlementWindowStateId** column of the **settlementWindowState** table. +4. An explanation of the state change. Column name: **reason**; type: VARCHAR(512); nullable. +5. The date and time when the change was recorded. Column name: **createdDate**; type DATETIME; not nullable; default value **CURRENT_TIMESTAMP**. + +#### Changes to the TransferParticipant table + +No changes to the **transferParticipant** table are required. The relationship between records in the **transferParticipant** table and records in the **transferParticipantStateChange** table is managed via the **transferParticipantId** column in the **transferParticipantStateChange** table. + +#### Changes to the settlementModel table + +Existing implementations have functionality which automatically adjusts participants' positions when settlements are completed. In order to support backwards compatibility for these implementations, the settlement model will be expanded to allow automated position adjustment to be switched off and on. + +This functionality will be managed through a new column in the **settlementModel** table. The name of the column will be **adjustPosition**. Its type will be TINYINT(1), and it should not be nullable. It should have a default value of zero (FALSE). + +### Processing changes + +The following changes to processing are required to support immediate settlement of gross ledger entries. + + +#### Generating entries in settlementContentAggregation + +The following changes to the process that creates aggregation records in the **settlementContentAggregation** table are required. + +1. The aggregation process for a settlement window may not be performed if there are any records in the **transferParticipant** table which belong to the settlement window to be aggregated (as defined by joining the **transferParticipant** records to the matching records in the **transferFulfilment** table on the **transferId** column in both tables) and which do not have any corresponding entries in the **transferParticipantStateChange** table. This test is performed via a LEFT OUTER JOIN relationship between the **transferParticipantStateChange** table and the **transferParticipant** table, using the foregin key relation between the **transferParticipantId** columns in the **transferParticipant** table and the **transferParticipantStateChange** table. +2. In the discussion which follows, the current status of a record in **transferParticipant** is defined as: the status of the record in the **transferParticipantStateChange** table which is keyed to the record in **transferParticipant** and which has the latest value in the **createdDate** column of the **transferParticipantStateChange** table. +3. When there are no records in **transferParticipant** which meet the blocking criteria described in step 1 above, then all records belonging to the settlement window which has just been closed, and which currently have the status OPEN, should have their status set to CLOSED. This means: a record should be added to the **transferParticipantStateChange** table for the qualifying **transferParticipant** record whose status is CLOSED, and the **currentStateChangeId** column for the qualifying **transferParticipant** record should be set to point to the newly created record. +4. When aggregating records for insertion into the **settlementContentAggregation** table, if all the records in the **transferParticipant** table which are to be aggregated into a single record in the **settlementContentAggregation** table have the same value in their **currentStateChangeId** column, then the value of the **currentStateId** column in the newly created record in the **settlementContentAggregation** table should be set as follows. The value of the **currentStateId** column in the newly created record in the **settlementContentAggregation** table should be set to the shared value in the constituent records from the **transferParticipant** table, except in the following case: if the shared value in the constituent records from the **transferParticipant** table is OPEN, then the value of the **currentStateId** column should be set to the value CLOSED. + +#### Marking transfers as settled + +The following additional processes are required in order to mark ledger entries which are settled immediate gross as having been settled. + +##### Queueing transfers for settlement processing + +When a transfer is completed, a record is generated in the **transferFulfilment** table. As part of the process that generates this record, the transfer should be placed on a Kafka stream for immediate settlement processing. + +##### Processing settlements + +A new service should be developed for processing gross (i.e. per-transfer) settlements. The requirements for this service are as follows: +1. It should enable an auditor to verify that a given transfer has been settled using the agreed process +2. It should allow transfer settlement to be recorded either internally, using an automatic process, or externally, exporting the information for each transfer to be settled to a configurable endpoint. +3. It should not delay processing of the transfer itself + +The characteristics of the service should be as follows: + +1. Pick a transfer from the Kafka stream holding transfers awaiting settlement processing. There is no requirement for sequence preservation, so this service can pick up multiple transfer entries if this would accelerate processing. +2. For each record in the **transferParticipant** table which belongs to the transfer *and* whose **ledgerEntryType** column specifies a ledger entry type which belongs to a settlement model which is settled both GROSS and IMMEDIATE, the service should generate consecutive records in the **transferParticipantStateChange** table with the values: CLOSED, PENDING_SETTLEMENT, and SETTLED, in that order. The **currentStateChangeId** column for the record in the **transferParticipant** table should be set to point to the record in the **transferParticipantStateChange** table whose value is SETTLED. +3. For each record in the **transferParticipant** table which belongs to the transfer *and* whose **ledgerEntryType** column specifies a ledger entry type which belongs to a settlement model which is settled both GROSS and IMMEDIATE *and* where the settlement model has an export endpoint configured, the process should export the information relating to the entry that is being settled to the endpoint specified in an agreed format. The format to be used, the means of specifying the endpoint to be addressed, and the process by which exports are generated and acknowledged, are not specified at this time. +4. For all other records in the **transferParticipant** table which belong to the transfer, the service should generate a record in the **transferParticipantStateChange** table with a value of OPEN. The **currentStateChangeId** column for the record in the **transferParticipant** table should be set to point to the record in the **transferParticipantStateChange** table which was created. + +#### Updating status values for net settlements + +When the status is updated for a participant in a settlement which belongs to a settlement model which is not settled both GROSS and IMMEDIATE, then the constituent records for that participant in the settlement in the **transferParticipant** table need to be updated. The rules for this are: + +1. When the settlement is created, all the records in **transferParticipant** which belong to a transfer which belongs to a window which belongs to the settlement being created (i.e. which are contained in the inner join between **transferParticipant**, **transferfulfilment** (on **transferId**) and **settlementSettlementWindow** (on **settlementWindowId**) for the settlement Id which is being created) should have a record created in **settlementContentAggregationStateChange** with the **settlementWindowStateId** column set to PENDING_SETTLEMENT. +2. When a participant's settlement status is updated to SETTLED in **settlementParticipantCurrency**, then all the records in **transferParticipant** for settlement windows which belong to that settlement, and whose participant and currency IDs match the participant and currency of the records in **settlementParticipantCurrency** which have been updated, should have their status set to SETTLED. + +#### Gross settlement and position management + +If gross settlement is enabled for a settlement model and that settlement model also has its **adjustPosition** flag set to TRUE, then an adjustment to both participants' positions should be made. This should be done in the following way: + +1. For each record in the **transferParticipant** table which is being settled, create a record in the **participantPositionChange** table with the following characteristics: + a. The **participantPositionId** column should be set to the value of the **participantPositionId** column in the **participantPosition** table for the record whose **participantCurrencyId** field is the same as that of the record in the **transferParticipant** table which has been settled. + b. The **transferStateChangeId** column should be set to the value of the **transferStateChangeId** column for the record in the **transferStateChange** table whose **transferId** column is the same as the value of the **transferId** column in the **transferParticipant** table for the record which is being settled, and which has the latet value in its **createdDate** column. + c. The **value** column should be set to the **amount** column in the **transferParticipant** table for the record which is being settled. + d. The **reservedValue** column should be set to zero. + e. The **createdDate** column should be set to the current date and time. +2. The record in the **participantPosition** table whose **participantCurrencyId** field matches that of the record in the **transferParticipant** table which has been settled should have the **amount** column of the corresponding record in the **transferParticipant** table added to its **value** column. + +Domain class diagram +==================== + +ERD +=== + +The following ERD describes the new data structures required to model settlements. + +![](/mojaloop-technical-overview/central-settlements/assets/diagrams/Settlement_ERD.png) + +Enumerations +------------ + +The following enumerations are required to support the new ERD: +``` +DELETE FROM settlementGranularity; +INSERT INTO settlementGranularity (name) +VALUES ('GROSS'), ('NET'); + +DELETE FROM settlementInterchange; +INSERT INTO settlementInterchange (name) +VALUES ('BILATERAL'), ('MULTILATERAL'); + +DELETE FROM settlementDelay; +INSERT INTO settlementDelay(name) +VALUES ('IMMEDIATE'), ('DEFERRED'); +``` diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/README.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/README.md new file mode 100644 index 000000000..1cf8e627b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/README.md @@ -0,0 +1,111 @@ +# Settlement Process + +## 1. Database Design + +### Notes: + +- `settlementWindow` - a table where all settlement windows are stored; +- `settlementWindowStateChange` - stores information regarding settlement windows state; +- `settlement` - keeps data regarding all settlements; +- `settlementContentAggregation` - contains aggregated values for a settlement, participant currency, role type and ledger entry type grouping in a settlement; +- `settlementModel` - contains the configured settlement models for the switch; +- `settlementWindowContent` - contains an entry for each item of content in a given settlement window, broken down by ledger account type and currency; +- `settlementWindowContentStateChange` - tracks settlement window content state changes; +- `settlementSettlementWindow` - association table for settlements and settlement windows, providing connection many-to-many; +- `settlementStateChange` - tracks the settlement state change; +- `settlementTransferParticipant` - this table is used for staging data for all transfers which are to be included in a settlement; +- `settlementParticipantCurrency` - stores grouped information by participant and currency. For calculation of netAmount, the summarized data from `settlementTransferParticipant` is used; +- `settlementParticipantCurrencyStateChange` - used to track the state change of each individual settlement participant account. + +The remaining tables in the below ERD are either transfer-specific (gray) or lookup (blue) and are included as direct dependencies to depict the relation between the settlement tables and transfer specific entities. + +![Central Settlements. Service ERD](./assets/entities/central-settlements-db-schema.png) + +* [Central Settlements Service DBeaver ERD](./assets/entities/central-settlements-db-schema-dbeaver.erd) + +## 2. Sequence diagrams + +### 2.1. Settlement Windows By Params + +Used for acquiring information regarding Settlement Windows. E.g.: +1. Find the ID of the current OPEN window by querying by state and later use the information for closing that window; +2. Find all CLOSED and/or ABORTED windows to be used for creating a settlement; +3. Other reporting needs. +- [Sequence Diagram for Get Settlement Windows by Parameters](get-settlement-windows-by-params.md) + +### 2.2. Settlement Windows By Params + +Used for acquiring settlement window information when ID is present. +- [Sequence Diagram for Request Settlement Window by Id](get-settlement-window-by-id.md) + +### 2.3. Close Settlement Window + +There is always one open settlement window which groups all ongoing transfers. This functionality is used to close the currently opened window and create the next one. The operations starts on the API and then the Deferred handler consumes a message after the validations are passed and prepares the Settlement Window Content and Settlement Content Aggregation records for the settlement process. +- [Sequence Diagram for Close Settlement Window](post-close-settlement-window.md) + +### 2.4. Create Settlement + +The creation of settlement is possible when at least one OPEN or ABORTED window is provided. The data from all transfers in all provided windows is summarized and as a result the settlement amount is calculated per participant and currency. Depending on its sign we distinct 3 types of participants in regards to the newly created settlement: SETTLEMENT_NET_RECIPIENT, SETTLEMENT_NET_SENDER and SETTLEMENT_NET_ZERO. Newly generated id of type bigint is returned as a response together it all other information. +- [Sequence Diagram for Trigger Settlement Event](post-create-settlement.md) + +### 2.5. Request Settlement + +This endpoint is used for acquiring information regarding a settlement and all included windows and accounts/positions. The ID from the previous request is being utilized for that purpose. +- [Sequence Diagram for Get Settlement by Id](get-settlement-by-id.md) + +### 2.6. Settlement Transfer Acknowledgment + +It is used to advance the settlement through all the states initiated with the creation and finilized by settle or abort. The actual state flow is: +- PENDING_SETTLEMENT: The net settlement report for this window has been taken, with the parameter set to indicate that settlement is to be processed; +- PS_TRANSFERS_RECORDED: Record transfer entries against the Position Account and the Multi-lateral Net Settlement Account, these are the "multi-lateral net  settlement transfers" (MLNS transfers). An identifier might be provided to be past to the reference bank; +- PS_TRANSFERS_RESERVED: All the debit entries for the MLNS transfers are reserved; +- PS_TRANSFERS_COMMITTED: All the credit entries for the MLNS transfers are committed. An identifier might be received and recorded from the Settlement bank to allow reconciliation; +- SETTLING: If all accounts are not yet SETTLED, the Status of the settlement is moved to SETTLING. Note: applies only on settlement level; +- SETTLED: Final state when all outstanding accounts are SETTLED, the entire Settlement is moved to SETTLED. + +[Sequence Diagram for Acknowledgement of Settlement Transfer](put-settlement-transfer-ack.md) + +### 2.7. Settlement Abort + +- ABORTED: Final state when the settlement is not possible. Please, note the settlement might be aborted up to when no account/position has been marked as PS_TRANSFERS_COMMITTED. Also there is no possibility to mark an individual account as ABORTED, but rahter the entire settlement is ABORTED. After performing such operation there is possibility to create a new settlement by including only non-problematic ABORTED accounts + +[Sequence Diagram for Settlement Abort](put-settlement-abort.md) + +### 2.8. Request Settlement By SPA + +Used to request drill-down information regarding a settlement, participant and account. Even though participant and account are optional, the order settlement/{id}/participant/{id}/account/{id} is mandatory. + +- [Sequence Diagram for Get Settlement by Settlement/Participant/Account](get-settlement-by-spa.md) + +### 2.9. Request Settlements By Params + +This endpoint enables advanced reporting capabilities. + +- [Sequence Diagram for Query Settlements by Parameters](get-settlements-by-params.md) + +### 2.10 Gross Settlement Handler + +This handler executes after each transfer is committed and performs the following operations on success: + Handle the updating of the POSITION and SETTLEMENT accounts for participants involved in a transfer where there is a settlement model defined as immediate and gross on the POSITION account to facilitate RTCGS (Real-Time Continuous Gross Settlement) per transfer. + +This is done by consuming events of the notification topic. + +- [Sequence Diagram for Gross Settlement Handler](gross-settlement-handler-consume.md) + +### 2.11 Rules Handler + +This handler executes after each transfer is committed and performs the following operations on success: + Execute the rules defined by the scripts in the SCRIPTS_FOLDER. The rules are validated for valid headers before loading. + +This is done by consuming events of the notification topic. + +- [Sequence Diagram for Rules Handler](rules-handler-consume.md) + +### 2.12 Deferred Handler + +This handler executes after close settlement window operation has been received and validated: + + Handle the updating of the participant accounts involved in the transfers for the settlement window that is closed. The process then continues with settlement event trigger. + +This is done by consuming events of the notification topic, that are emitted by the service after close settlement window command has been sent and validated. +- [Sequence Diagram for Close Settlement Window](post-close-settlement-window.md) \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.plantuml new file mode 100644 index 000000000..fc837adab --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.plantuml @@ -0,0 +1,204 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Neal Donnan + * Shashikant Hirugade + -------------- + ******'/ + +@startuml +' declare title +title Gross Settlement Handler Consume (Success) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors + +collections "topic-notification" as TOPIC_NOTIFICATION +control "Gross Settlement Handler" as SETTLEMENT_HANDLER +control "Gross Settlement Service" as SETTLEMENT_SERVICE +database "central_ledger" as DB +entity "Settlement DAO" as SETTLEMENT_DAO + +box "Settlement Service" #LightGreen + participant TOPIC_NOTIFICATION + participant SETTLEMENT_HANDLER + participant SETTLEMENT_SERVICE + participant SETTLEMENT_DAO +end box + +box "Central Services" #lightyellow + participant DB +end box + +' start flow +activate SETTLEMENT_HANDLER +group Gross Settlement Handler Consume (Success) + alt Consume Single Message + TOPIC_NOTIFICATION <- SETTLEMENT_HANDLER: Consume notification event message + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + group Validate Message + SETTLEMENT_HANDLER <-> SETTLEMENT_HANDLER: Validate event - Rule: message has payload\nError codes: 2001 + end + opt action == 'COMMIT' + + group Retry (default 3 retries) + group DB TRANSACTION: settle transfer + SETTLEMENT_HANDLER -> SETTLEMENT_SERVICE: Process fulfil message + SETTLEMENT_SERVICE -> SETTLEMENT_DAO: Get Gross settlement model + SETTLEMENT_DAO -> DB: Get settlement model records + activate DB + deactivate DB + hnote over DB #lightyellow + SELECT settlementModel.* + FROM **settlementModel** + INNER JOIN `participantCurrency` AS `pc` ON `pc`.`currencyId` = `settlementModel`.`currencyId` + AND `pc`.`ledgerAccountTypeId` `settlementModel`.`ledgerAccountTypeId` + INNER JOIN `transferParticipant` AS `tp` ON `tp`.`participantCurrencyId` = `pc`.`participantCurrencyId` + INNER JOIN settlementGranularity AS `g` ON `g`.`settlementGranularityId` = `settlementModel`.`settlementGranularityId` + WHERE `tp`.`transferId`, {transferId} + AND `g`.`name`, {settlementGranularityName} + AND `settlementModel`.`isActive`, {1}; + end hnote + SETTLEMENT_DAO <-- DB: Gross settlement model result + SETTLEMENT_SERVICE <-- SETTLEMENT_DAO: Gross settlement model result + group Validate settlement model + SETTLEMENT_SERVICE <-> SETTLEMENT_SERVICE: Valid Gross settlement model with given currency does not exist + SETTLEMENT_SERVICE <-> DB: Get all settlement models + alt Check if NET settlement model with the transfer currency exists + SETTLEMENT_SERVICE <-> SETTLEMENT_SERVICE: Return true + else + SETTLEMENT_SERVICE <-> SETTLEMENT_SERVICE: filter all settlement models by currencyId === null and granularityType === GROSS + SETTLEMENT_SERVICE <-> SETTLEMENT_SERVICE: Return default GROSS settlement model + end + end + SETTLEMENT_SERVICE -> SETTLEMENT_DAO: Settle transfer if CGS + SETTLEMENT_DAO -> DB: Insert transferParticipant entries + activate DB + deactivate DB + hnote over DB #lightyellow + insert into **`transferParticipant`** (transferID, participantCurrencyId, transferParticipantRoleTypeId, ledgerEntryTypeId, + amount) + select `TP`.`transferId`, + `TP`.`participantCurrencyId`, + `TP`.`transferParticipantRoleTypeId`, + `TP`.`ledgerEntryTypeId`, + `TP`.`amount` * -1 + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + union + select `TP`.`transferId`, + `PC1`.`participantCurrencyId`, + `TP`.`transferParticipantRoleTypeId`, + `TP`.`ledgerEntryTypeId`, + `TP`.`amount` + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + inner join `participantCurrency` as `PC1` + on `PC1`.`currencyId` = `PC`.`currencyId` and `PC1`.`participantId` = `PC`.`participantId` and + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')); + end hnote + SETTLEMENT_DAO -> DB: Update participantPosition records + activate DB + deactivate DB + hnote over DB #lightyellow + update **`participantPosition`** as `PP` + inner join (select `PC`.`participantCurrencyId`, `TP`.`Amount` + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` + on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + union + select `PC1`.`participantCurrencyId`, `TP`.`amount` + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` + on `M`.`ledgerAccountTypeId` = `PC`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + inner join `participantCurrency` as `PC1` + on `PC1`.`currencyId` = `PC`.`currencyId` and + `PC1`.`participantId` = `PC`.`participantId` and + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS'))) + AS TR ON PP.participantCurrencyId = TR.ParticipantCurrencyId + set `value` = `PP`.`value` - `TR`.`amount`; + end hnote + SETTLEMENT_DAO -> DB: Insert participantPositionChange records + activate DB + deactivate DB + hnote over DB #lightyellow + insert into **`participantPositionChange`** (participantPositionId, transferStateChangeId, value, reservedValue) + select `PP`.`participantPositionId`, `TSC`.`transferStateChangeId`, `PP`.`value`, `PP`.`reservedValue` + from `participantPosition` as `PP` + inner join (select `PC`.`participantCurrencyId` + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` + on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + union + select `PC1`.`participantCurrencyId` + from `transferParticipant` as `TP` + inner join `participantCurrency` as `PC` + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + inner join `settlementModel` as `M` + on `PC`.`ledgerAccountTypeId` = `PC`.`ledgerAccountTypeId` + inner join `settlementGranularity` as `G` + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + inner join `participantCurrency` as `PC1` on `PC1`.`currencyId` = `PC`.`currencyId` and + `PC1`.`participantId` = `PC`.`participantId` and + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS'))) AS TR + ON PP.participantCurrencyId = TR.ParticipantCurrencyId + inner join `transferStateChange` as `TSC` + on `TSC`.`transferID` = {transferId} and `TSC`.`transferStateId` = 'SETTLED'; + end hnote + end + end + end + else Consume Batch Messages + note left of SETTLEMENT_HANDLER #lightblue + To be delivered by future story + end note + end +end +deactivate SETTLEMENT_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.svg new file mode 100644 index 000000000..5d560d536 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-gross-settlement-handler.svg @@ -0,0 +1,567 @@ + + + + + + + + + + + Gross Settlement Handler Consume (Success) + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + + + topic-notification + + + + + topic-notification + + + Gross Settlement Handler + + + + + Gross Settlement Handler + + + + + Gross Settlement Service + + + + + Gross Settlement Service + + + + + Settlement DAO + + + + + Settlement DAO + + + + + central_ledger + + + + + central_ledger + + + + + + + + Gross Settlement Handler Consume (Success) + + + + + alt + + + [Consume Single Message] + + + + + 1 + + + Consume notification event message + + + + + Validate Message + + + + + 2 + + + Validate event - Rule: message has payload + + + Error codes: + + + 2001 + + + + + opt + + + [action == 'COMMIT'] + + + + + Retry (default 3 retries) + + + + + DB TRANSACTION: settle transfer + + + + + 3 + + + Process fulfil message + + + + + 4 + + + Get Gross settlement model + + + + + 5 + + + Get settlement model records + + + + SELECT settlementModel.* + + + FROM + + + settlementModel + + + INNER JOIN `participantCurrency` AS `pc` ON `pc`.`currencyId` = `settlementModel`.`currencyId` + + + AND `pc`.`ledgerAccountTypeId` `settlementModel`.`ledgerAccountTypeId` + + + INNER JOIN `transferParticipant` AS `tp` ON `tp`.`participantCurrencyId` = `pc`.`participantCurrencyId` + + + INNER JOIN settlementGranularity AS `g` ON `g`.`settlementGranularityId` = `settlementModel`.`settlementGranularityId` + + + WHERE `tp`.`transferId`, {transferId} + + + AND `g`.`name`, {settlementGranularityName} + + + AND `settlementModel`.`isActive`, {1}; + + + + + 6 + + + Gross settlement model result + + + + + 7 + + + Gross settlement model result + + + + + Validate settlement model + + + + + 8 + + + Valid Gross settlement model with given currency does not exist + + + + + 9 + + + Get all settlement models + + + + + alt + + + [Check if NET settlement model with the transfer currency exists] + + + + + 10 + + + Return true + + + + + + 11 + + + filter all settlement models by currencyId === null and granularityType === GROSS + + + + + 12 + + + Return default GROSS settlement model + + + + + 13 + + + Settle transfer if CGS + + + + + 14 + + + Insert transferParticipant entries + + + + insert into + + + `transferParticipant` + + + (transferID, participantCurrencyId, transferParticipantRoleTypeId, ledgerEntryTypeId, + + + amount) + + + select `TP`.`transferId`, + + + `TP`.`participantCurrencyId`, + + + `TP`.`transferParticipantRoleTypeId`, + + + `TP`.`ledgerEntryTypeId`, + + + `TP`.`amount` * -1 + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + + + union + + + select `TP`.`transferId`, + + + `PC1`.`participantCurrencyId`, + + + `TP`.`transferParticipantRoleTypeId`, + + + `TP`.`ledgerEntryTypeId`, + + + `TP`.`amount` + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + inner join `participantCurrency` as `PC1` + + + on `PC1`.`currencyId` = `PC`.`currencyId` and `PC1`.`participantId` = `PC`.`participantId` and + + + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')); + + + + + 15 + + + Update participantPosition records + + + + update + + + `participantPosition` + + + as `PP` + + + inner join (select `PC`.`participantCurrencyId`, `TP`.`Amount` + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` + + + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` + + + on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` + + + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + + + union + + + select `PC1`.`participantCurrencyId`, `TP`.`amount` + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` + + + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` + + + on `M`.`ledgerAccountTypeId` = `PC`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` + + + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + inner join `participantCurrency` as `PC1` + + + on `PC1`.`currencyId` = `PC`.`currencyId` and + + + `PC1`.`participantId` = `PC`.`participantId` and + + + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS'))) + + + AS TR ON PP.participantCurrencyId = TR.ParticipantCurrencyId + + + set `value` = `PP`.`value` - `TR`.`amount`; + + + + + 16 + + + Insert participantPositionChange records + + + + insert into + + + `participantPositionChange` + + + (participantPositionId, transferStateChangeId, value, reservedValue) + + + select `PP`.`participantPositionId`, `TSC`.`transferStateChangeId`, `PP`.`value`, `PP`.`reservedValue` + + + from `participantPosition` as `PP` + + + inner join (select `PC`.`participantCurrencyId` + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` + + + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` + + + on `PC`.`ledgerAccountTypeId` = `M`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` + + + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS')) + + + union + + + select `PC1`.`participantCurrencyId` + + + from `transferParticipant` as `TP` + + + inner join `participantCurrency` as `PC` + + + on `TP`.`participantCurrencyId` = `PC`.`participantCurrencyId` + + + inner join `settlementModel` as `M` + + + on `PC`.`ledgerAccountTypeId` = `PC`.`ledgerAccountTypeId` + + + inner join `settlementGranularity` as `G` + + + on `M`.`settlementGranularityId` = `G`.`settlementGranularityId` + + + inner join `participantCurrency` as `PC1` on `PC1`.`currencyId` = `PC`.`currencyId` and + + + `PC1`.`participantId` = `PC`.`participantId` and + + + `PC1`.`ledgerAccountTypeId` = `M`.`settlementAccountTypeId` + + + where (`TP`.`transferId` = {transferId} and (`G`.`name` = 'GROSS'))) AS TR + + + ON PP.participantCurrencyId = TR.ParticipantCurrencyId + + + inner join `transferStateChange` as `TSC` + + + on `TSC`.`transferID` = {transferId} and `TSC`.`transferStateId` = 'SETTLED'; + + + + [Consume Batch Messages] + + + + + To be delivered by future story + + diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.plantuml new file mode 100644 index 000000000..88ff1491c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.plantuml @@ -0,0 +1,219 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Neal Donnan + * Valentin Genev + -------------- + ******'/ + +@startuml +' declare title +title Rules Handler Consume (Success) +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors + +collections "topic-notification" as TOPIC_NOTIFICATION +control "Rules Handler" as RULES_HANDLER +database "central_ledger" as DB +entity "Scripts Loader" as SCRIPTS_LOADER +entity "Script Engine" as SCRIPT_ENGINE +entity "Transaction DAO" as TRANSACTION_DAO +entity "Settlement DAO" as SETTLEMENT_DAO +entity "Central Ledger DAO" as CENTRAL_LEDGER_DAO + +box "Settlement Service" #LightGreen + participant TOPIC_NOTIFICATION + participant RULES_HANDLER + participant SCRIPTS_LOADER + participant SCRIPT_ENGINE + participant TRANSACTION_DAO + participant SETTLEMENT_DAO + participant CENTRAL_LEDGER_DAO +end box + +box "Central Services" #lightyellow + participant DB +end box + +' start flow +activate RULES_HANDLER +group Rules Handler Consume (Success) + group Load Scripts + RULES_HANDLER -> SCRIPTS_LOADER: load scripts (yaml file) (scriptDirectory) + activate SCRIPTS_LOADER + loop script + SCRIPTS_LOADER -> SCRIPTS_LOADER: validate script type, action and status against enums; validate script is valid JS; validate start and end timestamps; Create a map ScriptMap[type][action][result] + end + SCRIPTS_LOADER --> RULES_HANDLER: create script map + note right of RULES_HANDLER #yellow + example: + { + scriptType: { + scriptAction: { + scriptStatus: {[ + { + name: "interchangeFeeCalculation", + startTime: "2020-06-01T00:00:00.000Z", + endTime: "2100-12-31T23:59:59.999Z", + script: [vm.Script] + } + ]} + } + } + } + end note + deactivate SCRIPTS_LOADER + end + group Process Single Message + TOPIC_NOTIFICATION <- RULES_HANDLER: Consume notification event message + activate TOPIC_NOTIFICATION + deactivate TOPIC_NOTIFICATION + group Validate Message + RULES_HANDLER <-> RULES_HANDLER: Validate event - Rule: message has payload\nError codes: 2001 + end + alt Rule found + RULES_HANDLER <-> RULES_HANDLER: check if ScriptMap[type][action][result] has valid script assigned + group Execute Scripts + RULES_HANDLER -> SCRIPTS_LOADER: execute scripts + activate SCRIPTS_LOADER + loop script + SCRIPTS_LOADER -> SCRIPT_ENGINE: execute(script, message payload) + activate SCRIPT_ENGINE + SCRIPT_ENGINE -> TRANSACTION_DAO: Get transaction by transfer Id + activate TRANSACTION_DAO + TRANSACTION_DAO -> DB: retrieve ILP packet from ilpPacket + activate DB + DB --> TRANSACTION_DAO: ilpPacket row + deactivate DB + TRANSACTION_DAO --> SCRIPT_ENGINE: ilpPacket row + SCRIPT_ENGINE -> TRANSACTION_DAO: Get transaction object + TRANSACTION_DAO -> TRANSACTION_DAO: decode ILP packet + TRANSACTION_DAO --> SCRIPT_ENGINE: Transaction object + SCRIPT_ENGINE -> SCRIPT_ENGINE: execute script in sandbox + deactivate + SCRIPT_ENGINE --> SCRIPTS_LOADER: Ledger entries + deactivate SCRIPT_ENGINE + SCRIPTS_LOADER -> SCRIPTS_LOADER: Merge results + end + SCRIPTS_LOADER --> RULES_HANDLER: script results + deactivate SCRIPTS_LOADER + end + + alt Has ledger entries + group DB TRANSACTION: Validate and Insert ledger entries + RULES_HANDLER -> SETTLEMENT_DAO: Insert valid ledger entries + SETTLEMENT_DAO -> DB: Get the records to insert + activate DB + hnote over DB #lightyellow + select {transferId} AS transferId, + `PC`.`participantCurrencyId`, + IFNULL(`T1`.`transferparticipantroletypeId`, + `T2`.`transferparticipantroletypeId`) as `transferParticipantRoleTypeId`, + `E`.`ledgerEntryTypeId`, + CASE `P`.`name` + WHEN {ledgerEntry.payerFspId} THEN {ledgerEntry.amount} + WHEN {ledgerEntry.payeeFspId} THEN {ledgerEntry.amount * -1} + ELSE 0 + END AS `amount` + from `participantCurrency` as `PC` + inner join `participant` as `P` on `P`.`participantId` = `PC`.`participantId` + inner join `ledgerEntryType` as `E` on `E`.`LedgerAccountTypeId` = `PC`.`LedgerAccountTypeId` + left outer join `transferParticipantRoleType` as `T1` on `P`.`name` = {ledgerEntry.payerFspId} and `T1`.`name` = 'PAYER_DFSP' + left outer join `transferParticipantRoleType` as `T2` on `P`.`name` = {ledgerEntry.payerFspId} and `T2`.`name` = 'PAYEE_DFSP' + where `E`.`name` = {ledgerEntry.ledgerEntryTypeId} + and `P`.`name` in ({ledgerEntry.payerFspId}, {ledgerEntry.payeeFspId}) + and `PC`.`currencyId` = {ledgerEntry.currency}; + end hnote + SETTLEMENT_DAO <-- DB: recordsToInsert + deactivate DB + + alt Has records to insert + SETTLEMENT_DAO -> DB: Insert transferParticipant records + activate DB + deactivate DB + hnote over DB #lightyellow + insert into **transferParticipant** + + end hnote + SETTLEMENT_DAO -> DB: Update positions + activate DB + deactivate DB + loop transferParticipant records + hnote over DB #lightyellow + update **`participantPosition`** + set `value` = `value` + {record.amount} + where `participantCurrencyId` = {record.participantCurrencyId}; + end hnote + end + SETTLEMENT_DAO -> DB: Get transferStateChange record + activate DB + hnote over DB #lightyellow + select `transferStateChangeId` + from **`transferStateChange`** + where `transferId` = {transferId} + and `transferStateId` = 'COMMITTED'; + end hnote + SETTLEMENT_DAO <-- DB: transferStateChange record + deactivate DB + SETTLEMENT_DAO -> DB: Get participantPosition record + activate DB + hnote over DB #lightyellow + select `participantPositionId`, `value`, `reservedValue` + from **`participantPosition`** + where `participantCurrencyId` = {recordsToInsert[0].participantCurrencyId} + OR `participantCurrencyId` = {recordsToInsert[1].participantCurrencyId}; + end hnote + SETTLEMENT_DAO <-- DB: participantPosition record + deactivate DB + SETTLEMENT_DAO -> DB: Insert participantPositionChange records + activate DB + deactivate DB + hnote over DB #lightyellow + insert into **`participantPositionChange`** + select `participantPositionId`, {transferStateChangeId}, `value`, `reservedValue` + from `participantPosition` + where `participantCurrencyId` = {transferParticipantRecord1.participantCurrencyId} + or `participantCurrencyId` = {transferParticipantRecord2.participantCurrencyId}; + end hnote + else No records found + SETTLEMENT_DAO <-> SETTLEMENT_DAO: Error + end + else + SETTLEMENT_DAO <-> SETTLEMENT_DAO: Rollback on Error + end + else + RULES_HANDLER <-> RULES_HANDLER: exit + end + + + else + RULES_HANDLER <-> RULES_HANDLER: exit + end + end +end +deactivate RULES_HANDLER +@enduml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.svg new file mode 100644 index 000000000..1a26ed085 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-rules-handler.svg @@ -0,0 +1,642 @@ + + + + + + + + + + + Rules Handler Consume (Success) + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + + + + + topic-notification + + + + + topic-notification + + + Rules Handler + + + + + Rules Handler + + + + + Scripts Loader + + + + + Scripts Loader + + + + + Script Engine + + + + + Script Engine + + + + + Transaction DAO + + + + + Transaction DAO + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Ledger DAO + + + + + Central Ledger DAO + + + + + central_ledger + + + + + central_ledger + + + + + + + + Rules Handler Consume (Success) + + + + + Load Scripts + + + + + 1 + + + load scripts (yaml file) (scriptDirectory) + + + + + loop + + + [script] + + + + + 2 + + + validate script type, action and status against enums; validate script is valid JS; validate start and end timestamps; Create a map ScriptMap[type][action][result] + + + + + 3 + + + create script map + + + + + example: + + + { + + + scriptType: { + + + scriptAction: { + + + scriptStatus: {[ + + + { + + + name: "interchangeFeeCalculation", + + + startTime: "2020-06-01T00:00:00.000Z", + + + endTime: "2100-12-31T23:59:59.999Z", + + + script: [vm.Script] + + + } + + + ]} + + + } + + + } + + + } + + + + + Process Single Message + + + + + 4 + + + Consume notification event message + + + + + Validate Message + + + + + 5 + + + Validate event - Rule: message has payload + + + Error codes: + + + 2001 + + + + + alt + + + [Rule found] + + + + + 6 + + + check if ScriptMap[type][action][result] has valid script assigned + + + + + Execute Scripts + + + + + 7 + + + execute scripts + + + + + loop + + + [script] + + + + + 8 + + + execute(script, message payload) + + + + + 9 + + + Get transaction by transfer Id + + + + + 10 + + + retrieve ILP packet from ilpPacket + + + + + 11 + + + ilpPacket row + + + + + 12 + + + ilpPacket row + + + + + 13 + + + Get transaction object + + + + + 14 + + + decode ILP packet + + + + + 15 + + + Transaction object + + + + + 16 + + + execute script in sandbox + + + + + 17 + + + Ledger entries + + + + + 18 + + + Merge results + + + + + 19 + + + script results + + + + + alt + + + [Has ledger entries] + + + + + DB TRANSACTION: Validate and Insert ledger entries + + + + + 20 + + + Insert valid ledger entries + + + + + 21 + + + Get the records to insert + + + + select {transferId} AS transferId, + + + `PC`.`participantCurrencyId`, + + + IFNULL(`T1`.`transferparticipantroletypeId`, + + + `T2`.`transferparticipantroletypeId`) as `transferParticipantRoleTypeId`, + + + `E`.`ledgerEntryTypeId`, + + + CASE `P`.`name` + + + WHEN {ledgerEntry.payerFspId} THEN {ledgerEntry.amount} + + + WHEN {ledgerEntry.payeeFspId} THEN {ledgerEntry.amount * -1} + + + ELSE 0 + + + END AS `amount` + + + from `participantCurrency` as `PC` + + + inner join `participant` as `P` on `P`.`participantId` = `PC`.`participantId` + + + inner join `ledgerEntryType` as `E` on `E`.`LedgerAccountTypeId` = `PC`.`LedgerAccountTypeId` + + + left outer join `transferParticipantRoleType` as `T1` on `P`.`name` = {ledgerEntry.payerFspId} and `T1`.`name` = 'PAYER_DFSP' + + + left outer join `transferParticipantRoleType` as `T2` on `P`.`name` = {ledgerEntry.payerFspId} and `T2`.`name` = 'PAYEE_DFSP' + + + where `E`.`name` = {ledgerEntry.ledgerEntryTypeId} + + + and `P`.`name` in ({ledgerEntry.payerFspId}, {ledgerEntry.payeeFspId}) + + + and `PC`.`currencyId` = {ledgerEntry.currency}; + + + + + 22 + + + recordsToInsert + + + + + alt + + + [Has records to insert] + + + + + 23 + + + Insert transferParticipant records + + + + insert into + + + transferParticipant + + + + + 24 + + + Update positions + + + + + loop + + + [transferParticipant records] + + + + update + + + `participantPosition` + + + set `value` = `value` + {record.amount} + + + where `participantCurrencyId` = {record.participantCurrencyId}; + + + + + 25 + + + Get transferStateChange record + + + + select `transferStateChangeId` + + + from + + + `transferStateChange` + + + where `transferId` = {transferId} + + + and `transferStateId` = 'COMMITTED'; + + + + + 26 + + + transferStateChange record + + + + + 27 + + + Get participantPosition record + + + + select `participantPositionId`, `value`, `reservedValue` + + + from + + + `participantPosition` + + + where `participantCurrencyId` = {recordsToInsert[0].participantCurrencyId} + + + OR `participantCurrencyId` = {recordsToInsert[1].participantCurrencyId}; + + + + + 28 + + + participantPosition record + + + + + 29 + + + Insert participantPositionChange records + + + + insert into + + + `participantPositionChange` + + + select `participantPositionId`, {transferStateChangeId}, `value`, `reservedValue` + + + from `participantPosition` + + + where `participantCurrencyId` = {transferParticipantRecord1.participantCurrencyId} + + + or `participantCurrencyId` = {transferParticipantRecord2.participantCurrencyId}; + + + + [No records found] + + + + + 30 + + + Error + + + + + + 31 + + + Rollback on Error + + + + + + 32 + + + exit + + + + + + 33 + + + exit + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml similarity index 98% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml index 59d493b43..54cafaa6c 100644 --- a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml @@ -167,6 +167,10 @@ activate OPERATOR SETTLE_DAO -> DB: Associate settlement windows with the settlement activate DB + SETTLE_DAO -> DB: Retrieve SettlementWindowContent id List + opt Settlement Model is Default + SETTLE_DAO -> SETTLE_DAO: filter out the SettlementWindowContent id List\n to exclude content that is not settled by default settlement model + end hnote over DB #lightyellow INSERT INTO **settlementSettlementWindow** (settlementId, settlementWindowId, createdDate) VALUES ({settlementId}, {payload.settlementWindows.idList}, {transactionTimestamp}) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.svg new file mode 100644 index 000000000..7a99625e7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.svg @@ -0,0 +1,1060 @@ + + + + + + + + + + + 6.2.1. Trigger Settlement Event (createSettlement) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Trigger Settlement Event + + + + + { + + + "settlementModel": "string", + + + "reason": "string", + + + "settlementWindows": [ + + + { + + + "id": 1, + + + }, + + + { + + + "id": 2, + + + } + + + ] + + + } + + + + + 1 + + + POST - /settlements + + + + + 2 + + + Request settlementModel + + + Error code: + + + 2001 + + + + + 3 + + + Retrieve settlementModel + + + + SELECT sg.name settlementGranularity, si.name settlementInterchange, + + + sd.name settlementDelay, sm.ledgerAccountTypeId, + + + sm.currencyId, sm.requireLiquidityCheck + + + FROM + + + settlementModel + + + sm + + + JOIN + + + settlementGranularity + + + sg + + + ON sg.settlementGranularityId = sm.settlementGranularityId + + + JOIN + + + settlementInterchange + + + si + + + ON si.settlementInterchangeId = sm.settlementInterchangeId + + + JOIN + + + settlementDelay + + + sd + + + ON sd.settlementDelayId = sm.settlementDelayId + + + WHERE name = {settlementModelName} + + + AND isActive = 1 + + + + + 4 + + + Return data + + + + + 5 + + + Return + + + settlementModelData (smd) + + + + + break + + + [smd.settlementGranularity != 'NET' || + + + smd.settlementInterchange != 'MULTILATERAL' || + + + smd.settlementDelay != 'DEFERRED'] + + + + + Log ERROR event + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Invalid settlement model" + + + } + + + } + + + + + 6 + + + Respond HTTP - 4xx (Client error) + + + + + 7 + + + Request settlementWindow(s) + + + Error code: + + + 2001 + + + + + 8 + + + Retrieve settlementWindow(s) + + + + SELECT DISTINCT sw.settlementWindowId, sw.currentStateChangeId, sw.createdDate + + + FROM + + + settlementWindow + + + sw + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + JOIN + + + settlementWindowContent + + + swc + + + ON swc.settlementWindowId = sw.settlementWindowId + + + JOIN + + + settlementWindowContentStateChange + + + swcsc + + + ON swcsc.settlementWindowContentStateChangeId = sw.currentStateChangeId + + + WHERE sw.settlementWindowId IN {payload.settlementWindows.idList} + + + AND swc.ledgerAccountType = smd.ledgerAccountType + + + AND swc.currencyId = ISNULL(smd.currencyId, swc.currencyId) + + + AND swsc.settlementWindowStateId IN ('CLOSED', 'ABORTED', 'PENDING_SETTLEMENT') + + + AND swcsc.settlementWindowStateId IN ('CLOSED', 'ABORTED') + + + + + 9 + + + Return data + + + + + 10 + + + Return + + + windowsData + + + + + break + + + [payload.settlementWindows.length != windowsData.length] + + + + + Log ERROR event + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Inapplicable windows found: ${windowId1}, ${windowId2}, ..." + + + } + + + } + + + + + 11 + + + Respond HTTP - 4xx (Client error) + + + + + All preliminary validations succeeded + + + + + Main processing + + + + + 12 + + + Create settlement + + + Error code: + + + 2001 + + + + + DB TRANSACTION + + + + + let + + + transactionTimestamp + + + = now() + + + + + 13 + + + Insert new settlement + + + + INSERT INTO + + + settlement + + + (reason, createdDate) + + + VALUES ({payload.reason}, {transactionTimestamp}) + + + + + 14 + + + Return + + + settlementId + + + + + 15 + + + Associate settlement windows with the settlement + + + + + 16 + + + Retrieve SettlementWindowContent id List + + + + + opt + + + [Settlement Model is Default] + + + + + 17 + + + filter out the SettlementWindowContent id List + + + to exclude content that is not settled by default settlement model + + + + INSERT INTO + + + settlementSettlementWindow + + + (settlementId, settlementWindowId, createdDate) + + + VALUES ({settlementId}, {payload.settlementWindows.idList}, {transactionTimestamp}) + + + + + 18 + + + Bind to settlement + + + + settlementWindowContent + + + .settlementId + + + settlementContentAggregation + + + .settlementId + + + .currentStateId + + + + + 19 + + + Change state to 'PENDING_SETTLEMENT' + + + + transferParticipantStateChange + + + transferParticipant + + + settlementWindowContentStateChange + + + settlementWindowContent + + + + + 20 + + + Aggregate settlement net amounts + + + + INSERT INTO + + + settlementParticipantCurrency + + + (settlementId, participantCurrencyId, netAmount, createdDate) + + + SELECT settlementId, participantCurrencyId, SUM(amount), {transactionTimestamp} + + + JOIN + + + settlementContentAggregation + + + WHERE settlementId = {settlementId} + + + GROUP BY settlementId, participantCurrencyId + + + + + 21 + + + Return inserted + + + settlementParticipantCurrencyIdList + + + + + 22 + + + Insert initial settlement accounts state 'PENDING_SETTLEMENT' + + + + INSERT INTO + + + settlementParticipantCurrencyStateChange + + + (settlementParticipantCurrencyId, settlementStateId, reason, createdDate) + + + VALUES ({settlementParticipantCurrencyIdList}, 'PENDING_SETTLEMENT', + + + {payload.reason}, {transactionTimestamp}) + + + + + 23 + + + Return inserted + + + settlementParticipantCurrencyStateChangeIdList + + + + + 24 + + + Merge settlementParticipantCurrencyStateChangeIdList + + + to settlementParticipantCurrencyIdList in order to + + + issue the following update in one knex command + + + + + 25 + + + Update pointers to current state change ids + + + + UPDATE + + + settlementParticipantCurrency + + + SET currentStateChangeId = {settlementParticipantCurrencyStateChangeIdList} + + + WHERE settlementParticipantCurrencyId = {settlementParticipantCurrencyIdList} + + + + + loop + + + [foreach w in windowsData] + + + + + opt + + + [if w.currentStateChangeId IN ('CLOSED', 'ABORTED')] + + + + + 26 + + + Insert new state for settlementWindow 'PENDING_SETTLEMENT' + + + + INSERT INTO + + + settlementWindowStateChange + + + (settlementWindowId, settlementWindowStateId, reason, createdDate) + + + VALUES ({w.settlementWindowId}, 'PENDING_SETTLEMENT', + + + {payload.reason}, {transactionTimestamp}) + + + + + 27 + + + Return inserted + + + settlementWindowStateChangeId + + + + + 28 + + + Update pointers to current state change ids + + + + UPDATE + + + settlementWindow + + + SET currentStateChangeId = {settlementWindowStateChangeId} + + + WHERE settlementWindowId = {w.settlementWindowId} + + + + + 29 + + + Insert initial state for settlement 'PENDING_SETTLEMENT' + + + + INSERT INTO + + + settlementStateChange + + + (settlementId, settlementStateId, reason, createdDate) + + + VALUES ({settlementId}, ‘PENDING_SETTLEMENT’, + + + {payload.reason}, {transactionTimestamp}) + + + + + 30 + + + Return + + + settlementStateChangeId + + + + + 31 + + + Update pointer to current state change id + + + + UPDATE + + + settlement + + + SET currentStateChangeId = {settlementStateChangeId} + + + WHERE settlementId = {settlementId} + + + + + 32 + + + Retrieve all content + + + + settlementWindowContent + + + settlementWindowContentStateChange + + + ledgerAccountType + + + currency + + + settlementWindow + + + settlementWindowStateChange + + + + + 33 + + + Return + + + settlementWindowContentReport + + + + + 34 + + + Use previous result to produce settlementWindowsData ( + + + swd + + + ) array + + + + + 35 + + + Select account data for response + + + + SELECT pc.participantId, spc.participantCurrencyId, spc.netAmount, pc.currencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementId = {settlementId} + + + + + 36 + + + Return + + + accountData + + + + + 37 + + + Construct and return result + + + + + { + + + "id": settlementId, + + + "state": "PENDING_SETTLEMENT", + + + "settlementWindows": [ + + + { + + + "id": swd[m].id, + + + "state": swd[m].state, + + + "reason": swd[m].reason, + + + "createdDate": swd[m].createdDate, + + + "changedDate": swd[m].changedDate, + + + "content": [ + + + { + + + "id": swd[m].content[n].settlementWindowContentId, + + + "state": swd[m].content[n].settlementWindowStateId, + + + "ledgerAccountType": swd[m].content[n].ledgerAccountType, + + + "currencyId": swd[m].content[n].currencyId, + + + "createdDate": swd[m].content[n].createdDate, + + + "changedDate": swd[m].content[n].changedDate + + + } + + + ] + + + } + + + ], + + + "participants": [ + + + { + + + "id": accountData.participantId, + + + "accounts": [ + + + { + + + "id": accountData.participantCurrencyId, + + + "state": "PENDING_SETTLEMENT", + + + "reason": payload.reason, + + + "netSettlementAmount": { + + + "amount": accountData.netAmount, + + + "currency": accountData.currencyId + + + } + + + } + + + ] + + + } + + + ] + + + } + + + + + 38 + + + Respond HTTP - 201 (Created) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.svg new file mode 100644 index 000000000..f47d21e98 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.svg @@ -0,0 +1,609 @@ + + + + + + + + + + + 6.2.2. Query Settlements by Parameters (getSettlementsByParams) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Query Settlements by Parameters + + + + + Params: + + + ?[state={settlementStateId}] + + + [&fromDateTime={fromDateTime}] + + + [&toDateTime={toDateTime}] + + + [&currency={currencyId}] + + + [&settlementWindowId={settlementWindowId}] + + + [&fromSettlementWindowDateTime={fromSettlementWindowDateTime}] + + + [&toSettlementWindowDateTime={toSettlementWindowDateTime}] + + + [&participantId={participantId}] + + + [&accountId={participantCurrencyId}] + + + + + 1 + + + GET - /settlements + + + + + 2 + + + Retrieve settlements + + + Error code: + + + 2001 + + + + + 3 + + + Retrieve requested data + + + + SELECT + + + DISTINCT + + + s.settlementId, ssc.settlementStateId, + + + ssw.settlementWindowId, swsc.settlementWindowStateId, swsc.reason + + + settlementWindowReason, sw.createdDate, swsc.createdDate changedDate, + + + pc.participantId, spc.participantCurrencyId, spcsc.reason + + + accountReason, spcsc.settlementStateId accountState, spc.netAmount + + + accountAmount, pc.currencyId accountCurrency + + + FROM + + + settlement + + + s + + + JOIN + + + settlementStateChange + + + ssc + + + ON ssc.settlementStateChangeId = s.currentStateChangeId + + + JOIN + + + settlementSettlementWindow + + + ssw + + + ON ssw.settlementId = s.settlementId + + + JOIN + + + settlementWindow + + + sw + + + ON sw.settlementWindowId = ssw.settlementWindowId + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + JOIN + + + settlementWindowContent + + + swc + + + ON swc.settlementWindowId = sw.settlementWindowId + + + JOIN + + + settlementWindowContentAggregation + + + swca + + + ON swca.settlementWindowContentId = swc.settlementWindowContentId + + + JOIN + + + settlementParticipantCurrency + + + spc + + + ON spc.settlementId = s.settlementId + + + AND spc.participantCurrencyId = swca.participantCurrencyId + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE [ssc.settlementStateId = {settlementStateId}] + + + [AND s.createdDate >= {fromDateTime}] + + + [AND s.createdDate <= {toDateTime}] + + + [AND pc.currencyId = {currencyId}] + + + [AND sw.settlementWindowId = + + + {settlementWindowId} + + + ] + + + [AND sw.createdDate >= {fromSettlementWindowDateTime}] + + + [AND sw.createdDate <= {toSettlementWindowDateTime}] + + + [AND pc.participantId = {participantId}] + + + [AND spc.participantCurrencyId = {participantCurrencyId}] + + + + + 4 + + + Return data + + + + + 5 + + + Return + + + settlementsData + + + + + alt + + + [Settlement(s) found] + + + + + let settlements = {} + + + let settlement + + + let participant + + + + + loop + + + [settlementsData] + + + + + if (!settlements[settlementsData.settlementId]) { + + + settlements[settlementsData.settlementId] = { + + + "id: settlementsData.settlementId, + + + "state": settlementsData.settlementStateId + + + } + + + } + + + settlement = settlements[settlementsData.settlementId] + + + if (!settlement.settlementWindows[settlementsData.settlementWindowId]) { + + + settlement.settlementWindows[settlementsData.settlementWindowId] = { + + + "id": settlementsData.settlementWindowId, + + + "state": settlementsData.settlementWindowStateId, + + + "reason": settlementsData.settlementWindowReason, + + + "createdDate": settlementsData.createdDate, + + + "changedDate": settlementsData.changedDate + + + } + + + } + + + if (!settlement.participants[settlementsData.participantId]) { + + + settlement.participants[settlementsData.participantId] = { + + + "id": settlementsData.participantId + + + } + + + } + + + participant = settlement.participants[settlementsData.participantId] + + + participant.accounts[settlementsData.accountId] = { + + + "id": settlementsData.participantCurrencyId, + + + "state": settlementsData.accountState, + + + "reason": settlementsData.accountReason, + + + "netSettlementAmount": { + + + "amount": settlementsData.accountAmount, + + + "currency": settlementsData.accountCurrency + + + } + + + } + + + + + 6 + + + Transform + + + settlements + + + map to array + + + + + [ + + + { + + + "id": settlementId, + + + "state": settlementStateId, + + + "settlementWindows": [ + + + { + + + "id": settlementWindowId, + + + "state": settlementWindowStateId, + + + "reason": settlementWindowReason, + + + "createdDate": createdDate, + + + "changedDate": changedDate + + + } + + + ], + + + "participants": [ + + + { + + + "id": participantId, + + + "accounts": [ + + + { + + + "id": participantCurrencyId, + + + "state": accountState, + + + "reason": accountReason, + + + "netSettlementAmount": { + + + "amount": accountAmount, + + + "currency": accountCurrency + + + } + + + } + + + ] + + + } + + + ] + + + } + + + ] + + + + + 7 + + + Respond HTTP - 200 (OK) + + + + + + Log ERROR event + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 8 + + + Respond HTTP - 4xx (Client error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.svg new file mode 100644 index 000000000..47915f13b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.svg @@ -0,0 +1,916 @@ + + + + + + + + + + + 6.2.3. Get Settlement By Settlement, Participant and Account (getSettlementBySPA) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Get Settlement By Settlement, Participant and Account + + + + + alt + + + + + 1 + + + GET - /settlements/{settlementId}/ + + + participants/{participantId} + + + + + + 2 + + + GET - /settlements/{settlementId}/ + + + participants/{participantId}/ + + + accounts/{accountId} + + + + + let settlementFound = false + + + let participantFoundInSettlement = false + + + let accountProvided = accountId > 0 + + + let participantAndAccountMatched = !accountProvided + + + let accountFoundInSettlement = !accountProvided + + + + + 3 + + + Request settlement state + + + Error code: + + + 2001 + + + + + 4 + + + Retrieve settlement + + + + SELECT s.settlementId, ssc.settlementStateId, s.reason, s.createdDate + + + FROM + + + settlement + + + s + + + JOIN + + + settlementStateChange + + + ssc + + + ON ssc.settlementStateChangeId = s.currentStateChangeId + + + WHERE s.settlementId = {id} + + + + + 5 + + + Return + + + settlement + + + + + if (settlement.settlementId) { + + + settlementFound + + + = true + + + } + + + + + opt + + + [settlementFound] + + + + + 6 + + + Check participant + + + Error code: + + + 2001 + + + + + 7 + + + Check exists + + + + SELECT settlementParticipantCurrencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementId = {id} + + + AND pc.participantId = {participantId} + + + + + 8 + + + Return + + + settlementParticipantCurrencyIdList + + + + + if (settlementParticipantCurrencyIdList.length > 0) { + + + participantFoundInSettlement + + + = true + + + } + + + + + opt + + + [participantFoundInSettlement && accountProvided] + + + + + 9 + + + Check participant + + + Error code: + + + 2001 + + + + + 10 + + + Check exists + + + + SELECT participantCurrencyId + + + JOIN + + + participantCurrency + + + WHERE participantCurrencyId = {accountId} + + + AND participantId = {participantId} + + + + + 11 + + + Return + + + account + + + + + if (account) { + + + participantAndAccountMatched + + + = true + + + } + + + + + opt + + + [participantAndAccountMatched] + + + + + 12 + + + Check account in settlement + + + Error code: + + + 2001 + + + + + 13 + + + Check exists + + + + SELECT settlementParticipantCurrencyId + + + FROM + + + settlementParticipantCurrency + + + WHERE spc.settlementId = {id} + + + AND pc.participantCurrencyId = {accountId} + + + + + 14 + + + Return + + + settlementParticipantCurrencyId + + + + + if (settlementParticipantCurrencyId) { + + + accountFoundInSettlement + + + = true + + + } + + + + + alt + + + [settlementFound && participantFoundInSettlement && participantAndAccountMatched && accountFoundInSettlement] + + + + + 15 + + + Request settlement windows + + + Error code: + + + 2001 + + + + + 16 + + + Retrieve windows + + + + + alt + + + [accountProvided] + + + + SELECT + + + DISTINCT + + + sw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementSettlementWindow + + + ssw + + + JOIN + + + settlementWindow + + + sw + + + ON sw.settlementWindowId = ssw.settlementWindowId + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + JOIN + + + settlementWindowContent + + + swc + + + ON swc.settlementWindowId = sw.settlementWindowId + + + JOIN + + + settlementWindowContentAggregation + + + swca + + + ON swca.settlementWindowContentId = swc.settlementWindowContentId + + + AND swca.participantCurrencyId = + + + {accountId} + + + WHERE ssw.settlementId = {id} + + + + + SELECT DISTINCT sw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementSettlementWindow + + + ssw + + + JOIN + + + settlementWindow + + + sw + + + ON sw.settlementWindowId = ssw.settlementWindowId + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + JOIN + + + settlementWindowContent + + + swc + + + ON swc.settlementWindowId = sw.settlementWindowId + + + JOIN + + + settlementWindowContentAggregation + + + swca + + + ON swca.settlementWindowContentId = swc.settlementWindowContentId + + + AND swca.participantCurrencyId IN( + + + SELECT participantCurrencyId + + + FROM participantCurrency + + + WHERE participantId = + + + {participantId} + + + ) + + + WHERE ssw.settlementId = {id} + + + + + 17 + + + Return + + + windows + + + + + 18 + + + Request settlement accounts + + + Error code: + + + 2001 + + + + + 19 + + + Retrieve accounts + + + + + alt + + + [accountProvided] + + + + SELECT pc.participantId, spc.participantCurrencyId, spcsc.settlementStateId, + + + spcsc.reason, spc.netAmount, pc.currencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementParticipantCurrencyId = {settlementParticipantCurrencyId} + + + + + SELECT pc.participantId, spc.participantCurrencyId, spcsc.settlementStateId, + + + spcsc.reason, spc.netAmount, pc.currencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementParticipantCurrencyId IN {settlementParticipantCurrencyIdList} + + + + + 20 + + + Return + + + accounts + + + + + { + + + "id": settlement.settlementId, + + + "state": settlement.settlementStateId, + + + "settlementWindows": [ + + + [ + + + { + + + "id": window.settlementWindowId, + + + "reason": window.reason, + + + "state": window.settlementWindowStateId, + + + "createdDate": window.createdDate, + + + "changedDate": window.changedDate + + + } + + + ] + + + ], + + + "participants": [ + + + { + + + "id": account.participantId, + + + "accounts": [ + + + { + + + "id": account.participantCurrencyId, + + + "reason": account.reason, + + + "state": account.settlementStateId, + + + "netSettlementAmount": { + + + "amount": account.netAmount, + + + "currency": account.currencyId + + + } + + + } + + + ] + + + } + + + ] + + + } + + + + + 21 + + + Respond HTTP - 200 (OK) + + + + [!settlementFound || !participantFoundInSettlement || !participantAndAccountMatched || !accountFoundInSettlement] + + + + + Log ERROR event (based on the failure) + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 22 + + + Respond HTTP - 4xx (Client error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.svg new file mode 100644 index 000000000..460c5a1ac --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.svg @@ -0,0 +1,442 @@ + + + + + + + + + + + 6.2.4. Get Settlement By Id (getSettlementById) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Get Settlement By Id + + + + + 1 + + + GET - /settlements/{id} + + + + + 2 + + + Request settlement state + + + Error code: + + + 2001 + + + + + 3 + + + Retrieve settlement + + + + SELECT s.settlementId, ssc.settlementStateId, s.reason, s.createdDate + + + FROM + + + settlement + + + s + + + JOIN + + + settlementStateChange + + + ssc + + + ON ssc.settlementStateChangeId = s.currentStateChangeId + + + WHERE s.settlementId = {id} + + + + + 4 + + + Return + + + settlement + + + + + alt + + + [settlement found] + + + + + 5 + + + Request settlement windows + + + Error code: + + + 2001 + + + + + 6 + + + Retrieve windows + + + + SELECT sw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementSettlementWindow + + + ssw + + + JOIN + + + settlementWindow + + + sw + + + ON sw.settlementWindowId = ssw.settlementWindowId + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + WHERE ssw.settlementId = {id} + + + + + 7 + + + Return + + + windows + + + + + 8 + + + Request settlement accounts + + + Error code: + + + 2001 + + + + + 9 + + + Retrieve accounts + + + + SELECT pc.participantId, spc.participantCurrencyId, spcsc.settlementStateId, + + + spcsc.reason, spc.netAmount, pc.currencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementId = {id} + + + + + 10 + + + Return + + + accounts + + + + + { + + + "id": settlement.settlementId, + + + "state": settlement.settlementStateId, + + + "settlementWindows": [ + + + [ + + + { + + + "id": window.settlementWindowId, + + + "reason": window.reason, + + + "state": window.settlementWindowStateId, + + + "createdDate": window.createdDate, + + + "changedDate": window.changedDate + + + } + + + ] + + + ], + + + "participants": [ + + + { + + + "id": account.participantId, + + + "accounts": [ + + + { + + + "id": account.participantCurrencyId, + + + "reason": account.reason, + + + "state": account.settlementStateId, + + + "netSettlementAmount": { + + + "amount": account.netAmount, + + + "currency": account.currencyId + + + } + + + } + + + ] + + + } + + + ] + + + } + + + + + 11 + + + Respond HTTP - 200 (OK) + + + + + + Log ERROR event + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 12 + + + Respond HTTP - 4xx (Client error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.svg new file mode 100644 index 000000000..73611b591 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.svg @@ -0,0 +1,1754 @@ + + + + + + + + + + + 6.2.5. Acknowledgement of Settlement Transfer (updateSettlementById) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + + + + + + + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Acknowledgement of Settlement Transfer + + + + + { + + + "participants": [ + + + { + + + "id": 1 + + + "accounts" : [ + + + { "id": 1, "state": "PENDING_SETTLEMENT", "reason": <string> }, + + + { "id": 2, "state": "PS_TRANSFERS_RECORDED", "reason": <string>, "externalReference": <string> }, + + + { "id": 3, "state": "PS_TRANSFERS_RESERVED", "reason": <string> }, + + + { "id": 4, "state": "PS_TRANSFERS_COMMITTED", "reason": <string>, "externalReference": <string> }, + + + { "id": 5, "state": "SETTLED", "reason": <string> } + + + ] + + + }, + + + { + + + "id": 2 + + + "accounts" : [ + + + { "id": 6, "state": "SETTLED", "reason": <string> } + + + ] + + + } + + + ] + + + } + + + + + 1 + + + PUT - /settlement/{id} + + + + + 2 + + + updateSettlementById routine + + + Error code: + + + 2001 + + + + + DB TRANSACTION + + + + + 3 + + + Retrieve settlement information + + + + SELECT s.settlementId, ssc.settlementStateId, + + + ssc.reason, ssc.createdDate, sm.autoPositionReset + + + FROM + + + settlement + + + s + + + JOIN + + + settlementStateChange + + + ssc + + + ON ssc.settlementStateChangeId = s.currentStateChangeId + + + JOIN + + + settlementModel + + + sm + + + ON sm.settlementModelId = s.settlementModelId + + + WHERE s.settlementId = {id} + + + FOR UPDATE + + + + + 4 + + + Return + + + settlementData + + + + + 5 + + + Retrive settlement accounts information + + + + SELECT pc.participantId, spc.participantCurrencyId, + + + spcsc.settlementStateId, spcsc.reason, + + + spcsc.createdDate, spc.netAmount, pc.currencyId, + + + spc.settlementParticipantCurrencyId AS + + + key + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = + + + spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementId = {id} + + + FOR UPDATE + + + + + 6 + + + Return + + + settlementAccountsList + + + + + All objects below are for the purpose of the syncronous request. + + + If at some point, Node process memory limit is reached, we may decide to: + + + A. Limit the amount of transfers per window and windows per settlement or + + + B. Move to asyncronous processing where we don't need these objects + + + + + Available raw datasets from DB: + + + settlementData + + + contains information about settlement and its current state/reason + + + settlementAccountsList + + + holds information about all accounts and their current state/reason + + + Local variables and objects: + + + settlementAccounts + + + : { // (derived from + + + settlementAccountsList + + + ) + + + pendingSettlementCount: <integer>, // count of accounts in PENDING_SETTLEMENT state + + + psTransfersRecordedCount: <integer>, // count of accounts in PS_TRANSFERS_RECORDED state + + + psTransfersReservedCount: <integer>, // count of accounts in PS_TRANSFERS_RESERVED state + + + psTransfersCommittedCount: <integer>, // count of accounts in PS_TRANSFERS_COMMITTED state + + + settledCount: <integer>, // count of accounts in SETTLED state + + + abortedCount: <integer> // count of accounts in ABORTED state + + + unknownCount: <integer>, + + + settledIdList: <array>, + + + changedIdList: <array> + + + } + + + settlementAccountsInit + + + copy of previous object to be preserved for comparission at the end + + + allAccounts + + + : { // same as previous but accessed by account id (derived from + + + settlementAccountsList + + + ) + + + participantCurrencyId_key: { // number used to access the object in map-like style + + + id: participantCurrencyId, + + + state: settlementStateId, + + + reason: reason, + + + createdDate: createdDate, + + + netSettlementAmount: { + + + amount: netAmount, + + + currency: currencyId + + + }, + + + participantId: participantId, // could be used to reconstruct allParticipants + + + key: + + + key + + + // will be used to insert new state for settlementParticipantCurrency + + + } + + + } + + + let + + + transactionTimestamp + + + = now() + + + + + 7 + + + Declare and initialize variables + + + + + let settlementAccounts = { + + + pendingSettlementCount: 0, + + + psTransfersRecordedCount: 0, + + + psTransfersReservedCount: 0, + + + psTransfersCommittedCount: 0, + + + settledCount: 0, + + + abortedCount: 0, + + + unknownCount: 0 + + + } + + + let allAccounts = {} // declare map + + + let pid // participantId + + + let aid // accountId (participantCurrencyId) + + + let state + + + + + loop + + + [settlementAccountsList as account] + + + + + 8 + + + Populate + + + allAccounts + + + + + pid = account.participantId + + + aid = account.participantCurrencyId + + + state = account.settlementStateId + + + allAccounts[aid] = { + + + id: aid, + + + state, + + + reason: account.reason, + + + createDate: account.createdDate, + + + netSettlementAmount: { + + + amount: account.netAmount, + + + currency: account.currencyId + + + }, + + + participantId: pid, + + + key: account.key + + + } + + + + + 9 + + + Populate + + + settlementAccounts + + + + + alt + + + [state == 'PENDING_SETTLEMENT'] + + + + + settlementAccounts.pendingSettlementCount++ + + + + [state == 'PS_TRANSFERS_RECORDED'] + + + + + settlementAccounts.psTransfersRecordedCount++ + + + + [state == 'PS_TRANSFERS_RESERVED'] + + + + + settlementAccounts.psTransfersReservedCount++ + + + + [state == 'PS_TRANSFERS_COMMITTED'] + + + + + settlementAccounts.psTransfersCommittedCount++ + + + + [state == 'SETTLED'] + + + + + settlementAccounts.settledCount++ + + + + [state == 'ABORTED'] + + + + + settlementAccounts.abortedCount++ + + + + [default] + + + + + settlementAccounts.unknownCount++ + + + + + 10 + + + Make a copy of settlementAccounts into + + + settlementAccountsInit + + + + + settlementAccountsInit = Object.assign({}, settlementAccounts) + + + + + Available objects after the setup: + + + settlementAccounts + + + is used for tracing settlement state and state transition allowance + + + allAccounts + + + is helper object, same as previous, providing direct access to account by id + + + Now we are ready to process the + + + payload + + + : + + + participants + + + = [] // part of the response object that lists the affected participants and respective accounts + + + settlementParticipantCurrencyStateChange + + + = [] // array to collect inserts to the table + + + settlementParticipantCurrencySettledList + + + = [] // array to collect settled accounts + + + processedAccounts + + + = [] // array to log processed accounts and restrict subsequent processing + + + + + loop + + + [let participant IN payload.participants] + + + + + 11 + + + Loop payload for each + + + participantPayload + + + + + let participantPayload = payload.participants[participant] + + + participants.push({id: participantPayload.id, accounts: []}) + + + let pi = participants.length - 1 + + + participant = participants[pi] + + + + + loop + + + [let account IN participantPayload.accounts] + + + + + 12 + + + Loop payload for each + + + accountPayload + + + + + let accountPayload = participantPayload.accounts[account] + + + + + alt + + + [allAccounts[accountPayload.id] == undefined] + + + + + 13 + + + If the account doesn't match the settlement + + + + + participant.accounts.push({ + + + id: accountPayload.id, + + + errorInformation: { + + + errorCode: 3000, + + + errorDescription: 'Account not found' + + + } + + + }) + + + + [participantPayload.id != allAccounts[accountPayload.id].participantId] + + + + + 14 + + + If the account doesn't match the participant + + + + + participant.accounts.push({ + + + id: accountPayload.id, + + + errorInformation: { + + + errorCode: 3000, + + + errorDescription: 'Participant and account mismatch' + + + } + + + }) + + + + [processedAccounts.indexOf(accountPayload.id) > -1] + + + + + 15 + + + If the account has been previosly processed (duplicated in the payload) + + + + + participant.accounts.push({ + + + id: accountPayload.id, + + + state: allAccounts[accountPayload.id].state, + + + reason: allAccounts[accountPayload.id].reason, + + + createdDate: allAccounts[accountPayload.id].createdDate, + + + netSettlementAmount: allAccounts[accountPayload.id].netSettlementAmount + + + errorInformation: { + + + errorCode: 3000, + + + errorDescription: 'Account already processed once' + + + } + + + }) + + + + [allAccounts[account.id].state == accountPayload.state // allowed] + + + + + 16 + + + Same-state reason amendment is always allowed + + + + + processedAccounts.push(accountPayload.id) + + + participant.accounts.push({ + + + id: accountPayload.id, + + + state: accountPayload.state, + + + reason: accountPayload.reason, + + + externalReference: accountPayload.externalReference, + + + createdDate: transactionTimestamp, + + + netSettlementAmount: allAccounts[accountPayload.id].netSettlementAmount + + + }) + + + settlementParticipantCurrencyStateChange.push({ + + + settlementParticipantCurrencyId: allAccounts[accountPayload.id].key, + + + settlementStateId: accountPayload.state, + + + reason: accountPayload.reason, + + + externalReference: accountPayload.externalReference + + + }) + + + allAccounts[accountPayload.id].reason = accountPayload.reason + + + allAccounts[accountPayload.id].createdDate = currentTimestamp + + + + [settlementData.state == 'PENDING_SETTLEMENT' && accountPayload.state == 'PS_TRANSFERS_RECORDED'] + + + + [settlementData.state == 'PS_TRANSFERS_RECORDED' && accountPayload.state == 'PS_TRANSFERS_RESERVED'] + + + + [settlementData.state == 'PS_TRANSFERS_RESERVED' && accountPayload.state == 'PS_TRANSFERS_COMMITTED'] + + + + [settlementData.state == 'PS_TRANSFERS_COMMITTED' || settlementData.state == 'SETTLING' && accountPayload.state == 'SETTLED'] + + + + + Note + + + : Since we previously checked same-state, here we don't need to match + + + allAccounts[account.id].state == settlementData.state. + + + + + 17 + + + Settlement acknowledgement + + + + + processedAccounts.push(accountPayload.id) + + + participant.accounts.push({ + + + id: accountPayload.id, + + + state: accountPayload.state, + + + reason: accountPayload.reason, + + + externalReference: accountPayload.externalReference, + + + createdDate: transactionTimestamp, + + + netSettlementAmount: allAccounts[accountPayload.id].netSettlementAmount + + + }) + + + settlementParticipantCurrencyStateChange.push({ + + + settlementParticipantCurrencyId: allAccounts[accountPayload.id].key, + + + settlementStateId: accountPayload.state, + + + reason: accountPayload.reason, + + + externalReference: accountPayload.externalReference, + + + settlementTransferId: Uuid() -- only for PS_TRANSFERS_RECORDED + + + }) + + + if (accountPayload.state == 'PS_TRANSFERS_RECORDED') { + + + settlementAccounts.pendingSettlementCount-- + + + settlementAccounts.psTransfersRecordedCount++ + + + } else if (accountPayload.state == 'PS_TRANSFERS_RESERVED') { + + + settlementAccounts.psTransfersRecordedCount-- + + + settlementAccounts.psTransfersReservedCount++ + + + } else if (accountPayload.state == 'PS_TRANSFERS_COMMITTED') { + + + settlementAccounts.psTransfersReservedCount-- + + + settlementAccounts.psTransfersCommittedCount++ + + + } else if (accountPayload.state == 'SETTLED') { + + + settlementParticipantCurrencySettledIdList.push(allAccounts[accountPayload.id].key) + + + settlementAccounts.psTransfersCommittedCount-- + + + settlementAccounts.settledCount++ + + + settlementAccounts.settledIdList.push(accountPayload.id) + + + } + + + settlementAccounts.changedIdList.push(accountPayload.id) + + + allAccounts[accountPayload.id].state = accountPayload.state + + + allAccounts[accountPayload.id].reason = accountPayload.reason + + + allAccounts[accountPayload.id].externalReference = accountPayload.externalReference + + + allAccounts[accountPayload.id].createdDate = currentTimestamp + + + + + + 18 + + + All other state transitions are not permitted + + + + + participant.accounts.push({ + + + id: accountPayload.id, + + + state: allAccounts[accountPayload.id].state, + + + reason: allAccounts[accountPayload.id].reason, + + + createdDate: allAccounts[accountPayload.id].createdDate, + + + netSettlementAmount: allAccounts[accountPayload.id].netSettlementAmount + + + errorInformation: { + + + errorCode: <integer>, + + + errorDescription: 'State change not allowed' + + + } + + + }) + + + + + Bulk insert settlementParticipantCurrencyStateChange + + + + + 19 + + + Insert settlementParticipantCurrencyStateChange + + + + settlementParticipantCurrencyStateChange + + + + + 20 + + + Return + + + settlementParticipantCurrencyStateChangeIdList + + + + + 21 + + + Merge settlementParticipantCurrencyStateChangeIdList + + + to + + + settlementParticipantCurrencyIdList + + + in order to + + + issue the following update in one knex command + + + + + 22 + + + Update pointers to current state change ids + + + + UPDATE + + + settlementParticipantCurrency + + + SET currentStateChangeId = + + + {settlementParticipantCurrencyStateChangeIdList}, + + + settlementTransferId = + + + settlementParticipantCurrencyStateChange.settlementTransferId + + + -- only for PENDING_SETTLEMENT to PS_TRANSFERS_RECORDED + + + WHERE settlementParticipantCurrencyId = + + + {settlementParticipantCurrencyStateChange + + + .settlementParticipantCurrencyIdList} + + + + + opt + + + [autoPositionReset == true] + + + + + alt + + + [settlementData.state == 'PENDING_SETTLEMENT'] + + + + + ref + + + Settlement Transfer Prepare + + + Inputs + + + : settlementId, transactionTimestamp, enums, trx + + + + [settlementData.state == 'PS_TRANSFERS_RECORDED'] + + + + + ref + + + Settlement Transfer Reserve + + + Inputs + + + : settlementId, transactionTimestamp, enums, trx + + + + [settlementData.state == 'PS_TRANSFERS_RESERVED'] + + + + + ref + + + Settlement Transfer Commit + + + Inputs + + + : settlementId, transactionTimestamp, enums, trx + + + + + Update aggregations, contents & windows + + + + + opt + + + [settlementParticipantCurrencySettledIdList.length > 0] + + + + + 23 + + + Change settlementWindowState where applicable + + + + settlementContentAggregation + + + transferParticipantStateChange + + + transferParticipant + + + settlementWindowContentStateChange + + + settlementWindowContent + + + settlementWindowStateChange + + + settlementWindow + + + + + 24 + + + Retrieve all affected content (incl. when settled) + + + + settlementContentAggregation + + + settlementWindowContent + + + settlementWindowContentStateChange + + + ledgerAccountType + + + settlementWindow + + + settlementWindowStateChange + + + + + 25 + + + Return + + + affectedWindowsReport + + + + + 26 + + + Use previous result to produce settlementWindowsData ( + + + swd + + + ) array + + + + + Prepare and insert settlementStateChange + + + + + let settlementStateChanged = true + + + + + alt + + + [settlementData.state == 'PENDING_SETTLEMENT' + + + && settlementAccounts.pendingSettlementCount == 0] + + + + + settlementData.state = 'PS_TRANSFERS_RECORDED' + + + settlementData.reason = 'All settlement accounts are PS_TRANSFERS_RECORDED' + + + + [settlementData.state == 'PS_TRANSFERS_RECORDED' + + + && settlementAccounts.psTransfersRecordedCount == 0] + + + + + settlementData.state = 'PS_TRANSFERS_RESERVED' + + + settlementData.reason = 'All settlement accounts are PS_TRANSFERS_RESERVED' + + + + [settlementData.state == 'PS_TRANSFERS_RESERVED' + + + && settlementAccounts.psTransfersReservedCount == 0] + + + + + settlementData.state = 'PS_TRANSFERS_COMMITTED' + + + settlementData.reason = 'All settlement accounts are PS_TRANSFERS_COMMITTED' + + + + [settlementData.state == 'PS_TRANSFERS_COMMITTED' + + + && settlementAccounts.psTransfersCommittedCount > 0 + + + && settlementAccounts.settledCount > 0] + + + + + settlementData.state = 'SETTLING' + + + settlementData.reason = 'Some settlement accounts are SETTLED' + + + + [(settlementData.state == 'PS_TRANSFERS_COMMITTED' || settlementData.state == 'SETTLING') + + + && settlementAccounts.psTransfersCommittedCount == 0] + + + + + settlementData.state = 'SETTLED' + + + settlementData.reason = 'All settlement accounts are SETTLED' + + + + + + settlementStateChanged = false + + + + + opt + + + [settlementStateChanged == true] + + + + + settlementData.createdDate = currentTimestamp + + + settlementStateChange.push(settlementData) + + + + + 27 + + + Insert settlementStateChange + + + + settlementStateChange + + + + + 28 + + + Return + + + settlementStateChangeId + + + + + 29 + + + Update pointer to current state change id + + + + UPDATE + + + settlement + + + .currentStateChangeId + + + + + 30 + + + Return transaction result + + + + + { + + + "id": {id}, + + + "state": settlementData.state, + + + "createdDate": settlementData.createdDate, + + + "settlementWindows": [ + + + { + + + "id": swd[m].id, + + + "state": swd[m].state, + + + "reason": swd[m].reason, + + + "createdDate": swd[m].createdDate, + + + "changedDate": swd[m].changedDate, + + + "content": [ + + + { + + + "id": swd[m].content[n].settlementWindowContentId, + + + "state": swd[m].content[n].settlementWindowStateId, + + + "ledgerAccountType": swd[m].content[n].ledgerAccountType, + + + "currencyId": swd[m].content[n].currencyId, + + + "createdDate": swd[m].content[n].createdDate, + + + "changedDate": swd[m].content[n].changedDate + + + } + + + ] + + + } + + + ], + + + "participants": [ + + + { + + + "id": <integer>, + + + "accounts": [ + + + { + + + "id": <integer>, + + + "state": "<string>, + + + "reason": <string>, + + + "externalReference": <string>, + + + "createdDate": <date>, + + + "netSettlementAmount": { + + + "amount": <decimal>, + + + "currency": <enum> + + + } + + + }, + + + { + + + "id": <integer>, + + + "state": <string>, + + + "reason": <string>, + + + "createdDate": <date>, + + + "netSettlementAmount": { + + + "amount": <decimal>, + + + "currency": <enum> + + + }, + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": <string> + + + } + + + } + + + ] + + + } + + + ] + + + } + + + + + 31 + + + Return response + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.svg new file mode 100644 index 000000000..38256e7a0 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.svg @@ -0,0 +1,801 @@ + + + + + + + + + + + 6.2.6. Settlement Abort (abortSettlementById) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Settlement Abort + + + + + { + + + "state": "ABORTED", + + + "reason": {abortReasonString} + + + } + + + + + 1 + + + PUT - /settlement/{id} + + + + + 2 + + + abortSettlementById facade method + + + Error code: + + + 2001 + + + + + 3 + + + Retrieve settlement information + + + + SELECT s.settlementId, ssc.settlementStateId, + + + ssc.reason, ssc.createdDate + + + FROM + + + settlement + + + s + + + JOIN + + + settlementStateChange + + + ssc + + + ON ssc.settlementStateChangeId = s.currentStateChangeId + + + WHERE s.settlementId = {id} + + + + + 4 + + + Return + + + settlementData + + + + + alt + + + [settlementData.settlementStateId == 'PS_TRANSFERS_COMMITTED'|| + + + settlementData.settlementStateId == 'SETTLING'|| + + + settlementData.settlementStateId == 'SETTLED'] + + + + + break + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "State change is not allowed" + + + } + + + } + + + + [settlementData.settlementStateId == 'ABORTED'] + + + + + break + + + + + 5 + + + Append additional info at settlement level + + + + INSERT INTO + + + settlementStateChange + + + (settlementId, settlementStateId, reason) + + + VALUES ({id}, 'ABORTED', {abortReasonString}) + + + + + { + + + "id": {id}, + + + "state": 'ABORTED', + + + "reason": {abortReasonString} + + + } + + + + [settlementData.settlementStateId == 'PS_TRANSFERS_RESERVED'] + + + + + 6 + + + Find account in PS_TRANSFERS_COMMITTED + + + + SELECT spc.participantCurrencyId + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = spc.currentStateChangeId + + + WHERE spc.settlementId = {id} + + + AND spcsc.settlementStateId = 'PS_TRANSFERS_COMMITTED' + + + LIMIT 1 + + + + + 7 + + + Return + + + transferCommittedAccount + + + + + break + + + [transferCommittedAccount != undefined] + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "At least one settlement transfer is committed" + + + } + + + } + + + + + DB TRANSACTION + + + + + 8 + + + Retrive settlement accounts information + + + + SELECT pc.participantId, spc.participantCurrencyId, + + + spcsc.settlementStateId, spcsc.reason, + + + spcsc.createdDate, spc.netAmount, pc.currencyId, + + + spc.settlementParticipantCurrencyId AS + + + key + + + FROM + + + settlementParticipantCurrency + + + spc + + + JOIN + + + settlementParticipantCurrencyStateChange + + + spcsc + + + ON spcsc.settlementParticipantCurrencyStateChangeId = + + + spc.currentStateChangeId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = spc.participantCurrencyId + + + WHERE spc.settlementId = {id} + + + FOR UPDATE + + + + + 9 + + + Return + + + settlementAccountsList + + + + + 10 + + + Retrive settlement windows information + + + + SELECT ssw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, swsc.createdDate + + + FROM + + + settlementSettlementWindow + + + ssw + + + JOIN + + + settlementWindow + + + sw + + + ON sw.settlementWindow = ssw.settlementWindowId + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + WHERE ssw.settlementId = {id} + + + FOR UPDATE + + + + + 11 + + + Return + + + windowsList + + + + + Bulk insert settlementParticipantCurrencyStateChange + + + + + 12 + + + Insert settlementParticipantCurrencyStateChange + + + + settlementParticipantCurrencyStateChange + + + + + 13 + + + Return + + + spcscIdList + + + + + 14 + + + Merge spcscIdList into settlementAccountsList + + + + + 15 + + + Update all pointers to current state change ids + + + + UPDATE + + + settlementParticipantCurrency + + + .currentStateChangeIds + + + + + ref + + + Settlement Transfer Abort + + + Inputs + + + : settlementId, transactionTimestamp, enums, trx + + + + + Bulk insert and reset contents & aggregations + + + + + 16 + + + Bulk insert aborted state + + + + settlementWindowContentStateChange + + + + + 17 + + + Return + + + swcscIdList + + + + + 18 + + + Merge swcscIdList + + + + + 19 + + + Update current state references and reset settlementId + + + + settlementWindowContent + + + .currentStateChangeIds + + + .settlementId + + + settlementContentAggregation + + + .settlementId + + + + + Bulk insert settlementWindowStateChange + + + + + 20 + + + Insert settlementWindowStateChange + + + + settlementWindowStateChange + + + + + 21 + + + Return + + + swscIdList + + + + + 22 + + + Merge swscIdList into windowList + + + + + 23 + + + Update all pointers to current state change ids + + + + UPDATE + + + settlementWindow + + + .currentStateChangeIds + + + + + Insert settlementStateChange + + + + + 24 + + + Insert settlementStateChange + + + + INSERT INTO + + + settlementStateChange + + + (settlementId, settlementStateId, reason) + + + VALUES ({id}, 'ABORTED', {abortReasonString}) + + + + + 25 + + + Return + + + settlementStateChangeId + + + + + 26 + + + Update pointer to current state change id + + + + UPDATE + + + settlement + + + .currentStateChangeId + + + + + 27 + + + Return facade method result + + + + + alt + + + [success] + + + + + { + + + "id": {id}, + + + "state": 'ABORTED', + + + "reason": {abortReasonString} + + + } + + + + + 28 + + + Respond HTTP - 200 (OK) + + + + + + Log ERROR event + + + + + { + + + errorInformation: { + + + "errorCode": <integer>, + + + "errorDescription": "Client/Server error description" + + + } + + + } + + + + + 29 + + + Respond HTTP 4xx or 5xx + + + (Client/Server error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.svg new file mode 100644 index 000000000..7ce3f9839 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + 6.1.1. Request Settlement Window By Id (getSettlementWindowById) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Request Settlement Window + + + + + 1 + + + GET - /settlementWindows/{id} + + + + + 2 + + + Request settlementWindow by id + + + Error code: + + + 2001 + + + + + 3 + + + Select from DB + + + + SELECT sw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementWindow + + + AS sw + + + JOIN + + + settlementWindowStateChange + + + AS swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + WHERE sw.settlementWindowId = {id} + + + + + 4 + + + Return + + + data + + + + + alt + + + [settlementWindow found] + + + + + 5 + + + Request settlementWindowContent(s) + + + Error code: + + + 2001 + + + + + 6 + + + Select from DB + + + + settlementWindowContent + + + settlementWindowContentStateChange + + + ledgerAccountType + + + + + 7 + + + Return + + + contentList + + + + + { + + + "id": data.settlementWindowId, + + + "state": data.settlementWindowStateId, + + + "reason": data.reason, + + + "createdDate": data.createdDate, + + + "changedDate": data.changedDate, + + + "content": [ + + + { + + + "id": contentList.settlementWindowContentId, + + + "state": contentList.settlementWindowStateId, + + + "ledgerAccountType": contentList.ledgerAccountType, + + + "currencyId": contentList.currencyId, + + + "createdDate": contentList.createdDate, + + + "changedDate": contentList.changedDate, + + + "settlementId": contentList.settlementId + + + } + + + ] + + + } + + + + + 8 + + + Respond HTTP - 200 (OK) + + + + + + Log ERROR event + + + + + { + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": <string> + + + } + + + } + + + + + 9 + + + Respond HTTP - 4xx (Client error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml similarity index 94% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml index cca5d36cf..79c75a058 100644 --- a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml @@ -199,7 +199,7 @@ group Close Settlement Window deactivate SSAPI deactivate OPERATOR - group Close settlement window (SettlementWindowHandler) + group Close settlement window (Deferred Handler) TOPIC_SET_WIN <- SET_WIN_HANDLER: Consume Settlement Window\nevent message activate TOPIC_SET_WIN deactivate TOPIC_SET_WIN @@ -252,18 +252,25 @@ group Close Settlement Window SETTLE_DAO -> DB: Determine window content and insert activate DB + SETTLE_DAO -> DB: Get all Settlement Models + SETTLE_DAO -> SETTLE_DAO: create Settlement Models <-> currencyId map + SETTLE_DAO -> SETTLE_DAO: create list of currencies with Settlement Models + SETTLE_DAO -> DB: Get Settlement Window Content list hnote over DB #lightyellow - INSERT INTO **settlementWindowContent** (settlementWindowId, ledgerAccountTypeId, - currencyId, createdDate) SELECT DISTINCT {id} settlementWindowId, pc.ledgerAccountTypeId, - pc.currencyId, transactionTimestamp + pc.currencyId, m.settlementModelId FROM **transferFulfilment** tf JOIN **transferParticipant** tp ON tp.transferId = tf.transferId JOIN **participantCurrency** pc ON pc.participantCurrencyId = tp.participantCurrencyId + JOIN **settlementModel** m + ON m.ledgerAccountTypeId = pc.ledgerAccountTypeId WHERE tf.settlementWindowId = {id} + AND m.settlementGranularityId = 'NET' end hnote + SETTLE_DAO -> SETTLE_DAO: filter swcList to add currency to each record based on model + SETTLE_DAO -> DB: Insert filtered list deactivate DB SETTLE_DAO -> DB: Aggregate window data and insert @@ -282,6 +289,8 @@ group Close Settlement Window ON swc.settlementWindowId = tf.settlementWindowId AND swc.ledgerAccountTypeId = pc.ledgerAccountTypeId AND swc.currencyId = pc.currencyId + JOIN **settlementModel** m + ON m.settlementModelId = swc.settlementModelId WHERE ttf.settlementWindowId = {id} GROUP BY swc.settlementWindowContentId, pc.participantCurrencyId, tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.svg new file mode 100644 index 000000000..19abe69d4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.svg @@ -0,0 +1,1135 @@ + + + + + + + + + + + 6.1.2. Close Settlement Window (closeSettlementWindow) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + + + topic- + + + settlement-window + + + + + topic- + + + settlement-window + + + Settlement Window + + + Handler + + + + + Settlement Window + + + Handler + + + + + + + topic-event + + + + + topic-event + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Close Settlement Window + + + + + { + + + "state": "CLOSED", + + + "reason": <string> + + + } + + + + + 1 + + + POST - /settlementWindows/{id} + + + + + 2 + + + Validate payload, existing window, + + + state, assigned transfers, etc. + + + + + break + + + + + { + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": "FSPIOP Error Description" + + + } + + + } + + + + + 3 + + + Respond HTTP - 400 (Bad Request) + + + + + 4 + + + Get requested settlementWindow and state + + + Error code: + + + 2001 + + + + + 5 + + + Get settlementWindow state + + + + SELECT sw.settlementWindowId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementWindow + + + AS sw + + + JOIN + + + settlementWindowStateChange + + + AS swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + WHERE sw.settlementWindowId = {id} + + + + + 6 + + + Return result + + + + + alt + + + [settlementWindow found && settlementWindowStateId == 'OPEN'] + + + + + Process settlement window + + + + + 7 + + + Terminate current window and open a new one + + + Error code: + + + 2001 + + + + + DB TRANSACTION: Terminate window usage and initate next + + + + + let + + + transactionTimestamp + + + = now() + + + + + 8 + + + Terminate requested window + + + + INSERT INTO + + + settlementWindowStateChange + + + (settlementWindowId, settlementWindowStateId, reason, createdDate) + + + VALUES ({id}, 'PROCESSING', {payload.reason}, {transactionTimestamp}) + + + + + 9 + + + Return + + + settlementWindowStateChangeId + + + + + 10 + + + Update pointer to current state change id + + + + UPDATE + + + settlementWindow + + + SET currentStateChangeId = {settlementWindowStateChangeId} + + + WHERE settlementWindowId = {id} + + + + + 11 + + + Create new settlementWindow + + + + INSERT INTO + + + settlementWindow + + + (reason, createdDate) + + + VALUES ({payload.reason}, {transactionTimestamp}) + + + + + 12 + + + Return + + + settlementWindowId + + + + + 13 + + + Insert intial state for the created window + + + + INSERT INTO + + + settlementWindowStateChange + + + (settlementWindowId, settlementWindowStateId, reason, createdDate) + + + VALUES ({settlementWindowId}, 'OPEN', {payload.reason}, {transactionTimestamp}) + + + + + 14 + + + Return + + + newSettlementWindowStateChangeId + + + + + 15 + + + Update pointer to current state change id + + + + UPDATE + + + settlementWindow + + + SET currentStateChangeId = {newSettlementWindowStateChangeId} + + + WHERE settlementWindowId = {settlementWindowId} + + + + + 16 + + + Return success + + + + + Message: + + + { + + + id: <uuid> + + + from: switch, + + + to: switch, + + + type: application/json + + + content: { + + + payload: { + + + settlementWindowId: {id} + + + } + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + responseTo: null, + + + type: setwin, + + + action: close, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + 17 + + + Produce Settlement Window + + + event message + + + Error codes: + + + 2003 + + + + + { + + + "id": settlementWindowId, + + + "state": 'OPEN', + + + "reason": payload.reason, + + + "createdDate": transactionTimestamp, + + + "changedDate": transactionTimestamp + + + } + + + + + 18 + + + Respond HTTP - 201 (Created) + + + + + Close settlement window (Deferred Handler) + + + + + 19 + + + Consume Settlement Window + + + event message + + + + + Persist Event Information + + + + + 20 + + + Publish event information + + + + + ref + + + Event Handler Consume + + + + + let + + + id + + + = message.content.payload.settlementWindowId + + + let + + + windowContentReady + + + = false + + + let + + + iter + + + = 0 + + + + + loop + + + [iter < Config.WIN_AGGREGATION_RETRY_COUNT && !windowContentReady] + + + + + iter++ + + + + + 21 + + + Check if all transferParticipant records + + + for the requested window have been set + + + (currentStateChangeId is NOT NULL). + + + Error code: + + + 2001 + + + + + 22 + + + Use EXISTS query to find NULL currentStateChangeId records + + + + transferFulfilment + + + transferParticipant + + + + + 23 + + + Return result (success / failure) + + + + + opt + + + [transferParticipant records have been processed by central-ledger SettlementModelHandler] + + + + + 24 + + + Generate window content and aggregations + + + Error code: + + + 2001 + + + + + DB TRANSACTION: Generate window content and aggregations + + + + + let + + + transactionTimestamp + + + = now() + + + + + 25 + + + Change all applicable entries to CLOSED state + + + + transferParticipantStateChange + + + transferParticipant + + + + + 26 + + + Determine window content and insert + + + + + 27 + + + Get all Settlement Models + + + + + 28 + + + create Settlement Models <-> currencyId map + + + + + 29 + + + create list of currencies with Settlement Models + + + + + 30 + + + Get Settlement Window Content list + + + + SELECT DISTINCT {id} settlementWindowId, pc.ledgerAccountTypeId, + + + pc.currencyId, m.settlementModelId + + + FROM + + + transferFulfilment + + + tf + + + JOIN + + + transferParticipant + + + tp + + + ON tp.transferId = tf.transferId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = tp.participantCurrencyId + + + JOIN + + + settlementModel + + + m + + + ON m.ledgerAccountTypeId = pc.ledgerAccountTypeId + + + WHERE tf.settlementWindowId = {id} + + + AND m.settlementGranularityId = 'NET' + + + + + 31 + + + filter swcList to add currency to each record based on model + + + + + 32 + + + Insert filtered list + + + + + 33 + + + Aggregate window data and insert + + + + INSERT INTO + + + settlementContentAggregation + + + (settlementWindowContentId, participantCurrencyId, + + + transferParticipantRoleTypeId, ledgerEntryTypeId, currentStateId, createdDate, amount) + + + SELECT swc.settlementWindowContentId, pc.participantCurrencyId, tp.transferParticipantRoleTypeId, + + + tp.ledgerEntryTypeId, 'CLOSED', transactionTimestamp, SUM(tp.amount) + + + FROM + + + transferFulfilment + + + tf + + + JOIN + + + transferParticipant + + + tp + + + ON tf.transferId = tp.transferId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = tp.participantCurrencyId + + + JOIN + + + settlementWindowContent + + + swc + + + ON swc.settlementWindowId = tf.settlementWindowId + + + AND swc.ledgerAccountTypeId = pc.ledgerAccountTypeId + + + AND swc.currencyId = pc.currencyId + + + JOIN + + + settlementModel + + + m + + + ON m.settlementModelId = swc.settlementModelId + + + WHERE ttf.settlementWindowId = {id} + + + GROUP BY swc.settlementWindowContentId, pc.participantCurrencyId, + + + tp.transferParticipantRoleTypeId, tp.ledgerEntryTypeId + + + + + 34 + + + Insert initial window content state change + + + + INSERT INTO + + + settlementWindowContentStateChange + + + (settlementWindowContentId, settlementWindowStateId) + + + SELECT swc.settlementWindowContentId, 'CLOSED' + + + FROM + + + settlementWindowContent + + + swc + + + WHERE swc.settlementWindowId = {id} + + + + + 35 + + + Update pointers to current state change ids + + + + settlementWindowContent + + + + + 36 + + + Return result (success / failure) + + + + + alt + + + [success] + + + + + windowContentReady = true + + + + + 37 + + + Close requested window + + + Error code: + + + 2001 + + + + + 38 + + + Change window state to 'CLOSED' + + + + settlementWindowStateChange + + + settlementWindow.currentStateChangeId + + + + [failure && iter < Config.WIN_AGGREGATION_RETRY_COUNT] + + + + + sleep + + + Config.WIN_AGGREGATION_RETRY_INTERVAL seconds + + + + [failure] + + + + + 39 + + + Fail requested window + + + Error code: + + + 2001 + + + + + 40 + + + Change window state to 'FAILED' + + + + settlementWindowStateChange + + + settlementWindow.currentStateChangeId + + + + 41 + + + Log ERROR event + + + + + 42 + + + Log ERROR event + + + + + { + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 43 + + + Respond HTTP - 4xx (Client error) + + diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.plantuml b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.plantuml similarity index 100% rename from mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.plantuml rename to legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.plantuml diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.svg b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.svg new file mode 100644 index 000000000..090e598ac --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + 6.1.3. Get Settlement Windows By Parameters (getSettlementWindowsByParams) + + + + Central HUB + + + + Settlement Service + + + + Central Services + + + + + + + + Hub Employee + + + + + Hub Employee + + + + + Settlement Service API + + + + + Settlement Service API + + + + + Settlement DAO + + + + + Settlement DAO + + + + + Central Store + + + + + Central Store + + + + + + + + Get Settlement Windows By Parameters + + + + + Params: + + + ?participantId={participantId} + + + &state={state} + + + &fromDateTime={fromDateTime} + + + &toDateTime={toDateTime} + + + + + 1 + + + GET - /settlementWindows/{params} + + + + + 2 + + + Request settlementWindow + + + Error code: + + + 2001 + + + + + 3 + + + Request settlementWindows + + + + SELECT DISTINCT sw.settlementId, swsc.settlementWindowStateId, + + + swsc.reason, sw.createdDate, swsc.createdDate changedDate + + + FROM + + + settlementWindow + + + sw + + + JOIN + + + settlementWindowStateChange + + + swsc + + + ON swsc.settlementWindowStateChangeId = sw.currentStateChangeId + + + JOIN + + + transferFulfilment + + + tf + + + ON tf.settlementWindowId = sw.settlementWindowId + + + JOIN + + + transferParticipant + + + tp + + + ON tp.transferId = tf.transferId + + + JOIN + + + participantCurrency + + + pc + + + ON pc.participantCurrencyId = tp.participantCurrencyId + + + [WHERE pc.participantId = {participantId}] + + + [AND swsc.settlementWindowStateId = {state}] + + + [AND sw.createdDate >= {fromDateTime}] + + + [AND sw.createdDate <= {toDateTime}] + + + + + 4 + + + Return data + + + + + 5 + + + Return + + + settlementWindows + + + + + alt + + + [One or more records found] + + + + + [ + + + { + + + "id": settlementWindow.settlementId, + + + "state": settlementWindow.settlementWindowStateId, + + + "reason": settlementWindow.reason, + + + "createdDate": settlementWindow.createdDate, + + + "changedDate": settlementWindow.changedDate + + + } + + + ] + + + + + 6 + + + Respond HTTP - 200 (OK) + + + + + + Log ERROR event + + + + + { + + + "errorInformation": { + + + "errorCode": <integer>, + + + "errorDescription": "Client error description" + + + } + + + } + + + + + 7 + + + Respond HTTP - 4xx (Client error) + + diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd new file mode 100644 index 000000000..57065a8da --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + COLOR LEGEND: +Green - subject specific entity +Gray - transfer specific entity +Red - settlement specific entity +Blue - lookup entity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png new file mode 100644 index 000000000..4930831f1 Binary files /dev/null and b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png differ diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md new file mode 100644 index 000000000..c77185bbc --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md @@ -0,0 +1,7 @@ +# Request Settlement + +Design for Get Settlement by Id process. + +## Sequence Diagram + +![seq-settlement-6.2.4.svg](./assets/diagrams/sequence/seq-settlement-6.2.4.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md new file mode 100644 index 000000000..8869a6679 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md @@ -0,0 +1,7 @@ +# Request Settlement By SPA + +Design for Get Settlement by Settlement/Participant/Account process. + +## Sequence Diagram + +![seq-settlement-6.2.3.svg](./assets/diagrams/sequence/seq-settlement-6.2.3.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md new file mode 100644 index 000000000..f025f69c8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md @@ -0,0 +1,7 @@ +# Request Settlement Window + +Design for Request Settlement Window by Id process. + +## Sequence Diagram + +![seq-setwindow-6.1.1.svg](./assets/diagrams/sequence/seq-setwindow-6.1.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md new file mode 100644 index 000000000..9275f765a --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md @@ -0,0 +1,7 @@ +# Settlement Windows By Params + +Design for Get Settlement Windows by Parameters process. + +## Sequence Diagram + +![seq-setwindow-6.1.3.svg](./assets/diagrams/sequence/seq-setwindow-6.1.3.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md new file mode 100644 index 000000000..6d0a79cb8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md @@ -0,0 +1,7 @@ +# Request Settlements By Params + +Design for Query Settlements by Parameters process. + +## Sequence Diagram + +![seq-settlement-6.2.2.svg](./assets/diagrams/sequence/seq-settlement-6.2.2.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.md new file mode 100644 index 000000000..51e54594b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/gross-settlement-handler-consume.md @@ -0,0 +1,7 @@ +# Gross Settlement Handler + +Sequence design diagram for the gross settlement handler. + +## Sequence Diagram + +![example](assets/diagrams/sequence/seq-gross-settlement-handler.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md new file mode 100644 index 000000000..ae1ce9dd1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md @@ -0,0 +1,7 @@ +# Close Settlement Window + +Design for Close Settlement Window process. + +## Sequence Diagram + +![seq-setwindow-6.1.2.svg](./assets/diagrams/sequence/seq-setwindow-6.1.2.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md new file mode 100644 index 000000000..da1f6685c --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md @@ -0,0 +1,7 @@ +# Create Settlement + +Design for Trigger Settlement Event process. + +## Sequence Diagram + +![seq-settlement-6.2.1.svg](./assets/diagrams/sequence/seq-settlement-6.2.1.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md new file mode 100644 index 000000000..18acb25f5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md @@ -0,0 +1,7 @@ +# Settlement Abort + +Design for Settlement Abort process. + +## Sequence Diagram + +![seq-settlement-6.2.6.svg](./assets/diagrams/sequence/seq-settlement-6.2.6.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md new file mode 100644 index 000000000..3cc0cf37b --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md @@ -0,0 +1,7 @@ +# Settlement Transfer Acknowledgment + +Design for Acknowledgement of Settlement Transfer process. + +## Sequence Diagram + +![seq-settlement-6.2.5.svg](./assets/diagrams/sequence/seq-settlement-6.2.5.svg) diff --git a/legacy/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.md b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.md new file mode 100644 index 000000000..70270ae50 --- /dev/null +++ b/legacy/mojaloop-technical-overview/central-settlements/settlement-process/rules-handler-consume.md @@ -0,0 +1,169 @@ +Rules Handler. Interchange fees example. File format. +----------------------------------------------------- + +## Rules Handler +The Rules handler provides the capability to execute custom rule-based actions as a result of transfer processing events. +Here we are giving example with Interchange fee calculation. +## Sequence Diagram +![example](assets/diagrams/sequence/seq-rules-handler.svg) + +### Interchange fee case +In order to support the various options for accumulating interchange or other fees, we need to generate and settle liabilities incurred as a consequence of making transfers between particular types of customer. The general form of an example rule, that we are using to illustrate how it works is as follows: +- If the transaction is a wallet-to-wallet P2P transaction, then the receiver + DFSP pays the sender DFSP 0.6% of the amount of the transaction. +- No interchange fees are levied for on-us transactions. + +The business decisions around this requirement are: +1. The definition of whether or not a payee account is a wallet is + returned by the payee DFSP as part of customer discovery. In the process, the `extension` of the transaction should should be extended with characterization of the account. +2. Interchange fees are captured by the switch when there is a matching trigger condition. +3. Interchange fees have the ledger entry type INTERCHANGE_FEE and are + recorded in accounts whose type is INTERCHANGE_FEE. +4. Interchange fees are settled multilaterally, net and deferred. + _Make sure Settlement type and ledger account type for the INTERCHANGE FEE records are availabe_ + +This functionality is implemented as a general +process for defining and executing rules, and for taking actions based on the +outcome of evaluation of a rule. + +### Evaluating a rule +The process of evaluating a rule is based on the following assumptions: + +1. There is a standard form of rule evaluation with the following + structure: + 1. A transaction object is passed as the parameter to the rule + evaluation function. + 2. The rule evaluation itself uses a combination of simple and/or complex nested if statements + 3. If the rule evaluates to TRUE, then an action should be executeds + +An example of a rule function to evaluate an interchange fee rule could be: +```js +function evaluateInterchangeFee (transaction) { + if( + (transaction.payee.fspId.toLowerCase() != transaction.payer.fspId.toLowerCase()) + && (transaction.extensionList[“payerAccountType”].toLowerCase() == + "Wallet".toLowerCase() + && transaction.extensionList[“payeeAccountType”].toLowerCase() == + "Wallet".toLowerCase()) + && (transaction.transactionType.scenario.toLowerCase() == + "TRANSFER".toLowerCase() + && transaction.transactionType.initiator.toLowerCase() == "PAYER".toLowerCase() + && transaction.transactionType.initiatorType.toLowerCase() == + "CONSUMER".toLowerCase()) + ) + // Do some good stuff + }; +}; +``` + +### Taking action after evaluating a rule +If a rule evaluates to TRUE, then appropriate action is taken. In the case of the immediate example of interchange fees, the action taken should be to add two entries to the participants’ interchange fee accounts, on recording the debit from the payee of the interchange fee amount and the other recording the credit to the payer of the interchange fee amount. + +There is defined class with methods that represent the actions to be taken. The rule evaluation instatiates the class and calls the appropriate functions. + +In the case of the interchange fees, we have defined an action called +addLedgerEntry, with the following parameters: + +1. The transfer ID for which the ledger entry is being created +2. The ledger entry type to be used +3. The currency in which the amount is denominated +4. The amount of the fee +5. The FSP ID of the credit party +6. The FSP ID of the debit party + +This might appear in the rule evaluation function as: + +```js +myAction.addLedgerEntry(transaction.transactionId, + "INTERCHANGE_FEE“, + "INTERCHANGE_FEE“, + transaction.currency, + transaction.amount\*0.006, + transaction.payer.fspId, + transaction.payee.fspId); +``` +### Providing rules +The files should be placed in a scripts directory, configured by the value of the environmental variable `SETTINGS__SCRIPTS_FOLDER` +Each rule file should be valid JS with the specified headers content. The required headers should be in the exact order and format as they are in the example below the table. + +| Header | Description | Required | +| :- | :- | :-: | +| Name | Rule name | no | +| Type | Message event type. Corresponds to Kafka topic | yes | +| Action | Message event action. ex. Commit, Prepare, Log, etc | yes | +| Status | Status of the operation: success or failure | yes | +| Start | Time to start abiding the rule | yes | +| End | Until when the rule is valid | yes | +| Description | Rule description | no | + +Based on the headers the rule is evaluated to be triggered or not. + +In the below example rule script, a message on the `notification` topic with action `commit` and status `success` will trigger the code. + +```js +/* eslint-disable no-undef */ +// ******************************************************** +// Name: Interchange fee calculation +// Type: notification +// Action: commit +// Status: success +// Start: 2020-06-01T00:00:00.000Z +// End: 2100-12-31T23:59:59.999Z +// Description: This script calculates the interchange fees between DFSPs where the account type is "Wallet" +// ******************************************************** + +// ## Globals: +// payload: The contents of the message from the Kafka topic. +// transfer: The transfer object. + +// # Functions: +// ## Data retrieval functions: +// getTransferFromCentralLedger(transferId): Retrieves a mojaloop transfer from the central-ledger API. + +// ## Helper functions: +// getExtensionValue(list, key): Gets a value from an extension list +// log(message): allows the script to log to standard out for debugging purposes + +// Math functions: +// multiply(number1, number2, decimalPlaces): Uses ml-number to handle multiplication of money values + +// Ledger functions: +// addLedgerEntry: Adds a debit and credit ledger entry to the specified account to the specified DFSPs + +log(JSON.stringify(transfer)) +const payerFspId = transfer.payer.partyIdInfo.fspId +const payeeFspId = transfer.payee.partyIdInfo.fspId + +if ((payeeFspId !== payerFspId) && + (transfer.payee.partyIdInfo.extensionList && // WORKAROUND for issue #2149 + transfer.payer.partyIdInfo.extensionList && // WORKAROUND for issue #2149 + transfer.payee.partyIdInfo.extensionList.extension && // WORKAROUND for issue #2149 + transfer.payer.partyIdInfo.extensionList.extension) && // WORKAROUND for issue #2149 + (getExtensionValue(transfer.payee.partyIdInfo.extensionList.extension, 'accountType') === 'Wallet' && + getExtensionValue(transfer.payer.partyIdInfo.extensionList.extension, 'accountType') === 'Wallet') && + (transfer.transactionType.scenario === 'TRANSFER' && + transfer.transactionType.initiator === 'PAYER' && + transfer.transactionType.initiatorType === 'CONSUMER')) { + log(`Adding an interchange fee for Wallet to Wallet from ${payerFspId} to ${payeeFspId}`) + addLedgerEntry(payload.id, 'INTERCHANGE_FEE', // Ledger account type Id + 'INTERCHANGE_FEE', // Ledger entry type Id + multiply(transfer.amount.amount, 0.006, 2), + transfer.amount.currency, + payerFspId, + payeeFspId) +} +``` + +### Rules script API + +#### Globals + +* `payload` - The contents of the message from the Kafka topic that has the rules script triggered +* `transfer` - The transfer object +#### Functions + +* `getTransferFromCentralLedger(transferId: uuid)` - Retrieves a mojaloop transfer from the central-ledger API. +* `getExtensionValue(list: array, key: string)` - Gets a value from an extension list +* `log(message: string)`: allows the script to log to configured logger with level *INFO* for debugging purposes +* `multiply(number1: number, number2: number, decimalPlaces: number)`: Uses ml-number to handle multiplication of money values +* `addLedgerEntry(transferId: uuid, ledgerAccountTypeId: string, ledgerEntryTypeId: string, amount: number, currency: string, payerFspId: string, payeeFspId: string)`: Adds a debit and credit ledger entries with given legdger account type, amount and currency to the accounts of the specified DFSPs diff --git a/legacy/mojaloop-technical-overview/event-framework/README.md b/legacy/mojaloop-technical-overview/event-framework/README.md new file mode 100644 index 000000000..d1a0f5ece --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-framework/README.md @@ -0,0 +1,233 @@ +# Event Framework + +The purpose of the Event Framework is to provide a standard unified architecture to capture all Mojaloop events. + +_Disclaimer: This is experimental and is being implemented as a PoC. As such the design may change based on the evolution of the PoC's implementation, and any lessons learned._ + + +## 1. Requirements + +- Events will be produced by utilising a standard common library that will publish events to a sidecar component utilising a light-weight highly performant protocol (e.g. gRPC). +- Sidecar module will publish events to a singular Kafka topic that will allow for multiple handlers to consume and process the events as required. +- Kafka partitions will be determined by the event-type (e.g. log, audit, trace, errors etc). +- Each Mojaloop component will have its own tightly coupled Sidecar. +- Event messages will be produced to Kafka using the Trace-Id as the message key. This will ensure that all the messages part of the same trace (transaction) are stored in the same partition in order. + + +## 2. Architecture + +### 2.1 Overview + +![Event Framework Architecture](./assets/diagrams/architecture/architecture-event-framework.svg) + +### 2.2 Micro Service Pods + +![Pod Architecture](./assets/diagrams/architecture/architecture-event-sidecar.svg) + +### 2.3 Event Flow + +![Tracing Architecture](./assets/diagrams/architecture/architecture-event-trace.svg) + + +## 3. Event Envelope Model + +## 3.1 JSON Example + +```JSON +{ + "from": "noresponsepayeefsp", + "to": "payerfsp", + "id": "aa398930-f210-4dcd-8af0-7c769cea1660", + "content": { + "headers": { + "content-type": "application/vnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "noresponsepayeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": "data:application/vnd.interoperability.transfers+json;version=1.0;base64,ewogICJmdWxmaWxtZW50IjogIlVObEo5OGhaVFlfZHN3MGNBcXc0aV9VTjN2NHV0dDdDWkZCNHlmTGJWRkEiLAogICJjb21wbGV0ZWRUaW1lc3RhbXAiOiAiMjAxOS0wNS0yOVQyMzoxODozMi44NTZaIiwKICAidHJhbnNmZXJTdGF0ZSI6ICJDT01NSVRURUQiCn0" + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7-3978-408e-ae2e-a13012c47739", + "parentSpanId": "4e3ce424-d611-417b-a7b3-44ba9bbc5840", + "spanId": "efeb5c22-689b-4d04-ac5a-2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } +} +``` + +## 3.2 Schema Definition + +### 3.2.1 Object Definition: EventMessage + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | The id references the related message. | | +| from | string | N | If the value is not present in the destination, it means that the notification was generated by the connected node (server). | | +| to | string | Y | Mandatory for the sender and optional in the destination. The sender can ommit the value of the domain. | | +| pp | string | N | Optional for the sender, when is considered the identity of the session. Is mandatory in the destination if the identity of the originator is different of the identity of the from property. | | +| metadata | object `` | N | The sender should avoid to use this property to transport any kind of content-related information, but merely data relevant to the context of the communication. Consider to define a new content type if there's a need to include more content information into the message. | | +| type | string | Y | `MIME` declaration of the content type of the message. | | +| content | object \ | Y | The representation of the content. | | + +##### 3.2.1.1 Object Definition: MessageMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| event | object `` | Y | Event information. | | +| trace | object `` | Y | Trace information. | | + +##### 3.2.1.2 Object Definition: EventMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | Generated UUIDv4 representing the event. | 3920382d-f78c-4023-adf9-0d7a4a2a3a2f | +| type | enum `` | Y | Type of event. | [`log`, `audit`, `error` `trace`] | +| action | enum `` | Y | Type of action. | [ `start`, `end` ] | +| createdAt | timestamp | Y | ISO Timestamp. | 2019-05-29T23:18:32.935Z | +| responseTo | string | N | UUIDv4 id link to the previous parent event. | 2019-05-29T23:18:32.935Z | +| state | object `` | Y | Object describing the state. | | + +##### 3.2.1.3 Object Definition: EventStateMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| status | enum `` | Y | The id references the related message. | success | +| code | number | N | The error code as per Mojaloop specification. | 2000 | +| description | string | N | Description for the status. Normally used to include an description for an error. | Generic server error to be used in order not to disclose information that may be considered private. | + +##### 3.2.1.4 Object Definition: EventTraceMetaData + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| service | string | Y | Name of service producing trace | central-ledger-prepare-handler | +| traceId | 32HEXDIGLC | Y | The end-to-end transaction identifier. | 664314d5b207d3ba722c6c0fdcd44c61 | +| spanId | 16HEXDIGLC | Y | Id for a processing leg identifier for a component or function. | 81fa25e8d66d2e88 | +| parentSpanId | 16HEXDIGLC | N | The id references the related message. | e457b5a2e4d86bd1 | +| sampled | number | N | Indicator if event message should be included in the trace `1`. If excluded it will be left the consumer to decide on sampling. | 1 | +| flags | number | N | Indicator if event message should be included in the trace flow. ( Debug `1` - this will override the sampled value ) | 0 | +| startTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the start timestamp of a span.| 2015-08-29T11:22:09.815479Z | +| finishTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the finish timestamp of a span | 2015-08-29T11:22:09.815479Z | +| tags | object `` | Y | The id references the related message. | success | + +_Note: HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lower case hex character. Ref: [WC3 standard for trace-context](https://www.w3.org/TR/trace-context/#field-value)._ + +##### 3.2.1.5 Object Definition: EventTraceMetaDataTags + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| transactionId | string | N | Transaction Id representing either a transfer, quote, etc | 659ee338-c8f8-4c06-8aff-944e6c5cd694 | +| transactionType | string | N | The transaction type represented by the transactionId. E.g. (transfer, quote, etc) | transfer | +| parentEventType | string | N | The event-type of the parent Span. | bulk-prepare | +| parentEventAction | string | N | The event-action of the parent Span. | prepare | +| tracestate | string | N | This tag is set if EventSDK environmental variable `EVENT_SDK_TRACESTATE_HEADER_ENABLED` is `true` or if parent span context has the `tracestate` header or tag included. The tag holds updated `tracestate` header value as per the W3C trace headers specification. [More here](#411-wc3-http-headers)| `congo=t61rcWkgMzE,rojo=00f067aa0ba902b7` | +| `` | string | N | Arbitary Key-value pair for additional meta-data to be added to the trace information. | n/a | + +##### 3.2.1.6 Enum: EventStatusType + +| Enum | Description | +| --- | --- | +| success | Event was processed successfully | +| fail | Event was processed with a failure or error | + +##### 3.2.1.7 Enum: EventType + +| Enum | Description | +| --- | --- | +| log | Event representing a general log entry. | +| audit | Event to be signed and persisted into the audit store. | +| trace | Event containing trace context information to be persisted into the tracing store. | + +##### 3.2.1.8 Enum: LogEventAction + +| Enum | Description | +| --- | --- | +| info | Event representing an `info` level log entry. | +| debug | Event representing a `debug` level log entry. | +| error | Event representing an `error` level log entry. | +| verbose | Event representing a `verbose` level log entry. | +| warning | Event representing a `warning` level log entry. | +| performance | Event representing a `performance` level log entry. | + +##### 3.2.1.9 Enum: AuditEventAction + +| Enum | Description | +| --- | --- | +| default | Standard audit action. | +| start | Audit action to represent the start of a process. | +| finish | Audit action to represent the end of a process. | +| ingress | Audit action to capture ingress activity. | +| egress | Audit action to capture egress activity. | + +##### 3.2.1.10 Enum: TraceEventAction + +| Enum | Description | +| --- | --- | +| span | Event action representing a span of a trace. | + + +## 4. Tracing Design + +### 4.1 HTTP Transports + +Below find the current proposed standard HTTP Transport headers for tracing. + +Mojaloop has yet to standardise on either standard, or if it will possible support both. + +#### 4.1.1 W3C Http Headers + +Refer to the following publication for more information: https://w3c.github.io/trace-context/ + +| Header | Description | Example | +| --- | --- | --- | +| traceparent | Dash delimited string of tracing information: \-\-\-\ | 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00 | +| tracestate | Comma delimited vendor specific format captured as follows: \=\| congo=t61rcWkgMzE,rojo=00f067aa0ba902b7 | + +Note: Before this specification was written, some tracers propagated X-B3-Sampled as true or false as opposed to 1 or 0. While you shouldn't encode X-B3-Sampled as true or false, a lenient implementation may accept them. + +Note: (Event-SDK)[https://github.com/mojaloop/event-sdk] since version v9.4.1 has methods to add key value tags in the tracestate, and since version v9.5.2 the tracestate is base64 encoded. To be able to use the tracestate consistently, use matching versions across all services in a system. + +#### 4.1.2 B3 HTTP Headers + +Refer to the following publication for more information: https://github.com/apache/incubator-zipkin-b3-propagation + +| Header | Description | Example | +| --- | --- | --- | +| X-B3-TraceId | Encoded as 32 or 16 lower-hex characters. | a 128-bit TraceId header might look like: X-B3-TraceId: 463ac35c9f6413ad48485a3953bb6124. Unless propagating only the Sampling State, the X-B3-TraceId header is required. | +| X-B3-SpanId | Encoded as 16 lower-hex characters. | a SpanId header might look like: X-B3-SpanId: a2fb4a1d1a96d312. Unless propagating only the Sampling State, the X-B3-SpanId header is required. | +| X-B3-ParentSpanId | header may be present on a child span and must be absent on the root span. It is encoded as 16 lower-hex characters. | A ParentSpanId header might look like: X-B3-ParentSpanId: 0020000000000001 | +| X-B3-Sampled | An accept sampling decision is encoded as `1` and a deny as `0`. Absent means defer the decision to the receiver of this header. | A Sampled header might look like: X-B3-Sampled: 1. | +| X-B3-Flags | Debug is encoded as `1`. Debug implies an accept decision, so don't also send the X-B3-Sampled header. | | + +### 4.2 Kafka Transports + +Refer to `Event Envelope Model` section. This defines the message that will be sent through the Kafka transport. + +Alternatively the tracing context could be stored in Kafka headers which are only supports v0.11 or later. Note that this would break support for older versions of Kafka. + +### 4.3 Known limitations + +- Transfer tracing would be limited to each of the transfer legs (i.e. Prepare and Fulfil) as a result of the Mojaloop API specification not catering for tracing information. The trace information will be send as part of the callbacks by the Switch, but the FSPs will not be required to respond appropriately with a reciprocal trace headers. diff --git a/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-framework.svg b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-framework.svg new file mode 100644 index 000000000..47c2c4acb --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-framework.svg @@ -0,0 +1,3 @@ + + +
    Central-Ledger
    (API)
    Central-Ledger<br>(API)<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    (Handler #)
    Central-Ledger<br>(Handler #)<br>

    <div style="text-align: left ; font-size: 8px"><br></div>
    ML-API-Adapter
    (API)
    ML-API-Adapter<br>(API)<br>
    Central-Settlements
    (API)
    Central-Settlements<br>(API)<br>
    ML-API-Adapter
    (Handler)
    ML-API-Adapter<br>(Handler)<br>
    Quoting-Service
    (API)
    Quoting-Service<br>(API)<br>
    Account-Lookup-Service
    (API)
    Account-Lookup-Service<br>(API)<br>

    <div style="text-align: left"><br></div>
    Message Types:
    - Tracing
    - Audit
    - Logs
    [Not supported by viewer]
    <div style="text-align: center"></div>
    Kafka
    (Event Stream)
    topic-events
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    EFK
    (Elasticsearch, Fluentd, 
    Kibana & APM)
    [Not supported by viewer]
    Forensic-Logging
    (Future - re-factored from Side-Car into Service for Batch Audits)
    [Not supported by viewer]
    Central-KMS
    Central-KMS
    Audits
    Audits
    Keys
    Keys
    Partitioned by Trace-Id
    [Not supported by viewer]
    Event-stream-processor
    (Mediation,  Translation)
    [Not supported by viewer]
    Open-Tracing
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    Key provisioning
    [Not supported by viewer]
    Key provisioning
    [Not supported by viewer]
    Message Types:
    - Tracing
    - Audit
    - Logs
    [Not supported by viewer]
    Message Types:
    - Audits
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg new file mode 100644 index 000000000..b274a9d3a --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg @@ -0,0 +1,3 @@ + + +

    <div style="text-align: left"><br></div>
    POD #2
    POD #2
    Service #2
    Service #2<br>
    POD #1
    POD #1
    <div style="text-align: center"></div>
    Kafka
    (Event Stream)
    topic-events
    [Not supported by viewer]
    Kubernetes Cluster
    [Not supported by viewer]
    Event Framework
    SideCar
    Event Framework<br>SideCar<br>
    gRPC Server
    gRPC Server
    gRPC Client
    gRPC Client
    Kafka
    Client
    [Not supported by viewer]
    Partitioned by Trace-Id
    [Not supported by viewer]
    Service #1
    Service #1<br>
    Event Framework
    SideCar
    Event Framework<br>SideCar<br>
    gRPC Server
    gRPC Server
    gRPC Client
    gRPC Client
    Kafka
    Client
    [Not supported by viewer]
    @mojaloop/
    event-sdk
    @mojaloop/<br>event-sdk
    Event Framework Sidecar included as part of each component Helm Chart
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-trace.svg b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-trace.svg new file mode 100644 index 000000000..5fd81ccfb --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-framework/assets/diagrams/architecture/architecture-event-trace.svg @@ -0,0 +1,3 @@ + + +
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Service
    Consumer 
    Service...
    Parent Span
    Parent Span
    Trace
    Trace
    Start
    Start
    End
    End
    Child Span
    Child Span
    Start
    Start
    End
    End
    Child Span
    Child Span
    Start
    Start
    End
    End
    Trace Context
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tracestate
    Trace Context...
    Service
    Producer 
    Service...
    Tags: [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination: payeeFsp, tracestate: mojaloop=f32c19568004ce8b ]
    Tags: [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination: payeeFsp, tracestate: mojaloop=f32c19568004ce...
    Child Span
    Child Span
    Start
    Start
    End
    End
    Message Transport
    - HTTP
    - Kafka

    Message Transport...
    Error
    Error
    Kafka
    (Event Topic)
    Kafka...
    Event Sidecar
    Event Sidecar
    Event Sidecar
    Event Sidecar
    Record Trace
    Record...
    Service A
    Service A
    Service B
    Service B
    Trace Message
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tags
    - tracestate
    - content / error
    Trace Message...
    Record Trace
    Record...
    Record Trace
    Record...
    Record Trace
    Record...
    Record Error
    Record...
    Audit
    Audit
    Record
    Audit
    Record...
    Log
    Log
    Record Log
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/event-stream-processor/README.md b/legacy/mojaloop-technical-overview/event-stream-processor/README.md new file mode 100644 index 000000000..b92c42e5c --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-stream-processor/README.md @@ -0,0 +1,20 @@ +# Event Stream Processor Service + +Event Stream Processor consumes event messages from the `topic-events` topic as a result of messages published by the [event-sidecar](https://github.com/mojaloop/event-sidecar) service. Refer to [Event Framework](../event-framework/README.md) for more information on the overall architecture. + +The Service delivers logs, including audits, and traces to EFK stack with enabled APM plugin. Based on the event message type, the messages are delivered to different indexes in the Elasticsearch. + +## 1. Prerequisites + +The service logs all the events to Elasticsearch instance with enabled APM plugin. Sample docker-compose of the Elastic stack is available [here](https://github.com/mojaloop/event-stream-processor/blob/master/test/util/scripts/docker-efk/docker-compose.yml). The logs and audits are created under custom index template, while the trace data is stored to the default `apm-*` index. +Please, ensure that you have created the `mojatemplate` as it is described into the [event-stream-processor](https://github.com/mojaloop/event-stream-processor#111-create-template) service documentation. + +## 2. Architecture overview + +### 2.1. Flow overview + +![Event Stream Processor flow overview](./assets/diagrams/architecture/event-stream-processor-overview.svg) + +### 2.2 Trace processing flow sequence diagram + +![process-flow.svg](./assets/diagrams/sequence/process-flow.svg) diff --git a/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg new file mode 100644 index 000000000..9deb189e9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg @@ -0,0 +1,3 @@ + + +
    topic-event
    topic-event
    Event Stream Processor
    Send to Elasticsearch mojaloop custom schema via Elasticsearch API
    [Not supported by viewer]
    Yes
    Yes
    Is it trace?
    Is it trace?
    No
    No
    Should create master span?
    Should create master span?
    exit
    exit
    No
    No
    APM Agent
    APM Agent
    Create cache for the trace
    Create cache for the trace
    Yes
    Yes
    No
    No
    Is last span?
    Is last span?
    Recreate trace
    Recreate trace
    exit
    exit
    EFK Stack (Elasticsearch, Kibana, APM)
    EFK Stack (Elasticsearch, Kibana, APM)
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml new file mode 100644 index 000000000..9817a79d8 --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml @@ -0,0 +1,280 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title Event Streaming Processor flow + +autonumber + +' Actor Keys: + +' declare actors + +collections "Notification topic" as TOPIC_NOTIFICATIONS +control "Topic Observable" as TOPIC_OBSERVABLE +control "Tracing Observable" as TRACING_OBSERVABLE +control "Caching Observable" as CACHING_OBSERVABLE +control "Check For Last Span Observable" as LASTSPAN_OBSERVABLE +control "Create Trace Observable" as CREATETRACE_OBSERVABLE +control "Cache Handler" as CACHE_HANDLER +control "Send Trace Handler" as TRACE_HANDLER +control "Send Span Handler" as SPAN_SENDER +database "Cache Storage" as CACHE +boundary "APM" as APM +boundary "Elasticsearch API" as ELASTIC + +box "Central Services" #lightGray + participant TOPIC_NOTIFICATIONS +end box + +box "Event Stream Processor" #LightBlue + participant TOPIC_OBSERVABLE + participant TRACING_OBSERVABLE + participant CACHING_OBSERVABLE + participant LASTSPAN_OBSERVABLE + participant CREATETRACE_OBSERVABLE + participant TRACE_HANDLER + participant SPAN_SENDER + participant CACHE_HANDLER +end box + +box "Cache" #LightSteelBlue + participant CACHE +end box + +box "Elasticsearch" #LightYellow + participant APM + participant ELASTIC +end box + +' start flow + +group New Event Message Received + TOPIC_NOTIFICATIONS -> TOPIC_OBSERVABLE: Consume Event Message + activate TOPIC_OBSERVABLE + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + note over TOPIC_OBSERVABLE #yellow + Message: + { + "from": "payeefsp", + "to": "payerfsp", + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "content": { + "headers": { + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "payeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": "44ba9bbc5840", + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } + } + end note + TOPIC_OBSERVABLE -> ELASTIC: Send message for log purposes to custom index + TOPIC_OBSERVABLE -> TOPIC_OBSERVABLE: Verify its tracing event Message + TOPIC_OBSERVABLE -> TRACING_OBSERVABLE: Send Message to Tracing Observable + deactivate TOPIC_OBSERVABLE + activate TRACING_OBSERVABLE + group Cache Span + TRACING_OBSERVABLE -> CACHING_OBSERVABLE: Send Span Context, \nmetadata.State and Content\nfrom Message + note right of TRACING_OBSERVABLE #yellow + { + spanContext: { + service: "central-ledger-prepare-handler", + traceId: "bbd7b2c7bbd7b2c7", + parentSpanId: "44ba9bbc5840", + spanId: "2aa9cd0a7e87", + startTimestamp: "2015-08-29T11:22:09.815479Z", + finishTimestamp: "2015-08-29T11:22:09.815479Z", + tags: { + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + transctionType: "transfer", + parentEventType: "bulk-prepare", + parentEventAction: "prepare" + }, + state: metadata.state, + content + } + end note + deactivate TRACING_OBSERVABLE + activate CACHING_OBSERVABLE + CACHING_OBSERVABLE <- CACHE: Get cachedTrace by traceId + alt the span should not be cached + CACHING_OBSERVABLE -> SPAN_SENDER: currentSpan + SPAN_SENDER -> APM: store to APM + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Complete + else + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + alt !cachedTrace + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Create new cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: {}, + masterSpan: null, + lastSpan: null + } + end note + end + alt !parentSpan + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Generate MasterSpanId + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Make received span child of masterSpan \nmerge({ parentSpanId: MasterSpanId }, { ...spanContext }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, \n{ ...spanContext }, \n{ spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Add masterSpan to cachedTrace + end + CACHING_OBSERVABLE <-> CACHE_HANDLER: Add span to cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: { + 2aa9cd0a7e87: { + state, + content + spanContext: { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": MasterSpanId, + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + }, + MasterSpanId: { + state, + content, + MasterSpanContext + } + }, + masterSpan: MasterSpanContext, + lastSpan: null + } + end note + CACHING_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + end + CACHING_OBSERVABLE -> LASTSPAN_OBSERVABLE: Send traceId to check if last span has been received\nand cached + deactivate CACHING_OBSERVABLE + activate LASTSPAN_OBSERVABLE + end + group Check for last span + LASTSPAN_OBSERVABLE <- CACHE: Get cachedTrace by traceId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Sort spans by startTimestamp + loop for currentSpan of SortedSpans + alt parentSpan + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: isError = (errorCode in parentSpan \nOR parentSpan status === failed \nOR status === failed) + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: apply masterSpan and error tags from parent to current span in cachedTrace + alt !isLastSpan + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + else + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Validate transactionType, TransactionAction, service and isError \nto match Config.START_CRITERIA && !parentSpandId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: cachedTrace.lastSpan = currentSpan.spanContext + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + LASTSPAN_OBSERVABLE -> CREATETRACE_OBSERVABLE: Send traceId + deactivate LASTSPAN_OBSERVABLE + activate CREATETRACE_OBSERVABLE + end + end + end + end + group Recreate Trace from Cached Trace + CREATETRACE_OBSERVABLE <- CACHE: get cachedTrace by TraceId + alt cachedTrace.lastSpan AND cachedTrace.masterSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: currentSpan = lastSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: resultTrace = [lastSpan] + loop for i = 0; i < cachedTrace.spans.length; i++ + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: get parentSpan of currentSpan + alt parentSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: insert parent span in resultTrace in front + else + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: break loop + end + end + alt cachedTrace.masterSpan === currentSpan.spanId + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + CREATETRACE_OBSERVABLE -> TRACE_HANDLER: send resultTrace + deactivate CREATETRACE_OBSERVABLE + activate TRACE_HANDLER + end + end + end + group send Trace + loop trace elements + TRACE_HANDLER -> SPAN_SENDER: send each span + SPAN_SENDER -> APM: send span to APM + end + TRACE_HANDLER -> TRACE_HANDLER: unsubscribe scheduler for traceId + TRACE_HANDLER -> CACHE: drop cachedTrace + + end + end +@enduml \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.svg b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.svg new file mode 100644 index 000000000..0919b3c48 --- /dev/null +++ b/legacy/mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.svg @@ -0,0 +1,1028 @@ + + + + + + + + + + + Event Streaming Processor flow + + + + Central Services + + + + Event Stream Processor + + + + Cache + + + + Elasticsearch + + + + + + + + + + + + + + + + + + + + + + + + Notification topic + + + + + Notification topic + + + Topic Observable + + + + + Topic Observable + + + + + Tracing Observable + + + + + Tracing Observable + + + + + Caching Observable + + + + + Caching Observable + + + + + Check For Last Span Observable + + + + + Check For Last Span Observable + + + + + Create Trace Observable + + + + + Create Trace Observable + + + + + Send Trace Handler + + + + + Send Trace Handler + + + + + Send Span Handler + + + + + Send Span Handler + + + + + Cache Handler + + + + + Cache Handler + + + + + Cache Storage + + + + + Cache Storage + + + + + APM + + + + + APM + + + + + Elasticsearch API + + + + + Elasticsearch API + + + + + + + + New Event Message Received + + + + + 1 + + + Consume Event Message + + + + + Message: + + + { + + + "from": "payeefsp", + + + "to": "payerfsp", + + + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "content": { + + + "headers": { + + + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + + + "date": "2019-05-28T16:34:41.000Z", + + + "fspiop-source": "payeefsp", + + + "fspiop-destination": "payerfsp" + + + }, + + + "payload": <payload> + + + }, + + + "type": "application/json", + + + "metadata": { + + + "event": { + + + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + + + "type": "trace", + + + "action": "span", + + + "createdAt": "2019-05-29T23:18:32.935Z", + + + "state": { + + + "status": "success", + + + "code": 0, + + + "description": "action successful" + + + }, + + + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + + + }, + + + "trace": { + + + "service": "central-ledger-prepare-handler", + + + "traceId": "bbd7b2c7bbd7b2c7", + + + "parentSpanId": "44ba9bbc5840", + + + "spanId": "2aa9cd0a7e87", + + + "startTimestamp": "2015-08-29T11:22:09.815479Z", + + + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + + + "tags": { + + + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "transctionType": "transfer", + + + "parentEventType": "bulk-prepare", + + + "parentEventAction": "prepare" + + + } + + + } + + + } + + + } + + + + + 2 + + + Send message for log purposes to custom index + + + + + 3 + + + Verify its tracing event Message + + + + + 4 + + + Send Message to Tracing Observable + + + + + Cache Span + + + + + 5 + + + Send Span Context, + + + metadata.State and Content + + + from Message + + + + + { + + + spanContext: { + + + service: "central-ledger-prepare-handler", + + + traceId: "bbd7b2c7bbd7b2c7", + + + parentSpanId: "44ba9bbc5840", + + + spanId: "2aa9cd0a7e87", + + + startTimestamp: "2015-08-29T11:22:09.815479Z", + + + finishTimestamp: "2015-08-29T11:22:09.815479Z", + + + tags: { + + + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + transctionType: "transfer", + + + parentEventType: "bulk-prepare", + + + parentEventAction: "prepare" + + + }, + + + state: metadata.state, + + + content + + + } + + + + + 6 + + + Get cachedTrace by traceId + + + + + alt + + + [the span should not be cached] + + + + + 7 + + + currentSpan + + + + + 8 + + + store to APM + + + + + 9 + + + Complete + + + + + + 10 + + + Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + + + + + alt + + + [!cachedTrace] + + + + + 11 + + + Create new cachedTrace + + + + + { + + + spans: {}, + + + masterSpan: null, + + + lastSpan: null + + + } + + + + + alt + + + [!parentSpan] + + + + + 12 + + + Generate MasterSpanId + + + + + 13 + + + Make received span child of masterSpan + + + merge({ parentSpanId: MasterSpanId }, { ...spanContext }) + + + + + 14 + + + Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, + + + { ...spanContext }, + + + { spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + + + + + 15 + + + Add masterSpan to cachedTrace + + + + + 16 + + + Add span to cachedTrace + + + + + { + + + spans: { + + + 2aa9cd0a7e87: { + + + state, + + + content + + + spanContext: { + + + "service": "central-ledger-prepare-handler", + + + "traceId": "bbd7b2c7bbd7b2c7", + + + "parentSpanId": + + + MasterSpanId + + + , + + + "spanId": "2aa9cd0a7e87", + + + "startTimestamp": "2015-08-29T11:22:09.815479Z", + + + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + + + "tags": { + + + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "transctionType": "transfer", + + + "parentEventType": "bulk-prepare", + + + "parentEventAction": "prepare" + + + } + + + } + + + }, + + + MasterSpanId: + + + { + + + state, + + + content, + + + MasterSpanContext + + + } + + + }, + + + masterSpan: + + + MasterSpanContext + + + , + + + lastSpan: null + + + } + + + + + 17 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 18 + + + unsubscribe from Scheduler + + + + + 19 + + + record cachedTrace + + + + + 20 + + + Reschedule scheduler for handling stale traces + + + + + 21 + + + Send traceId to check if last span has been received + + + and cached + + + + + Check for last span + + + + + 22 + + + Get cachedTrace by traceId + + + + + 23 + + + Sort spans by startTimestamp + + + + + loop + + + [for currentSpan of SortedSpans] + + + + + alt + + + [parentSpan] + + + + + 24 + + + isError = (errorCode in parentSpan + + + OR parentSpan status === failed + + + OR status === failed) + + + + + 25 + + + apply masterSpan and error tags from parent to current span in cachedTrace + + + + + alt + + + [!isLastSpan] + + + + + 26 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 27 + + + unsubscribe from Scheduler + + + + + 28 + + + record cachedTrace + + + + + 29 + + + Reschedule scheduler for handling stale traces + + + + + + 30 + + + Validate transactionType, TransactionAction, service and isError + + + to match Config.START_CRITERIA && !parentSpandId + + + + + 31 + + + cachedTrace.lastSpan = currentSpan.spanContext + + + + + 32 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 33 + + + unsubscribe from Scheduler + + + + + 34 + + + record cachedTrace + + + + + 35 + + + Reschedule scheduler for handling stale traces + + + + + 36 + + + Send traceId + + + + + Recreate Trace from Cached Trace + + + + + 37 + + + get cachedTrace by TraceId + + + + + alt + + + [cachedTrace.lastSpan AND cachedTrace.masterSpan] + + + + + 38 + + + currentSpan = lastSpan + + + + + 39 + + + resultTrace = [lastSpan] + + + + + loop + + + [for i = 0; i < cachedTrace.spans.length; i++] + + + + + 40 + + + get parentSpan of currentSpan + + + + + alt + + + [parentSpan] + + + + + 41 + + + insert parent span in resultTrace in front + + + + + + 42 + + + break loop + + + + + alt + + + [cachedTrace.masterSpan === currentSpan.spanId] + + + + + 43 + + + masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + + + + + 44 + + + send resultTrace + + + + + send Trace + + + + + loop + + + [trace elements] + + + + + 45 + + + send each span + + + + + 46 + + + send span to APM + + + + + 47 + + + unsubscribe scheduler for traceId + + + + + 48 + + + drop cachedTrace + + diff --git a/mojaloop-technical-overview/fraud-services/README.md b/legacy/mojaloop-technical-overview/fraud-services/README.md similarity index 100% rename from mojaloop-technical-overview/fraud-services/README.md rename to legacy/mojaloop-technical-overview/fraud-services/README.md diff --git a/legacy/mojaloop-technical-overview/fraud-services/related-documents/documentation.md b/legacy/mojaloop-technical-overview/fraud-services/related-documents/documentation.md new file mode 100644 index 000000000..920da7b7f --- /dev/null +++ b/legacy/mojaloop-technical-overview/fraud-services/related-documents/documentation.md @@ -0,0 +1,7 @@ +# Fraud Services + +Artefacts available for public reference related to the preventative measures in preventing and discouraging fraudulent activities within the ecosystem. + +## List of current artefacts + +#### [Mojaloop Ecosystem Fraud Overview Document](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/April%202019%20PI-6_OSS_community%20session/Mojaloop-Fraud-20190410.pdf) diff --git a/legacy/mojaloop-technical-overview/ml-testing-toolkit/README.md b/legacy/mojaloop-technical-overview/ml-testing-toolkit/README.md new file mode 100644 index 000000000..0d5af432d --- /dev/null +++ b/legacy/mojaloop-technical-overview/ml-testing-toolkit/README.md @@ -0,0 +1,16 @@ +Mojaloop Testing Toolkit +============================= + +The **Mojaloop Testing Toolkit** was designed to help Mojaloop Schemes scale effectively by easing the DFSP Onboarding process. Schemes can provide a set of rules and tests on the toolkit and DFSPs can use it for self testing (or self-certification in some cases). This ensures that DFSPs are well and truly ready with their implementations to be integrated with the Scheme and allows for a quick and smooth onboarding process for the Mojaloop Hubs, thereby increasing their scalability. + +This was initially aimed at FSPs/Participants that would like to participate in a Mojaloop scheme. However, in its current form, this tool set can potentially be used by both DFSPs and _Mojaloop Hubs_ to verify integration between the 2 entities. Intentionally build as a standard integration testing tool between a _Digital Financial Service Provider (DFSP)_ and the _Mojaloop Switch_ (Hub), to facilitate testing. + +For additional background on the Self Testing Toolkit, please see [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md). It would be to the particpant's benefit to familiarise themselves with the understanding of the [Architecture Diagram](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md#7-architecture) that explains the various components and related flows. + +## Usage Guides + +For Web interface follow this [Usage Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide.md) + +For Command line tool follow this [CLI User Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide-CLI.md) + +**If you have your own DFSP implementation you can point the peer endpoint to Mojaloop Testing Toolkit on port 5000 and try to send requests from your implementation instead of using mojaloop-simulator.** diff --git a/legacy/mojaloop-technical-overview/overview/README.md b/legacy/mojaloop-technical-overview/overview/README.md new file mode 100644 index 000000000..373cbfa93 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/README.md @@ -0,0 +1,24 @@ +# Mojaloop Hub + +There are several components that make up the Mojaloop ecosystem. The Mojaloop Hub is the primary container and reference we use to describe the core Mojaloop components. + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture: + +![Current Mojaloop Architecture Overview](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ + +These consist of: + +* The **Mojaloop API Adapters** (**ML-API-Adapter**) provide the standard set of interfaces a DFSP can implement to connect to the system for Transfers. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* The **Central Services** (**CS**) provide the set of components required to move money from one DFSP to another through the Mojaloop API Adapters. This is similar to how money moves through a central bank or clearing house in developed countries. The Central Services contains the core Central Ledger logic to move money but also will be extended to provide fraud management and enforce scheme rules. +* The **Account Lookup Service** (**ALS**) provides a mechanism to resolve FSP routing information through the Participant API or orchestrate a Party request based on an internal Participant look-up. The internal Participant look-up is handled by a number of standard Oracle adapter or services. Example Oracle adapter/service would be to look-up Participant information from Pathfinder or a Merchant Registry. These Oracle adapters or services can easily be added depending on the schema requirements. +* The **Quoting Service** (**QA**) provides Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. +* The **Simulator** (**SIM**) mocks several DFSP functions as follows: + * Oracle end-points for Oracle Participant CRUD operations using in-memory cache; + * Participant end-points for Oracles with support for parameterized partyIdTypes; + * Parties end-points for Payer and Payee FSPs with associated callback responses; + * Transfer end-points for Payer and Payee FSPs with associated callback responses; and + * Query APIs to verify transactions (requests, responses, callbacks, etc) to support QA testing and verification. + +On either side of the Mojaloop Hub there is sample open source code to show how a DFSP can send and receive payments and the client that an existing DFSP could host to connect to the network. diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg new file mode 100644 index 000000000..df9396cae --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg new file mode 100644 index 000000000..763c5697e --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Settlement Windows)
    Central-Settlements...
    Central-Settlements
    (Handler - Transfer Settlements)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg new file mode 100644 index 000000000..06680fbae --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg new file mode 100644 index 000000000..4a658b897 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    Central-Directory
    (Participant Lookup)
    [Not supported by viewer]
    Central-End-User-Registry
    (Custom Participant Store)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Central-Hub
    (Retired - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg new file mode 100644 index 000000000..ac0b21621 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Msisdn-Service
    (Pathfinder Lookup Adapter)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg new file mode 100644 index 000000000..9697dfc5b --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core
    <b>Core</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Persistence
    <b>Persistence</b>
    Scaffolding
    [Not supported by viewer]
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Event-Logging-Sidecar
    (POC - Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP, POCLogs, Error, Audits, Tracing)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational UI)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Deprecated - Auditing)
    [Not supported by viewer]
    Simulator
    (API - FSP Simulator /
    API - Oracle Simulator)

    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg new file mode 100644 index 000000000..2fedecbc1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core Components
    <b>Core Components</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Supporting Components
    <b style="line-height: 0%">Supporting Components</b>
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging
    (Future - Auditing)
    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Simulator
    (API - FSP & Oracle Simulator)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    Mojaloop-Simulator
    (SDK)
    [Not supported by viewer]
    License & Audit
    (Dependencies)
    [Not supported by viewer]
    Persistence
    <b>Persistence</b>
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Transaction Request Service
    (API - Transaction)
    <b>Transaction Request Service</b><br>(API - Transaction)
    Software Dev Kits
    <b>Software Dev Kits</b>
    Oracle SDK
    (Participant Store)
    [Not supported by viewer]
    Mojaloop SDK 
    (FSP Payer/Payee)
    [Not supported by viewer]
    Event SDK
    (Audit, Log, Trace - Client/Server)
    [Not supported by viewer]
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    <b>Event-Sidecar</b><br>(Logs, Error, Audits, Tracing)
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg new file mode 100644 index 000000000..3e5b75f13 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/overview/components-PI11.md b/legacy/mojaloop-technical-overview/overview/components-PI11.md new file mode 100644 index 000000000..35b839657 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI11.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI11 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI11: + +![Mojaloop Architecture Overview PI11](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI12.md b/legacy/mojaloop-technical-overview/overview/components-PI12.md new file mode 100644 index 000000000..d90d82eb9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI12.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI12 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI12: + +![Mojaloop Architecture Overview PI12](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI14.md b/legacy/mojaloop-technical-overview/overview/components-PI14.md new file mode 100644 index 000000000..d4c4e3887 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI14.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI14 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI14: + +![Mojaloop Architecture Overview PI14](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI3.md b/legacy/mojaloop-technical-overview/overview/components-PI3.md new file mode 100644 index 000000000..a3cb1b686 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI3.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI3 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI3: + +![Mojaloop Architecture Overview PI5](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI5.md b/legacy/mojaloop-technical-overview/overview/components-PI5.md new file mode 100644 index 000000000..f54ac4856 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI5.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI5 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI5: + +![Mojaloop Architecture Overview PI5](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI6.md b/legacy/mojaloop-technical-overview/overview/components-PI6.md new file mode 100644 index 000000000..a935f7cc5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI6.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI6 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI6: + +![Mojaloop Architecture Overview PI6](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI7.md b/legacy/mojaloop-technical-overview/overview/components-PI7.md new file mode 100644 index 000000000..f2f59dd8a --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI7.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI7 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI7: + +![Mojaloop Architecture Overview PI7](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/overview/components-PI8.md b/legacy/mojaloop-technical-overview/overview/components-PI8.md new file mode 100644 index 000000000..3d18e7fac --- /dev/null +++ b/legacy/mojaloop-technical-overview/overview/components-PI8.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI8 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI8: + +![Mojaloop Architecture Overview PI8](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/legacy/mojaloop-technical-overview/quoting-service/README.md b/legacy/mojaloop-technical-overview/quoting-service/README.md new file mode 100644 index 000000000..094ac1de2 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/README.md @@ -0,0 +1,8 @@ +# Quoting Service Overview +The **Quoting Service** (**QS**) _(refer to section `5.1`)_ as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) implements the quoting phase of the various use-cases. + +_Note: In addition to individual quotes, the quoting service supports bulk quotes as well._ + +## Sequence Diagram + +![seq-quotes-1.0.0.svg](./assets/diagrams/sequence/seq-quotes-1.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml new file mode 100644 index 000000000..0405a9868 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Retrieve Bulk Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP + +autonumber +note right of PayerFSP: Payer FSP sends request to get bulk quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /bulkQuotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve bulk quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode) + Switch -\ PayeeFSP: GET /bulkQuotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves bulk quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** + end note + Switch --/ PayeeFSP: 200 Ok + alt Response is ok + Switch -> Switch: Retrieve bulk quotes endpoint for the Payer FSP + alt Bulk Quotes callback endpoint found + note left of Switch: Switch forwards bulk quote response to Payer FSP + Switch -\ PayerFSP: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Bulk Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else bulkQuote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP Bulk quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg new file mode 100644 index 000000000..9cab870cb --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg @@ -0,0 +1,369 @@ + + + + + + + + + + + Retrieve Bulk Quote Information + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting Service] + + + + Switch + + + [Quoting Service] + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP sends request to get bulk quote details + + + to Payee FSP via the Switch + + + + + 1 + + + GET /bulkQuotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Retrieve bulk quotes endpoint for Payee FSP + + + + + alt + + + [Payee FSP quotes endpoint is found] + + + + + Switch forwards request to Payee FSP (pass-through mode) + + + + + 5 + + + GET /bulkQuotes/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Payee FSP retireves bulk quote + + + + + alt + + + [Payee FSP successfully retieves quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 9 + + + 200 Ok + + + + + alt + + + [Response is ok] + + + + + 10 + + + Retrieve bulk quotes endpoint for the Payer FSP + + + + + alt + + + [Bulk Quotes callback endpoint found] + + + + + Switch forwards bulk quote response to Payer FSP + + + + + 11 + + + PUT /bulkQuotes/{ID} + + + + + 12 + + + 200 Ok + + + + [Bulk Quotes callback endpoint not found] + + + + + Switch returns error to Payee FSP + + + + + 13 + + + PUT /bulkQuotes/{ID}/error + + + + + 14 + + + 200 Ok + + + + [Response is invalid] + + + + + Switch returns error to Payee FSP + + + + + 15 + + + PUT /bulkQuotes/{ID}/error + + + + + 16 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [bulkQuote not found] + + + + + Payee FSP returns error to Switch + + + Error code: 3205 + + + + + 17 + + + PUT /bulkQuotes/{ID}/error + + + + + 18 + + + 200 OK + + + + + Switch returns error to Payer FSP + + + Error code: 3205 + + + + + 19 + + + PUT /bulkQuotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [Payee FSP Bulk quotes endpoint is not found] + + + + + Switch returns error to Payer FSP + + + Error code: 3201 + + + + + 21 + + + PUT /bulkQuotes/{ID}error + + + + + 22 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml new file mode 100644 index 000000000..dfcb1918b --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml @@ -0,0 +1,86 @@ +@startuml +Title Retrieve Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber +note right of PayerFSP: Payer FSP sends request to get quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /quotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode)\n + Switch -\ PayeeFSP: GET /quotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 Ok + Switch -> Switch: Validate response (schema, headers (**Error code: 3100**)) + alt Response is ok + alt SimpleRoutingMode is FALSE + Switch -> Switch: Validate response (duplicate response check, handle resend scenario (**Error code: 3106**)) + alt Validation passed + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + end + alt SimpleRoutingMode is TRUE + Switch -> Switch: Retrieve quotes endpoint for the Payer FSP + else SimpleRoutingMode is FALSE + Switch -> Switch: Retrieve quote party endpoint (PAYER) + end + alt Quotes callback endpoint found + note left of Switch: Switch forwards quote response to Payer FSP\n + Switch -\ PayerFSP: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else Quote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode is FALSE + Switch -> Switch: Persist error data + end + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT quotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg new file mode 100644 index 000000000..679d20f98 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg @@ -0,0 +1,496 @@ + + + + + + + + + + + Retrieve Quote Information + + + + + + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting + + + Service] + + + + Switch + + + [Quoting + + + Service] + + + Central Store + + + + + Central Store + + + + + + Payee FSP + + + + Payee FSP + + + + + + Payer FSP sends request to get quote details + + + to Payee FSP via the Switch + + + + + 1 + + + GET /quotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Retrieve quotes endpoint for Payee FSP + + + + + alt + + + [Payee FSP quotes endpoint is found] + + + + + Switch forwards request to Payee FSP (pass-through mode) + + + <Payer based Rules> + + + + + 5 + + + GET /quotes/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Payee FSP retireves quote + + + + + alt + + + [Payee FSP successfully retieves quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate response (schema, headers ( + + + Error code: 3100 + + + )) + + + + + alt + + + [Response is ok] + + + + + alt + + + [SimpleRoutingMode is FALSE] + + + + + 11 + + + Validate response (duplicate response check, handle resend scenario ( + + + Error code: 3106 + + + )) + + + + + alt + + + [Validation passed] + + + + + 12 + + + Persist quote response + + + + quoteResponse + + + quoteResponseDuplicateCheck + + + quoteResponseIlpPacket + + + quoteExtensions + + + geoCode + + + + + 13 + + + Quote response saved + + + + + alt + + + [SimpleRoutingMode is TRUE] + + + + + 14 + + + Retrieve quotes endpoint for the Payer FSP + + + + [SimpleRoutingMode is FALSE] + + + + + 15 + + + Retrieve quote party endpoint (PAYER) + + + + + alt + + + [Quotes callback endpoint found] + + + + + Switch forwards quote response to Payer FSP + + + <Payee whole request Rule> + + + + + 16 + + + PUT /quotes/{ID} + + + + + 17 + + + 200 Ok + + + + [Quotes callback endpoint not found] + + + + + Switch returns error to Payee FSP + + + + + 18 + + + PUT /quotes/{ID}/error + + + + + 19 + + + 200 Ok + + + + [Response is invalid] + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /quotes/{ID}/error + + + + + 21 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [Quote not found] + + + + + Payee FSP returns error to Switch + + + Error code: 3205 + + + + + 22 + + + PUT quotes/{ID}/error + + + + + 23 + + + 200 OK + + + + + alt + + + [SimpleRoutingMode is FALSE] + + + + + 24 + + + Persist error data + + + + + Switch returns error to Payer FSP + + + Error code: 3205 + + + + + 25 + + + PUT quotes/{ID}/error + + + + + 26 + + + 200 OK + + + + [Payee FSP quotes endpoint is not found] + + + + + Switch returns error to Payer FSP + + + Error code: 3201 + + + + + 27 + + + PUT quotes/{ID}error + + + + + 28 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml new file mode 100644 index 000000000..ca4c1d30f --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml @@ -0,0 +1,99 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Request Bulk Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends bulk quote request\nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /bulkQuotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Bulk Quote request validation (rules engine etc.) +||| +Switch -> Switch: Duplicate check +||| +alt Request is a duplicate but not a resend +||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK +||| +else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario +end +||| +Switch -> Switch: Use fspiop-destination header to retrieve\n bulk quotes endpoint for Payee DFSP +alt Payee bulk quotes endpoint found + note right of Switch: Switch forwards bulk quote request to Payee FSP + Switch -\ PayeeFSP: POST /bulkQuotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP calculates individual quotes\nand responds with a bulk quote result + alt Payee bulkQuotes processing successful + note over PayeeFSP, Switch: Payee FSP sends bulk quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate bulk quote response + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects bulk quote or encounters an error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg new file mode 100644 index 000000000..4b3363dd6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg @@ -0,0 +1,387 @@ + + + + + + + + + + + Request Bulk Quote Creation + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting Service] + + + + Switch + + + [Quoting Service] + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP sends bulk quote request + + + to Payee FSP via the Switch + + + + + 1 + + + POST /bulkQuotes + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Bulk Quote request validation (rules engine etc.) + + + + + 5 + + + Duplicate check + + + + + alt + + + [Request is a duplicate but not a resend] + + + + + Switch returns error back to Payer FSP + + + Error code: 3106 + + + + + 6 + + + PUT /bulkQuotes/{ID}/error + + + + + 7 + + + 200 OK + + + + [Request is a duplicate and a resend] + + + + + 8 + + + Switch handles resend scenario + + + + + 9 + + + Use fspiop-destination header to retrieve + + + bulk quotes endpoint for Payee DFSP + + + + + alt + + + [Payee bulk quotes endpoint found] + + + + + Switch forwards bulk quote request to Payee FSP + + + + + 10 + + + POST /bulkQuotes + + + + + 11 + + + 202 OK + + + + + 12 + + + Payee FSP calculates individual quotes + + + and responds with a bulk quote result + + + + + alt + + + [Payee bulkQuotes processing successful] + + + + + Payee FSP sends bulk quote response back to Payer FSP via the Switch + + + + + 13 + + + PUT /bulkQuotes/{ID} + + + + + 14 + + + 200 OK + + + + + 15 + + + Validate bulk quote response + + + + + 16 + + + Duplicate check + + + + + alt + + + [Response is duplicate but not a resend] + + + + + 17 + + + PUT /bulkQuotes/{ID}/error + + + + + 18 + + + 200 OK + + + + + alt + + + [Response is a duplicate and a resend] + + + + + 19 + + + Switch handles resend scenario + + + + + Switch forwards quote response to Payer FSP + + + + + 20 + + + PUT /bulkQuotes/{ID} + + + + + 21 + + + 200 OK + + + + [Payee rejects bulk quote or encounters an error] + + + + + Payee FSP sends error callback to Payer FSP via the Switch + + + + + 22 + + + PUT /bulkQuotes/{ID}/error + + + + + 23 + + + 200 OK + + + + + Switch forwards error callback to Payer FSP + + + + + 24 + + + PUT /bulkQuotes/{ID}/error + + + + + 25 + + + 200 OK + + + + [Payee FSP quotes endpoint not found] + + + + + Switch sends an error callback to Payer FSP + + + Error code: 3201 + + + + + 26 + + + PUT /bulkQuotes/{ID}/error + + + + + 27 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml new file mode 100644 index 000000000..86fb8f8b6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml @@ -0,0 +1,117 @@ +@startuml +Title Request Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends request for quote \nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /quotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Quote request validation (rules engine etc.) +||| +alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + ||| + alt Request is a duplicate but not a resend + ||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + ||| + else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + ||| + Switch -\ DB: Persist quote request + activate DB + hnote over DB + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + end hnote + Switch \-- DB: Quote request saved + deactivate DB +end +||| +alt SimpleRoutingMode === TRUE + Switch -> Switch: Use fspiop-destination header to retrieve quotes endpoint for Payee FSP +else SimpleRoutingMode === FALSE + Switch -> Switch: Retireve Payee FSP endpoint using quote party information +end +||| +alt Payee quotes endpoint found + note right of Switch: Switch forwards quote request to Payee FSP + Switch -\ PayeeFSP: POST /quotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP presists and calculates quote + alt Payee quotes processing successful + note left of PayeeFSP: Payee FSP sends quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate quote response + alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects quotes or encounters and error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode === FALSE + Switch -\ DB: Store quote error + activate DB + hnote over DB + quoteError + end hnote + Switch \-- DB: Quote error saved + deactivate DB + end + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg new file mode 100644 index 000000000..6250d6e02 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + Request Quote Creation + + + + + + + + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting + + + Service] + + + + Switch + + + [Quoting + + + Service] + + + Central Store + + + + + Central Store + + + + + + Payee FSP + + + + Payee FSP + + + + + + Payer FSP sends request for quote + + + to Payee FSP via the Switch + + + + + 1 + + + POST /quotes + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Quote request validation (rules engine etc.) + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 5 + + + Duplicate check + + + + + alt + + + [Request is a duplicate but not a resend] + + + + + Switch returns error back to Payer FSP + + + Error code: 3106 + + + + + 6 + + + PUT /quotes/{ID}/error + + + + + 7 + + + 200 OK + + + + [Request is a duplicate and a resend] + + + + + 8 + + + Switch handles resend scenario + + + + + 9 + + + Persist quote request + + + + quoteDuplicateCheck + + + transactionReference + + + quote + + + quoteParty + + + quoteExtension + + + geoCode + + + + + 10 + + + Quote request saved + + + + + alt + + + [SimpleRoutingMode === TRUE] + + + + + 11 + + + Use fspiop-destination header to retrieve quotes endpoint for Payee FSP + + + + [SimpleRoutingMode === FALSE] + + + + + 12 + + + Retireve Payee FSP endpoint using quote party information + + + + + alt + + + [Payee quotes endpoint found] + + + + + Switch forwards quote request to Payee FSP + + + + + 13 + + + POST /quotes + + + + + 14 + + + 202 OK + + + + + 15 + + + Payee FSP presists and calculates quote + + + + + alt + + + [Payee quotes processing successful] + + + + + Payee FSP sends quote response back to Payer FSP via the Switch + + + + + 16 + + + PUT /quotes/{ID} + + + + + 17 + + + 200 OK + + + + + 18 + + + Validate quote response + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 19 + + + Duplicate check + + + + + alt + + + [Response is duplicate but not a resend] + + + + + 20 + + + PUT /quotes/{ID}/error + + + + + 21 + + + 200 OK + + + + + alt + + + [Response is a duplicate and a resend] + + + + + 22 + + + Switch handles resend scenario + + + + + 23 + + + Persist quote response + + + + quoteResponse + + + quoteDuplicateCheck + + + quoteResponseIlpPacket + + + geoCode + + + quoteExtension + + + + + 24 + + + Quote response saved + + + + + Switch forwards quote response to Payer FSP + + + + + 25 + + + PUT /quotes/{ID} + + + + + 26 + + + 200 OK + + + + [Payee rejects quotes or encounters and error] + + + + + Payee FSP sends error callback to Payer FSP via the Switch + + + + + 27 + + + PUT /quotes/{ID}/error + + + + + 28 + + + 200 OK + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 29 + + + Store quote error + + + + quoteError + + + + + 30 + + + Quote error saved + + + + + Switch forwards error callback to Payer FSP + + + + + 31 + + + PUT /quotes/{ID}/error + + + + + 32 + + + 200 OK + + + + [Payee FSP quotes endpoint not found] + + + + + Switch sends an error callback to Payer FSP + + + Error code: 3201 + + + + + 33 + + + PUT /quotes/{ID}/error + + + + + 34 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml new file mode 100644 index 000000000..4f3405364 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml @@ -0,0 +1,68 @@ +@startuml +Title Quoting Service Sequences +participant "Payer DFSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee DFSP" + +autonumber +note over "Payer DFSP", Switch: Payer DFSP requests quote from Payee DFSP +"Payer DFSP" -\ Switch: POST /quotes +Switch --/ "Payer DFSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee DFSP": Switch forwards quote request to Payee DFSP\n + Switch -\ "Payee DFSP": POST /quotes + "Payee DFSP" --/ Switch: 202 Accepted + "Payee DFSP" -> "Payee DFSP": Calculate Fees/Charges + + alt Payee DFSP successfully calculates quote + + note over "Payee DFSP", Switch: Payee DFSP responds to quote request + "Payee DFSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee DFSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + + Switch -> Switch: Persist Response Data + + note over Switch, "Payer DFSP": Switch forwards quote response to Payer DFSP\n + + Switch -\ "Payer DFSP": PUT /quotes/{ID} + "Payer DFSP" --/ Switch: 200 Ok + + note over "Payer DFSP" #3498db: Payer DFSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee DFSP": Switch returns error to Payee DFSP + + Switch -\ "Payee DFSP": PUT /quotes/{ID}/error + "Payee DFSP" --/ Switch : 200 Ok + + note over Switch, "Payee DFSP" #ec7063: Note that under this\nscenario the Payer DFSP\nmay not receive a response + + end + else Payee DFSP calculation fails or rejects the request + + note over "Payee DFSP", Switch: Payee DFSP returns error to Switch + + "Payee DFSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee DFSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg new file mode 100644 index 000000000..b79aecb9d --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + Quoting Service Sequences + + + + + + + + + Payer DFSP + + + + Payer DFSP + + + + Switch + + + Quoting + + + Service + + + + Switch + + + Quoting + + + Service + + + + Payee DFSP + + + + Payee DFSP + + + + + Payer DFSP requests quote from Payee DFSP + + + + + 1 + + + POST /quotes + + + + + 2 + + + 202 Accepted + + + + + 3 + + + Validate Quote Request + + + + + alt + + + [quote is valid] + + + + + 4 + + + Persist Quote Data + + + + + Switch forwards quote request to Payee DFSP + + + <Payer based Rules> + + + + + 5 + + + POST /quotes + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Calculate Fees/Charges + + + + + alt + + + [Payee DFSP successfully calculates quote] + + + + + Payee DFSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate Quote Response + + + + + alt + + + [response is ok] + + + + + 11 + + + Persist Response Data + + + + + Switch forwards quote response to Payer DFSP + + + <Payee whole request Rule> + + + + + 12 + + + PUT /quotes/{ID} + + + + + 13 + + + 200 Ok + + + + + Payer DFSP continues + + + with transfer if quote + + + is acceptable... + + + + [response invalid] + + + + + Switch returns error to Payee DFSP + + + + + 14 + + + PUT /quotes/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer DFSP + + + may not receive a response + + + + [Payee DFSP calculation fails or rejects the request] + + + + + Payee DFSP returns error to Switch + + + + + 16 + + + PUT quotes/{ID}/error + + + + + 17 + + + 200 OK + + + + + 18 + + + Persist error data + + + + + Switch returns error to Payer DFSP + + + + + 19 + + + PUT quotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [quote invalid] + + + + + Switch returns error to Payer DFSP + + + + + 21 + + + PUT quotes/{ID}/error + + + + + 22 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml new file mode 100644 index 000000000..3275abff7 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml @@ -0,0 +1,67 @@ +@startuml +Title Quoting Service Sequences +participant "Payer FSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee FSP" + +autonumber +note over "Payer FSP", Switch: Payer FSP requests quote from Payee FSP +"Payer FSP" -\ Switch: POST /quotes +Switch --/ "Payer FSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee FSP": Switch forwards quote request to Payee FSP\n + Switch -\ "Payee FSP": POST /quotes + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Calculate Fees/Charges + + alt Payee FSP successfully calculates quote + + note over "Payee FSP", Switch: Payee FSP responds to quote request + "Payee FSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee FSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + Switch -> Switch: Persist Response Data + + note over Switch, "Payer FSP": Switch forwards quote response to Payer FSP\n + + Switch -\ "Payer FSP": PUT /quotes/{ID} + "Payer FSP" --/ Switch: 200 Ok + + note over "Payer FSP" #3498db: Payer FSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee FSP": Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /quotes/{ID}/error + "Payee FSP" --/ Switch : 200 Ok + + note over Switch, "Payee FSP" #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + + end + else Payee FSP calculation fails or rejects the request + + note over "Payee FSP", Switch: Payee FSP returns error to Switch + + "Payee FSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee FSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer FSP", Switch: Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer FSP", Switch: Switch returns error to Payer FSP + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg new file mode 100644 index 000000000..69b7fb6d4 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + Quoting Service Sequences + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + Quoting + + + Service + + + + Switch + + + Quoting + + + Service + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP requests quote from Payee FSP + + + + + 1 + + + POST /quotes + + + + + 2 + + + 202 Accepted + + + + + 3 + + + Validate Quote Request + + + + + alt + + + [quote is valid] + + + + + 4 + + + Persist Quote Data + + + + + Switch forwards quote request to Payee FSP + + + <Payer based Rules> + + + + + 5 + + + POST /quotes + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Calculate Fees/Charges + + + + + alt + + + [Payee FSP successfully calculates quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate Quote Response + + + + + alt + + + [response is ok] + + + + + 11 + + + Persist Response Data + + + + + Switch forwards quote response to Payer FSP + + + <Payee whole request Rule> + + + + + 12 + + + PUT /quotes/{ID} + + + + + 13 + + + 200 Ok + + + + + Payer FSP continues + + + with transfer if quote + + + is acceptable... + + + + [response invalid] + + + + + Switch returns error to Payee FSP + + + + + 14 + + + PUT /quotes/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [Payee FSP calculation fails or rejects the request] + + + + + Payee FSP returns error to Switch + + + + + 16 + + + PUT quotes/{ID}/error + + + + + 17 + + + 200 OK + + + + + 18 + + + Persist error data + + + + + Switch returns error to Payer FSP + + + + + 19 + + + PUT quotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [quote invalid] + + + + + Switch returns error to Payer FSP + + + + + 21 + + + PUT quotes/{ID}/error + + + + + 22 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.md b/legacy/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.md new file mode 100644 index 000000000..b78339ff6 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/qs-get-bulk-quotes.md @@ -0,0 +1,7 @@ +# GET Quote By ID + +Design for the retrieval of a Bulk Quote by an FSP. + +## Sequence Diagram + +![seq-get-bulk-quotes-2.1.0.svg](./assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/quoting-service/qs-get-quotes.md b/legacy/mojaloop-technical-overview/quoting-service/qs-get-quotes.md new file mode 100644 index 000000000..765b5b4bf --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/qs-get-quotes.md @@ -0,0 +1,7 @@ +# GET Quote By ID + +Design for the retrieval of a Quote by an FSP. + +## Sequence Diagram + +![seq-get-quotes-1.1.0.svg](./assets/diagrams/sequence/seq-get-quotes-1.1.0.svg) diff --git a/legacy/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.md b/legacy/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.md new file mode 100644 index 000000000..28e692e68 --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/qs-post-bulk-quotes.md @@ -0,0 +1,7 @@ +# POST Quote + +Design for a Bulk Quote request by an FSP. + +## Sequence Diagram + +![seq-post-bulk-quotes-2.2.0.svg](./assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg) diff --git a/legacy/mojaloop-technical-overview/quoting-service/qs-post-quotes.md b/legacy/mojaloop-technical-overview/quoting-service/qs-post-quotes.md new file mode 100644 index 000000000..b8f99fedf --- /dev/null +++ b/legacy/mojaloop-technical-overview/quoting-service/qs-post-quotes.md @@ -0,0 +1,7 @@ +# POST Quote + +Design for a Quote request by an FSP. + +## Sequence Diagram + +![seq-post-quotes-1.2.0.svg](./assets/diagrams/sequence/seq-post-quotes-1.2.0.svg) diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/README.md b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/README.md similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/README.md rename to legacy/mojaloop-technical-overview/sdk-scheme-adapter/README.md diff --git a/mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md similarity index 100% rename from mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md rename to legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/README.md diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md new file mode 100644 index 000000000..5accc7ec1 --- /dev/null +++ b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md @@ -0,0 +1,206 @@ +# SDK Scheme Adapter and Local K8S cluster testing + +A detailed documentation for dfsps who want to test the mojaloop cluster deployment with scheme adapter and a mock backend service. + +![Overview](scheme-adapter-and-local-k8s-overview.png) + +## Prerequisite + +* A working mojaloop k8s cluster (Local / Cloud deployment) +* DFSP mock backend service +* sdk-scheme-adapter > 8.6.0 + +## Configuration & Starting services + +### Mojaloop Local K8S cluster deployment +Please follow the below link to deploy your own cluster on local system. +https://mojaloop.io/documentation/deployment-guide/ + +A Linux based operating system is recommended and at least 16GB RAM and 4 core processor is required. + +After installation please complete the `OSS-New-Deployment-FSP-Setup.postman_collection` collection available at https://github.com/mojaloop/postman + +Then make sure the oracles & endpoints are configured correctly and that the "Golden Path Collection" can be run successfully. + +### DFSP Mock Backend service & SDK Scheme adapter +The SDK scheme adapter version should be greater than 8.6.0 +The next step starts the scheme adapter from docker-compose file automatically. + +Please download the following repository +https://github.com/mojaloop/sdk-mock-dfsp-backend + +Edit the docker-compose.yml file and verify the following lines. + +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 +``` + +Edit the backend.env file and change the OUTBOUND_ENDPOINT value +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Edit scheme-adapter.env and change the following lines +Please replace the endpoint values with the appropriate hostnames provided in /etc/hosts file. + +``` +DFSP_ID=safsp +CACHE_HOST=redis2 +ALS_ENDPOINT=account-lookup-service.local +QUOTES_ENDPOINT=quoting-service.local +TRANSFERS_ENDPOINT=ml-api-adapter.local +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true +``` + +### Name resolution configuration - Mac ONLY + +Point the following hostnames to your local machine IP by adding the below line in /etc/hosts file +``` +192.168.5.101 ml-api-adapter.local account-lookup-service.local central-ledger.local central-settlement.local account-lookup-service-admin.local quoting-service.local moja-simulator.local central-ledger central-settlement ml-api-adapter account-lookup-service account-lookup-service-admin quoting-service simulator host.docker.internal moja-account-lookup-mysql +``` + +Make sure to change 192.168.5.101 to your real external IP. + +### Name resolution configuration - Linux ONLY + +Add extra_hosts configuration to scheme-adapter2 config in the docker-compose.yml file, so that the scheme-adapter2 container can resolve dns of account-lookup-service.local, quoting-service.local and ml-api-adapter.local. For example the config could be: + +``` + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 + extra_hosts: + - "account-lookup-service.local:172.17.0.1" + - "quoting-service.local:172.17.0.1" + - "ml-api-adapter.local:172.17.0.1" +``` + +The 172.17.0.1 is a default docker0 network interface on linux, however please make sure it's valid in your configuration and change it if needed. + +### Start + +Start the backend and scheme adapter using the following command. +``` +cd src +docker-compose up -d +``` + +## Testing + +### Configure new FSP +Download the following files: +* [Mojaloop-Local.postman_environment_modified.json](assets/postman_files/Mojaloop-Local.postman_environment_modified.json) - modified environment variables that point to your local setup +* [OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json](assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json) - steps that will setup new FSP + +The SCHEME_ADAPTER_ENDPOINT in the environment file should point to your local scheme-adapter deployment. For mac this is configured already to be http://host.docker.internal:4000. If you're running on Linux, please edit the environment file, so that SCHEME_ADAPTER_ENDPOINT points to your docker0 interface (usually 172.17.0.1 - see remarks in previous step). + +In postman, select the environment file and run the custom collection in the postman to provision a new FSP called "safsp". The endpoints for safsp will be set to the URL of the scheme adapter which is configured in environment file. + +### Add the target MSISDN to payee simulator which is running inside the K8S. Run the following commands +``` +curl -X POST \ + http://moja-simulator.local/payeefsp/parties/MSISDN/27713803912 \ + -H 'Accept: */*' \ + -H 'Accept-Encoding: gzip, deflate' \ + -H 'Cache-Control: no-cache' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 406' \ + -H 'Content-Type: application/json' \ + -H 'Host: moja-simulator.local' \ + -H 'User-Agent: PostmanRuntime/7.20.1' \ + -H 'cache-control: no-cache' \ + -d '{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "27713803912", + "fspId": "payeefsp" + }, + "name": "Siabelo Maroka", + "personalInfo": { + "complexName": { + "firstName": "Siabelo", + "lastName": "Maroka" + }, + "dateOfBirth": "1974-01-01" + } + } +}' + +curl -X POST \ + http://account-lookup-service.local/participants/MSISDN/27713803912 \ + -H 'Accept: application/vnd.interoperability.participants+json;version=1' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 50' \ + -H 'Content-Type: application/vnd.interoperability.participants+json;version=1.0' \ + -H 'Date: Fri, 21 Dec 2018 12:17:01 GMT' \ + -H 'FSPIOP-Source: payeefsp' \ + -H 'Host: account-lookup-service.local' \ + -H 'User-Agent: PostmanRuntime/7.11.0' \ + -H 'accept-encoding: gzip, deflate' \ + -H 'cache-control: no-cache,no-cache' \ + -d '{ + "fspId": "payeefsp", + "currency": "USD" +}' +``` + +### Try to send money +Try to send funds from "safsp" (Mock DFSP) to a MSISDN which is in "payeedfsp" (Simulator in K8S) through scheme adapter. +Run the following curl command to issue command to Mock DFSP service. +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "27713803912" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" +}' +``` + +You should get a response with COMPLETED currentState. diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json new file mode 100644 index 000000000..eddcac266 --- /dev/null +++ b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json @@ -0,0 +1,1012 @@ +{ + "id": "a9937c8b-0281-4128-8b53-1f1f913ff2aa", + "name": "Mojaloop-Local", + "values": [ + { + "key": "payeefsp", + "value": "payeefsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfsp", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiration", + "value": "2019-05-27T15:44:53.292Z", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transactionRequestId", + "value": "25a00155-c777-4629-a6b7-61cf0d16f499", + "enabled": true + }, + { + "key": "transferDate", + "value": "Fri, 21 Dec 2018 12:17:01 GMT", + "enabled": true + }, + { + "key": "currentTimestamp", + "value": "2018-12-06T17:09:56.386Z", + "enabled": true + }, + { + "key": "quoteDate", + "value": "Fri, 21 Dec 2018 12:19:49 GMT", + "enabled": true + }, + { + "key": "quoteExpiration", + "value": "2018-11-08T21:31:00.534+01:00", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_MOJALOOP", + "value": "localhost:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_MOJALOOP", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_LEDGER", + "value": "http://central-ledger.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_ADMIN", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ML_API", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_ML_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_SETTLEMENT", + "value": "http://central-settlement.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_SETTLEMENT", + "value": "/v1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_PREPARE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_QUOTE\n", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TIMESTAMP", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_PREPARE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSACTION_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiredExpiration", + "value": "2018-08-31T15:26:01.870Z", + "enabled": true + }, + { + "key": "condition", + "value": "HOr22-H3AfTDHrSkPjJtVPRdKouuMkDXTR4ejlQa8Ks", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "fulfilment", + "value": "uU0nuZNNPgilLlLX2n2r-sSE7-N6U4DukIj3rOLvzek", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR", + "value": "http://moja-simulator.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "SCHEME_ADAPTER_ENDPOINT", + "value": "http://host.docker.internal:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "quoteId", + "value": "ddaa67b3-5bf8-45c1-bfcf-1e8781177c37", + "enabled": true + }, + { + "key": "ilpPacket", + "value": "AQAAAAAAAADIEHByaXZhdGUucGF5ZWVmc3CCAiB7InRyYW5zYWN0aW9uSWQiOiIyZGY3NzRlMi1mMWRiLTRmZjctYTQ5NS0yZGRkMzdhZjdjMmMiLCJxdW90ZUlkIjoiMDNhNjA1NTAtNmYyZi00NTU2LThlMDQtMDcwM2UzOWI4N2ZmIiwicGF5ZWUiOnsicGFydHlJZEluZm8iOnsicGFydHlJZFR5cGUiOiJNU0lTRE4iLCJwYXJ0eUlkZW50aWZpZXIiOiIyNzcxMzgwMzkxMyIsImZzcElkIjoicGF5ZWVmc3AifSwicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7fX19LCJwYXllciI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjI3NzEzODAzOTExIiwiZnNwSWQiOiJwYXllcmZzcCJ9LCJwZXJzb25hbEluZm8iOnsiY29tcGxleE5hbWUiOnt9fX0sImFtb3VudCI6eyJjdXJyZW5jeSI6IlVTRCIsImFtb3VudCI6IjIwMCJ9LCJ0cmFuc2FjdGlvblR5cGUiOnsic2NlbmFyaW8iOiJERVBPU0lUIiwic3ViU2NlbmFyaW8iOiJERVBPU0lUIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJpbml0aWF0b3JUeXBlIjoiQ09OU1VNRVIiLCJyZWZ1bmRJbmZvIjp7fX19", + "enabled": true + }, + { + "key": "payerFspId", + "value": "3", + "enabled": true + }, + { + "key": "payerFspAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspId", + "value": "4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspAccountId", + "value": "5", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "openWindowID", + "value": 1, + "enabled": true + }, + { + "key": "newOpenWindowID", + "value": 2, + "enabled": true + }, + { + "key": "closedWindowID", + "value": 1, + "enabled": true + }, + { + "key": "settlementId", + "value": 1, + "enabled": true + }, + { + "key": "expectedFullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "expectedFirstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "expectedLastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "expectedDOB", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "pathfinderMSISDN", + "value": "27713803912", + "enabled": true + }, + { + "key": "fullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "firstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "lastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "dob", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "HOST_ML_API_ADAPTER", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "dateHeader", + "value": "Thu, 24 Jan 2019 10:22:12 GMT", + "enabled": true + }, + { + "key": "participant", + "value": "testfsp4", + "enabled": true + }, + { + "key": "payerfspBeforePosition", + "value": -1782, + "enabled": true + }, + { + "key": "HOST_SWITCH_TRANSFERS", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_PATH_SWITCH_TRANSFERS", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR_K8S_CLUSTER", + "value": "http://moja-simulator", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payeefspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "blockTransferAmount", + "value": 7494, + "enabled": true + }, + { + "key": "payeeNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "transferAmount", + "value": "99", + "enabled": true + }, + { + "key": "payeefspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransferBeforeExpiry", + "value": 1596, + "enabled": true + }, + { + "key": "fspName", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "settlementAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "reportEndDate", + "value": "2018-10-31", + "enabled": true + }, + { + "key": "reportFSPID", + "value": "payerfsp", + "enabled": true + }, + { + "key": "reportStartDate", + "value": "2018-10-01", + "enabled": true + }, + { + "key": "transactionId", + "value": "97f3f215-37a0-4755-a17c-c39313aa2f98", + "enabled": true + }, + { + "key": "payerfspSettlementAccountId", + "value": 8, + "enabled": true + }, + { + "key": "payeefspSettlementAccountId", + "value": 4, + "enabled": true + }, + { + "key": "fundsInPrepareTransferId", + "value": "b79a979e-9605-4db4-a052-85bc948be414", + "enabled": true + }, + { + "key": "HUBOPERATOR_BEARER_TOKEN", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hub_operator", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefspNetSettlementAmount", + "value": -198, + "enabled": true + }, + { + "key": "payerfspNetSettlementAmount", + "value": 198, + "enabled": true + }, + { + "key": "fundsInPrepareAmount", + "value": 500, + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalance", + "value": -4800, + "enabled": true + }, + { + "key": "hubReconAccountBalance", + "value": 4800, + "enabled": true + }, + { + "key": "payerfspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "payeefspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "fundsOutPrepareTransferId", + "value": "f60c555f-72a7-44c7-a3a8-1f4a4df4b100", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareAmount", + "value": "", + "enabled": true + }, + { + "key": "payerfspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionAccountId", + "value": 3, + "enabled": true + }, + { + "key": "payerfspPositionAccountId", + "value": 7, + "enabled": true + }, + { + "key": "testfsp1", + "value": "testfsp1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2", + "value": "testfsp2", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountId", + "value": 25, + "enabled": true + }, + { + "key": "testfsp1SettlementAccountId", + "value": 26, + "enabled": true + }, + { + "key": "testfsp2PositionAccountId", + "value": 29, + "enabled": true + }, + { + "key": "testfsp2SettlementAccountId", + "value": 30, + "enabled": true + }, + { + "key": "testfsp1Id", + "value": "13", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2Id", + "value": "14", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitTransferId", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "transfer_ID", + "value": "e7b43799-e69e-4578-bd26-2a4b9a22e92e", + "enabled": true + }, + { + "key": "get_transfer_ID", + "value": "7e19ae5f-7db6-4612-ab99-7538a56b4c25", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "env_prefix", + "value": "test", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "validCondition", + "value": "GRzLaTP7DJ9t4P-a_BA0WA9wzzlsugf00-Tn6kESAfM", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "validFulfillment", + "value": "UNlJ98hZTY_dsw0cAqw4i_UN3v4utt7CZFB4yfLbVFA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "currency", + "value": "USD", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfspId3", + "value": "15", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfspId4", + "value": "16", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "invalidFulfillment", + "value": "_3cco-YN5OGpRKVWV3n6x6uNpBTH9tYUdOYmHA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "completedTimestamp", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionAfterPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveTransferId", + "value": "", + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "fspiop-signature", + "value": "{\"signature\":\"iU4GBXSfY8twZMj1zXX1CTe3LDO8Zvgui53icrriBxCUF_wltQmnjgWLWI4ZUEueVeOeTbDPBZazpBWYvBYpl5WJSUoXi14nVlangcsmu2vYkQUPmHtjOW-yb2ng6_aPfwd7oHLWrWzcsjTF-S4dW7GZRPHEbY_qCOhEwmmMOnE1FWF1OLvP0dM0r4y7FlnrZNhmuVIFhk_pMbEC44rtQmMFv4pm4EVGqmIm3eyXz0GkX8q_O1kGBoyIeV_P6RRcZ0nL6YUVMhPFSLJo6CIhL2zPm54Qdl2nVzDFWn_shVyV0Cl5vpcMJxJ--O_Zcbmpv6lxqDdygTC782Ob3CNMvg\\\",\\\"protectedHeader\\\":\\\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1VUkkiOiIvdHJhbnNmZXJzIiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUE9TVCIsIkZTUElPUC1Tb3VyY2UiOiJPTUwiLCJGU1BJT1AtRGVzdGluYXRpb24iOiJNVE5Nb2JpbGVNb25leSIsIkRhdGUiOiIifQ\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3", + "value": "testfsp3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4", + "value": "testfsp4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payeefsp_fspiop_signature", + "value": "{\"signature\":\"abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess\",\"protectedHeader\":\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1Tb3VyY2UiOiJwYXllZWZzcCIsIkZTUElPUC1EZXN0aW5hdGlvbiI6InBheWVyZnNwIiwiRlNQSU9QLVVSSSI6Ii90cmFuc2ZlcnMvZDY3MGI1OTAtZjc5ZC00YWU5LThjNmUtMTVjZjZjNWMzODk5IiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUFVUIiwiRGF0ZSI6IiJ9\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_SERVICE", + "value": "http://account-lookup-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_ADMIN", + "value": "http://account-lookup-service-admin.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_QUOTING_SERVICE", + "value": "http://quoting-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefsp_signature", + "value": "abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess", + "type": "text", + "description": "", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2019-05-30T00:29:41.827Z", + "_postman_exported_using": "Postman/6.7.4" +} diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json new file mode 100644 index 000000000..70e2b3599 --- /dev/null +++ b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json @@ -0,0 +1,1072 @@ +{ + "info": { + "_postman_id": "52f405c0-bec3-4915-8c43-c250208623aa", + "name": "OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup", + "description": "Author: Sridevi Miriyala\nPurpose: Used to add new FSP and relevant Callback Information", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "FSP Onboarding", + "item": [ + { + "name": "safsp (p2p transfers)", + "item": [ + { + "name": "Add payerfsp - TRANSFERS", + "event": [ + { + "listen": "test", + "script": { + "id": "76c222f4-969b-4081-b4d7-133ebe48f50f", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\": \"safsp\",\"currency\": \"{{currency}}\"}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants" + ] + } + }, + "response": [] + }, + { + "name": "Add initial position and limits - payerfsp", + "event": [ + { + "listen": "test", + "script": { + "id": "d767079d-a9dd-401a-8d6a-5f94654c4259", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"currency\": \"{{currency}}\",\n\t\"limit\": {\n\t \"type\": \"NET_DEBIT_CAP\",\n\t \"value\": 1000000\n\t},\n\t\"initialPosition\": 0\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/initialPositionAndLimits", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "initialPositionAndLimits" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES GET", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_GET\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - QUOTES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_QUOTES\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER POST", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_POST\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER ERROR", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "9. Set Endpoint-NET_DEBIT_CAP_ADJUSTMENT_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "83984619-0430-4a4c-87ec-671bf97894de", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_ADJUSTMENT_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Set Endpoint-SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "16f8d261-3f2d-470b-986b-c8e23602605b", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "DFSP Endpoint-NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "67082524-b658-4f1c-90c4-af6fc24adb3e", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Record Funds In - payerfsp ", + "event": [ + { + "listen": "test", + "script": { + "id": "802139ed-ec95-40f8-99a7-d88f0e77e49d", + "exec": [ + "pm.test(\"Status code is 202\", function () {", + " pm.response.to.have.status(202);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "461d34bc-33f6-4031-bbc4-b26489ff1953", + "exec": [ + "var uuid = require('uuid');", + "var generatedUUID = uuid.v4();", + "pm.environment.set('fundsInPrepareTransferId', generatedUUID);", + "pm.environment.set('fundsInPrepareAmount', 5000);", + "", + "", + "const payerfspGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/'+pm.environment.get(\"payerfsp\")+'/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"hub_operator\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(payerfspGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'SETTLEMENT') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"payerfspSettlementAccountId\",jsonData[i].id)", + " pm.environment.set(\"payerfspSettlementAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "", + "const hubGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/hub/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"payerfsp\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(hubGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'HUB_RECONCILIATION') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"hubReconAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{payerfsp}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"transferId\": \"{{fundsInPrepareTransferId}}\",\n \"externalReference\": \"string\",\n \"action\": \"recordFundsIn\",\n \"reason\": \"string\",\n \"amount\": {\n \"amount\":\"{{fundsInPrepareAmount}}\" ,\n \"currency\": \"{{currency}}\"\n },\n \"extensionList\": {\n \"extension\": [\n {\n \"key\": \"string\",\n \"value\": \"string\"\n }\n ]\n }\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/accounts/{{payerfspSettlementAccountId}}", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "accounts", + "{{payerfspSettlementAccountId}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "e5ffaeb6-241f-4b10-af63-b52b064ff44f", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "efb91eb5-c6c5-460c-89b0-a424f39dcf9a", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "a29d64a2-7a89-4cc9-ac33-2a630283471d", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "7bcf1b8c-ce85-4b11-ac83-899cc81ce501", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "402cb439-04ee-4add-9a65-f4b3f9dafa58", + "type": "text/javascript", + "exec": [ + "", + "// Ensure that the following variables are not set in the environment", + "// This is a fix for the following issue: https://github.com/mojaloop/project/issues/903", + "// This will ensure that templates are not replaced in the endpoint configs:", + "pm.environment.unset('partyIdType')", + "pm.environment.unset('partyIdentifier')", + "pm.environment.unset('requestId')", + "pm.environment.unset('transferId')", + "", + "pm.globals.unset('partyIdType')", + "pm.globals.unset('partyIdentifier')", + "pm.globals.unset('requestId')", + "pm.globals.unset('transferId')" + ] + } + }, + { + "listen": "test", + "script": { + "id": "e73fb24a-c94a-4551-ac31-fb7ceb250579", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png new file mode 100644 index 000000000..4d6282c3c Binary files /dev/null and b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png differ diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md new file mode 100644 index 000000000..f780e85bc --- /dev/null +++ b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md @@ -0,0 +1,221 @@ +# SDK Scheme Adapter and WSO2 API Gateway + +This documentaion is for testing scheme adapter against a public hosted WSO2 API gateway with SSL encryption and bearer token authentication. + + +![Overview](scheme-adapter-and-wso2-api-gateway-overview.png) + +## Prerequisite + +* Accesss to WSO2 API production api with a generated token. +* sdk-scheme-adapter +* mojaloop-simulator + +## Generate access token and URL from WSO2 API + +* Login to your WSO2 store and go to applications in the menu. Create a new application and access keys if you don't have those already. +* Then go to APIs menu, you should find the following applications. Subscribe to these two APIs by selecting your application and tier from the each API main page. + * Central Ledger Admin API - We will use this endpoint for creating a new fsp and configure endpoints for that fsp. (Please contact your infra team for the proper https endpoints, they need to provision them on the hub) + * FSPIOP API - This is the main API for account lookup, quotes & transfers +* You can try some api requests in "API Console" tab by selecting the generated access token. +* Please make a note of the API URLs for both APIs and access token. + + +## Infrastructure Stuff +The following are the things your infrastructure team should take care off. +Please contact your infra team for further details. +* For getting back the responses, we need a machine with static public IP. And a domain name should be pointed to that IP. +* Generate client and server SSL certificates using MCM portal and keychain tool. This step is to establish secure communication using mutual SSL. +* Provision the endpoints pointing to your https address in WSO2 / HA Proxy. +* Establish JWS authentication +* **AWS Deployment** + * Launch an EC2 instance in AWS console + * Create an EC2 instance in AWS console and select **t2.micro** instance type. + * Select **Ubuntu 18.04** as your operating system. + * After your instance is ready, you can connect to it using ssh and the downloaded key file from AWS EC2 dashboard. + * Install docker and docker-compose in that EC2 instance + + * Open 4000 TCP port in security groups and assign elastic IP + * Add the inbound rule in security group of this EC2 instance that will expose the TCP 4000 port to public + * Use Elastic IP service to assign a static IP for this instance + + * Setup domain name for this instance + * You can use route53 in aws or any other DNS service to point a DNS name to this IP address + * This step is required because the Let's Encrypt certificate authority will not issue certificates for a bare IP address. + + +## Setting up Scheme Adapter with Mojaloop Simulator + +Please download the Mojaloop Simulator repo +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Replace the certificates and keys in src/secrets folder with the generated certificates in the previous step. + +* Edit the file src/docker-compose.yml and change the required parameters. Please refer the following file. + + ``` + version: '3' + services: + redis: + image: "redis:5.0.4-alpine" + container_name: redis + backend: + image: "mojaloop/mojaloop-simulator-backend" + env_file: ./sim-backend.env + container_name: ml_simulator + ports: + - "3000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + volumes: + - ./secrets:/src/secrets + ports: + - "3500:3000" + - "4000:4000" + depends_on: + - redis + ``` + +* Edit the file src/sim-backend.env file and change the container name of the scheme adapter in that. Please refer the following lines. + + ``` + OUTBOUND_ENDPOINT=http://src_scheme-adapter_1:4001 + DFSP_ID=extpayerfsp + ``` + +* Edit the file src/scheme-adapter.env and change the following settings + ``` + MUTUAL_TLS_ENABLED=true + CACHE_HOST=redis + DFSP_ID=extpayerfsp + BACKEND_ENDPOINT=ml_simulator:3000 + PEER_ENDPOINT= + AUTO_ACCEPT_QUOTES=true + ``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +We can now access the mojaloop simulator's test api on 3003. + +## Provision a new DFSP "extpayerfsp" with proper endpoints + +We should create a new fsp named "extpayerfp" or with any other name. + +The FSP onboarding section in "OSS-New-Deployment-FSP-Setup" postman collection can be used for this. You can get the postman repo from https://github.com/mojaloop/postman. +* Duplicate the "Mojaloop-Local" environment and change the following valuesin that + * payerfsp - extpayerfsp + * HOST_ML_API_ADAPTER, HOST_ML_API, HOST_SWITCH_TRANSFERS, HOST_ACCOUNT_LOOKUP_SERVICE, HOST_QUOTING_SERVICE - Your WSO2 FSPIOP API endpoint + * HOST_CENTRAL_LEDGER - Your WSO2 Central Services Admin API endpoint + * HOST_CENTRAL_SETTLEMENT - Your WSO2 Central Settlement API endpoint (optional for our testing) + * HOST_SIMULATOR & HOST_SIMULATOR_K8S_CLUSTER - https://:4000 +* Change the URLs in payerfsp onboarding in "FSP Onboarding" section of "OSS-New-Deployment-FSP-Setup" from "payerfsp" to "extpayerfsp" +* Change the authentication as "Bearer Token" and provide the access token we created in WSO2 store for the entire "Payer FSP Onboarding" folder. +* Change the endpoint URLs to the https endpoints provided by your infra team. +* Then run the "Payer FSP Onboarding" folder in that collection with the newly created environment. + +You should get 100% pass then we can confirm that the fsp is created and endpoints are set for the fsp. + +## Provision payeefsp and register a participant against MSISDN simulator + +Generally the simulator running in the switch contains payeefsp and you should register a new participant (phone number) of your choice. + +You can refer the postman request "p2p_happy_path SEND QUOTE / Register Participant {{pathfinderMSISDN}} against MSISDN Simulator for PayeeFSP" in "Golden_Path" collection to achieve this. + +The postman request will send a POST request to /participants/MSISDN/ with the following body and required http headers. +``` +{ + "fspId": "payeefsp", + "currency": "USD" +} +``` + +## Send money + +### In one step +If you want to send the money in one step, the configuration options "AUTO_ACCEPT_QUOTES" & "AUTO_ACCEPT_PARTY" in "scheme_adapter.env" should be enabled. + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "919848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + } +]' + +``` + +### In two steps + +The following command is used to send the money in two steps (i.e Requesting the quote first, accept after review the charges and party details) + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + }, + { + "name": "scenario2", + "operation": "putTransfers", + "params": { + "transferId": "{{scenario1.result.transferId}}" + }, + "body": { + "acceptQuote": true + } + } +]' + +``` \ No newline at end of file diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png new file mode 100644 index 000000000..206d31d45 Binary files /dev/null and b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png differ diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md new file mode 100644 index 000000000..b34595858 --- /dev/null +++ b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md @@ -0,0 +1,180 @@ +# Scheme Adapter to Scheme Adapter testing + +A detailed documentation for dfsps who want to test the transfer of funds from a scheme adapter to another scheme adapter directly using mock backend and mojaloop simulator services. + +![Overview](scheme-adapter-to-scheme-adapter-overview.png) + +## Prerequisite + +* Mojaloop Simulator +* DFSP mock backend service +* Scheme adapter is already included in both the above docker-compose scripts + +## Configuration & Starting services + +The idea is to run two docker-compose scripts in parallel from the above two services. To avoid conflicts we need to edit the docker-compose.yml files and specify the container names. + +### Mojaloop Simulator service + +Please download the Mojaloop Simulator repo +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Edit the file src/docker-compose.yml and add the container names for all the containers. Please refer the following lines + +``` +version: '3' +services: + redis1: + image: "redis:5.0.4-alpine" + container_name: redis1 + sim: + image: "mojaloop-simulator-backend" + build: ../ + env_file: ./sim-backend.env + container_name: ml_sim1 + ports: + - "13000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim1 + ports: + - "13500:3000" + - "14000:4000" + depends_on: + - redis1 +``` + +* Edit the file src/sim-backend.env file and change the container name of the scheme adapter in that. Please refer the following lines. + +``` +OUTBOUND_ENDPOINT=http://sa_sim1:4001 +``` + +* Edit the file src/scheme-adapter.env file and change the container names of the another scheme adapter and mojaloop simulator. Please refer the following lines + +``` +DFSP_ID=payeefsp +CACHE_HOST=redis1 +PEER_ENDPOINT=sa_sim2:4000 +BACKEND_ENDPOINT=ml_sim1:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +We can now access the mojaloop simulator's test api on 3003. + +A new party should be added to the simulator using the following command. Feel free to change the details you want. +``` +curl -X POST "http://localhost:3003/repository/parties" -H "accept: */*" -H "Content-Type: application/json" -d "{\"displayName\":\"Test Payee1\",\"firstName\":\"Test\",\"middleName\":\"\",\"lastName\":\"Payee1\",\"dateOfBirth\":\"1970-01-01\",\"idType\":\"MSISDN\",\"idValue\":\"9876543210\"}" +``` + +Then try to run the following command to check the new party added. +``` +curl -X GET "http://localhost:3003/repository/parties" -H "accept: */*" +``` + +Let's move on to setup another instance of scheme adapter with DFSP mock backend. + +### DFSP Mock Backend service + +The DFSP mock backend is a minimal implementation of an example DFSP. Only basic functions are supported at the moment. + +Please download the following repository +``` +git clone https://github.com/mojaloop/sdk-mock-dfsp-backend.git +``` + +Edit the files src/docker-compose.yml, src/backend.env and src/scheme-adapter.env and add the container names for all the containers. Please refer the following files. +docker-compose.yml +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + depends_on: + - redis2 +``` +scheme-adapter.env +``` +DFSP_ID=payerfsp +CACHE_HOST=redis2 +PEER_ENDPOINT=sa_sim1:4000 +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +backend.env +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +## Try to send money +Try to send funds from "payerfsp" (Mock DFSP) to a MSISDN which is in "payeefsp" (Mojaloop Simulator) through scheme adapter. +Run the following curl command to issue command to Mock DFSP service. +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9876543210" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "test payment", + "homeTransactionId": "123ABC" +}' +``` + +You should get a response with COMPLETED currentState. diff --git a/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png new file mode 100644 index 000000000..35702294c Binary files /dev/null and b/legacy/mojaloop-technical-overview/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png differ diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/README.md b/legacy/mojaloop-technical-overview/transaction-requests-service/README.md new file mode 100644 index 000000000..b339478a9 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/README.md @@ -0,0 +1,8 @@ +# Transaction Requests Service + +## Sequence Diagram + +![trx-service-overview-spec.svg](./assets/diagrams/sequence/trx-service-overview-spec.svg) + +* The transaction-requests-service is a mojaloop core service that enables Payee initiated use cases such as "Merchant Request to Pay". +* This is a pass through service which also includes Authorizations. diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml new file mode 100644 index 000000000..0d4005e68 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml @@ -0,0 +1,64 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Authorizations +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" --\ "Payee FSP": Lookup, Transaction request,\nprocessing not shown here +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payer FSP" --> "Payer FSP": Do quote, generate OTP\nnotify user (not shown here) +"Payer FSP" -\ Switch: GET /authorizations/{TransactionRequestID} +Switch --/ "Payer FSP": 202 Accepted + +alt authorization request is valid + + Switch -> Switch: Validate GET /authorizations/{TransactionRequestID} (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + note over Switch, "Payee FSP": Switch forwards GET /authorizations request to Payee FSP + Switch -\ "Payee FSP": GET /authorizations/{TransactionRequestID} + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Process authorization request\n(Payer approves/rejects transaction\nusing OTP) + + note over Switch, "Payee FSP": Payee FSP responds with PUT /authorizations//{TransactionRequestID} + "Payee FSP" -\ Switch: PUT /authorizations//{TransactionRequestID} + Switch --/ "Payee FSP": 200 Ok + + note over "Payer FSP", Switch: Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + Switch -\ "Payer FSP": PUT /authorizations//{TransactionRequestID} + "Payer FSP" --/ Switch: 200 Ok + + +else authorization request is invalid + note over "Payer FSP", Switch: Switch returns error callback to Payer FSP + Switch -\ "Payer FSP": PUT /authorizations/{TransactionRequestID}/error + "Payer FSP" --/ Switch: 200 OK + "Payer FSP" --> "Payer FSP": Validate OTP sent by Payee FSP +end +@enduml diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg new file mode 100644 index 000000000..20f251063 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + Transaction Requests Service - Authorizations + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + 1 + + + Lookup, Transaction request, + + + processing not shown here + + + + + Payee FSP generates a transaction-request to the Payer FSP + + + + + 2 + + + Do quote, generate OTP + + + notify user (not shown here) + + + + + 3 + + + GET /authorizations/{TransactionRequestID} + + + + + 4 + + + 202 Accepted + + + + + alt + + + [authorization request is valid] + + + + + 5 + + + Validate GET /authorizations/{TransactionRequestID} (internal validation) + + + + + 6 + + + Retrieve corresponding end-points for Payee FSP + + + + + Switch forwards GET /authorizations request to Payee FSP + + + + + 7 + + + GET /authorizations/{TransactionRequestID} + + + + + 8 + + + 202 Accepted + + + + + 9 + + + Process authorization request + + + (Payer approves/rejects transaction + + + using OTP) + + + + + Payee FSP responds with PUT /authorizations//{TransactionRequestID} + + + + + 10 + + + PUT /authorizations//{TransactionRequestID} + + + + + 11 + + + 200 Ok + + + + + Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + + + + + 12 + + + Retrieve corresponding end-points for Payer FSP + + + + + 13 + + + PUT /authorizations//{TransactionRequestID} + + + + + 14 + + + 200 Ok + + + + [authorization request is invalid] + + + + + Switch returns error callback to Payer FSP + + + + + 15 + + + PUT /authorizations/{TransactionRequestID}/error + + + + + 16 + + + 200 OK + + + + + 17 + + + Validate OTP sent by Payee FSP + + diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml new file mode 100644 index 000000000..655cf6e07 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml @@ -0,0 +1,93 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Create +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" -\ "Payee FSP": Lookup process\n(not shown here) +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payee FSP" -\ Switch: POST /transactionRequests +Switch -> Switch: Validate POST /transactionRequests schema +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request is valid + + Switch -> Switch: Validate POST /transactionRequests (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards POST /transactionRequests request to Payer FSP + Switch -\ "Payer FSP": POST /transactionRequests + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Process transaction-request + + alt Payer FSP successfully processes transaction-request + + note over "Payer FSP", Switch: Payer FSP responds to POST /transactionRequests + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + note over "Payee FSP" #3498db: Wait for a quote, transfer by Payer FSP\nor a rejected transaction-request + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP calculation fails or rejects the request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg new file mode 100644 index 000000000..b5a1c7313 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + Transaction Requests Service - Create + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + 1 + + + Lookup process + + + (not shown here) + + + + + Payee FSP generates a transaction-request to the Payer FSP + + + + + 2 + + + POST /transactionRequests + + + + + 3 + + + Validate POST /transactionRequests schema + + + + + 4 + + + 202 Accepted + + + + + alt + + + [transaction-request is valid] + + + + + 5 + + + Validate POST /transactionRequests (internal validation) + + + + + 6 + + + Retrieve corresponding end-points for Payer FSP + + + + + Switch forwards POST /transactionRequests request to Payer FSP + + + + + 7 + + + POST /transactionRequests + + + + + 8 + + + 202 Accepted + + + + + 9 + + + Process transaction-request + + + + + alt + + + [Payer FSP successfully processes transaction-request] + + + + + Payer FSP responds to POST /transactionRequests + + + + + 10 + + + PUT /transactionRequests/{ID} + + + + + 11 + + + 200 Ok + + + + + 12 + + + Validate PUT /transactionRequests/{ID} + + + + + alt + + + [response is ok] + + + + + Switch forwards transaction-request response to Payee FSP + + + + + 13 + + + Retrieve corresponding end-points for Payee FSP + + + + + 14 + + + PUT /transactionRequests/{ID} + + + + + 15 + + + 200 Ok + + + + + Wait for a quote, transfer by Payer FSP + + + or a rejected transaction-request + + + + [response invalid] + + + + + Switch returns error to Payer FSP + + + + + 16 + + + PUT /transactionRequests/{ID}/error + + + + + 17 + + + 200 Ok + + + + + Note that under this + + + scenario the Payee FSP + + + may not receive a response + + + + [Payer FSP calculation fails or rejects the request] + + + + + Payer FSP returns error to Switch + + + + + 18 + + + PUT /transactionRequests/{ID}/error + + + + + 19 + + + 200 OK + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /transactionRequests/{ID}/error + + + + + 21 + + + 200 OK + + + + [transaction-request is invalid] + + + + + Switch returns error to Payee FSP + + + + + 22 + + + PUT /transactionRequests/{ID}/error + + + + + 23 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml new file mode 100644 index 000000000..17262a24a --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml @@ -0,0 +1,90 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Query +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +note over "Payee FSP", Switch: Payee FSP requests the status of a transaction-request at the Payer FSP.\nID here is the ID of prevoiusly created transaction-request +"Payee FSP" -\ Switch: GET /transactionRequests/{ID} +Switch -> Switch: Validate GET /transactionRequests/{ID} +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request query is valid + + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards GET /transactionRequests/{ID} request to Payer FSP + Switch -\ "Payer FSP": GET /transactionRequests/{ID} + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Retrieve transaction-request + + alt Payer FSP successfully retrieves transaction-request + + note over "Payer FSP", Switch: Payer FSP responds with the\nPUT /transactionRequests/{ID} callback + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP is unable to retrieve the transaction-request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg new file mode 100644 index 000000000..bbc20538b --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + Transaction Requests Service - Query + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + Payee FSP requests the status of a transaction-request at the Payer FSP. + + + ID here is the ID of prevoiusly created transaction-request + + + + + 1 + + + GET /transactionRequests/{ID} + + + + + 2 + + + Validate GET /transactionRequests/{ID} + + + + + 3 + + + 202 Accepted + + + + + alt + + + [transaction-request query is valid] + + + + + 4 + + + Retrieve corresponding end-points for Payer FSP + + + + + Switch forwards GET /transactionRequests/{ID} request to Payer FSP + + + + + 5 + + + GET /transactionRequests/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Retrieve transaction-request + + + + + alt + + + [Payer FSP successfully retrieves transaction-request] + + + + + Payer FSP responds with the + + + PUT /transactionRequests/{ID} callback + + + + + 8 + + + PUT /transactionRequests/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate PUT /transactionRequests/{ID} + + + + + alt + + + [response is ok] + + + + + Switch forwards transaction-request response to Payee FSP + + + + + 11 + + + Retrieve corresponding end-points for Payee FSP + + + + + 12 + + + PUT /transactionRequests/{ID} + + + + + 13 + + + 200 Ok + + + + [response invalid] + + + + + Switch returns error to Payer FSP + + + + + 14 + + + PUT /transactionRequests/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payee FSP + + + may not receive a response + + + + [Payer FSP is unable to retrieve the transaction-request] + + + + + Payer FSP returns error to Switch + + + + + 16 + + + PUT /transactionRequests/{ID}/error + + + + + 17 + + + 200 OK + + + + + Switch returns error to Payee FSP + + + + + 18 + + + PUT /transactionRequests/{ID}/error + + + + + 19 + + + 200 OK + + + + [transaction-request is invalid] + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /transactionRequests/{ID}/error + + + + + 21 + + + 200 OK + + diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml new file mode 100644 index 000000000..d88913d33 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation +- Name Surname + +* Henk Kodde +-------------- +******'/ + +@startuml transactionRequests + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +payeefsp <- Payee: I would like to receive\nfunds from +123456789 +activate payeefsp +payeefsp <- payeefsp: Lookup +123456789\n(process not shown here) +Switch <<- payeefsp: **POST /transactionRequest/**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepted) +payerfsp <<- Switch: **POST /transactionRequests/**\n(Payee information,\ntransaction details) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepted) +payeefsp -> payeefsp: Perform optional validation +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Received status) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Received status) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Wait for either quote and\ntransfer, or rejected\ntransaction request by Payer +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg new file mode 100644 index 000000000..e54569705 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + Payer + + + FSP + + + + Optional + + + Switch + + + + Payee + + + FSP + + + + Payee + + + + + + + I would like to receive + + + funds from +123456789 + + + + Lookup +123456789 + + + (process not shown here) + + + + POST /transactionRequest/ + + + (Payee information, + + + transaction details) + + + + + HTTP 202 + + + (Accepted) + + + + POST /transactionRequests/ + + + (Payee information, + + + transaction details) + + + + + HTTP 202 + + + (Accepted) + + + + Perform optional validation + + + + PUT /transactionRequests/ + + + <ID> + + + (Received status) + + + + + HTTP 200 + + + (OK) + + + + PUT /transactionRequests/ + + + <ID> + + + (Received status) + + + + + HTTP 200 + + + (OK) + + + + Wait for either quote and + + + transfer, or rejected + + + transaction request by Payer + + diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/authorizations.md b/legacy/mojaloop-technical-overview/transaction-requests-service/authorizations.md new file mode 100644 index 000000000..614b5d0a5 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/authorizations.md @@ -0,0 +1,7 @@ +# Transaction Requests + +GET /authorizations/{TransactionRequestID} and PUT /authorizations/{TransactionRequestID} to support authorizations in "Merchant Request to Pay" and other Payee initiated use cases + +## Sequence Diagram + +![seq-trx-req-authorizations-3.0.0.svg](./assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.md b/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.md new file mode 100644 index 000000000..b99202192 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-get.md @@ -0,0 +1,7 @@ +# Transaction Requests - Query + +GET /transactionRequests and PUT /transacionRequests to suppport "Merchant Request to Pay" + +## Sequence Diagram + +![seq-trx-req-service-get-2.0.0.svg](./assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg) diff --git a/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.md b/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.md new file mode 100644 index 000000000..58ea60460 --- /dev/null +++ b/legacy/mojaloop-technical-overview/transaction-requests-service/transaction-requests-post.md @@ -0,0 +1,7 @@ +# Transaction Requests + +POST /transactionRequests and PUT /transacionRequests to suppport "Merchant Request to Pay" + +## Sequence Diagram + +![seq-trx-req-service-1.0.0.svg](./assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg) diff --git a/onboarding.md b/legacy/onboarding.md similarity index 100% rename from onboarding.md rename to legacy/onboarding.md diff --git a/legacy/package-lock.json b/legacy/package-lock.json new file mode 100644 index 000000000..b10908b77 --- /dev/null +++ b/legacy/package-lock.json @@ -0,0 +1,13528 @@ +{ + "name": "documentation", + "version": "11.3.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@korzio/djv-draft-04": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@korzio/djv-draft-04/-/djv-draft-04-2.0.1.tgz", + "integrity": "sha512-MeTVcNsfCIYxK6T7jW1sroC7dBAb4IfLmQe6RoCqlxHN5NFkzNpgdnBPR+/0D2wJDUJHM9s9NQv+ouhxKjvUjg==", + "dev": true, + "optional": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" + }, + "@npmcli/ci-detect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz", + "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==", + "dev": true + }, + "@npmcli/git": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.3.tgz", + "integrity": "sha512-c/ODsV5ppjB12VDXKc6hzVNgg6ZJX/etILUn3WgF5NLAYBhQLJ3fBq6uB2jQD4OwqOzJdPT1/xA3Xh3aaWGk5w==", + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^1.1.0", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.3", + "npm-pick-manifest": "^6.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "semver": "^7.3.2", + "unique-filename": "^1.1.1", + "which": "^2.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "@npmcli/move-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", + "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@npmcli/node-gyp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz", + "integrity": "sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==", + "dev": true + }, + "@npmcli/promise-spawn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.2.0.tgz", + "integrity": "sha512-nFtqjVETliApiRdjbYwKwhlSHx2ZMagyj5b9YbNt0BWeeOVxJd47ZVE2u16vxDHyTOZvk+YLV7INwfAE9a2uow==", + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + }, + "@sindresorhus/is": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", + "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/http-cache-semantics": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", + "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", + "dev": true + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.14.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", + "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "optional": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", + "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", + "optional": true + }, + "acorn-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", + "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", + "optional": true, + "requires": { + "acorn": "^2.1.0" + } + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, + "agentkeepalive": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", + "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "ansistyles": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz", + "integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=" + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "apache-crypt": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.4.tgz", + "integrity": "sha512-Icze5ny5W5uv3xgMgl8U+iGmRCC0iIDrb2PVPuRBtL3Zy1Y5TMewXP1Vtc4r5X9eNNBEk7KYPu0Qby9m/PmcHg==", + "requires": { + "unix-crypt-td-js": "^1.1.4" + } + }, + "apache-md5": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.5.tgz", + "integrity": "sha512-sbLEIMQrkV7RkIruqTPXxeCMkAAycv4yzTkBzRgOR1BrR5UB7qZtupqxkersTJSf0HZ3sbaNRrNV80TnnM7cUw==" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "audit-resolve-core": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.8.tgz", + "integrity": "sha512-F3IWaxu1Xw4OokmtG9hkmsKoJt8DQS7RZvot52zXHsANKvzFRMKVNTP1DAz1ztlRGmJx1XV16PcE+6m35bYoTA==", + "dev": true, + "requires": { + "concat-stream": "^1.6.2", + "debug": "^4.1.1", + "djv": "^2.1.2", + "spawn-shell": "^2.1.0", + "yargs-parser": "^18.1.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bash-color": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bash-color/-/bash-color-0.0.4.tgz", + "integrity": "sha1-6b6M4zVAytpIgXaMWb1jhlc26RM=" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, + "bootprint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bootprint/-/bootprint-1.0.2.tgz", + "integrity": "sha512-zrbDC1VVvOuOAf85Vc2Ni1AQxyQr0LqV6xJ8CAUCKRGo+EN1gWjTzmGfmRbeVIBsAouGSwYUcPonhHgbQct5+A==", + "requires": { + "commander": "^2.6.0", + "customize-engine-handlebars": "^1.0.0", + "customize-engine-less": "^1.0.1", + "customize-engine-uglify": "^1.0.0", + "customize-watch": "^1.0.0", + "customize-write-files": "^1.0.0", + "debug": "^2.1.2", + "get-promise": "^1.3.1", + "js-yaml": "^3.8.2", + "live-server": "^1.2.0", + "q": "^1.4.1", + "trace-and-clarify-if-possible": "^1.0.3" + } + }, + "bootprint-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bootprint-base/-/bootprint-base-1.1.0.tgz", + "integrity": "sha1-svYgtki/pvxuAnGzhxz8nPeM0DA=", + "requires": { + "bootstrap": "^3.3.2", + "cheerio": "^0.19.0", + "handlebars": "^3.0.0", + "highlight.js": "^8.4.0", + "jquery": "^2", + "json-stable-stringify": "^1.0.0", + "marked": "^0.3.3" + } + }, + "bootprint-json-schema": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bootprint-json-schema/-/bootprint-json-schema-1.1.0.tgz", + "integrity": "sha1-UI6PoRINyW0Lwsa6g0HrzdVFhSg=", + "requires": { + "bootprint-base": "^1.0.0", + "lodash": "^4.17.2" + } + }, + "bootprint-swagger": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bootprint-swagger/-/bootprint-swagger-1.0.1.tgz", + "integrity": "sha1-ykYPsXnZDXVymWwBaFJXroDNHDM=", + "requires": { + "bootprint-json-schema": "^1.0.0", + "highlight.js": "^8.9.1", + "json-stable-stringify": "^1.0.1", + "lodash": "^3.9.3", + "m-io": "^0.3.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "m-io": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/m-io/-/m-io-0.3.1.tgz", + "integrity": "sha1-SgeSJG9oGfdFyLxdlzzeiC8NHvs=", + "requires": { + "mkdirp": "^0.5.1", + "q": "^1.4.1", + "rimraf": "^2.5.3" + } + } + } + }, + "bootstrap": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", + "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacache": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", + "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true + }, + "cacheable-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", + "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^2.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cheerio": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", + "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", + "requires": { + "css-select": "~1.0.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "lodash": "^3.2.0" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cint": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/cint/-/cint-8.2.1.tgz", + "integrity": "sha1-cDhrG0jidz0NYxZqVa/5TvRFahI=", + "dev": true + }, + "clarify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clarify/-/clarify-2.1.0.tgz", + "integrity": "sha512-sWdsTozdtoFQbmncCXqCKeUzQbEZul/WJ8xYGVJgfIf4xMEM5q0La+Gjo2MFNOVL0FfTFteHqw6JX+9M71dAdQ==", + "optional": true, + "requires": { + "stack-chain": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "cli-table": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.5.tgz", + "integrity": "sha512-7uo2+RMNQUZ13M199udxqwk1qxTOS53EUak4gmu/aioUpdH5RvBz0JkJslcWz6ABKedZNqXXzikMZgHh+qF16A==", + "dev": true, + "requires": { + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, + "crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "css-select": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", + "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "1.0", + "domutils": "1.4", + "nth-check": "~1.0.0" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-what": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", + "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=" + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz", + "integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o=", + "optional": true + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "optional": true, + "requires": { + "cssom": "0.3.x" + } + }, + "customize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/customize/-/customize-1.1.1.tgz", + "integrity": "sha512-ldop1CRxbtctT+u8oBcihwoEC78m2xCJ4vyEsz/X/k49k8RouTosZeafkht+GzYKPQSnIdx+n8AZzr8o/zBfsg==", + "requires": { + "debug": "^2.2.0", + "deep-aplus": "^1.0.4", + "jsonschema": "^1.0.2", + "jsonschema-extra": "^1.2.0", + "lodash": "^3.9.3", + "m-io": "^0.5.0", + "minimatch": "^3.0.0", + "q": "^1.4.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "customize-engine-handlebars": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/customize-engine-handlebars/-/customize-engine-handlebars-1.0.3.tgz", + "integrity": "sha512-o9XSiASy/rsD7Hzy2MYIG1iGdsf7Nqu3hSSw6pH+TVTLdBNusnPxWTYkqxgUCJUnhIKq2Lx6qixZc9hXQGckYg==", + "requires": { + "debug": "^2.2.0", + "handlebars": "^3.0.3", + "lodash": "^3.9.3", + "promised-handlebars": "^1.0.0", + "q": "^1.4.1", + "q-deep": "^1.0.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "customize-engine-less": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/customize-engine-less/-/customize-engine-less-1.0.1.tgz", + "integrity": "sha1-rl//DPOSgGx9Dx1NqPfUsuZRCSk=", + "requires": { + "less": "^2.7.1", + "lodash": "^3.10.1", + "q": "^1.4.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "customize-engine-uglify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/customize-engine-uglify/-/customize-engine-uglify-1.0.0.tgz", + "integrity": "sha1-Eb3Mqslhn4zHCZHHGtB2K0cB+ug=", + "requires": { + "lodash": "^3.10.1", + "q": "^1.4.1", + "uglify-js": "^2.7.5" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "customize-watch": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/customize-watch/-/customize-watch-1.0.1.tgz", + "integrity": "sha512-2wPI3gLoz0hH9E0kg/srTVYYFyyCZsFmxm2whcXvTQERMBoXhdmGJAxyiI3dXvDbkRk7MoD8lOnonpF3i1Tn9Q==", + "requires": { + "chokidar": "^1.2.0", + "customize": "^1.0.0", + "debug": "^2.2.0", + "deep-aplus": "^1.0.4", + "lodash": "^3.10.1", + "m-io": "^0.5.0", + "q": "^1.4.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "customize-write-files": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/customize-write-files/-/customize-write-files-1.1.1.tgz", + "integrity": "sha512-zPcxlElbfDgDkY1lDFK+jiGor6W93iQ7GDcWFLFiIOcZdjQCeW9KeKXt5Yx8Kfpv7cw3w24xaqlJcNQMKqrHMg==", + "requires": { + "debug": "^2.2.0", + "deep-aplus": "^1.0.4", + "m-io": "^0.5.0", + "q": "^1.4.1", + "stream-equal": "^0.1.12" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } + } + }, + "deep-aplus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/deep-aplus/-/deep-aplus-1.0.4.tgz", + "integrity": "sha1-4exMEKALUEa1ng3dBRnRAa4xXo8=", + "requires": { + "lodash.isplainobject": "^4.0.6" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "optional": true + }, + "default-shell": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/default-shell/-/default-shell-1.0.1.tgz", + "integrity": "sha1-dSMEvdxhdPSespy5iP7qC4gTyLw=", + "dev": true + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "directory-tree": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/directory-tree/-/directory-tree-2.2.7.tgz", + "integrity": "sha512-fgTad/YdV6Y2njsCRK4fl4ZUlGhmb5xj1qrZUIMjvnrKvghVqh8dkB+OUssjYVvb/Q2L+5+8XG0l5uTGI9/8iQ==", + "dev": true + }, + "djv": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/djv/-/djv-2.1.4.tgz", + "integrity": "sha512-giDn+BVbtLlwtkvtcsZjbjzpALHB77skiv3FIu6Wp8b5j8BunDcVJYH0cGUaexp6s0Sb7IkquXXjsLBJhXwQpA==", + "dev": true, + "requires": { + "@korzio/djv-draft-04": "^2.0.1" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", + "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", + "requires": { + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "dev": true + }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "optional": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=", + "optional": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", + "optional": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "optional": true + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-promise": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-promise/-/get-promise-1.4.0.tgz", + "integrity": "sha1-RDBFyGUwvrvtIihh7+0TwNNv9qA=", + "requires": { + "lodash": "^3.8.0", + "q": "^1.2.0" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gitbook-cli": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gitbook-cli/-/gitbook-cli-2.3.2.tgz", + "integrity": "sha512-eyGtkY7jKHhmgpfuvgAP5fZcUob/FBz4Ld0aLRdEmiTrS1RklimN9epzPp75dd4MWpGhYvSbiwxnpyLiv1wh6A==", + "requires": { + "bash-color": "0.0.4", + "commander": "2.11.0", + "fs-extra": "3.0.1", + "lodash": "4.17.4", + "npm": "5.1.0", + "npmi": "1.0.1", + "optimist": "0.6.1", + "q": "1.5.0", + "semver": "5.3.0", + "tmp": "0.0.31", + "user-home": "2.0.0" + } + }, + "gitbook-plugin-back-to-top-button": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/gitbook-plugin-back-to-top-button/-/gitbook-plugin-back-to-top-button-0.1.4.tgz", + "integrity": "sha1-5iGDOLDvGdWOb2YAmUNQt26ANd8=" + }, + "gitbook-plugin-changelog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-changelog/-/gitbook-plugin-changelog-1.0.1.tgz", + "integrity": "sha1-CaEBwqXHm7q1NDyI3/qvZ9GPCVE=", + "requires": { + "lodash": "^4.17.4", + "moment": "^2.18.1" + } + }, + "gitbook-plugin-collapsible-chapters": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/gitbook-plugin-collapsible-chapters/-/gitbook-plugin-collapsible-chapters-0.1.8.tgz", + "integrity": "sha1-dxVcYcrBlRch2L9Es/ImphoeZcU=" + }, + "gitbook-plugin-editlink": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitbook-plugin-editlink/-/gitbook-plugin-editlink-1.0.2.tgz", + "integrity": "sha1-ej2Bk/guYfCUF83w52h2MfW2GV4=" + }, + "gitbook-plugin-fontsettings": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-fontsettings/-/gitbook-plugin-fontsettings-2.0.0.tgz", + "integrity": "sha1-g1+QCuPdERCG/n7UQl7j3gJIYas=" + }, + "gitbook-plugin-include": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-include/-/gitbook-plugin-include-0.1.0.tgz", + "integrity": "sha1-w1/0dlYKXv/e+tv2OYIknBy8dNw=", + "requires": { + "q": "*" + } + }, + "gitbook-plugin-insert-logo": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/gitbook-plugin-insert-logo/-/gitbook-plugin-insert-logo-0.1.5.tgz", + "integrity": "sha1-2q6N2kGiNtVPE5MeVwsmcpVXiFo=" + }, + "gitbook-plugin-page-toc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-page-toc/-/gitbook-plugin-page-toc-1.1.1.tgz", + "integrity": "sha1-YEZUSvoRNEJ2nwwLO0F8H+TfQRs=" + }, + "gitbook-plugin-plantuml-svg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-plantuml-svg/-/gitbook-plugin-plantuml-svg-1.0.1.tgz", + "integrity": "sha1-4QfoSCp/Gu3j0/IXzk1C/BWe6Qk=", + "requires": { + "js-base64": "^2.4.0", + "lodash": "^4.17.4", + "request": "^2.83.0", + "request-promise": "^4.2.2" + } + }, + "gitbook-plugin-search": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-search/-/gitbook-plugin-search-2.2.1.tgz", + "integrity": "sha1-bSW1p3aZD6mP39+jfeMx944PaxM=" + }, + "gitbook-plugin-swagger": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-swagger/-/gitbook-plugin-swagger-0.2.0.tgz", + "integrity": "sha1-g33zIY/9q9/LVu2Xr9SVYinZ0h0=", + "requires": { + "bootprint": "^1.0.0", + "bootprint-swagger": "^1.0.1" + } + }, + "gitbook-plugin-theme-api": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gitbook-plugin-theme-api/-/gitbook-plugin-theme-api-1.1.2.tgz", + "integrity": "sha1-jBRaS61JoSE8AlApC5vZtyrqiPw=", + "requires": { + "cheerio": "0.20.0", + "gitbook-plugin-search": ">=2.0.0", + "lodash": "4.12.0", + "q": "1.4.1", + "q-plus": "0.0.8" + }, + "dependencies": { + "cheerio": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", + "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "jsdom": "^7.0.2", + "lodash": "^4.1.0" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "lodash": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz", + "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg=" + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + } + } + }, + "gitbook-plugin-uml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-uml/-/gitbook-plugin-uml-1.0.1.tgz", + "integrity": "sha512-j9kWSFsfF7Y53LcfegQSkRUSc0cKcA93v0Sxg4wVzca7A9V1ridXiXcSeaKy7OZi386FB2mG+KihViUVZwfcCA==", + "requires": { + "crypto": "^1.0.1", + "fs-extra": "^4.0.1", + "node-plantuml": "^0.6.2", + "q": "^1.5.0" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "node-plantuml": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/node-plantuml/-/node-plantuml-0.6.2.tgz", + "integrity": "sha512-4/nf/gBvKVm4+EbBgFQZf0n8N3jfAA7mRExs3NfgujSsaouktZwYkUzBUqUR8nRzIWDmJ4hA1QiWOjpEArTiZQ==", + "requires": { + "commander": "^2.8.1", + "node-nailgun-client": "^0.1.0", + "node-nailgun-server": "^0.1.3", + "plantuml-encoder": "^1.2.5" + } + } + } + }, + "gitbook-plugin-variables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-variables/-/gitbook-plugin-variables-1.1.0.tgz", + "integrity": "sha512-+G97YsciufqZQenG1TziLfKEAIpKwnxiipBOtWM0lZu8OxSR2WG4n/9zGPq3RqYAfzb1BxD6m6i0LmxmOF0vPA==", + "requires": { + "fast-glob": "^2.2.2", + "fs-extra": "^7.0.0", + "js-yaml": "^3.12.0", + "lodash": "^4.17.10", + "native-require": "^1.1.4" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + }, + "dependencies": { + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + } + } + }, + "got": { + "version": "11.8.1", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.1.tgz", + "integrity": "sha512-9aYdZL+6nHmvJwHALLwKSUZ0hMwGaJGYv3hoPLPgnT8BoBXm1SjnZeky+91tfwJaDzun2s4RsBRy48IEYv2q2Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "handlebars": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-3.0.8.tgz", + "integrity": "sha512-frzSzoxbJZSB719r+lM3UFKrnHIY6VPY/j47+GNOHVnBHxO+r+Y/iDjozAbj1SztmmMpr2CcZY6rLeN5mqX8zA==", + "requires": { + "optimist": "^0.6.1", + "source-map": "^0.1.40", + "uglify-js": "^2.6" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, + "highlight.js": { + "version": "8.9.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-8.9.1.tgz", + "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + }, + "dependencies": { + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=", + "requires": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "http2-wrapper": { + "version": "1.0.0-beta.5.2", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", + "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "requires": { + "ms": "^2.0.0" + } + }, + "husky": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz", + "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "optional": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" + }, + "is-my-json-valid": { + "version": "2.20.5", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", + "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true + }, + "jquery": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", + "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=" + }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + }, + "js-quantities": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/js-quantities/-/js-quantities-1.7.6.tgz", + "integrity": "sha512-h6TH1xK1u/zdjD26M6kKVthZONJSDTIRzrohbqOILfJAyanWHGlJLWuAWkSMtqi8k/IxshStsc97Pkf8SL9yvA==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", + "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", + "optional": true, + "requires": { + "abab": "^1.0.0", + "acorn": "^2.4.0", + "acorn-globals": "^1.0.4", + "cssom": ">= 0.3.0 < 0.4.0", + "cssstyle": ">= 0.2.29 < 0.3.0", + "escodegen": "^1.6.1", + "nwmatcher": ">= 1.3.7 < 2.0.0", + "parse5": "^1.5.1", + "request": "^2.55.0", + "sax": "^1.1.4", + "symbol-tree": ">= 3.1.0 < 4.0.0", + "tough-cookie": "^2.2.0", + "webidl-conversions": "^2.0.0", + "whatwg-url-compat": "~0.6.5", + "xml-name-validator": ">= 2.0.1 < 3.0.0" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", + "dev": true, + "requires": { + "jju": "^1.1.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonlines": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsonlines/-/jsonlines-0.1.1.tgz", + "integrity": "sha1-T80kbcXQ44aRkHxEqwAveC0dlMw=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsonpointer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", + "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==" + }, + "jsonschema": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", + "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==" + }, + "jsonschema-extra": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonschema-extra/-/jsonschema-extra-1.2.0.tgz", + "integrity": "sha1-52eGotlQdb4ja5izuAUrD2wVTXs=", + "requires": { + "js-quantities": "^1.5.0", + "lodash.isplainobject": "^2.4.1" + }, + "dependencies": { + "lodash.isplainobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-2.4.1.tgz", + "integrity": "sha1-rHOF4uqawDIfMNw7gDKm0iMagBE=", + "requires": { + "lodash._isnative": "~2.4.1", + "lodash._shimisplainobject": "~2.4.1" + } + } + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "less": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", + "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "requires": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.2.11", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "2.81.0", + "source-map": "^0.5.3" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "optional": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "optional": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "optional": true, + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "optional": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "optional": true + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "optional": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "optional": true + }, + "qs": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.1.tgz", + "integrity": "sha512-LQy1Q1fcva/UsnP/6Iaa4lVeM49WiOitu2T4hZCyA/elLKu37L99qcBJk4VCCk+rdLvnMzfKyiN3SZTqdAZGSQ==", + "optional": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "optional": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "optional": true, + "requires": { + "punycode": "^1.4.1" + } + } + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "optional": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "libnpmconfig": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", + "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "live-server": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", + "integrity": "sha512-Yn2XCVjErTkqnM3FfTmM7/kWy3zP7+cEtC7x6u+wUzlQ+1UW3zEYbbyJrc0jNDwiMDZI0m4a0i3dxlGHVyXczw==", + "requires": { + "chokidar": "^2.0.4", + "colors": "^1.4.0", + "connect": "^3.6.6", + "cors": "^2.8.5", + "event-stream": "3.3.4", + "faye-websocket": "0.11.x", + "http-auth": "3.1.x", + "morgan": "^1.9.1", + "object-assign": "^4.1.1", + "opn": "^6.0.0", + "proxy-middleware": "^0.15.0", + "send": "^0.17.1", + "serve-index": "^1.9.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + } + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash._basebind": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.4.1.tgz", + "integrity": "sha1-6UC5690nwyfgqNqxtVkWxTQelXU=", + "requires": { + "lodash._basecreate": "~2.4.1", + "lodash._setbinddata": "~2.4.1", + "lodash._slice": "~2.4.1", + "lodash.isobject": "~2.4.1" + } + }, + "lodash._basecreate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz", + "integrity": "sha1-+Ob1tXip405UEXm1a47uv0oofgg=", + "requires": { + "lodash._isnative": "~2.4.1", + "lodash.isobject": "~2.4.1", + "lodash.noop": "~2.4.1" + } + }, + "lodash._basecreatecallback": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz", + "integrity": "sha1-fQsmdknLKeehOdAQO3wR+uhOSFE=", + "requires": { + "lodash._setbinddata": "~2.4.1", + "lodash.bind": "~2.4.1", + "lodash.identity": "~2.4.1", + "lodash.support": "~2.4.1" + } + }, + "lodash._basecreatewrapper": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz", + "integrity": "sha1-TTHy595+E0+/KAN2K4FQsyUZZm8=", + "requires": { + "lodash._basecreate": "~2.4.1", + "lodash._setbinddata": "~2.4.1", + "lodash._slice": "~2.4.1", + "lodash.isobject": "~2.4.1" + } + }, + "lodash._createwrapper": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz", + "integrity": "sha1-UdaVeXPaTtVW43KQ2MGhjFPeFgc=", + "requires": { + "lodash._basebind": "~2.4.1", + "lodash._basecreatewrapper": "~2.4.1", + "lodash._slice": "~2.4.1", + "lodash.isfunction": "~2.4.1" + } + }, + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=" + }, + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=" + }, + "lodash._setbinddata": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz", + "integrity": "sha1-98IAzRuS7yNrOZ7s9zxkjReqlNI=", + "requires": { + "lodash._isnative": "~2.4.1", + "lodash.noop": "~2.4.1" + } + }, + "lodash._shimisplainobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimisplainobject/-/lodash._shimisplainobject-2.4.1.tgz", + "integrity": "sha1-AeyTsu5j5Z8aqDiZrG+gkFrHWW8=", + "requires": { + "lodash.forin": "~2.4.1", + "lodash.isfunction": "~2.4.1" + } + }, + "lodash._slice": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.4.1.tgz", + "integrity": "sha1-dFz0GlNZexj2iImFREBe+isG2Q8=" + }, + "lodash.bind": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.4.1.tgz", + "integrity": "sha1-XRn6AFyMTSNvr0dCx7eh/Kvikmc=", + "requires": { + "lodash._createwrapper": "~2.4.1", + "lodash._slice": "~2.4.1" + } + }, + "lodash.forin": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.forin/-/lodash.forin-2.4.1.tgz", + "integrity": "sha1-gInq7X0lsIZyt8Zv0HrFXQYjIOs=", + "requires": { + "lodash._basecreatecallback": "~2.4.1", + "lodash._objecttypes": "~2.4.1" + } + }, + "lodash.identity": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.4.1.tgz", + "integrity": "sha1-ZpTP+mX++TH3wxzobHRZfPVg9PE=" + }, + "lodash.isfunction": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz", + "integrity": "sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE=" + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "requires": { + "lodash._objecttypes": "~2.4.1" + } + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.noop": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz", + "integrity": "sha1-T7VPgWZS5a4Q6PcvcXo4jHMmU4o=" + }, + "lodash.support": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.4.1.tgz", + "integrity": "sha1-Mg4LZwMWc8KNeiu12eAzGkUkBRU=", + "requires": { + "lodash._isnative": "~2.4.1" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "m-io": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/m-io/-/m-io-0.5.0.tgz", + "integrity": "sha1-chuybdjUN13Oy1bY3AFm64vp0AM=", + "requires": { + "fs-extra": "^2.0.0", + "q": "^1.4.1" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + } + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "dev": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "minipass-fetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", + "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "marked": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", + "integrity": "sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==", + "dev": true, + "requires": { + "is-plain-obj": "^1.1" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "requires": { + "mime-db": "1.46.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.0.tgz", + "integrity": "sha512-Yb23ESZZ/8QxiBvSpJ4atbVMVDx2CXrerzrtQzQ67eLqKg+zFIkYFTagk3xh6fdo+e/FvDtVuCD4QcuYDRR3hw==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "dependencies": { + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + } + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "native-require": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/native-require/-/native-require-1.1.4.tgz", + "integrity": "sha512-fOB7diEP3ErNZnMh+Zqdufw79rIPrcAbHanixB5WoWpfU06ZfoUjynGDDQ22uKBhkpgzcI3WXQglhzpWBPKKGA==" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nested-error-stacks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz", + "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==", + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", + "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-nailgun-client": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/node-nailgun-client/-/node-nailgun-client-0.1.2.tgz", + "integrity": "sha512-OC611lR0fsDUSptwnhBf8d3sj4DZ5fiRKfS2QaGPe0kR3Dt9YoZr1MY7utK0scFPTbXuQdSBBbeoKYVbME1q5g==", + "requires": { + "commander": "^2.8.1" + } + }, + "node-nailgun-server": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/node-nailgun-server/-/node-nailgun-server-0.1.4.tgz", + "integrity": "sha512-e0Hbh6XPb/7GqATJ45BePaUEO5AwR7InRW/pGeMKHH1cqPMBFCeqdBNfvi+bkVLnsbYOOQE+pAek9nmNoD8sYw==", + "requires": { + "commander": "^2.8.1" + } + }, + "node-plantuml": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/node-plantuml/-/node-plantuml-0.5.0.tgz", + "integrity": "sha1-A8LthW5rJyxxShVoRTp0fCZv3B8=", + "dev": true, + "requires": { + "commander": "^2.8.1", + "node-nailgun-client": "^0.1.0", + "node-nailgun-server": "^0.1.3", + "plantuml-encoder": "^1.2.4" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "npm": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-5.1.0.tgz", + "integrity": "sha512-pt5ClxEmY/dLpb60SmGQQBKi3nB6Ljx1FXmpoCUdAULlGqGVn2uCyXxPCWFbcuHGthT7qGiaGa1wOfs/UjGYMw==", + "requires": { + "JSONStream": "~1.3.1", + "abbrev": "~1.1.0", + "ansi-regex": "~3.0.0", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "~1.1.2", + "archy": "~1.0.0", + "bluebird": "~3.5.0", + "cacache": "~9.2.9", + "call-limit": "~1.1.0", + "chownr": "~1.0.1", + "cmd-shim": "~2.0.2", + "columnify": "~1.5.4", + "config-chain": "~1.1.11", + "debuglog": "*", + "detect-indent": "~5.0.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "fstream": "~1.0.11", + "fstream-npm": "~1.2.1", + "glob": "~7.1.2", + "graceful-fs": "~4.1.11", + "has-unicode": "~2.0.1", + "hosted-git-info": "~2.5.0", + "iferr": "~0.1.5", + "imurmurhash": "*", + "inflight": "~1.0.6", + "inherits": "~2.0.3", + "ini": "~1.3.4", + "init-package-json": "~1.10.1", + "lazy-property": "~1.0.0", + "lockfile": "~1.0.3", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "~4.1.1", + "mississippi": "~1.3.0", + "mkdirp": "~0.5.1", + "move-concurrently": "~1.0.1", + "node-gyp": "~3.6.2", + "nopt": "~4.0.1", + "normalize-package-data": "~2.4.0", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "~3.0.0", + "npm-package-arg": "~5.1.2", + "npm-registry-client": "~8.4.0", + "npm-user-validate": "~1.0.0", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "~1.4.3", + "osenv": "~0.1.4", + "pacote": "~2.7.38", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "~1.0.1", + "read-installed": "~4.0.3", + "read-package-json": "~2.0.9", + "read-package-tree": "~5.1.6", + "readable-stream": "~2.3.2", + "readdir-scoped-modules": "*", + "request": "~2.81.0", + "retry": "~0.10.1", + "rimraf": "~2.6.1", + "safe-buffer": "~5.1.1", + "semver": "~5.3.0", + "sha": "~2.0.1", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "~4.1.6", + "strip-ansi": "~4.0.0", + "tar": "~2.2.1", + "text-table": "~0.2.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "~1.1.0", + "unpipe": "~1.0.0", + "update-notifier": "~2.2.0", + "uuid": "~3.1.0", + "validate-npm-package-license": "*", + "validate-npm-package-name": "~3.0.0", + "which": "~1.2.14", + "worker-farm": "~1.3.1", + "wrappy": "~1.0.2", + "write-file-atomic": "~2.1.0" + }, + "dependencies": { + "JSONStream": { + "version": "1.3.1", + "resolved": false, + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "dependencies": { + "jsonparse": { + "version": "1.3.1", + "resolved": false, + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "through": { + "version": "2.3.8", + "resolved": false, + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + } + } + }, + "abbrev": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansicolors": { + "version": "0.3.2", + "resolved": false, + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "ansistyles": { + "version": "0.1.3", + "resolved": false, + "integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=" + }, + "aproba": { + "version": "1.1.2", + "resolved": false, + "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==" + }, + "archy": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "bluebird": { + "version": "3.5.0", + "resolved": false, + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "cacache": { + "version": "9.2.9", + "resolved": false, + "integrity": "sha512-ghg1j5OyTJ6qsrqU++dN23QiTDxb5AZCFGsF3oB+v9v/gY+F4X8L/0gdQMEjd+8Ot3D29M2etX5PKozHRn2JQw==", + "requires": { + "bluebird": "^3.5.0", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^1.3.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.1", + "ssri": "^4.1.6", + "unique-filename": "^1.1.0", + "y18n": "^3.2.1" + } + }, + "call-limit": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-b9YbA/PaQqLNDsK2DwK9DnGZH+o=" + }, + "chownr": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, + "cmd-shim": { + "version": "2.0.2", + "resolved": false, + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "columnify": { + "version": "1.5.4", + "resolved": false, + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "requires": { + "defaults": "^1.0.3" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.11", + "resolved": false, + "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + }, + "dependencies": { + "proto-list": { + "version": "1.2.4", + "resolved": false, + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + } + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=" + }, + "detect-indent": { + "version": "5.0.0", + "resolved": false, + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" + }, + "dezalgo": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + }, + "dependencies": { + "asap": { + "version": "2.0.5", + "resolved": false, + "integrity": "sha1-UidltQw1EEkOUtfc/ghe+bqWlY8=" + } + } + }, + "editor": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=" + }, + "fs-vacuum": { + "version": "1.2.10", + "resolved": false, + "integrity": "sha1-t2Kb7AekAxolSP35n17PHMizHjY=", + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": false, + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fstream-npm": { + "version": "1.2.1", + "resolved": false, + "integrity": "sha512-iBHpm/LmD1qw0TlHMAqVd9rwdU6M+EHRUnPkXpRi5G/Hf0FIFH+oZFryodAU2MFNfGRh/CzhUFlMKV3pdeOTDw==", + "requires": { + "fstream-ignore": "^1.0.0", + "inherits": "2" + }, + "dependencies": { + "fstream-ignore": { + "version": "1.0.5", + "resolved": false, + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": false, + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + } + } + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": false, + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": false, + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": false, + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": false, + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "iferr": { + "version": "0.1.5", + "resolved": false, + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": false, + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": false, + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "init-package-json": { + "version": "1.10.1", + "resolved": false, + "integrity": "sha1-zYc6FneWvvuZYSsodioLY5P9j2o=", + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "promzard": { + "version": "0.3.0", + "resolved": false, + "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "requires": { + "read": "1" + } + } + } + }, + "lazy-property": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=" + }, + "lockfile": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-Jjj8OaAzHpysGgS3F5mTHJxQ33k=" + }, + "lodash._baseindexof": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=" + }, + "lodash._baseuniq": { + "version": "4.6.0", + "resolved": false, + "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=", + "requires": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + }, + "dependencies": { + "lodash._createset": { + "version": "4.0.3", + "resolved": false, + "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + } + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "resolved": false, + "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=" + }, + "lodash._createcache": { + "version": "3.1.2", + "resolved": false, + "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=", + "requires": { + "lodash._getnative": "^3.0.0" + } + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": false, + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": false, + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": false, + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.union": { + "version": "4.6.0", + "resolved": false, + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": false, + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "lodash.without": { + "version": "4.4.0", + "resolved": false, + "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=" + }, + "lru-cache": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "yallist": { + "version": "2.1.2", + "resolved": false, + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "make-fetch-happen": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-2.6.0.tgz", + "integrity": "sha512-FFq0lNI0ax+n9IWzWpH8A4JdgYiAp2DDYIZ3rsaav8JDe8I+72CzK6PQW/oom15YDZpV5bYW/9INd6nIJ2ZfZw==", + "requires": { + "agentkeepalive": "^3.3.0", + "cacache": "^10.0.0", + "http-cache-semantics": "^3.8.0", + "http-proxy-agent": "^2.0.0", + "https-proxy-agent": "^2.1.0", + "lru-cache": "^4.1.1", + "mississippi": "^1.2.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^3.0.1", + "ssri": "^5.0.0" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "cacache": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", + "requires": { + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^2.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^5.2.4", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" + }, + "dependencies": { + "mississippi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", + "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^2.0.1", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + } + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "ssri": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", + "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + } + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mississippi": { + "version": "1.3.0", + "resolved": false, + "integrity": "sha1-0gFYPrEjJ+PFwWQqQEqcrPlONPU=", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^1.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": false, + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "resolved": false, + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + } + } + }, + "duplexify": { + "version": "3.5.0", + "resolved": false, + "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=", + "requires": { + "end-of-stream": "1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=", + "requires": { + "once": "~1.3.0" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": false, + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + } + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + } + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": false, + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "^1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "from2": { + "version": "2.3.0", + "resolved": false, + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "resolved": false, + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" + } + } + }, + "pump": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.3.5", + "resolved": false, + "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=", + "requires": { + "duplexify": "^3.1.2", + "inherits": "^2.0.1", + "pump": "^1.0.0" + } + }, + "stream-each": { + "version": "1.2.0", + "resolved": false, + "integrity": "sha1-HpXUdXP1gNgU3A/4zQ9m8c5TyZE=", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + } + } + }, + "through2": { + "version": "2.0.3", + "resolved": false, + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "run-queue": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + } + } + }, + "node-gyp": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.3.tgz", + "integrity": "sha512-7789TDMqJpv5iHxn1cAESCBEC/sBHAFxAvgXAcvzWenEWl0qf6E2Kk/Xwdl5ZclktUJzxJPVa27OMkBvaHKqCQ==", + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": ">=2.9.0 <2.82.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "nopt": { + "version": "3.0.6", + "resolved": false, + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + } + } + }, + "nopt": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": false, + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "^1.0.0" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + } + } + } + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=" + }, + "npm-install-checks": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-1K7N/VGlPjcjt7L5Oy7ijjB7wNc=", + "requires": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-package-arg": { + "version": "5.1.2", + "resolved": false, + "integrity": "sha512-wJBsrf0qpypPT7A0LART18hCdyhpCMxeTtcb0X4IZO2jsP6Om7EHN1d9KSKiqD+KVH030RVNpWS9thk+pb7wzA==", + "requires": { + "hosted-git-info": "^2.4.2", + "osenv": "^0.1.4", + "semver": "^5.1.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-registry-client": { + "version": "8.4.0", + "resolved": false, + "integrity": "sha512-PVNfqq0lyRdFnE//nDmn3CC9uqTsr8Bya9KPLIevlXMfkP0m4RpCVyFFk0W1Gfx436kKwyhLA6J+lV+rgR81gQ==", + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0", + "npmlog": "2 || ^3.1.0 || ^4.0.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3", + "ssri": "^4.1.2" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": false, + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "resolved": false, + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + } + } + } + } + }, + "npm-user-validate": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=" + }, + "npmlog": { + "version": "4.1.2", + "resolved": false, + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "1.1.4", + "resolved": false, + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "delegates": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "gauge": { + "version": "2.7.4", + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "string-width": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "wide-align": { + "version": "1.1.2", + "resolved": false, + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "requires": { + "string-width": "^1.0.2" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + } + } + }, + "once": { + "version": "1.4.0", + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.4.3", + "resolved": false, + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=" + }, + "osenv": { + "version": "0.1.4", + "resolved": false, + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + } + } + }, + "pacote": { + "version": "2.7.38", + "resolved": false, + "integrity": "sha512-XxHUyHQB7QCVBxoXeVu0yKxT+2PvJucsc0+1E+6f95lMUxEAYERgSAc71ckYXrYr35Ew3xFU/LrhdIK21GQFFA==", + "requires": { + "bluebird": "^3.5.0", + "cacache": "^9.2.9", + "glob": "^7.1.2", + "lru-cache": "^4.1.1", + "make-fetch-happen": "^2.4.13", + "minimatch": "^3.0.4", + "mississippi": "^1.2.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^5.1.2", + "npm-pick-manifest": "^1.0.4", + "osenv": "^0.1.4", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^4.0.0", + "safe-buffer": "^5.1.1", + "semver": "^5.3.0", + "ssri": "^4.1.6", + "tar-fs": "^1.15.3", + "tar-stream": "^1.5.4", + "unique-filename": "^1.1.0", + "which": "^1.2.12" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": false, + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + }, + "npm-pick-manifest": { + "version": "1.0.4", + "resolved": false, + "integrity": "sha512-MKxNdeyOZysPRTTbHtW0M5Fw38Jo/3ARsoGw5qjCfS+XGjvNB/Gb4qtAZUFmKPM2mVum+eX559eHvKywU856BQ==", + "requires": { + "npm-package-arg": "^5.1.2", + "semver": "^5.3.0" + } + }, + "promise-retry": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "err-code": { + "version": "1.1.2", + "resolved": false, + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" + } + } + }, + "protoduck": { + "version": "4.0.0", + "resolved": false, + "integrity": "sha1-/kh02MeRM2bP2erRJFOiLNNlf44=", + "requires": { + "genfun": "^4.0.1" + }, + "dependencies": { + "genfun": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-7RAEHy5KfxsKOEZtF6XD4n3x38E=" + } + } + }, + "tar-stream": { + "version": "1.5.4", + "resolved": false, + "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", + "requires": { + "bl": "^1.0.0", + "end-of-stream": "^1.0.0", + "readable-stream": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "bl": { + "version": "1.2.1", + "resolved": false, + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "requires": { + "readable-stream": "^2.0.5" + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": false, + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "^1.4.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + } + } + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "qs": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.1.tgz", + "integrity": "sha512-LQy1Q1fcva/UsnP/6Iaa4lVeM49WiOitu2T4hZCyA/elLKu37L99qcBJk4VCCk+rdLvnMzfKyiN3SZTqdAZGSQ==" + }, + "read": { + "version": "1.0.7", + "resolved": false, + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.7", + "resolved": false, + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + } + } + }, + "read-cmd-shim": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-installed": { + "version": "4.0.3", + "resolved": false, + "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "util-extend": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=" + } + } + }, + "read-package-json": { + "version": "2.0.9", + "resolved": false, + "integrity": "sha512-vuV8p921IgyelL4UOKv3FsRuRZSaRn30HanLAOKargsr8TbBEq+I3MgloSRXYuKhNdYP1wlEGilMWAIayA2RFg==", + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-helpfulerror": "^1.0.2", + "normalize-package-data": "^2.0.0" + }, + "dependencies": { + "json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", + "requires": { + "jju": "^1.1.0" + }, + "dependencies": { + "jju": { + "version": "1.3.0", + "resolved": false, + "integrity": "sha1-2t2e8BkkvHKLA/L3l5vb1i96Kqo=" + } + } + } + } + }, + "read-package-tree": { + "version": "5.1.6", + "resolved": false, + "integrity": "sha512-FCX1aT3GWyY658wzDICef4p+n0dB+ENRct8E/Qyvppj6xVpOYerBHfUu7OP5Rt1/393Tdglguf5ju5DEX4wZNg==", + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "once": "^1.3.0", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.2", + "resolved": false, + "integrity": "sha1-WgTfBeT1f+Pw3Gj90R3FyXx+b00=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.0", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": false, + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=", + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "request": { + "version": "2.81.0", + "resolved": false, + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "resolved": false, + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.6.0", + "resolved": false, + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "caseless": { + "version": "0.12.0", + "resolved": false, + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": false, + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "~1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + } + } + }, + "extend": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": false, + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.1.4", + "resolved": false, + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "dependencies": { + "asynckit": { + "version": "0.4.0", + "resolved": false, + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + } + } + }, + "har-validator": { + "version": "4.2.1", + "resolved": false, + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": false, + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "resolved": false, + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + }, + "dependencies": { + "jsonify": { + "version": "0.0.0", + "resolved": false, + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + } + } + } + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": false, + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + } + } + }, + "hawk": { + "version": "3.1.3", + "resolved": false, + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "resolved": false, + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": false, + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": false, + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "sntp": { + "version": "1.0.9", + "resolved": false, + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.x.x" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": false, + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": false, + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "jsprim": { + "version": "1.4.0", + "resolved": false, + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "extsprintf": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": false, + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "verror": { + "version": "1.3.6", + "resolved": false, + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "requires": { + "extsprintf": "1.0.2" + } + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": false, + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": false, + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "mime-types": { + "version": "2.1.15", + "resolved": false, + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "requires": { + "mime-db": "~1.27.0" + }, + "dependencies": { + "mime-db": { + "version": "1.27.0", + "resolved": false, + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": false, + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "performance-now": { + "version": "0.2.0", + "resolved": false, + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": false, + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": false, + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "requires": { + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": false, + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": false, + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + } + } + }, + "retry": { + "version": "0.10.1", + "resolved": false, + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + }, + "rimraf": { + "version": "2.6.1", + "resolved": false, + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": false, + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.3.0", + "resolved": false, + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "sha": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-YDCCL70smCOUn49y7WQR7lzyWq4=", + "requires": { + "graceful-fs": "^4.1.2", + "readable-stream": "^2.0.2" + } + }, + "slide": { + "version": "1.1.6", + "resolved": false, + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, + "smart-buffer": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", + "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=" + }, + "socks": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", + "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", + "requires": { + "ip": "^1.1.4", + "smart-buffer": "^1.0.13" + } + }, + "socks-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", + "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", + "requires": { + "agent-base": "^4.1.0", + "socks": "^1.1.10" + } + }, + "sorted-object": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=" + }, + "sorted-union-stream": { + "version": "2.1.3", + "resolved": false, + "integrity": "sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=", + "requires": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "resolved": false, + "integrity": "sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": false, + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "0.0.1", + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + } + } + }, + "stream-iterate": { + "version": "1.2.0", + "resolved": false, + "integrity": "sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=", + "requires": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + } + } + } + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "4.1.6", + "resolved": false, + "integrity": "sha512-WUbCdgSAMQjTFZRWvSPpauryvREEA+Krn19rx67UlJEJx/M192ZHxMmJXjZ4tkdFm+Sb0SXGlENeQVlA5wY7kA==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": false, + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + } + } + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": false, + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "uid-number": { + "version": "0.0.6", + "resolved": false, + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + }, + "umask": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=" + }, + "unique-filename": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "requires": { + "unique-slug": "^2.0.0" + }, + "dependencies": { + "unique-slug": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "requires": { + "imurmurhash": "^0.1.4" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "2.2.0", + "resolved": false, + "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=", + "requires": { + "boxen": "^1.0.0", + "chalk": "^1.0.0", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "boxen": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-sbad1SIwXoB6md7ud329blFnsQI=", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^1.1.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^0.1.0", + "widest-line": "^1.0.0" + }, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "^2.0.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": false, + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "string-width": { + "version": "2.1.0", + "resolved": false, + "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": false, + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "term-size": { + "version": "0.1.1", + "resolved": false, + "integrity": "sha1-hzYLljlsq1dgljcUzaDQy+7K2co=", + "requires": { + "execa": "^0.4.0" + }, + "dependencies": { + "execa": { + "version": "0.4.0", + "resolved": false, + "integrity": "sha1-TrZGejaglfq7KXD/nV4/t7zm68M=", + "requires": { + "cross-spawn-async": "^2.1.1", + "is-stream": "^1.1.0", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn-async": { + "version": "2.2.5", + "resolved": false, + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "requires": { + "path-key": "^1.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "path-key": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + } + } + } + } + }, + "widest-line": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "requires": { + "string-width": "^1.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + } + } + } + } + } + } + }, + "chalk": { + "version": "1.1.3", + "resolved": false, + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": false, + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": false, + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "configstore": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha1-Rd+QcHPibfoc9LLVL1tgVF6qEdE=", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "4.1.1", + "resolved": false, + "integrity": "sha1-qEk/C3te7sglJbXHWH+n3nyoWcE=", + "requires": { + "is-obj": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + } + } + }, + "make-dir": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": false, + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + }, + "dependencies": { + "crypto-random-string": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + } + } + } + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": false, + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "is-npm": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "latest-version": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + }, + "dependencies": { + "package-json": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "resolved": false, + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "create-error-class": { + "version": "3.0.2", + "resolved": false, + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + }, + "dependencies": { + "capture-stack-trace": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + } + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": false, + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": false, + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "unzip-response": { + "version": "2.0.1", + "resolved": false, + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + }, + "dependencies": { + "prepend-http": { + "version": "1.0.4", + "resolved": false, + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + } + } + } + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + } + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "semver-diff": { + "version": "2.1.0", + "resolved": false, + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "^5.0.3" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + } + } + }, + "uuid": { + "version": "3.1.0", + "resolved": false, + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": false, + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "^1.0.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "resolved": false, + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": false, + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + } + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "requires": { + "builtins": "^1.0.3" + }, + "dependencies": { + "builtins": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" + } + } + }, + "which": { + "version": "1.2.14", + "resolved": false, + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "requires": { + "isexe": "^2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + } + } + }, + "worker-farm": { + "version": "1.3.1", + "resolved": false, + "integrity": "sha1-QzMRK7SbF6oFC4eJXKayys9A5f8=", + "requires": { + "errno": ">=0.1.1 <0.2.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + }, + "dependencies": { + "errno": { + "version": "0.1.4", + "resolved": false, + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "requires": { + "prr": "~0.0.0" + }, + "dependencies": { + "prr": { + "version": "0.0.0", + "resolved": false, + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=" + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "2.1.0", + "resolved": false, + "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + } + } + }, + "npm-audit-resolver": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-2.2.1.tgz", + "integrity": "sha512-9Jo5EdxREaXRrFm7eiuT1qu7fXKDfO+oiu+EgvJ/JCd2PIAgzVGF+xFoNK9AnyUsMFvSTdJM6+YlgUgF/N86GA==", + "dev": true, + "requires": { + "audit-resolve-core": "^1.1.8", + "chalk": "^2.4.2", + "djv": "^2.1.2", + "jsonlines": "^0.1.1", + "read": "^1.0.7", + "spawn-shell": "^2.1.0", + "yargs-parser": "^18.1.3", + "yargs-unparser": "^1.6.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-check-updates": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-7.0.2.tgz", + "integrity": "sha512-MyH17fUCFbYShuIyxZj6yqB6YZ47+AjPCgXQiH1oqNe3vElBoJ0toY7nwy88qJbfXnFqjTFigzs9lsoKSK0iUw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cint": "^8.2.1", + "cli-table": "^0.3.1", + "commander": "^5.1.0", + "find-up": "4.1.0", + "get-stdin": "^8.0.0", + "json-parse-helpfulerror": "^1.0.3", + "libnpmconfig": "^1.2.1", + "lodash": "^4.17.19", + "p-map": "^4.0.0", + "pacote": "^11.1.10", + "progress": "^2.0.3", + "prompts": "^2.3.2", + "rc-config-loader": "^3.0.0", + "requireg": "^0.2.2", + "semver": "^7.3.2", + "semver-utils": "^1.1.4", + "spawn-please": "^0.3.0", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "npm-install-checks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "requires": { + "semver": "^7.1.1" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-package-arg": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.1.tgz", + "integrity": "sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.6", + "semver": "^7.0.0", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", + "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "npm-packlist": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.1.4.tgz", + "integrity": "sha512-Qzg2pvXC9U4I4fLnUrBmcIT4x0woLtUgxUi9eC+Zrcv1Xx5eamytGAfbDWQ67j7xOcQ2VW1I3su9smVTIdu7Hw==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz", + "integrity": "sha512-ygs4k6f54ZxJXrzT0x34NybRlLeZ4+6nECAIbr2i0foTnijtS1TJiyzpqtuUAJOps/hO0tNDr8fRV5g+BtRlTw==", + "dev": true, + "requires": { + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.0.0", + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "npm-registry-fetch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", + "dev": true, + "requires": { + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "dependencies": { + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npmi/-/npmi-1.0.1.tgz", + "integrity": "sha1-FddpJzVHVF5oCdzwzhiu1IsCkOI=", + "requires": { + "npm": "^2.1.12", + "semver": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtins": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-0.0.7.tgz", + "integrity": "sha1-NVIZzWzxjb58Acx/0tznZc/cVJo=" + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + } + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "node-gyp": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.3.tgz", + "integrity": "sha512-7789TDMqJpv5iHxn1cAESCBEC/sBHAFxAvgXAcvzWenEWl0qf6E2Kk/Xwdl5ZclktUJzxJPVa27OMkBvaHKqCQ==", + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": ">=2.9.0 <2.82.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "npm": { + "version": "2.15.12", + "resolved": "https://registry.npmjs.org/npm/-/npm-2.15.12.tgz", + "integrity": "sha1-33w+1aJ3w/nUtdgZsFMR0QogCuY=", + "requires": { + "abbrev": "~1.0.9", + "ansi": "~0.3.1", + "ansi-regex": "*", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "archy": "~1.0.0", + "async-some": "~1.0.2", + "block-stream": "0.0.9", + "char-spinner": "~1.0.1", + "chmodr": "~1.0.2", + "chownr": "~1.0.1", + "cmd-shim": "~2.0.2", + "columnify": "~1.5.4", + "config-chain": "~1.1.10", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "fs-vacuum": "~1.2.9", + "fs-write-stream-atomic": "~1.0.8", + "fstream": "~1.0.10", + "fstream-npm": "~1.1.1", + "github-url-from-git": "~1.4.0", + "github-url-from-username-repo": "~1.0.2", + "glob": "~7.0.6", + "graceful-fs": "~4.1.6", + "hosted-git-info": "~2.1.5", + "imurmurhash": "*", + "inflight": "~1.0.4", + "inherits": "~2.0.3", + "ini": "~1.3.4", + "init-package-json": "~1.9.4", + "lockfile": "~1.0.1", + "lru-cache": "~4.0.1", + "minimatch": "~3.0.3", + "mkdirp": "~0.5.1", + "node-gyp": "~3.6.0", + "nopt": "~3.0.6", + "normalize-git-url": "~3.0.2", + "normalize-package-data": "~2.3.5", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "~1.0.7", + "npm-package-arg": "~4.1.0", + "npm-registry-client": "~7.2.1", + "npm-user-validate": "~0.1.5", + "npmlog": "~2.0.4", + "once": "~1.4.0", + "opener": "~1.4.1", + "osenv": "~0.1.3", + "path-is-inside": "~1.0.0", + "read": "~1.0.7", + "read-installed": "~4.0.3", + "read-package-json": "~2.0.4", + "readable-stream": "~2.1.5", + "realize-package-specifier": "~3.0.1", + "request": "~2.74.0", + "retry": "~0.10.0", + "rimraf": "~2.5.4", + "semver": "~5.1.0", + "sha": "~2.0.1", + "slide": "~1.1.6", + "sorted-object": "~2.0.0", + "spdx-license-ids": "~1.2.2", + "strip-ansi": "~3.0.1", + "tar": "~2.2.1", + "text-table": "~0.2.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "validate-npm-package-license": "~3.0.1", + "validate-npm-package-name": "~2.2.2", + "which": "~1.2.11", + "wrappy": "~1.0.2", + "write-file-atomic": "~1.1.4" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" + }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, + "ansi-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async-some": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-TYqBYg1ZWHkbW5j4AtMgd3bpVQk=", + "requires": { + "dezalgo": "^1.0.2" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "char-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz", + "integrity": "sha1-5upnvSR+EHESmDt6sEee02KAAIE=" + }, + "chmodr": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz", + "integrity": "sha1-BGYrky0PAuxm3qorDqQoEZaOPrk=" + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, + "cmd-shim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "wcwidth": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.0.tgz", + "integrity": "sha1-AtBZ/3qPx0Hg9rXaHmmytA2uym8=", + "requires": { + "defaults": "^1.0.0" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.10.tgz", + "integrity": "sha1-f8OD3g/MhNcRy0Zb0XZXnK1hI0Y=", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + }, + "dependencies": { + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + } + } + }, + "dezalgo": { + "version": "1.0.3", + "resolved": false, + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + }, + "dependencies": { + "asap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.3.tgz", + "integrity": "sha1-H8HRVk7hFiDfym1nAphQkT+fRnk=" + } + } + }, + "editor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz", + "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=" + }, + "fs-vacuum": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.9.tgz", + "integrity": "sha1-T5AZOrjqAokJlbzU6ARlml02ay0=", + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz", + "integrity": "sha1-5Jqt3yiPh9Rv+eiC8hahOrxAd4s=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + } + } + }, + "fstream-npm": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fstream-npm/-/fstream-npm-1.1.1.tgz", + "integrity": "sha1-a5F122I5qD2CCeIyQmxJTbspaQw=", + "requires": { + "fstream-ignore": "^1.0.0", + "inherits": "2" + }, + "dependencies": { + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" + } + } + } + }, + "github-url-from-git": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.4.0.tgz", + "integrity": "sha1-KF5rUggZABveEoZ0cEN55P8D4N4=" + }, + "github-url-from-username-repo": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-fdeTMNKr5pwQws73lxTJchV5Hfo=" + }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "path-is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=" + } + } + }, + "graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha1-UUw4dysxvuLgi+3CGgrrOr9UwZ4=" + }, + "hosted-git-info": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", + "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "init-package-json": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.9.4.tgz", + "integrity": "sha1-tAU9C0Dwz4QqQZZpN8s9wPU06FY=", + "requires": { + "glob": "^6.0.0", + "npm-package-arg": "^4.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^2.0.1" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "path-is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=" + } + } + }, + "promzard": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", + "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "requires": { + "read": "1" + } + } + } + }, + "lockfile": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz", + "integrity": "sha1-nTU+z+P1TRULtX+J1RdGk1o5xPU=" + }, + "lru-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", + "integrity": "sha1-E0OVXtry432bnn7nJB4nxLn7cr4=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "yallist": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", + "integrity": "sha1-MGxUODXwnuGkyyO3vOmrNByRzdQ=" + } + } + }, + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": false, + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "normalize-git-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-git-url/-/normalize-git-url-3.0.2.tgz", + "integrity": "sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q=" + }, + "normalize-package-data": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", + "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=", + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "^1.0.0" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.0.tgz", + "integrity": "sha1-EFOVX9mUpXRuUl5Kxxe4HK8HSRw=" + } + } + } + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz", + "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=" + }, + "npm-install-checks": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-1.0.7.tgz", + "integrity": "sha1-bZGu2grJaAHx7Xqt7hFqbAoIalc=", + "requires": { + "npmlog": "0.1 || 1 || 2", + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-package-arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-4.1.0.tgz", + "integrity": "sha1-LgFfisAHN8uX+ZfJy/BZ9Cp0Un0=", + "requires": { + "hosted-git-info": "^2.1.4", + "semver": "4 || 5" + } + }, + "npm-registry-client": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-7.2.1.tgz", + "integrity": "sha1-x5ImawiMwxP4Ul5+NSSGJscj23U=", + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0", + "npmlog": "~2.0.0 || ~3.1.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + } + } + }, + "retry": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz", + "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=" + } + } + }, + "npm-user-validate": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-0.1.5.tgz", + "integrity": "sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs=" + }, + "npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "requires": { + "ansi": "~0.3.1", + "are-we-there-yet": "~1.1.2", + "gauge": "~1.2.5" + }, + "dependencies": { + "are-we-there-yet": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz", + "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + }, + "dependencies": { + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + } + } + }, + "gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "requires": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + }, + "dependencies": { + "has-unicode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.0.tgz", + "integrity": "sha1-o82Wwwe6QdVZxaLuQIwSoRxMLsM=" + }, + "lodash._baseslice": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash._baseslice/-/lodash._baseslice-4.0.0.tgz", + "integrity": "sha1-9c4d+YKUjsr/Y/IjhTQVt7l2NwQ=" + }, + "lodash._basetostring": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz", + "integrity": "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8=" + }, + "lodash.pad": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.4.0.tgz", + "integrity": "sha1-+qON8mwKaexQhqgiRslY4VDcsas=", + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.padend": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.5.0.tgz", + "integrity": "sha1-oonpN37i5t6Lp/EfOo6zJgcLdhk=", + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.padstart": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.5.0.tgz", + "integrity": "sha1-PqGQ9nNIQcM2TSedEeBWcmtgp5o=", + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.tostring": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.4.tgz", + "integrity": "sha1-Vgwn0fjq3eA8LM4Zj+9cAx2CmPs=" + } + } + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.1.tgz", + "integrity": "sha1-iXWQrNGu0zEbcDtYvMtNQ/VvKJU=" + }, + "osenv": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", + "integrity": "sha1-g88FxtZFj8TVrGNi6jJdkvJ1Qhc=", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.0.tgz", + "integrity": "sha1-43B4vGG1hpBjBTiXJX457BJhtwI=" + }, + "os-tmpdir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", + "integrity": "sha1-6bQjoe2vR5iCVi6S7XHXdDoHG24=" + } + } + }, + "qs": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.4.tgz", + "integrity": "sha512-E57gmgKXqDda+qWTkUJgIwgJICK7zgMfqZZopTRKZ6mY9gzLlmJN9EpXNnDrTxXFlOM/a+I28kJkF/60rqgnYw==" + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" + } + } + }, + "read-installed": { + "version": "4.0.3", + "resolved": false, + "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=" + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "resolved": false, + "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=", + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "util-extend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.1.tgz", + "integrity": "sha1-u3A7eUgCk93Nz7PGqf6iD0g0Fbw=" + } + } + }, + "read-package-json": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.4.tgz", + "integrity": "sha1-Ye0bIlbqQ42ACIlQkL6EuOeZyFM=", + "requires": { + "glob": "^6.0.0", + "graceful-fs": "^4.1.2", + "json-parse-helpfulerror": "^1.0.2", + "normalize-package-data": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "path-is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=" + } + } + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", + "requires": { + "jju": "^1.1.0" + }, + "dependencies": { + "jju": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz", + "integrity": "sha1-2t2e8BkkvHKLA/L3l5vb1i96Kqo=" + } + } + } + } + }, + "readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "requires": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + }, + "realize-package-specifier": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/realize-package-specifier/-/realize-package-specifier-3.0.1.tgz", + "integrity": "sha1-/eMukmRI44+ZM02Vt7CNUeOpjZ8=", + "requires": { + "dezalgo": "^1.0.1", + "npm-package-arg": "^4.0.0" + } + }, + "request": { + "version": "2.74.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz", + "integrity": "sha1-dpPKdou7DqXIzgjAhKRe+gW4kqs=", + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "bl": "~1.1.2", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~1.0.0-rc4", + "har-validator": "~2.0.6", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "node-uuid": "~1.4.7", + "oauth-sign": "~0.8.1", + "qs": "~6.2.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "~0.4.1" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz", + "integrity": "sha1-/efVKSRm0jDl7g9OA42d+qsI/GE=" + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "requires": { + "readable-stream": "~2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + } + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "~1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + } + } + }, + "extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "1.0.0-rc4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", + "integrity": "sha1-BaxrwiIntD5EYfSIFhVUaZ1Pi14=", + "requires": { + "async": "^1.5.2", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.10" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": ">= 1.0.0" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + } + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.x.x" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "jsprim": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz", + "integrity": "sha1-zi4b74NSBLTzCZkoxgL4tq5hVlA=", + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.2", + "verror": "1.3.6" + }, + "dependencies": { + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + }, + "json-schema": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", + "integrity": "sha1-UDVPGfYDkXxpX3C4Wvp3w7DyNQY=" + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "requires": { + "extsprintf": "1.0.2" + } + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "~1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + } + } + }, + "node-uuid": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "tough-cookie": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", + "integrity": "sha1-mcd9+7fYBCSeiimdTLD9gf7wg/0=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + } + } + }, + "retry": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz", + "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=" + }, + "rimraf": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "requires": { + "glob": "^7.0.5" + } + }, + "semver": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", + "integrity": "sha1-hfLPhVBGXE3wAM99hvawVBBqueU=" + }, + "sha": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sha/-/sha-2.0.1.tgz", + "integrity": "sha1-YDCCL70smCOUn49y7WQR7lzyWq4=", + "requires": { + "graceful-fs": "^4.1.2", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", + "integrity": "sha1-vsgb6ujPRVFovC5bKzH1vPrtmxs=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "process-nextick-args": "~1.0.0", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", + "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "process-nextick-args": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", + "integrity": "sha1-4nLu2CXV6fTqdNjXOx/jEcO+tjA=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "util-deprecate": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", + "integrity": "sha1-NVaj0TxMaqeYPX4kJUeBlxmbeIE=" + } + } + } + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, + "sorted-object": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.0.tgz", + "integrity": "sha1-HP6pgWCQR9gEOAekkKnZmzF/r38=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + }, + "umask": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz", + "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "^1.0.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.2.tgz", + "integrity": "sha1-1SsUtelnB3FECvIlvLVjEirEUvY=", + "requires": { + "spdx-exceptions": "^1.0.4", + "spdx-license-ids": "^1.0.0" + }, + "dependencies": { + "spdx-exceptions": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-1.0.4.tgz", + "integrity": "sha1-IguEI5EZrpBFqJLbgag/TOFvgP0=" + } + } + } + } + }, + "validate-npm-package-name": { + "version": "2.2.2", + "resolved": false, + "integrity": "sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU=", + "requires": { + "builtins": "0.0.7" + } + }, + "which": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.11.tgz", + "integrity": "sha1-yLLu6muMFln6fB3U/aq+lTPcXos=", + "requires": { + "isexe": "^1.1.1" + }, + "dependencies": { + "isexe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "integrity": "sha1-NvPiLmB1CSD15yQaR2qMakInWtA=" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "1.1.4", + "resolved": false, + "integrity": "sha1-sfUtwujcDjywTRh6JfdYo4qQyjs=", + "requires": { + "graceful-fs": "^4.1.2", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.1.tgz", + "integrity": "sha512-LQy1Q1fcva/UsnP/6Iaa4lVeM49WiOitu2T4hZCyA/elLKu37L99qcBJk4VCCk+rdLvnMzfKyiN3SZTqdAZGSQ==" + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nwmatcher": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", + "optional": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true + }, + "opn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", + "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "optional": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-cancelable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", + "dev": true + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "pacote": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.7.tgz", + "integrity": "sha512-ogxPor11v/rnU9ukwLlI2dPx22q9iob1+yZyqSwerKsOvBMhU9e+SJHtxY4y2N0MRH4/5jGsGiRLsZeJWyM4dQ==", + "dev": true, + "requires": { + "@npmcli/git": "^2.0.1", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.8.2", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^9.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "dependencies": { + "@npmcli/installed-package-contents": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "@npmcli/run-script": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.5.tgz", + "integrity": "sha512-NQspusBCpTjNwNRFMtz2C5MxoxyzlbuJ4YEhxAKrIonTiirKDtatsZictx9RgamQIx6+QuHMNmPl0wQdoESs9A==", + "dev": true, + "requires": { + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "infer-owner": "^1.0.4", + "node-gyp": "^7.1.0", + "read-package-json-fast": "^2.0.1" + }, + "dependencies": { + "@npmcli/promise-spawn": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", + "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + } + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "optional": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "~2.3" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "plantuml-encoder": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.4.0.tgz", + "integrity": "sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==" + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "optional": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "optional": true, + "requires": { + "asap": "~2.0.3" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "dependencies": { + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + } + } + }, + "promised-handlebars": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/promised-handlebars/-/promised-handlebars-1.0.6.tgz", + "integrity": "sha1-2ZfglDsD9j/oL/I8uQSyes/AUNg=", + "requires": { + "deep-aplus": "^1.0.2", + "q": "^1.4.1" + } + }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=" + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "optional": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "puppeteer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.3.0.tgz", + "integrity": "sha512-23zNqRltZ1PPoK28uRefWJ/zKb5Jhnzbbwbpcna2o5+QMn17F0khq5s1bdH3vPlyj+J36pubccR8wiNA/VE0Vw==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" + }, + "q-deep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/q-deep/-/q-deep-1.0.3.tgz", + "integrity": "sha1-zQcD2irMuuZXDmAMaKVt5mEHkMs=", + "requires": { + "deep-aplus": "^1.0.1", + "q": "^1.1.2" + } + }, + "q-plus": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/q-plus/-/q-plus-0.0.8.tgz", + "integrity": "sha1-TMZssZvRRbQ+nhtUAjYUI3e2Hqs=", + "requires": { + "q": "^1.1.2" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, + "rc-config-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-3.0.0.tgz", + "integrity": "sha512-bwfUSB37TWkHfP+PPjb/x8BUjChFmmBK44JMfVnU7paisWqZl/o5k7ttCH+EQLnrbn2Aq8Fo1LAsyUiz+WF4CQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "js-yaml": "^3.12.0", + "json5": "^2.1.1", + "require-from-string": "^2.0.2" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + } + }, + "read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "read-package-json-fast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz", + "integrity": "sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==", + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + } + } + }, + "request-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", + "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "requires": { + "lodash": "^4.17.19" + }, + "dependencies": { + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requireg": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz", + "integrity": "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==", + "dev": true, + "requires": { + "nested-error-stacks": "~2.0.1", + "rc": "~1.2.7", + "resolve": "~1.7.1" + }, + "dependencies": { + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", + "requires": { + "glob": "^7.1.3" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "semver-utils": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz", + "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.x.x" + } + }, + "socks": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.5.1.tgz", + "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", + "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4", + "socks": "^2.3.3" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": ">=0.0.4" + } + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + }, + "spawn-please": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-0.3.0.tgz", + "integrity": "sha1-2zOOxM/2Orxp8dDgjO6euL69nRE=", + "dev": true + }, + "spawn-shell": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spawn-shell/-/spawn-shell-2.1.0.tgz", + "integrity": "sha512-mjlYAQbZPHd4YsoHEe+i0Xbp9sJefMKN09JPp80TqrjC5NSuo+y1RG3NBireJlzl1dDV2NIkIfgS6coXtyqN/A==", + "dev": true, + "requires": { + "default-shell": "^1.0.1", + "merge-options": "~1.0.1", + "npm-run-path": "^2.0.2" + } + }, + "spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "requires": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "requires": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stack-chain": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", + "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==", + "optional": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "requires": { + "duplexer": "~0.1.1" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-equal": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/stream-equal/-/stream-equal-0.1.13.tgz", + "integrity": "sha1-F8LXz43lVw0P+5njpRQqWMdrxK4=", + "requires": { + "@types/node": "*" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "svgexport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/svgexport/-/svgexport-0.4.1.tgz", + "integrity": "sha512-qRQuxZA6gT34xMs+9m/BGVlxFxQ1ftLi1HB1gUiOGYrp/Jm6whhTZEmYchQFy+wHKGdkyLB93w5MXoEcNtbcNg==", + "requires": { + "async": "^3.2.0", + "puppeteer": "^3.0.2" + } + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I=", + "optional": true + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "optional": true + }, + "trace": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/trace/-/trace-3.1.1.tgz", + "integrity": "sha512-iVxFnDKps8bCRQ6kXj66rHYFJY3fNkoYPHeFTFZn89YdwmmQ9Hz97IFPf3NdfbCF3zuqUqFpRNTu6N9+eZR2qg==", + "optional": true, + "requires": { + "stack-chain": "^2.0.0" + } + }, + "trace-and-clarify-if-possible": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trace-and-clarify-if-possible/-/trace-and-clarify-if-possible-1.0.5.tgz", + "integrity": "sha512-CmBz2eGrPxQ5miq51B4XnON0iC62q6q7CEzrRaFYZYi8xdX1ivafyk5cYshmVXp6p14cYvK3H4o1drYa3MEJOA==", + "requires": { + "clarify": "^2.1.0", + "trace": "^3.1.1" + } + }, + "treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "optional": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=" + }, + "unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "webidl-conversions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz", + "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=", + "optional": true + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "whatwg-url-compat": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz", + "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=", + "optional": true, + "requires": { + "tr46": "~0.0.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "optional": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "yargs-unparser": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.4.tgz", + "integrity": "sha512-QxEx9+qEr7jwVM4ngnk95+sKZ5QXm5gx0cL97LDby0SiC8HHoUK0LPBg475JwQcRCqIVfMD8SubCWp1dEgKuwQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "decamelize": "^1.2.0", + "flat": "^5.0.2", + "is-plain-obj": "^1.1.0", + "yargs": "^14.2.3" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} \ No newline at end of file diff --git a/legacy/package.json b/legacy/package.json new file mode 100644 index 000000000..f3417fe6d --- /dev/null +++ b/legacy/package.json @@ -0,0 +1,72 @@ +{ + "name": "documentation", + "version": "11.3.2", + "description": "Mojaloop Documentation GitBook Project", + "dependencies": { + "express": "4.17.1", + "gitbook-cli": "2.3.2", + "gitbook-plugin-back-to-top-button": "0.1.4", + "gitbook-plugin-changelog": "1.0.1", + "gitbook-plugin-collapsible-chapters": "0.1.8", + "gitbook-plugin-editlink": "1.0.2", + "gitbook-plugin-fontsettings": "2.0.0", + "gitbook-plugin-include": "0.1.0", + "gitbook-plugin-insert-logo": "0.1.5", + "gitbook-plugin-page-toc": "1.1.1", + "gitbook-plugin-plantuml-svg": "1.0.1", + "gitbook-plugin-swagger": "0.2.0", + "gitbook-plugin-theme-api": "1.1.2", + "gitbook-plugin-uml": "1.0.1", + "gitbook-plugin-variables": "1.1.0", + "svgexport": "0.4.1" + }, + "devDependencies": { + "directory-tree": "^2.2.5", + "got": "^11.8.0", + "husky": "^4.2.5", + "license-checker": "25.0.1", + "node-plantuml": "^0.5.0", + "npm-audit-resolver": "2.2.1", + "npm-check-updates": "7.0.2", + "plantuml-encoder": "^1.4.0", + "strip-comments": "^2.0.1", + "svgo": "^1.3.2" + }, + "scripts": { + "audit:check": "SHELL=sh check-audit", + "audit:resolve": "SHELL=sh resolve-audit", + "build:plantuml:all": "./scripts/_build_plantuml_all.sh", + "build:plantuml:diff": "./scripts/_build_plantuml_diff.sh", + "dep:check": "npx ncu -e 2", + "dep:update": "npx ncu -u", + "docker:build": "docker build --no-cache -t mojaloop/documentation .", + "docker:push": "docker push mojaloop/documentation", + "docker:run": "docker run --rm -it --name mojadoc -p 8989:8989 mojaloop/documentation", + "express:run": "node index.js", + "gitbook:build": "gitbook build", + "gitbook:export:pdf": "gitbook pdf ./", + "gitbook:install": "gitbook install", + "gitbook:serve": "gitbook serve --port 8989", + "gitbook:serveNoReload": "gitbook serve --no-live --port 8989", + "license:check": "npm run license:list -- --failOn `cat .licensebanned | grep '^[^#;]' | awk 'BEGIN { ORS=\"\" } { print p$0\";\"; } END { print \n }'`", + "license:list": "license-checker . --excludePackages `cat .licenseignore | grep '^[^#;]' | awk 'BEGIN { ORS=\"\" } { print p$0\";\"; } END { print \n }'` --production --csv", + "run": "npm run gitbook:serve", + "start": "npm run gitbook:serveNoReload" + }, + "husky": { + "hooks": { + "pre-commit": "npm run build:plantuml:diff", + "post-commit": "git update-index --again" + } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/mojaloop/documentation.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/mojaloop/documentation/issues" + }, + "homepage": "https://github.com/mojaloop/documentation#readme" +} diff --git a/publish-gh-pages.sh b/legacy/publish-gh-pages.sh similarity index 100% rename from publish-gh-pages.sh rename to legacy/publish-gh-pages.sh diff --git a/legacy/quality-security/assets/cqs_overview.drawio b/legacy/quality-security/assets/cqs_overview.drawio new file mode 100644 index 000000000..85bb9fe29 --- /dev/null +++ b/legacy/quality-security/assets/cqs_overview.drawio @@ -0,0 +1 @@ +1ZZNc9sgEIZ/jY6ZESA57tFV7bSdeKapD8mVSFiiRaBiZMv59V0E+oqaTjNNMq0PGngXdlmeXckBScrmStOq2KqMiQCHWROQDwHGSxTD0wpnJ8SdkGueOQkNwo4/MC+GXq15xg6ThUYpYXg1FVMlJUvNRKNaq9N02V6JadSK5mwm7FIq5uotz0zh04rDQf/IeF50kVHoLSXtFnvhUNBMnUYSWQck0UoZNyqbhAl7d929uH2bJ6z9wTST5k82bL+d764/31xvYp7ebh9oc1ceLyLn5UhF7RMO8EKAv/f3MMjtoBP2CuJAGubs72bxo1ad4eLQklvBAoSqZjB2Xm5qKrg5B/aQIIY7lta6FZx3OLcLMA0K8uggeBIfa1XLjNn0EJhPBTdsV9HUWk9QjKAVphTebL378kIE5lSn3RRmR6YNB+orwXMJmlGV35MooXQbj2zan9W5ECOdLKPV5Qr0g9HqO+ssUknWH9sGYM2T6FBfENBITJXMaHtXTV9VbotvIhQt3Pw0lCR559cUo3LE2AOmvg3y3vdQKTDwxfKMwkGzwvmiVa5pCeKWSmiL0ib3V8gGRLgD6D2Fj4DGcygoJDja/Abi68FaTmEtyQwWwr+AhZbhK8HCM1g7Q2VGdXZoG3JBS3v17gnKlX3pCi7hxfuWAJ8D6hHtaBNFcfIyAHEU/2sAyQzgV7ZnkBBcPA4/lZVo240aruT/ggwneN026AsgI5fk7ZDBdPhqt7bRXx+y/gk= \ No newline at end of file diff --git a/legacy/quality-security/assets/cqs_overview.svg b/legacy/quality-security/assets/cqs_overview.svg new file mode 100644 index 000000000..99bedbfb2 --- /dev/null +++ b/legacy/quality-security/assets/cqs_overview.svg @@ -0,0 +1,3 @@ + + +
    Quality + Security
    Quality + Security
    Program Management
    Program Manageme...
    Standards & Guidelines
    Standards & Guid...
    Reference Implementation
    Reference Implem...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/legacy/quality-security/program-management/readme.md b/legacy/quality-security/program-management/readme.md new file mode 100644 index 000000000..10be50e8e --- /dev/null +++ b/legacy/quality-security/program-management/readme.md @@ -0,0 +1,77 @@ +# Program Management + +This section provides an overview of Mojaloop's Risk and Security Management Initiatives. + +**Who is this for?** +*Risk Management, Compliance, Governance, Regulatory, and Leadership Stakeholders* + +## 1. Mojaloop Data Security and Privacy Program: +### 1.1 Code Quality & Security Program Overview + +**Objective:** Continuously improve the Trust (reliability, transparency, privacy, quality, and security) of the Mojaloop System. + +**Delivery Model:** Supports both functional and non-functional requirements of the project, working alongside with other workstreams & various governance committees on a shared responsibility Model. + +#### Approach: +- Standards and Control Centric – Define and maintain Mojaloop software quality and security standards and guidelines – In certain areas we provide reference implementation. +- Risk and Threat Centric – Perform risk and threat modelling to identify, validate, classify & prioritize security requirements. + +#### Key Milestones: +- PI 1 – 8: Foundation Phase - Built-in confidentiality and Integrity as part of the Core Mojaloop Architecture. + - Developed and Implemented (To some degree) Signatures, MTLS, PKI, encryption standards + - Established a code quality and security framework - DevOps & CI/CD Tools automation, workflows & policies +- PI 9 – Current: Improvement Phase – Consolidate, optimize & improve. + - Introduced a risk and threat driven approach + - Baselining Mojaloop against best practice standards – PCI DSS and GDPR + - Focus on the data – Data Protection Standards and Introduction of a Cryptographic Processing Module (CPM) + +#### Guiding Principles: +- We endeavor to ensure that our policy and governance framework is as lightweight as possible to encourage community volunteers to contribute freely and easily. +- The overarching aim of the Code is to prescribe the use of certain quality/security practices and techniques delivered as guidelines and in some areas, we have reference technology implementations whereas for other areas we require certain policies or standards to be adhered to and verifiable. + +### 1.2 Current PI Objectives (PI 12) + +1. Enhance security in new functionality additions +2. Support major implementations +3. Design a secure cryptographic processing module +4. Improve data protection measures and controls +5. Baselining of Mojaloop against industry standards +6. Maintain and enhance secure DevOps/CI CD practices +7. Improve communication and community engagement +8. Improve access control measures + +#### Epics: +1. Data Protection and Privacy +2. Core Functionality Support +3. Implementation Support +4. Community Engagement +5. Identity and Access Management +6. DevSecOps Integration +7. Cryptography Support +8. Standard Baselining + +### 1.3 PI Reports (8 – 10) + +1. [PI 8](https://raw.githubusercontent.com/mojaloop/documentation-artifacts/master/presentations/September%202019%20PI-8_OSS_community%20session/cqs_pi_08_report.pdf) +2. [PI 9](https://raw.githubusercontent.com/mojaloop/documentation-artifacts/master/presentations/January%202020%20OSS%20Community%20Session/cqs_pi_09_report.pdf) +3. [PI 10](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/April%202020%20Community%20Event/Presentations/code_quality_and_security-PI%2010%20final.pdf) +4. [PI 11](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/July%202020%20Community%20Event/Presentations/Code%20Quality%20Security%20PI%2010%20Report%20-%2020%20July%202020%20v1.9%20Final.pdf) +5. PI 12 _(link coming soon)_ + +### 1.4 Vulnerability disclosure procedure + +See [Vulnerability Disclosure Procedure](./vulnerability-disclosure-procedure.md) for more information + + +## 2. Scheme Rules Risk Management, Security, Privacy and Data Confidentiality + +See [Scheme Rules Guidelines](./scheme-rules-guidelines.md) for more information + +## 3. Standard Baselining Reports + +- [GDPR Scoping Analysis Report](https://raw.githubusercontent.com/mojaloop/documentation-artifacts/master/reference/gdpr_scope_analysis_report.pdf) +- [PCI DSS Baseline report and recommendations – Responsibility matrix (Hub/Switch)](https://github.com/mojaloop/documentation-artifacts/raw/mojaloop/reference/Mojaloop%20PCI%20DSS%20Compliace%20Baseline%20Requirement%20Overall%20Report%20v1.0%2005012021.xlsx) + +## 4. Code Security Overview + +Refer to [this presentation](https://raw.githubusercontent.com/mojaloop/documentation-artifacts/master/reference/code_security_overview.pdf) for an overview of the Code Security Practices in the Mojaloop Community. \ No newline at end of file diff --git a/legacy/quality-security/program-management/scheme-rules-guidelines.md b/legacy/quality-security/program-management/scheme-rules-guidelines.md new file mode 100644 index 000000000..b2536916e --- /dev/null +++ b/legacy/quality-security/program-management/scheme-rules-guidelines.md @@ -0,0 +1,51 @@ +# Security, Risk Management, and Data Confidentiality + +> Note: this document is a reference from the [Scheme Business Rules](https://docs.mojaloop.io/mojaloop-business-docs/documents/scheme-business-rules.html) +> Please refer to [Mojaloop Business Docs](https://docs.mojaloop.io/mojaloop-business-docs/) for more information and context + +## 1.1 Confidentiality and Protection of Personal Information +- Confidential Information of the Scheme that is disclosed to Participants will be held in confidence by Participants and will be used only for the purposes permitted by the Rules. Scheme Confidential Information may include proprietary technology and other matters designated by the Scheme. +- Transaction data will not be owned by the Scheme and will be owned by a Participant as it relates to its Customer's Transactions. +- The confidentiality of Transaction data and any Personal Information processed in the Platform will be protected by the Scheme and Participants according to Applicable Law. +- Statistics or data which identify a Participant or from which the Participant may be identified will not be disclosed to other Participants. The Scheme may prepare for internal use and disclose to third parties for promotional purposes statistics based on aggregate, anonymized data as permitted by Applicable Law. +- The Scheme will make disclosures of Confidential Information to comply with Applicable Law or the directive of a Regulatory Authority. +- The Scheme will protect Personal Information in its possession or under its control from misuse and otherwise treat such information in accordance with Applicable Law protecting privacy of individuals. +- The Scheme will maintain industry leading security measures to protect information from unauthorized access and use. +- Participants will notify the Scheme and acknowledge that the Scheme may notify other Participants, of any Security Incident in the systems or premises of the Participant, its affiliated entities or any third-party vendor engaged by the Participant to provide services in support of the Participant's participation in the Scheme. +- The Scheme may conduct investigations into Security Incidents. Participants will cooperate fully and promptly with the investigation. Such investigations will be at the expense of the affected Participant. +- The Scheme may require a Participant to conduct investigations of Security Incidents and may require that such investigations be conducted by qualified independent security auditors acceptable to the Scheme. +- The Scheme may impose conditions of continued participation on the affected Participant regarding remedy of the causes of the Security Incident and ongoing security measures. +- The investigation and report, as well as remedies that may be required will be held confidential to the extent permitted by Applicable Law. + +## 1.2 Risk Management Policies + +This section assumes that the development of risk management policies by the Scheme and its participants will be evolving. This section contemplates that some of these policies will (eventually) be in the Rules; others will not + +- Risk management policies and procedures may be stated in the Rules, in Associated Documents, or in other written policy documents created by the Scheme and distributed to Participants +- Risk management policies and procedures will include fiscal soundness, system integrity, compliance with Applicable Law, particularly as to Anti-Money Laundering/Combatting Terrorism Financing measures, privacy of personal information and data security +- Risk management functions include procedures applicable to Participants for monitoring of risks, including reporting requirements and audits + + +## 1.3 Business Continuity +- Provisions to ensure business continuity on the part of the Scheme, its vendors, and Participants. + + +## Appendix: Risk Management, Security, Privacy, and Service Standards +> Schemes may or may not want to specify standards or require that Participants comply with other established standards. Schemes may furthermore specify different standards for different categories of Participants. The list below is given purely as an example. + +Participants must adhere to the following practices of service quality security, data privacy and customer service as they apply to a Participant in connection with the Scheme. +- Participants will establish a risk management framework for identifying, assessing and controlling risks relative to their use of the Scheme. +- Participants will ensure that the systems, applications and network that support the use of the Scheme are designed and developed securely. +- Participants will implement processes to securely manage all systems and operations that support the use of the Scheme. +- Participants will implement processes to ensure that systems used for the Scheme are secure from unauthorized intrusion or misuse. +- Participants will implement processes to ensure the authentication of their customers in creating and approving transactions that use the Scheme. +- Participants will develop effective business continuity and contingency plans. +- Participants will manage technical and business operations to allow timely responses to API calls received from the Scheme Platform or from other Participants via the Scheme Platform. +- Participants will establish written agreements governing their relationship with agents, processors, and other entities providing outsourced services that pertain to the Scheme. +- Participants will develop policies and processes for ongoing management and oversight of staff, agents, processors, and other entities providing outsourced services that pertain to the Scheme. +- Participants will ensure that customers are provided with clear, prominent, and timely information regarding fees and terms and conditions with respect to services using the Scheme. +- Participants will develop and publish customer service policies and procedures with respect to services using the Scheme. +- Participants will provide an appropriate mechanism for customers to address questions and problems. Participants will specify how disputes can be resolved if internal resolution fails. +- Participants will comply with good practices and Applicable Laws governing customer data privacy. +- Participants will ensure that Customers are provided with clear, prominent, and timely information regarding their data privacy practices. + diff --git a/legacy/quality-security/program-management/vulnerability-disclosure-procedure.md b/legacy/quality-security/program-management/vulnerability-disclosure-procedure.md new file mode 100644 index 000000000..a8770999d --- /dev/null +++ b/legacy/quality-security/program-management/vulnerability-disclosure-procedure.md @@ -0,0 +1,35 @@ +# Mojaloop Vulnerability Reporting Procedure + +## Overview + +This procedure is for guiding the public on how security vulnerabilities should be reported safely and responsibly to the dedicated security team within Mojaloop. As representatives of the Mojaloop Community, we strongly encourage everyone to alert us of the potential security vulnerabilities privately first, before disclosing them in a public forum – a right everyone is entitled to without any permission whatever from us as the maintainer of the platform. + +## Contacts + +Contact security@mojaloop.io to report a security vulnerability in the Mojaloop codebase. + +We cannot accept regular bug reports or other security related queries at these addresses. All mail sent to these addresses that does not relate to an undisclosed security problem in an Mojaloop project will be ignored. + +NB. Security vulnerabilities should not be entered in a project's public bug tracker unless the necessary configuration is in place to limit access to the issue to only the reporter and the project security team. + +## Reporting Format +Please send one plain-text email for each vulnerability you are reporting. We may ask you to resubmit your report if you send it as an image, movie, HTML, or PDF attachment when it could just as easily be described with plain text. + +## Vulnerability Types + +We have no restrictions whatsoever for the vulnerability type or method used to uncover the vulnerabilities. The public is welcome to use any methods or tools available to them, including analysis of the source, and apply any methodology of their own in finding vulnerabilities, provided that the vulnerability report is clear and self-descriptive. + +## Advance Security + +We use standard TLS encryption in our mail systems however should the reporter requires additional layer security before sending the info then we are flexible to cater for that on a case by case basis by contacting godfreyk@crosslaketech.com + +## Vulnerability Information + +Further information regarding handling of published vulnerabilities for an Mojaloop project can usually be found on the project’s GitHub Account. If you cannot find the information you are looking for on GitHub, you should ask your question on the project's user mailing list above. + +## Vulnerability Handling +An overview of the vulnerability handling process is: +1. The reporter reports the vulnerability privately to Mojaloop. +2. The appropriate project's security team works privately with the reporter to resolve the vulnerability. +3. A new release of the Mojaloop package concerned is made that includes the fix. +4. The vulnerability is publicly announced to the Mojaloop Community diff --git a/legacy/quality-security/readme.md b/legacy/quality-security/readme.md new file mode 100644 index 000000000..e6789cdbe --- /dev/null +++ b/legacy/quality-security/readme.md @@ -0,0 +1,17 @@ +# Quality & Security + + + +The Quality and Security effort in Mojaloop is focused on delivering high quality, secure, and maintable software. This spans from recommending best practices for deployers to architecting processes to ensure that our code is scanned for vulnerabilities and security patches are applied regularly. + +## Overview + +We break down this effort into the following three categories: + +1. [Program Management](./program-management/readme.md) +1. [Standards + Guidelines](./standards-guidelines/readme.md) +1. [Reference Implementation](./reference-implementation.md) + +## Other Links + +- [Summary of the Snyk investigation](./snyk_investigation.md) diff --git a/legacy/quality-security/reference-implementation.md b/legacy/quality-security/reference-implementation.md new file mode 100644 index 000000000..bf62b0140 --- /dev/null +++ b/legacy/quality-security/reference-implementation.md @@ -0,0 +1,22 @@ +# Reference Implementation + +> Reference implementations are standard, and guidelines as applied on the Mojaloop standard API. The target audience is architects, DevOps teams, security engineering, QA teams and Developers. + + +## 1. Architectural Implementations +- 1. [Signature Standard](https://docs.mojaloop.io/mojaloop-specification/documents/Signature.html) +- 2. [Encryption Standard](https://docs.mojaloop.io/mojaloop-specification/documents/Encryption.html) +- 3. [Interledger Cryptographic interlock](https://docs.mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#4-interledger-protocol) +- 4. [Secure PISP Account Linking](https://github.com/mojaloop/pisp/tree/master/docs/linking) +- 5. [Certificate Management (MCM)](https://github.com/modusbox/connection-manager-api) + +## 2. Code level security measures +- 1. Open Source Vulnerability Management + - i. [`npm`](https://github.com/modusbox/connection-manager-api) + `npm-audit-resolver` + - ii. [GitHub/Dependabot](https://github.blog/2020-06-01-keep-all-your-packages-up-to-date-with-dependabot/) +- 2. Open Source License Management - NPM Audit, [license-scanner](https://github.com/mojaloop/license-scanner) +- 3. Static Code Analysis – SonarQube _in progress, details coming soon_ +- 4. Container Security + - i. [Anchore-cli](https://github.com/mojaloop/ci-config#container-scanning) + + \ No newline at end of file diff --git a/code_quality_security/snyk_investigation.md b/legacy/quality-security/snyk_investigation.md similarity index 100% rename from code_quality_security/snyk_investigation.md rename to legacy/quality-security/snyk_investigation.md diff --git a/legacy/quality-security/standards-guidelines/audit_logging_standard.md b/legacy/quality-security/standards-guidelines/audit_logging_standard.md new file mode 100644 index 000000000..6f166062f --- /dev/null +++ b/legacy/quality-security/standards-guidelines/audit_logging_standard.md @@ -0,0 +1,71 @@ +# Audit Logging Standard + +| | | +|---|---| +|version| `v1.0`| + + +In order for audit logs to be useful, they must record sufficient information to serve the operational needs, preserve accountability, and detect malicious activity. This standard defines these events and content recommended to be captured in a Mojaloop implementation. Running applications and infrastructure components will produce audit records for at least the following events: +1. System start-up and shutdown +2. User logon and logoff +3. Privilege escalation +4. Account creation +5. Password changes + +Information systems should produce audit records for the following event types, depending on system capabilities: +1. Starting and stopping of processes and services / applications or APIs +2. Addition of modules / libraries to an application +3. Installation of patches and updates +4. Compiling of code within the environment +5. Initialization of a new pod or container within a cluster +6. Installation and removal of software +7. System alerts and error messages +8. System administration activities across applications and infrastructure +9. Access (as well as attempts to access) to and modification of Restricted Data + + +Audit logs create records that help you track access to the Mojaloop environment. Therefore, a complete audit log needs to include, at a minimum all or a combination of: +- Capture CRUD actions in systems and databases and operational use cases. This will ensure all actions that result in Creation, Read, Update and Delete actions are captured with relevant details as below. +- Record / Artifact ID +- Audit log ID and sequence number (tracking sequence of Audit logs ensures we can detect audit log deletion) +- Event type, status, and/or error codes +- Service/command/application name +- User or system account associated with an event +- Device used (e.g. source and destination IPs, terminal session ID, web browser, etc.) +- User IDs +- Date and time records for when Users log on and off the system +- Terminal ID +- Access to systems, applications, and data – whether successful or not +- Files accessed +- Networks access +- System configuration changes +- System utility usage +- Exceptions +- Security-related events such as triggered alarms +- Protection system notifications (i.e. intrusion detection or anti-malware notifications) +- Source and destination IP addresses + + +## Importance of Audit Logs + +Audit logging provides a historical account of all activities done by actors within a Mojaloop ecosystem. It will help Mojaloop implementations in the following ways: + +1. **Threat Detection Analytics** – Through audit logs it is possible for Mojaloop switch operators to track changes and detect possible anomalies and identify malicious actions and trigger appropriate responses. This will go a long way in mitigating against possible fraud at DFSP and switch level. +2. **Customer Forensics** – In cases of queries from DFSPs, audit logs can assist give a forensic breakdown of transaction details as well as actions by authorized switch actors. +3. **Compliance** – Compliance standards such as GDPR have requirements to extract “all” customer data and also “delete” all customer data. For this to be possible, the audit data may also need to be extracted and preserved/deleted as appropriate. Audit logs are a critical requirement in most global best practice standards and regulatory frameworks such as PCI-DSS and GDPR. + + +## Recommended logging standards + +| Item | Description | +| ---- | ----------- | +| **Ensure audit logs are in a format that is
    useful for human interrogation as well as machine analysis.** | In order to get the most out of your logs, you need to make your logs both readable for humans and structured for machines. Use a standard structured format like JSON where applicable. | +| **Have uniform log structure across all
    applications and infrastructure** | A prerequisite for good logging is to have a standard structure of your log file, which would be consistent across all log files.
    Each log line should represent one single event and contain at least the timestamp, the hostname, the service and the logger name. | +| **Develop metrics for your logs** | The common metric types are:

    Meter – measures the rate of events (e.g. rate of visitors to your website)
    Timer – measures the time some procedure takes (e.g. your webserver response time)
    Counter – increment and decrement an integer value (e.g. number of signed-in users)
    Gauge – measure an arbitrary value (e.g. CPU)

    track and log metrics, or alternatively store metrics separately from your logs. | +| **Provide adequate context in log entries** | Each log line should contain enough information to make it easy to understand exactly what was going on, and what the state of the application was during that time. | +| **Use an appropriate logging framework** | Logging frameworks enable you to set up different appenders, each with its output formats and its custom log pattern. Popular logging frameworks are log4j and log4net among others. | +| **Log security audit logs as well as application
    uptime event logs** | Application Event Log – This logging most often has to do with program level events, such as administrative actions and abnormal related events that technical staff use for debugging software problems. This identifies system problems before they are big enough to cause harm, such as system outages or failures, which can hinder productivity.

    Application Audit Log – Audit logs capture events which can show “who” did “what” activity and “how” the system behaved. These logs most often refers to user level transactions, such as a change to a financial record that was made by ‘Allan Smith’ at ‘21:00HRS’ on ‘May 12, 2019.’ | +| **Do not log sensitive information** | Ensure application logs do not contain sensitive information such as passwords, PII data and any information that may aid an attacker to gain further access to a network / application as much as possible.

    Lower exposure by not logging sensitive data or by scrubbing it before it is transmitted. | +| **Use fault tolerant protocols to transmit audit logs** | TCP or RELP (Reliable Event Logging Protocol) can be used to transmit logs instead of UDP, which can lose packets. Automatically retry if sending fails.| +| **Set up audit log access controls** | Set up adequate controls to restrict who can access, query, and administer audit log servers. This can be handled by third party tools that integrate with the logging server.

    NIST recommends that organizations create and maintain a secure log management infrastructure. | + diff --git a/legacy/quality-security/standards-guidelines/log_analysis_report.md b/legacy/quality-security/standards-guidelines/log_analysis_report.md new file mode 100644 index 000000000..03c558e16 --- /dev/null +++ b/legacy/quality-security/standards-guidelines/log_analysis_report.md @@ -0,0 +1,97 @@ +## Log Analysis Report – 03 Oct 2020 + +Below is a summary of the log analysis performed on Mojaloop on the 3rd Oct 2020 + +| Service | Mojaloop State | PII Data | Other Observations | +| ------- | -------------- | -------- | ------------------ | +| account-lookup | fresh-install | NONE | | +| bulk-api-adapter | fresh-install | NONE | | +| central-event-processor | fresh-install | NONE | MySQL Root password in log |s| +| central-ledger | fresh-install | NONE | MySQL root password in logs

    SQL script creating user contains password| +| central-settlement | fresh-install | NONE | | +| cl-handler-bulk-transfer-fulfil/prepare/process | fresh-install | NONE | | +| emailnotifier | fresh-install | NONE | | +| finance-portal | fresh-install | NONE | | +| finance-portal-settlement-management | fresh-install | NONE | Mysql centalledger passwor |d| +| kafka-broker | fresh-install | NONE | | +| kafka-metrics | fresh-install | NONE | | +| kafka-exporter | fresh-install | NONE | | +| ml-api-adapter | fresh-install | NONE | | +| ml-api-adapter-handler-notification| | fresh-install | NONE | | +| mongodb | fresh-install | NONE | | +| quoting-service | fresh-install | NONE | | +| sim-payeefsp-backend | fresh-install | NONE | | +| sim-payeefsp-cache | fresh-install | NONE | | +| sim-payeefsp-scheme-adapter | fresh-install | NONE | | +| sim-testfsp1-backend | fresh-install | NONE | | +| sim-testfsp1-cache | post-seeding | NONE | | +| sim-testfsp1-scheme-adapter | post-seeding | NONE | | +| account-lookup | post-seeding | YES | | +| bulk-api-adapter | post-seeding | NONE | | +| central-event-processor | post-seeding | NONE | | +| central-ledger | post-seeding | NONE | MySQL root password in logs

    SQL script creating user contains password | +| central-settlement | post-seeding | NONE | +| cl-handler-bulk-transfer-fulfil/prepare/process | post-seeding | NONE | +| emailnotifier | post-seeding | NONE | +| finance-portal-cmg-backend | post-seeding | NONE | MySQL Root password in logs
    Testkey and Testsecret
    azureclientID || +| finance-portal-cmg-frontend | post-seeding | NONE | +| finance-portal-settlement-management | post-seeding | NONE | Mysql centalledger password| +| kafka-broker | post-seeding | NONE | | +| kafka-metrics | post-seeding | NONE | | +| kafka-exporter | post-seeding | NONE | | +| ml-api-adapter | post-seeding | NONE | | +| ml-api-adapter-handler-notification | post-seeding | NONE | | +| mongodb | post-seeding | NONE | | +| quoting-service | post-seeding | NONE | | +| sim-payeefsp-backend | post-seeding | NONE | | +| sim-payeefsp-cache | post-seeding | NONE | | +| sim-payeefsp-scheme-adapter | post-seeding | NONE | | +| sim-testfsp1-backend | post-seeding | NONE | | +| sim-testfsp1-cache | post-seeding | NONE | | +| sim-testfsp1-scheme-adapter | post-seeding | NONE | | +| account-lookup-mysql-database | post-golden-path-tests | NONE | MySQL root password in logs

    SQL script creating service users contains password | +| account-lookup-mysql-logs | post-golden-path-tests | NONE | | +| account-lookup-mysql-metrics | post-golden-path-tests | NONE | | +| account-lookup-service | post-golden-path-tests | YES | | +| account-lookup-service-sidecar | post-golden-path-tests | NONE | | +| account-lookup-service-admin | post-golden-path-tests | NONE | | +| account-lookup-service-admin-sidecar | post-golden-path-tests | NONE | | +| bulk-api-adapter-handler-notification | post-golden-path-tests | NONE | | +| bulk-api-adapter | post-golden-path-tests | NONE | | +| bulk-api-adapter-service | post-golden-path-tests | NONE | | +| central-event-processor | post-golden-path-tests | NONE | | +| central-event-handler-admin-transfer | post-golden-path-tests | NONE | | +| central-event-handler-timeout | post-golden-path-tests | NONE | | +| central-event-handler-transfer-util | post-golden-path-tests | NONE | | +| central-event-handler-transfer-fulfil | post-golden-path-tests | NONE | | +| central-event-handler-transfer-get | post-golden-path-tests | NONE | | +| central-event-handler-transfer-position | post-golden-path-tests | NONE | | +| central-event-handler-transfer-prepare | post-golden-path-tests | NONE | | +| central-ledger-mysql-0-database | post-golden-path-tests | NONE | MySQL root password in logs

    SQL script creating user contains password | +| central-ledger-mysql-0-log | post-golden-path-tests | NONE | | +| central-ledger-mysql-0-metrics | post-golden-path-tests | NONE | | +| central-ledger-service | post-golden-path-tests | NONE | | +| central-settlement | post-golden-path-tests | NONE | | +| cl-handler-bulk-transfer-fulfil/prepare/process | post-golden-path-tests | NONE | | +| emailnotifier | post-golden-path-tests | NONE | | +| finance-portal-cmg-backend | post-golden-path-tests | NONE | | +| finance-portal-cmg-frontend | post-golden-path-tests | NONE | | +| finance-portal-settlement-management | post-golden-path-tests | NONE | Mysql centalledger password| +| kafka-broker | post-golden-path-tests | NONE | | +| kafka-metrics | post-golden-path-tests | NONE | | +| kafka-exporter | post-golden-path-tests | NONE | | +| ml-api-adapter | post-golden-path-tests | NONE | | +| ml-api-adapter-handler-notification | post-golden-path-tests | NONE | | +| ml-api-adapter-handler-adapter-service | post-golden-path-tests | NONE | | +| ml-api-adapter-handler-adapter-service-sidecar | post-golden-path-tests | NONE | | +| mongodb | post-golden-path-tests | NONE | | +| quoting-service | post-golden-path-tests | YES | | +| quoting-service-sidecar | post-golden-path-tests | NONE | | +| sim-payeefsp-backend | post-golden-path-tests | NONE | | +| sim-payeefsp-cache | post-golden-path-tests | NONE | | +| sim-payeefsp-scheme-adapter | post-golden-path-tests | NONE | | +| sim-payerfsp-backend | post-golden-path-tests | NONE | | +| sim-payerfsp-cache | post-golden-path-tests | NONE | | +| sim-testfsp1-backend | post-golden-path-tests | NONE | | +| sim-testfsp1-cache | post-golden-path-tests | NONE | | + diff --git a/legacy/quality-security/standards-guidelines/readme.md b/legacy/quality-security/standards-guidelines/readme.md new file mode 100644 index 000000000..2c4b9f357 --- /dev/null +++ b/legacy/quality-security/standards-guidelines/readme.md @@ -0,0 +1,32 @@ +# Standards and Guidelines + +> Standards and guidelines are basically recommended security measures and controls to be considered for implementation by the switch core team and hub operators. The target audience is architects, implementation engineers, security management and IT Ops. + +## 1. Design Principles +- 1. [Coding Standards](../contributors-guide/standards) + +## 2. Scheme Trust Architecture +- 1. [Encryption Standard](https://docs.mojaloop.io/mojaloop-specification/documents/Encryption.html) +- 2. [Signature Standard](https://docs.mojaloop.io/mojaloop-specification/documents/Signature.html) +- 3. [PKI Best Practice Standard](https://docs.mojaloop.io/mojaloop-specification/documents/PKI%20Best%20Practices.html) +- 4. [Interledger Cryptographic interlock](https://docs.mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#4-interledger-protocol) +- 5. Cryptographic Processing Module (CPM) Designs: + - [CPM High Level Design](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/cpm_high_level_design_v1.0.pdf) + - [CPM Techincal Spec](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/cpm_design_technical_spec_v1.0.pdf) + - [CPM Design Framework](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/cpm_design_framework_v1.0.pdf) + - [CPM Use Cases](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/cpm_design_use_cases_v1.0.pdf) + +## 3. Data Protection Standards +- 1. [Secure Kafka and Zookeeper Standard](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/kafka_zookeeper_security_standard_v1.0.pdf) +- 2. Secure Logging + Auditing Standard + - [Audit + Logging Standard](./audit_logging_standard.md) + - [Log Analyis Report](./log_analysis_report.md) +c) [Database Security Standard](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/database_security_standard_v1.0.pdf) +## 4. Security Architectural Reviews +- 1. [Mojaloop Portals](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/portal_threat_models_v1.0.pdf) +- 2. [PISP Linking and Transfer Flows](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/pisp_thread_analysis_v1.0.pdf) + +## 5. Secure Network Access + +- [Standard and Recommendations](https://github.com/mojaloop/documentation-artifacts/blob/master/reference/secure_network_access_v1.0.pdf) + diff --git a/repositories/README.md b/legacy/repositories/README.md similarity index 100% rename from repositories/README.md rename to legacy/repositories/README.md diff --git a/repositories/assets/diagrams/helm/HelmChartOverview.png b/legacy/repositories/assets/diagrams/helm/HelmChartOverview.png similarity index 100% rename from repositories/assets/diagrams/helm/HelmChartOverview.png rename to legacy/repositories/assets/diagrams/helm/HelmChartOverview.png diff --git a/repositories/assets/diagrams/helm/HelmHierarchyRelationship.png b/legacy/repositories/assets/diagrams/helm/HelmHierarchyRelationship.png similarity index 100% rename from repositories/assets/diagrams/helm/HelmHierarchyRelationship.png rename to legacy/repositories/assets/diagrams/helm/HelmHierarchyRelationship.png diff --git a/repositories/assets/diagrams/helm/HelmHierarchyValues.png b/legacy/repositories/assets/diagrams/helm/HelmHierarchyValues.png similarity index 100% rename from repositories/assets/diagrams/helm/HelmHierarchyValues.png rename to legacy/repositories/assets/diagrams/helm/HelmHierarchyValues.png diff --git a/repositories/helm.md b/legacy/repositories/helm.md similarity index 100% rename from repositories/helm.md rename to legacy/repositories/helm.md diff --git a/repositories/project.md b/legacy/repositories/project.md similarity index 100% rename from repositories/project.md rename to legacy/repositories/project.md diff --git a/legacy/scripts/_build_plantuml_all.sh b/legacy/scripts/_build_plantuml_all.sh new file mode 100755 index 000000000..342d5fd2f --- /dev/null +++ b/legacy/scripts/_build_plantuml_all.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PUML_PORT=9999 +export PUML_BASE_URL=http://localhost:${PUML_PORT} + +## +# searches through repo for plantuml sources +# and exports them using `node-plantuml` +## + +trap ctrl_c INT +function ctrl_c() { + echo "exit early - stopping docker" + docker stop puml-local + exit 1 +} + +# run the docker puml server +docker run -d --rm \ + --name puml-local \ + -p ${PUML_PORT}:8080 \ + plantuml/plantuml-server:jetty-v1.2020.21 + +# note: this `find` is not optimal, but both BSD and GNU compatible +for i in $(find ${DIR}/.. -name '*.p*uml' | grep -v node_modules); do + echo "rendering .puml -> .svg for diagram diagram: $i" + + ${DIR}/_render_svg.mjs $i +done + + +docker stop puml-local \ No newline at end of file diff --git a/legacy/scripts/_build_plantuml_diff.sh b/legacy/scripts/_build_plantuml_diff.sh new file mode 100755 index 000000000..4bed4e8b1 --- /dev/null +++ b/legacy/scripts/_build_plantuml_diff.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PUML_PORT=9999 +export PUML_BASE_URL=http://localhost:${PUML_PORT} + +## +# searches through staged files for .puml/.plantuml sources +# and updates svgs them using `node-plantuml` +## + +trap ctrl_c INT +function ctrl_c() { + echo "exit early - stopping docker" + docker stop puml-local + exit 1 +} + +# run the docker puml server +docker run -d --rm \ + --name puml-local \ + -p ${PUML_PORT}:8080 \ + plantuml/plantuml-server:jetty-v1.2020.21 + +for i in $(git diff --staged --name-only `find ${DIR}/.. -name '*.p*uml'`); do + echo "rendering .puml -> .svg for diagram diagram: $i" + ${DIR}/_render_svg.mjs $1 +done + +docker stop puml-local + +git add ./**/*.svg diff --git a/legacy/scripts/_render_svg.js b/legacy/scripts/_render_svg.js new file mode 100755 index 000000000..cc0f3c2f1 --- /dev/null +++ b/legacy/scripts/_render_svg.js @@ -0,0 +1,58 @@ +#!/usr/bin/env node + + +/** + * Uses plantuml server to render a puml to svg + */ + +const fs = require('fs') +const path = require('path') +const util = require('util') +const got = require('got') +const SVGO = require('svgo') +const plantumlEncoder = require('plantuml-encoder') + +const rendererBaseUrl = process.env.PUML_BASE_URL || 'http://www.plantuml.com/plantuml' + +svgo = new SVGO({ + js2svg: { pretty: true, indent: 2 }, + plugins: [ + { removeComments: true }, + ] +}); + +async function main() { + let [_, _script, inputPath, outputPath] = process.argv + + if (!inputPath) { + console.log("usage: ./_render_svg.mjs []") + process.exit(1) + } + + // If not specified, replace .puml or .plantuml with `.svg` + if (!outputPath) { + outputPath = inputPath.replace('.puml', '.svg') + .replace('.plantuml', '.svg') + } + + const rawPumlContents = fs.readFileSync(inputPath) + const encoded = plantumlEncoder.encode(rawPumlContents.toString()) + const url = path.join(rendererBaseUrl, 'svg', encoded) + let result + try { + result = await got.get(url) + } catch (err) { + console.log('http request failed to render puml with error', err.message) + if (err.message.indexOf('Response code 403') > -1) { + console.log('Note: sometimes the public puml renderer fails when the input diagrams are too large. Try running your own renderer server with docker.') + } + process.exit(1) + } + + // Strip comments and prettify svg + // This makes sure that our .svg files are deterministic and diffable + const formatted = await svgo.optimize(result.body) + fs.writeFileSync(outputPath, formatted.data) +} + +main() \ No newline at end of file diff --git a/markdownlint.yaml b/markdownlint.yaml new file mode 100644 index 000000000..2521dcb85 --- /dev/null +++ b/markdownlint.yaml @@ -0,0 +1,14 @@ +# Default state for all rules +default: true + +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md013---line-length +MD013: false + +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md024---multiple-headings-with-the-same-content +MD024: false + +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html +MD033: false + +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md034---bare-url-used +MD034: false diff --git a/mojaloop-roadmap.md b/mojaloop-roadmap.md deleted file mode 100644 index 87c32a1e2..000000000 --- a/mojaloop-roadmap.md +++ /dev/null @@ -1,244 +0,0 @@ -# Mojaloop Roadmap - -## Mojaloop Roadmap - -### Functional Epics - -* Event Logging Framework: Support operational reporting and auditing of processing -* Error Handling Framework: Consistent reporting in line with specification and support operational auditing -* API Gateway: Provide role, policy-based access, security, abstraction, throttling & control, identity management -* Endpoints for P2P, Merchant: Provide endpoints to support P2P and Merchant payments -* Settlements: Complete settlements process to handle failures and reconciliation positions -* Central directory/Account lookup service: Provide native implementation for ALS to confirm the API specification to provide user lookup -* Fraud & Risk Management System: Provide support for a fraud and risk management system -* Forensic Logging: Support forensic logging to support auditing and reporting -* Reporting API: Provide an API for reporting - -### Operational Epics - -* Testing Framework: Provide a framework for automated regression, functional and other testing to ensure quality -* Performance Improvements: Provide a framework for automated regression, functional and other testing to ensure quality -* ELK framework & logging: Provide framework or dashboards for Operational support, Debugging and Resolving issues -* DevOps: Provide flexibility, dynamism in deployments, improve monitoring and reliability mechanisms -* Rules Engine: Provide a framework to enforce, implement Business, Scheme rules - -### Non-Functional Epics - -* Deprecate Postgres: Avoid usage of multiple databases to improve supportability and maintenance and move to MySQL -* Security & Threat Modeling: Address security vulnerabilities, issues and provide a report on status of the System's security so that they can be addressed -* Documentation: Update documentation to support adoption by community, for labs, deployment by various partners -* API-Led Design: Refactor central services so that schema validation, paths can be addressed thoroughly \(automatically\) and decrease maintenance, development effort \(for those services don't already follow this\) -* API-led connectivity is a methodical way to connect data to applications through reusable and purposeful APIs. - -### Detailed Roadmap Items - \(Exported from StoriesOnBoard\) - -| Activity | Task | Subtask | Subtask description | Status | Estimation | Release | Personas | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| High Level Topics - Blue, Epics - Yellow, Releases - Orange. Stories - Green. | Designs/Whitepapers - Pink . Workshops - purple. Not in Scope / needs clarity - Gray | ? A third release with focus on Security, Auditing, Operational readiness | Includes features/functionality missing from PI5 and PI6 | Todo | | | Useful Resources | -| High Level Topics - Blue, Epics - Yellow, Releases - Orange. Stories - Green. | Designs/Whitepapers - Pink . Workshops - purple. Not in Scope / needs clarity - Gray | Release 5.0.0 - First version after the MVP with critical bug fixes and key features | First version after the MVP with critical bug fixes and features focusing on functionality needed with inputs from early adopters | Todo | | PI-5 | Useful Resources | -| High Level Topics - Blue, Epics - Yellow, Releases - Orange. Stories - Green. | Designs/Whitepapers - Pink . Workshops - purple. Not in Scope / needs clarity - Gray | Release 6.0.0 - A second release after the MVP with key features, streamlined deployment, on-boarding and monitoring capabilities | | Todo | | PI-6 | Useful Resources | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | Design provisioning & management of FSP onboarding | Description: End state: | Ready | | PI-5 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | Identify Approaches & Technologies for Management & Balancing of FSPs PoC | | Ready | | PI-5 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | PoC for Management & Balancing of FSPs on Test Handlers to determine the best approach | | Ready | | PI-5 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | Assess Performance capabilities, impact of the PoC | | Todo | | PI-5 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | Management & Balancing of FSPs for High-Availability and On-boarding for non-FSP Specific Handlers | | Ready | | PI-6 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | Management & Balancing of FSPs for High-Availability and On-boarding for FSP Specific Handlers | | Ready | | PI-6 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: DFSP Handler Provisioning | The Switch system scales when on-boarding FSPs | QA, testing - validation | | Ready | | PI-6 | Hub Tech Ops Hub Operator DFSP System Integrators DFSP | -| NFR: API Gateway | Gateway, Developer Portal | Access control policies | | Todo | | | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Apply validation controls at the API Gateway level | | Todo | | | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Confirm the technology for API Gateway, Developer Portal | Confirm that WSO2 is the way to go or if there's a better alternative \(better suited for Open Source\) | Todo | | PI-5 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Design solution with WSO2 API Gateway | **Security**: 1. Inbound rules 1. Outbound rules 1. Headers validation 1. Throttling | Todo | | PI-5 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Setup API Gateway using WSO2 - Infrastructure | | Ready | | PI-5 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Integration with Switch services \(ml-api-adapter\) | | Ready | | PI-5 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Provide Authentication | | Todo | | PI-6 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Developer Portal \(FSPs, Hub Operator\) | | Ready | | PI-6 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | Developer on-boarding | | Todo | | PI-6 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: API Gateway | Gateway, Developer Portal | QA, Testing | | Todo | | PI-6 | Switch DFSP DFSP System Integrators Hub Customer Care Hub Operator Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: DevOps, CI/CD | Deployment automation and Lab work | Making existing helm charts more maintainable & manageable | | Ready | | PI-5 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Deployment automation and Lab work | Automate Lab Setup - chooses services \(things like Gateway, etc\) | Possibly using something like Terraform, Vagrant | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Deployment automation and Lab work | Validate Lab envt setup using a test framework | | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | API Gateway is incorporated into the CI/CD pipeline & deployments are automated | Incorporating the API Gateway into the deployment process | | Todo | | PI-5 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | API Gateway is incorporated into the CI/CD pipeline & deployments are automated | Incorporating the API Gateway into the CI/CD pipeline | | Todo | | PI-5 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | API Gateway is incorporated into the CI/CD pipeline & deployments are automated | Automate deployment of artifacts as part of CI/CD pipeline | Currently the artifacts are published to dockerhub/npm repos based on the outcome of the testing phases but the deployment fails as quite a bit of automation is needed. This involves updating helm charts dynamically, values files and other such resources. This would tremendously reduce the amount of time involved in getting out a deployment after a release. Currently we do the deployment manually \(which is not that bad\) but this can be eliminated. | Ready | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | API Gateway is incorporated into the CI/CD pipeline & deployments are automated | Integrate Contract, Interface and Functional Tests in CI/CD Pipeline | | Ready | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Monitoring, Management of resources | Enable health checks to report holistically | | Ready | | PI-5 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Monitoring, Management of resources | Support for Zipkin | | Todo | | PI-5 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Monitoring, Management of resources | ELK: Support for Alerts, Notifications | | Ready | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Monitoring, Management of resources | Integrating ELK with Event Logging Framework, etc | | Ready | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: DevOps, CI/CD | Monitoring, Management of resources | ELK Dashboards for KPIs, etc | | Ready | | PI-6 | Switch Hub Tech Ops Hub Customer Care | -| NFR: Quality Assurance, Testing | Testing, QA | Standardized simulator \(mock FSPs\) to support automated testing | 1. Simulators that dynamically generate conditions, fulfilments etc as part of the end-to-end proccess 1. Include error end-points \(addressed in another item\) 1. Perform validations 1. Rework the simulator to generate the end-points based on the Swagger \(to easily validate\): API first approach | Ready | | PI-5 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Testing, QA | Automated Functional Tests - document coverage | | Ready | | PI-5 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Testing, QA | Periodic comprehensive functional testing on deployments | | Todo | | PI-5 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Testing, QA | Automated Integration Tests | | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Testing, QA | Automated Contract Tests | Contract - meaning the API Specification itself. Automated tests to ensure the Switch adheres to the API/Swagger specification, example, headers, schema, etc This ensures the users of the System that the implementation conforms to the API Specification. | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Testing, QA | Update Automated Contract, Integration, Functional Tests | | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | QA, Bug Fixes | QA, Bug Fixes | | Ready | | | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | QA, Bug Fixes | Bug Fixes, QA | | Ready | | PI-5 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | QA, Bug Fixes | QA, Bug Fixes | | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Performance Testing, Baselining | Performance testing & Improvements | | Ready | | | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Performance Testing, Baselining | Performance testing baselining after addition of new features, frameworks | Towards the end of the PI/Sprint | Ready | | PI-5 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Performance Testing, Baselining | Automated Performance Tests | | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| NFR: Quality Assurance, Testing | Performance Testing, Baselining | Regular Performance testing as part of CI/CD | | Ready | | PI-6 | Switch BMGF Hub Tech Ops Hub Security, Risk and Compliance Team | -| FR: Settlement Management | Settlements Management | Enhance Alerts and Notifications | | Ready | | PI-5 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Settlements Management | Follow-up items to be confirmed after the OSS Settlements API is drafted | | Todo | | PI-5 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Settlements Management | Handle failed acknowledgements for Settlements | | Ready | 8.00 | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Settlements Management | Settlement Reconciliation Reports | | Ready | | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Identification of Framework for reporting | | Todo | | PI-5 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Identify data sets that can be queried - Transactions | | Ready | | PI-5 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Settlements reporting format decisions | | Todo | | PI-5 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Identify data sets that can be queried - Transfers | | Ready | | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Standardize query API | | Ready | | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | Implementation of reporting functionality | | Todo | | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| FR: Settlement Management | Reporting API for FSP Consumption | QA, testing | | Todo | | PI-6 | DFSP Switch Hub Operator Hub Finance Team | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Scaling guidelines for deployment | | Todo | | | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Guidelines for optimal performance | | Todo | | | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | HA guidelines for deployment | | Todo | | | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Recommended deployment topologies | | Todo | | PI-5 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Security guidelines for implementation, deployment | | Todo | | PI-5 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Documentation - clarity, remove ambiguity. Review | | Todo | | PI-5 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Deployment Topology Guidelines | Guidelines for cloud/on-prem providers | | Todo | | PI-6 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Workshops | Workshops for Hub Operators | | Todo | | PI-5 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Workshops | Workshops for OSS contributors | | Todo | | PI-5 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Workshops | Workshops for FSP and System Integrators | | Todo | | PI-6 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Workshops | Workshops for OSS contributors - 2 | | Todo | | PI-6 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Implementation Topology Guidelines | Workshops | Workshops for Hub Operators - 2 | | Todo | | PI-6 | Switch DFSP System Integrators Hub Tech Ops | -| NFR: Event Logging | Event Logging Framework | Central processing of events and raising alerts/alarms/errors | Extend existing functionality **Interesting Events that need to be produced/captured**: 1. Up/down events for services, 1. Threshold on number of occurrences 1. Dashboards - Thresholds - CPU utilization, Disk space, configurable 1. Error events in services 1. Infrastructure events \(Up/Down\). 1. Connectivity events \(Connect/Disconnect\) 1. General service events \(started, halted, etc\) 1. Mojaloop errors based on the specification **Business**: 1. Thresholds 1. Limits \(NDC\) 1. Position events 1. Settlement events \(settling, window closure, etc\) **Things to take care of**: 1. Mode of notifications 1. Separation of Technical and Commercial/Financial/Business related information - access to logs to be restricted From Ops 1. Duration of persistence of logs, etc \(especially commercial/business data\) - comply with guidelines/ standards. 1. HA events and assess reliability - How do we measure the uptime of the system and availability | Todo | | | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Event Logging Framework | Recommended usage of the alerting system | | Todo | | | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Event Logging Framework | Design event logging Framework | Framework for producing & capturing Event logs that can be used for monitoring **Interesting Events that need to be produced/captured**: - Up/down events for services, - Threshold on number of occurrences - Dashboards - Thresholds - CPU utilization, Disk space, configurable - Error events in services - Infrastructure events \(Up/Down\). - Connectivity events \(Connect/Disconnect\) - General service events \(started, halted, etc\) - Mojaloop errors based on the specification **Business**: - Thresholds - Limits \(NDC\) - Position events - Settlement events \(settling, window closure, etc\) **Things to take care of**: - Mode of notifications - Separation of Technical and Commercial/Financial/Business related information - access to logs to be restricted From Ops - Duration of persistence of logs, etc \(especially commercial/business data\) - comply with guidelines/ standards. - HA events and assess reliability - How do we measure the uptime of the system and availability | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Event Logging Framework | Implement Common Library for events | | Ready | 15.00 | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Event Logging Framework | Implementation for producing & capturing Event logs that can be used for monitoring | Framework for producing & capturing Event logs that can be used for monitoring **Interesting Events that need to be produced/captured**: 1. Up/down events for services, 1. Threshold on number of occurrences 1. Dashboards - Thresholds - CPU utilization, Disk space, configurable 1. Error events in services 1. Infrastructure events \(Up/Down\). 1. Connectivity events \(Connect/Disconnect\) 1. General service events \(started, halted, etc\) 1. Mojaloop errors based on the specification **Business**: 1. Thresholds 1. Limits \(NDC\) 1. Position events 1. Settlement events \(settling, window closure, etc\) **Things to take care of**: 1. Mode of notifications 1. Separation of Technical and Commercial/Financial/Business related information - access to logs to be restricted From Ops 1. Duration of persistence of logs, etc \(especially commercial/business data\) - comply with guidelines/ standards. 1. HA events and assess reliability - How do we measure the uptime of the system and availability | Ready | 8.00 | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Event Logging Framework | Testing the common library, framework for producing, capturing events | | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Logging standards, implement & standardize | | Ready | | PI-5 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Changes to logging to enhance traceability | | Ready | | PI-5 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Design and identify dashboards needed for monitoring | | Todo | | PI-5 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Operational Dashboards for monitoring specific events end-to-end | | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Operational Dashboards for monitoring alerts/alarms/errors | | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Event Logging | Dashboards for Monitoring | Testing various dashboards | | Todo | | PI-6 | Switch Hub Tech Ops Hub Customer Care Hub Security, Risk and Compliance Team Hub Operator | -| NFR: Error Handling | Implementing error endpoints | Design solution for supporting error endpoints for transfers | | Todo | | PI-5 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Implementing error endpoints | Implement support for error endpoints for transfers | | Todo | | PI-5 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Implementing error endpoints | Updating simulators to support error endpoints | | Todo | | PI-5 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Implementing error endpoints | Support for endpoints for other resources | | Todo | | PI-5 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Implementing error endpoints | Enhance notification mechanism to handle notification issues, perform retries | Retries according to configuration that can be set | Todo | | PI-6 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Error Handling Framework | Publish an event to be consumed by the event framework | | Ready | | | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Error Handling Framework | Design an error handling framework for a standardized way of returning results of execution | | Todo | | PI-5 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Error Handling Framework | Design error mapping for the error handling framework | | Todo | | PI-6 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Error Handling Framework | Common library for error framework | | Ready | | PI-6 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| NFR: Error Handling | Error Handling Framework | Implement the error handling framework | | Ready | | PI-6 | Hub Tech Ops Switch DFSP DFSP System Integrators Hub Customer Care | -| FR: Bulk Payments | Bulk Payments Design | Design for Bulk Payments: version - 1, based on the ML Spec | | Ready | | PI-5 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Design | Design for Bulk Payments: version - 2 | | Ready | | PI-5 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Design | Finalize design for Bulk Payments | | Todo | | PI-6 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Implementing resources: bulkTransfers | | Todo | | | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Bulk payments error handling | | Todo | | | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Testing Bulk Payments | | Todo | | | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Implementing resources for bulk look-up, etc | | Todo | | PI-5 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Implementing resources: bulkQuotes | | Todo | | PI-6 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Bulk Payments | Bulk Payments Implementation | Implementing resources: bulkTransfers - PoC | | Ready | | PI-6 | DFSP Switch DFSP System Integrators Identity Oracles | -| FR: Forensic Logging | Forensic Logging | Migrate central-kms from scala to node and associated DB to the selected type | | Ready | | | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Forensic Logging | Revisit/review Forensic Logging Architecture | | Ready | | PI-5 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Forensic Logging | Migrate from postgres to selected persistent store \(mysql/kafka\) | | Ready | | PI-5 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Forensic Logging | Sidecars to periodically validate the connected services | | Todo | | PI-6 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Forensic Logging | Ensure algorithm and encryption functionality work as expected | | Ready | | PI-6 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Auditing | Define/gather auditing requirements | | Todo | | PI-5 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Auditing | Implement auditing events or logging capabilities in components | | Todo | | PI-6 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Auditing | Use for auditing \(test by generating reports\) | | Ready | | PI-6 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Forensic Logging | Auditing | Integration with Event Handling / ELK ? | | Ready | | PI-6 | DFSP Hub Security, Risk and Compliance Team Hub Tech Ops | -| FR: Central Directory \(account lookup\) | central directory alignment to ML Spec with existing capabilities | Design solution for integration with current services | | Ready | | PI-5 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | central directory alignment to ML Spec with existing capabilities | Migrate code from Mowali and replace the existing legacy code | | Ready | | PI-5 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | central directory alignment to ML Spec with existing capabilities | QA, testing for lookup, integration with overall use cases | | Todo | | PI-5 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | Extend Central directory capabilities to support Merchant registries, multiple identifiers | Support for multiple identifiers? | | Todo | | | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | Extend Central directory capabilities to support Merchant registries, multiple identifiers | Design solution for Merchant registries | - As an FSP, I want to know the FSP that a Merchant belongs to - As an FSP, I want to register a new Merchant and assign a unique TILL number - As a Merchant, I want to be able to request a DFSP to assign me a Merchant number \(design\) - As a Switch, I should maintain a record of mapping between FSPs and Merchant IDs | Todo | | PI-6 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | Extend Central directory capabilities to support Merchant registries, multiple identifiers | Implementing solution for Merchant payments | | Todo | | PI-6 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Central Directory \(account lookup\) | Extend Central directory capabilities to support Merchant registries, multiple identifiers | QA, testing for lookup, integration with overall merchant use cases | | Todo | | PI-6 | DFSP DFSP System Integrators Switch Identity Oracles | -| FR: Merchant "Request to Pay" | Supporting 'Merchant request to pay' | Design solution and identify pre-requisites for Merchant payments | | Todo | | PI-5 | DFSP Switch DFSP System Integrators | -| FR: Merchant "Request to Pay" | Supporting 'Merchant request to pay' | Implement Resources: transactionRequests, authorizations | | Ready | | PI-5 | DFSP Switch DFSP System Integrators | -| FR: Merchant "Request to Pay" | Supporting 'Merchant request to pay' | Implement error endpoints and related functionality | | Todo | | PI-5 | DFSP Switch DFSP System Integrators | -| FR: Merchant "Request to Pay" | Supporting 'Merchant request to pay' | 'Merchant request to pay' is supported, released | | Todo | | PI-5 | DFSP Switch DFSP System Integrators | -| FR: Merchant "Request to Pay" | Supporting 'Merchant request to pay' | QA, testing on the feature | | Todo | | PI-6 | DFSP Switch DFSP System Integrators | -| NFR \(new\): Community Support | Supporting community regarding deployment, Mojaloop Specification | Update documentation to support community | | Todo | | PI-5 | BMGF DFSP Useful Resources Hub Operator Hub Customer Care DFSP System Integrators | -| NFR \(new\): Community Support | Supporting community regarding deployment, Mojaloop Specification | Provide support to community requests on deployment | | Todo | | PI-5 | BMGF DFSP Useful Resources Hub Operator Hub Customer Care DFSP System Integrators | -| NFR \(new\): Community Support | Supporting community regarding deployment, Mojaloop Specification | Provide support to community requests regarding the Spec | | Todo | | PI-5 | BMGF DFSP Useful Resources Hub Operator Hub Customer Care DFSP System Integrators | -| NFR \(new\): Community Support | Supporting community regarding deployment, Mojaloop Specification | Provide an FAQ/Wiki section for deployment and Spec questions | | Todo | | PI-6 | BMGF DFSP Useful Resources Hub Operator Hub Customer Care DFSP System Integrators | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Formalizing the Operations/Admin API | Formalize the Admin/operations API | | Ready | | PI-5 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Formalizing the Operations/Admin API | Provide features to manage FSPs | | Ready | | PI-6 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Formalizing the Operations/Admin API | central hub with UI ? | | Ready | | PI-6 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | FRMS | Investigate capabilities & features needed | | Ready | | PI-6 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | FRMS | Prioritizing Rules/Policies to implement | | Ready | | PI-6 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Refactoring: API Led Design, Implementation for central services | Designing all central services to support API Led Design | | Ready | | PI-5 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Refactoring: API Led Design, Implementation for central services | Refactoring for ml-api-adapter | | Ready | | PI-6 | | -| Others \(not covered\) / Hardening \(Cleanup, Refactoring, etc\) | Refactoring: API Led Design, Implementation for central services | Refactoring for central services | | Ready | | PI-6 | | -| Security | | | | | | | Hub Security, Risk and Compliance Team DFSP Switch | -| Cross currency | Account Lookup Service | Change in Currency | ALS naming convention for routing - if moving from MSISDN only Identify currency and impact to Standard Transfers | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Quotation | Regulatory Data | KYC Data Need to clarify - including understanding Multi Currency What data needs to be passed - via DFSPs and through CCP How is that data passed and validated? Impact on timeouts Rules and Design | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Quotation | FX Rate Management | | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Quotation | Fees consolidation | How are fees passed along the chain? Not already in the quote Is there a need for transparency? If not how and where are all the fees calculated and brought to common currency? | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Transfer | Limit Management | Velocity Rules for sender and receiver Regulatory data required to confirm | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Transfer | Sequencing of Position management and fund movement | As now 4 \(+\) positions affected control financial risk | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Transfer | Rollback | How does it work - design | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Transfer | Timeout | | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Cross currency | Settlement | Reporting of Transfer | Managing the trail of the hops for the CCP and regulatory for Send and Receive | Todo | | PI-5 | DFSP Identity Oracles Hub Finance Team | -| Documentation | | | | | | | BMGF DFSP Useful Resources | -| FRMS | | | | | | | Hub Security, Risk and Compliance Team DFSP | -| Lab for FSPs, deployment tools | | | | | | | BMGF | -| Cross-network payments | | | | | | | | -| Payment Hub | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | -| | | | | | | | | - -## Beyond Phase 3 - -Below is a list of larger initiatives and epics by area that will help to further develop the Mojaloop project. Some of these have been entered as epics or stories, but most are still in the "concept" phase. - -### Functional Epics - -* Native Implementation P2P: Implementation of resources to support Payee initiated and other Use Cases from the Specification, along with supporting P2P Use case completely -* Native Implementation Payee: Implementation of resources to support Payee initiated transactions and ones that involve OTPs -* Bulk Payments: Design & Implementation of resources to support Bulk Payments - -### Central Services - -* Directory Interoperability -* Multi-currency and schemes -* Enforcing Currency configurations -* Fees: UI for configuring fees -* Increase performance -* Fraud Scores and Reasons -* Role management -* DSP Management -* Stopping/Pausing a DFSP -* boarding protocol - -### DFSP/Account Management - -* Agent Network -* NFCC identity merchant -* Persistent merchant ID -* Onboarding protocol -* Change password -* Password requirements -* Hold/Restart account - -### Security - -* Central certificate service -* Implement fee quote transfer service in the center -* Prevent user guessing from rogue DFSPs -* Preferred authorizations - -### Market Deployment - -* Integration with major mobile money vendors in Africa \(PDP initiative\) - -### CI/CD & Testing - -* Implement auto deployment to test environment -* Automatically run acceptance tests in test environment as part of build/deploy -* Automate bulk import tests -* Forensic log test -* Account management test diff --git a/mojaloop-technical-overview/README.md b/mojaloop-technical-overview/README.md deleted file mode 100644 index fb890d414..000000000 --- a/mojaloop-technical-overview/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Mojaloop Technical Overview - -## Mojaloop Services - -The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers (DFSPs) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. The following diagrams shows the Mojaloop interconnects between DFSPs and the Mojaloop Hub (schema implementation example) for a Peer-to-Peer (P2P) Transfer: - -Mojaloop addresses these issues in several key ways: -* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. -* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. -* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. - -![Mojaloop End-to-end Architecture Flow PI5](./assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg) - -The Mojaloop Hub is the primary container and reference we use to describe the Mojaloop echo-system which is split in to the following domains: -* Mojaloop Open Source Services - Core Mojaloop Open Source Software (OSS) that has been supported by the Bill & Melinda Gates Foundation in partnership with the Open Source Community. -* Mojaloop Hub - Overall Mojaloop reference (and customizable) implementation for Hub Operators is based on the above OSS solution. diff --git a/mojaloop-technical-overview/account-lookup-service/README.md b/mojaloop-technical-overview/account-lookup-service/README.md deleted file mode 100644 index f69b48dba..000000000 --- a/mojaloop-technical-overview/account-lookup-service/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# Account Lookup Service - -The **Account Lookup Service** (**ALS**) _(refer to section `6.2.1.2`)_ as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) implements the following use-cases: - -* Participant Look-up -* Party Look-up -* Manage Participants Registry information - * Adding Participant Registry information - * Deleting Participant Registry information - -Use-cases that have been implemented over and above for Hub Operational use: -* Admin Operations - * Manage Oracle End-point Routing information - * Manage Switch End-point Routing information - -## 1. Design Considerations - -### 1.1. Account Lookup Service (ALS) -The ALS design provides a generic Central-Service component as part of the core Mojaloop. The purpose of this component is to provide routing and alignment to the Mojaloop API Specification. This component will support multiple Look-up registries (Oracles). This ALS will provide an Admin API to configure routing/config for each of the Oracles similiar to the Central-Service API for the End-point configuration for DFSP routing by the Notification-Handler (ML-API-Adapter Component). The ALS will in all intense purpose be a switch with a persistence store for the storage/management of the routing rules/config. - -#### 1.1.1. Assumptions - -* The ALS design will only cater for a single switch for the time being. -* Support for multiple switches will utilise the same DNS resolution mechanism that is being developed for the Cross Border/Network design. - -#### 1.1.2. Routing - -The routing configuration will be based on the following: -* PartyIdType - See section `7.5.6` of the Mojaloop Specification -* Currency - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, however `isDefault` indicator must be set to `true` if the `Currency` is not provided. -* isDefault - Indicator that a specific Oracle is the default provider for a specific PartyIdType. Note that there can be many default Oracles, but there can only be a single Oracle default for a specific PartyIdType. The default Oracle for a specific PartyIdType will only be selected if the originating request does not include a Currency filter. - - -### 1.2. ALS Oracle -The ALS Oracle be implemented as either a **Service** or **Adapter** (semantic dependant on use - Mediation = Adapter, Service = Implementation) will provide a look-up registry component with similar functionality of the `/participants` Mojaloop API resources. It has however loosely based on the ML API specification as it's interface implements a sync pattern which reduces the correlation/persistence requirements of the Async Callback pattern implemented directly by the ML API Spec. This will provide all ALS Oracle Services/Adapters with a standard interface which will be mediated by the ALS based on its routing configuration. -This component (or back-end systems) will also be responsible for the persistence & defaulting of the Participant details. - -## 2. Participant Lookup Design - -### 2.1. Architecture overview -![Architecture Flow Account-Lookup for Participants](./assets/diagrams/architecture/arch-flow-account-lookup-participants.svg) - -_Note: The Participant Lookup use-case similarly applies to for a Payee Initiated use-case such as transactionRequests. The difference being that the Payee is the initiation in the above diagram._ - -### 2.2. Sequence diagrams - -#### 2.2.1. GET Participants - -- [Sequence Diagram for GET Participants](als-get-participants.md) - -#### 2.2.2. POST Participants - -- [Sequence Diagram for POST Participants](als-post-participants.md) - -#### 2.2.3. POST Participants (Batch) - -- [Sequence Diagram for POST Participants (Batch)](als-post-participants-batch.md) - -#### 2.2.4. DEL Participants - -- [Sequence Diagram for DEL Participants](als-del-participants.md) - -## 3. Party Lookup Design - -### 3.1. Architecture overview -![Architecture Flow Account-Lookup for Parties](./assets/diagrams/architecture/arch-flow-account-lookup-parties.svg) - -### 3.2. Sequence diagram - -#### 3.2.1. GET Parties - -- [Sequence Diagram for GET Parties](als-get-parties.md) - -## 4. Database Design - -### 4.1. ALS Database Schema - -#### Notes -- `partyIdType` - Values are currently seeded as per section _`7.5.6`_ [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}). -- `currency` - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, and must provide a "default" config if no Currency is either provided or provide a default if the Currency is provided, but only the "default" End-point config exists. -- `endPointType` - Type identifier for the end-point (e.g. `URL`) which provides flexibility for future transport support. -- `migration*` - Meta-data tables used by Knex Framework engine. -- A `centralSwitchEndpoint` must be associated to the `OracleEndpoint` by the Admin API upon insertion of a new `OracleEndpoint` record. If the `centralSwitchEndpoint` is not provided as part of the API Request, then it must be defaulted. - -![Acount Lookup Service ERD](./assets/entities/AccountLookupService-schema.png) - -* [Acount Lookup Service DBeaver ERD](./assets/entities/AccountLookupDB-schema-DBeaver.erd) -* [Acount Lookup Service MySQL Workbench Export](./assets/entities/AccountLookup-ddl-MySQLWorkbench.sql) - -## 5. ALS Oracle Design - -Detail design for the Oracle is out of scope for this document. The Oracle design and implementation is specific to each Oracle's requirements. - -### 5.1. API Specification - -Refer to **ALS Oracle API** in the [API Specifications](../../api/README.md#als-oracle-api) section. diff --git a/mojaloop-technical-overview/account-lookup-service/als-del-participants.md b/mojaloop-technical-overview/account-lookup-service/als-del-participants.md deleted file mode 100644 index 6070b84fc..000000000 --- a/mojaloop-technical-overview/account-lookup-service/als-del-participants.md +++ /dev/null @@ -1,11 +0,0 @@ -# DEL Participants - -Design for the deletion of a Participant by a DFSP. - -## Notes -- Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. ~ This has been addressed in the design by insuring that the Party currently belongs to the FSPs requesting the deletion of the record. Any other validations are out of scope for the Switch and should be addressed at the schema level. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/account-lookup-service/als-get-participants.md b/mojaloop-technical-overview/account-lookup-service/als-get-participants.md deleted file mode 100644 index 506868de0..000000000 --- a/mojaloop-technical-overview/account-lookup-service/als-get-participants.md +++ /dev/null @@ -1,8 +0,0 @@ -# GET Participants - -Design for the retrieval of a Participant by a DFSP. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/account-lookup-service/als-get-parties.md b/mojaloop-technical-overview/account-lookup-service/als-get-parties.md deleted file mode 100644 index f71acd30f..000000000 --- a/mojaloop-technical-overview/account-lookup-service/als-get-parties.md +++ /dev/null @@ -1,8 +0,0 @@ -# GET Parties - -Design for the retrieval of a Party by a DFSP. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md b/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md deleted file mode 100644 index 03718e473..000000000 --- a/mojaloop-technical-overview/account-lookup-service/als-post-participants-batch.md +++ /dev/null @@ -1,14 +0,0 @@ -# Sequence Diagram for POST Participants (Batch) - -Design for the creation of a Participant by a DFSP via a batch request. - -## Notes -- Operation only supports requests which contain: - - All Participant's FSPs match the FSPIOP-Source - - All Participant's will be of the same Currency as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) -- Duplicate POST Requests with matching TYPE and optional CURRENCY will be considered an __update__ operation. The existing record must be completely **replaced** in its entirety. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/account-lookup-service/als-post-participants.md b/mojaloop-technical-overview/account-lookup-service/als-post-participants.md deleted file mode 100644 index e954183ec..000000000 --- a/mojaloop-technical-overview/account-lookup-service/als-post-participants.md +++ /dev/null @@ -1,3 +0,0 @@ -# Sequence Diagram for POST Participants - -Coming soon. diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml b/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml deleted file mode 100644 index c3f3bf96f..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml +++ /dev/null @@ -1,219 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Samuel Kummary - -------------- - ******'/ - -@startuml -' declare title -title 1.1.0. DFSP1 sends a Bulk Prepare Transfer request to DFSP2 - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistance Store - -' declare actors -actor "DFSP1\nPayer" as DFSP1 -actor "DFSP2\nPayee" as DFSP2 -boundary "ML API Adapter" as MLAPI -control "ML API Notification \nHandler" as NOTIFY_HANDLER -collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE -boundary "Central Service API" as CSAPI -collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE -control "Bulk Prepare\nHandler" as BULK_PREP_HANDLER -collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE -control "Prepare Handler" as PREP_HANDLER -collections "topic-\ntransfer-position" as TOPIC_TRANSFER_POSITION -control "Position Handler" as POS_HANDLER -collections "topic-\nbulk-processing" as TOPIC_BULK_PROCESSING -control "Bulk Processing\nHandler" as BULK_PROC_HANDLER -collections "topic-\nnotifications" as TOPIC_NOTIFICATIONS - -box "Financial Service Providers" #lightGray - participant DFSP1 - participant DFSP2 -end box - -box "ML API Adapter Service" #LightBlue - participant MLAPI - participant NOTIFY_HANDLER -end box - -box "Central Service" #LightYellow - participant OBJECT_STORE - participant CSAPI - participant TOPIC_BULK_PREPARE - participant BULK_PREP_HANDLER - participant TOPIC_TRANSFER_PREPARE - participant PREP_HANDLER - participant TOPIC_TRANSFER_POSITION - participant POS_HANDLER - participant TOPIC_BULK_PROCESSING - participant BULK_PROC_HANDLER - participant TOPIC_NOTIFICATIONS -end box - -' start flow -activate NOTIFY_HANDLER -activate BULK_PREP_HANDLER -activate PREP_HANDLER -activate POS_HANDLER -activate BULK_PROC_HANDLER -group DFSP1 sends a Bulk Prepare Transfer request to DFSP2 - note right of DFSP1 #yellow - Headers - transferHeaders: { - Content-Length: , - Content-Type: , - Date: , - FSPIOP-Source: , - FSPIOP-Destination: , - FSPIOP-Encryption: , - FSPIOP-Signature: , - FSPIOP-URI: , - FSPIOP-HTTP-Method: - } - - Payload - bulkTransferMessage: - { - bulkTransferId: , - bulkQuoteId: , - payeeFsp: , - payerFsp: , - individualTransfers: [ - { - transferId: , - transferAmount: - { - currency: , - amount: - }, - ilpPacket: , - condition: , - extensionList: { extension: [ - { key: , value: } - ] } - } - ], - extensionList: { extension: [ - { key: , value: } - ] }, - expiration: - } - end note - DFSP1 ->> MLAPI: POST - /bulkTransfers - activate MLAPI - MLAPI -> MLAPI: Validate incoming message\nError codes: 3000-3002, 3100-3107 - MLAPI -> OBJECT_STORE: Persist incoming bulk message to\nobject store: **MLOS.individualTransfers** - activate OBJECT_STORE - OBJECT_STORE --> MLAPI: Return messageId reference to the stored object(s) - deactivate OBJECT_STORE - note right of MLAPI #yellow - Message: - { - id: - to: , - from: , - type: "application/json" - content: { - headers: , - payload: { - bulkTransferId: , - bulkQuoteId": , - payerFsp: , - payeeFsp: , - expiration: , - hash: - } - }, - metadata: { - event: { - id: , - type: "bulk-prepare", - action: "bulk-prepare", - createdAt: , - state: { - status: "success", - code: 0 - } - } - } - } - end note - MLAPI -> TOPIC_BULK_PREPARE: Route & Publish Bulk Prepare event \nfor Payer\nError code: 2003 - activate TOPIC_BULK_PREPARE - TOPIC_BULK_PREPARE <-> TOPIC_BULK_PREPARE: Ensure event is replicated \nas configured (ACKS=all)\nError code: 2003 - TOPIC_BULK_PREPARE --> MLAPI: Respond replication acknowledgements \nhave been received - deactivate TOPIC_BULK_PREPARE - MLAPI -->> DFSP1: Respond HTTP - 202 (Accepted) - deactivate MLAPI - ||| - TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume message - BULK_PREP_HANDLER -> OBJECT_STORE: Retrieve individual transfers by key:\n**MLOS.individualTransfers.messageId** - activate OBJECT_STORE - OBJECT_STORE --> BULK_PREP_HANDLER: Stream bulk's individual transfers - deactivate OBJECT_STORE - ref over TOPIC_BULK_PREPARE, BULK_PREP_HANDLER, TOPIC_TRANSFER_PREPARE: Bulk Prepare Handler Consume \n - alt Success - BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Produce (stream) single transfer message\nfor each individual transfer [loop] - else Failure - BULK_PREP_HANDLER --> TOPIC_NOTIFICATIONS: Produce single message for the entire bulk - end - ||| - TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume message - ref over TOPIC_TRANSFER_PREPARE, PREP_HANDLER, TOPIC_TRANSFER_POSITION: Prepare Handler Consume\n - alt Success - PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Produce message - else Failure - PREP_HANDLER --> TOPIC_BULK_PROCESSING: Produce message - end - ||| - TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume message - ref over TOPIC_TRANSFER_POSITION, POS_HANDLER, TOPIC_BULK_PROCESSING: Position Handler Consume\n - POS_HANDLER -> TOPIC_BULK_PROCESSING: Produce message - ||| - TOPIC_BULK_PROCESSING <- BULK_PROC_HANDLER: Consume message - ref over TOPIC_BULK_PROCESSING, BULK_PROC_HANDLER, TOPIC_NOTIFICATIONS: Bulk Processing Handler Consume\n - BULK_PROC_HANDLER -> OBJECT_STORE: Persist bulk message by destination to the\nobject store: **MLOS.bulkTransferResults** - activate OBJECT_STORE - OBJECT_STORE --> BULK_PROC_HANDLER: Return the reference to the stored \nnotification object(s): **messageId** - deactivate OBJECT_STORE - BULK_PROC_HANDLER -> TOPIC_NOTIFICATIONS: Send Bulk Prepare notification - ||| - TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: Consume message - NOTIFY_HANDLER -> OBJECT_STORE: Retrieve bulk notification(s) by reference & destination:\n**MLOS.bulkTransferResults.messageId + destination** - activate OBJECT_STORE - OBJECT_STORE --> NOTIFY_HANDLER: Return notification(s) payload - deactivate OBJECT_STORE - ref over DFSP2, TOPIC_NOTIFICATIONS: Send notification to Participant (Payee)\n - NOTIFY_HANDLER -> DFSP2: Send Bulk Prepare notification to Payee - ||| -end -deactivate POS_HANDLER -deactivate BULK_PREP_HANDLER -deactivate PREP_HANDLER -deactivate BULK_PROC_HANDLER -deactivate NOTIFY_HANDLER -@enduml diff --git a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml b/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml deleted file mode 100644 index 8cd357671..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml +++ /dev/null @@ -1,369 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Samuel Kummary - -------------- - ******'/ - -@startuml -' declare title -title 1.1.1. Bulk Prepare Handler Consume - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistance Store - -' declare actors -collections "topic-\nbulk-prepare" as TOPIC_BULK_PREPARE -collections "mojaloop-\nobject-store\n(**MLOS**)" as OBJECT_STORE -control "Bulk Prepare \nHandler" as BULK_PREP_HANDLER -collections "topic-\ntransfer-prepare" as TOPIC_TRANSFER_PREPARE -collections "topic-event" as TOPIC_EVENTS -collections "topic-\nnotification" as TOPIC_NOTIFICATIONS -collections "topic-bulk-\nprocessing" as TOPIC_BULK_PROCESSING -entity "Bulk DAO" as BULK_DAO -entity "Participant DAO" as PARTICIPANT_DAO -database "Central Store" as DB - -box "Central Service" #LightYellow - participant OBJECT_STORE - participant TOPIC_BULK_PREPARE - participant BULK_PREP_HANDLER - participant TOPIC_TRANSFER_PREPARE - participant TOPIC_EVENTS - participant TOPIC_NOTIFICATIONS - participant TOPIC_BULK_PROCESSING - participant BULK_DAO - participant PARTICIPANT_DAO - participant DB -end box - -' start flow -activate BULK_PREP_HANDLER -group Bulk Prepare Handler Consume - TOPIC_BULK_PREPARE <- BULK_PREP_HANDLER: Consume Bulk Prepare message - activate TOPIC_BULK_PREPARE - deactivate TOPIC_BULK_PREPARE - - break - group Validate Event - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate event - Rule: type == 'bulk-prepare' && action == 'bulk-prepare'\nError codes: 2001 - end - end - - group Persist Event Information - ||| - BULK_PREP_HANDLER -> TOPIC_EVENTS: Publish event information - ref over BULK_PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n - ||| - end - - group Validate Bulk Prepare Transfer - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Schema validation of the incoming message - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Verify the message's signature (to be confirmed in future requirement) - note right of BULK_PREP_HANDLER #lightgrey - The above validation steps are already handled by the - Bulk-API-Adapter for the open source implementation. - It may need to be added in future for custom adapters. - end note - - group Validate Duplicate Check - note right of BULK_PREP_HANDLER #cyan - The Specification doesn't touch on the duplicate handling - of bulk transfers, so the current design mostly follows the - strategy used for individual transfers, except in two places: - - 1. For duplicate requests where hash matches, the current design - includes only the status of the bulk & timestamp (if completed), - but not the individual transfers (for which a GET should be used). - - 2. For duplicate requests where hash matches, but are not in a - finalized state, only the state of the bulkTransfer is sent. - end note - ||| - BULK_PREP_HANDLER -> DB: Request Duplicate Check - ref over BULK_PREP_HANDLER, DB: Request Duplicate Check (using message.content.payload.hash)\n - DB --> BULK_PREP_HANDLER: Return { hasDuplicateId: Boolean, hasDuplicateHash: Boolean } - end - - alt hasDuplicateId == TRUE && hasDuplicateHash == TRUE - break - BULK_PREP_HANDLER -> BULK_DAO: Request to retrieve Bulk Transfer state & completedTimestamp\nError code: 2003 - activate BULK_DAO - BULK_DAO -> DB: Query database - hnote over DB #lightyellow - bulkTransfer - bulkTransferFulfilment - bulkTransferStateChange - end note - activate DB - BULK_DAO <-- DB: Return resultset - deactivate DB - BULK_DAO --> BULK_PREP_HANDLER: Return **bulkTransferStateId** & **completedTimestamp** (not null when completed) - deactivate BULK_DAO - - note right of BULK_PREP_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: { - bulkTransferState: , - completedTimestamp: - } - }, - metadata: { - event: { - id: , - responseTo: , - type: "notification", - action: "bulk-prepare-duplicate", - createdAt: , - state: { - status: "success", - code: 0 - } - } - } - } - end note - BULK_PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event for Payer - activate TOPIC_NOTIFICATIONS - deactivate TOPIC_NOTIFICATIONS - end - else hasDuplicateId == TRUE && hasDuplicateHash == FALSE - note right of BULK_PREP_HANDLER #yellow - { - id: , - from: , - to: , - type: "application/json", - content: { - headers: , - payload: { - errorInformation: { - errorCode: "3106", - errorDescription: "Modified request", - extensionList: { - extension: [ - { - key: "_cause", - value: - } - ] - } - }, - uriParams: { - id: - } - } - }, - metadata: { - correlationId: , - event: { - id: , - type: "notification", - action: "bulk-prepare", - createdAt: , - state: { - status: "error", - code: "3106", - description: "Modified request" - }, - responseTo: - } - } - } - end note - BULK_PREP_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError codes: 3106 - activate TOPIC_NOTIFICATIONS - deactivate TOPIC_NOTIFICATIONS - else hasDuplicateId == FALSE - group Validate Payer - BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payer Participant details (if it exists) - activate PARTICIPANT_DAO - PARTICIPANT_DAO -> DB: Request Participant details - hnote over DB #lightyellow - participant - participantCurrency - end note - activate DB - PARTICIPANT_DAO <-- DB: Return Participant details if it exists - deactivate DB - PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists - deactivate PARTICIPANT_DAO - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payer\nError codes: 3202 - end - group Validate Payee - BULK_PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve Payee Participant details (if it exists) - activate PARTICIPANT_DAO - PARTICIPANT_DAO -> DB: Request Participant details - hnote over DB #lightyellow - participant - participantCurrency - end note - activate DB - PARTICIPANT_DAO <-- DB: Return Participant details if it exists - deactivate DB - PARTICIPANT_DAO --> BULK_PREP_HANDLER: Return Participant details if it exists - deactivate PARTICIPANT_DAO - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate Payee\nError codes: 3203 - end - BULK_PREP_HANDLER <-> BULK_PREP_HANDLER: Validate crypto-condition\nError codes: 3100 - - alt Validate Bulk Prepare Transfer (success) - group Persist Bulk Transfer State (with bulkTransferState='RECEIVED') - BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\nError codes: 2003 - activate BULK_DAO - BULK_DAO -> DB: Persist bulkTransfer - hnote over DB #lightyellow - bulkTransfer - bulkTransferExtension - bulkTransferStateChange - end note - activate DB - deactivate DB - BULK_DAO --> BULK_PREP_HANDLER: Return success - deactivate BULK_DAO - end - else Validate Bulk Prepare Transfer (failure) - group Persist Bulk Transfer State (with bulkTransferState='INVALID') (Introducing a new status INVALID to mark these entries) - BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer\n(when Payee/Payer/crypto-condition validation fails)\nError codes: 2003 - activate BULK_DAO - BULK_DAO -> DB: Persist transfer - hnote over DB #lightyellow - bulkTransfer - bulkTransferExtension - bulkTransferStateChange - bulkTransferError - end note - activate DB - deactivate DB - BULK_DAO --> BULK_PREP_HANDLER: Return success - deactivate BULK_DAO - end - end - end - end - alt Validate Bulk Prepare Transfer (success) - loop for each individual transfer in the bulk - BULK_PREP_HANDLER -> OBJECT_STORE: Retrieve individual transfers from the bulk using\nreference: **MLOS.individualTransfers.messageId** - activate OBJECT_STORE - note right of OBJECT_STORE #lightgrey - Add elements such as Expiry time, Payer FSP, Payee FSP, etc. to each - transfer to make their format similar to a single transfer - end note - OBJECT_STORE --> BULK_PREP_HANDLER: Stream bulk's individual transfers - deactivate OBJECT_STORE - - group Insert Bulk Transfer Association (with bulkProcessingState='RECEIVED') - BULK_PREP_HANDLER -> BULK_DAO: Request to persist bulk transfer association\nError codes: 2003 - activate BULK_DAO - BULK_DAO -> DB: Insert bulkTransferAssociation - hnote over DB #lightyellow - bulkTransferAssociation - end note - activate DB - deactivate DB - BULK_DAO --> BULK_PREP_HANDLER: Return success - deactivate BULK_DAO - end - - note right of BULK_PREP_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: - }, - metadata: { - event: { - id: , - responseTo: , - type: "prepare", - action: "bulk-prepare", - createdAt: , - state: { - status: "success", - code: 0, - description:"action successful" - } - } - } - } - end note - BULK_PREP_HANDLER -> TOPIC_TRANSFER_PREPARE: Route & Publish Prepare event to the Payer for the Individual Transfer\nError codes: 2003 - activate TOPIC_TRANSFER_PREPARE - deactivate TOPIC_TRANSFER_PREPARE - end - else Validate Bulk Prepare Transfer (failure) - note right of BULK_PREP_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: "application/json", - content: { - headers: , - payload: { - "errorInformation": { - "errorCode": - "errorDescription": "", - "extensionList": - } - }, - metadata: { - event: { - id: , - responseTo: , - type: "bulk-processing", - action: "bulk-abort", - createdAt: , - state: { - status: "error", - code: - description: - } - } - } - } - end note - BULK_PREP_HANDLER -> TOPIC_BULK_PROCESSING: Publish Processing (failure) event for Payer\nError codes: 2003 - activate TOPIC_BULK_PROCESSING - deactivate TOPIC_BULK_PROCESSING - end -end -deactivate BULK_PREP_HANDLER -@enduml - diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md deleted file mode 100644 index 75f248785..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.0-bulk-prepare-transfer-request-overview.md +++ /dev/null @@ -1,16 +0,0 @@ -# Bulk Prepare Transfer Request [Overview] [includes individual transfers in a bulk] - -Sequence design diagram for Prepare Transfer Request process. - -## References within Sequence Diagram - -* [Bulk Prepare Handler Consume (1.1.1)](1.1.1-bulk-prepare-handler-consume.md) -* [Prepare Handler Consume (1.2.1)](1.2.1-prepare-handler-consume-for-bulk.md) -* [Position Handler Consume (1.3.0)](1.3.0-position-handler-consume-overview.md) -* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) -* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.0-bulk-prepare-overview.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md deleted file mode 100644 index 3ae05112f..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.1.1-bulk-prepare-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Bulk Prepare handler consume - -Sequence design diagram for Bulk Prepare Handler Consume process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.1.1-bulk-prepare-handler.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md deleted file mode 100644 index faaa73cec..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.2.1-prepare-handler-consume-for-bulk.md +++ /dev/null @@ -1,12 +0,0 @@ -# Prepare handler consume [that includes individual transfers in a bulk] - -Sequence design diagram for Prepare Handler Consume process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.2.1-prepare-handler.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md deleted file mode 100644 index 8c3c80e3f..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.0-position-handler-consume-overview.md +++ /dev/null @@ -1,15 +0,0 @@ -# Position Handler Consume [that includes individual transfers in a bulk] - -Sequence design diagram for Position Handler Consume process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) -* [Fufil Position Handler Consume (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) -* [Abort Position Handler Consume (2.2.2)](2.2.2-fulfil-abort-for-bulk.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.0-position-overview.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md deleted file mode 100644 index 883ed0f87..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.3.1-prepare-position-handler-consume.md +++ /dev/null @@ -1,8 +0,0 @@ -# Prepare Position Handler Consume [that includes individual transfers in a bulk] - -Sequence design diagram for Prepare Position Handler Consume process - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.3.1-position-prepare.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md deleted file mode 100644 index be712867f..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/1.4.1-bulk-processing-handler.md +++ /dev/null @@ -1,8 +0,0 @@ -# Bulk Processing Handler Consume - -Sequence design diagram for Bulk Processing Handler Consume process - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-1.4.1-bulk-processing-handler.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md deleted file mode 100644 index f2af1e970..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.0-bulk-fulfil-transfer-request-overview.md +++ /dev/null @@ -1,16 +0,0 @@ -# Bulk Fulfil Transfer Request Overview - -Sequence design diagram for the Bulk Fulfil Transfer request - -## References within Sequence Diagram - -* [Bulk Fulfil Handler Consume (Success) (2.1.1)](2.1.1-bulk-fulfil-handler-consume.md) -* [Fulfil Handler Consume (Success) (2.2.1)](2.2.1-fulfil-commit-for-bulk.md) -* [Position Handler Consume (Success) (2.3.1)](2.3.1-fulfil-position-handler-consume.md) -* [Bulk Processing Handler Consume (1.4.1)](1.4.1-bulk-processing-handler.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.0-bulk-fulfil-overview.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md deleted file mode 100644 index 3ce237bfd..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.1.1-bulk-fulfil-handler-consume.md +++ /dev/null @@ -1,14 +0,0 @@ -# Bulk Fulfil Handler Consume - -Sequence design diagram for the Bulk Fulfil Handler Consume process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [seq-signature-validation](../../central-event-processor/signature-validation.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.1.1-bulk-fulfil-handler.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md deleted file mode 100644 index e5a1af9d6..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.1-fulfil-commit-for-bulk.md +++ /dev/null @@ -1,12 +0,0 @@ -# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers - -Sequence design diagram for the Bulk Fulfil Transfer for the Commit option - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.1-fulfil-handler-commit.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md deleted file mode 100644 index 2511cf3b7..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.2.2-fulfil-abort-for-bulk.md +++ /dev/null @@ -1,14 +0,0 @@ -# Payee sends a Bulk Fulfil Transfer request - Bulk is broken down into individual transfers - -Sequence design diagram for the Fulfil Handler Consume Reject/Abort process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [seq-signature-validation](../../central-event-processor/signature-validation.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.2.2-fulfil-handler-abort.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md deleted file mode 100644 index a25cbe70f..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.1-fulfil-position-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Fulfil Position Handler Consume [that includes individual transfers in a bulk] - -Sequence design diagram for the Fulfil Position Handler Consume process - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.1-position-fulfil.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md deleted file mode 100644 index 7209b1b8e..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/2.3.2-position-consume-abort.md +++ /dev/null @@ -1,8 +0,0 @@ -# Position Handler Consume for Fulfil aborts at individual transfer level - -Sequence design diagram for Fulfil Position Handler Consume process - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-2.3.2-position-abort.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md deleted file mode 100644 index 8100587c9..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.0-transfer-timeout-overview-for-bulk.md +++ /dev/null @@ -1,8 +0,0 @@ -## Transfer Timeout [includes individual transfers in a Bulk] - -Sequence design diagram for the Transfer Timeout process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.0-timeout-overview.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md b/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md deleted file mode 100644 index c82f4792e..000000000 --- a/mojaloop-technical-overview/central-bulk-transfers/transfers/3.1.1-transfer-timeout-handler-consume.md +++ /dev/null @@ -1,8 +0,0 @@ -# TimeOut Handler - -Sequence design diagram for Timeout Handler process - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-bulk-transfers/assets/diagrams/sequence/seq-bulk-3.1.1-timeout-handler.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md b/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md deleted file mode 100644 index 8ffd4c195..000000000 --- a/mojaloop-technical-overview/central-event-processor/5.1.1-notification-handler-for-rejections.md +++ /dev/null @@ -1,13 +0,0 @@ -# Notification Handler for Rejections - -Sequence design diagram for the Notification Handler for Rejections process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](9.1.0-event-handler-placeholder.md) -* [Get Participant Callback Details (3.1.0)](../central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md b/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md deleted file mode 100644 index 38b7b87ca..000000000 --- a/mojaloop-technical-overview/central-event-processor/9.1.0-event-handler-placeholder.md +++ /dev/null @@ -1,8 +0,0 @@ -# Event Handler Placeholder - -Sequence design diagram for the Event Handler process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-event-processor/signature-validation.md b/mojaloop-technical-overview/central-event-processor/signature-validation.md deleted file mode 100644 index a6c9df9ba..000000000 --- a/mojaloop-technical-overview/central-event-processor/signature-validation.md +++ /dev/null @@ -1,8 +0,0 @@ -# Signature Validation - -Sequence design diagram for the Signature Validation process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/README.md b/mojaloop-technical-overview/central-ledger/README.md deleted file mode 100644 index 259d6ebf4..000000000 --- a/mojaloop-technical-overview/central-ledger/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Central-Ledger Services - -The central ledger is a series of services that facilitate clearing and settlement of transfers between DFSPs, including the following functions: - -* Brokering real-time messaging for funds clearing -* Maintaining net positions for a deferred net settlement -* Propagating scheme-level and off-transfer fees - -## 1. Central Ledger Process Design - -### 1.1 Architecture overview - -![Central-Ledger Architecture](assets/diagrams/architecture/Arch-mojaloop-central-ledger.svg) - -## 2. Transfers End-to-End Architecture - -![Transfers Architecture](assets/diagrams/architecture/Transfers-Arch-End-to-End.svg) - -## 3. Database Design - -### Note - -The tables *Grey* colored tables are specific to the transfer process. The *Blue* and *Green* color tables are used for reference purposes during the Transfer process. - -Summary of the tables specific to the transfer process; - -- `transfer` - stores data related to the transfer; -- `transferDuplicateCheck` - used to identify duplication during the transfer requests process; -- `transferError` - stores information on transfer errors encountered during the transfer process; -- `transferErrorDuplicateCheck` - used to identify duplication error transfer processes; -- `transferExtensions` - stores information on the transfer extension data; -- `transferFulfilment` - stores data for transfers that have completed the prepare transfer process; -- `transferFulfilmentDuplicateCheck` - used the identify duplicate transfer fulfil requests; -- `transferParticipant` - participant information related to the transfer process; -- `transferStateChange` - use to track state changes of each individual transfer, creating and audit trail for a specific transfer request; -- `transferTimeout` - stores information of transfers that encountered a timeout exception during the process; -- `ilpPacket` - stores the ilp package for the transfer; - -The remaining tables in the below ERD are either lookup (blue) or settlement-specific (red) and are included as direct or indirect dependencies to depict the relation between the transfer specific entities and the transfer tables. - -The **Central Ledger** database schema definition [Central-Ledger Database Schema Definition](assets/database/central-ledger-ddl-MySQLWorkbench.sql). - -![Central-Ledger Database Diagram](assets/database/central-ledger-schema.png) - -## 4. API Specification - -Refer to **Central Ledger API** in the [API Specifications](../../api/README.md#central-ledger-api) section. diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md deleted file mode 100644 index 272865cc9..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-health-check.md +++ /dev/null @@ -1,268 +0,0 @@ -# GET Health Check - -Design discussion for new Health Check implementation. - - -## Objectives - -The goal for this design is to implement a new Health check for mojaloop switch services that allows for a greater level of detail. - -It Features: -- Clear HTTP Statuses (no need to inspect the response to know there are no issues) -- ~Backwards compatibility with existing health checks~ - No longer a requirement. See [this discussion](https://github.com/mojaloop/project/issues/796#issuecomment-498350828). -- Information about the version of the API, and how long it has been running for -- Information about sub-service (kafka, logging sidecar and mysql) connections - -## Request Format -`/health` - -Uses the newly implemented health check. As discussed [here](https://github.com/mojaloop/project/issues/796#issuecomment-498350828) since there will be no added connection overhead (e.g. pinging a database) as part of implementing the health check, there is no need to complicate things with a simple and detailed version. - -Responses Codes: -- `200` - Success. The API is up and running, and is sucessfully connected to necessary services. -- `502` - Bad Gateway. The API is up and running, but the API cannot connect to necessary service (eg. `kafka`). -- `503` - Service Unavailable. This response is not implemented in this design, but will be the default if the api is not and running - -## Response Format - -| Name | Type | Description | Example | -| --- | --- | --- | --- | -| `status` | `statusEnum` | The status of the service. Options are `OK` and `DOWN`. _See `statusEnum` below_. | `"OK"` | -| `uptime` | `number` | How long (in seconds) the service has been alive for. | `123456` | -| `started` | `string` (ISO formatted date-time) | When the service was started (UTC) | `"2019-05-31T05:09:25.409Z"` | -| `versionNumber` | `string` (semver) | The current version of the service. | `"5.2.5"` | -| `services` | `Array` | A list of services this service depends on, and their connection status | _see below_ | - -### serviceHealth - -| Name | Type | Description | Example | -| --- | --- | --- | --- | -| `name` | `subServiceEnum` | The sub-service name. _See `subServiceEnum` below_. | `"broker"` | -| `status` | `enum` | The status of the service. Options are `OK` and `DOWN` | `"OK"` | - -### subServiceEnum - -The subServiceEnum enum describes a name of the subservice: - -Options: -- `datastore` -> The database for this service (typically a MySQL Database). -- `broker` -> The message broker for this service (typically Kafka). -- `sidecar` -> The logging sidecar sub-service this service attaches to. -- `cache` -> The caching sub-service this services attaches to. - - -### statusEnum - -The status enum represents status of the system or sub-service. - -It has two options: -- `OK` -> The service or sub-service is healthy. -- `DOWN` -> The service or sub-service is unhealthy. - -When a service is `OK`: the API is considered healthy, and all sub-services are also considered healthy. - -If __any__ sub-service is `DOWN`, then the entire health check will fail, and the API will be considered `DOWN`. - -## Defining Sub-Service health - -It is not enough to simply ping a sub-service to know if it is healthy, we want to go one step further. These criteria will change with each sub-service. - -### `datastore` - -For `datastore`, a status of `OK` means: -- An existing connection to the database -- The database is not empty (contains more than 1 table) - - -### `broker` - -For `broker`, a status of `OK` means: -- An existing connection to the kafka broker -- The necessary topics exist. This will change depending on which service the health check is running for. - -For example, for the `central-ledger` service to be considered healthy, the following topics need to be found: -``` -topic-admin-transfer -topic-transfer-prepare -topic-transfer-position -topic-transfer-fulfil -``` - -### `sidecar` - -For `sidecar`, a status of `OK` means: -- An existing connection to the sidecar - - -### `cache` - -For `cache`, a status of `OK` means: -- An existing connection to the cache - - -## Swagger Definition - ->_Note: These will be added to the existing swagger definitions for the following services:_ -> - `ml-api-adapter` -> - `central-ledger` -> - `central-settlement` -> - `central-event-processor` -> - `email-notifier` - -```json -{ - /// . . . - "/health": { - "get": { - "operationId": "getHealth", - "tags": [ - "health" - ], - "responses": { - "default": { - "schema": { - "$ref": "#/definitions/health" - }, - "description": "Successful" - } - } - } - }, - // . . . - "definitions": { - "health": { - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": [ - "OK", - "DOWN" - ] - }, - "uptime": { - "description": "How long (in seconds) the service has been alive for.", - "type": "number", - }, - "started": { - "description": "When the service was started (UTC)", - "type": "string", - "format": "date-time" - }, - "versionNumber": { - "description": "The current version of the service.", - "type": "string", - "example": "5.2.3", - }, - "services": { - "description": "A list of services this service depends on, and their connection status", - "type": "array", - "items": { - "$ref": "#/definitions/serviceHealth" - } - }, - }, - }, - "serviceHealth": { - "type": "object", - "properties": { - "name": { - "description": "The sub-service name.", - "type": "string", - "enum": [ - "datastore", - "broker", - "sidecar", - "cache" - ] - }, - "status": { - "description": "The connection status with the service.", - "type": "string", - "enum": [ - "OK", - "DOWN" - ] - } - } - } - } -} -``` - - -### Example Requests and Responses: - -__Successful Legacy Health Check:__ - -```bash -GET /health HTTP/1.1 -Content-Type: application/json - -200 SUCCESS -{ - "status": "OK" -} -``` - - -__Successful New Health Check:__ - -``` -GET /health?detailed=true HTTP/1.1 -Content-Type: application/json - -200 SUCCESS -{ - "status": "OK", - "uptime": 0, - "started": "2019-05-31T05:09:25.409Z", - "versionNumber": "5.2.3", - "services": [ - { - "name": "broker", - "status": "OK", - } - ] -} -``` - -__Failed Health Check, but API is up:__ - -``` -GET /health?detailed=true HTTP/1.1 -Content-Type: application/json - -502 BAD GATEWAY -{ - "status": "DOWN", - "uptime": 0, - "started": "2019-05-31T05:09:25.409Z", - "versionNumber": "5.2.3", - "services": [ - { - "name": "broker", - "status": "DOWN", - } - ] -} -``` - -__Failed Health Check:__ - -``` -GET /health?detailed=true HTTP/1.1 -Content-Type: application/json - -503 SERVICE UNAVAILABLE -``` - - -## Sequence Diagram - -Sequence design diagram for the GET Health - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-health-1.0.0.plantuml" %} -{% enduml %} - -![](../assets/diagrams/sequence/seq-get-health-1.0.0.svg) \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md deleted file mode 100644 index 7303b7b5c..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-get-limits-for-all-participants.md +++ /dev/null @@ -1,8 +0,0 @@ -# GET Participant Limit Details For All Participants - -Sequence design diagram for the GET Participant Limit Details For All Participants process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-all-participant-limit-1.0.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md deleted file mode 100644 index 06822896a..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.0.0-post-participant-position-limit.md +++ /dev/null @@ -1,8 +0,0 @@ -# Create initial position and limits for Participant - -Sequence design diagram for the POST (create) Participant Initial Position and Limit process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participant-position-limits-1.0.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md deleted file mode 100644 index 555eb5aa6..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-get-participant-limit-details.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request Participant Position and Limit Details - -Sequence design diagram for the Request Participant Position and Limit Details process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-participant-position-limit-1.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md deleted file mode 100644 index f62de5e7a..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.0-post-participant-limits.md +++ /dev/null @@ -1,8 +0,0 @@ -# Adjust Participant Limit for a certain Currency - -Sequence design diagram for the POST (manage) Participant Limit Details process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-manage-participant-limit-1.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md b/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md deleted file mode 100644 index 20b722a29..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/1.1.5-get-transfer-status.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request transfer status - -Sequence design diagram for the GET Transfer Status process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-get-transfer-1.1.5-phase2.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md b/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md deleted file mode 100644 index 1a26bf67d..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-get-participant-callback-details.md +++ /dev/null @@ -1,8 +0,0 @@ -# 3.1.0 Get Participant Callback Details - -Sequence design diagram for the GET Participant Callback Details process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-3.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md b/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md deleted file mode 100644 index 3182dacd2..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/3.1.0-post-participant-callback-details.md +++ /dev/null @@ -1,8 +0,0 @@ -# 3.1.0 Add Participant Callback Details - -Sequence design diagram for the POST (Add) Participant Callback Details process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-callback-add-3.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md b/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md deleted file mode 100644 index 1d43a103d..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/4.1.0-get-participant-position-details.md +++ /dev/null @@ -1,8 +0,0 @@ -# Get Participant Position Details - -Sequence design diagram for the GET Participant Position Details process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-4.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md b/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md deleted file mode 100644 index 2e52dbd82..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/4.2.0-get-positions-of-all-participants.md +++ /dev/null @@ -1,8 +0,0 @@ -# Get Position Details for all Participants - -Sequence design diagram for the Get Positions of all Participants process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-participants-positions-query-all-4.2.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/admin-operations/README.md b/mojaloop-technical-overview/central-ledger/admin-operations/README.md deleted file mode 100644 index ad1133844..000000000 --- a/mojaloop-technical-overview/central-ledger/admin-operations/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Mojaloop HUB/Switch operations. - -Operational processes normally initiated by a HUB/Switch operator. diff --git a/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd b/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd deleted file mode 100644 index dc18f82f2..000000000 --- a/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema-DBeaver.erd +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - COLOR LEGEND: -Green - subject specific entity -Gray - transfer specific entity -Brown - bulk transfer entity -Red - settlement specific entity -Blue - enumeration entity -Purple - to be removed -Cyan - impl. specific -Yellow - tbd - - \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png b/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png deleted file mode 100644 index 6ae8e2e18..000000000 Binary files a/mojaloop-technical-overview/central-ledger/assets/database/central-ledger-schema.png and /dev/null differ diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml b/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml deleted file mode 100644 index 517a6c490..000000000 --- a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml +++ /dev/null @@ -1,283 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Georgi Georgiev - * Rajiv Mothilal - * Miguel de Barros - -------------- - ******'/ - -@startuml -' declate title -title 1.3.1. Prepare Position Handler Consume - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistence Store - -' declare actors -control "Position Handler" as POS_HANDLER - -entity "Position\nManagement\nFacade" as POS_MGMT -collections "Notification-Topic" as TOPIC_NOTIFICATIONS -entity "Position DAO" as POS_DAO -database "Central Store" as DB - -box "Central Service" #LightYellow - participant POS_HANDLER - participant TOPIC_NOTIFICATIONS - participant POS_MGMT - participant POS_DAO - participant DB -end box - -' start flow -activate POS_HANDLER -group Prepare Position Handler Consume - POS_HANDLER -> POS_MGMT: Request transfers to be processed - activate POS_MGMT - POS_MGMT -> POS_MGMT: Check 1st transfer to select the Participant and Currency - group DB TRANSACTION - ' DB Trans: This is where 1st DB Transaction would start in 2 DB transacation future model for horizontal scaling - POS_MGMT -> POS_MGMT: Loop through batch and build list of transferIds and calculate sumTransfersInBatch,\nchecking all in Batch are for the correct Paricipant and Currency\nError code: 2001, 3100 - POS_MGMT -> DB: Retrieve current state of all transfers in array from DB with select whereIn\n(FYI: The two DB transaction model needs to add a mini-state step here (RECEIVED_PREPARE => RECEIVDED_PREPARE_PROCESSING) so that the transfers are left alone if processing has started) - activate DB - hnote over DB #lightyellow - transferStateChange - transferParticipant - end note - DB --> POS_MGMT: Return current state of all selected transfers from DB - deactivate DB - POS_MGMT <-> POS_MGMT: Validate current state (transferStateChange.transferStateId == 'RECEIVED_PREPARE')\nError code: 2001 against failing transfers\nBatch is not rejected as a whole. - - note right of POS_MGMT #lightgray - List of transfers used during processing - **reservedTransfers** is list of transfers to be processed in the batch - **abortedTransfers** is the list of transfers in the incorrect state going into the process. Currently the transferStateChange is set to ABORTED - this should only be done if not already in a final state (idempotency) - **processedTransfers** is the list of transfers that have gone through the position management algorithm. Both successful and failed trasnfers appear here as the order and "running position" against each is necessary for reconciliation - - Scalar intermidate values used in the algorithm - **transferAmount** = payload.amount.amount - **sumTransfersInBatch** = SUM amount against each Transfer in batch - **currentPosition** = participantPosition.value - **reservedPosition** = participantPosition.{original}reservedValue - **effectivePosition** = currentPosition + reservedPosition - **heldPosition** = effectivePosition + sumTransfersInBatch - **availablePosition** = participantLimit(NetDebitCap) - effectivePosition - **sumReserved** = SUM of transfers that have met rule criteria and processed - end note - note over POS_MGMT,DB - Going to reserve the sum of the valid transfers in the batch against the Participants Positon in the Currency of this batch - and calculate the available position for the Participant to use - end note - POS_MGMT -> DB: Select effectivePosition FOR UPDATE from DB for Payer - activate DB - hnote over DB #lightyellow - participantPosition - end note - DB --> POS_MGMT: Return effectivePosition (currentPosition and reservedPosition) from DB for Payer - deactivate DB - POS_MGMT -> POS_MGMT: Increment reservedValue to heldPosition\n(reservedValue = reservedPosition + sumTransfersInBatch) - POS_MGMT -> DB: Persist reservedValue - activate DB - hnote over DB #lightyellow - UPDATE **participantPosition** - SET reservedValue += sumTransfersInBatch - end note - deactivate DB - ' DB Trans: This is where 1st DB Transaction would end in 2 DB transacation future model for horizontal scaling - - - POS_MGMT -> DB: Request position limits for Payer Participant - activate DB - hnote over DB #lightyellow - FROM **participantLimit** - WHERE participantLimit.limitTypeId = 'NET-DEBIT-CAP' - AND participantLimit.participantId = payload.payerFsp - AND participantLimit.currencyId = payload.amount.currency - end note - DB --> POS_MGMT: Return position limits - deactivate DB - POS_MGMT <-> POS_MGMT: **availablePosition** = participantLimit(netDebitCap) - effectivePosition (same as = netDebitCap - currentPosition - reservedPosition) - note over POS_MGMT,DB - For each transfer in the batch, validate the availablility of position to meet the transfer amount - this will be as per the position algorithm documented below - end note - POS_MGMT <-> POS_MGMT: Validate availablePosition for each tranfser (see algorithm below)\nError code: 4001 - note right of POS_MGMT #lightgray - 01: sumReserved = 0 // Record the sum of the transfers we allow to progress to RESERVED - 02: sumProcessed =0 // Record the sum of the transfers already processed in this batch - 03: processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position - 04: foreach transfer in reservedTransfers - 05: sumProcessed += transfer.amount // the total processed so far **(NEED TO UPDATE IN CODE)** - 06: if availablePosition >= transfer.amount - 07: transfer.state = "RESERVED" - 08: availablePosition -= preparedTransfer.amount - 09: sumRESERVED += preparedTransfer.amount - 10: else - 11: preparedTransfer.state = "ABORTED" - 12: preparedTransfer.reason = "Net Debit Cap exceeded by this request at this time, please try again later" - 13: end if - 14: runningPosition = currentPosition + sumReserved // the initial value of the Participants position plus the total value that has been accepted in the batch so far - 15: runningReservedValue = sumTransfersInBatch - sumProcessed + reservedPosition **(NEED TO UPDATE IN CODE)** // the running down of the total reserved value at the begining of the batch. - 16: Add transfer to the processedTransfer list recording the transfer state and running position and reserved values { transferState, transfer, rawMessage, transferAmount, runningPosition, runningReservedValue } - 16: end foreach - end note - note over POS_MGMT,DB - Once the outcome for all transfers is known,update the Participant's position and remove the reserved amount associated with the batch - (If there are any alarm limits, process those returning limits in which the threshold has been breached) - Do a bulk insert of the trasnferStateChanges associated with processing, using the result to complete the participantPositionChange and bulk insert of these to persist the running position - end note - POS_MGMT->POS_MGMT: Assess any limit thresholds on the final position\nadding to alarm list if triggered - - ' DB Trans: This is where 2nd DB Transaction would start in 2 DB transacation future model for horizontal scaling - POS_MGMT->DB: Persist latest position **value** and **reservedValue** to DB for Payer - hnote over DB #lightyellow - UPDATE **participantPosition** - SET value += sumRESERVED, - reservedValue -= sumTransfersInBatch - end note - activate DB - deactivate DB - - POS_MGMT -> DB: Bulk persist transferStateChange for all processedTransfers - hnote over DB #lightyellow - batch INSERT **transferStateChange** - select for update from transfer table where transferId in ([transferBatch.transferId,...]) - build list of transferStateChanges from transferBatch - - end note - activate DB - deactivate DB - - POS_MGMT->POS_MGMT: Populate batchParticipantPositionChange from the resultant transferStateChange and the earlier processedTransfer list - - note right of POS_MGMT #lightgray - Effectively: - SET transferStateChangeId = processedTransfer.transferStateChangeId, - participantPositionId = preparedTransfer.participantPositionId, - value = preparedTransfer.positionValue, - reservedValue = preparedTransfer.positionReservedValue - end note - POS_MGMT -> DB: Bulk persist the participant position change for all processedTransfers - hnote over DB #lightyellow - batch INSERT **participantPositionChange** - end note - activate DB - deactivate DB - ' DB Trans: This is where 2nd DB Transaction would end in 2 DB transacation future model for horizontal scaling - end - POS_MGMT --> POS_HANDLER: Return a map of transferIds and their transferStateChanges - deactivate POS_MGMT - alt Calculate & Validate Latest Position Prepare (success) - note right of POS_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: - }, - metadata: { - event: { - id: , - responseTo: , - type: transfer, - action: prepare, - createdAt: , - state: { - status: "success", - code: 0 - } - } - } - } - end note - POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification event\nError code: 2003 - activate TOPIC_NOTIFICATIONS - deactivate TOPIC_NOTIFICATIONS - else Calculate & Validate Latest Position Prepare (failure) - note right of POS_HANDLER #red: Validation failure! - - group Persist Transfer State (with transferState='ABORTED' on position check fail) - POS_HANDLER -> POS_DAO: Request to persist transfer\nError code: 2003 - activate POS_DAO - note right of POS_HANDLER #lightgray - transferStateChange.state = "ABORTED", - transferStateChange.reason = "Net Debit Cap exceeded by this request at this time, please try again later" - end note - POS_DAO -> DB: Persist transfer state - hnote over DB #lightyellow - transferStateChange - end note - activate DB - deactivate DB - POS_DAO --> POS_HANDLER: Return success - deactivate POS_DAO - end - - note right of POS_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: { - "errorInformation": { - "errorCode": 4001, - "errorDescription": "Payer FSP insufficient liquidity", - "extensionList": - } - }, - metadata: { - event: { - id: , - responseTo: , - type: notification, - action: prepare, - createdAt: , - state: { - status: 'error', - code: - description: - } - } - } - } - end note - POS_HANDLER -> TOPIC_NOTIFICATIONS: Publish Notification (failure) event for Payer\nError code: 2003 - activate TOPIC_NOTIFICATIONS - deactivate TOPIC_NOTIFICATIONS - deactivate POS_HANDLER - end -end -deactivate POS_HANDLER -@enduml diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml b/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml deleted file mode 100644 index 647cd0d20..000000000 --- a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml +++ /dev/null @@ -1,182 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Georgi Georgiev - * Miguel de Barros - -------------- - ******'/ - -@startuml -' declate title -title 1.1.1.b. Prepare Handler Consume (batch messages) - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistance Store - -' declare actors -collections "topic-transfer-prepare" as TOPIC_TRANSFER_PREPARE -control "Prepare Event Handler" as PREP_HANDLER -collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION -collections "Event-Topic" as TOPIC_EVENTS -collections "Notification-Topic" as TOPIC_NOTIFICATIONS -entity "Position DAO" as POS_DAO -entity "Participant DAO" as PARTICIPANT_DAO -database "Central Store" as DB - -box "Central Service" #LightYellow - participant TOPIC_TRANSFER_PREPARE - participant PREP_HANDLER - participant TOPIC_TRANSFER_POSITION - participant TOPIC_EVENTS - participant TOPIC_NOTIFICATIONS - participant POS_DAO - participant PARTICIPANT_DAO - participant DB -end box - -' start flow -activate PREP_HANDLER -group Prepare Handler Consume - TOPIC_TRANSFER_PREPARE <- PREP_HANDLER: Consume Prepare event batch of messages for Payer - activate TOPIC_TRANSFER_PREPARE - deactivate TOPIC_TRANSFER_PREPARE - group Persist Event Information - ||| - PREP_HANDLER -> TOPIC_EVENTS: Publish event information - ref over PREP_HANDLER, TOPIC_EVENTS : Event Handler Consume\n - ||| - end - - group Fetch batch Payer information - PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payer Participant details (if it exists) - activate PARTICIPANT_DAO - PARTICIPANT_DAO -> DB: Request Participant details - hnote over DB #lightyellow - participant - end note - activate DB - PARTICIPANT_DAO <-- DB: Return Participant details if it exists - deactivate DB - PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists - deactivate PARTICIPANT_DAO - PREP_HANDLER <-> PREP_HANDLER: Validate Payer - PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYER - end - - group Fetch batch Payee information - PREP_HANDLER -> PARTICIPANT_DAO: Request to retrieve batch of Payee Participant details (if it exists) - activate PARTICIPANT_DAO - PARTICIPANT_DAO -> DB: Request Participant details - hnote over DB #lightyellow - participant - end note - activate DB - PARTICIPANT_DAO <-- DB: Return Participant details if it exists - deactivate DB - PARTICIPANT_DAO --> PREP_HANDLER: Return Participant details if it exists - deactivate PARTICIPANT_DAO - PREP_HANDLER <-> PREP_HANDLER: Validate Payee - PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_PARTICIPANTS_DETAILS_PAYEE - end - - group Fetch batch of transfers - PREP_HANDLER -> POS_DAO: Request to retrieve batch of Transfers (if it exists) - activate POS_DAO - POS_DAO -> DB: Request batch of Transfers - hnote over DB #lightyellow - transfer - end note - activate DB - POS_DAO <-- DB: Return batch of Transfers (if it exists) - deactivate DB - POS_DAO --> PREP_HANDLER: Return batch of Transfer (if it exists) - deactivate POS_DAO - PREP_HANDLER -> PREP_HANDLER: store result set in var: $LIST_TRANSFERS - end - - loop for each message in batch - - group Validate Prepare Transfer - group Validate Payer - PREP_HANDLER <-> PREP_HANDLER: Validate Payer against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYER - end - group Validate Payee - PREP_HANDLER <-> PREP_HANDLER: Validate Payee against in-memory var $LIST_PARTICIPANTS_DETAILS_PAYEE - end - group Duplicate check - PREP_HANDLER <-> PREP_HANDLER: Validate duplicate Check against in-memory var $LIST_TRANSFERS - end - PREP_HANDLER <-> PREP_HANDLER: Validate amount - PREP_HANDLER <-> PREP_HANDLER: Validate crypto-condition - PREP_HANDLER <-> PREP_HANDLER: Validate message signature (to be confirmed in future requirement) - end - - group Persist Transfer State (with transferState='RECEIVED' on validation pass) - PREP_HANDLER -> POS_DAO: Request to persist transfer - activate POS_DAO - POS_DAO -> DB: Persist transfer - hnote over DB #lightyellow - transferStateChange - end note - activate DB - deactivate DB - POS_DAO --> PREP_HANDLER: Return success - deactivate POS_DAO - end - - note right of PREP_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: - }, - metadata: { - event: { - id: , - responseTo: , - type: position, - action: prepare, - createdAt: , - state: { - status: "success", - code: 0 - } - } - } - } - end note - PREP_HANDLER -> TOPIC_TRANSFER_POSITION: Route & Publish Position event for Payer - activate TOPIC_TRANSFER_POSITION - deactivate TOPIC_TRANSFER_POSITION - end -end -deactivate PREP_HANDLER -@enduml diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml b/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml deleted file mode 100644 index a312d219d..000000000 --- a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml +++ /dev/null @@ -1,145 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Georgi Georgiev - * Miguel de Barros - -------------- - ******'/ - -@startuml -' declate title -title 1.1.2.b. Position Handler Consume (batch messages) - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistance Store - -' declare actors -collections "topic-transfer-position" as TOPIC_TRANSFER_POSITION -control "Position Event Handler" as POS_HANDLER -collections "Transfer-Topic" as TOPIC_TRANSFERS -entity "Position DAO" as POS_DAO -entity "Event-Topic" as TOPIC_EVENTS -collections "Notification-Topic" as TOPIC_NOTIFICATIONS -entity "Transfer DAO" as TRANS_DAO -database "Central Store" as DB - -box "Central Service" #LightYellow - participant TOPIC_TRANSFER_POSITION - participant POS_HANDLER - participant TOPIC_TRANSFERS - participant TOPIC_EVENTS - participant TOPIC_NOTIFICATIONS - participant POS_DAO - participant TRANS_DAO - participant DB -end box - -' start flow -activate POS_HANDLER -group Position Handler Consume - TOPIC_TRANSFER_POSITION <- POS_HANDLER: Consume Position event batch of messages for Payer - activate TOPIC_TRANSFER_POSITION - deactivate TOPIC_TRANSFER_POSITION - - group Persist Event Information - ||| - POS_HANDLER -> TOPIC_EVENTS: Publish event information - ref over POS_HANDLER, TOPIC_EVENTS : Event Handler Consume\n - ||| - end - - loop for each message in batch - group Calculate position and persist change - POS_HANDLER -> POS_DAO: Request latest position from DB for Payer - activate POS_DAO - POS_DAO -> DB: Retrieve latest position from DB for Payer - hnote over DB #lightyellow - transferPosition - end note - activate DB - deactivate DB - POS_DAO --> POS_HANDLER: Return latest position - deactivate POS_DAO - - POS_HANDLER <-> POS_HANDLER: Calculate latest position (lpos) by incrementing transfer for prepare - POS_HANDLER <-> POS_HANDLER: Validate Calculated latest position against the net-debit cap (netcap) - Rule: lpos < netcap - - POS_HANDLER -> POS_DAO: Request to persist latest position for Payer - activate POS_DAO - POS_DAO -> DB: Persist latest position to DB for Payer - hnote over DB #lightyellow - transferPosition - end note - activate DB - deactivate DB - POS_DAO --> POS_HANDLER: Return success - deactivate POS_DAO - end - group Persist Transfer State (with transferState='RESERVED' on position check pass) - POS_HANDLER -> TRANS_DAO: Request to persist batch transfer - activate TRANS_DAO - TRANS_DAO -> DB: Persist batch transfer - hnote over DB #lightyellow - transferStateChange - end note - activate DB - deactivate DB - TRANS_DAO --> POS_HANDLER: Return success - deactivate TRANS_DAO - end - note right of POS_HANDLER #yellow - Message: - { - id: - from: , - to: , - type: application/json - content: { - headers: , - payload: - }, - metadata: { - event: { - id: , - responseTo: , - type: transfer, - action: prepare, - createdAt: , - state: { - status: "success", - code: 0 - } - } - } - } - end note - POS_HANDLER -> TOPIC_TRANSFERS: Publish Transfer event - activate TOPIC_TRANSFERS - deactivate TOPIC_TRANSFERS - end -end -deactivate POS_HANDLER -@enduml diff --git a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml b/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml deleted file mode 100644 index ec71dbe29..000000000 --- a/mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml +++ /dev/null @@ -1,104 +0,0 @@ -/'***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Georgi Georgiev - * Miguel de Barros - -------------- - ******'/ - -@startuml -' declate title -title 1.1.4.b. Send notification to Participant (Payer/Payee) (batch messages) - -autonumber - -' Actor Keys: -' boundary - APIs/Interfaces, etc -' collections - Kafka Topics -' control - Kafka Consumers -' entity - Database Access Objects -' database - Database Persistance Store - -' declare actors -actor "DFSP(n)\nParticipant" as DFSP -control "ML API Notification Event Handler" as NOTIFY_HANDLER -boundary "Central Service API" as CSAPI -collections "Notification-Topic" as TOPIC_NOTIFICATIONS -collections "Event-Topic" as TOPIC_EVENTS -entity "Notification DAO" as NOTIFY_DAO -database "Central Store" as DB - -box "Financial Service Provider" #lightGray - participant DFSP -end box - -box "ML API Adapter Service" #LightBlue - participant NOTIFY_HANDLER -end box - -box "Central Service" #LightYellow -participant TOPIC_NOTIFICATIONS - participant CSAPI - participant TOPIC_EVENTS - participant EVENT_DAO - participant NOTIFY_DAO - participant DB -end box - -' start flow -activate NOTIFY_HANDLER -group Send notification to Participant - TOPIC_NOTIFICATIONS <- NOTIFY_HANDLER: **Consume Notifications event batch of messages for Participant** - activate TOPIC_NOTIFICATIONS - deactivate TOPIC_NOTIFICATIONS - loop for each message in batch - group Persist Event Information - NOTIFY_HANDLER -> CSAPI: Request to persist event information - POST - /events - activate CSAPI - CSAPI -> TOPIC_EVENTS: Publish event information - activate TOPIC_EVENTS - ||| - ref over TOPIC_EVENTS : Event Handler Consume\n - ||| - TOPIC_EVENTS --> CSAPI: Return success - deactivate TOPIC_EVENTS - CSAPI --> NOTIFY_HANDLER: Return success - deactivate CSAPI - end - NOTIFY_HANDLER -> CSAPI: Request Notifications details for Participant - GET - /notifications/DFPS(n) - activate CSAPI - CSAPI -> NOTIFY_DAO: Fetch Notifications details for Participant - activate NOTIFY_DAO - NOTIFY_DAO -> DB: Fetch Notifications details for Participant - activate DB - hnote over DB #lightyellow - transferPosition - end note - DB --> NOTIFY_DAO: Retrieved Notification details for Participant - 'deactivate DB - NOTIFY_DAO --> CSAPI: Return Notifications details for Participant - deactivate NOTIFY_DAO - CSAPI --> NOTIFY_HANDLER: Return Notifications details for Participant - deactivate CSAPI - NOTIFY_HANDLER --> DFSP: Callback with Prepare result to Participant to specified URL - PUT - />/transfers - end -end -deactivate NOTIFY_HANDLER -@enduml diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md deleted file mode 100644 index b9e886f76..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.0-prepare-transfer-request.md +++ /dev/null @@ -1,17 +0,0 @@ -# Prepare Transfer Request - -Sequence design diagram for Prepare Transfer Request process. - -## References within Sequence Diagram - -* [Prepare Handler Consume (1.1.1.a)](1.1.1.a-prepare-handler-consume.md) -* [Prepare Handler Consume (1.1.1.b)](1.1.1.b-prepare-handler-consume.md) -* [Position Handler Consume (1.1.2.a)](1.1.2.a-position-handler-consume.md) -* [Position Handler Consume (1.1.2.b)](1.1.2.b-position-handler-consume.md) -* [Send notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) -* [Send notification to Participant (1.1.4.b)](1.1.4.b-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md deleted file mode 100644 index 1dba54a81..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.1.a-prepare-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Prepare handler consume - -Sequence design diagram for Prepare Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.a.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md deleted file mode 100644 index b010006d0..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.1.b-prepare-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Prepare handler consume - -Sequence design diagram for Prepare Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.1.b.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md deleted file mode 100644 index 960c51ca7..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.2.a-position-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Position handler consume - -Sequence design diagram for Position Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.a.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md deleted file mode 100644 index d3173f66d..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.2.b-position-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -# Position handler consume - -Sequence design diagram for Position Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.2.b.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md deleted file mode 100644 index ab3653ed0..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.4.a-send-notification-to-participant.md +++ /dev/null @@ -1,12 +0,0 @@ -# Send Notification to Participant - -Sequence design diagram for the Send Notification to Participant request. - -## References within Sequence Diagram - -* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.a.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md b/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md deleted file mode 100644 index bac639f0c..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.1.4.b-send-notification-to-participant.md +++ /dev/null @@ -1,12 +0,0 @@ -# Send Notification to Participant - -Sequence design diagram for the Send Notification to Participant request. - -## References within Sequence Diagram - -* [9.1.0-event-handler-consume](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-prepare-1.1.4.b.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md deleted file mode 100644 index aa37559a3..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.3.0-position-handler-consume.md +++ /dev/null @@ -1,15 +0,0 @@ -# Position Handler Consume - -Sequence design diagram for Position Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [Prepare Position Handler Consume (1.3.1)](1.3.1-prepare-position-handler-consume.md) -* [Fufil Position Handler Consume (1.3,2)](1.3.2-fulfil-position-handler-consume.md) -* [Abort Position Handler Consume (1.3,3)](1.3.3-abort-position-handler-consume.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md deleted file mode 100644 index 79689403a..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.3.1-prepare-position-handler-consume.md +++ /dev/null @@ -1,8 +0,0 @@ -# Prepare Position Handler Consume - -Sequence design diagram for Prepare Position Handler Consume process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.1-prepare.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md deleted file mode 100644 index 9320beb8f..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.3.2-fulfil-position-handler-consume.md +++ /dev/null @@ -1,8 +0,0 @@ -# Fulfil Position Handler Consume - -Sequence design diagram for Fulfil Position Handler Consume process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.2-fulfil.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md deleted file mode 100644 index 1089efeb4..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/1.3.3-abort-position-handler-consume.md +++ /dev/null @@ -1,8 +0,0 @@ -# Abort Position Handler Consume - -Sequence design diagram for Abort Position Handler Consume process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-position-1.3.3-abort.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md b/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md deleted file mode 100644 index 53dbce24f..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.1.0-fulfil-transfer-request.md +++ /dev/null @@ -1,14 +0,0 @@ -# Fulfil Transfer Request success - -Sequence design diagram for the Fulfil Success Transfer request. - -## References within Sequence Diagram - -* [Fulfil Handler Consume (Success) (2.1.1)](2.1.1-fulfil-handler-consume.md) -* [Position Handler Consume (Success) (1.3.2)](1.3.2-fulfil-position-handler-consume.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.0.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md deleted file mode 100644 index b702f8366..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.1.1-fulfil-handler-consume.md +++ /dev/null @@ -1,14 +0,0 @@ -# Fulfil Handler Consume (Success) - -Sequence design diagram for the Fulfil Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [seq-signature-validation](../../central-event-processor/signature-validation.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-fulfil-2.1.1.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md b/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md deleted file mode 100644 index d31ba9ce2..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.2.0-fulfil-reject-transfer.md +++ /dev/null @@ -1,14 +0,0 @@ -# Payee sends a Fulfil Reject Transfer request - -Sequence design diagram for the Fulfil Reject Transfer process. - -## References within Sequence Diagram - -* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) -* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md b/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md deleted file mode 100644 index 55f445174..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.2.0.a-fulfil-abort-transfer.md +++ /dev/null @@ -1,14 +0,0 @@ -# Payee sends a PUT call on /error end-point for a Transfer request - -Sequence design diagram for the Fulfil Reject Transfer process. - -## References within Sequence Diagram - -* [Fulfil Handler Consume (Reject/Abort)(2.2.1)](2.2.1-fulfil-reject-handler.md) -* [Position Handler Consume (Reject)(1.3.3)](1.3.3-abort-position-handler-consume.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.0.a.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md b/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md deleted file mode 100644 index 65bce91aa..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.2.1-fulfil-reject-handler.md +++ /dev/null @@ -1,14 +0,0 @@ -## Fulfil Handler Consume (Reject/Abort) - -Sequence design diagram for the Fulfil Handler Consume Reject/Abort process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) -* [seq-signature-validation](../../central-event-processor/signature-validation.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-reject-2.2.1.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md b/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md deleted file mode 100644 index 28ecf4ab7..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.3.0-transfer-timeout.md +++ /dev/null @@ -1,14 +0,0 @@ -## Transfer Timeout - -Sequence design diagram for the Transfer Timeout process. - -## References within Sequence Diagram - -* [Timeout Handler Consume (2.3.1)](2.3.1-timeout-handler-consume.md) -* [Position Handler Consume (Timeout)(1.3.3)](1.3.3-abort-position-handler-consume.md) -* [Send Notification to Participant (1.1.4.a)](1.1.4.a-send-notification-to-participant.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.0.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md b/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md deleted file mode 100644 index a77dd359e..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/2.3.1-timeout-handler-consume.md +++ /dev/null @@ -1,12 +0,0 @@ -## Timeout Handler Consume - -Sequence design diagram for the Timeout Handler Consume process. - -## References within Sequence Diagram - -* [Event Handler Consume (9.1.0)](../../central-event-processor/9.1.0-event-handler-placeholder.md) - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-ledger/assets/diagrams/sequence/seq-timeout-2.3.1.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-ledger/transfers/README.md b/mojaloop-technical-overview/central-ledger/transfers/README.md deleted file mode 100644 index 6d770e2fd..000000000 --- a/mojaloop-technical-overview/central-ledger/transfers/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Mojaloop Transfer operations. - -Operational processes that is the core of the transfer operational process; - -- Prepare process -- Fulfil process -- Notifications process -- Reject/Abort process \ No newline at end of file diff --git a/mojaloop-technical-overview/central-settlements/README.md b/mojaloop-technical-overview/central-settlements/README.md deleted file mode 100644 index ff260b960..000000000 --- a/mojaloop-technical-overview/central-settlements/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Central-Settlements Service - -The Central Settlements service is part of the Mojaloop project and deployment. - -* The central settlements service exposes Settlement API to manage the settlements between FSPs and the Central Hub. -* The service manages Settlement Windows and Settlements Event Triggers and provides information about FSPs accounts and settlements. - -## 1. Settlement Process Design - -### 1.1. Architecture overview - -![The Settlements Architecture](./assets/diagrams/architecture/Arch-Mojaloop-Settlements-PI4.svg) - -## 2. Funds In/Out - -Record Funds In and Record Funds Out operations are used respectively to deposit and withdraw funds into participant SETTLEMENT ledgers. The balance of the SETTLEMENT account relates to the NET_DEBIT_CAP set by the switch for every participant of the scheme. NET_DEBIT_CAP value is always lower or equal to the SETTLEMENT value. On the other side, the balance of the participant's POSITION account is limited to the value of the NET_DEBIT_CAP. - -## 3. API Specification - -Refer to **Central Settlements API** in the [API Specifications](../../api/README.md#central-settlements-api) section. diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md b/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md deleted file mode 100644 index 64288328a..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-in-prepare-reserve-commit.md +++ /dev/null @@ -1,8 +0,0 @@ -# Funds In - Prepare, Reserve, Commit - -Funds In operation performs all the stages of the transfer (prepare, reserve and commit) at once. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.1-in.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md b/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md deleted file mode 100644 index ad93a4b73..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-abort.md +++ /dev/null @@ -1,8 +0,0 @@ -# Funds Out - Abort - -Funds out abort of a prepared reconciliation transfer. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.3-out-abort.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md b/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md deleted file mode 100644 index 5a10b0a3d..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-commit.md +++ /dev/null @@ -1,8 +0,0 @@ -# Funds Out - Commit - -Funds out commit of a prepared reconciliation transfer. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.2-out-commit.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md b/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md deleted file mode 100644 index 5fb1ad08e..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/funds-out-prepare-reserve.md +++ /dev/null @@ -1,9 +0,0 @@ -# Funds Out - Prepare & Reserve - -Funds Out operation performs the prepare and reserve stages of the transfer at once. But the commit of the transfer or the abort operation are separate processes. - -## Sequence Diagram - - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.2.1-out-prepare-reserve.plantuml" %} -{% enduml %} \ No newline at end of file diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md b/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md deleted file mode 100644 index b4c76a93f..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/reconciliation-transfer-prepare.md +++ /dev/null @@ -1,8 +0,0 @@ -# Reconciliation Transfer Prepare - -Design for Reconciliation Transfer Prepare sub-process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.a-reconciliationTransferPrepare.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md b/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md deleted file mode 100644 index 65188d67f..000000000 --- a/mojaloop-technical-overview/central-settlements/funds-in-out/transfer-state-and-position-change.md +++ /dev/null @@ -1,8 +0,0 @@ -# Transfer State and Position Change - -Design for Transfer State and Position Change sub-process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/funds-in-out/assets/diagrams/sequence/seq-recfunds-5.1.0.b-transferStateAndPositionChange.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/README.md b/mojaloop-technical-overview/central-settlements/settlement-process/README.md deleted file mode 100644 index 978920e87..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# Settlement Process - -## 1. Database Design - -### Notes: - -- `settlementWindow` - a table where all settlement windows are stored; -- `settlementWindowStateChange` - stores information regarding settlement windows state; -- `settlement` - keeps data regarding all settlements; -- `settlementSettlementWindow` - association table for settlements and settlement windows, providing connection many-to-many; -- `settlementStateChange` - tracks the settlement state change; -- `settlementTransferParticipant` - this table is used for staging data for all transfers which are to be included in a settlement; -- `settlementParticipantCurrency` - stores grouped information by participant and currency. For calculation of netAmount, the summarized data from `settlementTransferParticipant` is used; -- `settlementParticipantCurrencyStateChange` - used to track the state change of each individual settlement participant account. - -The remaining tables in the below ERD are either transfer-specific (gray) or lookup (blue) and are included as direct dependencies to depict the relation between the settlement tables and transfer specific entities. - -![Central Settlements. Service ERD](./assets/entities/central-settlements-db-schema.png) - -* [Central Settlements Service DBeaver ERD](./assets/entities/central-settlements-db-schema-dbeaver.erd) - -## 2. Sequence diagrams - -### 2.1. Settlement Windows By Params - -Used for acquiring information regarding Settlement Windows. E.g.: -1. Find the ID of the current OPEN window by querying by state and later use the information for closing that window; -2. Find all CLOSED and/or ABORTED windows to be used for creating a settlement; -3. Other reporting needs. -- [Sequence Diagram for Get Settlement Windows by Parameters](get-settlement-windows-by-params.md) - -### 2.2. Settlement Windows By Params - -Used for acquiring settlement window information when ID is present. -- [Sequence Diagram for Request Settlement Window by Id](get-settlement-window-by-id.md) - -### 2.3. Close Settlement Window - -There is always one open settlement window which groups all ongoing transfers. This functionality is used to close the currently opened window and create the next one. -- [Sequence Diagram for Close Settlement Window](post-close-settlement-window.md) - -### 2.4. Create Settlement - -The creation of settlement is possible when at least one OPEN or ABORTED window is provided. The data from all transfers in all provided windows is summarized and as a result the settlement amount is calculated per participant and currency. Depending on its sign we distinct 3 types of participants in regards to the newly created settlement: SETTLEMENT_NET_RECIPIENT, SETTLEMENT_NET_SENDER and SETTLEMENT_NET_ZERO. Newly generated id of type bigint is returned as a response together it all other information. -- [Sequence Diagram for Trigger Settlement Event](post-create-settlement.md) - -### 2.5. Request Settlement - -This endpoint is used for acquiring information regarding a settlement and all included windows and accounts/positions. The ID from the previous request is being utilized for that purpose. -- [Sequence Diagram for Get Settlement by Id](get-settlement-by-id.md) - -### 2.6. Settlement Transfer Acknowledgment - -It is used to advance the settlement through all the states initiated with the creation and finilized by settle or abort. The actual state flow is: -- PENDING_SETTLEMENT: The net settlement report for this window has been taken, with the parameter set to indicate that settlement is to be processed; -- PS_TRANSFERS_RECORDED: Record transfer entries against the Position Account and the Multi-lateral Net Settlement Account, these are the "multi-lateral net  settlement transfers" (MLNS transfers). An identifier might be provided to be past to the reference bank; -- PS_TRANSFERS_RESERVED: All the debit entries for the MLNS transfers are reserved; -- PS_TRANSFERS_COMMITTED: All the credit entries for the MLNS transfers are committed. An identifier might be received and recorded from the Settlement bank to allow reconciliation; -- SETTLING: If all accounts are not yet SETTLED, the Status of the settlement is moved to SETTLING. Note: applies only on settlement level; -- SETTLED: Final state when all outstanding accounts are SETTLED, the entire Settlement is moved to SETTLED. - -[Sequence Diagram for Acknowledgement of Settlement Transfer](put-settlement-transfer-ack.md) - -### 2.7. Settlement Abort - -- ABORTED: Final state when the settlement is not possible. Please, note the settlement might be aborted up to when no account/position has been marked as PS_TRANSFERS_COMMITTED. Also there is no possibility to mark an individual account as ABORTED, but rahter the entire settlement is ABORTED. After performing such operation there is possibility to create a new settlement by including only non-problematic ABORTED accounts - -[Sequence Diagram for Settlement Abort](put-settlement-abort.md) - -### 2.8. Request Settlement By SPA - -Used to request drill-down information regarding a settlement, participant and account. Even though participant and account are optional, the order settlement/{id}/participant/{id}/account/{id} is mandatory. - -- [Sequence Diagram for Get Settlement by Settlement/Participant/Account](get-settlement-by-spa.md) - -### 2.9. Request Settlements By Params - -This endpoint enables advanced reporting capabilities. - -- [Sequence Diagram for Query Settlements by Parameters](get-settlements-by-params.md) diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd b/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd deleted file mode 100644 index f1875c51b..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema-dbeaver.erd +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - COLOR LEGEND: -Green - subject specific entity -Gray - transfer specific entity -Red - settlement specific entity -Blue - lookup entity - - \ No newline at end of file diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png b/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png deleted file mode 100644 index 0b1e60f06..000000000 Binary files a/mojaloop-technical-overview/central-settlements/settlement-process/assets/entities/central-settlements-db-schema.png and /dev/null differ diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md b/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md deleted file mode 100644 index 6e086a50c..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-id.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request Settlement - -Design for Get Settlement by Id process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.4.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md b/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md deleted file mode 100644 index bebda59db..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-by-spa.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request Settlement By SPA - -Design for Get Settlement by Settlement/Participant/Account process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.3.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md b/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md deleted file mode 100644 index 75ad34793..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-window-by-id.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request Settlement Window - -Design for Request Settlement Window by Id process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.1.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md b/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md deleted file mode 100644 index 4c2dcfe26..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlement-windows-by-params.md +++ /dev/null @@ -1,8 +0,0 @@ -# Settlement Windows By Params - -Design for Get Settlement Windows by Parameters process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.3.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md b/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md deleted file mode 100644 index 0458a88ab..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/get-settlements-by-params.md +++ /dev/null @@ -1,8 +0,0 @@ -# Request Settlements By Params - -Design for Query Settlements by Parameters process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.2.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md b/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md deleted file mode 100644 index 20f9d1617..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/post-close-settlement-window.md +++ /dev/null @@ -1,8 +0,0 @@ -# Close Settlement Window - -Design for Close Settlement Window process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-setwindow-6.1.2.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md b/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md deleted file mode 100644 index 07ab60084..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/post-create-settlement.md +++ /dev/null @@ -1,8 +0,0 @@ -# Create Settlement - -Design for Trigger Settlement Event process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.1.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md b/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md deleted file mode 100644 index b43b0646c..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-abort.md +++ /dev/null @@ -1,8 +0,0 @@ -# Settlement Abort - -Design for Settlement Abort process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.6.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md b/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md deleted file mode 100644 index 3c29eb012..000000000 --- a/mojaloop-technical-overview/central-settlements/settlement-process/put-settlement-transfer-ack.md +++ /dev/null @@ -1,8 +0,0 @@ -# Settlement Transfer Acknowledgment - -Design for Acknowledgement of Settlement Transfer process. - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/central-settlements/settlement-process/assets/diagrams/sequence/seq-settlement-6.2.5.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/event-framework/README.md b/mojaloop-technical-overview/event-framework/README.md deleted file mode 100644 index 2f8a9d3fb..000000000 --- a/mojaloop-technical-overview/event-framework/README.md +++ /dev/null @@ -1,231 +0,0 @@ -# Event Framework - -The purpose of the Event Framework is to provide a standard unified architecture to capture all Mojaloop events. - -_Disclaimer: This is experimental and is being implemented as a PoC. As such the design may change based on the evolution of the PoC's implementation, and any lessons learned._ - - -## 1. Requirements - -- Events will be produced by utilising a standard common library that will publish events to a sidecar component utilising a light-weight highly performant protocol (e.g. gRPC). -- Sidecar module will publish events to a singular Kafka topic that will allow for multiple handlers to consume and process the events as required. -- Kafka partitions will be determined by the event-type (e.g. log, audit, trace, errors etc). -- Each Mojaloop component will have its own tightly coupled Sidecar. -- Event messages will be produced to Kafka using the Trace-Id as the message key. This will ensure that all the messages part of the same trace (transaction) are stored in the same partition in order. - - -## 2. Architecture - -### 2.1 Overview - -![Event Framework Architecture](./assets/diagrams/architecture/architecture-event-framework.svg) - -### 2.2 Micro Service Pods - -![Pod Architecture](./assets/diagrams/architecture/architecture-event-sidecar.svg) - -### 2.3 Event Flow - -![Tracing Architecture](./assets/diagrams/architecture/architecture-event-trace.svg) - - -## 3. Event Envelope Model - -## 3.1 JSON Example - -```JSON -{ - "from": "noresponsepayeefsp", - "to": "payerfsp", - "id": "aa398930-f210-4dcd-8af0-7c769cea1660", - "content": { - "headers": { - "content-type": "application/vnd.interoperability.transfers+json;version=1.0", - "date": "2019-05-28T16:34:41.000Z", - "fspiop-source": "noresponsepayeefsp", - "fspiop-destination": "payerfsp" - }, - "payload": "data:application/vnd.interoperability.transfers+json;version=1.0;base64,ewogICJmdWxmaWxtZW50IjogIlVObEo5OGhaVFlfZHN3MGNBcXc0aV9VTjN2NHV0dDdDWkZCNHlmTGJWRkEiLAogICJjb21wbGV0ZWRUaW1lc3RhbXAiOiAiMjAxOS0wNS0yOVQyMzoxODozMi44NTZaIiwKICAidHJhbnNmZXJTdGF0ZSI6ICJDT01NSVRURUQiCn0" - }, - "type": "application/json", - "metadata": { - "event": { - "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", - "type": "trace", - "action": "span", - "createdAt": "2019-05-29T23:18:32.935Z", - "state": { - "status": "success", - "code": 0, - "description": "action successful" - }, - "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" - }, - "trace": { - "service": "central-ledger-prepare-handler", - "traceId": "bbd7b2c7-3978-408e-ae2e-a13012c47739", - "parentSpanId": "4e3ce424-d611-417b-a7b3-44ba9bbc5840", - "spanId": "efeb5c22-689b-4d04-ac5a-2aa9cd0a7e87", - "startTimestamp": "2015-08-29T11:22:09.815479Z", - "finishTimestamp": "2015-08-29T11:22:09.815479Z", - "tags": { - "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", - "transctionType": "transfer", - "parentEventType": "bulk-prepare", - "parentEventAction": "prepare" - } - } - } -} -``` - -## 3.2 Schema Definition - -### 3.2.1 Object Definition: EventMessage - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| id | string | Y | The id references the related message. | | -| from | string | N | If the value is not present in the destination, it means that the notification was generated by the connected node (server). | | -| to | string | Y | Mandatory for the sender and optional in the destination. The sender can ommit the value of the domain. | | -| pp | string | N | Optional for the sender, when is considered the identity of the session. Is mandatory in the destination if the identity of the originator is different of the identity of the from property. | | -| metadata | object `` | N | The sender should avoid to use this property to transport any kind of content-related information, but merely data relevant to the context of the communication. Consider to define a new content type if there's a need to include more content information into the message. | | -| type | string | Y | `MIME` declaration of the content type of the message. | | -| content | object \ | Y | The representation of the content. | | - -##### 3.2.1.1 Object Definition: MessageMetadata - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| event | object `` | Y | Event information. | | -| trace | object `` | Y | Trace information. | | - -##### 3.2.1.2 Object Definition: EventMetadata - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| id | string | Y | Generated UUIDv4 representing the event. | 3920382d-f78c-4023-adf9-0d7a4a2a3a2f | -| type | enum `` | Y | Type of event. | [`log`, `audit`, `error` `trace`] | -| action | enum `` | Y | Type of action. | [ `start`, `end` ] | -| createdAt | timestamp | Y | ISO Timestamp. | 2019-05-29T23:18:32.935Z | -| responseTo | string | N | UUIDv4 id link to the previous parent event. | 2019-05-29T23:18:32.935Z | -| state | object `` | Y | Object describing the state. | | - -##### 3.2.1.3 Object Definition: EventStateMetadata - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| status | enum `` | Y | The id references the related message. | success | -| code | number | N | The error code as per Mojaloop specification. | 2000 | -| description | string | N | Description for the status. Normally used to include an description for an error. | Generic server error to be used in order not to disclose information that may be considered private. | - -##### 3.2.1.4 Object Definition: EventTraceMetaData - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| service | string | Y | Name of service producing trace | central-ledger-prepare-handler | -| traceId | 32HEXDIGLC | Y | The end-to-end transaction identifier. | 664314d5b207d3ba722c6c0fdcd44c61 | -| spanId | 16HEXDIGLC | Y | Id for a processing leg identifier for a component or function. | 81fa25e8d66d2e88 | -| parentSpanId | 16HEXDIGLC | N | The id references the related message. | e457b5a2e4d86bd1 | -| sampled | number | N | Indicator if event message should be included in the trace `1`. If excluded it will be left the consumer to decide on sampling. | 1 | -| flags | number | N | Indicator if event message should be included in the trace flow. ( Debug `1` - this will override the sampled value ) | 0 | -| startTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the start timestamp of a span.| 2015-08-29T11:22:09.815479Z | -| finishTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the finish timestamp of a span | 2015-08-29T11:22:09.815479Z | -| tags | object `` | Y | The id references the related message. | success | - -_Note: HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lower case hex character. Ref: [WC3 standard for trace-context](https://www.w3.org/TR/trace-context/#field-value)._ - -##### 3.2.1.5 Object Definition: EventTraceMetaDataTags - -| Name | Type | Mandatory (Y/N) | Description | Example | -| --- | --- | --- | --- | --- | -| transactionId | string | N | Transaction Id representing either a transfer, quote, etc | 659ee338-c8f8-4c06-8aff-944e6c5cd694 | -| transactionType | string | N | The transaction type represented by the transactionId. E.g. (transfer, quote, etc) | transfer | -| parentEventType | string | N | The event-type of the parent Span. | bulk-prepare | -| parentEventAction | string | N | The event-action of the parent Span. | prepare | -| tracestate | string | N | This tag is set if EventSDK environmental variable `EVENT_SDK_TRACESTATE_HEADER_ENABLED` is `true` or if parent span context has the `tracestate` header or tag included. The tag holds updated `tracestate` header value as per the W3C trace headers specification. [More here](#411-wc3-http-headers)| `congo=t61rcWkgMzE,rojo=00f067aa0ba902b7` | -| `` | string | N | Arbitary Key-value pair for additional meta-data to be added to the trace information. | n/a | - -##### 3.2.1.6 Enum: EventStatusType - -| Enum | Description | -| --- | --- | -| success | Event was processed successfully | -| fail | Event was processed with a failure or error | - -##### 3.2.1.7 Enum: EventType - -| Enum | Description | -| --- | --- | -| log | Event representing a general log entry. | -| audit | Event to be signed and persisted into the audit store. | -| trace | Event containing trace context information to be persisted into the tracing store. | - -##### 3.2.1.8 Enum: LogEventAction - -| Enum | Description | -| --- | --- | -| info | Event representing an `info` level log entry. | -| debug | Event representing a `debug` level log entry. | -| error | Event representing an `error` level log entry. | -| verbose | Event representing a `verbose` level log entry. | -| warning | Event representing a `warning` level log entry. | -| performance | Event representing a `performance` level log entry. | - -##### 3.2.1.9 Enum: AuditEventAction - -| Enum | Description | -| --- | --- | -| default | Standard audit action. | -| start | Audit action to represent the start of a process. | -| finish | Audit action to represent the end of a process. | -| ingress | Audit action to capture ingress activity. | -| egress | Audit action to capture egress activity. | - -##### 3.2.1.10 Enum: TraceEventAction - -| Enum | Description | -| --- | --- | -| span | Event action representing a span of a trace. | - - -## 4. Tracing Design - -### 4.1 HTTP Transports - -Below find the current proposed standard HTTP Transport headers for tracing. - -Mojaloop has yet to standardise on either standard, or if it will possible support both. - -#### 4.1.1 W3C Http Headers - -Refer to the following publication for more information: https://w3c.github.io/trace-context/ - -| Header | Description | Example | -| --- | --- | --- | -| traceparent | Dash delimited string of tracing information: \-\-\-\ | 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00 | -| tracestate | Comma delimited vendor specific format captured as follows: \=\| congo=t61rcWkgMzE,rojo=00f067aa0ba902b7 | - -Note: Before this specification was written, some tracers propagated X-B3-Sampled as true or false as opposed to 1 or 0. While you shouldn't encode X-B3-Sampled as true or false, a lenient implementation may accept them. - -#### 4.1.2 B3 HTTP Headers - -Refer to the following publication for more information: https://github.com/apache/incubator-zipkin-b3-propagation - -| Header | Description | Example | -| --- | --- | --- | -| X-B3-TraceId | Encoded as 32 or 16 lower-hex characters. | a 128-bit TraceId header might look like: X-B3-TraceId: 463ac35c9f6413ad48485a3953bb6124. Unless propagating only the Sampling State, the X-B3-TraceId header is required. | -| X-B3-SpanId | Encoded as 16 lower-hex characters. | a SpanId header might look like: X-B3-SpanId: a2fb4a1d1a96d312. Unless propagating only the Sampling State, the X-B3-SpanId header is required. | -| X-B3-ParentSpanId | header may be present on a child span and must be absent on the root span. It is encoded as 16 lower-hex characters. | A ParentSpanId header might look like: X-B3-ParentSpanId: 0020000000000001 | -| X-B3-Sampled | An accept sampling decision is encoded as `1` and a deny as `0`. Absent means defer the decision to the receiver of this header. | A Sampled header might look like: X-B3-Sampled: 1. | -| X-B3-Flags | Debug is encoded as `1`. Debug implies an accept decision, so don't also send the X-B3-Sampled header. | | - -### 4.2 Kafka Transports - -Refer to `Event Envelope Model` section. This defines the message that will be sent through the Kafka transport. - -Alternatively the tracing context could be stored in Kafka headers which are only supports v0.11 or later. Note that this would break support for older versions of Kafka. - -### 4.3 Known limitations - -- Transfer tracing would be limited to each of the transfer legs (i.e. Prepare and Fulfil) as a result of the Mojaloop API specification not catering for tracing information. The trace information will be send as part of the callbacks by the Switch, but the FSPs will not be required to respond appropriately with a reciprocal trace headers. diff --git a/mojaloop-technical-overview/event-stream-processor/README.md b/mojaloop-technical-overview/event-stream-processor/README.md deleted file mode 100644 index 427b3246d..000000000 --- a/mojaloop-technical-overview/event-stream-processor/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Event Stream Processor Service - -Event Stream Processor consumes event messages from the `topic-events` topic as a result of messages published by the [event-sidecar](https://github.com/mojaloop/event-sidecar) service. Refer to [Event Framework](../event-framework/README.md) for more information on the overall architecture. - -The Service delivers logs, including audits, and traces to EFK stack with enabled APM plugin. Based on the event message type, the messages are delivered to different indexes in the Elasticsearch. - -## 1. Prerequisites - -The service logs all the events to Elasticsearch instance with enabled APM plugin. Sample docker-compose of the Elastic stack is available [here](https://github.com/mojaloop/event-stream-processor/blob/master/test/util/scripts/docker-efk/docker-compose.yml). The logs and audits are created under custom index template, while the trace data is stored to the default `apm-*` index. -Please, ensure that you have created the `mojatemplate` as it is described into the [event-stream-processor](https://github.com/mojaloop/event-stream-processor#111-create-template) service documentation. - -## 2. Architecture overview - -### 2.1. Flow overview -![Event Stream Processor flow overview](./assets/diagrams/architePcture/event-stream-processor-overview.svg) - - -### 2.2 Trace processing flow sequence diagram -{% uml src="./mojaloop-technical-overview/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/overview/README.md b/mojaloop-technical-overview/overview/README.md deleted file mode 100644 index 78e405de9..000000000 --- a/mojaloop-technical-overview/overview/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Mojaloop Hub - -There are several components that make up the Mojaloop ecosystem. The Mojaloop Hub is the primary container and reference we use to describe the core Mojaloop components. - -The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture: - -![Current Mojaloop Architecture Overview](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) - -_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ - -These consist of: - -* The **Mojaloop API Adapters** (**ML-API-Adapter**) provide the standard set of interfaces a DFSP can implement to connect to the system for Transfers. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. -* The **Central Services** (**CS**) provide the set of components required to move money from one DFSP to another through the Mojaloop API Adapters. This is similar to how money moves through a central bank or clearing house in developed countries. The Central Services contains the core Central Ledger logic to move money but also will be extended to provide fraud management and enforce scheme rules. -* The **Account Lookup Service** (**ALS**) provides mechanism to resolve FSP routing information through the Particpant API or orchestrate a Party request based on an internal Participant look-up. The internal Participant look-up is handled by a number of standard Oracle adapter or services. Example Oracle adapter/service would be to look-up Participant information from Pathfinder or a Merchant Registry. These Oracle adapter or services can easily be added depending on the schema requirements. -* The **Quoting Service** (**QA**) provides Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. -* The **Simulator** (**SIM**) mocks several DFSP functions as follows: - - Oracle end-points for Oracle Participant CRUD operations using in-memory cache; - - Participant end-points for Oracles with support for parameterized partyIdTypes; - - Parties end-points for Payer and Payee FSPs with associated callback responses; - - Transfer end-points for Payer and Payee FSPs with associated callback responses; and - - Query APIs to verify transactions (requests, responses, callbacks, etc) to support QA testing and verification. - -On either side of the Mojaloop Hub there is sample open source code to show how a DFSP can send and receive payments and the client that an existing DFSP could host to connect to the network. diff --git a/mojaloop-technical-overview/overview/components-PI8.md b/mojaloop-technical-overview/overview/components-PI8.md deleted file mode 100644 index 383a75614..000000000 --- a/mojaloop-technical-overview/overview/components-PI8.md +++ /dev/null @@ -1,7 +0,0 @@ -# Mojaloop Hub Legacy Components - PI8 - -The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI8: - -![Mojaloop Architecture Overview PI8](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) - -_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/mojaloop-technical-overview/quoting-service/README.md b/mojaloop-technical-overview/quoting-service/README.md deleted file mode 100644 index a6077be69..000000000 --- a/mojaloop-technical-overview/quoting-service/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Quoting Service -The **Quoting Service** (**QS**) _(refer to section `5.1`)_ as per the [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) implements the following use-cases: -* P2P Transfers - -_Note: other use-cases as per [Mojaloop {{ book.importedVars.mojaloop.spec.version }} Specification]({{ book.importedVars.mojaloop.spec.uri.doc }}) are yet to be verified_ - -## Sequence Diagram - -{% uml src="mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml" %} -{% enduml %} diff --git a/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml b/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml deleted file mode 100644 index 38ece23b0..000000000 --- a/mojaloop-technical-overview/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml +++ /dev/null @@ -1,66 +0,0 @@ -@startuml -Title Quoting Service Sequences -participant "Payer DFSP" -participant "Switch\nQuoting\nService" as Switch -participant "Payee DFSP" - -autonumber -note over "Payer DFSP", Switch: Payer DFSP requests quote from Payee DFSP -"Payer DFSP" -\ Switch: POST /quotes -Switch --/ "Payer DFSP": 202 Accepted -Switch -> Switch: Validate Quote Request -alt quote is valid - Switch -> Switch: Persist Quote Data - note over Switch, "Payee DFSP": Switch forwards quote request to Payee DFSP\n - Switch -\ "Payee DFSP": POST /quotes - "Payee DFSP" --/ Switch: 202 Accepted - "Payee DFSP" -> "Payee DFSP": Calculate Fees/Charges - - alt Payee DFSP successfully calculates quote - - note over "Payee DFSP", Switch: Payee DFSP responds to quote request - "Payee DFSP" -\ Switch: PUT /quotes/{ID} - Switch --/ "Payee DFSP": 200 Ok - - Switch -> Switch: Validate Quote Response - - alt response is ok - - Switch -> Switch: Persist Response Data - - note over Switch, "Payer DFSP": Switch forwards quote response to Payer DFSP\n - - Switch -\ "Payer DFSP": PUT /quotes/{ID} - "Payer DFSP" --/ Switch: 200 Ok - - note over "Payer DFSP" #3498db: Payer DFSP continues\nwith transfer if quote\nis acceptable... - else response invalid - - note over Switch, "Payee DFSP": Switch returns error to Payee DFSP - - Switch -\ "Payee DFSP": PUT /quotes/{ID}/error - "Payee DFSP" --/ Switch : 200 Ok - - note over Switch, "Payee DFSP" #ec7063: Note that under this\nscenario the Payer DFSP\nmay not receive a response - - end - else Payee DFSP calculation fails or rejects the request - - note over "Payee DFSP", Switch: Payee DFSP returns error to Switch - - "Payee DFSP" -\ Switch: POST quotes/{ID}/error - Switch --/ "Payee DFSP": 202 Accepted - Switch -> Switch: Persist error data - - note over "Payer DFSP", Switch: Switch returns error to Payer DFSP - - Switch -\ "Payer DFSP": POST quotes/{ID}/error - "Payer DFSP" --/ Switch: 202 Accepted - - end -else quote invalid - note over "Payer DFSP", Switch: Switch returns error to Payer DFSP - Switch -\ "Payer DFSP": POST quotes/{ID}/error - "Payer DFSP" --/ Switch: 202 Accepted -end -@enduml diff --git a/package-lock.json b/package-lock.json index 2d26d05a8..e2904d458 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9396 +1,20199 @@ { - "name": "documentation", - "version": "9.1.0", - "lockfileVersion": 1, + "name": "mojaloop-docs-vuepress", + "version": "1.0.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" + "packages": { + "": { + "name": "mojaloop-docs-vuepress", + "version": "1.0.0", + "license": "Apache-2.0", + "devDependencies": { + "@vuepress/plugin-back-to-top": "^1.9.10", + "@vuepress/plugin-medium-zoom": "^1.9.10", + "got": "^15.0.5", + "husky": "^9.1.7", + "markdownlint-cli": "^0.48.0", + "npm-check-updates": "^22.2.3", + "plantuml-encoder": "^1.4.0", + "svgo": "^4.0.1", + "vuepress": "^1.9.10", + "vuepress-plugin-mermaidjs": "^2.0.0-beta.2", + "vuepress-plugin-versioning": "git+https://github.com/mojaloop/vuepress-plugin-versioning.git#dcb14962a69b8e5aaf184d2d1a31ae4f43870bc1", + "vuepress-theme-titanium": "^5.0.0" } }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" - }, - "@types/node": { - "version": "12.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.7.tgz", - "integrity": "sha512-4jUncNe2tj1nmrO/34PsRpZqYVnRV1svbU78cKhuQKkMntKB/AmdLyGgswcZKjFHEHGpiY8pVD8CuVI55nP54w==", - "optional": true + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } }, - "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", - "optional": true + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "node_modules/@babel/compat-data": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", + "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, - "acorn": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", - "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", - "optional": true + "node_modules/@babel/core": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", + "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } }, - "acorn-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", - "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", - "optional": true, - "requires": { - "acorn": "^2.1.0" + "node_modules/@babel/generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" } }, - "apache-crypt": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz", - "integrity": "sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw=", - "requires": { - "unix-crypt-td-js": "^1.0.0" + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "apache-md5": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.2.tgz", - "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI=" + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "requires": { - "arr-flatten": "^1.0.1" + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "optional": true + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" } }, - "bash-color": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/bash-color/-/bash-color-0.0.4.tgz", - "integrity": "sha1-6b6M4zVAytpIgXaMWb1jhlc26RM=" - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" + "node_modules/@babel/helpers": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "optional": true, - "requires": { - "hoek": "2.x.x" + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.0.tgz", + "integrity": "sha512-kYsT+f5ARWF6AdFmqoEEp+hpqxEB8vGmRWfw2aj78M2vTwS2uHW91EF58iFm1Z9U8Y/RrLu2XKJn46P9ca1b0w==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.22.10" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "bootprint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bootprint/-/bootprint-1.0.2.tgz", - "integrity": "sha512-zrbDC1VVvOuOAf85Vc2Ni1AQxyQr0LqV6xJ8CAUCKRGo+EN1gWjTzmGfmRbeVIBsAouGSwYUcPonhHgbQct5+A==", - "requires": { - "commander": "^2.6.0", - "customize-engine-handlebars": "^1.0.0", - "customize-engine-less": "^1.0.1", - "customize-engine-uglify": "^1.0.0", - "customize-watch": "^1.0.0", - "customize-write-files": "^1.0.0", - "debug": "^2.1.2", - "get-promise": "^1.3.1", - "js-yaml": "^3.8.2", - "live-server": "^1.2.0", - "q": "^1.4.1", - "trace-and-clarify-if-possible": "^1.0.3" - } - }, - "bootprint-base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bootprint-base/-/bootprint-base-1.1.0.tgz", - "integrity": "sha1-svYgtki/pvxuAnGzhxz8nPeM0DA=", - "requires": { - "bootstrap": "^3.3.2", - "cheerio": "^0.19.0", - "handlebars": "^3.0.0", - "highlight.js": "^8.4.0", - "jquery": "^2", - "json-stable-stringify": "^1.0.0", - "marked": "^0.3.3" - } - }, - "bootprint-json-schema": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bootprint-json-schema/-/bootprint-json-schema-1.1.0.tgz", - "integrity": "sha1-UI6PoRINyW0Lwsa6g0HrzdVFhSg=", - "requires": { - "bootprint-base": "^1.0.0", - "lodash": "^4.17.2" + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "bootprint-swagger": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bootprint-swagger/-/bootprint-swagger-1.0.1.tgz", - "integrity": "sha1-ykYPsXnZDXVymWwBaFJXroDNHDM=", - "requires": { - "bootprint-json-schema": "^1.0.0", - "highlight.js": "^8.9.1", - "json-stable-stringify": "^1.0.1", - "lodash": "^3.9.3", - "m-io": "^0.3.1" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "bootstrap": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", - "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz", + "integrity": "sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "requires": { - "css-select": "~1.0.0", - "dom-serializer": "~0.1.0", - "entities": "~1.1.1", - "htmlparser2": "~3.8.1", - "lodash": "^3.2.0" + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "clarify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clarify/-/clarify-2.1.0.tgz", - "integrity": "sha512-sWdsTozdtoFQbmncCXqCKeUzQbEZul/WJ8xYGVJgfIf4xMEM5q0La+Gjo2MFNOVL0FfTFteHqw6JX+9M71dAdQ==", - "optional": true, - "requires": { - "stack-chain": "^2.0.0" + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" - } + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "optional": true + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", + "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", + "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", + "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "optional": true, - "requires": { - "boom": "2.x.x" + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "requires": { - "boolbase": "~1.0.0", - "css-what": "1.0", - "domutils": "1.4", - "nth-check": "~1.0.0" + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=" + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "optional": true + "node_modules/@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", - "optional": true, - "requires": { - "cssom": "0.3.x" + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "customize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/customize/-/customize-1.1.0.tgz", - "integrity": "sha1-jn3hMVqxV336ISTqmQbs6oijyS0=", - "requires": { - "debug": "^2.2.0", - "deep-aplus": "^1.0.4", - "jsonschema": "^1.0.2", - "jsonschema-extra": "^1.2.0", - "lodash": "^3.9.3", - "m-io": "^0.3.1", - "minimatch": "^3.0.0", - "q": "^1.4.1" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "customize-engine-handlebars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/customize-engine-handlebars/-/customize-engine-handlebars-1.0.1.tgz", - "integrity": "sha1-SAElQInR6IRi4/1vIXMpk6p7+ZY=", - "requires": { - "debug": "^2.2.0", - "handlebars": "^3.0.3", - "lodash": "^3.9.3", - "m-io": "^0.3.1", - "promised-handlebars": "^1.0.0", - "q": "^1.4.1", - "q-deep": "^1.0.1" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz", + "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "customize-engine-less": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/customize-engine-less/-/customize-engine-less-1.0.1.tgz", - "integrity": "sha1-rl//DPOSgGx9Dx1NqPfUsuZRCSk=", - "requires": { - "less": "^2.7.1", - "lodash": "^3.10.1", - "q": "^1.4.1" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "customize-engine-uglify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/customize-engine-uglify/-/customize-engine-uglify-1.0.0.tgz", - "integrity": "sha1-Eb3Mqslhn4zHCZHHGtB2K0cB+ug=", - "requires": { - "lodash": "^3.10.1", - "q": "^1.4.1", - "uglify-js": "^2.7.5" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", + "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "customize-watch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/customize-watch/-/customize-watch-1.0.0.tgz", - "integrity": "sha1-D6nLpHG+/6Kb+U5lVN8FwN7A9YA=", - "requires": { - "chokidar": "^1.2.0", - "customize": "^1.0.0", - "debug": "^2.2.0", - "deep-aplus": "^1.0.4", - "lodash": "^3.10.1", - "m-io": "^0.3.1", - "q": "^1.4.1" + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "customize-write-files": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/customize-write-files/-/customize-write-files-1.1.0.tgz", - "integrity": "sha1-zCd89CCNT6OXJgUeQ8Z7G3QQU54=", - "requires": { - "debug": "^2.2.0", - "deep-aplus": "^1.0.4", - "m-io": "^0.3.1", - "q": "^1.4.1", - "stream-equal": "^0.1.12" + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "deep-aplus": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/deep-aplus/-/deep-aplus-1.0.4.tgz", - "integrity": "sha1-4exMEKALUEa1ng3dBRnRAa4xXo8=", - "requires": { - "lodash.isplainobject": "^4.0.6" + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "optional": true + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", + "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.15.tgz", + "integrity": "sha512-tEVLhk8NRZSmwQ0DJtxxhTrCht1HVo8VaMzYT4w6lwyKBuHsgoioAUA7/6eT2fRfc5/23fuGdlwIxXhRVgWr4g==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "requires": { - "domelementtype": "1" + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "requires": { - "domelementtype": "1" + "node_modules/@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "optional": true, - "requires": { - "prr": "~1.0.1" + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", - "optional": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "node_modules/@babel/preset-env": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.20.tgz", + "integrity": "sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.20", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.15", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.15", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.15", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.15", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.22.19", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - } + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "optional": true + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "optional": true + "node_modules/@babel/traverse": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "requires": { - "fill-range": "^2.1.0" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "node_modules/@braintree/sanitize-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-3.1.0.tgz", + "integrity": "sha512-GcIY79elgB+azP74j8vqkiXz8xLFfIzbQJdlwOPisgbKT00tviJQuEghOXSMVxJ00HoYJbGswr4kcllUc4xCcg==", + "deprecated": "Potential XSS vulnerability patched in v6.0.0.", + "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", - "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-8.1.0.tgz", + "integrity": "sha512-2SX/1jW6CIMAiebvVv5ZInoCEuWQmMyBoJXXGC6Vjakjp/fpxP5eHs7/V6WKuPEIbuK06+VpjH+vjLQhr98rDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "@types/connect": "*", + "@types/node": "*" } }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "optional": true + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "requires": { - "websocket-driver": ">=0.5.1" + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" } }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "requires": { - "pend": "~1.2.0" + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "node_modules/@types/highlight.js": { + "version": "9.12.4", + "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz", + "integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "dev": true, + "dependencies": { + "@types/node": "*" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + "node_modules/@types/json-schema": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-10.0.3.tgz", + "integrity": "sha512-daHJk22isOUvNssVGF2zDnnSyxHhFYhtjeX4oQaKD6QzL3ZR1QSgiD1g+Q6/WSWYVogNXYDXODtbgW/WiFCtyw==", + "dev": true, + "dependencies": { + "@types/highlight.js": "^9.7.0", + "@types/linkify-it": "*", + "@types/mdurl": "*", + "highlight.js": "^9.7.0" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "dev": true + }, + "node_modules/@types/q": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.6.tgz", + "integrity": "sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" } }, - "forwarded": { + "node_modules/@types/source-list-map": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" + "node_modules/@types/tapable": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", + "dev": true + }, + "node_modules/@types/uglify-js": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.1.tgz", + "integrity": "sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/webpack": { + "version": "4.41.33", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.33.tgz", + "integrity": "sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + "node_modules/@types/webpack-dev-server": { + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.6.tgz", + "integrity": "sha512-XCph0RiiqFGetukCTC3KVnY1jwLcZ84illFRMbyFzCcWl90B/76ew0tSqF46oBhnLC4obNDG7dMO0JfTN0MgMQ==", + "dev": true, + "dependencies": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/serve-static": "*", + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + } }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" + "node_modules/@types/webpack-sources": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", + "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "node_modules/@types/webpack-sources/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha1-P17WZYPM1vQAtaANtvfoYTY+OI8=", - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "node_modules/@vue/babel-helper-vue-jsx-merge-props": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz", + "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==", + "dev": true + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.1.5.tgz", + "integrity": "sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==", + "dev": true + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.5.tgz", + "integrity": "sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "@vue/babel-helper-vue-transform-on": "^1.1.5", + "camelcase": "^6.3.0", + "html-tags": "^3.3.1", + "svg-tags": "^1.0.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-plugin-jsx/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vue/babel-plugin-transform-vue-jsx": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz", + "integrity": "sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==", + "dev": true, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0", + "html-tags": "^2.0.0", + "lodash.kebabcase": "^4.1.1", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-plugin-transform-vue-jsx/node_modules/html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/babel-preset-app": { + "version": "4.5.19", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.19.tgz", + "integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.0", + "@babel/helper-compilation-targets": "^7.9.6", + "@babel/helper-module-imports": "^7.8.3", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.11.0", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.0", + "@vue/babel-plugin-jsx": "^1.0.3", + "@vue/babel-preset-jsx": "^1.2.4", + "babel-plugin-dynamic-import-node": "^2.3.3", + "core-js": "^3.6.5", + "core-js-compat": "^3.6.5", + "semver": "^6.1.0" + }, + "peerDependencies": { + "@babel/core": "*", + "core-js": "^3", + "vue": "^2 || ^3.0.0-0" + }, + "peerDependenciesMeta": { + "core-js": { "optional": true }, - "yallist": { - "version": "3.0.3", - "bundled": true, + "vue": { "optional": true } } }, - "get-promise": { + "node_modules/@vue/babel-preset-jsx": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-promise/-/get-promise-1.4.0.tgz", - "integrity": "sha1-RDBFyGUwvrvtIihh7+0TwNNv9qA=", - "requires": { - "lodash": "^3.8.0", - "q": "^1.2.0" - }, + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.4.0.tgz", + "integrity": "sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA==", + "dev": true, "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.4.0", + "@vue/babel-sugar-composition-api-inject-h": "^1.4.0", + "@vue/babel-sugar-composition-api-render-instance": "^1.4.0", + "@vue/babel-sugar-functional-vue": "^1.4.0", + "@vue/babel-sugar-inject-h": "^1.4.0", + "@vue/babel-sugar-v-model": "^1.4.0", + "@vue/babel-sugar-v-on": "^1.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "vue": "*" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true } } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" + "node_modules/@vue/babel-sugar-composition-api-inject-h": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.4.0.tgz", + "integrity": "sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "gitbook-cli": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gitbook-cli/-/gitbook-cli-2.3.2.tgz", - "integrity": "sha512-eyGtkY7jKHhmgpfuvgAP5fZcUob/FBz4Ld0aLRdEmiTrS1RklimN9epzPp75dd4MWpGhYvSbiwxnpyLiv1wh6A==", - "requires": { - "bash-color": "0.0.4", - "commander": "2.11.0", - "fs-extra": "3.0.1", - "lodash": "4.17.4", - "npm": "5.1.0", - "npmi": "1.0.1", - "optimist": "0.6.1", - "q": "1.5.0", - "semver": "5.3.0", - "tmp": "0.0.31", - "user-home": "2.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - } + "node_modules/@vue/babel-sugar-composition-api-render-instance": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.4.0.tgz", + "integrity": "sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "gitbook-plugin-back-to-top-button": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/gitbook-plugin-back-to-top-button/-/gitbook-plugin-back-to-top-button-0.1.4.tgz", - "integrity": "sha1-5iGDOLDvGdWOb2YAmUNQt26ANd8=" - }, - "gitbook-plugin-changelog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitbook-plugin-changelog/-/gitbook-plugin-changelog-1.0.1.tgz", - "integrity": "sha512-X1wDTUfBRLiuS29SBN6e4X2A08JsGMh/KsAqBblrPQ2ltbM2Ivb6i2k9FinH4AVCdvdXEuM+KgQI8Q2tQzujtQ==", - "requires": { - "lodash": "^4.17.4", - "moment": "^2.18.1" + "node_modules/@vue/babel-sugar-functional-vue": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.4.0.tgz", + "integrity": "sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "gitbook-plugin-collapsible-chapters": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/gitbook-plugin-collapsible-chapters/-/gitbook-plugin-collapsible-chapters-0.1.8.tgz", - "integrity": "sha1-dxVcYcrBlRch2L9Es/ImphoeZcU=" + "node_modules/@vue/babel-sugar-inject-h": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.4.0.tgz", + "integrity": "sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "gitbook-plugin-editlink": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitbook-plugin-editlink/-/gitbook-plugin-editlink-1.0.2.tgz", - "integrity": "sha1-ej2Bk/guYfCUF83w52h2MfW2GV4=" + "node_modules/@vue/babel-sugar-v-model": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.4.0.tgz", + "integrity": "sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.4.0", + "camelcase": "^5.0.0", + "html-tags": "^2.0.0", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "gitbook-plugin-fontsettings": { + "node_modules/@vue/babel-sugar-v-model/node_modules/html-tags": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitbook-plugin-fontsettings/-/gitbook-plugin-fontsettings-2.0.0.tgz", - "integrity": "sha1-g1+QCuPdERCG/n7UQl7j3gJIYas=" - }, - "gitbook-plugin-include": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/gitbook-plugin-include/-/gitbook-plugin-include-0.1.0.tgz", - "integrity": "sha1-w1/0dlYKXv/e+tv2OYIknBy8dNw=", - "requires": { - "q": "*" + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", + "dev": true, + "engines": { + "node": ">=4" } }, - "gitbook-plugin-insert-logo": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/gitbook-plugin-insert-logo/-/gitbook-plugin-insert-logo-0.1.5.tgz", - "integrity": "sha1-2q6N2kGiNtVPE5MeVwsmcpVXiFo=" - }, - "gitbook-plugin-page-toc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gitbook-plugin-page-toc/-/gitbook-plugin-page-toc-1.1.1.tgz", - "integrity": "sha512-0ii4d4gxaLsZuWvSFyz2eLQvpjB3Sjg8pTBW8P6mT0j1jw3ifS5Jx8HvQLYrOPyolktUqmd0AebrKCur667zfw==" + "node_modules/@vue/babel-sugar-v-on": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.4.0.tgz", + "integrity": "sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.4.0", + "camelcase": "^5.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "gitbook-plugin-plantuml-svg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitbook-plugin-plantuml-svg/-/gitbook-plugin-plantuml-svg-1.0.1.tgz", - "integrity": "sha512-YP3nmYI+6j2aUPk3hKkWkggIlORgGwLhvaoReZvdyVM5cvomyd9iq4leRMvxBUSwuD6I1fXyYLMGqunOIjkXbw==", - "requires": { - "js-base64": "^2.4.0", - "lodash": "^4.17.4", - "request": "^2.83.0", - "request-promise": "^4.2.2" + "node_modules/@vue/compiler-sfc": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz", + "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" } }, - "gitbook-plugin-search": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gitbook-plugin-search/-/gitbook-plugin-search-2.2.1.tgz", - "integrity": "sha1-bSW1p3aZD6mP39+jfeMx944PaxM=" + "node_modules/@vue/compiler-sfc/node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } }, - "gitbook-plugin-swagger": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/gitbook-plugin-swagger/-/gitbook-plugin-swagger-0.2.0.tgz", - "integrity": "sha1-g33zIY/9q9/LVu2Xr9SVYinZ0h0=", - "requires": { - "bootprint": "^1.0.0", - "bootprint-swagger": "^1.0.1" + "node_modules/@vue/component-compiler-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", + "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.36", + "postcss-selector-parser": "^6.0.2", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" } }, - "gitbook-plugin-theme-api": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gitbook-plugin-theme-api/-/gitbook-plugin-theme-api-1.1.2.tgz", - "integrity": "sha1-jBRaS61JoSE8AlApC5vZtyrqiPw=", - "requires": { - "cheerio": "0.20.0", - "gitbook-plugin-search": ">=2.0.0", - "lodash": "4.12.0", - "q": "1.4.1", - "q-plus": "0.0.8" - }, - "dependencies": { - "cheerio": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", - "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", - "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.0", - "entities": "~1.1.1", - "htmlparser2": "~3.8.1", - "jsdom": "^7.0.2", - "lodash": "^4.1.0" - } - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "lodash": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz", - "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg=" - }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" - } + "node_modules/@vuepress/core": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.9.10.tgz", + "integrity": "sha512-H9ddo5fSinPb8QYl8OJFbZikMpOW84bm/U3Drzz8CnCXNtpda7CU2wX/XzOhe98G8jp45xhtZRkxOrqzBBAShA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.8.4", + "@vue/babel-preset-app": "^4.1.2", + "@vuepress/markdown": "1.9.10", + "@vuepress/markdown-loader": "1.9.10", + "@vuepress/plugin-last-updated": "1.9.10", + "@vuepress/plugin-register-components": "1.9.10", + "@vuepress/shared-utils": "1.9.10", + "@vuepress/types": "1.9.10", + "autoprefixer": "^9.5.1", + "babel-loader": "^8.0.4", + "bundle-require": "2.1.8", + "cache-loader": "^3.0.0", + "chokidar": "^2.0.3", + "connect-history-api-fallback": "^1.5.0", + "copy-webpack-plugin": "^5.0.2", + "core-js": "^3.6.4", + "cross-spawn": "^6.0.5", + "css-loader": "^2.1.1", + "esbuild": "0.14.7", + "file-loader": "^3.0.1", + "js-yaml": "^3.13.1", + "lru-cache": "^5.1.1", + "mini-css-extract-plugin": "0.6.0", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "portfinder": "^1.0.13", + "postcss-loader": "^3.0.0", + "postcss-safe-parser": "^4.0.1", + "toml": "^3.0.0", + "url-loader": "^1.0.1", + "vue": "^2.6.10", + "vue-loader": "^15.7.1", + "vue-router": "^3.4.5", + "vue-server-renderer": "^2.6.10", + "vue-template-compiler": "^2.6.10", + "vuepress-html-webpack-plugin": "^3.2.0", + "vuepress-plugin-container": "^2.0.2", + "webpack": "^4.8.1", + "webpack-chain": "^6.0.0", + "webpack-dev-server": "^3.5.1", + "webpack-merge": "^4.1.2", + "webpackbar": "3.2.0" + }, + "engines": { + "node": ">=8.6" } }, - "gitbook-plugin-uml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitbook-plugin-uml/-/gitbook-plugin-uml-1.0.1.tgz", - "integrity": "sha512-j9kWSFsfF7Y53LcfegQSkRUSc0cKcA93v0Sxg4wVzca7A9V1ridXiXcSeaKy7OZi386FB2mG+KihViUVZwfcCA==", - "requires": { - "crypto": "^1.0.1", - "fs-extra": "^4.0.1", - "node-plantuml": "^0.6.2", - "q": "^1.5.0" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - } + "node_modules/@vuepress/core/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "gitbook-plugin-variables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitbook-plugin-variables/-/gitbook-plugin-variables-1.1.0.tgz", - "integrity": "sha512-+G97YsciufqZQenG1TziLfKEAIpKwnxiipBOtWM0lZu8OxSR2WG4n/9zGPq3RqYAfzb1BxD6m6i0LmxmOF0vPA==", - "requires": { - "fast-glob": "^2.2.2", - "fs-extra": "^7.0.0", - "js-yaml": "^3.12.0", - "lodash": "^4.17.10", - "native-require": "^1.1.4" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "node_modules/@vuepress/core/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node_modules/@vuepress/core/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "node_modules/@vuepress/core/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@vuepress/markdown": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.9.10.tgz", + "integrity": "sha512-sXTLjeZzH8SQuAL5AEH0hhsMljjNJbzWbBvzaj5yQCCdf+3sp/dJ0kwnBSnQjFPPnzPg5t3tLKGUYHyW0KiKzA==", + "dev": true, + "dependencies": { + "@vuepress/shared-utils": "1.9.10", + "markdown-it": "^8.4.1", + "markdown-it-anchor": "^5.0.2", + "markdown-it-chain": "^1.3.0", + "markdown-it-emoji": "^1.4.0", + "markdown-it-table-of-contents": "^0.4.0", + "prismjs": "^1.13.0" } }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "requires": { - "is-glob": "^2.0.0" + "node_modules/@vuepress/markdown-loader": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.9.10.tgz", + "integrity": "sha512-94BlwKc+lOaN/A5DkyA9KWHvMlMC1sWunAXE3Tv0WYzgYLDs9QqCsx7L5kLkpcOOVVm/8kBJumnXvVBwhqJddw==", + "dev": true, + "dependencies": { + "@vuepress/markdown": "1.9.10", + "loader-utils": "^1.1.0", + "lru-cache": "^5.1.1" } }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" + "node_modules/@vuepress/markdown-loader/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + "node_modules/@vuepress/markdown-loader/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, - "handlebars": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-3.0.7.tgz", - "integrity": "sha512-Pb/VCTFwbcm3KbD5rIzVVsbVBk7XMfhS4ZIJUfXdMF7H+UngtsofnUBfop/i24GSr3HCDG1PL0KoIX0YqEsXTg==", - "requires": { - "optimist": "^0.6.1", - "source-map": "^0.1.40", - "uglify-js": "^2.6" + "node_modules/@vuepress/markdown/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "node_modules/@vuepress/markdown/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/@vuepress/markdown/node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" } }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "node_modules/@vuepress/markdown/node_modules/markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/@vuepress/plugin-active-header-links": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.9.10.tgz", + "integrity": "sha512-2dRr3DE2UBFXhyMtLR3sGTdRyDM8YStuY6AOoQmoSgwy1IHt7PO7ypOuf1akF+1Nv8Q2aISU06q6TExZouu3Mw==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "@vuepress/types": "1.9.10", + "lodash.debounce": "^4.0.8" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, + "node_modules/@vuepress/plugin-back-to-top": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-back-to-top/-/plugin-back-to-top-1.9.10.tgz", + "integrity": "sha512-iInIp66wu717CAnT2pyd9Bs/vAgrUBOBIQ7WMnfJo07cW/ZIothpyrSHnpCRSsfJ/jLivMPqW0pviqppt64BzQ==", + "dev": true, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "@vuepress/types": "1.9.10", + "lodash.debounce": "^4.0.8" } }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" + "node_modules/@vuepress/plugin-last-updated": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.9.10.tgz", + "integrity": "sha512-YxzWGF/OfU6WsHSynZFn74NGGp7dY27Bjy9JyyFo8wF5+2V1gpyDjveHKHGKugS/pMXlxfjzhv9E2Wmy9R7Iog==", + "dev": true, + "dependencies": { + "@vuepress/types": "1.9.10", + "cross-spawn": "^6.0.5" } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "optional": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, - "highlight.js": { - "version": "8.9.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-8.9.1.tgz", - "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "optional": true + "node_modules/@vuepress/plugin-medium-zoom": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-medium-zoom/-/plugin-medium-zoom-1.9.10.tgz", + "integrity": "sha512-/MsICWZ/mUTs+ZdqqA1AVtWAtNL5ksgnnGR2X24LnXaPJp+M1IB2ETcyNKh264YVODSrmVsS/Y+kbCRK0qKkdg==", + "dev": true, + "dependencies": { + "@vuepress/types": "1.9.10", + "medium-zoom": "^1.0.4" + } }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - }, - "dependencies": { - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } + "node_modules/@vuepress/plugin-nprogress": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.9.10.tgz", + "integrity": "sha512-I1kkm6yWUQd7vwiV3lEDVpVP0Lr04K0zlczU502lDUa1RufSZ7vt+mlF5fOM28GqT+pKTEToWmm+VNT/R3qvMQ==", + "dev": true, + "dependencies": { + "@vuepress/types": "1.9.10", + "nprogress": "^0.2.0" } }, - "http-auth": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", - "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=", - "requires": { - "apache-crypt": "^1.1.2", - "apache-md5": "^1.0.6", - "bcryptjs": "^2.3.0", - "uuid": "^3.0.0" - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "node_modules/@vuepress/plugin-register-components": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.9.10.tgz", + "integrity": "sha512-sgdJ5OydTPZAoTkselpvVP3Xsd6bfZ0FpaxOTinal0gJ99h49lvLu9bvzMx13rdGRFO/kRXn0qQQpwKTAfTPqA==", + "dev": true, + "dependencies": { + "@vuepress/shared-utils": "1.9.10", + "@vuepress/types": "1.9.10" } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" + "node_modules/@vuepress/plugin-search": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.9.10.tgz", + "integrity": "sha512-bn2XJikaRgQZXvu8upCjOWrxbLHIRTqnJ3w7G0mo6jCYWGVsHNo6XhVpqylpLR2PWnHT/ImO2bGo38/5Bag/tQ==", + "dev": true, + "dependencies": { + "@vuepress/types": "1.9.10" + } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "node_modules/@vuepress/shared-utils": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.9.10.tgz", + "integrity": "sha512-M9A3DocPih+V8dKK2Zg9FJQ/f3JZrYsdaM/vQ9F48l8bPlzxw5NvqXIYMK4kKcGEyerQNTWCudoCpLL5uiU0hg==", + "dev": true, + "dependencies": { + "chalk": "^2.3.2", + "escape-html": "^1.0.3", + "fs-extra": "^7.0.1", + "globby": "^9.2.0", + "gray-matter": "^4.0.1", + "hash-sum": "^1.0.2", + "semver": "^6.0.0", + "toml": "^3.0.0", + "upath": "^1.1.0" } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "node_modules/@vuepress/shared-utils/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "optional": true + "node_modules/@vuepress/shared-utils/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "node_modules/@vuepress/shared-utils/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "node_modules/@vuepress/shared-utils/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + "node_modules/@vuepress/theme-default": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.9.10.tgz", + "integrity": "sha512-XnXn9t+pYCIhWi3cZXJlighuy93FFm5yXdISAAlFlcNkshuGtqamkjacHV8q/QZMfOhSIs6wX7Hj88u2IsT5mw==", + "dev": true, + "dependencies": { + "@vuepress/plugin-active-header-links": "1.9.10", + "@vuepress/plugin-nprogress": "1.9.10", + "@vuepress/plugin-search": "1.9.10", + "@vuepress/types": "1.9.10", + "docsearch.js": "^2.5.2", + "lodash": "^4.17.15", + "stylus": "^0.54.8", + "stylus-loader": "^3.0.2", + "vuepress-plugin-container": "^2.0.2", + "vuepress-plugin-smooth-scroll": "^0.0.3" + } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" + "node_modules/@vuepress/types": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@vuepress/types/-/types-1.9.10.tgz", + "integrity": "sha512-TDNQn4og85onmBpLTTXXmncW3rUnYGr2MkuI8OIFJZetDNM49t1WbjNVlrT+kx7C6qXi6okDQgrHGYXajHZWfg==", + "dev": true, + "dependencies": { + "@types/markdown-it": "^10.0.0", + "@types/webpack-dev-server": "^3", + "webpack-chain": "^6.0.0" } }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } + "@webassemblyjs/wast-printer": "1.9.0" } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "requires": { - "is-primitive": "^2.0.0" + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "requires": { - "is-extglob": "^1.0.0" + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" } }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "@xtuc/long": "4.2.2" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, - "jquery": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", - "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=" - }, - "js-base64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", - "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==" - }, - "js-quantities": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/js-quantities/-/js-quantities-1.7.4.tgz", - "integrity": "sha512-mjwSQ+1XwSTqStOQNocgRgwebWZYc4CDhoe9DFY51u0n23B/VQmwCb4z1GTn9vxz/gMXHTnnyCdXBGrCMbMy8g==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "jsdom": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", - "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", - "optional": true, - "requires": { - "abab": "^1.0.0", - "acorn": "^2.4.0", - "acorn-globals": "^1.0.4", - "cssom": ">= 0.3.0 < 0.4.0", - "cssstyle": ">= 0.2.29 < 0.3.0", - "escodegen": "^1.6.1", - "nwmatcher": ">= 1.3.7 < 2.0.0", - "parse5": "^1.5.1", - "request": "^2.55.0", - "sax": "^1.1.4", - "symbol-tree": ">= 3.1.0 < 4.0.0", - "tough-cookie": "^2.2.0", - "webidl-conversions": "^2.0.0", - "whatwg-url-compat": "~0.6.5", - "xml-name-validator": ">= 2.0.1 < 3.0.0" - } - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "json-stable-stringify": { + "node_modules/ajv-errors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "peerDependencies": { + "ajv": ">=5.0.0" } }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "requires": { - "graceful-fs": "^4.1.6" + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + "node_modules/algoliasearch": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", + "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", + "dev": true, + "dependencies": { + "agentkeepalive": "^2.2.0", + "debug": "^2.6.9", + "envify": "^4.0.0", + "es6-promise": "^4.1.0", + "events": "^1.1.0", + "foreach": "^2.0.5", + "global": "^4.3.2", + "inherits": "^2.0.1", + "isarray": "^2.0.1", + "load-script": "^1.0.0", + "object-keys": "^1.0.11", + "querystring-es3": "^0.2.1", + "reduce": "^1.0.1", + "semver": "^5.1.0", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=0.8" + } }, - "jsonschema": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.4.tgz", - "integrity": "sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw==" + "node_modules/algoliasearch/node_modules/agentkeepalive": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", + "integrity": "sha512-TnB6ziK363p7lR8QpeLC8aMr8EGYBKZTpgzQLfqTs3bR0Oo5VbKdwKf8h0dSzsYrB7lSCgfJnMZKqShvlq5Oyg==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } }, - "jsonschema-extra": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/jsonschema-extra/-/jsonschema-extra-1.2.0.tgz", - "integrity": "sha1-52eGotlQdb4ja5izuAUrD2wVTXs=", - "requires": { - "js-quantities": "^1.5.0", - "lodash.isplainobject": "^2.4.1" - }, - "dependencies": { - "lodash.isplainobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-2.4.1.tgz", - "integrity": "sha1-rHOF4uqawDIfMNw7gDKm0iMagBE=", - "requires": { - "lodash._isnative": "~2.4.1", - "lodash._shimisplainobject": "~2.4.1" - } - } + "node_modules/algoliasearch/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "node_modules/algoliasearch/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/algoliasearch/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" } }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=" + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", + "dev": true }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" } }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, - "less": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", - "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", - "requires": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "mime": "^1.2.11", - "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "2.81.0", - "source-map": "^0.5.3" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "optional": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "optional": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - } - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "optional": true, - "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "optional": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "optional": true - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "optional": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "optional": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "optional": true - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "optional": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "optional": true - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "optional": true, - "requires": { - "punycode": "^1.4.1" - } - } + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "optional": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "live-server": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", - "integrity": "sha512-Yn2XCVjErTkqnM3FfTmM7/kWy3zP7+cEtC7x6u+wUzlQ+1UW3zEYbbyJrc0jNDwiMDZI0m4a0i3dxlGHVyXczw==", - "requires": { - "chokidar": "^2.0.4", - "colors": "^1.4.0", - "connect": "^3.6.6", - "cors": "^2.8.5", - "event-stream": "3.3.4", - "faye-websocket": "0.11.x", - "http-auth": "3.1.x", - "morgan": "^1.9.1", - "object-assign": "^4.1.1", - "opn": "^6.0.0", - "proxy-middleware": "^0.15.0", - "send": "^0.17.1", - "serve-index": "^1.9.1" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - } - } + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash._basebind": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.4.1.tgz", - "integrity": "sha1-6UC5690nwyfgqNqxtVkWxTQelXU=", - "requires": { - "lodash._basecreate": "~2.4.1", - "lodash._setbinddata": "~2.4.1", - "lodash._slice": "~2.4.1", - "lodash.isobject": "~2.4.1" + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash._basecreate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz", - "integrity": "sha1-+Ob1tXip405UEXm1a47uv0oofgg=", - "requires": { - "lodash._isnative": "~2.4.1", - "lodash.isobject": "~2.4.1", - "lodash.noop": "~2.4.1" + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash._basecreatecallback": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz", - "integrity": "sha1-fQsmdknLKeehOdAQO3wR+uhOSFE=", - "requires": { - "lodash._setbinddata": "~2.4.1", - "lodash.bind": "~2.4.1", - "lodash.identity": "~2.4.1", - "lodash.support": "~2.4.1" + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" } }, - "lodash._basecreatewrapper": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz", - "integrity": "sha1-TTHy595+E0+/KAN2K4FQsyUZZm8=", - "requires": { - "lodash._basecreate": "~2.4.1", - "lodash._setbinddata": "~2.4.1", - "lodash._slice": "~2.4.1", - "lodash.isobject": "~2.4.1" + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "lodash._createwrapper": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz", - "integrity": "sha1-UdaVeXPaTtVW43KQ2MGhjFPeFgc=", - "requires": { - "lodash._basebind": "~2.4.1", - "lodash._basecreatewrapper": "~2.4.1", - "lodash._slice": "~2.4.1", - "lodash.isfunction": "~2.4.1" + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=" - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=" - }, - "lodash._setbinddata": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz", - "integrity": "sha1-98IAzRuS7yNrOZ7s9zxkjReqlNI=", - "requires": { - "lodash._isnative": "~2.4.1", - "lodash.noop": "~2.4.1" + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "lodash._shimisplainobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimisplainobject/-/lodash._shimisplainobject-2.4.1.tgz", - "integrity": "sha1-AeyTsu5j5Z8aqDiZrG+gkFrHWW8=", - "requires": { - "lodash.forin": "~2.4.1", - "lodash.isfunction": "~2.4.1" + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "lodash._slice": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.4.1.tgz", - "integrity": "sha1-dFz0GlNZexj2iImFREBe+isG2Q8=" - }, - "lodash.bind": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.4.1.tgz", - "integrity": "sha1-XRn6AFyMTSNvr0dCx7eh/Kvikmc=", - "requires": { - "lodash._createwrapper": "~2.4.1", - "lodash._slice": "~2.4.1" + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "lodash.forin": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.forin/-/lodash.forin-2.4.1.tgz", - "integrity": "sha1-gInq7X0lsIZyt8Zv0HrFXQYjIOs=", - "requires": { - "lodash._basecreatecallback": "~2.4.1", - "lodash._objecttypes": "~2.4.1" + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "lodash.identity": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.4.1.tgz", - "integrity": "sha1-ZpTP+mX++TH3wxzobHRZfPVg9PE=" + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true }, - "lodash.isfunction": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz", - "integrity": "sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE=" + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "requires": { - "lodash._objecttypes": "~2.4.1" + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.noop": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz", - "integrity": "sha1-T7VPgWZS5a4Q6PcvcXo4jHMmU4o=" + "node_modules/array.prototype.reduce": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", + "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "lodash.support": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.4.1.tgz", - "integrity": "sha1-Mg4LZwMWc8KNeiu12eAzGkUkBRU=", - "requires": { - "lodash._isnative": "~2.4.1" + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } }, - "m-io": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/m-io/-/m-io-0.3.1.tgz", - "integrity": "sha1-SgeSJG9oGfdFyLxdlzzeiC8NHvs=", - "requires": { - "mkdirp": "^0.5.1", - "q": "^1.4.1", - "rimraf": "^2.5.3" + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + "node_modules/assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", + "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.4", + "util": "^0.10.4" + } }, - "map-visit": { + "node_modules/assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" } }, - "marked": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", - "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" + "node_modules/assert/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, - "merge-descriptors": { + "node_modules/async-limiter": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true }, - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" } }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "node_modules/autocomplete.js": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", + "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", + "dev": true, + "dependencies": { + "immediate": "^3.2.3" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autoprefixer/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "dev": true, + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz", + "integrity": "sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.32.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" } }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "requires": { - "basic-auth": "~2.0.0", + "node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "ms": { + "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha1-eBj3IgJ7JFmobwKV1DTR/CM2xSw=", - "optional": true + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "native-require": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/native-require/-/native-require-1.1.4.tgz", - "integrity": "sha512-fOB7diEP3ErNZnMh+Zqdufw79rIPrcAbHanixB5WoWpfU06ZfoUjynGDDQ22uKBhkpgzcI3WXQglhzpWBPKKGA==" + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } }, - "node-nailgun-client": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/node-nailgun-client/-/node-nailgun-client-0.1.2.tgz", - "integrity": "sha512-OC611lR0fsDUSptwnhBf8d3sj4DZ5fiRKfS2QaGPe0kR3Dt9YoZr1MY7utK0scFPTbXuQdSBBbeoKYVbME1q5g==", - "requires": { - "commander": "^2.8.1" + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "node-nailgun-server": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-nailgun-server/-/node-nailgun-server-0.1.4.tgz", - "integrity": "sha512-e0Hbh6XPb/7GqATJ45BePaUEO5AwR7InRW/pGeMKHH1cqPMBFCeqdBNfvi+bkVLnsbYOOQE+pAek9nmNoD8sYw==", - "requires": { - "commander": "^2.8.1" + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" } }, - "node-plantuml": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/node-plantuml/-/node-plantuml-0.6.2.tgz", - "integrity": "sha512-4/nf/gBvKVm4+EbBgFQZf0n8N3jfAA7mRExs3NfgujSsaouktZwYkUzBUqUR8nRzIWDmJ4hA1QiWOjpEArTiZQ==", - "requires": { - "commander": "^2.8.1", - "node-nailgun-client": "^0.1.0", - "node-nailgun-server": "^0.1.3", - "plantuml-encoder": "^1.2.5" + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "npm": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-5.1.0.tgz", - "integrity": "sha512-pt5ClxEmY/dLpb60SmGQQBKi3nB6Ljx1FXmpoCUdAULlGqGVn2uCyXxPCWFbcuHGthT7qGiaGa1wOfs/UjGYMw==", - "requires": { - "JSONStream": "~1.3.1", - "abbrev": "~1.1.0", - "ansi-regex": "~3.0.0", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "aproba": "~1.1.2", - "archy": "~1.0.0", - "bluebird": "~3.5.0", - "cacache": "~9.2.9", - "call-limit": "~1.1.0", - "chownr": "~1.0.1", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.11", - "debuglog": "*", - "detect-indent": "~5.0.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "fstream": "~1.0.11", - "fstream-npm": "~1.2.1", - "glob": "~7.1.2", - "graceful-fs": "~4.1.11", - "has-unicode": "~2.0.1", - "hosted-git-info": "~2.5.0", - "iferr": "~0.1.5", - "imurmurhash": "*", - "inflight": "~1.0.6", - "inherits": "~2.0.3", - "ini": "~1.3.4", - "init-package-json": "~1.10.1", - "lazy-property": "~1.0.0", - "lockfile": "~1.0.3", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "~4.1.1", - "mississippi": "~1.3.0", - "mkdirp": "~0.5.1", - "move-concurrently": "~1.0.1", - "node-gyp": "~3.6.2", - "nopt": "~4.0.1", - "normalize-package-data": "~2.4.0", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~3.0.0", - "npm-package-arg": "~5.1.2", - "npm-registry-client": "~8.4.0", - "npm-user-validate": "~1.0.0", - "npmlog": "~4.1.2", - "once": "~1.4.0", - "opener": "~1.4.3", - "osenv": "~0.1.4", - "pacote": "~2.7.38", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", - "read": "~1.0.7", - "read-cmd-shim": "~1.0.1", - "read-installed": "~4.0.3", - "read-package-json": "~2.0.9", - "read-package-tree": "~5.1.6", - "readable-stream": "~2.3.2", - "readdir-scoped-modules": "*", - "request": "~2.81.0", - "retry": "~0.10.1", - "rimraf": "~2.6.1", - "safe-buffer": "~5.1.1", - "semver": "~5.3.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "~4.1.6", - "strip-ansi": "~4.0.0", - "tar": "~2.2.1", - "text-table": "~0.2.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "~1.1.0", - "unpipe": "~1.0.0", - "update-notifier": "~2.2.0", - "uuid": "~3.1.0", - "validate-npm-package-license": "*", - "validate-npm-package-name": "~3.0.0", - "which": "~1.2.14", - "worker-farm": "~1.3.1", - "wrappy": "~1.0.2", - "write-file-atomic": "~2.1.0" - }, - "dependencies": { - "JSONStream": { - "version": "1.3.1", - "bundled": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "dependencies": { - "jsonparse": { - "version": "1.3.1", - "bundled": true - }, - "through": { - "version": "2.3.8", - "bundled": true - } - } - }, - "abbrev": { - "version": "1.1.0", - "bundled": true - }, - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true - }, - "aproba": { - "version": "1.1.2", - "bundled": true - }, - "archy": { - "version": "1.0.0", - "bundled": true - }, - "bluebird": { - "version": "3.5.0", - "bundled": true - }, - "cacache": { - "version": "9.2.9", - "bundled": true, - "requires": { - "bluebird": "^3.5.0", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^1.3.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.1", - "ssri": "^4.1.6", - "unique-filename": "^1.1.0", - "y18n": "^3.2.1" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.1", - "bundled": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true - } - } - }, - "y18n": { - "version": "3.2.1", - "bundled": true - } - } - }, - "call-limit": { - "version": "1.1.0", - "bundled": true - }, - "chownr": { - "version": "1.0.1", - "bundled": true - }, - "cmd-shim": { - "version": "2.0.2", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "columnify": { - "version": "1.5.4", - "bundled": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "requires": { - "defaults": "^1.0.3" - }, - "dependencies": { - "defaults": { - "version": "1.0.3", - "bundled": true, - "requires": { - "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.2", - "bundled": true - } - } - } - } - } - } - }, - "config-chain": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - }, - "dependencies": { - "proto-list": { - "version": "1.2.4", - "bundled": true - } - } - }, - "debuglog": { - "version": "1.0.1", - "bundled": true - }, - "detect-indent": { - "version": "5.0.0", - "bundled": true - }, - "dezalgo": { - "version": "1.0.3", - "bundled": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - }, - "dependencies": { - "asap": { - "version": "2.0.5", - "bundled": true - } - } - }, - "editor": { - "version": "1.0.0", - "bundled": true - }, - "fs-vacuum": { - "version": "1.2.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-npm": { - "version": "1.2.1", - "bundled": true, - "requires": { - "fstream-ignore": "^1.0.0", - "inherits": "2" - }, - "dependencies": { - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - } - } - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "hosted-git-info": { - "version": "2.5.0", - "bundled": true - }, - "iferr": { - "version": "0.1.5", - "bundled": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true - }, - "init-package-json": { - "version": "1.10.1", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "promzard": { - "version": "0.3.0", - "bundled": true, - "requires": { - "read": "1" - } - } - } - }, - "lazy-property": { - "version": "1.0.0", - "bundled": true - }, - "lockfile": { - "version": "1.0.3", - "bundled": true - }, - "lodash._baseindexof": { - "version": "3.1.0", - "bundled": true - }, - "lodash._baseuniq": { - "version": "4.6.0", - "bundled": true, - "requires": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - }, - "dependencies": { - "lodash._createset": { - "version": "4.0.3", - "bundled": true - }, - "lodash._root": { - "version": "3.0.1", - "bundled": true - } - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "bundled": true - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "bundled": true - }, - "lodash._createcache": { - "version": "3.1.2", - "bundled": true, - "requires": { - "lodash._getnative": "^3.0.0" - } - }, - "lodash._getnative": { - "version": "3.9.1", - "bundled": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "bundled": true - }, - "lodash.restparam": { - "version": "3.6.1", - "bundled": true - }, - "lodash.union": { - "version": "4.6.0", - "bundled": true - }, - "lodash.uniq": { - "version": "4.5.0", - "bundled": true - }, - "lodash.without": { - "version": "4.4.0", - "bundled": true - }, - "lru-cache": { - "version": "4.1.1", - "bundled": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true - } - } - }, - "mississippi": { - "version": "1.3.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^1.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.0", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "typedarray": { - "version": "0.0.6", - "bundled": true - } - } - }, - "duplexify": { - "version": "3.5.0", - "bundled": true, - "requires": { - "end-of-stream": "1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "end-of-stream": { - "version": "1.0.0", - "bundled": true, - "requires": { - "once": "~1.3.0" - }, - "dependencies": { - "once": { - "version": "1.3.3", - "bundled": true, - "requires": { - "wrappy": "1" - } - } - } - }, - "stream-shift": { - "version": "1.0.0", - "bundled": true - } - } - }, - "end-of-stream": { - "version": "1.4.0", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - }, - "flush-write-stream": { - "version": "1.0.2", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - } - }, - "from2": { - "version": "2.3.0", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "parallel-transform": { - "version": "1.1.0", - "bundled": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "cyclist": { - "version": "0.2.2", - "bundled": true - } - } - }, - "pump": { - "version": "1.0.2", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.3.5", - "bundled": true, - "requires": { - "duplexify": "^3.1.2", - "inherits": "^2.0.1", - "pump": "^1.0.0" - } - }, - "stream-each": { - "version": "1.2.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "stream-shift": { - "version": "1.0.0", - "bundled": true - } - } - }, - "through2": { - "version": "2.0.3", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - }, - "dependencies": { - "xtend": { - "version": "4.0.1", - "bundled": true - } - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "copy-concurrently": { - "version": "1.0.3", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "run-queue": { - "version": "1.0.3", - "bundled": true, - "requires": { - "aproba": "^1.1.1" - } - } - } - }, - "node-gyp": { - "version": "3.6.2", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - }, - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - } - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "requires": { - "builtin-modules": "^1.0.0" - }, - "dependencies": { - "builtin-modules": { - "version": "1.1.1", - "bundled": true - } - } - } - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true - }, - "npm-install-checks": { - "version": "3.0.0", - "bundled": true, - "requires": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-package-arg": { - "version": "5.1.2", - "bundled": true, - "requires": { - "hosted-git-info": "^2.4.2", - "osenv": "^0.1.4", - "semver": "^5.1.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-registry-client": { - "version": "8.4.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0", - "npmlog": "2 || ^3.1.0 || ^4.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^4.1.2" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.0", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "typedarray": { - "version": "0.0.6", - "bundled": true - } - } - } - } - }, - "npm-user-validate": { - "version": "1.0.0", - "bundled": true - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - }, - "dependencies": { - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "delegates": { - "version": "1.0.0", - "bundled": true - } - } - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.1", - "bundled": true - } - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "^1.0.2" - } - } - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - } - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.4.3", - "bundled": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - }, - "dependencies": { - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - } - } - }, - "pacote": { - "version": "2.7.38", - "bundled": true, - "requires": { - "bluebird": "^3.5.0", - "cacache": "^9.2.9", - "glob": "^7.1.2", - "lru-cache": "^4.1.1", - "make-fetch-happen": "^2.4.13", - "minimatch": "^3.0.4", - "mississippi": "^1.2.0", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^5.1.2", - "npm-pick-manifest": "^1.0.4", - "osenv": "^0.1.4", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^4.0.0", - "safe-buffer": "^5.1.1", - "semver": "^5.3.0", - "ssri": "^4.1.6", - "tar-fs": "^1.15.3", - "tar-stream": "^1.5.4", - "unique-filename": "^1.1.0", - "which": "^1.2.12" - }, - "dependencies": { - "make-fetch-happen": { - "version": "2.4.13", - "bundled": true, - "requires": { - "agentkeepalive": "^3.3.0", - "cacache": "^9.2.9", - "http-cache-semantics": "^3.7.3", - "http-proxy-agent": "^2.0.0", - "https-proxy-agent": "^2.0.0", - "lru-cache": "^4.1.1", - "mississippi": "^1.2.0", - "node-fetch-npm": "^2.0.1", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^3.0.0", - "ssri": "^4.1.6" - }, - "dependencies": { - "agentkeepalive": { - "version": "3.3.0", - "bundled": true, - "requires": { - "humanize-ms": "^1.2.1" - }, - "dependencies": { - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "requires": { - "ms": "^2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - } - } - }, - "http-cache-semantics": { - "version": "3.7.3", - "bundled": true - }, - "http-proxy-agent": { - "version": "2.0.0", - "bundled": true, - "requires": { - "agent-base": "4", - "debug": "2" - }, - "dependencies": { - "agent-base": { - "version": "4.1.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - }, - "dependencies": { - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - }, - "dependencies": { - "es6-promise": { - "version": "4.1.1", - "bundled": true - } - } - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - } - } - }, - "https-proxy-agent": { - "version": "2.0.0", - "bundled": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^2.4.1" - }, - "dependencies": { - "agent-base": { - "version": "4.1.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - }, - "dependencies": { - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - }, - "dependencies": { - "es6-promise": { - "version": "4.1.1", - "bundled": true - } - } - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - } - } - }, - "node-fetch-npm": { - "version": "2.0.1", - "bundled": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-helpfulerror": "^1.0.3", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "encoding": { - "version": "0.1.12", - "bundled": true, - "requires": { - "iconv-lite": "~0.4.13" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.18", - "bundled": true - } - } - }, - "json-parse-helpfulerror": { - "version": "1.0.3", - "bundled": true, - "requires": { - "jju": "^1.1.0" - }, - "dependencies": { - "jju": { - "version": "1.3.0", - "bundled": true - } - } - } - } - }, - "socks-proxy-agent": { - "version": "3.0.0", - "bundled": true, - "requires": { - "agent-base": "^4.0.1", - "socks": "^1.1.10" - }, - "dependencies": { - "agent-base": { - "version": "4.1.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - }, - "dependencies": { - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - }, - "dependencies": { - "es6-promise": { - "version": "4.1.1", - "bundled": true - } - } - } - } - }, - "socks": { - "version": "1.1.10", - "bundled": true, - "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - }, - "dependencies": { - "ip": { - "version": "1.1.5", - "bundled": true - }, - "smart-buffer": { - "version": "1.1.15", - "bundled": true - } - } - } - } - } - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - }, - "npm-pick-manifest": { - "version": "1.0.4", - "bundled": true, - "requires": { - "npm-package-arg": "^5.1.2", - "semver": "^5.3.0" - } - }, - "promise-retry": { - "version": "1.1.1", - "bundled": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "err-code": { - "version": "1.1.2", - "bundled": true - } - } - }, - "protoduck": { - "version": "4.0.0", - "bundled": true, - "requires": { - "genfun": "^4.0.1" - }, - "dependencies": { - "genfun": { - "version": "4.0.1", - "bundled": true - } - } - }, - "tar-fs": { - "version": "1.15.3", - "bundled": true, - "requires": { - "chownr": "^1.0.1", - "mkdirp": "^0.5.1", - "pump": "^1.0.0", - "tar-stream": "^1.1.2" - }, - "dependencies": { - "pump": { - "version": "1.0.2", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.0", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - } - } - } - } - }, - "tar-stream": { - "version": "1.5.4", - "bundled": true, - "requires": { - "bl": "^1.0.0", - "end-of-stream": "^1.0.0", - "readable-stream": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "bl": { - "version": "1.2.1", - "bundled": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "end-of-stream": { - "version": "1.4.0", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - }, - "xtend": { - "version": "4.0.1", - "bundled": true - } - } - } - } - }, - "path-is-inside": { - "version": "1.0.2", - "bundled": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true - }, - "read": { - "version": "1.0.7", - "bundled": true, - "requires": { - "mute-stream": "~0.0.4" - }, - "dependencies": { - "mute-stream": { - "version": "0.0.7", - "bundled": true - } - } - }, - "read-cmd-shim": { - "version": "1.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "read-installed": { - "version": "4.0.3", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - }, - "dependencies": { - "util-extend": { - "version": "1.0.3", - "bundled": true - } - } - }, - "read-package-json": { - "version": "2.0.9", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-helpfulerror": "^1.0.2", - "normalize-package-data": "^2.0.0" - }, - "dependencies": { - "json-parse-helpfulerror": { - "version": "1.0.3", - "bundled": true, - "requires": { - "jju": "^1.1.0" - }, - "dependencies": { - "jju": { - "version": "1.3.0", - "bundled": true - } - } - } - } - }, - "read-package-tree": { - "version": "5.1.6", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "once": "^1.3.0", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.2", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.1.0", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "string_decoder": { - "version": "1.0.3", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - } - } - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - }, - "dependencies": { - "aws-sign2": { - "version": "0.6.0", - "bundled": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - }, - "dependencies": { - "delayed-stream": { - "version": "1.0.0", - "bundled": true - } - } - }, - "extend": { - "version": "3.0.1", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - }, - "dependencies": { - "asynckit": { - "version": "0.4.0", - "bundled": true - } - } - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "bundled": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - }, - "dependencies": { - "co": { - "version": "4.6.0", - "bundled": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "requires": { - "jsonify": "~0.0.0" - }, - "dependencies": { - "jsonify": { - "version": "0.0.0", - "bundled": true - } - } - } - } - }, - "har-schema": { - "version": "1.0.5", - "bundled": true - } - } - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - }, - "dependencies": { - "boom": { - "version": "2.10.1", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "requires": { - "boom": "2.x.x" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - } - } - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "bundled": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "requires": { - "extsprintf": "1.0.2" - } - } - } - }, - "sshpk": { - "version": "1.13.1", - "bundled": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "asn1": { - "version": "0.2.3", - "bundled": true - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - } - } - } - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "requires": { - "mime-db": "~1.27.0" - }, - "dependencies": { - "mime-db": { - "version": "1.27.0", - "bundled": true - } - } - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true - }, - "qs": { - "version": "6.4.0", - "bundled": true - }, - "stringstream": { - "version": "0.0.5", - "bundled": true - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "requires": { - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "bundled": true - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - } - } - }, - "retry": { - "version": "0.10.1", - "bundled": true - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true - }, - "semver": { - "version": "5.3.0", - "bundled": true - }, - "sha": { - "version": "2.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - } - }, - "slide": { - "version": "1.1.6", - "bundled": true - }, - "sorted-object": { - "version": "2.0.1", - "bundled": true - }, - "sorted-union-stream": { - "version": "2.1.3", - "bundled": true, - "requires": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - }, - "dependencies": { - "from2": { - "version": "1.3.0", - "bundled": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - } - } - } - } - }, - "stream-iterate": { - "version": "1.2.0", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "stream-shift": { - "version": "1.0.0", - "bundled": true - } - } - } - } - }, - "ssri": { - "version": "4.1.6", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - } - } - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - }, - "dependencies": { - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "umask": { - "version": "1.1.0", - "bundled": true - }, - "unique-filename": { - "version": "1.1.0", - "bundled": true, - "requires": { - "unique-slug": "^2.0.0" - }, - "dependencies": { - "unique-slug": { - "version": "2.0.0", - "bundled": true, - "requires": { - "imurmurhash": "^0.1.4" - } - } - } - }, - "unpipe": { - "version": "1.0.0", - "bundled": true - }, - "update-notifier": { - "version": "2.2.0", - "bundled": true, - "requires": { - "boxen": "^1.0.0", - "chalk": "^1.0.0", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "dependencies": { - "boxen": { - "version": "1.1.0", - "bundled": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^1.1.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^0.1.0", - "widest-line": "^1.0.0" - }, - "dependencies": { - "ansi-align": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "camelcase": { - "version": "4.1.0", - "bundled": true - }, - "cli-boxes": { - "version": "1.0.0", - "bundled": true - }, - "string-width": { - "version": "2.1.0", - "bundled": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "term-size": { - "version": "0.1.1", - "bundled": true, - "requires": { - "execa": "^0.4.0" - }, - "dependencies": { - "execa": { - "version": "0.4.0", - "bundled": true, - "requires": { - "cross-spawn-async": "^2.1.1", - "is-stream": "^1.1.0", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn-async": { - "version": "2.2.5", - "bundled": true, - "requires": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "is-stream": { - "version": "1.1.0", - "bundled": true - }, - "npm-run-path": { - "version": "1.0.0", - "bundled": true, - "requires": { - "path-key": "^1.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "path-key": { - "version": "1.0.0", - "bundled": true - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true - } - } - } - } - }, - "widest-line": { - "version": "1.0.0", - "bundled": true, - "requires": { - "string-width": "^1.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.1", - "bundled": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - } - } - } - } - } - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "bundled": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true - } - } - }, - "supports-color": { - "version": "2.0.0", - "bundled": true - } - } - }, - "configstore": { - "version": "3.1.0", - "bundled": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "dependencies": { - "dot-prop": { - "version": "4.1.1", - "bundled": true, - "requires": { - "is-obj": "^1.0.0" - }, - "dependencies": { - "is-obj": { - "version": "1.0.1", - "bundled": true - } - } - }, - "make-dir": { - "version": "1.0.0", - "bundled": true, - "requires": { - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "bundled": true - } - } - }, - "unique-string": { - "version": "1.0.0", - "bundled": true, - "requires": { - "crypto-random-string": "^1.0.0" - }, - "dependencies": { - "crypto-random-string": { - "version": "1.0.0", - "bundled": true - } - } - } - } - }, - "import-lazy": { - "version": "2.1.0", - "bundled": true - }, - "is-npm": { - "version": "1.0.0", - "bundled": true - }, - "latest-version": { - "version": "3.1.0", - "bundled": true, - "requires": { - "package-json": "^4.0.0" - }, - "dependencies": { - "package-json": { - "version": "4.0.1", - "bundled": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - }, - "dependencies": { - "got": { - "version": "6.7.1", - "bundled": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "create-error-class": { - "version": "3.0.2", - "bundled": true, - "requires": { - "capture-stack-trace": "^1.0.0" - }, - "dependencies": { - "capture-stack-trace": { - "version": "1.0.0", - "bundled": true - } - } - }, - "duplexer3": { - "version": "0.1.4", - "bundled": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true - }, - "is-redirect": { - "version": "1.0.0", - "bundled": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "bundled": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true - }, - "lowercase-keys": { - "version": "1.0.0", - "bundled": true - }, - "timed-out": { - "version": "4.0.1", - "bundled": true - }, - "unzip-response": { - "version": "2.0.1", - "bundled": true - }, - "url-parse-lax": { - "version": "1.0.0", - "bundled": true, - "requires": { - "prepend-http": "^1.0.1" - }, - "dependencies": { - "prepend-http": { - "version": "1.0.4", - "bundled": true - } - } - } - } - }, - "registry-auth-token": { - "version": "3.3.1", - "bundled": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "rc": { - "version": "1.2.1", - "bundled": true, - "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "deep-extend": { - "version": "0.4.2", - "bundled": true - }, - "minimist": { - "version": "1.2.0", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - } - } - } - } - }, - "registry-url": { - "version": "3.1.0", - "bundled": true, - "requires": { - "rc": "^1.0.1" - }, - "dependencies": { - "rc": { - "version": "1.2.1", - "bundled": true, - "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "deep-extend": { - "version": "0.4.2", - "bundled": true - }, - "minimist": { - "version": "1.2.0", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - } - } - } - } - } - } - } - } - }, - "semver-diff": { - "version": "2.1.0", - "bundled": true, - "requires": { - "semver": "^5.0.3" - } - }, - "xdg-basedir": { - "version": "3.0.0", - "bundled": true - } - } - }, - "uuid": { - "version": "3.1.0", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "bundled": true, - "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" - }, - "dependencies": { - "spdx-correct": { - "version": "1.0.2", - "bundled": true, - "requires": { - "spdx-license-ids": "^1.0.2" - }, - "dependencies": { - "spdx-license-ids": { - "version": "1.2.2", - "bundled": true - } - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "bundled": true - } - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "bundled": true, - "requires": { - "builtins": "^1.0.3" - }, - "dependencies": { - "builtins": { - "version": "1.0.3", - "bundled": true - } - } - }, - "which": { - "version": "1.2.14", - "bundled": true, - "requires": { - "isexe": "^2.0.0" - }, - "dependencies": { - "isexe": { - "version": "2.0.0", - "bundled": true - } - } - }, - "worker-farm": { - "version": "1.3.1", - "bundled": true, - "requires": { - "errno": ">=0.1.1 <0.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - }, - "dependencies": { - "errno": { - "version": "0.1.4", - "bundled": true, - "requires": { - "prr": "~0.0.0" - }, - "dependencies": { - "prr": { - "version": "0.0.0", - "bundled": true - } - } - }, - "xtend": { - "version": "4.0.1", - "bundled": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "write-file-atomic": { - "version": "2.1.0", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.0.tgz", + "integrity": "sha512-v+Jcv64L2LbfTC6OnRcaxtqJNJuQAVhZKSJfR/6hn7lhnChUXl4amwVviqN1k411BB+3rRoKMitELRn1CojeRA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001539", + "electron-to-chromium": "^1.4.530", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/buffer-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", + "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/buffer/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/bundle-require": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-2.1.8.tgz", + "integrity": "sha512-oOEg3A0hy/YzvNWNowtKD0pmhZKseOFweCbgyMqTIih4gRY1nJWsvrOCT27L9NbIyL5jMjTFrAUpGxxpW68Puw==", + "dev": true, + "peerDependencies": { + "esbuild": ">=0.13" + } + }, + "node_modules/byte-counter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz", + "integrity": "sha512-jheRLVMeUKrDBjVw2O5+k4EvR4t9wtxHL+bo/LxfkxsVeuGMy3a5SEGgXdAFA4FSzTrU8rQXQIrsZ3oBq5a0pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "npmi": { + "node_modules/cache-base": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npmi/-/npmi-1.0.1.tgz", - "integrity": "sha1-FddpJzVHVF5oCdzwzhiu1IsCkOI=", - "requires": { - "npm": "^2.1.12", - "semver": "^4.1.0" - }, - "dependencies": { - "npm": { - "version": "2.15.12", - "resolved": "https://registry.npmjs.org/npm/-/npm-2.15.12.tgz", - "integrity": "sha1-33w+1aJ3w/nUtdgZsFMR0QogCuY=", - "requires": { - "abbrev": "~1.0.9", - "ansi": "~0.3.1", - "ansi-regex": "*", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "archy": "~1.0.0", - "async-some": "~1.0.2", - "block-stream": "0.0.9", - "char-spinner": "~1.0.1", - "chmodr": "~1.0.2", - "chownr": "~1.0.1", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.10", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "fs-vacuum": "~1.2.9", - "fs-write-stream-atomic": "~1.0.8", - "fstream": "~1.0.10", - "fstream-npm": "~1.1.1", - "github-url-from-git": "~1.4.0", - "github-url-from-username-repo": "~1.0.2", - "glob": "~7.0.6", - "graceful-fs": "~4.1.6", - "hosted-git-info": "~2.1.5", - "imurmurhash": "*", - "inflight": "~1.0.4", - "inherits": "~2.0.3", - "ini": "~1.3.4", - "init-package-json": "~1.9.4", - "lockfile": "~1.0.1", - "lru-cache": "~4.0.1", - "minimatch": "~3.0.3", - "mkdirp": "~0.5.1", - "node-gyp": "~3.6.0", - "nopt": "~3.0.6", - "normalize-git-url": "~3.0.2", - "normalize-package-data": "~2.3.5", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~1.0.7", - "npm-package-arg": "~4.1.0", - "npm-registry-client": "~7.2.1", - "npm-user-validate": "~0.1.5", - "npmlog": "~2.0.4", - "once": "~1.4.0", - "opener": "~1.4.1", - "osenv": "~0.1.3", - "path-is-inside": "~1.0.0", - "read": "~1.0.7", - "read-installed": "~4.0.3", - "read-package-json": "~2.0.4", - "readable-stream": "~2.1.5", - "realize-package-specifier": "~3.0.1", - "request": "~2.74.0", - "retry": "~0.10.0", - "rimraf": "~2.5.4", - "semver": "~5.1.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.0", - "spdx-license-ids": "~1.2.2", - "strip-ansi": "~3.0.1", - "tar": "~2.2.1", - "text-table": "~0.2.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "validate-npm-package-license": "~3.0.1", - "validate-npm-package-name": "~2.2.2", - "which": "~1.2.11", - "wrappy": "~1.0.2", - "write-file-atomic": "~1.1.4" - }, - "dependencies": { - "abbrev": { - "version": "1.0.9", - "bundled": true - }, - "ansi": { - "version": "0.3.1", - "bundled": true - }, - "ansi-regex": { - "version": "2.0.0", - "bundled": true - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true - }, - "archy": { - "version": "1.0.0", - "bundled": true - }, - "async-some": { - "version": "1.0.2", - "bundled": true, - "requires": { - "dezalgo": "^1.0.2" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "char-spinner": { - "version": "1.0.1", - "bundled": true - }, - "chmodr": { - "version": "1.0.2", - "bundled": true - }, - "chownr": { - "version": "1.0.1", - "bundled": true - }, - "cmd-shim": { - "version": "2.0.2", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "columnify": { - "version": "1.5.4", - "bundled": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - }, - "dependencies": { - "wcwidth": { - "version": "1.0.0", - "bundled": true, - "requires": { - "defaults": "^1.0.0" - }, - "dependencies": { - "defaults": { - "version": "1.0.3", - "bundled": true, - "requires": { - "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.2", - "bundled": true - } - } - } - } - } - } - }, - "config-chain": { - "version": "1.1.10", - "bundled": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - }, - "dependencies": { - "proto-list": { - "version": "1.2.4", - "bundled": true - } - } - }, - "dezalgo": { - "version": "1.0.3", - "bundled": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - }, - "dependencies": { - "asap": { - "version": "2.0.3", - "bundled": true - } - } - }, - "editor": { - "version": "1.0.0", - "bundled": true - }, - "fs-vacuum": { - "version": "1.2.9", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.8", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "fstream": { - "version": "1.0.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-npm": { - "version": "1.1.1", - "bundled": true, - "requires": { - "fstream-ignore": "^1.0.0", - "inherits": "2" - }, - "dependencies": { - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - } - } - }, - "github-url-from-git": { - "version": "1.4.0", - "bundled": true - }, - "github-url-from-username-repo": { - "version": "1.0.2", - "bundled": true - }, - "glob": { - "version": "7.0.6", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "path-is-absolute": { - "version": "1.0.0", - "bundled": true - } - } - }, - "graceful-fs": { - "version": "4.1.6", - "bundled": true - }, - "hosted-git-info": { - "version": "2.1.5", - "bundled": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true - }, - "inflight": { - "version": "1.0.5", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true - }, - "init-package-json": { - "version": "1.9.4", - "bundled": true, - "requires": { - "glob": "^6.0.0", - "npm-package-arg": "^4.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^2.0.1" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "bundled": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "bundled": true - } - } - }, - "promzard": { - "version": "0.3.0", - "bundled": true, - "requires": { - "read": "1" - } - } - } - }, - "lockfile": { - "version": "1.0.1", - "bundled": true - }, - "lru-cache": { - "version": "4.0.1", - "bundled": true, - "requires": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - }, - "dependencies": { - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "2.0.0", - "bundled": true - } - } - }, - "minimatch": { - "version": "3.0.3", - "bundled": true, - "requires": { - "brace-expansion": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.6", - "bundled": true, - "requires": { - "balanced-match": "^0.4.1", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - } - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true - } - } - }, - "node-gyp": { - "version": "3.6.0", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "bundled": true - } - } - }, - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-git-url": { - "version": "3.0.2", - "bundled": true - }, - "normalize-package-data": { - "version": "2.3.5", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "requires": { - "builtin-modules": "^1.0.0" - }, - "dependencies": { - "builtin-modules": { - "version": "1.1.0", - "bundled": true - } - } - } - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true - }, - "npm-install-checks": { - "version": "1.0.7", - "bundled": true, - "requires": { - "npmlog": "0.1 || 1 || 2", - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-package-arg": { - "version": "4.1.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "semver": "4 || 5" - } - }, - "npm-registry-client": { - "version": "7.2.1", - "bundled": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0", - "npmlog": "~2.0.0 || ~3.1.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "bundled": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - } - } - }, - "typedarray": { - "version": "0.0.6", - "bundled": true - } - } - }, - "retry": { - "version": "0.10.0", - "bundled": true - } - } - }, - "npm-user-validate": { - "version": "0.1.5", - "bundled": true - }, - "npmlog": { - "version": "2.0.4", - "bundled": true, - "requires": { - "ansi": "~0.3.1", - "are-we-there-yet": "~1.1.2", - "gauge": "~1.2.5" - }, - "dependencies": { - "are-we-there-yet": { - "version": "1.1.2", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.0 || ^1.1.13" - }, - "dependencies": { - "delegates": { - "version": "1.0.0", - "bundled": true - } - } - }, - "gauge": { - "version": "1.2.7", - "bundled": true, - "requires": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - }, - "dependencies": { - "has-unicode": { - "version": "2.0.0", - "bundled": true - }, - "lodash._baseslice": { - "version": "4.0.0", - "bundled": true - }, - "lodash._basetostring": { - "version": "4.12.0", - "bundled": true - }, - "lodash.pad": { - "version": "4.4.0", - "bundled": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.padend": { - "version": "4.5.0", - "bundled": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.padstart": { - "version": "4.5.0", - "bundled": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.tostring": { - "version": "4.1.4", - "bundled": true - } - } - } - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.4.1", - "bundled": true - }, - "osenv": { - "version": "0.1.3", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - }, - "dependencies": { - "os-homedir": { - "version": "1.0.0", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.1", - "bundled": true - } - } - }, - "path-is-inside": { - "version": "1.0.1", - "bundled": true - }, - "read": { - "version": "1.0.7", - "bundled": true, - "requires": { - "mute-stream": "~0.0.4" - }, - "dependencies": { - "mute-stream": { - "version": "0.0.5", - "bundled": true - } - } - }, - "read-installed": { - "version": "4.0.3", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - }, - "dependencies": { - "debuglog": { - "version": "1.0.1", - "bundled": true - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "util-extend": { - "version": "1.0.1", - "bundled": true - } - } - }, - "read-package-json": { - "version": "2.0.4", - "bundled": true, - "requires": { - "glob": "^6.0.0", - "graceful-fs": "^4.1.2", - "json-parse-helpfulerror": "^1.0.2", - "normalize-package-data": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "bundled": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "bundled": true - } - } - }, - "json-parse-helpfulerror": { - "version": "1.0.3", - "bundled": true, - "requires": { - "jju": "^1.1.0" - }, - "dependencies": { - "jju": { - "version": "1.3.0", - "bundled": true - } - } - } - } - }, - "readable-stream": { - "version": "2.1.5", - "bundled": true, - "requires": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - } - } - }, - "realize-package-specifier": { - "version": "3.0.1", - "bundled": true, - "requires": { - "dezalgo": "^1.0.1", - "npm-package-arg": "^4.0.0" - } - }, - "request": { - "version": "2.74.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~1.0.0-rc4", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" - }, - "dependencies": { - "aws-sign2": { - "version": "0.6.0", - "bundled": true - }, - "aws4": { - "version": "1.4.1", - "bundled": true - }, - "bl": { - "version": "1.1.2", - "bundled": true, - "requires": { - "readable-stream": "~2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - } - } - } - } - }, - "caseless": { - "version": "0.11.0", - "bundled": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - }, - "dependencies": { - "delayed-stream": { - "version": "1.0.0", - "bundled": true - } - } - }, - "extend": { - "version": "3.0.0", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "1.0.0-rc4", - "bundled": true, - "requires": { - "async": "^1.5.2", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.10" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "bundled": true - } - } - }, - "har-validator": { - "version": "2.0.6", - "bundled": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "bundled": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "bundled": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "bundled": true - } - } - }, - "commander": { - "version": "2.9.0", - "bundled": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - }, - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "bundled": true - } - } - }, - "is-my-json-valid": { - "version": "2.13.1", - "bundled": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "jsonpointer": "2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "generate-function": { - "version": "2.0.0", - "bundled": true - }, - "generate-object-property": { - "version": "1.2.0", - "bundled": true, - "requires": { - "is-property": "^1.0.0" - }, - "dependencies": { - "is-property": { - "version": "1.0.2", - "bundled": true - } - } - }, - "jsonpointer": { - "version": "2.0.0", - "bundled": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true - } - } - }, - "pinkie-promise": { - "version": "2.0.1", - "bundled": true, - "requires": { - "pinkie": "^2.0.0" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "bundled": true - } - } - } - } - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - }, - "dependencies": { - "boom": { - "version": "2.10.1", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "requires": { - "boom": "2.x.x" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - } - } - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "bundled": true - }, - "jsprim": { - "version": "1.3.0", - "bundled": true, - "requires": { - "extsprintf": "1.0.2", - "json-schema": "0.2.2", - "verror": "1.3.6" - }, - "dependencies": { - "extsprintf": { - "version": "1.0.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.2", - "bundled": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "requires": { - "extsprintf": "1.0.2" - } - } - } - }, - "sshpk": { - "version": "1.9.2", - "bundled": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jodid25519": "^1.0.0", - "jsbn": "~0.1.0", - "tweetnacl": "~0.13.0" - }, - "dependencies": { - "asn1": { - "version": "0.2.3", - "bundled": true - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "dashdash": { - "version": "1.14.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "getpass": { - "version": "0.1.6", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "jsbn": { - "version": "0.1.0", - "bundled": true, - "optional": true - }, - "tweetnacl": { - "version": "0.13.3", - "bundled": true, - "optional": true - } - } - } - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "mime-types": { - "version": "2.1.11", - "bundled": true, - "requires": { - "mime-db": "~1.23.0" - }, - "dependencies": { - "mime-db": { - "version": "1.23.0", - "bundled": true - } - } - }, - "node-uuid": { - "version": "1.4.7", - "bundled": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true - }, - "qs": { - "version": "6.2.1", - "bundled": true - }, - "stringstream": { - "version": "0.0.5", - "bundled": true - }, - "tough-cookie": { - "version": "2.3.1", - "bundled": true - }, - "tunnel-agent": { - "version": "0.4.3", - "bundled": true - } - } - }, - "retry": { - "version": "0.10.0", - "bundled": true - }, - "rimraf": { - "version": "2.5.4", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "semver": { - "version": "5.1.0", - "bundled": true - }, - "sha": { - "version": "2.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.2", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "process-nextick-args": "~1.0.0", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "bundled": true - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.3", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.1", - "bundled": true - } - } - } - } - }, - "slide": { - "version": "1.1.6", - "bundled": true - }, - "sorted-object": { - "version": "2.0.0", - "bundled": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "umask": { - "version": "1.1.0", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "bundled": true, - "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" - }, - "dependencies": { - "spdx-correct": { - "version": "1.0.2", - "bundled": true, - "requires": { - "spdx-license-ids": "^1.0.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.2", - "bundled": true, - "requires": { - "spdx-exceptions": "^1.0.4", - "spdx-license-ids": "^1.0.0" - }, - "dependencies": { - "spdx-exceptions": { - "version": "1.0.4", - "bundled": true - } - } - } - } - }, - "validate-npm-package-name": { - "version": "2.2.2", - "bundled": true, - "requires": { - "builtins": "0.0.7" - }, - "dependencies": { - "builtins": { - "version": "0.0.7", - "bundled": true - } - } - }, - "which": { - "version": "1.2.11", - "bundled": true, - "requires": { - "isexe": "^1.1.1" - }, - "dependencies": { - "isexe": { - "version": "1.1.2", - "bundled": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "write-file-atomic": { - "version": "1.1.4", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - } - } - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" - } + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cache-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-3.0.1.tgz", + "integrity": "sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw==", + "dev": true, + "dependencies": { + "buffer-json": "^2.0.0", + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.2.3", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/cache-loader/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/cache-loader/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cache-loader/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cache-loader/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/cache-loader/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "engines": { + "node": ">=14.16" } }, - "nth-check": { + "node_modules/cacheable-request": { + "version": "13.0.18", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.18.tgz", + "integrity": "sha512-rFWadDRKJs3s2eYdXlGggnBZKG7MTblkFBB0YllFds+UYnfogDp2wcR6JN97FhRkHTvq59n2vhNoHNZn29dh/Q==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.4", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.2.0", + "keyv": "^5.5.5", + "mimic-response": "^4.0.0", + "normalize-url": "^8.1.1", + "responselike": "^4.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "requires": { - "boolbase": "~1.0.0" + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "nwmatcher": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", - "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", - "optional": true + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true, + "license": "MIT" }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001674", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001674.tgz", + "integrity": "sha512-jOsKlZVRnzfhLojb+Ykb+gyUSp9Xb57So+fAiFlLzzTKpqg8xxSav0e40c8/4F/v9N8QSvrRRaLeVzQbLqomYw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "license": "CC-BY-4.0" + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/chokidar/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/chokidar/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/chokidar/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chunk-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chunk-data/-/chunk-data-0.1.0.tgz", + "integrity": "sha512-zFyPtyC0SZ6Zu79b9sOYtXZcgrsXe0RpePrzRyj52hYVFG1+Rk6rBqjjOEk+GNQwc3PIX+86teQMok970pod1g==", + "dev": true, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cipher-base": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", + "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "engines": { + "node": ">=20" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-concurrently/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/copy-concurrently/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/copy-concurrently/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/copy-concurrently/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/copy-concurrently/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/copy-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "dev": true, + "dependencies": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/copy-webpack-plugin/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/copy-webpack-plugin/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/copy-webpack-plugin/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/copy-webpack-plugin/node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/core-js": { + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz", + "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", + "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dev": true, + "dependencies": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/css-loader/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/css-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==", + "dev": true, + "dependencies": { + "css": "^2.0.0" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "dev": true + }, + "node_modules/cyclist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", + "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==", + "dev": true + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dev": true, + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dev": true, + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dev": true, + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==", + "dev": true + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dev": true, + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dev": true, + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dev": true, + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dev": true, + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dev": true, + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dev": true, + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dev": true, + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dev": true, + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dev": true, + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-voronoi": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==", + "dev": true + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "dev": true, + "dependencies": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, + "node_modules/dagre-d3": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.6.4.tgz", + "integrity": "sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==", + "dev": true, + "dependencies": { + "d3": "^5.14", + "dagre": "^0.8.5", + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, + "node_modules/dagre-d3/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.16.0.tgz", + "integrity": "sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==", + "dev": true, + "dependencies": { + "d3-array": "1", + "d3-axis": "1", + "d3-brush": "1", + "d3-chord": "1", + "d3-collection": "1", + "d3-color": "1", + "d3-contour": "1", + "d3-dispatch": "1", + "d3-drag": "1", + "d3-dsv": "1", + "d3-ease": "1", + "d3-fetch": "1", + "d3-force": "1", + "d3-format": "1", + "d3-geo": "1", + "d3-hierarchy": "1", + "d3-interpolate": "1", + "d3-path": "1", + "d3-polygon": "1", + "d3-quadtree": "1", + "d3-random": "1", + "d3-scale": "2", + "d3-scale-chromatic": "1", + "d3-selection": "1", + "d3-shape": "1", + "d3-time": "1", + "d3-time-format": "2", + "d3-timer": "1", + "d3-transition": "1", + "d3-voronoi": "1", + "d3-zoom": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-axis": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-brush": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.6.tgz", + "integrity": "sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA==", + "dev": true, + "dependencies": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-chord": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", + "dev": true, + "dependencies": { + "d3-array": "1", + "d3-path": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-color": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-contour": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", + "dev": true, + "dependencies": { + "d3-array": "^1.1.1" + } + }, + "node_modules/dagre-d3/node_modules/d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-drag": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz", + "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==", + "dev": true, + "dependencies": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-dsv": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz", + "integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==", + "dev": true, + "dependencies": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json", + "csv2tsv": "bin/dsv2dsv", + "dsv2dsv": "bin/dsv2dsv", + "dsv2json": "bin/dsv2json", + "json2csv": "bin/json2dsv", + "json2dsv": "bin/json2dsv", + "json2tsv": "bin/json2dsv", + "tsv2csv": "bin/dsv2dsv", + "tsv2json": "bin/dsv2json" + } + }, + "node_modules/dagre-d3/node_modules/d3-ease": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz", + "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-fetch": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.2.0.tgz", + "integrity": "sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA==", + "dev": true, + "dependencies": { + "d3-dsv": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "dev": true, + "dependencies": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-geo": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz", + "integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==", + "dev": true, + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-interpolate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz", + "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==", + "dev": true, + "dependencies": { + "d3-color": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-polygon": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz", + "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-scale": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz", + "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==", + "dev": true, + "dependencies": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "node_modules/dagre-d3/node_modules/d3-scale-chromatic": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz", + "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==", + "dev": true, + "dependencies": { + "d3-color": "1", + "d3-interpolate": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-selection": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz", + "integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dev": true, + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-time-format": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz", + "integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==", + "dev": true, + "dependencies": { + "d3-time": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==", + "dev": true + }, + "node_modules/dagre-d3/node_modules/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==", + "dev": true, + "dependencies": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "node_modules/dagre-d3/node_modules/d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==", + "dev": true, + "dependencies": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "node_modules/dagre-d3/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", + "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^4.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/del/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/del/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dev": true, + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/docsearch.js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", + "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @docsearch/js.", + "dev": true, + "dependencies": { + "algoliasearch": "^3.24.5", + "autocomplete.js": "0.36.0", + "hogan.js": "^3.0.2", + "request": "^2.87.0", + "stack-utils": "^1.0.1", + "to-factory": "^1.0.0", + "zepto": "^1.2.0" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.5.tgz", + "integrity": "sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==", + "dev": true + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.531", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.531.tgz", + "integrity": "sha512-H6gi5E41Rn3/mhKlPaT1aIMg/71hTAqn0gYEllSuw9igNWtvQwu185jiCZoZD29n7Zukgh7GVZ3zGf0XvkhqjQ==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/enhanced-resolve/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/enhanced-resolve/node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/enhanced-resolve/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/enhanced-resolve/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/enhanced-resolve/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", + "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.0", + "through": "~2.3.4" + }, + "bin": { + "envify": "bin/envify" + } + }, + "node_modules/envinfo": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.7.tgz", + "integrity": "sha512-+u/msd6iu+HvfysUPkZ9VHm83LImmSNnecYPfFI01pQ7TTcsFR+V0BkybZX7mPtIaI7LCrse6YRj+v3eraJSgw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "esbuild-android-arm64": "0.14.7", + "esbuild-darwin-64": "0.14.7", + "esbuild-darwin-arm64": "0.14.7", + "esbuild-freebsd-64": "0.14.7", + "esbuild-freebsd-arm64": "0.14.7", + "esbuild-linux-32": "0.14.7", + "esbuild-linux-64": "0.14.7", + "esbuild-linux-arm": "0.14.7", + "esbuild-linux-arm64": "0.14.7", + "esbuild-linux-mips64le": "0.14.7", + "esbuild-linux-ppc64le": "0.14.7", + "esbuild-netbsd-64": "0.14.7", + "esbuild-openbsd-64": "0.14.7", + "esbuild-sunos-64": "0.14.7", + "esbuild-windows-32": "0.14.7", + "esbuild-windows-64": "0.14.7", + "esbuild-windows-arm64": "0.14.7" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.7.tgz", + "integrity": "sha512-9/Q1NC4JErvsXzJKti0NHt+vzKjZOgPIjX/e6kkuCzgfT/GcO3FVBcGIv4HeJG7oMznE6KyKhvLrFgt7CdU2/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.7.tgz", + "integrity": "sha512-Z9X+3TT/Xj+JiZTVlwHj2P+8GoiSmUnGVz0YZTSt8WTbW3UKw5Pw2ucuJ8VzbD2FPy0jbIKJkko/6CMTQchShQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.7.tgz", + "integrity": "sha512-68e7COhmwIiLXBEyxUxZSSU0akgv8t3e50e2QOtKdBUE0F6KIRISzFntLe2rYlNqSsjGWsIO6CCc9tQxijjSkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.7.tgz", + "integrity": "sha512-76zy5jAjPiXX/S3UvRgG85Bb0wy0zv/J2lel3KtHi4V7GUTBfhNUPt0E5bpSXJ6yMT7iThhnA5rOn+IJiUcslQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.7.tgz", + "integrity": "sha512-lSlYNLiqyzd7qCN5CEOmLxn7MhnGHPcu5KuUYOG1i+t5A6q7LgBmfYC9ZHJBoYyow3u4CNu79AWHbvVLpE/VQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.7.tgz", + "integrity": "sha512-Vk28u409wVOXqTaT6ek0TnfQG4Ty1aWWfiysIaIRERkNLhzLhUf4i+qJBN8mMuGTYOkE40F0Wkbp6m+IidOp2A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.7.tgz", + "integrity": "sha512-+Lvz6x+8OkRk3K2RtZwO+0a92jy9si9cUea5Zoru4yJ/6EQm9ENX5seZE0X9DTwk1dxJbjmLsJsd3IoowyzgVg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.7.tgz", + "integrity": "sha512-OzpXEBogbYdcBqE4uKynuSn5YSetCvK03Qv1HcOY1VN6HmReuatjJ21dCH+YPHSpMEF0afVCnNfffvsGEkxGJQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.7.tgz", + "integrity": "sha512-kJd5beWSqteSAW086qzCEsH6uwpi7QRIpzYWHzEYwKKu9DiG1TwIBegQJmLpPsLp4v5RAFjea0JAmAtpGtRpqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.7.tgz", + "integrity": "sha512-mFWpnDhZJmj/h7pxqn1GGDsKwRfqtV7fx6kTF5pr4PfXe8pIaTERpwcKkoCwZUkWAOmUEjMIUAvFM72A6hMZnA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.7.tgz", + "integrity": "sha512-wM7f4M0bsQXfDL4JbbYD0wsr8cC8KaQ3RPWc/fV27KdErPW7YsqshZZSjDV0kbhzwpNNdhLItfbaRT8OE8OaKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.7.tgz", + "integrity": "sha512-J/afS7woKyzGgAL5FlgvMyqgt5wQ597lgsT+xc2yJ9/7BIyezeXutXqfh05vszy2k3kSvhLesugsxIA71WsqBw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ] + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.7.tgz", + "integrity": "sha512-7CcxgdlCD+zAPyveKoznbgr3i0Wnh0L8BDGRCjE/5UGkm5P/NQko51tuIDaYof8zbmXjjl0OIt9lSo4W7I8mrw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.7.tgz", + "integrity": "sha512-GKCafP2j/KUljVC3nesw1wLFSZktb2FGCmoT1+730zIF5O6hNroo0bSEofm6ZK5mNPnLiSaiLyRB9YFgtkd5Xg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ] + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.7.tgz", + "integrity": "sha512-5I1GeL/gZoUUdTPA0ws54bpYdtyeA2t6MNISalsHpY269zK8Jia/AXB3ta/KcDHv2SvNwabpImeIPXC/k0YW6A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.7.tgz", + "integrity": "sha512-CIGKCFpQOSlYsLMbxt8JjxxvVw9MlF1Rz2ABLVfFyHUF5OeqHD5fPhGrCVNaVrhO8Xrm+yFmtjcZudUGr5/WYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.7.tgz", + "integrity": "sha512-eOs1eSivOqN7cFiRIukEruWhaCf75V0N8P0zP7dh44LIhLl8y6/z++vv9qQVbkBm5/D7M7LfCfCTmt1f1wHOCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fast-glob/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", + "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/flush-write-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/flush-write-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/flush-write-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/flush-write-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreach": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", + "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/from2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs-write-stream-atomic/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/fs-write-stream-atomic/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/fs-write-stream-atomic/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/fs-write-stream-atomic/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "dev": true, + "license": "BSD" + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "1.3.7" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globby/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/globby/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/got/-/got-15.0.5.tgz", + "integrity": "sha512-PMIMaZuYUCK43+Z9JWEXea4kkX2b3301m81D5TS6QpfG4PmNyirzEdO/Oa2OHAN4GsjnPfvWCWsshKN2rq4/gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^8.0.0", + "byte-counter": "^0.1.0", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^13.0.18", + "chunk-data": "^0.1.0", + "decompress-response": "^10.0.0", + "http2-wrapper": "^2.2.1", + "keyv": "^5.6.0", + "lowercase-keys": "^4.0.1", + "responselike": "^4.0.2", + "type-fest": "^5.6.0", + "uint8array-extras": "^1.5.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/lowercase-keys": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-4.0.1.tgz", + "integrity": "sha512-wI9Nui/L8VfADa/cr/7NQruaASk1k23/Uh1khQ02BCVYiiy8F4AhOGnQzJy3Fl/c44GnYSbZHv8g7EcG3kJ1Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "node_modules/highlight.js": { + "version": "9.18.5", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", + "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", + "deprecated": "Support has ended for 9.x series. Upgrade to @latest", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": "*" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "dev": true, + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, + "node_modules/hogan.js/node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hogan.js/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", + "dev": true + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", + "dev": true + }, + "node_modules/html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", + "dev": true + }, + "node_modules/html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-minifier/node_modules/commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", + "dev": true + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==", + "dev": true, + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "dev": true + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ip": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", + "dev": true, + "dependencies": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/katex": { + "version": "0.16.27", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.27.tgz", + "integrity": "sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/khroma": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-1.4.1.tgz", + "integrity": "sha512-+GmxKvmiRuCcUYDgR7g5Ngo0JEDeOsGdNONdU2zsiBQaK4z19Y2NvXqfEDE0ZiIrg45GTZyAnPLVsLZZACYm3Q==", + "dev": true + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dev": true, + "dependencies": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/linkify-it/node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/loglevel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true, + "peerDependencies": { + "markdown-it": "*" + } + }, + "node_modules/markdown-it-chain": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", + "integrity": "sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ==", + "dev": true, + "dependencies": { + "webpack-chain": "^4.9.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "markdown-it": ">=5.0.0" + } + }, + "node_modules/markdown-it-chain/node_modules/javascript-stringify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", + "integrity": "sha512-fnjC0up+0SjEJtgmmG+teeel68kutkvzfctO/KxE3qJlbunkJYAshgH3boU++gSBHP8z5/r0ts0qRIrHf0RTQQ==", + "dev": true + }, + "node_modules/markdown-it-chain/node_modules/webpack-chain": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", + "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", + "dev": true, + "dependencies": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^1.6.0" + } + }, + "node_modules/markdown-it-container": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-2.0.0.tgz", + "integrity": "sha512-IxPOaq2LzrGuFGyYq80zaorXReh2ZHGFOB1/Hen429EJL1XkPI3FJTpx9TsJeua+j2qTru4h3W1TiCRdeivMmA==", + "dev": true + }, + "node_modules/markdown-it-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", + "integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==", + "dev": true + }, + "node_modules/markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", + "dev": true, + "engines": { + "node": ">6.4.0" + } + }, + "node_modules/markdown-it/node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, + "node_modules/markdown-it/node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, + "node_modules/markdownlint": { + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.40.0.tgz", + "integrity": "sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.2", + "string-width": "8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.48.0.tgz", + "integrity": "sha512-NkZQNu2E0Q5qLEEHwWj674eYISTLD4jMHkBzDobujXd1kv+yCxi8jOaD/rZoQNW1FBBMMGQpuW5So8B51N/e0A==", + "dev": true, + "dependencies": { + "commander": "~14.0.3", + "deep-extend": "~0.6.0", + "ignore": "~7.0.5", + "js-yaml": "~4.1.1", + "jsonc-parser": "~3.3.1", + "jsonpointer": "~5.0.1", + "markdown-it": "~14.1.1", + "markdownlint": "~0.40.0", + "minimatch": "~10.2.4", + "run-con": "~1.3.2", + "smol-toml": "~1.6.0", + "tinyglobby": "~0.2.15" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/medium-zoom": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.8.tgz", + "integrity": "sha512-CjFVuFq/IfrdqesAXfg+hzlDKu6A2n80ZIq0Kl9kWjoHh9j1N9Uvk5X0/MmN0hOfm5F9YBswlClhcwnmtwz7gA==", + "dev": true + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/memory-fs/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/memory-fs/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/memory-fs/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/memory-fs/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.14.0.tgz", + "integrity": "sha512-ITSHjwVaby1Li738sxhF48sLTxcNyUAoWfoqyztL1f7J6JOLpHOuQPNLBb6lxGPUA0u7xP9IRULgvod0dKu35A==", + "dev": true, + "dependencies": { + "@braintree/sanitize-url": "^3.1.0", + "d3": "^7.0.0", + "dagre": "^0.8.5", + "dagre-d3": "^0.6.4", + "dompurify": "2.3.5", + "graphlib": "^2.1.8", + "khroma": "^1.4.1", + "moment-mini": "^2.24.0", + "stylis": "^4.0.10" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-document": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", + "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz", + "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "^2.0.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/moment-mini": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.29.4.tgz", + "integrity": "sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==", + "dev": true + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/move-concurrently/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/move-concurrently/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/move-concurrently/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/move-concurrently/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/move-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==", + "dev": true + }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "dev": true, + "optional": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/node-libs-browser/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-check-updates": { + "version": "22.2.3", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-22.2.3.tgz", + "integrity": "sha512-n8HZ0ywZugYRgEqIm67hbZC5L/9S/gLX+MkGchJB43pP2xib1+u76OpVEJRZ4QP2BksPRi5M1CCStJVfc16+/A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "ncu": "build/cli.js", + "npm-check-updates": "build/cli.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": ">=10.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "dev": true + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", + "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", + "dev": true, + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "safe-array-concat": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true, + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optimize-css-assets-webpack-plugin": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", + "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", + "dev": true, + "dependencies": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json/node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json/node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json/node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/package-json/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json/node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/package-json/node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/package-json/node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/package-json/node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/package-json/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json/node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/parallel-transform/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/parallel-transform/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/parallel-transform/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/parallel-transform/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", + "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "~1.1.3", + "create-hmac": "^1.1.7", + "ripemd160": "=2.0.1", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.11", + "to-buffer": "^1.2.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pbkdf2/node_modules/create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" + } + }, + "node_modules/pbkdf2/node_modules/hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/pbkdf2/node_modules/ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^2.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plantuml-encoder": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.4.0.tgz", + "integrity": "sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==", + "dev": true + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/postcss-svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/postcss-svgo/node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/postcss-svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/postcss-svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/postcss-svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/postcss-svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-svgo/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/postcss-svgo/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/postcss-svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/postcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/readdirp/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/readdirp/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readdirp/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/readdirp/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reduce": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", + "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.1.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/renderkid": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/renderkid/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/responselike": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", + "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", + "dev": true + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", + "dev": true + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "dev": true + }, + "node_modules/run-con": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", + "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/run-con/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/run-queue/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "dev": true + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", + "dev": true, + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/smol-toml": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", + "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", + "dev": true, + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/smoothscroll-polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", + "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==", + "dev": true + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://tidelift.com/funding/github/npm/sockjs-client" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true + }, + "node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.3.1.tgz", + "integrity": "sha512-eOsoKTWnr6C8aWrqJJ2KAReXoa7Vn5Ywyw6uCXgA/xDhxPoaIsBa5aNJmISY04dLwXPBnDHW4diGM7Sn5K4R/g==", + "dev": true, + "dependencies": { + "ci-info": "^3.1.1" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-browserify/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-browserify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/stream-browserify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-http/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-http/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/stream-http/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "dev": true + }, + "node_modules/stylus": { + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", + "dev": true, + "dependencies": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + }, + "peerDependencies": { + "stylus": ">=0.52.4" + } + }, + "node_modules/stylus/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/stylus/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stylus/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/stylus/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/stylus/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "dev": true, + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/svgo/node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.6.tgz", + "integrity": "sha512-2lBVf/VMVIddjSn3GqbT90GvIJ/eYXJkt8cTzU7NbjKqK8fwv18Ftr4PlbF46b/e88743iZFL5Dtr/rC4hjIeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/terser-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/terser-webpack-plugin/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/terser-webpack-plugin/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "dev": true + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "dev": true + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-factory": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-factory/-/to-factory-1.0.0.tgz", + "integrity": "sha512-JVYrY42wMG7ddf+wBUQR/uHGbjUHZbLisJ8N62AMm0iTZ0p8YTcZLzdtomU0+H+wa99VbkyvQGB3zxB7NDzgIQ==", + "dev": true + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "dev": true + }, + "node_modules/toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha512-FclLrw8b9bMWf4QlCJuHBEVhSRsqDj6u3nIjAzPeJvgl//1hBlffdlk0MALceL14+koWEdU4ofRAXofbODxQzg==", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", + "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "dependencies": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "dev": true + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", + "dev": true + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "dev": true + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", "isobject": "^3.0.0" }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "engines": { + "node": ">=0.10.0" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + "node_modules/unset-value/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" } }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "node_modules/update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "optional": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "optional": true - } + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" } }, - "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", - "optional": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "requires": { - "through": "~2.3" + "node_modules/url-loader": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", + "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" } }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + "node_modules/url-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", - "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - }, - "dependencies": { - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - } + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/url/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "plantuml-encoder": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.4.0.tgz", - "integrity": "sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==" + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "optional": true + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + "node_modules/util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "optional": true, - "requires": { - "asap": "~2.0.3" + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" } }, - "promised-handlebars": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/promised-handlebars/-/promised-handlebars-1.0.6.tgz", - "integrity": "sha1-2ZfglDsD9j/oL/I8uQSyes/AUNg=", - "requires": { - "deep-aplus": "^1.0.2", - "q": "^1.4.1" + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" } }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" } }, - "proxy-middleware": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", - "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "optional": true - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" - }, - "q-deep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/q-deep/-/q-deep-1.0.3.tgz", - "integrity": "sha1-zQcD2irMuuZXDmAMaKVt5mEHkMs=", - "requires": { - "deep-aplus": "^1.0.1", - "q": "^1.1.2" + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "q-plus": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/q-plus/-/q-plus-0.0.8.tgz", - "integrity": "sha1-TMZssZvRRbQ+nhtUAjYUI3e2Hqs=", - "requires": { - "q": "^1.1.2" + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/vue": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", + "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-sfc": "2.7.16", + "csstype": "^3.1.0" + } }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + "node_modules/vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue-loader": { + "version": "15.11.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz", + "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + }, + "peerDependencies": { + "css-loader": "*", + "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "cache-loader": { + "optional": true + }, + "prettier": { + "optional": true }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "vue-template-compiler": { + "optional": true } } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "node_modules/vue-router": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==", + "dev": true + }, + "node_modules/vue-server-renderer": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.7.16.tgz", + "integrity": "sha512-U7GgR4rYmHmbs3Z2gqsasfk7JNuTsy/xrR5EMMGRLkjN8+ryDlqQq6Uu3DcmbCATAei814YOxyl0eq2HNqgXyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "hash-sum": "^2.0.0", + "he": "^1.2.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.22.0", + "serialize-javascript": "^6.0.0", + "source-map": "0.5.6" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "node_modules/vue-server-renderer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "node_modules/vue-server-renderer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/vue-server-renderer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "requires": { - "is-equal-shallow": "^0.1.3" + "node_modules/vue-server-renderer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/vue-server-renderer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "node_modules/vue-server-renderer/node_modules/hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "dev": true + }, + "node_modules/vue-server-renderer/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "node_modules/vue-server-renderer/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + "node_modules/vue-server-renderer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "node_modules/vue-style-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vuepress": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.9.10.tgz", + "integrity": "sha512-UnGm9vjQvG918SZVNvgiUlNimLqawdYPq0aPRXDpEB1VksvqegVFy/GKdA8ShXJaEpOMPSt7YD4uK21jaMs3kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@vuepress/core": "1.9.10", + "@vuepress/theme-default": "1.9.10", + "@vuepress/types": "1.9.10", + "cac": "^6.5.6", + "envinfo": "^7.2.0", + "opencollective-postinstall": "^2.0.2", + "update-notifier": "^4.0.0" }, + "bin": { + "vuepress": "cli.js" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/vuepress-html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A==", + "dev": true, "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true, + "engines": { + "node": "*" } }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "requires": { - "throttleit": "^1.0.0" + "node_modules/vuepress-html-webpack-plugin/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true, + "engines": { + "node": ">= 0.10" } }, - "request-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz", - "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==", - "requires": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.2", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" + "node_modules/vuepress-html-webpack-plugin/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true, + "bin": { + "json5": "lib/cli.js" } }, - "request-promise-core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", - "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", - "requires": { - "lodash": "^4.17.11" - }, + "node_modules/vuepress-html-webpack-plugin/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", + "dev": true, "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "node_modules/vuepress-plugin-container": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.5.tgz", + "integrity": "sha512-TQrDX/v+WHOihj3jpilVnjXu9RcTm6m8tzljNJwYhxnJUW0WWQ0hFLcDTqTBwgKIFdEiSxVOmYE+bJX/sq46MA==", + "dev": true, + "dependencies": { + "@vuepress/shared-utils": "^1.2.0", + "markdown-it-container": "^2.0.0" + } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + "node_modules/vuepress-plugin-mermaidjs": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/vuepress-plugin-mermaidjs/-/vuepress-plugin-mermaidjs-2.0.0-beta.2.tgz", + "integrity": "sha512-0pDJjLFsnMuvy3wc2iEhz0OQy+tQva04ynVdhMKdH6KtetuezxtNbwazEJcRQGzDzyo2r/5rGRLYvA4MhGnj5w==", + "dev": true, + "dependencies": { + "mermaid": "^8.14.0" + } }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "requires": { - "align-text": "^0.1.1" + "node_modules/vuepress-plugin-smooth-scroll": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", + "integrity": "sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg==", + "dev": true, + "dependencies": { + "smoothscroll-polyfill": "^0.4.3" } }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" + "node_modules/vuepress-plugin-versioning": { + "version": "4.10.2", + "resolved": "git+ssh://git@github.com/mojaloop/vuepress-plugin-versioning.git#dcb14962a69b8e5aaf184d2d1a31ae4f43870bc1", + "integrity": "sha512-8sUoK+REHLrmnF9nzGxljTDS0v6edozzPjhUvNIazsSNfTBRcMMmGgVlzQmS1d6GgSMUex7HyfIDMjamWybgvg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vuepress/shared-utils": "^1.7.1", + "fs-extra": "^9.0.1" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/vuepress-plugin-versioning/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" + "node_modules/vuepress-plugin-versioning/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "node_modules/vuepress-plugin-versioning/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "optional": true + "node_modules/vuepress-theme-titanium": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vuepress-theme-titanium/-/vuepress-theme-titanium-5.0.0.tgz", + "integrity": "sha512-hKkpt2qPIrSQEFHdaqqoBa5oKIlQ+CKMdWO7NcC0T9TGOtbh8yZOTjAN5dxoT7UXsYtv86Le4K2pnuKk1Ceeeg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vuepress/plugin-nprogress": "^1.7.1", + "@vuepress/plugin-search": "^1.7.1", + "docsearch.js": "^2.6.3", + "lodash": "^4.17.15", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "vuepress-plugin-container": "^2.1.5" + } }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/watchpack/node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/watchpack/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" + "node_modules/watchpack/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/watchpack/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/watchpack/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", + "integrity": "sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==", + "dev": true, + "license": "MIT", "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "webpack-command": { + "optional": true } } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" + "node_modules/webpack-chain": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz", + "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==", + "dev": true, + "dependencies": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^2.0.1" + }, + "engines": { + "node": ">=8" } }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "node_modules/webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dev": true, + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz", + "integrity": "sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==", + "dev": true, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } + "ansi-html-community": "0.0.8", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true } } }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", + "node_modules/webpack-dev-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "engines": { + "node": ">=0.10.0" } }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "node_modules/webpack-dev-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true, + "engines": { + "node": ">=8" } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "optional": true, - "requires": { - "hoek": "2.x.x" + "node_modules/webpack-dev-server/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" } }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "requires": { - "amdefine": ">=0.0.4" + "node_modules/webpack-dev-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + "node_modules/webpack-dev-server/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "requires": { - "through": "2" + "node_modules/webpack-dev-server/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "node_modules/webpack-dev-server/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "node_modules/webpack-dev-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "stack-chain": { + "node_modules/webpack-log": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", - "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==", - "optional": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } + "lodash": "^4.17.15" } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "requires": { - "duplexer": "~0.1.1" + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" } }, - "stream-equal": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/stream-equal/-/stream-equal-0.1.13.tgz", - "integrity": "sha1-F8LXz43lVw0P+5njpRQqWMdrxK4=", - "requires": { - "@types/node": "*" + "node_modules/webpack/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" + "node_modules/webpack/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "optional": true - }, - "svgexport": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/svgexport/-/svgexport-0.3.2.tgz", - "integrity": "sha1-ci8xhAMotIPopdyqc+/4GNiE0QY=", - "requires": { - "async": "^1.0.0", - "phantomjs-prebuilt": "^2.1.4" + "node_modules/webpack/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" } }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "optional": true + "node_modules/webpack/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=" + "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "node_modules/webpack/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "requires": { - "os-tmpdir": "~1.0.1" + "node_modules/webpack/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" + "node_modules/webpack/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" } }, - "to-regex-range": { + "node_modules/webpack/node_modules/to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpackbar": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-3.2.0.tgz", + "integrity": "sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw==", + "dev": true, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - } + "ansi-escapes": "^4.1.0", + "chalk": "^2.4.1", + "consola": "^2.6.0", + "figures": "^3.0.0", + "pretty-time": "^1.1.0", + "std-env": "^2.2.1", + "text-table": "^0.2.0", + "wrap-ansi": "^5.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" } }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "node_modules/webpackbar/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "optional": true + "node_modules/webpackbar/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } }, - "trace": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/trace/-/trace-3.1.1.tgz", - "integrity": "sha512-iVxFnDKps8bCRQ6kXj66rHYFJY3fNkoYPHeFTFZn89YdwmmQ9Hz97IFPf3NdfbCF3zuqUqFpRNTu6N9+eZR2qg==", - "optional": true, - "requires": { - "stack-chain": "^2.0.0" + "node_modules/webpackbar/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "trace-and-clarify-if-possible": { + "node_modules/webpackbar/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/webpackbar/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trace-and-clarify-if-possible/-/trace-and-clarify-if-possible-1.0.5.tgz", - "integrity": "sha512-CmBz2eGrPxQ5miq51B4XnON0iC62q6q7CEzrRaFYZYi8xdX1ivafyk5cYshmVXp6p14cYvK3H4o1drYa3MEJOA==", - "requires": { - "clarify": "^2.1.0", - "trace": "^3.1.1" + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" + "node_modules/webpackbar/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "optional": true, - "requires": { - "prelude-ls": "~1.1.2" + "node_modules/webpackbar/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" } }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "node_modules/webpackbar/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "node_modules/webpackbar/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "unix-crypt-td-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.0.0.tgz", - "integrity": "sha1-HAgkFQSBvHoB1J6Y8exmjYJBLzs=" + "node_modules/when": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", + "integrity": "sha512-d1VUP9F96w664lKINMGeElWdhhb5sC+thXM+ydZGU3ZnaE09Wv6FaS+mpM9570kcDs/xMfcXJBTLsMdHEFYY9Q==", + "dev": true }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "requires": { - "os-homedir": "^1.0.0" + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" } }, - "util-deprecate": { + "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" } }, - "webidl-conversions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz", - "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=", - "optional": true + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } }, - "whatwg-url-compat": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz", - "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=", - "optional": true, - "requires": { - "tr46": "~0.0.1" + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" + "node_modules/yargs/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", - "optional": true + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" + "node_modules/yargs/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" } }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "requires": { - "fd-slicer": "~1.0.1" + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } + }, + "node_modules/zepto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz", + "integrity": "sha512-C1x6lfvBICFTQIMgbt3JqMOno3VOtkWat/xEakLTOurskYIHPmzJrzd1e8BnmtdDVJlGuk5D+FxyCA8MPmkIyA==", + "dev": true } } } diff --git a/package.json b/package.json index 3a136d614..ed72812a1 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,43 @@ { - "name": "documentation", - "version": "9.1.0", - "description": "Mojaloop Documentation GitBook Project", - "dependencies": { - "express": "4.17.1", - "gitbook-cli": "2.3.2", - "gitbook-plugin-back-to-top-button": "0.1.4", - "gitbook-plugin-changelog": "1.0.1", - "gitbook-plugin-collapsible-chapters": "0.1.8", - "gitbook-plugin-editlink": "1.0.2", - "gitbook-plugin-fontsettings": "2.0.0", - "gitbook-plugin-include": "0.1.0", - "gitbook-plugin-insert-logo": "0.1.5", - "gitbook-plugin-page-toc": "1.1.1", - "gitbook-plugin-plantuml-svg": "1.0.1", - "gitbook-plugin-swagger": "0.2.0", - "gitbook-plugin-theme-api": "1.1.2", - "gitbook-plugin-uml": "1.0.1", - "gitbook-plugin-variables": "1.1.0", - "svgexport": "0.3.2" - }, - "devDependencies": {}, + "name": "mojaloop-docs-vuepress", + "version": "1.0.0", + "description": "Mojaloop Documentation 3.0", + "license": "Apache-2.0", + "contributors": [ + "Sam Kummary ", + "Uduak Obong-Eren ", + "Steven Oderayi ", + "Tony Williams " + ], + "repository": "https://www.github.com/mojaloop/documentation", "scripts": { - "run": "npm run gitbook:serve", - "start": "npm run gitbook:serveNoReload", - "gitbook:install": "gitbook install", - "gitbook:build": "gitbook build", - "gitbook:serve": "gitbook serve --port 8989", - "gitbook:serveNoReload": "gitbook serve --no-live --port 8989", - "gitbook:export:pdf": "gitbook pdf ./", - "docker:build": "docker build --no-cache -t mojaloop/documentation .", - "docker:push": "docker push mojaloop/documentation", - "docker:run": "docker run --rm -it --name mojadoc -p 8989:8989 mojaloop/documentation", - "express:run": "node index.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/mojaloop/documentation.git" + "dev": "NODE_OPTIONS=--openssl-legacy-provider npx npx vuepress dev docs", + "build": "NODE_OPTIONS='--max-old-space-size=8192' npx npx vuepress build docs", + "build:plantuml:all": "./scripts/_build_plantuml.sh", + "build:plantuml:diff": "MODE=STAGED_GIT ./scripts/_build_plantuml.sh", + "lint": "npx markdownlint './docs/**/*.md' --ignore node_modules --config markdownlint.yaml", + "lint:fix": "npm run lint -- --fix", + "dep:check": "npx ncu -e 2", + "dep:update": "npx ncu -u", + "prepare": "npx husky install" }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/mojaloop/documentation/issues" + "devDependencies": { + "@vuepress/plugin-back-to-top": "^1.9.10", + "@vuepress/plugin-medium-zoom": "^1.9.10", + "got": "^15.0.5", + "husky": "^9.1.7", + "markdownlint-cli": "^0.48.0", + "npm-check-updates": "^22.2.3", + "plantuml-encoder": "^1.4.0", + "svgo": "^4.0.1", + "vuepress": "^1.9.10", + "vuepress-plugin-mermaidjs": "^2.0.0-beta.2", + "vuepress-plugin-versioning": "git+https://github.com/mojaloop/vuepress-plugin-versioning.git#dcb14962a69b8e5aaf184d2d1a31ae4f43870bc1", + "vuepress-theme-titanium": "^5.0.0" }, - "homepage": "https://github.com/mojaloop/documentation#readme" + "overrides": { + "vuepress": { + "vue-loader": "15.1.1" + } + } } diff --git a/scripts/_build_plantuml.sh b/scripts/_build_plantuml.sh new file mode 100755 index 000000000..7b888209d --- /dev/null +++ b/scripts/_build_plantuml.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + + +## +# _build_plantuml.sh +# +# searches through repo for plantuml sources matching $PUML_MATCH +# and exports them using `node-plantuml`. +# +# In order to build deterministic .svgs, we use a puml docker image that is +# pegged to a specific version +## + +set -eu + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PUML_PORT=9999 +export PUML_BASE_URL=http://localhost:${PUML_PORT} + +# Match filenames ending with .puml or .plantuml by default +PUML_MATCH=${PUML_MATCH:=*.p*uml} + +# if MODE=STAGED_GIT, then search staged git files +# if MODE=ALL, then search the whole repo +MODE=${MODE:=ALL} + +# Pre-commit hook: do not require Docker when no PlantUML sources were staged. +if [[ "${MODE}" == "STAGED_GIT" ]]; then + if ! git diff --staged --name-only | grep -Eq '\.(puml|plantuml)$'; then + echo "No staged PlantUML sources; skipping render." + exit 0 + fi +fi + +trap ctrl_c INT +function ctrl_c() { + echo "exit early - stopping docker" + docker stop puml-local + exit 1 +} + +# run the docker puml server +docker run -d --rm \ + --name puml-local \ + -p ${PUML_PORT}:8080 \ + plantuml/plantuml-server:jetty-v1.2024.7 + +# Wait for docker to be up +sleep 2 + +echo "Searching for ${MODE} files matching pattern: ${PUML_MATCH}" + +case ${MODE} in + # search only for the staged files - much faster to run as a git hook + STAGED_GIT) + for i in $(git diff --staged --name-only `find ${DIR}/../docs -name ${PUML_MATCH}`); do + echo "rendering .puml -> .svg for diagram diagram: $i" + + # add the .svg file alongside the original + ${DIR}/_render_svg.mjs $i + done + ;; + + # search all files + ALL) + for i in $(find ${DIR}/../docs -name ${PUML_MATCH}); do + echo "rendering .puml -> .svg for diagram diagram: $i" + + # add the .svg file alongside the original + ${DIR}/_render_svg.mjs $i + done + ;; + + *) + echo "unsupported search MODE:${MODE}" + exit 1 + ;; +esac + +docker stop puml-local diff --git a/scripts/_deploy_preview_s3.sh b/scripts/_deploy_preview_s3.sh new file mode 100755 index 000000000..1811e5086 --- /dev/null +++ b/scripts/_deploy_preview_s3.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + + +# deploys the preview docs to an s3 bucket +# I manually created the bucket: `mojaloop-docs-preview` +# in the eu-west-2 region +# and followed the guide: https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html +# to manually configure the bucket for website hosting +# And this guide: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/ +# to set up Cloudfront and Route53 +# "Using a REST API endpoint as the origin, with access restricted by an OAI" + +# The website should be available at: +# https://docs.mojaloop.io/pr/ + +# Required tools: +# - aws-cli +# - aws-mfa (if running as user, not CI) + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +NVM_DIR=$HOME/.nvm +export AWS_REGION="${AWS_REGION:-eu-west-2}" +export BUCKET_NAME="${BUCKET_NAME:-docs.mojaloop.io-root}" +export DOMAIN="${DOMAIN:-docs.mojaloop.io}" +export IS_PR="${IS_PR:-false}" +export PR_NUMBER="${PR_NUMBER:-}" + +set -e +set -u + +# make sure we can actually list the s3 buckets +aws s3 ls s3://${BUCKET_NAME} + +# build new vuepress site +rm -rf ${DIR}/../build +cd ${DIR}/../ +npm ci +# Pass environment variables to VuePress build +export VUEPRESS_IS_PR="${IS_PR}" +export VUEPRESS_PR_NUMBER="${PR_NUMBER}" +npm run build +mv ${DIR}/../docs/.vuepress/dist ${DIR}/../build + +# Copy assets from nested directories to build output +echo "Copying assets from nested directories..." +find ${DIR}/../docs -name "assets" -type d | while read asset_dir; do + # Get the relative path from docs directory + rel_path=$(echo "$asset_dir" | sed "s|${DIR}/../docs/||") + # Create the target directory in build output + target_dir="${DIR}/../build/${rel_path}" + mkdir -p "$target_dir" + # Copy all files from the asset directory + cp -r "$asset_dir"/* "$target_dir/" 2>/dev/null || true +done + + +# build legacy docs - will be removed once all docs are migrated to v2.0 +# Removing from here! multiple node versions in CI/CD are really hard! +# cd ${DIR}/../legacy +# [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" +# nvm install 10.15.1 +# nvm use 10.15.1 +# npm i +# npm run gitbook:build +# copy to a legacy subfolder +mv ${DIR}/../legacy/_book ${DIR}/../build/legacy + + +# TODO: can we be smart about docs versions here? maybe every minor version we can keep... + +# Determine the target path based on whether this is a PR or not +if [ "$IS_PR" = "true" ] && [ -n "$PR_NUMBER" ]; then + TARGET_PATH="pr/${PR_NUMBER}" +else + TARGET_PATH="" +fi + +# upload built files to s3 +if [ -n "$TARGET_PATH" ]; then + aws s3 sync ${DIR}/../build s3://${BUCKET_NAME}/${TARGET_PATH} \ + --acl public-read +else + aws s3 sync ${DIR}/../build s3://${BUCKET_NAME} \ + --acl public-read +fi + +if [ "$IS_PR" = "true" ] && [ -n "$PR_NUMBER" ]; then + echo "Preview deployment is available at: https://${DOMAIN}/pr/${PR_NUMBER}" +else + echo "Deployment is available at: https://${DOMAIN}" +fi \ No newline at end of file diff --git a/scripts/_render_svg.mjs b/scripts/_render_svg.mjs new file mode 100755 index 000000000..aa01947d5 --- /dev/null +++ b/scripts/_render_svg.mjs @@ -0,0 +1,86 @@ +#!/usr/bin/env node + +/** + * NOTES: + * - This file is an ESM Module (thus the extension `.mjs`). This is required for the `got` dependency which only supports ESM! + * - Uses PlantUml server to render a PUML to SVG + */ + +import fs from 'fs' +import path from 'path' +import util from 'util' +import got from 'got' +import * as SVGO from 'svgo' +import * as plantumlEncoder from 'plantuml-encoder' + +const rendererBaseUrl = process.env.PUML_BASE_URL || 'http://www.plantuml.com/plantuml' + +async function main() { + + let [_, _script, inputPath, outputPath] = process.argv + + if (!inputPath) { + console.log("usage: ./_render_svg.mjs []") + process.exit(1) + } + + // If not specified, replace .puml or .plantuml with `.svg` + if (!outputPath) { + outputPath = inputPath.replace('.puml', '.svg') + .replace('.plantuml', '.svg') + } + + const rawPumlContents = fs.readFileSync(inputPath) + const encoded = plantumlEncoder.encode(rawPumlContents.toString()) + const url = `${rendererBaseUrl}/svg/${encoded}` + let result + try { + result = await got.get(url) + } catch (err) { + console.log('http request failed to render puml with error', err.message) + if (err.message.indexOf('Response code 403') > -1) { + console.log('Note: sometimes the public puml renderer fails when the input diagrams are too large. Try running your own renderer server with docker.') + } + + if (err.message.indexOf('Response code 400') > -1) { + console.log('This could be due to bad syntax in the puml diagram. Url is:') + console.log(url) + } + + process.exit(1) + } + + // Strip comments and prettify svg + // This makes sure that our .svg files are deterministic and diff'able + const formatted = await SVGO.optimize( + result.body, + { + path: outputPath, + multipass: true, + js2svg: { pretty: true, indent: 2 }, + plugins: [ + //// preset-defaults plugin override + // { + // name: 'preset-default', + // params: { + // overrides: { + // Insert overrides here. + // } + // } + // }, + // removeComments plugin + { + name: 'removeComments', + params: { + overrides: { + active: true + } + } + } + ] + } + ) + fs.writeFileSync(outputPath, formatted.data) +} + +main() diff --git a/scripts/_sync_sequence_puml.sh b/scripts/_sync_sequence_puml.sh new file mode 100755 index 000000000..64a0c660c --- /dev/null +++ b/scripts/_sync_sequence_puml.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +## +# The images and puml diagrams for the Mojaloop API come from +# the mojaloop/mojaloop-specification repo +# +# This script copies the latest diagrams from that repo +# into this one. +## + + +set -eu pipefail + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SOURCE_REPO_URL=git@github.com:mojaloop/mojaloop-specification.git +SOURCE_PATH_TO_COPY=/tmp/mojaloop-specification/assets/diagrams/ +DESTINATION_PATH=${DIR}/../docs/api/assets + +git clone ${SOURCE_REPO_URL} /tmp/mojaloop-specification || echo 'already cloned' + +ls ${SOURCE_PATH_TO_COPY} + +cp -R ${SOURCE_PATH_TO_COPY} ${DESTINATION_PATH} + +# cleanup +rm -rf /tmp/mojaloop-specification \ No newline at end of file diff --git a/tmp-regex.md b/tmp-regex.md new file mode 100644 index 000000000..a3d0b8f4d --- /dev/null +++ b/tmp-regex.md @@ -0,0 +1,16 @@ + +replace the uml line with just the path +find: ^\{%.*(".*").*\n +replace: $1\n + + +Find all uml end tags: +find (plain): {% enduml %} +replace: + +Replace string with image ref: + +find: ^".*plantuml" +replace: ![]($0) + + diff --git a/website/README.md b/website/README.md new file mode 100644 index 000000000..b7d4930aa --- /dev/null +++ b/website/README.md @@ -0,0 +1,7 @@ +# Versioned Docs + +This directory contains previous versions of the documentation. + +Please don't edit them! If you have a fix to make in +the documentation, then make it in `./docs`. We keep the old versions in the same repo to make switching between versions and referencing simple. + diff --git a/website/versioned_docs/v1.0.1/api/README.md b/website/versioned_docs/v1.0.1/api/README.md new file mode 100644 index 000000000..518535f9a --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/README.md @@ -0,0 +1,13 @@ +# API Catalog + +The Mojaloop Family of APIs is a set of several different APIs that cater for several business or transactional functions. So far, the well defined and adopted APIs are: + +- [FSP Interoperability (FSPIOP) APIs](./fspiop/) +- [Administration API]() +- [Settlement API]() +- [Third-party Payment Initiaion (3PPI/PISP) API]() + +There are other APIs that are either in active development and design or on the roadmap: + +- Cross-network API (FX) +- Reporting API diff --git a/website/versioned_docs/v1.0.1/api/administration/README.md b/website/versioned_docs/v1.0.1/api/administration/README.md new file mode 100644 index 000000000..b1851d4be --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/administration/README.md @@ -0,0 +1,14 @@ +## Administration API +The Administration API includes the following documents. + +### Administration Central Ledger API + +[The specification of the Central Ledger API](./central-ledger-api) introduces and describes the **Central Ledger API**. The purpose of the API is to enable Hub Operators to manage admin processes around: + +- Creating/activating/deactivating participants in the Hub +- Adding and updating participant endpoint information +- Managing participant accounts, limits, and positions +- Creating Hub accounts +- Performing Funds In and Funds Out operations +- Creating/updating/viewing settlement models +- Retrieving transfer details \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/administration/central-ledger-api.md b/website/versioned_docs/v1.0.1/api/administration/central-ledger-api.md new file mode 100644 index 000000000..5d3370d99 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/administration/central-ledger-api.md @@ -0,0 +1,1728 @@ +--- +showToc: true +--- +# Central Ledger API + +## Introduction + +This document provides detailed information about the Central Ledger API. The Central Ledger API is a Mojaloop API enabling Hub Operators to manage admin processes around: + +- Creating/activating/deactivating participants in the Hub +- Adding and updating participant endpoint information +- Managing participant accounts, limits, and positions +- Creating Hub accounts +- Performing Funds In and Funds Out operations +- Creating/updating/viewing settlement models +- Retrieving transfer details + + For background information about the participant and settlement model details that the Hub Operator can administer using the Central Ledger API, see section [Basic concepts](#basic-concepts). + +
    + +## Basic concepts + +To provide context for the admin operations that the Central Ledger API enables, this section gives a brief definition of some basic concepts. + +### Participant + +Either the Hub itself or a Digital Financial Service Provider (DFSP) that is a participant in a Mojaloop scheme. + +### Endpoint + +The DFSP callback URL where the Hub routes API callbacks. The URL specified is the endpoint set up in the outbound API gateway. + +### Limit + +Currently, only one type of limit is supported, it is called "_Net Debit Cap (NDC)_". In the future, it is possible to add support for further types of limits. + +The _Net Debit Cap_ represents the liquidity cover available for a specific account (the Position account). It is the total amount of good funds which the scheme attests are available to guarantee that a participant is able to settle the liabilities it incurs on the Position account as a consequence of transferring funds. This amount of good funds is represented as the balance of an account (the Settlement account), which is tied to the Position account by a settlement model. The source of the funds in this account can be either funds recorded by the scheme's administrators as having been deposited to or withdrawn from the Settlement account, or funds which are automatically credited to or debited from the account by the scheme if the account is the Settlement account for an immediate gross settlement model. + +It should also be possible for a participant to specify that an amount, or a proportion, of the funds available in a Settlement account should be excluded from the Net Debit Cap calculation. In cases where a participant is a long-term net beneficiary of funds via settlement, or where participants keep extra funds in their Settlement account to cover periods when it may not be possible to deposit funds to those accounts, it may wish to exclude part of the balance of its Settlement account from use as cover for transfers. + +### Account + +Also called _Ledger_. The Hub maintains a number of internal accounts to keep track of the movement of money (both e-money and real money) between DFSPs. + +### Position + +The Position represents the net of: +- transfers on that account which have cleared but have not yet settled, and +- transfers on that account where: + - the DFSP is the debtor party, and + - the transfer has been accepted for processing by the Hub, but has not yet cleared. + +The Position for a given account is always verifiably up to date. + +When a transfer is requested, the Hub will check that the DFSP has liquidity cover available on that account to cover the amount of the transfer. If it does not, the transfer will be rejected. + +We currently allow liabilities to the participant which have been created as a consequence of transfers on the account where the participant is the beneficiary to reduce the participant's Position as if the liabilities had already been settled. + +### Funds In and Funds Out + +Funds In and Funds Out operations are used to track (in the Hub accounts) money movements related to deposits and withdrawals, as well as settlements. + +Funds In operations record either the deposit of money into a DFSP's settlement bank account or the settlement amount for a receiving DFSP. + +Funds Out operations record either the withdrawal of money from a DFSP's settlement bank account or the settlement amount for a sending DFSP. + +### Settlement model + +Refers to how settlement happens within a scheme. Settlement is the process of transferring funds from one DSFP to another, so that the payer's DFSP reimburses the payee's DFSP for funds given to the payee during a transaction. A settlement model specifies if participants settle with each other separately or settle with the scheme, whether transfers are settled one by one or as a batch, whether transfers are settled immediately or with a delay, and so on. + +
    + +## HTTP details + +This section contains detailed information regarding the use of the application-level protocol HTTP in the API. + +### HTTP header fields + +HTTP headers are generally described in [RFC 7230](https://tools.ietf.org/html/rfc7230). Any headers specific to the Central Ledger API will be standardised in the future. + +### HTTP methods + +The following HTTP methods, as defined in [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4), are supported by the API: + +- `GET` – The HTTP GET method is used from a client to retrieve information about a previously-created object on a server. +- `POST` – The HTTP POST method is used from a client to request an object to be created on the server. +- `PUT` – The HTTP PUT method is used from a client to request an object already existing on the server to be modified (to replace a representation of the target resource with the request payload). + +> **NOTE:** The `DELETE` method is not supported. + +### HTTP response status codes + +The [HTTP response status codes](#http-response-status-codes) table lists the HTTP response status codes that the API supports: + +|Status Code|Reason|Description| +|---|---|---| +|**200**|OK|Standard response for a successful `GET`, `PUT`, or `POST` operation. The response will contain an entity corresponding to the requested resource.| +|**201**|Created|The `POST` request has been fulfilled, resulting in the creation of a new resource. The response will not contain an entity describing or containing the result of the action.| +|**202**|Accepted|The request has been accepted for processing, but the processing has not been completed.| +|**400**|Bad Request|The server could not understand the request due to invalid syntax.| +|**401**|Unauthorized|The request requires authentication in order to be processed.| +|**403**|Forbidden|The request was denied and will be denied in the future.| +|**404**|Not Found|The requested resource is not available at the moment.| +|**405**|Method Not Allowed|An unsupported HTTP method for the request was used.| +|**406**|Not Acceptable|The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.| +|**500**|Internal Server Error|A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.| +|**501**|Not Implemented|The server does not support the requested service. The client should not retry.| +|**503**|Service Unavailable|The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame.| + +
    + +## API services + +This section introduces and details all services that the API supports for each resource and HTTP method. + +### High-level API services + +On a high level, the API can be used to perform the following actions: + +- **`/participants`**: View, create, update participant-related details, such as limit (Net Debit Cap), position, or endpoints configured. +- **`/settlementModels`**: View, create, update settlement-model-related details, such as granularity, delay, liquidity check, and so on. +- **`/transactions`**: View transaction details for a particular transfer. + +### Supported API services + +The [Supported API services](#supported-api-services) table includes high-level descriptions of the services that the API provides. For more detailed information, see the sections that follow. + +| URI | HTTP method `GET`| HTTP method `PUT` | HTTP method `POST` | HTTP method `DELETE` | +|---|---|---|---|---| +| **`/participants`** | Get information about all participants | Not supported | Create participants in the Hub | Not supported | +| `/participants/limits` | View limits for all participants | Not supported | Not supported | Not supported | +| `/participants/{name}` | Get information about a particular participant | Update participant details (activate/deactivate a participant) | Not supported | Not supported | +| `/participants/{name}/endpoints` | View participant endpoints | Not supported | Add/Update participant endpoints | Not supported | +| `/participants/{name}/limits` | View participant limits | Adjust participant limits | Not supported | Not supported | +| `/participants/{name}/positions` | View participant positions | Not supported | Not supported | Not supported | +| `/participants/{name}/accounts` | View participant accounts and balances | Not supported | Create Hub accounts | Not supported | +| `/participants/{name}/accounts/{id}` | Not supported | Update participant accounts | Record Funds In or Out of participant account | Not supported | +| `/participants/{name}/accounts/{id}/transfers/{transferId}` | Not supported | Not supported | Record a Transfer as a Funds In or Out transaction for a participant account | Not supported | +| `/participants/{name}/initialPositionAndLimits` | Not supported | Not supported | Add initial participant limits and position | Not supported | +| **`/settlementModels`** | View all settlement models | Not supported | Create a settlement model | Not supported | +| `/settlementModels/{name}` | View settlement model by name | Update a settlement model (activate/deactivate a settlement model) | Not supported | Not supported | +| **`/transactions/{id}`** | Retrieve transaction details by `transferId` | Not supported | Not supported | Not supported | + + +
    + +## API Resource `/participants` + +The services provided by the resource `/participants` are primarily used by the Hub Operator for viewing, creating, and updating participant-related details, such as limit (Net Debit Cap), position, or endpoints configured. + +### GET /participants + +Retrieves information about all participants. + +#### Example request + +``` +curl 'http:///participants' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "greenbankfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp", + "created": "\"2021-03-04T14:20:17.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/greenbankfsp" + }, + "accounts": [ + { + "id": 15, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 16, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 21, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + }, + { + "name": "Hub", + "id": "dev1-central-ledger.mojaloop.live/participants/Hub", + "created": "\"2021-03-04T13:37:25.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/Hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 2, + "ledgerAccountType": "HUB_RECONCILIATION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### POST /participants + +Creates a participant in the Hub. + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"name": "payerfsp", "currency": "USD"}' \ + http:///participants +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency that the participant will transact in. | + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-01-12T10:56:30.000Z\"", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 30, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 31, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### GET /participants/limits + +Retrieves limits information for all participants. + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | +| `limit` | no | [String](#string) | Limit type. | + +#### Example request + +``` +curl 'http:///participants/limits' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "name": "payerfsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + }, + { + "name": "payeefsp", + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Response data model + +Each limit in the returned list is applied to the specified participant name and currency in each object. + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### GET /participants/{name} + +Retrieves information about a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp' +``` + +#### Example response + +> **NOTE:** In the example below, `dev1-central-ledger.mojaloop.live` indicates where the Central Ledger service of the Mojaloop Hub is running. This detail will be different in your implementation. + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### PUT /participants/{name} + +Updates participant details (activates/deactivates a participant). + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the participant is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "payerfsp", + "id": "dev1-central-ledger.mojaloop.live/participants/payerfsp", + "created": "\"2021-03-04T13:42:02.000Z\"", + "isActive": 1, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/payerfsp" + }, + "accounts": [ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "createdDate": null, + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### GET /participants/{name}/endpoints + +Retrieves information about the endpoints configured for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/endpoints' +``` + +#### Example response +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_DELETE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/{{partySubIdOrType}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_AUTHORIZATIONS", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/participants/{{requestId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_GET", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/parties/{{partyIdType}}/{{partyIdentifier}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_QUOTES", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRX_REQ_SERVICE", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/transfers/{{transferId}}/error" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_POST", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_PUT", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}" + }, + { + "type": "FSPIOP_CALLBACK_URL_BULK_TRANSFER_ERROR", + "value": "http://dev1-sim-payerfsp-scheme-adapter:4000/bulkTransfers/{{id}}/error" + }, + { + "type": "NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", + "value": "some.email@gmail.com" + }, + { + "type": "SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL", + "value": "some.email@gmail.com" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Type of endpoint. | +| `value` | yes | [String](#string) | Endpoint value. | + +
    + +### POST /participants/{name}/endpoints + +Adds/updates endpoints for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"type": "NET_DEBIT_CAP_ADJUSTMENT_EMAIL", "value": "some.email@org.com"}' + http:///participants/payerfsp/endpoints +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Type of endpoint. | +| `value` | yes | [String](#string) | Endpoint value. | + +#### Example response + +``` +HTTP/1.1 201 Created +Content-Type: application/json +``` + +
    + + +### GET /participants/{name}/limits + +Retrieves limits information for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | +| `limit` | no | [String](#string) | Limit type. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/limits' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 10 + } + } +] +``` + +#### Response data model + +Each limit in the returned list is applied to the specified participant name and currency in each object. + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### PUT /participants/{name}/limits + +Adjusts limits for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": NET_DEBIT_CAP", \ + "value": 10000, \ + "alarmPercentage": 20 + } \ + }' \ + http:///participants/payerfsp/limits +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "currency": "USD", + "limit": { + "type": "NET_DEBIT_CAP", + "value": 10000, + "alarmPercentage": 20 + } +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +
    + +### GET /participants/{name}/positions + +Retrieves the position of a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Query parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | no | [CurrencyEnum](#currencyenum) | The currency of the limit. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/positions' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "currency": "USD", + "value": 150, + "changedDate": "2021-05-10T08:01:38.000Z" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `value` | yes | [Number](#number) | Position value. | +| `changedDate` | yes | [DateTime](#datetime) | Date and time when the position last changed. | + +
    + +### GET /participants/{name}/accounts + +Retrieves the accounts and balances of a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl 'http:///participants/payerfsp/accounts' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "id": 3, + "ledgerAccountType": "POSITION", + "currency": "USD", + "isActive": 1, + "value": 150, + "reservedValue": 0, + "changedDate": "2021-05-10T08:01:38.000Z" + }, + { + "id": 4, + "ledgerAccountType": "SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": -165000, + "reservedValue": 0, + "changedDate": "2021-05-10T14:27:02.000Z" + }, + { + "id": 24, + "ledgerAccountType": "INTERCHANGE_FEE_SETTLEMENT", + "currency": "USD", + "isActive": 1, + "value": 0, + "reservedValue": 0, + "changedDate": "2021-03-30T12:23:06.000Z" + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [Integer](#integer) | Identifier of the ledger account. | +| `ledgerAccountType` | yes | [String](#string) | Type of ledger account. | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the ledger account. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the ledger account is active. Possible values are `1` and `0`. | +| `value` | yes | [Number](#number) | Account balance value. | +| `reservedValue` | yes | [Number](#number) | Value reserved in the account. | +| `changedDate` | yes | [DateTime](#datetime) | Date and time when the ledger account last changed. | + +
    + +### POST /participants/{name}/accounts + +Creates accounts in the Hub. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{"currency": "USD", "type": "HUB_MULTILATERAL_SETTLEMENT"}' \ + http:///participants/payerfsp/accounts +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the participant ledger account. | +| `type` | yes | [String](#string) | Type of ledger account. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "name": "hub", + "id": "dev1-central-ledger.mojaloop.live/participants/hub", + "created": "2021-01-12T10:56:30.000Z", + "isActive": 0, + "links": { + "self": "dev1-central-ledger.mojaloop.live/participants/hub" + }, + "accounts": [ + { + "id": 1, + "ledgerAccountType": "HUB_MULTILATERAL_SETTLEMENT", + "currency": "USD", + "isActive": 0, + "createdDate": "2021-01-12T10:56:30.000Z", + "createdBy": "unknown" + } + ] +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +
    + +### POST /participants/{name}/accounts/{id} + +Records Funds In or Out of a participant account. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | + +#### Example request + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "transferId": "bfd38d14-893f-469d-a6ca-a312a0223949", \ + "externalReference": "660616", \ + "action": "recordFundsIn", \ + "reason": "settlement", \ + "amount": { \ + "amount": "5000", \ + "currency": "USD" \ + }, \ + "extensionList": { \ + "extension": [ \ + { \ + "key": "scheme", \ + "value": "abc" \ + } \ + ] \ + } \ + }' \ + http:///participants/payerfsp/accounts/2 +```` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | +| `externalReference` | yes | [String](#string) | Reference to any external data, such as an identifier from the settlement bank. | +| `action` | yes | [Enum](#enum) | The action performed on the funds. Possible values are: `recordFundsIn` and `recordFundsOutPrepareReserve`. | +| `reason` | yes | [String](#string) | The reason for the FundsIn or FundsOut action. | +| `amount` | yes | [Money](#money) | The FundsIn or FundsOut amount. | +| `extensionList` | no | [ExtensionList](#extensionlist) | Additional details. | + +#### Example response + +```` +HTTP/1.1 202 Accepted +```` + +
    + +### PUT /participants/{name}/accounts/{id} + +Updates a participant account. Currently, updating only the `isActive` flag is supported. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///participants/payerfsp/account/2 +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the participant account is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +``` + +
    + +### PUT /participants/{name}/accounts/{id}/transfers/{transferId} + +Records a transfer as a Funds In or Out transaction for a participant account. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | +| `id` | yes | [Integer](#integer) | Account identifier. | +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"action": "recordFundsOutCommit", "reason": "fix"}' \ + http:///participants/payerfsp/account/2/transfers/bfd38d14-893f-469d-a6ca-a312a0223949 +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `action` | yes | [Enum](#enum) | The FundsOut action performed. Possible values are: `recordFundsOutCommit` and `recordFundsOutAbort`. | +| `reason` | yes | [String](#string) | The reason for the FundsOut action. | + +#### Example response + +``` +HTTP/1.1 202 Accepted +``` + +
    + +### POST /participants/{name}/initialPositionAndLimits + +Adds initial limits and a position for a particular participant. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String(2..30)](#string) | The name of the participant. | + +#### Example request + +```` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "currency": "USD", \ + "limit": { \ + "type": "NET_DEBIT_CAP", \ + "value": "10000" \ + }, \ + "initialPosition": 0 \ + }' \ + http:///participants/payerfsp/initialPositionAndLimits +```` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | +| `initialPosition` | no | [Number](#number) | Initial Position. | + +#### Example response + +``` +HTTP/1.1 201 Created +``` + +
    + +## API Resource `/settlementModels` + +The services provided by the resource `/settlementModels` are used by the Hub Operator for creating, updating, and viewing settlement models. + +### GET /settlementModels + +Retrieves information about all settlement models. + +#### Example request + +``` +curl 'http:///settlementModels' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "settlementModelId": 1, + "name": "DEFERREDNETUSD", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true + }, + { + "settlementModelId": 4, + "name": "DEFERREDNETEUR", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "EUR", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "SETTLEMENT", + "autoPositionReset": true + } +] +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active.| +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +### POST /settlementModels + +Creates a settlement model. + +#### Example request + +``` +curl -X POST -H "Content-Type: application/json" \ + -d '{ \ + "name": "DEFERREDNET", \ + "settlementGranularity": "NET", \ + "settlementInterchange": "MULTILATERAL", \ + "settlementDelay": "DEFERRED", \ + "requireLiquidityCheck": true, \ + "ledgerAccountType": "POSITION", \ + "autoPositionReset": true \ + }' \ + http:///settlementModels +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | Settlement model name. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `settlementAccountType` | yes | [String](#string) | A special type of ledger account into which settlements should be settled. Possible values are:
    `SETTLEMENT`: A settlement account for the principal value of transfers (that is, the amount of money that the Payer wants the Payee to receive).
    `INTERCHANGE_FEE_SETTLEMENT`: A settlement account for the fees associated with transfers. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +#### Example response + +``` +HTTP/1.1 201 Created +``` + +
    + +### GET /settlementModels/{name} + +Retrieves information about a particular settlement model. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the settlement model. | + +#### Example request + +``` +curl 'http:///settlementModels/DEFERREDNET' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +### PUT /settlementModels/{name} + +Updates a settlement model (activates/deactivates a settlement model). + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the settlement model. | + +#### Example request + +``` +curl -X PUT -H "Content-Type: application/json" \ + -d '{"isActive": true}' \ + http:///settlementModels/DEFERREDNET +``` + +#### Request data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model is active. | + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "settlementModelId": 1, + "name": "DEFERREDNET", + "isActive": true, + "settlementGranularity": "NET", + "settlementInterchange": "MULTILATERAL", + "settlementDelay": "DEFERRED", + "currency": "USD", + "requireLiquidityCheck": true, + "ledgerAccountTypeId": "POSITION", + "autoPositionReset": true +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds. | +| `autoPositionReset` | yes | [Boolean](boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +
    + +## API Resource `/transactions` + +The services provided by the resource `/transactions` are used by the Hub Operator for retrieving transfer details. + +### GET /transactions/{id} + +Retrieves information about a particular transaction. + +#### Path parameters + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [UUID](#uuid) | Transfer identifier. | + +#### Example request + +``` +curl 'http:///transactions/85feac2f-39b2-491b-817e-4a03203d4f14' +``` + +#### Example response + +``` +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "transactionRequestId": "a8323bc6-c228-4df2-ae82-e5a997baf898", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoneyAbc" + }, + "name": "John Doe", + "personalInfo": { + "complexName": { + "firstName": "John", + "middleName": "William", + "lastName": "Doe" + }, + "dateOfBirth": "1966-06-16" + } + }, + "payer": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "987654321", + "fspId": "MobileMoneyXyz" + }, + "name": "Jane Doe", + "personalInfo": { + "complexName": { + "firstName": "Mary", + "middleName": "Jane", + "lastName": "Doe" + }, + "dateOfBirth": "1975-05-15" + } + }, + "amount": { + "currency": "USD", + "amount": "50" + }, + "transactionType": { + "scenario": "DEPOSIT", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + } +} +``` + +#### Response data model + +| Name | Required | Type | Description | +|---|---|--|--| +| `quoteId` | | [UUID](#uuid) | Quote identifier. | +| `transactionId` | | [UUID](#uuid) | Transaction identifier. | +| `transactionRequestId` | | [String](#string) | Identifies an optional previously-sent transaction request. | +| `payee` | | [Party](#party) | Payee details. | +| `payer` | | [Party](#party) | Payer details. | +| `amount` | | [Money](#money) | Transaction amount. | +| `transactionType` | | [TransactionType](#transactiontype) | Transaction details. | +| `note` | | [String](#string) | A memo that will be attached to the transaction. | +| `extensionList` | | [ExtensionList](#extensionlist) | Additional details. | + +
    + +## Data models used by the API + +### Format + +For details on the formats used for element data types used by the API, see section [Element Data Type Formats](../fspiop/logical-data-model#element-data-type-formats) in the Mojaloop FSPIOP API Definition. + +### Element Data Type Formats + +This section defines element data types used by the API. + +#### Amount + +For details, see section [Amount](../fspiop/logical-data-model#amount) in the Mojaloop FSPIOP API Definition. + +#### Boolean + +A `"true"` or `"false"` value. + +#### DateTime + +For details, see section [DateTime](../fspiop/logical-data-model#datetime) in the Mojaloop FSPIOP API Definition. + +#### Enum + +For details, see section [Enum](../fspiop/logical-data-model#enum) in the Mojaloop FSPIOP API Definition. + +#### Integer + +For details, see section [Integer](../fspiop/logical-data-model#integer) in the Mojaloop FSPIOP API Definition. + +#### Number + +The API data type `Number` is a an arbitrary-precision, base-10 decimal number value. + +#### String + +For details, see section [String](../fspiop/logical-data-model#string) in the Mojaloop FSPIOP API Definition. + +#### UUID + +For details, see section [UUID](../fspiop/logical-data-model#uuid) in the Mojaloop FSPIOP API Definition. + +
    + +## Element Definitions + +This section defines element types used by the API. + +#### IsActive + +Data model for the element **IsActive**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not a ledger account / participant is active. Possible values are `1` (active) and `0` (not active). | + +#### IsActiveBoolean + +Data model for the element **IsActiveBoolean**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not an account / participant / settlement model is active. | + +#### CurrencyEnum + +For details, see section [Currency](../fspiop/logical-data-model#currencycode-enum) enum in the Mojaloop FSPIOP API Definition. + +#### RequireLiquidityCheck + +Data model for the element **RequireLiquidityCheck**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `requireLiquidityCheck` | yes | [Boolean](#boolean) | A flag to indicate whether or not a settlement model requires liquidity check. | + +#### Self + +Data model for the element **Self**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `self` | yes | [String](#string) | Fully qualified domain name combined with the `fspId` of the participant. | + +#### SettlementDelay + +Data model for the element **SettlementDelay**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementDelay` | yes | [Enum](#enum) of String | Specifies if settlement happens immediately after a transfer has completed or with a delay. Allowed values for the enumeration are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule. | + +#### SettlementGranularity + +Data model for the element **SettlementGranularity**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementGranularity` | yes | [Enum](#enum) of String | Specifies whether transfers are settled one by one or as a batch. Allowed values for the enumeration are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time. | + +#### SettlementInterchange + +Data model for the element **SettlementInterchange**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementInterchange` | yes | [Enum](#enum) of String | Specifies the type of settlement arrangement between parties. Allowed values for the enumeration are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party. | + +
    + +## Complex types + +#### Accounts + +The list of ledger accounts configured for the participant. For details on the account object, see [IndividualAccount](#individualaccount). + +#### ErrorInformation + +For details, see section [ErrorInformation](../fspiop/logical-data-model#errorinformation) in the Mojaloop FSPIOP API Definition. + +#### ErrorInformationResponse + +Data model for the complex type object that contains an optional element [ErrorInformation](#errorinformation) used along with 4xx and 5xx responses. + +#### Extension + +For details, see section [Extension](../fspiop/logical-data-model#extension) in the Mojaloop FSPIOP API Definition. + +#### ExtensionList + +For details, see section [ExtensionList](../fspiop/logical-data-model#extensionlist) in the Mojaloop FSPIOP API Definition. + +#### IndividualAccount + +Data model for the complex type **IndividualAccount**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `id` | yes | [Integer](#integer) | Identifier of the ledger account. | +| `ledgerAccountType` | yes | [String](#string) | Type of the ledger account (for example, POSITION). | +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency of the account. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the ledger account is active. Possible values are `1` and `0`. | +| `createdDate` | yes | [DateTime](#datetime) | Date and time when the ledger account was created. | +| `createdBy` | yes | [String](#string) | The entity that created the ledger account. | + +#### Limit + +Data model for the complex type **Limit**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | Limit type. | +| `value` | yes | a positive [Number](#number) | Limit value. | + +#### Money + +For details, see section [Money](../fspiop/logical-data-model#mondey) in the Mojaloop FSPIOP API Definition. + +#### Participant + +Data model for the complex type **Participant**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `name` | yes | [String](#string) | The name of the participant. | +| `id` | yes | [String](#string) | The identifier of the participant in the form of a fully qualified domain name combined with the participant's `fspId`. | +| `created` | yes | [DateTime](#datetime) | Date and time when the participant was created. | +| `isActive` | yes | [Integer(1)](#integer) | A flag to indicate whether or not the participant is active. Possible values are `1` and `0`. | +| `links` | yes | [Self](#self) | List of links for a Hypermedia-Driven RESTful Web Service. | +| `accounts` | yes | [Accounts](#accounts) | The list of ledger accounts configured for the participant. | + +#### ParticipantFunds + +Data model for the complex type **ParticipantFunds**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `transferId` | yes | [UUID](#uuid) | Transfer identifier. | +| `externalReference` | yes | [String](#string) | Reference to any external data, such as an identifier from the settlement bank. | +| `action` | yes | [Enum](#enum) | The action performed on the funds. Possible values are: `recordFundsIn` and `recordFundsOutPrepareReserve`. | +| `reason` | yes | [String](#string) | The reason for the FundsIn or FundsOut action. | +| `amount` | yes | [Money](#money) | The FundsIn or FundsOut amount. | +| `extensionList` | no | [ExtensionList](#extensionlist) | Additional details. | + +#### ParticipantLimit + +Data model for the complex type **ParticipantLimit**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | The type of participant limit (for example, `NET_DEBIT_CAP`.) | +| `value` | yes | [Number](#number) | The value of the limit that has been set for the participant. | +| `alarmPercentage` | yes | [Number](#number) | An alarm notification is triggered when a pre-specified percentage of the limit is reached. Specifying an `alarmPercentage` is optional. If not specified, it will default to 10 percent, expressed as `10`. | + +#### ParticipantsNameEndpointsObject + +Data model for the complex type **ParticipantsNameEndpointsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `type` | yes | [String](#string) | The endpoint type. | +| `value` | yes | [String](#string) | The endpoint value. | + +#### ParticipantsNameLimitsObject + +Data model for the complex type **ParticipantsNameLimitsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the participant. | +| `limit` | yes | [ParticipantLimit](#participantlimit) | The limit configured for the participant. | + +#### Party + +For details, see section [Party](../fspiop/logical-data-model#party) in the Mojaloop FSPIOP API Definition. + +#### PartyComplexName + +For details, see section [PartyComplexName](../fspiop/logical-data-model#partycomplexname) in the Mojaloop FSPIOP API Definition. + +#### PartyIdInfo + +For details, see section [PartyIdInfo](../fspiop/logical-data-model#partyidinfo) in the Mojaloop FSPIOP API Definition. + +#### PartyPersonalInfo + +For details, see section [PartyPersonalInfo](../fspiop/logical-data-model#partypersonalinfo) in the Mojaloop FSPIOP API Definition. + +#### RecordFundsOut + +Data model for the complex type **RecordFundsOut**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `action` | yes | [Enum](#enum) | The FundsOut action performed. Possible values are: `recordFundsOutCommit` and `recordFundsOutAbort`. | +| `reason` | yes | [String](#string) | The reason for the FundsOut action. | + +#### Refund + +Data model for the complex type **Refund**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `originalTransactionId` | yes | [UUID](#uuid) | Reference to the original transaction id that is requested to be refunded. | +| `refundReason` | no | [String(1-128)](#string) | Free text indicating the reason for the refund. | + +#### SettlementModelsObject + +Data model for the complex type **SettlementModelsObject**. + +| Name | Required | Type | Description | +|---|---|--|--| +| `settlementModelId` | yes | [Integer](#integer) | Settlement model identifier. | +| `name` | yes | [String](#string) | Settlement model name. | +| `isActive` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model is active. | +| `settlementGranularity` | yes | [String](#string) | Specifies whether transfers are settled one by one or as a batch. Possible values are:
    `GROSS`: Settlement is executed after each transfer is completed, that is, there is a settlement transaction that corresponds to every transaction.
    `NET`: A group of transfers is settled together in a single settlement transaction, with each participant settling the net of all transfers over a given period of time.| +| `settlementInterchange` | yes | [String](#string) | Specifies the type of settlement arrangement between parties. Possible values are:
    `BILATERAL`: Each participant settles its obligations with each other separately, and the scheme is not a party to the settlement.
    `MULTILATERAL`: Each participant settles with the scheme for the net of its obligations, rather than settling separately with each other party.| +| `settlementDelay` | yes | [String](#string) | Specifies if settlement happens immediately after a transfer has completed or with a delay. Possible values are:
    `IMMEDIATE`: Settlement happens immediately after a transfer has completed.
    `DEFERRED`: Settlement is managed by the Hub operator on-demand or via a schedule.| +| `currency` | yes | [CurrencyEnum](#currencyenum) | The currency configured for the settlement model. | +| `requireLiquidityCheck` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model requires liquidity check. | +| `ledgerAccountTypeId` | yes | [String](#string) | Type of ledger account. Possible values are:
    `INTERCHANGE_FEE`: Tracks the interchange fees charged for transfers.
    `POSITION`: Tracks how much a DFSP owes or is owed.
    `SETTLEMENT`: The DFSP's Settlement Bank Account mirrored in the Hub. Acts as a reconciliation account and mirrors the movement of real funds.| +| `autoPositionReset` | yes | [Boolean](#boolean) | A flag to indicate whether or not the settlement model requires the automatic reset of the position. | + +#### TransactionType + +For details, see section [TransactionType](../fspiop/logical-data-model#transactiontype) in the Mojaloop FSPIOP API Definition. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/assets/figure1-platforms-layout.svg b/website/versioned_docs/v1.0.1/api/assets/figure1-platforms-layout.svg new file mode 100644 index 000000000..8a12de358 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/assets/figure1-platforms-layout.svg @@ -0,0 +1,3 @@ + + +
    CA
    CA
    ALS
    ALS
    FSP-1
    FSP-1
    FSP-2
    FSP-2
    Switch
    Switch
    FSP-3
    FSP-3
    FSP-4
    FSP-4
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Issuer: CN=CA
    O=CA
    Subject: CN=CA
    O=CA
    Issuer: CN=CA...
    Legend:
    Solid lines indicate TLS-secured communication.
    Dashed lines indicate certificate owner.
    Legend:...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-1-http-timeout.png b/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-1-http-timeout.png new file mode 100644 index 000000000..9d3faf74e Binary files /dev/null and b/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-1-http-timeout.png differ diff --git a/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-2-callback-timeout.png b/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-2-callback-timeout.png new file mode 100644 index 000000000..04f5da996 Binary files /dev/null and b/website/versioned_docs/v1.0.1/api/assets/scheme-rules-figure-2-callback-timeout.png differ diff --git a/website/versioned_docs/v1.0.1/api/assets/sequence-diagram-figure-1.png b/website/versioned_docs/v1.0.1/api/assets/sequence-diagram-figure-1.png new file mode 100644 index 000000000..53215785d Binary files /dev/null and b/website/versioned_docs/v1.0.1/api/assets/sequence-diagram-figure-1.png differ diff --git a/website/versioned_docs/v1.0.1/api/fspiop/README.md b/website/versioned_docs/v1.0.1/api/fspiop/README.md new file mode 100644 index 000000000..eed734703 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/README.md @@ -0,0 +1,19 @@ +# FSPIOP API + +The Open API for FSP Interoperability Specification includes the following documents: + +### Logical Documents +* [Logical Data Model](#logical-data-model) +* [Generic Transaction Patterns](#generic-transaction-patterns) +* [Use Cases](#use-cases) + +### Asynchronous REST Binding Documents +* [API Definition](#api-definition) +* [Central Ledger API](#central-ledger-api) +* [JSON Binding Rules](#json-binding-rules) +* [Scheme Rules](#scheme-rules) + +### Data Integrity, Confidentiality, and Non-Repudiation +* [PKI Best Practices](#pki-best-practices) +* [Signature](#signature) +* [Encryption](#encryption) diff --git a/website/versioned_docs/v1.0.1/api/fspiop/definitions.md b/website/versioned_docs/v1.0.1/api/fspiop/definitions.md new file mode 100644 index 000000000..6c2e3c8f1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/definitions.md @@ -0,0 +1,10 @@ +# FSPIOP API + + +## Versions + +|Version|Date|Change Description| +|---|---|---| +|[1.0](./v1.0/api-definition)|2018-03-13|Initial version| +|[1.1](./v1.1/api-definition)|2020-05-19|1. This version contains a new option for a Payee FSP to request a commit notification from the Switch. The Switch should then send out the commit notification using the new request **PATCH /transfers/**_{ID}_. The option to use commit notification replaces the previous option of using the ”Optional Additional Clearing Check”. The section describing this has been replaced with the new section ”Commit Notification”. As the **transfers** resource has been updated with the new **PATCH** request, this resource has been updated to version 1.1. As part of adding the possibility to use a commit notification, the following changes has been made:
    a. PATCH has been added as an allowed HTTP Method in Section 3.2.2. b. The call flow for **PATCH** is described in Section 3.2.3.5.
    c. Table 6 in Section 6.1.1 has been updated to include **PATCH** as a possible HTTP Method.
    d. Section 6.7.1 contains the new version of the **transfers** resource.
    e. Section 6.7.2.6 contains the process for using commit notifications
    f. Section 6.7.3.3 describes the new **PATCH /transfers**/_{ID}_ request.

    2. In addition to the changes mentioned above regarding the commit notification, the following non-API affecting changes has been made:
    a. Updated Figure 6 as it contained a copy-paste error.
    b. Added Section 6.1.2 to describe a comprehensive view of the current version for each resource.
    c. Added a section for each resource to be able to see the resource version history.
    d. Minor editorial fixes.

    3. The descriptions for two of the HTTP Header fields in Table 1 have been updated to add more specificity and context
    a. The description for the **FSPIOP-Destination** header field has been updated to indicate that it should be left empty if the destination is not known to the original sender, but in all other cases should be added by the original sender of a request.
    b. The description for the **FSPIOP-URI** header field has been updated to be more specific.

    4. The examples used in this document have been updated to use the correct interpretation of the Complex type ExtensionList which is defined in Table 84. This doesn’t imply any change as such.
    a. Listing 5 has been updated in this regard.

    5. The data model is updated to add an optional ExtensionList element to the **PartyIdInfo** complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 103 has been updated. For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.

    6. A new Section 6.5.2.2 is added to describe the process involved in the rejection of a quote.

    7. A note is added to Section 6.7.4.1 to clarify the usage of ABORTED state in **PUT /transfers/**_{ID}_ callbacks.| +|**1.1.1**|2021-09-22|This document version only adds information about optional HTTP headers regarding tracing support in [Table 2](#table-2), see _Distributed Tracing Support for OpenAPI Interoperability_ for more information. There are no changes in any resources as part of this version.| \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/generic-transaction-patterns.md b/website/versioned_docs/v1.0.1/api/fspiop/generic-transaction-patterns.md new file mode 100644 index 000000000..8e68d41de --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/generic-transaction-patterns.md @@ -0,0 +1,1851 @@ +# Generic Transaction Patterns + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document introduces the four generic transaction patterns that are supported in a logical version of the Interoperability API. Additionally, all logical services that are part of the API are presented on a high-level. + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](#) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Logical API Services + +The Interoperability API consists of a number of logical API resources. Each resource defines one or more services that clients can use to connect to a server that has implemented the API. This section introduces these services. + +**Note:** API services identified in this section may not be relevant to (and therefore may not appear in) the generic transaction patterns identified in [Generic Transaction Patterns](#generic-transaction-patterns). + +For example, some services are used for provisioning of information, are part of error cases, or are for retrieving information that is not necessary in a generic transaction pattern. + +
    + +### Common Functionality + +This section introduces functionality that is used by more than one logical API resource or service. + +#### Party Addressing + +A Party is an entity such as an individual, a business, an organization that has a financial account in one of the FSPs. A party is addressed by a combination of an _ID type_ and an _ID_, and possibly also a _subtype_ or _sub ID_. Some examples of _ID type_ and _ID_ combinations are: + +- _ID type_: **MSISDN**, _ID_: **+123456789** + +- _ID type_: **Email**, _ID_: **john@doe.com** + +#### Interledger + +The API includes basic support for the Interledger Protocol (ILP) by defining a concrete implementation of the Interledger Payment Request protocol[1](https://interledger.org/rfcs/0011-interledger-payment-request)(ILP) in the logical API resources **Quotes** and **Transfers**. More details of the ILP protocol can be found on the Interledger project website[2](https://interledger.org), in the Interledger Whitepaper[3](https://interledger.org/interledger.pdf), and in the Interledger architecture specification[4](https://interledger.org/rfcs/0001-interledger-architecture). + +
    + +### API Resource Participants + +In the API, a _Participant_ is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource **Participants** is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Lookup Participant Information + +The logical API service request `Lookup Participant Information` is used from an FSP to request from another system, which could be another FSP or a common system, information regarding in which FSP a counterparty in an interoperable financial transaction is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +##### Create Participant Information + +The logical API service request `Create Participant Information` is used to provision information regarding in which FSP a party is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +##### Create Bulk Participant Information + +The logical API service request `Create Bulk Participant Information` is used to provision information regarding in which FSP one or more parties are located. + +- Successful response: [Return Bulk Participant Information](#return-bulk-participant-information) + +- Error response: [Return Bulk Participant Information Error](#return-bulk-participant-information-error) + +##### Delete Participant Information + +The logical API service request `Delete Participant Information` is used to remove information regarding in which FSP a party is located. + +- Successful response: [Return Participant Information](#return-participant-information) + +- Error response: [Return Participant Information Error](#return-participant-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Participant Information + +The logical API service response `Return Participant Information` is used to return information from the requests [Lookup Participant Information](#lookup-participant-information), [Create Participant Information](#create-participant-information) and [Delete Participant Information](#delete-participant-information). + +##### Return Bulk Participant Information + +The logical API service response `Return Bulk Participant Information` is used to return information from the request [Create Bulk Participant Information](#create-bulk-participant-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Participant Information Error + +The logical API service error response `Return Participant Information Error` is used to return error information regarding the requests [Lookup Participant Information](#lookup-participant-information), [Create Participant Information](#create-participant-information) and [Delete Participant Information](#delete-participant-information). + +##### Return Bulk Participant Information Error + +The logical API service error response `Return Bulk Participant Information Error` is used to return information from the request [Create Bulk Participant Information](#create-bulk-participant-information). + +
    + +### API Resource Parties + +In the API, a _Party_ is an individual, a business, an organization, or a similar entity, that has a financial account in one of the FSPs. The primary purpose of the logical API resource **Parties** is for FSPs to ascertain information regarding a counterparty in an interoperable financial transaction, such as name and birth date of the Party. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Lookup Party Information + +The logical API service request `Lookup Party Information` is used by an FSP to request from another FSP information regarding a counterparty in an interoperable financial transaction. + +- Successful response: [Return Party Information](#return-party-information). + +- Error response: [Return Party Information Error](#return-party-information-error). + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Party Information + +The logical API service response `Return Party Information` is used to return information from the request [Lookup Party Information](#lookup-party-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Party Information Error + +The logical API service error response `Return Party Information Error` is used to return error information regarding the request [Lookup Party Information](#lookup-party-information). + +
    + +### API Resource Transaction Requests + +In the API, a _Transaction Request_ is a request from a Payee to a Payer to transfer electronic funds to the Payee, which the Payer can accept or reject. The primary purpose of the logical API resource **Transaction Requests** is for a Payee FSP to send the request to transfer to the Payer FSP. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Transaction Request + +The logical API service request `Perform Transaction Request` is used to send a Transaction Request from a Payee FSP to the Payer FSP; that is, to ask if a Payer will accept or reject a transaction from the Payer to the Payee. + +- Successful response: [Return Transaction Request Information](#return-transaction-request-information) + +- Error response: [Return Transaction Request Information Error](#return-transaction-request-information-error) + +##### Retrieve Transaction Request Information + +The logical API service request `Retrieve Transaction Request Information` is used from a Payee FSP to a Payer FSP to request information regarding a previously-sent Transaction Request. + +- Successful response: [Return Transaction Request Information](#return-transaction-request-information) + +- Error response: [Return Transaction Request Information Error](#return-transaction-request-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transaction Request Information + +The logical API service response `Return Transaction Request Information` is used to return information from the requests [Perform Transaction Request](#perform-transaction-request) or [Retrieve Transaction Request Information](#retrieve-transaction-request-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transaction Request Information Error + +The logical API service error response `Return Transaction Request Information Error` is used to return error information regarding the requests [Perform Transaction Request](#perform-transaction-request) or [Retrieve Transaction Request Information](#retrieve-transaction-request-information). + +
    + +### API Resource Quotes + +In the API, a _Quote_ is the price for performing an interoperable financial transaction from the Payer FSP to the Payee FSP. The primary purpose of the logical API resource **Quotes** is for a Payer FSP to request a Payee FSP to calculate the Payee FSP's part of the quote. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Calculate Quote + +The logical API service request `Calculate Quote` is used from a Payer FSP to ask a Payee FSP to calculate the Payee FSP's part of the quote to perform an interoperable financial transaction. The Payee FSP should also create the ILP Packet and the condition (see [Interledger](#interledger) section for links to more information) when receiving the request. + +- Successful response: [Return Quote Information](#return-quote-information) + +- Error response: [Return Quote Information Error](#return-quote-information-error) + +
    + +##### Retrieve Quote Information + +The logical API service request `Retrieve Quote Information` is used by a Payer FSP to request that a Payee FSP ask for information regarding a previously-sent [Calculate Quote](#calculate-quote) request. + +- Successful response: [Return Quote Information](#return-quote-information) + +- Error response: [Return Quote Information Error](#return-quote-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Quote Information + +The logical API service response `Return Quote Information` is used to return information from the requests [Calculate Quote](#calculate-quote) or [Retrieve Quote Information](#retrieve-quote-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Quote Information Error + +The logical API service error response `Return Quote Information Error` is used to return error information regarding the requests [Calculate Quote](#calculate-quote) or [Retrieve Quote Information](#retrieve-quote-information). + +
    + +### API Resource Authorizations + +In the API, an _Authorization_ is an approval from a Payer to perform an interoperable financial transaction by entering the applicable credentials in a Payee FSP system. An example where this kind of approval is used, is when a Payer is using an ATM that is managed by another FSP. The primary purpose of the logical API resource **Authorizations** is for a Payer FSP to request a Payee FSP to ask the Payer to enter the credentials. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Authorization + +The logical API service request `Perform Authorization` is used from a Payer FSP to ask a Payee FSP to enter the applicable credentials to approve an interoperable financial transaction. + +- Successful response: [Return Authorization Result](#return-authorization-result) + +- Error response: [Return Authorization Error](#return-authorization-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Authorization Result + +The logical API service response `Return Authorization Result` is used to return information from the request [Perform Authorization](#perform-authorization). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Authorization Error + +The logical API service error response `Return Authorization Error` is used to return error information regarding the request [Perform Authorization](#perform-authorization). + +
    + +### API Resource Transfers + +In the API, a _Transfer_ is hop-to-hop ILP (see [Interledger](#interledger) section for links to more information) transfer of funds. + +The transfer also contains information regarding the end-to-end interoperable financial transaction. The primary purpose of the logical API resource **Transfers** is for an FSP or Switch to request that the next entity in the chain of the ILP Payment perform the transfer involved in the interoperable financial transaction. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Transfer + +The logical API service request `Perform Transfer` is used by an FSP or Switch to request the next entity in the chain of the ILP Payment to reserve the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +##### Retrieve Transfer Information + +The logical API service request `Retrieve Transfer Information` is used by an FSP or Switch to request the next entity in the chain of the ILP Payment for information regarding the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transfer Information + +The logical API service response `Return Transfer Information` is used to return information from the requests [Perform Transfer](#perform-transfer) or [Retrieve Transfer Information](#retrieve-transfer-information). On receiving the [Return Transfer Information](#return-transfer-information) response, the FSP or Switch should validate the fulfilment (see [Interledger](#interledger) section for links to more information) and commit the reserved transfer if the validation is successful. + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transfer Information Error + +The logical API service error response `Return Transfer Information Error` is used to return error information regarding the requests [Perform Transfer](#perform-transfer) or [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +### API Resource Transactions + +In the API, a _Transaction_ is an end-to-end interoperable financial transaction between the Payer FSP and Payee FSP. The primary purpose of the logical API resource **Transactions** is for a Payer FSP to request end-to-end information from the Payee FSP regarding an interoperable financial transaction; for example, in order to get a token or code that the Payer can use to redeem a service or product. + +### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Retrieve Transaction Information + +The logical API service request `Retrieve Transaction Information` is used by a Payer FSP to request that a Payee FSP get information regarding a previously-performed interoperable financial transaction (by using the logical API resource **Transfers**, see [API Resource Tarnsfers](#api-resource-transfers) section). + +- Successful response: [Return Transfer Information](#return-transfer-information) + +- Error response: [Return Transfer Information Error](#return-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Transaction Information + +The logical API service response`*Return Transaction Information` is used to return information from the request [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Transaction Information Error + +The logical API service error response `Return Transaction Information Error` is used to return error information regarding the request [Retrieve Transfer Information](#retrieve-transfer-information). + +
    + +### API Resource Bulk Quotes + +In the API, a _Bulk Quote_ is a collection of individual quotes (see [API Resource Quotes](#api-resource-quotes) section for information regarding a single quote) for performing more than one interoperable financial transaction from the Payer FSP to the Payee FSP. + +The primary purpose of the logical API resource **Bulk Quotes** is for a Payer FSP to request a Payee FSP to calculate the Payee FSP's part of the bulk quote. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Calculate Bulk Quote + +The logical API service request `Calculate Bulk Quote` is used by a Payer FSP to request that a Payee FSP calculate the Payee FSP's part of the quotes to perform more than one interoperable financial transaction. + +The Payee FSP should also create the ILP Packet and the condition (see [Interledger](#interledger) section for links to more information) per quote when receiving the request. + +- Successful response: [Return Bulk Quote Information](#return-bulk-quote-information) + +- Error response: [Return Bulk Quote Information Error](#return-bulk-quote-information-error) + +##### Retrieve Bulk Quote Information + +The logical API service request `Retrieve Bulk Quote Information` is used by a Payer FSP to request that a Payee FSP ask for information regarding a previously-sent [Calculate Bulk Quote](#calculate-bulk-quote) request. + +- Successful response: [Return Bulk Quote Information](#return-bulk-quote-information) + +- Error response: [Return Bulk Quote Information Error](#return-bulk-quote-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Bulk Quote Information + +The logical API service response `Return Bulk Quote Information` is used to return information from the requests [Calculate Bulk Quote](#calculate-bulk-quote) or [Retrieve Bulk Quote Information](#retrieve-bulk-quote-information). + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Bulk Quote Information Error + +The logical API service error response `Return Bulk Quote Information Error` is used to return error information regarding the requests [Calculate Bulk Quote](#calculate-bulk-quote) or [Retrieve Bulk Quote Information](#retrieve-bulk-quote-information). + +
    + +### API Resource Bulk Transfers + +In the API, a _Bulk Transfer_ is a collection of hop-to-hop ILP (see [Interledger.](#interledger)section for links to more information) transfers of funds. The transfers also contain information regarding the end-to-end interoperable financial transactions. + +The primary purpose of the logical API resource **Bulk Transfers** is to enable an FSP or Switch to request that the next entity in the chain of the ILP Payment perform the transfers involved in the interoperable financial transactions. + +#### Requests + +This section identifies the logical API service requests that can be sent from a client to a server. + +##### Perform Bulk Transfer + +The logical API service request `Perform Bulk Transfer` is used by an FSP or Switch to request that the next entity in the chain of the ILP Payment reserve the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Bulk Transfer Information](#return-bulk-transfer-information) + +- Error response: [Return Bulk Transfer Information Error](#return-bulk-transfer-information-error) + + +##### Retrieve Bulk Transfer Information + +The logical API service request `Retrieve Bulk Transfer Information` is used from an FSP or Switch to request that the next entity in the chain of the ILP Payment for information regarding the transfer involved in an interoperable financial transaction. + +- Successful response: [Return Bulk Transfer Information](#return-bulk-transfer-information) + +- Error response: [Return Bulk Transfer Information Error](#return-bulk-transfer-information-error) + +
    + +#### Responses + +This section identifies the logical API service responses that can be sent back to a client from a server. + +##### Return Bulk Transfer Information + +The logical API service response `Return Bulk Transfer Information` is used to return information from the requests [Perform Bulk Transfer](#perform-bulk-transfer) or [Retrieve Bulk Transfer Information](#retrieve-bulk-transfer-information). + +On receiving the response **Return Bulk Transfer Information**, the FSP or Switch should validate the fulfilments (see [Interledger](#interledger) section for links to more information) and commit the reserved transfers if the validations are successful. + +
    + +#### Error Responses + +This section identifies the logical API service error responses that can be sent back to a client from a server. + +##### Return Bulk Transfer Information Error + +The logical API service error response `Return Bulk Transfer Information Error` is used to return error information regarding the requests [Perform Bulk Transfer](#perform-bulk-transfer) or [Retrieve Bulk Transfer Information](#retrieve-bulk-transfer-information). + +
    + +## Generic Transaction Patterns + +This section provides information about the three primary transaction patterns defined in the Interoperability API: + +- [Payer-Initiated Transaction](#payer-initiated-transaction) + +- [Payee-Initiated Transaction](#payee-initiated-transaction) + +- [Bulk Transaction](#bulk-transaction) + +Each transaction pattern defines how funds can be transferred from a Payer located in one Financial Service Provider (FSP) to a Payee located in another FSP. + +Both the [Payer-Initiated Transaction](#payer-initiated-transaction) and the [Payee-Initiated Transaction](#payee-initiated-transaction) patterns are intended for a single transfer of funds from one Payer to one Payee. The significant difference between the two patterns is in which of the participants in the transaction is responsible for the initiation of the transaction. + +The [Bulk Transaction](#bulk-transaction) pattern should be used when a single Payer would like to transfer funds to multiple Payees, possibly in different FSPs, in a single transaction. + +This section also provides information about _Payee-Initiated Transaction using OTP_. which is an alternative to the [Payee-Initiated Transaction](#payee-initiated-transaction). + +Additionally, the section provides high-level information about all logical services that are part of the API. + +
    + +### Payer-Initiated Transaction + +In a _Payer-Initiated Transaction_, the `Payer` initiates the transaction. + +#### Business Process Pattern Description + +The _Payer-Initiated Transaction_ pattern should be used whenever a `Payer` would like to transfer funds to another party whose account is not located in the same FSP. + +In most implementations, `Payee` involvement is limited to receiving a notification in the event of a successful transaction. Exceptions in which the Payee is more involved are: + +- In countries that require the `Payee` to confirm receipt of funds. + +- Cases in which the `Payee` should accept the terms of the transaction (for example, Agent-Initiated Cash-In). + +#### Participants and Roles + +The actors in a _Payer-Initiated Transaction_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + + +The intermediary objects used in a _Payer-Initiated Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + + +#### Business Process Sequence Diagram + +Figure 1 shows the UML sequence diagram for a _Payer-Initiated Transaction_. + +{% uml src="assets/diagrams/sequence/figure64a.plantuml" %} +{% enduml %} +**Figure 1 -- Payer-Initiated Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in [Figure 1](#business-process-sequence-diagram). + +##### Lookup Counterparty + +1. **Description** + + The `Payer` initiates the transaction by requesting to send funds to a `Payee`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +2. **Description** + + The `Payer FSP` tries to find the `Payee` within the FSP system. Because the `Payee` cannot be found in the `Payer FSP` system, the request [Lookup Party Information](#lookup-party-information) is sent by the `Payer FSP` to the optional `Switch` to get information regarding the `Payee`, including in which FSP the `Payee` is located. + + **Assumptions** + + The Payee is assumed to be in a different FSP than the `Payer`. Also, a `Switch` is assumed to be placed between the `Payer FSP` and the `Payee FSP` to route the messages between FSPs. The `Switch` is optional in the process, as the request [Lookup Party Information](#lookup-party-information) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. As the `Payer FSP` should not know in which FSP the `Payee` is located if there is no `Switch` present, the request might need to be sent to more than one FSP. + +3. **Description** + + The `Switch` receives the request [Lookup Party Information](#lookup-party-information). The `Switch` then tries to find in which FSP the `Payee` is located by sending the request [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + + **Assumptions** + + An `Account Lookup System` is assumed to exist in a different server than the `Switch`. It is possible that the `Account Lookup System` is in the same system as the `Switch`. + +4. **Description** + + The `Account Lookup System` receives the request [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payee` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the Switch about which FSP the `Payee` is located in. + + **Assumptions** + + The `Payee` can be found by the `Account Lookup System`. + +5. **Description** + + The `Switch` receives the response [Return Participant Information](#return-participant-information). As the `Switch` now knows in which FSP the `Payee` is located, the `Switch` sends the request [Lookup Participant Information](#lookup-participant-information) to the `Payee FSP` to get more information about the `Payee`. + + **Assumptions** + + None. + +6. **Description** + + The `Payee FSP` receives the request [Lookup Participant Information](#lookup-participant-information). The `Payee FSP` then does an internal lookup to find more information regarding the `Payee` and sends the response [Return Participant Information](#return-participant-information) to the `Switch`. + + **Assumptions** + + None. + +7. **Description** + + The `Switch` receives the response [Return Party Information](#return-party-information). The `Switch` then routes the [Return Party Information](#return-party-information) response to the `Payer FSP` to send the information about the `Payee`. + + **Assumptions** + + None. + +8. **Description** + + The `Payer FSP` receives the response [Return Party Information](#return-party-information) containing information about the `Payee`. + + **Assumptions** + + None. + +
    + +##### Calculate Quote + +9. **Description** + + Depending on the fee model used, the `Payer FSP` rates the transaction internally and includes the quote information in the request [Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request[Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +10. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +11. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition are then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None. + + **Optional procedure: Quote Confirmation by Payee** + + a. **Description** + + Depending on the use case and the fee model used, the `Payee` might be informed of the quote in order to confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front-end API (outside the scope of this API). The `Payee` receives the quote including information regarding the transaction including fees and optionally `Payer` name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API), and the `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee` FSP to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional procedure** + +12. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +13. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` will then route the response to the `Payer FSP`. + + **Assumptions** + + None. + +14. **Description** + + The `Payer FSP` receives the response[Return Quote Information](#return-quote-information) from the `Switch`. The `Payer FSP` then informs the `Payer` using a front-end API (outside the scope of this API) about the total fees to perform the transaction, along with the `Payee` name. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. Also, the `Payee` name was allowed to be sent during the counterparty lookup (depending on regulation on privacy laws). + +15. **Description** + + The `Payer` receives the transaction information including fees, taxes and optionally `Payee` name. If the `Payer` rejects the transaction, the sequence ends here. + + **Assumptions** + + The `Payer` is assumed to approve the transaction in this sequence. If the `Payer` would reject the transaction at this stage, no response regarding the rejection is sent to the `Payee FSP`. The created quote at the `Payee FSP` should have an expiry time, at which time it is automatically deleted. + +
    + +##### Perform Transfer + +16. **Description** + + The `Payer FSP` receives an approval of the interoperable financial transaction using a front-end API (out of scope of this API). The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the Switch to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + Internal validations and reservation are assumed to be successful. In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +17. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks blacklist check and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Payee FSP`, including the same ILP Packet and condition as was received from the `Payer FSP`. The expiry time should be decreased by the `Switch` so that the `Payee FSP` should answer before the `Switch` answers to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +18. **Description** + + The `Payee FSP` receives the request [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a `Payer FSP` account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API) and the response **Return Transfer Information** is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +19. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +20. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` then uses the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +21. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The `Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +**Optional fragment: Get Transaction Details** + +22. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`, such as a code or a voucher token, the `Payer FSP` can use the request [Return Transfer Information](#return-transfer-information) to get the additional transaction information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the `Switch`. + + **Assumptions** + + None. + +23. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the [Retrieve Transaction Information](#retrieve-transaction-information) request to the `Payee FSP`. + + **Assumptions** + + None. + +24. **Description** + + The `Payee FSP` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and sends the response [Return Transaction Information](#return-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the `Payee FSP`. + +25. **Description** + + The `Switch` receives the response [Return Transaction Information](#return-transaction-information). The Switch then routes the [Return Transaction Information](#return-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +26. **Description** + + The `Payer FSP` receives the response [Return Transaction Information](#return-transaction-information). + + **Assumptions** + + None. + + **End of Optional fragment** + +28. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +29. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Payee-Initiated Transaction + +In a _Payee-Initiated Transaction_, the `Payee` (that is, the recipient of electronic funds) initiates the transaction. + +#### Business Process Pattern Description + +The pattern should be used whenever a `Payee` would like to receive funds from another party whose account is not located in the same FSP. + +In all alternatives to this pattern, the `Payer` must in some way confirm the request of funds. Some possible alternatives for confirming the request are: + +- **Manual approval** -- A transaction request is routed from the Payee to the Payer, the Payer can then either approve or reject the transaction. + +- **Pre-approval of Payee** -- A Payer can pre-approve a specific Payee to request funds, used for automatic approval of, for example, school fees or electric bills. + +Another alternative for approval is to use the business pattern [Payee-Initiated Transaction using OTP](#payee-initiated-transaction-using-otp). + +#### Participants and Roles + +The actors in a _Payee-Initiated Transaction_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + +The intermediary objects used in a _Payee-Initiated Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + +#### Business Process Sequence Diagram + +Figure 2 shows the UML sequence diagram for a _Payee-Initiated Transaction_. + +{% uml src="assets/diagrams/sequence/figure65a.plantuml" %} +{% enduml %} +**Figure 2 -- Payee-Initiated Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 2 above. + +##### Lookup Counterparty + +1. **Description** + + The `Payee` initiates the transaction by requesting to receive funds from a `Payer`, using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +2. **Description** + + The `Payee FSP` tries to find the Payer within the FSP system. Because the `Payer` cannot be found in the `Payee FSP` system, the `Payee FSP` sends the request to the optional `Account Lookup System` to get information regarding in which FSP the `Payer` is located. + + **Assumptions** + + The `Payer` is assumed to be located in a different FSP than the `Payee`. Also, an `Account Lookup System` is assumed to exist. + + The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the` Payer FSP` if there is no `Account Lookup System`. As the `Payee FSP` should not know in which FSP the Payer is located if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payee FSP` would like more information about the `Payer` before a transaction request is sent; in that case the request [Lookup Participant Information](#lookup-participant-information), either to the Switch or directly to the `Payer FSP`, should be sent instead of [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +3. **Description** + + The `Account Lookup System` receives the [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payer` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the `Payee FSP` about which FSP the `Payer` is located. + + **Assumptions** + + The `Payer` can be found by the `Account Lookup System`. + +4. **Description** + + The `Payee FSP` receives the response [Return Participant Information](#return-participant-information). + + **Assumptions** + + None. + + **Transaction Request** + +5. **Description** + + The `Payee FSP` sends the request [Perform Transaction Request](#perform-transaction-request) to the `Switch`. The request contains the transaction details including the amount that the Payee would like to receive. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payee FSP` and the `Payer FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transaction Request](#perform-transaction-request) could also be sent directly to the `Payer FSP` if there is no Switch in-between. + +6. **Description** + + The `Switch` receives the [Perform Transaction Request](#perform-transaction-request). The `Switch` then routes the request to the `Payer FSP`, using the same parameters. + + **Assumptions** + + None. + +7. **Description** + + The `Payer FSP` receives the request [Perform Transaction Request](#perform-transaction-request). The `Payer FSP` then optionally validates the transaction request (for example, whether the `Payer` exists) and uses the response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` via the `Switch` that the transaction request has been received. + + **Assumptions** + + The optional validation succeeds. + +8. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information). The `Switch` then sends the same response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` about the successfully delivered transaction request to the `Payer FSP`. + + **Assumptions** + + None. + +9. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Switch`. + + **Assumptions** + + None. + +
    + +##### Calculate Quote + +10. **Description** + + The `Payer FSP` rates the transaction internally based on the fee model used and includes the quote information in the request[Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details, including a reference to the earlier sent transaction request, are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +11. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`. + + **Assumptions** + + None. + +12. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition are then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None + +13. **Description** + + Depending on use case and the fee model used, the `Payee` might be informed of the quote so that the `Payee` can confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front-end API (outside the scope of this API). The `Payee` receives the quote including information regarding the transaction including fees and optionally Payer name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API). The `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The quote is assumed to be sent to the `Payer` for confirmation, and the `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee FSP` to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional fragment** + +14. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +15. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` then routes the response to the `Payer FSP`. + + **Assumptions** + + None. + +16. **Description** + + The `Payer FSP` receives the response [Return Quote Information](#return-quote-information) from the `Switch`. The `Payer FSP` then informs the `Payer` using a front-end API (outside the scope of this API) about the transaction request from the `Payee`, including the amount and the total fees required to perform the transaction, along with the `Payee` name. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. Also, the `Payee` name was allowed to be sent during the counterparty lookup (depending on regulation on privacy laws). + +17. **Description** + + The `Payer` receives the transaction request information including fees, taxes and optionally `Payee` name. + + **Assumptions** + + If the `Payer` rejects the transaction request, the sequence proceeds to Step 18. If the `Payer` approves the transaction request, the sequence proceeds to Step 22. + + **Alternative: Transaction Rejection** + +18. **Description** + + The `Payer FSP` receives the rejection of the transaction request using a front-end API (out of scope of this API). The `Payer FSP` then uses the response [Return Transaction Request Information](#return-transaction-request-information) with a rejected status to inform the `Switch` that the transaction was rejected. + + **Assumptions** + + The `Payer` is assumed to reject the transaction request in Step 17. + +19. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Payer FSP`. The `Switch` then routes the response [Return Transaction Request Information](#return-transaction-request-information) to the `Payee FSP`. + + **Assumptions** + + None. + +20. **Description** + + The `Payee FSP` receives the response *[Return Transaction Request Information](#return-transaction-request-information) with a rejected status from the `Switch`. The `Payee FSP` then informs the Payee using a front-end API (outside the scope of this API) about the rejected transaction request. + + **Assumptions** + + None. + +21. **Description** + + The `Payee` receives the notification that the transaction was rejected. The process ends here as the transaction request was rejected and the `Payee` has been informed of the decision. + + **Assumptions** + + None. + + **Alternative: Perform Transfer** + +22. **Description** + + The `Payer FSP` receives an approval of the interoperable financial transaction using a front-end API (out of scope of this API). The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the `Switch` to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + The `Payer` is assumed to approve the transaction request in Step 17. Internal validations and reservation are assumed to be successful. In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +23. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Payee FSP`, including the same ILP Packet and condition as was received from the Payer FSP. The expiry time should be decreased by the `Switch`, so that the `Payee FSP` should answer before the `Switch` should answer to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +24. **Description** + + The `Payee FSP` receives the request [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a `Payer FSP` account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the Payee using a front-end API (out of scope of this API) and the response [Return Transfer Information](#return-transfer-information) is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +25. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +26. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` then uses the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +27. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The `Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + + **Optional fragment: Get Transaction Details** + +28. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`; for example, a code or a voucher token, the `Payer FSP` can use the request [Retrieve Transaction Information](#retrieve-transaction-information) to get the additional information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the `Switch`. + + **Assumptions** + + None. + +29. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the request [Retrieve Transaction Information](#retrieve-transaction-information) to the `Payee FSP`. + + **Assumptions** + + None. + +30. **Description** + + The `Payee FSP` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and uses the response [Retrieve Transaction Information](#retrieve-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the Payee FSP. + +31. **Description** + + The `Switch` receives the response [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the [Retrieve Transaction Information](#retrieve-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +32. **Description** + + The `Payer FSP` receives the response [Retrieve Transaction Information](#retrieve-transaction-information) from the `Switch`. + + **Assumptions** + + None. + + **End of Optional fragment** + +33. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +34. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Payee-Initiated Transaction using OTP + +A _Payee-Initiated Transaction using OTP_ is very similar to a [Payee-Initiated Transaction](#payee-initiated-transaction), but the transaction information (including fees and taxes) and approval for the `Payer` is shown/entered on a `Payee` device instead. + +#### Business Process Pattern Description + +The pattern should be used when a `Payee` would like to receive funds from another party whose account is not located in the same FSP, and both the transaction information (including fees and taxes) and approval is shown/entered on a `Payee` device instead. + +- **Approval using OTP** -- A `Payer` can approve a transaction by first creating an OTP in his/her FSP. An alternative to user- initiated creation of OTP is that the OTP is automatically generated and sent by the `Payer FSP`. The same OTP is then entered by the `Payer` in a `Payee` device, usually a POS device or an ATM. The OTP in the transaction request is automatically matched by the `Payer FSP` to either approve or reject the transaction. The OTP does not need to be encrypted as it should only be valid once during a short time period. + +#### Participants and Roles + +The actors in a _Payee-Initiated Transaction using OTP_ are: + +- **Payer** -- The payer of funds in a financial transaction. + +- **Payee** -- The recipient of funds in a financial transaction. + +The intermediary objects used in a _Payee-Initiated Transaction using OTP_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of requests between different FSPs. This object can be removed if requests should be routed directly between a Payer and Payee FSP. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which the Payee's account is located. + +#### Business Process Sequence Diagram + +Figure 3 shows the UML sequence diagram for a _Payee-Initiated Transaction using OTP_. + +{% uml src="assets/diagrams/sequence/figure66a.plantuml" %} +{% enduml %} +**Figure 3 -- Payee-Initiated Transaction using OTP** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 3 above. + +##### Optional fragment: Manual OTP request + +1. **Description** + + The `Payer` requests that an OTP be generated, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + There are two alternatives for generating an OTP; either it is generated upon request by the `Payer` (this option), or it is automatically generated in Step 19. + +2. **Description** + + The `Payer FSP` receives the request to generate an OTP and returns a generated OTP to the `Payer`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +3. **Description** + + `Payer` receives the generated OTP. The OTP can then be used by the `Payer` in Step 25 for automatic approval. + + **Assumptions** + + None. + + **End of Optional fragment** + +###### Lookup Counterparty + +4. **Description** + + The `Payee` initiates the transaction by requesting to receive funds from a `Payer`, using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +5. **Description** + + The `Payee FSP` tries to find the `Payer` within the FSP system. Because the `Payer` cannot be found in the `Payee FSP` system, the request **Lookup Participant Information** is sent by the `Payee FSP` to the optional Account Lookup System to get information regarding in which FSP the Payer is located. + + **Assumptions** + + The `Payer` is assumed to be in a different FSP than the `Payee`. Also, an `Account Lookup System` is assumed to exist. The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the `Payer FSP` if there is no `Account Lookup System`. As the `Payee FSP` should not know in which FSP the `Payer` is located if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payee FSP` would like more information about the Payer before a transaction request is sent; in that case the request [Lookup Party Information](#lookup-party-information), either to the `Switch` or directly to the `Payer FSP`, should be sent instead of [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +6. **Description** + + The `Account Lookup System` receives the [Lookup Participant Information](#lookup-participant-information). It then performs an internal lookup to find in which FSP the `Payer` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the `Payee FSP` about which FSP the `Payer` is located in. + + **Assumptions** + + The `Payer` can be found by the `Account Lookup System`. + +7. **Description** + + The `Payee FSP` receives the response [Return Participant Information](#return-participant-information). + + **Assumptions** + + None. + +##### Transaction Request + +8. **Description** + + The Payee FSP sends the request [Perform Transaction Request](#perform-transaction-request) to the `Switch`. The request contains the transaction details including the amount that the `Payee` would like to receive, and that the request should be validated using an OTP (possibly a QR code containing a OTP). + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payee FSP` and the `Payer FSP` to route the messages. The `Switch` is optional in the process, as the request [Perform Transaction Request](#perform-transaction-request) could also be sent directly to the `Payer FSP` if there is no `Switch` in-between. + +9. **Description** + + The `Switch` receives the request [Perform Transaction Request](#perform-transaction-request). The `Switch` then routes the request to the `Payer FSP`, using the same parameters. + + **Assumptions** + + None. + +10. **Description** + + The `Payer FSP` receives the request [Perform Transaction Request](#perform-transaction-request). The `Payer FSP` then optionally validates the transaction request (for example, whether the `Payer` exists or not) and sends the response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` via the `Switch` that the transaction request has been received. + + **Assumptions** + + The optional validation succeeds. + +11. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transaction-request-information). The `Switch` then uses the same response [Return Transaction Request Information](#return-transaction-request-information) to inform the `Payee FSP` about the successfully delivered transaction request to the `Payer FSP`. + + **Assumptions:** + + None. + +12. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transaction-request-information) from the `Switch`. + + **Assumptions** + + None. + + **Calculate Quote** + +13. **Description** + + The `Payer FSP` rates the transaction internally based on the fee model used and includes the quote information in the request [Calculate Quote](#calculate-quote) to a `Switch` to retrieve the full quote for performing the interoperable financial transaction from the `Payer FSP` to the `Payee FSP`. The transaction details, including a reference to the transaction request, are sent in the parameters of the request to allow for the `Payee FSP` to correctly calculate the quote. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request [Calculate Quote](#calculate-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +14. **Description** + + The `Switch` receives the [Calculate Quote](#calculate-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +15. **Description** + + The `Payee FSP` receives the [Calculate Quote](#calculate-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing the transaction. It then constructs the ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition is then generated out of the ILP Packet combined with a local secret. + + **Assumptions** + + None. + + **Optional fragment: Quote Confirmation by Payee** + +16. **Description** + + Depending on the fee model used and which use case it is, the `Payee` might be informed of the quote to be able to confirm the proposed financial transaction. The quote is in that case sent to the `Payee` using a front- end API (outside the scope of this API. The `Payee` receives the quote including information regarding the transaction including fees and optionally `Payer` name. The `Payee` then confirms the quote using a front-end API (outside the scope of this API). The `Payee FSP` receives the confirmation from the `Payee`. + + **Assumptions** + + The quote is assumed to be sent to the Payer for confirmation, and the `Payee` is assumed to accept and confirm the quote. If the `Payee` would reject the quote, an error response would be sent from the `Payee FSP` to the `Payer FSP` via the `Switch` to inform about the rejected quote. + + **End of Optional fragment** + +17. **Description** + + The `Payee FSP` uses the response [Return Quote Information](#return-quote-information) to the `Switch` to return information to the `Payer FSP` about the quote, the ILP Packet, and the condition. The quote has an expiration time, to inform the `Payer FSP` until which point in time the quote is valid. + + **Assumptions** + + None. + +18. **Description** + + The `Switch` receives the response [Return Quote Information](#return-quote-information). The `Switch` will then route the request to the `Payer FSP`. + + **Assumptions** + + None. + +19. **Description** + + The `Payer FSP` receives the response [Return Quote Information](#return-quote-information) from the Switch. + + **Assumptions** + + The total quote can be calculated by the `Payer FSP`. + + **Optional fragment: Automatic OTP generation** + +20. **Description** + + The `Payer FSP` automatically generates an OTP and sends it to the `Payer`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + There are two alternatives for generating the OTP. Either it is generated upon request by the `Payer` (Step 1), or it is automatically generated (this option). + +21. **Description** + + The `Payer` receives the automatically-generated OTP. + + **Assumptions** + + None. + + **End of Optional fragment** + +22. **Description** + + The `Payer FSP` sends the request [Perform Authorization](#perform-authorization) to the `Switch`, to get an authorization to perform the transaction from the Payer via a POS, ATM, or similar payment device, in the `Payee FSP`. The request includes the amount to be withdrawn from the `Payer`'s account, and how many retries are left for the `Payer` to retry the OTP. + + **Assumptions** + + None. + +23. **Description** + + The `Switch` receives the request [Perform Authorization](#perform-authorization) from the `Payer FSP`. The `Switch` then routes the [Perform Authorization](#perform-authorization) to the `Payee FSP`. + + **Assumptions** + + None. + +24. **Description** + + The `Payee FSP` receives the request [Perform Authorization](#perform-authorization) from the `Switch`. The `Payee FSP` sends the authorization request to the `Payee` device (POS, ATM, or similar payment device) using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + +25. **Description** + + The `Payee` device receives the authorization request, and the `Payer` can see the amount that will be withdrawn from his or her account. The `Payer` then uses the OTP received in Step 3 or Step 21, depending on whether the OTP was manually requested or automatically generated. The entered or scanned OTP is then sent to the `Payee FSP` using the `Payee FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + The `Payer` has received the OTP in Step 3 or Step 21. + +26. **Description** + + The `Payee FSP` receives the OTP from the `Payee` device. The `Payee FSP` then sends the response [Return Authorization Result](#return-authorization-result) to the Switch containing the OTP from the Payer. + + **Assumptions** + + None. + +27. **Description** + + The `Switch` receives the request [Return Authorization Result](#return-authorization-result) from the `Payee FSP`. The `Switch` then routes the [Return Authorization Result](#return-authorization-result) to the `Payer FSP`. + + **Assumptions** + + None. + +28. **Description** + + The `Payer FSP` receives the request [Return Authorization Result](#return-authorization-result) to the `Switch`. The `Payer FSP` then validates the OTP received from the OTP generated in Step 2 or Step 20. If the `Payer FSP` is unable to validate the OTP (for example, because the OTP is incorrect) and this was the last remaining retry for the Payer, the sequence continues with Step 29. If the `Payer FSP` correctly validates the OTP, the sequence continues with Step 33. + + **Assumptions** + + None. + + **Alternative: OTP validation failed** + +29. **Description** + + The validation in Step 28 fails and this was the final retry for the Payer. The `Payer FSP` then uses the response [Return Transaction Request Information](#return-transation-request-information) with a rejected state to inform the `Switch` that the transaction was rejected. + + **Assumptions** + + The OTP validation in Step 28 is assumed to fail and no more retries remains for the Payer. + +30. **Description** + + The `Switch` receives the response [Return Transaction Request Information](#return-transation-request-information) from the Payer FSP. The `Switch` then routes the [Return Transaction Request Information](#return-transation-request-information) response to the `Payee FSP`. + + **Assumptions** + + None. + +31. **Description** + + The `Payee FSP` receives the response [Return Transaction Request Information](#return-transation-request-information) with a rejected status from the `Switch`. The `Payee FSP` then informs the `Payee` using a front-end API (outside the scope of this API) about the rejected transaction request. + + **Assumptions** + + None. + +32. **Description** + + The `Payee` receives the notification that the transaction was rejected. The process ends here as the transaction request was rejected and the `Payee` has been informed of the decision. The `Payer` is also assumed to receive the notification via the `Payee` device. + + **Assumptions** + + None. + + **Alternative: OTP validation succeed** + +33. **Description** + + The validation in Step 28 is successful. The `Payer FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer of funds is reserved from the `Payer`'s account to either a combined Switch account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the `Switch` to request the `Switch` to transfer the funds from the `Payer FSP` account in the `Switch` to the `Payee FSP` account. The request [Perform Transfer](#perform-transfer) includes a reference to the earlier quote, an expiry of the transfer, the ILP Packet, and the condition that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the `Payer FSP`. + + **Assumptions** + + The OTP validation in Step 28 is assumed to be successful. Internal validations and reservation are assumed to be successful. In this sequence, a Switch is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Perform Transfer](#perform-transfer) could also be sent directly to the `Payee FSP` if there is no Switch in-between. + + 34. **Description** + + The `Switch` receives the request [Perform Transfer](#perform-transfer). The `Switch` then performs all its applicable internal transfer validations (for example, limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a `Payer FSP` account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Transfer](#perform-transfer) is sent to the Payee FSP, including the same ILP Packet and condition as was received from the Payer FSP. The expiry time should be decreased by the Switch so that the `Payee FSP` should answer before the Switch should answer to the `Payer FSP`. The transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +35. **Description** + + The `Payee FSP` receives the [Perform Transfer](#perform-transfer). The `Payee FSP` then performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on). It also verifies that the amount and ILP Address in the ILP Packet are correct, and match the amount and `Payee` in the transaction details stored in the ILP Packet. If all the validations are successful, a transfer of funds is performed from either a combined `Switch` account or a Payer FSP account to the `Payee`'s account and the fulfilment of the condition is regenerated, using the same secret as in Step 11. After the interoperable financial transaction has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API) and the response [Return Transfer Information](#return-transfer-information) is sent to the `Switch`, including the regenerated fulfilment. The transfer is now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfer of funds are successful. + +36. **Description** + + The `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +37. **Description** + + The `Switch` receives the response [Return Transfer Information](#return-transfer-information). The `Switch` then validates the fulfilment and commits the earlier reserved transfer. The `Switch` will then use the response [Return Transfer Information](#return-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + +38. **Description** + + The `Payer FSP` receives the response [Return Transfer Information](#return-transfer-information). The` Payer FSP` then validates the fulfilment and commits the earlier reserved transaction. + + **Assumptions** + + The fulfilment is assumed to be correctly validated. + + **Optional fragment: Get Transaction Details** + +39. **Description** + + In case the interoperable financial transaction contains additional information that is useful for the `Payer` or the `Payer FSP`, such as a code or a voucher token, the `Payer FSP` can use the request [Retrieve Transaction Information](#retrieve-transaction-information) to get the additional information. The request [Retrieve Transaction Information](#retrieve-transaction-information) is sent to the Switch. + + **Assumptions** + + None. + +40. **Description** + + The `Switch` receives the request [Retrieve Transaction Information](#retrieve-transaction-information). The `Switch` then routes the request[Retrieve Transaction Information](#retrieve-transaction-information) to the `Payee FSP`. + + **Assumptions** + + None. + +41. **Description** + + The `Payee FSP` receives the request *[Retrieve Transaction Information](#retrieve-transaction-information). The `Payee FSP` then collects the requested information and uses the response [Return Transaction Information](#return-transaction-information) to the `Switch`. + + **Assumptions** + + The transaction with the provided ID can be found in the `Payee FSP`. + +42. **Description** + + The `Switch` receives the response [Return Transaction Information](#return-transaction-information). The `Switch` then routes the [Return Transaction Information](#return-transaction-information) response to the `Payer FSP`. + + **Assumptions** + + None. + +43. **Description** + + The `Payer FSP` receives the response [Return Transaction Information](#return-transaction-information) from the `Switch`. + + **Assumptions** + + None. + + **End of Optional fragment** + +44. **Description** + + The `Payer FSP` sends a transaction notification to the `Payee` using a front-end API (out of scope of this API), optionally including transaction details retrieved from the `Payee FSP`. + + **Assumptions** + + None. + +45. **Description** + + The `Payer` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +
    + +### Bulk Transactions + +In a _Bulk Transaction_, the `Payer` (that is, the sender of funds) initiates multiple transactions to multiple Payees, potentially located in different FSPs. + +#### Business Process Pattern Description + +The pattern should be used whenever a `Payer` would like to transfer funds to multiple Payees in the same transaction. The Payees can potentially be located in different FSPs. + +#### Participants and Roles + +The actors in a _Bulk Transaction_ are: + +- **Payer** -- The sender of funds. + +- **Payees** -- The recipients of funds. There should be multiple Payees in a _Bulk Transaction_. + +The intermediary objects used in a _Bulk Transaction_ to perform the transaction are: + +- **Payer FSP** -- The FSP in which the Payer's account is located. + +- **Switch (optional)** -- An optional entity used for routing of transactions between different FSPs. This object can be removed if transactions should be routed directly between a Payer and `Payee FSP`. + +- **Account Lookup System** -- An entity used for retrieving information regarding accounts or participants. Could be hosted in a separate server, in the Switch, or in the different FSPs. + +- **Payee FSP** -- The FSP in which a Payee's account is located. There may be multiple Payee FSPs in a _Bulk Transaction_. + +#### Business Process Sequence Diagram + +Figure 4 below shows the UML sequence diagram for a _Bulk Transaction_. + +{% uml src="assets/diagrams/sequence/figure67a.plantuml" %} +{% enduml %} +**Figure 4 -- Bulk Transaction** + +#### Internal Processing Steps + +This section provides descriptions of and assumptions made for all steps in the sequence shown in Figure 4. + +##### Lookup Counterparties + +1. **Description** + + The `Payer` initiates the bulk transaction process by uploading a bulk file to the `Payer FSP`, using the `Payer FSP`'s front-end API (outside the scope of this API). + + **Assumptions** + + None. + + **Loop for each Transaction in bulk file** + +2. **Description** + + `Payer FSP` tries to find the Payee within the `Payer FSP` system. + + **Assumptions** + + The `Payee` is assumed to be located in a different FSP than the `Payer`. If the `Payee` is within the `Payer FSP`, the transaction can be handled internally in the `Payer FSP` (outside the scope of this API). + +3. **Description** + + The `Payer FSP` sends the request [Lookup Participant Information](#lookup-participant-information) to the optional `Account Lookup System` to get information regarding in which FSP the `Payer` is present in. + + **Assumptions** + + The `Payee` is assumed to in a different FSP than the `Payer`. Also, an `Account Lookup System` is assumed to exist. The `Account Lookup System` is optional in the process, as the request [Lookup Participant Information](#lookup-participant-information) could also be sent directly to the `Payee FSP`s if there is no `Account Lookup System`. As the `Payer FSP `should not know in which FSP the `Payee` is located in if there is no `Account Lookup System` present, the request might need to be sent to more than one FSP. It is also possible that the `Payer FSP` would like more information about the `Payee` before a bulk transaction is executed; for example, for additional verification purposes of the `Payee` name. In that case, the request [Lookup Party Information](#lookup-party-information), either to the `Switch` or directly to the `Payee FSP`, should be sent instead of the request [Lookup Participant Information](#lookup-participant-information) to the `Account Lookup System`. + +4. **Description** + + The `Account Lookup System` receives the request [Lookup Participant Information](#lookup-participant-information) It then performs an internal lookup to find in which FSP the `Payee` is located. When the lookup is completed, the response [Return Participant Information](#return-participant-information) is sent to inform the Payer FSP about which FSP the `Payee` is located in. + + **Assumptions** + + The `Payee` can be found by the `Account Lookup System`. + +5. **Description** + + The `Payer FSP` receives the response [Return Participant Information](#return-participant-information). The `Payee` and the related transaction is then placed in a new bulk file separated per `Payee FSP`. + + **Assumptions** + + None. + + **End of loop for each Transaction** + +##### Calculate Bulk Quote + + **Loop for each `Payee FSP` to Calculate Bulk Quote** + +6. **Description** + + The `Payer FSP` uses the request [Calculate Bulk Quote](#calculate-bulk-quote) on a `Switch` to retrieve a quote for performing the bulk transaction from the `Payer FSP` to the `Payee FSP`. The request contains details for each individual transaction in the bulk transaction. + + **Assumptions** + + In this sequence, a `Switch` is placed between the `Payer FSP` and the `Payee FSP` to route the messages. The Switch is optional in the process, as the request [Calculate Bulk Quote](#calculate-bulk-quote) could also be sent directly to the `Payee FSP` if there is no `Switch` in-between. + +7. **Description** + + The `Switch` receives the [Calculate Bulk Quote](#calculate-bulk-quote) request. The `Switch` then routes the request to the `Payee FSP`, using the same parameters. + + **Assumptions** + + None. + +8. **Description** + + The `Payee FSP` receives the [Calculate Bulk Quote](#calculate-bulk-quote) request. The `Payee FSP` then internally calculates the fees or FSP commission for performing each individual transaction in the bulk transaction. For each individual transaction, the `Payee FSP` then constructs an ILP Packet containing the ILP Address of the `Payee`, the amount that the `Payee` will receive, and the transaction details. The fulfilment and the condition is then generated out of the ILP Packet combined with a local secret. It then uses the response [Return Bulk Quote Information](#return-bulk-quote-information) to the `Switch` to inform the `Payer FSP` about the fees involved in performing the bulk transaction and the ILP Packet and condition. The bulk quote has an expiration date and time, to inform the `Payer FSP` until which time the bulk quote is valid. + + **Assumptions** + + The bulk quote can be calculated by the `Payee FSP`. + +9. **Description** + + The Switch receives the response [Return Bulk Quote Information](#return-bulk-quote-information). The `Switch` then routes the response to the Payer FSP. + + **Assumptions** + + None. + +10. **Description** + + The `Payer FSP` receives the response [Return Bulk Quote Information](#return-bulk-quote-information) from the `Switch`. + + **Assumptions** + + None. + + **End of loop for each `Payee FSP`** + +11. **Description** + + The `Payer FSP` calculates any internal bulk fees and taxes, and informs the `Payer` using a front-end API (outside the scope of this API) about the total fees and taxes to perform the bulk transaction. + + **Assumptions** + + None. + +12. **Description** + + The `Payer` receives the notification about the completed processing of the bulk transaction and the fees and taxes to perform the bulk transaction. The `Payer` then decides to execute the bulk transaction. + + **Assumptions** + + The `Payer` is assumed to execute the bulk transaction. If the `Payer` would reject the bulk transaction at this stage, no response is sent to the `Payee FSP`. The created bulk quote at the `Payee FSP`s should have an expiry date; that is, at which time it's automatically deleted. + +##### Perform Bulk Transfer** + +13. **Description** + + The `Payer FSP` receives the request to execute the bulk transaction from the `Payer`. + + **Assumptions** + + None. + + **Loop for each `Payee FSP` to perform Bulk Transfer** + +14. **Description** + + The `Payer FSP` performs all applicable internal transaction validations (for example, limit checks, blacklist check, and so on) for the bulk transaction to the `Payee FSP`. If the validations are successful, a transfer of funds is reserved from the Payer's account to either a combined `Switch` account or a `Payee FSP` account, depending on setup. After the transfer has been successfully reserved, the request [Perform Bulk Transfer](#perform-bulk-transfer) is sent to the `Switch`. The request [Perform Bulk Transfer](#perform-bulk-transfer) includes a reference to the earlier bulk quote, an expiry of the bulk transfer, and the ILP Packets and condition per transfer that was received from the `Payee FSP`. The interoperable financial transaction is now irrevocable from the Payer FSP. The interoperable bulk transaction is now irrevocable from the Payer FSP. + + **Assumptions** + + In this sequence, a Switch is placed between the `Payer FSP `and the `Payee FSP` to route the messages. The `Switch` is optional in the process, as the request *[Perform Bulk Transfer](#perform-bulk-transfer) could also be sent directly to the `Payee FSP` if there is no Switch in-between. + +15. **Description** + + The Switch receives the request [Perform Bulk Transfer](#perform-bulk-transfer). The Switch then performs all applicable internal transfer validations (such as limit checks, blacklist check, and so on). If the validations are successful, a transfer is reserved from a Payer FSP account to a `Payee FSP` account. After the transfer has been successfully reserved, the request [Perform Bulk Transfer](#perform-bulk-transfer) is sent to the `Payee FSP`, including the same ILP Packets and conditions for each transfer that were received from the `Payer FSP`. The expiry time should be decreased by the Switch so that the `Payee FSP` should answer before the Switch should answer to the `Payer FSP`. The bulk transfer is now irrevocable from the `Switch`. + + **Assumptions** + + Internal validations and reservation are successful. + +16. **Description** + + The `Payee FSP` receives the request [Perform Bulk Transfer](#perform-bulk-transfer). The `Payee FSP` then performs all applicable internal transaction validations (such as limit checks, and blacklist checks) for each individual transaction in the bulk transaction. If the validations are successful, a transfer of funds is performed from either a combined Switch account or a `Payer FSP` account, depending on setup, to each of the Payees' accounts and the fulfilment of each condition is regenerated, using the same secret as in Step 8. After each transfer to a `Payee` has been successfully performed, a transaction notification is sent to the `Payee` using a front-end API (out of scope of this API). After each of the individual transactions in the bulk transaction has been completed, the response [Return Bulk Transfer Information](#return-bulk-transfer-information) is sent to the Switch to inform the Switch and the Payer FSP of the result including each fulfilment. The transactions in the bulk transaction are now irrevocable from the `Payee FSP`. + + **Assumptions** + + Internal validations and transfers of funds are successful. + +17. **Description** + + Each `Payee` receives a transaction notification containing information about the successfully performed transaction. + + **Assumptions** + + None. + +18. **Description** + + The `Switch` receives the response [Return Bulk Transfer Information](#return-bulk-transfer-information). The `Switch` then validates the fulfilments and commits the earlier reserved transfers. The `Switch` then uses the response [Return Bulk Transfer Information](#return-bulk-transfer-information) to the `Payer FSP`, using the same parameters. + + **Assumptions** + + Each individual transaction in the bulk transaction is assumed to be successful in the `Payee FSP`, and the validation of the fulfilments is also assumed to be correct. If one or more of the transactions in the bulk transaction were unsuccessful, the earlier reserved, now unsuccessful, transfer or transfers in the `Switch` would need to be cancelled. + +19. **Description** + + The `Payer FSP` receives the response [Return Bulk Transfer Information](#return-bulk-transfer-information). The `Payer FSP` then commits the earlier reserved transfers. After the bulk transaction has been successfully committed, a transaction notification is sent to the `Payer` using a front-end API (out of scope of this API). + + **Assumptions** + + Each individual transaction in the bulk transaction is assumed to be successful in the `Payee FSP`, and the validation of the fulfilments is also assumed to be correct. If one or more of the transactions in the bulk transaction were unsuccessful, the earlier reserved transfer in the `Payer FSP` would need to be updated with the total amount of all successful transactions before being committed. + + **End of loop for each `Payee FSP`** + +20. **Description** + + After each of the `Payee FSP`s has executed their part of the bulk transaction, a response is sent to the Payer using a front- end API (out of scope for this API). + + **Assumptions** + + None. + +21. **Description** + + The `Payer` receives a bulk transaction notification containing information about the successfully performed bulk transaction. + + **Assumptions** + + None. + +## References + +1 [https://interledger.org/rfcs/0011-interledger-payment-request/ - Interledger Payment Request (IPR)](https://interledger.org/rfcs/0011-interledger-payment-request) + +2 [https://interledger.org/ - Interledger](https://interledger.org) + +3 [https://interledger.org/interledger.pdf - A Protocol for Interledger Payments](https://interledger.org/interledger.pdf) + +4 [https://interledger.org/rfcs/0001-interledger-architecture/ - Interledger Architecture](https://interledger.org/rfcs/0001-interledger-architecture) + + + +**List of Figures** + +[Figure 1 -- Payer-Initiated Transaction](#443-business-process-sequence-diagram) + +[Figure 2 -- Payee-Initiated Transaction](#423-business-process-sequence-diagram) + +[Figure 3 -- Payee-Initiated Transaction using OTP](#433-business-process-sequence-diagram) + +[Figure 4 -- Bulk Transaction](#443-business-process-sequence-diagram) diff --git a/website/versioned_docs/v1.0.1/api/fspiop/glossary.md b/website/versioned_docs/v1.0.1/api/fspiop/glossary.md new file mode 100644 index 000000000..84ac44885 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/glossary.md @@ -0,0 +1,282 @@ +# Glossary + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +| **Type of Information** | **Convention** | **Example** | +| :--- | :--- | :--- | +| **Elements of the API, such as resources** | Boldface | **/authorization** | +| **Variables** | Italics within curled brackets | _{ID}_ | +| **Glossary** | Italics on first occurrence; defined in _Glossary_ | The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of **terms** electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. | +| **Library documents** | Italics | User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +| **Version** | **Date** | **Change Description** | +| :--- | :--- | :--- | +| **1.0** | 2018-03-13 | Initial version | + +
    + +## Introduction + +This document provides the glossary for the Open API for FSP Interoperability Specification. Terms have been compiled from three sources: + +- ITU-T Digital Financial Services Focus Group Glossary (ITU-T)[ITU-T Digital Financial Services Focus Group Glossary (ITU-T)](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-E.pdf), + +- Feedback from Technology Service Providers (TSPs) in the Product Development Partnership (PDP) work groups, and + +- Feedback from the L1P IST Reference Implementation team (RI). + +Information is shared in accordance with Creative Commons Licensing[LICENSE](https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md). + + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](#) + +
    + + +## API Glossary + +| **Term** | **Alternative and Related Terms** | **Definition** | **Source** | +| --- | --- | --- | --- | +| **Access Channel** | POS ("Point of Sale"), Customer Access Point, ATM, Branch, MFS Access Point | Places or capabilities that are used to initiate or receive a payment. Access channels can include bank branch offices, ATMs, terminals at the POS, agent outlets, mobile phones, and computers. | ITU-T | +| **Account ID** | | A unique identifier assigned by the FSP that created the account. | PDP | +| **Account Lookup System** | | Account Lookup System is an abstract entity used for retrieving information regarding in which FSP an account, wallet, or identity is hosted. The Account Lookup System itself can be hosted in its own server, as part of a financial switch, or in the different FSPs. | PDP | +| **Active User** | | A term used by many providers in describing how many of their account holders are frequent users of their service. | +| **Agent** | Agent Til , Agent Outlet | An entity authorized by the provider to handle various functions such as customer enrollment, cash-in and cash-out using an agent til . | ITU-T | +| **Agent Outlet** | Access Point | A physical location that carries one or more agent tills, enabling it to perform enrollment, cash-in, and cash-out transactions for customers on behalf of one or more providers. National law defines whether an agent outlet may remain exclusive to one provider. Agent outlets may have other businesses and support functions. | ITU-T | +| **Agent Till** | Registered Agent | An agent till is a provider-issued registered “line”, either a special SIM card or a POS machine, used to perform enrollment, cash-in and cash-out transactions for clients. National law dictates which financial service providers can issue agent tills. | ITU-T | +| **Aggregator** | Merchant Aggregator | A specialized form of a merchant services provider, who typically handles payment transactions for a large number of small merchants. Scheme rules often specify what aggregators are allowed to do. | ITU-T | +| **Anti-Money Laundering** | AML; also "Combating the Financing of Terrorism", or CFT | Initiatives to detect and stop the use of financial systems to disguise the use of funds that have been criminally obtained. | ITU-T | +| **API** | Application Programming Interface | A set of clearly defined methods of communication to allow interaction and sharing of data between different software programs. |PDP | +| **Arbitration** | | The use of an arbitrator, rather than courts, to resolve disputes. | ITU-T | +| **Authentication** | Verification, Validation | The process of ensuring that a person or a transaction is valid for the process (account opening, transaction initiation, and so on) being performed. | ITU-T | +| **Authorization** | | A process used during a "pull" payment (such as a card payment), in which the payee requests (through their provider) confirmation from the payer's bank that the transaction is good. | ITU-T | +| **Authorized /institution entity** | | Non-financial institutions that have followed the appropriate authorization by State Bank and/or relevant regulatory authorities to partake in the provisioning of mobile financial services. | PDP | +| **Automated Clearing House** | ACH | An electronic clearing system in which payment orders are exchanged among payment service providers, primarily via magnetic media or telecommunications networks, and then cleared amongst the participants. All operations are handled by a data processing center. An ACH typically clears credit transfers and debit transfers, and in some cases also cheques. | ITU-T | +| **Bank** | Savings Bank, Credit Union, Payments Bank | A chartered financial system within a country that has the ability to ITU-T accept deposits and make and receive payments into customer accounts. | ITU-T | +| **Bank Accounts and Transaction Services** | Mobile Banking, Remote Banking, Digital Banking| A transaction account held at a bank. This account may be accessible by ITU-T a mobile phone, in which case it is sometimes referred to as "mobile banking".| ITU-T | +| **Bank-Led Model** | Bank-Centric Model| A reference to a system in which banks are the primary providers of digital financial services to end users. National law may require this. | ITU-T | +| **Basic Phone** | | Minimum device required to use digital financial services. | PDP | +| **Bill Payment** | C2B, Utility Payments, School Payments | Making a payment for a recurring service, either in person ("face to face") or remotely. | ITU-T | +| **Biometric Authentication** | | The use of a physical characteristic of a person (fingerprint, IRIS, and so on) to authenticate that person. | ITU-T | +| **Biometric Authentication** | | Any process that validates the identity of a user who wishes to sign into a system by measuring some intrinsic characteristic of that user. | ITU-T | +| **Blacklist** | | A list or register of entities (registered users) that are being denied/blocked from a particular privilege, service, mobility, access or recognition. Entities on the list will not be accepted, approved and or recognized. It is the practice of identifying entities that such entities are denied, unrecognized, or ostracized. Where entities are registered users (or user accounts, if granularity allows) and services are informational (for example, balance check), transactional (for example, debit/credit) payments services or lifecycle (for example, registration, closure) services. | PDP | +| **Blockchain** | Digital Currency, Cryptocurrency, Distributed Ledger Technology| The technology underlying bitcoin and other cryptocurrencies—a shared digital ledger, or a continually updated list of all transactions.| ITU-T | +| **Borrowing** | | Borrowing money to finance a short-term or long-term need. | ITU-T | +| **Bulk Payments** | G2C, B2C, G2P, Social Transfers| Making and receiving payments from a government to a consumer: benefits, cash transfers, salaries, pensions, and so on | ITU-T | +| **Bulk Payment Services** | | A service which allows a government agency or an enterprise to make payments to a large number of payees - typically consumers but can be businesses as well | ITU-T | +| **Bulk upload service** | | A service allowing the import of multiple transactions per session, most often via a bulk data transfer file which is used to initiate payments. Example: salary payment file. | ITU-T | +| **Bundling** | Packaging, Tying | A business model in which a provider which groups a collection of services into one product which an end user agrees to buy or use.| ITU-T | +| **Business** | | Entity such as a public limited or limited company or corporation that uses mobile money as a service; for example, making and accepting bill payments and disbursing salaries.| PDP | +| **Cash Management** | Agent Liquidity Management | Management of cash balances at an agent. | ITU-T | +| **Cash-In** | CICO (Cash-In Cash-Out) | Receiving eMoney credit in exchange for physical cash - typically done at an agent. | ITU-T | +| **Cash-Out** | CICO (Cash-In Cash-Out) | Receiving physical cash in exchange for a debit to an eMoney account - typically done at an agent. | ITU-T | +| **Certificate Signing Request** | CSR | Message sent from an applicant to a Certificate Authority in order to apply for a digital identity certificate. | | +| **Chip Card** | EMV Chip Card, Contactless Chip Card | A chip card contains a computer chip: it may be either contactless or contact (requires insertion into terminal). Global standards for chip cards are set by EMV. | ITU-T | +| **Clearing** | | The process of transmitting, reconciling, and, in some cases, confirming transactions prior to settlement, potentially including the netting of transactions and the establishment of final positions for settlement. Sometimes this term is also used (imprecisely) to cover settlement. For the clearing of futures and options, this term also refers to the daily balancing of profits and losses and the daily calculation of collateral requirements. | RI | +| **Clearing House** | | A central location or central processing mechanism through which financial institutions agree to exchange payment instructions or other financial obligations (for example, securities). The institutions settle for items exchanged at a designated time based on the rules and procedures of the clearinghouse. In some cases, the clearinghouse may assume significant counterparty, financial, or risk management responsibilities for the clearing system.| ITU-T | +| **Client Authentication** | TLS | A client authentication certificate is a certificate used to authenticate clients during an SSL handshake. It authenticates users who access a server by exchanging the client authentication certificate. ... This is to verify that the client is who they claim to be (Source: Techopedia). | | +| **Closed-Loop** | | A payment system used by a single provider, or a very tightly constrained group of providers.| ITU-T | +| **Combatting Terrorist Financing** | | Initiatives to detect and stop the use of financial systems to transfer funds to terrorist organizations or people. | ITU-T | +| **Commission** | | An incentive payment made, typically to an agent or other intermediary who acts on behalf of a DFS provider. Provides an incentive for agent. | ITU-T | +| **Commit** | | Part of a 2-phase transfer operation in which the funds that were reserved to be transferred, are released to the payee; the transfer is completed between the originating/payer and destination/payee accounts. | PDP | +| **Condition** | | In the Interledger protocol, a cryptographic lock used when a transfer is reserved. Usually in the form of a SHA-256 hash of a secret preimage. When provided as part of a transfer request the transfer must be reserved such that it is only committed if the fulfillment of the condition (the secret preimage) is provided. | PDP | +| **Counterparty** | Payee, Payer, Borrower, Lender | The other side of a payment or credit transaction. A payee is the counterparty to a payer, and vice-versa. | ITU-T | +| **Coupon** | | A token that entitles the holder to a discount or that may be exchanged for goods or services.| PDP | +| **Credit History** | Credit Bureaus, Credit Files | A set of records kept for an end user reflecting their use of credit, including borrowing and repayment. | ITU-T | +| **Credit Risk Management** | | Tools to manage the risk that a borrower or counterparty will fail to meet its obligations in accordance with agreed terms. | ITU-T | +| **Credit Scoring** | | A process which creates a numerical score reflecting credit worthiness. | ITU-T | +| **Cross Border Trade Finance Services** | | Services which enable one business to sell or buy to businesses or individuals in other countries; may include management of payments transactions, data handling, and financing. | ITU-T | +| **Cross-FX Transfer** | | Transfer involving multiple currencies including a foreign exchange calculation.| PDP | +| **Customer Database Management** | | The practices that providers do to manage customer data: this may be enabled by the payment platform the provider is using. | ITU-T | +| **Customer Financial Data** | Customer Financial Data | Means a set of financial information of the customer, which includes account balances, deposits and data relating to financial transactions, and so on | PDP | +| **Data Controller** | Data Controller | Data Controller shall mean any person, public authority, agency or any other body which alone or jointly with others determines the purposes and means of the processing of personal data; where the purposes and means of processing are determined by national or Community laws or regulations, the controller or the specific criteria for his nomination may be designated by national or Community law. Also, Data Controller is responsible for providing a secure infrastructure in support of the data, including, but not limited to, providing physical security, backup and recovery processes, granting authorized access privileges and implementing and administering controls. | PDP | +| **Data Portability** | Data Portability | Data Portability shall mean a data subject’s ability to request a copy of personal data being processed in a format usable by this person and be able to transmit it electronically to another processing system | PDP | +| **Data Protection** | PCI-DSS | The practices that enterprises do to protect end user data and credentials. "PCI-DSS" is a card industry standard for this. | ITU-T | +| **Deposit Guarantee System** | Deposit Insurance | A fund that insures the deposits of account holders at a provider; often a government function used specifically for bank accounts. | ITU-T | +| **Diffie-Hellman solution** | | A secure mechanism for exchanging a shared symmetric key between two anonymous peers. | | +| **Digital Financial Services** | DFS, Mobile Financial Services | Digital financial services include methods to electronically store and transfer funds; to make and receive payments; to borrow, save, insure and invest; and to manage a person's or enterprise's finances. | ITU-T | +| **Digital Liquidity** | | A state in which a consumer willing to leave funds (eMoney or bank deposits) in electronic form, rather than performing a "cash-out". | ITU-T | +| **Digital Payment** | Mobile Payment, Electronic Funds Transfer | A broad term including any payment which is executed electronically. Includes payments which are initiated by mobile phone or computer. Card payments in some circumstances are considered to be digital payments. The term "mobile payment" is equally broad and includes a wide variety of transaction types which in some way use a mobile phone. | ITU-T | +| **Dispute Resolution** | | A process specified by a provider or by the rules of a payment scheme to resolve issues between end users and providers, or between an end user and its counter party. | ITU-T | +| **Electronic consent** | Electronic consent |Any sound, symbol, or process which is:
    1. Related to technology
      a. Having electrical, digital, magnetic, wireless, optical, electromagnetic, or similar capabilities, including (but not limited to) mobile telephone, facsimile and internet and
      b. Which may only be accessed through a security access code, and


    2. Logically associated with a legally binding agreement or authorization and executed or adopted by a person with the intent to be bound by such agreement or authorization.
    | PDP | +| **Electronic Invoicing, ERP, Digital Accounting, Supply Chain Solutions, Services, Business Intelligence** | | Services which support merchant or business functions relating to DFS services. | ITU-T | +| **eMoney** |eFloat, Float, Mobile Money, Electronic Money, Prepaid Cards, Electronic Funds | A record of funds or value available to a consumer stored on a payment device such as chip, prepaid cards, mobile phones or on computer systems as a non-traditional account with a banking or non-banking entity. | ITU-T | +| **eMoney Accounts and Transaction Services** | Digital Wallet, Mobile Wallet, Mobile Money Account |A transaction account held at a non-bank. The value in such an account is referred to as eMoney. | ITU-T | +| **eMoney Issuer** | Issuer, Provider | A provider (bank or non-bank) who deposits eMoney into an account they establish for an end user. eMoney can be created when the provider receives cash ("cash-in") from the end user (typically at an agent location) or when the provider receives a digital payment from another provider. | ITU-T | +| **Encryption** |Decryption | The process of encoding a message so that it can be read only by the sender and the intended recipient. | ITU-T | +| **End User** |Consumer, Customer, Merchant, Biller | The customer of a digital financial services provider: the customer may be a consumer, a merchant, a government, or another form of enterprise. | ITU-T | +| **External Account** | | An account hosted outside the FSP, regularly accessible by an external provider interface API. | PDP | +| **FATF** | | The Financial Action Task Force is an intergovernmental organization to combat money laundering and to act on terrorism financing. | ITU-T | +| **Feature Phone** | |A mobile telephone without significant computational . | ITU-T | +| **Fees** | | The payments assessed by a provider to their end user. This may either be a fixed fee, a percent-of-value fee, or a mixture. A Merchant Discount Fee is a fee charged by a Merchant Services Provider to a merchant for payments acceptance. Payments systems or schemes, as well as processors, also charge fees to their customer (typically the provider.) | ITU-T | +| **Financial Inclusion** | | The sustainable provision of affordable digital financial services that bring the poor into the formal economy.| ITU-T | +| **Financial Literacy** | |Consumers and businesses having essential financial skills, such as preparing a family budget or an understanding of concepts such as the time value of money, the use of a DFS product or service, or the ability to apply for such a service. | ITU-T | +| **FinTech** | |A term that refers to the companies providing software, services, and products for digital financial services: often used in reference to newer technologies. | ITU-T | +| **Float** | |This term can mean a variety of different things. In banking, float is created when one party's account is debited or credited at a different time than the counterparty to the transaction. eMoney, as an obligation of a non-bank provider, is sometimes referred to as float. | ITU-T | +| **Fraud** | Fraud Management, Fraud Detection, Fraud Prevention | Criminal use of digital financial services to take funds from another individual or business, or to damage that party in some other way. | ITU-T | +| **Fraud Risk Management** | | Tools to manage providers' risks, and at times user's risks (for example, for merchants or governments) in providing and/or using DFS services. | ITU-T | +| **FSP** | Provider, Financial Service Provider (FSP), Payment Service Provider, Digital Financial Services Provider (DFSP) | The entity that provides a digital financial service to an end user (either a consumer, a business, or a government.) In a closed-loop payment system, the Payment System Operator is also the provider. In an open- loop payment system, the providers are the banks or non-banks which participate in that system. | ITU-T | +| **FSP On-boarding** | | The process of adding a new FSP to this financial network. | RI | +| **Fulfillment** | | In the Interledger protocol, a secret that is the preimage of a SHA-256 hash, used as a condition on a transfer. The preimage is required in the commit message to trigger the transfer to be committed.| PDP | +| **FX** | | Foreign Exchange | PDP | +| **Government Payments Acceptance Services** | | Services which enable governments to collect taxes and fees from individuals and businesses. | ITU-T | +| **HCE** | | Host Card Emulation. A communication technology that enables payment data to be safely stored without using the Secure Element in the phone. | ITU-T | +| **Identity** | National Identity, Financial Identity, Digital Identity |A credential of some sort that identifies an end user. National identities are issued by national governments. In some countries a financial identity is issued by financial service providers. | ITU-T | +| **Immediate Funds Transfer** | Real Time | A digital payment which is received by the payee almost immediately upon the payer having initiated the transaction | ITU-T | +| **Insurance Products** | | A variety of products which allow end user to insure assets or lives that they wish to protect.| ITU-T | +| **Insuring Lives or assets** | | Paying to protect the value of a life or an asset. | ITU-T | +| **Interchange** | Swipe Fee, Merchant Discount Fee | A structure within some payments schemes which requires one provider to pay the other provider a fee on certain transactions. Typically used in card schemes to effect payment of a fee from a merchant to a consumer's card issuing bank. | ITU-T | +| **Interledger** | | The Interledger protocol is a protocol for transferring monetary value across multiple disconnected payment networks using a choreography of conditional transfers on each network. | PDP | +| **International Remittance** | P2P; Remote Cross-Border Transfer of Value, Cross-Border Remittance | Making and receiving payments to another person in another country. | ITU-T | +| **Interoperability** | Interconnectivity | When payment systems are interoperable, they allow two or more proprietary platforms or even different products to interact seamlessly. The result is the ability to exchange payments transactions between and among providers. This can be done by providers participating in a scheme, or by a variety of bilateral or multilateral arrangements. Both technical and business rules issues need to be resolved for interoperability to work. | ITU-T | +| **Interoperability Service for Transfers (IST)** | Switch | An entity which receives transactions from one provider and routes those transactions on to another provider. A switch may be owned or hired by a scheme or be hired by individual providers. A switch may connect to a settlement system for inter-participant settlement and could also implicitly host other services - such as a common account locator service. | ITU-T | +| **Interoperability settlement bank** | | Entity that facilitates the exchange of funds between the FSPs. The settlement bank is one of the main entities involved in any inter-FSP transaction. | PDP | +| **Investment Products** | | A variety of products which allow end users to put funds into investments other than a savings account.| ITU-T | +| **Irrevocable** | |A transaction that cannot be "called back" by the payer; an irrevocable payment, once received by a payee, cannot be taken back by the payer. | ITU-T | +| **JSON** | JavaScript Object Notation | JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 (Source: www.json.org). | | +| **Know Your Customer** | KYC, Agent and Customer Due Diligence, Tiered KYC, Zero Tier | The process of identifying a new customer at the time of account opening, in compliance with law and regulation. The identification requirements may be lower for low value accounts ("Tiered KYC"). The term is also used in connection with regulatory requirements for a provider to understand, on an ongoing basis, who their customer is and how they are using their account. | ITU-T | +| **Liability** | Agent Liability, Issuer Liability, Acquirer Liability | A legal obligation of one party to another; required by either national law, payment scheme rules, or specific agreements by providers. Some scheme rules transfer liabilities for a transaction from one provider to another under certain conditions. | ITU-T | +| **Liquidity** | Agent Liquidity | The availability of liquid assets to support an obligation. Banks and non-bank providers need liquidity to meet their obligations. Agents need liquidity to meet cash-out transactions by consumers and small merchants.| ITU-T | +| **Loans** | Microfinance, P2P Lending, Factoring, Cash Advances, Credit, Overdraft, Facility | Means by which end users can borrow money. | ITU-T | +| **M2C** | | Merchant to Customer or Consumer. | PDP | +| **mCommerce** | eCommerce | Refers to buying or selling in a remote fashion: by phone or tablet (mCommerce) or by computer (eCommerce). | ITU-T | +| **Merchant** | Payments Acceptor | An enterprise which sells goods or services and receives payments for such goods or services. | ITU-T | +| **Merchant Acquisition** | Onboarding | The process of enabling a merchant for the receipt of electronic payments.| ITU-T | +| **Merchant payment - POS** | C2B, Proximity Payments | Making a payment for a good or service in person ("face to face"); includes kiosks and vending machines. | ITU-T | +| **Merchant payment - Remote** |C2b, eCommerce Payment, Mobile Payment | Making a payment for a good or service remotely; transacting by phone, computer, and so on | ITU-T | +| **Merchant Payments Acceptance Services** | Acquiring Services | A service which enables a merchant or other payment acceptor to accept one or more types of electronic payments. The term "acquiring" is typically used in the card payments systems. | ITU-T | +| **Merchant Service Provider** | Acquirer | A provider (bank or non-bank) who supports merchants or other payments acceptors requirements to receive payments from customers. The term "acquirer" is used specifically in connection with acceptance of card payments transactions. | ITU-T | +| **Mobile Network Operator** | MNO | An enterprise which sells mobile phone services, including voice and data communication. | ITU-T | +| **Money Transfer Operator** | | A specialized provider of DFS who handles domestic and/or international remittances. | ITU-T | +| **MSISDN** | | Number uniquely identifying a subscription in a mobile phone network. These numbers use the E.164 standard that defines numbering plan for a world-wide public switched telephone network (PSTN).| RI | +| **Mutual Authentication** | TLS | Mutual authentication or two-way authentication refers to two parties authenticating each other at the same time, being a default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS) (Source: Wikipedia). | | +| **Near Field Communication** | NFC | A communication technology used within payments to transmit payment data from an NFC equipped mobile phone to a capable terminal.| ITU-T | +| **Netting** | | The offsetting of obligations between or among participants in the settlement arrangement, thereby reducing the number and value of payments or deliveries needed to settle a set of transactions.| RI | +| **Non-Bank** | Payments Institution, Alternative Lender | An entity that is not a chartered bank, but which is providing financial services to end users. The requirements of non-banks to do this, and the limitations of what they can do, are specified by national law| ITU-T | +| **Non-Bank-Led Model** | MNO-Led Model | A reference to a system in which non-banks are the providers of digital financial services to end users. Non-banks typically need to meet criteria established by national law and enforced by regulators.| ITU-T | +| **Non-repudiation** | | Ability to prove the authenticity of a transaction, such as by validating a digital signature.| PDP | +| **Nostro Account** | | From the Payer's perspective: Payer FSP funds/accounts held/hosted at Payee FSP.| PDP | +| **Notification** | | Notice to a payer or payee regarding the status of transfer. |PDP | +| **Off-Us Payments** | Off-Net Payments | Payments made in a multiple-participant system or scheme, where the payer's provider is a different entity as the payee's provider. | ITU-T | +| **On-Us Payments** | On-Net Payments | Payments made in a multiple-participant system or scheme, where the payer's provider is the same entity as the payee's provider. | ITU-T | +| **Open-Loop** | | A payment system or scheme designed for multiple providers to participate in. Payment system rules or national law may restrict participation to certain classes of providers.| ITU-T | +| **Operations Risk Management** | | Tools to manage providers' risks in operating a DFS system. | ITU-T | +| **Organization** | Business | An entity such as a business, charity or government department that uses mobile money as a service; for example, taking bill payments, making bill payments and disbursing salaries. | PDP | +| **OTP** | One-Time Password | OTP is a credential which by definition can only be used once. It is generated and later validated by the same FSP for automatic approval. The OTP is usually tied to a specific Payer in a Payment. The generated OTP is usually a numeric between 4 and 6 digits. | PDP | +| **Over The Counter Services** | OTC, Mobile to Cash | Services provided by agents when one end party does not have an eMoney account: the (remote) payer may pay the eMoney to the agent's account, who then pays cash to the non- account holding payee. | ITU-T | +| **P2P** | Domestic Remittance, Remote Domestic Transfer of Value| Making and receiving payments to another person in the same country. | ITU-T | +| **Participant** | | A provider who is a member of a payment scheme, and subject to that scheme's rules.| ITU-T | +| **Partner Bank** | | Financial institution supporting the FSP and giving it access to the local banking ecosystem. | PDP | +| **Payee** | Receiver | The recipient of electronic funds in a payment transaction. | ITU-T | +| **Payee FSP** | | Payee's Financial Service Provider. | PDP | +| **Payer** | Sender | The payer of electronic funds in a payment transaction. | ITU-T | +| **Payer FSP** | | Payer's Financial Service Provider. | PDP | +| **Paying for Purchases** | C2B - Consumer to Business | Making payments from a consumer to a business: the business is the "payment acceptor” or merchant. | ITU-T | +| **Payment Device** | ATM (Automated Teller Machine), POS (Point of Sale), Access Point, Point of Sale Device | Payment device is the abstract notion of an electronic device, other than the Payer’s own device, that is capable of letting a Payer accept a transaction through the use of a credential (some kind of OTP). Examples of (Payment) Devices are ATM and POS. | PDP | +| **Payment Instruction** | Payment Instruction | An instruction by a sender to a sender’s payment service provider, transmitted orally, electronically, or in writing, to pay, or to cause another payment service provider to pay, a fixed or determinable amount of money to a payee if:
    a) The instruction does not state a condition of payment to the payee other than time of payment; and

    b) The instruction is transmitted by the sender directly to the sender’s payment service provider or to an agent, electronic fund transfers system or communication system for transmittal to the sender’s payment service provider.
    | PDP | +| **Payment System** | Payment Network, Money Transfer System | ncompasses all payment-related activities, processes, mechanisms, infrastructure, institutions and users in a country or a broader region (for example a common economic area). | ITU-T | +| **Payment System Operator** | Mobile Money Operator, Payment Service Provider | The entity that operates a payment system or scheme. | ITU-T | +| **Peer FSP** | | The counterparty financial service provider. | PDP | +| **PEP** | | Politically Exposed Person. Someone who has been entrusted with a prominent public function. A PEP generally presents a higher risk for potential involvement in bribery and corruption by virtue of their position and the influence that they may hold (for example, ‘senior foreign political figure', 'senior political figure', foreign official', and so on).| PDP | +| **Platform** | Payment Platform, Payment Platform Provider, Mobile Money Platform |A term used to describe the software or service used by a provider, a scheme, or a switch to manage end user accounts and to send and receive payment transactions. | ITU-T | +| **Posting** | Clearing | The act of the provider of entering a debit or credit entry into the end user's account record. | ITU-T | +| **Pre-approval** |Debit Authorization, Mandate |Pre-approval means that a Payer is allowing a specific Payee to withdraw funds without the Payer having to manually accept the payment transaction. The pre-approval can be valid one time, valid during a specific time period or valid until the Payer cancels the pre-approval.| PDP | +| **Prefunding** | | The process of adding funds to Vostro/Nostro accounts. | PDP | +| **Prepaid Cards** | |eMoney product for general purpose use where the record of funds is stored on the payment card (on magnetic stripe or the embedded integrated circuit chip) or a central computer system, and which can be drawn down through specific payment instructions to be issued from the bearer’s payment card. | ITU-T | +| **Processing of Personal/Consumer Data** | Processing of Personal/Consumer Data | Processing of personal/consumer data shall mean any operation or set of operations which is performed upon personal/consumer data, whether or not by automatic means, such as collection, recording, organization, storage, adaptation or alteration, retrieval, consultation, use, disclosure by transmission, dissemination or otherwise making available, alignment or combination, blocking, erasure or destruction. | PDP | +| **Processor** | Gateway | An enterprise that manages, on an out-sourced basis, various functions for a digital financial services provider. These functions may include transaction management, customer database management, and risk management. Processors may also do functions on behalf of payments systems, schemes, or switches. | ITU-T | +| **Promotion** | | FSP marketing initiative offering the user a transaction/service fee discount on goods or services. May be implemented through the use of a coupon. | PDP | +| **Pull Payments** | | A payment type which is initiated by the payee: typically, a merchant or payment acceptor, whose provider "pulls" the funds out of the payer's account at the payer's provider. | ITU-T | +| **Push Payments** | |A payment type which is initiated by the payer, who instructs their provider to debit their account and "push" the funds to the receiving payee at the payee's provider. | ITU-T | +| **Quote** | | Quote can be seen as the price for performing a hypothetical financial transaction. Some factors that can affect a Quote are Fees, FX rate, Commission, and Taxes. A Quote is usually guaranteed a short time period, after that the Quote expires and is no longer valid. | PDP | +| **Reconciliation** | | Cross FSP Reconciliation is the process of ensuring that two sets of records, usually the balances of two accounts, are in agreement between FSPs. Reconciliation is used to ensure that the money leaving an account matches the actual money transferred. This is done by making sure the balances match at the end of a particular accounting period. | PDP | +| **Recourse** | | Rights given to an end user by law, private operating rules, or specific agreements by providers, allowing end users the ability to do certain things (sometimes revoking a transaction) in certain circumstances. | ITU-T | +| **Refund** | | A repayment of a sum of money (i.e. repayment, reimbursement or rebate) to a customer returning the goods/services bought. | PDP | +| **Registration** | Enrollment, Agent Registration, User Creation, User On- Boarding | The process of opening a provider account. Separate processes are used for consumers, merchants’ agents, and so on | ITU-T | +| **Regulator** | | A governmental organization given power through national law to set and enforce standards and practices. Central Banks, Finance and Treasury Departments, Telecommunications Regulators, and Consumer Protection Authorities are all regulators involved in digital financial services. | ITU-T | +| **Reserve** | Prepare | Part of a 2-phase transfer operation in which the funds to be transferred are locked (the funds cannot be used for any purpose until either rolled back or committed). This is usually done for a predetermined duration, the expiration of which results in the reservation being rolled back.| PDP | +| **Reversal** | | The process of reversing a completed transfer. | PDP | +| **Risk Management** | Fraud Management | The practices that enterprises do to understand, detect, prevent, and manage various types of risks. Risk management occurs at providers, at payments systems and schemes, at processors, and at many merchants or payments acceptors.| ITU-T | +| **Risk-based Approach** | | A regulatory and/or business management approach that creates different levels of obligation based on the risk of the underlying transaction or customer. | ITU-T | +| **Roll back** | Reject | Roll back means that the electronic funds that were earlier reserved are put back in the original state. The financial transaction is cancelled. The electronic funds are no longer locked for usage.| PDP | +| **Rollback** | | The process of reversing a transaction - restoring the system (i.e. account balances affected by the transaction) to a previously defined state, typically to recover from an error and via an administrator-level user action. | PDP | +| **Rules** | | The private operating rules of a payments scheme, which bind the direct participants (either providers, in an open-loop system, or end users, in a closed-loop system). | ITU-T | +| **Saving and Investing** | | Keeping funds for future needs and financial return. | ITU-T | +| **Savings Products** | | An account at either a bank or non-bank provider, which stores funds with the design of helping end users save money. | ITU-T | +| **Scheme** | | A set of rules, practices and standards necessary for the functioning of payment services. | ITU-T | +| **Secure Element** | | A secure chip on a phone that can be used to store payment data. | ITU-T | +| **Security Access Code** | Security Access Code | A personal identification number (PIN), password/one-time password (OTP), biometric recognition, code or any other device providing a means of certified access to a customer’s account for the purposes of, among other things, initiating an electronic fund transfer. | PDP | +| **Security Level** | | Security specification of the system which defines effectiveness of risk protection. | ITU-T | +| **Sensitive Consumer Data** | Sensitive Consumer Data |Consumer Sensitive Data means any or all information that is used by a consumer to authenticate identity and gain authorization for performing mobile banking services, including but not limited to User ID, Password, Mobile PIN, Transaction PIN. Also includes data relating to religious or other beliefs, sexual orientation, health, race, ethnicity, political views, trades union membership, criminal record. | PDP | +| **Settlement** | Real Time Gross Settlement (RTGS) | An act that discharges obligations in respect of funds or securities transfers between two or more parties. | RI | +| **Settlement Instruction** | | Means an instruction given to a settlement system by a settlement system participant or by a payment clearing house system operator on behalf of a Central Bank settlement system participant to effect settlement of one or more payment obligations, or to discharge any other obligation of one system participant to another system participant.| PDP | +| **Settlement Obligation** | | Means an indebtedness that is owed by one settlement system participant to another as a result of one or more settlement instructions. | PDP | +| **Settlement System** | Net Settlement, Gross Settlement, RTGS | A system used to facilitate the settlement of transfers of funds, assets or financial instruments. Net settlement system: a funds or securities transfer system which settles net settlement positions during one or more discrete periods, usually at pre-specified times in the course of the business day. Gross settlement system: a transfer system in which transfer orders are settled one by one. | ITU-T | +| **Short Message Service** | | A service for sending short messages between mobile phones. | ITU-T | +| **SIM Card** | SIM ToolKit, Thin SIM | A smart card inside a cellular phone, carrying an identification number unique to the owner, storing personal data, and preventing operation if removed. A SIM Tool Kit is a standard of the GSM system which enables various value-added services. A "Thin SIM" is an additional SIM card put in a mobile phone. | ITU-T | +| **Smart Phone** | | A device that combines a mobile phone with a computer. | ITU-T | +| **Standards Body** | EMV, ISO, ITU, ANSI, GSMA | An organization that creates standards used by providers, payments schemes, and payments systems. | ITU-T | +| **Stored Value Account** | SVA | Account in which funds are kept in a secure, electronic format. May be a bank account or an eMoney account. | PDP | +| **Storing Funds** | Account, Wallet, Cash-In, Deposit | Converting cash into electronic money and keeping funds in secure electronic format. May be a bank account or an eMoney account. | PDP | +| **Super-Agent** | Master Agent | In some countries, agents are managed by Super Agents or Master Agents who are responsible for the actions of their agents to the provider. | ITU-T | +| **Supplier Payment** | B2B - Business to Business, B2G - Business to Government | Making a payment from one business to another for supplies, and so on: may be in-person or remote, domestic or cross border. Includes cross- border trade. | ITU-T | +| **Suspicious Transaction Report** | Suspicious Transaction Report | If a financial institution notes something suspicious about a transaction or activity, it may file a report with the Financial Intelligence Unit that will analyze it and cross check it with other information. The information on an STR varies by jurisdiction. | PDP | +| **Systemic Risk** | | In payments systems, the risk of collapse of an entire financial system or entire market, as opposed to risk associated with any one individual provider or end user. | ITU-T | +| **Tax Payment** | C2G, B2G |Making a payment from a consumer to a government, for taxes, fees, and so on | ITU-T | +| **Tokenization** | | The use of substitute a token ("dummy numbers") in lieu of "real" numbers, to protect against the theft and misuse of the "real" numbers. Requires a capability to map the token to the "real" number. | ITU-T | +| **Trading** | International Trade | The exchange of capital, goods, and services across international borders or territories. | ITU-T | +| **Transaction Accounts** | | Transaction account: broadly defined as an account held with a bank or other authorized and/or regulated service provider (including a non- bank) which can be used to make and receive payments. Transaction accounts can be further differentiated into deposit transaction accounts and eMoney accounts. Deposit transaction account: deposit account held with banks and other authorized deposit-taking financial institutions that can be used for making and receiving payments. Such accounts are known in some countries as current accounts, chequing accounts or other similar terms. | ITU-T | +| **Transaction Cost** | | The cost to a DFS provider of delivering a digital financial service. This could be for a bundle of services (for example, a "wallet") or for individual transactions. | ITU-T | +| **Transaction Request** | Payment Request | Transaction Request is a request sent by a Payee, meant for a Payer to transfer electronic funds to the Payee. The Transaction Request usually requires manual approval by the Payer to perform the financial transaction, but the Payee can also be pre-approved or a credential (usually OTP) can be sent as part of the transaction request for automatic validation and approval. | PDP | +| **Transfer** | | Generic term to describe any financial transaction where value is transferred from one account to another. | PDP | +| **Transfer Funds** | Sending or Receiving Funds | Making and receiving payments to another person. | ITU-T | +| **Transport Layer Security** | TLS, client authentication, mutual authentication | Transport Layer Security (TLS) is a cryptographic protocol that provides communications security over a computer network, used to secure point to point communication (Source: Wikipedia). | | +| **Trust Account** | Escrow, Funds Isolation, Funds Safeguarding, Custodian Account, Trust Account | A means of holding funds for the benefit of another party. eMoney Issuers are usually required by law to hold the value of end users' eMoney accounts at a bank, typically in a Trust Account. This accomplishes the goals of funds isolation and funds safeguarding. | ITU-T | +| **Trusted Execution Environment** | | A development execution environment that has security capabilities and meets certain security-related requirements. | ITU-T | +| **Ubiquity** | | The ability of a payer to reach any (or most) payees in their country, regardless of the provider affiliation of the receiving payee. Requires some type of interoperability. | ITU-T | +| **Unbanked** | Underbanked, Underserved| Unbanked people do not have a transaction account. Underbanked people may have a transaction account but do not actively use it. Underserved is a broad term referring to people who are the targets of financial inclusion initiatives. It is also sometimes used to refer to a person who has a transaction account but does not have additional DFS services. | ITU-T | +| **User ID** | | A unique identifier of a user. This may be an MSISDN, bank account, some form of DFSP-provided ID, national ID, and so on. In a transaction, money is generally addressed to a user ID and not directly to an account ID. | PDP | +| **USSD** | | A communication technology that is used to send text between a mobile phone and an application program in the network. | ITU-T | +| **Vostro Account** | | From the Payee's perspective: Payer FSP funds/accounts held/hosted at Payee FSP. | PDP | +| **Voucher** | | A monetary value instrument commonly used to transfer funds to customers (Payees) who do not have an account at the Payer's FSP. This could be Payees with no account or account at another FSP. | ITU-T | +| **Wallet** | eWallet | Repository of funds for an account. Relationship of Wallet to Account can be many to one. | PDP | +| **Whitelist** | | A list or register of entities (registered users) that are being provided a particular privilege, service, mobility, access or recognition, especially those that were initially blacklisted. Entities on the list will be accepted, approved and/or recognized. Whitelisting is the reverse of blacklisting, the practice of identifying entities that are denied, unrecognized, or ostracized. Where entities are registered users (or user accounts, if granularity allows) and services are informational (for example, balance check), transactional (for example, debit/credit) payments services or lifecycle (for example, registration, closure) services. | PDP | +| **'x'-initiated** | | Used when referring to the side that initiated a transaction; for example, agent-initiated cash-out vs. user-initiated cash-out. | PDP | diff --git a/website/versioned_docs/v1.0.1/api/fspiop/json-binding-rules.md b/website/versioned_docs/v1.0.1/api/fspiop/json-binding-rules.md new file mode 100644 index 000000000..a3f524c77 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/json-binding-rules.md @@ -0,0 +1,1286 @@ +--- +showToc: true +--- +# JSON Binding Rules + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +## Introduction + +The purpose of this document is to express the data model used by the Open API for FSP Interoperability (hereafter cited as "the API") in the form of JSON Schema binding rules, along with the validation rules for their corresponding instances. + +This document adds to and builds on the information provided in _Open API for FSP Interoperability Specification._ The contents of the Specification are listed in [FSPIOP API Overview](/). + +The types used in the PDP API fall primarily into three categories: + +- Basic data types and Formats used + +- Element types + +- Complex types + +The various types used in _API Definition_, _Data Model_ and the _Open API Specification_, as well as the JSON transformation rules to which their instances must adhere, are identified in the following sections. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](#) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Keywords and Usage + +The _keywords_ used in the JSON Schemas and rules are derived from _JSON Schema Specification_[1](http://json-schema.org/documentation.html). The types of keywords used are identified in [Validation Keywords](#validation-keywords), [Metadata Keywords](#metadata-keywords) and [Instance-and-$ref](#instance-and-$ref) sections. As discussed in detail later, some of these keywords specify validation parameters whereas others are more descriptive, such as Metadata. The description that follows specifies details such as whether a field MUST[2](https://www.ietf.org/rfc/rfc2119.txt) be present in the definition and whether a certain field is associated with a particular data type. + +### Validation Keywords + +This section[3](http://json-schema.org/latest/json-schema-validation.html) provides descriptions of the keywords used for validation in _API Definition_. Validation keywords in a schema impose requirements for successful validation of an instance. + +#### maxLength + +The value of this keyword MUST be a non-negative integer. A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. The length of a string instance is defined as the number of its characters as defined by RFC 7159[RFC7159]. + +#### minLength + +The value of this keyword MUST be a non-negative integer. A string instance is valid against this keyword if its length is greater than, or equal to, the value of this keyword. The length of a string instance is defined as the number of its characters as defined by RFC 7159[RFC7159]. Omitting this keyword has the same behaviour as assigning it a value of **0**. + +#### pattern + +The value of this keyword MUST be a string. This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect. A string instance is considered valid if the regular expression matches the instance successfully. Recall: regular expressions are not implicitly anchored. + +#### items + +The value of `items` MUST be either a valid JSON Schema or an array of valid JSON Schemas. This keyword determines how child instances validate for arrays; it does not directly validate the immediate instance itself. If `items` is a schema, validation succeeds if all elements in the array successfully validate against that schema. If `items` is an array of schemas, validation succeeds if each element of the instance validates against the schema at the same position, if such a schema exists. Omitting this keyword has the same behaviour as specifying an empty schema. + +#### maxItems + +The value of this keyword MUST be a non-negative integer. An array instance is valid against `maxItems` if its size is less than, or equal to, the value of this keyword. + +#### minItems + +The value of this keyword MUST be a non-negative integer. An array instance is valid against `minItems` if its size is greater than, or equal to, the value of this keyword. Omitting this keyword has the same behaviour as a value of **0**. + +#### required + +The value of this keyword MUST be an array. Elements of this array (if there are any) MUST be strings and MUST be unique. An object instance is valid against this keyword if every item in the array is the name of a property in the instance. Omitting this keyword results in the same behaviour as does having the array be empty. + +#### properties + +The value of `properties` MUST be an object. Each value of this object MUST be a valid JSON Schema. This keyword determines how child instances validate for objects; it does not directly validate the immediate instance itself. Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, the child instance for that name successfully validates against the corresponding schema. Omitting this keyword results in the same behaviour as does having an empty object. + +#### enum + +The value of this keyword MUST be an array. This array SHOULD have at least one element. Elements in the array SHOULD be unique. An instance validates successfully against this keyword if its value is equal to one of the elements in this keyword's array value. Elements in the array might be of any value, including null. + +#### type + +The value of this keyword MUST be either a string or an array. If it is an array, elements of the array MUST be strings and MUST be unique. String values MUST be one of the six primitive types (null, boolean, object, array, number, or string), or integer which matches any number with a zero-fractional part. An instance validates if and only if the instance is in any of the sets listed for this keyword. + +This specification uses string type for all basic types and element types, but enforces restrictions using regular expressions as `patterns`. Complex types are of object type and contain properties that are either element or object types in turn. Array types are used to specify lists, which are currently only used as part of complex types. + +### Metadata Keywords + +This section provides descriptions of the fields used in the JSON definitions of the types used. The description specifies whether a field MUST be present in the definition and specifies whether a certain field is associated with a primary data type. Validation keywords in a schema impose requirements for successful validation of an instance. + +#### definitions + +This keyword's value MUST be an object. Each member value of this object MUST be a valid JSON Schema. This keyword plays no role in validation. Its role is to provide a standardized location for schema authors to incorporate JSON Schemas into a more general schema. + +#### title and description + +The value of both keywords MUST be a string. Both keywords can be used to provide a user interface with information about the data produced by this user interface. A title will preferably be short, whereas a description will provide explanation about the purpose of the instance described in this schema. + +### Instance and $ref + +Two keywords, **Instance** and **$ref** are used in either the JSON Schema definitions or the transformation rules in this document, which are described in [Instance](#instance) and [Schema References with $ref](#schema-references-with-$ref-keyword) sections. `Instance` is not used in the Open API Specification; this term is used in this document to describe validation and transformation rules. `$ref` contains a URI value as a reference to other types; it is used in the Specification. + +#### Instance + +JSON Schema interprets documents according to a data model. A JSON value interpreted according to this data model is called an `instance`[4](http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2). An instance has one of six primitive types, and a range of possible values depending on the type: + +- **null**: A JSON `null` production. + +- **boolean**: A `true` or `false` value, from the JSON `true` or `false` productions. + +- **object**: An unordered set of properties mapping a string to an instance, from the JSON `object` production. + +- **array**: An ordered list of instances, from the JSON `array` production. + +- **number**: An arbitrary-precision, base-10 decimal number value, from the JSON `number` production. + +- **string**: A string of Unicode code points, from the JSON `string` production. + +Whitespace and formatting concerns are outside the scope of the JSON Schema. Since an object cannot have two properties with the same key, behaviour for a JSON document that tries to define two properties (the `member` production) with the same key (the `string` production) in a single object is undefined. + +#### Schema references with $ref keyword + +The `$ref`[5](http://json-schema.org/latest/json-schema-core.html\#rfc.section.8) keyword is used to reference a schema and provides the ability to validate recursive structures through self- reference. An object schema with a `$ref` property MUST be interpreted as a `"$ref"` reference. The value of the `$ref` property MUST be a URI Reference. Resolved against the current URI base, it identifies the URI of a schema to use. All other properties in a `"$ref"` object MUST be ignored. + +The URI is not a network locator, only an identifier. A schema need not be downloadable from the address if it is a network- addressable URL, and implementations SHOULD NOT assume they should perform a network operation when they encounter a network-addressable URI. A schema MUST NOT be run into an infinite loop against a schema. For example, if two schemas "#alice" and "#bob" both have an "allOf" property that refers to the other, a naive validator might get stuck in an infinite recursive loop trying to validate the instance. Schemas SHOULD NOT make use of infinite recursive nesting like this; the behavior is undefined. + +It is used with the syntax `"$ref"` and is mapped to an existing definition. From the syntax, the value part of `_$ref_`, `#/definitions/`, indicates that the type being referenced is from the Definitions section of the Open API Specification (Typically, an Open API Specification has sections named Paths, Definitions, Responses and Parameters.). An example for this can be found in [Listing 26](#listing-26), where the types for properties _authentication_ and _authenticationValue_ are provided by using references to `Authenticationtype` and `AuthenticationValue` types, respectively. + +### JSON Definitions and Examples + +JSON definitions and examples are provided after most sections defining the transformation rules, where relevant. These are provided in JSON form, taken from the JSON version of the Open API Specification. The Regular Expressions in the examples may have minor differences (sometimes having an additional '**\\**' symbol) when compared to the ones in rules and descriptions because the regular expressions in the examples are taken from the JSON version whereas the rules and descriptions are from the standard Open API (Swagger) Specification. They are provided in the relevant section as a numbered Listing. For example, [Listing 1](#listing-1) provides the JSON representation of the definition of data type `Amount`. + +For each of the data types, a description of the JSON Schema from the Open API Specification and (where relevant) an example of that type are provided. Following the Schema description are transformation rules that apply to an instance of that particular type. + +
    + +## Element and Basic Data Types + +This section contains the definitions of and transformation rules for the basic formats and _element_ types used by the API as specified in _API Definition_ and _API Data Model_. These definitions are basic in the context of the API specification, but *not* the Open API Technical Specification. Often, these basic data types are derived from the basic types supported by Open API Specification standards, such as string type. + +### Data Type Amount + +This section provides the JSON Schema definition for the data type `Amount`. [Listing 1](#listing-1) provides a JSON Schema for the `Amount` type. + +- JSON value pair with Name "**title**" and Value "**Amount**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^(\[0\]\|(\[1-9\]\[0-9\]{0,17}))(\[.\]\[0-9\]{0,3}\[1-9\])?\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.**" + +##### Listing 1 + + +```JSON +"Amount": { + "title": "Amount", + "type": "string", + "pattern": + "^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$", + "maxLength": 32, + "description": "The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons." +} +``` +**Listing 1 -- JSON Schema for Data type Amount** + +The transformation rules for an instance of Amount data type are as follows: + +- A given Instance of `Amount` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\[0\]\|(\[1-9\]\[0-9\]{0,17}))(\[.\]\[0-9\]{0,3}\[1-9\])?\$** + +- The length of this instance is restricted by the regular expression above as 23, with 18 digits in the major currency unit and four digits in the minor currency unit. Valid example values for Amount type: **124.45**, **5, 5.5, 4.4444, 0.5, 0, 181818181818181818** + +### Data Type BinaryString + +This section provides the JSON Schema definition for the data type BinaryString. [Listing 2](#listing-2) provides a JSON Schema for the BinaryString type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BinaryString**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$**" + +- JSON value pair with Name "**description**" and Value the content of Property **description** + +##### Listing 2 + +```JSON +"BinaryString":{ + "title":"BinaryString", + "type":"string", + "pattern":"^[A-Za-z0-9-_]+[=]{0,2}$", + "description":"The API data type BinaryString is a JSON String. The string is the base64url encoding of a string of raw bytes, where padding (character '=') is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters. +} +``` +**Listing 2 -- JSON Schema for Data type BinaryString** + +The section on [BinaryString Type IlpPacket](#binarystring-type-ilppacket) gives an example for `BinaryString` type. + +The transformation rules for an instance of `BinaryString` data type are as follows: + +- A given Instance of `BinaryString` type MUST be of string type. +- The instance MUST be a match for the regular expression **^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$** + +An example value for `BinaryString` type is + +``` +AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgyOVc4bXFmNEpLMHlGTFGCAUBQU0svMS4wCk5vbmNlOiB1SXlweUYzY3pYSXBFdzVVc05TYWh3CkVuY3J5cHRpb246IG5vbmUKUGF5bWVudC1JZDogMTMyMzZhM2ItOGZhOC00MTYzLTg0NDctNGMzZWQzZGE5OGE3CgpDb250ZW50LUxlbmd0aDogMTM1CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbgpTZW5kZXItSWRlbnRpZmllcjogOTI4MDYzOTEKCiJ7XCJmZWVcIjowLFwidHJhbnNmZXJDb2RlXCI6XCJpbnZvaWNlXCIsXCJkZWJpdE5hbWVcIjpcImFsaWNlIGNvb3BlclwiLFwiY3JlZGl0TmFtZVwiOlwibWVyIGNoYW50XCIsXCJkZWJpdElkZW50aWZpZXJcIjpcIjkyODA2MzkxXCJ9Ig +``` + +#### BinaryString Type IlpPacket + +This section provides the JSON Schema definition for the `BinaryString` type `IlpPacket`. [Listing 3](listing-3) provides a JSON Schema for the IlpPacket type. The transformation rules for an instance of `IlpPacket` are the same as those of data type `BinaryString`. + + - JSON value pair with Name "**title**" and Value "**IlpPacket**" + + - JSON value pair with Name "**type**" and Value "**string**" + + - JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]+\[=\]{0,2}\$**" + + - JSON value pair with Name "**minLength**" and Value **1** + + - JSON value pair with Name "**pattern**" and Value **32768** + + - JSON value pair with Name "**description**" and Value "**Information for recipient (transport layer information).**" + +##### Listing 3 + +```json +"IlpPacket":{ + "title":"IlpPacket", + "type":"string", + "pattern":"^[A-Za-z0-9-_]+[=]{0,2}$", + "minLength":1 + "maxLength":32768 + "description":"Information for recipient (transport layer information)." +} +``` + +**Listing 3 -- JSON Schema for BinaryString type IlpPacket** + +### Data Type BinaryString32 + +This section provides the JSON Schema definition for the data type `BinaryString32`. [Listing 4](#listing-4) provides a JSON Schema for the `BinaryString32` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BinaryString32**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]{43}\$**" + +- JSON value pair with Name "**description**" and Value the content of Property **description** + +##### Listing 4 + +```json +"BinaryString32":{ + "title":"BinaryString32", + "type":"string", + "pattern":"^[A-Za-z0-9-_]{43}$", + "description":"The API data type BinaryString32 is a fixed size version of the API data type BinaryString, where the raw underlying data is always of 32 bytes. The data type BinaryString32 should not use a padding character as the size of the underlying data is fixed." +} +``` + +**Listing 4 -- JSON Schema for Data type BinaryString32** + +The section on [BinaryString32 Type IlpCondition](#binarystring32-type-ilpcondition) gives an example for `BinaryString32` type. Another example in the API of `BinaryString32` type is `IlpFulfilment`. The transformation rules for an instance of `BinaryString32` data type are as follows: + +- A given Instance of `BinaryString32` type MUST be of string type. + +- The instance MUST be a match for the regular expression "**^\[A-Za-z0-9-\_\]{43}\$**". + +An example value for `BinaryString32` type is: + +``` +AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgyOVc4bXFmNEpLMHlGTFGCAUBQU0svMS4wCk5vbmNlOiB1SXlweUYzY3pYSXBFdzVVc05TYWh3CkVuY3J5cHRpb246IG5vbmUKUGF5bWVudC1JZDogMTMyMzZhM2ItOGZhOC00MTYzLTg0NDctNGMzZWQzZGE5OGE3CgpDb250ZW50LUxlbmd0aDogMTM1CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbgpTZW5kZXItSWRlbnRpZmllcjogOTI4MDYzOTEKCiJ7XCJmZWVcIjowLFwidHJhbnNmZXJDb2RlXCI6XCJpbnZvaWNlXCIsXCJkZWJpdE5hbWVcIjpcImFsaWNlIGNvb3BlclwiLFwiY3JlZGl0TmFtZVwiOlwibWVyIGNoYW50XCIsXCJkZWJpdElkZW50aWZpZXJcIjpcIjkyODA2MzkxXCJ9IgA +``` + +#### BinaryString32 Type IlpCondition + +This section provides the JSON Schema definition for the `BinaryString32` type `IlpCondition`. [Listing 5](#listing-5) provides a JSON Schema for the `IlpCondition` type. The transformation rules for an instance of `IlpCondition` are the same as those of data type `BinaryString32`. + +- JSON value pair with Name "**title**" and Value "**IlpCondition**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Za-z0-9-\_\]{43}\$**" + +- JSON value pair with Name "**maxLength**" and Value **48** + +- JSON value pair with Name "**description**" and Value "**Condition that must be attached to the transfer by the Payer.**" + +##### Listing 5 + +```json +"IlpCondition":{ + "title":"IlpCondition", + "type":"string", + "pattern":"^[A-Za-z0-9-_]{43}$", + "maxLength":48, + "description":"Condition that must be attached to the transfer by the Payer." +} +``` + +**Listing 5 -- JSON Schema for BinaryString32 type IlpCondition** + +### Data Type BopCode + +This section provides the JSON Schema definition for the data type `BopCode`. [Listing 6](#listing-6) provides a JSON Schema for the `BopCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**BalanceOfPayments**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\\d{2}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type BopCode is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/).**" + +#### Listing 6 + +```json +"BalanceOfPayments":{ + "title":"BalanceOfPayments", + "type":"string", + "pattern":"^[1-9]\d{2}$", + "description":"(BopCode) The API data type BopCode is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. https://www.imf.org/external/np/sta/bopcode/" +} +``` + +**Listing 6 -- JSON Schema for Data type BopCode** + +The transformation rules for an instance of `BopCode` data type are as follows: + +- A given Instance of `BopCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\\d{2}\$**. + +An example value for `BopCode` type is **124**. + +### Data Type Enum + +This section provides the JSON Schema definition for the data type `Enum`. These are generic characteristics of an `Enum` type, alternately known as `CodeSet`. [Listing 8](#listing-8) provides an example JSON Schema for the data type Enumeration (CodeSet). + +- CodeSet.Name is the name of the JSON object. + +- JSON value pair with Name "**title**" and Value "**CodeSet.Name**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**enum**" and Value the array containing all the CodeSetLiteral values of the CodeSet + +- If Property description is not empty, JSON value pair with Name "**description**" and Value the content of Property description An example for Enum/CodeSet type -- "AmountType" can found in the [Enumeration AmountType](#enumeration-amounttype) section. [Listing 7](#listing-7) lists the other Enum types defined and used in the API. + +##### Listing 7 + +``` +AuthenticationType, AuthorizationResponse, BulkTransferState, Currency, PartyIdentifier, PartyIdType, PartySubIdOrType , PersonalIdentifierType, TransactionInitiator, TransactionInitiatorType, TransactionRequestState, TransactionScenario, TransactionState, TransferState. +``` + +**Listing 7 -- List of Enum types specified and used in the API** + +The transformation rules for an instance of Enum data type are as +follows: + +- A given Instance of `Enum` type MUST be of string type. + +- The instance MUST be one of the values specified in the `CodeSetLiteral` values. + +#### Enumeration AmountType + +This section provides the JSON Schema definition for the Enum type `AmountType`. [Listing 8](#listing-8) provides a JSON Schema for the `AmountType` type. + +- CodeSet.Name "**AmountType**" + +- JSON value pair with Name "**title**" and Value "**AmountType**" + +- JSON value pair with Name "**type**"and Value "**string**" + +- JSON value pair with Name **description** and Value "**_Below are the allowed values for the enumeration AmountType_** + - **_SEND The amount the Payer would like to send, i.e. the amount that should be withdrawn from the Payer account including any fees._** + - **_RECEIVE The amount the Payer would like the Payee to receive, i.e. the amount that should be sent to the receiver exclusive fees._**" + +- JSON value pair with Name **enum** and Value the array containing the values: + + → **SEND** + + → **RECEIVE** + +###### Listing 8 + +```json +"AmountType":{ + "title":"AmountType", + "type":"string", + "enum":[ + "SEND", + "RECEIVE" + ], + "description":"Below are the allowed values for the enumeration AmountType - SEND The amount the Payer would like to send, i.e. the amount that should be withdrawn from the Payer account including any fees. - RECEIVE The amount the Payer would like the Payee to receive, i.e. the amount that should be sent to the receiver exclusive fees." +} +``` + +**Listing 8 -- JSON Schema for Enumeration Type AmountType** + +The transformation rules for an instance of `AmountType` data type are as follows (same as those of Data Type Enum, but listing the rules here to demonstrate a valid set of literal values): + +- A given Instance of AmountType type MUST be of string type. + +- The instance MUST be one of the values defined in the set: {"**SEND**", "**RECEIVE**"}. + +An example value for `AmountType` type is "**SEND**". + +### Data Type Date + +This section provides the JSON Schema definition for the data type `Date`. [Listing 9](#listing-9) provides a JSON Schema for the `Date` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Date**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Date is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601 containing a date only. A more readable version of the format is "yyyy-MM-dd", e.g. "1982-05-23" or "1987-08- 05"**." + +##### Listing 9 + +```json +"Date": { + "title": "Date", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$", + "description": "The API data type Date is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601 containing a date only. A more readable version of the format is “yyyy-MM-dd”, e.g. "1982-05-23" or "1987-08-05”." +} +``` + +**Listing 9 -- JSON Schema for Data type Date** + +The transformation rules for an instance of `Date` data type are as follows: + +- A given Instance of `Date` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**. + +An example value for `Date` type is **1971-12-25**. + +#### Data Type DateOfBirth + +This section provides the JSON Schema definition for the Date type `DateOfBirth`. [Listing 10](#listing-10) provides a JSON Schema for the `DateOfBirth` type. The transformation rules for an instance of `DateOfBirth` are the same as those of data type `Date`. + +- JSON value pair with Name "**title**" and Value "**DateOfBirth (type Date)**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**description**" and Value "**Date of Birth for the Party**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)\$**" + +##### Listing 10 + +```json +"DateOfBirth": { + "title": "DateOfBirth (type Date)", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$", + "description": "Date of Birth for the Party." +} +``` + +**Listing 10 -- JSON Schema for Date type DateOfBirth** + +### Data Type DateTime + +The JSON Schema definition for this section provides the JSON Schema definition for the data type `DateTime`. [Listing 11](#listing-11) provides a JSON Schema for the `DateTime` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**DateTime**" + +- JSON value pair with Name "**pattern**" and Value "**^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0- 8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1- 9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)T(?:\[01\]\\d\|2\[0-3\]):\[0-5\]\\d:\[0-5\]\\d(?:(\\.\\d{3}))(?:Z\|\[+-\]\[01\]\\d:\[0-5\]\\d)\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601, expressed in a combined date, time and time zone format. A more readable version of the format is "yyyy-MM-ddTHH:mm:ss.SSS\[-HH:MM\]", e.g. \"2016-05-24T08:38:08.699-04:00\" or \"2016-05-24T08:38:08.699Z\" (where Z indicates Zulu time zone, same as UTC)**." + +##### Listing 11 + +```json +"DateTime": { + "title":"DateTime", + "type": "string", + "pattern": "^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\\d)$", + "description": "The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. This format is according to ISO 8601, expressed in a combined date, time and time zone format. A more readable version of the format is “yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]”, e.g. "2016-05-24T08:38:08.699-04:00" or "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC)." +} +``` + +**Listing 11 -- JSON Schema for Data type DateTime** + +The transformation rules for an instance of DateTime data type are as follows: + +- A given Instance of type `DateTime` MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?:\[1-9\]\\d{3}-(?:(?:0\[1-9\]\|1\[0-2\])-(?:0\[1-9\]\|1\\d\|2\[0-8\])\|(?:0\[13-9\]\|1\[0-2\])-(?:29\|30)\|(?:0\[13578\]\|1\[02\])-31)\|(?:\[1-9\]\\d(?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\])\|(?:\[2468\]\[048\]\|\[13579\]\[26\])00)-02-29)T(?:\[01\]\\d\|2\[0-3\]):\[0-5\]\\d:\[0-5\]\\d(?:(\\.\\d{3}))(?:Z\|\[+-\]\[01\]\\d:\[0-5\]\\d)\$**. + +An example value for `DateTime` type is **2016-05-24T08:38:08.699-04:00**. + +### Data Type ErrorCode + +This section provides the JSON Schema definition for the data type `ErrorCode`. [Listing 12](#listing-12) provides a JSON Schema for the `ErrorCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**ErrorCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\\d{3}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type ErrorCode is a JSON String of 4 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Specific error number in the form _{C}{E}{SS}_ where _{C}_ is a one-digit category _{E}_ is a one-digit error within the category _{SS}_ is a scheme defined two-digit sub-error within the error. Please refer to x.x for the list of the possible category/error codes**". + +##### Listing 12 + +```json +"ErrorCode": { + "title": "ErrorCode", + "type": "string", + "pattern": "^[1-9]\d{3}$", + "description": "The API data type ErrorCode is a JSON String of 4 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Specific error number in the form {C}{E}{SS} where {C} is a one-digit category {E} is a one-digit error within the category {SS} is a scheme defined two-digit sub-error within the error. Please refer to x.x for the list of the possible category/error codes" +} +``` + +**Listing 12 -- JSON Schema for Data type ErrorCode** + +The transformation rules for an instance of `ErrorCode` data type are as follows: + +- A given Instance of `ErrorCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\d{3}\$**. + +An example value for `ErrorCode` type is **5100**. + +### Data Type Integer + +This section provides the JSON Schema definition for the data type `Integer`. [Listing 13](#listing-13) provides a JSON Schema for the Integer type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Integer**" + +- JSON value pair with Name "**pattern**" and Value "**^\[1-9\]\d\*\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Integer is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits.**" + +##### Listing 13 + +```json +"Integer": { + "title": "Integer", + "type": "string", + "pattern": "^[1-9]\d*$", + "description": "The API data type Integer is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits." +} +``` + +**Listing 13 -- JSON Schema for Data type Integer** + +The transformation rules for an instance of `Integer` data type are as follows: + +- A given Instance of Integer type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[1-9\]\d\*\$**. + +An example value for `Integer` type is **12345**. + +### Data Type Latitude + +This section provides the JSON Schema definition for the data type `Latitude`. [Listing 14](#listing-14) provides a JSON Schema for the `Latitude` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Latitude**" + +- JSON value pair with Name "**pattern**" and Value "**^(\\+\|-)?(?:90(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-8\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons**". + +##### Listing 14 + +```json +"Latitude": { + "title": "Latitude", + "type": "string", + "pattern": "^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$", + "description": "The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons." +} +``` + +**Listing 14 -- JSON Schema for Data type Latitude** + +The transformation rules for an instance of `Latitude` data type are as follows: + +- A given Instance of `Latitude` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\\+\|-)?(?:90(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-8\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**. + +An example value for `Latitude` type is **+45.4215**. + +### Data Type Longitude + +This section provides the JSON Schema definition for the data type `Longitude`. [Listing 15](#listing-15) provides a JSON Schema for the `Longitude` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Longitude**" + +- If Property pattern is not empty, JSON value pair with Name "**pattern**" and Value "**^(\\+\|-)?(?:180(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-9\]\[0-9\]\|1\[0-7\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**". + +- JSON value pair with Name "**description**" and Value "**The API data type Longitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons.**" + +##### Listing 15 + +```json +"Longitude": { + "title": "Longitude", + "type": "string", + "pattern": "^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$", + "description": "The API data type Longitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons." +} +``` + +**Listing 15 -- JSON Schema for Data type Longitude** + +The transformation rules for an instance of `Longitude` data type are as follows: + +- A given Instance of `Longitude` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(\\+\|-)?(?:180(?:(?:\\.0{1,6})?)\|(?:\[0-9\]\|\[1-9\]\[0-9\]\|1\[0-7\]\[0-9\])(?:(?:\\.\[0-9\]{1,6})?))\$**. + +An example value for `Longitude` type is **+75.6972**. + +### Data Type MerchantClassificationCode + +This section provides the JSON Schema definition for the data type `MerchantClassificationCode`. [Listing 16](#listing-16) provides a JSON Schema for the `MerchantClassificationCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**MerchantClassificationCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[\\d\]{1,4}\$**". + +- JSON value pair with Name "**description**" and Value "**A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.**" + +##### Listing 16 + +```json +"MerchantClassificationCode": { + "title": "MerchantClassificationCode", + "type": "string", + "pattern": "^[\d]{1,4}$", + "description": "A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc." +} +``` + +**Listing 16 -- JSON Schema for Data type MerchantClassificationCode** + +The transformation rules for an instance of `MerchantClassificationCode` data type are as follows: + +- A given Instance of `MerchantClassificationCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[\\d\]{1,4}\$**. + +An example value for `MerchantClassificationCode` type is **99**. + +### Data Type Name + +This section provides the JSON Schema definition for the data type `Name`. [Listing 17](#listing-17) provides the JSON Schema for a `Name` type. [Name Type Firstname](#name-type-firstname) contains an example of `Name` type -- "First Name". Other Name types used in the API are "Middle Name" and "Last Name". + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**Name**" + +- JSON value pair with Name "**minLength**" and Value the content of Property **minLength** + +- JSON value pair with Name "**maxLength**" and Value the content of Property **maxLength** + +- JSON value pair with Name "**pattern**" and Value "**^(?!\\\\s\*\$)\[\\\\w .,'-\]+\$**". + +- JSON value pair with Name "**description**" and Value "**The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. The restriction will not allow a string consisting of whitespace only, all Unicode characters should be allowed, as well as the characters ".", "'" (apostrophe), "-", "," and " " (space). Note - In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag UNICODE\_CHARACTER\_CLASS needs to be enabled to allow Unicode characters.**" + +##### Listing 17 + +```json +"Name": { + "title": "Name", + "type": "string", + "pattern": "^(?!\\s*$)[\\w .,'-]+$", + "description": "The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. The restriction will not allow a string consisting of whitespace only, all Unicode characters should be allowed, as well as the characters ".", "'" (apostrophe), "- ", "," and " " (space). Note - In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag UNICODE_CHARACTER_CLASS needs to be enabled to allow Unicode characters." +} +``` + +**Listing 17 -- JSON Schema for Data type Name** + +The transformation rules for an instance of `Name` data type are as follows: + +- A given Instance of `Name` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^(?!\\\\s\*\$)\[\\\\w .,'-\]+\$**. + +An example value for `Name` type is **Bob**. + +#### Name Type FirstName + +This section provides the JSON Schema definition for the `Name` type `FirstName`. [Listing 18](#listing-18) provides a JSON Schema for the `FirstName` type. The transformation rules for an instance of `FirstName` are the same as those of data type `Name`. + +- JSON value pair with Name "**title**" and Value "**FirstName**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^(?!\\s\*\$)\[\\w .,\'-\]+\$**" + +- JSON value pair with Name "**maxLength**" and Value **128** + +- JSON value pair with Name "**minLength**" and Value **1** + +- JSON value pair with Name "**description**" and Value "**First name of the Party (Name type).**" + +##### Listing 18 + +```json +"FirstName": { + "title": "FirstName", + "type": "string", + "minLength": 1, + "maxLength": 128, + "pattern": "^(?!\s*$)[\w .,'-]+$", + "description": "First name of the Party (Name Type)." +} +``` + +**Listing 18 -- JSON Schema for Name type FirstName** + +### Data Type OtpValue + +This section provides the JSON Schema definition for the data type `OtpValue`. [Listing 19](#listing-19) provides a JSON Schema for the `OtpValue` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**OtpValue**" + +- JSON value pair with Name "**pattern**" and Value "**^\\d{3,10}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type OtpValue is a JSON String of 3 to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed.**" + +##### Listing 19 + +```json +"OtpValue": { + "title": "OtpValue", + "type": "string", + "pattern": "^\d{3,10}$", + "description": "The API data type OtpValue is a JSON String of 3 to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed." +} +``` + +**Listing 19 -- JSON Schema for Data type OtpValue** + +The transformation rules for an instance of `OtpValue` data type are as follows: + +- A given Instance of `OtpValue` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\\d{3,10}\$**. + +An example value for `OtpValue` type is **987345**. + +### Data Type String + +This section provides the JSON Schema definition for the data type `String`. [Listing 21](#listing-21) provides an example JSON Schema for a `String` type. + +- **String.Name** is the name of the JSON object. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**String.Name**" + +- JSON value pair with Name "**minLength**" and Value the content of Property "**minLength**" + +- JSON value pair with Name "**maxLength**" and Value the content of Property "**maxLength**" + +- If Property pattern is not empty, JSON value pair with Name **pattern** and Value the content of Property **pattern**. + +- JSON value pair with Name "**description**" and Value the content of Property **description**. [Below](#string-type-errordescription), is an example for Stri`ng type, `ErrorDescription`. [Listing 20](#listing-20) has other `String` types specified and used in the API. + +##### Listing 20 + +``` +AuthenticationValue, ExtensionKey, ExtensionValue, FspId, Note, PartyName, QRCODE, RefundReason, TransactionSubScenario. +``` + +**Listing 20 -- String types specified and used in the API** + +The transformation rules for an instance of `String` data type are as follows: + +- A given Instance of `String` type MUST be of string type. + +- The length of this instance MUST not be greater than the **maxLength** specified. + +- The length of this instance MUST not be less than the **minLength** specified. + +- The instance MUST be a match for the regular expression specified by a **pattern** property if one is specified. + +An example value for `String` type is **Financial Services for the Poor**. + +### String Type ErrorDescription + +This section provides the JSON Schema definition for the `String` type `ErrorDescription`. [Listing 21](#listing-21) provides a JSON Schema for the `ErrorDescription` type. + +- JSON value pair with Name "**title**" and Value "**ErrorDescription**" + +- JSON value pair with Name "**type**" and Value "**ErrorDescription**" + +- JSON value pair with Name "**description**" and Value "**Error description string**" + +- JSON value pair with Name "**minLength**" and Value **1** + +- JSON value pair with Name "**maxLength**" and Value **128** + +##### Listing 21 + +```json +"ErrorDescription": { + "title": "ErrorDescription", + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "Error description string." +} +``` + +**Listing 21 -- JSON Schema for Data type ErrorDescription** + +The transformation rules for an instance of `ErrorDescription` data type are as follows (same as those of `Data` Type String, but listing the rules here to demonstrate a valid set of values for length properties): + +- A given Instance of `ErrorDescription` type MUST be of String Type. + +- The length of this instance MUST not be greater than 128. + +- The length of this instance MUST not be less than 1. + +An example value for `ErrorDescription` type is **This is an error description**. + +### Data Type TokenCode + +This section provides the JSON Schema definition for the data type `TokenCode`. [Listing 22](#listing-22) provides a JSON Schema for the `TokenCode` type. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and Value "**TokenCode**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-zA-Z\]{4,32}\$**" + +- JSON value pair with Name "**description**" and Value "**The API data type TokenCode is a JSON String between 4 and 32 characters, consisting of digits or characters from a to z (case insensitive).**" + +##### Listing 22 + +```json +"TokenCode": { + "title": "TokenCode", + "type": "string", + "pattern": "^[0-9a-zA-Z]{4,32}$", + "description": "The API data type TokenCode is a JSON String between 4 and 32 characters, consisting of digits or characters from a to z (case insensitive)." +} +``` + +**Listing 22 -- JSON Schema for Data type TokenCode** + +The transformation rules for an instance of `TokenCode` data type are as follows: + +- A given Instance of `TokenCode` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[0-9a-zA-Z\]{4,32}\$**. + +An example value for `TokenCode` type is **Test-Code**. + +#### TokenCode Type Code + +This section provides the JSON Schema definition for the `TokenCode` type `Code`. [Listing 23](#listing-23) provides a JSON Schema for the `Code` type. The transformation rules for an instance of `Code` are the same as those of Data Type `TokenCode`. + +- JSON value pair with Name "**title**" and Value "**Code**" + +- JSON value pair with Name "**type**" and Value "**String**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-zA-Z\]{4,32}\$**" + +- JSON value pair with Name "**description**" and Value "**Any code/token returned by the Payee FSP (TokenCode type).**" + +##### Listing 23 + +```json +"Code": { + "title": "Code", + "type": "string", + "pattern": "^[0-9a-zA-Z]{4,32}$", + "description": "Any code/token returned by the Payee FSP (TokenCode Type)." +} +``` + +**Listing 23 -- JSON Schema for TokenCode type Code** + +### Data Type UndefinedEnum + +This section provides the JSON Schema definition for the data type `UndefinedEnum`. [Listing 24](#listing-24) provides the JSON Schema for the data type `UndefinedEnum` (Enumeration). + +- JSON value pair with Name "**title**" and Value "**UndefinedEnum**" + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**pattern**" and Value "**^\[A-Z\_\]{1,32}\$**" + +- If Property description is not empty, JSON value pair with Name "**description**" and Value "**The API data type UndefinedEnum is a JSON String consisting of 1 to 32 uppercase characters including "\_" (underscore).**" + +##### Listing 24 + +```json +"UndefinedEnum": { + "title": "UndefinedEnum", + "type": "string", + "pattern": "^[A-Z_]{1,32}$", + "description": "The API data type UndefinedEnum is a JSON String consisting of 1 to 32 uppercase characters including "_" (underscore)." +} +``` + +**Listing 24 -- JSON Schema for Data type UndefinedEnum** + +The transformation rules for an instance of `UndefinedEnum` data type are as follows: + +- A given Instance of UndefinedEnum type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[A-Z\_\]{1,32}\$**. + +An example value for `UndefinedEnum` type depends on the list of values specified. + +### Data Type UUID + +This section provides the JSON Schema definition for the data type `UUID`. [Listing 25](#listing-25) provides a JSON Schema for `CorrelationId` which is of `UUID` type. Since `CorrelationId` is an element type in the *API Definition*, it is being used interchangeably with `UUID` in the Open API Specification version. + +- JSON value pair with Name "**type**" and Value "**string**" + +- JSON value pair with Name "**title**" and "**Value CorrelationId**" + +- JSON value pair with Name "**pattern**" and Value "**^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[1-5\]\[0-9a-f\]{3}-\[89ab\]\[0-9a-f\]{3}-\[0-9a- f\]{12}\$**" + +- JSON value pair with Name "**description**" and Value "**Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122, that is restricted by a regular expression for interoperability reasons. An example of a UUID is "b51ec534-ee48-4575-b6a9-ead2955b8069". An UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes ("-").**" + +##### Listing 25 + +```json +"CorrelationId": { + "title": "CorrelationId", + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a- f]{12}$", + "description": "Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122, that is restricted by a regular expression for interoperability reasons. An example of a UUID is "b51ec534-ee48-4575-b6a9- ead2955b8069". An UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes ("-")." +} +``` + +**Listing 25 -- JSON Schema for Data type UUID** + +The transformation rules for an instance of `UUID` data type are as follows: + +- A given Instance of `UUID` type MUST be of string type. + +- The instance MUST be a match for the regular expression **^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[1-5\]\[0-9a-f\]{3}-\[89ab\]\[0-9a- f\]{3}-\[0-9a-f\]{12}\$**. + +An example value for `UUID` type is **b51ec534-ee48-4575-b6a9-ead2955b8069**. + +## Complex Types + +This section contains definitions of and transformation characteristics for complex types that are used by the API. Along with the complex types defined in the [API Definition]() and [Data Model]() documents, there are other complex types defined in the PDP Open API Specification based on the objects present in several requests and responses in the **body** section. These are discussed in the [Types of Objects in Requests or Responses](#types-of-objects-in-requests-or-responses) section. + +### Complex Type Definition, Transformation + +This section provides the JSON Schema definition for a complex type. [Listing 26](#listing-26) provides an example JSON Schema for a complex type, `AuthenticationInfo`. Transformation rules specific to a complex type are listed [here](#complex-type-authenticationinfo). + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**complextype.Name**" + +- If Property **description** is not empty, JSON value pair with Name "**description**" and Value the content of Property **description**. + +- An array with Name "**required**" and Value the list of properties that MUST be present in an instance of complex type. + +- A JSON object **properties** with the following content: + + - A list of key, value pairs with Name **key.Name** and Value of element, complex or Array type + + - JSON value pair with Name **$ref** and as Value the concatenation of **#/definitions/** with **key.Type** type. An example for a complex type is provided under the [Complex Type AuthenticationInfo](#complex-type-authenticationinfo) section. + +#### Complex Type AuthenticationInfo + +This section provides the JSON Schema definition for the complex type `AuthenticationInfo` can be expressed as follows. [Listing 26](#listing-26) provides the JSON Schema for `AuthenticationInfo`. + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**AuthenticationInfo**" + +- JSON value pair with Name "**description**" and Value "**complex type AuthenticationInfo**" + +- An array with Name "**required**" and as Value a list with elements "**authentication**" and "**authenticationValue**" + +- A JSON object **properties** with the following content: + + - A JSON object **authentication** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the concatenation of **#/definitions/** with Authenticationtype type. + + - A JSON object **authenticationValue** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the concatenation of **#/definitions/** with AuthenticationValue type. + +##### Listing 26 + +```json +"AuthenticationInfo": { + "title": "AuthenticationInfo", + "type": "object", + "description": "complex type AuthenticationInfo", + "properties": { + "authentication": { + "$ref": "#/definitions/AuthenticationType", + "description": "The type of authentication." + }, + "authenticationValue":\ { + "$ref": "#/definitions/AuthenticationValue", + "description": " The authentication value." + } + }, + "required": [ + "authentication", + "authenticationValue" + ] +} +``` + +**Listing 26 -- JSON Schema for complex type AuthenticationInfo** + +The transformation rules for an instance of `AuthenticationInfo` complex type are as follows: + +- A given Instance of AuthenticationInfo type MUST be of `Object` type. + +- The instance MUST contain a property with name **authentication**. + +- The JSON object titled **authentication** MUST be an instance of AuthenticationType type, provided in the definitions. + +- The instance MUST contain a property with name **authenticationValue**. + +- The JSON object titled **authenticationValue** MUST be an instance of AuthenticationValue type, provided in the definitions. An example instance for AuthenticationInfo complex type is given in [Listing 27](#listing-27). + +##### Listing 27 + +```json +"authenticationInfo": { + "authentication": "OTP", + "authenticationValue": "1234" +} +``` + +**Listing 27 -- Example instance of AuthenticationInfo complex type** + +#### Complex Types in the API + +The examples for complex type from the API appear in [Listing 28](#listing-28). The list includes complex types defined in [API Definition]() and [Data Model]() documents and does not contain the complex types defined only in the Open API version of the specification which captures the objects in Requests and Reponses. + +##### Listing 28 + +``` +ErrorInformation, Extension, ExtensionList, GeoCode, IndividualQuote, IndividualQuoteResult, IndividualTransfer, IndividualTransferResult, Money, Party, PartyComplexName, PartyIdInfo, PartyPersonalInfo, PartyResult, Refund, Transaction, TransactionType. +``` + +**Listing 28 -- Complex type Examples** + +### Types of Objects in Requests or Responses + +This section contains the definitions and transformation characteristics of the complex types that are used in the API Specification of the PDP API to capture objects in Requests and Responses. These have the same characteristics as the complex data types discussed in the Complex Type section. + +#### Complex Type AuthorizationsIDPutResponse + +This section provides the JSON Schema definition for the complex type `AuthorizationsIDPutResponse`. [Listing 29](#listing-29) provides a JSON Schema for complex type `AuthorizationsIDPutResponse`. + +- JSON value pair with Name "**type**" and Value "**object**" + +- JSON value pair with Name "**title**" and Value "**AuthorizationsIDPutResponse**". + +- JSON value pair with Name "**description**" and Value "**PUT /authorizations/{ID} object**". + +- A JSON object "**properties**" with the following content: + + - If Property "**authenticationInfo**" is present, a JSON object "**authenticationInfo**" with the following content: + + - JSON value pair with Name "**$ref**" and as Value the definition of AuthenticationInfo type, located under **definitions** as indicated by **#/definitions/** + + - A JSON object **responseType** with the following content: + + - JSON value pair with Name "**$ref**" and as Value the definition of AuthorizationResponse type, located under **definitions** as indicated by "**#/definitions/**". + +- An array **required** and as Value a list with single element "**responseType**" + +##### Listing 29 + +```json +"AuthorizationsIDPutResponse": { + "title": "AuthorizationsIDPutResponse", + "type": "object", + "description": "PUT /authorizations/{ID} object", + "properties": { + "authenticationInfo": { + "$ref": "#/definitions/AuthenticationInfo", + "description": "OTP or QR Code if entered, otherwise empty." + } + "responseType": { + "$ref": "#/definitions/AuthorizationResponse", + "description": "Enum containing response information; if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value." + } + }, + "required ": [ + "responseType" + ] +} +``` + +**Listing 29 -- JSON Schema for complex type AuthorizationsIDPutResponse** + +The transformation rules for an instance of `AuthorizationsIDPutResponse` complex type are as follows: + +- A given Instance of `AuthorizationsIDPutResponse` type MUST be of object type. + +- The instance MUST contain a property with name "**authenticationInfo**". + +- The JSON object titled "**authenticationInfo**" MUST be an instance of AuthenticationInfo type, provided in the definitions. + +- The instance MUST contain a property with name "**responseType**". + +- The JSON object titled "**responseType**" MUST be an instance of AuthorizationReponse type, provided in the definitions. + +An example instance for `AuthorizationsIDPutResponse` complex type is given in [Listing 30](#listing-30). + +##### Listing 30 + +```json +{ + "authenticationInfo": { + "authentication": "OTP", + "authenticationValue": "1234" + }, + "responseType": "ENTERED" +} +``` + +**Listing 30 -- Example instance of AuthorizationsIDPutResponse complex type** + +**5.2.2 Other Complex types in Requests and Responses** + +Other complex type examples from the API used in Requests or Responses can be found in [Listing 31](#listing-31). + +##### Listing 31 + +``` +BulkQuotesPostRequest, BulkQuotesIDPutResponse, BulkTransfersPostRequest, BulkTransfersIDPutResponse, ErrorInformationObject, ErrorInformationResponse, ParticipantsTypeIDSubIDPostRequest, ParticipantsTypeIDPutResponse, ParticipantsIDPutResponse, ParticipantsPostRequest, QuotesPostRequest, QuotesIDPutResponse, TransactionRequestsIDPutResponse, TransactionsIDPutResponse, TransfersPostRequest, TransactionRequestsPostRequest, TransfersIDPutResponse. +``` + +**Listing 31 -- Complex type Examples for Objects in Requests and Responses in the API** + +## References + +1 The link for this is: [http://json-schema.org/documentation.html](http://json-schema.org/documentation.html) + +2 MUST, MAY, OPTIONAL in this document are to be interpreted as described\ in [RFC2119](https://www.ietf.org/rfc/rfc2119.txt) + +3 Most of the items in this section and the next one, "Metadata Keywords" are taken from: [http://json-schema.org/latest/json-schema-validation.html](http://json-schema.org/latest/json-schema-validation.html). Some changes are made based on Open API limitations or constraints. Also, only relevant keywords are referenced. + +4 The description for "Instance" keyword is taken from: [http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2](http://json-schema.org/latest/json-schema-core.html\#rfc.section.4.2) + +5 Meaning and usage of \$ref as specified here: [http://json-schema.org/latest/json-schema-core.html\#rfc.section.8](http://json-schema.org/latest/json-schema-core.html\#rfc.section.8) + + + +## Table of Listings + +[Listing 1 -- JSON Schema for Data type Amount](#listing-1) + +[Listing 2 -- JSON Schema for Data type BinaryString](#listing-2) + +[Listing 3 -- JSON Schema for BinaryString type IlpPacket](#listing-3) + +[Listing 4 -- JSON Schema for Data type BinaryString32](#listing-4) + +[Listing 5 -- JSON Schema for BinaryString32 type IlpCondition](#listing-5) + +[Listing 6 -- JSON Schema for Data type BopCode](#listing-6) + +[Listing 7 -- List of Enum types specified and used in the API](#listing-7) + +[Listing 8 -- JSON Schema for Enumeration Type AmountType](#listing-8) + +[Listing 9 -- JSON Schema for Data type Date](#listing-9) + +[Listing 10 -- JSON Schema for Date type DateOfBirth](#listing-10) + +[Listing 11 -- JSON Schema for Data type DateTime](#listing-11) + +[Listing 12 -- JSON Schema for Data type ErrorCode](#listing-12) + +[Listing 13 -- JSON Schema for Data type Integer](#listing-13) + +[Listing 14 -- JSON Schema for Data type Latitude](#listing-14) + +[Listing 15 -- JSON Schema for Data type Longitude](#listing-15) + +[Listing 16 -- JSON Schema for Data type MerchantClassificationCode](#listing-16) + +[Listing 17 -- JSON Schema for Data type Name](#listing-17) + +[Listing 18 -- JSON Schema for Name type FirstName](#listing-18) + +[Listing 19 -- JSON Schema for Data type OtpValue](#listing-19) + +[Listing 20 -- String types specified and used in the API](#listing-20) + +[Listing 21 -- JSON Schema for Data type ErrorDescription](#listing-21) + +[Listing 22 -- JSON Schema for Data type TokenCode](#listing-22) + +[Listing 23 -- JSON Schema for TokenCode type Code](#listing-23) + +[Listing 24 -- JSON Schema for Data type UndefinedEnum](#listing-24) + +[Listing 25 -- JSON Schema for Data type UUID](#listing-25) + +[Listing 26 -- JSON Schema for complex type AuthenticationInfo](#listing-26) + +[Listing 27 -- Example instance of AuthenticationInfo complex type](#listing-27) + +[Listing 28 -- Complex type Examples](#listing-28) + +[Listing 29 -- JSON Schema for complex type AuthorizationsIDPutResponse](#listing-29) + +[Listing 30 -- Example instance of AuthorizationsIDPutResponse complex type](#listing-30) + +[Listing 31 -- Complex type Examples for Objects in Requests and Responses in the API](#listing-31) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/logical-data-model.md b/website/versioned_docs/v1.0.1/api/fspiop/logical-data-model.md new file mode 100644 index 000000000..262603287 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/logical-data-model.md @@ -0,0 +1,2437 @@ +# Logical Data Model + + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document specifies the logical data model used by Open API (Application Programming Interface) for FSP (Financial Service Provider) Interoperability (hereafter cited as “the API”). + +The [Services Elements](#api-services-elements) section lists elements used by each service. + +The [Supporting Data Model](#api-supporting-data-model) section describes the data model in terms of basic elements, simple data types and complex data types. + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](#) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## API Services Elements + +The section identifies and describes elements used by each service. + +### API Resource Participants + +This section describes the data model of services for the resource **Participants**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Participants**. +
    + +##### Lookup Participant Information + +Table 1 contains the data model for _Lookup Participant Information_. + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party.| + +**Table 1 – Lookup Participant Information data model** + +
    + +##### Create Participant Information + +Table 2 below contains the data model for _Create Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) |The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 1 | [FspId](#fspid-element) | FSP Identifier that the Party belongs to. | +| **currency** | 0..1 | [Currency](#currency-element) | Indicate that the provided Currency is supported by the Party. | + +**Table 2 – Create Participant Information data model** + +
    + +##### Create Bulk Participant Information + +Table 3 below contains the data model for _Create Bulk Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **partyList** | 1..10000 | [PartyIdInfo](#partyidinfo) | List of Party elements that the Client would like to update or create FSP information about. | +| **currency** | 0..1 | [Currency](#currency-enum) | Indicate that the provided Currency is supported by each PartyIdInfo in the list. | + +**Table 3 – Create Bulk Participant Information data model** + +
    + +##### Delete Participant Information + +Table 4 below contains the data model for _Delete Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | + +**Table 4 – Delete Participant Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Participants**. + +##### Return Participant Information + +Table 5 below contains the data model for _Return Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | [FspId](#fspid-element) | FSP Identifier that the Party belongs to. | + +**Table 5 – Return Participant Information data model** + +
    + +##### Return Bulk Participant Information + +Table 6 below contains the data model for _Return Bulk Participant Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **partyList** | 1..10000 | [PartyResult](#partyresult) | List of PartyResult elements for which creation was attempted (and either succeeded or failed). | +| **Currency** | 0..1 | [Currency](#currency-element) | Indicates that the provided Currency was set to be supported by each successfully added PartyIdInfo. | + +**Table 6 – Return Bulk Participant Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Participants**. + +##### Return Participant Information Error + +Table 7 below contains the data model for _Return Participant Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 7 – Return Participant Information Error data model** + +
    + +##### Return Bulk Participant Information Error + +Table 8 below contains the data model for _Return Bulk Participant Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **requestId** | 1 | [CorrelationId](#correlationid-element) | The ID of the request, determined by the client. Used for identification of the callback from the server. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 8 – Return Bulk Participant Information Error data model** + +
    + +### API Resource Parties + +This section describes the data model of services for the resource **Parties**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Parties**. + +##### Lookup Party Information + +Table 9 below contains the data model for _Lookup Party Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartyIdSubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | + +**Table 9 – Lookup Party Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Parties**. + +##### Return Party Information + +Table 10 below contains the data model for _Return Party Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | A sub-identifier or sub-type for the Party. | +| **party** | 1 | [Party](#party) | Information regarding the requested Party. | + + +**Table 10 – Return Party Information data model** + + +
    + +#### Error Responses + +##### Return Party Information Error + +Table 11 below contains the data model for _Return Party Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysuboridtype-element) | A sub-identifier or sub-type for the Party. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 11 – Return Party Information Error data model** + +
    + +### API Resource Transaction Requests + +This section describes the data model of services for the resource **Transaction Requests**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transaction Requests**. + +##### Retrieve Transaction Request + +Table 12 below contains the data model for _Retrieve Transaction Request_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for re-sends of the same transaction request. A new ID should be generated for each new transaction request. | + +**Table 12 – Retrieve Transaction Request data model** + + +
    + +##### Perform Transaction Request Information + +Table 13 below contains the data model for _Perform Transaction Request Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [PartyIdInfo](#partyidinfo) | Information about the Payer type, id, subtype/id, FSP Id in the proposed financial transaction. +| **amount** | 1 | [Money](#money) | The requested amount to be transferred from the Payer to Payee. | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction. | +| **note** | 0..1 | [Note](#note-element) | Reason for the transaction request, intended to the Payer. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating party.

    Can be used to detect fraud.

    | +| **authenticationType** | 0..1 | [AuthenticationType](#authenticationtype-element) | OTP or QR Code, otherwise empty. | +| **expiration** | 0..1 | [DateTime](#datetime) | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also useful for notifying Consumer, Agent, Merchant that their request has a time limit. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 13 – Perform Transaction Request Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transaction Requests**. + + +##### Return Transaction Request Information + +Table 14 below contains the data model for _Return Transaction Request Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for re-sends of the same transaction request. A new ID should be generated for each new transaction request. | +| **transactionId** | 0..1 | [CorrelationId](#correlationid-element) | Identifies related /transactions (if a transaction has been created). | +| **transactionRequestState** | 1 | [TransactionRequestState](#transactionrequeststate-element) | The state of the transaction request. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 14 – Return Transaction Request Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Transaction Requests**. + +##### Return Transaction Request Information Error + +Table 15 below contains the data model for _Return Transaction Request Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the transaction request object, determined by the Payee FSP. The ID should be re-used for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 15 – Return Transaction Request Information Error data model** + +
    + +### API Resource Quotes + +This section describes the data model of services for the resource **Quotes**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Quotes**. + +##### Retrieve Quote Information + +Table 16 bleow contains the data model for _Retrieve Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message.| + +**Table 16 – Retrieve Quote Information data model** + +
    + +##### Calculate Quote + +Table 17 below contains the data model for _Calculate Quote_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **transactionRequestId** | 1 | [CorrelationId](#correlationid-element) | Identifies transactionRequest message. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [Party](#party) | Information about the Payer in the proposed financial transaction. | +| **amountType** | 1 | [AmountType](#amounttype-element) | SEND for sendAmount, RECEIVE for receiveAmount. | +| **amount** | 1 | [Money](#money) | Depending on amountType:
    If SEND: The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.

    If RECEIVE: The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities.
    | +| **fees** | 0..1 | [Money](#money) | The fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction for which the quote is requested. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating party. Can be used to detect fraud. | +| **note** | 0..1 | [Note](#note-element) | A memo that will be attached to the transaction. | +| **expiration** | 0..1 | [DateTime](#datetime) | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also useful for notifying Consumer, Agent, Merchant that their request has a time limit. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 17 – Calculate Quote data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Quotes**. + +##### Return Quote Information + +Table 18 below contains the data model for _Return Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transferAmount** | 1 | [Money](#money) | The amount of money that the Payer FSP should transfer to the Payee FSP. | +| **payerReceiveAmount** | 1 | [Money](#money) | The amount of money that the Payee should receive in the end-to-end transaction. Optional, as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | [Money](#money) | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | [Money](#money) | Transaction commission from the Payee FSP. | +| **expiration** | 1 | [DateTime](#datetime) | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction. | +| **geoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the Payee. Can be used to detect fraud. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be attached to the transfer by the payer. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment | + +**Table 18 – Return Quote Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Quotes**. + +##### Return Quote Information Error + +Table 19 below contains the data model for _Return Quote Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 19 – Return Quote Information Error data model** + +
    + +### API Resource Authorizations + +This section describes the data model of services for the resource **Authorizations**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Authorizations**. + +##### Perform Authorization + +Table 20 below contains the data model for _Perform Authorization_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **authenticationType** | 0..1 | [AuthenticationType](#authenticationtype-element) | The type of authentication. | +| **retriesLeft** | 0..1 | [NrOfRetries](#nrofretries-element) | Number of retries left. | +| **amount** | 0..1 | [Money](#money) | The authorization amount. | +| **currency** | 0..1 | [CurrencyCode](#currencycode-enum) | The authorization currency. | + +**Table 20 – Perform Authorization data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Authorizations**. + +##### Return Authorization Result + +Table 21 below contains the data model for _Return Authorization Result_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **authenticationInfo** | 0..1 | [AuthenticationInfo](#authenticationinfo) | OTP or QR Code if entered, otherwise empty. | +| **responseType** | 1 | [AuthorizatonResponse](#authorizationresponse-element) | Enum containing response information, if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value. | + +**Table 21 – Return Authorization Result data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Authorizations**. + +##### Return Authorization Error + +Table 22 below contains the data model for _Return Authorization Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authorizationId** | 1 | [CorrelationId](#correlationid-element) | Identifies authorization message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 22 – Return Authorization Error data model** + +
    + +### API Resource Transfers + +This section describes the data model of services for the resource **Transfers**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transfers**. + +##### Retrieve Transfer Information + +Table 23 below contains the data model for _Retrieve Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | + +**Table 23 – Retrieve Transfer Information data model** + +
    + +##### Perform Transfer + +Table 24 below contains the data model for _Perform Transfer_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **payeeFsp** | 1 | [FspId](#fspid-element) | Payee FSP in the proposed financial transaction. | +| **payerFsp** | 1 | [FspId](#fspid-element) | Payer FSP in the proposed financial transaction. | +| **amount** | 1 | [Money](#money) | The transfer amount to be sent. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet containing the amount delivered to the payee and the ILP Address of the payee and any other end-to-end data. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be fulfilled to commit the transfer. | +| **expiration** | 1 | [DateTime](#datetime) | Expiration can be set to get a quick failure Expiration of the transfer. The transfer should be rolled back if no fulfilment is delivered before this time. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 24 – Perform Transfer data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transfers**. + +##### Return Transfer Information + +Table 25 below contains the data model for _Return Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **fulfilment** | 0..1 | [IlpFulfilment](#ilpfulfilment-element) | The fulfilment of the condition specified with the transaction. Mandatory if transfer has completed successfully. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the transaction was completed. | +| **transferState** | 1 | [TransferState](#transferstate-enum) | The state of the transfer. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 25 – Return Transfer Information data model** + +
    + +#### Error Responses + +This section describes the data model of error responses used by the server in the API for services provided by the resource **Transfers**. + +##### Return Transfer Information Error + +Table 26 below contains the data model for _Return Transfer Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the transfer object, determined by the Payer FSP. The ID should be reused for re-sends of the same transfer. A new ID should be generated for each new transfer. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 26 – Return Transfer Information Error data model** + +
    + +### API Resource Transactions + +This section describes the data model of services for the resource **Transactions**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Transactions**. + +##### Retrieve Transaction Information + +Table 27 below contains the data model for **Retrieve Transaction Information**. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | + +**Table 27 – Retrieve Transaction Information data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Transactions**. + +##### Return Transaction Information + +Table 28 below contains the data model for _Return Transaction Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the transaction was completed. | +| **transactionState** | 1 | [TransactionState](#transactionstate-element) | The state of the transaction. | +| **code** | 0..1 | [Code](#code-element) | Optional redemption information provided to Payer after transaction has been completed. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 28 – Return Transaction Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Transactions**. + +##### Return Transaction Information Error + +Table 29 below contains the data model for _Return Transaction Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 29 – Return Transaction Information Error data model** + +
    + +### API Resource Bulk Quotes + +This section describes the data model of services for the resource **Bulk Quotes**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Bulk Quotes**. + +##### Retrieve Bulk Quote Information + +Table 30 below contains the data model for _Retrieve Bulk Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be reused for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | + +**Table 30 – Retrieve Bulk Quote data model** + +
    + +##### Calculate Bulk Quote + +Table 31 contains the data model for _Calculate Bulk Quote_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. payer 1 PartyIdInfo Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| **GeoCode** | 0..1 | [GeoCode](#geocode) | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **expiration** | 0..1 | [DateTime](#datetime) | Proposed expiration of the quote. | +| **individualQuotes** | 1..1000 | [IndividualQuote](#individualquote) | List of `IndividualQuote` elements. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 31 – Calculate Bulk Quote data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Bulk Quotes**. + +##### Return Bulk Quote Information + +Table 32 below contains the data model for _Return Bulk Quote Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **individualQuoteResults** | 0..1000 | [IndividualQuoteResult](#individualquoteresult) | Fees for each individual transaction (if any are charged per transaction). expiration 1 DateTime Date and time until when the quotation is valid and can be honored when used in the subsequent transaction request. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 32 – Return Bulk Quote Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Bulk Quotes**. + +##### Return Bulk Quote Information Error + +Table 33 below contains the data model for _Return Bulk Quote Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs for the bulk quote object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 33 – Return Bulk Quote Information Error data model** + +
    + +### API Resource Bulk Transfers + +This section describes the data model of services for the resource **Bulk Transfers**. + +#### Requests + +This section describes the data model of services that can be requested by a client in the API for the resource **Bulk Transfers**. + +##### Retrieve Bulk Transfer Information + +Table 34 below contains the data model for _Retrieve Bulk Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | + +**Table 34 – Retrieve Bulk Transfer Information data model** + +
    + +##### Perform Bulk Transfer + +Table 35 contains the data model for _Perform Bulk Transfer_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **bulkQuoteId** | 1 | [CorrelationId](#correlationid-element) | This identifies previous quotation request. The fees specified in the previous quotation will have to be honored in the transfer. | +| **payeeFsp** | 1 | [FspId](#fspid-element) | Payee FSP identifier. | +| **payerFsp** | 1 | [FspId](#fspid-element) | Information about the Payer in the proposed financial transaction. | +| **individualTransfers** | 1..1000 | [IndividualTransfer](#individualtransfer) | List of `IndividualTransfer` elements. | +| **expiration** | 1 | [DateTime](#datetime) | Expiration time of the transfers. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 35 – Perform Bulk Transfer data model** + +
    + +#### Responses + +This section describes the data model of responses used by the server in the API for services provided by the resource **Bulk Transfers**. + +##### Return Bulk Transfer Information + +Table 36 below contains the data model for _Return Bulk Transfer Information_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **completedTimestamp** | 0..1 | [DateTime](#datetime) | The time and date when the bulk transfer was completed. | +| **individualTransferResults** | 0..1000 | [IndividualTransferResult](#individualtransferresult) | List of `IndividualTransferResult` elements. | +| **bulkTransferState** | 1 | [BulkTransferState](#bulktransferstate-enum) | The state of the bulk transaction. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 36 – Return Bulk Transfer Information data model** + +
    + +#### Error Responses + +This section describes the data model of the error responses used by the server in the API for services provided by the resource **Bulk Transfers**. + +##### Return Bulk Transfer Information Error + +Table 37 below contains the data model for _Return Bulk Transfer Information Error_. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | [CorrelationId](#correlationid-element) | The common ID between the FSPs and the optional Switch for the bulk transfer object, determined by the Payer FSP. The ID should be re-used for re-sends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **errorInformation** | 1 | [ErrorInformation](#errorinformation) | Error code, category description. | + +**Table 37 – Return Bulk Transfer Information Error data model** + +
    + +## API Supporting Data Model + +This section defines the data model and contains the following sub-sections: + +- [Length Specification](#length-specification) introduces the formats used for the element data types used by the API. + +- [Element Data Type Formats](#element-data-type-formats) defines the element data types used by the API. + +- [Element Defintions](#element-defintions) defines the elements types used by the API. + +- [Complex Types](#complex-types) identifies the complex types used by the API. + +- [Enumerations](#enumerations) identifies the enumerations used by the API. + +
    + +### Length Specification +All element data types have both a minimum and maximum length. These lengths are indicated by one of the following: + +- A minimum and maximum length +- An exact length +- A regular expression limiting the element such that only a specific length or lengths can be used. + +#### Minimum and Maximum Length + +If a minimum and maximum length is used, this will be indicated after the data type in parentheses: First the minimum value (inclusive value), followed by two period characters (..), and then the maximum value (inclusive value). + +Examples: + +- `String(1..32)` – A String that is minimum one character and maximum 32 characters long. +- `Integer(3..10)` - An Integerr that is minimum 3 digits, but maximum 10 digits long. + +#### Exact Length + +If an exact length is used, this will be indicated after the data type in parentheses containing only one exact value. Other lengths are not allowed. + +Examples: + +- `String(3)` – A String that is exactly three characters long. +- `Integer(4)` – An Integer that is exactly four digits long. + +#### Regular Expressions + +Some element data types are restricted using regular expressions. The regular expressions in this document use the standard for syntax and character classes established by the programming language Perl[1](https://perldoc.perl.org/perlre.html#Regular-Expressions). + +
    + +### Element Data Type Formats + +This section contains the definition of element data types used by the API. + +#### String + +The API data type `String` is a normal JSON String[2](https://tools.ietf.org/html/rfc7159#section-7), limited by a minimum and maximum number of characters. + +##### Example Format I + +`String(1..32)` – A String that is minimum *1* character and maximum *32* characters long. + +An example of `String(1..32)` appears below: + +- _This String is 28 characters_ + +##### Example Format II + +`String(1..128)` – A String that is minimum *1* character and maximum *128* characters long. + +An example of `String(32..128)` appears below: + +- _This String is longer than 32 characters, but less than 128_ + +
    + +#### Enum + +The API data type `Enum` is a restricted list of allowed JSON [String](#string)) values; an enumeration of values. Other values than the ones defined in the list are not allowed. + +##### Example Format + +`Enum of String(1..32)` – A String that is minimum one character and maximum 32 characters long and restricted by the allowed list of values. The description of the element contains a link to the enumeration. + +
    + +#### UndefinedEnum + +The API data type `UndefinedEnum` is a JSON String consisting of one to 32 uppercase characters including an underscore character ( _) . + +##### Regular Expression + +The regular expression for restricting the `UndefinedEnum` type appears in Listing 1 below: + +``` +^[A-Z_]{1,32}$ +``` +**Listing 1 – Regular expression for data type UndefinedEnum** + +
    + +#### Name + +The API data type `Name` is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + +##### Regular Expression + +The regular expression for restricting the `Name` type is shown in Listing 2 below. The restriction will not allow a string consisting of whitespace only, all Unicode[3](http://www.unicode.org/) characters should be allowed, as well as period (.), apostrophe (“), dash (-), comma (,) and space ( ) characters. The maximum number of characters in the **Name** is 128. + +**Note:** In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag `UNICODE_CHARACTER_CLASS` needs to be enabled to allow Unicode characters. + +``` +^(?!\s*$)[\w .,'-]{1,128}$ +``` + +**Listing 2 – Regular expression for data type Name** + +
    + +#### Integer + +The API data type `Integer` is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits. + +##### Regular Expression + +The regular expression for restricting an `Integer` is shown in Listing 3 below. + +``` +^[1-9]\d*$ +``` + +**Listing 3 – Regular expression for data type Integer** + +##### Example Format + +`Integer(1..6)` – An `Integer` that is at minimum one digit long, maximum six digits. + +An example of `Integer(1..6)` appears below: + +- _123456_ + +
    + +#### OtpValue + +The API data type `OtpValue` is a JSON String of three to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed. + +##### Regular Expression + +The regular expression for restricting the `OtpValue` type appears in Listing 4 below. + +``` +^\d{3,10}$ +``` + +**Listing 4 – Regular expression for data type OtpValue** + +
    + +#### BopCode + +The API data type `BopCode` is a JSON String of three characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `BopCode` type appears in Listing 5 below. +``` +^[1-9]\d{2}$ +``` + +**Listing 5 – Regular expression for data type BopCode** + +
    + +#### ErrorCode + +The API data type `ErrorCode` is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `ErrorCode` type appears in Listing 6 below. + +``` +^[1-9]\d{3}$ +``` + +**Listing 6 – Regular expression for data type ErrorCode** + +
    + +#### TokenCode + +The API data type `TokenCode` is a JSON String between four and 32 characters, consisting of digits or upper or lowercase characters from **a** to **z**. + +##### Regular Expression + +The regular expression for restricting the `TokenCode` type appears in Listing 7 below. + +``` +^[0-9a-zA-Z]{4,32}$ +``` + +**Listing 7 – Regular expression for data type TokenCode** + +
    + +#### MerchantClassificationCode + +The API data type `MerchantClassificationCode` is a JSON String consisting of one to four digits. + +##### Regular Expression + +The regular expression for restricting the `MerchantClassificationCode` type appears in Listing 8 below. + +``` +^[\d]{1,4}$ +``` + +**Listing 8 - Regular expression for data type MerchantClassificationCode** + +
    + +#### Latitude + +The API data type `Latitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Latitude` type appears in Listing 9 below. + +``` +^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 9 – Regular expression for data type Latitude** + +
    + +#### Longitude + +The API data type `Longitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Longitude` type is shown in Listing 10 below. + +``` +^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0- +9]{1,6})?))$ +``` + +**Listing 10 – Regular expression for data type Longitude** + +
    + +#### Amount + +The API data type `Amount` is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Amount` type appears in Listing 11 below. This pattern: + +- Does not allow trailing zeroes. +- Allows an amount without a minor currency unit. +- Allows only four digits in the minor currency unit; a negative value is not allowed. +- Does not allow more than 18 digits in the major currency unit. + +The regular expression for restricting the `Amount` type is shown in Listing 11 below. + +``` +^([0]|([1-9][0-9]*))([.][0-9]{0,3}[1-9])?$ +``` + +**Listing 11 – Regular expression for data type Amount** + +##### Examples + +See [table](#results-for-validated-amount-values) below for validation results for some example `Amount` values using the [regular expression](#regular-expression-11) defined above. + +##### Results for validated Amount values + +| Value | Validation result | +| --- | --- | +| _5_ | Accepted | +| _5.0_ | Rejected | +| _5._ | Rejected | +| _5.00_ | Rejected | +| _5.5_ | Accepted | +| _5.50_ | Rejected | +| _5.5555_ | Accepted | +| _5.55555_ | Rejected | +| _555555555555555555_ | Accepted | +| _5555555555555555555_ | Rejected | +| _-5.5_ | Rejected | +| _0.5_ | Accepted | +| _.5_ | Rejected | +| _00.5_ | Rejected | +| _0_ | Accepted | + +**Table 38 – Example results for different values for Amount type** + +
    + +#### DateTime + +The API data type `DateTime` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting `DateTime` appears in Listing 12 below. The format is according to ISO 8601[4](https://www.iso.org/iso-8601-date-and-time-format.html) , expressed in a combined date, time and time format. A more readable version of the format is `yyyy-MM-dd'T'HH:mm:ss.SSS[-HH:MM]` + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])- +(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1- +9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02- +29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ +``` + +**Listing 12 – Regular expression for data type DateTime** + +##### Examples + +Two examples of the `DateTime` type appear below: + +- _2016-05-24T08:38:08.699-04:00_ + +- _2016-05-24T08:38:08.699Z_ (where **Z** indicates Zulu time zone, which is the same as UTC). + +
    + +#### Date + +The API data type `Date` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Date` type appears in Listing 13 below. This format, as specified in ISO 8601, contains a date only. A more readable version of the format is `yyyy-MM-dd`. + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])- +(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1- +9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ +``` + +**Listing 13 – Regular expression for data type Date** + +##### Examples + +Two examples of the `Date` type appear below: + +- _1982-05-23_ + +- _1987-08-05_ + +
    + +#### UUID + +The API data type `UUID` (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 4122[5](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A `UUID` is always 36 characters long, 32 hexadecimal symbols and four dashes (-). + +##### Regular Expression + +The regular expression is shown in Listing 14 below. + +``` +^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ +``` + +**Listing 14 – Regular expression for data type UUID** + +##### Example + +An example of a `UUID` type appears below: + +- _a8323bc6-c228-4df2-ae82-e5a997baf898_ + +
    + +#### BinaryString + +The API data type `BinaryString` is a JSON String. The String is the base64url[6](https://tools.ietf.org/html/rfc4648#section-5) encoding of a string of raw bytes. The length restrictions for the `BinaryString` type apply to the underlying binary data, indicating the allowed number of bytes. For data types with a fixed size no padding character is used. + +##### Regular Expression + +The regular expression for restricting the **BinaryString** type appears in Listing 15 below. + +``` +^[A-Za-z0-9-_]+[=]?$ +``` + +**Listing 15 – Regular expression for data type BinaryString** + +##### Example Format + +`BinaryString(32)` –32 bytes of data base64url encoded. + +An example of a `BinaryString(32..256)` appears below. Note that a padding character, `'='` has been added to ensure that the string is a multiple of four characters. + +- _QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE=_ + + +
    + +#### BinaryString32 + +The API data type _BinaryString32_ is a fixed size variation of the API data type `BinaryString` defined [here](#binarystring), in which the raw underlying data is always of 32 bytes. The data type _BinaryString32_ should not use a padding character because the size of the underlying data is fixed. + +##### Regular Expression +The regular expression for restricting the _BinaryString32_ type appears in Listing 16 below. + +``` +^[A-Za-z0-9-_]{43}$ +``` + +**Listing 16 – Regular expression for data type BinaryString32** + +##### Example Format +`BinaryString(32)` – 32 bytes of data base64url encoded. + +An example of a `BinaryString32` appears below. Note that this is the same binary data as the example shown in the [Example Format](#example-format-3) of the `BinaryString` type, but due to the underlying data being fixed size, the padding character `'='` is excluded. + +``` +QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE +``` + +
    + +### Element Definitions + +This section contains the definition of the elements types that are used by the API. + +#### AmountType element + +Table 39 below contains the data model for the element `AmountType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AmountType** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the amount type. See [AmountType](#amounttype-enum) enumeration for more information on allowed values. | + +**Table 39 – Element AmountType** + +
    + +#### AuthenticationType element + +Table 40 below contains the data model for the element `AuthenticationType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Authentication** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authentication type. See [AuthenticationType](#authenticationtype-enum) enumeration for possible enumeration values. | + +**Table 40 – Element AuthenticationType** + +
    + +#### AuthenticationValue element + +Table 41 below contains the data model for the element `AuthenticationValue`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthenticationValue** | 1 | Depends on [AuthenticationType](#authenticationtype-element).

    If `OTP`: type is [Integer(1..6)](#integer). For example:**123456**

    OtpValue
    If `QRCODE`: type is [String(1..64)](#string) | This element contains the authentication value. The format depends on the authentication type used in the [AuthenticationInfo](#authenticationinfo) complex type. | + +**Table 41 – Element AuthenticationValue** + +
    + +#### AuthorizationResponse element + +Table 42 below contains the data model for the element `AuthorizationResponse`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthorizationResponse** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authorization response. See [AuthorizationResponse](#authorizationresponse-enum) enumeration for possible enumeration values. | + +**Table 42 – Element AuthorizationResponse** + +
    + +#### BalanceOfPayments element + +Table 43 below contains the data model for the element `BalanceOfPayment`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BalanceOfPayments** | 1 | [BopCode](#bopcode) | The possible values and meaning are defined in [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/) | + +**Table 43 – Element BalanceOfPayments** + +
    + +#### BulkTransferState element + +Table 44 below contains the data model for the element `BulkTransferState`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BulkTransferState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [BulkTransferState](#bulktransferstate-enum) enumeration for information on allowed values| + +**Table 44 – Element BulkTransferState** + +
    + +#### Code element + +Table 45 below contains the data model for the element `Code`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Code** | 1 | [TokenCode](#tokencode) | Any code/token returned by the Payee FSP. | + +**Table 45 – Element Code** + +
    + +#### CorrelationId element + +Table 46 below contains the data model for the element `CorrelationId`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **CorrelationId** | 1 |[UUID](#uuid) | Identifier that correlates all messages of the same sequence. | + + +**Table 46 – Element CorrelationId** + +
    + +#### Currency element + +Table 47 below contains the data model for the element `Currency`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Currency** | 1 | [Enum](#enum) of [String(3)](#string) | See [Currency](#currencycode-enum) enumeration for information on allowed values | + +**Table 47 – Element Currency** + +
    + +#### DateOfBirth element + +Table 48 below contains the data model for the element `DateOfBirth`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **DateOfBirth** | 1 | Examples

    Two examples of the [DateTime](#datetime) type appear below:

    2016-05-24T08:38:08.699-04:00

    2016-05-24T08:38:08.699Z (where Z indicates Zulu time zone, which is the same as UTC).

    Date

    | Date of Birth of the Party.| + +**Table 48 – Element DateOfBirth** + +
    + +#### ErrorCode element + +Table 49 below contains the data model for the element `ErrorCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorCode** | 1 | [ErrorCode](#errorcode) | Four digit error code, see section on [Error Codes](#error-codes) for more information. | + +**Table 49 – Element ErrorCode** + +
    + +#### ErrorDescription element + +Table 50 below contains the data model for the element `ErrorDescription`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorDescription** | 1 | [String(1..128)](#string) | Error description string. | + +**Table 50 – Element ErrorDescription** + +
    + +#### ExtensionKey element + +Table 51 below contains the data model for the element `ExtensionKey`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionKey** | 1 | [String(1..32)](#string) | The extension key. | + +**Table 51 – Element ExtensionKey** + +
    + +#### ExtensionValue element + +Table 52 below contains the data model for the element `ExtensionValue`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionValue** | 1 | [String(1..128)](#string) | The extension value. | + +**Table 52 – Element ExtensionValue** + +
    + +#### FirstName element +Table 53 below contains the data model for the element `FirstName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FirstName** | 1 | [Name](#name) | First name of the Party | + +**Table 53 – Element FirstName** + +
    + +#### FspId element + +Table 54 below contains the data model for the element `FspId`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FspId** | 1 | [String(1..32)](#string)| The FSP identifier. | + +**Table 54 – Element FspId** + +
    + +#### IlpCondition element + +Table 55 below contains the data model for the element `IlpCondition`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpCondition** | 1 | [BinaryString32](#binarystring32) | The condition that must be attached to the transfer by the Payer. | + +**Table 55 – Element IlpCondition** + +
    + +#### IlpFulfilment element + +Table 56 below contains the data model for the element `IlpFulfilment`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpFulfilment** | 1 | [BinaryString32](#binarystring32) | The fulfilment that must be attached to the transfer by the Payee. | + +**Table 56 – Element IlpFulfilment** + +
    + +#### IlpPacket element + +Table 57 below cntains the data model for the element `IlpPacket`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpPacket** | 1 | Example

    An example of a [UUID](#uuid) type appears below:

    a8323bc6-c228-4df2-ae82-e5a997baf898

    [BinaryString(1..32768)](#binarystring)

    | Information for recipient (transport layer information). | + +**Table 57 – Element IlpPacket** + +
    + +#### LastName element + +Table 58 below contains the data model for the element `LastName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **LastName** | 1 | [Name](#name) | Last name of the Party (ISO 20022 definition). | + +**Table 58 – Element LastName** + +
    + +#### MerchantClassificationCode element + +Table 59 below contains the data model for the element `MerchantClassificationCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MerchantClassificationCode** | 1 | [MerchantClassificationCode](#merchantclassificationcode) | A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, and so on. | + +**Table 59 – Element MerchantClassificationCode** + +
    + +#### MiddleName element + +Table 60 below contains the data model for the element `MiddleName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MiddleName** | 1 | [Name](#name) | Middle name of the Party (ISO 20022 definition). | + +**Table 60 – Element MiddleName** + +
    + +#### Note element + +Table 61 below contains the data model for the element `Note`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Note** | 1 | [String(1..128)](#string) | Memo assigned to transaction. | + +**Table 61 – Element Note** + +
    + + +#### NrOfRetries element + +Table 62 below contains the data model for the element `NrOfRetries`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **NrOfRetries** | 1 | [Integer(1..2)](#integer) | Number of retries. | + +**Table 62 – Element NrOfRetries** + +
    + +#### PartyIdentifier element + +Table 63 below contains the data model for the element `PartyIdentifier`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdentifier** | 1 | [String(1..128)](#string) | Identifier of the Party.| + +**Table 63 – Element PartyIdentifier** + +
    + +#### PartyIdType element + +Table 64 below contains the data model for the element `PartyIdType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdType** | 1 | Enum of [String(1..32)](#string) | See [PartyIdType](#partyidtype-enum) enumeration for more information on allowed values. | + +**Table 64 – Element PartyIdType** + +
    + +#### PartyName element + +Table 65 below contains the data model for the element `PartyName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyName** | 1 | `Name` | Name of the Party. Could be a real name or a nickname. | + +**Table 65 – Element PartyName** + +
    + +#### PartySubIdOrType element + +Table 66 below contains the data model for the element `PartySubIdOrType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartySubIdOrType** | 1 | [String(1..128)](#string) | Either a sub-identifier of a [PartyIdentifier](#partyidentifier-element), or a sub-type of the [PartyIdType](#partyidtype-element), normally a `PersonalIdentifierType`. | + +**Table 66 – Element PartySubIdOrType** + +
    + +#### RefundReason element + +Table 67 below contains the data model for the element `RefundReason`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **RefundReason** | 1 | [String(1..128)](#string) | Reason for the refund. | + +**Table 67 – Element RefundReason** + +
    + +#### TransactionInitiator element + +Table 68 below contains the data model for the element `TransactionInitiator`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiator** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiator](#transactioninitiator-enum) enumeration for more information on allowed values. | + +**Table 68 – Element TransactionInitiator** + +
    + +#### TransactionInitiatorType element + +Table 69 below contains the data model for the element `TransactionInitiatorType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiatorType** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiatorType](#transactioninitiatortype-enum) enumeration for more information on allowed values. | + +**Table 69 – Element TransactionInitiatorType** + +
    + +#### TransactionRequestState element + +Table 70 below contains the data model for the element `TransactionRequestState`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionRequestState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionRequestState](#transactionrequeststate-enum) enumeration for more information on allowed values. | + + +**Table 70 – Element TransactionRequestState** + +
    + +#### TransactionScenario element + +Table 71 below contains the data model for the element `TransactionScenario`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionScenario** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionScenario](#transactionscenario-enum) enumeration for more information on allowed values. | + +**Table 71 – Element TransactionScenario** + +
    + +#### TransactionState element + +Table 72 below contains the data model for the element `TransactionState`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionState](#transactionstate-enum) enumeration for more information on allowed values. | + +**Table 72 – Element TransactionState** + +
    + +#### TransferState element + +Table 73 below contains the data model for the element `TransferState`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransferState](#transferstate-enum) enumeration for more information on allowed values. | + +**Table 73 – Element TransferState** + +
    + +#### TransactionSubScenario element + +Table 74 below contains the data model for the element `TransactionSubScenario`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionSubScenario** | 1 | [UndefinedEnum](#undefinedenum) | Possible sub-scenario, defined locally within the scheme.| + +**Table 74 – Element TransactionSubScenario** + +
    + +### Complex Types + +This section contains the complex types that are used by the API. + +#### AuthenticationInfo + +Table 75 below contains the data model for the complex type `AuthenticationInfo`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **authentication** | 1 | [AuthenticationType](#authenticationtype-element) | The type of authentication. | +| **authenticationValue** | 1 | [AuthenticationValue](#authenticationvalue-element) | The authentication value. | + +**Table 75 – Complex type AuthenticationInfo** + +
    + +#### ErrorInformation + +Table 76 below contains the data model for the complex type `ErrorInformation`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **errorCode** | 1 | [ErrorCode](#errorcode) | Specific error number. | +| **errorDescription** | 1 | [ErrorDescription](#errordescription-element) | Error description string. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional list of extensions, specific to deployment. | + +**Table 76 – Complex type ErrorInformation** + +
    + +#### Extension + +Table 77 below contains the data model for the complex type `Extension`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **key** | 1 | [ExtensionKey](#extensionkey-element) | The extension key. | +| **value** | 1 | [ExtensionValue](#extensionvalue-element) | The extension value. | + +**Table 77 – Complex type Extension** + +
    + +#### ExtensionList + +Table 78 below contains the data model for the complex type `ExtensionList`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **extension** | 1..16 | [Extension](#extension) | A number of Extension elements. | + +**Table 78 – Complex type ExtensionList** + +
    + +#### IndividualQuote + +Table 79 below contains the data model for the complex type `IndividualQuote`. + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies quote message. | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | Identifies transaction message. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **amountType** | 1 | [AmountType](#amounttype-element) | `SEND_AMOUNT` for _sendAmount_,

    `RECEIVE_AMOUNT` for _receiveAmount_.

    +| **amount** | 1 | [Money](#money) | Depending on amountType:

    If `SEND`: The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.

    If `RECEIVE`: The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. | +| **fees** | 0..1 | [Money](#money) | The fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of transaction that the quote is requested for. | +| **note** | 0..1 | [Note](#note-element) | A memo that will be attached to the transaction. This is sent in the quote so it can be included in the ILP Packet. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 79 – Complex type IndividualQuote** + +
    + +#### IndividualQuoteResult + +Table 80 below contains the data model for the complex type `IndividualQuoteResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | Identifies the quote message. | +| **payeeReceiveAmount** | 0..1 | [Money](#money) | Amount that the Payee should receive in the end-toend transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | [Money](#money) | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | [Money](#money) | Transaction commission from the Payee FSP. | +| **ilpPacket** | 0..1 | [IlpPacket](#ilppacket-element) | The ILP Packet that must be attached to the transfer by the payer. | +| **condition** | 0..1 | [IlpCondition](#ilpcondition-element) | The condition that must be attached to the transfer by the payer. | +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | Error code, category description.

    Note: If errorInformation is set, the following are not set:

    • receiveAmount
    • payeeFspFee
    • payeeFspCommission
    • ilpPacket
    • condtion
    | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment | + +**Table 80 – Complex type IndividualQuoteResult** + +
    + +#### IndividualTransfer + +Table 81 below contains the data model for the complex type `IndividualTransfer`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | Identifies messages related to the same /transfers sequence. | +| **transferAmount** | 1 | [Money](#money) | The transaction amount to be sent. | +| **ilpPacket** | 1 | [IlpPacket](#ilppacket-element) | The ILP Packet containing the amount delivered to the payee and the ILP Address of the payee and any other end-to-end data. | +| **condition** | 1 | [IlpCondition](#ilpcondition-element) | The condition that must be fulfilled to commit the transfer. +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 81 – Complex type IndividualTransfer** + +
    + +#### IndividualTransferResult + +Table 82 below contains the data model for the complex type `IndividualTransferResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transferId** | 1 | [CorrelationId](#correlationid-element) | Identifies messages related to the same /transfers sequence. | +| **fulfilment** | 0..1 | [IlpFulfilment](#ilpfulfilment-element) | The fulfilment of the condition specified with the transaction.

    Note: Either fulfilment is set or errorInformation is set, not both.

    +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | If transactionState is `REJECTED`, error information may be provided.

    Note: Either fulfilment is set or errorInformation is set, not both.

    +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 82 – Complex type IndividualTransferResult** + +#### GeoCode + +Table 83 below contains the data model for the complex type `GeoCode`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **latitude** | 1 | [Latitude](#latitude) | The Latitude of the service initiating Party. | +| **longitude** | 1 | [Longitude](#longitude) | The Longitude of the service initiating Party. | + +**Table 83 – Complex type GeoCode** + +
    + +#### Money + +Table 84 below contains the data model for the complex type `Money`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **currency** | 1 | [Currency](#currency-element) | The currency of the Amount. | +| **amount** | 1 | [Amount](#amount) | The amount of Money. | + +**Table 84 – Complex type Money** + +
    + +#### Party + +Table 85 below contains the data model for the complex type `Party`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdInfo** | 1 | [PartyIdInfo](#partyidinfo) | Party Id type, id, sub ID or type, and FSP Id. | +| **merchantClassificationCode** | 0..1 | [MerchantClassificationCode](#merchantclassificationcode) | Optional: Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments. | +| **name** | 0..1 | [PartyName](#partyname-element) | The name of the party, could be a real name or a nick name. | +| **personalInfo** | 0..1 | [PartyPersonalInfo](#partypersonalinfo) | Personal information used to verify identity of Party such as first, middle, last name and date of birth. | + +**Table 85 – Complex type Party** + +
    + +#### PartyComplexName + +Table 86 below contains the data model for the complex type `PartyComplexName`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **firstName** | 0..1 | [FirstName](#firstname-element) | First name. | +| **middleName** | 0..1 | [MiddleName](#middlename-element) | Middle name. | +| **lastName** | 0..1 | [LastName](#lastname-element) | Last name. | + +**Table 86 – Complex type PartyComplexName** + +
    + +#### PartyIdInfo + +Table 87 below contains the data model for the complex type `PartyIdInfo`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyIdType** | 1 | [PartyIdType](#partyidtype-element) | The type of the identifier. | +| **partyIdentifier** | 1 | [PartyIdentifier](#partyidentifier-element) | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | [PartySubIdOrType](#partysubidortype-element) | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | [FspId](#fspid-element) | The FSP ID (if known) | + +**Table 87 – Complex type PartyIdInfo** + +
    + +#### PartyPersonalInfo + +Table 88 below contains the data model for the complex type `PartyPersonalInfo`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **complexName** | 0..1 | [PartyComplexName](#partycomplexname) | First, middle and last name. | +| **dateOfBirth** | 0..1 | [DateOfBirth](#dateofbirth-element) | Date of birth. | + +**Table 88 – Complex type PartyPersonalInfo** + +
    + +#### PartyResult + +Table 89 below contains the data model for the complex type `PartyResult`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **partyId** | 1 | [PartyIdInfo](#partyidinfo) | Party Id type, id, sub ID or type, and FSP Id. | +| **errorInformation** | 0..1 | [ErrorInformation](#errorinformation) | If the Party failed to be added, error information should be provided. Otherwise, this parameter should be empty to indicate success. | + +**Table 89 – Complex type PartyPersonalInfo** + +
    + +#### Refund + +Table 90 below contains the data model for the complex type `Refund`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **originalTransactionId** | 1 | [CorrelationId](#correlationid-element) | Reference to the original transaction ID that is requested to be refunded.| +| **refundReason** | 0..1 | [RefundReason](#refundreason-element) | Free text indicating the reason for the refund. | + +**Table 90 – Complex type Refund** + +
    + +#### Transaction + +Table 91 below contains the data model for the complex type `Transaction`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **transactionId** | 1 | [CorrelationId](#correlationid-element) | ID of the transaction, the ID is determined by the Payer FSP during the creation of the quote. | +| **quoteId** | 1 | [CorrelationId](#correlationid-element) | ID of the quote, the ID is determined by the Payer FSP during the creation of the quote. | +| **payee** | 1 | [Party](#party) | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | [Party](#party) | Information about the Payer in the proposed financial transaction. | +| **amount** | 1 | [Money](#money) | The transaction amount to be sent. | +| **transactionType** | 1 | [TransactionType](#transactiontype) | The type of the transaction. | +| **note** | 0..1 | [Note](#note-element) | Memo associated to the transaction,intended to the Payee. | +| **extensionList** | 0..1 | [ExtensionList](#extensionlist) | Optional extension, specific to deployment. | + +**Table 91 – Complex type Transaction** + +#### TransactionType + +Table 92 below contains the data model for the complex type `TransactionType`. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **scenario** | 1 | [TransactionScenario`](#transactionscenario-element) | Deposit, withdrawal, refund, … | +| **subScenario** | 0..1 | [TransactionSubScenario](#transactionsubscenario-element) | Possible sub-scenario, defined locally within the scheme. | +| **initiator** | 1 | [TransactionInitiator](#transactioninitiator-enum) | Who is initiating the transaction: payer or payee | +| **initiatorType** | 1 | [TransactionInitiatorType](#transactioninitiatortype-enum) | Consumer, agent, business, … | +| **refundInfo** | 0..1 | [Refund](#refund) | Extra information specific to a refund scenario. Should only be populated if scenario is `REFUND`. | +| **balanceOfPayments** | 0..1 | [BalanceOfPayments](#balanceofpayments-element) | Balance of Payments code. | + +**Table 92 – Complex type TransactionType** + +
    + + +### Enumerations + +This section contains the enumerations used by the API. + +#### AmountType enum + +Table 93 below contains the allowed values for the enumeration `AmountType`. + +| Name | Description | +| --- | --- | +| **SEND** | The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. | +| **RECEIVE** | The amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive fees. | + +**Table 93 – Enumeration AmountType** + +
    + +#### AuthenticationType enum + +Table 94 below contains the allowed values for the enumeration `AuthenticationType`. + +| Name | Description | +| --- | ---| +| **OTP** | One-time password, either chosen by the Party, or generated by the Party’s FSP. | +| **QRCODE** | QR code used as One Time Password. | + +**Table 94 – Enumeration AuthenticationType** + +
    + +#### AuthorizationResponse enum + +Table 95 below contains the allowed values for the enumeration `AuthorizationResponse`. + +| Name | Description | +| --- | --- | +| **ENTERED** | Consumer entered the authentication value. | +| **REJECTED** | Consumer rejected the transaction. | +| **RESEND** | Consumer requested to resend the authentication value. | + +**Table 95 – Enumeration AuthorizationResponse** + +
    + +#### BulkTransferState + +Table 96 below contains the allowed values for the enumeration `BulkTransferState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payee FSP has received the bulk transfer from the Payer FSP. | +| **PENDING** | Payee FSP has validated the bulk transfer. | +| **ACCEPTED** | Payee FSP has accepted to process the bulk transfer. | +| **PROCESSING** | Payee FSP has started to transfer fund to the Payees. | +| **COMPLETED** | Payee FSP has completed transfer of funds to the Payees. | +| **REJECTED** | Payee FSP has rejected to process the transfer. | + +**Table 96 – Enumeration BulkTransferState** + +
    + +#### CurrencyCode enum + +The currency codes defined in ISO 4217[7](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies. The currency codes from ISO 4217 are not is shown in this document, implementers are instead encouraged to use the information provided by the ISO 4217 standard directly. + +
    + +#### PartyIdType enum + +Table 97 below contains the allowed values for the enumeration `PartyIdType`. + +| Name | Description | +| --- | ---| +| **MSISDN** | Used when an MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. | +| **EMAIL** | Used when an email should be used as reference to a participant. The format of the email should be according to the informational RFC 3696. | +| **PERSONAL_ID** | Used when some kind of personal identifier should be used as reference to a participant. Examples of personal identification can be passport number, birth certificate number, national registration number or similar. The identifier number shall be added in the PartyIdentifier element. The personal identifier type shall be added in the PartySubIdOrType element. | +| **BUSINESS** | Used when a specific Business (for example, an Organization or a Company) should be used as reference to a participant. The Business identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. | +| **DEVICE** | Used when a specific Device (for example, a POS or ATM) ID connected to a specific Business or Organization should be used as reference to a Party. To use a specific device under a specific Business or Organization, the PartySubIdOrType element should be used. | +| **ACCOUNT_ID** | Used when a bank account number or FSP account ID should be used as reference to a participant. The `ACCOUNT_ID` identifier can be in any format, as formats can greatly differ depending on country and FSP. | +| **IBAN** | Used when a bank account number or FSP account ID should be used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without any whitespace. | +| **ALIAS** | Used when an alias should be used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias can be username in the FSP system. The `ALIAS` identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. | + +**Table 97 – Enumeration PartyIdType** + +
    + +#### PersonalIdentifierType enum + +Table 98 below contains the allowed values for the enumeration `PersonalIdentifierType`. + +| Name | Description | +| --- | --- | +| **PASSPORT** | Used when a passport number should be used as reference to a Party | +| **NATIONAL_REGISTRATION** | Used when a national registration number should be used as reference to a Party | +| **DRIVING_LICENSE** | Used when a driving license should be used as reference to a Party | +| **ALIEN_REGISTRATION** | Used when an alien registration number should be used as reference to a Party | +| **NATIONAL_ID_CARD** | Used when a national ID card number should be used as reference to a Party | +| **EMPLOYER_ID** | Used when a tax identification number should be used as reference to a Party | +| **TAXI_ID_NUMBER** | Used when a tax identification number should be used as reference to a Party. | +| **SENIOR_CITIZENS_CARD** | Used when a senior citizens card number should be used as reference to a Party | +| **MARRIAGE_CERTIFICATE** | Used when a marriage certificate number should be used as reference to a Party | +| **HEALTH_CARD** | Used when a health card number should be used as reference to a Party | +| **VOTERS_ID** | Used when a voters identification number should be used as reference to a Party | +| **UNITED_NATIONS** | Used when an UN (United Nations) number should be used as reference to a Party | +| **OTHER_ID** | Used when any other type of identification type number should be used as reference to a Party | + +**Table 98 – Enumeration PersonalIdentifierType** + +
    + +#### TransactionInitiator enum + +Table 99 below contains the allowed values for the enumeration `TransactionInitiator`. + +| Name | Description | +| --- | --- | +| **PAYER** | The sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. | +| **PAYEE** | The recipient of the funds is also initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP, pre-approval of the Payee, or by manually approving in his or her own Device. | + +**Table 99 – Enumeration TransactionInitiator** + +
    + +#### TransactionInitiatorType enum + +Table 100 below contains the allowed values for the enumeration `TransactionInitiatorType`. + +| Name | Description | +| --- | --- | +| **CONSUMER** | Consumer is the initiator of the transaction. | +| **AGENT** | Agent is the initiator of the transaction. | +| **BUSINESS** | Business is the initiator of the transaction. | +| **DEVICE** | Device is the initiator of the transaction. | + +**Table 100 – Enumeration TransactionInitiatorType** + +
    + +#### TransactionRequestState enum + +Table 101 below contains the allowed values for the enumeration `TransactionRequestState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payer FSP has received the transaction from the Payee FSP. | +| **PENDING** | Payer FSP has sent the transaction request to the Payer. | +| **ACCEPTED** | Payer has approved the transaction. | +| **REJECTED** | Payer has rejected the transaction. | + +**Table 101 – Enumeration TransactionRequestState** + +
    + +#### TransactionScenario enum + +Table 102 below contains the allowed values for the enumeration `TransactionScenario`. + +| Name | Description | +| --- | --- | +| **DEPOSIT** | Used for performing a Cash-In (deposit) transaction, where in the normal case electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. | +| **WITHDRAWAL** | Used for performing a Cash-Out (withdrawal) transaction, where in the normal case electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. | +| **TRANSFER** | Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. | +| **PAYMENT** | Typically used for performing a transaction from a Consumer to a Merchant/Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online to purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. | +| **REFUND** | Used for performing a refund of transaction. | + +**Table 102 – Enumeration TransactionScenario** + +
    + +#### TransactionState enum + +Table 103 below contains the allowed values for the enumeration `TransactionState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | Payee FSP has received the transaction from the Payer FSP. | +| **PENDING** | Payee FSP has validated the transaction. | +| **COMPLETED** | Payee FSP has successfully performed the transaction. | +| **REJECTED** | Payee FSP has failed to perform the transaction. | + +**Table 103 – Enumeration TransactionState** + +
    + +#### TransferState enum + +Table 104 below contains the allowed values for the enumeration `TransferState`. + +| Name | Description | +| --- | --- | +| **RECEIVED** | The next ledger has received the transfer. | +| **RESERVED** | The next ledger has reserved the transfer. | +| **COMMITTED** | The next ledger has successfully performed the transfer. | +| **ABORTED** | The next ledger has aborted the transfer due a rejection or failure to perform the transfer. | + +**Table 104 – Enumeration TransferState** + +
    + +### Error Codes + +Each error code in the API is a four-digit number, such as **1234**, where the first number (**1** in the example) represents the highlevel error category, the second number (**2** in the example) represents the low-level error category, and the last two numbers (**34** in the example) represents the specific error. Figure 1 shows the structure of an error code. The following sub-sections contains information and defined error codes per high-level error category. + +![Figure 1 - Error code structure](../assets/sequence-diagram-figure-1.png) + +**Figure 1 – Error code structure** + +Each defined high- and low-level category combination contains a generic error (_x_**0**_xx_), which can be used if there is no specific error, or if the server would not like to return information which is considered private. + +All specific errors below _xx_**40**, that is, _xx_**00** to _xx_**39**, are reserved for future use by the API. All specific errors above and including _xx40_, can be used for scheme-specific errors. If a client receives an unknown scheme-specific error, the unknown scheme-specific error should be interpreted as a generic error for the high- and low-level category combination instead (_xx_**00**). + +#### Communication Errors – 1xxx + +All possible communication or network errors that could arise that cannot be represented by an HTTP status code should use +the high-level error code 1 (error codes **1**_xxx_). Because all services in the API are asynchronous, these error codes should generally be used by a Switch in the Callback to the client FSP if the Peer FSP could not be reached, or if a callback is not received from the Peer FSP within an agreed timeout. + +Low level categories defined under Communication Errors: + +- **Generic Communication Error – 10**_xx_ + +See Table 105 below for all communication errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **1000** | Communication error | Generic communication error. | X | X | X | X | X | X | X | X | X | +| **1001** | Destination communication error | The Destination of the request failed to be reached. This usually indicates that a Peer FSP failed to respond from an intermediate entity. | X | X | X | X | X | X | X | X | X | + +**Table 105 – Communication errors – 1xxx** + +
    + +#### Server Errors – 2xxx + +All errors occurring in the server in which the server failed to fulfil an apparently valid request from the client should use the high-level error code 2 (error codes **2**_xxx_). These error codes should indicate that the server is aware that it has encountered an error or is otherwise incapable of performing the requested service. + +Low-level categories defined under server Errors: + +- **Generic server Error – 20**_xx_ + +See Table 106 below for all server errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **2000** | Generic server error | Generic server error to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **2001** | Internal server error | A generic unexpected exception. This usually indicates a bug or unhandled error case. | X | X | X | X | X | X | X | X | X | +| **2002** | Not implemented | Service requested is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **2003** | Service currently unavailable | Service requested is currently unavailable on the server. This could be because maintenance is taking place, or because of a temporary failure. | X | X | X | X | X | X | X | X | X | +| **2004** | Server timed out | A time out has occurred, meaning the next Party in the chain did not send a callback in time. This could be because a timeout is set too low or because something took longer than it should. | X | X | X | X | X | X | X | X | X | +| **2005** | Server busy | Server is rejecting requests due to overloading. Try again later. | X | X | X | X | X | X | X | X | X | + +**Table 106 – Server errors – 2xxx** + +
    + +#### Client Errors – 3xxx** + +All possible errors occurring in the server where the server’s opinion is that the client have sent one or more erroneous parameters should use the high-level error code 3 (error codes **3**_xxx_). These error codes should indicate that the server could not perform the service according to the request from the client. The server should provide an explanation why the service could not be performed. + +Low level categories defined under client Errors: +- **Generic Client Error – 30**_xx_ + - See Table 107 for the generic client errors defined in the API. +- **Validation Error – 31**_xx_ + - See Table 108 for the validation errors defined in the API. +- **Identifier Error – 32**_xx_ + - See Table 109 for the identifier errors defined in the API. +- **Expired Error – 33**_xx_ + - See Table 110 for the expired errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3000** | Generic client error | Generic client error, to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3001** | Unacceptable version requested | Client requested to use a protocol version which is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **3002** | Unknown URI | The provided URI was unknown by the server. | | | | | | | | | | +| **3003** | Add Party information error | An error occurred while adding or updating information regarding a Party. | X | | | | | | | | | | + +**Table 107 – Generic client errors – 30xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3100** | Generic validation error | Generic validation error to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3101** | Malformed syntax | The format of the parameter is not valid. For example, amount set to 5.ABC. The error description field should specify which element is erroneous. |X | X | X | X | X | X | X | X | X | +| **3102** | Missing mandatory element | A mandatory element in the data model was missing. | X | X | X | X | X | X | X | X | X | +| **3103** | Too many elements | The number of elements of an array exceeds the maximum number allowed. | X | X | X | X | X | X | X | X | X | +| **3104** | Too large payload | The size of the payload exceeds the maximum size. | X | X | X | X | X | X | X | X | X | +| **3105** | Invalid signature | Some parameters have changed in the message, making the signature invalid. This may indicate that the message may have been modified maliciously. |X | X | X | X | X | X | X | X | X | +| **3106** | Modified request | A request with the same ID has previously been processed where the parameters are not the same. | | | X | X | | X | | X | X | +| **3107** | Missing mandatory extension parameter |A scheme mandatory extension parameter was missing. | | | X | X | X | X | X | X | X | + +**Table 108 – Validation Errors – 31xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3200** | Generic ID not found | Generic ID error provided by the client. | X | X | X | X | X | X | X | X | X | +| **3201** | Destination FSP Error| The Destination FSP does not exist or cannot be found. | X | X | X | X | X | X | X | X | X | +| **3202** | Payer FSP ID not found | The provided Payer FSP ID not found. | | | | | | X | | X | X | +| **3203** | Payee FSP ID not found | The provided Payer FSP ID not found. | | | | | | X | | X | X | +| **3204** | Party not found | The Party with the provided identifier, identifier type, and optional sub id or type was not found. | X | X | X | X | | | | | | +| **3205** | Quote ID not found | The provided Quote ID was not found in the server. | | | | X | | X | | | | +| **3206** | Transaction request ID not found | The provided Transaction Request ID was not found in the server. | | | X | | | X | | | | +| **3207** | Transaction ID not found | The provided Transaction ID was not found in the server. | | | | | | | X | | | +| **3208** | Transfer ID not found | The provided Transfer ID was not found in the server. | | | | | | X | | | | +| **3209** | Bulk quote ID not found | The provided Bulk Quote ID was not found in the server. | | | | | | | | X | X | +| **3210** | Bulk transfer ID not found | The provided Bulk Transfer ID was not found in the server. | | | | | | | | | X | + +**Table 109 – Identifier Errors – 32xx** + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **3300** |Generic expired error | Generic expired object error, to be used for not disclosing information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3301** | Transaction request expired | Client requested to use a transaction request that has already expired. | | | | X | | | | | | +| **3302** | Quote expired | Client requested to use a quote that has already expired. | | | | | X | | | X | X | +| **3303** | Transfer expired | Client requested to use a transfer that has already expired. | X | X | X | X | X | X | X | X | X | + +**Table 110 – Expired Errors – 33xx** + +
    + +#### Payer Errors – 4xxx + +All possible errors occurring in the server when the Payer or the Payer FSP is the cause of an error should use the high-level error code 4 (error codes **4**_xxx_). These error codes should indicate that there was no error in the server or in the request from the client, but the request failed for some reason due to the Payer or the Payer FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payer Errors: +- **Generic Payer Error – 40**_xx_ +- **Payer Rejection Error – 41**_xx_ +- **Payer Limit Error – 42**_xx_ +- **Payer Permission Error – 43**_xx_ +- **Payer Blocked Error – 44**_xx_ + +See Table 111 below for all Payer errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **4000** | Generic Payer error | Generic error due to the Payer or Payer FSP, to be used for not disclosing information that may be considered private. | | | X | X | X | X | X | X | X | +| **4001** | Payer FSP insufficient liquidity | The Payer FSP has insufficient liquidity to perform the transfer. | | | | | | X | | | | +| **4100** | Generic Payer rejection | Payer or Payer FSP rejected the request. | | | X | X | X | X | X | X | X | +| **4101** | Payer rejected transaction request | Payer rejected the transaction request from the Payee. | | | X | | | | | | | +| **4102** | Payer FSP unsupported transaction type | The Payer FSP does not support or rejected the requested transaction type | | | X | | | | | | | +| **4103** | Payer unsupported currency | Payer doesn’t have an account which supports the requested currency. | | | X | | | | | | | +| **4200** | Payer limit error | Generic limit error, for example, the Payer is making more payments per day or per month than they are allowed to, or is making a payment that is larger than the allowed maximum per transaction. | | | X | X | | X | | X | X | +| **4300** | Payer permission Error | Generic permission error, the Payer or Payer FSP doesn’t have the access rights to perform the service. | | | X | X | X | X | X | X | X | +| **4400** | Generic Payer blocked error | Generic Payer blocked error, the Payer is blocked or has failed regulatory screenings. | | | X | X | X | X | X | X | X | + +**Table 111 – Payer errors – 4xxx** + + +
    + +#### Payee Errors – 5xxx + +All possible errors occurring in the server when the Payee or the Payee FSP is the cause of an error should use the high-level error code 5 (error codes **5**_xxx_). These error codes should indicate that there was no error in the server or in the request from the client, but the request failed for some reason due to the Payee or the Payee FSP. The server should provide an explanation for why the service could not be performed. + +Low level categories defined under Payee Errors: + +- **Generic Payee Error – 50**_xx_ +- **Payee Rejection Error – 51**_xx_ +- **Payee Limit Error – 52**_xx_ +- **Payee Permission Error – 53**_xx_ +- **Payee Blocked Error – 54**_xx_ + +See Table 112 below for all Payee errors defined in the API. + +| Error Code | Name | Description | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| **5000** |Generic Payee error |Generic error due to the Payer or Payer FSP, to be used for not disclosing information that may be considered private. | | | X | X | X | X | X | X | X | +| **5001** | Payee FSP insufficient liquidity | The Payee FSP has insufficient liquidity to perform the transfer. | | | | | | X | | | | +| **5100** | Generic Payee rejection | Payee or Payee FSP rejected the request. | | | X | X | X | X | X | X | X | +| **5101** | Payee rejected quote | Payee does not want to proceed with the financial transaction after receiving a quote. | | | | X | | | | X | | +| **5102** | Payee FSP unsupported transaction type | The Payee FSP either does not support or rejected the requested transaction type. | | | | X | | | | X | | +| **5103** | Payee FSP rejected quote | Payee doesn’t want to proceed with the financial transaction after receiving a quote. | | | | X | | | | X | | +| **5104** | Payee rejected transaction | Payee rejected the financial transaction. | | | | | | X | | | X | +| **5105** | Payee FSP rejected transaction | Payee FSP rejected the financial transaction. | | | | | | X | | | X | +| **5106** | Payee unsupported currency | Payee doesn’t have an account which supports the requested currency. | | | | X | | X | | X | X | +| **5200** | Payee limit error | Generic limit error, for example, the Payee is receiving more payments per day or per month than they are allowed to, or is receiving a payment which is larger than the allowed maximum per transaction. | | | X | X | | X | | X | X | +| **5300** | Payee permission error | Generic permission error; the Payee or Payee FSP does not have the access rights to perform the service. | | | X | X | X | X | X | X | X | +| **5400** | Generic Payee blocked error | Generic Payee Blocked error, the Payee is blocked or has failed regulatory screenings. | | | X | X | X | X | X | X | X | + +**Table 112 – Payee errors – 5xxx** + + +
    + +## References + +1 [https://perldoc.perl.org/perlre.html#Regular-Expressions](https://perldoc.perl.org/perlre.html#Regular-Expressions) - perlre - Perl regular expressions + +2 [https://tools.ietf.org/html/rfc7159#section-7](https://tools.ietf.org/html/rfc7159#section-7) – The JavaScript Object Notation (JSON) Data Interchange Format - Strings + +3 [http://www.unicode.org/](http://www.unicode.org/) - The Unicode Consortium + +4 [https://www.iso.org/iso-8601-date-and-time-format.html](https://www.iso.org/iso-8601-date-and-time-format.html) - Date and time format - ISO 8601 + +5 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) - A Universally Unique IDentifier (UUID) URN Namespace + +6 [https://tools.ietf.org/html/rfc4648#section-5](https://tools.ietf.org/html/rfc4648#section-5) - The Base16, Base32, and Base64 Data Encodings - Base 64 Encoding with URL +and Filename Safe Alphabet + +7 [https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html) - Currency codes - ISO 4217 + + + + +## List of Figures + +- [Figure 1](#error-codes) – Error code structure + +## List of Tables + +- [Table 1](#lookup-participant-information) – Lookup Participant Information data model +- [Table 2](#create-participant-information) – Create Participant Information data model +- [Table 3](#create-bulk-participant-information) – Create Bulk Participant Information data model +- [Table 4](#delete-participant-information) – Delete Participant Information data model +- [Table 5](#return-participant-information) – Return Participant Information data model +- [Table 6](#return-bulk-participant-information) – Return Bulk Participant Information data model +- [Table 7](#return-participant-information-error) – Return Participant Information Error data model +- [Table 8](#return-bulk-participant-information-error) – Return Bulk Participant Information Error data model +- [Table 9](#lookup-party-information) – Lookup Party Information data model +- [Table 10](#return-party-information) – Return Party Information data model +- [Table 11](#return-party-information-error) – Return Party Information Error data model +- [Table 12](#retrieve-transaction-request) – Retrieve Transaction Request data model +- [Table 13](#perform-transaction-request-information) – Perform Transaction Request Information data model +- [Table 14](#return-transaction-request-information) – Return Transaction Request Information data model +- [Table 15](#return-transaction-request-information-error) – Return Transaction Request Information Error data model +- [Table 16](#retrieve-quote-information) – Retrieve Quote Information data model +- [Table 17](#calculate-quote) – Calculate Quote data model +- [Table 18](#return-quote-information) – Return Quote Information data model +- [Table 19](#return-quote-information-error) – Return Quote Information Error data model +- [Table 20](#perform-authorization) – Perform Authorization data model +- [Table 21](#return-authorization-result) – Return Authorization Result data model +- [Table 22](#return-authorization-error) – Return Authorization Error data model +- [Table 23](#retrieve-transfer-information) – Retrieve Transfer Information data model +- [Table 24](#perform-transfer) – Perform Transfer data model +- [Table 25](#return-transfer-information) – Return Transfer Information data model +- [Table 26](#return-transfer-information-error) – Return Transfer Information Error data model +- [Table 27](#retrieve-transaction-information) – Retrieve Transaction Information data model +- [Table 28](#return-transaction-information) – Return Transaction Information data model +- [Table 29](#return-transaction-information-error) – Return Transaction Information Error data model +- [Table 30](#retrieve-bulk-quote-information) – Retrieve Bulk Quote data model +- [Table 31](#calculate-bulk-quote) – Calculate Bulk Quote data model +- [Table 32](#return-bulk-quote-information) – Return Bulk Quote Information data model +- [Table 33](#return-bulk-quote-information-error) – Return Bulk Quote Information Error data model +- [Table 34](#retrieve-bulk-transfer-information) – Retrieve Bulk Transfer Information data model +- [Table 35](#perform-bulk-transfer) – Perform Bulk Transfer data model +- [Table 36](#return-bulk-transfer-information) – Return Bulk Transfer Information data model +- [Table 37](#return-bulk-transfer-information-error) – Return Bulk Transfer Information Error data model +- [Table 38](#results-for-validated-amount-values) – Example results for different values for Amount type +- [Table 39](#amounttype-element) – Element AmountType +- [Table 40](#authenticationtype-element) – Element AuthenticationType +- [Table 41](#authenticationvalue-element) – Element AuthenticationValue +- [Table 42](#authorizationresponse-element) – Element AuthorizationResponse +- [Table 43](#balanceofpayments-element) – Element BalanceOfPayments +- [Table 44](#bulktransferstate-element) – Element BulkTransferState +- [Table 45](#code-element) – Element Code +- [Table 46](#correlationid-element) – Element CorrelationId +- [Table 47](#currency-element) – Element Currency +- [Table 48](#dateofbirth-element) – Element DateOfBirth +- [Table 49](#errorcode-element) – Element ErrorCode +- [Table 50](#errordescription-element) – Element ErrorDescription +- [Table 51](#extensionkey-element) – Element ExtensionKey +- [Table 52](#extensionvalue-element) – Element ExtensionValue +- [Table 53](#firstname-element) – Element FirstName +- [Table 54](#fspid-element) – Element FspId +- [Table 55](#ilpcondition-element) – Element IlpCondition +- [Table 56](#ilpfulfilment-element) – Element IlpFulfilment +- [Table 57](#ilppacket-element) – Element IlpPacket +- [Table 58](#lastname-element) – Element LastName +- [Table 59](#merchantclassificationcode-element) – Element MerchantClassificationCode +- [Table 60](#middlename-element) – Element MiddleName +- [Table 61](#note-element) – Element Note +- [Table 62](#nrofretries-element) – Element NrOfRetries +- [Table 63](#partyidentifier-element) – Element PartyIdentifier +- [Table 64](#partyidtype-element) – Element PartyIdType +- [Table 65](#partyname-element) – Element PartyName +- [Table 66](#partysubidortype-element) – Element PartySubIdOrType +- [Table 67](#refundreason-element) – Element RefundReason +- [Table 68](#transactioninitiator-element) – Element TransactionInitiator +- [Table 69](#transactioninitiatortype-element) – Element TransactionInitiatorType +- [Table 70](#transactionrequeststate-element) – Element TransactionRequestState +- [Table 71](#transactionscenario-element) – Element TransactionScenario +- [Table 72](#transactionstate-element) – Element TransactionState +- [Table 73](#transferstate-element) – Element TransferState +- [Table 74](#transactionsubscenario-element) – Element TransactionSubScenario +- [Table 75](#authenticationinfo) – Complex type AuthenticationInfo +- [Table 76](#errorinformation) – Complex type ErrorInformation +- [Table 77](#extension) – Complex type Extension +- [Table 78](#extensionlist) – Complex type ExtensionList +- [Table 79](#individualquote) – Complex type IndividualQuote +- [Table 80](#individualquoteresult) – Complex type IndividualQuoteResult +- [Table 81](#individualtransfer) – Complex type IndividualTransfer +- [Table 82](#individualtransferresult) – Complex type IndividualTransferResult +- [Table 83](#geocode) – Complex type GeoCode +- [Table 84](#money) – Complex type Money +- [Table 85](#party) – Complex type Party +- [Table 86](#partycomplexname) – Complex type PartyComplexName +- [Table 87](#partyidinfo) – Complex type PartyIdInfo +- [Table 88](#partypersonalinfo) – Complex type PartyPersonalInfo +- [Table 89](#partyresult) – Complex type PartyResult +- [Table 90](#refund) – Complex type Refund +- [Table 91](#transaction) – Complex type Transaction +- [Table 92](#transactiontype) – Complex type TransactionType +- [Table 93](#amounttype-enum) – Enumeration AmountType +- [Table 94](#authenticationtype-enum) – Enumeration AuthenticationType +- [Table 95](#authorizationresponse-enum) – Enumeration AuthorizationResponse +- [Table 96](#bulktransferstate-enum) – Enumeration BulkTransferState +- [Table 97](#partyIdtype-enum) – Enumeration PartyIdType +- [Table 98](#personalidentifiertype-enum) – Enumeration PersonalIdentifierType +- [Table 99](#transactioninitiator-enum) – Enumeration TransactionInitiator +- [Table 100](#transactioninitiatortype-enum) – Enumeration TransactionInitiatorType +- [Table 101](#transactionrequeststate-enum) – Enumeration TransactionRequestState +- [Table 102](#transactionscenario-enum) – Enumeration TransactionScenario +- [Table 103](#transactionstate-enum) – Enumeration TransactionState +- [Table 104](#transferstate-enum) – Enumeration TransferState +- [Table 105](#461-communication-errors-–-1xxx) – Communication errors – 1xxx +- [Table 106](#462-server-errors-–-2xxx) – Server errors – 2xxx +- [Table 107](#client-errors-–-3xxx) – Generic client errors – 30xx +- [Table 108](#client-errors-–-3xxx) – Validation Errors – 31xx +- [Table 109](#client-errors-–-3xxx) – Identifier Errors – 32xx +- [Table 110](#client-errors-–-3xxx) – Expired Errors – 33xx +- [Table 111](#463-payer-errors-–-4xxx) – Payer errors – 4xxx +- [Table 112](#464-payee-errors-–-5xxx) – Payee errors – 5xxx + + +## Table of Listings +- [Listing 1](#regular-expression) – Regular expression for data type UndefinedEnum +- [Listing 2](#regular-expression-2) – Regular expression for data type Name +- [Listing 3](#regular-expression-3) – Regular expression for data type Integer +- [Listing 4](#regular-expression-4) – Regular expression for data type OtpValue +- [Listing 5](#regular-expression-5) – Regular expression for data type BopCode +- [Listing 6](#regular-expression-6) – Regular expression for data type ErrorCode +- [Listing 7](#regular-expression-7) – Regular expression for data type TokenCode +- [Listing 8](#regular-expression-8) - Regular expression for data type MerchantClassificationCode +- [Listing 9](#regular-expression-9) – Regular expression for data type Latitude +- [Listing 10](#regular-expression-10) – Regular expression for data type Longitude +- [Listing 11](#regular-expression-11) – Regular expression for data type Amount +- [Listing 12](#regular-expression-12) – Regular expression for data type DateTime +- [Listing 13](#regular-expression-13) – Regular expression for data type Date +- [Listing 14](#regular-expression-14) – Regular expression for data type UUID +- [Listing 15](#regular-expression-15) – Regular expression for data type BinaryString +- [Listing 16](#regular-expression-16) – Regular expression for data type BinaryString32 diff --git a/website/versioned_docs/v1.0.1/api/fspiop/pki-best-practices.md b/website/versioned_docs/v1.0.1/api/fspiop/pki-best-practices.md new file mode 100644 index 000000000..8b3b33e82 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/pki-best-practices.md @@ -0,0 +1,703 @@ +# Public Key Infrastructure Best Practices + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +## Introduction + +This document explains _Public Key Infrastructure_ (PKI)1 best practices to apply in an _Open API for FSP Interoperability_ (hereafter cited as “the API”) deployment. See [PKI Background](#pki-background) section for more information about PKI. + +The API should be implemented in an environment that consists of either: + +- _Financial Service Providers_ (FSPs) that communicate with other FSPs (in a bilateral setup) or + +- A _Switch_ that acts as an intermediary platform between FSP platforms. There is also an _Account Lookup System_ (ALS) available to identify in which FSP an account holder is located. + +For more information about the environment, see [Network Topology](#network-topology) section. [Certificate Authority PKI Management Strategy](#certificate-authority-pki-management-strategy) and [Platform PKI Management Strategy](#platform-pki-management-strategy) identify management strategies for the CA and for the platform. + +Communication between platforms is performed using a REST (REpresentational State Transfer)-based HTTP protocol (for more information, see _API Definition_). Because this protocol does not provide a means for ensuring either integrity or confidentiality between platforms, extra security layers must be added to protect sensitive information from alteration or exposure to unauthorized parties. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](#) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + + +## PKI Background + +Public Key Infrastructure (PKI) is a set of standards, procedures, and software for implementing authentication using public key cryptography. PKI is used to request, install, configure, manage and revoke digital certificates. PKI offers authentication using digital certificates; these digital certificates are signed and provided by _Certificate Authorities_ (CA). + +PKI uses public key cryptography and works with X.509 standard certificates. It also provides features such as: + +- User authentication + +- Certificate production and distribution + +- Certificate maintenance, management, and revocation + +PKI consists of a number of components that enable the infrastructure to work; it is not a single process or algorithm. In addition to authentication, PKI also enables the provision of integrity, non-repudiation and encryption. + +To obtain a public key, a company must obtain a digital certificate. It should request this certificate from a CA or a _Registration Authority_ (RA) - an organization that processes requests on behalf of a CA. All participants must trust the CA to manage and maintain certificates. The CA requires the company to supply a number of details (_Common Name_ (CN), _Organization_ (O), _Country_ (C) and so on) and validate their request before it provides a certificate. This certificate is proof that the company is who it says it is in the digital world (like a passport in the real world). + +PKI combines well with a _Diffie-Hellman solution_ (a secure mechanism for exchanging a shared symmetric key between two anonymous peers) in providing secure key exchanges. Because Diffie-Hellman does not provide authentication, PKI is used with additional protocols, such as _Pretty Good Privacy_ (PGP) and _Transport Layer Security_ (TLS). + +### Layered Protection + +The API should be used with protection at both the transport- and application-level. + +#### Transport-Level Protection + +To protect the transport level, _Transport Layer Security_2 (TLS) should be used. TLS is a fundamental technique used for securing point-to-point communication. It has been proven to be stable and secure when using strong algorithms with the most recent versions of TLS, and is widely used around the world. TLS is a secure mechanism for exchanging a shared symmetric key between two anonymous peers, with identity verification (that is, trusted certificates). It provides _confidentiality_ (no one has read the content) and _integrity_ (no one has changed the content). Using TLS efficiently as-is requires certificate management. + +#### Application-Level Protection + +This layer provides end-to-end integrity and confidentiality. The API uses the JSON Web Signature3 (JWS) standard for integrity and _non-repudiation_ (provide proof of the integrity and origin of data), and the JSON Web Encryption (JWE) 4 standard for confidentiality. An extended version of JWE is used to support field level encryption. + +Using these standards requires certificate management; therefore, _Certificate Authorities_ (CA) and related PKI techniques are needed. For more information, see PKI Background. + +## Network Topology + +This section identifies the platforms that constitute the API. + +### Platforms Point-to-Point Layout + +Figure 1 shows an example platform point-to-point layout. + +![Figure1 Platforms Layout](../assets/figure1-platforms-layout.svg) + +**Figure 1 - Platforms layout** + +All communication between platforms must be TLS-secured using _client authentication_, also known as _mutual authentication_. + +### Platform Roles + +#### Certificate Authority (CA) + +The CA performs the following functions: + +- Sign _Certificate Signing Requests_ (CSRs) - CSRs is a secure mechanism for exchanging a shared symmetric key between two anonymous peers. The CA signs different types of certificates (for example, TLS, Content signature, Content encryption). + +- Revoke certificates – Mark one or more certificates as invalid. + +- Support CRLs – Maintain and provide certificate revocation lists (CRLs) to be downloaded by clients so that they can see which certificates have been revoked. + +- Support Online Certificate Status Protocol (OCSP) – Provide real-time certificate revocation checks. + +#### Account Lookup System (ALS) + +- Holds basic information about account holders. + +- Answer questions like “Where should I send my financial transaction request for account holder with **MSISDN 0123456**?” + +#### Financial Services Provider (FSP) + +Has account holders to which or from which money is transferred. + +#### Switch + +- Relays transaction information to other platforms. + +- Can perform financial services, as specified in _API Definition_. + +## Certificate Authority PKI Management Strategy + +This section describes the PKI management strategy for Certificate Authorities. + +### Certificate Authority Importance and Selection Criteria + +The Certificate Authority (CA) role is important because: + +- The CA provides a single legal entity that is trustworthy for all platforms. + +- The point-to-point TLS protocol depends on certificates. + +- The end-to-end protocols JWS and JWE depend on certificates for proof of non-repudiation and confidentiality. + +#### Reasons Not to Use a Public CA + +- A public CA can revoke the intermediate certificate used for signing our certificates, thus effectively shutting down all communication between platforms. + +- A public CA also signs certificates which are not part of the _Open API for FSP Interoperability_ setup. Because you trust the certificate the CA signed for you, you then trust all certificates signed by that CA. + +- There is no service in the _Open API for FSP Interoperability_ setup that is open to the public, so there is no reason to have a public CA already trusted by public clients (such as web browsers). + +#### Private CA Options + +- Build your own CA from scratch + +- Build a CA using existing tools (for example, _openssl_) + +- Use a full-featured CA (for example, the open source product _EJBCA_) + +### Trusted Certificate Chain + +A centralized CA makes certificate management easier for the involved platforms. By trusting the same CA certificate, each platform need only trust one certificate; the CA’s self-signed root certificate. + +Thus, the CA should sign all types of certificates (TLS, signature, and encryption), but only for the participants in the _Open API for FSP Interoperability_ setup. + +No intermediate CA certificates are required, because a segmented layout is not used in the _Open API for FSP Interoperability_ setup. + +### CA Root Certificate + +- The CA must create a self-signed root certificate to be used for signing all supported types of certificates (TLS, signing, and encryption). + +- The minimum key length of the asymmetric RSA key pair is 4096 bits, and the signature algorithm should be sha512WithRSAEncryption. + +- The _X.509 Basic Constraints_ must have the attribute **CA** set to **TRUE**. + +- The time validity of the CA root certificate should be ten years. After eight years, a new self-signed root certificate should be created by the CA; the asymmetric RSA key pair must be recreated, not reused. This certificate becomes the certificate to use for signing the platforms CSRs. However, the old CA root certificate must still be active until it expires. This gives the platforms a window of two years to change the CA root certificate without disturbing their ongoing secured communication. + +### Signing Platforms CSRs + +The CA must provide a mechanism for the platforms to get their CSRs signed. Common signing methods are by email and by a web page. The chosen solution and policy must be known to the platforms. + +The CA signs three types of platform certificates; TLS (for communication), JWS (for signature) and JWE (for encryption). Common requirements for these certificates are: + +- The minimum key length of the asymmetric RSA key pair is 2048 bits, and the signature algorithm should be sha256WithRSAEncryption. + +- The _X.509 Basic Constraints_ must have the attribute **CA** set to **FALSE**. + +- The subject distinguished names must contain at least the following attributes: + + - _Common Name_ (CN) – This must be the hostname of the platform which has created the certificate. A N can never be the same for two different platforms or organizations. + + - _Organization_ (O) – The name of the organization. + + - _Country_ (C) – The country of the organization. + +- The URL for platforms to download CRLs must be present. + +- The URL for platforms to send OCSP requests must be present. + +- The time validity should be two years. + +Depending on the type of certificate to sign, the _X.509 Key Usage_ and X.509 Extended Key Usage of the platform’s certificate will differ; see Table 1 for more information. + +| Certificate Type | X.509 Key Usage | X.509 Extended Key Usage | +| --- | --- | --- | +| **TLS Certificates** | Digital Signature, Key Encipherment | TLS Web Server Authentication, TLS Web Client Authentication | +| **Signature Certificates** | Digital Signature | | +| **Encryption Certificates** | Key Encipherment | | + +**Table 1 – Certificate type and key usage** + +### Revoking Certificates + +- The CA must be able to revoke a platform’s certificates. Revoking a certificate means that it will no longer be trusted by any party. It will be marked as invalid by the CA and its revocation status published to the platforms, either in a revocation list (CRL) to be downloaded by platforms, or through a real-time HTTP query using _Online Certificate Status Protocol_ (OCSP) requested by platforms. + +- The CA should support both CRL downloads and OCSP queries. + +- The CA should update and sign the CRL daily and should provide (daily) a HTTP URL to the platforms that points to the CRL to be downloaded. The URL should be stored in the _CRL Distribution Points_ for each signed certificate. + +- The OCSP URL should be stored in the _Authority Information Access_ for each signed certificate. An OCSP response must be signed. Nonce values in an OCSP request should be supported to prevent reply attacks. + +- The CA has the right to revoke certificates, but no obligation to inform the platforms about such revocations. The platforms do not have the right to revoke certificates, but they do have an obligation to check regularly for a certificate’s revocation status. + +### Certificate Enrollment and Renewal + +The CA does not support enrollment or renewal of certificates for which an asymmetric key pair is reused. For increased security, the asymmetric key pairs must be recreated every time a certificate is enrolled or renewed through a new CSR. + +## Platform PKI Management Strategy + +This section describes the PKI management strategy for platforms. + +### Keys, Certificates, and Stores + +A certificate provides the identity of its owner through a trusted CA that has signed the certificate. This can be validated through its signed certificate chain. It also provides the technical means to ensure integrity (signature) and confidentiality (encryption) of data using its asymmetric key pair (known as a _public key and private key_). The public key is within the signed certificate, but its corresponding private key must be kept private and protected. A common solution for handling certificates and private keys is to put them into a protected storage area known as a store. A store can be a file, directory, or something else that provides access and confidentiality. + +A single private key and its associated certificate can be used for all cryptographic purposes, but to enhance security, the following set of keys and certificates is required for each platform: + +- One private key and certificate for TLS communication + +- One private key and certificate for end-to-end integrity using JWS + +- One private key and certificate for end-to-end confidentiality using JWE + +Different keys and types of certificates can all be in the same store, but a more common setup is the following: + +- For TLS communication: + + - One protected key store to hold the private key, its associated certificate, and certificate chain. These items are used for server- and client authentication in TLS. + + - One protected certificate store to hold all trusted TLS certificates. These certificates will be trusted by your platform during a TLS handshake, meaning that they will allow secure communication with the owners of the certificates. Since all participants trust the same CA, it is sufficient to keep only the CA’s root certificate here. + +- For signature and encryption: + + - One protected key store to hold your private keys, their associated certificates, and certificate chains used for signatures and encryption. + + - One private key and certificate chain used for signing using JWS, and one private key and certificate chain used for encryption using JWE. + + - One protected certificate store to hold all trusted signature and encryption certificates from other platforms. Here you must store the certificates (signature and encryption certificates) for each platform that you want to trust for end-to-end integrity and confidentiality. + +### Creating a CSR and Obtaining CA Signature + +To be able to communicate with other platforms, you must create a key store (if one does not already exist), an asymmetric key pair, and an associated certificate that identifies your platform. This unsigned certificate must be signed by the CA before it can be trusted by other platforms. The procedure of getting a certificate signed by a CA begins with a CSR (_Certificate Signing Request_). + +When you create your keys, certificates, and CSRs, the following requirements apply: + +- The minimum key length of the asymmetric RSA key pair is 2048 bits, and the signature algorithm is sha256WithRSAEncryption. + +- The following attributes in the subject distinguished names are mandatory: + + - Common Name (CN) – This must be the hostname of the platform who created the certificate. A CN can never be the same for two different platforms or organizations. + + - Organization (O) – The name of the organization. + + - Country (C) – The country of the organization. + +**For examples of how to create a store, certificate, and CSR, see Appendix C – Common PKI Tasks** + +How to create a store, certificate, and CSR. + +Create your CSR and send it to your CA according to their instructions. + +**Note:** The same procedure must be performed for all your different keys and certificates (TLS, signature, and encryption). + +### Importing a Signed CSR + +After signing your CSR, you will have two certificates in your response from the CA. The first certificate is your own signed certificate. The second is the CA’s own root certificate, which was used for signing your certificate. That certificate must now be trusted by you. + +First you must import your signed certificate into your key store. It must replace your unsigned certificate. For examples, see How to import a signed certificate into your key store. + +Then you must import the CA’s root certificate into the same key store to complete the chain between your certificate and the CA. For examples, see How to import the CA certificate into your key store. + +#### TLS Certificates + +For TLS certificates, you must also import the CA’s root certificate into your TLS trust store to automatically trust the other platforms when establishing new communication channels with them. For examples, see How to import the CA certificate into TLS trust store. + +The above procedure should be performed for each of your signed CSRs. Remember to send your signed certificate and the CA’s root certificate to all other platforms with which you need to communicate. + +The CA will create a validity period of two years for your signed certificate. After 18 months, you should create a new CSR to be signed by the same CA. Your newly signed certificate and the CA’s root certificate should once again be imported into your stores and sent to the other platforms. This will give you and your peers a window of six months to make sure that your new signed certificate works. After two years, the old expired certificate can be deleted. + +### Trusting Certificates from Other Platforms + +Just as your peers must have your certificates to be able to trust you, they must send their certificates to you for you to trust them. + +Make sure that you always receive at least two certificates from a trusted peer: + +- The signed certificate of the peer to trust. + +- The root certificate of the CA that signed the peer’s certificate. + +**Note:** A peer’s CA certificate can differ from yours. This can happen if the CA has created a new CA root certificate when the old one is about to expire. + +You should always view a peer’s certificates (check CN, validity period, and so on) and validate the certificate chain (that is, that each certificate is correctly signed by the given CA) before you import them into your trust store. + +For examples, see How to view a certificate. + +Next, import the peer’s certificate and its CA root certificate into your trust store. For examples, see How to import a trusted certificate. + +### Checking Certificate Revocation Status + +Certificates can be revoked by the CA. A revoked certificate is considered not trusted and should be removed from the trust store. A certificate can also be _on hold_, which means that it is in pending state due to investigation and should not be removed. + +All platforms should perform revocation checks on a regular basis. There are two common ways to find out which certificates have been revoked; either through viewing a revocation list (CRL) to be downloaded by platforms, or through a real-time HTTP query (OCSP) requested by platforms. + +#### Certificate Revocation List + +This is a file maintained by a CA. It contains a list of certificate serial numbers that have been revoked by the CA. This file can be downloaded by any platform at any time. The URL to the CRL file to be downloaded is included in the certificate itself and can be found in _CRL Distribution Points_. A CRL is signed by the CA and should be validated. + +A CRL should be downloaded once per day and cached by the platform. + +For examples, see How to verify a certificate through a CRL. + +#### Online Certificate Status Protocol + +The status of a certificate can be retrieved by sending an OCSP request to an _OCSP Responder_ (which can be the CA). The request contains the serial number of the certificate to be checked. The responder sends back a signed response including the status of the certificate. + +The request should contain a nonce value, which the responder will put in the response, for the platform to validate on receipt. This is to prevent reply attacks. + +An OCSP request/response is considered very fast and can be executed for each received client certificate operation, but depending on the load towards the responder, it might have to be cached by the platform as well. + +The OCSP URL is included in the certificate itself and can be found in _Authority Information Access_. + +For examples, see How to verify a certificate through an OCSP request. + +### Renewing Certificates + +Do not renew certificates for which an asymmetric key pair is reused. For increased security, the asymmetric key pairs must be recreated every time through a new CSR. + +## Transport Layer Protection + +This section describes transport layer protection. + +### TLS + +TLS provides point-to-point integrity and confidentiality, and is used for all communication between peers. + +The setup requires both _server authentication_ - meaning that the server presents itself through its own TLS certificate - and _client authentication_ (also known as mutual authentication) in which the client presents itself through its own TLS certificate. + +#### TLS Protocol Versions + +The TLS protocol version used must be 1.2 or higher. + +#### TLS Cipher Suites + +The following cipher suites should be used: + +- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + +- TLS_RSA_WITH_AES_256_GCM_SHA384 + +- TLS_RSA_WITH_AES_128_GCM_SHA256 + +## Application Layer Protection + +This section describes the application layer protection. + +### JSON Web Signature + +The _JSON Web Signature_ (JWS) standard is used for providing end-to-end integrity and non-repudiation; that is, to guarantee that the sender is who it claims to be, and that the message was not tampered with. + +The use of JWS is mandatory and certificates should be used. For more information, see _API Signature_. + +### JSON Web Encryption + +The _JSON Web Encryption_ (JWE) standard is used for providing end-to-end confidentiality; that is, to protect data from being read by unauthorized parties. + +The use of JWE is optional and is applied to specific fields. This is to fulfill regulatory requirements that might exist for certain type of data in certain countries. + +For more information about how to apply JWE to fields in messages, see the extended JWE standard specification _API Encryption_. + + +## List of Appendices + +### Appendix A - Key Lengths and Algorithms + +Table 2 contains the required key length and algorithm for each entity. + +| Entity | Algorithm | Key length/hash size | +| --- | --- | --- | +| CA asymmetric keys | RSA | 4096 bits | +| CA signing algorithm | RSA with SHA2 | >= 256 bits | +| TLS asymmetric keys | RSA | 2048 bits | +| TLS signing algorithm | RSA with SHA2 | >= 256 bits | +| Signature asymmetric keys | RSA | 2048 bits | +| Signature algorithm | RSA with SHA2 | >= 256 bits | +| Encryption asymmetric keys | RSA | 2048 bits | +| HMAC | SHA2 - AES | >= 256 bits| +| Symmetric keys | AES | 256 bits | +| Hashing | SHA2 | >= 256 bits | + +**Table 2 – Key lengths and algorithms** + +### Appendix B - Terminology + +| | | +| --- | --- | +| PKI | Public Key Infrastructure +| API | Application Program Interface +| TLS | Transport Layer Security +| JWS | JSON Web Signature +| JWE | JSON Web Encryption +| FSP | Financial Service Provider +| AL | Account Lookup +| CA | Certificate Authority +| CSR | Certificate Signing Request +| CRL | Certificate Revocation List +| OCSP | Online Certificate Status Protocol +| PEM | Privacy Enhanced Mail +| RSA | Rivest, Shamir, & Adleman +| HMA | Hashed Message Authentication Code +| AES | Advanced Encryption Standard +| SHA | Secure Hash Algorithm + +### Appendix C - Common PKI Tasks + +#### Appendix C.1 - How to create a store, certificate, and CSR + +**Using the Java keytool** + +Use the following command to create an asymmetric RSA key pair and associated certificate information to be signed by the +CA. It will automatically create a JKS key store if the given one does not exist: + +``` +keytool -genkey -dname "CN=" -alias -keyalg RSA - +keystore -keysize 2048 +``` + +**Example** + +``` +keytool -genkey -dname "CN=bank-fsp" -alias tlscert -keyalg RSA -keystore +tlskeystore.jks -keysize 2048 +``` + +**Notes:** + +1. The certificate attribute CN specifies the hostname of the host who identifies itself using this certificate during a TLS session. +2. When asked for password, use the same password for the key as the key store. + +Use the following command to create the actual CSR to be signed by the CA: + +``` +keytool -certreq -alias -keystore –file .csr +``` + +**Example** + +``` +keytool -certreq -alias tlscert -keystore tlskeystore.jks -file tlscert.csr +``` + +**Using openssl** + +Use the following command to create an asymmetric RSA key pair, and CSR to be signed by the CA: + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=" -out +.csr -keyout .key +``` + +**Example** + +``` +openssl req -new -newkey rsa:2048 -nodes -subj "/CN=bank-fsp" -out tlscert.csr - +keyout tlscert.key +``` + +**Note:** The certificate attribute CN specifies the hostname of the host who identifies itself using this certificate during a TLS session. + +Important to note is that the created private key is stored unencrypted. Use the following command to encrypt it: + +``` +openssl rsa -aes256 -in -out +``` + +**Example** + +``` +openssl rsa -aes256 -in tlscert.key -out tlscert_encrypted.key +``` + +#### Appendix C.2 - How to import a signed certificate into your key store + +**Using the Java keytool** + +Import your signed certificate into your key store. This certificate should replace the old unsigned one, so make sure that you use the correct alias. + +``` +keytool -importcert -alias -file -keystore +``` + +**Example** + +``` +keytool -importcert -alias tlscert -file bank-fsp.pem -keystore tlskeystore.jks +``` + +**Using openssl** + +Remove your old CSR file and replace it with the new signed certificate. + +#### Appendix C.3 - How to import the CA certificate into your key store + +**Using Java keytool** + +Import the CA certificate into your key store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlskeystore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Using openssl** + +Put the CA certificate with your other certificate files + +#### Appendix C.4 - How to import the CA certificate into TLS trust store + +**Using Java keytool** + +Import the CA certificate into your trust store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias rootca -file rootca.pem -keystore tlstruststore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` +**Using openssl** + +Put the CA certificate with your other certificate files. + +#### Appendix C.5 - How to view a certificate + +**Using Java keytool** + +Use this command to list all certificates stored in a key store in readable format: + +``` +keytool -list -keystore -v +``` + +**Example:** + +``` +keytool -list -keystore tlskeystore.jks -v +``` + +**Using openssl** + +Use this command to show the content of a PEM encoded certificate in readable format: + +``` +openssl x509 -in -text -nout +``` + +**Example:** + +``` +openssl x509 -in rootca.pem -text -nout +``` + +#### Appendix C.6 - How to import a trusted certificate + +**Using Java keytool** + +Import the certificate into your trust store: + +``` +keytool -importcert -alias -file -keystore +``` + +**Example:** + +``` +keytool -importcert -alias trustedcert -file cert.pem -keystore truststore.jks +``` + +When you are asked to trust the imported certificated, answer **yes**: + +``` +Trust this certificate? [no]: yes +Certificate was added to keystore +``` + +**Using openssl** + +Put the trusted certificate with your other certificate files. + +#### Appendix C.7 - How to verify a certificate through a CRL + +**Using Java** + +You can use a specific security library for this (for example, Bouncy Castle), or use the in-built support for it, see: +[https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006](#https://stackoverflow.com/questions/10043376/java-x509-certificate-parsing-and-validating/10068006#10068006) + +**Using openssl** + +A good example is found at the following link: +[https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html](#https://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html) + +#### Appendix C.8 - How to verify a certificate through an OCSP request + +**Using Java** + +Some Java examples is found in the following link: +[https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate](#https://stackoverflow.com/questions/5161504/ocsp-revocation-on-client-certificate) + +**Using openssl** + +A good example is found at the following link: +[https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html](#https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html) + + +1 This term, and other italicized terms, are defined in Glossary for Open API for FSP Interoperability Specification. + +2 [https://tools.ietf.org/html/rfc5246](#https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + +3 [https://tools.ietf.org/html/rfc7515](#https://tools.ietf.org/html/rfc7515) - JSON Web Signature (JWS) + +4 [https://tools.ietf.org/html/rfc7516](#https://tools.ietf.org/html/rfc7516) - JSON Web Encryption (JWE) + +
    + +## Table of Figures + +- [Figure 1 - Platforms layout](#platforms-point-to-point-layout) + +
    + +## Table of Tables + +- [Table 1 – Certificate type and key usage](#Table-1–Certificate-type-and-key-usage) + +- [Table 2 – Key lengths and algorithms](#Table-2-Key-lengths-and-algorithms) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/sandbox.md b/website/versioned_docs/v1.0.1/api/fspiop/sandbox.md new file mode 100644 index 000000000..e69de29bb diff --git a/website/versioned_docs/v1.0.1/api/fspiop/scheme-rules.md b/website/versioned_docs/v1.0.1/api/fspiop/scheme-rules.md new file mode 100644 index 000000000..7aa2e4e04 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/scheme-rules.md @@ -0,0 +1,216 @@ +# Scheme Rules + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +## Introduction + +This document defines scheme rules for Open API for FSP Interoperability (hereafter cited as the API) in three categories. + +1. Business Scheme Rules: + + a. These business rules should be governed by FSPs and an optional regulatory authority implementing the API within a scheme. + + b. The regulatory authority or implementing authority should identify valid values for these business scheme rules in their API policy document. + +2. API implementation Scheme Rules: + + a. These API parameters should be agreed on by FSPs and the optional Switch. These parameters should be part of the implementation policy of a scheme. + + b. All participants should configure these API parameters as indicated by the API-level scheme rules for the implementation with which they are working. + +3. Security and Non-Functional Scheme Rules. + + a. Security and non-functional scheme rules should be determined and identified in the implementation policy of a scheme. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](#) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## Business Scheme Rules + +This section describes the business scheme rules. The data model for the parameters in this section can be found in _API Definition._ + +#### Authentication Type + +The authentication type scheme rule controls the authentication types OTP and QR code. It lists the various authentication types available for _Payer_ authentication. A scheme can choose to support all the authentication types mentioned in “AuthenticationTypes” in _API Definition_ or a subset thereof. + +#### Consumer KYC Identification Required + +A scheme can mandate verification of consumer KYC (Know Your Customer) identification by Agent or Merchant at the time of transaction (for example, cash-out, cash-in, merchant payment). The API cannot control this scheme rule; therefore, it should be documented in scheme policy so that it is followed by all participants in a scheme. The scheme can also decide on the valid KYC proof of identification that should be accepted by all FSPs. + +#### Currency + +A scheme may recommend allowing transactions in more than one currency. This scheme may define the list of valid currencies in which transactions can be performed by participants; however, this is not required. A Switch may work as transaction router and doesn’t validate the transaction currency. If a scheme does not define the list of valid currencies, then the Switch works as transaction router and the participating FSP can accept or reject the transaction based on its supported currencies. Foreign exchange is not supported; that is, the transaction currency for the Payer and the _Payee_ should be the same. + +#### FSP ID Format + +A scheme may determine the format of the FSP ID. The FSP ID should be of string type. Each participant will be issued a unique FSP ID by the scheme. Each FSP should prepend the FSP ID to a merchant code (a unique identifier for a merchant) so that the merchant code is unique across all the participants (that is, across the scheme). The scheme can also determine an alternate strategy to ensure that FSP IDs and merchant codes are unique across participating FSPs. + +#### Interoperability Transaction Type + +The API supports the use cases documented in _Use Cases_. A scheme may recommend implementation of all the supported usecases or a subset thereof. A scheme may also recommend to rollout the use cases in phases. Two or more FSPs in the scheme might decide to implement additional use-cases supported by the API. A Switch may work as a transaction router and does not validate transaction type; the FSP can accept or reject the transaction based on its supported transaction types. If a participant FSP initiates a supported API transaction type due to incorrect configuration on the Payer end, then the transaction must be rejected by the peer FSP if the peer FSP doesn’t support the specific transaction type. + +#### Geo-Location Required + +The API supports geolocation of the Payer and the Payee; however, this is optional. A scheme can mandate the geolocation of transactions. In this case, all participants must send the geolocation of their respective party. + +#### Extension Parameters + +The API supports one or more extension parameters. A scheme can recommend that the list of extension parameters be supported. All participants must agree with the scheme rule and support the scheme-mandatory extension parameters. + +#### Merchant Code Format + +The API supports merchant payment transaction. Typically, a consumer either enters or scans a merchant code to initiate merchant payment. In case of merchant payment, the merchant code should be unique across all the schemes. Currently, the merchant code is not unique in the way that mobile numbers or email addresses are unique. Therefore, it is recommended to prepend a prefix or suffix (FSP ID) to the merchant code so that the merchant code is unique across the FSPs. + +#### Max Size Bulk Payments + +The API supports the Bulk Payment use-case. The scheme can define the maximum number of transactions in a bulk payment. + +#### OTP Length + +The API supports One-time Password (OTP) as authentication type. A scheme can define the minimum and maximum length of OTP to be used by all FSPs. + +#### OTP Expiration Time + +An OTP’s expiration time is configured by each FSP. A scheme can recommend it to be uniform for all schemes so that users from different FSPs have a uniform user experience. + +#### Party ID Types + +The API supports account lookup system. An account lookup can be performed based on valid party ID types of a party. A scheme can choose which party ID types to support from **PartyIDType** in API Definition. + +#### Personal Identifier Types + +A scheme can choose the valid or supported personal identifier types mentioned in **PersonalIdentifierType** in API Definition. + +#### QR Code Format + +A scheme should standardize the QR code format in the following two scenarios as indicated. + +##### Payer-Initiated transaction + +Payer scans the QR code of Payee (Merchant) to initiate a Payer-Initiated Transaction. In this case, the QR code should be standardized to include the Payee information, transaction amount, transaction type and transaction note, if any. The scheme should standardize the format of QR code for Payee. + +##### Payee-Initiated Transaction + +Payee scans the QR code of Payer to initiate Payee-Initiated transaction. For example: Merchant scans the QR code of Payer to initiate a Merchant Payment. In this case, the QR code should be standardized to locate the Payer without using the account lookup system. The scheme should standardize the format of QR code; that is, FSP ID, Party ID Type and Payer ID, or only Party ID Type and Party ID. + +## API Implementation Scheme Rules + +This section describes API implementation scheme rules. + +#### API Version + +API version information must be included in all API calls as defined in _API Definition_. A scheme should recommend that all FSPs implement the same version of the API. + +#### HTTP or HTTPS + +The API supports both HTTP and HTTPS. A scheme should recommend that the communication is secured using TLS (see [Communication Security](#communication-security) section). + +#### HTTP Timeout + +FSPs and Switch should configure HTTP timeout. If FSP doesn’t get HTTP response (either **HTTP 202** or **HTTP 200**) for the **POST** or **PUT** request then FSP should timeout. Refer to the diagram in Figure 1 for the **HTTP 202** and **HTTP 200** timeouts shown in dashed lines. + +###### Figure-1 + +![Figure 1 HTTP Timeout](../assets/scheme-rules-figure-1-http-timeout.png) + +**Figure 1 – HTTP Timeout** + +#### Callback Timeouts + +The FSPs and the Switch should configure callback timeouts. The callback timeouts of the initiating FSP should be greater than the callback timeout of the Switch. A scheme should determine callback timeout for the initiating FSP and the Switch. Refer to the diagram in Figure 2 for the callback timeouts highlighted in red. + +###### Figure-2 + +![Figure 1 Callback Timeout](../assets/scheme-rules-figure-2-callback-timeout.png) + + +**Figure 2 – Callback Timeout** + +## Security and Non-Functional Requirements Scheme Rules + +This section describes the scheme rules for security, environment and other network requirements. + +#### Clock Synchronization + +It is important to synchronize clocks between FSPs and Switches. It is recommended that an NTP server or servers be used for clock synchronization. + +#### Data Field Encryption + +Data fields that need to be encrypted will be determined by national and local laws, and any standard that must be complied with. Encryption should follow _Encryption_. + +#### Digital Signing of Message + +A scheme can decide that all messages must be signed as described in _Signature_. Response messages need not to be signed. + +#### Digital Certificates + +To use the signing and encryption features detailed in _Signature_ and _Encryption_ in a scheme, FSPs and Switches must obtain digital certificates as specified by the scheme-designated _CA_ (Certificate Authority). + +#### Cryptographic Requirement + +All parties must support the encoding and encryption ciphers as specified in _Encryption_, if encryption features are to be used in the scheme. + +#### Communication Security + +A scheme should require that all HTTP communication between parties is secured using TLS[1](https://tools.ietf.org/html/rfc5246) version 1.2 or later. + +1 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) - The Transport Layer Security (TLS) Protocol - Version 1.2 + + +### Table of Figures + +[Figure 1 – HTTP Timeout](#figure-1) + +[Figure 2 – Callback](#figure-2) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/use-cases.md b/website/versioned_docs/v1.0.1/api/fspiop/use-cases.md new file mode 100644 index 000000000..bb076dc26 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/use-cases.md @@ -0,0 +1,1098 @@ +# Use Cases + + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +The purpose of this document is to define a set of use cases that can be implemented using the Open API for FSP interoperability (hereafter cited as the API). The use cases referenced within this document provide an overview of transaction processing flows and business rules of each transaction step as well as relevant error conditions. + +The primary purpose of the API is to support the movement of financial transactions between one _Financial Services Provider_ (FSP) and another. + +It should be noted that the API is only responsible for message exchange between FSPs and a Switch when a cross-FSP transaction is initiated by an _End User_ in one of the FSPs. This can occur in either of two scenarios: + +- A bilateral scenario in which FSPs communicate with each other + +- A Switch based scenario in which all communication goes through a Switch + +Reconciliation, clearing and settlement after real time transactions is out of scope for the API. Additionally, account lookup is supported by the API, but it relies on the implementation in a local market in which a third party or Switch would provide such services. Therefore, the need for effective on-boarding processes and appropriate scheme rules must be considered when implementing use cases. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### General Documents + +- _Glossary_ + +#### Logical Documents + +- _Logical Data Model_ + +- _Generic Transaction Patterns_ + +- _Use Cases_ + +#### Asynchronous REST Binding Documents + +- _API Definition_ + +- _JSON Binding Rules_ + +- _Scheme Rules_ + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- _PKI Best Practices_ + +- _Signature_ + +- _Encryption_ + +
    + +## Use Case Summaries + +The following generic transaction patterns are introduced in [Generic Transaction Patterns]() to reduce duplication of each use case description. These patterns summarize the common transaction process flows and shared function of the relevant use cases. + +- **Payer-Initiated Transaction** + - In a _Payer-Initiated Transaction_, it is the _Payer_ (that is, the payer of electronic funds) who initiates the transaction. + + The pattern should be used whenever a Payer would like to transfer funds to another party whose account is not located in the same FSP. + +- **Payee-Initiated Transaction** + + - In a _Payee-Initiated Transaction_, it is the _Payee_ (that is, the recipient of electronic funds) who initiates the transaction. + + This pattern should be used whenever a Payee would like to receive funds from another party whose account is not located in the same FSP. + +- **Payee-Initiated Transaction using OTP** + + - A _Payee-Initiated Transaction using One-Time Password (OTP)_ is like a _Payee-Initiated Transaction_, but the transaction information (including fees and taxes) and approval for the Payer is shown or entered on a Payee device instead. + + - This pattern should be used when a Payee would like to receive funds from another party whose account is not located in the same FSP, and both the transaction information (including fees and taxes) and approval is shown or entered on a Payee device instead. + +- **Bulk Transactions** + + - In a _Bulk Transaction_, it is the Payer (that is, the sender of funds) who initiates multiple transactions to multiple Payees, potentially located in different FSPs. + + - The pattern should be used whenever a Payer would like to transfer funds to multiple Payees in the same transaction. The Payees can potentially be in different FSPs. + +It is recommended to read all Generic Transaction Patterns before reading the use cases. For more information, see [Generic Transaction Patterns](). + +Each use case describes variations on and special considerations for the generic transaction pattern to which it refers. The use cases are introduced in [Table 1](#table-1) below: + +##### Table 1 + +| Use Case Name | Description | +| --- | --- | +| P2P |This use case describes the business process and business rules in which an individual End User initiates a transaction to send money to another individual End User who doesn’t belong to the same FSP as the Payer.

    This is usually a remote transaction in which Payer and Payee are not in the same location. | +| Agent-Initiated Cash-In | This use case describes the business process and business rules in which a customer requests an agent of a different FSP to cash-in (deposit funds) to their account.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Agent-Initiated Cash-Out | This use case describes the business process and business rules in which a customer requests that an agent of a different FSP to cash-out (withdraw funds) from their account.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Agent-Initiated Cash-Out
    Authorized on POS
    | This use case describes the business process and business rules in which a customer requests an agent of a different FSP to cash-out (withdraw funds) from their account. In this use case, the agent initiates the transaction through a point-of-sale (_POS_) and the customer inputs OTP on POS to authorize the transaction. Alternatively, the agent can use POS to scan a QR code generated by a customer’s mobile app to initiate the transaction. | +| Customer-Initiated Cash-Out | This use case describes the business process and business rules in which a registered customer initiates a transaction to cash-out (withdraw funds) using an agent who doesn’t belong to the customer’s FSP.

    This is typically a face-to-face transaction in which the customer and the agent are in the same location. | +| Customer-Initiated Merchant
    Payment
    | This use case describes the business process and business rules in which an individual End User initiates a purchase transaction to pay a merchant who does not belong to the same FSP as the customer.

    This is usually a face to face transaction when a customer buys goods or services at a merchant store.

    A variant of this use case is online payment, in which the online shopping system generates a QR code and displays it on a web page, and the consumer then scans the QR code by handset and completes the payment transaction. | +| Merchant-Initiated Merchant
    Payment
    | This use case describes the business process and business rules in which a merchant initiates a request for payment to the customer; the customer reviews the transaction amount in the request and confirms the request by providing authentication on their own handset. | +| Merchant-Initiated Merchant
    Payment Authorized on POS
    | This use case describes the business process and business rules in which merchant initiates a request for payment from the customer; the customer reviews the payment request on a merchant device and authorizes the payment by OTP or QR code on the merchant device. The customer authentication information is sent from _Payee FSP_ to _Payer FSP_ for authentication by Payer FSP. | +| ATM-Initiated Cash-Out | This use case describes the business process and business rules in which an ATM initiates a cash-out request from a customer account. Customer pregenerates an OTP for cash-out and uses this OTP on the ATM device to initiate ATM cash-out. The Payer FSP validates the OTP received in the ATM-Initiated Cash-Out request for authentication purposes. | +| Bulk Payments | _Bulk Payments_ is used when an organization or business is paying out funds – for example, aid or salary to multiple Payees who have accounts located in the different FSPs. The organization or business can group transactions together to make it easier for uploading and validating individual transactions in bulk before the bulk transaction is executed. It is also possible for the organization to follow up the result of the individual transactions in the bulk transaction after the bulk transaction is executed. | +| Refund | This use case describes the business flow how to refund a completed interoperability transaction. | + +**Table 1 – Use Case Summary** + +
    + +## Use Cases + +This section demonstrates ways in which the API can be used through the use cases identified in [Table 1](#table-1) – _Use Case Summary_. + +For each use case, the following is presented: +- Use Case Description +- Reference to Generic Pattern +- Actors and Roles +- Addition to Generic Transaction Pattern +- Relevant Error Conditions + +### P2P + +#### Use Case Description + +This section describes the business process and business rules for a use case in which an individual End User initiates a transaction to send money to another individual End User who doesn’t belong to the same FSP as the Payer. + +This is usually a remote transaction in which Payer and Payee are not in the same location. + +There are four steps necessary to complete a _P2P_ Transfer transaction from one FSP user to another FSP user. + +##### Step 1 + +Payer initiates a transaction to their FSP, and Payer FSP then locates Payee FSP through an API call to the Account Lookup System or by the agreed-upon _scheme_ rules. + +##### Step 2 + +Payer FSP calculates the transaction fee applied to Payer. Payer FSP sends a quote request through an API call to Payee FSP. + +##### Step 3 + +Payer FSP presents the total transaction fee and Payee name (optional) to the Payer to confirm the transaction. + +##### Step 4 + +Payer accepts the transaction and Payer FSP performs the transaction through an API call to the Switch or to Payee FSP. The transaction completes and notifications are sent to both Payer and Payee; or the Payer rejects the transaction and the transaction ends. + +
    + +### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for P2P are described in [Table 2](#table-2) below: + +##### Table 2 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | An individual who is a registered customer of an FSP who initiates a transaction to send money to another individual. | +| Customer | Payee | The person who will receive money from Payer.

    Payee could be a registered customer of Payee FSP or, if the scheme rules allow it, an unregistered customer who will be registered during the transaction process, which is determined by the design of Payee FSP. + +**Table 2 – P2P Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 2 + +The Payee FSP ID could be determined by the scheme rule without any dependence on the API. Otherwise, **Lookup Party Information** request is an option for determining in which FSP a Payee is located. + +Payer FSP will use the request **Lookup Party Information** to retrieve details of Payee from Payee FSP directly if there is no Switch between Payer FSP and Payee FSP. + +##### Steps 9 – Step 15 + +In the current version of the API, the **Calculate Quote** request to Payee FSP is mandatory even if a wholesale fee is agreed upon in the scheme. Payee FSP needs to receive transaction details from the **Calculate Quote** request to generate the condition for this transaction. + +Payer FSP can use information from response **Return Quote Information** from Payee FSP to calculate the transaction fee it will apply on Payer. The business rules for how Payer FSP calculates the transaction fee could be defined by the scheme rules; this is out of scope for the API. + +In P2P Transfer case, it is the common practice that Payer pays the entire transaction fee, and Payee is free of charge in the transaction. + +##### Step 16 + +There are several ways to push a confirmation message to Payer to authorize the transaction. For example, USSD Push Message, or SMSC notification; then Payer opens the USSD menu to query and confirm the pending transaction + +The interaction between Payer and Payer FSP is designed by each FSP, and is out-of-scope for the API. + +##### Step 19 + +The Quote ID applied in the previous step is verified in the transaction processing step. If the quote is expired, Payee FSP will reject the transaction. + +##### Step 20 + +A notification is sent to the Payee once the transaction is performed by Payee FSP. + +##### Step 28 + +Payer FSP sends notification to Payer to indicate the transaction result. + +#### Relevant Error Conditions +[Table 3](#table-3) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 3 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +|4 | Payee is unreachable | Account Lookup System fails to locate Payee| Cancel the transaction | +|6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +|11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +|17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +|19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breach
  • Payer or Payee is blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +|22 | Funds reservation timed out | Funds reservation at Payer FSP is timed out and the transaction fails at Payer FSP but succeeds at Payee FSP. | Reconcile according to the scheme rules + +**Table 3 – P2P Relevant Error Conditions** + +
    + +### Agent-Initiated Cash-In + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests an agent of a different FSP to cash-in (deposit funds) to their account. This is a two-step transaction: Agent initiates a cash-in transaction from their handset or POS and then receives transaction information including possible fees. Agent can either approve or reject the transaction. Once transaction is completed, the customer gives cash to the agent. + +Agent-Initiated Cash-In is typically a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-In are described in [Table 4](#table-4) below: + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +|Agent | Payer | Payer is an agent (individual or organization) who will receive cash from the customer and transfer money to the customer’s account.

    Agent is a registered party with Payer FSP. | +| Customer | Payee | Customer is an individual who would like to deposit cash into their account.

    Customer is a registered individual in Payee FSP. | + +**Table 4 – Agent-Initiated Cash-In: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +Customer requests that an agent cash-in to their account. + +If a smart phone is used, the agent can scan a static QR code from the customer to capture the customer’s information and initiate the transaction. + +Optionally the agent verifies the identity of the customer. + +##### Step 12 + +This is an optional step. The customer checks cash-in transaction information and related fees on their own handset and then makes the decision to accept or reject the transaction. + +##### Step 16 + +The agent checks fees and taxes and either accepts or rejects. + +##### Step 20 + +A notification is sent to the customer after the transaction is performed by Payee FSP. + +##### Step 28 + +Payer FSP sends notification to the agent to indicate the transaction result. + +#### Relevant Error Conditions + +[Table 5](#table-5) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 5 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +|4 | Payee cannot be found | Account Lookup System fails to locate Payee | Cancel the transaction | +|6 |Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +|9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +|15 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction +|17 | Timeout | **Perform Transfer** request timed out | Query transfer status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +|19 |Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Low balance of Payee
  • Limit breached
  • Quote is expired
  • Payer or Payee blacklisted
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +|22 |Funds reservation timeout | Funds reservation at Payer FSP timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules + +**Table 5 – Agent-Initiated Cash-In: Relevant Error Conditions** + +
    + +### Agent-Initiated Cash-Out + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests an agent of a different FSP to cash-out (withdraw funds) from their account. This is a 2-step transaction, the agent initiates cash-out transaction request and the customer authorizes the transaction on their handset. Once transaction is completed, the agent gives cash to the customer. + +Agent-Initiated Cash-Out is a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-Out are described in [Table 6](#table-6). + +##### Table 6 + +| Role | Map to Generic
    Transaction Pattern
    | Description | +| --- | --- | --- | +|Customer | Payer | Payer is a customer (individual or organization) who wants to withdraw cash using an agent.

    Customer is a registered party in Payer FSP. | +|Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    Agent is a registered party in Payee FSP. | + +**Table 6 – Agent-Initiated Cash-Out: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +The customer requests that an agent cash-out (withdraw funds) from their account. + +If a smart phone is used, the agent can scan a static QR code containing the customer’s information to capture that information and initiate the transaction. + +Optionally, the agent may verify the identity of the customer to satisfy regulatory requirements. + +##### Step 17 + +The Payer FSP shows fees and taxes to the customer. The customer indicates whether they want to proceed or not. + +##### Step 25 + +A transaction notification is sent to the agent after the transaction is performed by Payee FSP. + +##### Step 33 + +After receiving transaction notification, the agent gives the cash-out amount to the customer. + +##### Relevant Error Conditions + +[Table 7](#table-7) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 7 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 3 | Payer cannot be found | Account Lookup System fails to locate the Payer | Cancel the transaction | +| 7 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction supported by Payee FSP | +| 22 | Timeout | **Perform Transfer** request timed out | Query transfer status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 24 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 27 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP. | Reconcile according to scheme rules | + +**Table 7 – Agent-Initiated Cash-Out: Relevant Error Conditions** + +### Agent-Initiated Cash-Out Authorized on POS + +#### Use Case Description + +This section describes the business process and business rules for the use case in which a customer requests that an agent of a different FSP cash-out (withdraw funds) from their account. In this use case, the agent initiates the transaction through a POS, and the customer inputs a OTP on POS to authorize the transaction. Alternatively, the agent can use POS to scan a QR code generated by the mobile app of the customer to initiate the transaction. + +- Approval using OTP – A Payer can approve a transaction by first creating an OTP in their FSP. The OTP is then entered in a Payee device (usually a POS device). The OTP in the transaction request is automatically matched by the Payer FSP to either approve or reject the transaction. The OTP does not need to be encrypted as it should only be valid once during a short time period. + +- Approval using QR code – A Payer can approve a transaction by requesting a Payer FSP to generate a QR code that encodes an OTP and customer’s identifier. + +- Approval using NFC – A Payer can approve a transaction by swiping a _Near Field Communication_ (NFC) phone on a POS. The interoperability for NFC POS of one FSP to read data from NFC tag or NFC phone of another FSP should be considered if NFC technology is adopted. + +Agent-Initiated Cash-Out Authorized on POS is typically a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and Roles + +The actors and roles for Agent-Initiated Cash-Out Authorized on POS are described in [Table 8](#table-8). + +##### Table 8 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer (individual or organization) who wants to withdraw cash using an agent.

    The customer is a registered party with Payer FSP.| +| Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    The agent is registered party with Payee FSP. | + +**Table 8 – Agent-Initiated Cash-Out Authorized on POS: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +For OTP: + +- The customer requests Payer FSP to generate an OTP. + +For QR code: + +- The customer enters cash-out amount and requests Payer FSP to generate a QR code. + +- The QR code generation should be approved by customer transaction PIN. + +##### Step 4 + +The customer requests the agent to cash-out some amount from their account. + +For OTP: + +- The agent inputs the customer’s ID and cash-out amount to initiate the transaction + +For mobile app: + +- The agent inputs cash-out amount and then scan QR code of customer via scanner POS + +For NFC: + +- The agent inputs cash-out amount and the customer taps phone on NFC POS. + +- The agent verifies identity of the customer to satisfy regulation requirements. + +##### Step 21 + +There is a risk that someone other than the owner of phone may attempt to use the phone to make a transaction at an agent store. Thus, the transaction should be approved via PIN to allow an OTP to be generated automatically. + +##### Step 25 + +The customer checks fees and taxes. If the customer agrees: + +- For OTP: The customer enters OTP on the agent phone or device. + +- For QR code/NFC: The customer confirms the payment on POS. + +If the customer disagrees: + +- For OTP: The customer doesn’t enter OTP on the agent phone or device. + +- For QR code/NFC: The customer rejects the payment on POS. + +##### Step 36 + +A notification is sent to the agent after the transaction is performed by the Payee FSP. After receiving transaction notification, the agent gives the cash-out amount to the customer. + +##### Step 44 + +The Payer FSP sends a notification of the transaction result to the customer. + +##### Relevant Error Conditions + +[Table 9](#table-9) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 9 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timedout| Retry| +| 6 | Payer cannot be found | Account Lookup System fails to locate the Payer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 28 | OTP is expired | OTP is expired | Push another authentication request to Payee FSP
    or
    Cancel the transaction in the Payer FSP | +| 28 | Invalid OTP | OTP is unrecognized | Push another authentication request to Payee FSP
    or
    Cancel the transaction in the Payer FSP | +| 35 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 38 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 9 – Agent-Initiated Cash-Out Authorized on POS: Relevant Error Conditions** + +### Customer-Initiated Cash-Out + +#### Use Case Description + +This section describes the business process and business rules for a use case in which a registered customer initiates a transaction to withdraw cash using an agent who is in a different FSP. This is two-step business process: a customer initiates cash-out transaction on their handset and then receives transaction information including fees, which can either be rejected or accepted. + +Customer-Initiated Cash-Out usually is a face-to-face transaction in which the customer and the agent are in the same location. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Customer-Initiated Cash-Out are described in [Table 10](#table-10). + +##### Table 10 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer (individual or organization) who wants to cash-out (withdraw funds) using an agent.

    Customer is a registered party with Payer FSP. | +| Agent | Payee | Payee is an agent registered with the Payee FSP. A pre-funded wallet for the agent is maintained at Payee FSP.

    Agent is registered party with Payee FSP. | + +**Table 10 – Customer-Initiated Cash-Out: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +The customer requests that the agent cash-out some amount from their account. + +For USSD: + +- The customer inputs cash-out amount and merchant ID to initiate the transaction. + +For mobile app: + +- If a smart phone is used, the customer can scan the static QR code of the agent to capture the agent’s information and initiate transaction. + +Optionally, the agent can verify the identity of the customer to satisfy regulatory requirements. + +##### Step 12 + +This is an optional step. Payee FSP shows fees, taxes or both to the agent. If the agent does not accept the fees or commission, they can reject the transaction. + +##### Step 16 + +Payer FSP shows fees and taxes to the customer. If the customer doesn’t want to proceed, they reject the transaction. + +##### Step 20 + +A notification is sent to the agent once the transaction is performed by Payee FSP. + +##### Step 29 + +After the customer receives transaction notification, the agent gives cash-out amount to the customer. + +#### Relevant Error Conditions + +[Table 11](#table-11) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 11 + +|Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +|2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Agent cannot be found | Account Lookup System fails to locate agent | Cancel the transaction | +| 6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 |Timeout | **Calculate Quote** request timed out | Retry with the same ID | +| 11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 11 – Customer-Initiated Cash-Out: Relevant Error Conditions** + +### Customer-Initiated Merchant Payment + +#### Use Case Description + +This section describes the business process and business rules for a use case in which a registered customer initiates a merchant payment transaction to pay a merchant who is in another FSP. + +This could be a face to face transaction; for example, when a customer buys goods or services at the merchant store. Another case is online payment, in which an online shopping system generates a QR code and displays on the web page, and the customer then scans the QR code on the web page and authorizes and completes the payment transaction on their handset. + +**Assumption:** Encoding/Decoding QR code is handled in each FSP and is out of scope of API. The data and its format encoded in the QR code should be defined in the scheme rules to enable QR codes to be interoperable. + +#### Reference to General Pattern + +_Payer-Initiated Transaction_ + +#### Actors and Roles + +The actors and roles for Customer-Initiated Merchant Payment are described in [Table 12](#table-12). + +##### Table 12 + +| Role | Map to Generic Transaction Pattern | Description +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business that sells goods or provide service and then receives payment from the customer. | + +**Table 12 – Customer-Initiated Merchant Payment: Actors and Roles** + +#### Addition to Generic Transaction Pattern + +##### Step 1 + +For feature phone: + +- The customer can initiate a payment transaction by inputting relevant payment information on the USSD menu, such as amount and merchant ID. + +For smart phone: + +- The customer initiates merchant payment transaction by scanning the merchant QR code. After resolving the merchant QR code, there are two scenarios: + + a) The customer inputs transaction amount in their handset to continue the transaction if the transaction amount is not encoded in the QR code. This is the case for face-to-face payment at retailer merchant store. + + b) Transaction amount has already been encoded in the QR code, and then Payer FSP has enough information to continue the transaction. This case then follows the process of the online payment case identified in [4.6.1](#461-use-case-description). + +##### Step 2 + +The merchant FSP ID could be determined by the scheme rules without depending on an Account Lookup System. Otherwise, **Lookup Party Information** request is an option to find out in which FSP the merchant is located. + +In most cases, the merchant FSP ID is captured during initiating the transaction. For example, the customer selects the merchant FSP from USSD menu, or it is already encoded in the merchant QR code. + +##### Step 9 – Step 15 + +In most cases, the customer is free of charge for the purchase transaction. **Calculate Quote** request is still necessary, because all transaction details will be sent to Payee FSP and the condition of the transfer will be generated by Payee FSP for later use (in **Perform Transfer**). + +##### Step 20 + +A notification is sent to the merchant once the transaction is performed by the Payee FSP. + +##### Step 29 + +Customer receives transaction notification and customer receives goods. + +#### Relevant Error Conditions + +[Table 13](#table-13) describes relevant errors and recommended follow-up actions for this use case. + +##### Table 13 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Merchant is unreachable | Account Lookup System fails to locate merchant | Cancel the transaction | +| 6 | Currency is not supported | The transaction currency is not supported. | Initiate a new transaction with supported currency by Payee FSP | +| 9 | Timeout | **Calculate Quote** request timed out | Retry with the same ID | +| 11 | Wrong quote | Payee FSP cannot provide quote due to internal business rule validation failure or system error.

    For example, invalid account status of Payee, wrong fee configuration or database error | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Reservation is expired | Funds reservation is expired and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 13 – Customer-Initiated Merchant Payment: Relevant Error Conditions** + +### Merchant-Initiated Merchant Payment + +#### Use Case Description + +This use case describes a merchant payment transaction, initiated by a merchant and then authorized by the customer on their handset. + +The business process involves two parties, a merchant and a customer. The merchant initiates a _request to pay_ transaction to the customer. The customer can review the transaction details and approve or reject the transaction on their mobile device. + +Thus, it is a two-step business process in which the merchant initiates a payment transaction and the customer authorizes the transaction from their account. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction_ + +#### Actors and roles + +The actors and roles for Merchant-Initiated Merchant Payment are described in [Table 14](#table-14). + +##### Table 14 + +| Role | Map to Generic Transaction Pattern | Description | +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business who sells goods or provides services and then receives payment from the customer. | + +**Table 14 – Merchant-Initiated Merchant Payment: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the End User as the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +For feature phone: + +- The merchants can input the customers’ ID in their USSD/STK menu when initiating payment transactions. + +For smart phone: + +- To capture the customer’s ID, the merchant may use a scan device or mobile app to scan QR code generated by the customer’s mobile app. + +##### Step 10-16 + +In a merchant payment transaction, the customer is usually free-of-charge. + +##### Step 13 + +This is an optional step. Payee FSP shows the transaction details including fees to the merchant; and the merchant can accept or reject the transaction. + +##### Step 25 + +A notification is sent to the merchant after the transaction is performed by the Payee FSP. + +##### Step 33 + +Payer FSP sends a notification to the customer to indicate the transaction result. + +#### Relevant Error Conditions + +[Table 15](#table-15) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 15 + +| Step | Error Condition | Error Description | Follow Up Action | +| -- | -- | -- | -- | +| 2 | Account Lookup Timeout | **Lookup Party Information** request timed out | Retry | +| 3 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 5 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 10 | Quote request failed | **Calculate Quote** request timed out or failed at Switch or Payee FSP | Cancel the transaction | +| 24 | Quote expired | Quote expired | Cancel the transaction | +| 27 | Reservation timeout | Funds reservation timed out at Payer FSP and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to scheme rules | + +**Table 15 – Merchant-Initiated Merchant Payment: Relevant Error Conditions** + +
    + +### Merchant-Initiated Merchant Payment Authorized on POS + +#### Use Case Description + +This use case describes a merchant payment initiated by a merchant using a device such as POS, and how to authorize a transaction with an OTP or a QR code. + +The merchant initiates a merchant payment transaction using a POS device. This device has the capability to capture the customer’s authorization on POS instead of the customer’s mobile device. The authorization information captured in POS should be sent to Payer FSP to perform the authorization. + +The business process involves two parties, Merchant and Customer. The merchant initiates a request to pay for the customer, and the customer reviews the payment request on POS and authorizes the payment by OTP or QR code on the POS itself. The customer authentication information is sent from Payee FSP to Payer FSP for authentication by Payer FSP. If authentication is successful then transaction will be posted on Payer FSP and Payee FSP. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and roles + +The actors and roles for Merchant-Initiated Merchant Payment Authorized on POS are described in [Table 16](#table-16) below: + +##### Table 16 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Customer | Payer | An individual End User of one FSP who buys goods or service from a merchant of another FSP. | +| Merchant | Payee | The business who sells goods or provide service and then receive payment from the customer. | + +**Table 16 – Merchant-Initiated Merchant Payment Authorized on POS: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user, because the interactions between the participating systems are described in the general pattern. + +##### Step 1-3 + +The customer can pre-authorize the transaction by generating a dynamic payment QR code on a mobile app if they have a smart phone. + +The customer can request an OTP on the USSD menu if they have a feature phone. + +##### Step 4 + +For mobile app: + +- The merchant uses a scan device such as a POS to capture the QR code and initiate the payment. + +- Both customer ID and OTP are encoded in the QR code. + +For feature phone: + +- The merchant inputs customer’s ID and amount to initiate the transaction. + +##### Step 20 + +Steps 1-3 are optional and will be used only when OTP is generated by Payer to authenticate the purchase at the merchant +device. However, it would be very rare for a customer to generate the OTP manually; instead Payer FSP would generate an OTP for the customer as described in Step 20. + +##### Step 21 + +There is a risk that someone other than the owner of phone may attempt to use the phone to make a transaction at agent store. Thus, the transaction should be approved via PIN to allow OTP to be generated automatically. + +##### Step 25 + +The customer need only confirm the transaction on POS if initiating transaction with a QR code in step 4, because OTP is encoded in the QR code and parsed in Step 4. + +##### Step 36 + +A notification is sent to the merchant once the transaction is performed by the Payee FSP. After receiving the transaction notification, the merchant gives goods to the customer. + +##### Step 44 +The Payer FSP sends a notification of the transaction result to the customer. + +#### Relevant Error Conditions + +[Table 17](#table-17) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 17 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timed out | Retry | +| 6 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** to Payer FSP timed out | Query status and retry | +| 19 | Quote request failed | Quote failed at Switch or Payee FSP | Cancel the transaction | +| 33 | Transfer request timeout | **Perform Transfer** request to Payee FSP timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 35 | Transaction failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of Payee
  • Payee FSP internal system error

  • | Cancel the transaction | +| 38 | Reservation is expired | Funds reservation timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 17 – Merchant-Initiated Merchant Payment Authorized on POS: Relevant Error Conditions** + +
    + +### ATM-Initiated Cash-Out + +#### Use Case Description + +This section describes the business flows and rules of an _ATM-Initiated Cash-Out_ use case. + +This use case involves two parties: ATM and Customer. ATM initiates a Cash-Out request from the customer account and the customer confirms the request by providing authentication (OTP) on ATM. The customer pre-generates an OTP for cash-out and uses this OTP on ATM device to initiate ATM Cash-out. The Payer FSP validates the OTP received in _ATM-Initiated Cash-Out_ request for the validity of OTP as well as for authentication. If the customer authentication via OTP is successful; then the customer’s account will be debited at Payer FSP and ATM account maintained at Payee FSP will be credited. As a result, the customer receives cash from ATM. + +#### Reference to Generic Pattern + +_Payee-Initiated Transaction using OTP_ + +#### Actors and roles + +The actors and roles for ATM Initiated Cash Out are described in [Table 18](#table-18). + +##### Table 18 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Customer | Payer | Payer is a customer who wants to withdraw cash from ATM device belonging to another FSP. | +| ATM Provider | Payee | Payee is an ATM provider who provides cash withdrawal service on ATM device to a customer belonging to another FSP. ATM would be connected to a bank network which is connected to Payee FSP. There would be a pre-funded account in Payee FSP corresponding to an ATM or ATMs, or to a Bank Switch. | + +**Table 18 – ATM-Initiated Cash-Out: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user as the interactions between the participating systems are described in the general pattern. + +##### Step 1-3 + +Steps 1 to 3 are optional; however, it is recommended that customer generate an OTP before initiating the transaction request from ATM. + +Alternatively, a customer generates a QR code for cash-out via mobile app other than OTP. + +##### Step 4 + +For mobile app: + +- ATM can scan previously-generated cash-out QR code. + +For feature phone: + +- The customer initiates withdrawal transaction by inputting their account ID and amount. + +##### Step 20 + +In _ATM-Initiated Cash-Out_, it is very rare that an OTP is automatically generated by a Payer FSP, because this will delay the transaction due to SMS delivery, and the ATM transaction will time out. Therefore, it is recommended that customer generate an OTP for ATM Cash-out as mentioned in Steps 1-3. + +##### Step 21 + +There is a risk that someone other than the owner of phone holding the handset may make a transaction at an ATM device. In this case, the transaction should be approved via PIN so that the OTP can be generated automatically. + +##### Step 25 + +If an OTP is used, the customer enters the OTP that was generated in Steps 1-3 or Step 21. + +If a QR code is used to cash-out and it is captured by an ATM when initiating the transaction in Step 4, then the customer must confirm or reject the transaction on the ATM only; inputting security credentials such as OTP or password is not necessary. + +#### Relevant Error Conditions + +[Table 19](#table-19) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 19 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Timeout | **Lookup Party Information** request timed out | Retry | +| 6 | Customer cannot be found | Account Lookup System fails to locate the customer | Cancel the transaction | +| 8 | Transaction request timeout | **Perform Transaction Request** timed out at Switch or Payee FSP | Query and retry | +| 14 | Quote request timeout | **Calculate Quote** request timed out | Retry | +| 15 | Quote request failed | **Calculate Quote** request fails at Switch or Payee FSP | Cancel the transaction | +| 33 | Transfer request timeout | Perform Transfer request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 35 | Transaction request is failed | Transaction failed at the Payee FSP.
    Possible reasons:
  • Limit Breached
  • Payer or Payee blacklisted
  • Quote is expired
  • Invalid account status of merchant
  • Payee FSP internal system error

  • | Cancel the transaction and try another new transaction | +| 38 | Reservation is timeout | Funds reservation is timeout and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 19 – ATM-Initiated Cash-Out: Relevant Error Conditions** + +
    + +### Bulk Payments + +#### Use Case Description + +This section describes a _Bulk Payments_ use case. The use case is written from the end-user perspective to give additional information to the _Generic Transaction Patterns_ document. + +Bulk Payments are used when an organization or business is paying out funds; for example, aid or salary to multiple Payees. The organization or business can group transactions together to make it easier to upload and validate individual transactions in bulk before the bulk transaction is executed. It is also possible for the organization to follow up the result of the individual transactions in the bulk transaction after the bulk transaction is executed. + +#### Reference to Generic Pattern + +_Bulk Transactions_ + +#### Actors and roles + +The actors and roles for Bulk Payments are described in [Table 20](#table-20) below: + +##### Table 20 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | +| Payer | Payer | The Payer is a corporate, government or aid organization that is transferring money from its own account to multiple Payees. The reason can for instance be payout of monthly salary or aid disbursement.

    The Payer is a registered user with an account in the Payer FSP. | +| Payee | Payee | The Payee is, for example, an employee at a corporate or receiver of aid that is receiving a payout from the Payer.

    The Payee is a registered user with an account in one of the connected FSPs. | + +**Table 20 – Bulk Payments: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user as the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +The Payer creates a bulk transaction according to the format of the Payer FSP. Each row in the bulk transaction includes information about a transfer between a Payer account and a Payee account. The information includes: + +- A unique transaction ID for the bulk so that the Payer can follow up the status of individual transactions in the bulk. + +- Identifier of the Payee + +- Amount and currency to be transferred + +The Payer will upload the bulk transaction using the interface provided by the Payer FSP. + +##### Step 12 + +The Payer is notified by the Payer FSP that the bulk is ready for review. + +The Payer will get a bulk transaction report and validate that the specified Payees have accounts and can receive funds. + +The Payer can also validate any fees that will be charged for executing the bulk transaction. Fees will be calculated per transaction in the bulk transaction. + +Before the bulk transaction is executed, the Payer must ensure that there are enough funds in the Payer account for the value of the complete bulk transaction to be completed. Depending on scheme rules the Payer FSP needs to ensure that there are enough funds prefunded to the Payee FSP to be able to complete the transactions to the Payee. + +If the Payer is satisfied after reviewing the bulk transaction, then the Payer will initiate the execution of the bulk transaction. + +If the Payer does not want to execute the bulk transaction, then the bulk transaction can be canceled. Cancellation will be +handled internally in the Payer FSP. No information regarding cancelation will be sent to the Payee FSP. + +How execution and cancelation is handled depends on the implementation in the Payer FSP. + +##### Step 21 + +The Payer can review the result of the bulk transaction execution when the Payer FSP has processed all the transactions in the uploaded bulk transaction. + +The Payer will be able to get details about the execution for each individual transaction. + +Any reprocessing that might be needed to be executed (for example, failed transactions) will be treated as a new bulk transaction in the API. + +#### Relevant Error Conditions + +Bulk Transactions have two main types of logical errors: Errors connected to the header and errors related to the transactions in the bulk transaction. + +An error related to the header will fail the complete bulk transaction. For example, if the Payer of the bulk transaction is blocked, then no transaction shall be executed. + +Errors related to an individual transaction within the bulk transaction will get a failed status and be assigned an error code. The amount of the transaction that failed will be rolled back. Other transactions in the bulk transaction will not be affected if one individual transaction fails. + +[Table 21](#table-21) below contains a description of general error cases to give an overview of the bulk transaction use case and how different error cases are handled. Detailed error codes for the operations are not included, nor are codes for communication errors and format validations errors. + +##### Table 21 + +| Step | Error Condition | Error Description | Follow Up Action | +| --- | --- | --- | --- | +| 5 | Payee not found | Account lookup fails to look up Payee at any FSP. | Payee will be excluded from any bulk transactions request and marked as failed in the bulk transaction response to the Payer | +| 8 | Payee not found | Payee FSP cannot find the Payee account | Payee FSP will mark the individual transaction in the bulk transaction as failed. | +| 15 | Not enough funds on Payer FSP account | The Payer FSP account in the | Switch has not been prefunded to cover for the complete bulk transaction. Switch would fail the complete bulk transaction as the funds for the bulk transaction cannot be reserved. | +| 16 | Not enough funds on Payer FSP account | The Payer FSP account in the Payee FSP has not been prefunded to cover for the complete bulk transaction. | Payee FSP is not able to reserve the amount for the bulk transaction.

    Payee FSP can decide to execute as many transactions as possible or to fail the complete bulk transaction. | +| 16 | Payee transfer not allowed | The Payee FSP cannot complete the transfer of funds to the Payee. This could, for example, be blocked due to an account limit. | The individual transaction will be rolled back and reported in Payer response as failed. | +| 16 | Bulk quote expired | The quote for the bulk transaction has expired | The Payee FSP will fail the complete bulk transaction requests. | + +**Table 21 – Bulk Payments: Relevant Error Conditions** + +
    + +### Refund + +This section describes how to refund a completed interoperability transaction. + +There are several refund scenarios for merchant payment transaction: + +1. The customer has entered an amount incorrectly and paid more than the invoice. + +2. The merchant is not able to deliver the goods as specified by the invoice already paid by the customer, so the merchant wants to refund money to the customer. + +3. An online merchant selling tickets (train, air or bus) provides a refund to a customer when the customer cancels the ticket. + +4. The customer has returned the goods to the merchant and the merchant wants to refund the customer. + +Additional business scenarios may require transaction reversals. For example: + +1. The customer has sent money to incorrect recipient. + +2. The customer accidently created the same transaction twice. + +It is recommended to use refund transaction to fulfill the business purpose. + +The business process will remain as reversal, but the technical implementation would require Payee FSP CCE to initiate a refund transaction. Payer FSP CCE coordinates with Payee CCE manually. If there is a Switch, then Switch administrator may help to facilitate the conversation between Payer FSP and Payee FSP. + +Note the following: + +- Refund can only be initiated by Payee of the original transaction. Alternatively, CCE of Payee FSP in the original transaction can also initiate refund from Payee account. + +- An original transaction can be refunded multiple times. + +#### Reference to Generic Pattern + +_Payer-Initiated Transaction_ + +#### Actors and roles + +The actors and roles for Bulk Payment are described in [Table 22](#table-22). + +##### Table 22 + +| Role | Map to Generic Transaction | Pattern Description | +| --- | --- | --- | --- | +| Payee | Payee | The End User who has made a wrong payment and requests a refund. | +| Payer | Payer | The End User who has received the payment in the original transaction. | + +**Table 22 – Refund: Actors and Roles** + +#### Addition to General Pattern + +This section describes how the use case connects to the general pattern. The description is focused on the end-user, because the interactions between the participating systems are described in the general pattern. + +##### Step 1 + +Payer of the original transaction can contact Payee or CCE of Payer FSP to request refund. The actual refund amount is negotiated between Payer and Payee before the refund. + +##### Step 9-15 + +Typically, the refund transaction is free-of-charge. + +##### Step 17 + +The original transaction ID should be captured in the refund transaction. + +#### Relevant Error Conditions + +[Table 23](#table-23) below describes relevant errors and recommended follow-up actions for this use case. + +##### Table 23 + +| Step | Error Condition | Error Description | Follow on Action | +| --- | --- | --- | --- | +| 2 | Timeout | **Lookup Party Information** request timed out | Retry | +| 4 | Payee cannot be found | Account Lookup System fails to locate Customer | Cancel the transaction | +| 17 | Timeout | **Perform Transfer** request timed out | Query transaction status and decide to complete or retry

    The retry policy will be defined by the scheme rules. For example, retry times and period | +| 19 | Transaction failed | Transaction failed at Payee FSP.
    Possible reasons:
  • Limit Breached
  • Quote is expired
  • Invalid account status of customer
  • Payee FSP internal system error

  • | Cancel the transaction | +| 22 | Funds reservation timeout | Funds reservation at Payer FSP timed out and the transaction fails at Payer FSP but succeeds at Payee FSP | Reconcile according to the scheme rules | + +**Table 23 – Refund: Relevant Error Conditions** + +
    + +## List of Tables + +[Table 1](#table-1) – Use Case Summary + +[Table 2](#table-2) – P2P Actors and Roles + +[Table 3](#table-3) – P2P Relevant Error Conditions + +[Table 4](#table-4) – Agent-Initiated Cash-In: Actors and Roles + +[Table 5](#table-5) – Agent-Initiated Cash-In: Relevant Error Conditions + +[Table 6](#table-6) – Agent-Initiated Cash-Out: Actors and Roles + +[Table 7](#table-7) – Agent-Initiated Cash-Out: Relevant Error Conditions + +[Table 8](#table-8) – Agent-Initiated Cash-Out Authorized on POS: Actors and Roles + +[Table 9](#table-9) – Agent-Initiated Cash-Out Authorized on POS: Relevant Error Conditions + +[Table 10](#table-10) – Customer-Initiated Cash-Out: Actors and Roles + +[Table 11](#table-11) – Customer-Initiated Cash-Out: Relevant Error Conditions + +[Table 12](#table-12) – Customer-Initiated Merchant Payment: Actors and Roles + +[Table 13](#table-13) – Customer-Initiated Merchant Payment: Relevant Error Conditions + +[Table 14](#table-14) – Merchant-Initiated Merchant Payment: Actors and Roles + +[Table 15](#table-15) – Merchant-Initiated Merchant Payment: Relevant Error Conditions + +[Table 16](#table-16) – Merchant-Initiated Merchant Payment Authorized on POS: Actors and Roles + +[Table 17](#table-17) – Merchant-Initiated Merchant Payment Authorized on POS: Relevant Error Conditions + +[Table 18](#table-18) – ATM-Initiated Cash-Out: Actors and Roles + +[Table 19](#table-19) – ATM-Initiated Cash-Out: Relevant Error Conditions + +[Table 20](#table-20) – Bulk Payments: Actors and Roles + +[Table 21](#table-21) – Bulk Payments: Relevant Error Conditions + +[Table 22](#table-22) – Refund: Actors and Roles + +[Table 23](#table-23) – Refund: Relevant Error Conditions \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/v1.0/README.md b/website/versioned_docs/v1.0.1/api/fspiop/v1.0/README.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/v1.0/README.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/v1.0/api-definition.md b/website/versioned_docs/v1.0.1/api/fspiop/v1.0/api-definition.md new file mode 100644 index 000000000..96cef71e4 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/v1.0/api-definition.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/mojaloop-specification/master/fspiop-api/documents/v1.0-document-set/fspiop-rest-v1.0-OpenAPI-implementation.yaml \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/v1.1/api-definition.md b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/api-definition.md new file mode 100644 index 000000000..1cb2bb96f --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/api-definition.md @@ -0,0 +1,5492 @@ +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.0**|2018-03-13|Initial version| +|**1.1**|2020-05-19|1. This version contains a new option for a Payee FSP to request a commit notification from the Switch. The Switch should then send out the commit notification using the new request **PATCH /transfers/**_{ID}_. The option to use commit notification replaces the previous option of using the ”Optional Additional Clearing Check”. The section describing this has been replaced with the new section ”Commit Notification”. As the **transfers** resource has been updated with the new **PATCH** request, this resource has been updated to version 1.1. As part of adding the possibility to use a commit notification, the following changes has been made:
    a. PATCH has been added as an allowed HTTP Method in Section 3.2.2. b. The call flow for **PATCH** is described in Section 3.2.3.5.
    c. Table 6 in Section 6.1.1 has been updated to include **PATCH** as a possible HTTP Method.
    d. Section 6.7.1 contains the new version of the **transfers** resource.
    e. Section 6.7.2.6 contains the process for using commit notifications
    f. Section 6.7.3.3 describes the new **PATCH /transfers**/_{ID}_ request.

    2. In addition to the changes mentioned above regarding the commit notification, the following non-API affecting changes has been made:
    a. Updated Figure 6 as it contained a copy-paste error.
    b. Added Section 6.1.2 to describe a comprehensive view of the current version for each resource.
    c. Added a section for each resource to be able to see the resource version history.
    d. Minor editorial fixes.

    3. The descriptions for two of the HTTP Header fields in Table 1 have been updated to add more specificity and context
    a. The description for the **FSPIOP-Destination** header field has been updated to indicate that it should be left empty if the destination is not known to the original sender, but in all other cases should be added by the original sender of a request.
    b. The description for the **FSPIOP-URI** header field has been updated to be more specific.

    4. The examples used in this document have been updated to use the correct interpretation of the Complex type ExtensionList which is defined in Table 84. This doesn’t imply any change as such.
    a. Listing 5 has been updated in this regard.

    5. The data model is updated to add an optional ExtensionList element to the **PartyIdInfo** complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 103 has been updated. For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.

    6. A new Section 6.5.2.2 is added to describe the process involved in the rejection of a quote.

    7. A note is added to Section 6.7.4.1 to clarify the usage of ABORTED state in **PUT /transfers/**_{ID}_ callbacks.| +|**1.1.1**|2021-09-22|This document version only adds information about optional HTTP headers regarding tracing support in [Table 2](#table-2), see _Distributed Tracing Support for OpenAPI Interoperability_ for more information. There are no changes in any resources as part of this version.| + +## Introduction + +This document introduces and describes the _Open API_ (Application Programming Interface) _for FSP_ (Financial Service Provider) _Interoperability_ (hereafter cited as "the API"). The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. The API does not specify any front-end services between a Payer or Payee and its own FSP; all services defined in the API are between FSPs. FSPs are connected either (a) directly to each other or (b) by a _Switch_ placed between the FSPs to route financial transactions to the correct FSP. + +The transfer of funds from a Payer to a Payee should be performed in near real-time. As soon as a financial transaction has been agreed to by both parties, it is deemed irrevocable. This means that a completed transaction cannot be reversed in the API. To reverse a transaction, a new negated refund transaction should be created from the Payee of the original transaction. + +The API is designed to be sufficiently generic to support both a wide number of use cases and extensibility of those use cases. However, it should contain sufficient detail to enable implementation in an unambiguous fashion. + +Version 1.0 of the API is designed to be used within a country or region, international remittance that requires foreign exchange is not supported. This version also contains basic support for the [Interledger Protocol](#4-interledger-protocol), which will in future versions of the API be used for supporting foreign exchange and multi-hop financial transactions. + +This document: + +- Defines an asynchronous REST binding of the logical API introduced in _Generic Transaction Patterns_. +- Adds to and builds on the information provided in [Open API for FSP Interoperability Specification](#open-api-for-fsp-interoperability-specification). + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](../logical-data-model) + +- [Generic Transaction Patterns](../generic-transaction-patterns) + +- [Use Cases](../use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](../definitions) + +- [JSON Binding Rules](../json-binding-rules) + +- [Scheme Rules](../scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](../pki-best-practices) + +- [Signature](../v1.1/signature) + +- [Encryption](../v1.1/encryption) + +#### General Documents + +- [Glossary](../glossary) + +
    + +## API Definition + +This section introduces the technology used by the API, including: + +- [General Characteristics](#general-characteristics) +- [HTTP Details](#http-details) +- [API Versioning](#api-versioning) + +### General Characteristics + +This section describes the general characteristics of the API. + +#### Architectural Style + +The API is based on the REST (REpresentational State Transfer1) architectural style. There are, however, some differences between a typical REST implementation and this one. These differences include: + +- **Fully asynchronous API** -- To be able to handle numerous concurrent long-running processes and to have a single mechanism for handling requests, all API services are asynchronous. Examples of long-running processes are: + - Financial transactions done in bulk + - A financial transaction in which user interaction is needed + +- **Decentralized** -- Services are decentralized, there is no central authority which drives a transaction. + +- **Service-oriented** -- The resources provided by the API are relatively service-oriented compared to a typical implementation of a REST-based API. + +- **Not fully stateless** -- Some state information must be kept in both client and server during the process of performing a financial transaction. + +- **Client decides common ID** -- In a typical REST implementation, in which there is a clear distinction between client and server, it is the server that generates the ID of an object when the object is created on the server. In this API, a quote or a financial transaction resides both in the Payer and Payee FSP as the services are decentralized. Therefore, there is a need for a common ID of the object. The reason for having the client decide the common ID is two-fold: + - The common ID is used in the URI of the asynchronous callback to the client. The client therefore knows which URI to listen to for a callback regarding the request. + - The client can use the common ID in an HTTP **GET** request directly if it does not receive a callback from the server (see [HTTP Details](#http-details) section for more information). + + To keep the common IDs unique, each common ID is defined as a UUID (Universally Unique IDentifier2 (UUID). To further guarantee uniqueness, it is recommended that a server should separate each client FSP's IDs by mapping the FSP ID and the object ID together. If a server still receives a non-unique common ID during an HTTP **POST** request (see [HTTP Details](#http-details) section for more details). The request should be handled as detailed in [Idempotent Services in server](#idempotent-services-in-server) section. + +#### Application-Level Protocol + +HTTP, as defined in RFC 72303, is used as the application-level protocol in the API. All communication in production environments should be secured using HTTPS (HTTP over TLS4). For more details about the use of HTTP in the API, see [HTTP Details](#http-details). + +#### URI Syntax + +The syntax of URIs follows RFC 39865 to identify resources and services provided by the API. This section introduces and notes implementation subjects specific to each syntax part. + +A generic URI has the form shown in [Listing 1](#listing-1), where the part \[_user:password@_\]_host_\[_:port_\] is the `Authority` part described in [Authority](#authority) section. +_{resource}_. + +###### Listing 1 + +``` +scheme:[//[user:password@]host[:port]][/]path[?query][#fragment] +``` + +**Listing 1 -- Generic URI format** + +##### Scheme + +In accordance with the [Application Level Protocol](#aplication-level-protocol) section, the _scheme_ (that is, the set of rules, practices and standards necessary for the functioning of payment services) will always be either **http** or **https**. + +##### Authority + +The authority part consists of an optional authentication (`User Information`) part, a mandatory host part, followed by an optional port number. + +###### User Information + +User information should in general not be used by API deployments; the security measures detailed in *API Signature* and _API_ _Encryption_ should be used instead. + +###### Host + +The host is the server's address. It can be either an IP address or a hostname. The host will (usually) differ for each deployment. + +###### Port + +The port number is optional; by default, the HTTP port is **80** and HTTPS is **443**, but other ports could also be used. Which port to use might differ from deployment to deployment. + +##### Path + +The path points to an actual API resource or service. The resources in the API are: + +- **participants** +- **parties** +- **quotes** +- **transactionRequests** +- **authorizations** +- **transfers** +- **transactions** +- **bulkQuotes** +- **bulkTransfers** + +All resources found above are also organized further in a hierarchical form, separated by one or more forward slashes (**'/'**). Resources support different services depending on the HTTP method used. All supported API resources and services, tabulated with URI and HTTP method, appear in [Table 6](#table-6). + +##### Query + +The query is an optional part of a URI; it is currently only used and supported by a few services in the API. See the API resources in [API Services](#api-services) section for more details about which services support query strings. All other services should ignore the query string part of the URI, as query strings may be added in future minor versions of the API (see [HTTP Methods](#http-methods)). + +If more than one key-value pair is used in the query string, the pairs should be separated by an ampersand symbol (**'&'**). + +[Listing 2](#listing-2) shows a URI example from the API resource **/authorization**, in which four different key-value pairs are present in the query string, separated by an ampersand symbol. + +###### Listing 2 + +``` +/authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD +``` + +**Listing 2 -- Example URI containing several key-value pairs in the query string** + +##### Fragment + +The fragment is an optional part of a URI. It is not supported for use by any service in the API and therefore should be ignored if received. + +#### URI Normalization and Comparison + +As specified in RFC 72306, the [scheme](#scheme)) and [host](#host)) part of the URI should be considered case-insensitive. All other parts of the URI should be processed in a case-sensitive manner. + +#### Character Set + +The character set should always be assumed to be UTF-8, defined in 36297; therefore, it does not need to be sent in any of the HTTP header fields (see [HTTP Header Fields](#http-header-fields)). No character set other than UTF-8 is supported by the API. + +#### Data Exchange Format + +The API uses JSON (JavaScript Object Notation), defined in RFC 71598, as its data exchange format. JSON is an open, lightweight, human-readable and platform-independent format, well-suited for interchanging data between systems. + +
    + +### HTTP Details + +This section contains detailed information regarding the use of the application-level protocol HTTP in the API. + +#### HTTP Header Fields + +HTTP Headers are generally described in RFC 72309. The following two sections describes the HTTP header fields that should be expected and implemented in the API. + +The API supports a maximum size of 65536 bytes (64 Kilobytes) in the HTTP header. + +#### HTTP Request Header Fields + +[Table 1](#table-1) contains the HTTP request header fields that must be supported by implementers of the API. An implementation should also expect other standard and non-standard HTTP request header fields not listed here. + +###### Table 1 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**Accept**|**application/vnd.interoperability.resource+json**|0..1
    Mandatory in a request from a client. Not used in a callback from the server.
    The **Accept**10 header field indicates the version of the API the client would like the server to use. See [HTTP Accept Header](#http-accept-header) for more information on requesting a specific version of the API.| +|**Content-Length**|**3495**|0..1|The **Content-Length**11 header field indicates the anticipated size of the payload body. Only sent if there is a body.
    **Note**: The API supports a maximum size of 5242880 bytes (5 Megabytes).
    | +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|The **Content-Type**12 header indicates the specific version of the API used to send the payload body. See [Acceptable Version Requested by Client](#acceptable-version-requested-by-client) for more information.| +|**Date**|**Tue, 15 Nov 1994 08:12:31 GMT**|1|The **Date**13 header field indicates the date when the request was sent.| +|**X- Forwarded- For**|**X-Forwarded-For: 192.168.0.4, 136.225.27.13**|1..0|The **X-Forwarded-For**14 header field is an unofficially accepted standard used to indicate the originating client IP address for informational purposes, as a request might pass multiple proxies, firewalls, and so on. Multiple **X-Forwarded-For** values as in the example shown here should be expected and supported by implementers of the API.
    **Note**: An alternative to **X-Forwarded-For** is defined in RFC 723915. However, as of 2018, RFC 7239 is less-used and supported than **X-Forwarded-For**.
    | +|**FSPIOP- Source**|**FSP321**|1|The **FSPIOP-Source** header field is a non- HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing (see [Call Flow Routing](#call-flow-routing-using-fspiop-destination-and-fspiop-source) section) and signature verification (see header field **FSPIOP-Signature**).| +|**FSPIOP- Destination**|**FSP123**|0..1|The **FSPIOP-Destination** header field is a non-HTTP standard field used by the API for HTTP header-based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes (see [Call Flow Routing](#3236-call-flow-routing-using-fspiop-destination-and-fspiop-source) section for more information regarding routing). If the destination is not known (valid for service GET /parties), the field should be left empty.| +|**FSPIOP- Encryption**||0..1|The **FSPIOP-Encryption** header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request.
    For more information, see API Encryption.
    | +|**FSPIOP- Signature**||0..1|The **FSPIOP-Signature** header field is a non-HTTP standard field used by the API for applying an end-to-end request signature.
    For more information, see API Signature.
    | +|**FSPIOP-URI**|**/parties/msisdn/123456789**|0..1|The **FSPIOP-URI** header field is a non- HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information see _API Signature_.
    In the context of the Mojaloop FSPIOP API, the value for FSPIOP-URI starts with the **_service_** in the URI value. For example, if a URL is http://stg-simulator.moja.live/payerfsp/participants/MSISDN/123456789, then the FSPIOP-URI value is “/participants/MSISDN/123456789”.| +|**FSPIOP- HTTP- Method**|**GET**|0..1|The **FSPIOP-HTTP-Method** header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information see API Signature.| + +**Table 1 -- HTTP request header fields that must be supported** + +[Table 2](#table-2) contains the HTTP request header fields that are optional to support by implementers of the API. + +###### Table 2 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**traceparent**|**00-91e502e28cd723686e9940bd3f378f85-b0f903d000944947-01**|0..1|The traceparent header represents the incoming request in a tracing system in a common format. See _Distributed Tracing Support for OpenAPI Interoperability_ for more information.| +|**tracestate**|**banknrone=b0f903d0009449475**|0..1|Provides optional vendor-specific trace information, and support for multiple distributed traces. See _Distributed Tracing Support for OpenAPI Interoperability_ for more information.| + +**Table 2 -- HTTP request header fields that are optional to support** + +##### HTTP Response Header Fields + +[Table 3](#table-3) contains the HTTP response header fields that must be supported by implementers of the API. An implementation should also expect other standard and non-standard HTTP response header fields that are not listed here. + +###### Table 3 + +|Field|Example Values|Cardinality|Description| +|---|---|---|---| +|**Content-Length**|**3495**|0..1|The **Content-Length**16 header field indicates the anticipated size of the payload body. Only sent if there is a body.| +|**Content-Type**|**application/vnd.interoperability.resource+json;version=1.0**|1|The **Content-Type**17 header field indicates the specific version of the API used to send the payload body. See [Section 3.3.4.2](#3342-acceptable-version-requested-by-client) for more information.| + +**Table 3 -- HTTP response header fields** + +#### HTTP Methods + +The following HTTP methods, as defined in RFC 723118, are supported by the API: + +- **GET** -- The HTTP **GET** method is used from a client to request information about a previously-created object on a server. As all services in the API are asynchronous, the response to the **GET** method will not contain the requested object. The requested object will instead come as part of a callback using the HTTP **PUT** method. + +- **PUT** -- The HTTP **PUT** method is used as a callback to a previously sent HTTP **GET**, HTTP **POST** or HTTP **DELETE** method, sent from a server to its client. The callback will contain either: + + - Object information concerning a previously created object (HTTP **POST**) or sent information request (HTTP **GET**). + - Acknowledgement that whether an object was deleted (HTTP **DELETE**). + - Error information in case the HTTP **POST** or HTTP **GET** request failed to be processed on the server. + +- **POST** -- The HTTP **POST** method is used from a client to request an object to be created on the server. As all services in the API are asynchronous, the response to the **POST** method will not contain the created object. The created object will instead come as part of a callback using the HTTP **PUT** method. + +- **DELETE** -- The HTTP **DELETE** method is used from a client to request an object to be deleted on the server. The HTTP **DELETE** method should only be supported in a common Account Lookup System (ALS) for deleting information regarding a previously added Party (an account holder in an FSP), no other object types can be deleted. As all services in the API are asynchronous, the response to the HTTP **DELETE** method will not contain the final acknowledgement that the object was deleted or not; the final acknowledgement will come as a callback using the HTTP **PUT** method. + +- **PATCH** -- The HTTP **PATCH** method is used from a client to send a notification regarding an update of an existing object. As all services in the API are asynchronous, the response to the **POST** method will not contain the created object. This HTTP method does not result in a callback, as the **PATCH** request is used as a notification. + +
    + +#### HTTP Sequence Flow + +All the sequences and related services use an asynchronous call flow. No service supports a synchronous call flow. + +##### HTTP POST Call Flow + +[Figure 1](#figure-1) shows the normal API call flow for a request to create an object in a Peer FSP using HTTP **POST**. The service **_/service_** in the flow should be renamed to any of the services in [Table 6](#table-6) that support the HTTP **POST** method. + +###### Figure 1 + +{% uml src="assets/diagrams/sequence/figure1.plantuml" %} +{% enduml %} + +**Figure 1 -- HTTP POST call flow** + +##### HTTP GET Call Flow + +[Figure 2](#figure-2) shows the normal API call flow for a request to get information about an object in a Peer FSP using HTTP **GET**. The service **/service/**_{ID}_ in the flow should be renamed to any of the services in [Table 6](#table-6) that supports the HTTP **GET** method. + +###### Figure 2 + +{% uml src="assets/diagrams/sequence/figure2.plantuml" %} +{% enduml %} + +**Figure 2 -- HTTP GET call flow** + +##### HTTP DELETE Call Flow + +[Figure 3](#figure-3) contains the normal API call flow to delete FSP information about a Party in an ALS using HTTP **DELETE**. The service **/service/**_{ID}_ in the flow should be renamed to any of the services in [Table 6](#table-6) that supports the HTTP DELETE method. HTTP DELETE is only supported in a common ALS, which is why the figure shows the ALS entity as a server only. + +###### Figure 3 + +{% uml src="assets/diagrams/sequence/figure3.plantuml" %} +{% enduml %} + +**Figure 3 -- HTTP DELETE call flow** + +**Note:** It is also possible that requests to the ALS be routed through a Switch, or that the ALS and the Switch are the same server. + +##### HTTP PUT Call Flow** + +The HTTP **PUT** is always used as a callback to either a **POST** service request, a **GET** service request, or a **DELETE** service request. + +The call flow of a **PUT** request and response can be seen in [Figure 1](#figure-1), [Figure 2](#figure-2), and [Figure 3](#figure-3). + +##### HTTP PATCH Call Flow + +[Figure 4](#figure-4) shows an example call flow for a HTTP **PATCH**, which is used for sending a notification. First, an object is created using a **POST** service request from the Switch. The object is created in the FSP in a non-finalized state. The FSP then requests to get a notification regarding the finalized state from the Switch by sending the non-finalized state in the **PUT** callback. The Switch handles the callback and sends the notification regarding the finalized state in a **PATCH** service request. The only resource that supports updated object notification using HTTP **PATCH** is /transfers. + +###### Figure 4 + +{% uml src="assets/diagrams/sequence/figure4.plantuml" %} +{% enduml %} + +**Figure 4 -- HTTP PATCH call flow** + +**Note:** It is also possible that requests to the ALS be routed through a Switch, or that the ALS and the Switch are the same server. + +##### Call Flow Routing using FSPIOP-Destination and FSPIOP-Source + +The non-standard HTTP header fields **FSPIOP-Destination** and **FSPIOP-Source** are used for routing and message signature verification purposes (see _API Signature_ for more information regarding signature verification). [Figure 5](#figure-5) shows how the header fields are used for routing in an abstract **POST /service** call flow, where the destination (Peer) FSP is known. + +###### Figure 5 + +{% uml src="assets/diagrams/sequence/figure5.plantuml" %} +{% enduml %} + +**Figure 5 -- Using the customized HTTP header fields FSPIOP-Destination and FSPIOP-Source** + +For some services when a Switch is used, the destination FSP might be unknown. An example of this scenario is when an FSP sends a **GET /parties** to the Switch without knowing which Peer FSP that owns the Party (see [Section 6.3.2](#632-service-details) describing the scenario). **FSPIOP-Destination** will in that case be empty (or set to the Switch's ID) from the FSP, but will subsequently be set by the Switch to the correct Peer FSP. See [Figure 6](#figure-6) for an example describing the usage of **FSPIOP-Destination** and **FSPIOP-Source**. + +###### Figure 6 + +{% uml src="assets/diagrams/sequence/figure6.plantuml" %} +{% enduml %} + +**Figure 6 -- Example scenario where FSPIOP-Destination is unknown to FSP** + +
    + +#### HTTP Response Status Codes + +The API supports the HTTP response status codes19 in [Table 4](#table-4) below: + +###### Table 4 + +|Status Code|Reason|Description| +|---|---|---| +|**200**|`OK`|Standard response for a successful request. Used in the API by the client as a response on a callback to mark the completion of an asynchronous service.| +|**202**|`Accepted`|The request has been accepted for future processing at the server, but the server cannot guarantee that the outcome of the request will be successful. Used in the API to acknowledge that the server has received an asynchronous request.| +|**400**| `Bad Request`|The application cannot process the request; for example, due to malformed syntax or the payload exceeded size restrictions.| +|**401**|`Unauthorized`|The request requires authentication in order to be processed.| +|**403**|`Forbidden`|The request was denied and will be denied in the future.| +|**404**|`Not Found`|The resource specified in the URI was not found.| +|**405**|`Method Not Allowed`|An unsupported HTTP method for the request was used; see Table 6 for information on which HTTP methods are allowed in which services.| +|**406**|`Not acceptable`|The server is not capable of generating content according to the Accept headers sent in the request. Used in the API to indicate that the server does not support the version that the client is requesting.| +|**501**|`Not Implemented`|The server does not support the requested service. The client should not retry.| +|**503**|`Service Unavailable`|The server is currently unavailable to accept any new service requests. This should be a temporary state, and the client should retry within a reasonable time frame.| + + **Table 4 -- HTTP response status codes supported in the API** + +Any HTTP status codes 3*xx*20 returned by the server should not be retried and require manual investigation. + +An implementation of the API should also be capable of handling other errors not defined above as the request could potentially be routed through proxy servers. + +As all requests in the API are asynchronous, additional HTTP error codes for server errors (error codes starting with 5*xx*21 that are *not* defined in [Table 4](#table-4)) are not used by the API itself. Any error on the server during actual processing of a request will be sent as part of an error callback to the client (see [Section 9.2](#92-error-in-server-during-processing-of-request)). + +
    + +##### Error Information in HTTP Response + +In addition to the HTTP response code, all HTTP error responses (4*xx* and 5*xx* status codes) can optionally contain an **ErrorInformation** element, defined in the section on [ErrorInformation](#errorinformation). This element should be used to give more detailed information to the client if possible. + +
    + +##### Idempotent Services in Server + +All services that support HTTP **GET** must be _idempotent_; that is, the same request can be sent from a client any number of times without changing the object on the server. The server is allowed to change the state of the object; for example, a transaction state can be changed, but the FSP sending the **GET** request cannot change the state. + +All services that support HTTP **POST** must be idempotent in case the client is sending the same service ID again; that is, the server must not create a new service object if a client sends the same **POST** request again. The reason behind this is to simplify the handling of resends during error-handling in a client; however, this creates some extra requirements of the server that receives the request. An example in which the same **POST** request is sent several times can be seen [here](#client-missing-response-from-server---using-resend-of-request). + +##### Duplicate Analysis in Server on Receiving a HTTP POST Request + +When a server receives a request from a client, the server should check to determine if there is an already-existing service object with the same ID; for example, if a client has previously sent the request **POST /transfers** with the identical **transferId**. If the object already exists, the server must check to determine if the parameters of the already-created object match the parameters from the new request. + +- If the previously-created object matches the parameter from the new request, the request should be assumed to be a resend from the client. + + - If the server has not finished processing the old request and therefore has not yet sent the callback to the client, this new request can be ignored, because a callback is about to be sent to the client. + - If the server has finished processing the old request and a callback has already been sent, a new callback should be sent to the client, similar to if a HTTP **GET** request had been sent. + +- If the previously-created object does not match the parameters from the new request, an error callback should be sent to the client explaining that an object with the provided ID already exists with conflicting parameters. + +To simplify duplicate analysis, it is recommended to create and store a hash value of all incoming **POST** requests on the server, so that it is easy to compare the hash value against later incoming **POST** requests. + +
    + +### API Versioning + +The strategy of the development of the API is to maintain backwards compatibility between the API and its resources and services to the maximum extent possible; however, changes to the API should be expected by implementing parties. Versioning of the API is specific to the API resource (for example, **/participants**, **/quotes**, **/transfers**). + +There are two types of API resource versions: _Minor_ versions, which are backwards-compatible, and _major_ versions, which are backwards-incompatible. + +- Whenever a change in this document defining the characteristics of the API is updated that in some way affects an API service, the affected resource will be updated to a new major or minor version (depending on whether the changes are backwards-compatible or not). + +- Whenever a change is made to a specific service in the API, a new version of the corresponding resource will be released. + +The format of the resource version is _x_._y_ where _x_ is the major version and _y_ is the minor version. Both major and minor versions are sequentially numbered. When a new major version of a service is released, the minor version is reset to **0**. The initial version of each resource in the API is **1.0**. + +#### Changes not Affecting the API Resource Version + +Some changes will not affect the API resource version; for example, if the order of parameters within a request or callback were to be changed. + +#### Minor API Resource Version + +The following list describes the changes that are considered backwards compatible if the change affects any API service connected to a resource. API implementers should implement their client/server in such a way that the API services automatically support these changes without breaking any functionality. + +- Optional input parameters such as query strings added in a request +- Optional parameters added in a request or a callback +- Error codes added + +These types of changes affect the minor API service version. + +#### Major API Resource Versions + +The following list describes the changes that are considered backwards-incompatible if the change affects any API service connected to a resource. API implementers do _not_ need to implement their client/server in such a way that it automatically supports these changes. + +- Mandatory parameters removed or added to a request or callback +- Optional parameters changed to mandatory in a request or callback +- Parameters renamed +- Data types changed +- Business logic of API resource or connected services changed +- API resource/service URIs changed + +These types of changes affect the major API service version. Please note that the list is not comprehensive; there might be other changes as well that could affect the major API service version. + +#### Version Negotiation between Client and Server + +The API supports basic version negotiation by using HTTP content negotiation between the server and the client. A client should send the API resource version that it would like to use in the **Accept** header to the server (see [HTTP Accept Header](#http-accept-header)). If the server supports that version, it should use that version in the callback (see [Acceptable Version Requested by Client](#acceptable-version-requested-by-client)). If the server does not support the requested version, the server should reply with HTTP status 40622 including a list of supported versions (see [Non-Acceptable Version Requested by Client](#non-acceptable-version-requested-by-client)). + +#### HTTP Accept Header + +See below for an example of a simplified HTTP request which only includes an **Accept** header23. The **Accept** header should be used from a client requesting a service from a server specifying a major version of the API service. The example in [Listing 3](#listing-3) should be interpreted as "I would like to use major version 1 of the API resource, but if that version is not supported by the server then give me the latest supported version". + +###### Listing 3 + +``` +POST /service HTTP/1.1 +Accept: application/vnd.interoperability.{resource}+json;version=1, +application/vnd.interoperability.{resource}+json + +{ + ... +} +``` + +**Listing 3 -- HTTP Accept header example, requesting version 1 or the latest supported version** + +Regarding the example in [Listing 3](#listing-3): + +- The **_POST /service_** should be changed to any HTTP method and related service or resource that is supported by the API (see [Table 6](#table-6)). +- The **Accept** header field is used to indicate the API resource version the client would like to use. If several versions are supported by the client, more than one version can be requested separated by a comma (**,**) as in the example above. + - The application type is always **application/vnd.interoperability.**_{resource}_, where _{resource}_ is the actual resource (for example, **participants** or **quotes**). + - The only data exchange format currently supported is **json**. + - If a client can use any minor version of a major version, only the major version should be sent; for example, **version=1** or **version=2**. + - If a client would like to use a specific minor version, this should be indicated by using the specific _major.minor_ version; for example, **version=1.2** or **version=2.8**. The use of a specific _major.minor_ version in the request should generally be avoided, as minor versions should be backwards-compatible. + +#### Acceptable Version Requested by Client + +If the server supports the API resource version requested by the client in the Accept Headers, it should use that version in the subsequent callback. The used _major.minor_ version should always be indicated in the **Content-Type** header by the server, even if the client only requested a major version of the API. See the example in [Listing 4](#listing-4), which indicates that version 1.0 is used by the server: + +###### Listing 4 + +``` +Content-Type: application/vnd.interoperability.resource+json;version=1.0 +``` + +**Listing 4 -- Content-Type HTTP header field example** + +#### Non-Acceptable Version Requested by Client + +If the server does not support the version requested by the client in the **Accept** header, the server should reply with HTTP status 406, which indicates that the requested version is not supported. + +**Note:** There is also a possibility that the information might be sent as part of an error callback to a client instead of directly in the response; for example, when the request is routed through a Switch which does support the requested version, but the destination FSP does not support the requested version. + +Along with HTTP status 406, the supported versions should be listed as part of the error message in the extensions list, using the major version number as _key_ and minor version number as _value_. Please see error information in the example in [Listing 5](#listing-5), describing the server's supported versions. The example should be interpreted as "I do not support the resource version that you requested, but I do support versions 1.0, 2.1, and 4.2". + +###### Listing 5 + +```json +{ + "errorInformation": { + "errorCode": "3001", + "errorDescription": "The Client requested an unsupported version, see extension list for supported version(s).", + "extensionList": { + "extension": + [ + { "key": "1", "value": "0"}, + { "key": "2", "value": "1"}, + { "key": "4", "value": "2"} + ] + } + } +} +``` + +**Listing 5 -- Example error message when server does not support the requested version** + + +
    + +## Interledger Protocol + +The current version of the API includes basic support for the Interledger Protocol (ILP), by defining a concrete implementation of the Interledger Payment Request protocol24 in API Resource [/quotes](#api-resource-quotes), and API Resource, [**/transfers**](#api-resource-transfers). + +### More Information + +This document contains ILP information that is relevant to the API. For more information about the ILP protocol, see the Interledger project website25, the Interledger Whitepaper26, and the Interledger architecture specification27. + +### Introduction to Interledger + +ILP is a standard for internetworking payment networks. In the same way that the Internet Protocol (IP) establishes a set of basic standards for the transmission and addressing of data packets between different data networks, ILP establishes a set of basic standards for the addressing of financial transactions and transfer of value between accounts on different payment networks. + +ILP is not a scheme. It is a set of standards that, if implemented by multiple payment schemes, will allow those schemes to be interoperable. Therefore, implementing ILP involves adapting an existing scheme to conform to those standards. Conformance means ensuring that transfers between accounts within the scheme are done in two phases (_reserve_ and _commit_) and defining a mapping between the accounts in the scheme and the global ILP Addressing scheme. This can be done by modifying the scheme itself, or by the entities that provide ILP-conformant access to the scheme using scheme adaptors. + +The basic prerequisites for an ILP payment are the Payee ILP address (see [ILP addressing](#ilp-addressing)) and the condition (see [Conditional Transfers](#conditional-transfers)). In the current version of the API, both these prerequisites should be returned by the Payee FSP during quoting API Resource [**/quotes**](#api-resource-quotes)) of the financial transaction. + +### ILP Addressing + +A key component of the ILP standard is the ILP addressing28 scheme. It is a hierarchical scheme that defines one or more addresses for every account on a ledger. + +[Table 5](#table-5) shows some examples of ILP addresses that could be used in different scenarios, for different accounts. Note that while the structure of addresses is standardized, the content is not, except for the first segment (up to the first period (**.**)). + +###### Table 5 + +|ILP Address|Description| +|---|---| +|**g.tz.fsp1.msisdn.1234567890**|A mobile money account at **FSP1** for the user with **MSISDN 1234567890**.| +|**g.pk.fsp2.ac03396c-4dba-4743**|A mobile money account at **FSP2** identified by an opaque account id.| +|**g.us.bank1.bob**|A bank account at **Bank1** for the user **bob**.| + +**Table 5 -- ILP address examples** + +The primary purpose of an ILP addresses is to identify an account in order to route a financial transaction to that account. + +**Note:** An ILP address should not be used for identifying a counterparty in the Interoperability API. See section on [Refund](#refund) regarding how to address a Party in the API. + +It is useful to think of ILP addresses as analogous to IP addresses. They are seldom, if ever, be seen by end users but are used by the systems involved in a financial transaction to identify an account and route the ILP payment. The design of the addressing scheme means that a single account will often have many ILP addresses. The system on which the account is maintained may track these or, if they are all derived from a common prefix, may track a subset only. + +### Conditional Transfers + +ILP depends on the concept of _conditional transfers_, in which all ledgers involved in a financial transaction from the Payer to the Payee can first reserve funds out of a Payer account and then later commit them to the Payee account. The transfer from the Payer to the Payee account is conditional on the presentation of a fulfilment that satisfies the condition attached to the original transfer request. + +To support conditional transfers for ILP, a ledger must support a transfer API that attaches a condition and an expiry to the transfer. The ledger must prepare the transfer by reserving the funds from the Payer account, and then wait for one of the following events to occur: + +- The fulfilment of the condition is submitted to the ledger and the funds are committed to the Payee account. + +- The expiry timeout is reached, or the financial transaction is rejected by the Payee or Payee FSP. The transfer is then aborted and the funds that were reserved from the Payer account are returned. + +When the fulfilment of a transfer is submitted to a ledger, the ledger must ensure that the fulfilment is valid for the condition that was attached to the original transfer request. If it is valid, the transfer is committed, otherwise it is rejected, and the transfer remains in a pending state until a valid fulfilment is submitted or the transfer expires. + +ILP supports a variety of conditions for performing a conditional payment, but implementers of the API should use the SHA-256 hash of a 32-byte pre-image. The condition attached to the transfer is the SHA-256 hash and the fulfilment of that condition is the pre-image. Therefore, if the condition attached to a transfer is a SHA-256 hash, then when a fulfilment is submitted for that transaction, the ledger will validate it by calculating the SHA-256 hash of the fulfilment and ensuring that the hash is equal to the condition. + +See [Interledger Payment Request](#interledger-payment-request) for concrete information on how to generate the fulfilment and the condition. + +### ILP Packet + +The ILP Packet is the mechanism used to package end-to-end data that can be passed in a hop-by-hop service. It is included as a field in hop-by-hop service calls and should not be modified by any intermediaries. The integrity of the ILP Packet is tightly bound to the integrity of the funds transfer, as the commit trigger (the fulfilment) is generated using a hash of the ILP Packet. + +The packet has a strictly defined binary format, because it may be passed through systems that are designed for high performance and volume. These intermediary systems must read the ILP Address and the amount from the packet headers, but do not need to interpret the **data** field in the ILP Packet (see [Listing 6](#listing-6)). Since the intermediary systems should not need to interpret the **data** field, the format of the field is not strictly defined in the ILP Packet definition. It is simply defined as a variable length octet string. [Interledger Payment Request](#interledger-payment-request) contains concrete information on how the ILP Packet is populated in the API. + +The ILP Packet is the common thread that connects all the individual ledger transfers that make up an end-to-end ILP payment. The packet is parsed by the Payee of the first transfer and used to determine where to make the next transfer, and for how much. It is attached to that transfer and parsed by the Payee of the next transfer, who again determines where to make the next transfer, and for how much. This process is repeated until the Payee of the transfer is the Payee in the end-to-end financial transaction, who fulfils the condition, and the transfers are committed in sequence starting with the last and ending with the first. + +The ILP Packet format is defined in ASN.129 (Abstract Syntax Notation One), shown in [Listing 6](#listing-6). The packet is encoded using the canonical Octet Encoding Rules. + +###### Listing 6 + +``` +InterledgerProtocolPaymentMessage ::= SEQUENCE { + -- Amount which must be received at the destination amount UInt64, + -- Destination ILP Address account Address, + -- Information for recipient (transport layer information) data OCTET STRING (SIZE (0..32767)), + -- Enable ASN.1 Extensibility + extensions SEQUENCE { + ... + } +} +``` + +**Listing 6 -- The ILP Packet format in ASN.1 format** + +**Note:** The only mandatory data elements in the ILP Packet are the amount to be transferred to the account of the Payee and the ILP Address of the Payee. + +
    + +## Common API Functionality + +This section describes the common functionality used by the API, including: + +- [Quoting](#quoting) +- [Party Addressing](#party-addressing) +- [Mapping of Use Cases to Transaction Types](#mapping-of-use-cases-to-transaction-types) + +### Quoting + +Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. + +Two different modes for quoting between FSPs are supported in the API: _Non-disclosing of fees_ and _Disclosing of fees_. + +- _Non-Disclosing of fees_ should be used when either the Payer FSP does not want to show the Payee FSP its fee structure, or when the Payer FSP would like to have more control of the fees paid by the Payer after quoting has been performed (the latter is only applicable for _Receive amount_; see next bullet list). + +- _Disclosing of fees_ can be used for use cases in which the Payee FSP wants to subsidize the transaction in some use cases; for example, Cash-In at another FSP's agent. + +The _Non-Disclosing of fees_ mode should be the standard supported way of quoting in most schemes. _Disclosing of fees_ might be used in some schemes; for example, a scheme in which a dynamic fee structure is used and an FSP wants the ability to subsidize the Cash-In use case based on the dynamic cost. + +In addition, the Payer can decide if the amount should be _Receive amount_ or _Send amount_. + +- _Send amount_ should be interpreted as the actual amount that should be deducted from the Payer's account, including any fees. + +- _Receive amount_ should be interpreted as the amount that should be added to the Payee's account, regardless of any interoperable transaction fees. The amount excludes possible internal Payee fees added by the Payee FSP. + +The Payee FSP can choose if the actual receive amount for the Payee should be sent or not in the callback to the Payer FSP. The actual Payee receive amount should include any Payee FSP internal fees on the Payee. + +All taxes are assumed to be FSP-internal, which means that taxes are not sent as part of the API. See [Tax Information](#tax-information) for more information regarding taxes. + +**Note:** Dynamic fees implemented using a Switch, or any other intermediary, are not supported in this version of the API. + + +#### Non-Disclosing of Fees + +The fees and commission payments related to an interoperable transaction when fees are not disclosed are shown in [Figure 7](#figure-7). The fees and commission that are directly part of the API are identified by green text. The FSP internal fees, commission, and bonus payments are identified by red text. These are not part of the transaction between a Payer FSP and a Payee FSP, but the amount that the Payee will receive after any FSP internal fees can be sent for information by the Payee FSP. + +For send amount (see [Non-Disclosing Send Amount](#non-disclosing-send-amount) for more information), internal Payer FSP fees on the Payer will affect the amount that is sent from the Payer FSP. For example, if the Payer FSP has a fee of 1 USD for a 100 USD interoperable financial transaction, 99 USD is sent from the Payer FSP. For receive amount (see [Non-Disclosing Receive Amount](#non-disclosing-receive-amount) for more information), internal Payer FSP fees on the Payer will not affect the amount that is sent from the Payer FSP. Internal Payer FSP bonus or commission on the Payer should be hidden regardless of send or receive amount. + +###### Figure 7 + +![Figure 7](/assets/diagrams/images/figure7.svg) + +**Figure 7 -- Fees and commission related to interoperability when fees are not disclosed** + +See [Fee Types](#fee-types) for more information on the fee types sent in the Interoperability API. + +#### Non-Disclosing Receive Amount + +[Figure 8](#figure-8) shows an example of non-disclosing receive amount, in which the Payer would like the Payee to receive exactly 100 USD. For non-disclosing receive amount, the Payer FSP need not set the internal rating of the transaction until after the quote has been received because the Payee FSP knows what amount it will receive. + +In this example, the Payee FSP decides to give commission to the Payer FSP since funds are flowing to the Payee FSP, which will later be spent in some way; this results in a future fee income for the Payee FSP. The Payer FSP can then decide how much in fees should be taken from the Payer for cost-plus pricing. In this example, the Payer FSP would like to have 1 USD from the Payer, which means that the Payer FSP will earn 2 USD in total, as the Payer FSP will also receive 1 USD in FSP commission from the Payee FSP. + +###### Figure 8 + +{% uml src="assets/diagrams/sequence/figure8.plantuml" %} +{% enduml %} + +**Figure 8 -- Example of non-disclosing receive amount** + +###### Figure 9 + +![Figure 9](/assets/diagrams/images/figure9.svg) + +**Figure 9 -- Simplified view of money movement for non-disclosing receive amount example** + +To calculate the element **transferAmount** in the Payee FSP for a non-disclosing receive amount quote, the equation in [Listing 9](#listing-9) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 23](#table-23), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is payeeFspCommission in [Table 24](#table-24). + +###### Listing 7 + +``` +Transfer amount = Quote Amount + Payee FSP Fee -- Payee FSP Commission +``` + +**Listing 7 -- Relation between transfer amount and quote amount for non-disclosing receive amount** + +#### Non-Disclosing Send Amount + +[Figure 10](#figure-10) shows an example of non-disclosing send amount, where the Payer would like to send 100 USD from the Payer's account. For non-disclosing send amount, the Payer FSP must rate (determine the internal transaction fees, commission, or both) the transaction before the quote is sent to the Payee FSP so that the Payee FSP knows how much in funds it will receive in the transaction. The actual amount withdrawn from the Payer's account is not disclosed, nor are the fees. + +In the example, the Payer FSP and the Payee FSP would like to have 1 USD each in fees so that the amount that will be received by the Payee is 98 USD. The actual amount that will be received by the Payee is in this example (not mandatory) returned in the callback to the Payer FSP, in the element **payeeReceiveAmount**. + +###### Figure 10 + +{% uml src="assets/diagrams/sequence/figure10.plantuml" %} +{% enduml %} + +**Figure 10 -- Example of non-disclosing send amount** + +###### Figure 11 + +[Figure 11](#figure-11) shows a simplified view of the movement of money for the non-disclosing send amount example. + +![Figure 11](/assets/diagrams/images/figure11.svg) + +**Figure 11 -- Simplified view of money movement for non-disclosing send amount example** + +To calculate the element **transferAmount** in the Payee FSP for a non-disclosing send amount quote, the equation in [Listing 8](#listing-8) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 8 + +``` +Transfer amount = Quote Amount -- Payee FSP Commission +``` + +**Listing 8 -- Relation between transfer amount and quote amount for non-disclosing send amount** + +The reason for a Payee FSP fee to be absent in the equation is that the Payer would like to send a certain amount from their account. The Payee will receive less funds instead of a fee being added on top of the amount. + +#### Disclosing of Fees + +The fees and commission payments related to an interoperable transaction when fees are disclosed can be seen in [Figure 11](#figure-11). The fees and commission that are directly related to the API are marked with green text. Internal Payee fees, bonus, and commission are marked with red text, these will have an implication on the amount that is sent by the Payer and received by the Payee. They are not part of the interoperable transaction between a Payer FSP and a Payee FSP, but the actual amount to be received by the Payee after internal Payee FSP fees have been deducted can be sent for information by the Payee FSP. + +When disclosing of fees are used, the FSP commission that the Payee FSP sends should subsidize the transaction cost for the Payer. This means that any FSP commission sent from the Payee FSP will effectively pay either a part or all of the fees that the Payer FSP has added to the transaction. If the FSP commission amount from the Payee FSP is higher than the actual transaction fees for the Payer, the excess amount should be handled as a fee paid by Payee FSP to Payer FSP. An example of excess FSP commission can be found [here](#excess-fsp-commission-example). + +###### Figure 12 + +![Figure 12](/assets/diagrams/images/figure12.svg) + +**Figure 12 -- Fees and commission related to interoperability when fees +are disclosed** + +See [Fee Types](#fee-types) for more information on the fee types sent in the Interoperability API. + +#### Disclosing Receive Amount + +[Figure 13](#figure-13) shows an example of disclosing receive amount where the Payer would like the Payee to receive exactly 100 USD. For disclosing receive amount, the Payer FSP must internally rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this example, the Payer FSP would like to have 1 USD in fees from the Payer. The Payee FSP decides to give 1 USD in commission to subsidize the transaction, so that the transaction is free for the Payer. + +###### Figure 13 + +{% uml src="assets/diagrams/sequence/figure13.plantuml" %} +{% enduml %} + +**Figure 13 -- Example of disclosing receive amount** + +[Figure 14](#figure-14) shows a simplified view of the movement of money for the disclosing receive amount example. + +###### Figure 14 + +![Figure 14](/assets/diagrams/images/figure14.svg) + +**Figure 14 -- Simplified view of money movement for disclosing receive amount example** + +To calculate the element **transferAmount** in the Payee FSP for a disclosing receive amount quote, the equation in [Listing 9](#listing-9) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 9 + +``` +Transfer amount = Quote Amount + Payee FSP Fee -- Payee FSP Commission +``` + +**Listing 9 -- Relation between transfer amount and quote amount for disclosing receive amount** + +#### Disclosing Send Amount + +[Figure 15](#figure-15) shows an example of disclosing send amount, where the Payer would like to send 100 USD from the Payer's account to the Payee. For disclosing send amount, the Payer FSP must rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this example, the Payer FSP and the Payee FSP would like to have 1 USD each in fees from the Payer. + +###### Figure 15 + +{% uml src="assets/diagrams/sequence/figure15.plantuml" %} +{% enduml %} + +**Figure 15 -- Example of disclosing send amount** + +###### Figure 16 + +[Figure 16](#figure-16) shows a simplified view of the movement of money for the disclosing send amount example. +![Figure 16](/assets/diagrams/images/figure16.svg) + +**Figure 16 -- Simplified view of money movement for disclosing send amount example** + +To calculate the element **transferAmount** in the Payee FSP for a disclosing send amount quote, the equation in [Listing 10](#listing-10) should be used, where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Quote_ _Amount_ is **amount** in [Table 24](#table-24), _Payer_ _Fee_ is **fees** in [Table 24](#table-24), and Payee FSP commission is **payeeFspCommission** in [Table 24](#table-24). + +###### Listing 10 + +``` +If (Payer Fee <= Payee FSP Commission) + Transfer amount = Quote Amount +Else + Transfer amount = Quote Amount -- (Payer Fee - Payee FSP Commission) +``` + +**Listing 10 -- Relation between transfer amount and quote amount for disclosing send amount** + +The reason for a Payee FSP fee to be absent in the equation, is that the Payer would like to send a certain amount from their account. The Payee will receive less funds instead of a fee being added on top of the amount. + +#### Excess FSP Commission Example + +[Figure 17](#figure-17) shows an example of excess FSP commission using disclosing send amount, where the Payer would like to send 100 USD from the Payer's account to the Payee. For disclosing send amount, the Payer FSP must rate the transaction before the quote request is sent to the Payee FSP, because the fees are disclosed. In this excess commission example, the Payer FSP would like to have 1 USD in fees from the Payer, and the Payee FSP gives 3 USD in FSP commission. Out of the 3 USD in FSP commission, 1 USD should cover the Payer fees, and 2 USD is for the Payer FSP to keep. + +###### Figure 17 + +{% uml src="assets/diagrams/sequence/figure17.plantuml" %} +{% enduml %} + +**Figure 17 -- Example of disclosing send amount** + +###### Figure 18 + +[Figure 18](#figure-18) shows a simplified view of the movement of money for the excess commission using disclosing send amount example. + +![Figure 18](/assets/diagrams/images/figure18.svg) + +**Figure 18 -- Simplified view of money movement for excess commission using disclosing send amount example** + +#### Fee Types + +As can be seen in [Figure 7](#figure-7) and [Figure 12](#figure-12), there are two different fee and commission types in the Quote object between the + +FSPs: + +1. **Payee FSP fee** -- A transaction fee that the Payee FSP would like to have for the handling of the transaction. + +2. **Payee FSP commission** -- A commission that the Payee FSP would like to give to the Payer FSP (non-disclosing of fees) or subsidize the transaction by paying some or all fees from the Payer FSP (disclosing of fees). In case of excess FSP commission, the excess commission should be handled as the Payee FSP pays a fee to the Payer FSP, see [here](#excess-fsp-commission-example) for an example. + +
    + +#### Quote Equations + +This section contains useful equations for quoting that have not already been mentioned. + +#### Payee Receive Amount Relation to Transfer Amount + +The amount that the Payee should receive, excluding any internal Payee FSP fees, bonus, or commission, can be calculated by the Payer FSP using the equation in [Listing 11](#listing-11), where _Transfer Amount_ is **transferAmount** in [Table 24](#table-24), _Payee_ _FSP fee_ is **payeeFspFee** in [Table 24](#table-24), and Payee FSP commission is payeeFspCommission in [Table 24](#table-24). + +###### Listing 11 + +``` +Payee Receive Amount = Transfer Amount - Payee FSP Fee + Payee FSP Commission +``` + +**Listing 11 -- Relation between transfer amount and Payee receive amount** + +The Payee receive amount including any internal Payee FSP fees can optionally be sent by the Payee FSP to the Payer FSP in the Quote callback, see element **payeeReceiveAmount** in [Table 24](#table-24). +
    + +#### Tax Information + +Tax information is not sent in the API, as all taxes are assumed to be FSP-internal. The following sections contain details pertaining to common tax types related to the API. + +##### Tax on Agent Commission + +Tax on Agent Commission is tax for an _Agent_ as a result of the Agent receiving commission as a kind of income. Either the Agent or its FSP has a relation with the tax authority, depending on how the FSP deployment is set up. As all Agent commissions are FSP-internal, no information is sent through the Interoperability API regarding Tax on Agent Commission. + +##### Tax on FSP Internal Fee + +FSPs could be taxed on FSP internal fees that they receive from the transactions; for example, Payer fees to Payer FSP or Payee fees to Payee FSP. This tax should be handled internally within the FSP and collected by the FSPs because they receive a fee. + +##### Tax on Amount (Consumption tax) + +Examples of tax on amount are VAT (Value Added Tax) and Sales Tax. These types of taxes are typically paid by a Consumer to the Merchant as part of the price of goods, services, or both. It is the Merchant who has a relationship with the tax authority, and forwards the collected taxes to the tax authority. If any VAT or Sales Tax is applicable, a Merchant should include these taxes in the requested amount from the Consumer. The received amount in the Payee FSP should then be taxed accordingly. + +##### Tax on FSP Fee + +In the API, there is a possibility for a Payee FSP to add a fee that the Payer or Payer FSP should pay to the Payee FSP. The Payee FSP should handle the tax internally as normal when receiving a fee (if local taxes apply). This means that the Payee FSP should consider the tax on the fee while rating the financial transaction as part of the quote. The tax is not sent as part of the API. + +##### Tax on FSP Commission + +In the API, there is a possibility for a Payee FSP to add a commission to either subsidize the transaction (if disclosing of fees) or incentivize the Payer FSP (if non-disclosing of fees). + +###### Non-Disclosing of Fees + +For non-disclosing of fees, all FSP commission from the Payee FSP should be understood as the Payer FSP receiving a fee from the Payee FSP. The tax on the received fee should be handled internally within the Payer FSP, similar to the way it is handled in [Tax on FSP Internal Fee](#tax-on-fsp-internal-fee). + +###### Disclosing of Fees + +If the Payee FSP commission amount is less than or equal to the amount of transaction fees originating from the Payer FSP, then the Payee FSP commission should always be understood as being used for covering fees that the Payer would otherwise need to pay. + +If the Payee FSP commission amount is higher than the fees from the Payer FSP, the excess FSP commission should be handled similarly as [Non-Disclosing of Fees](#non-disclosing-of-fees). + +
    + +#### Examples for each Use Case + +This section contains one or more examples for each use case. + +#### P2P Transfer + +A P2P Transfer is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 19](#figure-19) for an example. In this example, the Payer would like the Payee to receive 100 USD. The Payee FSP decides to give FSP commission to the Payer FSP, because the Payee FSP will receive funds into the system. The Payer FSP would also like to have 1 USD in fee from the Payer, so the total fee that the Payer FSP will earn is 2 USD. 99 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 1 USD. + +###### Figure 19 + +{% uml src="assets/diagrams/sequence/figure19.plantuml" %} +{% enduml %} + +**Figure 19 -- P2P Transfer example with receive amount** + +###### Simplified View of Money Movement + +###### Figure 20 + +See [Figure 20](#figure-20) for a highly simplified view of the movement of money for the P2P Transfer example. + +![Figure 20](/assets/diagrams/images/figure20.svg) + +**Figure 20 -- Simplified view of the movement of money for the P2P Transfer example** + +#####Agent-Initiated Cash-In (Send amount) + +[Figure 21](#figure-21) shows an example of an Agent-Initiated Cash-In where send amount is used. The fees are disclosed because the Payee (the customer) would like to know the fees in advance of accepting the Cash-In. In the example, the Payee would like to Cash-In a 100 USD bill using an Agent (the Payer) in the Payer FSP system. The Payer FSP would like to have 2 USD in fees to cover the agent commission. The Payee FSP decides to subsidize the transaction by 2 USD by giving 2 USD in FSP commission to cover the Payer FSP fees. 98 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 2 USD. + +###### Figure 21 + +{% uml src="assets/diagrams/sequence/figure21.plantuml" %} +{% enduml %} + +**Figure 21 -- Agent-Initiated Cash-In example with send amount** + +###### Simplified View of Money Movement + +See [Figure 22](#figure-22) for a highly simplified view of the movement of money for the Agent-initiated Cash-In example with send amount. + +###### Figure 22 + +![Figure 22](/assets/diagrams/images/figure22.svg) + +**Figure 22 -- Simplified view of the movement of money for the Agent-initiated Cash-In with send amount example** + +##### Agent-Initiated Cash-In (Receive amount) + +[Figure 23](#figure-23) shows an example of Agent-Initiated Cash-In where receive amount is used. The fees are disclosed as the Payee (the Consumer) would like to know the fees in advance of accepting the Cash-In. In the example, the Payee would like to Cash-In so that they receive 100 USD using an Agent (the Payer) in the Payer FSP system. The Payer FSP would like to have 2 USD in fees to cover the agent commission; the Payee FSP decides to subsidize the transaction by 1 USD by giving 1 USD in FSP commission to cover 50% of the Payer FSP fees. 99 USD is transferred from the Payer FSP to the Payee FSP after deducting the FSP commission amount of 1 USD. + +###### Figure 23 + +{% uml src="assets/diagrams/sequence/figure23.plantuml" %} +{% enduml %} + +**Figure 23 -- Agent-initiated Cash-In example with receive amount** + +##### Simplified View of Money Movement + +###### Figure 24 + +See [Figure 24](#figure-24) for a highly simplified view of the movement of money for the Agent-initiated Cash-In example with receive amount. + +![Figure 24](/assets/diagrams/images/figure24.svg) + +**Figure 24 -- Simplified view of the movement of money for the Agent-initiated Cash-In with receive amount example** + +##### Customer-Initiated Merchant Payment + +A Customer-Initiated Merchant Payment is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 25](#figure-25) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP would not like to charge any fees from the Payer, but 1 USD in an internal hidden fee from the Merchant. The Payer FSP wants 1 USD in fees from the Payer. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 25 + +{% uml src="assets/diagrams/sequence/figure25.plantuml" %} +{% enduml %} + +**Figure 25 -- Customer-Initiated Merchant Payment example** + +###### Simplified View of Money Movement + +See [Figure 26](#figure-26) for a highly simplified view of the movement of money for the Customer-Initiated Merchant Payment example. + +###### Figure 26 + +![Figure 26](/assets/diagrams/images/figure26.svg) + +**Figure 26 -- Simplified view of the movement of money for the Customer-Initiated Merchant Payment example** + +##### Customer-Initiated Cash-Out (Receive amount) + +A Customer-Initiated Cash-Out is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 27](#figure-27) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 102 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 27 + +{% uml src="assets/diagrams/sequence/figure27.plantuml" %} +{% enduml %} + +**Figure 27 -- Customer-Initiated Cash-Out example (receive amount)** + +###### Simplified View of Money Movement + +See [Figure 28](#figure-28) for a highly simplified view of the movement of money for the Customer-Initiated Cash-Out with receive amount example. + +###### Figure 28 + +![Figure 28](/assets/diagrams/images/figure28.svg) + +**Figure 28 -- Simplified view of the movement of money for the Customer-Initiated Cash-Out with receive amount example** + +##### Customer-Initiated Cash-Out (Send amount) + +A Customer-Initiated Cash-Out is typically a receive amount, this +example is shown in [Customer-Initiated Cash-Out](#customer-initiated-cash-out). This section shows an example where send amount is used instead; see [Figure 29](#figure-29) for an example. In the example, the Payer would like to Cash-Out 100 USD from their account. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 99 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 29 + +{% uml src="assets/diagrams/sequence/figure29.plantuml" %} +{% enduml %} + +**Figure 29 -- Customer-Initiated Cash-Out example (send amount)** + +###### Simplified View of Money Movement + +See [Figure 30](#figure-30) for a highly simplified view of the movement of money for the Customer-Initiated Cash-Out with send amount example. + +###### Figure 30 + +![Figure 30](/assets/diagrams/images/figure30.svg) + +**Figure 30 -- Simplified view of the movement of money for the Customer-Initiated Cash-Out with send amount example** + +#### Agent-Initiated Cash-Out + +An Agent-Initiated Cash-Out is typically a receive amount, in which the Payer FSP does not disclose any fees to the Payee FSP. See [Figure 31](#Figure-31) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 2 USD in fees to cover the agent commission and the Payer FSP would like to have 1 USD in fee. 102 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 31 + +{% uml src="assets/diagrams/sequence/figure31.plantuml" %} +{% enduml %} + +**Figure 31 -- Agent-Initiated Cash-Out example** + +######1 Simplified View of Money Movement + +See [Figure 32](#figure-32) for a highly simplified view of the movement of money for the Agent-Initiated Cash-Out example. + +###### Figure 32 + +![Figure 32](/assets/diagrams/images/figure32.svg) + +**Figure 32 -- Simplified view of the movement of money for the Agent-Initiated Cash-Out example** + +##### Merchant-Initiated Merchant Payment + +A Merchant-Initiated Merchant Payment is typically a receive amount, where the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 33](#figure-33) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP does not want any fees and the Payer FSP would like to have 1 USD in fee. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 33 + +{% uml src="assets/diagrams/sequence/figure33.plantuml" %} +{% enduml %} + +**Figure 33 -- Merchant-Initiated Merchant Payment example** + +###### Simplified View of Money Movement + +See [Figure 34](#figure-34) for a highly simplified view of the movement of money for the Merchant-Initiated Merchant Payment example. + +###### Figure 34 + +![Figure 34](/assets/diagrams/images/figure34.svg) + +**Figure 34 -- Simplified view of the movement of money for the Merchant-Initiated Merchant Payment example** + +##### ATM-Initiated Cash-Out + +An ATM-Initiated Cash-Out is typically a receive amount, in which the Payer FSP is not disclosing any fees to the Payee FSP. See [Figure 35](#figure-35) for an example. In the example, the Payer would like to Cash-Out so that they will receive 100 USD in cash. The Payee FSP would like to have 1 USD in fees to cover any ATM fees and the Payer FSP would like to have 1 USD in fees. 101 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 35 + +{% uml src="assets/diagrams/sequence/figure35.plantuml" %} +{% enduml %} + +**Figure 35 -- ATM-Initiated Cash-Out example** + +###### Simplified View of Money Movement + +See [Figure 36](#figure-36) for a highly simplified view of the movement of money for the ATM-Initiated Cash-Out example. + +###### Figure 36 + +![Figure 36](/assets/diagrams/images/figure36.svg) + +**Figure 36 -- Simplified view of the movement of money for the ATM-Initiated Cash-Out example** + +##### Merchant-Initiated Merchant Payment authorized on POS + +A Merchant-Initiated Merchant Payment authorized on a POS device is typically a receive amount, in which the Payer FSP does not disclose any fees to the Payee FSP. See [Figure 37](#figure-37) for an example. In the example, the Payer would like to buy goods or services worth 100 USD from a Merchant (the Payee) in the Payee FSP system. The Payee FSP decides to give 1 USD in FSP commission, and the Payer FSP decides to use the FSP commission as the transaction fee. 100 USD is transferred from the Payer FSP to the Payee FSP. + +###### Figure 37 + +{% uml src="assets/diagrams/sequence/figure37.plantuml" %} +{% enduml %} + +**Figure 37 -- Merchant-Initiated Merchant Payment authorized on POS example** + +###### Simplified View of Money Movement + +See [Figure 38](#figure-38) for a highly simplified view of the movement of money for the Merchant-Initiated Merchant Payment authorized on POS example. + +###### Figure 38 + +![Figure 38](/assets/diagrams/images/figure38.svg) + +**Figure 38 -- Simplified view of the movement of money for the +Merchant-Initiated Merchant Payment authorized on POS example** + +##### Refund + +[Figure 39](#figure-39) shows an example of a Refund transaction of the entire amount of the [Agent-Initiated Cash-In (Receive amount)](#agent-initiated-cash-in-receive-amount) example. + +###### Figure 39 + +{% uml src="assets/diagrams/sequence/figure39.plantuml" %} +{% enduml %} + +**Figure 39 -- Refund example** + +#### 5.1.6.11.1 Simplified View of Money Movement + +See [Figure 40](#figure-40) for a highly simplified view of the movement of money for the Refund example. + +###### Figure 40 + +![Figure 40](/assets/diagrams/images/figure40.svg) + +**Figure 40 -- Simplified view of the movement of money for the Refund example** + +
    + +### Party Addressing + +Both Parties in a financial transaction, (that is, the `Payer` and the `Payee`) are addressed in the API by a _Party ID Type_ (element [**PartyIdType**](#partyidtype-element)), a _Party ID_ ([**PartyIdentifier**](#partyidentifier-element)), and an optional _Party Sub ID or Type_ ([PartySubIdOrType](#partysubidortype-element)). Some Sub-Types are pre-defined in the API for personal identifiers ([PersonalIdentifierType](#personalidentifiertype-enum)); for example, for passport number or driver's license number. + +The following are basic examples of how the elements _Party ID Type_ and _Party ID_ can be used: +- To use mobile phone number **+123456789** as the counterparty in a financial transaction, set *Party ID Type* to **MSISDN** and _Party ID_ to **+123456789**. + - Example service to get FSP information: + + **GET /participants/MSISDN/+123456789** + +- To use the email **john\@doe.com** as the counterparty in a financial transaction, set _Party ID Type_ to **EMAIL**, and _Party_ _ID_ to **john\@doe.com**. + + - Example service to get FSP information: + + **GET /participants/EMAIL/john\@doe.com** + +- To use the IBAN account number **SE45 5000 0000 0583 9825 7466** as counterparty in a financial transaction, set _Party_ _ID Type_ to **IBAN**, and _Party ID_ to **SE4550000000058398257466** (should be entered without any whitespace). + + - Example service to get FSP information: + + **GET /participants/IBAN/SE4550000000058398257466** + +The following are more advanced examples of how the elements _Party ID +Type_, _Party ID_, and _Party Sub ID or Type_ can be used: + +- To use the person who has passport number **12345678** as counterparty in a financial transaction, set _Party ID Type_ to **PERSONAL\_ID**, _Party ID_ to **12345678**, and _Party Sub ID or Type_ to **PASSPORT**. + + - Example service to get FSP information: + + **GET /participants/PERSONAL\_ID/123456789/PASSPORT** + +- To use **employeeId1** working in the company **Shoe-company** as counterparty in a financial transaction, set _Party ID_ _Type_ to **BUSINESS**, _Party ID_ to **Shoe-company**, and _Party Sub ID or Type_ to **employeeId1**. + + - Example service to get FSP information: + + **GET /participants/BUSINESS/Shoe-company/employeeId1** + +**5.2.1 Restricted Characters in Party ID and Party Sub ID or Type** + +Because the _Party ID_ and the _Party Sub ID or Type_ are used as part of the URI (see [URI Syntax](#uri-syntax)), some restrictions exist on the ID: + +- Forward slash (**/**) is not allowed in the ID, as it is used by the [Path](#path), to indicate a separation of the Path. + +- Question mark (**?**) is not allowed in the ID, as it is used to indicate the [Query](#query)) part of the URI. + +
    + +### Mapping of Use Cases to Transaction Types + +This section contains information about how to map the currently supported non-bulk use cases in the API to the complex type [**TransactionType**](#transactiontype)), using the elements [TransactionScenario](#transactionscenario)), and [TransactionInitiator](#transactioninitiator)). + +For more information regarding these use cases, see _API Use Cases_. + +#### P2P Transfer + +To perform a P2P Transfer, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **TRANSFER** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER**. + +#### Agent-Initiated Cash In + +To perform an Agent-Initiated Cash In, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **DEPOSIT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT**. + +#### Agent-Initiated Cash Out + +To perform an Agent-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT** + +#### Agent-Initiated Cash Out Authorized on POS + +To perform an Agent-Initiated Cash Out on POS, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **AGENT** + + +#### Customer-Initiated Cash Out + +To perform a Customer-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER** + +#### Customer-Initiated Merchant Payment + +To perform a Customer-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **CONSUMER**. + +#### Merchant-Initiated Merchant Payment + +To perform a Merchant-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **BUSINESS** + +#### Merchant-Initiated Merchant Payment Authorized on POS + +To perform a Merchant-Initiated Merchant Payment, set elements as +follows: + +- [**TransactionScenario**](#transactionscenario) to **PAYMENT** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **DEVICE** + +#### ATM-Initiated Cash Out + +To perform an ATM-Initiated Cash Out, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **WITHDRAWAL** +- [**TransactionInitiator**](#transactioninitiator) to **PAYEE** +- [**TransactionInitiatorType**](#transactioninitiatortype) to **DEVICE** + +#### Refund + +To perform a Refund, set elements as follows: + +- [**TransactionScenario**](#transactionscenario) to **REFUND** +- [**TransactionInitiator**](#transactioninitiator) to **PAYER** +- [**TransactionInitiatorType**](#transactioninitiatortype) depends on the initiator of the Refund. + +Additionally, the [Refund](#refund) complex type must be populated with the transaction ID of the original transaction that is to be refunded. + +
    + +## API Services + +This section introduces and details all services that the API supports for each resource and HTTP method. Each API resource and service is also mapped to a logical API resource and service described in [Generic Transaction Patterns](../generic-transaction-patterns). + + +### High Level API Services + +On a high level, the API can be used to perform the following actions: + +- **Lookup Participant Information** -- Find out in which FSP the counterparty in a financial transaction is located. + + - Use the services provided by the API resource **/participants**. + +- **Lookup Party Information** -- Get information about the counterparty in a financial transaction. + + - Use the services provided by the API resource **/parties**. + +- **Perform Transaction Request** -- Request that a Payer transfer electronic funds to the Payee, at the request of the Payee. The Payer can approve or reject the request from the Payee. An approval of the request will initiate the actual financial transaction. + + - Use the services provided by the API resource **/transactionRequests**. + +- **Calculate Quote** -- Calculate all parts of a transaction that will influence the transaction amount; that is, fees and FSP commission. + + - Use the services provided by the API resource **/quotes** for a single transaction quote; that is, one Payer to one Payee. + - Use the services provided by the API resource **/bulkQuotes** for a bulk transaction quote; that is, one Payer to multiple Payees. + +- **Perform Authorization** -- Request the Payer to enter the applicable credentials when they have initiated the transaction from a POS, ATM, or similar device in the Payee FSP system. + + - Use the services provided by the API resource **/authorizations**. + +- **Perform Transfer** -- Perform the actual financial transaction by transferring the electronic funds from the Payer to the Payee, possibly through intermediary ledgers. + + - Use the services provided by the API resource **/transfers** for single transaction; that is, one Payer to one Payee. + - Use the services provided by the API resource **/bulkTransfers** for bulk transaction; that is, one Payer to multiple Payees. + +- **Retrieve Transaction Information** -- Get information related to the financial transaction; for example, a possible created token on successful financial transaction. + + - Use the services provided by the API resource **/transactions**. + + +#### Supported API services + +[Table 6](#table-6) includes high-level descriptions of the services that the API provides. For more detailed information, see the sections that follow. + +###### Table 6 + +|URI|HTTP method GET|HTTP method PUT|HTTP method POST|HTTP method DELETE|HTTP method PATCH| +|---|---|---|---|---|---| +|**/participants**|Not supported|Not supported|Request that an ALS create FSP information regarding the parties provided in the body or, if the information already exists, request that the ALS update it|Not supported|Not Supported| +|**/participants/**_{ID}_|Not supported|Callback to inform a Peer FSP about a previously-created list of parties.|Not supported|Not Supported|Not Supported| +|**/participants/**_{Type}_/_{ID}_ Alternative: **/participants/**_{Type}_/_{ID}_/_{SubId}_|Get FSP information regarding a Party from either a Peer FSP or an ALS.|Callback to inform a Peer FSP about the requested or created FSP information.|Request an ALS to create FSP information regarding a Party or, if the information already exists, request that the ALS update it|Request that an ALS delete FSP information regarding a Party.|Not Supported| +|**/parties/**_{Type}_/_{ID}_ Alternative: **/parties/**_{Type}_/_{ID}_/_{SubId}_|Get information regarding a Party from a Peer FSP.|Callback to inform a Peer FSP about the requested information about the Party.|Not supported|Not support|Not Supported| +|**/transactionRequests**|Not supported|Not supported|Request a Peer FSP to ask a Payer for approval to transfer funds to a Payee. The Payer can either reject or approve the request.|Not supported|Not Supported| +|**/transactionRequests/**_{ID}_|Get information about a previously-sent transaction request.|Callback to inform a Peer FSP about a previously-sent transaction request.|Not supported|Not supported|Not Supported| +|**/quotes**|Not supported|Not supported|Request that a Peer FSP create a new quote for performing a transaction.|Not supported|Not Supported| +|**/quotes/**_{ID}_|Get information about a previously-requested quote.|Callback to inform a Peer FSP about a previously- requested quote.|Not supported|Not supported|Not Supported| +|**/authorizations/**_{ID}_|Get authorization for a transaction from the Payer whom is interacting with the Payee FSP system.|Callback to inform Payer FSP regarding authorization information.|Not supported|Not supported|Not Supported| +|**/transfers**|Not supported|Not supported|Request a Peer FSP to perform the transfer of funds related to a transaction.|Not supported|Not Supported| +|**/transfers/**_{ID}_|Get information about a previously-performed transfer.|Callback to inform a Peer FSP about a previously-performed transfer.|Not supported|Not supported|Commit notification to Payee FSP| +|**/transactions/**_{ID}_|Get information about a previously-performed transaction.|Callback to inform a Peer FSP about a previously-performed transaction.|Not supported|Not supported|Not Supported| +|**/bulkQuotes**|Not supported|Not supported|Request that a Peer FSP create a new quote for performing a bulk transaction.|Not supported|Not Supported| +|**/bulkQuotes/**_{ID}_|Get information about a previously-requested bulk transaction quote.|Callback to inform a Peer FSP about a previously-requested bulk transaction quote.|Not supported|Not supported|Not Supported| +|**/bulkTransfers**|Not supported|Not supported|Request that a Peer FSP create a bulk transfer.|Not supported|Not Supported| +|**/bulkTransfers/**_{ID}_|Get information about a previously-sent bulk transfer.|Callback to inform a Peer FSP about a previously-sent bulk transfer.|Not supported|Not supported|Not supported| + +**Table 6 – API-supported services** + +#### Current Resource Versions + +[Table 7](#table-7) contains the version for each resource that this document version describes. + +###### Table 7 + +|Resource|Current Version|Last Updated| +|---|---|---| +|/participants|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/parties|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transactionRequests|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/quotes|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/authorizations|1.0|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transfers|1.1|Added possible commit notification using PATCH /transfers/``. The process of using commit notifications is described in Section 6.7.2.6. The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/transactions|1.0|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/bulkQuotes|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| +|/bulkTransfers|1.1|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 7 – Current resource versions** + +
    + +### API Resource /participants + +This section defines the logical API resource **Participants**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-participants). + +The services provided by the resource **/participants** are primarily used for determining in which FSP a counterparty in a financial transaction is located. Depending on the scheme, the services should be supported, at a minimum, by either the individual FSPs or a common service. + +If a common service (for example, an ALS) is supported in the scheme, the services provided by the resource **/participants** can also be used by the FSPs for adding and deleting information in that system. + +#### Resource Version History + +[Table 8](#table-8) contains a description of each different version of the **/participants** resource. + +###### Table 8 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated. +For consistency, the data model for the **POST /participants/**_{Type}/{ID}_ and **POST /participants/**_{Type}/{ID}/{SubId}_ calls in Table 10 has been updated to include the optional ExtensionList element as well.| + +**Table 8 – Version history for resource /participants** + +#### Service Details + +Different models are used for account lookup, depending on whether an ALS exists. The following sections describe each model in turn. + +#### No Common Account Lookup System + +[Figure 41](#figure-41) shows how an account lookup can be performed if there is no common ALS in a scheme. The process is to ask the other FSPs (in sequence) if they "own" the Party with the provided identity and type pair until the Party can be found. + +If this model is used, all FSPs should support being both client and server of the different HTTP **GET** services under the **/participants** resource. The HTTP **POST** or HTTP **DELETE** services under the **/participants** resource should not be used, as the FSPs are directly used for retrieving the information (instead of a common ALS). + +###### Figure 41 + +{% uml src="assets/diagrams/sequence/figure41.plantuml" %} +{% enduml %} + +**Figure 41 -- How to use the services provided by /participants if there is no common Account Lookup System** + +#### Common Account Lookup System + +[Figure 42](#figure-42) shows how an account lookup can be performed if there is a common ALS in a scheme. The process is to ask the common Account Lookup service which FSP owns the Party with the provided identity. The common service is depicted as "Account Lookup" in the flows; this service could either be implemented by the switch or as a separate service, depending on the setup in the market. + +The FSPs do not need to support the server side of the different HTTP **GET** services under the **/participants** resource; the server side of the service should be handled by the ALS. Instead, the FSPs (clients) should provide FSP information regarding its accounts and account holders (parties) to the ALS (server) using the HTTP **POST** (to create or update FSP information, see [POST /participants](#post-participants) and [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id)) and HTTP **DELETE** (to delete existing FSP information, see [DELETE /participants/_{Type}_/_{ID}_](#delete-participantstypeid)) methods. + +###### Figure 42 + +{% uml src="assets/diagrams/sequence/figure42.plantuml" %} +{% enduml %} + +**Figure 42 -- How to use the services provided by /participants if there is a common Account Lookup System** + +#### Requests + +This section describes the services that can be requested by a client on the resource **/participants**. + +##### GET /participants/_{Type}_/_{ID}_ + +Alternative URI: **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Lookup Participant Information](../generic-transaction-patterns#lookup-participant-information) + +The HTTP request **GET /participants/**_{Type}_**/**_{ID}_ (or **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to find out in which FSP the requested Party, defined by _{Type}_, _{ID}_ and optionally _{SubId}_, is located (for example, **GET** **/participants/MSISDN/123456789**, or **GET /participants/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +This HTTP request should support a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) for filtering of currency. To use filtering of currency, the HTTP request **GET /participants/**_{Type}_**/**_{ID}_**?currency=**_XYZ_ should be used, where _XYZ_ is the requested currency. + +Callback and data model information for **GET /participants/**_{Type}_**/**_{ID}_ (alternative **GET /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback - [**PUT /participants/**_{Type}_/_{ID}_](#put-participants-type-id) +- Error Callback - [**PUT /participants/**_{Type}_/_{ID}_**/error**](#put-participants-type-iderror) +- Data Model -- Empty body + +##### POST /participants + +Alternative URI: N/A + +Logical API service: [Create Bulk Participant Information](../generic-transaction-patterns#create-bulk-participant-information) + +The HTTP request **POST /participants** is used to create information on the server regarding the provided list of identities. This request should be used for bulk creation of FSP information for more than one Party. The optional currency parameter should indicate that each provided Party supports the currency. + +Callback and data model information for **POST /participants**: + +- Callback -- [**PUT /participants/**_{ID}_](#put-participants-type-id) +- Error Callback -- [**PUT /participants/**_{ID}_ **/error**](#put-participants-type-iderror) +- Data Model -- See [Table 9](#table-9) + +###### Table 9 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**requestId**|1|CorrelationId|The ID of the request, decided by the client. Used for identification of the callback from the server.| +|**partyList**|1..10000|PartyIdInfo|List of PartyIdInfo elements that the client would like to update or create FSP information about.| +|**currency**|0..1|Currency|Indicate that the provided Currency is supported by each PartyIdInfo in the list.| + +**Table 9 - POST /participants data model** + +##### POST /participants/_{Type}_/_{ID}_ + +Alternative URI: **POST /participants/**_{Type}_/_{ID}_/_{SubId}_ + +Logical API service: [Create Participant Information](../generic-transaction-patterns#create-participant-information) + +The HTTP request **POST /participants/**_{Type}_**/**_{ID}_ (or **POST /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to create information on the server regarding the provided identity, defined by _{Type}_, _{ID}_, and optionally _{SubId}_ (for example, **POST** **/participants/MSISDN/123456789** or **POST /participants/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +Callback and data model information for **POST /participants**/_{Type}_**/**_{ID}_ (alternative **POST** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) +- Error Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) +- Data Model -- See [Table 10](#table-10) + +###### Table 10 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**fspId**|1|FspId|FSP Identifier that the Party belongs to.| +|**currency**|0..1|Currency|Indicate that the provided Currency is supported by the Party.| +|**extensionList**| 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 10 -- POST /participants/_{Type}_/_{ID}_ (alternative POST /participants/_{Type}_/_{ID}_/_{SubId}_) data model** + +##### DELETE /participants/_{Type}_/_{ID}_ + +Alternative URI: **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Delete Participant Information](../generic-transaction-patterns#delete-participant-information) + +The HTTP request **DELETE /participants/**_{Type}_**/**_{ID}_ (or **DELETE /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to delete information on the server regarding the provided identity, defined by _{Type}_ and _{ID}_) (for example, **DELETE** **/participants/MSISDN/123456789**), and optionally _{SubId}_. See [Refund](#refund) for more information regarding addressing of a Party. + +This HTTP request should support a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) to delete FSP information regarding a specific currency only. To delete a specific currency only, the HTTP request **DELETE** **/participants/**_{Type}_**/**_{ID}_**?currency**_=XYZ_ should be used, where _XYZ_ is the requested currency. + +**Note:** The ALS should verify that it is the Party's current FSP that is deleting the FSP information. + +Callback and data model information for **DELETE /participants/**_{Type}_**/**_{ID}_ (alternative **GET** **/participants/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_](#put-participants-type-id) + +- Error Callback -- [**PUT /participants/**_{Type}_**/**_{ID}_**/error**](#put-participants-type-iderror) + +- Data Model -- Empty body + +
    + +#### Callbacks + +This section describes the callbacks used by the server for services provided by the resource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_ + +Alternative URI: **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Return Participant Information](../generic-transaction-patterns#return-participant-information) + +The callback **PUT /participants/**_{Type}_**/**_{ID}_ (or **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to inform the client of a successful result of the lookup, creation, or deletion of the FSP information related to the Party. If the FSP information is deleted, the **fspId** element should be empty; otherwise the element should include the FSP information for the Party. + +See [Table 11](#table-11) for data model. + +###### Table 11 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**fspId**|0..1|FspId|FSP Identifier that the Party belongs to.| + +**Table 11 -- PUT /participants/_{Type}_/_{ID}_ (alternative PUT /participants/_{Type}_/_{ID}_/_{SubId}_) data model** + +##### PUT /participants/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Bulk Participant Information](../generic-transaction-patterns#return-bulk-participant-information) + +The callback **PUT /participants/**_{ID}_ is used to inform the client of the result of the creation of the provided list of identities. + +See [Table 12](#table-12) for data model. + +###### Table 12 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**partyList**|1..10000|PartyResults|List of PartyResult elements that were either created or failed to be created.| +|**currency**|0..1|Currency|Indicate that the provided Currency was set to be supported by each successfully added PartyIdInfo.| + +**Table 12 -- PUT /participants/_{ID}_ data model** + +####Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/participants**. + +##### PUT /participants/_{Type}_/_{ID}_/error + +Alternative URI: **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Logical API service: [Return Participant Information Error](../generic-transaction-patterns#return-participant-information-error) + +If the server is unable to find, create or delete the associated FSP of the provided identity, or another processing error occurred, the error callback **PUT /participants/**_{Type}_**/**_{ID}_**/error** (or **PUT /participants/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) is used. See [Table 13](#table-13) for data model. + +###### Table 13 + +|Name|Cardinality|Type|Description| +|---|---|---|---| +|**errorInformation**|1|ErrorInformation|Error code, category description.| + +**Table 13 -- PUT /participants/_{Type}_/_{ID}_/error (alternative PUT /participants/_{Type}_/_{ID}_/_{SubId}_/error) data model** + +##### PUT /participants/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Bulk Participant Information Error](../generic-transaction-patterns#return-bulk-participant-information-error) + +If there is an error during FSP information creation on the server, the error callback **PUT /participants/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **requestId** (see [Table 9](#table-9)) that was used for the creation of the participant information. See [Table 14](#table-14) for data model. + +###### Table 14 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **error Information** | 1 | ErrorInformation | Error code, category description. | + +**Table 14 -- PUT /participants/_{ID}_/error data model** + +#### States + +There are no states defined for the **/participants** resource; either the server has FSP information regarding the requested identity or it does not. + +
    + +### API Resource /parties + +This section defines the logical API resource **Parties,** described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-parties). + +The services provided by the resource **/parties** is used for finding out information regarding a Party in a Peer FSP. + +#### Resource Version History + +[Table 15](#table-15) contains a description of each different version of the **/parties** resource. + +###### Table 15 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 15 – Version history for resource /parties** + +#### Service Details + +[Figure 43](#figure-43) contains an example process for the [**/parties**](../generic-transaction-patterns#api-resource-parties) resource. Alternative deployments could also exist; for example, a deployment in which the Switch and the ALS are in the same server, or one in which the User's FSP asks FSP 1 directly for information regarding the Party. + +###### Figure 43 + +{% uml src="assets/diagrams/sequence/figure43.plantuml" %} +{% enduml %} + +**Figure 43 -- Example process for /parties resource** + +
    + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/parties**. + +##### GET /parties/_{Type}_/_{ID}_ + +Alternative URI: **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Lookup Party Information](../generic-transaction-patterns#lookup-party-information) + +The HTTP request **GET /parties/**_{Type}_**/**_{ID}_ (or **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to lookup information regarding the requested Party, defined by _{Type}_, _{ID}_ and optionally _{SubId}_ (for example, **GET /parties/MSISDN/123456789**, or **GET** **/parties/BUSINESS/shoecompany/employee1**). See [Refund](#refund) for more information regarding addressing of a Party. + +Callback and data model information for **GET /parties/**_{Type}_**/**_{ID}_ (alternative **GET /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_): + +- Callback - [**PUT /parties/**_{Type}_**/**_{ID}_](#put-partiestypeid) +- Error Callback - [**PUT /parties/**_{Type}_**/**_{ID}_**/error**](#put-partiestypeiderror) +- Data Model -- Empty body + +
    + +#### Callbacks + +This section describes the callbacks that are used by the server for services provided by the resource **/parties**. + +##### PUT /parties/_{Type}_/_{ID}_ + +Alternative URI: **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_ + +Logical API service: [Return Party Information](../generic-transaction-patterns#return-party-information) + +The callback **PUT /parties/**_{Type}_**/**_{ID}_ (or **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_) is used to inform the client of a successful result of the Party information lookup. See [Table 16](#table-16) for data model. + +###### Table 16 + +| **Name** | **Cardinal** | **Type** | **Description** | +| --- | --- | --- | --- | +| **party** | 1 | Party | Information regarding the requested Party. | + +**Table 16 -- PUT /parties/_{Type}_/_{ID}_ (alternative PUT /parties/_{Type}_/_{ID}_/_{SubId}_) data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/parties**. + +#### PUT /parties/_{Type}_/_{ID}_/error + +Alternative URI: **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error** + +Logical API service: [Return Party Information Error](../generic-transaction-patterns#return-party-information-error) + +If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback **PUT /parties/**_{Type}_**/**_{ID}_**/error** (or **PUT /parties/**_{Type}_**/**_{ID}_**/**_{SubId}_**/error**) is used. See [Table 17](#table-17) for data model. + +###### Table 17 + +| **Name** | **Cardinality** | **Type** | **Description** | +|---|---|---|---| +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 17 -- PUT /parties/_{Type}_/_{ID}_/error (alternative PUT /parties/_{Type}_/_{ID}_/_{SubId}_/error) data model** + +#### States + +There are no states defined for the **/parties** resource; either an FSP has information regarding the requested identity or it does not. + +
    + +### API Resource /transactionRequests + +This section defines the logical API resource **Transaction Requests**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-transaction-requests). + +The primary service that the API resource **/transactionRequests** enables is for a Payee to request a Payer to transfer electronic funds to the Payee. The Payer can either approve or reject the request from the Payee. The decision by the Payer could be made programmatically if: + +- The Payee is trusted (that is, the Payer has pre-approved the Payee in the Payer FSP), or + +- An authorization value - that is, a _one-time password_ (_OTP_) is correctly validated using the API Resource **/authorizations**, see [Section 6.6](#66-api-resource-authorizations). + +Alternatively, the Payer could make the decision manually. + +#### Resource Version History + +[Table 18](#table-18) contains a description of each different version of the **/transactionRequests** resource. + +###### Table 18 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 18 – Version history for resource /transactionRequests** + +#### Service Details + +[Figure 44](#figure-44) shows how the request transaction process works, using the **/transactionRequests** resource. The approval or rejection is not shown in the figure. A rejection is a callback **PUT /transactionRequests/**_{ID}_ with a **REJECTED** state, similar to the callback in the figure with the **RECEIVED** state, as described in [Section 6.4.2.1](#6421-payer-rejected-transaction-request). An approval by the Payer is not sent as a callback; instead a quote and transfer are sent containing a reference to the transaction request. + +###### Figure 44 + +{% uml src="assets/diagrams/sequence/figure44.plantuml" %} +{% enduml %} +**Figure 44 -- How to use the /transactionRequests service** + +##### Payer Rejected Transaction Request + +[Figure 45](#figure-45) shows the process by which a transaction request is rejected. Possible reasons for rejection include: + +- The Payer rejected the request manually. +- An automatic limit was exceeded. +- The Payer entered an OTP incorrectly more than the allowed number of times. + +###### Figure 45 + +{% uml src="assets/diagrams/sequence/figure45.plantuml" %} +{% enduml %} +**Figure 45 -- Example process in which a transaction request is rejected** + +#### Requests + +This section describes the services that a client can request on the resource **/transactionRequests**. + +##### GET /transactionRequests/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Transaction Request Information](../generic-transaction-patterns#retrieve-transaction-request-information) + +The HTTP request **GET /transactionRequests/**_{ID}_ is used to get information regarding a previously-created or requested transaction request. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 15](#table-15)) that was used for the creation of the transaction request. + +Callback and data model information for **GET /transactionRequests/**_{ID}_: + +- Callback - [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Error Callback - [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Data Model -- Empty body + +##### POST /transactionRequests + +Alternative URI: N/A + +Logical API service: [Perform Transaction Request](../generic-transaction-patterns#perform-transaction-request) + +The HTTP request **POST /transactionRequests** is used to request the creation of a transaction request for the provided financial transaction on the server. + +Callback and data model information for **POST /transactionRequests**: + +- Callback - [**PUT /transactionRequests/**_{ID}_](#put-transactionrequestsid) +- Error Callback - [**PUT /transactionRequests/**_{ID}_**/error**](#put-transactionrequestsiderror) +- Data Model -- See [Table 19](#table-19) + +###### Table 19 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transactionRequestId** | 1 | CorrelationId | Common ID between the FSPs for the transaction request object, decided by the Payee FSP. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| **payee** | 1 | Party | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | PartyInfo | Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| **amount** | 1 | Money | Requested amount to be transferred from the Payer to Payee. | +| **transactionType** | 1 | TransactionType | Type of transaction. | +| **note** | 0..1 | Note | Reason for the transaction request, intended to the Payer. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **authenticationType** | 0.11 | AuthenticationType | OTP or QR Code, otherwise empty. | +| **expiration** | 0..1 | DateTime | Can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, Merchant to know that their request has a time limit. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 19 -- POST /transactionRequests data model** + +####Callbacks + +This section describes the callbacks that are used by the server under the resource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_ + +Alternative URI: N/A + +Logical API service: **Return Transaction Request Information** + +The callback **PUT /transactionRequests/**_{ID}_ is used to inform the client of a requested or created transaction request. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 19](#table-19)) that was used for the creation of the transaction request, or the _{ID}_ that was used in the [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). See [Table 20](#table-20) for data model. + +###### Table 20 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transactionId** | 0..1 | CorrelationId | Identifies a related transaction (if a transaction has been created). | +| **transactionRequestState** | 1 | TransactionRequestState | State of the transaction request. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 20 -- PUT /transactionRequests/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transactionRequests**. + +##### PUT /transactionRequests/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transaction Request Information Error](../generic-transaction-patterns#return-transaction-request-information-error) + +If the server is unable to find or create a transaction request, or another processing error occurs, the error callback **PUT** **/transactionRequests/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **transactionRequestId** (see [Table 19](#table-19)) that was used for the creation of the transaction request, or the _{ID}_ that was used in the [**GET /transactionRequests/**_{ID}_](#get-transactionrequestsid). See [Table 21](#table-21) for data model. + +###### Table 21 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | ---| --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 21 -- PUT /transactionRequests/_{ID}_/error data model** + +#### 6.4.6 States + +The possible states of a transaction request can be seen in [Figure 46](#figure-46). + +**Note:** A server does not need to keep transaction request objects that have been rejected in their database. This means that a client should expect that an error callback could be received for a rejected transaction request. + +###### Figure 46 + +![Figure 46](/assets/diagrams/images/figure46.svg) + +**Figure 46 -- Possible states of a transaction request** + +
    + +### API Resource /quotes + +This section defines the logical API resource **Quotes**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-quotes). + +The main service provided by the API resource **/quotes** is calculation of possible fees and FSP commission involved in performing an interoperable financial transaction. Both the Payer and Payee FSP should calculate their part of the quote to be able to get a total view of all the fees and FSP commission involved in the transaction. + +A quote is irrevocable; it cannot be changed after it has been created. However, it can expire (all quotes are valid only until they reach expiration). + +**Note:** A quote is not a guarantee that the financial transaction will succeed. The transaction can still fail later in the process. A quote only guarantees that the fees and FSP commission involved in performing the specified financial transaction are applicable until the quote expires. + +For more information see [Quoting](#quoting). + +#### Resource Version History + +[Table 22](#table-22) contains a description of each different version of the **/quotes** resource. + +###### Table 22 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| +|1.1|2020-05-19|The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 22 – Version history for resource /quotes** + +#### Service Details + +[Figure 47](#figure-47) contains an example process for the API resource **/quotes**. The example shows a Payer Initiated Transaction, but it could also be initiated by the Payee, using the API Resource [**/transactionRequests**](#api-resource-transactionrequests). The lookup process is in that case performed by the Payee FSP instead. + +###### Figure 47 + +{% uml src="assets/diagrams/sequence/figure47.plantuml" %} +{% enduml %} + +**Figure 47 -- Example process for resource /quotes** + +#### Quote Expiry Details + +The quote request from the Payer FSP can contain an expiry of the quote, if the Payer FSP would like to indicate when it is no longer useful for the Payee FSP to return a quote. For example, the transaction itself might otherwise time out, or if its quote might time out. + +The Payee FSP should set an expiry of the quote in the callback to indicate when the quote is no longer valid for use by the Payer FSP. + +#### Rejection of Quote + +The Payee FSP can reject a quote request from the Payer FSP by sending the error callback **PUT /quotes/**_{ID}_/**error** instead of the callback **PUT /quotes/**_{ID}_. +Depending on which generic transaction pattern (see Section 8 for more information) that is used, the Payer FSP can reject a quote using one of the following processes: + +- If the transaction is initiated by the Payer (see Section 8.1), the Payer FSP should not inform the Payee FSP regarding the rejection. The created quote at the Payee FSP should have an expiry time, at which time it is automatically deleted. +- If the transaction is initiated by the Payee (see Section 8.2 and 8.3), the Payer FSP should inform the Payee FSP regarding the rejection using the callback **PUT /transactionRequests/**_{ID}_ with a rejected state. The process is described in more detail in Section 6.4.2.1. + +#### Interledger Payment Request + +As part of supporting Interledger and the concrete implementation of the Interledger Payment Request (see [Interledgeer Protocol](#interledger-protocol)), the Payee FSP must: + +- Determine the ILP Address (see [ILP Addressing](#ILP-addressing) for more information) of the Payee and the amount that the Payee will receive. Note that since the **amount** element in the ILP Packet is defined as an UInt64, which is an Integer value, the amount should be multiplied with the currency's exponent (for example, USD's exponent is 2, which means the amount should be multiplied by 102, and JPY's exponent is 0, which means the amount should be multiplied by 100). Both the ILP Address and the amount should be populated in the ILP Packet (see [ILP Packet](#ilp-packet) for more information). + +- Populate the **data** element in the ILP Packet by the [Transaction](#transaction) data model. +- Generate the fulfilment and the condition (see [Conditional Transfers](#conditional-transfers) for more information). Populate the **condition** element in the [PUT /quotes/**_{ID}_](#put-quotes-id)). [Table 19](#table-19) shows data model with the generated condition. + +The fulfilment is a temporary secret that is generated for each financial transaction by the Payee FSP and used as the trigger to commit the transfers that make up an ILP payment. + +The Payee FSP uses a local secret to generate a SHA-256 HMAC of the ILP Packet. The same secret may be used for all financial transactions or the Payee FSP may store a different secret per Payee or based on another segmentation. + +The choice and cardinality of the local secret is an implementation decision that may be driven by scheme rules. The only requirement is that the Payee FSP can determine which secret that was used when the ILP Packet is received back later as part of an incoming transfer (see [API Resource Transfers](#api-resource-transfers)). + +The fulfilment and condition are generated in accordance with the algorithm defined in [Listing 12](#listing-12). Once the Payee FSP has derived the condition, the fulfilment can be discarded as it can be regenerated later. + +###### Listing 12 + +Generation of the fulfilment and condition + +**Inputs:** + +- Local secret (32-byte binary string) +- ILP Packet + +**Algorithm:** + +1. Let the fulfilment be the result of executing the HMAC SHA-256 algorithm on the ILP Packet using the local secret as the key. + +2. Let the condition be the result of executing the SHA-256 hash algorithm on the fulfilment. + +**Outputs:** + +- Fulfilment (32-byte binary string) +- Condition (32-byte binary string) + +**Listing 12 -- Algorithm to generate the fulfilment and the condition** + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/quotes**. + +##### GET /quotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Quote Information](../generic-transaction-patterns#retrieve-quote-information) + +The HTTP request **GET /quotes/**_{ID}_ is used to get information regarding a previously-created or requested quote. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote. + +Callback and data model information for **GET /quotes/**_{ID}_: + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Error Callback -- [**PUT /quotes/**_{ID}_**/_error_**](#put-quotes-iderror) +- Data Model -- Empty body + +##### POST /quotes + +Alternative URI: N/A + +Logical API service: [Calculate Quote Information](../generic-transaction-patterns#calculate-quote-information) + +The HTTP request **POST /quotes** is used to request the creation of a quote for the provided financial transaction on the server. + +Callback and data model information for **POST /quotes**: + +- Callback -- [**PUT /quotes/**_{ID}_](#put-quotes-id) +- Error Callback -- [**PUT /quotes/**_{ID}_**/error**](#put-quotes-iderror) +- Data Model -- See [Table 23](#table-23) + +###### Table 23 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | CorrelationId | Common ID between the FSPs for the quote object, decided by the Payer FSP. The ID should be reused for resends of the same quote for a transaction. A new ID should be generated for each new quote for a transaction. | +| **transactionId** | 1 | CorrelationId | Common ID (decided by the Payer FSP) between the FSPs for the future transaction object. The actual transaction will be created as part of a successful transfer process. The ID should be reused for resends of the same quote for a transaction. A new ID should be generated for each new quote for a transaction. | +| **transactionRequestId** | 0..1 | CorrelationId | Identifies an optional previously-sent transaction request. | +| **payee** | 1 | Party | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | Party | Information about the Payer in the proposed financial transaction. | +| **amountType** | 1 | AmountType |**SEND** for send amount, **RECEIVE** for receive amount. | +| **amount** | 1 | Money | Depending on **amountType**:
    If **SEND**: The amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.
    If **RECEIVE**: The amount the Payee should receive; that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities.
    | +| **fees** | 0..1 | Money | Fees in the transaction.
  • The fees element should be empty if fees should be non-disclosed.
  • The fees element should be non-empty if fee should be disclosed.
  • | +| **transactionType** | 1 | TransactionType | Type of transaction for which the quote is requested. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **note** | 0..1 | Note | A memo that will be attached to the transaction. | +| **expiration** | 0..1 | DateTime | Expiration is optional. It can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, and Merchant to know that their request has a time limit. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 23 -- POST /quotes data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/quotes**. + +#### PUT /quotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Quote Information](../generic-transaction-patterns#return-quote-information) + +The callback **PUT /quotes/**_{ID}_ is used to inform the client of a requested or created quote. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote, or the _{ID}_ that was used in the [**GET /quotes/**_{ID}_](#get-quotesid). See [Table 24](#table-24) for data model. + +###### Table 24 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferAmount** | 1 | Money | The amount of Money that the Payer FSP should transfer to the Payee FSP. | +| **payeeReceiveAmount** | 0..1 | Money | The amount of Money that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | Money | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | Money | Transaction commission from the Payee FSP. | +| **expiration** | 1 | DateTime | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the Payee. Can be used to detect fraud. | +| **ilpPacket** | 1 | IlpPacket | The ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 1 | IlpCondition | The condition that must be attached to the transfer by the Payer. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment | + +**Table 24 -- PUT /quotes/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server +under the resource **/quotes**. + +##### PUT /quotes/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Quote Information Error](../generic-transaction-patterns#return-quote-information-error) + +If the server is unable to find or create a quote, or some other processing error occurs, the error callback **PUT** **/quotes/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **quoteId** (see [Table 23](#table-23)) that was used for the creation of the quote, or the _{ID}_ that was used in the [**GET /quotes/**_{ID}_](#get-quotesid). See [Table 25](#table-25) for data model. + +###### Table 25 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description.| + +**Table 25 -- PUT /quotes/_{ID}_/error data model** + +#### States + +###### Figure 48 + +[Figure 48](#figure-48) contains the UML (Unified Modeling Language) state machine for the possible states of a quote object. + +**Note:** A server does not need to keep quote objects that have been either rejected or expired in their database. This means that a client should expect that an error callback could be received for an expired or rejected quote. + +![Figure 48](/assets/diagrams/images/figure48.svg) + +**Figure 48 -- Possible states of a quote** + +
    + +### API Resource /authorizations + +This section defines the logical API resource **Authorizations**, described in [Generic Transaction Patterns](../gerneric-transaction-patterns#api-resource-authorizations). + +The API resource **/authorizations** is used to request the Payer to enter the applicable credentials in the Payee FSP system for approving the financial transaction, when the Payer has initiated the transaction from a POS, ATM, or similar, in the Payee FSP system and would like to authorize by an OTP. + +#### Resource Version History + +[Table 26](#table-26) contains a description of each different version of the **/authorizations** resource. + +###### Table 26 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| + +**Table 26 – Version history for resource /authorizations** + +#### Service Details + +[Figure 49](#figure-49) contains an example process for the API resource **/authorizations.** The Payee FSP first sends a [transaction request](#api-resource-transactionrequests)) that is authorized using OTP. The Payer FSP then performs the quoting process (see [API Resource Quotes](#api-resource-quotes)) before an authorization request is sent to the Payee FSP system for the Payer to approve by entering the OTP. If the OTP is correct, the transfer process should be initiated (see [API Resource Transfers](#api-resource-transfers)). + +###### Figure 49 + +{% uml src="assets/diagrams/sequence/figure49.plantuml" %} +{% enduml %} + +**Figure 49 -- Example process for resource /authorizations** + +#### Resend Authorization Value + +If the notification containing the authorization value fails to reach the Payer, the Payer can choose to request a resend of the authorization value if the POS, ATM, or similar device supports such a request. See [Figure 50](#figure-50) for an example of a process where the Payer requests that the OTP be resent. + +###### Figure 50 + +{% uml src="assets/diagrams/sequence/figure50.plantuml" %} +{% enduml %} + +**Figure 50 -- Payer requests resend of authorization value (OTP)** + +##### Retry Authorization Value + +The Payer FSP must decide the number of times a Payer can retry the authorization value in the POS, ATM, or similar device. This will be set in the **retriesLeft** query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) of the [**GET** **/authorizations/**_{ID}_](#get-authorizationsid) service for more information. If the Payer FSP sends retriesLeft=1, this means that it is the Payer's last try of the authorization value. See [Figure 51](#figure-51) for an example process where the Payer enters the incorrect OTP, and the **retriesLeft** value is subsequently decreased. + +###### Figure 51 + +{% uml src="assets/diagrams/sequence/figure51.plantuml" %} +{% enduml %} + +**Figure 51 -- Payer enters incorrect authorization value (OTP)** + +##### Failed OTP authorization + +If the user fails to enter the correct OTP within the number of allowed retries, the process described in [Payer Rejected Transaction Request](#payer-rejected-transaction-request) is performed. + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/authorizations**. + +##### GET /authorizations/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Perform Authorization](../generic-transaction-patterns#perform-authorization) + +The HTTP request **GET /authorizations/**_{ID}_ is used to request the Payer to enter the applicable credentials in the Payee FSP system. The _{ID}_ in the URI should contain the **transactionRequestID** (see [Table 15](#table-15)), received from the [**POST** **/transactionRequests**](#post-transactionrequests)) service earlier in the process. + +This request requires a query string (see [URI Syntax](#uri-syntax) for more information regarding URI syntax) to be included in the URI, with the following key-value pairs: + +- **authenticationType=**_{Type}_, where _{Type}_ value is a valid authentication type from the enumeration [AuthenticationType](#authenticationtype). +- **retriesLeft=**_{NrOfRetries}_, where _{NrOfRetries}_ is the number of retries left before the financial transaction is rejected. _{NrOfRetries}_ must be expressed in the form of the data type [Integer](#integer)). **retriesLeft=1** means that this is the last retry before the financial transaction is rejected. +- **amount=**_{Amount}_, where _{Amount}_ is the transaction amount that will be withdrawn from the Payer's account. _{Amount}_ must be expressed in the form of the data type [Amount](#amount). +- **currency=**_{Currency}_, where _{Currency}_ is the transaction currency for the amount that will be withdrawn from the Payer's account. The _{Currency}_ value must be expressed in the form of the enumeration [CurrencyCode](#currencycode)). + +An example URI containing all the required key-value pairs in the query string is the following: + +**GET /authorization/3d492671-b7af-4f3f-88de-76169b1bdf88?authenticationType=OTP&retriesLeft=2&amount=102¤cy=USD** + +Callback and data model information for **GET /authorization/**_{ID}_: + +- Callback - [**PUT /authorizations/**_{ID}_](#6641-put-authorizationsid) +- Error Callback - [**PUT /authorizations/**_{ID}_**/error**](#6651-put-authorizationsiderror) +- Data Model -- Empty body + +#### 6.6.4 Callbacks + +This section describes the callbacks that are used by the server under the resource **/authorizations**. + +#### 6.6.4.1 PUT /authorizations/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Authorization Result](../generic-transaction-patterns#return-authorization-result) + +The callback **PUT /authorizations/** _{ID}_ is used to inform the client of the result of a previously-requested authorization. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /authorizations/**_{ID}_](#get-authorizationsid). **See** [Table 27](#table-27) **for** data model. + +###### Table 27 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **authenticationInfo** | 0..1 | AuthenticationInfo | OTP or QR Code if entered, otherwise empty. | +| **responseType** | 1 | AuthorizationResponse | Enum containing response information; if the customer entered the authentication value, rejected the transaction, or requested a resend of the authentication value. | + +**Table 27 – PUT /authorizations/{ID} data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/authorizations**. + +#### PUT /authorizations/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Authorization Error](../generic-transaction-patterns#return-authorization-error) + +If the server is unable to find the transaction request, or another processing error occurs, the error callback **PUT** **/authorizations/**_{ID}_ **/error** is used. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /authorizations/**_{ID}_](#get-authorizationsid). **See** [Table 28](#table-28) **for** data model. + +###### Table 28 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description | + +**Table 28 -- PUT /authorizations/_{ID}_/error data model** + +#### States + +There are no states defined for the **/authorizations** resource. + +
    + +### API Resource /transfers + +This section defines the logical API resource **Transfers**, described in [Generic Transaction Patterns](../generic-transation-patterns#api-resource-transfers). + +The services provided by the API resource **/transfers** are used for performing the hop-by-hop ILP transfer or transfers, and to perform the end-to-end financial transaction by sending the transaction details from the Payer FSP to the Payee FSP. The transaction details are sent as part of the transfer data model in the ILP Packet. + +The Interledger protocol assumes that the setup of a financial transaction is achieved using an end-to-end protocol, but that an ILP transfer is implemented on the back of hop-by-hop protocols between FSPs connected to a common ledger. In the current version of the API, the API Resource **/quotes** performs the setup of the financial transaction. Before a transfer can be performed, the quote must be performed to setup the financial transaction. See [API Resource Quotes](#api-resource-quotes) for more information. + +An ILP transfer is exchanged between two account holders on either side of a common ledger. It is usually expressed in the form of a request to execute a transfer on the common ledger and a notification to the recipient of the transfer that the transfer has been reserved in their favor, including a condition that must be fulfilled to commit the transfer. + +When the Payee FSP presents the fulfilment to the common ledger, the transfer is committed in the common ledger. At the same time, the Payer FSP is notified that the transfer has been committed along with the fulfilment. + +#### Resource Version History + +Table 29 contains a description of each different version of the **/transfers** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The resource is updated to support commit notifications using HTTP Method **PATCH**. The new request **PATCH /transfers/{ID}** is described in Section 6.7.3.3. The process of using commit notifications is described in Section 6.7.2.6.

    The data model is updated to add an optional ExtensionList element to the PartyIdInfo complex type based on the Change Request: [https://github.com/mojaloop/mojaloop-specification/issues/30](https://github.com/mojaloop/mojaloop-specification/issues/30). Following this, the data model as specified in Table 93 has been updated.| + +**Table 29 –- Version history for resource /transfers** + +#### Service Details + +This section provides details regarding hop-by-hop transfers and end-to-end financial transactions. + +#### Process + +[Figure 52](#figure-52) shows how the transaction process works using the **POST /transfers** service. + +###### Figure 52 + +{% uml src="assets/diagrams/sequence/figure52.plantuml" %} +{% enduml %} + +**Figure 52 -- How to use the POST /transfers service** + +#### Transaction Irrevocability + +The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions. + +As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using **POST /transfers** including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer's expiry time is exceeded before the Payee FSP responds (see [Expired Quote](#expired-quote) and [Client Receiving Expired Transfer](#client-receiving-expired-transfer) for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties. + +#### Expired Quote + +If a server receives a transaction that is using an expired quote, the server should reject the transfer or transaction. + +#### Timeout and Expiry + +The Payer FSP must always set a transfer expiry time to allow for use cases in which a swift completion or failure is needed. If the use case does not require a swift completion, a longer expiry time can be set. If the Payee FSP fails to respond before the expiry time, the transaction is cancelled in the Payer FSP. The Payer FSP should still expect a callback from the Payee FSP. + +Short expiry times are often required in retail scenarios, in which a customer may be standing in front of a merchant; both parties need to know if the transaction was successful before the goods or services are given to the customer. + +In [Figure 52](#figure-52), an expiry has been set to 30 seconds from the current time in the request from the Payer FSP, and to 20 seconds from the same time in the request from the Switch to the Payee FSP. This strategy of using shorter timeouts for each entity in the chain from Payer FSP to Payee FSP should always be used to allow for extra communication time. + +**Note:** It is possible that a successful callback might be received in the Payer FSP after the expiry time; for example, due to congestion in the network. The Payer FSP should allow for some extra time after the actual expiry time before cancelling the financial transaction in the system. If a successful callback is received after the financial transaction has been cancelled, the transaction should be marked for reconciliation and handled separately in a reconciliation process. + +#### Client Receiving Expired Transfer + +[Figure 53](#figure-53) shows an example of a possible error scenario connected to expiry and timeouts. For some reason, the callback from the Payee FSP takes longer time to send than the expiry time in the optional Switch. This leads to the Switch cancelling the reserved transfer, and an error callback for the transfer is sent to the Payer FSP. Now the Payer FSP and the Payee FSP have two different views of the result of the financial transaction; the transaction should be marked for reconciliation. + +###### Figure 53 + +{% uml src="assets/diagrams/sequence/figure53.plantuml" %} +{% enduml %} + +**Figure 53 -- Client receiving an expired transfer** + +To limit these kinds of error scenarios, the clients (Payer FSP and optional Switch in [Figure 52](#figure-52)) participating in the ILP transfer should allow some extra time after actual expiry time during which the callback from the server can be received. The client(s) should also query the server after expiry, but before the end of the extra time, if any callback from the server has been lost due to communication failure. Reconciliation could still be necessary though, even with extra time allowed and querying the server for the transaction. + +#### Commit Notification + +As an alternative option to avoid the error scenario described in [Client Receiving Expired Transfer](#client-receiving-expired-transfer) for use cases where it is complicated to perform a refund, a Payee FSP can (if the scheme allows it) reserve the transfer and then wait for a subsequent commit notification from the Switch. To request a commit notification instead of committing directly is a business decision made by the Payee FSP (if the scheme allows it), based on the context of the transaction. For example, a Cash Out or a Merchant Payment transaction can be understood as a higher-risk transaction, because it is not possible to reverse a transaction if the customer is no longer present; a P2P Transfer can be understood as lower risk because it is easier to reverse by refunding the transaction to the customer. +To request a commit notification from the Switch, the Payee FSP must mark the transfer state (see Section 6.7.6) as reserved instead of committed in the **PUT /transfers/**_{ID}_ callback. Based on the transfer state, the Switch should then perform the following: + +- If the transfer is committed, the Switch should not send a commit notification as the Payee FSP has already accepted the risk that the transfer in some rare cases might fail. This is the default way of committing, shown in [Process](#process). +- If the transfer is reserved, the Switch must send a commit notification to the Payee FSP when the transfer is completed (committed or aborted). + +The commit notification is sent in the request **PATCH /transfers/**_{ID}_ from the Switch to the Payee FSP. If the Payee FSP does not get a commit notification from the Switch within a reasonable time, the Payee FSP should resend the **PUT /transfers/**_{ID}_ callback to the Switch. The Payee FSP needs to receive the commit notification from the Switch before committing the transfer, or accept the risk that the transfer in the Switch might have failed. The Payee FSP is not allowed to rollback the transfer without receiving an aborted state (see Section 6.7.6) from the Switch, as the Payee FSP has sent the fulfilment (which is the commit trigger) to the Switch. +[Figure 54](#figure-54) shows an example where a commit notification is requested by the Payee FSP. In this example the commit was successful in the Switch. + +###### Figure 54 + +{% uml src="assets/diagrams/sequence/figure54.plantuml" %} +{% enduml %} + +**Figure 54 -- Commit notification where commit of transfer was successful in Switch** + +[Figure 55](#figure-55) shows an example in which the commit in the Switch failed due to some reason, for example the expiry time had expired in the Switch due to network issues. This is the same example as in [Figure 53](#figure-53), but where no reconciliation is needed as the Payee FSP receives a commit notification before performing the actual transfer to the Payee. + +###### Figure 55 + +{% uml src="assets/diagrams/sequence/figure55.plantuml" %} +{% enduml %} + +**Figure 55 -- Commit notification where commit of transfer in Switch failed** + +#### Refunds + +Instead of supporting reversals, the API supports refunds. To refund a transaction using the API, a new transaction should be created by the Payee of the original transaction. The new transaction should revers the original transaction (either the full amount or a partial amount); for example, if customer X sent 100 USD to merchant Y in the original transaction, a new transaction where merchant Y sends 100 USD to customer X should be created. There is a specific transaction type to indicate a refund transaction; for example, if the quote of the transaction should be handled differently than any other type of transaction. The original transaction ID should be sent as part of the new transaction for informational and reconciliation purposes. + +#### Interledger Payment Request + +As part of supporting Interledger and the concrete implementation of the Interledger Payment Request (see [Interledger Protocol](#interledger-protocol)), the Payer FSP must attach the ILP Packet, the condition, and an expiry to the transfer. The condition and the ILP Packet are the same as those sent by the Payee FSP in the callback of the quote; see [Interledger Payment Request](#interledger-payment-request) section for more information. + +The end-to-end ILP payment is a chain of one or more conditional transfers that all depend on the same condition. The condition is provided by the Payer FSP when it initiates the transfer to the next ledger. + +The receiver of that transfer parses the ILP Packet to get the Payee ILP Address and routes the ILP payment by performing another transfer on the next ledger, attaching the same ILP Packet and condition and a new expiry that is less than the expiry of the incoming transfer. + +When the Payee FSP receives the final incoming transfer to the Payee account, it extracts the ILP Packet and performs the following steps: + +1. Validates that the Payee ILP Address in the ILP Packet corresponds to the Payee account that is the destination of the transfer. +2. Validates that the amount in the ILP Packet is the same as the amount of the transfer and directs the local ledger to perform a reservation of the final transfer to the Payee account (less any hidden receiver fees, see [Quoting](#quoting)). +3. If the reservation is successful, the Payee FSP generates the fulfilment using the same algorithm that was used when generating the condition sent in the callback of the quote (see [Interledger Payment Request](#interledger-payment-request)). +4. The fulfilment is submitted to the Payee FSP ledger to instruct the ledger to commit the reservation in favor of the Payee. The ledger will validate that the SHA-256 hash of the fulfilment matches the condition attached to the transfer. If it does, it commits the reservation of the transfer. If not, it rejects the transfer and the Payee FSP rejects the payment and cancels the previously-performed reservation. + +The fulfilment is then passed back to the Payer FSP through the same ledgers in the callback of the transfer. As funds are committed on each ledger after a successful validation of the fulfilment, the entity that initiated the transfer will be notified that the funds it reserved have been committed and the fulfilment will be shared as part of that notification message. + +The final transfer to be committed is the transfer on the Payer FSP's ledger where the reservation is committed from their account. At this point the Payer FSP notifies the Payer of the successful financial transaction. + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/transfers**. + +##### GET /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Authorization Result](../generic-transaction-patterns#return-authorization-result) + +The HTTP request **GET /transfers/**_{ID}_ is used to get information regarding a previously-created or requested transfer. The _{ID}_ in the URI should contain the **transferId** (see [Table 23](#table-23)) that was used for the creation of the transfer. + +Callback and data model information for **GET /transfer/**_{ID}_: + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Error Callback -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Data Model -- Empty body + +##### POST /transfers + +Alternative URI: N/A + +Logical API service: [Perform Transfer](../generic-transaction-patterns#perform-transfer) + +The HTTP request **POST /transfers** is used to request the creation of a transfer for the next ledger, and a financial transaction for the Payee FSP. + +Callback and data model information for **POST /transfers**: + +- Callback -- [**PUT /transfers/**_{ID}_](#put-transfersid) +- Error Callback -- [**PUT /transfers/**_{ID}_**/error**](#put-transfersiderror) +- Data Model -- See [Table 30](#table-30) + +###### Table 30 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1| CorrelationId | The common ID between the FSPs and the optional Switch for the transfer object, decided by the Payer FSP. The ID should be reused for resends of the same transfer. A new ID should be generated for each new transfer. | +| **payeeFsp** | 1 | FspId | Payee FSP in the proposed financial transaction. | +| **payerFsp** | 1 | FspId | Payer FSP in the proposed financial transaction. | +| **amount** | 1 | Money | The transfer amount to be sent. | +| **ilpPacket** | 1 | IlpPacket | The ILP Packet containing the amount delivered to the Payee and the ILP Address of the Payee and any other end-to-end data. | +| **condition** | 1 | IlpCondition | The condition that must be fulfilled to commit the transfer. | +| **expiration** | 1 | DateTime | Expiration can be set to get a quick failure expiration of the transfer. The transfer should be rolled back if no fulfilment is delivered before this time. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 30 – POST /transfers data model** + +##### PATCH /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Commit Notiifcation](../generic-transaction-patterns#commit-notification) + +The HTTP request **PATCH /transfers/**_{ID}_ is used by a Switch to update the state of an earlier reserved transfer, if the Payee FSP has requested a commit notification when the Switch has completed processing of the transfer. The _{ID}_ in the URI should contain the transferId (see Table 30) that was used for the creation of the transfer. Please note that this request does not generate a callback. See Table 31 for data model. + +###### Table 31 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 1| DateTime | Time and date when the transaction was completed | +| **transferState** | 1 | TransferState | State of the transfer | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 31 –- PATCH /transfers/_{ID}_ data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/transfers**. + +##### PUT /transfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Transfer Information](../generic-transaction-patterns#return-transfer-information) + +The callback **PUT /transfers/**_{ID}_ is used to inform the client of a requested or created transfer. The _{ID}_ in the URI should contain the **transferId** (see [Table 30](#table-30)) that was used for the creation of the transfer, or the _{ID}_ that was used in the [**GET** **/transfers/**_{ID}_](#6731-get-transfersid). **See** [Table 32](#table-32) **for** data model. + +**Note**: For **PUT /transfers/**_{ID}_ callbacks, the state ABORTED is not a valid enumeration option as **transferState** in Table 32. If a transfer is to be rejected, then the FSP making the callback should use an error callback, i.e., a callback on the /error endpoint. At the same time, it should be noted that a **transferState** value ‘ABORTED’ is valid for a callback to a **GET /transfers/**_{ID}_ call. + +###### Table 32 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **fulfilment** | 0..1 | IlpFulfilment | Fulfilment of the condition specified with the transaction. Mandatory if transfer has completed successfully. | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the transaction was completed | +| **transferState** | 1 | TransferState | State of the transfer | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment | + +**Table 32 -- PUT /transfers/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transfers**. + +##### PUT /transfers/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transfer Information Error](../generic-transaction-patterns#return-transfer-information-error) + +If the server is unable to find or create a transfer, or another processing error occurs, the error callback **PUT** + +**/transfers/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **transferId** (see [Table 30](#table-30)) that was used for the creation of the transfer, or the _{ID}_ that was used in the [**GET /transfers/**_{ID}_](#6731-get-transfersid). See [Table 33](#table-33) for data model. + +###### Table 33 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 33 -- PUT /transfers/_{ID}_/error data model** + +**6.7.6 States** + +###### Figure 56 + +The possible states of a transfer can be seen in [Figure 56](#figure-56). + +![Figure 56](/assets/diagrams/images/figure56.svg) + +**Figure 56 -- Possible states of a transfer** + +
    + + +### API Resource /transactions + +This section defines the logical API resource **Transactions**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-transactions). + +The services provided by the API resource **/transactions** are used for getting information about the performed end-to-end financial transaction; for example, to get information about a possible token that was created as part of the transaction. + +The actual financial transaction is performed using the services provided by the API Resource [**/transfers**](#67-api-resource-transfers), which includes the end-to-end financial transaction between the Payer FSP and the Payee FSP. + +#### Resource Version History + +[Table 34](#table-34) contains a description of each different version of the **/transactions** resource. + +###### Table 34 + +|Version|Date|Description| +|---|---|---| +|1.0|2018-03-13|Initial version| + +**Table 34 – Version history for resource /transactions** + +#### Service Details + +[Figure 57](#figure-57) shows an example for the transaction process. The actual transaction will be performed as part of the transfer process. The service **GET /transactions/**_{TransactionID}_ can then be used to get more information about the financial transaction that was performed as part of the transfer process. + +###### Figure 57 + +{% uml src="assets/diagrams/sequence/figure57.plantuml" %} +{% enduml %} + +**Figure 57 -- Example transaction process** + +#### Requests + +This section describes the services that can be requested by a client on the resource **/transactions**. + +##### GET /transactions/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Transaction Information](../generic-transaction-patterns#retrieve-transaction-information) + +The HTTP request **GET /transactions/**_{ID}_ is used to get transaction information regarding a previously-created financial transaction. The _{ID}_ in the URI should contain the **transactionId** that was used for the creation of the quote (see [Table 23](#table-23)), as the transaction is created as part of another process (the transfer process, see [API Resource Transfers](#api-resource-transfers)). + +Callback and data model information for **GET /transactions/**_{ID}_: + +- Callback -- [**PUT /transactions/**_{ID}_](#put-transactionsid) +- Error Callback -- [**PUT /transactions/**_{ID}_**/error**](#put-transactionsiderror) +- Data Model -- Empty body + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/transactions**. + +##### PUT /transactions/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Transaction Information](../generic-transaction-patterns#return-transaction-information) + +The callback **PUT /transactions/**_{ID}_ is used to inform the client of a requested transaction. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /transactions/**_{ID}_](#get-transactionsid). See [Table 35](#table-35) for data model. + +###### Table 35 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the transaction was completed. | +| **transactionState** | 1 | TransactionState | State of the transaction. | +| **code** | 0..1 | Code | Optional redemption information provided to Payer after transaction has been completed. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 35 -- PUT /transactions/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/transactions**. + +##### PUT /transactions/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Return Transaction Information Error](../generic-transaction-patterns#retrieve-transaction-information-error) + +If the server is unable to find or create a transaction, or another processing error occurs, the error callback **PUT** **/transactions/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the _{ID}_ that was used in the [**GET /transactions/**_{ID}_](#get-transactionsid). See [Table 36](#table-36) for data model. + +###### Table 36 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 36 -- PUT /transactions/_{ID}_/error data model** + +#### States + +###### Figure 58 + +The possible states of a transaction can be seen in [Figure 58](#figure-58). + +**Note:** For reconciliation purposes, a server must keep transaction objects that have been rejected in its database for a scheme-agreed time period. This means that a client should expect a proper callback about a transaction (if it has been received by the server) when requesting information regarding the same. + +![Figure 58](/assets/diagrams/images/figure58.svg) + +**Figure 58 -- Possible states of a transaction** + +
    + +### API Resource /bulkQuotes + +This section defines the logical API resource **Bulk Quotes**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-bulk-quotes). + +The services provided by the API resource **/bulkQuotes** service are used for requesting the creation of a bulk quote; that is, a quote for more than one financial transaction. For more information regarding a single quote for a transaction, see API Resource [/quotes](#api-resource-quotes). + +A created bulk quote object contains a quote for each individual transaction in the bulk in a Peer FSP. A bulk quote is irrevocable; it cannot be changed after it has been created However, it can expire (all bulk quotes are valid only until they reach expiration). + +**Note:** A bulk quote is not a guarantee that the financial transaction will succeed. The bulk transaction can still fail later in the process. A bulk quote only guarantees that the fees and FSP commission involved in performing the specified financial transaction are applicable until the bulk quote expires. + +#### Resource Version History + +Table 37 contains a description of each different version of the **/bulkQuotes** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 37 –- Version history for resource /bulkQuotes** + +#### Service Details + +[Figure 59](#figure-59) shows how the bulk quotes process works, using the **POST /bulkQuotes** service. When receiving the bulk of transactions from the Payer, the Payer FSP should: + +1. Lookup the FSP in which each Payee is; for example, using the API Resource [/participants](#api-resource-participants). + +2. Divide the bulk based on Payee FSP. The service **POST /bulkQuotes** is then used for each Payee FSP to get the bulk quotes from each Payee FSP. Each quote result will contain the ILP Packet and condition (see [ILP Packet](#ilp-packet) and [Conditional Transfers](#conditional-transfers)) needed to perform each transfer in the bulk transfer (see API Resource [/bulkTransfers](#api-resource-bulktransfers)), which will perform the actual financial transaction from the Payer to each Payee. + +###### Figure 59 + +{% uml src="assets/diagrams/sequence/figure59.plantuml" %} +{% enduml %} + +**Figure 59 -- Example bulk quote process** + +#### Requests + +This section describes the services that can be requested by a client in the API on the resource **/bulkQuotes**. + +##### GET /bulkQuotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Quote Information](../generic-transaction-patterns#retrieve-bulk-quote-information) + +The HTTP request **GET /bulkQuotes/**_{ID}_ is used to get information regarding a previously-created or requested bulk quote. + +The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote. + +Callback and data model information for **GET /bulkQuotes/**_{ID}_: + +- Callback -- [PUT /bulkQuotes/**_{ID}_](#put-bulkquotesid) +- Error Callback -- [PUT /bulkQuotes/**_{ID}_**/error**](#put-bulkquotesiderror) +- Data Model -- Empty body + +##### POST /bulkQuotes + +Alternative URI: N/A + +Logical API service: **Calculate Bulk Quote** + +The HTTP request **POST /bulkQuotes** is used to request the creation of a bulk quote for the provided financial transactions on the server. + +Callback and data model information for **POST /bulkQuotes**: + +- Callback -- [**PUT /bulkQuotes/**_{ID}_](#6941-put-bulkquotesid) +- Error Callback -- [**PUT /bulkQuotes/**_{ID}_**/error**](#6951-put-bulkquotesiderror) +- Data Model -- See [Table 38](#table-38) + +###### Table 38 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkQuoteId** | 1 | CorrelationId | Common ID between the FSPs for the bulk quote object, decided by the Payer FSP. The ID should be reused for resends of the same bulk quote. A new ID should be generated for each new bulk quote. | +| **payer** | 1 | Party | Information about the Payer in the proposed financial transaction. | +| **geoCode** | 0..1 | GeoCode | Longitude and Latitude of the initiating Party. Can be used to detect fraud. | +| **expiration** | 0..1 | DateTime | Expiration is optional to let the Payee FSP know when a quote no longer needs to be returned. | +| **individualQuotes** | 1..1000 | IndividualQuote | List of quotes elements. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 38 -- POST /bulkQuotes data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Return Bulk Quote Information](../generic-transaction-patterns#return-bulk-quote-information) + +The callback **PUT /bulkQuotes/**_{ID}_ is used to inform the client of a requested or created bulk quote. The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote, or the _{ID}_ that was used in the [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). See [Table 39](#table-39) for data model. + +###### Table 39 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **individualQuoteResults** | 0..1000 | IndividualQuoteResult | Fees for each individual transaction, if any of them are charged per transaction. | +| **expiration** | 1 | DateTime | Date and time until when the quotation is valid and can be honored when used in the subsequent transaction request. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 39 -- PUT /bulkQuotes/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/bulkQuotes**. + +##### PUT /bulkQuotes/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Quote Information Error](../generic-transaction-patterns#retrieve-bulk-quote-information-error) + +If the server is unable to find or create a bulk quote, or another processing error occurs, the error callback **PUT** **/bulkQuotes/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **bulkQuoteId** (see [Table 38](#table-38)) that was used for the creation of the bulk quote, or the _{ID}_ that was used in the [**GET /bulkQuotes/**_{ID}_](#6931-get-bulkquotesid). See [Table 40](#table-40) for data model. + +###### Table 40 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 40 -- PUT /bulkQuotes/_{ID}_/error data model** + +#### States + +###### Figure 60 + +The possible states of a bulk quote can be seen in [Figure 60](#figure-60). + +**Note:** A server does not need to keep bulk quote objects that have been either rejected or expired in their database. This means that a client should expect that an error callback could be received for a rejected or expired bulk quote. + +![Figure 60](/assets/diagrams/images/figure60.svg) + +**Figure 60 -- Possible states of a bulk quote** + +
    + +### API Resource /bulkTransfers + +This section defines the logical API resource **Bulk Transfers**, described in [Generic Transaction Patterns](../generic-transaction-patterns#api-resource-bulk-transfers). + +The services provided by the API resource **/bulkTransfers** are used for requesting the creation of a bulk transfer or for retrieving information about a previously-requested bulk transfer. For more information about a single transfer, see API Resource [/transfers](#api-resource-transfers). Before a bulk transfer can be requested, a bulk quote needs to be performed. See API Resource [/bulkQuotes](#api-resource-bulkquotes), for more information. + +A bulk transfer is irrevocable; it cannot be changed, cancelled, or reversed after it has been sent from the Payer FSP. + +#### Resource Version History + +Table 41 contains a description of each different version of the **/bulkTransfers** resource. + +| Version | Date | Description| +| ---- | ---- | ---- | +| **1.0** | 2018-03-13 | Initial version | +| **1.1** | 2020-05-19 | The data model is updated to add an optional ExtensioinList element to the PartyIdInfo complex type based on the Change Request: https://github.com/mojaloop/mojaloop-specification/issues/30. Following this, the data model as specified in Table 93 has been updated.| + +**Table 41 –- Version history for resource /bulkTransfers** + +#### Service Details + +[Figure 61](#figure-61) shows how the bulk transfer process works, using the **POST /bulkTransfers** service. When receiving the bulk transactions from the Payer, the Payer FSP should perform the following: + +1. Lookup the FSP in which each Payee is; for example, using the API Resource **/participants**, [Section 6.2](#62-api-resource-participants). +2. Perform the bulk quote process using the API Resource **/bulkQuotes**, [Section 6.9](#69-api-resource-bulkquotes). The bulk quote callback should contain the required ILP Packets and conditions needed to perform each transfer. +3. Perform bulk transfer process in [Figure 61](#figure-61) using **POST /bulkTransfers**. This performs each hop-to-hop transfer and the end-to-end financial transaction. For more information regarding hop-to-hop transfers vs end-to-end financial transactions, see [Section 6.7](#67-api-resource-transfers). + +###### Figure 61 + +{% uml src="assets/diagrams/sequence/figure61.plantuml" %} +{% enduml %} + +**Figure 61 -- Example bulk transfer process** + +#### Requests + +This section describes the services that can a client can request on the resource **/bulkTransfers**. + +##### GET /bulkTransfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +The HTTP request **GET /bulkTransfers/**_{ID}_ is used to get information regarding a previously-created or requested bulk transfer. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer. + +Callback and data model information for **GET /bulkTransfers/**_{ID}_: + +- Callback -- [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Error Callback -- [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Data Model -- Empty body + +##### POST /bulkTransfers + +Alternative URI: N/A + +Logical API service: [Perform Bulk Transfer](../generic-transaction-patterns#perform-bulk-transfer) + +The HTTP request **POST /bulkTransfers** is used to request the creation of a bulk transfer on the server. + +- Callback - [PUT /bulkTransfers/_{ID}_](#put-bulktransfersid) +- Error Callback - [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfersiderror) +- Data Model -- See [Table 42](#table-42) + +###### Table 42 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **bulkTransferId** | 1 | CorrelationId | Common ID between the FSPs and the optional Switch for the bulk transfer object, decided by the Payer FSP. The ID should be reused for resends of the same bulk transfer. A new ID should be generated for each new bulk transfer. | +| **bulkQuoteId** | 1 | CorrelationId | ID of the related bulk quote | +| **payeeFsp** | 1 | FspId | Payee FSP identifier. | +| **payerFsp** | 1 | FspId | Payer FSP identifier. | +| **individualTransfers** | 1..1000 | IndividualTransfer | List of IndividualTransfer elements. | +| **expiration** | 1 | DateTime | Expiration time of the transfers. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 42 -- POST /bulkTransfers data model** + +#### Callbacks + +This section describes the callbacks that are used by the server under the resource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_ + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information](../generic-transaction-patterns#retrieve-bulk-transfer-information) + +The callback **PUT /bulkTransfers/**_{ID}_ is used to inform the client of a requested or created bulk transfer. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer ([POST /bulkTransfers](#post-bulktransfers)), or the _{ID}_ that was used in the [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). See [Table 43](#table-43) for data model. + +###### Table 43 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **completedTimestamp** | 0..1 | DateTime | Time and date when the bulk transaction was completed. | +| **individualTransferResults** | 0..1000 | **Error! Reference source not found.** | List of **Error! Reference source not found.** elements. | +| **bulkTransferState** | 1 | BulkTransferState | The state of the bulk transfer. | +| **extensionList** | 0..1 | ExtensionList | Optional extension, specific to deployment. | + +**Table 43 -- PUT /bulkTransfers/_{ID}_ data model** + +#### Error Callbacks + +This section describes the error callbacks that are used by the server under the resource **/bulkTransfers**. + +##### PUT /bulkTransfers/_{ID}_/error + +Alternative URI: N/A + +Logical API service: [Retrieve Bulk Transfer Information Eerror](../generic-transaction-patterns#retrieve-bulk-transfer-information-error) + +If the server is unable to find or create a bulk transfer, or another processing error occurs, the error callback **PUT** **/bulkTransfers/**_{ID}_**/error** is used. The _{ID}_ in the URI should contain the **bulkTransferId** (see [Table 42](#table-42)) that was used for the creation of the bulk transfer ([POST /bulkTransfers](#post-bulktransfers)), or the _{ID}_ that was used in the [GET /bulkTransfers/_{ID}_](#get-bulktransfersid). See [Table 44](#table-44) for data model. + +###### Table 44 + +| **Name** | **Cardinality** | **Type** | **Description** | +| --- | --- | --- | --- | +| **errorInformation** | 1 | ErrorInformation | Error code, category description. | + +**Table 44 -- PUT /bulkTransfers/_{ID}_/error data model** + +#### States + +###### Figure 62 + +The possible states of a bulk transfer can be seen in [Figure 62](#figure-62). + +**Note:** A server must keep bulk transfer objects that have been rejected in their database during a market agreed time-period for reconciliation purposes. This means that a client should expect a proper callback about a bulk transfer (if it has been received by the server) when requesting information regarding the same. + +![Figure 62](/assets/diagrams/images/figure62.svg) + +**Figure 62 -- Possible states of a bulk transfer** + +
    + +## API Supporting Data Models + +This section provides information about additional supporting data models used by the API. + +### Format Introduction + +This section introduces formats used for element data types used by the API. + +All element data types have both a minimum and maximum length. These lengths are indicated by one of the following: + +- A minimum and maximum length +- An exact length +- A regular expression limiting the element such that only a specific length or lengths can be used. + +#### Minimum and Maximum Length + +If a minimum and maximum length is used, this will be indicated after the data type in parentheses: First the minimum value (inclusive value), followed by two period characters (..), and then the maximum value (inclusive value). + +Examples: + +- `String(1..32)` – A String that is minimum one character and maximum 32 characters long. +- `Integer(3..10)` - An Integerr that is minimum 3 digits, but maximum 10 digits long. + +#### Exact Length + +If an exact length is used, this will be indicated after the data type in parentheses containing only one exact value. Other lengths are not allowed. + +Examples: + +- `String(3)` – A String that is exactly three characters long. +- `Integer(4)` – An Integer that is exactly four digits long. + +#### Regular Expressions + +Some element data types are restricted using regular expressions. The regular expressions in this document use the standard for syntax and character classes established by the programming language Perl[30](https://perldoc.perl.org/perlre.html#Regular-Expressions). + +### Element Data Type Formats + +This section defines element data types used by the API. + + + +#### String + +The API data type `String` is a normal JSON String[31](https://tools.ietf.org/html/rfc7159#section-7), limited by a minimum and maximum number of characters. + +##### Example Format I + +`String(1..32)` – A String that is minimum *1* character and maximum *32* characters long. + +An example of `String(1..32)` appears below: + +- _This String is 28 characters_ + +##### Example Format II + +`String(1..128)` – A String that is minimum *1* character and maximum *128* characters long. + +An example of `String(32..128)` appears below: + +- _This String is longer than 32 characters, but less than 128_ + +
    + +#### Enum + +The API data type `Enum` is a restricted list of allowed JSON [String](#string)) values; an enumeration of values. Other values than the ones defined in the list are not allowed. + +##### Example Format + +`Enum of String(1..32)` – A String that is minimum one character and maximum 32 characters long and restricted by the allowed list of values. The description of the element contains a link to the enumeration. + +
    + +#### UndefinedEnum + +The API data type **UndefinedEnum** is a JSON String consisting of 1 to 32 uppercase characters including an underscore character (**\_**). + +##### Regular Expression + +The regular expression for restricting the **UndefinedEnum** type appears in [Listing 13](#listing-13). + +###### Listing 13 + +``` +^[A-Z_]{1,32}$ +``` + +**Listing 13 -- Regular expression for data type UndefinedEnum** + +
    + +#### Name + +The API data type `Name` is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + +##### Regular Expression + +The regular expression for restricting the `Name` type appears in [Listing 14](#listing-14) below. The restriction does not allow a string consisting of whitespace only, all Unicode32 characters are allowed, as well as the period (**.**), apostrophe (**'**), dash (**-**), comma (**,**) and space characters ( ). The maximum number of characters in the **Name** is 128. + +**Note:** In some programming languages, Unicode support needs to be specifically enabled. As an example, if Java is used the flag `UNICODE_CHARACTER_CLASS` needs to be enabled to allow Unicode characters. + +###### Listing 14 + +``` +^(?!\s*$)[\w .,'-]{1,128}$ +``` + +**Listing 14 -- Regular expression for data type Name** + +
    + +#### Integer + +The API data type `Integer` is a JSON String consisting of digits only. Negative numbers and leading zeroes are not allowed. The data type is always limited by a number of digits. + +##### 7.2.5.1 Regular Expression + +The regular expression for restricting an `Integer` appears in [Listing 15](#listing-15). + +###### Listing 15 + +``` +^[1-9]\d*$ +``` + +**Listing 15 -- Regular expression for data type Integer** + + +##### Example Format + +`Integer(1..6)` – An `Integer` that is at minimum one digit long, maximum six digits. + +An example of `Integer(1..6)` appears below: + +- _123456_ + +
    + +#### OtpValue + +The API data type `OtpValue` is a JSON String of three to 10 characters, consisting of digits only. Negative numbers are not allowed. One or more leading zeros are allowed. + +##### Regular Expression + +The regular expression for restricting the `OtpValue` type appears in [Listing 16](#listing-16). + +###### Listing 16 + +``` +^\d{3,10}$ +``` + +**Listing 16 -- Regular expression for data type OtpValue** + +
    + +#### BopCode + +The API data type `BopCode` is a JSON String of three characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `BopCode` type appears in [Listing 17](#listing-17). + +###### Listing 17 + +``` +^[1-9]\d{2}$ +``` + +**Listing 17 -- Regular expression for data type BopCode** + +
    + +#### ErrorCode + +The API data type `ErrorCode` is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. + +##### Regular Expression + +The regular expression for restricting the `ErrorCode` type appears in [Listing 18](#listing-18). + +###### Listing 18 + +``` +^[1-9]\d{3}$ +``` + +**Listing 18 -- Regular expression for data type ErrorCode** + +
    + +#### TokenCode + +The API data type `TokenCode` is a JSON String between four and 32 characters. It can consist of either digits, uppercase characters from **A** to **Z**, lowercase characters from **a** to **z**, or a combination of the three. + +##### 7.2.9.1 Regular Expression + +The regular expression for restricting the `TokenCode` appears in [Listing 19](#listing-19). + +###### Listing 19 + +``` +^[0-9a-zA-Z]{4,32}$ +``` + +**Listing 19 -- Regular expression for data type TokenCode** + +
    + +#### MerchantClassificationCode + +The API data type `MerchantClassificationCode` is a JSON String consisting of one to four digits. + +##### 7.2.10.1 Regular Expression + +The regular expression for restricting the `MerchantClassificationCode` type appears in [Listing 20](#listing-20). + +###### Listing 20 + +``` +^[\d]{1,4}$ +``` + +**Listing 20 -- Regular expression for data type MerchantClassificationCode** + +
    + +#### Latitude + +The API data type `Latitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.11.1 Regular Expression + +The regular expression for restricting the `Latitude` type appears in [Listing 21](#listing-21). + +###### Listing 21 + +``` +^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 21 -- Regular expression for data type Latitude** + +
    + +#### Longitude + +The API data type `Longitude` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.12.1 Regular Expression + +The regular expression for restricting the `Longitude` type appears in [Listing 22](#listing-22). + +###### Listing 22 + +``` +^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ +``` + +**Listing 22 -- Regular expression for data type Longitude** + +
    + +#### Amount + +The API data type `Amount` is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the `Amount` type appears in [Listing 23](#listing-23). This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed. + +###### Listing 23 + +``` +^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$ +``` + +**Listing 23 -- Regular expression for data type Amount** + +##### Example Values + +See [Table 45](#table-45) for validation results for some example **Amount** values using the [regular expression](#regular-expression-6). + +###### Table 45 + +| **Value** | **Validation result** | +| --- | --- | +| **5** | Accepted | +| **5.0** | Rejected | +| **5.** | Rejected | +| **5.00** | Rejected | +| **5.5** | Accepted | +| **5.50** | Rejected | +| **5.5555** | Accepted | +| **5.55555** | Rejected | +| **555555555555555555** | Accepted | +| **5555555555555555555** | Rejected | +| **-5.5** | Rejected | +| **0.5** | Accepted | +| **.5** | Rejected | +| **00.5** | Rejected | +| **0** | Accepted | + +**Table 45 -- Example results for different values for Amount type** + +
    + +#### DateTime + +The API data type `DateTime` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### 7.2.14.1 Regular Expression + +The regular expression for restricting the `DateTime` type appears in [Listing 24](#listing-24). The format is according to ISO 860133, expressed in a combined date, time and time zone format. A more readable version of the format is + +_yyyy_**-**_MM_**-**_dd_**T**_HH_**:**_mm_**:**_ss_**.**_SSS_[**-**_HH_**:**_MM_] + +###### Listing 24 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468\][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ +``` + +**Listing 24 -- Regular expression for data type DateTime** + +##### Examples + +Two examples of the `DateTime` type appear below: + +**2016-05-24T08:38:08.699-04:00** + +**2016-05-24T08:38:08.699Z** (where **Z** indicates Zulu time zone, which is the same as UTC). + +
    + +#### Date + +The API data type `Date` is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + +##### Regular Expression + +The regular expression for restricting the **Date** type appears in [Listing 25](#listing-25). This format, as specified in ISO 8601, contains a date only. A more readable version of the format is _yyyy_**-**_MM_**-**_dd_. + +###### Listing 25 + +``` +^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ +``` + +**Listing 25 -- Regular expression for data type Date** + +##### Examples + +Two examples of the `Date` type appear below: + +- _1982-05-23_ + +- _1987-08-05_ + +
    + +#### UUID + +The API data type `UUID` (Universally Unique Identifier) is a JSON String in canonical format, conforming to RFC 412234, that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and four dashes ('**-**'). + +##### 7.2.16.1 Regular Expression + +The regular expression for restricting the `UUID` type appears in [Listing 26](#listing-26). + +###### Listing 26 + +``` +^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ +``` + +**Listing 26 -- Regular expression for data type UUID** + +##### Example + +An example of a `UUID` type appears below: + +- _a8323bc6-c228-4df2-ae82-e5a997baf898_ + +
    + +#### BinaryString + +The API data type `BinaryString` is a JSON String. The string is a base64url35 encoding of a string of raw bytes, where a padding (character '**=**') is added at the end of the data if needed to ensure that the string is a multiple of four characters. The length restriction indicates the allowed number of characters. + +##### Regular Expression + +The regular expression for restricting the `BinaryString` type appears in [Listing 27](#listing-27). + +###### Listing 27 + +``` +^[A-Za-z0-9-_]+[=]{0,2}$ +``` + +**Listing 27 -- Regular expression for data type BinaryString** + +##### Example Format + +`BinaryString(32)` –32 bytes of data base64url encoded. + +An example of a `BinaryString(32..256)` appears below. Note that a padding character, `'='` has been added to ensure that the string is a multiple of four characters. + +- _QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE=_ + +
    + +#### BinaryString32 + +The API data type `BinaryString32` is a fixed size version of the API data type `BinaryString` defined [here](#binarystring), where the raw underlying data is always of 32 bytes. The data type **BinaryString32** should not use a padding character as the size of the underlying data is fixed. + +##### Regular Expression + +The regular expression for restricting the `BinaryString32` type appears in [Listing 28](#listing-28). + +###### Listing 28 + +``` +^[A-Za-z0-9-_]{43}$ +``` + +**Listing 28 -- Regular expression for data type BinaryString32** + +##### Example Format +`BinaryString(32)` – 32 bytes of data base64url encoded. + +An example of a `BinaryString32` appears below. Note that this is the same binary data as the example shown in the [Example Format](#example-format-4) of the `BinaryString` type, but due to the underlying data being fixed size, the padding character `'='` is excluded. + +``` +QmlsbCAmIE1lbGluZGEgR2F0ZXMgRm91bmRhdGlvbiE +``` + +
    + +### Element Definitions + +This section defines elements types used by the API. + +#### AmountType element + +[Table 46](#table-46) below contains the data model for the element `AmountType`. + +###### Table 46 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AmountType** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the amount type. See [AmountType](#amounttype-enum) enumeration for more information on allowed values. | + +**Table 46 – Element AmountType** + +
    + +#### AuthenticationType element + +[Table 47](#table-47) below contains the data model for the element `AuthenticationType`. + +###### Table 47 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Authentication** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authentication type. See [AuthenticationType](#authenticationtype-enum) enumeration for possible enumeration values. | + +**Table 47 – Element AuthenticationType** + +
    + +#### AuthenticationValue element + +[Table 48](#table-48) below contains the data model for the element `AuthenticationValue`. + +###### Table 48 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthenticationValue** | 1 | Depends on [AuthenticationType](#authenticationtype-element).

    If `OTP`: type is [Integer(1..6)](#integer). For example:**123456**

    OtpValue
    If `QRCODE`: type is [String(1..64)](#string) | This element contains the authentication value. The format depends on the authentication type used in the [AuthenticationInfo](#authenticationinfo) complex type. | + +**Table 48 – Element AuthenticationValue** + +
    + +#### AuthorizationResponse element + +[Table 49](#table-49) below contains the data model for the element `AuthorizationResponse`. + +###### Table 49 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **AuthorizationResponse** | 1 | [Enum](#enum) of [String(1..32)](#string) | This element contains the authorization response. See [AuthorizationResponse](#authorizationresponse-enum) enumeration for possible enumeration values. | + +**Table 49 – Element AuthorizationResponse** + +
    + +#### BalanceOfPayments element + +[Table 50](#table-50) below contains the data model for the element `BalanceOfPayment`. + +###### Table 50 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BalanceOfPayments** | 1 | [BopCode](#bopcode) | The possible values and meaning are defined in [https://www.imf.org/external/np/sta/bopcode/](https://www.imf.org/external/np/sta/bopcode/) | + +**Table 50 – Element BalanceOfPayments** + +
    + +#### BulkTransferState element + +[Table 51](#table-51) below contains the data model for the element `BulkTransferState`. + +###### Table 51 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **BulkTransferState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [BulkTransferState](#bulktransferstate-enum) enumeration for information on allowed values| + +**Table 51 – Element BulkTransferState** + +
    + +#### Code element + +[Table 52](#table-52) below contains the data model for the element `Code`. + +###### Table 52 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Code** | 1 | [TokenCode](#tokencode) | Any code/token returned by the Payee FSP. | + +**Table 52 – Element Code** + +
    + +#### CorrelationId element + +[Table 53](#table-53) below contains the data model for the element `CorrelationId`. + +###### Table 53 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **CorrelationId** | 1 |[UUID](#uuid) | Identifier that correlates all messages of the same sequence. | + + +**Table 53 – Element CorrelationId** + +
    + +#### Currency element + +[Table 54](#table-54) below contains the data model for the element `Currency`. + +###### Table 54 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Currency** | 1 | [Enum](#enum) of [String(3)](#string) | See [Currency](#currencycode-enum) enumeration for information on allowed values | + +**Table 54 – Element Currency** + +
    + +#### DateOfBirth element + +[Table 55](#table-55) below contains the data model for the element `DateOfBirth`. + +###### Table 55 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **DateOfBirth** | 1 | Examples

    Two examples of the [DateTime](#datetime) type appear below:

    2016-05-24T08:38:08.699-04:00

    2016-05-24T08:38:08.699Z (where Z indicates Zulu time zone, which is the same as UTC).

    Date

    | Date of Birth of the Party.| + +**Table 55 – Element DateOfBirth** + +
    + +#### ErrorCode element + +[Table 56](#table-56) below contains the data model for the element `ErrorCode`. + +###### Table 56 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorCode** | 1 | [ErrorCode](#errorcode) | Four digit error code, see section on [Error Codes](#error-codes) for more information. | + +**Table 56 – Element ErrorCode** + +
    + +#### ErrorDescription element + +[Table 57](#table-57] below contains the data model for the element `ErrorDescription`. + +###### Table 57 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ErrorDescription** | 1 | [String(1..128)](#string) | Error description string. | + +**Table 57 – Element ErrorDescription** + +
    + +#### ExtensionKey element + +[Table 58](#table-58) below contains the data model for the element `ExtensionKey`. + +###### Table 58 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionKey** | 1 | [String(1..32)](#string) | The extension key. | + +**Table 58 – Element ExtensionKey** + +
    + +#### ExtensionValue element + +[Table 59](#table-59) below contains the data model for the element `ExtensionValue`. + +###### Table 59 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **ExtensionValue** | 1 | [String(1..128)](#string) | The extension value. | + +**Table 59 – Element ExtensionValue** + +
    + +#### FirstName element +[Table 60](#table-60) below contains the data model for the element `FirstName`. + +###### Table 60 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FirstName** | 1 | [Name](#name) | First name of the Party | + +**Table 60 – Element FirstName** + +
    + +#### FspId element + +[Table 61](#table-61) below contains the data model for the element `FspId`. + +###### Table 61 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **FspId** | 1 | [String(1..32)](#string)| The FSP identifier. | + +**Table 61 – Element FspId** + +
    + +#### IlpCondition element + +[Table 62](#table-62) below contains the data model for the element `IlpCondition`. + +###### Table 62 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpCondition** | 1 | [BinaryString32](#binarystring32) | The condition that must be attached to the transfer by the Payer. | + +**Table 62 – Element IlpCondition** + +
    + +#### IlpFulfilment element + +[Table 63](#table-63) below contains the data model for the element `IlpFulfilment`. + +###### Table 63 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpFulfilment** | 1 | [BinaryString32](#binarystring32) | The fulfilment that must be attached to the transfer by the Payee. | + +**Table 63 – Element IlpFulfilment** + +
    + +#### IlpPacket element + +[Table 64](#table-64) below cntains the data model for the element `IlpPacket`. + +###### Table 64 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **IlpPacket** | 1 | Example

    An example of a [UUID](#uuid) type appears below:

    a8323bc6-c228-4df2-ae82-e5a997baf898

    [BinaryString(1..32768)](#binarystring)

    | Information for recipient (transport layer information). | + +**Table 64 – Element IlpPacket** + +
    + +#### LastName element + +[Table 65](#table-65) below contains the data model for the element `LastName`. + +###### Table 65 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **LastName** | 1 | [Name](#name) | Last name of the Party (ISO 20022 definition). | + +**Table 65 – Element LastName** + +
    + +#### MerchantClassificationCode element + +[Table 66](#table-66) below contains the data model for the element `MerchantClassificationCode`. + +###### Table 66 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MerchantClassificationCode** | 1 | [MerchantClassificationCode](#merchantclassificationcode) | A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, and so on. | + +**Table 66 – Element MerchantClassificationCode** + +
    + +#### MiddleName element + +[Table 67](#table-67) below contains the data model for the element `MiddleName`. + +###### Table 67 + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **MiddleName** | 1 | [Name](#name) | Middle name of the Party (ISO 20022 definition). | + +**Table 67 – Element MiddleName** + +
    + +#### Note element + +[Table 68](#table-68) below contains the data model for the element `Note`. + +###### Table 68 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **Note** | 1 | [String(1..128)](#string) | Memo assigned to transaction. | + +**Table 68 – Element Note** + +
    + + +#### PartyIdentifier element + +[Table 69](#table-69) below contains the data model for the element `PartyIdentifier`. + +###### Table 69 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdentifier** | 1 | [String(1..128)](#string) | Identifier of the Party.| + +**Table 69 – Element PartyIdentifier** + +
    + +#### PartyIdType element + +[Table 70](#table-70) below contains the data model for the element `PartyIdType`. + +###### Table 70 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyIdType** | 1 | Enum of [String(1..32)](#string) | See [PartyIdType](#partyidtype-enum) enumeration for more information on allowed values. | + +**Table 70 – Element PartyIdType** + +
    + +#### PartyName element + +[Table 71](#table-71) below contains the data model for the element `PartyName`. + +###### Table 71 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartyName** | 1 | `Name` | Name of the Party. Could be a real name or a nickname. | + +**Table 71 – Element PartyName** + +
    + +#### PartySubIdOrType element + +[Table 72](#table-72) below contains the data model for the element `PartySubIdOrType`. + +###### Table 72 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **PartySubIdOrType** | 1 | [String(1..128)](#string) | Either a sub-identifier of a [PartyIdentifier](#partyidentifier-element), or a sub-type of the [PartyIdType](#partyidtype-element), normally a `PersonalIdentifierType`. | + +**Table 72 – Element PartySubIdOrType** + +
    + +#### RefundReason element + +[Table 73](#table-73) below contains the data model for the element `RefundReason`. + +###### Table 73 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **RefundReason** | 1 | [String(1..128)](#string) | Reason for the refund. | + +**Table 73 – Element RefundReason** + +
    + +#### TransactionInitiator element + +[Table 74](#table-74) below contains the data model for the element `TransactionInitiator`. + +###### Table 74 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiator** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiator](#transactioninitiator-enum) enumeration for more information on allowed values. | + +**Table 74 – Element TransactionInitiator** + +
    + +#### TransactionInitiatorType element + +[Table 75](#table-75) below contains the data model for the element `TransactionInitiatorType`. + +###### Table 75 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionInitiatorType** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionInitiatorType](#transactioninitiatortype-enum) enumeration for more information on allowed values. | + +**Table 75 – Element TransactionInitiatorType** + +
    + +#### TransactionRequestState element + +[Table 76](#table-76) below contains the data model for the element `TransactionRequestState`. + +###### Table 76 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionRequestState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionRequestState](#transactionrequeststate-enum) enumeration for more information on allowed values. | + + +**Table 76 – Element TransactionRequestState** + +
    + +#### TransactionScenario element + +[Table 77](#table-77) below contains the data model for the element `TransactionScenario`. + +###### Table 77 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionScenario** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionScenario](#transactionscenario-enum) enumeration for more information on allowed values. | + +**Table 77 – Element TransactionScenario** + +
    + +#### TransactionState element + +[Table 78](#table-78) below contains the data model for the element `TransactionState`. + +###### Table 78 + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransactionState](#transactionstate-enum) enumeration for more information on allowed values. | + +**Table 78 – Element TransactionState** + +
    + + +#### TransactionSubScenario element + +[Table 79](#table-79) below contains the data model for the element `TransactionSubScenario`. + +###### Table 79 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionSubScenario** | 1 | [UndefinedEnum](#undefinedenum) | Possible sub-scenario, defined locally within the scheme.| + +**Table 79 – Element TransactionSubScenario** + +
    + +#### TransferState element + +[Table 80](#table-80) below contains the data model for the element `TransferState`. + +###### Table 80 + +|Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| **TransactionState** | 1 | [Enum](#enum) of [String(1..32)](#string) | See [TransferState](#transferstate-enum) enumeration for more information on allowed values. | + +**Table 80 – Element TransferState** + + +
    + + +### Complex Types + +This section describes complex types used by the API. + +#### AuthenticationInfo + +[Table 81](#table-81) contains the data model for the complex type `AuthenticationInfo`. + +###### Table 81 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **authentication** | 1 | `AuthenticationType` | Type of authentication. | +| **authenticationValue** | 1 | `AuthenticationValue` | Authentication value. | + +**Table 81 -- Complex type AuthenticationInfo** + +
    + +#### ErrorInformation + +[Table 82](#table-82) contains the data model for the complex type `ErrorInformation`. + +###### Table 82 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **errorCode** | 1 | `Errorcode` | Specific error number. | +| **errorDescription** | 1 | `ErrorDescription` | Error description string. | +| **extensionList** | 1 | `ExtensionList` | Optional list of extensions, specific to deployment. | + +**Table 82 -- Complex type ErrorInformation** + +
    + +#### Extension + +[Table 83](#table-83) contains the data model for the complex type `Extension`. + +###### Table 83 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **key** | 1 | `ExtensionKey` | Extension key. | +| **value** | 1 | `ExtensionValue` | Extension value. | + +**Table 83 -- Complex type Extension** + +
    + +#### ExtensionList + +[Table 84](#table-84) contains the data model for the complex type `ExtensionList`. + +###### Table 84 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **extension** | 1..16 | `Extension` | Number of Extension elements. | + +**Table 84 -- Complex type ExtensionList** + +
    + +#### IndividualQuote + +[Table 85](#table-85) contains the data model for the complex type `IndividualQuote`. + +###### Table 85 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifies quote message. | +| **transactionId** | 1 | `CorrelationId` | Identifies transaction message. | +| **payee** | 1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **amountType** | 1 | `AmountType` | **SEND** for sendAmount, **RECEIVE** for receiveAmount. | +| **amount** | 1 | `Money` | Depending on **amountType**:
    If **SEND**: The amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction.
    If **RECEIVE**: The amount the Payee should receive; that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. | +| **fees** | 0..1 | `Money` | Fees in the transaction.
    • The fees element should be empty if fees should be non-disclosed.
    • The fees element should be non-empty if fees should be disclosed.
    +| **transactionType** | 1 | `TransactionType` | Type of transaction that the quote is requested for. | +| **note** | 0..1 | Note | Memo that will be attached to the transaction.| +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 85 -- Complex type IndividualQuote** + +
    + +#### IndividualQuoteResult + +[Table 86](#table-86) contains the data model for the complex type `IndividualQuoteResult`. + +###### Table 86 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **quoteId** | 1 | `CorrelationId` | Identifies the quote message. | +| **payee** | 0..1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **transferAmount** | 0..1 | `Money` | The amount of Money that the Payer FSP should transfer to the Payee FSP. | +| **payeeReceiveAmount** | 0..1 | `Money` | Amount that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees. | +| **payeeFspFee** | 0..1 | `Money` | Payee FSP’s part of the transaction fee. | +| **payeeFspCommission** | 0..1 | `Money` | Transaction commission from the Payee FSP. | +| **ilpPacket** | 0..1 | `IlpPacket` | ILP Packet that must be attached to the transfer by the Payer. | +| **condition** | 0..1 | `IlpCondition` | Condition that must be attached to the transfer by the Payer. | +| **errorInformation** | 0..1 | `ErrorInformation` | Error code, category description.
    **Note: payee, transferAmount, payeeReceiveAmount, payeeFspFee, payeeFspCommission, ilpPacket,** and **condition** should not be set if **errorInformation** is set.
    +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment | + +**Table 86 -- Complex type IndividualQuoteResult** + +
    + +#### IndividualTransfer + +[Table 87](#table-87) contains the data model for the complex type `IndividualTransfer`. + +###### Table 87 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifies messages related to the same **/transfers** sequence. | +| **transferAmount** | 1 | `Money` | Transaction amount to be sent. | +| **ilpPacket** | 1 | `IlpPacket` | ILP Packet containing the amount delivered to the Payee and the ILP Address of the Payee and any other end-to-end data. | +| **condition** | 1 | `IlpCondition` | Condition that must be fulfilled to commit the transfer. | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 87 -- Complex type IndividualTransfer** + +
    + +#### IndividualTransferResult + +[Table 88](#table-88) contains the data model for the complex type `IndividualTransferResult`. + +###### Table 88 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transferId** | 1 | `CorrelationId` | Identifies messages related to the same /transfers sequence. | +| **fulfilment** | 0..1 | `IlpFulfilment` | Fulfilment of the condition specified with the transaction.
    **Note:** Either **fulfilment** or **errorInformation** should be set, not both. | +| **errorInformation** | 0..1 | `ErrorInformation` | If transfer is REJECTED, error information may be provided.
    **Note:** Either **fulfilment** or **errorInformation** should be set, not both.| +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment.| + +**Table 88 -- Complex type IndividualTransferResult** + +
    + +#### GeoCode + +[Table 89](#table-89) contains the data model for the complex type `GeoCode`. + +###### Table 89 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **latitude** | 1 | `Latitude` | Latitude of the Party. | +| **longitude** | 1 | `Longitude` | Longitude of the Party. | + +**Table 89 -- Complex type GeoCode** + +
    + +#### Money + +[Table 90](#table-90) contains the data model for the complex type `Money`. + +###### Table 90 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **currency** | 1 | `Currency` | Currency of the amount. | +| **amount** | 1 | `Amount` | Amount of money. | + +**Table 90 -- Complex type Money** + +
    + +#### Party + +[Table 91](#table-91) contains the data model for the complex type `Party`. + +###### Table 91 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdInfo** | 1 | `PartyIdInfo` | Party Id type, id, sub ID or type, and FSP Id. | +| **merchantClassificationCode** | 0..1 | `MerchantClassificationCode` | Used in the context of Payee Information, where the Payee happens to be a merchant accepting merchant payments. | +| **name** | 0..1 | `PartyName` | Display name of the Party, could be a real name or a nick name. | +| **personalInfo** | 0..1 | `PartyPersonalInfo` | Personal information used to verify identity of Party such as first, middle, last name and date of birth. | + +**Table 91 -- Complex type Party** + +
    + +#### PartyComplexName + +[Table 92](#table-92) contains the data model for the complex type `PartyComplexName`. + +###### Table 92 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **firstName** | 0..1 | `FirstName` | Party's first name. | +| **middleName** | 0..1 | `MiddleName` | Party's middle name. | +| **lastName** | 0..1 | `LastName` | Party's last name. | + +**Table 92 -- Complex type PartyComplexName** + +
    + +#### PartyIdInfo + +[Table 93](#table-93) contains the data model for the complex type `PartyIdInfo`. + +###### Table 93 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyIdType** | 1 | `PartyIdType` | Type of the identifier. | +| **partyIdentifier** | 1 | `PartyIdentifier` | An identifier for the Party. | +| **partySubIdOrType** | 0..1 | `PartySubIdOrType` | A sub-identifier or sub-type for the Party. | +| **fspId** | 0..1 | `FspId` | FSP ID (if know) | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 93 -- Complex type PartyIdInfo** + +
    + +#### PartyPersonalInfo + +[Table 94](#table-94) contains the data model for the complex type `PartyPersonalInfo`. + +###### Table 94 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **complexName** | 0..1 | `PartyComplexName` | First, middle and last name for the Party. | +| **dateOfBirth** | 0..1 | `DateOfBirth` | Date of birth for the Party. | + +**Table 94 -- Complex type PartyPersonalInfo** + +
    + +#### PartyResult + +[Table 95](#table-95) contains the data model for the complex type `PartyResult`. + +###### Table 95 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **partyId** | 1 | `PartyIdInfo` | Party Id type, id, sub ID or type, and FSP Id. | +| **errorInformation** | 0..1 | `ErrorInformation` | If the Party failed to be added, error information should be provided. Otherwise, this parameter should be empty to indicate success. | + +**Table 95 -- Complex type PartyResult** + +
    + +#### Refund + +[Table 96](#table-96) contains the data model for the complex type `Refund`. + +###### Table 96 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **originalTransactionId** | 1 | `CorrelationId` | Reference to the original transaction ID that is requested to be refunded. | +| **refundReason** | 0..1 | `RefundReason` | Free text indicating the reason for the refund. | + +**Table 96 -- Complex type Refund** + +
    + +#### Transaction + +[Table 97](#table-97) contains the data model for the complex type Transaction. The Transaction type is used to carry end-to-end data between the Payer FSP and the Payee FSP in the ILP Packet, see [IlpPacket](#ilp-packet). Both the **transactionId** and the **quoteId** in the data model is decided by the Payer FSP in the [POST /quotes](#post-quotes), see [Table 23](#table-23). + +###### Table 97 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **transactionId** | 1 | `CorrelationId` | ID of the transaction, the ID is decided by the Payer FSP during the creation of the quote. | +| **quoteId** | 1 | `CorrelationId` | ID of the quote, the ID is decided by the Payer FSP during the creation of the quote. | +| **payee** | 1 | `Party` | Information about the Payee in the proposed financial transaction. | +| **payer** | 1 | `Party` | Information about the Payer in the proposed financial transaction. | +| **amount** | 1 | `Money` | Transaction amount to be sent. | +| **transactionType** | 1 | `TransactionType` | Type of the transaction. | +| **note** | 0..1 | `Note` | Memo associated to the transaction, intended to the Payee. | +| **extensionList** | 0..1 | `ExtensionList` | Optional extension, specific to deployment. | + +**Table 97 -- Complex type Transaction** + +
    + +#### TransactionType + +[Table 98](#table-98) contains the data model for the complex type `TransactionType`. + +###### Table 98 + +| **Name** | **Cardinality** | **Format** | **Description** | +| --- | --- | --- | --- | +| **scenario** | 1 | `TransactionScenario` | Deposit, withdrawal, refund, ... | +| **subScenario** | 0..1 | `TransactionSubScenario` | Possible sub-scenario, defined locally within the scheme. | +| **initiator** | 1 | `TransactionInitiator` | Who is initiating the transaction: Payer or Payee | +| **initiatorType** | 1 | `TransactionInitiatorType` | Consumer, agent, business, ... | +| **refundInfo** | 0..1 | `Refund` | Extra information specific to a refund scenario. Should only be populated if scenario is REFUND. | +| **balanceOfPayments** | 0..1 | `BalanceOfPayments` | Balance of Payments code. | + +**Table 98 -- Complex type TransactionType** + +
    + +### Enumerations + +This section contains the enumerations that are used by the API. + +#### AmountType enum + +[Table 99](#table-99) contains the allowed values for the enumeration `AmountType`. + +###### Table 99 + +| **Name** | **Description** | +| --- | --- | +| **SEND** | Amount the Payer would like to send; that is, the amount that should be withdrawn from the Payer account including any fees. | +| **RECEIVE** | Amount the Payer would like the Payee to receive; that is, the amount that should be sent to the receiver exclusive fees. | + +**Table 99 -- Enumeration AmountType** + +
    + +#### AuthenticationType enum + +[Table 100](#table-100) contains the allowed values for the enumeration `AuthenticationType`. + +###### Table 100 + +| **Name** | **Description** | +| --- | --- | +| **OTP** | One-time password generated by the Payer FSP. | +| **QRCODE** | QR code used as One Time Password. | + +**Table 100 -- Enumeration AuthenticationType** + +
    + +#### AuthorizationResponse enum + +[Table 101](#table-101) contains the allowed values for the enumeration `AuthorizationResponse`. + +###### Table 101 + +| **Name** | **Description** | +| --- | --- | +| **ENTERED** | Consumer entered the authentication value. | +| **REJECTED** | Consumer rejected the transaction. | +| **RESEND** | Consumer requested to resend the authentication value. | + +**Table 101 -- Enumeration AuthorizationResponse** + +
    + +#### BulkTransferState enum + +[Table 102](#table-102) contains the allowed values for the enumeration `BulkTransferState`. + +###### Table 102 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payee FSP has received the bulk transfer from the Payer FSP. | +| **PENDING** | Payee FSP has validated the bulk transfer. | +| **ACCEPTED** | Payee FSP has accepted the bulk transfer for processing. | +| **PROCESSING** | Payee FSP has started to transfer fund to the Payees. | +| **COMPLETED** | Payee FSP has completed transfer of funds to the Payees. | +| **REJECTED** | Payee FSP has rejected processing the bulk transfer. | + +**Table 102 -- Enumeration BulkTransferState** + +
    + +#### CurrencyCode enum + +The currency codes defined in ISO 421736 as three-letter alphabetic codes are used as the standard naming representation for currencies. The currency codes from ISO 4217 are not shown in this document, implementers are instead encouraged to use the information provided by the ISO 4217 standard directly. + +
    + +#### PartyIdType enum + +[Table 103](#Table-103) contains the allowed values for the enumeration `PartyIdType`. + +###### Table 103 + +| **Name** | **Description** | +| --- | --- | +| **MSISDN** | An MSISDN (Mobile Station International Subscriber Directory Number; that is, a phone number) is used in reference to a Party. The MSISDN identifier should be in international format according to the ITU-T E.16437 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. | +| **EMAIL** | An email is used in reference to a Party. The format of the email should be according to the informational RFC 369638. | +| **PERSONAL_ID** | A personal identifier is used in reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the [PartyIdentifier](#partyidentifier-element) element. The personal identifier type is added in the [PartySubIdOrType](#partysubidortype-element) element. | +| **BUSINESS** | A specific Business (for example, an organization or a company) is used in reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the [PartySubIdOrType](#partysubidortype-element) element should be used. | +| **DEVICE** | A specific device (for example, POS or ATM) ID connected to a specific business or organization is used in reference to a Party. For referencing a specific device under a specific business or organization, use the [PartySubIdOrType](#partysubidortype-element) element. | +| **ACCOUNT_ID** | A bank account number or FSP account ID should be used in reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. +| **IBAN** | A bank account number or FSP account ID is used in reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. | +| **ALIAS** | An alias is used in reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the [PartySubIdOrType](#partysubidortype-element) element for identifying an account under an Alias defined by the [PartyIdentifier](#partyidentifier-element). | + +**Table 103 -- Enumeration PartyIdType** + +
    + +#### PersonalIdentifierType enum + +[Table 104](#table-104) contains the allowed values for the enumeration `PersonalIdentifierType`. + +###### Table 104 + +| **Name** | **Description** | +| --- | --- | +| **PASSPORT** | A passport number is used in reference to a Party. | +| **NATIONAL_REGISTRATION** | A national registration number is used in reference to a Party. | +| **DRIVING_LICENSE** | A driving license is used in reference to a Party. | +| **ALIEN_REGISTRATION** | An alien registration number is used in reference to a Party. | +| **NATIONAL_ID_CARD** | A national ID card number is used in reference to a Party. | +| **EMPLOYER_ID** | A tax identification number is used in reference to a Party. | +| **TAX_ID_NUMBER** | A tax identification number is used in reference to a Party. | +| **SENIOR_CITIZENS_CARD** | A senior citizens card number is used in reference to a Party. | +| **MARRIAGE_CERTIFICATE** | A marriage certificate number is used in reference to a Party. | +| **HEALTH_CARD** | A health card number is used in reference to a Party. | +| **VOTERS_ID** | A voter’s identification number is used in reference to a Party. | +| **UNITED_NATIONS** | An UN (United Nations) number is used in reference to a Party. | +| **OTHER_ID** | Any other type of identification type number is used in reference to a Party. | + +**Table 104 -- Enumeration PersonalIdentifierType** + +
    + +#### TransactionInitiator + +[Table 105](#table-105) describes valid values for the enumeration `TransactionInitiator`. + +###### Table 105 + +| **Name** | **Description** | +| --- | --- | +| **PAYER** | Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. | +| **PAYEE** | Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or manually by approving on their own Device. | + +**Table 105 -- Enumeration TransactionInitiator** + +
    + +#### TransactionInitiatorType + +[Table 106](#table-106) contains the allowed values for the enumeration `TransactionInitiatorType`. + +###### Table 106 + +| **Name** | **Description** | +| --- | --- | +| **CONSUMER ** | Consumer is the initiator of the transaction. | +| **AGENT** | Agent is the initiator of the transaction. | +| **BUSINESS** | Business is the initiator of the transaction. | +| **DEVICE** | Device is the initiator of the transaction. | + +**Table 106 -- Enumeration TransactionInitiatorType** + +
    + +#### TransactionRequestState + +[Table 107](#table-107) contains the allowed values for the enumeration `TransactionRequestState`. + +###### Table 107 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payer FSP has received the transaction from the Payee FSP. | +| **PENDING** | Payer FSP has sent the transaction request to the Payer. | +| **ACCEPTED** | Payer has approved the transaction. | +| **REJECTED** | Payer has rejected the transaction. | + +**Table 107 -- Enumeration TransactionRequestState** + +
    + +#### TransactionScenario + +[Table 108](#table-108) contains the allowed values for the enumeration `TransactionScenario`. + +###### Table 108 + +| **Name** | **Description** | +| --- | --- | +| **DEPOSIT** | Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. | +| **WITHDRAWAL** | Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. | +| **TRANSFER** | Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. | +| **PAYMENT** | Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. | +| **REFUND** | Used for performing a refund of transaction. | + +**Table 108 -- Enumeration TransactionScenario** + +
    + +#### TransactionState + +[Table 109](#table-109) contains the allowed values for the enumeration `TransactionState`. + +###### Table 109 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Payee FSP has received the transaction from the Payer FSP. | +| **PENDING** | Payee FSP has validated the transaction. | +| **COMPLETED** | Payee FSP has successfully performed the transaction. | +| **REJECTED** | Payee FSP has failed to perform the transaction. | + +**Table 109 -- Enumeration TransactionState** + +
    + +#### TransferState + +[Table 110](#table-110) contains the allowed values for the enumeration `TransferState`. + +###### Table 110 + +| **Name** | **Description** | +| --- | --- | +| **RECEIVED** | Next ledger has received the transfer. | +| **RESERVED** | Next ledger has reserved the transfer. | +| **COMMITTED** | Next ledger has successfully performed the transfer. | +| **ABORTED** | Next ledger has aborted the transfer due a rejection or failure to perform the transfer. | + +**Table 110 -- Enumeration TransferState** + +
    + +### Error Codes + +###### Figure 63 + +Each error code in the API is a four-digit number, for example, **1234**, where the first number (**1** in the example) represents the high-level error category, the second number (**2** in the example) represents the low-level error category, and the last two numbers (**34** in the example) represents the specific error. [Figure 63](#figure-63) shows the structure of an error code. The following sections contain information about defined error codes for each high-level error category. + +![Figure 63](/assets/diagrams/images/figure63.svg) + +**Figure 63 -- Error code structure** + +Each defined high- and low-level category combination contains a generic error (_x_**0**_xx_), which can be used if there is no specific error, or if the server would not like to return information which is considered private. + +All specific errors below _xx_**40**; that is, _xx_**00** to _xx_**39**, are reserved for future use by the API. All specific errors above and including _xx_**40** can be used for scheme-specific errors. If a client receives an unknown scheme-specific error, the unknown scheme-specific error should be interpreted as a generic error for the high- and low-level category combination instead (_xx_**00**). + +#### Communication Errors -- 1_xxx_ + +All possible communication or network errors that could arise that cannot be represented by an HTTP status code should use the high-level error code **1** (error codes **1**_xxx_). Because all services in the API are asynchronous, these error codes should generally be used by a Switch in the Callback to the client FSP if the Peer FSP cannot be reached, or when a callback is not received from the Peer FSP within an agreed timeout. + +Low level categories defined under Communication Errors: + +- **Generic Communication Error** -- **10**_xx_ + +See [Table 111](#table-111) for all communication errors defined in the API. + +###### Table 111 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **1000** | Communication error | Generic communication error. | X | X | X | X | X | X | X | X | X | +| **1001** | Destination communication error | Destination of the request failed to be reached. This usually indicates that a Peer FSP failed to respond from an intermediate entity. | X | X | X | X | X | X | X | X | X | + +**Table 111 -- Communication errors -- 1_xxx_** + +#### Server Errors -- 2_xxx_ + +All possible errors occurring on the server in which it failed to fulfil an apparently valid request from the client should use the high-level error code **2** (error codes **2**_xxx_). These error codes should indicate that the server is aware that it has encountered an error or is otherwise incapable of performing the requested service. + +Low-level categories defined under server errors: + +- **Generic server error** -- **20**_xx_ + +See [Table 112](#Table-112) for server errors defined in the API. + +###### Table 112 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **2000** | Generic server error | Generic server error to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **2001** | Internal server error | Generic unexpected exception. This usually indicates a bug or unhandled error case. | X | X | X | X | X | X | X | X | X | +| **2002** | Not implemented | Service requested is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **2003** | Service currently unavailable | Service requested is currently unavailable on the server. This could be because maintenance is taking place, or because of a temporary failure. | X | X | X | X | X | X | X | X | X | +| **2004** | Server timed out | Timeout has occurred, meaning the next Party in the chain did not send a callback in time. This could be because a timeout is set too low or because something took longer than expected. | X | X | X | X | X | X | X | X | X | +| **2005** | Server busy | Server is rejecting requests due to overloading. Try again later. | X | X | X | X | X | X | X | X | X | + +**Table 112 -- Server errors -- 2_xxx_** + +#### Client Errors -- 3_xxx_ + +All possible errors occurring on the server in which the server reports that the client has sent one or more erroneous parameters should use the high-level error code **3** (error codes **3**_xxx_). These error codes should indicate that the server could not perform the service according to the request from the client. The server should provide an explanation why the service could not be performed. + +Low level categories defined under client Errors: + +- **Generic Client Error** -- **30**_xx_ + + - See [Table 113](#table-113) for generic client errors defined in the API. + +- **Validation Error** -- **31**_xx_ + + - See [Table 114](#table-114) the validation errors defined in the API. + +- **Identifier Error** -- **32**_xx_ + + - See [Table 115](#table-115) for identifier errors defined in the API. + +- **Expired Error** -- **33**_xx_ + + - See [Table 116](#table-116) for expired errors defined in the API. + +###### Table 113 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3000** | Generic client error | Generic client error, used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3001** | Unacceptable version requested | Client requested to use a protocol version which is not supported by the server. | X | X | X | X | X | X | X | X | X | +| **3002** | Unknown URI | Provided URI was unknown to the server. | X | X | X | X | X | X | X | X | X | +| **3003** | Add Party information error | Error occurred while adding or updating information regarding a Party. | X | X | X | X | X | X | X | X | X | + +**Table 113 -- Generic client errors -- 30_xx_** + +###### Table 114 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3100** | Generic validation error | Generic validation error to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3101** | Malformed syntax | Format of the parameter is not valid. For example, amount set to **5.ABC**. The error description field should specify which information element is erroneous. | X | X | X | X | X | X | X | X | X | +| **3102** | Missing mandatory element | Mandatory element in the data model was missing. | X | X | X | X | X | X | X | X | X | +| **3103** | Too many elements | Number of elements of an array exceeds the maximum number allowed. | X | X | X | X | X | X | X | X | X | +| **3104** | Too large payload | Size of the payload exceeds the maximum size. | X | X | X | X | X | X | X | X | X | +| **3105** | Invalid signature | Some parameters have changed in the message, making the signature invalid. This may indicate that the message may have been modified maliciously. | X | X | X | X | X | X | X | X | X | +| **3106** | Modified request | Request with the same ID has previously been processed in which the parameters are not the same. ||| X | X | X | X | X | X | X | +| **3107** | Missing mandatory extension parameter | Scheme-mandatory extension parameter was missing. ||| X | X | X | X | X | X | X | + +**Table 114 -- Validation errors -- 31_xx_** + +###### Table 115 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3200** | Generic ID not found | Generic ID error provided by the client. | X | X | X | X | X | X | X | X | X | +| **3201** | Destination FSP Error | Destination FSP does not exist or cannot be found. | X | X | X | X | X | X | X | X | X | +| **3202** | Payer FSP ID not found |Provided Payer FSP ID not found. |||||| X ||| X | +| **3203** | Payee FSP ID not found |Provided Payee FSP ID not found. |||||| X ||| X | +| **3204** | Party not found |Party with the provided identifier, identifier type, and optional sub id or type was not found. | X | X | X | X |||||| +| **3205** | Quote ID not found |Provided Quote ID was not found on the server. |||| X || X |||| +| **3206** | Transaction request ID not found |Provided Transaction Request ID was not found on the server. ||| X ||| X |||| +| **3207** | Transaction ID not found |Provided Transaction ID was not found on the server. ||||||| X ||| +| **3208** | Transfer ID not found |Provided Transfer ID was not found on the server. |||||| X |||| +| **3209** | Bulk quote ID not found |Provided Bulk Quote ID was not found on the server. |||||||| X | X | +| **3210** | Bulk transfer ID not found |Provided Bulk Transfer ID was not found on the server. ||||||||| X | + +**Table 115 -- Identifier errors -- 32_xx_** + +###### Table 116 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **3300** | Generic expired error | Generic expired object error, to be used in order not to disclose information that may be considered private. | X | X | X | X | X | X | X | X | X | +| **3301** | Transaction request expired | Client requested to use a transaction request that has already expired. |||| X |||||| +| **3302** | Quote expired | Client requested to use a quote that has already expired. ||||| X | X ||| X | +| **3303** | Transfer expired | Client requested to use a transfer that has already expired. | X | X | X | X | X | X | X | X | X | + +**Table 116 -- Expired errors -- 33_xx_** + +#### Payer Errors -- 4_xxx_ + +All errors occurring on the server for which the Payer or the Payer FSP is the cause of the error should use the high-level error code **4** (error codes **4**_xxx_). These error codes indicate that there was no error on the server or in the request from the client, but the request failed for a reason related to the Payer or the Payer FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payer Errors: + +- **Generic Payer Error** -- **40**_xx_ + +- **Payer Rejection Error** -- **41**_xx_ + +- **Payer Limit Error** -- **42**_xx_ + +- **Payer Permission Error** -- **43**_xx_ + +- **Payer Blocked Error** -- **44**_xx_ + +See [Table 117](#table-117) for Payer errors defined in the API. + +###### Table 117 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **4000** | Generic Payer error | Generic error related to the Payer or Payer FSP. Used for protecting information that may be considered private. ||| X | X | X | X | X | X | X | +| **4001** | Payer FSP insufficient liquidity | Payer FSP has insufficient liquidity to perform the transfer. |||||| X |||| +| **4100** | Generic Payer rejection | Payer or Payer FSP rejected the request. ||| X | X | X | X | X | X | X | +| **4101** | Payer rejected transaction request | Payer rejected the transaction request from the Payee. ||| X ||||||| +| **4102** | Payer FSP unsupported transaction type |Payer FSP does not support or rejected the requested transaction type ||| X ||||||| +| **4103** | Payer unsupported currency | Payer does not have an account which supports the requested currency. ||| X ||||||| +| **4200** | Payer limit error | Generic limit error, for example, the Payer is making more payments per day or per month than they are allowed to, or is making a payment which is larger than the allowed maximum per transaction. ||| X | X || X || X | X | +| **4300** | Payer permission error | Generic permission error, the Payer or Payer FSP does not have the access rights to perform the service. ||| X | X | X | X | X | X | X | +| **4400** | Generic Payer blocked error | Generic Payer blocked error; the Payer is blocked or has failed regulatory screenings. ||| X | X | X | X | X | X | X | + +**Table 117 -- Payer errors -- 4_xxx_** + +#### Payee Errors -- 5_xxx_ + +All errors occurring on the server for which the Payee or the Payee FSP is the cause of an error use the high-level error code **5** (error codes **5**_xxx_). These error codes indicate that there was no error on the server or in the request from the client, but the request failed for a reason related to the Payee or the Payee FSP. The server should provide an explanation why the service could not be performed. + +Low level categories defined under Payee Errors: + +- **Generic Payee Error** -- **50**_xx_ + +- **Payee Rejection Error** -- **51**_xx_ + +- **Payee Limit Error** -- **52**_xx_ + +- **Payee Permission Error** -- **53**_xx_ + +- **Payee Blocked Error** -- **54**_xx_ + +See [Table 118](#table-118) for all Payee errors defined in the API. + +###### Table 118 + +| **Error Code** | **Name** | **Description** | /participants | /parties | /transactionRequests | /quotes | /authorizations | /transfers | /transactions | /bulkQuotes | /bulkTransfers | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **5000** | Generic Payee error | Generic error due to the Payer or Payer FSP, to be used in order not to disclose information that may be considered private. ||| X | X | X | X | X | X | X | +| **5001** | Payee FSP insufficient liquidity | Payee FSP has insufficient liquidity to perform the transfer. |||||| X |||| +| **5100** | Generic Payee rejection | Payee or Payee FSP rejected the request. ||| X | X | X | X | X | X | X | +| **5101** | Payee rejected quote | Payee does not want to proceed with the financial transaction after receiving a quote. |||| X |||| X || +| **5102** | Payee FSP unsupported transaction type | Payee FSP does not support or has rejected the requested transaction type |||| X ||||| X | +| **5103** | Payee FSP rejected quote | Payee FSP does not want to proceed with the financial transaction after receiving a quote. |||| X |||| X || +| **5104** | Payee rejected transaction | Payee rejected the financial transaction. |||||| X ||| X | +| **5105** | Payee FSP rejected transaction | Payee FSP rejected the financial transaction. |||||| X ||| X | +| **5106** | Payee unsupported currency | Payee does not have an account that supports the requested currency. |||| X || X || X | X | +| **5200** | Payee limit error | Generic limit error, for example, the Payee is receiving more payments per day or per month than they are allowed to, or is receiving a payment that is larger than the allowed maximum per transaction. ||| X | X || X || X | X | +| **5300** |Payee permission error | Generic permission error, the Payee or Payee FSP does not have the access rights to perform the service. ||| X | X | X | X | X | X | X | +| **5400** | Generic Payee blocked error | Generic Payee Blocked error, the Payee is blocked or has failed regulatory screenings. ||| X | X | X | X | X | X | X | + +**Table 118 -- Payee errors -- 5_xxx_** + + +## Generic Transaction Patterns Binding + +This section provides information about how the logical transaction patterns from [Generic Transaction Patterns](../generic-transaction-patterns) are used in the asynchronous REST binding of the API. Much of the information is provided by way of sequence diagrams. For more information regarding the steps in these diagrams, see [Generic Transaction Patterns](../generic-transaction-patterns). + +### Payer Initiated Transaction + +The `Payer Initiated Transaction` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). On a high-level, the pattern should be used whenever a Payer would like to transfer funds to another Party whom is not located in the same FSP as the Payer. [Figure 64](#figure-64) shows the sequence diagram for a `Payer Initiated Transaction` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). + +###### Figure 64 + +{% uml src="assets/diagrams/sequence/figure64.plantuml" %} +{% enduml %} + +**Figure 64 -- Payer Initiated Transaction pattern using the asynchronous REST binding** + +### Payee Initiated Transaction + +The `Payee Initiated Transaction` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payer-initiated-transaction). On a high-level, the pattern should be used whenever a Payee would like to request that Payer transfer funds to a Payee. The Payer and the Payee are assumed to be in different FSPs, and the approval of the transaction is performed in the Payer FSP. If the transaction information and approval occur on a Payee device instead, use the related Payee Initiated Transaction using OTP](#payee-initiated-transaction-using-otp) instead. [Figure 65](#figure-65) shows the sequence diagram for a `Payee Initiated Transaction` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction). + +###### Figure 65 + +{% uml src="assets/diagrams/sequence/figure65.plantuml" %} +{% enduml %} + +**Figure 65 -- Payee Initiated Transaction pattern using the asynchronous REST binding** + +### Payee Initiated Transaction using OTP + +The `Payee Initiated Transaction using OTP` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction-using-otp). On a high-level, this pattern is like the [Payee Initiated Transaction](#payee-initiated-transaction); however, in this pattern the transaction information and approval for the Payer is shown and entered on a Payee device instead. As in other transaction patterns, the Payer and the Payee are assumed to be in different FSPs. [Figure 66](#figure-66) shows the sequence diagram for a `Payee Initiated Transaction using OTP` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#payee-initiated-transaction-using-otp). + +###### Figure 66 + +{% uml src="assets/diagrams/sequence/figure66.plantuml" %} +{% enduml %} + +**Figure 66 -- Payee Initiated Transaction using OTP pattern using the asynchronous REST binding** + +### Bulk Transactions + +The `Bulk Transactions` pattern is introduced in [Generic Transaction Patterns](../generic-transaction-patterns#bulk-transactions). On a high-level, the pattern is used whenever a Payer would like to transfer funds to multiple Payees using one single transaction. The Payees can be in different FSPs. [Figure 67](#figure-67) shows the sequence diagram for a `Bulk Transactions` using the asynchronous REST binding of the logical version. The process for each number in the sequence diagram is described in [Generic Transaction Patterns](../generic-transaction-patterns#bulk-transactions). + +###### Figure 67 + +{% uml src="assets/diagrams/sequence/figure67.plantuml" %} +{% enduml %} + +**Figure 67 -- Bulk Transactions pattern using the asynchronous REST binding** + +
    + +## API Error Handling + +This section describes how to handle missing responses or callbacks, as well as how to handle errors in a server during processing of a request. + +### Erroneous Request + +If a server receives an erroneous service request that can be handled immediately (for example, malformed syntax or resource not found), a valid HTTP client error code (starting with **4_xx_**39) should be returned to the client in the response. The HTTP error codes defined in the API appear in [Table 4](#table-4). The HTTP response may also contain an [**ErrorInformation**](#errorinformation) element for the purpose of describing the error in more detail (for more information, see [Error Information in HTTP Response](#error-information-in-http-response)). + +
    + +### Error in Server During Processing of Request + +[Figure 68](#figure-68) shows an example of how to handle an error on a server during processing. + +###### Figure 68 + +{% uml src="assets/diagrams/sequence/figure68.plantuml" %} +{% enduml %} + +**Figure 68 -- Error on server during processing of request** + +#### Internal Processing Steps + +The following list describes the steps in the sequence (see [Figure 68](#figure-68)). + +1. The client would like the server to create a new service object and thus uses a **POST** request. + +2. The server receives the request. It immediately sends an **accepted** response to the client, and then tries to create the object based on the service request. A processing error occurs, and the request cannot be handled as requested. The server sends the callback **_PUT_ /**_{resource}_**/**_{ID}_**/error** including an error code ([Error Codes](#error-codes)) and error description to notify the client of the error. + +3. The client receives the error callback and immediately responds with **OK**. The client then handles the error. + +4. The server receives the **OK** response and the process is completed. + +
    + +### Client Handling on Error Callback + +The following sections explain how a client handles error callbacks from a server. + +#### API Resource /participants + +The typical error from the **/participants** service is that the requested Party could not be found. The client could either try another server, or notify the end user that the requested Party could not be found. + +#### API Resource /parties + +The typical error from the **/parties** service is that the requested Party could not be found. The client could either try another server, or notify the end user that information regarding the requested Party could not be found. + +#### API Resource /quotes + +The typical error from the **/quotes** service is that a quote could not be calculated for the requested transaction. The client should notify the end user that the requested transaction could not be performed. + +#### API Resource /transactionRequests + +The typical error from the **/transactionRequests** service is that the Payer rejected the transaction or that an automatic validation failed. The client should notify the Payee that the transaction request failed. + +#### API Resource /authorizations + +The typical error from the **/authorizations** service is that the transaction request could not be found. The client should notify the Payer that the transaction request has been cancelled. + +#### API Resource /transfers + +The typical error from the **/transfers** service is that either the hop-to-hop transfer process or the end-to-end financial transaction failed. For example, a limit breach was discovered, or the Payee could not be found. The client (the Payer FSP) should in any error case cancel the reservation for the financial transaction that was performed before requesting the transaction to be performed on the server (the Payee FSP). See [Figure 69](#figure-69) for an example including a financial Switch between the FSPs. + +###### Figure 69 + +{% uml src="assets/diagrams/sequence/figure69.plantuml" %} +{% enduml %} + +**Figure 69 -- Handling of error callback from POST /transfers** + +##### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 69](#figure-69)). + +1. The transfer is reserved from the Payer's account to either a combined Switch account or a Payee FSP account, depending on setup. After the transfer has been successfully reserved, the request [POST /transfers](#post-transfers) is used on the Switch. The transfer is now irrevocable from the Payer FSP. The Payer FSP then waits for an **accepted** response from the Switch. + +2. The Switch receives the request [POST /transfers](#post-transfers) and immediately sends an **accepted** response to the Payer FSP. The Switch then performs all applicable internal transfer validations. If the validations are successful, a transfer is reserved from a Payer FSP account to a Payee FSP account. After the transfer has been successfully reserved, the request [POST /transfers](#post-transfers) is used on the Payee FSP. The transfer is now irrevocable from the Switch. The Switch then waits for an **accepted** response from the Payee FSP. + +3. The Payee FSP receives the [POST /transfers](#post-transfers) and immediately sends an **accepted** response to the Switch. The Payee FSP then performs all applicable internal transaction validations. The validation is assumed to fail at this point, for example, due to a limit breach. The error callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) is used on the Switch to inform the Payer FSP about the error. The Payee FSP then waits for an **OK** response from the Switch to complete the transfer process. + +4. The Switch receives the error callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) and immediately responds with an **OK** response. The Switch then cancels the earlier reserved transfer, as it has received an error callback. The Switch will then use the callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) to the Payer FSP, using the same parameters, and wait for an **OK** response to complete the transfer process. + +5. The Payer FSP receives the callback [PUT /transfers/_{ID}_/error](#put-transfers-id-error) and immediately responds with an **OK** response. The Payer FSP then cancels the earlier reserved transfer because it has received an error callback. + +#### API Resource /transactions + +The normal error case from the **/transactions** service is that the transaction could not be found in the Peer FSP. + +#### API Resource /bulkQuotes + +The typical error from the **/bulkQuotes** service is that a quote could not be calculated for the requested transaction. The client should notify the end user that the requested transaction could not be performed. + +#### API Resource /bulkTransfers + +The typical error case from the **/bulkTransfers** service is that the bulk transaction was not accepted; for example, due to a validation error. The client (the Payer FSP) should in any error case cancel the reservation for the financial transaction that was performed before requesting that the transaction be performed on the server (the Payee FSP). See [Figure 70](#figure-70) for an example including a financial Switch between the FSPs. + +###### Figure 70 + +{% uml src="assets/diagrams/sequence/figure70.plantuml" %} +{% enduml %} + +**Figure 70 -- Handling of error callback from API Service /bulkTransfers** + +##### Internal Processing Steps + +The following list describes the steps in the sequence (see [Figure 70](#figure-70)). + +1. Each individual transfer in the bulk transfer is reserved from the Payer's account to either a combined Switch account or a Payee FSP account, depending on setup. After each transfer has been successfully reserved, the request [POST /bulkTransfers](#post-bulktransfers) is used on the Switch. The bulk transfer is now irrevocable from the Payer FSP. The Payer FSP then waits for an **accepted** response from the Switch. + +2. The Switch receives the request [POST /bulkTransfers](#post-bulktransfers) and immediately sends an **accepted** response to the Payer FSP. The Switch then performs all applicable internal transfer validations. If the validations are successful, each individual transfer is reserved from a Payer FSP account to a Payee FSP account. After the transfers have been successfully reserved, the request [POST /bulkTransfers](#post-bulktransfers) is used on the Payee FSP. The bulk transfer is now irrevocable from the Switch. The Switch then waits for an **accepted** response from the Payee FSP. + +3. The Payee FSP receives [POST /bulkTransfers](#post-bulktransfers) and immediately sends an **accepted** response to the Switch. The Payee FSP then performs all applicable internal bulk transfer validations. The validation is assumed to fail due to some reason; for example, a validation failure that prevents the entire bulk transfer from being performed. The error callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) is used on the Switch to inform the Payer FSP about the error. The Payee FSP then waits for an **OK** response from the Switch to complete the bulk transfer process. + +4. The Switch receives the error callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) and immediately responds with an **OK** response. The Switch then cancels all the previous reserved transfers, because it has received an error callback. The Switch then uses the callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) to the Payer FSP, using the same parameters, and waits for an **OK** response to complete the bulk transfer process. + +5. The Payer FSP receives the callback [PUT /bulkTransfers/_{ID}_/error](#put-bulktransfers-id-error) and immediately responds with an **OK** response. The Payer FSP then cancels all the earlier reserved transfers, as it has received an error callback. + +
    + +### Client Missing Response from Server - Using Resend of Request + +[Figure 71](#figure-71) shows an example UML (Unified Modeling Language) sequence diagram in which a client (FSP or Switch) performs error handling when the client misses a response from a server (Switch or Peer FSP) pertaining to a service request, using resend of the same service request. + +###### Figure 71 + +{% uml src="assets/diagrams/sequence/figure71.plantuml" %} +{% enduml %} + +**Figure 71 -- Error handling from client using resend of request** + +#### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 71](#figure-71)). + +1. The client would like the server to create a new service object. The HTTP request is lost somewhere on the way to the server. + +2. The client notes that no response has been received from the server within a specified timeout. The client resends the service request. + +3. The server receives the resent request. It immediately sends an **accepted** response to the client, and then creates the object in accordance with the service request. + +4. The **accepted** HTTP response from the server is lost on the way to the client, and the client notes that no response has been received from the server within a specified timeout. The client resends the service request. + +5. The server receives the resent request. It immediately sends an **accepted** response to the client, and then notes that the service request is the same as in [Step 3](#figure-70). As the service request is a resend, the server should not create a new object based on the service request. The server sends a callback to notify the client about the object created in [Step 3](#figure-70). + +6. The client receives the callback regarding the created object. The client sends an **OK** HTTP response to the server to complete the process. + +7. The server receives the **OK** HTTP response from the client, completing the process. + +
    + +### Server Missing Response from Client + +A server using the API is not responsible for making sure that a callback is properly delivered to a client. However, it is considered good practice to retry if the server does not receive an **OK** response from the client. + +#### Client Missing Callback - Using GET request + +[Figure 72](#figure-72) is a UML sequence diagram showing how a client (Switch or Peer FSP) would perform error handling in case of no callback from a client (FSP or Switch) within a reasonable time. + +###### Figure 72 + +{% uml src="assets/diagrams/sequence/figure72.plantuml" %} +{% enduml %} + +**Figure 72 -- Error handling from client using GET request** + +#### Internal Processing Steps + +The following list provides a detailed description of all the steps in the sequence (see [Figure 71](#figure-71)). + +1. The client would like the server to create a new service object; a service request is sent. + +2. The server receives the service request. It immediately sends an **accepted** response to the client, and then creates the object based on the service request. The object creation is a long running process; for example, a bulk transfer consisting of numerous financial transactions. + +3. The server notes that no callback has been received from the client within a reasonable time. The client uses a **GET** service request with the ID that was provided in the original service request. + +4. The server receives the **GET** service request. The server sends an accepted HTTP response to the client to notify that the request will be handled. + +5. The client receives the **accepted** HTTP response and waits for the callback, which arrives sometime later; the client sends an **OK** HTTP response and the process is completed. + +6. The server sends the callback to the client containing the requested information, and an **OK** HTTP response is received from the client, which completes the process. + +
    + +## End-to-End Example + +This section contains an end-to-end example in which an account holder is provisioned, and then a P2P Transfer from a Payer located in one FSP to a Payee located in another FSP is performed. The example includes both HTTP requests and responses, HTTP headers, and data models in JSON, but without additional security features of using JWS (see [_Signature_](./signature.md)) and field level encryption using JWE (see [_Encryption_](./encryption.md)). + +### Example Setup + +This section explains the setup of the example. + +#### Nodes + +###### Figure 73 + +The nodes in the end-to-end example in this section are simplified by having only two FSPs, where one FSP is a bank (identifier **BankNrOne**) and the other FSP is a mobile money operator (identifier **MobileMoney**), and one Switch (identifier **Switch**). The Switch also acts as the Account Lookup System (ALS) in this simplified setup (see [Figure 73](#figure-73)). + +![Figure 73](/assets/diagrams/images/figure73.svg) + +**Figure 73 -- Nodes in end-to-end example** + +#### Account Holders + +The account holders in the example are: + +- One account holder in the FSP **BankNrOne** named Mats Hagman. Mats Hagman has a bank account with IBAN number **SE4550000000058398257466**. The currency of the account is USD. + +- One account holder in the FSP **MobileMoney** named Henrik Karlsson. Henrik Karlsson has a mobile money account that is identified by his phone number **123456789**. The currency of the account is USD. + +#### Scenario + +The scenario in the example is that Mats Hagman in FSP **BankNrOne** wants to transfer 100 USD to Henrik Karlsson in the FSP **MobileMoney**. Before Henrik Karlsson can be found by FSP **BankNrOne**, Henrik's FSP **MobileMoney** should provide information to the Switch specifying in which FSP Henrik Karlsson can be found in. The end-to-end flow including all used services can be found in [Other Notes](#other-notes). + +#### Other Notes + +The JSON messages used in the examples are formatted with color coding, indentations, and line breaks for very long lines to simplify the read of the examples. + +Both FSPs are assumed to have a pre-funded Switch account in their respective FSPs. + +### End-to-End Flow + +[Figure 74](#figure-74) shows the end-to-end flow of the entire example, from provisioning of FSP information to the actual transaction. + +###### Figure 74 + +{% uml src="assets/diagrams/sequence/figure74.plantuml" %} +{% enduml %} + +**Figure 74 -- End-to-end flow, from provision of account holder FSP information to a successful transaction** + +### Provision Account Holder + +Before the Payee Henrik Karlsson can be found by the Payer FSP **BankNrOne**, Henrik Karlsson should be provisioned to the ALS, which is also the Switch in this simplified example, by Henrik's FSP (**MobileMoney**). This is performed through either one of the services [**POST /participants**](#6232-post-participants) (bulk version) or [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) (single version). As the Payee in this example is only one (Henrik Karlsson), the single [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) version is used by FSP **MobileMoney**. The provision could happen anytime, for example when Henrik Karlsson signed up for the financial account, or when the FSP **MobileMoney** connected to the Switch for the first time. + +#### FSP MobileMoney Provisions Henrik Karlsson: Step 1 in End-to-End Flow + +[Listing 29](#listing-29) shows the HTTP request where the FSP **MobileMoney** provisions FSP information for account holder Henrik Karlsson, identified by **MSISDN** and **123456789** (see [Party Addressing](#party-addressing) for more information). The JSON element **fspId** is set to the FSP identifier (MobileMoney), and JSON element **currency** is set to the currency of the account (USD). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, +and [POST /participants/_{Type}_/_{ID}_](#post-participants-type-id) for more information about the service ). **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 29 + +``` +POST /participants/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.participants+json;version=1 +Content-Length: 50 +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +Date: Tue, 14 Nov 2017 08:12:31 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 29 -- Provision FSP information for account holder Henrik Karlsson** + +[Listing 30](#listing-30) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 29](#listing-29). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 30 + +``` +HTTP/1.1 202 Accepted +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 30 -- Synchronous response on provision request** + +
    + +#### Switch Handles Provision: Step 2 in End-to-End Flow + +When the Switch has received the HTTP request in [Listing 29](#listing-29) and sent the synchronous response in [Listing 30](#listing-30), the Switch should verify the body of the request in [Listing 29](#listing-29). An example verification is to check that the **fspId** element is the same as the **FSPIOP-Source** , as it should be the FSP of the account holder who provisions the information. A scheme could also have restrictions on which currencies are allowed, which means that the Switch should then check that the currency in the **currency** element is allowed. + +After the Switch has verified the request correctly, the information that the account holder identified by **MSISDN** and **123456789** is located in FSP **MobileMoney** should be stored in the Switch's database. + +
    + +#### Switch Sends Successful Callback: Step 3 in End-to-End Flow + +When the Switch has successfully stored the information that the account holder identified by **MSISDN** and **123456789** is located in FSP **MobileMoney**, the Switch must send a callback using the service [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id) to notify the FSP **MobileMoney** about the outcome of the request in [Listing 29](#listing-29). [Listing 31](#listing-31) shows the HTTP request for the callback. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request. In the callback, the **Accept** header should not be used as this is a callback to an earlier requested service. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 29](#listing-29), as detailed in the section on [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id). + +###### Listing 31 + +``` +PUT /participants/MSISDN/123456789 HTTP/1.1 +Content-Length: 50 +Content-Type: +Date: Tue, 14 Nov 2017 08:12:32 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: Switch +{ + "fspId": "MobileMoney", + "currency": "USD" +} +``` + +**Listing 31 -- Callback for the earlier requested provision service** + +[Listing 32](#listing-32) shows the synchronous HTTP response where the FSP **MobileMoney** immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 31](#listing-31). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 32 + +``` +HTTP/1.1 200 OK +Content-Type: +application/vnd.interoperability.participants+json;version=1.0 +``` + +**Listing 32 -- Synchronous response for the callback** + +
    + +### P2P Transfer + +As the intended Payee Henrik Karlsson is now known by the Switch (which is also the ALS) as detailed in [Provision Account Holder](#provision-account-holder), Mats Hagman can now initiate and approve the use case P2P Transfer from his bank to Henrik Karlsson. + +#### Initiate Use Case: Step 4 in End-to-End Flow + +Mats Hagman knows that Henrik Karlsson has phone number **123456789**, so he inputs that number on his device as recipient and 100 USD as amount. The actual communication between Mats' device and his bank **BankNrOne** is out of scope for this API. + +
    + +#### Request Party Information from Switch: Step 5 in End-to-End Flow + +In Step 5 in the end-to-end flow, **BankNrOne** receives the request from Mats Hagman that he would like the phone number 123456789 to receive 100 USD. **BankNrOne** performs an internal search to see if 123456789 exists within the bank, but fails to find the account internally. **BankNrOne** then uses the service [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) in the Switch to see if the Switch knows anything about the account. + +[Listing 33](#listing-33) shows the HTTP request where the FSP **BankNrOne** asks the Switch for Party information regarding the account identified by **MSISDN** and **123456789**. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) for more information about the service. **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). In this request, the FSP **BankNrOne** does not know in which FSP the other account holder resides. Thus, the **FSPIOP-Destination** is not present. Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 33 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:37 GMT +FSPIOP-Source: BankNrOne +``` + +**Listing 33 -- Get Party information for account identified by MSISDN and 123456789 from FSP BankNrOne** + +[Listing 34](#listing-34) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 33](#listing-33). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 34 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 34 -- Synchronous response on the request for Party information** + +#### Request Party Information from FSP: Step 6 in End-to-End Flow + +When the Switch has received the HTTP request in [Listing 33](#listing-33) and sent the synchronous response in [Listing 34](#listing-34), the Switch can proceed with checking its database if it has information regarding in which FSP the account holder identified by **MSISDN** and **123456789** is located. As that information was provisioned as detailed in [Provisoin Account Holder](#provision-account-holder), the Switch knows that the account is in FSP **MobileMoney**. Therefore, the Switch sends the HTTP request in [Listing 35](#listing-35). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [GET /parties/_{Type}_/_{ID}_](#get-parties-type-id) for more information about the service. **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source); in this request the Switch has added the header **FSPIOP-Destination** because the Switch knew to where the request should be routed. Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + + + +###### Listing 35 + +``` +GET /parties/MSISDN/123456789 HTTP/1.1 +Accept: application/vnd.interoperability.parties+json;version=1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Date: Tue, 15 Nov 2017 10:13:38 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +``` + +**Listing 35 -- Get Party information for account identified by MSISDN and 123456789 from Switch** + +[Listing 36](#listing-36) shows the synchronous HTTP response where the FSP **MobileMoney** immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 35](#listing-35). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 36 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 36 -- Synchronous response on request for Party information** + +
    + +#### Lookup Party Information in FSP MobileMoney: Step 7 in End-to-End Flow + +When the FSP **MobileMoney** has received the HTTP request in [Listing 35](#listing-35) and sent the synchronous response in [Listing 36](#listing-36), the FSP **MobileMoney** can proceed with checking its database for more information regarding the account identified by **MSISDN** and **123456789**. As the account exists and is owned by Henrik Karlsson, the FSP **MobileMoney** sends the callback in [Listing 37](#listing-37). The FSP **MobileMoney** does not want to share some details, for example birth date, with the other FSP (**BankNrOne**), so some optional elements are not sent. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, +and [PUT /participants/_{Type}_/_{ID}_](#put-participants-type-id) for more information about the callback. **In** the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 35](#listing-35), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 37 + +```` +PUT /parties/MSISDN/123456789 HTTP/1.1 +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +Content-Length: 347 +Date: Tue, 15 Nov 2017 10:13:39 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + } +} +```` + +**Listing 37 -- Callback to the request for Party information** + +[Listing 38](#listing-38) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 37](#listing-37). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 38 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.parties+json;version=1.0 +``` + +**Listing 38 -- Synchronous response for the Party information callback** + +
    + +#### Send Callback to FSP BankNrOne: Step 8 in End-to-End Flow + +When the Switch has received the callback in [Listing 37](#listing-37) and sent the synchronous response in [Listing 38](#listing-38), it should relay the exact same callback as in [Listing 37](#listing-37) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the exact same response as in [Listing 38](#listing-38). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 37](#listing-37)) and from **BankNrOne** to the Switch (HTTP response in [Listing 38](#listing-38)) instead. + +
    + +#### Send Quote Request from FSP BankNrOne: Step 9 in End-to-End Flow + +After receiving Party information in the callback [PUT /parties/_{Type}_/_{ID}_](#put-parties-type-id), the FSP **BankNrOne** now knows that the account identified by **MSISDN** and **123456789** exists and that it is in the FSP **MobileMoney**. It also knows the name of the account holder. Depending on implementation, the name of the intended Payee (Henrik Karlsson) could be shown to Mats Hagman already in this step before sending the quote. In this example, a quote request is sent before showing the name and any fees. + +The FSP **BankNrOne** sends the HTTP request in [Listing 39](#listing-39) to request the quote. **BankNrOne** does not want to disclose its fees (see [Quoting](#quoting) for more information about quoting), which means that it does not include the **fees** element in the request. The **amountType** element is set to RECEIVE as Mats wants Henrik to receive 100 USD. The **transactionType** is set according to [Mapping of Use Cases to Transaction Types](#mapping-of-use-cases-to-transaction-types). Information about Mats is sent in the **payer** element. **BankNrOne** has also generated two UUIDs for the quote ID (7c23e80c-d078-4077-8263-2c047876fcf6) and the transaction ID (85feac2f-39b2-491b-817e-4a03203d4f14). These IDs must be unique, as described in [Architectural Style](#architectural-style). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [Section 6.5.3.2](#6532-post-quotes) for more information about the service [POST /quotes](#6532-post-quotes). **More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 39 + +```` +POST /quotes HTTP/1.1 +Accept: application/vnd.interoperability.quotes+json;version=1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 975 +Date: Tue, 15 Nov 2017 10:13:40 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amountType": "RECEIVE", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats", + "expiration": "2017-11-15T22:17:28.985-01:00" +} +```` + +**Listing 39 -- Request quote for transaction of 100 USD** + +[Listing 40](#listing-40) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 39](#listing-39). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 40 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Listing 40 -- Synchronous response on quote request** + +#### Send Quote Request from Switch: Step 10 in End-to-End Flow** + +When the Switch has received the quote request in [Listing 39](#listing-39) and sent the synchronous response in [Listing 40](#listing-40), it should relay the same request as in [Listing 39](#listing-39) to the FSP **MobileMoney**, and **MobileMoney** should then respond synchronously with the same response as in [Listing 40](#listing-40). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **MobileMoney** (HTTP request in [Listing 39](#listing-39)) and from **MobileMoney** to the Switch (HTTP response in [Listing 40](#listing-40)) instead. + +
    + +#### Determine fees and FSP commission in FSP MobileMoney: Step 11 in End-to-End Flow + +When the FSP **MobileMoney** has received the HTTP request in [Listing 39](#listing-40) and sent the synchronous response in [Listing 40](#listing-40), the FSP **MobileMoney** should validate the request and then proceed to determine the applicable fees and/or FSP commission for performing the transaction in the quote request. + +In this example, the FSP **MobileMoney** decides to give 1 USD in FSP commission as the FSP **MobileMoney** will receive money, which should later generate more income for the FSP (future possible fees). Since the Payee Henrik Karlsson should receive 100 USD and the FSP commission is determined to 1 USD, the FSP **BankNrOne** only needs to transfer 99 USD to the FSP **MobileMoney** (see [Non Disclosing Receive Amount](#non-disclosing-receive-amount) for the equation). The 99 USD is entered in the transferAmount element in the callback, which is the amount that should later be transferred between the FSPs. + +To send the callback, the FSP **MobileMoney** then needs to create an ILP Packet (see [ILP Packet](#ilp-packet) for more information) that is base64url-encoded, as the **ilpPacket** element in the [PUT /quotes/_{ID}_](#put-quotes-id) callback is defined as a [BinaryString](#binarystring). How to populate the ILP Packet is explained in [Interledger Payment Request](#interledger-payment-request). Henrik's ILP address in the FSP **MobileMoney** has been set to **g.se.mobilemoney.msisdn.123456789** (see [ILP Addressing](#ilp-addressing) for more information about ILP addressing). As the transfer amount is 99 USD and the currency USD's exponent is 2, the amount to be populated in the ILP Packet is 9900 (99 \* 10\^2 = 9900). The remaining element in the ILP Packet is the **data** element. As described in [Interledger Payment Request](#interledger-payment-request), this element should contain the Transaction data model (see [Transaction](#transaction)). With the information from the quote request, the Transaction in this example becomes as shown in [Listing 41](#listing-41). Base64url-encoding the entire ILP Packet with the **amount**, **account**, and the **data** element then results in the **ilpPacket** element in the [PUT /quotes/_{ID}_](#put-quotes-id) callback. + +When the ILP Packet has been created, the fulfilment and the condition can be generated as defined in the algorithm in [Listing 12](#listing-12). Using a generated example secret shown in [Listing 42](#listing-42) (shown as base64url-encoded), the fulfilment becomes as in [Listing 43](#listing-43) (shown as base64url-encoded) after executing the HMAC SHA-256 algorithm on the ILP Packet using the generated secret as key. The FSP **MobileMoney** is assumed to save the fulfilment in the database, so that it does not have to be regenerated later. The condition is then the result of executing the SHA-256 hash algorithm on the fulfilment, which becomes as in [Listing 44](#listing-44) (shown as base64url-encoded). + +The complete callback to the quote request becomes as shown in [Listing 45](#listing-45). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [PUT /quotes/_{ID}_](#put-quotes-id) for more information about the callback. **The** _{ID}_ in the URI should be taken from the quote ID in the quote request, which in the example is 7c23e80c-d078-4077-8263-2c047876fcf6. In the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 39](#listing-39), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 41 + +``` +{ + "transactionId": "85feac2f-39b2-491b-817e-4a03203d4f14", + "quoteId": "7c23e80c-d078-4077-8263-2c047876fcf6", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "MobileMoney" + }, + "personalInfo": { + "complexName": { + "firstName": "Henrik", + "lastName": "Karlsson" + } + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Mats", + "lastName": "Hagman" + } + }, + "partyIdInfo": { + "partyIdType": "IBAN", + "partyIdentifier": "SE4550000000058398257466", + "fspId": "BankNrOne" + } + }, + "amount": { + "amount": "99", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "From Mats" +} +``` + +**Listing 41 -- The Transaction JSON object** + +###### Listing 42 + +``` +JdtBrN2tskq9fuFr6Kg6kdy8RANoZv6BqR9nSk3rUbY +``` + +**Listing 42 -- Generated secret, encoded in base64url** + +###### Listing 43 + +``` +mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s +``` + +**Listing 43 -- Calculated fulfilment from the ILP Packet and secret, encoded in base64url** + +###### Listing 44 + +``` +fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG\_fqGnR7Xs +``` + +**Listing 44 -- Calculated condition from the fulfilment, encoded in base64url** + +###### Listing 45 + +``` +PUT /quotes/7c23e80c-d078-4077-8263-2c047876fcf6 HTTP/1.1 +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +Content-Length: 1802 +Date: Tue, 15 Nov 2017 10:13:41 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "transferAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2017-11-15T14:17:09.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", + "condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 45 -- Quote callback** + +**Note:** The element **ilpPacket** in [Listing 45](#listing-45) should be on a single line in a real implementation; it is shown with line breaks in this example in order to show the entire value. + +[Listing 46](#listing-46) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 45](#listing-45). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 46 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.quotes+json;version=1.0 +``` + +**Listing 46 -- Synchronous response on the quote callback** + +#### Send Callback to FSP BankNrOne: Step 12 in End-to-End Flow + +When the Switch has received the quote callback in [Listing 45](#listing-45) and sent the synchronous response in [Listing 46](#listing-46), it should relay the exact same callback as in [Listing 45](#listing-45) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the exact same response as in [Listing 46](#listing-46). + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 45](#listing-45)) and from **BankNrOne** to the Switch (HTTP response in [Listing 46](#listing-46)) instead. + +
    + +#### Determine fees in FSP BankNrOne: Step 13 in End-to-End Flow + +When the FSP **BankNrOne** has received the quote callback in [Listing 45](#listing-45) and sent the synchronous response in [Listing 46](#listing-46), the FSP **BankNrOne** can proceed with determining the fees for the Payer Mats Hagman. In this example, the fee for the Payer is set to 0 USD, but the FSP commission from the FSP **MobileMoney** is kept as an income for the FSP **BankNrOne**. This means that for the Payee Henrik Karlsson to receive 100 USD, the Payer Mats Hagman must transfer 100 USD from his account. 99 USD will then be transferred between the FSPs **BankNrOne** and **MobileMoney**. + +The FSP **BankNrOne** then notifies Mats Hagman that the transaction to transfer 100 USD to Henrik Karlsson will cost 0 USD in fees. How Mats Hagman is notified is out of scope of this API. + +
    + +#### Payer Accepts Transaction: Step 14 in End-to-End Flow + +In this example, Mats Hagman accepts to perform the transaction. How the acceptance is sent is outside the scope of this API. + +#### Send Transfer Request from FSP BankNrOne: Step 15 in End-to-End Flow + +When Mats Hagman has accepted the transaction, FSP **BankNrOne** reserves the internal transfers needed to perform the transaction. This means that 100 USD will be reserved from Mats Hagman's account, where 1 USD will end up as income for the FSP and 99 USD will be transferred to the prefunded Switch account. After the reservations are successfully performed, the FSP **BankNrOne** sends a [POST /transfers](#post-transfers) to the Switch as in [Listing 47](#listing-47). The same ilpPacket and condition elements are sent as was received in the quote callback and the **amount** is the same as the received **transferAmount**, see [Listing 45](#listing-45). + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [Post Transfers](#post-transfers) for more information about the service [POST /transfers](#post-transfers).**More** information regarding routing of requests using **FSPIOP-Destination** and **FSPIOP-Source** can be found in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). Information about API version negotiation can be found in [Version Negotiation between Client and Server](#version-negotiation-between-client-and-server). + +###### Listing 47 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:17:01.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 47 -- Request to transfer from FSP BankNrOne to FSP MobileMoney** + +**Note:** The element **ilpPacket** in [Listing 47](#listing-47) should be on a single line in a real implementation, it is shown with line breaks in this example for being able to show the entire value. + +[Listing 48](#listing-48) shows the synchronous HTTP response where the Switch immediately (after basic verification of for example required headers) acknowledges the HTTP request in [Listing 47](#listing-47). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 48 + +``` +HTTP/1.1 202 Accepted +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Listing 48 -- Synchronous response on transfer request** + +
    + +#### Send Transfer Request from Switch: Step 16 in End-to-End Flow + +When the Switch has received the transfer request in [Listing 47](#listing-47) and sent the synchronous response in [Listing 48](#listing-48), it should reserve the transfer from **BankNrOne**'s account in the Switch to **MobileMoney**'s account in the Switch. After the reservation is successful, the Switch relays nearly the same request as in [Listing 47](#listing-47) to the FSP **MobileMoney**; expect that the **expiration** element should be decreased as mentioned in [Timeout and Expiry](#timeout-and-expiry). [Listing 49](#listing-49) shows the HTTP request with the **expiration** decreased by 30 seconds compared to [Listing 47](#listing-47). The FSP **MobileMoney** should then respond synchronously with the same response as in [Listing 48](#listing-48). + +###### Listing 49 + +``` +POST /transfers HTTP/1.1 +Accept: application/vnd.interoperability.transfers+json;version=1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 1820 +Date: Tue, 15 Nov 2017 10:14:01 GMT +FSPIOP-Source: BankNrOne +FSPIOP-Destination: MobileMoney +{ + "transferId":"11436b17-c690-4a30-8505-42a2c4eafb9d", + "payerFsp":"BankNrOne", + "payeeFsp": "MobileMoney", + "amount": { + "amount": "99", + "currency": "USD" + }, + "expiration": "2017-11-15T11:16:31.663+01:00", + "ilpPacket": "AQAAAAAAACasIWcuc2UubW9iaWxlbW9uZXkubXNpc2RuLjEyMzQ1Njc4OY- +IEIXsNCiAgICAidHJhbnNhY3Rpb25JZCI6ICI4NWZlY- +WMyZi0zOWIyLTQ5MWItODE3ZS00YTAzMjAzZDRmMTQiLA0KICAgICJxdW90ZUlkIjogIjdjMjNlOD- +BjLWQwNzgtNDA3Ny04MjYzLTJjMDQ3ODc2ZmNmNiIsDQogICAgInBheWVlIjogew0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiTVNJU0ROIiwNCiAgI- +CAgICAgICAgICJwYXJ0eUlkZW50aWZpZXIiOiAiMTIzNDU2Nzg5IiwNCiAgICAgICAgI- +CAgICJmc3BJZCI6ICJNb2JpbGVNb25leSINCiAgICAgICAgfSwNCiAgICAgI- +CAgInBlcnNvbmFsSW5mbyI6IHsNCiAgICAgICAgICAgICJjb21wbGV4TmFtZSI6IHsNCiAgICAgICAgI- +CAgICAgICAiZmlyc3ROYW1lIjogIkhlbnJpayIsDQogICAgICAgICAgICAgICAgImxhc3ROYW1lIjogIk- +thcmxzc29uIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCiAgICAicGF5ZXIi- +OiB7DQogICAgICAgICJwZXJzb25hbEluZm8iOiB7DQogICAgICAgICAgICAiY29tcGxleE5hbWUi- +OiB7DQogICAgICAgICAgICAgICAgImZpcnN0TmFtZSI6ICJNYXRzIiwNCiAgICAgICAgICAgICAgI- +CAibGFzdE5hbWUiOiAiSGFnbWFuIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgI- +CAicGFydHlJZEluZm8iOiB7DQogICAgICAgICAgICAicGFydHlJZFR5cGUiOiAiSUJBTiIsDQogICAgI- +CAgICAgICAicGFydHlJZGVudGlmaWVyI- +jogIlNFNDU1MDAwMDAwMDA1ODM5ODI1NzQ2NiIsDQogICAgICAgICAgICAiZnNwSWQiOiAiQmFua05yT25 +lIg0KICAgICAgICB9DQogICAgfSwNCiAgICAiYW1vdW50Ijogew0KICAgICAgICAiYW1vdW50IjogIjEw- +MCIsDQogICAgICAgICJjdXJyZW5jeSI6ICJVU0QiDQogICAgfSwNCiAgICAidHJhbnNhY3Rpb25UeXBlI- +jogew0KICAgICAgICAic2NlbmFyaW8iOiAiVFJBTlNGRVIiLA0KICAgICAgICAiaW5pdGlhdG9yI- +jogIlBBWUVSIiwNCiAgICAgICAgImluaXRpYXRvclR5cGUiOiAiQ09OU1VNRVIiDQogICAgfSwNCiAgI- +CAibm90ZSI6ICJGcm9tIE1hdHMiDQp9DQo\u003d\u003d", +"condition": "fH9pAYDQbmoZLPbvv3CSW2RfjU4jvM4ApG_fqGnR7Xs" +} +``` + +**Listing 49 -- Request to transfer from FSP BankNrOne to FSP MobileMoney with decreased expiration** + +**Note:** The element **ilpPacket** in [Listing 49](#listing-49) should be on a single line in a real implementation; it is shown with line breaks in this example in order to show the entire value. + +
    + +#### Perform Transfer in FSP MobileMoney: Step 17 in End-to-End Flow + +When the FSP **MobileMoney** has received the transfer request in [Listing 47](#listing-47), it should perform the transfer as detailed in the earlier quote request, this means that 100 USD should be transferred to Henrik Karlsson's account, where 99 USD is from the prefunded Switch account and 1 USD is from an FSP commission account. + +As proof of performing the transaction, the FSP **MobileMoney** then retrieves the stored fulfilment [(Listing 43](#listing-43)) from the database (stored in [Determine Fees and FSP commission in FSP MobileMoney](#determine-fees-and-fsp-commission-in-fsp-mobilemoney-step-11-in-end-to-end-flow)) and enters that in the **fulfilment** element in the callback [PUT /transfers/_{ID}_](#put-transfersid). The **transferState** is set to COMMITTED and the **completedTimestamp** is set to when the transaction was completed; see [Listing 50](#listing-50) for the complete HTTP request. + +At the same time, a notification is sent to the Payee Henrik Karlsson to +say that he has received 100 USD from Mats Hagman. + +How the notification is sent is out of scope for this API. + +See [Table 1](#table-1) for the required HTTP headers in a HTTP request, and [PUT /transfers/_{ID}_](#put-transfersid) for more information about the callback. **The** _{ID}_ in the URI should be taken from the transfer ID in the transfer request, which in the example is 11436b17-c690-4a30-8505-42a2c4eafb9d. In the callback, the **Accept** header should not be sent. The HTTP headers **FSPIOP-Destination** and **FSPIOP-Source** are now inverted compared to the HTTP request in [Listing 47](#listing-47), as detailed in [Call Flow Routing using FSPIOP Destination and FSPIOP Source](#call-flow-routing-using-fspiop-destination-and-fspiop-source). + +###### Listing 50 + +``` +PUT /transfers/11436b17-c690-4a30-8505-42a2c4eafb9d HTTP/1.1 +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +Content-Length: 166 +Date: Tue, 15 Nov 2017 10:14:02 GMT +FSPIOP-Source: MobileMoney +FSPIOP-Destination: BankNrOne +{ + "fulfilment": "mhPUT9ZAwd-BXLfeSd7-YPh46rBWRNBiTCSWjpku90s", + "completedTimestamp": "2017-11-16T04:15:35.513+01:00", + "transferState": "COMMITTED" +} +``` + +**Listing 50 -- Callback for the transfer request** + +[Listing 51](#listing-51) shows the synchronous HTTP response in which the Switch immediately (after basic verification of for example required headers) acknowledges the completion of the process, after receiving the callback in [Listing 50](#listing-50). + +See [Table 3](#table-3) for the required HTTP headers in a HTTP response. + +###### Listing 51 + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.interoperability.transfers+json;version=1.0 +``` + +**Listing 51 -- Synchronous response on the transfers callback** + +
    + +#### Payee Receives Transaction Notification: Step 18 in End-to-End Flow + +The Payee Henrik Karlsson receives the transaction notification, and is thereby informed of the successful transaction. + +
    + +#### Perform Transfer in Switch: Step 19 in End-to-End Flow + +When the Switch has received the transfer callback in [Listing 50](#listing-50) and sent the synchronous response in [Listing 51](#listing-51), it should validate the fulfilment, perform the earlier reserved transfer and relay the exact same callback as in [Listing 50](#listing-50) to the FSP **BankNrOne**, and **BankNrOne** should then respond synchronously with the same response as in [Listing 51](#listing-51). + +The validation of the fulfilment is done by calculating the SHA-256 hash of the fulfilment and ensuring that the hash is equal to the condition from the transfer request. + +The HTTP request and response are not repeated in this section, as they are the same as in the last section, but sent from the Switch to **BankNrOne** (HTTP request in [Listing 50](#listing-51)) and from **BankNrOne** to the Switch (HTTP response in [Listing 51](#listing-51)) instead. + +
    + +#### Perform Transfer in FSP BankNrOne: Step 20 in End-to-End Flow + +When the FSP **BankNrOne** has received the transfer callback in [Listing 50](#listing-50) and sent the synchronous response in [Listing 51](#listing-51), the FSP **BankNrOne** should validate the fulfilment (see [Section 10.4.16](#10416-perform-transfer-in-switch----step-19-in-end-to-end-flow)) and then perform the earlier reserved transfer. + +After the reserved transfer has been performed, the Payer Mats Hagman should be notified of the successful transaction. How the notification is sent is outside the scope of this API. + +#### Payer Receives Transaction Notification: Step 21 in End-to-End Flow + +The Payer Mats Hagman receives the transaction notification and is thereby informed of the successful transaction. + + + + + +1 [http://www.ics.uci.edu/\~fielding/pubs/dissertation/rest\_arch\_style.htm](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) -- Representational State Transfer (REST) + +2 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- A Universally Unique IDentifier (UUID) URN Namespace + +3 [https://tools.ietf.org/html/rfc7230](https://tools.ietf.org/html/rfc7230) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing + +4 [https://tools.ietf.org/html/rfc5246](https://tools.ietf.org/html/rfc5246) -- The Transport Layer Security (TLS) Protocol - Version 1.2 + +5 [https://tools.ietf.org/html/rfc3986](https://tools.ietf.org/html/rfc3986) -- Uniform Resource Identifier (URI): Generic Syntax + +6 [https://tools.ietf.org/html/rfc7230\#section-2.7.3](https://tools.ietf.org/html/rfc7230#section-2.7.3) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing - http and https URI Normalization and Comparison + +7 [https://tools.ietf.org/html/rfc3629](https://tools.ietf.org/html/rfc3629) -- UTF-8, a transformation format of ISO 10646 + +8 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) -- The JavaScript Object Notation (JSON) Data Interchange Format + +9 [https://tools.ietf.org/html/rfc7230\#section-3.2](https://tools.ietf.org/html/rfc7230#section-3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing - Header Fields + +10 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Accept + +11 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing -- Content-Length + +12 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Content-Type + +13 [https://tools.ietf.org/html/rfc7231\#section-7.1.1.2](https://tools.ietf.org/html/rfc7231#section-7.1.1.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Date + +14 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) -- X-Forwarded-For + +15 [https://tools.ietf.org/html/rfc7239](https://tools.ietf.org/html/rfc7239) -- Forwarded HTTP Extension + +16 [https://tools.ietf.org/html/rfc7230\#section-3.3.2](https://tools.ietf.org/html/rfc7230#section-3.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing -- Content-Length + +17 [https://tools.ietf.org/html/rfc7231\#section-3.1.1.5](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content -- Content-Type + +18 [https://tools.ietf.org/html/rfc7231\#section-4](https://tools.ietf.org/html/rfc7231#section-4) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Request Methods + +19 [https://tools.ietf.org/html/rfc7231\#section-6](https://tools.ietf.org/html/rfc7231#section-6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Response Status Codes + +20 [https://tools.ietf.org/html/rfc7231\#section-6.4](https://tools.ietf.org/html/rfc7231#section-6.4) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Redirection 3xx + +21 [https://tools.ietf.org/html/rfc7231\#section-6.6](https://tools.ietf.org/html/rfc7231#section-6.6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Server Error 5xx + +22 [https://tools.ietf.org/html/rfc7231\#section-6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - 406 Not Acceptable + +23 [https://tools.ietf.org/html/rfc7231\#section-5.3.2](https://tools.ietf.org/html/rfc7231#section-5.3.2) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Accept + +24 [https://interledger.org/rfcs/0011-interledger-payment-request/](https://interledger.org/rfcs/0011-interledger-payment-request/) -- Interledger Payment Request (IPR) + +25 [https://interledger.org/](https://interledger.org/) -- Interledger + +26 [https://interledger.org/interledger.pdf](https://interledger.org/interledger.pdf) -- A Protocol for Interledger Payments + +27 [https://interledger.org/rfcs/0001-interledger-architecture/](https://interledger.org/rfcs/0001-interledger-architecture/) -- Interledger Architecture + +28 [https://interledger.org/rfcs/0015-ilp-addresses/](https://interledger.org/rfcs/0015-ilp-addresses/) -- ILP Addresses + +29 [https://www.itu.int/rec/dologin\_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.696-201508-I!!PDF-E&type=items) -- Information technology -- ASN.1 encoding rules: Specification of Octet Encoding Rules (OER) + +30 [https://perldoc.perl.org/perlre.html\#Regular-Expressions](https://perldoc.perl.org/perlre.html#Regular-Expressions) -- perlre - Perl regular expressions + +31 [https://tools.ietf.org/html/rfc7159\#section-7](https://tools.ietf.org/html/rfc7159#section-7) -- The JavaScript Object Notation (JSON) Data Interchange Format - Strings + +32 [http://www.unicode.org/](http://www.unicode.org/) -- The Unicode Consortium + +33 [https://www.iso.org/iso-8601-date-and-time-format.html](https://www.iso.org/iso-8601-date-and-time-format.html) -- Date and time format - ISO 8601 + +34 [https://tools.ietf.org/html/rfc4122](https://tools.ietf.org/html/rfc4122) -- A Universally Unique IDentifier (UUID) URN Namespace + +35 [https://tools.ietf.org/html/rfc4648\#section-5](https://tools.ietf.org/html/rfc4648#section-5) -- The Base16, Base32, and Base64 Data Encodings - Base 64 Encoding with URL and Filename Safe Alphabet + +36 [https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html) -- Currency codes - ISO 4217 + +37 [https://www.itu.int/rec/T-REC-E.164/en](https://www.itu.int/rec/T-REC-E.164/en) -- E.164 : The international public telecommunication numbering plan + +38 [https://tools.ietf.org/html/rfc3696](https://tools.ietf.org/html/rfc3696) -- Application Techniques for Checking and Transformation of Names + +39 [https://tools.ietf.org/html/rfc7231\#section-6.5](https://tools.ietf.org/html/rfc7231#section-6.5) -- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content - Client Error 4xx \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/v1.1/encryption.md b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/encryption.md new file mode 100644 index 000000000..cc20c46b3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/encryption.md @@ -0,0 +1,635 @@ +# Encryption + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +The following conventions are used in this document to identify the specified types of information + +| **Type of Information** | **Convention** | **Example** | +| :--- | :--- | :--- | +| **Elements of the API, such as resources** | Boldface | **/authorization** | +| **Variables** | Italics within curly brackets | _{ID}_ | +| **Glossary terms** | Italics on first occurrence; defined in _Glossary_ | The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP. | +| **Library documents** | Italics | User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead. | + +### Document Version Information + +| **Version** | **Date** | **Change Description** | +| :--- | :--- | :--- | +|**1.1**|2020-05-19|This version contains these changes: 1. ExstensionList elements in Section 4 have been updated based on the issue [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), to fix the data model of the extensionList Object.| +| **1.0** | 2018-03-13 | Initial version | + +
    + +## Introduction + +This document details security methods to be implemented for Open API (Application Programming Interface) for FSP (Financial Service Provider) Interoperability (hereafter cited as "the API") to ensure confidentiality of API messages between an API client and the API +server. + +In information security, _confidentiality_ means that information is not made available or disclosed to unauthorized individuals, entities, or processes (excerpt from ISO27000[The ISO 27000 Directory](http://www.27000.org)). For the API, confidentiality means that some sensitive fields in the payload of an API message cannot be accessed or identified in an unauthorized or undetected manner by the intermediaries involved in the API communication. That is, if some fields of an API message are encrypted by the API client, then only the expected API recipient can decrypt those fields. + +JSON Web Encryption (JWE, defined in RFC 7516[JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516)) must be applied to the API to provide end to end message confidentiality. When an API client sends an HTTP request (such as an API request or callback message) to a counterparty, the API client can determine whether there are sensitive fields in the API message to be protected according to the regulation or local schema. If there is a field to be protected, then the API client uses JWE to encrypt the value of that field. Subsequently, the cipher text of that field will be transmitted to the counterparty. + +To support encryption for multiple fields of an API message, JWE is extended in this document to adapt to the requirements of the API. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./api-definition) + +- [JSON Binding Rules](../json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](./v1.1/signature) + +- [Encryption](#) + +#### General Documents + +- [Glossary](./glossary) + +
    + +## API Encryption Definition + +This section introduces the technology used by API encryption, including: + +- Data exchange format for the encrypted fields of an API message. + +- Mechanism for encrypting and decrypting fields. + +### Encryption Data Model + +The API uses the customized HTTP header parameter **FSPIOP-Encryption** to represent the encrypted fields of an API message; its value is a JSON object serialization. The data model of this parameter is described in [Table 1](#table-1), [Table 2](#table-2) and [Table 3](#table-3). + +**Note**: If **FSPIOP-Encryption** is present in an API message, then it must also be protected by the API signature. That means **FSPIOP-Encryption** must be included in the JWS Protected Header of the signature. + +###### Table 1 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedFields** | 1 | EncryptedFields | Information about the encrypted fields of an API message | +**Table 1 -- Data model of HTTP Header Field FSPIOP-Encryption** + +###### Table 2 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +| **encryptedField** | 1..* | EncryptedField | Information about the encrypted field of an API message | +**Table 2 -- Data model of complex type EncryptedFields** + +###### Table 3 + +| **Name** | **Cardinality** | **Type** | **Description** | +| :--- | :---: | :--- | :--- | +|**fieldName** | 1 | String(1..512) | This element identifies the field to be encrypted in the payload of an API message.
    Because the API payload is a JSON Object serialization string, the field name must be able to identify the exact element path in the JSON Object. A single period ('**.**') character is used to separate the elements in an element path. For example, **payer.personalInfo.dateOfBirth** is a valid value for this element for the API request **POST /quotes**.
    | +| **encryptedKey** | 1 | String(1..512) | Encrypted Content Encryption Key (CEK) value. Its value is encoded by BASE64URL(JWE Encrypted Key).
    If there are multiple fields of the API message to be encrypted, we recommend that the same JWE Encrypted Key be used to simplify the implementation; however, this is a decision to be made by each FSP internally based on their implementation.
    | +|**protectedHeader** | 1 | String(1..1024) | This element identifies the Header Parameters that are applied to JWE to encrypt the specified field. Its value is encoded by BASE64URL(UTF8(JWE Protected Header)).
    For example, if the JWE Protected Header applied to the encryption is ```{"alg":"RSA-OAEP- 256","enc":"A256GCM"}```, then the value is ```eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ```.
    | +| **initializationVector** | 1 | String(1..128) | Initialization Vector value used when encrypting the plaintext. Its value is encoded by BASE64URL(JWE Initialization Vector). | +| **authenticationTag** | 1 | String(1..128) | Authentication Tag value resulting from authenticated encryption of the plaintext with Additional Authenticated Data. Its value is encoded by BASE64URL(JWE Authentication Tag) | +**Table 3 -- Data model of complex type EncryptedField** + +### Encrypt Fields of API Message + +This section describes the encryption process for message fields. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. + +1. Determine the algorithm used to determine the CEK value (this is the algorithm recorded in the **alg** (algorithm) Header Parameter of the resulting JWE). Because the CEK should be encrypted with the public key of the API recipient, in the API the available algorithms to protect the CEK can only be **RSA-OAEP-256**. +2. If there are multiple fields to be encrypted in the API message, then perform Steps 3-15 for each field. +3. Generate a random CEK. The FSP can generate the value using either its own application or using the JWE implementation employed. +4. Encrypt the CEK with the algorithm determined by the JWE header parameter **alg**. +5. Compute the encoded key value BASE64URL(JWE Encrypted Key). +6. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm (if required for the algorithm); otherwise, let the JWE Initialization Vector be the empty octet sequence. +7. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). +8. If a **zip** parameter was included, compress the plaintext using the specified compression algorithm and let *M* be the octet sequence representing the compressed plain text; otherwise, let _M_ be the octet sequence representing the plain text. +9. Create the JSON object or objects containing the desired set of header parameters, which together comprise the JWE Protected Header. Besides the parameter **alg**, the parameter **enc** must be included in the JWE Protected Header. The available values for the parameter **enc** in the API can only be: **A128GC**_M_, **A192GC**_M_, **A256GC**_M_. **A256GC**_M_ is recommended. +10. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). +11. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +12. Encrypt *M* using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +13. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). +14. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). +15. Compute the **encryptedField** element (see Table 3) for the HTTP header parameter **FSPIOP-Encryption**. +16. Compute the value for the HTTP Header parameter **FSPIOP-Encryption** as described in [FSPIOP API](/fspiop) documentation. The value for this **FSPIOP-Encryption** is JSON Object Serialization string. + +**Note**: If JWE is used to encrypt some fields of the payload, then the API client should: + +1. Encrypt the desired fields. + +2. Replace those fields' value with the encoded cipher text in the payload. + +3. Sign the payload. + +### Decrypt Fields of API Message + +If the HTTP Header parameter **FSPIOP-Encryption** (which is also protected by the API signature) is present, then the API message recipient should decrypt the encrypted fields of the API message after the API signature is validated successfully. The message decryption process is the reverse of the encryption process. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. If there are multiple fields being encrypted, then all fields must be decrypted successfully; otherwise it indicates the API message is invalid. + +1. Parse the HTTP Header parameter **FSPIOP-Encryption** to get encrypted fields' information, including field name, JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, and JWE Authentication Tag for each field. If there are multiple fields being encrypted, then perform Steps 2-9 for each encrypted field. +2. Get the cipher text of the encrypted field by parsing the payload with the specified field path. The value of the specified field is already encoded with BASE64URL. +3. Verify that the octet sequence resulting from decoding the encoded JWE Protected Header is a UTF-8-encoded representation of a valid JSON object conforming to JSON Data Interchange Format (defined in RFC 7159[The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)); let the JWE Protected Header be this JSON object. +4. Verify that the parameters in the JWE Protected Header understand and can process all fields that are required to support the JWE specification; for example, the algorithm being used. +5. Determine that the algorithm specified by the **alg** (algorithm) Header Parameter matches the algorithm of the public / private key of the API recipient. +6. Decrypt the JWE Encrypted Key with the private key of the API recipient to get the JWE CEK. +7. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +8. Decrypt the JWE Cipher Text using the CEK, the JWE Initialization Vector, the Additional Authenticated Data value, and the JWE Authentication Tag (which is the Authentication Tag input to the calculation) using the specified content encryption algorithm, returning the decrypted plaintext and validating the JWE Authentication Tag in the manner specified for the algorithm. If the JWE Authentication Tag is incorrect, then reject the input without any decryption. +9. If a **zip** parameter was included, then the API recipient should decompress the decrypted plaintext using the specified compression algorithm. + +## API Encryption/Decryption Examples + +This section uses a typical quote process to explain how the API encryption and decryption are implemented using JWE. As the algorithm of public / private key of the API recipient can only be RSA, the RSA key used for this example is represented in JSON Web Key (JWK, defined in RFC 7517[JSON Web Key(JWK)](https://tools.ietf.org/html/rfc7517)) format below (with line breaks and indentation within values for display purposes only): + +```json +{ + "kty": "RSA", + "n": "oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E- + BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9Le + wND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH- + PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5tw + XTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC- + FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm- + L5StowjzGy-_bq6Gw", + "e": "AQAB", + "d": "kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4- + WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93D + t62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3 + kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOz + lpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K- + VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ", + "p": "1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ- + SWxkbk- + moEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lffNn03IXqWF5M + DFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0", + "q": + "wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBmUDdaD + YVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aXIWxKwd4gvxF + ImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc", + "dp": "ZK- + YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo-uz- + KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgq + rXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE", + "dq": + "Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCjywcMlY + Yg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDBUfCAiJVeESOj + JDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis", + "qi": "VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8- + ZW1FxU7AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E + 3eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY" +} +``` + +### Encryption Example + +The following message text is an example of POST /quotes without encryption sent by Payer FSP to a Payee FSP. + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +``` + +```json +{ + "payee": { + "partyIdInfo": { "partyIdType": "MSISDN", "partyIdentifier": "15295558888", + "fspId": "5678" } }, + "amountType": "RECEIVE", + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", "initiatorType": "CONSUMER" }, + "note": "this is a sample for POST /quotes", + "amount": { "amount": "150","currency": "USD" }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1"}, + { "value": "value2", "key": "key2"}, + { "value": "value3", "key": "key3" } + ] + }, + "geoCode": { "latitude": "57.323889", "longitude": "125.520001" + }, + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "complexName": { "firstName": "Bill", "middleName": "Ben", "LastName": "Lee" + }, "dateOfBirth": "1986-02-14" }, + "partyIdInfo": { "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": "16135551212", + "fspId": "1234" + }, "name": "Bill Lee" + }, "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc" +} +``` + +In this case, the Payer FSP would like to encrypt two fields of the API message: **payer** and **payee.partyIdInfo.partyIdentifier**. + +#### Encrypt the Required Fields + +Because there are two fields to be encrypted, the Payer FSP needs to encrypt the two fields one-by-one. + +##### Encrypt "payer" + +The Payer FSP performs the following steps to encrypt the field **payer** in the **POST /quotes** API message. + +1. Determine the algorithm used to determine the CEK value. In this case, assuming it is **RSA-OAEP-256**. +2. Generate a 256-bit random CEK. In this case, its value is (using JSON Array notation): + +``` +191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167 +``` + +3. Encrypt the CEK with the Payee FSP's public key shown in JSON Web +Key format in [API Encryption/Decryption Examples](#api-encryptiondecryption-examples). In this case, the encrypted value is (using JSON Array notation): + +``` +22 210 45 47 153 95 183 79 84 26 194 42 27 152 50 195 163 18 235 121 140 120 224 129 180 120 21 0 46 196 21 114 251 148 127 75 198 42 87 250 186 98 15 136 249 131 224 73 111 108 159 140 107 156 80 30 133 77 86 26 28 13 66 83 248 229 132 77 203 113 229 24 208 155 81 172 9 164 25 126 206 217 25 206 30 218 38 190 128 196 250 233 34 47 86 91 157 140 87 240 29 119 126 136 168 10 87 246 213 23 104 114 215 134 71 87 46 55 131 174 15 193 194 90 194 208 212 15 24 33 143 38 253 125 121 175 220 202 106 95 127 129 192 2 72 137 14 40 147 207 166 239 161 248 159 203 52 223 103 129 54 83 85 199 211 228 56 82 83 135 166 103 42 76 191 146 80 40 192 123 42 18 31 113 25 198 24 58 87 149 47 182 144 86 182 137 253 103 214 34 192 76 254 64 14 114 97 194 28 60 75 164 131 170 210 231 168 205 181 78 79 136 82 115 218 174 5 48 158 162 230 229 164 85 26 135 15 164 206 36 182 131 115 224 207 12 178 234 145 6 181 140 243 41 8 151 +``` + +4. Compute the encoded key value BASE64URL(JWE Encrypted Key). In this case, its value is: + +``` +FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g-BJb2yfjGucUB6 FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE-ukiL1ZbnYxX8B13foioClf21Rdoct eGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU 4emZypMv5JQKMB7KhIfcRnGGDpXlS-2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPa rgUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw +``` + +5. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm. In this case, its value is (using JSON Array notation): + +``` +101 98 192 15 167 157 93 152 54 145 173 236 83 4 6 243 +``` + +6. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). In this case, its value is: + +``` +ZWLAD6edXZg2ka3sUwQG8w +``` + +7. Get the plaintext of the field **payer** of the API message as the payload to be encrypted. In this case, its value is: + +```json +{ + "personalInfo": { + "dateOfBirth": "1986-02-14", "complexName": { + "middleName": "Ben", "lastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": "16135551212" + } +} +``` + +8. Create the JSON object or objects containing the desired set of header parameters, which together comprise the JWE Protected Header. In this case, its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +9. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). In this case, its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +10. Let the Additional Authenticated Data encryption parameter be ASCII(Base64URL(JWE Protected Header)). +11. Encrypt the plain text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +12. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). In this case its value is: + +``` +BfXbxoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs_Nvk ZkE4WlqGNlQ_nBS1xYknxjh7hkPVb-V-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4- 4ejXXv80cbknRJtDl_mmjaU_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8h fPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB1OeZRq06ZBEfKZzAAJ0u3KZqoO BAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6YugwFotZbg +``` + +13. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +9GaZEDZD9wmzqVGCI-FDgQ +``` + +##### Encrypt payee.partyIdInfo.partyIdentifier + +1. Determine the algorithm used to determine the CEK value. In this case, assuming it is **RSA-OAEP-256**. +2. Generate a 256-bit random CEK. In this case, the same CEK defined in [Encryption Data Model](#encryption-data-model) is used., Its value is (using JSON Array notation): + +``` +191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167 +``` + +3. Encrypt the CEK with the Payee FSP's public key represented in JSON Web Key format in [API Encryption/Decryption Examples](#api-encryptiondecryption-examples). In this case, its value is (using JSON Array notation): + +``` +149 174 138 153 221 70 241 229 93 27 56 185 185 210 242 238 81 187 207 88 40 43 24 7 245 121 94 73 151 150 249 19 15 158 11 97 80 99 194 60 143 138 168 211 202 210 52 19 128 211 156 179 101 248 95 163 23 166 217 222 14 12 163 206 242 182 170 211 119 22 84 107 3 97 153 207 240 211 82 113 100 254 39 62 224 183 250 176 156 63 198 73 245 187 239 16 136 127 120 130 146 236 29 47 255 116 223 240 39 224 94 165 102 120 242 9 182 84 138 109 205 55 242 20 186 91 140 49 198 244 250 58 123 3 63 22 51 59 5 183 112 17 160 238 34 217 11 109 79 246 174 221 138 118 82 21 15 239 72 185 77 20 178 20 192 89 45 68 140 190 251 233 82 123 33 49 191 135 49 21 25 42 253 171 211 151 7 238 142 206 201 140 206 6 129 23 173 56 153 159 31 39 52 119 102 147 197 213 230 97 113 71 168 184 6 57 183 109 173 233 206 110 112 202 179 74 56 153 184 122 114 234 151 28 15 131 79 192 80 145 130 170 188 82 92 61 121 90 63 148 37 110 20 132 49 131 +``` + +**Note**: Although the same CEK is used for the two fields **payer** and **payee.partyIdInfo.partyIdentifier**, the encrypted CEK values may be different from each other because of the use of a random number when encrypting the CEK by JWE implementations (for example, jose4j, nimbus-jose-jwt, and so on). This depends on how the JWE is implemented in each FSP system. +4. Compute the encoded key value BASE64URL(JWE Encrypted Key). In this case, its value is: + +``` +la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI-KqNPK0jQTgNOcs2X4X6M XptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u--niH94gpLsHS__dN_wJ-BepW Z48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1Ej L776VJ7ITG_hzEVGSr9q9OXB-6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqz SjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw +``` + +5. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm. In this case, its value is (using JSON Array notation): + +``` +86 250 136 87 147 231 201 138 65 75 164 215 147 100 136 195 +``` + +6. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector). In this case, its value is: + +``` +VvqIV5PnyYpBS6TXk2SIww +``` + +7. Get the plain text of the field **payee.partyIdInfo.partyIdentifier** of the API message as the payload to be encrypted. In this case, its value is + +``` +15295558888 +``` + +8. Create the JSON object or objects containing the desired set of Header Parameters, which together comprise the JWE Protected Header. In this case, its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +9. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). In this case, its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +10. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). +11. Encrypt the plain text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to create the JWE Cipher text value and the JWE Authentication Tag (which is the Authentication Tag output from the encryption operation). +12. Compute the encoded cipher text value BASE64URL(JWE Cipher Text). In this case its value is: + +``` +WBQN5nLDGK26EiM +``` + +13. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +6jQVo7kmZq3jMNXfavxoXQ +``` + +#### Producing FSPIOP-Encryption + +Using the given data model of the header **FSPIOP-Encryption**, get the header's value as shown below (line break and indentation are only for display purpose): + +```json +{ + "encryptedFields": + [ + { + "initializationVector":"ZWLAD6edXZg2ka3sUwQG8w", + "fieldName":"payer", + "encryptedKey":"FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g- + BJb2yfjGucUB6FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE- + ukiL1ZbnYxX8B13foioClf21RdocteGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcAC- + SIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU4emZypMv5JQKMB7KhIfcRnGGDpXlS- + 2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPargUwnqLm5aRVGo- + cPpM4ktoNz4M8MsuqRBrWM8ykIlw", + "authenticationTag":"9GaZEDZD9wmzqVGCI-FDgQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + }, + { + "initializationVector":"VvqIV5PnyYpBS6TXk2SIww", + "fieldName":"payee.partyIdInfo.partyIdentifier", + "encryptedKey":"la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI- + KqNPK0jQTgNOcs2X4X6MXptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u-- + niH94gpLsHS__dN_wJ-BepWZ48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEa- + DuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1EjL776VJ7ITG_hzEVGSr9q9OXB- + 6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqzS- + jiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw", + "authenticationTag":"6jQVo7kmZq3jMNXfavxoXQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + } + ] +} +``` + +#### Re-produce API message with encryption + +Using the cipher text of the encrypted field to replace the plain text of the corresponding field of the API message (the string with, **light grey** background in the message text below), add parameter **FSPIOP-Encryption** (the string with **light grey** background in the message text below) into the HTTP header of the API message. + +**Note**: The **FSPIOP-Encryption** parameter should be included in the JWS Protected Header for the signature of the API message, and the HTTP body of the API message below should be the JWS Payload for the signature. The signature process is out-of- scope for this document. + +```json +POST /quotes HTTP/1.1 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +FSPIOP-Destination:5678 +Content-Length:1068 +FSPIOP-Encryption: {"encryptedFields":{ + "initializationVector":"ZWLAD6edXZg2ka3sUwQG8w", + "fieldName":"payer", + "encryptedKey":"FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX- +rpiD4j5g-BJb2yfjGucUB6FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE- +ukiL1ZbnYxX8B13foioClf21RdocteGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu- +h-J_LNN9ngTZTVcfT5DhSU4emZypMv5JQKMB7KhIfcRnGGDpXlS- +2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk- +IUnPargUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw", + "authenticationTag":"9GaZEDZD9wmzqVGCI-FDgQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + }, { + "initializationVector":"VvqIV5PnyYpBS6TXk2SIww", + "fieldName":"payee.partyIdInfo.partyIdentifier", + "encryptedKey":"la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI- +KqNPK0jQTgNOcs2X4X6MXptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u-- +niH94gpLsHS__dN_wJ- +BepWZ48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD- +9IuU0UshTAWS1EjL776VJ7ITG_hzEVGSr9q9OXB- +6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqzSjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw", + "authenticationTag":"6jQVo7kmZq3jMNXfavxoXQ", + "protectedHeader":"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0" + } + ] +} +{"amount":{"amount":"150","currency":"USD"},"transactionType":{"scenario":"TRANSFER","initiator":"PAYER","subScenario":"P2P Transfer across MM systems","initiatorType":"CONSUMER"},"transactionId":"36629a51-393a-4e3c-b347-c2cb57e1e1fc","quoteId":"59e331fa-345f-4554-aac8-fcd8833f7d50","payer":"BfXbcoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs_NvkZkE4WlqGNlQ_nBS1xYknxjh7hkPVb-B-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4-4ejXXv80cbknRJtDl_mmjaU_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8hfPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB10eZRq06ZBEfKZzAAJ0u3KZqoOBAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6ugwFotZbg","expiration":"2017-05-24T08:40:00.000-04:00","payee":{"partyIdInfo":{"fspId":"5678","partyIdType":"MSISDN","partyIdentifier":"WBQN5nLDGK26EiM"}},"fees":{"amount":"1.5","currency":"USD"},"extensionList":{"extension":[{"value":"value1","key":"key1"},{"value":"value2","key":"key2"},{"value":"value3","key":"key3"}]},"note":"this is a sample for POST/quotes","geoCode":{"longitude":"125.520001","latitude":"57.323889"},"amountType":"RECEIVE"} +``` + +### Decryption Example + +In this example, the Payee FSP receives the POST /quotes API message from Payer FSP. The message is described in [Encryption Data Model](#encryption-data-model). If the Payee FSP detects that the HTTP header parameter **FSPIOP-Encryption** is present in the message, then the Payee FSP knows that some fields were encrypted by the Payer FSP. The Payee FSP then performs the following steps to decrypt the encrypted fields.] + +#### Parse FSPIOP-Encryption + +The Payee FSP verifies that the value of **FSPIOP-Encryption** is a UTF-8-encoded representation of a valid JSON object conforming to RFC 7159. The FSP then parses the HTTP Header parameter **FSPIOP-Encryption** to get encrypted fields information, including field name, JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, and JWE Authentication Tag for each field. + +#### Decrypt the Encrypted Fields + +In this case, the Payee FSP gets two fields **payer** and **payee.partyIdInfo.partyIdentifier** from the HTTP header **FSPIOP- Encryption**. Then the Payee FSP decrypts the two fields one-by-one. + +##### Decrypt payer + +The Payer FSP performs the following steps to decrypt the field **payer** in the **POST /quotes** API message. + +1. Get the encoded BASE64RUL(JWE Protected Header) from the parsed **FSPIOP-Encryption** for the field **payer**. In this case its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +2. Decode the encoded JWE Protected Header. In this case its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM" +``` + +3. Check that the decoded value of JWE Protected Header is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format (RFC 7159), and that the parameters in the JWE Protected Header can process all fields that are required to support the JWE specification. +4. Get the encoded BASE64URL(JWE Encrypted Key). In this case its value is: + +``` +FtItL5lft09UGsIqG5gyw6MS63mMeOCBtHgVAC7EFXL7lH9LxipX-rpiD4j5g-BJb2yfjGucUB6 FTVYaHA1CU_jlhE3LceUY0JtRrAmkGX7O2RnOHtomvoDE-ukiL1ZbnYxX8B13foioClf21Rdoct eGR1cuN4OuD8HCWsLQ1A8YIY8m_X15r9zKal9_gcACSIkOKJPPpu-h-J_LNN9ngTZTVcfT5DhSU 4emZypMv5JQKMB7KhIfcRnGGDpXlS-2kFa2if1n1iLATP5ADnJhwhw8S6SDqtLnqM21Tk-IUnPa rgUwnqLm5aRVGocPpM4ktoNz4M8MsuqRBrWM8ykIlw] +``` + +5. Decode the encoded JWE Encrypted Key. In this case its value is as follows (using JSON Array notation): + +``` +[22 210 45 47 153 95 183 79 84 26 194 42 27 152 50 195 163 18 235 121 140 120 224 129 180 120 21 0 46 196 21 114 251 148 127 75 198 42 87 250 186 98 15 136 249 131 224 73 111 108 159 140 107 156 80 30 133 77 86 26 28 13 66 83 248 229 132 77 203 113 229 24 208 155 81 172 9 164 25 126 206 217 25 206 30 218 38 190 128 196 250 233 34 47 86 91 157 140 87 240 29 119 126 136 168 10 87 246 213 23 104 114 215 134 71 87 46 55 131 174 15 193 194 90 194 208 212 15 24 33 143 38 253 125 121 175 220 202 106 95 127 129 192 2 72 137 14 40 147 207 166 239 161 248 159 203 52 223 103 129 54 83 85 199 211 228 56 82 83 135 166 103 42 76 191 146 80 40 192 123 42 18 31 113 25 198 24 58 87 149 47 182 144 86 182 137 253 103 214 34 192 76 254 64 14 114 97 194 28 60 75 164 131 170 210 231 168 205 181 78 79 136 82 115 218 174 5 48 158 162 230 229 164 85 26 135 15 164 206 36 182 131 115 224 207 12 178 234 145 6 181 140 243 41 8 151] +``` + +6. Decrypt the JWE Encrypted Key using the specified algorithm **RSA-OAEP-256** with the Payee FSP's private key to get the CEK. In this case the decrypted CEK is (using JSON Array notat ion): + +``` +[191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167] +``` + +7. Get the encoded BASE64URL(JWE Initialization Vector). Its value is: + +``` +ZWLAD6edXZg2ka3sUwQG8w +``` + +8. Decode the encoded JWE Initialization Vector. In this case, its value is (using JSON Array notation): + +``` +[101 98 192 15 167 157 93 152 54 145 173 236 83 4 6 243] +``` + +9. Get the value of the field **payer** from the API message as the encoded BASE64URL(JWE Cipher Text) to be decrypted. In this case, its value is + +``` +BfXbxoyXcWCzL3DwG7B2P5UswlP8MPXerIkKbRR3vDLuN7lfa33puj7VICFeqG1fAlxrXgs\_Nvk ZkE4WlqGNlQ\_nBS1xYknxjh7hkPVb-V-Z9ZEvLdcaHlGJrH5oEvR7RIB8TOHgVHP1brlrEptB4- 4ejXXv80cbknRJtDl\_mmjaU\_Na4irGrWhA3ZhXZM1aM7wtquJLIk-1ZNLadGnGPygl21sEITF8h fPzbk7Djs45nBc5izWcoskCCNvLDU6PqOEhWe3y6GdsDiqFPB1OeZRq06ZBEfKZzAAJ0u3KZqoO BAEVHVvt41D3ejVimTVQJs1dVL2HacvuJyVW6YugwFotZbg +``` + +10. Get the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +9GaZEDZD9wmzqVGCI-FDgQ +``` + +11. Decrypt the cipher text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to decrypt the JWE Cipher text. In this case, the plain text is + +```json +{ + "personalInfo": { + "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", "lastName": "Lee", + "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { + "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", "partyIdentifier": + "16135551212" + } +} +``` + +12. Verify that the plaintext is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159, and the content matches the data mode definition for the **payer**. + +##### Decrypt payee.partyIdInfo.partyIdentifier + +The Payer FSP performs the following steps to decrypt the field **payee.partyIdInfo.partyIdentifier** in the **POST /quotes** API message. + +1. Get the encoded BASE64RUL(JWE Protected Header) from the parsed **FSPIOP-Encryption** for the field **payee.partyIdInfo.partyIdentifier**. In this case its value is: + +``` +eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0 +``` + +2. Decode the encoded JWE Protected Header. In this case its value is: + +```json +{"alg":"RSA-OAEP-256","enc":"A256GCM"} +``` + +3. Verify that the decoded value of JWE Protected Header is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159, and that the parameters in the JWE Protected Header understand and can process all fields that are required to support the JWE specification. +4. Get the encoded BASE64URL(JWE Encrypted Key). In this case its value is: + +``` +la6Kmd1G8eVdGzi5udLy7lG7z1goKxgH9XleSZeW-RMPngthUGPCPI-KqNPK0jQTgNOcs2X4X6M XptneDgyjzvK2qtN3FlRrA2GZz_DTUnFk_ic-4Lf6sJw_xkn1u--niH94gpLsHS__dN_wJ-BepW Z48gm2VIptzTfyFLpbjDHG9Po6ewM_FjM7BbdwEaDuItkLbU_2rt2KdlIVD-9IuU0UshTAWS1Ej L776VJ7ITG_hzEVGSr9q9OXB-6OzsmMzgaBF604mZ8fJzR3ZpPF1eZhcUeouAY5t22t6c5ucMqz SjiZuHpy6pccD4NPwFCRgqq8Ulw9eVo_lCVuFIQxgw +``` + +5. Decode the encoded JWE Encrypted Key. In this case its value is (using JSON Array notation): + +``` +[149 174 138 153 221 70 241 229 93 27 56 185 185 210 242 238 81 187 207 88 40 43 24 7 245 121 94 73 151 150 249 19 15 158 11 97 80 99 194 60 143 138 168 211 202 210 52 19 128 211 156 179 101 248 95 163 23 166 217 222 14 12 163 206 242 182 170 211 119 22 84 107 3 97 153 207 240 211 82 113 100 254 39 62 224 183 250 176 156 63 198 73 245 187 239 167 136 127 120 130 146 236 29 47 255 116 223 240 39 224 94 165 102 120 242 9 182 84 138 109 205 55 242 20 186 91 140 49 198 244 250 58 123 3 63 22 51 59 5 183 112 17 160 238 34 217 11 109 79 246 174 221 138 118 82 21 15 239 72 185 77 20 178 20 192 89 45 68 140 190 251 233 82 123 33 49 191 135 49 21 25 42 253 171 211 151 7 238 142 206 201 140 206 6 129 23 173 56 153 159 31 39 52 119 102 147 197 213 230 97 113 71 168 184 6 57 183 109 173 233 206 110 112 202 179 74 56 153 184 122 114 234 151 28 15 131 79 192 80 145 130 170 188 82 92 61 121 90 63 148 37 110 20 132 49 131] +``` + +6. Decrypt the JWE Encrypted Key using the specified algorithm **RSA-OAEP-256** with the Payee FSP's private key to get the CEK. In this case the decrypted CEK is (using JSON Array notation): + +``` +[191 100 167 60 2 248 21 136 172 39 145 120 102 7 73 31 166 66 114 199 219 157 104 162 7 253 10 105 33 136 57 167] +``` + +7. Get the encoded BASE64URL(JWE Initialization Vector). Its value is: + +``` +VvqIV5PnyYpBS6TXk2SIww +``` + +8. Decode the encoded JWE Initialization Vector. In this case, its value is (using JSON Array notation): + +``` +[86 250 136 87 147 231 201 138 65 75 164 215 147 100 136 195] +``` + +9. Get the value of the field **payee.partyIdInfo.partyIdentifier** from the API message as the encoded BASE64URL(JWE Cipher Text) to be decrypted. In this case, its value is: + +``` +WBQN5nLDGK26EiM +``` + +10. Get the encoded Authentication Tag value BASE64URL(JWE Authentication Tag). In this case its value is: + +``` +6jQVo7kmZq3jMNXfavxoXQ +``` + +11. Decrypt the cipher text using the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value using the specified content encryption algorithm to decrypt the JWE Cipher text. In this case, the plain text is + +``` +15295558888 +``` + +12. Verify that the plain text is a valid **partyIdentifier** value. + +
    + +## Table of Tables +- [Table 1 -- Data model of HTTP Header Field FSPIOP-Encryption](#table-1) +- [Table 2 -- Data model of complex type EncryptedFields](#table-2) +- [Table 3 -- Data model of complex type EncryptedField](#table-3) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/fspiop/v1.1/signature.md b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/signature.md new file mode 100644 index 000000000..42f8f32ed --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/fspiop/v1.1/signature.md @@ -0,0 +1,423 @@ +# Signature + +## Preface + +This section contains information about how to use this document. + +### Conventions Used in This Document + +This document uses the notational conventions for BASE64URL(OCTETS), UTF8(STRING), ASCII(STRING), and || defined in RFC 7515[1](https://tools.ietf.org/html/rfc7515#section-1.1). + +The following conventions are used in this document to identify the specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics within curly brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature_ and _API Encryption_ should be used instead.| + +### Document Version Information + +|Version|Date|Change Description| +|---|---|---| +|**1.1**|2020-05-19|This version contains the below changes: 1. Sections 3.1, 3.2 and 3.3 have been updated based on ”Solution Proposal 12 - Clarify usage of FSPIOP-Destination”. 2. ExtensionList elements in Section 4 have been updated based on the issue [Interpretation of the Data Model for the ExtensionList element](https://github.com/mojaloop/mojaloop-specification/issues/51), to fix the data model of the extensionList Object.| +|**1.0**|2018-03-13|Initial version| + +
    + +## Introduction + +This document details the security methods to be implemented for Open API for FSP Interoperability (hereafter cited as the API) to ensure _integrity_ and _non-repudiation_ between the API client and the API server. + +In information security, _data integrity_ means maintaining and assuring the accuracy and completeness of data over its entire life-cycle. For the API, data integrity means that an API message cannot be modified in an unauthorized or undetected manner by parties involved in the API communication. + +In legal terms, _non-repudiation_ means that a person intends to fulfill their obligations to a contract. It also means that one party in a transaction cannot deny having received the transaction, nor can the other party deny having sent the transaction. For the API, non-repudiation means that an API client cannot deny having sent an API message to a counterparty. JSON Web Signature (JWS), as defined in RFC 7515[2](https://tools.ietf.org/html/rfc7515), must be applied to the API to provide message integrity and non-repudiation for either component fields of an API payload or the full API payload. Whenever an API client sends an API message to a counterparty, the API client should sign the message using its private key. After the counterparty receives the API message, the counterparty must validate the signature with the API client’s public key. Only the HTTP request message of an API message need to be signed, any HTTP response message of the APIs SHALL NOT be signed. + +**Note:** The corresponding public key should either be shared in advance with the counterparty or retrieved by the counterparty (for example, the local scheme Certificate Authority). + +Because intermediary fees are not supported in the current version of the API, intermediaries involved in API message-transit may not modify the API message payload. Thus, the signature at full payload level is used to protect the integrity of the full payload of an API message from end-to-end. Regardless of how many intermediaries there are in transit, the original payload cannot be modified by the intermediaries. The final recipient of the API message must validate the signature generated by the original API client based on the message payload received. + +**Note:** Whether the signature needs to be validated by the intermediaries in transit is determined by the internal implementation of each intermediary or the local schema. + +**Note:** In a future version of the API, intermediary fees may be supported; at that time, signature-at-field-level may also be supported. However, both features are out-of-scope for the current version of the API. + +
    + +### Open API for FSP Interoperability Specification + +The Open API for FSP Interoperability Specification includes the following documents. + +#### Logical Documents + +- [Logical Data Model](./logical-data-model) + +- [Generic Transaction Patterns](./generic-transaction-patterns) + +- [Use Cases](./use-cases) + +#### Asynchronous REST Binding Documents + +- [API Definition](./definitions) + +- [JSON Binding Rules](./json-binding-rules) + +- [Scheme Rules](./scheme-rules) + +#### Data Integrity, Confidentiality, and Non-Repudiation + +- [PKI Best Practices](./pki-best-practices) + +- [Signature](#) + +- [Encryption](./v1.1/encryption) + +#### General Documents + +- [Glossary](../glossary) + +
    + +## API Signature Definition + +This section introduces the technology used by the API signature, including the data exchange format for the signature of an API message and the mechanism used to generate and verify a signature. + + +### Signature Data Model + +The API uses a customized HTTP header parameter **FSPIOP-Signature** to represent the signature that is produced by the initiating API client for the API message. The data model for this parameter is described in [Table 1](#table-1). + +**Note:** Currently the API does not support intermediaries in an API message; only the message-initiator can sign a message. If this is required in the future, there will be new customized HTTP header parameter, but this is out-of-scope for the current version of the API. + +###### Table 1 + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| protectedHeader | 1 | String(1..32768) |
    This element indicates the HTTP header parameters that are protected by the signature. Its value must be BASE64URL(UTF8(JWS Protected Header)).

    According to JWS specification, the **alg** header parameter must be present to identify the cryptographic algorithm used to secure the JWS.

    A customized parameter **FSPIOP-URI** that represents the URI path and query parameters of HTTP request message of the APIs must be present.

    A customized parameter **FSPIOP-HTTP-Method** that holds the HTTP method used in the HTTP message must be present.

    A customized parameter **FSPIOP-Source** that represents the system which sent the API request must be present.

    The customized HTTP header parameter **FSPIOP-Destination** is mandatory in protectedHeader if the destination FSP is known by the message-initiator. Otherwise this header must not be protected as it can be changed by intermediate systems. See API Definition for more information regarding which services that the header FSPIOP-Destination is optional for.
    | +| signature | 1 | String(1..512) | This element indicates the signature. Its value is part of JWS serialization; that is, BASE64URL(JWS Signature). | +**Table 1 – Data model of HTTP header field FSPIOP-Signature** + +### Generating a Signature + +To create the signature for an API message, the following steps are performed. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. + +1. Create the content to be used as the JWS Payload. Because the signature is currently at full payload level, the full HTTP body of the API message is the JWS Payload. + +2. Compute the encoded payload value BASE64URL(JWS Payload). + +3. Create the JSON object or objects containing the desired JWS Protected Header. + + A. The **alg** JWS Protected Header parameter must be present. In the API, the available algorithms for the signature are **RS256, RS384, RS512**. A key of size 2048 bits or larger must be used with these algorithms. + + B. Other parameters registered in the IANA JSON _Web Signature and Encryption Header Parameters_[3](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) are optional. + + C. The customized parameter **FSPIOP-URI** must be included in JWS Protected Header to protect the URI path and query parameters of the APIs. + + D. The customized parameter **FSPIOP-HTTP-Method** must be included in JWS Protected Header to protect the HTTP request operation method. + + E. The parameter **FSPIOP-Source** must be present, and its value comes from the corresponding HTTP header parameter **FSPIOP-Source**. + + F. The parameter **FSPIOP-Destination** must be present if the destination FSP is known by the message-initiator, and its value must then be the same as the HTTP header parameter **FSPIOP-Destination**. + + G. Other HTTP Header parameters of the APIs are recommended to be included in JWS Protected Header, but they are optional in this JWS Protected Header. + +4. Compute the encoded header value BASE64URL(UTF8(JWS Protected Header)). + +5. Compute the JWS Signature according to the JWS specification using the output of Step 2 and Step 4. + +6. Compute the encoded signature value BASE64URL(JWS Signature). + +7. Compute the value for the HTTP header parameter **FSPIOP-Signature** as described in the [Signature Data Model](#signature-data-model) section. The value for this **FSPIOP-Signature** is a JSON Object Serialization string. + +**Note:** If JSON Web Encryption (JWE) is used to encrypt some fields of the payload (for more information, see Encryption), then the API client should first encrypt the desired fields, then replace the plain text of those fields with the encoded cipher text in the payload, and then finally sign the payload. + +### Validating Signature + +When validating the signature of an API request, the following steps are performed. The order of the steps is not significant in cases where there are no dependencies between the inputs and outputs of the steps. If any of the listed steps fails, then the signature cannot be validated. + +1. Parse the HTTP header parameter **FSPIOP-Signature** to get the components **protectedHeader** and **signature**. + +2. Use BASE64URL to decode the encoded representation of the JWS Protected Header. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format, defined in RFC 7159[4](https://tools.ietf.org/html/rfc7159). + +3. Verify the parameters in the JWS Protected Header. + + a) The parameter **alg** must be present and its value must be one of **RS256, RS384, RS512**. + + b) Other parameters registered in the IANA JSON _Web Signature and Encryption Header Parameters_ are optional. + + c) The parameter **FSPIOP-URI** must be present and Its value must be the same as the input URL value of the request. + + d) The parameter **FSPIOP-HTTP-Method** must be present and its value must be same as the operation method of the request. + + e) The parameter **FSPIOP-Source** must be present, and its value must be the same as the corresponding HTTP header parameter **FSPIOP-Source**. + + f) If the parameter **FSPIOP-Destination** is present in the JWS Protected Header, then its value must be same as the corresponding HTTP header parameter **FSPIOP-Destination**. + + g) If there are other HTTP header parameters present in JWS Protected Header, then their values must be validated with the corresponding HTTP header values. + +4. Compute the encoded payload value BASE64URL(JWS Payload). Because the current signature is at full payload level, the full HTTP body of the API message is the JWS Payload. + +5. Validate the JWS Signature against the JWS Signing Input ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)) in the manner defined for the algorithm being used, which must be accurately represented by the value of the **alg** (algorithm) Header Parameter. + +6. Record whether the validation succeeded. + +
    + +## API Signature Examples + +This section uses a typical quote process to explain how the API signature is implemented using JWS. The FSPs in the API can verify that their internal implementation for API signature is correct using the following case. + +The case in this section uses RS256 as the signature algorithm. The RSA key used for the signature example is represented in JSON Web Key (JWK), defined in RFC 7517[5](https://tools.ietf.org/html/rfc7517), format below (with line breaks and indentation within values for display purposes only): + +```json +{ + "kty": "RSA", + "n": "ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", + "e": "AQAB", + "d": "Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ", + "p": "4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdiYrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPGBY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc", + "q": "uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxaewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc", + "dp": "BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3QCLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0", + "dq": "h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-kyNlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU", + "qi": "IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2oy26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLUW0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U" +} +``` + +### Generating a Sample Signature + +The following message text is an example of `POST /quotes` without a signature sent by Payer FSP to a counterparty (line breaks and indentation within values for display purposes only). + +```json +POST /quotes HTTP/1.1 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Source:1234 +FSPIOP-Destination:5678 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +{ + "amount": { "amount": "150", "currency": "USD" },"transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER","subScenario": "P2P Transfer across MM systems","initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc","quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50","expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { + "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer","partyIdentifier": "16135551212" } + }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } + }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { + "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +#### Computing Signature Input + +According to JWS specification, the signature input is BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload). + +Assuming the HTTP header parameters **Date** and **FSPIOP-Destination** are protected by the signature, and the algorithm RS256 is used to sign the message, the JWS Protected Header in this case is as follows (line breaks and indentation within values for display purposes only): + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +Encoding this JWS Protected Header as BASE64URL(UTF8(JWS Protected Header)) gives this value: + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +In this case, JWS Payload is the HTTP Body described in [Generating A Signature](#generating-a-signature) section. Encoding this JWS Payload as BASE64URL(JWS Payload) gives this value: + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +#### Producing Signature + +Use the given RSA Private Key, the JWS Protected Header and the JWS Payload to generate the signature, then encoding the signature as BASE64URL(JWS Signature) produces this value: + +``` +dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEB-uve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGw-QkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg +``` + +#### Re-produce API Request with Signature + +As described in the [Signature Data Model](#signature-data-model) section, the API signature is represented by a customized HTTP header parameter **FSPIOP-Signature**; thus the API request with the signature in this case is the following message text (line breaks and indentation within values for display purposes only). + +```json +POST /quotes HTTP/1.1 +FSPIOP-Destination:5678 +Accept:application/vnd.interoperability.quotes+json;version=1.0 +Content-Length:975 +Date:Tue, 23 May 2017 21:12:31 GMT +FSPIOP-Source:1234 +Content-Type:application/vnd.interoperability.quotes+json;version=1.0 +FSPIOP-Signature: {"signature": "dz2ntyS0_rDyA0pLeWluG--tBcYYrlvG99ffkXcEBuve5Qzvzyn0ZUi82J7h17RsdfHPuTnbEGvCeU9Y4Bg0nIZHGL4icswaaO09T5hPPYKBTzVQeHkokLmL4dXpHdr1ggSEpu3WEU3nfgOFGGAdOq355i1iGuDbhqm_lSfVHaqdVCEhkJ2Y_r2glO2QpdZrcbvsBV39derj_PlfISBBGjdh0dIPxnFIVcZuPHiq9Ha2MslrBHfqwFfNeU_xhErBd2PywkDQJbKOlfqdkmFC9bS8Ofx0O6Mg7qdFGwQkseJTfp0HMbH1d9e6H0cocY8xfuDNGaZpOJhxiYtiPLg", "protectedHeader": "eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjoiL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYXkgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9" +} +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { + "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} +``` + +### Validating the Signature + +After the Payee FSP receives the `POST /quotes` API message from Payer FSP, the Payee FSP must validate the signature signed by the Payer FSP. + +#### Parse FSPIOP-Signature + +1. Parse the HTTP header parameter **FSPIOP-Signature** to get the components **protectedHeader** and signature. In this case, the value of **protectedHeader** is: + +``` +eyJhbGciOiJSUzI1NiIsIkZTUElPUC1EZXN0aW5hdGlvbiI6IjU2NzgiLCJGU1BJT1AtVVJJIjo +iL3F1b3RlcyIsIkZTUElPUC1IVFRQLU1ldGhvZCI6IlBPU1QiLCJEYXRlIjoiVHVlLCAyMyBNYX +kgMjAxNyAyMToxMjozMSBHTVQiLCJGU1BJT1AtU291cmNlIjoiMTIzNCJ9 +``` + +2. Use BASE64URL to decode the encoded representation of the JWS Protected Header. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to JSON Data Interchange Format, defined in RFC7159. In this case, the decoded JSON object is: + +```json +{ + "alg":"RS256", + "FSPIOP-Destination":"5678", + "FSPIOP-URI":"/quotes", + "FSPIOP-HTTP-Method":"POST", + "Date":"Tue, 23 May 2017 21:12:31 GMT", + "FSPIOP-Source":"1234" +} +``` + +3. Verify that the **alg** parameter is valid for the API. That means it must be in the list of **RS256, RS384, RS512**. In this case, the value of **alg** is **RS256**, which is valid. + +4. Verify that the value of the parameter **FSPIOP-URI** is same as the input URL of this API message. + +5. Verify that the value of the parameter **FSPIOP-HTTP-Method** is same as the HTTP method of this API message. + +6. Verify that the value of the HTTP header parameter **FSPIOP-Source** is the same as the corresponding value listed in this JWS Protected Header. + +7. Verify that the values for the HTTP header parameter **FSPIOP-Destination** are the same as the corresponding values stated in this JWS Protected Header. + +8. Verify the other protected HTTP header parameters. In this case, the **Date** parameter is protected by JWS Protected Header. If the parameters **Date** in the HTTP header of this API message and **Date** in the JWS Protected Header are equal, then the validation is successful. Both **Date** parameters in the example should be the following value: + +``` +"Tue, 23 May 2017 21:12:31 GMT" +``` + +The validation is passed. + +#### Verify JWS Signature + +1. In this case, the JWS Payload is the full HTTP body of the API message, that is (line breaks and indentation within values for display purposes only): + +```json +{ + "amount": { "amount": "150", "currency": "USD" }, + "transactionType": { "scenario": "TRANSFER", "initiator": "PAYER", + "subScenario": "P2P Transfer across MM systems", + "initiatorType": "CONSUMER" + }, + "transactionId": "36629a51-393a-4e3c-b347-c2cb57e1e1fc", + "quoteId": "59e331fa-345f-4554-aac8-fcd8833f7d50", + "expiration": "2017-05-24T08:40:00.000-04:00", + "payer": { + "personalInfo": { "dateOfBirth": "1986-02-14", + "complexName": { "middleName": "Ben", + "LastName": "Lee", "firstName": "Bill" } }, + "name": "Bill Lee", + "partyIdInfo": { "fspId": "1234", + "partyIdType": "MSISDN", + "partySubIdOrType": "RegisteredCustomer", + "partyIdentifier": "16135551212" } }, + "payee": { + "partyIdInfo": { "fspId": "5678", + "partyIdType": "MSISDN", + "partyIdentifier": "15295558888" } }, + "fees": { "amount": "1.5", "currency": "USD" }, + "extensionList": { + "extension": [ + { "value": "value1", "key": "key1" }, + { "value": "value2", "key": "key2" }, + { "value": "value3", "key": "key3" } + ] + }, + "note": "this is a sample for POST /quotes", + "geoCode": { "longitude": "125.520001", "latitude": "57.323889" }, + "amountType": "RECEIVE" +} + ``` + +2. Compute the encoded payload value BASE64URL(JWS Payload). Get the encoded value as: + +``` +eyJwYXllZSI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjE1Mjk1NTU4ODg4IiwiZnNwSWQiOiI1Njc4In19LCJhbW91bnRUeXBlIjoiUkVDRUlWRSIsInRyYW5zYWN0aW9uVHlwZSI6eyJzY2VuYXJpbyI6IlRSQU5TRkVSIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJzdWJTY2VuYXJpbyI6IlAyUCBUcmFuc2ZlciBhY3Jvc3MgTU0gc3lzdGVtcyIsImluaXRpYXRvclR5cGUiOiJDT05TVU1FUiJ9LCJub3RlIjoidGhpcyBpcyBhIHNhbXBsZSBmb3IgUE9TVCAvcXVvdGVzIiwiYW1vdW50Ijp7ImFtb3VudCI6IjE1MCIsImN1cnJlbmN5IjoiVVNEIn0sImZlZXMiOnsiYW1vdW50IjoiMS41IiwiY3VycmVuY3kiOiJVU0QifSwiZXh0ZW5zaW9uTGlzdCI6W3sidmFsdWUiOiJ2YWx1ZTEiLCJrZXkiOiJrZXkxIn0seyJ2YWx1ZSI6InZhbHVlMiIsImtleSI6ImtleTIifSx7InZhbHVlIjoidmFsdWUzIiwia2V5Ijoia2V5MyJ9XSwiZ2VvQ29kZSI6eyJsYXRpdHVkZSI6IjU3LjMyMzg4OSIsImxvbmdpdHVkZSI6IjEyNS41MjAwMDEifSwiZXhwaXJhdGlvbiI6IjIwMTctMDUtMjRUMDg6NDA6MDAuMDAwLTA0OjAwIiwicGF5ZXIiOnsicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7ImZpcnN0TmFtZSI6IkJpbGwiLCJtaWRkbGVOYW1lIjoiQmVuIiwiTGFzdE5hbWUiOiJMZWUifSwiZGF0ZU9mQmlydGgiOiIxOTg2LTAyLTE0In0sInBhcnR5SWRJbmZvIjp7InBhcnR5SWRUeXBlIjoiTVNJU0ROIiwicGFydHlTdWJJZE9yVHlwZSI6IlJlZ2lzdGVyZWRDdXN0b21lciIsInBhcnR5SWRlbnRpZmllciI6IjE2MTM1NTUxMjEyIiwiZnNwSWQiOiIxMjM0In0sIm5hbWUiOiJCaWxsIExlZSJ9LCJxdW90ZUlkIjoiNTllMzMxZmEtMzQ1Zi00NTU0LWFhYzgtZmNkODgzM2Y3ZDUwIiwidHJhbnNhY3Rpb25JZCI6IjM2NjI5YTUxLTM5M2EtNGUzYy1iMzQ3LWMyY2I1N2UxZTFmYyJ9 +``` + +3. Validate the JWS Signature against the JWS Signing Input (that is, the JWS Protected Header, JWS Payload) with the specified algorithm **RS256** (specified in the JWS Protected Header), and the public key. Record whether the validation succeeded or not. + +
    + +## References + +1 [https://tools.ietf.org/html/rfc7515#section-1.1](https://tools.ietf.org/html/rfc7515#section-1.1) – JSON Web Signature (JWS) - Notational Conventions + +2 [https://tools.ietf.org/html/rfc7515](https://tools.ietf.org/html/rfc7515) - JSON Web Signature (JWS) + +3 [https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-header-parameters) - JSON Web Signature and Encryption Header Parameters + +4 [https://tools.ietf.org/html/rfc7159](https://tools.ietf.org/html/rfc7159) - The JavaScript Object Notation (JSON) Data Interchange Format + +5 [https://tools.ietf.org/html/rfc7517](https://tools.ietf.org/html/rfc7517) - JSON Web Key (JWK) diff --git a/website/versioned_docs/v1.0.1/api/settlement/README.md b/website/versioned_docs/v1.0.1/api/settlement/README.md new file mode 100644 index 000000000..6ee179c40 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/settlement/README.md @@ -0,0 +1,4 @@ +--- +showToc: false +--- +https://raw.githubusercontent.com/mojaloop/central-settlement/master/src/interface/swagger.json \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/README.md b/website/versioned_docs/v1.0.1/api/thirdparty/README.md new file mode 100644 index 000000000..0a05cd1e1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/README.md @@ -0,0 +1,41 @@ +# Third Party API + +The Third Party API is an API for non-fund-holding participants to interact over a centralized Mojaloop hub. +Specifically, this API allows Payment Initiation Service Providers (PISPs) to act as a proxy in initiating +payments, while allowing for the strong authentication of users. + +## Terms + +The following terms are commonly used across the Third Party API Documentation + +| **Term** | **Alternative and Related Terms** | **Definition** | **Source** | +| --- | --- | --- | --- | +| **Payment Initiation Service Provider** | PISP, 3rd Party Payment Initiator (3PPI) | Regulated entities like retail banks or third parties, that allow customers to make payments without accessing bank accounts or cards | [PSD2](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32015L2366&qid=1633311418487) | +| **FSP** | Provider, Financial Service Provider (FSP), Payment Service Provider, Digital Financial Services Provider (DFSP) | The entity that provides a digital financial service to an end user (either a consumer, a business, or a government.) In a closed-loop payment system, the Payment System Operator is also the provider. In an open-loop payment system, the providers are the banks or non-banks which participate in that system. | [ITU-T](https://www.itu.int/dms_pub/itu-t/opb/tut/T-TUT-ECOPO-2018-PDF-E.pdf) | +| **User** | End User | An end user that is shared between a PISP and DFSP. Mostly used in the context of a real human being, but this could also be a machine user, or a business for example | +| **Consent** | Account Link | A representation of an agreement between the DFSP, PISP and User | | +| **Auth-Service** | | A service run by the Mojaloop Hub that is responsible for verifying and storing Consents, and verifying transaction request signatures | | + +## API Definitions + +The Third Party API is defined across the following OpenAPI 3.0 files: + +- [Third Party API - PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +- [Third Party API - DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml) + +The implementation of these APIs will depend on the role of the participant. PISPs should implement the [Third Party API - PISP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-pisp-v1.0.yaml) +interface in order to request and manage Account Linking operations, and initiate Third Party Transaction Requests. + +DFSPs who wish to support Account Linking operations, and be able to respond to and verify Third Party Transaction Requests should +implement the [Third Party API - DFSP](https://github.com/mojaloop/mojaloop-specification/blob/master/thirdparty-api/thirdparty-dfsp-v1.0.yaml). + +## Transaction Patterns + +The interactions and examples of how a DFSP and PISP will interact with the Third Party API can be found in the following Transaction Patterns Documents: + +1. [Linking](./transaction-patterns-linking.md) describes how an account link and credential can be established between a DFSP and a PISP +2. [Transfer](./transaction-patterns-transfer.md) describes how a PISP can initate a payment from a DFSP's account using the account link + +## Data Models + +The [Data Models Document](./data-models.md) describes in detail the Data Models used in the Third Party API diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/_sync_docs.sh b/website/versioned_docs/v1.0.1/api/thirdparty/_sync_docs.sh new file mode 100644 index 000000000..fd92ad483 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/_sync_docs.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +## +# Synchronises the definition docs from their disparate locations into one place. +# +# The API Spec for the Third Party API is managed by the api-snippets project +## + +set -eu + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +GIT_URL="https://github.com/mojaloop/api-snippets.git" +BRANCH='master' +CLONE_DIR='/tmp/api-snippets' + +rm -rf ${CLONE_DIR} + +git clone -b ${BRANCH} ${GIT_URL} ${CLONE_DIR} + +# API definition, grab from mojaloop/pisp-project +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-dfsp-api.yaml ${DIR}/thirdparty-dfsp-v1.0.yaml +cp ${CLONE_DIR}/thirdparty/openapi3/thirdparty-pisp-api.yaml ${DIR}/thirdparty-pisp-v1.0.yaml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/README.md b/website/versioned_docs/v1.0.1/api/thirdparty/assets/README.md new file mode 100644 index 000000000..8ef0a6124 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/README.md @@ -0,0 +1,15 @@ +# thirdparty-api/assets + +Supporting Assets for the Third Party API Specification + + +## Rebuild all Puml -> svg + +For consistent rending of sequence diagrams, we build the .puml sources to .svgs using the following script + +```bash +./_build_plantuml_all.sh +``` + +This also ensures that the sequence diagrams are easily readable inline in markdown documents. + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_all.sh b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_all.sh new file mode 100644 index 000000000..06435f49d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_all.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PUML_PORT=9999 +export PUML_BASE_URL=http://localhost:${PUML_PORT} + +## +# searches through repo for plantuml sources +# and exports them using `node-plantuml` +## + +trap ctrl_c INT +function ctrl_c() { + echo "exit early - stopping docker" + docker stop puml-local + exit 1 +} + +# run the docker puml server +docker run -d --rm \ + --name puml-local \ + -p ${PUML_PORT}:8080 \ + plantuml/plantuml-server:jetty-v1.2020.21 + +# Wait for docker to be up +sleep 2 + +for i in $(find ${DIR}/diagrams -name '*.puml'); do + echo "rendering .puml -> .svg for diagram diagram: $i" + ${DIR}/_render_svg.mjs $i $(echo $i | sed 's/puml/svg/g') +done + +docker stop puml-local diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_diff.sh b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_diff.sh new file mode 100644 index 000000000..c54d72603 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_build_plantuml_diff.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PUML_PORT=9999 +export PUML_BASE_URL=http://localhost:${PUML_PORT} + +## +# searches through repo for plantuml sources +# and exports them using `node-plantuml` +## + +trap ctrl_c INT +function ctrl_c() { + echo "exit early - stopping docker" + docker stop puml-local + exit 1 +} + +# run the docker puml server +docker run -d --rm \ + --name puml-local \ + -p ${PUML_PORT}:8080 \ + plantuml/plantuml-server:jetty-v1.2020.21 + +# Wait for docker to be up +sleep 2 + +for i in $(git diff --staged --name-only `find ${DIR}/../docs -name '*.puml'`); do + echo "rendering .puml -> .svg for diagram diagram: $i" + ${DIR}/_render_svg.mjs $i $(echo $i | sed 's/puml/svg/g') +done + + +git add ./ + +docker stop puml-local diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/_render_svg.js b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_render_svg.js new file mode 100644 index 000000000..02ef94920 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/_render_svg.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node + + +/** + * Uses plantuml server to render a puml to svg + */ + +const fs = require('fs') +const path = require('path') +const util = require('util') +const got = require('got') +const SVGO = require('svgo') +const plantumlEncoder = require('plantuml-encoder') + +const rendererBaseUrl = process.env.PUML_BASE_URL || 'http://www.plantuml.com/plantuml' + +svgo = new SVGO({ + js2svg: { pretty: true, indent: 2 }, + plugins: [ + { removeComments: true }, + ] +}); + +async function main() { + let [_, _script, inputPath, outputPath] = process.argv + + if (!inputPath) { + console.log("usage: ./_render_svg.mjs []") + process.exit(1) + } + + // If not specified, replace .puml or .plantuml with `.svg` + if (!outputPath) { + outputPath = inputPath.replace('.puml', '.svg') + .replace('.plantuml', '.svg') + } + + const rawPumlContents = fs.readFileSync(inputPath) + const encoded = plantumlEncoder.encode(rawPumlContents.toString()) + const url = path.join(rendererBaseUrl, 'svg', encoded) + let result + try { + result = await got.get(url) + } catch (err) { + console.log('http request failed to render puml with error', err.message) + if (err.message.indexOf('Response code 403') > -1) { + console.log('Note: sometimes the public puml renderer fails when the input diagrams are too large. Try running your own renderer server with docker.') + } + + if (err.message.indexOf('Response code 400') > -1) { + console.log('This could be due to bad syntax in the puml diagram. Url is:') + console.log(url) + } + + process.exit(1) + } + + // Strip comments and prettify svg + // This makes sure that our .svg files are deterministic and diffable + const formatted = await svgo.optimize(result.body) + fs.writeFileSync(outputPath, formatted.data) +} + +main() diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml new file mode 100644 index 000000000..b07cf9129 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.puml @@ -0,0 +1,49 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Pre-linking + +box "Mobile device" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +autonumber 1 "PRE-#" +activate App +App -> PISP ++: What DFSPs are available to link with? + + +PISP -> Switch ++: ""GET /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: pispa""\n""FSPIOP-Destination: switch"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> PISP ++: ""PUT /services/THIRD_PARTY_DFSP""\n""FSPIOP-Source: switch""\n""FSPIOP-Destination: pispa""\n\ + ""{""\n\ + "" "serviceProviders": ["" \n\ + "" "dfspa", "dfspb""" \n\ + "" ]"" \n\ + ""}"" +PISP --> Switch: ""200 OK"" + +PISP --> App --: We have dfspa and dfspb\n + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg new file mode 100644 index 000000000..c7ee47f89 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/0-pre-linking.svg @@ -0,0 +1,107 @@ + + + PISP Linking: Pre-linking + + + + Mobile device + + + + PISP + + + + Mojaloop + + + + + + App + + + + PISP + + + + Switch + + + + + PRE-1 + + + What DFSPs are available to link with? + + + + PRE-2 + + + GET /services/THIRD_PARTY_DFSP + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: switch + + + + + PRE-3 + + + 202 Accepted + + + + PRE-4 + + + PUT /services/THIRD_PARTY_DFSP + + + FSPIOP-Source: switch + + + FSPIOP-Destination: pispa + + + { + + + "serviceProviders": [ + + + "dfspa", "dfspb + + + " + + + ] + + + } + + + + + PRE-5 + + + 200 OK + + + + + PRE-6 + + + We have dfspa and dfspb + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.puml new file mode 100644 index 000000000..c719fb2af --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.puml @@ -0,0 +1,85 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title PISP Linking: Discovery + +box "Mobile device" + participant App +end box + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +... + +note over App, DFSP + The user will be prompted in the PISP App for the unique ID they use with their DFSP, and the type of identifier they use. This could be a an account ALIAS, MSISDN, email address, etc. +end note + +... + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> Switch ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""[""\n\ + "" { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" },""\n\ + "" { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" }""\n\ + ""]"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over App, DFSP + The PISP can now present a list of possible accounts to the user for pairing. +end note + +... + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.svg new file mode 100644 index 000000000..68f6c49c0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/1-discovery.svg @@ -0,0 +1,194 @@ + + + PISP Linking: Discovery + + + + Mobile device + + + + PISP + + + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + App + + + + PISP + + + + Switch + + + + DFSP + + + + + + + + + + The user will be prompted in the PISP App for the unique ID they use with their DFSP, and the type of identifier they use. This could be a an account ALIAS, MSISDN, email address, etc. + + + + DISC-1 + + + GET /accounts/username1234 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + DISC-2 + + + 202 Accepted + + + + DISC-3 + + + GET /accounts/username1234 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + DISC-4 + + + 202 Accepted + + + + DISC-5 + + + PUT /accounts/username1234 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + [ + + + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, + + + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } + + + ] + + + + + DISC-6 + + + 200 OK + + + + DISC-7 + + + PUT /accounts/username1234 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + [ + + + { accountNickname: "Chequing Account", id: "dfspa.username.1234", currency: "ZAR" }, + + + { accountNickname: "Everyday Spend", id: "dfspa.username.5678", currency: "USD" } + + + ] + + + + + DISC-8 + + + 200 OK + + + + + The PISP can now present a list of possible accounts to the user for pairing. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml new file mode 100644 index 000000000..8d52071bc --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.puml @@ -0,0 +1,119 @@ +@startuml + + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Request consent (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the consentRequest validity + + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" + +note over PISP, DFSP + Here, the DFSP sends an OTP directly to the user (e.g., via SMS). +end note + +deactivate DFSP + +Switch -> PISP: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ +""{""\n\ + "" authChannels: [ "OTP" ], ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + At this point, the PISP knows that the OTP authChannel is in use and the PISP App should prompt the user to provide the OTP. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg new file mode 100644 index 000000000..ad65ece6b --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-otp.svg @@ -0,0 +1,294 @@ + + + PISP Linking: Request consent (OTP) + + + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + + + + + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. + + + + REQ-1 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-2 + + + 202 Accepted + + + + REQ-3 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-4 + + + 202 Accepted + + + + REQ-5 + + + Verify the consentRequest validity + + + + REQ-6 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + authChannels: [ "OTP" ], + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-7 + + + 200 OK + + + + + Here, the DFSP sends an OTP directly to the user (e.g., via SMS). + + + + REQ-8 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + authChannels: [ "OTP" ], + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-9 + + + 200 OK + + + + + At this point, the PISP knows that the OTP authChannel is in use and the PISP App should prompt the user to provide the OTP. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml new file mode 100644 index 000000000..de404fc39 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.puml @@ -0,0 +1,118 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +title PISP Linking: Request consent (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "REQ-#" + +activate PISP + +... + +note over PISP, DFSP + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. +end note + +... + +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234", ""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ + "" {""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" + +DFSP -> DFSP: Verify the consentRequest validity +DFSP -> DFSP: In this case, DFSP chooses to use the Web channel, \n and adds the PISP's callback uri to an allow-list +deactivate Switch + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + "" {""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "Web" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + "" authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch + +note over PISP, DFSP + At this point, the PISP knows that the Web authChannel is in use and the PISP App should redirect the user to the provided ""authUri"". +end note + + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg new file mode 100644 index 000000000..ecffd688a --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/2-request-consent-web.svg @@ -0,0 +1,311 @@ + + + PISP Linking: Request consent (Web) + + + + Mojaloop + + + + + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + + + + + The user initiated some sort of account linking by choosing the appropriate DFSP from a screen inside the PISP application. + + + + REQ-1 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-2 + + + 202 Accepted + + + + REQ-3 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-4 + + + 202 Accepted + + + + REQ-5 + + + Verify the consentRequest validity + + + + REQ-6 + + + In this case, DFSP chooses to use the Web channel, + + + and adds the PISP's callback uri to an allow-list + + + + REQ-7 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web" ], + + + callbackUri: "pisp-app://callback... + + + " + + + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" + + + } + + + + + REQ-8 + + + 200 OK + + + + REQ-9 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "Web" ], + + + callbackUri: "pisp-app://callback... + + + " + + + authUri: "dfspa.com/authorize?consentRequestId=11111111-0000-0000-0000-000000000000" + + + } + + + + + REQ-10 + + + 200 OK + + + + + At this point, the PISP knows that the Web authChannel is in use and the PISP App should redirect the user to the provided + + + authUri + + + . + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml new file mode 100644 index 000000000..2fdb17e5d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.puml @@ -0,0 +1,62 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (OTP) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +... + +note over PISP, DFSP + Here the user provides the OTP sent directly to them by the DFSP into the PISP App. It's then used as the secret to prove to the DFSP that the user trusts the PISP. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the OTP is correct. + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg new file mode 100644 index 000000000..3372bda19 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-otp.svg @@ -0,0 +1,116 @@ + + + PISP Linking: Authentication (OTP) + + + + Mojaloop + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + Here the user provides the OTP sent directly to them by the DFSP into the PISP App. It's then used as the secret to prove to the DFSP that the user trusts the PISP. + + + + AUTH-1 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + AUTH-2 + + + 202 Accepted + + + + AUTH-3 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + AUTH-4 + + + 202 Accepted + + + + AUTH-5 + + + Verify the OTP is correct. + + + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml new file mode 100644 index 000000000..9d05ec448 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.puml @@ -0,0 +1,45 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (Third-party FIDO registration) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "3P-FIDO-AUTH-#" + +... + +note over PISP, DFSP + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter indicating to the PISP that it should wait to be notified about a credential. +end note + +... + +autonumber 1 "AUTH-#" + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg new file mode 100644 index 000000000..32fdc6524 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-third-party-fido.svg @@ -0,0 +1,50 @@ + + + PISP Linking: Authentication (Third-party FIDO registration) + + + + Mojaloop + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + Here the user goes through the web authentication process with their DFSP. + + + The end result is a redirect back to the PISP with a special URL parameter indicating to the PISP that it should wait to be notified about a credential. + + + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml new file mode 100644 index 000000000..f31a9ed55 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.puml @@ -0,0 +1,65 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication (Web) + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "WEB-AUTH-#" + +... + +note over PISP, DFSP + Here the user goes through the web authentication process with their DFSP. + The end result is a redirect back to the PISP with a special URL parameter with a secret provided by the DFSP. +end note + +... + +autonumber 1 "AUTH-#" + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the auth token is correct. + +note over PISP, DFSP + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg new file mode 100644 index 000000000..8ed74081e --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/3-authentication-web.svg @@ -0,0 +1,119 @@ + + + PISP Linking: Authentication (Web) + + + + Mojaloop + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + Here the user goes through the web authentication process with their DFSP. + + + The end result is a redirect back to the PISP with a special URL parameter with a secret provided by the DFSP. + + + + AUTH-1 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<SECRET>" + + + } + + + + + AUTH-2 + + + 202 Accepted + + + + AUTH-3 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<SECRET>" + + + } + + + + + AUTH-4 + + + 202 Accepted + + + + AUTH-5 + + + Verify the auth token is correct. + + + + + At this point, the DFSP believes that the User is their customer and that User trusts the PISP. This means that the DFSP can continue by granting consent. + + + Note that the DFSP never "responds" to the Consent Request itself. Instead, it will create a Consent resource in the Grant phase. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml new file mode 100644 index 000000000..e0ede15d5 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.puml @@ -0,0 +1,64 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Grant consent + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +DFSP -> Switch ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" +Switch --> DFSP: ""202 Accepted"" +deactivate DFSP + +Switch -> PISP ++: ""POST /consents""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000",""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + ""}"" + +PISP --> Switch: ""202 Accepted"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg new file mode 100644 index 000000000..60e2e7345 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/4-grant-consent.svg @@ -0,0 +1,134 @@ + + + + Mojaloop + + + PISP Linking: Grant consent + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + GRANT-1 + + + POST /consents + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + consentId: "22222222-0000-0000-0000-000000000000", + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + status: "ISSUED", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + } + + + + + GRANT-2 + + + 202 Accepted + + + + GRANT-3 + + + POST /consents + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + consentId: "22222222-0000-0000-0000-000000000000", + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + status: "ISSUED", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + } + + + + + GRANT-4 + + + 202 Accepted + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml new file mode 100644 index 000000000..7e4b6ac64 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.puml @@ -0,0 +1,217 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Credential registration (verification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 0 "CRED-#" + +... + +note over PISP, DFSP + The PISP uses the FIDO registration flow to generate a new keypair and sign the challenge, relying on the user performing an "unlock action" on their mobile device. + + The PISP uses the PublicKeyCredential as the fidoPayload for the credential, which can be understood by the Auth Service and DFSP + See https://webauthn.guide/#authentication for more information on this object +end note + +... + +PISP -> Switch ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + + +Switch -> DFSP ++: ""PUT /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: ""202 Accepted"" + + +rnote over DFSP + 1. DFSP checks the signed challenge against the derived challenge from the scopes + + If the DFSP opts to use the hub-hosted Auth-Service it then: + 1. Registers the consent with the Auth Service ""POST /consents"" + 2. If the DFSP recieves a `PUT /consents/{id}` and the callback contains + ""Consent.credential.status"" of ""VERIFIED"", for each scope in the + Consent, the DFSP creates a ""CredentialScope"" else, if it recieves + a `PUT /consents/{id}/error` callback, it knows that the Consent is + invalid, and can propagate the error back to the PISP + +end note + + +DFSP -> Switch: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {""\n\ + "" consentId: "22222222-0000-0000-0000-000000000000"""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000"""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ],""\n\ + "" }""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "PENDING",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" + +Switch --> DFSP: "202 Accepted" + + +Switch -> Auth: ""POST /consents"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: central-auth""\n\ +"" {...}"" + +Auth --> Switch: "202 Accepted" + + +rnote over Auth + The Auth Service checks the signature against the challenge +end note + +rnote over Auth + The auth service is now the authoritative source for the Consent object. + + It must register the consentId with the ALS + - `Consent` - to allow for `GET /consent/{ID}` calls etc. Will point to the fspId of the Auth Service responsible for the Consent +end note + +Auth -> ALS: ""POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +ALS --> Auth: ""202 Accepted"" + +rnote over ALS #LightGray + ALS registers a new entry in the Consents oracle +end note + +ALS -> Auth: ""PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: account-lookup-service""\n\ +"" FSIOP-Destination: central-auth""\n\ +"" {""\n\ +"" fspId: "central-auth",""\n\ +"" }"" +Auth --> ALS: ""200 OK"" + +rnote over Auth #LightGray + The auth service now informs the DFSP that the credential is valid +end note + + +Auth -> Switch: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {""\n\ + "" status: "ISSUED",""\n\ + "" scopes: [""\n\ + "" {""\n\ + "" accountId: "dfsp.username.1234",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" {""\n\ + "" accountId: "dfsp.username.5678",""\n\ + "" actions: [ "accounts.transfer", "accounts.getBalance" ],""\n\ + "" },""\n\ + "" ],""\n\ + "" credential: { ""\n\ + "" credentialType: "FIDO",""\n\ + "" status: "VERIFIED",""\n\ + "" fidoPayload: { ""\n\ + "" id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", "" \n\ + "" response: { ""\n\ + "" "" authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==",\n\ + "" "" clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...",\n\ + "" "" signature: "MEUCIDcJRBu5aOLJVc..."\n\ + "" } ""\n\ + "" } ""\n\ + "" }""\n\ +"" }"" +Switch --> Auth: "200 OK" + +Switch -> DFSP: ""PUT /consents/22222222-0000-0000-0000-000000000000"" \n\ +"" FSIOP-Source: central-auth""\n\ +"" FSPIOP-Destination: dfspa""\n\ +"" {...}"" + +DFSP --> Switch: "200 OK" + +rnote over DFSP + DFSP is now satisfied that the Consent registered by the PISP is valid. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg new file mode 100644 index 000000000..8a792580e --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5a-credential-registration.svg @@ -0,0 +1,577 @@ + + + + Mojaloop + + + PISP Linking: Credential registration (verification) + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + + + Thirdparty-API-Adapter + + + + Account Lookup Service + + + + Auth Service + + + + DFSP + + + + + The PISP uses the FIDO registration flow to generate a new keypair and sign the challenge, relying on the user performing an "unlock action" on their mobile device. + + + The PISP uses the PublicKeyCredential as the fidoPayload for the credential, which can be understood by the Auth Service and DFSP + + + See https://webauthn.guide/#authentication for more information on this object + + + + CRED-0 + + + PUT /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + status: "ISSUED", + + + scopes: [ + + + { + + + accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ], + + + }, + + + { + + + accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ], + + + } + + + ], + + + credential: { + + + credentialType: "FIDO", + + + status: "PENDING", + + + fidoPayload: { + + + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", + + + response: { + + + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", + + + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", + + + signature: "MEUCIDcJRBu5aOLJVc..." + + + } + + + } + + + } + + + } + + + + + CRED-1 + + + 202 Accepted + + + + CRED-2 + + + PUT /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + {...} + + + + + CRED-3 + + + 202 Accepted + + + + 1. DFSP checks the signed challenge against the derived challenge from the scopes + + + If the DFSP opts to use the hub-hosted Auth-Service it then: + + + 1. Registers the consent with the Auth Service + + + POST /consents + + + 2. If the DFSP recieves a `PUT /consents/{id}` and the callback contains + + + Consent.credential.status + + + of + + + VERIFIED + + + , for each scope in the + + + Consent, the DFSP creates a + + + CredentialScope + + + else, if it recieves + + + a `PUT /consents/{id}/error` callback, it knows that the Consent is + + + invalid, and can propagate the error back to the PISP + + + + CRED-4 + + + POST /consents + + + FSIOP-Source: dfspa + + + FSPIOP-Destination: central-auth + + + { + + + consentId: "22222222-0000-0000-0000-000000000000 + + + " + + + consentRequestId: "11111111-0000-0000-0000-000000000000 + + + " + + + status: "ISSUED", + + + scopes: [ + + + { + + + accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ], + + + } + + + }, + + + { + + + accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ], + + + } + + + }, + + + ], + + + credential: { + + + credentialType: "FIDO", + + + status: "PENDING", + + + fidoPayload: { + + + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", + + + response: { + + + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", + + + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", + + + signature: "MEUCIDcJRBu5aOLJVc..." + + + } + + + } + + + } + + + } + + + + + CRED-5 + + + "202 Accepted" + + + + CRED-6 + + + POST /consents + + + FSIOP-Source: dfspa + + + FSPIOP-Destination: central-auth + + + {...} + + + + + CRED-7 + + + "202 Accepted" + + + + The Auth Service checks the signature against the challenge + + + + The auth service is now the authoritative source for the Consent object. + + + It must register the consentId with the ALS + + + - `Consent` - to allow for `GET /consent/{ID}` calls etc. Will point to the fspId of the Auth Service responsible for the Consent + + + + CRED-8 + + + POST /participants/CONSENTS/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + { + + + fspId: "central-auth", + + + } + + + + + CRED-9 + + + 202 Accepted + + + + ALS registers a new entry in the Consents oracle + + + + CRED-10 + + + PUT /participants/CONSENTS/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: account-lookup-service + + + FSIOP-Destination: central-auth + + + { + + + fspId: "central-auth", + + + } + + + + + CRED-11 + + + 200 OK + + + + The auth service now informs the DFSP that the credential is valid + + + + CRED-12 + + + PUT /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSPIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000 + + + " + + + status: "ISSUED", + + + scopes: [ + + + { + + + accountId: "dfsp.username.1234", + + + actions: [ "accounts.transfer", "accounts.getBalance" ], + + + }, + + + { + + + accountId: "dfsp.username.5678", + + + actions: [ "accounts.transfer", "accounts.getBalance" ], + + + }, + + + ], + + + credential: { + + + credentialType: "FIDO", + + + status: "VERIFIED", + + + fidoPayload: { + + + id: "45c-TkfkjQovQeAWmOy-RLBHEJ_e4jYzQYgD8VdbkePgM5d98BaAadadNYrknxgH0jQEON8zBydLgh1EqoC9DA", + + + response: { + + + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAACA==", + + + clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4...", + + + signature: "MEUCIDcJRBu5aOLJVc..." + + + } + + + } + + + } + + + } + + + + + CRED-13 + + + "200 OK" + + + + CRED-14 + + + PUT /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSPIOP-Destination: dfspa + + + {...} + + + + + CRED-15 + + + "200 OK" + + + + DFSP is now satisfied that the Consent registered by the PISP is valid. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml new file mode 100644 index 000000000..791a929de --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.puml @@ -0,0 +1,97 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Credential registration (verification) + +participant "PISP" as PISP + +box "Mojaloop" + participant "Switch" as Switch + participant "Account Lookup Service" as ALS +end box + +participant "DFSP" as DFSP + +autonumber 16 "CRED-#" + +... + + +rnote over DFSP + DFSP is now satisfied that the Consent registered by the PISP is valid, + and now proceeds to register with the ALS: + - `THIRD_PARTY_LINK` (optional - for routing of funds to a Third Party Link) + ALS +end note + +loop for each scope in ""Consents.scopes"" + +DFSP -> ALS: ""POST /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSIOP-Source: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +ALS --> DFSP: ""202 Accepted"" + +rnote over ALS #LightGray + ALS registers a new entry in the THIRD_PARTY_LINK oracle +end note + +ALS -> DFSP: ""PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678"" \n\ +"" FSIOP-Source: account-lookup-service""\n\ +"" FSIOP-Destination: dfspa""\n\ +"" {""\n\ +"" fspId: "dfspa",""\n\ +"" }"" +DFSP --> ALS: ""200 OK"" +end + + +rnote over DFSP + Now that the Credentials are verified and registered with the Auth Service, + the DFSP can update the PISP with the final status +end note + +DFSP -> Switch: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +DFSP --> Switch: ""200 OK"" + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSPIOP-Destination: pispa""\n\ +"" Content-Type: application/merge-patch+json""\n\ +"" {""\n\ + "" credential: {""\n\ + "" **status: "VERIFIED", //this is new!**""\n\ + "" }""\n\ +"" }"" +PISP --> Switch: ""200 OK"" + + +note over PISP, DFSP + Now we have a new identifier that the PISP can use to initiate transactions, a registered credential, and that credential is stored in the auth-service +end note + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg new file mode 100644 index 000000000..54ba44707 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/5b-finalize_consent.svg @@ -0,0 +1,215 @@ + + + + Mojaloop + + + PISP Linking: Credential registration (verification) + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + Account Lookup Service + + + + DFSP + + + + DFSP is now satisfied that the Consent registered by the PISP is valid, + + + and now proceeds to register with the ALS: + + + - `THIRD_PARTY_LINK` (optional - for routing of funds to a Third Party Link) + + + ALS + + + + + loop + + + [for each scope in + + + Consents.scopes + + + ] + + + + CRED-16 + + + POST /participants/THIRD_PARTY_LINK/dfsp.username.5678 + + + FSIOP-Source: dfspa + + + { + + + fspId: "dfspa", + + + } + + + + + CRED-17 + + + 202 Accepted + + + + ALS registers a new entry in the THIRD_PARTY_LINK oracle + + + + CRED-18 + + + PUT /participants/THIRD_PARTY_LINK/dfsp.username.5678 + + + FSIOP-Source: account-lookup-service + + + FSIOP-Destination: dfspa + + + { + + + fspId: "dfspa", + + + } + + + + + CRED-19 + + + 200 OK + + + + Now that the Credentials are verified and registered with the Auth Service, + + + the DFSP can update the PISP with the final status + + + + CRED-20 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + Content-Type: application/merge-patch+json + + + { + + + credential: { + + + status: "VERIFIED", //this is new! + + + } + + + } + + + + + CRED-21 + + + 200 OK + + + + CRED-22 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + Content-Type: application/merge-patch+json + + + { + + + credential: { + + + status: "VERIFIED", //this is new! + + + } + + + } + + + + + CRED-23 + + + 200 OK + + + + + Now we have a new identifier that the PISP can use to initiate transactions, a registered credential, and that credential is stored in the auth-service + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml new file mode 100644 index 000000000..4c2ff1b57 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Unlinking + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-A-#" + +activate PISP + +... + +note over PISP, DFSP + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the ""Consent"" object. +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Mark the ""Consent"" object as "REVOKED" + +DFSP -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: dfspa""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg new file mode 100644 index 000000000..14dabe215 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg @@ -0,0 +1,172 @@ + + + + Mojaloop + + + PISP Linking: Unlinking + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the + + + Consent + + + object. + + + + UNLINK-A-1 + + + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + UNLINK-A-2 + + + 202 Accepted + + + + UNLINK-A-3 + + + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + + + UNLINK-A-4 + + + 202 Accepted + + + + UNLINK-A-5 + + + Mark the + + + Consent + + + object as "REVOKED" + + + + UNLINK-A-6 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + " + + + } + + + + + UNLINK-A-7 + + + 200 OK + + + + UNLINK-A-8 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + } + + + + + UNLINK-A-9 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml new file mode 100644 index 000000000..914dc7704 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.puml @@ -0,0 +1,105 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +!pragma teoz true + +title PISP Linking: Unlinking + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "UNLINK-B-#" + +activate PISP + +... + +note over PISP, DFSP + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the ""Consent"" object. +end note + +... + +PISP -> Switch ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: pispa""\n\ +"" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> ALS: ""GET /participants/CONSENT/22222222-0000-0000-0000-000000000000"" +ALS --> Switch: ""200 OK""\n\ +"" { "fspId": "central-auth" }"" + +rnote over Switch #LightGray + Hub has determined that 'central-auth- is responsible for ""Consent"" 22222222-0000-0000-0000-000000000000 +end note + +Switch -> Auth ++: ""DELETE /consents/22222222-0000-0000-0000-000000000000"" +Auth --> Switch: ""202 Accepted"" +deactivate Switch + +Auth -> Auth: Mark the ""Consent"" object as "REVOKED" + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> PISP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: pispa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +PISP --> Switch: ""200 OK"" + + +rnote over Auth #LightGray + Auth Service must also inform the DFSP of the updated status +end note + +Auth -> Switch ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +Switch --> Auth: ""200 OK"" +deactivate Auth + +Switch -> DFSP ++: ""PATCH /consents/22222222-0000-0000-0000-000000000000""\n\ +"" FSIOP-Source: central-auth""\n\ +"" FSIOP-Destination: dfspa""\n\ +""{ ""\n\ +"" status: "REVOKED",""\n\ +"" revokedAt: "2020-06-15T13:00:00.000"""\n\ +""}"" +DFSP --> Switch: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg new file mode 100644 index 000000000..bb3c50196 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/6b-unlinking-hub-hosted.svg @@ -0,0 +1,298 @@ + + + + Mojaloop + + + PISP Linking: Unlinking + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + Account Lookup Service + + + + Auth Service + + + + DFSP + + + + + In this scenario there is no Hub-hosted Auth Service. The DFSP is the authority on the + + + Consent + + + object. + + + + UNLINK-B-1 + + + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + UNLINK-B-2 + + + 202 Accepted + + + + UNLINK-B-3 + + + GET /participants/CONSENT/22222222-0000-0000-0000-000000000000 + + + + + UNLINK-B-4 + + + 200 OK + + + { "fspId": "central-auth" } + + + + Hub has determined that 'central-auth- is responsible for + + + Consent + + + 22222222-0000-0000-0000-000000000000 + + + + UNLINK-B-5 + + + DELETE /consents/22222222-0000-0000-0000-000000000000 + + + + + UNLINK-B-6 + + + 202 Accepted + + + + UNLINK-B-7 + + + Mark the + + + Consent + + + object as "REVOKED" + + + + UNLINK-B-8 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSIOP-Destination: pispa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + " + + + } + + + + + UNLINK-B-9 + + + 200 OK + + + + UNLINK-B-10 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSIOP-Destination: pispa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + " + + + } + + + + + UNLINK-B-11 + + + 200 OK + + + + Auth Service must also inform the DFSP of the updated status + + + + UNLINK-B-12 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSIOP-Destination: dfspa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + " + + + } + + + + + UNLINK-B-13 + + + 200 OK + + + + UNLINK-B-14 + + + PATCH /consents/22222222-0000-0000-0000-000000000000 + + + FSIOP-Source: central-auth + + + FSIOP-Destination: dfspa + + + { + + + status: "REVOKED", + + + revokedAt: "2020-06-15T13:00:00.000 + + + " + + + } + + + + + UNLINK-B-15 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml new file mode 100644 index 000000000..bf5d76ca5 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.puml @@ -0,0 +1,79 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Discovery error case + +box "PISP" + participant PISP +end box + +box "Mojaloop" + participant Switch +end box + +participant DFSP + +autonumber 1 "DISC-#" +activate PISP + +PISP -> Switch ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""GET /accounts/username1234""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Lookup a user for **username1234** +DFSP -> DFSP: No user found + +DFSP -> Switch ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /accounts/username1234/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6205", ""\n\ + "" errorDescription: "No accounts found" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +... + +note over Switch + The PISP can now show error message and user can try again with another username or different DFSP. +end note + +... + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg new file mode 100644 index 000000000..d3d18465e --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/1-discovery-error.svg @@ -0,0 +1,182 @@ + + + PISP Linking: Discovery error case + + + + PISP + + + + Mojaloop + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + DISC-1 + + + GET /accounts/username1234 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + DISC-2 + + + 202 Accepted + + + + DISC-3 + + + GET /accounts/username1234 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + + + DISC-4 + + + 202 Accepted + + + + DISC-5 + + + Lookup a user for + + + username1234 + + + + DISC-6 + + + No user found + + + + DISC-7 + + + PUT /accounts/username1234/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6205", + + + errorDescription: "No accounts found" + + + } + + + } + + + + + DISC-8 + + + 200 OK + + + + DISC-9 + + + PUT /accounts/username1234/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6205", + + + errorDescription: "No accounts found" + + + } + + + } + + + + + DISC-10 + + + 200 OK + + + + + The PISP can now show error message and user can try again with another username or different DFSP. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml new file mode 100644 index 000000000..e3cbf4565 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.puml @@ -0,0 +1,162 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title **PISP Linking: consentRequest error cases** + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +== NO_SUPPORTED_SCOPE_ACTIONS == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.91011",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "pisp-app://callback..."""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: The PISP requested permissions \nfor accountId dfsp.username.91011 which \n isn't owned by username1234 + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6101", ""\n\ + "" errorDescription: "Unsupported scopes were requested" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +== UNTRUSTED_CALLBACK_URI == + +autonumber 1 "REQ-#" +PISP -> Switch ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234", ""\n\ + "" scopes: [ ""\n\ + "" { **accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""POST /consentRequests""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +""{""\n\ + "" consentRequestId: "11111111-0000-0000-0000-000000000000",""\n\ + "" userId: "username1234",""\n\ + "" scopes: [ ""\n\ + "" { accountId: "dfsp.username.1234",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" { accountId: "dfsp.username.5678",""\n\ + "" actions: [ "ACCOUNTS_TRANSFER" ] },""\n\ + "" ],""\n\ + "" authChannels: [ "WEB", "OTP" ],""\n\ + "" callbackUri: "http://phishing.com"""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +autonumber 1 "DFSP-#" +DFSP -> DFSP: The callbackUri uses http scheme \ninstead of https. Reject the consentRequest + +autonumber 5 "REQ-#" +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6204", ""\n\ + "" errorDescription: "Bad callbackUri" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg new file mode 100644 index 000000000..50cacb14f --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/2-request-consent-error.svg @@ -0,0 +1,455 @@ + + + PISP Linking: consentRequest error cases + + + + Mojaloop + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + + NO_SUPPORTED_SCOPE_ACTIONS + + + + REQ-1 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.91011", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "WEB", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-2 + + + 202 Accepted + + + + REQ-3 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.91011", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "WEB", "OTP" ], + + + callbackUri: "pisp-app://callback... + + + " + + + } + + + + + REQ-4 + + + 202 Accepted + + + + DFSP-1 + + + The PISP requested permissions + + + for accountId dfsp.username.91011 which + + + isn't owned by username1234 + + + + REQ-5 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6101", + + + errorDescription: "Unsupported scopes were requested" + + + } + + + } + + + + + REQ-6 + + + 200 OK + + + + REQ-7 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6101", + + + errorDescription: "Unsupported scopes were requested" + + + } + + + } + + + + + REQ-8 + + + 200 OK + + + + + + UNTRUSTED_CALLBACK_URI + + + + REQ-1 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { **accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "WEB", "OTP" ], + + + callbackUri: "http://phishing.com + + + " + + + } + + + + + REQ-2 + + + 202 Accepted + + + + REQ-3 + + + POST /consentRequests + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + consentRequestId: "11111111-0000-0000-0000-000000000000", + + + userId: "username1234", + + + scopes: [ + + + { accountId: "dfsp.username.1234", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + { accountId: "dfsp.username.5678", + + + actions: [ "ACCOUNTS_TRANSFER" ] }, + + + ], + + + authChannels: [ "WEB", "OTP" ], + + + callbackUri: "http://phishing.com + + + " + + + } + + + + + REQ-4 + + + 202 Accepted + + + + DFSP-1 + + + The callbackUri uses http scheme + + + instead of https. Reject the consentRequest + + + + REQ-5 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6204", + + + errorDescription: "Bad callbackUri" + + + } + + + } + + + + + REQ-6 + + + 200 OK + + + + REQ-7 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6204", + + + errorDescription: "Bad callbackUri" + + + } + + + } + + + + + REQ-8 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml new file mode 100644 index 000000000..c88560017 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.puml @@ -0,0 +1,87 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISP Linking: Authentication Invalid authToken + +participant "PISP" as PISP + +box "Mojaloop" + participant Switch +end box + +participant "DFSP" as DFSP + +autonumber 1 "AUTH-#" + +== Failure case == + +... + +note over PISP, DFSP + The user enters an incorrect OTP for authentication. +end note + +... + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: The OTP is incorrect. + +note over PISP, DFSP + We respond with an error that the OTP is incorrect so the PISP can inform the user. +end note + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "6203", ""\n\ + "" errorDescription: "Invalid authentication token" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg new file mode 100644 index 000000000..4320e199d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg @@ -0,0 +1,197 @@ + + + PISP Linking: Authentication Invalid authToken + + + + Mojaloop + + + + + + + + + + + + + + + + + + PISP + + + + Switch + + + + DFSP + + + + + + + Failure case + + + + + The user enters an incorrect OTP for authentication. + + + + AUTH-1 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + AUTH-2 + + + 202 Accepted + + + + AUTH-3 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + AUTH-4 + + + 202 Accepted + + + + AUTH-5 + + + The OTP is incorrect. + + + + + We respond with an error that the OTP is incorrect so the PISP can inform the user. + + + + AUTH-6 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6203", + + + errorDescription: "Invalid authentication token" + + + } + + + } + + + + + AUTH-7 + + + 200 OK + + + + AUTH-8 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "6203", + + + errorDescription: "Invalid authentication token" + + + } + + + } + + + + + AUTH-9 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml new file mode 100644 index 000000000..c9e4f772d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + + +!pragma teoz true + +title PISP Linking: Grant consent scope retrieval error + +participant "PISP" as PISP + +box "Mojaloop" + participant "Thirdparty-API-Adapter" as Switch + participant "Account Lookup Service" as ALS + participant "Auth Service" as Auth +end box + +participant "DFSP" as DFSP + +autonumber 1 "GRANT-#" + +== Failure case == + +PISP -> Switch ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +Switch --> PISP: ""202 Accepted"" +deactivate PISP + +Switch -> DFSP ++: ""PATCH /consentRequests/11111111-0000-0000-0000-000000000000""\n\ + "" FSIOP-Source: pispa""\n\ + "" FSIOP-Destination: dfspa""\n\ +"" {""\n\ + "" authToken: "" ""\n\ + ""}"" +DFSP --> Switch: ""202 Accepted"" +deactivate Switch + +DFSP -> DFSP: Verify the OTP is correct. + +DFSP -> DFSP: Unable to fetch stored scopes + +DFSP -> Switch ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +Switch --> DFSP: ""200 OK"" +deactivate DFSP + +Switch -> PISP ++: ""PUT /consentRequests/11111111-0000-0000-0000-000000000000/error""\n\ + "" FSIOP-Source: dfspa""\n\ + "" FSIOP-Destination: pispa""\n\ + ""{""\n\ + "" errorInformation : { ""\n\ + "" errorCode: "7207", ""\n\ + "" errorDescription: "FSP failed retrieve scopes for consent request" ""\n\ + "" } ""\n\ + ""}"" +PISP --> Switch: ""200 OK"" +deactivate Switch +deactivate PISP + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg new file mode 100644 index 000000000..cc0b292ec --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/linking/error_scenarios/4-grant-consent-scope-error.svg @@ -0,0 +1,191 @@ + + + + Mojaloop + + + PISP Linking: Grant consent scope retrieval error + + + + + + + + PISP + + + + Thirdparty-API-Adapter + + + + Account Lookup Service + + + + Auth Service + + + + DFSP + + + + + + Failure case + + + + GRANT-1 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + GRANT-2 + + + 202 Accepted + + + + GRANT-3 + + + PATCH /consentRequests/11111111-0000-0000-0000-000000000000 + + + FSIOP-Source: pispa + + + FSIOP-Destination: dfspa + + + { + + + authToken: "<OTP>" + + + } + + + + + GRANT-4 + + + 202 Accepted + + + + GRANT-5 + + + Verify the OTP is correct. + + + + GRANT-6 + + + Unable to fetch stored scopes + + + + GRANT-7 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "7207", + + + errorDescription: "FSP failed retrieve scopes for consent request" + + + } + + + } + + + + + GRANT-8 + + + 200 OK + + + + GRANT-9 + + + PUT /consentRequests/11111111-0000-0000-0000-000000000000/error + + + FSIOP-Source: dfspa + + + FSIOP-Destination: pispa + + + { + + + errorInformation : { + + + errorCode: "7207", + + + errorDescription: "FSP failed retrieve scopes for consent request" + + + } + + + } + + + + + GRANT-10 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml new file mode 100644 index 000000000..4cbf4dc6d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.puml @@ -0,0 +1,72 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.1 Discovery + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + + +== Discovery (Lookup) == +rnote right of D1 #Light +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +end note +D1 -> S: ""GET /parties/MSISDN/+4412345678"" +S --> D1: ""202 Accepted"" + +... ALS lookup flow not shown here ... + +rnote over S #Light +**""GET /parties/MSISDN/+4412345678""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspb"" +end note +S -> D3: ""GET /parties/MSISDN/+4412345678"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #Light +**""PUT /parties/MSISDN/+4412345678""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: pispa"" +{ + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + party: { + partyIdInfo: { + partyIdType: "MSISDN", + partyIdentifier: "+4412345678", + fspId: 'dfspb", + }, + name: "Bhavesh S.", + } +} +end note +D3 -> S: ""PUT /parties/MSISDN/+4412345678"" +S --> D3: ""200 OK"" +S -> D1: ""PUT /parties/MSISDN/+4412345678"" +D1 --> S: ""200 OK"" + +... PISP confirms payee party with their user ... + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg new file mode 100644 index 000000000..3517b835d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-1-discovery.svg @@ -0,0 +1,156 @@ + + + Transfer: 1.1 Discovery + + + + PISP + + + + Mojaloop + + + + DFSP B + + + + + + + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP B + + + (Payee) + + + + + + Discovery (Lookup) + + + + GET /parties/MSISDN/+4412345678 + + + FSPIOP-Source: pispa + + + + GET /parties/MSISDN/+4412345678 + + + + + 202 Accepted + + + ALS lookup flow not shown here + + + + GET /parties/MSISDN/+4412345678 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspb + + + + GET /parties/MSISDN/+4412345678 + + + + + 202 Accepted + + + + PUT /parties/MSISDN/+4412345678 + + + FSPIOP-Source: dfspb + + + FSPIOP-Destination: pispa + + + { + + + partyIdType: "MSISDN", + + + partyIdentifier: "+4412345678", + + + party: { + + + partyIdInfo: { + + + partyIdType: "MSISDN", + + + partyIdentifier: "+4412345678", + + + fspId: 'dfspb", + + + }, + + + name: "Bhavesh S.", + + + } + + + } + + + + PUT /parties/MSISDN/+4412345678 + + + + + 200 OK + + + + PUT /parties/MSISDN/+4412345678 + + + + + 200 OK + + + PISP confirms payee party with their user + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml new file mode 100644 index 000000000..3d5aabd80 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.puml @@ -0,0 +1,87 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.1 Agreement + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +== Agreement Phase == +rnote right of D1 #Light +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" +D2 -> D2: Lookup the consent for this ""payer"", verify that they exist, and consent \nis granted with a valid credential +D2 -> D2: Store a referece to the ""consentId"" with the ""transactionRequestId"" +D2 -> D2: Generate a unique transactionId for this transaction request:\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg new file mode 100644 index 000000000..4c898f7e1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-1-agreement.svg @@ -0,0 +1,224 @@ + + + Transfer: 1.2.1 Agreement + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + + Agreement Phase + + + + POST /thirdpartyRequests/transactions + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "payer": { + + + "partyIdType": "THIRD_PARTY_LINK", + + + "partyIdentifier": "qwerty-56789", + + + "fspId": "dfspa" + + + }, + + + "amountType": "SEND", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "expiration": "2020-06-15T22:17:28.985-01:00" + + + } + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + + Lookup the consent for this + + + payer + + + , verify that they exist, and consent + + + is granted with a valid credential + + + + Store a referece to the + + + consentId + + + with the + + + transactionRequestId + + + + Generate a unique transactionId for this transaction request: + + + 11111111-0000-0000-0000-000000000000 + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "transactionRequestState": "RECEIVED" + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml new file mode 100644 index 000000000..798e8224b --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.puml @@ -0,0 +1,150 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.2 Authorization + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +rnote left of D2 #Light +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "123456789", + "fspId": "dfspa" + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +rnote left of D2 #Light +**""PUT /quotes/22222222-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "transferAmount": { + "amount": "100", + "currency": "USD" + }, + "payeeReceiveAmount": { + "amount": "99", + "currency": "USD" + }, + "payeeFspFee": { + "amount": "1", + "currency": "USD" + }, + "expiration": "2020-06-15T12:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note left of D2 + DFSP A has the quote, they can now ask + the PISP for authorization +end note + +D2 -> D2: Generate a UUID for the authorization Request:\n""33333333-0000-0000-0000-000000000000"" +D2 -> D2: Derive the challenge based \non ""PUT /quotes/{ID}"" + +rnote left of D2 #Light +**""POST /thirdpartyRequests/authorizations""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "challenge": """", + "transferAmount": {"amount": "100", "currency": "USD"}, + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + "fees": {"amount": "1", "currency": "USD"}, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T12:00:00.000", +} +end note +D2 -> S: ""POST /thirdpartyRequests/authorizations"" +S --> D2: ""202 Accepted"" +S -> D1: ""POST /thirdpartyRequests/authorizations"" +D1 --> S: ""202 Accepted"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg new file mode 100644 index 000000000..a483f8633 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-2-authorization.svg @@ -0,0 +1,396 @@ + + + Transfer: 1.2.2 Authorization + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + DFSP B + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + DFSP B + + + (Payee) + + + + POST /quotes + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "quoteId": "22222222-0000-0000-0000-000000000000", + + + "transactionId": "11111111-0000-0000-0000-000000000000", + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "payer": { + + + "personalInfo": { + + + "complexName": { + + + "firstName": "Ayesha", + + + "lastName": "Takia" + + + } + + + }, + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "123456789", + + + "fspId": "dfspa" + + + }, + + + }, + + + "amountType": "SEND", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "note": "quote note" + + + } + + + + POST /quotes + + + + + 202 Accepted + + + + POST /quotes + + + + + 202 Accepted + + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspb + + + FSPIOP-Destination: dfspa + + + { + + + "transferAmount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "payeeReceiveAmount": { + + + "amount": "99", + + + "currency": "USD" + + + }, + + + "payeeFspFee": { + + + "amount": "1", + + + "currency": "USD" + + + }, + + + "expiration": "2020-06-15T12:00:00.000", + + + "ilpPacket": "...", + + + "condition": "...", + + + } + + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /quotes/22222222-0000-0000-0000-000000000000 + + + + + 200 OK + + + + + DFSP A has the quote, they can now ask + + + the PISP for authorization + + + + Generate a UUID for the authorization Request: + + + 33333333-0000-0000-0000-000000000000 + + + + Derive the challenge based + + + on + + + PUT /quotes/{ID} + + + + POST /thirdpartyRequests/authorizations + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "authorizationRequestId": "33333333-0000-0000-0000-000000000000", + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "challenge": + + + <base64 encoded binary - the encoded challenge> + + + , + + + "transferAmount": {"amount": "100", "currency": "USD"}, + + + "payeeReceiveAmount": {"amount": "99", "currency": "USD"}, + + + "fees": {"amount": "1", "currency": "USD"}, + + + "payer": { + + + "partyIdType": "THIRD_PARTY_LINK", + + + "partyIdentifier": "qwerty-56789", + + + "fspId": "dfspa" + + + }, + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "expiration": "2020-06-15T12:00:00.000", + + + } + + + + POST /thirdpartyRequests/authorizations + + + + + 202 Accepted + + + + POST /thirdpartyRequests/authorizations + + + + + 202 Accepted + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml new file mode 100644 index 000000000..01205b804 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.puml @@ -0,0 +1,76 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Rejected Authorization + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + + + User rejects the terms of the transcationRequest +end note + +rnote right of D1 #Light +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "REJECTED" +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" + +note over D2 + User has rejected the transaction request. +end note + +rnote over D2 #Light +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "REJECTED", + "transactionId": "11111111-0000-0000-0000-000000000000", +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + PISP can inform the user the transaction did not proceed +end note + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg new file mode 100644 index 000000000..0187f0d38 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-rejected-authorization.svg @@ -0,0 +1,165 @@ + + + Transfer: 1.2.3 Rejected Authorization + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + + Agreement Phase + + + + + PISP looks up the + + + transactionRequestId + + + and + + + checks the quote with the user, + + + User rejects the terms of the transcationRequest + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "responseType": "REJECTED" + + + } + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Look up the + + + transactionRequestId + + + for this + + + authorizationId + + + + + User has rejected the transaction request. + + + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "transactionRequestState": "REJECTED", + + + "transactionId": "11111111-0000-0000-0000-000000000000", + + + } + + + + PATCH /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PATCH /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + + PISP can inform the user the transaction did not proceed + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml new file mode 100644 index 000000000..90b1b7b83 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.puml @@ -0,0 +1,74 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Signed Authorization FIDO + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the terms with the user. + + If the user agrees to the terms, the PISP + uses the FIDO API on the user's device to sign the + the **""challenge""** string +end note + +rnote right of D1 #Light +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" + +note over D2 + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg new file mode 100644 index 000000000..789519f61 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg @@ -0,0 +1,187 @@ + + + Transfer: 1.2.3 Signed Authorization FIDO + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + + Agreement Phase + + + + + PISP looks up the + + + transactionRequestId + + + and + + + checks the terms with the user. + + + If the user agrees to the terms, the PISP + + + uses the FIDO API on the user's device to sign the + + + the + + + challenge + + + string + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "responseType": "ACCEPTED" + + + "signedPayload": { + + + "signedPayloadType": "FIDO", + + + "fidoSignedPayload": { + + + "id": "string", + + + "rawId": "string - base64 encoded utf-8", + + + "response": { + + + "authenticatorData": "string - base64 encoded utf-8", + + + "clientDataJSON": "string - base64 encoded utf-8", + + + "signature": "string - base64 encoded utf-8", + + + "userHandle": "string - base64 encoded utf-8", + + + }, + + + "type": "public-key" + + + } + + + } + + + } + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Look up the + + + transactionRequestId + + + for this + + + authorizationId + + + + Look up the + + + consentId + + + for this + + + transactionRequestId + + + + + DFSP has the signed challenge. + + + It now needs to ask the Auth-Service to verify + + + the signed challenge. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml new file mode 100644 index 000000000..28d5c723a --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.puml @@ -0,0 +1,63 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.3 Signed Authorization + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +== Agreement Phase == +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user. + + If the user agrees to the terms, the PISP uses + the Credential's privateKey to sign the challenge +end note + +rnote right of D1 #Light +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" + +note over D2 + DFSP has the signed challenge. + It now needs to ask the Auth-Service to verify + the signed challenge. +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg new file mode 100644 index 000000000..474f7023b --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg @@ -0,0 +1,148 @@ + + + Transfer: 1.2.3 Signed Authorization + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + + Agreement Phase + + + + + PISP looks up the + + + transactionRequestId + + + and + + + checks the quote with the user. + + + If the user agrees to the terms, the PISP uses + + + the Credential's privateKey to sign the challenge + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "responseType": "ACCEPTED" + + + "signedPayload": { + + + "signedPayloadType": "GENERIC", + + + "genericSignedPayload": "utf-8 base64 encoded signature" + + + } + + + } + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Look up the + + + transactionRequestId + + + for this + + + authorizationId + + + + Look up the + + + consentId + + + for this + + + transactionRequestId + + + + + DFSP has the signed challenge. + + + It now needs to ask the Auth-Service to verify + + + the signed challenge. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml new file mode 100644 index 000000000..8bde91c2c --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.puml @@ -0,0 +1,82 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 1.2.4 Verify Authorization + + +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +D2 -> D2: Generate a new ""verificationRequestId"", and associate \n it with the ""thirdpartyTransactionRequestId"" + +rnote left of D2 #Light +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Lookup this consent based on consentId +AUTHS -> AUTHS: Ensure the accountAddress matches what is in Consent +AUTHS -> AUTHS: Check that the signed bytes match the \npublickey we have stored for the consent + +rnote right of AUTHS #Light +**""PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "authenticationResponse": "VERIFIED" +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +note over D2 + DFSPA now knows that the user signed this transaction + and can go ahead and initiate the transfer +end note + + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg new file mode 100644 index 000000000..1c7b39fe0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-2-4-verify-authorization.svg @@ -0,0 +1,196 @@ + + + Transfer: 1.2.4 Verify Authorization + + + + Mojaloop + + + + DFSP A + + + + + Switch + + + + Auth-Service + + + + DFSP A + + + (Payer) + + + + Generate a new + + + verificationRequestId + + + , and associate + + + it with the + + + thirdpartyTransactionRequestId + + + + POST /thirdpartyRequests/verifications + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: central-auth + + + { + + + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + + + "challenge": + + + <base64 encoded binary - the encoded challenge> + + + , + + + "consentId": "123", + + + "signedPayloadType": "FIDO", + + + "fidoValue": { + + + "id": "string", + + + "rawId": "string - base64 encoded utf-8", + + + "response": { + + + "authenticatorData": "string - base64 encoded utf-8", + + + "clientDataJSON": "string - base64 encoded utf-8", + + + "signature": "string - base64 encoded utf-8", + + + "userHandle": "string - base64 encoded utf-8", + + + }, + + + "type": "public-key" + + + } + + + } + + + + POST /thirdpartyRequests/verifications + + + + + 202 Accepted + + + + POST /thirdpartyRequests/verifications + + + + + 202 Accepted + + + + Lookup this consent based on consentId + + + + Ensure the accountAddress matches what is in Consent + + + + Check that the signed bytes match the + + + publickey we have stored for the consent + + + + PUT /thirdpartyRequests/verifications/44444444-0000-0000-0000-000000000000 + + + FSPIOP-Source: central-auth + + + FSPIOP-Destination: dfspa + + + { + + + "authenticationResponse": "VERIFIED" + + + } + + + + PUT /thirdpartyRequests/verifications + + + /44444444-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/verifications + + + /44444444-0000-0000-0000-000000000000 + + + + + 200 OK + + + + + DFSPA now knows that the user signed this transaction + + + and can go ahead and initiate the transfer + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml new file mode 100644 index 000000000..1af60155e --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.puml @@ -0,0 +1,178 @@ +@startuml + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +hide footbox + +title Transfer: 1.3 Final transfer + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box +actor "<$actor>\nPayee" as CB + + + +== Transfer Phase == + +... DFSP A initiates a normal Mojaloop P2P Transfer ... + +D2 -> D2: Generate a new ""transferId"", and associate \n it with the ""transactionRequestId"" + +rnote over D2 #Light +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #Light +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #Light +**""PUT /transfers/55555555-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "fulfilment": "...", + "completedTimestamp": "2020-06-15T12:01:00.000", + "transferState": "COMMITTED" +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +S --> D3: ""200 OK"" +D3 -> CB: You have received funds! +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + + +D2 -> D2: Look up ""transactionRequestId"" from the ""transferId"" + +rnote over D2 #Light +**""PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", + "transactionState": "COMMITTED" +} +end note +D2 -> S: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PATCH /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +note over D1 + PISP can now inform the user the + funds have been sent +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg new file mode 100644 index 000000000..4adab1df0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/1-3-transfer.svg @@ -0,0 +1,309 @@ + + + Transfer: 1.3 Final transfer + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + DFSP B + + + + + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + DFSP B + + + (Payee) + + + + Payee + + + + + + + + Transfer Phase + + + DFSP A initiates a normal Mojaloop P2P Transfer + + + + Generate a new + + + transferId + + + , and associate + + + it with the + + + transactionRequestId + + + + POST /transfers + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "transferId": "55555555-0000-0000-0000-000000000000", + + + "payerFsp": "dfspa", + + + "payeeFsp": "dfspb", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "expiration": "2020-06-15T13:00:00.000", + + + "ilpPacket": "...", + + + "condition": "...", + + + } + + + + POST /transfers + + + + + 202 Accepted + + + + POST /transfers + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "transferId": "55555555-0000-0000-0000-000000000000", + + + "payerFsp": "dfspa", + + + "payeeFsp": "dfspb", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "expiration": "2020-06-15T13:00:00.000", + + + "ilpPacket": "...", + + + "condition": "...", + + + } + + + + POST /transfers + + + + + 202 Accepted + + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspb + + + FSPIOP-Destination: dfspa + + + { + + + "fulfilment": "...", + + + "completedTimestamp": "2020-06-15T12:01:00.000", + + + "transferState": "COMMITTED" + + + } + + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + + + 200 OK + + + + You have received funds! + + + + PUT /transfers/55555555-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Look up + + + transactionRequestId + + + from the + + + transferId + + + + PATCH /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "transactionRequestState": "ACCEPTED", + + + "transactionState": "COMMITTED" + + + } + + + + PATCH /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PATCH /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + + PISP can now inform the user the + + + funds have been sent + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml new file mode 100644 index 000000000..1252be904 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.puml @@ -0,0 +1,90 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.2.1 Bad Thirdparty Transaction Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +== Agreement Phase == +rnote right of D1 #Light +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: DFSP finds something wrong with this transaction request. + + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6104", + "errorDescription": "Thirdparty request rejection", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg new file mode 100644 index 000000000..c62356dfc --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-2-1-bad-tx-request.svg @@ -0,0 +1,207 @@ + + + Transfer: 3.2.1 Bad Thirdparty Transaction Request + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + + Agreement Phase + + + + POST /thirdpartyRequests/transactions + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "payer": { + + + "partyIdType": "THIRD_PARTY_LINK", + + + "partyIdentifier": "qwerty-56789", + + + "fspId": "dfspa" + + + }, + + + "amountType": "SEND", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "expiration": "2020-06-15T22:17:28.985-01:00" + + + } + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + + DFSP finds something wrong with this transaction request. + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "errorInformation": { + + + "errorCode": "6104", + + + "errorDescription": "Thirdparty request rejection", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml new file mode 100644 index 000000000..b6ebf6ce3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.puml @@ -0,0 +1,141 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.3.1 Bad Quote Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +D2 -> D2: Generate a unique transactionId for this transaction request:\n**""11111111-0000-0000-0000-000000000000""** + + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestState": "RECEIVED" +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +rnote left of D2 #Light +**""POST /quotes""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "quoteId": "22222222-0000-0000-0000-000000000000", + "transactionId": "11111111-0000-0000-0000-000000000000", + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "personalInfo": { + "complexName": { + "firstName": "Ayesha", + "lastName": "Takia" + } + }, + "partyIdInfo": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + }, + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "note": "quote note" +} +end note +D2 -> S: ""POST /quotes"" +S --> D2: ""202 Accepted"" +S -> D3: ""POST /quotes"" +D3 --> S: ""202 Accepted"" + +D3 -> D3: Quote fails for some reason. + +rnote left of D3 #Light +**""PUT /quotes/22222222-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /quotes/22222222-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Quote failed, DFSP needs to inform PISP +end note + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream Failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg new file mode 100644 index 000000000..841d82c6d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-1-bad-quote-request.svg @@ -0,0 +1,369 @@ + + + Transfer: 3.3.1 Bad Quote Request + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + DFSP B + + + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + DFSP B + + + (Payee) + + + PISP has initiated Thirdparty Transaction Request with + + + POST /thirdpartyRequests/transactions + + + + Generate a unique transactionId for this transaction request: + + + 11111111-0000-0000-0000-000000000000 + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "transactionId": "11111111-0000-0000-0000-000000000000", + + + "transactionRequestState": "RECEIVED" + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000 + + + + + 200 OK + + + + POST /quotes + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "quoteId": "22222222-0000-0000-0000-000000000000", + + + "transactionId": "11111111-0000-0000-0000-000000000000", + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "payer": { + + + "personalInfo": { + + + "complexName": { + + + "firstName": "Ayesha", + + + "lastName": "Takia" + + + } + + + }, + + + "partyIdInfo": { + + + "partyIdType": "THIRD_PARTY_LINK", + + + "partyIdentifier": "qwerty-56789", + + + "fspId": "dfspa" + + + }, + + + }, + + + }, + + + "amountType": "SEND", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "note": "quote note" + + + } + + + + POST /quotes + + + + + 202 Accepted + + + + POST /quotes + + + + + 202 Accepted + + + + Quote fails for some reason. + + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspb + + + FSPIOP-Destination: dfspa + + + { + + + "errorInformation": { + + + "errorCode": "XXXX", + + + "errorDescription": "XXXX", + + + "extensionList": [] + + + } + + + } + + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /quotes/22222222-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + + Quote failed, DFSP needs to inform PISP + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "errorInformation": { + + + "errorCode": "6003", + + + "errorDescription": "Downstream Failure", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml new file mode 100644 index 000000000..3a7f78799 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.puml @@ -0,0 +1,122 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.3.2 Bad Transfer Request + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box +box "DFSP B" + participant "DFSP B\n(Payee)" as D3 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +... DFSP A has received ""PUT /thirdpartyRequests/verifications from Auth-Service""... + +... DFSP A initiates a normal Mojaloop P2P Transfer ... + +D2 -> D2: Generate a new ""transferId"", and associate \n it with the ""transactionRequestId"" + +rnote over D2 #Light +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +D2 -> S: ""POST /transfers"" +S --> D2: ""202 Accepted"" + +rnote over S #Light +**""POST /transfers""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: dfspb"" +{ + "transferId": "55555555-0000-0000-0000-000000000000", + "payerFsp": "dfspa", + "payeeFsp": "dfspb", + "amount": { + "amount": "100", + "currency": "USD" + }, + "expiration": "2020-06-15T13:00:00.000", + "ilpPacket": "...", + "condition": "...", +} +end note +S -> D3: ""POST /transfers"" +D3 --> S: ""202 Accepted"" + +rnote left of D3 #Light +**""PUT /transfers/55555555-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspb"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "XXXX", + "errorDescription": "XXXX", + "extensionList": [] + } +} +end note +D3 -> S: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +S --> D3: ""200 OK"" +S -> D2: ""PUT /transfers/55555555-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note left of D2 + Transfer failed, DFSP needs to inform PISP +end note + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6003", + "errorDescription": "Downstream failure", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg new file mode 100644 index 000000000..85626c5b2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-3-2-bad-transfer-request.svg @@ -0,0 +1,332 @@ + + + Transfer: 3.3.2 Bad Transfer Request + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + DFSP B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + DFSP B + + + (Payee) + + + PISP has initiated Thirdparty Transaction Request with + + + POST /thirdpartyRequests/transactions + + + DFSP A has received quote, and asked PISP to verify + + + DFSP A has received + + + PUT /thirdpartyRequests/verifications from Auth-Service + + + DFSP A initiates a normal Mojaloop P2P Transfer + + + + Generate a new + + + transferId + + + , and associate + + + it with the + + + transactionRequestId + + + + POST /transfers + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "transferId": "55555555-0000-0000-0000-000000000000", + + + "payerFsp": "dfspa", + + + "payeeFsp": "dfspb", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "expiration": "2020-06-15T13:00:00.000", + + + "ilpPacket": "...", + + + "condition": "...", + + + } + + + + POST /transfers + + + + + 202 Accepted + + + + POST /transfers + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: dfspb + + + { + + + "transferId": "55555555-0000-0000-0000-000000000000", + + + "payerFsp": "dfspa", + + + "payeeFsp": "dfspb", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "expiration": "2020-06-15T13:00:00.000", + + + "ilpPacket": "...", + + + "condition": "...", + + + } + + + + POST /transfers + + + + + 202 Accepted + + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspb + + + FSPIOP-Destination: dfspa + + + { + + + "errorInformation": { + + + "errorCode": "XXXX", + + + "errorDescription": "XXXX", + + + "extensionList": [] + + + } + + + } + + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /transfers/55555555-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + + Transfer failed, DFSP needs to inform PISP + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "errorInformation": { + + + "errorCode": "6003", + + + "errorDescription": "Downstream failure", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml new file mode 100644 index 000000000..5bc586ee2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.puml @@ -0,0 +1,95 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.4.1 Bad Signed Challenge - Self Hosted Auth-Service + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + and uses the FIDO API to sign the + the **""challenge""** string +end note + +rnote right of D1 #Light +**""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Look up the ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Look up the ""consentId"" for this ""transactionRequestId"" +D2 -> D2: Look up the ""publicKey"" for this ConsentId. Check the signing of the signed challenge + +note over D2 + Signed challenge is invalid. Transaction Request failed. +end note + + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg new file mode 100644 index 000000000..213f6fc07 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg @@ -0,0 +1,261 @@ + + + Transfer: 3.4.1 Bad Signed Challenge - Self Hosted Auth-Service + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + + + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + PISP has initiated Thirdparty Transaction Request with + + + POST /thirdpartyRequests/transactions + + + DFSP A has received quote, and asked PISP to verify + + + + + PISP looks up the + + + transactionRequestId + + + and + + + checks the quote with the user, + + + and uses the FIDO API to sign the + + + the + + + challenge + + + string + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "responseType": "ACCEPTED" + + + "signedPayload": { + + + "signedPayloadType": "FIDO", + + + "fidoSignedPayload": { + + + "id": "string", + + + "rawId": "string - base64 encoded utf-8", + + + "response": { + + + "authenticatorData": "string - base64 encoded utf-8", + + + "clientDataJSON": "string - base64 encoded utf-8", + + + "signature": "string - base64 encoded utf-8", + + + "userHandle": "string - base64 encoded utf-8", + + + }, + + + "type": "public-key" + + + } + + + } + + + } + + + + PUT /thirdpartyRequests/authorizations/33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Look up the + + + transactionRequestId + + + for this + + + authorizationId + + + + Look up the + + + consentId + + + for this + + + transactionRequestId + + + + Look up the + + + publicKey + + + for this ConsentId. Check the signing of the signed challenge + + + + + Signed challenge is invalid. Transaction Request failed. + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "errorInformation": { + + + "errorCode": "6201", + + + "errorDescription": "Invalid transaction signature", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml new file mode 100644 index 000000000..ce3645d30 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.puml @@ -0,0 +1,149 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.4.2 Bad Signed Challenge - Hub Hosted Auth-Service + + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S + participant "Auth-Service" as AUTHS +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +... PISP has initiated Thirdparty Transaction Request with ""POST /thirdpartyRequests/transactions""... + +... DFSP A has received quote, and asked PISP to verify... + +note right of D1 + PISP looks up the ""transactionRequestId"" and + checks the quote with the user, + and uses the FIDO API to sign the + the **""challenge""** string +end note + +rnote right of D1 #Light +**""PUT /thirdpartyRequests/authorizations""** +**"" /33333333-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "responseType": "ACCEPTED" + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } + } +} +end note +D1 -> S: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +S --> D1: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/authorizations""\n""/33333333-0000-0000-0000-000000000000"" +D2 --> S: ""200 OK"" + +D2 -> D2: Lookup ""transactionRequestId"" for this ""authorizationId"" +D2 -> D2: Lookup ""consentId"" for this ""transactionRequestId"" + + +D2 -> D2: Generate a new ""verificationRequestId"", and associate \n it with the ""thirdpartyTransactionRequestId"" + +rnote left of D2 #Light +**""POST /thirdpartyRequests/verifications""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: central-auth"" +{ + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + "challenge": """", + "consentId": "123", + "signedPayloadType": "FIDO", + "fidoValue": { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" + } +} +end note +D2 -> S: ""POST /thirdpartyRequests/verifications"" +S --> D2: ""202 Accepted"" +S -> AUTHS: ""POST /thirdpartyRequests/verifications"" +AUTHS --> S: ""202 Accepted"" + +AUTHS -> AUTHS: Lookup this consent based on consentId +AUTHS -> AUTHS: Ensure the accountAddress matches what is in Consent +AUTHS -> AUTHS: Check that the signed bytes match the \npublickey we have stored for the consent + +rnote right of AUTHS #Light +**""PUT /thirdpartyRequests/verifications""** +**"" /44444444-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: central-auth"" +""FSPIOP-Destination: dfspa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +AUTHS -> S: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +S --> AUTHS: ""200 OK"" +S -> D2: ""PUT /thirdpartyRequests/verifications""\n"" /44444444-0000-0000-0000-000000000000/error"" +D2 --> S: ""200 OK"" + +note over D2 + Signed challenge is invalid. Transaction Request failed. +end note + + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions""** +**"" /00000000-0000-0000-0000-000000000000/error""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "errorInformation": { + "errorCode": "6201", + "errorDescription": "Invalid transaction signature", + "extensionList": [] + } +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +S --> D2: ""200 OK"" +S -> D1: ""PUT /thirdpartyRequests/transactions""\n"" /00000000-0000-0000-0000-000000000000/error"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg new file mode 100644 index 000000000..58c8e9957 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg @@ -0,0 +1,439 @@ + + + Transfer: 3.4.2 Bad Signed Challenge - Hub Hosted Auth-Service + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + + + + + + + + + + + + + + + + + PISP Server + + + + Switch + + + + Auth-Service + + + + DFSP A + + + (Payer) + + + PISP has initiated Thirdparty Transaction Request with + + + POST /thirdpartyRequests/transactions + + + DFSP A has received quote, and asked PISP to verify + + + + + PISP looks up the + + + transactionRequestId + + + and + + + checks the quote with the user, + + + and uses the FIDO API to sign the + + + the + + + challenge + + + string + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "responseType": "ACCEPTED" + + + "signedPayload": { + + + "signedPayloadType": "FIDO", + + + "fidoSignedPayload": { + + + "id": "string", + + + "rawId": "string - base64 encoded utf-8", + + + "response": { + + + "authenticatorData": "string - base64 encoded utf-8", + + + "clientDataJSON": "string - base64 encoded utf-8", + + + "signature": "string - base64 encoded utf-8", + + + "userHandle": "string - base64 encoded utf-8", + + + }, + + + "type": "public-key" + + + } + + + } + + + } + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + PUT /thirdpartyRequests/authorizations + + + /33333333-0000-0000-0000-000000000000 + + + + + 200 OK + + + + Lookup + + + transactionRequestId + + + for this + + + authorizationId + + + + Lookup + + + consentId + + + for this + + + transactionRequestId + + + + Generate a new + + + verificationRequestId + + + , and associate + + + it with the + + + thirdpartyTransactionRequestId + + + + POST /thirdpartyRequests/verifications + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: central-auth + + + { + + + "verificationRequestId": "44444444-0000-0000-0000-000000000000", + + + "challenge": + + + <base64 encoded binary - the encoded challenge> + + + , + + + "consentId": "123", + + + "signedPayloadType": "FIDO", + + + "fidoValue": { + + + "id": "string", + + + "rawId": "string - base64 encoded utf-8", + + + "response": { + + + "authenticatorData": "string - base64 encoded utf-8", + + + "clientDataJSON": "string - base64 encoded utf-8", + + + "signature": "string - base64 encoded utf-8", + + + "userHandle": "string - base64 encoded utf-8", + + + }, + + + "type": "public-key" + + + } + + + } + + + + POST /thirdpartyRequests/verifications + + + + + 202 Accepted + + + + POST /thirdpartyRequests/verifications + + + + + 202 Accepted + + + + Lookup this consent based on consentId + + + + Ensure the accountAddress matches what is in Consent + + + + Check that the signed bytes match the + + + publickey we have stored for the consent + + + + PUT /thirdpartyRequests/verifications + + + /44444444-0000-0000-0000-000000000000/error + + + FSPIOP-Source: central-auth + + + FSPIOP-Destination: dfspa + + + { + + + "errorInformation": { + + + "errorCode": "6201", + + + "errorDescription": "Invalid transaction signature", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/verifications + + + /44444444-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/verifications + + + /44444444-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + + Signed challenge is invalid. Transaction Request failed. + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "errorInformation": { + + + "errorCode": "6201", + + + "errorDescription": "Invalid transaction signature", + + + "extensionList": [] + + + } + + + } + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + + + PUT /thirdpartyRequests/transactions + + + /00000000-0000-0000-0000-000000000000/error + + + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml new file mode 100644 index 000000000..dfcae6698 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.puml @@ -0,0 +1,77 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title Transfer: 3.Thirdparty Transaction Request Times Out + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + + +rnote right of D1 #Light +**""POST /thirdpartyRequests/transactions""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +{ + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + "payee": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "+4412345678", + "fspId": "dfspb" + } + }, + "payer": { + "partyIdType": "THIRD_PARTY_LINK", + "partyIdentifier": "qwerty-56789", + "fspId": "dfspa" + }, + "amountType": "SEND", + "amount": { + "amount": "100", + "currency": "USD" + }, + "transactionType": { + "scenario": "TRANSFER", + "initiator": "PAYER", + "initiatorType": "CONSUMER" + }, + "expiration": "2020-06-15T22:17:28.985-01:00" +} +end note +D1 -> S: ""POST /thirdpartyRequests/transactions"" +S --> D1: ""202 Accepted"" +S -> D2: ""POST /thirdpartyRequests/transactions"" +D2 --> S: ""202 Accepted"" + + +... DFSP doesn't respond for some reason... + + +D1 -> D1: Thirdparty Transaction Request expiration reached + +note over D1 + PISP informs their user that the transaction failed. + +end note + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg new file mode 100644 index 000000000..e9ba78514 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/3-6-tpr-timeout.svg @@ -0,0 +1,157 @@ + + + Transfer: 3.Thirdparty Transaction Request Times Out + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + + + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + POST /thirdpartyRequests/transactions + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + { + + + "transactionRequestId": "00000000-0000-0000-0000-000000000000", + + + "payee": { + + + "partyIdInfo": { + + + "partyIdType": "MSISDN", + + + "partyIdentifier": "+4412345678", + + + "fspId": "dfspb" + + + } + + + }, + + + "payer": { + + + "partyIdType": "THIRD_PARTY_LINK", + + + "partyIdentifier": "qwerty-56789", + + + "fspId": "dfspa" + + + }, + + + "amountType": "SEND", + + + "amount": { + + + "amount": "100", + + + "currency": "USD" + + + }, + + + "transactionType": { + + + "scenario": "TRANSFER", + + + "initiator": "PAYER", + + + "initiatorType": "CONSUMER" + + + }, + + + "expiration": "2020-06-15T22:17:28.985-01:00" + + + } + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + + POST /thirdpartyRequests/transactions + + + + + 202 Accepted + + + DFSP doesn't respond for some reason + + + + Thirdparty Transaction Request expiration reached + + + + + PISP informs their user that the transaction failed. + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml new file mode 100644 index 000000000..c8ca6b83b --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.puml @@ -0,0 +1,67 @@ +@startuml + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +hide footbox + +title PISPGetTransactionRequest + +box "PISP" +participant "PISP Server" as D1 +end box +box "Mojaloop" + participant Switch as S +end box +box "DFSP A" + participant "DFSP A\n(Payer)" as D2 +end box + +autonumber 1 "GTR-#" + +note over S + Assuming a previously created thirdparty transaction request with id: ""00000000-0000-0000-0000-000000000000"" + +end note + + + +rnote right of D1 #Light +**""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: pispa"" +""FSPIOP-Destination: dfspa"" +end note + +D1 -> S: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D1: ""202 Accepted"" + +S -> D2: ""GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D2 --> S: ""202 Accepted"" + +D2 -> D2: DFSP looks up already created \nthirdparty transaction request +D2 -> D2: DFSP ensures that the FSPIOP-Source (pisp)\nis the same as the original sender of \n""POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" + +rnote left of D2 #Light +**""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000""** +""FSPIOP-Source: dfspa"" +""FSPIOP-Destination: pispa"" +{ + "transactionRequestState": "ACCEPTED", +} +end note +D2 -> S: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +S --> D2: ""200 OK"" + +S -> D1: ""PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000"" +D1 --> S: ""200 OK"" + +@enduml diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg new file mode 100644 index 000000000..ffaa28ada --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/assets/diagrams/transfer/get_transaction_request.svg @@ -0,0 +1,153 @@ + + + PISPGetTransactionRequest + + + + PISP + + + + Mojaloop + + + + DFSP A + + + + + PISP Server + + + + Switch + + + + DFSP A + + + (Payer) + + + + + Assuming a previously created thirdparty transaction request with id: + + + 00000000-0000-0000-0000-000000000000 + + + + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: pispa + + + FSPIOP-Destination: dfspa + + + + GTR-1 + + + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + + + GTR-2 + + + 202 Accepted + + + + GTR-3 + + + GET /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + + + GTR-4 + + + 202 Accepted + + + + GTR-5 + + + DFSP looks up already created + + + thirdparty transaction request + + + + GTR-6 + + + DFSP ensures that the FSPIOP-Source (pisp) + + + is the same as the original sender of + + + POST /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + FSPIOP-Source: dfspa + + + FSPIOP-Destination: pispa + + + { + + + "transactionRequestState": "ACCEPTED", + + + } + + + + GTR-7 + + + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + + + GTR-8 + + + 200 OK + + + + GTR-9 + + + PUT /thirdpartyRequests/transactions/00000000-0000-0000-0000-000000000000 + + + + + GTR-10 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md b/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md new file mode 100644 index 000000000..d9afaea7d --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md @@ -0,0 +1,990 @@ +# Data Models + +Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Third Party API Elements](#ThirdPartyAPIElements) + 3.1 [Resources](#Resources) + 3.2 [Data Models](#DataModels) + 3.3 [Error Codes](#ErrorCodes) +# 1. Preface +This section contains information about how to use this document. + +## 1.1 Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2 Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3 References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document specifies the data model used by the Mojaloop Third Party API ("the API"). + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Third Party API Elements + +This section describes the content of the API which will be used by PISPs and DFSPs. + +The content of the API falls into two sections: + +1. [Transaction Patterns - Linking](./transaction-patterns-linking.md) describes the process for linking customer accounts and providing a general permission mechanism for PISPs to perform operations on those accounts +2. [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) describes the transfer of funds at the instigation of a PISP. + +The API is used by the following different types of participant, as follows: + 1. PISPs + 2. DFSPs who offer services to their customer which allow the customer to access their account via one or more PISPs + 3. Auth-Services + 4. The Mojaloop switch + +Each resource in the API definition is accompanied by a definition of the type(s) of participant allowed to access it. + +## 3.1 Resources + +The API contains the following resources: + +### 3.1.1 **/accounts** + +The **/accounts** resource is used to request information from a DFSP relating to the accounts +it holds for a given identifier. The identifier is a user-provided value which the user +uses to access their account with the DFSP, such as a phone number, email address, or +some other identifier previously provided by the DFSP. + +The DFSP returns a set of information about the accounts it is prepared to divulge to the PISP. +The PISP can then display the names of the accounts to the user, and allow the user to select +the accounts with which they wish to link via the PISP. + +The **/accounts** resource supports the endpoints described below. + +#### 3.1.1.1 Requests + +This section describes the services that a PISP can request on the /accounts resource. + +##### 3.1.1.1.1 **GET /accounts/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /accounts/**_{ID}_ is used to lookup information about the requested +user's accounts, defined by an identifier *{ID}*, where *{ID}* is an identifier a user +uses to access their account with the DFSP, such as a phone number, email address, or +some other identifier previously provided by the DFSP. + +Callback and data model information for **GET /accounts/**_{ID}_: +- Callback - **PUT /accounts/**_{ID}_ +- Error Callback - **PUT /accounts/**_{ID}_**/error** +- Data Model – Empty body + +#### 3.1.1.2 Callbacks + +The responses for the **/accounts** resource are as follows + +##### 3.1.1.2.1 **PUT /accounts/**_{ID}_ + +Used by: DFSP + +The **PUT /accounts/**_{ID}_ response is used to inform the requester of the result of a request +for accounts information. The identifier ID given in the call are the +values given in the original request (see Section 3.1.1.1.1 above.) + +The data content of the message is given below. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| accountList | 1 | AccountList | Information about the accounts that the DFSP associates with the identifier sent by the PISP. | + +##### 3.1.1.2.2 **PUT /accounts/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /accounts/**_{ID}_**/error** response is used to inform the requester that an account list +request has given rise to an error. The identifier ID given in the call are +the values given in the original request (see Section 3.1.1.1.1 above.) + +The data content of the message is given below. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.2 **/consentRequests** + +The **/consentRequests** resource is used by a PISP to initiate the process of linking with a DFSP’s +account on behalf of a user. The PISP contacts the DFSP and sends a list of the permissions that +it wants to obtain and the accounts for which it wants permission. + +#### 3.1.2.1 Requests + +This section describes the services that can be requested by a client on the API resource +**/consentRequests**. +##### 3.1.2.1.1 **GET /consentRequests/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /consentRequests/**_{ID}_ is used to get information about a previously +requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the +request by the PISP when the PISP originated the request. + +Callback and data model information for **GET /consentRequests/**_{ID}_: +- Callback – **PUT /consentRequests/**_{ID}_ +- Error Callback – **PUT /consentRequests/**_{ID}_**/error** +- Data Model – Empty body + +##### 3.1.2.1.2 **POST /consentRequests** + +Used by: PISP + +The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more +accounts owned by a customer of the DFSP for the PISP who sends the request. + +Callback and data model for **POST /consentRequests**: +- Callback: **PUT /consentRequests/**_{ID}_ +- Error callback: **PUT /consentRequests/**_{ID}_**/error** +- Data model – see below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| consentRequestId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the consent request object. The ID should be reused for resends of the same consent request. A new ID should be generated for each new consent request. | +| userId | 1 | String(1..128) | The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest` | +| scopes | 1..256 | Scope | One or more requests for access to a particular account. In each case, the address of the account and the types of access required are given. | +| authChannels | 1..256 | ConsentRequestChannelType | A collection of the types of authentication that the DFSP may use to verify that its customer has in fact requested access for the PISP to the accounts requested. | +| callbackUri | 1 | Uri | The callback URI that the user will be redirected to after completing verification via the WEB authorization channel. This field is mandatory as the PISP does not know ahead of time which AuthChannel the DSFP will use to authenticate their user. | + +#### 3.1.2.2 Callbacks + +This section describes the callbacks that are used by the server under the resource /consentRequests. + +##### 3.1.2.2.1 **PUT /consentRequests/**_{ID}_ + +Used by: DFSP + +A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, +and (2) communicate to the PISP which `authChannel` it should use to authenticate their user +with. + +When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all +the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization +process may result in additional privileges being granted by the account holder to the PISP. The +**PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a +particular authorization request. The data model for this call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopes | 1..256 | Scope | One or more requests for access to a particular account. In each case, the address of the account and the types of access required are given. | +| authChannels | 1 | ConsentRequestChannelType | A list of one element, which the DFSP uses to inform the PISP of the selected authorization channel. | +| callbackUri | 0..1 | Uri |The callback URI that the user will be redirected to after completing verification via the WEB authorization channel | +| authUri | 0..1 | Uri | The URI that the PISP should call to complete the linking procedure if completion is required. | + + +##### 3.1.2.2.2 **PATCH /consentRequests/**_{ID}_ + +Used by: PISP + +After the user completes an out-of-band authorization with the DFSP, the PISP will receive +a token which they can use to prove to the DFSP that the user trusts this PISP. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authToken | 1 | BinaryString |The token given to the PISP by the DFSP as part of the out-of-band authentication process | + +#### 3.1.2.3 Error callbacks + +This section describes the error callbacks that are used by the server under the resource +**/consentRequests**. + +##### 3.1.2.3.1 **PUT /consentRequests/**_{ID}_**/error** + +Used by: DFSP + +If the server is unable to complete the consent request, or if an out-of-band processing error or +another processing error occurs, the error callback **PUT /consentRequests/**_{ID}_**/error** is used. The +*{ID}* in the URI should contain the *{ID}* that was used in the **GET /consentRequests/**_{ID}_ +request or the **POST /consentRequests** request. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + + +### 3.1.3 **/consents** + +The **/consents** resource is used to negotiate a series of permissions between the PISP and the +DFSP which owns the account(s) on behalf of which the PISP wants to transact. + +A **/consents** call is originally sent to the PISP by the DFSP following the original consent +request process described in Section 3.1.2.1.2 above. At the close of this process, the DFSP +which owns the customer’s account(s) will have satisfied itself that its customer really has +requested that the PISP be allowed access to their accounts, and will have defined the accounts in +question and the type of access which is to be granted. +#### 3.1.3.1 Requests +The **/consents** resource will support the following requests. +##### 3.1.3.1.1 **GET /consents/**_{ID}_ + +Used by: DFSP + +The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The +*{ID}* used in the URI of the request should be the consent request ID which was used to identify +the consent when it was created. + +Callback and data model information for **GET /consents/**_{ID}_: +- Callback – **PUT /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.3.1.2 **POST /consents** + +Used by: DFSP + +The **POST /consents** request is used to request the creation of a consent for interactions between +a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + +Callback and data model information for **POST /consents/**: + +- Callback – **PUT /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** +- Data Model – defined below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| consentId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the consent object. The ID should be reused for resends of the same consent. A new ID should be generated for each new consent.| +| consentRequestId | 1 | CorrelationId | The ID given to the original consent request on which this consent is based. | +| scopes | 1..256 | Scope | A list Scope objects, which represent the accounts and attached permissions on which the DFSP is prepared to grant specified permissions to the PISP. | +| status | 1 | ConsentStatus | The status of the Consent. | +| credential | 0..1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment | +##### 3.1.3.1.3 **DELETE /consents/**_{ID}_ + +Used by PISP, DFSP + +The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. +For tracing and auditing purposes, the switch should be sure not to delete the consent physically; +instead, information relating to the consent should be marked as deleted and requests relating to the +consent should not be honoured. + +> Note: the ALS should verify that the participant who is requesting the deletion is either the +> initiator named in the consent or the account holding institution named in the consent. If any +> other party attempts to delete a consent, the request should be rejected, and an error raised. + +Callback and data model information for **DELETE /consents/**_{ID}_: +- Callback – **PATCH /consents/**_{ID}_ +- Error Callback – **PUT /consents/**_{ID}_**/error** + +#### 3.1.3.2 Callbacks +The **/consents** resource supports the following callbacks: +##### 3.1.3.2.1 **PATCH/consents/**_{ID}_ + +Used by: Auth-Service, DFSP + +**PATCH /consents/**_{ID}_ is used in 2 places: +1. To inform the PISP that the `consent.credential` is valid and the account linking process completed + successfully. +2. To inform the PISP or the DFSP that the Consent has been revoked. + +In the first case, a DFSP sends a **PATCH/consents/**_{ID}_ request to the PISP with a `credential.status` +of `VERIFIED`. + +In the second case, an Auth-Service or DFSP sends a **PATCH/consents/**_{ID}_ request with a `status` of +`REVOKED`, and the `revokedAt` field set. + +The syntax of this call complies with the JSON Merge Patch specification [RFC-7386](https://datatracker.ietf.org/doc/html/rfc7386) +rather than the JSON Patch specification [RFC-6902](https://datatracker.ietf.org/doc/html/rfc6902). +The **PATCH /consents/**_{ID}_ resource contains a set of proposed changes to the current state of the +permissions relating to a particular authorization grant. The data model +for this call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| status | 0..1 | ConsentStatus | The status of the Consent. | +| revokedAt | 0..1 | DateTime | The DateTime the consent was revoked at. | +| credential | 0..1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | + +##### 3.1.3.2.2 **PUT /consents/**_{ID}_ + +Used by: PISP + +The **PUT /consents/**_{ID}_ resource is used to return information relating to the consent object +whose `consentId` is given in the URI. And for registering a credential for the consent. The +data returned by the call is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopes | 1..256 | Scope | The scopes covered by the consent. | +| status | 0..1 | ConsentStatus | The status of the Consent. | +| credential | 1 | Credential | The credential which is being used to support the consents. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | +#### 3.1.3.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource **/consents**. +##### 3.1.3.3.1 **PUT /consents/**_{ID}_**/error** + +Used by: PISP, DFSP, Auth-Service + +If the server is unable to complete the consent, or if an out-of-loop processing error or another +processing error occurs, the error callback **PUT /consents/**_{ID}_**/error** is used. The *{ID}* in the +URI should contain the *{ID}* that was used in the **GET /consents/**_{ID}_ request or the +**POST /consents** request. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.4 **/parties** + +The **/parties** resource will be used by the PISP to identify a party to a transfer. This will be +used by the PISP to identify the payee DFSP when it requests a transfer. + +The PISP will be permitted to issue a **PUT /parties** response. Although it does not own any +transaction accounts, there are circumstances in which another party may want to pay a customer +via their PISP identification: for instance, where the customer is at a merchant’s premises and +tells the merchant that they would like to pay via their PISP app. In these circumstances, the PISP +will need to be able to confirm that it does act for the customer. +#### 3.1.4.1 Requests + +The **/parties** resource will support the following requests. +##### 3.1.4.1.1 **GET /parties** + +Used by: PISP + +The **GET /parties** resource will use the same form as the resource described in +[Section 6.3.3.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6331-get-partiestypeid) of Ref. 1 above. +#### 3.1.4.2 Callbacks +The parties resource will support the following callbacks. +##### 3.1.4.2.1 **PUT /parties** + +Used by: DFSP + +The **PUT /parties** resource will use the same form as the resource described in +[Section 6.3.4.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6341-put-partiestypeid) of Ref. 1 above. + +### 3.1.5 **/services** +The **/services** resource is a new resource which enables a participant to query for other +participants who offer a particular service. The requester will issue a `GET` request, specifying +the type of service for which information is required as part of the query string. The switch will +respond with a list of the current DFSPs in the scheme which are registered as providing that +service. +#### 3.1.5.1 Requests +The services resource will support the following requests. +#### 3.1.5.2 **GET /services/**_{ServiceType}_ + +Used by: DFSP, PISP + +The HTTP request **GET /services/**_{ServiceType}_ is used to find out the names of the participants in a +scheme which provide the type of service defined in the *{ServiceType}* parameter. The *{ServiceType}* parameter +should specify a value from the ServiceType enumeration. If it does not, the request will be +rejected with an error. + +Callback and data model information for **GET /services/**_{ServiceType}_: +- Callback - **PUT /services/**_{ServiceType}_ +- Error Callback - **PUT /services/**_{ServiceType}_**/error** +- Data Model – Empty body +#### 3.1.5.3 Callbacks +This section describes the callbacks that are used by the server for services provided by the +resource **/services**. +##### 3.1.5.3.1 **PUT /services/**_{ServiceType}_ + +Used by: Switch + +The callback **PUT /services/**_{ServiceType}_ is used to inform the client of a successful result of +the service information lookup. The information is returned in the following form: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| providers | 0...256 | FspId | A list of the Ids of the participants who provide the service requested. | + +##### 3.1.5.3.2 **PUT /services/**_{ServiceType}_**/error** + +Used by: Switch + +If the server encounters an error in fulfilling a request for a list of participants who +provide a service, the error callback **PUT /services/**_{ServiceType}_**/error** is used to inform the +client that an error has occurred. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +### 3.1.6 **thirdpartyRequests/authorizations** + +The **/thirdpartyRequests/authorizations** resource is analogous to the **/authorizations** resource + described in [Section 6.6](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#66-api-resource-authorizations) of Ref. 1 above. The DFSP uses it to request the PISP to: + +1. Display the information defining the terms of a proposed transfer to its customer; +2. Obtain the customer’s confirmation that they want the transfer to proceed; +3. Return a signed version of the terms which the DFSP can use to verify the consent + +The **/thirdpartyRequests/authorizations** resource supports the endpoints described below. +#### 3.1.6.1 Requests + +This section describes the services that a client can request on the +**/thirdpartyRequests/authorizations** resource. +##### 3.1.6.1.1 **GET /thirdpartyRequests/authorizations/**_{ID}_ + +Used by: DFSP + +The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating +to a previously issued authorization request. The *{ID}* in the request should match the +`authorizationRequestId` which was given when the authorization request was created. + +Callback and data model information for **GET /thirdpartyRequests/authorizations/**_{ID}_: +- Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.6.1.2 **POST /thirdpartyRequests/authorizations** + +Used by: DFSP + +The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a + customer for the transfer described in the request. + +Callback and data model information for **POST /thirdpartyRequests/authorizations:** + +- Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** +- Data Model – See Table below + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authorizationRequestId | 1 | CorrelationId | Common ID between the PISP and the Payer DFSP for the authorization request object. The ID should be reused for resends of the same authorization request. A new ID should be generated for each new authorization request. | +| transactionRequestId | 1 | CorrelationId | The unique identifier of the transaction request for which authorization is being requested. | +| challenge | 1 | BinaryString | The challenge that the PISP’s client is to sign. | +| transferAmount | 1 | Money | The amount that will be debited from the sending customer’s account as a consequence of the transaction. | +| payeeReceiveAmount | 1 | Money | The amount that will be credited to the receiving customer’s account as a consequence of the transaction. | +| fees | 1 | Money | The amount of fees that the paying customer will be charged as part of the transaction. | +| payer | 1 | PartyIdInfo | Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| payee | 1 | Party | Information about the Payee in the proposed transaction | +| transactionType | 1 | TransactionType | The type of the transaction. | +| expiration | 1 | DateTime | The time by which the transfer must be completed, set by the payee DFSP. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment. | + +#### 3.1.6.2 Callbacks +The following callbacks are supported for the **/thirdpartyRequests/authorizations** resource +##### 3.1.6.2.1 **PUT /thirdpartyRequests/authorizations/**_{ID}_ + +Used by: PISP + +After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the +transaction to their user, and request that the client sign the `challenge` field using the credential +they previously registered. + +The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| responseType | 1 | AuthorizationResponseType | `ACCEPTED` or `REJECTED` | +| signedPayload | 0..1 | SignedPayload | If the `responseType` is `ACCEPTED`, `signedPayload` is required. | + +#### 3.1.6.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/authorizations**. +##### 3.1.6.3.1 **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /thirdpartyRequests/authorizations/**_{ID}_**/error** resource will have the same content +as the **PUT /authorizations/**_{ID}_**/error** resource described in [Section 6.6.5.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6651-put-authorizationsiderror) +of Ref. 1 above. +### 3.1.7 **/thirdpartyRequests/transactions** +The **/thirdpartyRequests/transactions` resource is analogous to the `/transactionRequests** +resource described in [Section 6.4](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#64-api-resource-transactionrequests) of Ref. 1 above. The PISP uses it to request the +owner of the PISP’s customer’s account to transfer a specified amount from the customer’s +account with the DFSP to a named Payee. + +The **/thirdpartyRequests/transactions** resource supports the endpoints described below. +#### 3.1.7.1 Requests + +This section describes the services that a client can request on the +**/thirdpartyRequests/transactions** resource. +##### 3.1.7.1.1 **GET /thirdpartyRequests/transactions/**_{ID}_ + +Used by: PISP + +The HTTP request **GET /thirdpartyRequests/transactions/**_{ID}_ is used to get information +relating to a previously issued transaction request. The *{ID}* in the request should +match the `transactionRequestId` which was given when the transaction request was created. + +Callback and data model information for **GET /thirdpartyRequests/transactions/**_{ID}_: +- Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.7.1.2 **POST /thirdpartyRequests/transactions** + +Used by: PISP + +The HTTP request **POST /thirdpartyRequests/transactions** is used to request the creation +of a transaction request on the server for the transfer described in the request. + +Callback and data model information for **POST /thirdpartyRequests/transactions**: +- Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** +- Data Model – See Table below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| transactionRequestId | 1 | CorrelationId |Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. | +| payee | 1 | Party |Information about the Payee in the proposed financial transaction. | +| payer | 1 | PartyIdInfo |Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction. | +| amountType | 1 | AmountType | SEND for send amount, RECEIVE for receive amount. | +| amount | 1 | Money | Requested amount to be transferred from the Payer to Payee. | +| transactionType | 1 | TransactionType |Type of transaction | +| note | 0..1 | Note | Memo assigned to Transaction. | +| expiration | 0..1 | DateTime |Can be set to get a quick failure in case the peer FSP takes too long to respond. Also, it may be beneficial for Consumer, Agent, Merchant to know that their request has a time limit. | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment. | +#### 3.1.7.2 Callbacks +The following callbacks are supported for the **/thirdpartyRequests/transactions** resource +##### 3.1.7.2.1 **PUT /thirdpartyRequests/transactions/**_{ID}_ + +Used by: DFSP + +After a PISP requests the creation of a Third Party Transaction request (**POST /thirdpartyRequests/transactions**) +or the status of a previously created Third Party Transaction request +(**GET /thirdpartyRequests/transactions/**_{ID}_), the DFSP will send this callback. + +The data model for this endpoint is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| transactionRequestState | 1 | TransactionRequestState | State of the transaction request. | +| extensionList | 0..1 | ExtensionList | Optional extension, specific to deployment | + +##### 3.1.7.2.2 **PATCH /thirdpartyRequests/transactions/**_{ID}_ + +Used by: DFSP + +The issuing PISP will expect a response to their request for a transfer which describes +the finalised state of the requested transfer. This response will be given by a `PATCH` call on the +**/thirdpartyRequests/transactions/**_{ID}_ resource. The *{ID}* given in the query string should be +the `transactionRequestId` which was originally used by the PISP to identify the transaction +request (see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above.) + +The data model for this endpoint is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| completedTimestamp | 0..1 | DateTime |Time and date when the transaction was completed, if it was completed. | +| transactionRequestState | 1 | TransactionRequestState | State of the transaction request | +| transactionState | 1 | TransactionState | State of the transaction created by the DFSP in response to this transaction request | +| extensionList | 0..1 | ExtensionList |Optional extension, specific to deployment | + +#### 3.1.7.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/transactions**. +##### 3.1.7.3.1 **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** + +Used by: DFSP + +The **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** resource will have the same content as +the **PUT /transactionRequests/**_{ID}_**/error** resource described in [Section 6.4.5.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#6451-put-transactionrequestsiderror) of Ref. 1 above. + +### 3.1.8 **/thirdpartyRequests/verifications** + +The **/thirdpartyRequests/verifications** resource is used by a Payer DFSP to verify that an authorization +response received from a PISP was signed using the correct private key, in cases where the authentication service +to be used is implemented by the switch and not internally by the DFSP. The DFSP sends the original +challenge and the signed response to the authentication service, together with the `consentId` to be used +for the verification. The authentication service compares the response with the result of signing the +challenge with the private key associated with the `consentId`, and, if the two match, it returns a +positive result. Otherwise, it returns an error. + +The **/thirdpartyRequests/verifications** resource supports the endpoints described below. +#### 3.1.8.1 Requests +This section describes the services that a client can request on the **/thirdpartyRequests/verifications** +resource. +##### 3.1.8.1.1 **GET /thirdpartyRequests/verifications/**_{ID}_ + +Used by: DFSP + +The HTTP request **/thirdpartyRequests/verifications/**_{ID}_ is used to get information regarding a previously +created or requested authorization. The *{ID}* in the URI should contain the verification request ID +(see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) below) that was used for the creation of the transfer.Callback and data model +information for **GET /thirdpartyRequests/verifications/**_{ID}_: + +- Callback – **PUT /thirdpartyRequests/verifications/**_{ID}_ +- Error Callback – **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** +- Data Model – Empty body +##### 3.1.8.1.2 **POST /thirdpartyRequests/verifications** + +Used by: DFSP + +The **POST /thirdpartyRequests/verifications** resource is used to request confirmation from an authentication +service that a challenge has been signed using the correct private key. + +Callback and data model information for **POST /thirdpartyRequests/verifications**: +- Callback - **PUT /thirdpartyRequests/verifications/**_{ID}_ +- Error Callback - **PUT /thirdpartyRequests/verifications /**_{ID}_**/error** +- Data Model – See Table below + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| verificationRequestId | 1 | CorrelationId |Common ID between the DFSP and authentication service for the verification request object. The ID should be reused for resends of the same authorization request. A new ID should be generated for each new authorization request. | +| challenge | 1 | BinaryString |The challenge originally sent to the PISP | +| consentId | 1 | CorrelationId |Common Id between the DFSP and the authentication service for the agreement against which the authentication service is to evaluate the signature | +| signedPayloadType | 1 | SignedPayloadType | The type of the SignedPayload, depending on the type of credential registered by the PISP | +| genericSignedPayload | 0..1 | BinaryString | Required if signedPayloadType is GENERIC. The signed challenge returned by the PISP. A BinaryString representing a signature of the challenge + private key of the credential. | +| fidoSignedPayload | 0..1 | FIDOPublicKeyCredentialAssertion | Required if signedPayloadType is FIDO. The signed challenge returned by the PISP in the form of a [`FIDOPublicKeyCredentialAssertion` Object](https://w3c.github.io/webauthn/#iface-pkcredential) | + +#### 3.1.8.2 Callbacks +This section describes the callbacks that are used by the server under the resource +**/thirdpartyRequests/verifications** +##### 3.1.8.2.1 **PUT /thirdpartyRequests/verifications/**_{ID}_ + +Used by: Auth Service + +The callback **PUT /thirdpartyRequests/verifications/**_{ID}_ is used to inform the client of the result +of an authorization check. The *{ID}* in the URI should contain the `authorizationRequestId` +(see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above) which was used to request the check, or the *{ID}* that was +used in the **GET /thirdpartyRequests/verifications/**_{ID}_. The data model for this resource is as follows: + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authenticationResponse | 1 | AuthenticationResponse | The result of the authorization check. | +#### 3.1.8.3 Error callbacks +This section describes the error callbacks that are used by the server under the resource +**/thirdpartyRequests/verifications**. +##### 3.1.8.3.1 **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** + +Used by: Auth Service + +If the server is unable to complete the authorization request, or another processing error occurs, the +error callback **PUT /thirdpartyRequests/verifications/**_{ID}_**/error** is used.The *{ID}* in the URI should +contain the `verificationRequestId` (see [Section 3.1.8.1.2](#31812-post-thirdpartyrequestsverifications) above) which was used to request the +check, or the *{ID}* that was used in the **GET /thirdpartyRequests/verifications/**_{ID}_. + +The data model for this resource is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| errorInformation | 1 | ErrorInformation | Information describing the error and error code. | + +## 3.2 Data Models + +The following additional data models will be required to support the Third Party API + +### 3.2.1 Element definitions +#### 3.2.1.1 Account + +The Account data model contains information relating to an account. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| address | 1 | AccountAddress | An address which can be used to identify the account | +| currency | 1 | Currency | The currency in which the account is denominated | +| accountNickname | 0..1 | Name | Display name of the account, as set by the account owning DFSP. This will normally be a type name, such as “Transaction Account” or “Savings Account” | +#### 3.2.1.2 AccountAddress + +The AccountAddress data type is a variable length string with a maximum size of 1023 characters and consists of: +- Alphanumeric characters, upper or lower case. (Addresses are case-sensitive so that they can contain data encoded in formats such as base64url.) +- Underscore (\_) +- Tilde (~) +- Hyphen (-) +- Period (.) Addresses MUST NOT end in a period (.) character + +An entity providing accounts to parties (i.e. a participant) can provide any value for an `AccountAddress` that is meaningful to that entity. +It does not need to provide an address that makes the account identifiable outside the entity’s domain. + +> ***IMPORTANT:* The policy for defining addresses and the life-cycle of these is at the discretion of the address space owner (the payer DFSP in this case).** +#### 3.2.1.3 AccountList +The AccountList data model is used to hold information about the accounts that a party controls. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| account | 1..256 | Account | Information relating to an account that a party controls. | + + +#### 3.2.1.5 AuthenticationResponse + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| AuthenticationResponse | 1 | Enum of String(1..32) | See [Section 3.2.2.1](#3221-AuthenticationResponse) below (AuthenticationResponse) for more information on allowed values.| +#### 3.2.1.6 BinaryString +The BinaryString type used in these definitions is as defined in [Section 7.2.17](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7217-binarystring) of Ref. 1 above. +#### 3.2.1.7 ConsentRequestChannelType +The ConsentRequestChannelType is used to hold an instance of the ConsentRequestChannelType enumeration. Its data model is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| ConsentRequestChannelType | 1 | Enum of String(1..32) | See [Section 3.2.2.4](#3223-consentrequestchanneltype) below ( ConsentRequestChannelType) for more information on allowed values. | + +#### 3.2.1.8 ConsentStatus +The ConsentStatus type stores the status of a consent request, as described in [Section 3.1.3.2.2](#31322-put-consentsid) above. Its data model is as follows: +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| ConsentStatus | 1 | Enum of String(1..32) | See [Section 3.2.2.5](#3224-consentstatustype) below (ConsentStatusType) for more information on allowed values.| + +#### 3.2.1.9 CorrelationId +The CorrelationId type used in these definitions is as defined in [Section 7.3.8](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#738-correlationid) of Ref. 1 above. +##### 3.2.1.10 Credential +The Credential object is used to store information about a publicKey and signature that has been registered with a Consent. +This publicKey can be used to verify that transaction authorizations have been signed by the previously-registered privateKey, +which resides on a User's device. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| credentialType | 1 | CredentialType | The type of credential this is - `FIDO` or `GENERIC` | +| status | 1 | CredentialStatus | The current status of the credential. | +| genericPayload | 0..1 | GenericCredential | Required if credentialType is GENERIC. A description of the credential and information which allows the recipient of the credential to test its veracity. | +| fidoPayload | 0..1 | FIDOPublicKeyCredentialAttestation | Required if credentialType is FIDO. A description of the credential and information which allows the recipient of the credential to test its veracity. | + +##### 3.2.1.11 CredentialStatus +The CredentialStatus data type stores the state of a credential request. Its data model is as follows. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| CredentialStatus | 1 | Enum of String(1..32) |See [Section 3.2.2.6](#3225-CredentialStatus) below (CredentialStatus) for more information on allowed values. | + +##### 3.2.1.12 DateTime +The DateTime data type used in these definitions is as defined in [Section 7.2.14](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7214-datetime) of Ref. 1 above. +##### 3.2.1.13 ErrorInformation +The ErrorInformation data type used in these definitions is as defined in [Section 7.4.2](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#742-errorinformation) of Ref. 1 above + +Valid values for ErrorCode and ErrorDescription are defined in [Error Codes](#ErrorCodes) + +##### 3.2.1.14 ExtensionList +The ExtensionList data type used in these definitions is as defined in [Section 7.4.4](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#744-extensionlist) of Ref. 1 above. +##### 3.2.1.15 FspId +The FspId data type used in these definitions is as defined in [Section 7.3.16](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7316-fspid) of Ref. 1 above. + +##### 3.2.1.16 GenericCredential +The GenericCredential object stores the payload for a credential which is validated according to a comparison of the signature created from the challenge using a private key against the same challenge signed using a public key. Its content is as follows. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| publicKey | 1 | BinaryString | The public key to be used in checking the signature. | +| signature | 1 | BinaryString | The signature to be checked against the public key. | + +##### 3.2.1.17 Money +The Money type used in these definitions is a defined in [Section 7.4.10](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7410-money) of Ref. 1 above. +##### 3.2.1.18 Note +The Note data type used in these definitions is as defined in [Section 7.3.23](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7323-note) of Ref. 1 above. +##### 3.2.1.19 Party + +The Note data type used in these definitions is as defined in [Section 7.4.11](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7411-party) of Ref. 1 above. + +##### 3.2.1.20 PartyIdInfo +The PartyIdInfo data type used in these definitions is as defined in [Section 7.4.13](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7413-partyidinfo) of Ref. 1 above. + + +##### 3.2.1.21 Scope +The Scope element contains an identifier defining, in the terms of a DFSP, an account on which access types can be requested or granted. It also defines the access types which are requested or granted. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| address | 1 |AccountAddress | The address of the account to which the PISP wishes to be permitted access, or is being granted access | +| actions | 1..32 |ScopeAction | The action that the PISP wants permission to take in relation to the customer’s account, or that it has been granted in relation to the customer’s account| +##### 3.2.1.22 ScopeAction +The ScopeAction element contains an access type which a PISP can request from a DFSP, or which a DFSP can grant to a PISP. It must be a member of the appropriate enumeration. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| scopeAction | 1 | Enum of String(1..32)| See [Section 3.2.2.9](#3228-scopeenumeration) below (ScopeEnumeration) for more information on allowed values. | +##### 3.2.1.23 ServiceType +The ServiceType element contains a type of service where the requester wants a list of the participants in the scheme which provide that service. It must be a member of the appropriate enumeration. +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| serviceType | 1 | Enum of String(1..32) | See [Section 3.2.2.10](#3229-servicetype) below (ServiceType) for more information on allowed values. | + +##### 3.2.1.24 TransactionType +The TransactionType type used in these definitions is as defined in [Section 7.4.18](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7418-transactiontype) of Ref. 1 above. +##### 3.2.1.25 TransactionState +The TransactionState type used in these definitions is as defined in [Section 7.3.33](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7333-transactionstate) of Ref. 1 above. +##### 3.2.1.26 Uri +The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. The regular expression for restricting the Uri type is as follows: +`^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? ` +##### 3.2.1.27 FIDOPublicKeyCredentialAttestation + +A data model representing a FIDO Attestation result. Derived from [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + +The `PublicKeyCredential` interface represents the below fields with a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). +For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| id | 1 | String(59..118) | The identifier of a keypair created by an authenticator | +| rawId | 0..1 | String(59..118) | The identifier of a keypair created by an authenticator, base64 encoded | +| response | 1 | AuthenticatorAttestationResponse | The attestation response from the authenticator | + +##### 3.2.1.28 FIDOPublicKeyCredentialAssertion + +A data model representing a FIDO Assertion result. Derived from [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential) in [WebAuthN](https://w3c.github.io/webauthn/). + +The `PublicKeyCredential` interface represents the below fields with a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). +For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| id | 1 | String(59..118) | The identifier of a keypair created by an authenticator | +| rawId | 0..1 | String(59..118) | The identifier of a keypair created by an authenticator, base64 encoded | +| response | 1 | AuthenticatorAssertionResponse | The assertion response from the authenticator | + +##### 3.2.1.29 AuthenticatorAttestationResponse + +A data model representing an [AttestationStatement](https://w3c.github.io/webauthn/#attestation-statement) from [WebAuthN](https://w3c.github.io/webauthn/). + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| clientDataJSON | 1 | String(121...512) | JSON string with client data | +| attestationObject | 1 | String(306...2048) | Object encoded in Concise Binary Object Representation(CBOR), as defined in [RFC-8949](https://www.rfc-editor.org/rfc/rfc8949)| + +##### 3.2.1.30 AuthenticatorAssertionResponse + +A data model representing an [AuthenticatorAssertionResponse](https://w3c.github.io/webauthn/#authenticatorassertionresponse). + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| authenticatorData | 1 | String(29..256) | Information about the authenticator. | +| clientDataJSON | 1 | String(121..512) | base64 encoded JSON string containing information about the client. | +| signature | 1 | String(59..256) | The signature generated by the private key associated with this credential. | +| userHandle | 0..1 | String(1..88) | This field is optionally provided by the authenticator, and represents the user.id that was supplied during registration, as defined in [WebAuthN's user.id](https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-id).| + +##### 3.2.1.31 SignedPayload + +A data model representing a Third Party Transaction request signature. + +| Name | Cardinality | Type | Description | +| --- | --- | --- | --- | +| signedPayloadType | 1 | SignedPayloadType | `FIDO` or `GENERIC` | +| genericSignedPayload | 0..1 | BinaryString(256) | Required if signedPayloadType is of type `GENERIC`. A BinaryString(256) of a signature of a sha-256 hash of the challenge. | +| fidoSignedPayload | 0..1 | FIDOPublicKeyCredentialAssertion | Required if signedPayloadType is of type `FIDO`. | + +### 3.2.2 Enumerations +#### 3.2.2.1 AuthenticationResponse +The AuthenticationResponse enumeration describes the result of authenticating verification request. +| Name | Description | +| --- | ----------- | +| VERIFIED | The challenge was correctly signed. | +#### 3.2.2.2 AuthorizationResponseType +The AuthorizationResponseType enumeration is the same as the AuthorizationResponse enumeration described in [Section 7.5.3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#753-authorizationresponse) of Ref. 1 above. +#### 3.2.2.3 ConsentRequestChannelType + +| Name | Description | +| --- | ----------- | +| WEB | DFSP can support authorization via a web-based login | +| OTP | DFSP can support authorization via a One Time PIN | + +#### 3.2.2.4 ConsentStatusType +The ConsentStatusType enumeration describes the allowed status values that a consent item can have. These are as follows: +| Name | Description | +| --- | ----------- | +| ISSUED | The consent has been issued by the DFSP. | +| REVOKED | The consent has been revoked. | + +#### 3.2.2.5 CredentialStatus +This contains the allowed values for the CredentialStatus +| Name | Description | +| --- | ----------- | +| PENDING | The credential has been created but not yet verified. | +| VERIFIED | Authentication service has verified the credential. | + +#### 3.2.2.6 CredentialType +The CredentialType enumeration contains the allowed values for the type of credential which is associated with a permission. +| Name | Description | +| --- | ----------- | +| FIDO | The credential is based on a FIDO challenge. Its payload is a FIDOPublicKeyCredentialAttestation object. | +| GENERIC | The credential is based on a simple public key validation. Its payload is a GenericCredential object | + +#### 3.2.2.7 PartyIdType +The PartyIdType enumeration is extended for PISPs to include a definition for the identifier which represents a link between a specific PISP and an account at a DFSP which a customer has given the PISP permission to access. + +| Name | Description | +| --- | ----------- | +| MSISDN | An MSISDN (Mobile Station International Subscriber Directory Number; that is, a phone number) is used in reference to a Party. The MSISDN identifier should be in international format according to the ITU-T E.16437 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.| +| EMAIL | An email is used in reference to a Party. The format of the email should be according to the informational RFC 369638.| +| PERSONAL_ID | A personal identifier is used in reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.| +| BUSINESS | A specific Business (for example, an organization or a company) is used in reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.| +| DEVICE | A specific device (for example, POS or ATM) ID connected to a specific business or organization is used in reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.| +| ACCOUNT_ID | A bank account number or FSP account ID should be used in reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.| +| IBAN | A bank account number or FSP account ID is used in reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.| +| ALIAS | An alias is used in reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.| +| THIRD_PARTY_LINK | A third-party link which represents an agreement between a specific PISP and a customer’s account at a DFSP. The content of the link is created by the DFSP at the time when it gives permission to the PISP for specific access to a given account.| + +#### 3.2.2.8 ScopeEnumeration + +| Name | Description | +| --- | ----------- | +| ACCOUNTS_GET_BALANCE | PISP can request a balance for the linked account | +| ACCOUNTS_TRANSFER | PISP can request a transfer of funds from the linked account in the DFSP | +| ACCOUNTS_STATEMENT | PISP can request a statement of individual transactions on a user’s account | + +#### 3.2.2.9 ServiceType +The ServiceType enumeration describes the types of role for which a DFSP may query using the /services resource. +| Name | Description | +| --- | ----------- | +| THIRD_PARTY_DFSP| DFSPs which will support linking with PISPs | +| PISP | PISPs | +| AUTH_SERVICE | Participants which provide Authentication Services | + +##### 3.2.2.10 SignedPayloadType +The SignedPayloadType enumeration contains the allowed values for the type of a signed payload +| Name | Description | +| --- | ----------- | +| FIDO | The signed payload is based on a FIDO Assertion Response. Its payload is a FIDOPublicKeyCredentialAssertion object. | +| GENERIC | The signed payload is based on a simple public key validation. Its payload is a BinaryString object | + +##### 3.2.2.11 AmountType +See [7.3.1 AmountType](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#731-amounttype) + +##### 3.2.2.12 TransactionRequestState +See [7.5.10 TransactionRequestState](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7510-transactionrequeststate) + + +## 3.3 Error Codes + +The Third Party API Error Codes are defined in [Section 7.6](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#76-error-codes) of ref 1 above. + +In addition, the Third Party API adds the following error codes, starting with the prefix `6`: + +- General Third Party Error -- **60**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6000** | Third party error | Generic error. | X | X | X | X | X | X | X | X | +| **6001** | Third party request error | Third party request failed. | X | X | X | X | X | X | X | X | +| **6003** | Downstream Failure | The downstream request failed. | X | X | X | X | X | X | X | X | + +- Permission Error -- **61**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6100** | Authentication rejection | Generic authentication rejection | | X | | | | X | | | +| **6101** | Unsupported scopes were requested | PISP requested scopes that the DFSP doesn’t allow/support | | X | X | | | | | | +| **6102** | Consent not granted | User did not grant consent to the PISP | | X | X | | | | | | +| **6103** | Consent not valid | Consent object is not valid or has been revoked | | X | X | | | X | X | X | +| **6104** | Third Party request rejection | The request was rejected | X | X | X | X | X | X | X | X | + +- Validation Error -- **62**_xx_ + +| **Error Code** | **Name** | **Description** | /accounts | /consentRequests | /consents | /parties | /services | /thirdpartyRequests/authorizations | thirdpartyRequests/transactions | thirdpartyRequests/verifications | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| **6200** | Invalid Consent Credential | The signature of the credential submitted by the PISP is invalid | | | X | | | | | | +| **6201** | Invalid transaction signature | The signature of the verification response doesn't match the credential | | | | | | X | | X | +| **6203** | Invalid authentication token | DFSP receives invalid authentication token from PISP. | | X | | | | | | | +| **6204** | Bad callbackUri | The callbackUri is deemed invalid or untrustworthy. | | X | | | | | | | +| **6205** | No accounts found | No accounts were found for the given identifier | X | | | | | | | | + diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-dfsp-v1.0.yaml b/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-dfsp-v1.0.yaml new file mode 100644 index 000000000..8bc925308 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-dfsp-v1.0.yaml @@ -0,0 +1,2721 @@ +openapi: 3.0.2 +info: + title: Mojaloop Third Party API (DFSP) + version: '1.0' + description: | + A Mojaloop API for DFSPs supporting Third Party functions. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) to perform actions on behalf of a DFSP's user should implement this API. + PISPs should implement the accompanying API - Mojaloop Third Party API (PISP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: |- + Callback and data model information for GET /accounts/{ID}: + Callback - PUT /accounts/{ID} Error Callback - PUT /accounts/{ID}/error Data Model - Empty body + The PUT /accounts/{ID} response is used to inform the requester of the result of a request for accounts information. The identifier ID given in the call are the values given in the original request. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31121--put-accountsid + properties: + accountList: + title: AccountList + type: array + description: |- + The AccountList data model is used to hold information about the accounts that a party controls. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3213-accountlist + items: + title: Account + type: object + description: |- + Data model for the complex type Account. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3211-account + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0/properties/currency' + required: + - accountNickname + - address + - currency + minItems: 1 + maxItems: 256 + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: |- + Used by: PISP + The HTTP request POST /consentRequests is used to request a DFSP to grant access to one or more accounts owned by a customer of the DFSP for the PISP who sends the request. + Callback and data model for POST /consentRequests: + Callback: PUT /consentRequests/{ID} Error callback: PUT /consentRequests/{ID}/error Data model - see below url + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31212-post-consentrequests + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: |- + The Scope element contains an identifier defining, in the terms of a DFSP, an account on which access types can be requested or granted. It also defines the access types which are requested or granted. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#32121-scope + properties: + address: + title: AccountAddress + type: string + description: |- + The AccountAddress data type is a variable length string with a maximum size of 1023 characters and consists of: + Alphanumeric characters, upper or lower case. (Addresses are case-sensitive so that they can contain data encoded in formats such as base64url.) + - Underscore (_) - Tilde (~) - Hyphen (-) - Period (.) Addresses MUST NOT end in a period (.) character + An entity providing accounts to parties (i.e. a participant) can provide any value for an AccountAddress that is meaningful to that entity. It does not need to provide an address that makes the account identifiable outside the entity's domain. + IMPORTANT: The policy for defining addresses and the life-cycle of these is at the discretion of the address space owner (the payer DFSP in this case). + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3212-accountaddress + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + description: | + The ScopeAction element contains an access type which a PISP can request + from a DFSP, or which a DFSP can grant to a PISP. + It must be a member of the appropriate enumeration. + + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user's account + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consent request. + - WEB - DFSP can support authorization via a web-based login. + - OTP - DFSP can support authorization via a One Time PIN. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for `PUT /consentRequest/{ID}` request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for `PUT /consentRequests/{ID}` request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: |- + Used by: PISP + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31222-patch-consentrequestsid + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /consents: + parameters: + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + consentRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for re-sends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1consents/post/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1consents/post/responses/400/headers/Content-Type' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is issued and verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatusVerified + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatusRevoked + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + status: + title: ConsentStatusIssued + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: |- + The type of the Credential. - "FIDO" - The credential is based on a FIDO challenge. Its payload is a FIDOPublicKeyCredentialAttestation object. - "GENERIC" - The credential is based on a simple public key validation. Its payload is a GenericCredential object. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3226-credentialtype + status: + title: CredentialStatusPending + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair. + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of Credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + $ref: '#/paths/~1consents~1%7BID%7D/patch/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/status' + genericPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/genericPayload' + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/fidoPayload' + required: + - credentialType + - status + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: |- + Used by: DFSP + The HTTP request POST /thirdpartyRequests/authorizations is used to request the validation by a customer for the transfer described in the request. + Callback and data model information for POST /thirdpartyRequests/authorizations: + Callback - PUT /thirdpartyRequests/authorizations/{ID} Error Callback - PUT /thirdpartyRequests/authorizations/{ID}/error Data Model - See below url + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31612-post-thirdpartyrequestsauthorizations + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer's account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer's account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseRejected + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseTypeRejected + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + title: SignedPayloadFIDO + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/signedPayloadType' + fidoSignedPayload: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/0/properties/fidoSignedPayload' + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + title: SignedPayloadGeneric + type: object + properties: + signedPayloadType: + $ref: '#/paths/~1thirdpartyRequests~1verifications/post/requestBody/content/application~1json/schema/oneOf/1/properties/signedPayloadType' + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: |- + Used by: PISP + The HTTP request POST /thirdpartyRequests/transactions is used to request the creation of a transaction request on the server for the transfer described in the request. + Callback and data model information for POST /thirdpartyRequests/transactions: + Callback - PUT /thirdpartyRequests/transactions/{ID} Error Callback - PUT /thirdpartyRequests/transactions/{ID}/error Data Model - See link below + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31712-post-thirdpartyrequeststransactions + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: |- + Used by: DFSP + After a PISP requests the creation of a Third Party Transaction request (POST /thirdpartyRequests/transactions) or the status of a previously created Third Party Transaction request (GET /thirdpartyRequests/transactions/{ID}), the DFSP will send this callback. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31721-put-thirdpartyrequeststransactionsid + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: |- + Used by: DFSP + The issuing PISP will expect a response to their request for a transfer which describes the finalized state of the requested transfer. + This response will be given by a PATCH call on the /thirdpartyRequests/transactions/{ID} resource. + The {ID} given in the query string should be the transactionRequestId which was originally used by the PISP to identify the transaction request. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31612-post-thirdpartyrequestsauthorizations + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + /thirdpartyRequests/verifications: + parameters: + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + post: + tags: + - thirdpartyRequests + - sampled + operationId: PostThirdpartyRequestsVerifications + summary: PostThirdpartyRequestsVerifications + description: | + The HTTP request `POST /thirdpartyRequests/verifications` is used by the DFSP to verify a third party authorization. + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The thirdparty authorization details to verify + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsVerificationsPostRequestFIDO + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + A data model representing a FIDO Assertion result. + Derived from PublicKeyCredential Interface in WebAuthN. + + The PublicKeyCredential interface represents the below fields with a Type of + Javascript ArrayBuffer. + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#32128-fidopublickeycredentialassertion + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - fidoSignedPayload + - title: ThirdpartyRequestsVerificationsPostRequestGeneric + type: object + description: The object sent in the POST /thirdpartyRequests/verifications request. + properties: + verificationRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: Base64 encoded bytes - The challenge generated by the DFSP. + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The id of the stored consent object that contains the credential with which to verify + the signed challenge against. + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - verificationRequestId + - challenge + - consentId + - signedPayloadType + - genericSignedPayload + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyRequestsVerificationsById + summary: GetThirdpartyRequestsVerificationsById + description: | + The HTTP request `/thirdpartyRequests/verifications/{ID}` is used to get + information regarding a previously created or requested authorization. The *{ID}* + in the URI should contain the verification request ID + parameters: + - $ref: '#/paths/~1consents/post/parameters/0' + responses: + '202': + $ref: '#/paths/~1consents/post/responses/202' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsById + summary: PutThirdpartyRequestsVerificationsById + description: |- + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}` is used by the Auth-Service to inform the DFSP of a successful result in validating the verification of a Thirdparty Transaction Request. + If the validation fails, the auth-service will send back `PUT /thirdpartyRequests/verifications/{ID}` with `authenticationResponse: 'REJECTED'`. + In unplanned error cases the Auth-Service MUST use `PUT /thirdpartyRequests/verifications/{ID}/error`. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: The result of validating the Thirdparty Transaction Request + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsVerificationsIDPutResponse + type: object + description: |- + Used by: Auth Service + The callback PUT /thirdpartyRequests/verifications/{ID} is used to inform the client of the result of an authorization check. The {ID} in the URI should contain the authorizationRequestId which was used to request the check, or the {ID} that was used in the GET /thirdpartyRequests/verifications/{ID}. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31821-put-thirdpartyrequestsverificationsid + properties: + authenticationResponse: + title: AuthenticationResponse + type: string + enum: + - VERIFIED + description: |- + The AuthenticationResponse enumeration describes the result of authenticating verification request. + Below are the allowed values for the enumeration AuthenticationResponse. - VERIFIED - The challenge was correctly signed. + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - authenticationResponse + example: + authenticationResponse: VERIFIED + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' + '/thirdpartyRequests/verifications/{ID}/error': + parameters: + - $ref: '#/paths/~1accounts~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1consents/parameters/0' + - $ref: '#/paths/~1consents/parameters/1' + - $ref: '#/paths/~1consents/parameters/2' + - $ref: '#/paths/~1consents/parameters/3' + - $ref: '#/paths/~1consents/parameters/4' + - $ref: '#/paths/~1consents/parameters/5' + - $ref: '#/paths/~1consents/parameters/6' + - $ref: '#/paths/~1consents/parameters/7' + - $ref: '#/paths/~1consents/parameters/8' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsVerificationsByIdAndError + summary: PutThirdpartyRequestsVerificationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/verifications/{ID}/error` is used by the Auth-Service to inform + the DFSP of a failure in validating or looking up the verification of a Thirdparty Transaction Request. + parameters: + - $ref: '#/paths/~1consents/post/parameters/1' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1accounts~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1consents/post/responses/400' + '401': + $ref: '#/paths/~1consents/post/responses/401' + '403': + $ref: '#/paths/~1consents/post/responses/403' + '404': + $ref: '#/paths/~1consents/post/responses/404' + '405': + $ref: '#/paths/~1consents/post/responses/405' + '406': + $ref: '#/paths/~1consents/post/responses/406' + '501': + $ref: '#/paths/~1consents/post/responses/501' + '503': + $ref: '#/paths/~1consents/post/responses/503' diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-pisp-v1.0.yaml b/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-pisp-v1.0.yaml new file mode 100644 index 000000000..0a42d8dd4 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/thirdparty-pisp-v1.0.yaml @@ -0,0 +1,2923 @@ +openapi: 3.0.1 +info: + title: Mojaloop Third Party API (PISP) + version: '1.0' + description: | + A Mojaloop API for Payment Initiation Service Providers (PISPs) to perform Third Party functions on DFSPs' User's accounts. + DFSPs who want to enable Payment Initiation Service Providers (PISPs) should implement the accompanying API - Mojaloop Third Party API (DFSP) instead. + license: + name: Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version) + url: 'https://github.com/mojaloop/mojaloop-specification/blob/master/LICENSE.md' +servers: + - url: / +paths: + '/accounts/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /accounts/{ID}` is used to return the list of potential accounts available for linking + operationId: UpdateAccountsByUserId + summary: UpdateAccountsByUserId + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: AccountsIDPutResponse + type: object + description: |- + Callback and data model information for GET /accounts/{ID}: + Callback - PUT /accounts/{ID} Error Callback - PUT /accounts/{ID}/error Data Model - Empty body + The PUT /accounts/{ID} response is used to inform the requester of the result of a request for accounts information. The identifier ID given in the call are the values given in the original request. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31121--put-accountsid + properties: + accountList: + title: AccountList + type: array + description: |- + The AccountList data model is used to hold information about the accounts that a party controls. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3213-accountlist + items: + title: Account + type: object + description: |- + Data model for the complex type Account. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3211-account + properties: + accountNickname: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: |- + The API data type Name is a JSON String, restricted by a regular expression to avoid characters which are generally not used in a name. + + Regular Expression - The regular expression for restricting the Name type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a string consisting of whitespace only, all Unicode characters are allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) and space characters ( ). + + **Note:** In some programming languages, Unicode support must be specifically enabled. For example, if Java is used, the flag UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + address: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items/properties/address' + currency: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0/properties/currency' + required: + - accountNickname + - address + - currency + minItems: 1 + maxItems: 256 + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - accounts + example: + - accountNickname: dfspa.user.nickname1 + id: dfspa.username.1234 + currency: ZAR + - accountNickname: dfspa.user.nickname2 + id: dfspa.username.5678 + currency: USD + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/accounts/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /accounts/{ID}/error` is used to return error information + operationId: UpdateAccountsByUserIdError + summary: UpdateAccountsByUserIdError + tags: + - accounts + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + title: ErrorInformationObject + type: object + description: Data model for the complex type object that contains ErrorInformation. + properties: + errorInformation: + title: ErrorInformation + type: object + description: Data model for the complex type ErrorInformation. + properties: + errorCode: + title: ErrorCode + type: string + pattern: '^[1-9]\d{3}$' + description: 'The API data type ErrorCode is a JSON String of four characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed. Each error code in the API is a four-digit number, for example, 1234, where the first number (1 in the example) represents the high-level error category, the second number (2 in the example) represents the low-level error category, and the last two numbers (34 in the example) represent the specific error.' + example: '5100' + errorDescription: + title: ErrorDescription + type: string + minLength: 1 + maxLength: 128 + description: Error description string. + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - errorCode + - errorDescription + required: + - errorInformation + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consentRequests: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consentRequests + - sampled + operationId: CreateConsentRequest + summary: CreateConsentRequest + description: | + The HTTP request **POST /consentRequests** is used to request a DFSP to grant access to one or more + accounts owned by a customer of the DFSP for the PISP who sends the request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: The consentRequest to create + required: true + content: + application/json: + schema: + title: ConsentRequestsPostRequest + type: object + description: |- + Used by: PISP + The HTTP request POST /consentRequests is used to request a DFSP to grant access to one or more accounts owned by a customer of the DFSP for the PISP who sends the request. + Callback and data model for POST /consentRequests: + Callback: PUT /consentRequests/{ID} Error callback: PUT /consentRequests/{ID}/error Data model - see below url + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31212-post-consentrequests + properties: + consentRequestId: + title: CorrelationId + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' + description: 'Identifier that correlates all messages of the same sequence. The API data type UUID (Universally Unique Identifier) is a JSON String in canonical format, conforming to [RFC 4122](https://tools.ietf.org/html/rfc4122), that is restricted by a regular expression for interoperability reasons. A UUID is always 36 characters long, 32 hexadecimal symbols and 4 dashes (‘-‘).' + example: b51ec534-ee48-4575-b6a9-ead2955b8069 + userId: + type: string + description: 'The identifier used in the **GET /accounts/**_{ID}_. Used by the DFSP to correlate an account lookup to a `consentRequest`' + minLength: 1 + maxLength: 128 + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + title: Scope + type: object + description: |- + The Scope element contains an identifier defining, in the terms of a DFSP, an account on which access types can be requested or granted. It also defines the access types which are requested or granted. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#32121-scope + properties: + address: + title: AccountAddress + type: string + description: |- + The AccountAddress data type is a variable length string with a maximum size of 1023 characters and consists of: + Alphanumeric characters, upper or lower case. (Addresses are case-sensitive so that they can contain data encoded in formats such as base64url.) + - Underscore (_) - Tilde (~) - Hyphen (-) - Period (.) Addresses MUST NOT end in a period (.) character + An entity providing accounts to parties (i.e. a participant) can provide any value for an AccountAddress that is meaningful to that entity. It does not need to provide an address that makes the account identifiable outside the entity's domain. + IMPORTANT: The policy for defining addresses and the life-cycle of these is at the discretion of the address space owner (the payer DFSP in this case). + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3212-accountaddress + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + actions: + type: array + minItems: 1 + maxItems: 32 + items: + title: ScopeAction + type: string + description: | + The ScopeAction element contains an access type which a PISP can request + from a DFSP, or which a DFSP can grant to a PISP. + It must be a member of the appropriate enumeration. + + - ACCOUNTS_GET_BALANCE: PISP can request a balance for the linked account + - ACCOUNTS_TRANSFER: PISP can request a transfer of funds from the linked account in the DFSP + - ACCOUNTS_STATEMENT: PISP can request a statement of individual transactions on a user's account + enum: + - ACCOUNTS_GET_BALANCE + - ACCOUNTS_TRANSFER + - ACCOUNTS_STATEMENT + required: + - address + - actions + authChannels: + type: array + minLength: 1 + maxLength: 256 + items: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consent request. + - WEB - DFSP can support authorization via a web-based login. + - OTP - DFSP can support authorization via a One Time PIN. + callbackUri: + title: Uri + type: string + pattern: '^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' + minLength: 1 + maxLength: 512 + description: | + The API data type Uri is a JSON string in a canonical format that is restricted by a regular expression for interoperability reasons. + extensionList: + title: ExtensionList + type: object + description: 'Data model for the complex type ExtensionList. An optional list of extensions, specific to deployment.' + properties: + extension: + type: array + items: + title: Extension + type: object + description: Data model for the complex type Extension. + properties: + key: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + value: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + required: + - key + - value + minItems: 1 + maxItems: 16 + description: Number of Extension elements. + required: + - extension + required: + - consentRequestId + - userId + - scopes + - authChannels + - callbackUri + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetConsentRequestsById + summary: GetConsentRequestsById + description: | + The HTTP request `GET /consentRequests/{ID}` is used to get information about a previously + requested consent. The *{ID}* in the URI should contain the consentRequestId that was assigned to the + request by the PISP when the PISP originated the request. + tags: + - consentRequests + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - consentRequests + - sampled + operationId: UpdateConsentRequest + summary: UpdateConsentRequest + description: | + A DFSP uses this callback to (1) inform the PISP that the consentRequest has been accepted, + and (2) communicate to the PISP which `authChannel` it should use to authenticate their user + with. + + When a PISP requests a series of permissions from a DFSP on behalf of a DFSP’s customer, not all + the permissions requested may be granted by the DFSP. Conversely, the out-of-band authorization + process may result in additional privileges being granted by the account holder to the PISP. The + **PUT /consentRequests/**_{ID}_ resource returns the current state of the permissions relating to a + particular authorization request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentRequestsIDPutResponseWeb + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking web flow, + the result is the PISP being instructed on a specific URL where this + supposed user should be redirected. This URL should be a place where + the user can prove their identity (e.g., by logging in). + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeWeb + type: string + enum: + - WEB + description: | + The web auth channel being used for `PUT /consentRequest/{ID}` request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + authUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - authChannels + - callbackUri + - authUri + additionalProperties: false + - title: ConsentRequestsIDPutResponseOTP + type: object + description: | + The object sent in a `PUT /consentRequests/{ID}` request. + + Schema used in the request consent phase of the account linking OTP/SMS flow. + properties: + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + authChannels: + type: array + minLength: 1 + maxLength: 1 + items: + title: ConsentRequestChannelTypeOTP + type: string + enum: + - OTP + description: | + The OTP auth channel being used for `PUT /consentRequests/{ID}` request. + callbackUri: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/callbackUri' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - authChannels + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + tags: + - consentRequests + - sampled + operationId: PatchConsentRequest + summary: PatchConsentRequest + description: | + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ConsentRequestsIDPatchRequest + type: object + description: |- + Used by: PISP + After the user completes an out-of-band authorization with the DFSP, the PISP will receive a token which they can use to prove to the DFSP that the user trusts this PISP. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31222-patch-consentrequestsid + properties: + authToken: + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + description: 'The API data type BinaryString is a JSON String. The string is a base64url encoding of a string of raw bytes, where padding (character ‘=’) is added at the end of the data if needed to ensure that the string is a multiple of 4 characters. The length restriction indicates the allowed number of characters.' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - authToken + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consentRequests/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consentRequests + operationId: NotifyErrorConsentRequests + summary: NotifyErrorConsentRequests + description: | + DFSP responds to the PISP if something went wrong with validating an OTP or secret. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /consents: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + tags: + - consents + - sampled + operationId: PostConsents + summary: PostConsents + description: | + The **POST /consents** request is used to request the creation of a consent for interactions between a PISP and the DFSP who owns the account which a PISP’s customer wants to allow the PISP access to. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentPostRequestAUTH + type: object + description: | + The object sent in a `POST /consents` request to the Auth-Service + by a DFSP to store registered Consent and credential + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and FSP for the Consent object + determined by the DFSP who creates the Consent. + consentRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + scopes: + minLength: 1 + maxLength: 256 + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + allOf: + - $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential' + status: + title: ConsentStatus + type: string + enum: + - ISSUED + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + - REVOKED - The consent has been revoked + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - consentId + - scopes + - credential + - status + additionalProperties: false + - title: ConsentPostRequestPISP + type: object + description: | + The provisional Consent object sent by the DFSP in `POST /consents`. + properties: + consentId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the consent object. The ID + should be reused for re-sends of the same consent. A new ID should be generated + for each new consent. + consentRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + The ID given to the original consent request on which this consent is based. + scopes: + type: array + minLength: 1 + maxLength: 256 + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + status: + $ref: '#/paths/~1consents/post/requestBody/content/application~1json/schema/oneOf/0/properties/status' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - consentId + - consentRequestId + - scopes + - status + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The **GET /consents/**_{ID}_ resource allows a party to enquire after the status of a consent. The *{ID}* used in the URI of the request should be the consent request ID which was used to identify the consent when it was created. + tags: + - consents + operationId: GetConsent + summary: GetConsent + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + description: | + The HTTP request `PATCH /consents/{ID}` is used + + - In account linking in the Credential Registration phase. Used by a DFSP + to notify a PISP a credential has been verified and registered with an + Auth service. + + - In account unlinking by a hub hosted auth service and by DFSPs + in non-hub hosted scenarios to notify participants of a consent being revoked. + + Called by a `auth-service` to notify a PISP and DFSP of consent status in hub hosted scenario. + Called by a `DFSP` to notify a PISP of consent status in non-hub hosted scenario. + tags: + - consents + - sampled + operationId: PatchConsentByID + summary: PatchConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPatchResponseVerified + description: | + PATCH /consents/{ID} request object. + + Sent by the DFSP to the PISP when a consent is issued and verified. + Used in the "Register Credential" part of the Account linking flow. + type: object + properties: + credential: + type: object + properties: + status: + title: CredentialStatusVerified + type: string + enum: + - VERIFIED + description: | + The status of the Credential. + - "VERIFIED" - The Credential is valid and verified. + required: + - status + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - credential + - title: ConsentsIDPatchResponseRevoked + description: | + PATCH /consents/{ID} request object. + + Sent to both the PISP and DFSP when a consent is revoked. + Used in the "Unlinking" part of the Account Unlinking flow. + type: object + properties: + status: + title: ConsentStatusRevoked + type: string + enum: + - REVOKED + description: |- + Allowed values for the enumeration ConsentStatus + - REVOKED - The consent has been revoked + revokedAt: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - status + - revokedAt + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP and Auth Service. + + - Called by a `PISP` to after signing a challenge. Sent to an DFSP for verification. + - Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + tags: + - consents + - sampled + operationId: PutConsentByID + summary: PutConsentByID + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - title: ConsentsIDPutResponseSigned + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the PISP to update a Consent with a signed challenge and register a credential. + Called by a `PISP` to after signing a challenge. Sent to a DFSP for verification. + properties: + status: + title: ConsentStatusIssued + type: string + enum: + - ISSUED + description: |- + Allowed values for the enumeration ConsentStatus + - ISSUED - The consent has been issued by the DFSP + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + title: SignedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + SignedCredential is a special formatting of the credential to allow us to be + more explicit about the `status` field - it should only ever be PENDING when + updating a credential. + properties: + credentialType: + title: CredentialType + type: string + enum: + - FIDO + - GENERIC + description: |- + The type of the Credential. - "FIDO" - The credential is based on a FIDO challenge. Its payload is a FIDOPublicKeyCredentialAttestation object. - "GENERIC" - The credential is based on a simple public key validation. Its payload is a GenericCredential object. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#3226-credentialtype + status: + title: CredentialStatusPending + type: string + enum: + - PENDING + description: | + The status of the Credential. + - "PENDING" - The credential has been created, but has not been verified + genericPayload: + title: GenericCredential + type: object + description: | + A publicKey + signature of a challenge for a generic public/private keypair. + properties: + publicKey: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + signature: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - publicKey + - signature + additionalProperties: false + fidoPayload: + title: FIDOPublicKeyCredentialAttestation + type: object + description: | + A data model representing a FIDO Attestation result. Derived from + [`PublicKeyCredential` Interface](https://w3c.github.io/webauthn/#iface-pkcredential). + + The `PublicKeyCredential` interface represents the below fields with + a Type of Javascript [ArrayBuffer](https://heycam.github.io/webidl/#idl-ArrayBuffer). + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAttestationResponse + properties: + clientDataJSON: + type: string + description: | + JSON string with client data + minLength: 121 + maxLength: 512 + attestationObject: + type: string + description: | + CBOR.encoded attestation object + minLength: 306 + maxLength: 2048 + required: + - clientDataJSON + - attestationObject + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - response + - type + additionalProperties: false + required: + - credentialType + - status + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - credential + additionalProperties: false + - title: ConsentsIDPutResponseVerified + type: object + description: | + The HTTP request `PUT /consents/{ID}` is used by the DFSP or Auth-Service to update a Consent object once it has been Verified. + Called by a `auth-service` to notify a DFSP that a credential has been verified and registered. + properties: + status: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/status' + scopes: + type: array + items: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/scopes/items' + credential: + title: VerifiedCredential + type: object + description: | + A credential used to allow a user to prove their identity and access + to an account with a DFSP. + + VerifiedCredential is a special formatting of Credential to allow us to be + more explicit about the `status` field - it should only ever be VERIFIED when + updating a credential. + properties: + credentialType: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/credentialType' + status: + $ref: '#/paths/~1consents~1%7BID%7D/patch/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/status' + genericPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/genericPayload' + fidoPayload: + $ref: '#/paths/~1consents~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/0/properties/credential/properties/fidoPayload' + required: + - credentialType + - status + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - scopes + - credential + additionalProperties: false + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + delete: + description: | + Used by PISP, DFSP + + The **DELETE /consents/**_{ID}_ request is used to request the revocation of a previously agreed consent. + For tracing and auditing purposes, the switch should be sure not to delete the consent physically; + instead, information relating to the consent should be marked as deleted and requests relating to the + consent should not be honoured. + operationId: DeleteConsentByID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - consents + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/consents/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - consents + operationId: NotifyErrorConsents + summary: NotifyErrorConsents + description: | + DFSP responds to the PISP if something went wrong with validating or storing consent. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/authorizations: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + description: | + The HTTP request **POST /thirdpartyRequests/authorizations** is used to request the validation by a customer for the transfer described in the request. + operationId: PostThirdpartyRequestsAuthorizations + summary: PostThirdpartyRequestsAuthorizations + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Authorization request details + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsAuthorizationsPostRequest + description: |- + Used by: DFSP + The HTTP request POST /thirdpartyRequests/authorizations is used to request the validation by a customer for the transfer described in the request. + Callback and data model information for POST /thirdpartyRequests/authorizations: + Callback - PUT /thirdpartyRequests/authorizations/{ID} Error Callback - PUT /thirdpartyRequests/authorizations/{ID}/error Data Model - See below url + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31612-post-thirdpartyrequestsauthorizations + type: object + properties: + authorizationRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + transactionRequestId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + challenge: + type: string + description: The challenge that the PISP's client is to sign + transferAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be debited from the sending customer's account as a consequence of the transaction. + payeeReceiveAmount: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount that will be credited to the receiving customer's account as a consequence of the transaction. + fees: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/amount/allOf/0' + description: The amount of fees that the paying customer will be charged as part of the transaction. + payer: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + description: 'Information about the Payer type, id, sub-type/id, FSP Id in the proposed financial transaction.' + payee: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payee/allOf/0' + description: Information about the Payee in the proposed financial transaction. + transactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: |- + Below are the allowed values for the enumeration. + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a normal scenario, electronic funds are transferred from a Business account to a Consumer account, and physical cash is given from the Consumer to the Business User. + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. In a normal scenario, electronic funds are transferred from a Consumer’s account to a Business account, and physical cash is given from the Business User to the Consumer. + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to Consumer) transaction. + - PAYMENT - Usually used for performing a transaction from a Consumer to a Merchant or Organization, but could also be for a B2B (Business to Business) payment. The transaction could be online for a purchase in an Internet store, in a physical store where both the Consumer and Business User are present, a bill payment, a donation, and so on. + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + subScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: 'Possible sub-scenario, defined locally within the scheme (UndefinedEnum Type).' + example: LOCALLY_DEFINED_SUBSCENARIO + initiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: |- + Below are the allowed values for the enumeration. + - PAYER - Sender of funds is initiating the transaction. The account to send from is either owned by the Payer or is connected to the Payer in some way. + - PAYEE - Recipient of the funds is initiating the transaction by sending a transaction request. The Payer must approve the transaction, either automatically by a pre-generated OTP or by pre-approval of the Payee, or by manually approving in his or her own Device. + example: PAYEE + initiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + refundInfo: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + refundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + required: + - originalTransactionId + balanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: '(BopCode) The API data type [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String of 3 characters, consisting of digits only. Negative numbers are not allowed. A leading zero is not allowed.' + example: '123' + required: + - scenario + - initiator + - initiatorType + expiration: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/completedTimestamp' + description: 'The time by which the transfer must be completed, set by the payee DFSP.' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - authorizationRequestId + - transactionRequestId + - challenge + - transferAmount + - payeeReceiveAmount + - fees + - payer + - payee + - transactionType + - expiration + additionalProperties: false + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: | + The HTTP request **GET /thirdpartyRequests/authorizations/**_{ID}_ is used to get information relating + to a previously issued authorization request. The *{ID}* in the request should match the + `authorizationRequestId` which was given when the authorization request was created. + operationId: GetThirdpartyRequestsAuthorizationsById + summary: GetThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + After receiving the **POST /thirdpartyRequests/authorizations**, the PISP will present the details of the + transaction to their user, and request that the client sign the `challenge` field using the credential + they previously registered. + + The signed challenge will be sent back by the PISP in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + operationId: PutThirdpartyRequestsAuthorizationsById + summary: PutThirdpartyRequestsAuthorizationsById + tags: + - authorizations + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Signed authorization object + required: true + content: + application/json: + schema: + oneOf: + - title: ThirdpartyRequestsAuthorizationsIDPutResponseRejected + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseTypeRejected + description: | + The customer rejected the terms of the transfer. + type: string + enum: + - REJECTED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - title: ThirdpartyRequestsAuthorizationsIDPutResponseFIDO + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + title: AuthorizationResponseType + description: | + The customer accepted the terms of the transfer + type: string + enum: + - ACCEPTED + signedPayload: + title: SignedPayloadFIDO + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeFIDO + type: string + enum: + - FIDO + description: Describes a challenge that has been signed with FIDO Attestation flows + fidoSignedPayload: + title: FIDOPublicKeyCredentialAssertion + type: object + description: | + A data model representing a FIDO Assertion result. + Derived from PublicKeyCredential Interface in WebAuthN. + + The PublicKeyCredential interface represents the below fields with a Type of + Javascript ArrayBuffer. + For this API, we represent ArrayBuffers as base64 encoded utf-8 strings. + + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#32128-fidopublickeycredentialassertion + properties: + id: + type: string + description: | + credential id: identifier of pair of keys, base64 encoded + https://w3c.github.io/webauthn/#ref-for-dom-credential-id + minLength: 59 + maxLength: 118 + rawId: + type: string + description: | + raw credential id: identifier of pair of keys, base64 encoded. + minLength: 59 + maxLength: 118 + response: + type: object + description: | + AuthenticatorAssertionResponse + properties: + authenticatorData: + type: string + description: | + Authenticator data object. + minLength: 49 + maxLength: 256 + clientDataJSON: + type: string + description: | + JSON string with client data. + minLength: 121 + maxLength: 512 + signature: + type: string + description: | + The signature generated by the private key associated with this credential. + minLength: 59 + maxLength: 256 + userHandle: + type: string + description: | + This field is optionally provided by the authenticator, and + represents the user.id that was supplied during registration. + minLength: 1 + maxLength: 88 + required: + - authenticatorData + - clientDataJSON + - signature + additionalProperties: false + type: + type: string + description: 'response type, we need only the type of public-key' + enum: + - public-key + required: + - id + - rawId + - response + - type + additionalProperties: false + required: + - signedPayloadType + - fidoSignedPayload + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - signedPayload + additionalProperties: false + - title: ThirdpartyRequestsAuthorizationsIDPutResponseGeneric + type: object + description: 'The object sent in the PUT /thirdpartyRequests/authorizations/{ID} callback.' + properties: + responseType: + $ref: '#/paths/~1thirdpartyRequests~1authorizations~1%7BID%7D/put/requestBody/content/application~1json/schema/oneOf/1/properties/responseType' + signedPayload: + title: SignedPayloadGeneric + type: object + properties: + signedPayloadType: + title: SignedPayloadTypeGeneric + type: string + enum: + - GENERIC + description: Describes a challenge that has been signed with a private key + genericSignedPayload: + $ref: '#/paths/~1consentRequests~1%7BID%7D/patch/requestBody/content/application~1json/schema/properties/authToken' + required: + - signedPayloadType + - genericSignedPayload + additionalProperties: false + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - responseType + - signedPayload + additionalProperties: false + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/authorizations/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: PutThirdpartyRequestsAuthorizationsByIdAndError + summary: PutThirdpartyRequestsAuthorizationsByIdAndError + description: | + The HTTP request `PUT /thirdpartyRequests/authorizations/{ID}/error` is used by the DFSP or PISP to inform + the other party that something went wrong with a Thirdparty Transaction Authorization Request. + + The PISP may use this to tell the DFSP that the Thirdparty Transaction Authorization Request is invalid or doesn't + match a `transactionRequestId`. + + The DFSP may use this to tell the PISP that the signed challenge returned in `PUT /thirdpartyRequest/authorizations/{ID}` + was invalid. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + /thirdpartyRequests/transactions: + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + post: + operationId: ThirdpartyRequestsTransactionsPost + summary: ThirdpartyRequestsTransactionsPost + description: The HTTP request POST `/thirdpartyRequests/transactions` is used by a PISP to initiate a 3rd party Transaction request with a DFSP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Transaction request to be created. + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: |- + Used by: PISP + The HTTP request POST /thirdpartyRequests/transactions is used to request the creation of a transaction request on the server for the transfer described in the request. + Callback and data model information for POST /thirdpartyRequests/transactions: + Callback - PUT /thirdpartyRequests/transactions/{ID} Error Callback - PUT /thirdpartyRequests/transactions/{ID}/error Data Model - See link below + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31712-post-thirdpartyrequeststransactions + properties: + transactionRequestId: + allOf: + - $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/consentRequestId' + description: | + Common ID between the PISP and the Payer DFSP for the transaction request object. The ID should be reused for resends of the same transaction request. A new ID should be generated for each new transaction request. + payee: + allOf: + - title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0' + merchantClassificationCode: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/merchantClassificationCode' + name: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/name' + personalInfo: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/party/properties/personalInfo' + required: + - partyIdInfo + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: | + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + Number, that is, the phone number) is used as reference to a participant. + The MSISDN identifier should be in international format according to the + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + Optionally, the MSISDN may be prefixed by a single plus sign, indicating the + international prefix. + - EMAIL - An email is used as reference to a + participant. The format of the email should be according to the informational + [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. + Examples of personal identification are passport number, birth certificate + number, and national registration number. The identifier number is added in + the PartyIdentifier element. The personal identifier type is added in the + PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) + is used as reference to a participant. The BUSINESS identifier can be in any + format. To make a transaction connected to a specific username or bill number + in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a + specific business or organization is used as reference to a Party. + For referencing a specific device under a specific business or organization, + use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + reference to a participant. The ACCOUNT_ID identifier can be in any format, + as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a + participant. The IBAN identifier can consist of up to 34 alphanumeric + characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be + created in the FSP as an alternative reference to an account owner. + Another example of an alias is a username in the FSP system. + The ALIAS identifier can be in any format. It is also possible to use the + PartySubIdOrType element for identifying an account under an Alias defined + by the PartyIdentifier. + - CONSENT - A Consent represents an agreement between a PISP, a Customer and + a DFSP which allows the PISP permission to perform actions on behalf of the + customer. A Consent has an authoritative source: either the DFSP who issued + the Consent, or an Auth Service which administers the Consent. + - THIRD_PARTY_LINK - A Third Party Link represents an agreement between a PISP, + a DFSP, and a specific Customer's account at the DFSP. The content of the link + is created by the DFSP at the time when it gives permission to the PISP for + specific access to a given account. + example: PERSONAL_ID + partyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + partySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: 'Either a sub-identifier of a PartyIdentifier, or a sub-type of the PartyIdType, normally a PersonalIdentifierType.' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: |- + Below are the allowed values for the enumeration AmountType. + - SEND - Amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. + - RECEIVE - Amount the Payer would like the Payee to receive, that is, the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + title: Currency + description: 'The currency codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic codes are used as the standard naming representation for currencies.' + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - XTS + - XXX + - YER + - ZAR + - ZMW + - ZWD + amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: 'The API data type Amount is a JSON String in a canonical format that is restricted by a regular expression for interoperability reasons. This pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 digits in the major currency unit is not allowed.' + example: '123.45' + required: + - currency + - amount + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/paths/~1thirdpartyRequests~1authorizations/post/requestBody/content/application~1json/schema/properties/transactionType' + description: Type of transaction. + note: + type: string + minLength: 1 + maxLength: 256 + description: A memo that will be attached to the transaction. + expiration: + type: string + description: | + Date and time until when the transaction request is valid. It can be set to get a quick failure in case the peer FSP takes too long to respond. + example: '2016-05-24T08:38:08.699-04:00' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + tags: + - thirdpartyRequests + - sampled + operationId: GetThirdpartyTransactionRequests + summary: GetThirdpartyTransactionRequests + description: | + The HTTP request `GET /thirdpartyRequests/transactions/{ID}` is used to request the + retrieval of a third party transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + tags: + - thirdpartyRequests + - sampled + operationId: UpdateThirdPartyTransactionRequests + summary: UpdateThirdPartyTransactionRequests + description: | + The HTTP request `PUT /thirdpartyRequests/transactions/{ID}` is used by the DFSP to inform the client about + the status of a previously requested thirdparty transaction request. + + Switch(Thirdparty API Adapter) -> PISP + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPutResponse + type: object + description: |- + Used by: DFSP + After a PISP requests the creation of a Third Party Transaction request (POST /thirdpartyRequests/transactions) or the status of a previously created Third Party Transaction request (GET /thirdpartyRequests/transactions/{ID}), the DFSP will send this callback. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31721-put-thirdpartyrequeststransactionsid + properties: + transactionRequestState: + title: TransactionRequestState + type: string + enum: + - RECEIVED + - PENDING + - ACCEPTED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payer FSP has received the transaction from the Payee FSP. + - PENDING - Payer FSP has sent the transaction request to the Payer. + - ACCEPTED - Payer has approved the transaction. + - REJECTED - Payer has rejected the transaction. + example: RECEIVED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestState + example: + transactionRequestState: RECEIVED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + patch: + operationId: NotifyThirdpartyTransactionRequests + summary: NotifyThirdpartyTransactionRequests + description: | + The HTTP request `PATCH /thirdpartyRequests/transactions/{ID}` is used to + notify a thirdparty of the outcome of a transaction request. + + Switch(Thirdparty API Adapter) -> PISP + tags: + - thirdpartyRequests + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ThirdpartyRequestsTransactionsIDPatchResponse + type: object + description: |- + Used by: DFSP + The issuing PISP will expect a response to their request for a transfer which describes the finalized state of the requested transfer. + This response will be given by a PATCH call on the /thirdpartyRequests/transactions/{ID} resource. + The {ID} given in the query string should be the transactionRequestId which was originally used by the PISP to identify the transaction request. + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31612-post-thirdpartyrequestsauthorizations + properties: + completedTimestamp: + title: DateTime + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$' + description: 'The API data type DateTime is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. The format is according to [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html), expressed in a combined date, time and time zone format. A more readable version of the format is yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples are "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z indicates Zulu time zone, same as UTC).' + example: '2016-05-24T08:38:08.699-04:00' + transactionRequestState: + $ref: '#/paths/~1thirdpartyRequests~1transactions~1%7BID%7D/put/requestBody/content/application~1json/schema/properties/transactionRequestState' + transactionState: + title: TransactionState + type: string + enum: + - RECEIVED + - PENDING + - COMPLETED + - REJECTED + description: |- + Below are the allowed values for the enumeration. + - RECEIVED - Payee FSP has received the transaction from the Payer FSP. + - PENDING - Payee FSP has validated the transaction. + - COMPLETED - Payee FSP has successfully performed the transaction. + - REJECTED - Payee FSP has failed to perform the transaction. + example: RECEIVED + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - transactionRequestState + - transactionState + example: + transactionRequestState: ACCEPTED + transactionState: COMMITTED + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/thirdpartyRequests/transactions/{ID}/error': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + tags: + - thirdpartyRequests + - sampled + operationId: ThirdpartyTransactionRequestsError + summary: ThirdpartyTransactionRequestsError + description: | + If the server is unable to find the transaction request, or another processing error occurs, + the error callback `PUT /thirdpartyRequests/transactions/{ID}/error` is used. + The `{ID}` in the URI should contain the `transactionRequestId` that was used for the creation of + the thirdparty transaction request. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Error information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}': + parameters: + - name: Type + in: path + required: true + schema: + type: string + description: 'The type of the party identifier. For example, `MSISDN`, `PERSONAL_ID`.' + - name: ID + in: path + required: true + schema: + type: string + description: The identifier value. + - name: Content-Type + in: header + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + - name: Date + in: header + schema: + type: string + required: true + description: The `Date` header field indicates the date when the request was sent. + - name: X-Forwarded-For + in: header + schema: + type: string + required: false + description: |- + The `X-Forwarded-For` header field is an unofficially accepted standard used for informational purposes of the originating client IP address, as a request might pass multiple proxies, firewalls, and so on. Multiple `X-Forwarded-For` values should be expected and supported by implementers of the API. + + **Note:** An alternative to `X-Forwarded-For` is defined in [RFC 7239](https://tools.ietf.org/html/rfc7239). However, to this point RFC 7239 is less-used and supported than `X-Forwarded-For`. + - name: FSPIOP-Source + in: header + schema: + type: string + required: true + description: The `FSPIOP-Source` header field is a non-HTTP standard field used by the API for identifying the sender of the HTTP request. The field should be set by the original sender of the request. Required for routing and signature verification (see header field `FSPIOP-Signature`). + - name: FSPIOP-Destination + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-Destination` header field is a non-HTTP standard field used by the API for HTTP header based routing of requests and responses to the destination. The field must be set by the original sender of the request if the destination is known (valid for all services except GET /parties) so that any entities between the client and the server do not need to parse the payload for routing purposes. If the destination is not known (valid for service GET /parties), the field should be left empty.' + - name: FSPIOP-Encryption + in: header + schema: + type: string + required: false + description: The `FSPIOP-Encryption` header field is a non-HTTP standard field used by the API for applying end-to-end encryption of the request. + - name: FSPIOP-Signature + in: header + schema: + type: string + required: false + description: The `FSPIOP-Signature` header field is a non-HTTP standard field used by the API for applying an end-to-end request signature. + - name: FSPIOP-URI + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-URI` header field is a non-HTTP standard field used by the API for signature verification, should contain the service URI. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + - name: FSPIOP-HTTP-Method + in: header + schema: + type: string + required: false + description: 'The `FSPIOP-HTTP-Method` header field is a non-HTTP standard field used by the API for signature verification, should contain the service HTTP method. Required if signature verification is used, for more information, see [the API Signature document](https://github.com/mojaloop/docs/tree/master/Specification%20Document%20Set).' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesByTypeAndID + parameters: + - name: Accept + in: header + required: true + schema: + type: string + description: The `Accept` header field indicates the version of the API the client would like the server to use. + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + application/json: + schema: + title: ErrorInformationResponse + type: object + description: Data model for the complex type object that contains an optional element ErrorInformation used along with 4xx and 5xx responses. + properties: + errorInformation: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema/properties/errorInformation' + headers: + Content-Length: + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + Content-Type: + schema: + type: string + required: true + description: The `Content-Type` header indicates the specific version of the API used to send the payload body. + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '405': + description: Method Not Allowed + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '501': + description: Not Implemented + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/content/application~1json/schema' + headers: + Content-Length: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Length' + Content-Type: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400/headers/Content-Type' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesByTypeAndID2 + parameters: + - name: Content-Length + in: header + required: false + schema: + type: integer + description: |- + The `Content-Length` header field indicates the anticipated size of the payload body. Only sent if there is a body. + + **Note:** The API supports a maximum size of 5242880 bytes (5 Megabytes). + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + title: PartiesTypeIDPutResponse + type: object + description: 'The object sent in the PUT /parties/{Type}/{ID} callback.' + properties: + party: + title: Party + type: object + description: Data model for the complex type Party. + properties: + partyIdInfo: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. An ExtensionList element has been added to this reqeust in version v1.1 + properties: + partyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + description: |- + Below are the allowed values for the enumeration. + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix. + - EMAIL - An email is used as reference to a participant. The format of the email should be according to the informational [RFC 3696](https://tools.ietf.org/html/rfc3696). + - PERSONAL_ID - A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element. + - BUSINESS - A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used. + - DEVICE - A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element. + - ACCOUNT_ID - A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP. + - IBAN - A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace. + - ALIAS An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier. + partyIdentifier: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partyIdentifier' + partySubIdOrType: + $ref: '#/paths/~1thirdpartyRequests~1transactions/post/requestBody/content/application~1json/schema/properties/payer/allOf/0/properties/partySubIdOrType' + fspId: + $ref: '#/paths/~1services~1%7BServiceType%7D/put/requestBody/content/application~1json/schema/properties/providers/items' + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - partyIdType + - partyIdentifier + merchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: 'A limited set of pre-defined numbers. This list would be a limited set of numbers identifying a set of popular merchant types like School Fees, Pubs and Restaurants, Groceries, etc.' + name: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + personalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + middleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + lastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\p{L}\p{gc=Mark}\p{digit}\p{gc=Connector_Punctuation}\p{Join_Control} .,''''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + dateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: '^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$' + description: Date of Birth of the Party. + example: '1966-06-16' + required: + - partyIdInfo + required: + - party + responses: + '200': + description: OK + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubI}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}': + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - name: SubId + in: path + required: true + schema: + type: string + description: 'A sub-identifier of the party identifier, or a sub-type of the party identifier''s type. For example, `PASSPORT`, `DRIVING_LICENSE`.' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + description: 'The HTTP request `GET /parties/{Type}/{ID}` (or `GET /parties/{Type}/{ID}/{SubId}`) is used to look up information regarding the requested Party, defined by `{Type}`, `{ID}` and optionally `{SubId}` (for example, `GET /parties/MSISDN/123456789`, or `GET /parties/BUSINESS/shoecompany/employee1`).' + summary: Look up party information + tags: + - parties + operationId: PartiesSubIdByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: 'The callback `PUT /parties/{Type}/{ID}` (or `PUT /parties/{Type}/{ID}/{SubId}`) is used to inform the client of a successful result of the Party information lookup.' + summary: Return party information + tags: + - parties + operationId: PartiesSubIdByTypeAndIDPut + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Party information returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/parties/{Type}/{ID}/{SubId}/error': + put: + description: 'If the server is unable to find Party information of the provided identity, or another processing error occurred, the error callback `PUT /parties/{Type}/{ID}/error` (or `PUT /parties/{Type}/{ID}/{SubId}/error`) is used.' + summary: Return party information error + tags: + - parties + operationId: PartiesSubIdErrorByTypeAndID + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/1' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D~1%7BSubId%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}': + parameters: + - name: ServiceType + in: path + required: true + schema: + type: string + description: 'The type of the service identifier. For example, `THIRD_PARTY_DFSP`' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + get: + operationId: GetServicesByServiceType + summary: GetServicesByServiceType + description: | + The HTTP request `GET /services/{ServiceType}` is used to retrieve the list of participants + that support a specified service. + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/parameters/0' + tags: + - services + - sampled + responses: + '202': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/202' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + put: + description: | + The HTTP request `PUT /services/{ServiceType}` is used to return list of participants + that support a specified service. + operationId: PutServicesByServiceType + summary: PutServicesByServiceType + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + required: true + content: + application/json: + schema: + title: ServicesServiceTypePutResponse + type: object + description: |- + Used by: Switch + The callback PUT /services/{ServiceType} is used to inform the client of a successful result of the service information lookup. + Callback and data model information for GET /services/{ServiceType}: + Callback - PUT /services/{ServiceType} Error Callback - PUT /services/{ServiceType}/error Data Model - Empty body + https://github.com/mojaloop/documentation/blob/master/website/versioned_docs/v1.0.1/api/thirdparty/data-models.md#31531-put-servicesservicetype + properties: + providers: + type: array + minLength: 0 + maxLength: 256 + items: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + extensionList: + $ref: '#/paths/~1consentRequests/post/requestBody/content/application~1json/schema/properties/extensionList' + required: + - providers + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' + '/services/{ServiceType}/error': + parameters: + - $ref: '#/paths/~1services~1%7BServiceType%7D/parameters/0' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/2' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/3' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/4' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/5' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/6' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/7' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/8' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/9' + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/parameters/10' + put: + description: | + The HTTP request `PUT /services/{ServiceType}/error` is used to return error information + operationId: PutServicesByServiceTypeAndError + summary: PutServicesByServiceTypeAndError + tags: + - services + - sampled + parameters: + - $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/parameters/0' + requestBody: + description: Details of the error returned. + required: true + content: + application/json: + schema: + $ref: '#/paths/~1accounts~1%7BID%7D~1error/put/requestBody/content/application~1json/schema' + responses: + '200': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/put/responses/200' + '400': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/400' + '401': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/401' + '403': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/403' + '404': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/404' + '405': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/405' + '406': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/406' + '501': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/501' + '503': + $ref: '#/paths/~1parties~1%7BType%7D~1%7BID%7D/get/responses/503' diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-linking.md b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-linking.md new file mode 100644 index 000000000..7e317db8a --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-linking.md @@ -0,0 +1,412 @@ + +# Transaction Patterns - Linking + +Mojaloop Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Linking](#Linking) + 3.1 [Pre-linking](#Pre-linking) + 3.2 [Discovery](#Discovery) + 3.3 [Request consent](#Requestconsent) + 3.4 [Authentication](#Authentication) + 3.5 [Grant consent](#Grantconsent) + 3.6 [Credential registration](#Credentialregistration) +4. [Unlinking](#Unlinking) + 4.1 [Unlinking without a Switch Hosted Auth Service](#UnlinkingwithoutaSwitchHostedAuthService) + 4.2 [Unlinking with a Switch Hosted Auth Service](#UnlinkingwithaSwitchHostedAuthService) +5. [Error Scenarios](#ErrorScenarios) + 5.1 [Discovery](#Discovery-1) + 5.2 [Bad consentRequests](#BadconsentRequests) + 5.3 [Authentication](#Authentication-1) + 5.4 [Grant consent](#Grantconsent-1) + +# 1. Preface + +This section contains information about how to use this document. + +## 1.1. Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2. Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3. References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document introduces the transaction patterns supported by the Third Party API relating +to the establishment of a relationship between a User, a DFSP and a PISP. + +The API design and architectural style of this API are based on [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) of Ref 1. above. + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Linking + +The goal of the linking process is to explain how users establish trust between +all three interested parties: + +1. User +2. DFSP where User has an account +3. PISP that User wants to rely on to initiate payments + +Linking is broken down into several separate phases: + +1. **Pre-linking** + In this phase, a PISP asks what DFSPs are available to link with. +2. **Request consent** + In this phase, a PISP attempts to establish trust between the 3 parties. +3. **Authentication** + In this phase, a User proves their identity to their DFSP. +4. **Grant consent** + In this phase, a PISP proves to the DFSP that the User and PISP have + established trust and, as a result, the DFSP confirms that mutual trust + exists between the 3 parties. +5. **Credential registration** + In this phase, a User establishes the credential they'll use to consent to + future transfers from the DFSP and initiated by the PISP. + +## 3.1 Pre-linking + +In this phase, a PISP Server needs to know what DFSPs are available to link +with. This is *unlikely* to be done on-demand (e.g., when a User clicks "link" +in the PISP mobile App), and far more likely to be done periodically and cached +by the PISP Server. The reason for this is simply that new DFSPs don't typically +join the Mojaloop network all that frequently, so calling this multiple times on +the same day would likely yield the same results. We recommend that the PISP +calls this request once per day to keep the list of available DFSPs up to date. + +The end-goal of this phase is for the PISP Server to have a final list of DFSPs +available and any relevant metadata about those DFPSs that are necessary to +begin the linking process. + +The PISP can display this list of DFSPs to their user, and the user can select +which DFSP they hold an account with for linking. + +![Pre-linking](./assets/diagrams/linking/0-pre-linking.svg) + +## 3.2 Discovery + +In this phase, we ask the user to select the type and value of identifier they use +with the DFSP they intend to link with. This could be a username, MSISDN (phone number), +or email address. + +The result of this phase is a list of potential accounts available for linking. +The user will then choose one or more of these source accounts and the PISP will +provide these to the DFSP when requesting consent. + +The DFSP MAY send back an `accountNickname` to the PISP in the list of accounts. This list +will be displayed to the user in the PISP application for them to select which accounts +they wish to link. A DFSP could obfuscate some of the nickname depending on their requirements +for displaying account information without authorizing the user. + +**NOTE:** When using the Web authentication channel, it's possible that the +choices made (i.e., the accounts to link with) will be overridden by the user in +a web view. In other words, the user may decide during the Authentication phase +that they actually would like to link a different account than those chosen at +the very beginning. This is perfectly acceptable and should be expected from +time to time. + +![Discovery](./assets/diagrams/linking/1-discovery.svg) + +## 3.3 Request consent + +In this phase, a PISP is asking a specific DFSP to start the process of +establishing consent between three parties: + +1. The PISP +2. The specified DFSP +3. A User that is presumed to be a customer of the DFSP in (2) + +The PISPs request to establish consent must include a few important pieces of +information: + +- The authentication channels that are acceptable to the User +- The scopes required as part of the consent (in this case, almost always just + the ability to view a balance of a specific account and send funds from an + account). + +Some information depends on the authentication channel used (either Web or OTP). +Specifically, if the web authentication channel is used, the following extra +information is required: + +- A callback URI of where a user can be redirected with any extra information. + +The end result of this phase depends on the authentication channel used: + +### 3.3.1 Web + +In the web authentication channel, the result is the PISP being instructed on +a specific URL where this supposed user should be redirected. This URL should be +a place where the user can prove their identity (e.g., by logging in). + +![Request consent](./assets/diagrams/linking/2-request-consent-web.svg) + +### 3.3.2 OTP / SMS + +In the OTP authentication channel, the DFSP sends an 'out of bound' OTP message +to their user (e.g. over SMS or Email). The PISP prompts the user for this OTP +message, and includes it in the `authToken` field in the **PATCH /consentRequests/**_{ID}_ +callback. + +![Request consent](./assets/diagrams/linking/2-request-consent-otp.svg) + +## 3.4 Authentication + +In the authentication phase, the user is expected to prove their identity to the +DFSP. Once this is done, the DFSP will provide the User with some sort of secret +(e.g., an OTP or access token). This secret will then be passed along to the +PISP so that the PISP can demonstrate a chain of trust: + +- The DFSP trusts the User +- The DFSP gives the User a secret +- The User trusts the PISP +- The User gives the PISP the secret that came from the DFSP +- The PISP gives the secret to the DFSP +- The DFSP verified that the secret is correct + +This chain results in the conclusion: The DFSP can trust the PISP is acting on +behalf of the User, and mutual trust exists between all three parties. + +The process of establishing this chain of trust depends on the authentication +channel being used: + +### 3.4.1 Web + +In the web authentication channel, the PISP uses the `authUri` field from +the **PUT /consentRequests/**_{ID}_ callback to redirect the user to the DFSP's +website where they can prove their identity (likely by a typical username and +password style login). + + +**Note:** Keep in mind that at this stage, the User may update their choices of +which accounts to link with. The result of this will be seen later on when +during the Grant consent phase, where the DFSP will provide the correct values +to the PISP in the `scopes` field. + +![Authentication (Web)](./assets/diagrams/linking/3-authentication-web.svg) + + +### 3.4.2 OTP + +When using the OTP authentication channel, the DFSP will send the User some sort +of one-time password over a pre-established channel (such as SMS). The PISP +should prompt the user for this one-time password and then provide it back +to the DFSP using the API call **PATCH /consentRequests/**_{ID}_. + +![Authentication (OTP)](./assets/diagrams/linking/3-authentication-otp.svg) +## 3.5 Grant consent + +Now that mutual trust has been established between all three parties, the DFSP +is able to create a record of that fact by creating a new Consent resource. +This resource will store all the relevant information about the relationship +between the three parties, and will eventually contain additional information +for how the User can prove that it consents to each individual transfer in the +future. + +This phase consists exclusively of the DFSP requesting that a new consent be +created. + +![Grant consent](./assets/diagrams/linking/4-grant-consent.svg) + + +## 3.6 Credential registration + +Once the consent resource has been created, the PISP will attempt to establish +with the DFSP the credential that should be used to verify that a user has +given consent for each transfer in the future. + +This will be done by storing a FIDO credential (e.g., a public key) on the Auth +service inside the consent resource. When future transfers are proposed, we will +require that those transfers be digitally signed by the FIDO credential (in this +case, the private key) in order to be considered valid. + +This credential registration is composed of three phases: (1) deriving the +challenge, (2) registering the credential, and (3) finalizing the consent. + +### 3.6.1 Deriving the challenge + +The PISP must derive the challenge to be used as an input to the FIDO Key +Registration step. This challenge must not be guessable ahead of time by +the PISP. + + +1. _Let `consentId` be the value of the `body.consentId` in the **POST /consents** request_ +2. _Let `scopes` be the value of `body.scopes` in the **POST /consents** request_ + +3. The PISP must build the JSON object `rawChallenge` +``` +{ + "consentId": , + "scopes": +} +``` + +4. Next, the PISP must convert this json object to a string representation using a [RFC-8785 Canonical JSON format](https://tools.ietf.org/html/rfc8785) + +5. Finally, the PISP must calculate a SHA-256 hash of the canonicalized JSON string. +i.e. `SHA256(CJSON(rawChallenge))` + +The output of this algorithm, `challenge` will be used as the challenge for the [FIDO registration flow](https://webauthn.guide/#registration) + + +### 3.6.2 Registering the credential + +Once the PISP has derived the challenge, the PISP will generate a new +credential on the device, digitally signing the challenge, and provide additional +information about the credential on the Consent resource: + +1. The `PublicKeyCredential` object - which contains the key's Id, and an [AuthenticatorAttestationResponse](https://w3c.github.io/webauthn/#iface-authenticatorattestationresponse) which contains the public key +2. A `credentialType` field set to `FIDO` +3. A `status` field set to `PENDING` + +> **Note:** Generic `Credential` objects +> While we are focused on FIDO first, we don't want to exclude PISPs who want +> to offer services to users over other channels, eg. USSD or SMS, for this +> reason, the API also supports a `GENERIC` Credential type, i.e.: +>``` +> CredentialTypeGeneric { +> credentialType: 'GENERIC' +> status: 'PENDING', +> payload: { +> publicKey: base64(...), +> signature: base64(...), +> } +> } +>``` + +The DFSP receives the **PUT /consents/**_{ID}_ call from the PISP, and optionally +validates the Credential object included in the request body. The DFSP then +asks the Auth-Service to create the `Consent` object, and validate the Credential. + +If the DFSP receives a **PUT /consents/**_{ID}_ callback from the Auth-Service, with a +`credential.status` of `VERIFIED`, it knows that the credential is valid according +to the Auth Service. + +Otherwise, if it receives a **PUT /consents/**_{ID}_**/error** callback, it knows that something +went wrong with registering the Consent and associated credential, and can inform +the PISP accordingly. + + +The Auth service is then responsible for calling **POST /participants/CONSENTS/**_{ID}_. +This call will associate the `consentId` with the auth-service's `participantId` and +allows us to look up the Auth service given a `consentId` at a later date. + +![Credential registration: Register](./assets/diagrams/linking/5a-credential-registration.svg) + + +### 3.6.3 Finalizing the Consent + +Once the DFSP is satisfied that the credential is valid, it calls +**POST /participants/THIRD_PARTY_LINK/**_{ID}_ for each account in the +`Consent.scopes` list. This entry is a representation of the account +link between the PISP and DFSP, which the PISP can use to specify +the _source of funds_ for the transaction request. + +Finally, the DFSP calls **PUT /consent/**_{ID}_ with the finalized Consent +object it received from the Auth Service. + + +![Credential registration: Finalize](./assets/diagrams/linking/5b-finalize_consent.svg) + + +# 4. Unlinking + +At some point in the future, it's possible that a User, PISP, or DFSP may decide +that the relationship of trust previously established should no longer exist. +For example, a very common scenario might be a user losing their mobile device +and using an interface from their DFSP to remove the link between the lost +device, the PISP, and the DFSP. + +To make this work, we simply need to provide a way for a member on the network +to remove the Consent resource and notify the other parties about the removal. + + +There are 2 scenarios we need to cater for with a **DELETE /consents/**_{ID}_ request: +1. A DFSP-hosted Auth Service, where no details about the Consent are stored in the Switch, and +2. A Switch hosted Auth Service, where the Switch hosted auth service is considered the Authoritative source on the `Consent` object + + +## 4.1 Unlinking without a Switch Hosted Auth Service +In this case, the switch passes on the **DELETE /consents/22222222-0000-0000-0000-000000000000** request to the DFSP in the `FSPIOP-Destination` header. + +![Unlinking-DFSP-Hosted](./assets/diagrams/linking/6a-unlinking-dfsp-hosted.svg) + +In the case where Unlinking is requested from the DFSP's side, the DFSP can +simply call **PATCH /consents/22222222-0000-0000-0000-000000000000** to inform the PISP of an update to the +`Consent` object. + +## 4.2 Unlinking with a Switch Hosted Auth Service + +In this instance, the PISP still addresses it's **DELETE /consents/22222222-0000-0000-0000-000000000000** call to the +DFSP in the `FSPIOP-Destination` header. + +Internally, the switch will lookup the Authoritative source of the `Consent` object, +using the ALS Call, **GET /participants/CONSENT/**_{ID}_. If it is determined that there +is a Switch hosted Auth Service which 'owns' this `Consent`, the HTTP call **DELETE /consents/**_{ID}_ +will be redirected to the Auth Service. + +![Unlinking-Switch-Hosted](./assets/diagrams/linking/6b-unlinking-hub-hosted.svg) + +# 5.Error Scenarios + +## 5.1 Discovery + +When the DFSP is unable to find a user for the identifier in **GET /accounts/**_{ID}_, +the DFSP responds with error code `6205` in **PUT /accounts/**_{ID}_**/error**. + +![Accounts error](./assets/diagrams/linking/error_scenarios/1-discovery-error.svg) + +## 5.2 ConsentRequest Errors +When the DFSP receives the **POST /consentRequests** request from the PISP, the following processing errors +could occur: + +1. DFSP does not support the specified scopes: `6101`. For example, the `userId` specified does not match the specified accounts, or the `scope.actions` field contains permissions that this DFSP does not support. +2. The PISP sent a bad callbackUri: `6204`. For example, the scheme of the callbackUri could be http, which +the DFSP may choose to not trust. +3. Any other checks or validation of the consentRequests on the DFSP's side fail: `6104`. For example, the user's account may be inactive or suspended. + +In this case, the DFSP must inform the PISP of the failure by sending a **PUT /consentRequests/**_{ID}_**/error** callback to the PISP. + +![consentRequests error](./assets/diagrams/linking/error_scenarios/2-request-consent-error.svg) + +## 5.3 Authentication + +When a PISP sends a **PATCH /consentRequests/**_{ID}_ to the DFSP, the `authToken` may be expired or invalid: + +![Authentication Invalid OTP](./assets/diagrams/linking/error_scenarios/3-authentication-otp-invalid.svg) diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-transfer.md b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-transfer.md new file mode 100644 index 000000000..2b46f3c01 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns-transfer.md @@ -0,0 +1,380 @@ +# Transaction Patterns - Transfer + +Mojaloop Third Party API + +### Table Of Contents + +1. [Preface](#Preface) + 1.1 [Conventions Used in This Document](#ConventionsUsedinThisDocument) + 1.2 [Document Version Information](#DocumentVersionInformation) + 1.3 [References](#References) +2. [Introduction](#Introduction) + 2.1 [Third Party API Specification](#ThirdPartyAPISpecification) +3. [Transfers](#Transfers) + 3.1 [Discovery](#Discovery) + 3.2 [Agreement](#Agreement) + 3.3 [Transfer](#Transfer) +4. [Request TransactionRequest Status](#RequestTransactionRequestStatus) +5. [Error Conditions](#ErrorConditions) + 5.1 [Bad Payee Lookup](#badpayeelookup) + 5.2 [Bad Thirdparty Transaction Request](#badtptr) + 5.3 [Downstream FSPIOP-API Failure](#downstreamapifailure) + 5.4 [Invalid Signed Challenge](#invalidsignedchallenge) + 5.5 [Thirdparty Transaction Request Timeout](#thirdpartytransactionrequesttimeout) +6. [Appendix](#Appendix) + 6.1 [Deriving the Challenge](#DerivingtheChallenge) + +# 1. Preface + +This section contains information about how to use this document. + +## 1.1. Conventions Used in This Document + +The following conventions are used in this document to identify the +specified types of information. + +|Type of Information|Convention|Example| +|---|---|---| +|**Elements of the API, such as resources**|Boldface|**/authorization**| +|**Variables**|Italics with in angle brackets|_{ID}_| +|**Glossary terms**|Italics on first occurrence; defined in _Glossary_|The purpose of the API is to enable interoperable financial transactions between a _Payer_ (a payer of electronic funds in a payment transaction) located in one _FSP_ (an entity that provides a digital financial service to an end user) and a _Payee_ (a recipient of electronic funds in a payment transaction) located in another FSP.| +|**Library documents**|Italics|User information should, in general, not be used by API deployments; the security measures detailed in _API Signature and API Encryption_ should be used instead.| + +## 1.2. Document Version Information + +| Version | Date | Change Description | +| --- | --- | --- | +| **1.0** | 2021-10-03 | Initial Version + +## 1.3. References + +The following references are used in this specification: + +| Reference | Description | Version | Link | +| --- | --- | --- | --- | +| Ref. 1 | Open API for FSP Interoperability | `1.1` | [API Definition v1.1](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md)| + + +# 2. Introduction + +This document introduces the transaction patterns supported by the Third Party API relating +to the initiation of a Transaction Request from a PISP. + +The API design and architectural style of this API are based on [Section 3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#3-api-definition) of Ref 1. above. + +## 2.1 Third Party API Specification + +The Mojaloop Third Party API Specification includes the following documents: + +- [Data Models](./data-models.md) +- [Transaction Patterns - Linking](./transaction-patterns-linking.md) +- [Transaction Patterns - Transfer](./transaction-patterns-transfer.md) +- [Third Party Open API Definition - DFSP](./thirdparty-dfsp-v1.0.yaml) +- [Third Party Open API Definition - PISP](./thirdparty-dfsp-v1.0.yaml) + + +# 3. Transfers + +Transfers is broken down into the separate sections: +1. **Discovery**: PISP looks up the Payee Party to send funds to + +2. **Agreement** PISP confirms the Payee Party, and looks up the terms of the transaction. If the User accepts the terms of the transaction, they sign the transaction with the credential established in the Linking API flow + +3. **Transfer** The Payer DFSP initiates the transaction, and informs the PISP of the transaction result. + +## 3.1 Discovery + +In this phase, a user enters the identifier of the user they wish to send funds to. The PISP executes a **GET /parties/**_{Type}/{ID}_** (or **GET /parties/**_{Type}/{ID}/{SubId}_) call and awaits a callback from the Mojaloop switch. [Section 6.3](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#63-api-resource-parties) +of Ref 1. above describes the **/parties** resource in detail. + +If the **GET /parties/**_{Type}/{ID}_ request is successful, the PISP will receive a **PUT /parties** callback from the Mojaloop switch. The PISP then confirms the Payee with their user. + +Should the PISP receive a **PUT /parties/**_{Type}/{ID}_**/error** (or **PUT /parties/**_{Type}/{ID}/{SubId}_**/error**) callback, the PISP should display the relevant error to their user. + + + +![Discovery](./assets/diagrams/transfer/1-1-discovery.svg) + +## 3.2 Agreement + +### 3.2.1 Thirdparty Transaction Request + +Upon confirming the details of the Payee with their user, the PISP asks the user to enter the `amount` of funds they wish to send to the Payee, and whether or not they wish the Payee to _receive_ that amount, or they wish to _send_ that amount (`amountType` field). + +If the User has linked more than 1 account with the PISP application, the PISP application can ask the user to choose an account they wish to send funds from. Upon confirming the _source of funds_ account, the PISP can determine: +1. the `FSPIOP-Destination` as the DFSP who the User's account is linked with +2. The `payer` field of the **POST /thirdpartyRequests/transactions** request body. The `partyIdType` is `THIRD_PARTY_LINK`, the `fspId` is the fspId of the DFSP who issued the link, and the `partyIdentifier` is the `accountId` specified in the **POST /consents#scopes** body. + +> See [Grant Consent](./transaction-patterns-linking.md#Grantconsent) for more information. + +The PISP then generates a random `transactionRequestId` of type UUID (see [RFC 4122 UUID](https://tools.ietf.org/html/rfc4122)). + +![1-2-1-agreement](./assets/diagrams/transfer/1-2-1-agreement.svg) + +Upon receiving the **POST /thirdpartyRequests/transactions** call from the PISP, the DFSP performs some validation such as: +1. Determine that the `payer` identifier exists, and is one that was issued by this DFSP to the PISP specified in the `FSPIOP-Source`. +2. Confirms that the `Consent` that is identified by the `payer` identifier exists, and is valid. +3. Confirm that the User's account is active and holds enough funds to complete the transaction. +4. Any other validation that the DFSP wishes to do. + +Should this validation succeed, the DFSP will generate a unique `transactionId` for the request, and call **PUT /thirdpartyRequests/transactions/**_{ID}_ with this `transactionId` and a `transactionRequestState` of `RECEIVED`. + +This call informs the PISP that the Thirdparty Transaction Request was accepted, and informs them of the final `transactionId` to watch for at a later date. + +If the above validation fail, the DFSP should send a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** call to the PISP, +with an error message communicating the failure to the PISP. See [Error Codes](./data-models.md#errorcodes) for more information. + +### 3.2.2 Thirdparty Authorization Request + +The Payer DFSP (that is, the institution sending funds at the request of the PISP) may then issue a quotation request (**POST /quotes**) to the Payee DFSP (that is, the institution receiving the funds). Upon receiving the **PUT /quotes/**_{ID}_ callback from the Payee DFSP, the Payer DFSP needs to confirm the details of the transaction with the PISP. + +They use the API call **POST /thirdpartyRequests/authorizations**. The request body is populated with the following fields: + +- `transactionRequestId` - the original id of the **POST /thirdpartyRequests/transactions**. Used by the PISP to correlate an Authorization Request to a Thirdparty Transaction Request +- `authorizationRequestId` - a random UUID generated by the DFSP to identify this Thirdparty Authorization Request +- `challenge` - the challenge is a `BinaryString` which will be signed by the private key on the User's device. While the challenge +could be a random string, we recommend that it be derived from something _meaningful_ to the actors involved in the transaction, +that can't be predicted ahead of time by the PISP. See [Section 4.1](#DerivingtheChallenge) for an example of how the challenge +could be derived. +- `transactionType` the `transactionType` field from the original **POST /thirdpartyRequests/transactions** request + + +![1-2-2-authorization](./assets/diagrams/transfer/1-2-2-authorization.svg) + + +### 3.2.3 Signed Authorization + +Upon receiving the **POST /thirdpartyRequests/authorizations** request from the Payer DFSP, the PISP presents the terms of the proposed +transaction to the user, and asks them if they want to proceed. + +The results of the authorization request are returned to the DFSP via the **PUT /thirdpartyRequests/authorizations/**_{ID}_, where +the *{ID}* is the `authorizationRequestId`. + + +If the user rejects the transaction, the following is the payload sent in **PUT /thirdpartyRequests/authorizations/**_{ID}_: + +```json +{ + "responseType": "REJECTED" +} +``` + +![1-2-3-rejected-authorization](./assets/diagrams/transfer/1-2-3-rejected-authorization.svg) + + +Should the user accept the transaction, the payload will depend on the `credentialType` of the `Consent.credential`: + +1. If `FIDO`, the PISP asks the user to complete the [FIDO Assertion](https://webauthn.guide/#authentication) flow to sign the challenge. + The `signedPayload.fidoSignedPayload` is the `FIDOPublicKeyCredentialAssertion` returned from the FIDO Assertion process. See [3.2.3.1 Signing the Challenge FIDO](#SigningTheChallengeFIDO) + +2. If `GENERIC`, the private key created during the [credential registration process](../linking/README.md#162-registering-the-credential) is + used to sign the challenge. See [3.2.3.2 Signing the Challenge with a GENERIC Credential](#SigningTheChallengeGeneric) + +#### 3.2.3.1 Signing the Challenge FIDO + +For a `FIDO` `credentialType`, the PISP asks the user to complete the [FIDO Assertion](https://webauthn.guide/#authentication) flow to sign the challenge. The `signedPayload.value` is the [`PublicKeyCredential`](https://w3c.github.io/webauthn/#publickeycredential) returned from the FIDO Assertion process, where the `ArrayBuffer`s are parsed as base64 encoded utf-8 strings. As a `PublicKeyCredential` is the response of both the FIDO Attestation and Assertion, we define the following interface: `FIDOPublicKeyCredentialAssertion`: + + +```json +FIDOPublicKeyCredentialAssertion { + "id": "string", + "rawId": "string - base64 encoded utf-8", + "response": { + "authenticatorData": "string - base64 encoded utf-8", + "clientDataJSON": "string - base64 encoded utf-8", + "signature": "string - base64 encoded utf-8", + "userHandle": "string - base64 encoded utf-8", + }, + "type": "public-key" +} +``` + +The final payload of the **PUT /thirdpartyRequests/authorizations/**_{ID}_ is then: + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "FIDO", + "fidoSignedPayload": FIDOPublicKeyCredentialAssertion + } +} +``` + +![1-2-3-signed-authorization-fido](./assets/diagrams/transfer/1-2-3-signed-authorization-fido.svg) + + +#### 3.2.3.2 Signing the Challenge with a GENERIC Credential + +For a `GENERIC` credential, the PISP will perform the following steps: + + +1. Given the inputs: + - `challenge` (`authorizationRequest.challenge`) as a base64 encoded utf-8 string + - `privatekey` (stored by the PISP when creating the credential), as a base64 encoded utf-8 string + - SHA256() is a one way hash function, as defined in [RFC6234](https://datatracker.ietf.org/doc/html/rfc6234) + - sign(data, key) is a signature function that takes some data and a private key to produce a signature +2. _Let `challengeHash` be the result of applying the SHA256() function over the `challenge`_ +3. _Let `signature` be the result of applying the sign() function to the `challengeHash` and `privateKey`_ + +The response from the PISP to the DFSP then uses this _signature_ as the `signedPayload.genericSignedPayload` field: + + +The final payload of the **PUT /thirdpartyRequests/authorizations/**_{ID}_ is then: + +```json +{ + "responseType": "ACCEPTED", + "signedPayload": { + "signedPayloadType": "GENERIC", + "genericSignedPayload": "utf-8 base64 encoded signature" + } +} +``` + +![1-2-3-signed-authorization-generic](./assets/diagrams/transfer/1-2-3-signed-authorization-generic.svg) + + +### 3.2.4 Validate Authorization + +> __Note:__ If the DFSP uses a self-hosted authorization service, this step can be skipped. + +The DFSP now needs to check that challenge has been signed correctly, and by the private key that corresponds to the +public key that is attached to the `Consent` object. + +The DFSP uses the API call **POST /thirdpartyRequests/verifications**, the body of which is comprised of: + +- `verificationRequestId` - A UUID created by the DFSP to identify this verification request. +- `challenge` - The same challenge that was sent to the PISP in [3.2.2 Thirdparty Authorization Request](#ThirdpartyAuthorizationRequest) +- `consentId` - The `consentId` of the Consent resource that contains the credential public key with which to verify this transaction. +- `signedPayloadType` - The type of the SignedPayload, depending on the type of credential registered by the PISP +- `fidoValue` or `genericValue` - The corresponding field from the **PUT /thirdpartyRequests/authorizations** request body from the PISP. +The DFSP must lookup the `consentId` based on the `payer` details of the `ThirdpartyTransactionRequest`. + +![1-2-4-verify-authorization](./assets/diagrams/transfer/1-2-4-verify-authorization.svg) + +## 3.3 Transfer + +Upon validating the signed challenge, the DFSP can go ahead and initiate a standard Mojaloop Transaction using the FSPIOP API. + +After receiving the **PUT /transfers/**_{ID}_ call from the switch, the DFSP looks up the ThirdpartyTransactionRequestId for the given transfer, +and sends a **PATCH /thirdpartyRequests/transactions/**_{ID}_ call to the PISP. + +Upon receiving this callback, the PISP knows that the transfer has completed successfully, and can inform their user. + +![1-3-transfer](./assets/diagrams/transfer/1-3-transfer.svg) + + +# 4. Request TransactionRequest Status + +A PISP can issue a **GET /thirdpartyRequests/transactions/**_{ID}_ to find the status of a transaction request. + +![PISPTransferSimpleAPI](./assets/diagrams/transfer/get_transaction_request.svg) + +1. PISP issues a **GET /thirdpartyRequests/transactions/**_{ID}_ +1. Switch validates request and responds with `202 Accepted` +1. Switch looks up the endpoint for `dfspa` for forwards to DFSP A +1. DFSPA validates the request and responds with `202 Accepted` +1. DFSP looks up the transaction request based on its `transactionRequestId` + - If it can't be found, it calls **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** to the Switch, with a relevant error message + +1. DFSP Ensures that the `FSPIOP-Source` header matches that of the originator of the **POST /thirdpartyRequests/transactions** + - If it does not match, it calls **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** to the Switch, with a relevant error message + +1. DFSP calls **PUT /thirdpartyRequests/transactions/**_{ID}_ with the following request body: + ``` + { + transactionRequestState: TransactionRequestState + } + ``` + + Where `transactionId` is the DFSP-generated id of the transaction, and `TransactionRequestState` is `RECEIVED`, `PENDING`, `ACCEPTED`, `REJECTED`, as defined in [7.5.10 TransactionRequestState](https://github.com/mojaloop/mojaloop-specification/blob/master/fspiop-api/documents/v1.1-document-set/API%20Definition%20v1.1.md#7510-transactionrequeststate) of the API Definition + + +1. Switch validates request and responds with `200 OK` +1. Switch looks up the endpoint for `pispa` for forwards to PISP +1. PISP validates the request and responds with `200 OK` + +# 5. Error Conditions + +After the PISP initiates the Thirdparty Transaction Request with **POST /thirdpartyRequests/transactions**, the DFSP must send either a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** or **PATCH /thirdpartyRequests/transactions/**_{ID}_ callback to inform the PISP of a final status to the Thirdparty Transaction Request. + +- **PATCH /thirdpartyRequests/transactions/**_{ID}_ is used to inform the PISP of the final status of the Thirdparty Transaction Request. This could be either a Thirdparty Transaction Request that was rejected by the user, or a Thirdparty Transaction Request that was approved and resulted in a successful transfer of funds. +- **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** is used to inform the PISP of a failed Thirdparty Transaction Request. +- If a PISP doesn't receive either of the above callbacks within the `expiration` DateTime specified in the **POST /thirdpartyRequests/transactions**, it can assume the Thirdparty Transaction Request failed, and inform their user accordingly + + +## 5.1 Unsuccessful Payee Lookup + +When the PISP performs a Payee lookup (**GET /parties/**_{Type}/{ID}_), they may receive the callback **PUT /parties/**_{Type}/{ID}_**/error**. + +See [6.3.4 Parties Error Callbacks](https://docs.mojaloop.io/mojaloop-specification/documents/API%20Definition%20v1.0.html#634-error-callbacks) of the FSPIOP API Definition for details on how to interpret use this error callback. + +In this case, the PISP may wish to display an error message to their user informing them to try a different identifier, or try again at a later stage. +## 5.2 Bad Thirdparty Transaction Request + +When the DFSP receives the **POST /thirdpartyRequests/transactions** request from the PISP, the following processing or validation errors may occur: +1. The `payer.partyIdType` or `payer.partyIdentifier` is not valid, or not linked with a valid **Consent** that the DFSP knows about +2. The user's account identified by `payer.partyIdentifier` doesn't have enough funds to complete the transaction +3. The currency specified by `amount.currency` is not a currency that the user's account transacts in +4. `payee.partyIdInfo.fspId` is not set - it's an optional property, but payee fspId will be required to properly address quote request +5. Any other checks or verifications of the transaction request on the DFSP's side fail + +In this case, the DFSP must inform the PISP of the failure by sending a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + +![3-2-1-bad-tx-request](./assets/diagrams/transfer/3-2-1-bad-tx-request.svg) + +The PISP can then inform their user of the failure, and can ask them to restart the Thirdparty Transaction request if desired. + + +## 5.3 Downstream FSPIOP-API Failure + +The DFSP may not want to (or may not be able to) expose details about downstream failures in the FSPIOP API to PISPs. + +For example, before issuing a **POST /thirdpartyRequests/authorizations** to the PISP, if the **POST /quotes** call with the Payee FSP fails, the DFSP sends a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + +![3-3-1-bad-quote-request](./assets/diagrams/transfer/3-3-1-bad-quote-request.svg) + +Another example is where the **POST /transfers** request fails: + +![3-3-2-bad-transfer-request](./assets/diagrams/transfer/3-3-2-bad-transfer-request.svg) + + +## 5.4 Invalid Signed Challenge + +After receiving a **POST /thirdpartyRequests/authorizations** call from the DFSP, the PISP asks the user to sign the `challenge` using the credential that was registered during the account linking flow. + +The signed challenge is returned to the DFSP with the call **PUT /thirdpartyRequest/authorizations/**_{ID}_. + +The DFSP either: +1. Performs validation of the signed challenge itself +2. Queries the Auth-Service with the **thirdpartyRequests/verifications** resource to check the validity of the signed challenge against the publicKey registered for the Consent. + +Should the signed challenge be invalid, the DFSP sends a **PUT /thirdpartyRequests/transactions/**_{ID}_**/error** callback to the PISP. + + +### Case 1: DFSP self-verifies the signed challenge + +![3-4-1-bad-signed-challenge-self-hosted](./assets/diagrams/transfer/3-4-1-bad-signed-challenge-self-hosted.svg) + + +### Case 2: DFSP uses the hub-hosted Auth-Service to check the validity of the signed challenge against the registered credential. + +![3-4-2-bad-signed-challenge-auth-service](./assets/diagrams/transfer/3-4-2-bad-signed-challenge-auth-service.svg) + +## 5.5 Thirdparty Transaction Request Timeout + +If a PISP doesn't receive either of the above callbacks within the `expiration` DateTime specified in the **POST /thirdpartyRequests/transactions**, it can assume the Thirdparty Transaction Request failed, and inform their user accordingly. + + +![3-6-tpr-timeout](./assets/diagrams/transfer/3-6-tpr-timeout.svg) + +# 6. Appendix + +## 6.1 Deriving the Challenge + +1. _Let `quote` be the value of the response body from the **PUT /quotes/**_{ID}_ call_ +2. _Let the function `CJSON()` be the implementation of a Canonical JSON to string, as specified in [RFC-8785 - Canonical JSON format](https://tools.ietf.org/html/rfc8785)_ +3. _Let the function `SHA256()` be the implementation of a SHA-256 one way hash function, as specified in [RFC-6234](https://tools.ietf.org/html/rfc6234)_ +4. The DFSP must generate the value `jsonString` from the output of `CJSON(quote)` +5. The `challenge` is the value of `SHA256(jsonString)` \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns.md b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns.md new file mode 100644 index 000000000..5110f83e0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/api/thirdparty/transaction-patterns.md @@ -0,0 +1,6 @@ +## Transaction Patterns + +The interactions and examples of how a DFSP and PISP will interact with the Third Party API can be found in the following Transaction Patterns Documents: + +1. [Linking](./transaction-patterns-linking.md) describes how an account link and credential can be established between a DFSP and a PISP +2. [Transfer](./transaction-patterns-transfer.md) describes how a PISP can initate a payment from a DFSP's account using the account link \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/README.md b/website/versioned_docs/v1.0.1/community/README.md new file mode 100644 index 000000000..385329179 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/README.md @@ -0,0 +1,20 @@ +# Welcome to Mojaloop Community + +## How do I get started? + +* A good first place to get started is the [Contributors' Guide](./contributing/contributors-guide.md), which provides information on how you can contribute to the project. +* If you would like an overview of the technologies used in the project, head over to the [Tools and Technologies](./tools/tools-and-technologies.md) section. +* To get a sense of the features we are building, view the [Product Roadmap](./mojaloop-roadmap.md). +* The [Project board](https://github.com/mojaloop/project#zenhub) showcases what is currently being worked on; you can start with a [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). + +## Where can I get help? + +Join the [Mojaloop Slack Discussions](https://mojaloop-slack.herokuapp.com/) to connect with other members of the community. + +## What if I have more questions? +You can checkout some of our frequently asked questions in the [FAQ](../getting-started/faqs.md) section. Or better still head over to the community on [Slack](https://mojaloop-slack.herokuapp.com/). + +## How do I stay up to date with the project? +Subscribe by joining the [commmunity](https://community.mojaloop.io/) where you can be notified about upcoming [events](https://community.mojaloop.io/c/events/8) and [product announcements](https://community.mojaloop.io/c/announcements/9). + +You can also join our [Slack Announcements](https://mojaloop.slack.com/messages/CG3MAJZ5J) channel to receive information on the latest release. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/Mojaloop Performance 2020.pdf b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/Mojaloop Performance 2020.pdf new file mode 100644 index 000000000..719dec47e Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/Mojaloop Performance 2020.pdf differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/README.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/README.md new file mode 100644 index 000000000..67fffae5f --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/README.md @@ -0,0 +1,27 @@ +# Discussion Documents (Archive) + +## PI 10 +- [Performance Project](./Mojaloop%20Performance%202020.pdf) +- [Code Improvement Project](./code-improvement.md) +- [Cross Border Project](./cross-border.md) +- [PSIP Project](./pisp.md) + +## PI 9 + +- [Versioning Draft Proposal](./versioning-draft-proposal.md) +- [Code Improvement Project](./code-improvement.md) +- [Performance Project](./performance.md) +- [Cross Border Project](./crossborder.md) +- [PSIP Project](./pisp.md) + +## PI 8 + +- [Cross Border Meeting Notes Day 1](./cross-border-day-1.md) +- [Cross Border Meeting Notes Day 2](./cross-border-day-2.md) +- [ISO integration Overivew](./iso-integration.md) +- [Mojaoop Decimal Type; Based on XML Schema Decimal Type](./mojaloop-decimal.md) + +## PI 7 + +- [Workbench Workstream](./workbench.md) + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/aws_tagging.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/aws_tagging.md new file mode 100644 index 000000000..a50c7b2ef --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/aws_tagging.md @@ -0,0 +1,127 @@ +# AWS Tagging Guidelines + Policies + +> **Note:** These guidelines are specific to the Mojaloop Community's AWS Environment for testing and validating Mojaloop installations, and are primarily for internal purposes. They may, however, be a useful reference to others wishing to implement similar tagging strategies in their own organizations. + +To better manage and understand our AWS usage and spending, we are implementing the following tagging guidelines. + +## Contents +- [Proposed tags and their meanings](#proposed-tags-and-their-meanings) + - [mojaloop/cost_center](#mojaloopcost_center) + - [mojaloop/owner](#mojaloopowner) +- [Manual Tagging](#manual-tagging) +- [Automated Tagging](#automated-tagging) +- [AWS Tagging Policies](#aws-tagging-policies) + - [Viewing Tag Reports + Compliance](#viewing-tag-reports--compliance) + - [Editing Tag Policies](#editing-tag-policies) + - [Attaching/Detaching Tag Policies](#attachingdetaching-tag-policies) + +## Proposed tags and their meanings + +We propose the following 2 tag _keys_: + +- `mojaloop/cost_center` +- `mojaloop/owner` + +### `mojaloop/cost_center` + +`mojaloop/cost_center` is a breakdown of different resources in AWS by the workstream or project that is incurring the associated costs. + +It loosely follows the format of `-[-subpurpose]`, where account is something like `oss`, `tips`, or `woccu`. +> Note: It's likely that most of the resources will be under the `oss` "account", but I managed to find some older resources that fall under the `tips` and `woccu` categories. We also want to plan for future types of resources that might be launched in the future. + +Some potential values for `mojaloop/cost_center` are: + +- `oss-qa`: Open source QA work, such as the existing dev1 and dev2 environments +- `oss-perf`: Open source performance work, such as the ongoing performance workstream +- `oss-perf-poc`: Performance/Architecture POC + +We also reserve some special values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/cost_center:unknown` tags and produce a report +- `n/a`: This resource incurrs no cost, so we're not really worried about assigning a `cost_center` to it + - This can be useful for mass tagging resources that are hard to figure out where the belong, such as EC2 Security Groups + +### `mojaloop/owner` + +`mojaloop/owner` is a person who is responsible for the managing and shutdown of a given resource. + +The goal of this tag is to prevent long running resources that everybody else thinks _someone else_ knows about, but we no longer need. By applying this tag, we will be able to have a list of _who to go to_ in order to ask questions about the resource. + +The value can simply be a person's name, all lowercase: +- `lewis` +- `miguel` +- etc. + +Once again, we will reserve the following values: +- `unknown`: This resource was evaluated (perhaps manually, or perhaps by an automated tool), and no appropriate `cost_center` could be determined. + - This will allow us to easily filter for the `mojaloop/owner:unknown` tags and see what resources are 'orphaned' + + +## Manual Tagging + +We can use the "Tag Editor" in the AWS console to search for untagged resources. + +1. Log into the AWS Console +2. Under Resource Groups, select "Tag Editor" +![](./images/tagging_01.png) +3. From the tag editor, select a Region (I typically use "All regions"), and Resource Type (I also typically use "All resource types") +4. Now select "Search Resources", and wait for the resources to appear + +You can also search by tags, or the absense of tags to see what resources have not been tagged yet. +![](./images/tagging_02.png) + +5. Once you have a list of the resources, you can select and edit tags for many resources at once! +6. You can also export a `.csv` file of resources found in your search + + +## Automated Tagging + +We currently automate tagging on the following + +As we have a firmer grasp of our tagging guidelines, we need to introduce them into our tooling so that all of the grunt work of manual tagging. + +At the moment, this will look like introducing tags into: +1. Rancher - which currently manages our Kubernetes clusters for both QA and Performance purposes +2. IAC - The upcoming IAC code that will eventually be running our dev environments + + +## AWS Tagging Policies + +As of August 3, 2020, we have started introducing [AWS Tagging Policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) to better enforce tags and monitor our resources (especially with respect to costs). + + +### Viewing Tag Reports + Compliance + +1. Log in to the AWS Console +2. "Resource Groups" > "Tag Editor" +3. On the left sidebar, select "Tag Policies" + +From here you can see the tag policies "compliance report" + +![](./images/tagging_03.png) + + +### Editing Tag Policies + +> Note: This may require special admin priviledges to access these pages + +1. Log in to the AWS Console +2. Select "username@mojaloop" in the top right > "My Organization" +3. Select "Policies" > "Tag Policies" + +![](./images/tagging_04.png) + +4. From here, you can view the current tag policies + +![](./images/tagging_05.png) + +5. In the sidebar, you can click "View details" > "Edit policy" to edit the policy + + +### Attaching/Detaching Tag Policies + +1. Go to the "My Organization" page +2. Select the relevant account > "Tag policies" in the sidebar +3. From here you can Attach + Detach tag policies + +![](./images/tagging_06.png) diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/code-improvement.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/code-improvement.md new file mode 100644 index 000000000..284f97299 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/code-improvement.md @@ -0,0 +1,26 @@ +# Code_Improvement Project + +## Overview +Purpose to improve code quality and security for the Mojaloop project. Includes analysis and introduction of new open sources tools, process improvments, gates checks (w/in pull requests and builds) along with documentation. + +Scope: project is focused on quality and security but can lead to other areas such as test automation and DevOps automation and tools. + +## OutPut (phase one by end of January): +- Implementation and analysis of new OSS tools +- Update Release Scripts: Security aspects need to be embedded in release/devops (CI/CD) +- Update rules for Pull Requests: Security aspects embedded in pull requests (before check-ins) +- Update documentations: Standards and contribution guides +  +Slack Channel:#code_security + + ## Discussions: + ### Implement changes at the Dockerfile and CI/CD build process to help bolster our container security + - Create a non-root user within the Dockerfile + - Enable docker-content-trust on the docker host (this will be inside CircleCI) + - Run builds with --no-cache during CircleCI step to ensure that we are pulling in any new security patches each time (I don’t think this is a major issue since we don’t have CircleCI docker image caching on anyway + + ### Move from Javascript to Typescript + - Transition to typescript (mix and match js and ts) for more security/quality + - Typescript is preferred but not required: https://github.com/mojaloop/template-typescript-public + + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-1.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-1.md new file mode 100644 index 000000000..5c5d51d79 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-1.md @@ -0,0 +1,270 @@ +# Cross Border Discussion Day 1 + +>**Links** +>- [Day 2 Notes](./cross_border_day_2.md) +>- [Relevant Issue on DA Board](https://github.com/mojaloop/design-authority/issues/32) +>- [Mojaloop Spec Pull Request](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Attendees: + +In person +- Lewis, Crosslake +- Adrian, Coil +- Nico, MB +- Sam, MB +- Miguel, MB +- Carol Benson, Glenbrook +- Michael Richards, MB +- Henrik Karlsson, Ericsson +- Rob Reeve, MB +- Vanburn, Terra Pay +- Razin, Terra Pay +- Ram, Terra Pay +- JJ, Google +- Matt Bohan, Gates Foundation +- David Power, EY +- James Bush, MB +- Warren, MB +- Judit, MB +- Bart-Jan and Bruno from GSMA - Day #2 + +Phone +- Kim Walters, Crosslake +- Istvan Molnar, DPC +- Innocent Ephraim, MB + +## Session 1 + +**Goal: Update the API definitions** + +- Privacy: + - Can I send USD? _yes/no_ + - What can I send? _list of currencies_ + +Business agreements: there are a few ways this can happen +- Global scheme, made up of scheme to scheme agreements +- bilateral scheme agreements +- scheme to scheme +- region + + +Definitions: +- Gateway FSP: An FSP that 'bridges' across 2 networks +e.g. Mowali + - 2 logical networks (USD,XOF?) + - a single mojaloop network + +- Cross Network Provider (CNP) + - FXP, same thing? + +Michael: +- there is a reason for that assumption +- other legal implications here... + +- single entity, legally in 2 different jurisdictions + - a close analogy of a scheme without jurisdiction + +- participant: + - has a tx account that can be debited or credited + - bank, fxp etc. + +>Q: Can we have a participant that doesn't settle? Or would this be covered by CNP that is a party +>e.g. Visa, doesn't always settle in a given market, but holds an account + +- Resident vs. Non-resident + - reporting requirements are different + +- what are the technical requirements for reporters? + +- settlement + - not too worried about it at this stage (our focus is on the API changes) + - we assume that settlement is possible, but need to narrow scope witht the api first + +- Not only mojaloop + - need to allow for non-mojaloop -> mojaloop transfers and vice versa (both inbound and outbound) + - must still be interoperable + + +- who provides routing? + - switch? + - ALS? + - CNP? + + +>*Follow Up:* Need a formal definition of FXP and CNP roles, along with requirements and responsibilities + + +At a scheme level + - should the sceheme maintain a list of other schemes it allows its FSPs to connect with? + - or should the CNP take care of this? + +- not scheme -> scheme, but part of the onboarding CNP process +- but the scheme can/should still maintain rules + +- how will quoting work? Should an FSP send multiple quotes, one addressed to each CNP? Or should the switch have some rules engine that helps it determine who to send quotes to? + +James: We want to be flexible. Can see instances where we would want both to happen, so we shouldn't assume too much at this stage. + +Simplest option: The switch talks to the ALS, determines a transfer is not in our network, and then finds a list of CNPs + +CNP + FXP -> essentially the same thing +- they are *Roles*, and a DFSP can assume more than 1 role +- fxps can also exist in more than 1 zone (e.g. Mowali case) + - single network fxp is just an fxp, + - multi-network fxp is likely also a CNP + + +## Session 2 + +- debate about single or multiple lookups + - we should never return "empty result" + +- are wallets addressable by MSISDN? + - only 1 account at the moment + - but this is internal to the switch + - the oracle's job is to convert MSIDN -> Mojaloop Address + +- in the future: MSISDN + accounts will be less related + - this topic is adjacently related to addressing + +- 'going outisde' mojaloop with addressing will be a little tricky +- Standardize addressing? + - not something we want to do + +Ram: There are existing tools (no need to reinvent the wheel), outside the mojaloop scheme + +- sending to unknown currency + - currently: 1 routing table answer + - future: multiple answers + +- privacy: + - no real need for hard rules at the moment (at least not at the API level, rules come along with schemes) + - we do need a method for mediating information that one switch requires from another (and rejecting quotes should these prerequesites not be met) + +--- +- Domestic vs. Cross border: USer has/needs different information + - e.g. do we only want to support discovery in domestic case? +--- + +Adrian: A lot of this stuff is business rule and scheme specific +- maintains competitive space +- How much information is in the: + - lookup? + - Quote? + +--- +- Proposal: Address lookup -> Returns multiple responses? +- MSISDN -> ID, not an address. Someone, not an account + +- there should be only 1 response from the ALS +- Michael disagrees + +- need to separate out *addressing* from *routing* + +- we need to think about the downstream affects this will have on testing + - need to find a clear way to test these lookups + + +For example, airtel UPI issue (where existing MSIDSNs were replaced when they grandfathered in their mobile customers to become mobile money customers) + - we need to avoid a situation like that + +--- + +Bring it back to first (L1P) principles +- transfers should clear immediately +- no such thing as a future + +- For domestic: we can guarantee delivery, but cross-border is much harder +- need to maintain transparency requirement on CNPs + - this comes down to business rules + +- Reversible tx's or rules abour downstream issues + - ILP takes care of *most* of this for us + +- in TIPS case: 1 ID maps to 1 account +- as always, there needs to be a compromise between privacy and features (and that's ok!) + +--- + +At the end of a quote: +- ValueDate +- how much will be received +- what are the fees? (broken down, by step and currency) + +--- + +How do we support protocols that don't support quotes (this is a question for moja to non-moja systems) + +Risk: CNP: they hold the risk in this type of transaction + +CNP as a participant? + - holds an account with a participant + - direct vs indirect approach + - this doesn't affect the technical requirements (so out of scope for this discussion) + + +--- + +- fixed send and receive: + - What direction does data need to be appended to the quote? It depends on if it is fixed receive vs fixed send + +- Either: `A send 20 USD to B` OR `B receives 1000 PHP` + +- translating fees back for user: FXP __must__ apply the same rate for fees as the principal transfer + +- From L1P Perspective: __the goal is transparency__ + +- how about quotes outside of Mojaloop? + - CNP should take care of this - it is the last bastion of Mojaloopyness + +--- + +- Participant Object + - Attached to the Quotes, one entry per hop? + - So multi-hop quotes hold _n_ participant objects, where _n_ = number of hops + 1 + +As part of this we need: +- interoperable bits of data (common defs) +- scheme for encryption +- a place to put the data (in the quotes object) + +Should we worry about encryption for now? +- perhaps not, but still should allow for it in the API + +Encryption adds extra integration challenge +- what is the need to get data in the clear? + - from a techincal perspective: just use a blank encryption key + +Do we need to encrypt to ensure the switch(es) can't see the data? + - perhaps not at this stage + + +>### Decision: +>- No encryption for now +>- in outbound quote request: have a list of data requirements +>- for inbound quote request: participants fill out those requirements +>- if requirements are not met: abort the quote +>- Don't hardcode the data requirements, we should use existing standards + + +- we need to specify whether or not fields _have_ been verified + - ties in with tiered KYC processes + +- need a common dictionary of data that can/should be requested + + +## Boards: + +_board 1: Fixed send flows_ +![board_1](./images/cb_board_1.jpg) + +_board 2: Fixed receive flows_ +![board_2](./images/cb_board_2.jpg) + + + + + + + + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-2.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-2.md new file mode 100644 index 000000000..fbbbfd799 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border-day-2.md @@ -0,0 +1,124 @@ +# Cross Border Discussion Day 2 + +>**Links** +>- [Day 1 Notes](./cross_border_day_1.md) +>- [Relevant Issue on DA Board](https://github.com/mojaloop/design-authority/issues/32) +>- [Mojaloop Spec Pull Request](https://github.com/mojaloop/mojaloop-specification/pull/22) + +## Next Steps: + +- Updated the proposal APIs +- Present the consolidated change to the CCB in writing +- Couple of weeks to put together the changes (Michael/Adrian to split up the work) +- Mid-November CCB call + + +## Session 1 + +Unanswered Questions: +- addressing + - break it down? + - cross-mojaloop + - what does a PayerFSP do with an address? + +- ALS + routing + - what optimizations does the API need to do/allow? + +- local vs. remote DFSP ids + +- Downstream failures + - When paymnet does clear, does the payer receive a notification (esp. with 'delayed' payments that may interface with non-mojaloop systems) + - Can a CNP send a `PATCH` of the tx to update the Payee somehow? + +--- + +- multiple quotes and route responses: + - how do display to the user? + - We need to establish rules for filtering routes + - hard to do: e.g. blacklisting a switch? or express a preference for certain routes + +- how will Sender DFSP discover the scheme rules for a receiver? +- does the Sender DFSP need to 'know' the final switch? Or can it just 'know' the next one? + +--- + +Running up against ML + non-ML assumptions +- does this mean CNP needs to do more work when connecting to non-ML? + - e.g. knowing the resulting scheme/switch? + - why? Failure handling + - based on yesterday's decision: Should the CNP do the work here? + +- Take a lesson from SWIFT: + - bank doesn't know where the money is going + - can we avoid this in ML? + +--- + +CNP: Goal is to 'act like' a normal member of the network + - This minimizes the responsibilities that the scheme assumes + +When is the TX considered completed? + - There might be cases where the scheme considers it done, but it is not techincally finished end to end + +How do we deal with service deteroriation? + - Scheme rules + +--- + +Back to quotes: + +- how to express quote information? + - are quotes and routes separate? Presumably, yes + +- The quote is the most expensive step + - Can we provide QOS information here as part of the lookup? + +Addressing: +- Need for a globally unique address + - Allow an address space for DFSPs and unique persons/accounts +- sheme says "this isn't in my space" +- CNP figures out the routes to get to that space + +--- + +### Michael's Tangent: + +- did we make the wrong assumptions about the CNP? + +**switch:** Knows CNPs + FXPs +**CNPs:** holds routing table and lookup + +- if the sender or receiver is an FXP, the the tx is *not* a cross-currency tx + +--- + +## Session 2 + +*Decision:* +- header value is CNP id +- partId object is the final FSP + +valueDate +- implied that funds are expected to clear before the valueDate +- can still have short expiry times on tx + +- CNP: + - returns an obfuscated set of fees + - fits into our current model + + +- condition: + - existing object cryptographically tied to the tx object + - but for multi-hop, we don't only know this + - fixed receive makes this tricker (which is what echo data hopes to solve) + + - We want **only 1 condition for all hops** + - the idea of a multi-condition is a "perversion" (according to some) + + +## Boards: + +_board 3: Cross Network lookup and quotes flow, fixed receive of 1000 PHP from USD_ +![board_3](./images/cb_board_3.jpg) + + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border.md new file mode 100644 index 000000000..4deec6f8d --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/cross-border.md @@ -0,0 +1,396 @@ +**Cross-border Workstream Meeting** + +March 10th & 11th (London/remote) + +**Next Steps for PI:** + +• Proposal for how the CNP query and host oracle services and global goals - Adrian, Michael + +• Compound identifiers, ways in which this is captured in the system or expressed in apis - open + +• What information is captured in the data model or the extension list - Michael + +• Follow-up w/ SWIFT to discuss requirements - Matt + +**Open Items:** + +• Finalize CNP Requirements + +• Has to aggregate information and put them together into a single request & they will need to sign separately + +• Finalize FXP has to manage FX rates, the settlements and what expires when + +• CNPs can extend this and determine additional scheme rules + +• FXP handles rounding errors + +• FXP Guarantee a given rate + +• How do you get non-Mojaloop folks in the schema? + +• How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + +• How do we manage requests for regulatory reasons + +• Investigate identifier mappings (Map pathfinder accounts/mobile accounts to DFSP unique IDs) + +• Investigate Certification (Hash and PKKI) + + +Detailed Meeting Notes: +Day #1: + - Quote response + + ○ How do we code the SLA into the response + + ○ Ask a 2nd CNP to route + + ○ In the API - need to package up how to get it there + + ○ As a CMP in Mowali if I return a quote response the scheme has implications + + ○ Follow the whole route from payer to payee + + ○ Limiting the participation of CNP - they need to be the last hop + + § How to define the requirements of a CNP? + + - Message format + + ○ Http syntax + + ○ Started from the mojaloop scheme + + § Move towards the CNP should manage the conversion + + ○ SWIFT version + + ○ Security - TLS + + ○ Header/content encrypted in JWS + + - Retail system + + ○ Off network - remit to someone hub + + - Data Model + + ○ Structure: Ways in which we added new information, different routes, etc. + + ○ Privacy: Visibility and Security - only accessible to the people that can see it + + ○ Content of the data model + + - Transfer is done through the switch (movement of money) + + ○ In mowali - the amounts are expressed but the rate is important because it impacts settlements + + § Data flow - we add the rate when we send the quote back + + § Added in the extension list - should it be part of the standard? + + § Send and receive amount (differ currency) + + - Data element + + ○ Fee for each participant + + ○ Payer DFSP adds it up + + ○ Fee element for the transaction + + - Proposal + + ○ Account lookup service + + § List of local FSP + + ○ Switch - need to maintain state and lookup requests + + § Should look like a domestic transfer to the sender + + § Collect the information and send it back - + + ○ CNP - making assumptions to meet requirements + + § Do you need to see the route + + § Collecting different information downstream + + § Sending FSPs needs to know who is the receiver + + ○ CNP has to aggregate information and put them together into a single request & they will need to sign separately + + § Condition and fulfillment is part of a PKI structure + + § If there is more than one CNP - there needs to ensure the DFSP payee has to be certain the DFSP payer - connections + + § CNP needs to know everything, regulatory reporting - + + ○ Do we need to duplicate the structure in a Cross-network transfer? + + § Trying to prevent a rouge partner from joining + + § Trust the CNP to meet their SLAs + + ○ Mojaloop to another scheme - we don’t have control + + § Require they confirm receipt + + § How can I tell + + § How can I tell the person at the end got the money + + ○ External signing authority to confirm the money was received + + § If your scheme wants to participate in x-border then all the participants need to get signed + + § Public key - need to join a mojaloop network have to issue public keys + + § Central certificate issuing authority + + § Need a PKI structure in place + + ○ How do you get non-Mojaloop folks in the schema? + + § How do we integrate Mojaloop and some Mojaloop scheme to provide a full PVT payments - working group with Michael, Adrian, Sybrin, others as needed + + § Identify the participants - FSP, DFSP - all have signed + + § Parties - end users (Bob/Alice) + + § Single transaction (with multiple transfers) + + § No one commits their funds to everyone is satisfied + + § How to extend mojaloop and non-mojaloop scheme + + ○ Certification + + § Hash and PKKI + + § Gold and silver network + + § New partner - live on the network + + § Scheme decides requirement on the network + + § Self-signing cert + + ○ Liquidity + + § FXP does position mgmt + + § What requirements do we put on a FXP + + § Mobile money has less flexibility + + § Rules that happened across schemes + + ○ FXP has to manage the settlements, what expires when, etc.. + + § FXP has to manage the shortage of quote validity + + § Allow FXP to reject the requests + + ○ How do we manage requests for regulatory reasons + + § There is a dictionary + + □ Is the a requirement to share KYC? + + □ You can ask for many things - up to the participant + + □ Need to agree on the baseline scheme + +**Day #2:** + + - Switch data + + ○ Account numbers + + ○ Blacklist, white list (oversight and blocking) + + ○ Keeping it simple + + ○ Hub + + ○ Side service for folks that can do this + + § Mobile data capture + + § Side car + + § Digital process + + § Value added services for the hub (managed service) + + - Switch - need to maintain state and lookup requests + + - CNP can be an ordinary DFSP + + ○ All DFSP supports all the use cases + + ○ Full participants (might just provide a CNP or FXP service) + + - FXP definition and requirements + + ○ FXP - require rates/fees as part of the Quoting service - need standard industry rate + + § CNPs can extend this and determine additional scheme rules + + ○ FXP handles rounding errors + + ○ Guarantee a given rate + + ○ Manage settlement across schemas + + ○ FX rates + + ○ Should allow people that just do FX + + ○ Edge cases for failure + + § Details in the error messages to find the errors + + ○ FXP needs to point back the right information + + § How messages passed work + + § Edge cases - share what is done too date + + § Jo owns got a working API - identified + + § Changed the quote (intercepted the quote) -- + + § KYC extension list - extended the quote for this + + § Rates are in the extended list (are the list) + + § Where the FXP is applied ? + + § What do we do with fees downstream + + □ (payee DFSP takes place of the aggregation) + + - How to manage identifier resolution + + ○ 2 types of Identifiers + + § Global ones (pass to CNP) - to get a response + + § Local ones - expect the user to provide + + ○ Mojaloop we use identifiers as proxy + + ○ Merchant numbers might be specific to a scheme + + ○ Multiple identifiers for a single account + + ○ How do we uniquely identify the account? + + ○ Rely on CNP (restrict each identifiers in this scheme) + + ○ What sort of structures in place + + ○ Passport identification - place holders + + ○ Map pathfinder accounts/mobile accounts to DFSP unique IDs + + § Service - primary account is X + + § Each country has a service they provide + + § Each CNP understands the address scheme + + § Global one - need to know which ways to use + + ○ Sends a get parties to the switch + + § ALS never heard of them + + § 2 ways + + □ Global way (path finder and conversion to BIC) + - CNP + + ○ Not hosting anything + + ○ Route through the CNP - ask others + + ○ Constructing the alternative routes + + - Global registry does not exist + + ○ Ultimate beneficiary + + ○ Established communication + + ○ Challenge will we able to have 2 DFSPs share direct communication and will be a stretch? + + - Switch has schemes + + ○ A Hub operator following Scheme Rules may allow names of FSPs as decided by those Rules + + ○ The technology or the Admin API itself doesn’t restrict the names (apart from restrictions on length, type or characters, etc) + + ○ BGP: Border Gateway Protocol  + + - Query each CNP and then come up with optimizations, matrix that provides global route - goal would be not to query the CNP directly + +• How to connect with Mojaloop? + + - Any financial service can connect to Mowali + + - Scheme rules, technical + + - Regulatory + + - How do I assign stuff? - no one knows the steps + + - Mojaloop API - understand this. + + - 2 instances Mojaloop instances - TIPs and Mowali + + ○ WOCCU, Asia, US - applied for instance + + ○ Still pushing the boundries + + - What dos an integration look like + + ○ Need sandbox, simulators + + ○ Standard approach + +• Instance payment service + + - Get the flows flowing in a timely manner + + - Need real-time ledgers; what happens if they are offline? + + - Exception for off network (banks take advantage of float) + +• Discovery process (sending FSP) + + - Switch determines if they need to contact a FXP + + - What currency the receiving account can receive in + + - Multiple lookups + + - Data model - set of accounts, w/ one currency at a DFSP + + +Attendees: + + - Mike, Patricia - Thume + + - Michael R, Rob R, Sam - Modusbox + + - Kim, Lewis - Crosslake + + - Rolland, Greg, Phillip - Sybrin + + - Vanburn -- Terrapay + + - Megan, Simeon - Virtual diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_1.jpg b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_1.jpg new file mode 100644 index 000000000..e53cad0b9 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_1.jpg differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_2.jpg b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_2.jpg new file mode 100644 index 000000000..8afa47d94 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_2.jpg differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_3.jpg b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_3.jpg new file mode 100644 index 000000000..7cce85870 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/cb_board_3.jpg differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/mojaloop_spokes.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/mojaloop_spokes.png new file mode 100644 index 000000000..b0c67eb08 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/mojaloop_spokes.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_01.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_01.png new file mode 100644 index 000000000..4379443ce Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_01.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_02.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_02.png new file mode 100644 index 000000000..b86ac0a91 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_02.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_03.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_03.png new file mode 100644 index 000000000..d8ab17646 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_03.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_04.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_04.png new file mode 100644 index 000000000..a2913b226 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_04.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_05.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_05.png new file mode 100644 index 000000000..ba54dbf64 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_05.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_06.png b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_06.png new file mode 100644 index 000000000..8c4eb717f Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/images/tagging_06.png differ diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/iso-integration.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/iso-integration.md new file mode 100644 index 000000000..333ed8729 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/iso-integration.md @@ -0,0 +1,61 @@ +Mojaloop ISO Integration discussions + +# Mojaloop-ISO integration + +The proposed solution would be able to handle ISO to Open API translation and vice versa, by making use of an ISO-OPEN API converter/connecter plug-in or interface, similar to the Scheme Adapter in the Mojaloop system. As the Scheme adapter performs Mojaloop API to FSP API conversion, the custom plug-in/interface would function as a protocol and message translator between the ISO interface and the ML API or the Scheme Adapter. + +## Scope + +Define message flows in both and ISO and Open API networks and mappings between messages. + - Document failure scenarios and message flows for these. + - Define a mechanism for routing that is MSISDN-based . + - Mojaloop Transactions could be sent through existing payment rails conforming to their standards(such as ISO) + - Develop a scheme adapter/plug-ins that could perform ISO-Open API and vice versa. + - To be able to send Mojaloop transactions originating from ATM and POS over ISO networks, across Mojaloop systems + + ## ISO 8583 - Mojaloop - An Inter-network case study + +Africa is a great continent with a multitude of Financial Service providers who focuses on region based financial inclusion and services provision. The continent boasts of a vast network of Payment service providers and financial institutions. Some of the most prominent networks are listed below: + +- InterSwitch ( Nigeria) +- eProcess ( Ghana) +- Umoja Switch ( Tanzania) +- KenSwitch ( Kenya) +- ZimSwitch ( ZImbabwe) +- RSwitch ( Rwanda) + +Almost all of these networks make use of an ISO 8583 based Payments processing platform ( Postilion Switch) to drive ATM’s, POS & Mobile channels, process card based and non card based transactions for both acquiring and issuing verticals. + +As such, the proposition is to create a solution, where by the existing Payment networks could integrate with a Mojaloop based system like Mowali, without having to make any development or design changes to their existing infrastructure. + +In this case study, we are considering the case of Umoja Switch in Tanzania and provide them with a solution whereby, Umoja could provide Mojaloop transactions through their existing ATM deployments. + +### Umoja Switch + +UmojaSwitch was established in the year 2006 by six banks in Tanzania with the main purpose being able to establish a joint shared infrastructure for financial services and enjoying the economies of scale. + +The aim of establishment was to create a shared platform where financial institutions can integrate and interpolate through a shared switch. + +Eventually, the number of members joining the UmojaSwitch network continued to increase and as of now there are around 27 banks who has joined the Umoja Switch consortium. + +## ISO Networks to Open API + +The goal of the PoC would be to showcase how a Mojaloop transaction would be sent over a standard ISO switch/Network through to a Mojaloop system such as Mowali. + +As a part of this an ISO-Open API Adapter would be implemented which would process ISO messages originating from an ISO network like InterSwitch and send it through to an Open API network like Mowali. + +## Proposed Solution + +The proposed solution will consist of an interface or adapter/plugin that could process transactions between ISO networks and Mojaloop systems. + +The ISO payments platform makes use of an ISO interface which uses standard TCP/IP connection to send and respond to ISO messages to and from the various channels. In order to accept and process connections from the interface, our solution would have a TCP/IP listener, which would receive and process transactions from ISO network and then map it to Open API , after which the transactions will be sent over to a Mojaloop system like Mowali on a URL. + +In this case the payment networks are largely dependent on their respective (i.e. Visa/ MasterCard/Verve/etc) card or account number, which is used to define the BIN look up table for routing purposes . One of the options would be to predefine a Bin range (eg: 757575) that would identify a Mojaloop transaction and then let the payment network implement a routing logic that would send all Moja transactions through to the Open API network. + +The ISO-Open API adapter would process the ISO message received from the ISO switch and send it through to the Mojaloop system in Open API format. + +However, such changes would imply configurational changes to download applications on ATM and other terminal devices, but this could be handled as a standard operational change similar to the existing configurational changes performed as per the business requirements. + + + + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/mojaloop-decimal.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/mojaloop-decimal.md new file mode 100644 index 000000000..119e51501 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/mojaloop-decimal.md @@ -0,0 +1,38 @@ +# Mojaloop Decimal Type; Based on XML Schema Decimal Type + +## Decimal value type + + Definition: decimal represents a subset of the real numbers, which can be represented by decimal numerals. The value space of decimal is the set of numbers that can be obtained by multiplying an integer by a non-positive power of ten, i.e., expressible as _i_ × 10-n where _i_ and _n_ are integers and _n_ ≥ 0. Precision is not reflected in this value space; the number 2.0 is not distinct from the number 2.00. The order relation on decimal is the order relation on real numbers, restricted to this subset. + Req: All Level One processors must support decimal numbers with a minimum of 18 decimal digits. However, Level One processors may conform to a scheme-defined limit on the maximum number of decimal digits they are prepared to support, which must be 18 or more digits, in which case that scheme-defined maximum number must be clearly documented. + +## Lexical representation + +decimal has a lexical representation consisting of a finite-length sequence of decimal digits (#x30 – #x39) separated by a period as a decimal indicator. An optional leading sign is allowed. If the sign is omitted, "+" is assumed. Leading and trailing zeroes are optional. If the fractional part is zero, the period and following zero(es) can be omitted. For example: -1.23, 12678967.543233, +100000.00, 210., 452 + +## Canonical representation + + The canonical representation for decimal is defined by prohibiting certain options from the Lexical representation (§3.2.3.1). Specifically, the preceding optional "+" sign is prohibited. The decimal point is required. Leading and trailing zeroes are prohibited subject to the following: there must be at least one digit, which may be a zero, to the right and to the left of the decimal point. + + This canonical form conforms to XML Decimal lexical representation, so it would be accepted by any XML schema conforming system. + + What others write in canonical form, we can read as a lexical representation; what we write in canonical form, others can read as a lexical representation. But we reject exponential formats on reading and we won’t write exponential form. We can directly compare the canonical string representations of two values for equality. + + When exchanging messages, a lexical form that shows implied precision using trailing zeros is preferred to pure canonical form if it improves clarity. E.g. We might write “5.00” instead of “5.0” where the unit of exchange is commonly specified precise to two decimal places, as in USD, EUR, or GBP. This lexical representation option is permitted within valid lexical forms of both XML decimal and Mojaloop decimal. + +## Validators + + Decimal Lexical Validator (what our message receivers accept): + +```^[-+]?(([0-9]+[.]?[0-9]*)|([.]?[0-9]+))$``` + +Decimal Canonical Validator (the form we store and compare; this pattern could be used to assert canonical form in generated messages): + +```^([0]|([-]?[1-9][0-9]*))[.]([0]|([0-9]*[1-9]))$``` + +## Translating Between External and Internal Forms + + When converting from lexical or canonical form to a binary internal representation, the value space of the internal representation must be large enough to hold the scheme-specific range of decimal values, with a significand defined as the signed integer range –10_m_–1..10_m_–1, and a non-positive integer exponent in the range –_m_..0, where _m_ is the maximum number of decimal digits, at least 18, and as defined by the specific Level One scheme. + +An implementation must not translate between decimal external representations and any floating-point binary internal representation. And all calculations on internal representations of decimal values must produce results as if they were performed in decimal long hand on the external representation. + +It should be noted that the value space of a signed 64-bit binary integer is sufficiently large to encode a signed 18-digit decimal significand and the value space of a signed 6-bit binary integer is sufficiently large to encode its required non-positive base-ten exponent. diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/performance-project.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/performance-project.md new file mode 100644 index 000000000..a554f6610 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/performance-project.md @@ -0,0 +1,175 @@ +# Performance Workstream + +Wednesday, March 11, 2020 + +## Performance Goals: + +- Current HW system achieving stable 1k TPS, peak 5k and proven horizontal scalability + 1. More instances = more performance in almost linear fashion. + 1. Validate the minimum infrastructure to do 1K TPS (fin TPS) + 1. Determine the entry level configuration and cost (AWS and on-premise) + +## POCs: + +Test the impact or a direct replace of the mysql DB with an shared memory network service like redis (using redlock alg if locks are required) + +Test a different method of sharing state, using a light version of event-drive with some CQRS + +## Resources: + +- Slack Channel: `#perf-engineering` +- [Mid-PI performance presentation](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/March2020-PI9-MidPI-Review) +- [Setting up the monitoring components](https://github.com/mojaloop/helm/tree/master/monitoring) + +## Action/Follow-up Items: + +- What Kafka metrics (client & server side) should we be reviewing? - Confluent to assist +- Explore Locking and position settlement - Sybrin to assist + 1. Review RedLock - pessimistic locking vs automatic locking + 2. Remove the shared DB in the middle (automatic locking on Reddis) + +- Combine prepare/position handler w/ distributed DB +- Review node.js client and how it impact kafka, configuration of Node and ultimate Kafka client - Nakul +- Turn back on tracing to see how latency and applications are behaving +- Ensure the call counts have been rationalized (at a deeper level) +- Validate the processing times on the handlers and we are hitting the cache +- Async patterns in Node + 1. Missing someone who is excellent on mysql and percona + 2. Are we leveraging this correctly + +- What cache layer are we using (in memory) +- Review the event modeling implementation - identify the domain events +- Node.js/kubernetes - +- Focus on application issues not as much as arch issues +- How we are doing async technology - review this (Node.JS - larger issue) threaded models need to be optimize - Nakul + +## Meeting Notes/Details + +### History + +1. Technology has been put in place, hoped the design solves an enterprise problem + +2. Community effort did not prioritize on making the slices of the system enterprise grade or cheap to run + +3. OSS technology choices + +### Goals + +1. Optimize current system +2. Make it cheaper to run +3. Make it scalable to 5K TPS +4. Ensure value added services can effectively and securely access transaction data + +### Testing Constraints + +1. Only done the golden transfer - transfer leg +2. Flow of transfer +3. Simulators (legacy and advance) - using the legacy one for continuity +4. Disabled the timeout handler +5. 8 DFSP (participant organizations) w/ more DFSPs we would be able to scale + +### Process + +1. Jmeter initiates payer request +2. Legacy simulator Receives fulfill notify callback +3. Legacy simulator Handles Payee processing, initiatives Fulfillment Callback +4. Record in the positions table for each DFSP + - a. Partial algorithm where the locking is done to reserve the funds, do calculations and do the final commits + - b. Position handler is Processing one record at a time + +5. Future algorithm would do a bulk + +- One transfer is handler by one position handler + - Transfers are all pre-funded + +1. Reduced settlement costs +2. Can control how fast DFSPs respond to the fulfill request (complete the transfers committed first before handling new requests) +- System need to timeout transfers that go longer then 30 seconds + - Any redesign of the DBs + - Test Cases + +- Financial transaction + - End-to-end + - Prepare-only + - Fulfil only + +- Individual Mojaloop Characterization + - Services & Handlers + - Streaming Arch & Libraries + - Database + - What changed: 150 to 300 TPS? + +- How we process the messages +- Position handler (run in mixed mode, random + - Latency Measurement + +1. 5 sec for DB to process, X sec for Kafka to process +2. How to measure this? + +### Targets + +1. High enough the system has to function well +2. Crank the system up to add scale (x DFSPs addition) +3. Suspicious cases for investigations +4. Observing contentions around the DB +5. Shared DB, 600MS w/ out any errors + - Contention is fully on the DB + - Bottleneck is the DB (distribute systems so they run independently + + + +- 16 databases run end to end +- GSMA - 500 TPS +- What is the optimal design? + +### Contentions + +1. System handler contention + - Where the system can be scaled +1. If there are arch changes that we need to make we can explore this + - Consistency for each DFSP + - Threading of info flows - open question + +1. Sku'ed results of single DB for all DFSPs +1. Challenge is where get to with additional HW + - What are the limits of the application design +1. Financial transfers (in and out of the system) + - Audit systems + - Settlement activity + - Grouped into DB solves some issues + - Confluent feedback + +1. Shared DB issues, multiple DBs + +1. Application design level issues + +1. Seen situations where we ran a bunch of simulators/sandboxes + - Need to rely on tracers and scans once this gets in productions + - Miguel states we disable tracing for now + +### Known Issues + +1. Load CPU resources on boxes (node waiting around) - reoptimize code +2. Processing times increase over time + +## Optimization + 1. Distributed monolithic - PRISM - getting rid of redundant reads + 2. Combine the handlers - Prepare+Position & Fulfil+Position + +### What are we trying to fix? + 1. Can we scale the system? + 2. What does this cost to do this? (scale unit cost) + 3. Need to understand - how to do this from a small and large scale + 3. Optimized the resources + 4. 2.5 sprints + 5. Need to scale horizontal + 6. Add audit and repeatability - + +### Attendees: + +- Don, Joran (newly hired perf expert) - Coil +- Sam, Miguel, Roman, Valentine, Warren, Bryan, Rajiv - ModusBox +- Pedro - Crosslake +- Rhys, Nakul Mishra - Confluent +- Miller - Gates Foundation +- In-person: Lewis (CL), Rob (MB), Roland (Sybrin), Greg (Sybrin), Megan (V), Simeon (V), Kim (CL) diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/psip-project.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/psip-project.md new file mode 100644 index 000000000..d517d6f10 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/psip-project.md @@ -0,0 +1,21 @@ +# PISP (3rd party payment initiation) + +## Goal: + +Updated Mojaloop specification documents, and POC implementation of a PISP + + +## Action Items: + +- Revisit /authorizaitons resource: [Michael] and raise with CCB +- Identity provider research and follow-up: [Matt de Haast] +- Share all sequence diagrams: [JJ] +- Outline proposal at high level including new API calls - Unassigned +- Mapping account information (info about accounts for PISP) - [Lewis] + +## Links: + +- [London Meeting Notes](./pisp_meeting_march_2020.md) +- [WIP Separate Docs Repo with sequence diagrams](https://github.com/jgeewax/mojaloop-pisp) +- [End to End Sequence Diagram](https://plantuml-server.kkeisuke.app/svg/xLhhRnkv4V--VmKX571iI8eaEx4Z875aoyu9Tt44hz8WWFg1sgMaFQz87ScreXRvtpl3nxuaEx7H5bVW0kJXvN1cE9pvpODvhpILEbkbWKvqoiXu58w9bfIhEPDa9MAMJlcBJ2LyGJuo6Iqfr-IM_P4nfOaMP4otv2DI7GOqqaAImPQf9ILKaSj1i0RUIPIiSLF3i1wirmrSXB_th8PCtZC90eVNuVZG40wxLRfma-XeQPR2wihWjz2o9ZNET0j7GOwECHaurhrTGbOXl724n-vmZOiblOVpmVh5-r2is6R99BD4bnS15veH0IS0rIRBH96r56kXQ4fYmHI1PIB1T8ba10svW6zWmi5uH82tCWTh1oXOaSrIa5mvu9fmefUCg6Z9LeniaZGbdB4Ozw_e7IDw8ppFVj0z9AEveSzl4fH9UA8Ju1MJsPPGSzDD4edrrb3-aQ7oagcru8eXN_oAH47l6UnoohqSVnEB9C8lCqOoPOz1LSIafd1GC2fGIZGAcko7WiV04RwhfTXmD5IQSDOEHXg9gLBP2WKigUu7hNU4WkMYJ6cuF4be1imv69dgH72aZwYK2T2BJ1DXRUwf3nI9sNqICMHZt2FETC9G8JXbQbbWI9H323I0suxP77IAQxSeinHsKmxIrap2VeYnHPP0C06n2XWie4S5Rz-IOQ8YTAmjUVisk1oqta7yz4Ta8x8qXlFUMVCwcLF-jswdWrzAJeeUdDoZAs7emU_Mks6txwBrMNmWCeVTbbNb0znJejj1p2fYO1sbV07Zet6jDB3ZseJa7TkUJ_b8muV1-wjKEG6uAOGzIRIqPePhhL30fXT7Hn-k9kIb2H6cZeuE2xr24eGj8xVNwVN9w01kVC4qcT7e3W-p5LbPJpX628TuL639U2GOj50_exP5aygfaHc8jYj4hHczKsIEm5WwueuDGz2rGpxzsYGBOyaoIpXF0IomOUAYY2Y3bWPR-87EyU2EYqrWvE1F2jq8dGvilW9VxyCFS1M880547q16dC8-gWpS454BzBaKgy0TqpiaUU2AIbxob2jwzWsLvJrwGnUxDtJS7nevzeRC1Urd1zW_F7Otz6DLGoH6xhTC0uxS5-W1iGz2LXObZ3YRIio6iFyBI0LrtKSC4S0EmI5rbFRj6l3u4Ry1pH_onT9HftooB6kPw_149pK-WL0GRfLcAq34jP1QJNdEcbF0l7tySq2w7FGd01M57Pf49ekbFaV8izo_CjK4qS0dnx3BakvBkZO92F16BS6WKux-Zy3gqe_X1yf1MaqW6kg0LGcqK82xRyZ8H1IP2RqqB6131lVY_BhleWEbkp1prOPTk2WlsEeYk35SVRnALqqvFdb6BsAsI0KsyCOfev1HgRehRQgXDWQkByOGmUj6_t48abeCLgiRvWeMj2LBxZ6HaHLJYYwOjNyg17YRpIb0BJY3R9-A3MRc0wI6ofF7LCPGF_vEWNhjzmVZJo40XpaGAY2uApWL-MKo6R_ijhi177lqQTmAHIOZrhTLXVis1Cg4cu3fU_i4_me8_6hiyXp5ZJvfdCN79_CttRWLTqxFMYUTqzFMMU_rSQiNTKvEpqvVpwFvwqRJyZ0N2PiiI_T9wkqe7a6eLXRAYvFj6dT1cJeQX8vNdGPhaNd29DALOhJH95NokLfRlQsBDVBLx-PVtqkQofgc3bRsgng9rJfbtsuWKdSMhU14AksM6zQxQaSnP2ajg2RqBg6D2ittGj_cVzU8fQHRfwxQSF2G3UbAP5nxkRTNbrUZlryrAejL2-VV6X269Q6DA9EIyMYBIv_3OQCYfkIOJbQ99LJ6dCf467FU3cx2wwlRCcTN4GjpvF7WwmEh_X2Ndsx2pn-1gA81XdTng-G-iJMzFohxjawa2Iea0ipej3gzLlVLfDVhTq_xlRFscxDNhKwt3uSsE_uHV2zL327YLWXAC5j_ED0p6Qht7m4qwEQ6lQSawfuHlKSdgBS72yaOGYyPBr4pgBgHFeTUQEpkeL0dfXU3l41D_rGaTyFF7w04kXPpUpzNzlGga3jOG6_Kj9oniI4sM3LBjmMK-YxE7kG6Vp1WZ1cJHsaMCrNKTpKSj1OsM0rPCi7QmpEgeQsh1n_4smiFjqOT6sMdKU-OdNMYdq7OadOEdb_DmIwzUUlupQpNEddJdRNEkgUiTK8xnxtESNmoxvxisVn_1V5_8VnV2FyaX2TFXlWdONWDlQ7LSDXdCSOCH_8H5rQoEsZtpDPf3Aq3bIoVIjdMfsYJV45Th3srBIh3AjRY6rOTfb4tIiCFIrY7W_85zCn2tc57q0w-i5BrZdsEW-LIYrSQTpK39N8OZYZl1_IGVEOn12hYjgtqfO2KerIz0GzcX-JMYd3ZACtaQeUCl63jHPlC6LE7NhHll8hkmIRRkWsBgT_-PFf8osTJw4ZPurFRuxIA0PrXZxE0fCtQTWXQICK43dlsuVNvOK1JJMw4w_NuWVR2XjYKcGi960G-AHh2jYUvJfnHpLJEkwOLaQUqikxbvimEwB1LfSenCHjSKtTk5DiZT9BdvReH_1srfxok_Cu1m_wra1lCv3-OoUuhAIeNjJEBnWdfbclS6D4KYePiaMwRq9D5D0FcPXQon3aWpfAmQmueEJeQVvuS7H7sBM9hRGUTXJBKswPDBZ8DKOGH3a4Yjm6TuG3Lze6WfMotsrKtxFg9Ht5Er00gGB0OHD6JHsH-r3YvFlV__hHi0dqRMcq8EZYIguMA2ieVPihDQKepQtSiWrdOo99iNHzhEpUoedmLwSzYYiAz6wezTQMenFAt7BXeutkQ9Z7LhC9iojri3UVNKApzqq2EUhalb8wEdbz-selwNsbNlkYVIXVMz1-0PbMsFIX4TulmoetX9Cd0eCyp5bHn4uYHvP7_Rbhpuwh7vvT-eFMOc18oU2CN3n8c8AHYwTmy4KI2Gscs0bT57uQb0ydyk4jW-eWW8ULF0owuLbio1x1XSYqJRlnvjRjdPuu67Gy18cXnM5oetIwc_Gy7eX_wXrLkJddFBdSKyp3WqWBSbPyVcOZ3oH6aZh4KCpe3kFezKte7dFqECm_Vm4S0BjsSSYY2uPpADsSp1ZU07dl7J6PsdgaOub8zFBgF5GzTbqH_udZFpAO5bDHTb_1iDSDNA-m4bKPNg7HoVdsHt3FktvfCJBHnokkc_kxDRPwb-D36gvAWFO3BC7wCRV34Vy-xuDA0jES7fFcppepoEpCiLVa8jcgV8F-yeLoRrq_VnLRrADSwWPZ39_lSLyp7CHct2SuXZLH4-0LSx99HI5mGBzvcPRRcKR1mDsSXZZKR68D2DiITK0skayY27LmoP3C0VsFpmc0gYo9mFJHYyLZkVD5C4inCD0v0vThZIQcE6LLAeF95KwL4PAg7ANUfn4EPlUhpwaLyOOW6xZnVyGR5joPHK5qmsIHmFUsg_6gPyVXRxGyhZOT75iRdj11_vje3Id2TxTRJVxvYPCftgf5AhL5r438QJhbnPpHmOlwlnjpNnG_cn3pU3PJcFhx_gUOhfh1vncF05Kno1JrSi1SXRPVauhPTFEHCbXYsQ6RphBtAyFy-r3995NZHBV3tU_WZMwN_1W00.svg) +- [Initial PISP Design Doc, v5](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/January%202020%20OSS%20Community%20Session/%5BEXTERNAL%5D%20Mojaloop_%20PISP%20Credit%20Transactions(3).pdf) diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/versioning-draft-proposal.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/versioning-draft-proposal.md new file mode 100644 index 000000000..790dd4452 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/versioning-draft-proposal.md @@ -0,0 +1,281 @@ +--- +Authors: Lewis Daly, Matthew De Haast, Samuel Kummary +Proposal Name: Mojaloop Versioning Proposal +Solution Proposal Status: Draft +Created: 26-Feb-2020 +Last Updated: 17-Mar-2020 +Approved/Rejected Date: N/A +--- + +# Mojaloop Versioning, A Proposal + +_Note: This document is a living draft of a proposal for versioning within Mojaloop. Once the proposal is ready, it will be submitted to the CCB for approval._ + +## Overview + +The aim is to produce a proposal that keeps the versioning Scheme simple to use and clear regarding compatibility issues. However, it needs to include all the details needed for a Mojaloop ecosystem as well. + +Goal: +Propose a standard for a new 'Mojaloop Version', which embodies: +1. Helm: Individual Service Versions, Monitoring Component Versions +2. API Versions: FSPIOP API, Hub Operations / Admin API, Settlement API +3. Internal Schema Versions: Database Schema and Internal Messaging Versions + +## Versioning Strategies/Background (Literature Review) + +How do current systems handle versioning? Give a brief overview of the current space. +* Most best practices follow semantic versioning for APIs, this will be covered more in [#1198](https://github.com/mojaloop/project/issues/1198) + +### Demonstrates zero-downtime deployment approaches with Kubernetes [5] + +Key observations: +* in order to support rollbacks, the services must be both forward and backwards compatible. +consecutive app versions must be schema compatible +* 'Never deploy any breaking schema changes', separate into multiple deployments instead + +For example, start with a PERSON table: +``` +PK ID + NAME + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +And we want to break this down (normalize) into 2 tables, PERSON and ADDRESS: + +``` +#person +PK ID + NAME + +#address +PK ID +FK PERSON_ID + ADDRESS_LINE_1 + ADDRESS_LINE_2 + ZIPCODE + COUNTRY +``` + +If this change were made in one migration, 2 different versions of our application won't be compatible. Instead, the schema changes must be broken down: +1. Create ADDRESS table + * App use the PERSON table data as previously + * Trigger a copy of data to the ADDRESS table +2. The ADDRESS now becomes the 'source of truth' + * App now uses the ADDRESS table data + * Trigger a copy of new added to address to the PERSON table +3. Stop copying data +4. Remove extra columns from PERSON table + +This means for any one change of the database schema, multiple application versions will need to be created, and multiple deployments must be made in succession for this change to be made. +* [5] also notes how simple Kubernetes makes deploying such a change + * rolling upgrade deployments + * Tip: make sure your health endpoint waits for the migrations to finish! +* Q: so how do we make big changes that touch both the database schema and the API? + * this seems really hard, and would need a lot of coordination + * If we don't design it correctly, it could mean that a single schema change could require all DFSPs to be on board + * This is why I think the API version and Service version should be unrelated. We should be able to + deploy a new version of a service (which runs a migration), and supports an old API version + + +### Using a schema registry for Kafka Messages [6] + +* [6] suggests some approaches, such as using a schema registry for kafka messages, such as [Apache Arvo](https://docs.confluent.io/current/schema-registry/index.html) +* This adds a certain level of 'strictness' to the messages we produce, and will help enforce versioning +* Adds a separate 'schema registry' component, which ensures messages conform to a given schema. This doesn't really + help enforce versioning, and leaves the work up to us still, but does give more guarantees about the message formats. + +### Backwards and Forwards Compatibility [3], [4] + +* "The Robustness principle states that you should be “liberal in what you accept and conservative in what you send +”. In terms of APIs this implies a certain tolerance in consuming services." [3] +* Backwards Compatibility vs Backwards Incompatibility [4]: + * Generally, additions are considered backwards compatible + * Removing or changing names is backwards incompatible + * It's more something to assess on a case-by-case basis, but [Google's API Design Doc](https://cloud.google.com/apis/design/compatibility) helps lay out the cases. + +## Mojaloop Ecosystem +When discussing versioning we need to be clear that we are versioning interfaces for various parties. + +# Proposal +The following section will outline the versioning proposal. + +## A “Mojaloop Version” +A Mojaloop Version **x.y**.z can be defined that can encompass the versions of all the three APIs included (detailed below). +In the version **x.y**.z, ‘x’ indicates the Major version and ‘y’ a minor version, similar to the Mojaloop FSPIOP API versioning standards; ‘z’ represents the ‘hotfix’ version or a version released with the same major, minor version x.y but to keep things simple, there is a need to bundle all the components included in the Mojaloop ecosystem indicating what all items are included there. + +In effect we may say Mojaloop version **x.y** includes +1. Mojaloop FSPIOP API + * Maintained by the CCB (Change Control Board) + * Uses x.y format + * Currently version v1.0, v1.1 and v2.0 are in the pipeline +2. Settlement API + * Maintained by the CCB + * To use x.y format + * Currently version v1.1 and v2.0 is in the pipeline +3. Admin / Operations API + * Maintained by the CCB + * To use x.y format + * Can use version v1.0 +4. Helm + * Maintained by the Design Authority + * Uses x.y.z format + * PI (Program Increment) + Sprint based versioning. + > *Note:* _PI + Sprint based versioning_ make sense in the context of the current Mojaloop Program Increments, but will need to be revised at a later date. + * Bundles compatible versions of individual services together +5. Internal Schemas + * Maintained by the Design Authority + * DB Schema x.y + * Internal messaging Schema (Kafka) x.y + +| **Mojaloop** | x.y | | | +|---|---|---|--- +| | Owner/Maintainer | Format | Meaning | +| **APIs** | | | | +| - FSPIOP API | CCB | *x.y* | Major.Minor | +| - Settlement API | CCB | *x.y* | Major.Minor | +| - Admin/Operations API | CCB | *x.y* | Major.Minor | +| Helm | Design Authority | *x.y.z* | PI.Sprint.Increment | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *x.y* | Major.Minor | +| - Internal Messaging | Design Authority | *x.y* | Major.Minor | + + + +For example: Mojaloop 1.0 includes +1. APIs + * FSPIOP API v1.0 + * Settlements API v1.1 + * Admin API v1.0 +2. Helm v9.1.0 + * Individual services' versions + * Monitoring components versions +3. Internal Schemas + * DB Schema v1.0 + * Internal messaging version v1.0 + +| **Mojaloop** | v1.0 | | | +|---|---|---|--- +| | Owner/Maintainer | Version | +| **APIs** | | | | +| - FSPIOP API | CCB | *1.0* | +| - Settlement API | CCB | *1.1* | +| - Admin/Operations API | CCB | *1.0* | +| Helm | Design Authority | *9.1.0* | +| **Internal Schemas** | | | | +| - DB Schema | Design Authority | *1.0* | +| - Internal Messaging | Design Authority | *1.0* | + +### Advantages + +1. The advantage of this strategy is primarily simplicity. A given version say - Mojaloop v1.0 can just be used in + discussions which then refers to specific versions of the three APIs - FSPIOP, Settlements, Admin APIs, along with the Helm version that is a bundle of the individual services which are compatible with each other and can be deployed together. +Along with these, the Schema versions for the DB and Internal messaging to communicate whether any changes have been made to these or not since the previously released version. +2. The other advantage, obviously, is that it caters for everyone who may be interested in differing levels of details +, whether high level or detailed. Because of the nature of the major and minor versions, it should be easy for Users and adopters to understand compatibility issues as well. + +### Compatibility +As described in [section 3.3 of the API Definition v1.0](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning), whether or not a version is backwards compatible is + indicated by the **Major** version. All versions with the same major version must be compatible while those having different major versions, will most likely not be compatible. + +_Important Note: Hub operators will likely need to support multiple versions of the FSPIOP API at the same time, in order to cater for different participants as they can't all be expected to upgrade at the same time._ + +## Breaking down the “Mojaloop Version” +This section aims to break down the above proposed mojaloop version into its constituent parts, and provide support for the above proposed versioning strategy + +### APIs + +The [Mojaloop Spec](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#33-api-versioning) already outlines many of the decisions made around versioning APIs. + +In terms of common best practices, there are many approaches for requesting different versions, including adding in a + version in the url, but let's not worry about this because the spec already lays this out for us, using the HTML vendor extension: [3.3.4.1 Http Accept Header](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3341-http-accept-header) + +As for version negotiation, the spec also states that in the event of an unsupported version being requested by a + client, a HTTP status 406 can be returned, along with an error message which describes the supported versions. [3.3.4.3 Non-Acceptable Version Requested by Client](https://github.com/mojaloop/mojaloop-specification/blob/master/documents/API%20Definition%20v1.0.md#3343-non-acceptable-version-requested-by-client) + +Another best practice around versioning is specifying to what level clients may request specific apis. +* In a development environment, many APIs will allow specificy up to the BUGFIX version, i.e. vX.X.X +* In production however, this is limited to Major versions only, e.g. v1, v2 +* e.g. The Google API Platform supports only major versions, not minor and patch versions +* Given the new features that may become available with v1.1 of the Mojaloop API, we might want to allow participants + to specify MAJOR and MINOR versions, i.e. vX.X. This practice should be avoided however, since minor versions should be backwards compatible + +Participants using the same MAJOR version of the API should be able to interact. Participants on different MAJOR +versions are not able to interact. For example, a participant on API v1.1 can send transfers to another participant on v1.0, but not to a different participant on v2.0. + +### Helm +This section deals with how Mojaloop services interact within a given deployment. Here, we attempt to propose questions such as "should an instance of central-ledger:v10.0.1 be able to talk to ml-api-adapter:v10.1.0? How about ml-api-adapter:v11.0.0?"? or "how do we make sure both central-ledger:v10.0.1 and central-ledger:v10.1.0 talk to the database at the same time?" + +There are two places where this happens: +1. Where services interact with saved state - MySQL Percona Databases +2. Where services interact with each other - Apache Kakfa and (some) internal APIs + +This implies we need to version: +* the database schema +* messages within Apache kafka + * need to make sure the right services can appropriately read the right messages. E.g. Can mojaloop/ml-api-adapter:v10 +.1.0 publish messages to kafka that mojaloop/central-ledger:v10.0.1 can understand? + * Q: If we decide to make breaking changes to the message format, how can we ensure that messages in the kafka streams + don't get picked up by the wong services? + +### Internal Schemas + +#### Database + +todo: anything to be said here? + +#### Kafka/Messaging +Currently, we use the lime protocol for our kafka message formats: https://limeprotocol.org/ + +Also refer to the mojaloop/central-services-stream readme for more information about the message format. + +The lime protocol provides for a type, field, which supports MIME type declarations. So we could potentially handle messages in a manner similar to the API above (e.g. application/vnd.specific+json). Versioning messages in this manner means that consumers reading these messages would need to be backwards and fowards compatible (consecutive message versions must be schema compatible). +* Q. does it make sense to put the version in the Kafka topic? + * One example, ml-api-adapter publishes messages to the prepare topic + * If we add versioning to this, ml-api-adapter:v10.0.0 publishes messages to a prepare_v10.0 topic, and a new instance + of the ml-api-adapter:v10.1.0 will publish to the prepare_v10.1 topic. + * subscribers can subscribe to whichever prepare topic they want, or both, depending on their own tolerance to such + messages + * This may have some serious performance side effects +* Another potential option would be to allow for a message 'adapter' in the deployment. Say the ml-api-adapter:v10.1.0 is producing messages to a prepare_v10.1 topic, and there is no corresponding central-ledger in the deployment to read such messages, we could have an adapter, which subscribes to prepare_v10.1, reformats them to be backwards compatible, and publishes them to prepare_v10.0 in the old format. + +Such an approach would allow for incremental schema changes to the messaging format as services are gradually upgraded. + +All in all, I didn't see too much about this subject, so we'll likely need to return later down the line. + +## Version Negotiation +todo: @sam Discuss how to deal with version negotiation strategy + +## Long Term Support +todo: Discuss how long term support fits into the versioning proposal. I don’t think we want to get into too much detail, but more outline what it might look like + +Mention current (lack of) lts support, current PI cadence + +## Appendix A: Definitions + +* **service**: Mojaloop follows a microservices oriented approach, where a large application is broken down into smaller + micro services. In this instance, Service refers to a containerized application running as part of a Mojaloop deployment. At the moment, this takes the form of a Docker container running inside of a Kubernetes cluster. e.g. mojaloop/central-ledger is the central-ledger service +* **service version**: The version of the given service. This currently doesn't follow semantic versioning, but may in the + future e.g. mojaloop/central-ledger:v10.0.1. The current approach is described in more detail in the [standards + /Versioning doc](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/versioning.md). +* **helm**: Helm is an application package manager that runs on top of Kubernetes. It may also be referred to as the + "deployment". A single helm deployment runs many different services, and MAY run multiple versions of the same service simultaneously. We also refer to the deployment as it's repo, mojaloop/helm interchangeably. +* **helm version**: A helm version is the version of the packaged helm charts, e.g.mojaloop/helm:v1.1.0 +* **interface**: An interface is the protocol by which a Mojaloop switch interacts with the outside world. This includes + interactions with Participants (DFSPs) who transfer funds through the switch, hub operators running a Mojaloop switch, and admins performing administrative functions. +* **api**: Application Programming Interface - in most cases referring to the FSPIOP-API a.k.a. Open API for FSP + Interoperability defined [here](https://github.com/mojaloop/mojaloop-specification). +* **api version**: The Version of the FSPIOP-API, e.g. FSPIOP-API v1. For the purposes of this document, it refers to the + contract between a Mojaloop Switch and Participants (DFSPs) who implement the FSPIOP-API + +## References + +[1] LTS versioning within nodejs. This is a great example of an LTS strategy, and how to clearly communicate such a strategy. +[2] Semantic Versioning Reference +[3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ +[4] https://cloud.google.com/apis/design/compatibility +[5] Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway +[6] Stackoverflow - Kafka Topic Message Versioning + diff --git a/website/versioned_docs/v1.0.1/community/archive/discussion-docs/workbench.md b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/workbench.md new file mode 100644 index 000000000..34b7f49ee --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/discussion-docs/workbench.md @@ -0,0 +1,246 @@ +# Mojaloop Lab/Workbench Discussion + +___Goal:__ This discussion document aims to lay out the case and align the community around the development of an educational Mojaloop Lab environment._ + + +## 1. Goals for the PI8 Convening: + +1. Define terms and outline assumptions +2. Outline existing efforts and how the OSS Community aligns with them (GSMA, MIFOS, ModusBox) +3. Define users and usecases, and exclude the users we won't worry about +4. Recommendations for a few different solutions to the "Lab Problem" + - Documentation around business cases and personas Dan developed + - Basic implementation of Lab Configurer, help people build labs with different features + - Simple Mojaloop-over-spreadsheets demo, to get people using mojaloop without Postman +5. Basic implementation and demo +6. Pose important questions and discuss next steps + +## 2. Nomenclature + +**1. Tools:** +- 1.1 A device used to carry out a function +- 1.2 Different tools for different functions: You wouldn't use a screwdriver to drive a nail. +- 1.3 In a Mojaloop context, one example of a tool is the Bank Oracle + - The Bank Oracle is a tool that plugs into the Account Lookup Service, can be used to allow Mojaloop to connect to existing bank accounts with an IBAN + +**2. Workbench:** +- 2.1 Combines different tools together in one place +- 2.2 For example, a hand plane, table saw and chisel can make up a woodworking workbench, while a hacksaw, file and angle grinder can make up a metalworking workbench +- 2.3 In the mojaloop parlance, tools to test my DFSP's JWS keys are in a different workbench than tools that demonstrate to a fintech how wholesale api's can work on top of Mojaloop + +**3. Lab:** +- 3.1 A lab is a place you go to run experiments +- 3.2 We run experiments in order to learn, and test our assumptions + - For example, a DFSP can set up and run an _experiment_ where they send and receive Quotes using an in-development API +- 3.3 A single lab combines multiple workbenches together in one place + +**4. Simulator:** +- 4.1 A tool that simplifies or abstracts away some function so you can test one thing at a time +- 4.2 Pilots train with simulators _before_ flying a real life, dangerous and expensive plane. +- 4.3 Within Mojaloop: a simulator can simulate interacting with some component of the system + - Replace an entire switch to test a DFSP implementation + - Simulate 2 DFSPs to test a switch deployment + - A simulator also reduces the need for someone to be with the person testing. So a DFSP can send and receive via the switch, without interaction with the Hub Operator. + + +## 3. Assumptions + +>_Some of these may go without saying, but it's noting them here anyway._ + +- 1\. The Gates Foundation wants to encourage adoption for Mojaloop at all levels (not just switches) +- 2\. We don't need a lab environment to serve the needs of a Switch deployment or implementing DFSP - these needs will be met elsewhere +- 3\. The Mojaloop OSS Community wants to make itself attractive + - This doesn't mean removing all barriers to entry; but assessing which barriers we should be removing + + +## 4. Users + +We divide users in 2 camps: Primary users and Secondary users. + +### 4.1 Primary Users +1. DFSPs needing to integrate with Mojaloop: (shorthand: Implementing DFSP) +2. Organisations/Individuals wishing to learn about Mojaloop and wanting to build and test functionality or use cases as a DFSP (shorthand: Evaluating DFSP) +3. Organisations/Individuals wishing to learn about Mojaloop and wanting to build and test functionality or use cases as a Hub Operator (shorthand: Evaluating Hub Operators) +4. Regulators, Organisations or Individuals wishing to understand and evaluate Mojaloop and how it might impact their existing service (shorthand: General Evaluators) + +### 4.2 Secondary Users +5. Systems Integrators wishing to offer Mojaloop as a Service or pieces of Mojaloop integration as a Service (Systems integrator) +6. Individual Contributors (including bug bounty hunters?) (Individual Contributor) +7. Fintechs operating on top of or who will operate on top of a mojaloop-enabled switch (Mojaloop-powered fintech) +8. 3rd Party App Provider interacting with wholesale mobile money APIs, selling integrations to fintechs and the like (3rd party app provider) +9. Financial Advocates, who are interested in promoting Mojaloop and other technologies that help drive financial inclusion (Financial Inclusion Advocates) + +In addition to thinking of each of the above users, it's important to understand at what level these users exist at in relationship to a mojaloop deployment. For that we will borrow from Dan Kleinbaum's [_Fintech primer on Mojaloop_](https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb) + +![the 3 levels of mojaloopyness](./images/mojaloop_spokes.png) +>_The 3 levels of Mojaloopyness, https://medium.com/dfs-lab/what-the-fintech-a-primer-on-mojaloop-50ae1c0ccafb by Dan Kleinbaum_ + +**Level 1:** Running a Mojaloop switch (e.g. Hub Operators) +**Level 2:** Interacting with a Mojaloop Switch directly (e.g. DFSPs, Systems Integrators) +**Level 3:** Interacting with a DFSP over a Mojaloop Switch (e.g. Fintechs) + + +## 5. Use Cases + +__a.__ Test a Mojaloop compatible DFSP implementation +__b.__ Validate assumptions about Mojaloop +__c.__ View and use a reference implementation +__d.__ Learn about Mojaloop internals +__e.__ Learn about Mojaloop-enabled switches and associated use cases (technology) +__f.__ Assess how Mojaloop will change fintech business landscape +__g.__ Be able to demonstrate a value proposition for DFSPs/Fintechs/etc. to use mojaloop (instead of technology _x_) + + +## 6. User/Use Case Matrix: + +We can plot the users and use cases in a matrix: + + +| __Usecase:__ | a. Test DFSP Impl | b. Validate Assumptions | c. Reference Impl | d. Learn Internals | e. Learn about Tech | f. Evaluate Business Cases | g. Demonstrate ML Value | +| :----------------------------------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| __User:__ | | | | | | | | +| __1. Implementing DFSP__ | X | | X | | | | | +| __2. Evalutating DFSP__ | | X | X | | X | X | | +| __3. Evaluating Hub Operator__ | | | X | | X | X | | +| __4. General Evaluator__ | | | | | X | X | | +| __5. Systems Integrator__ | X | X | X | X | | | X | +| __6. Individual Contributor__ | | X | X | X | | | | +| __7. Mojaloop-powered fintech__ | | X | | | X | X | X | +| __8. 3rd Party App Provider__ | | | | X | | | X | +| __9. Financial Inclusion Advocates__ | | X | | | | X | X | + + +## 7. Usecase Inputs and outputs: + +>_Pick 2 or 3 different users/usecases and drill down into the inputs and outputs for what meeting their needs may look like_ +>>_Note: As with anything of this nature, a lot of the users/usecases and associated conclusions are somewhat squishy, and can likely be put into different or altogether new boxes. Nonetheless, we will try to define these as well as possible._ + +### 7.1 Evaluating Hub Operator + Implementing DFSP +As stated in our above assumptions, we aren't going to worry about Hub operators and Implementing DFSPs here. + +### 7.2 Evaluating DFSP + +>_We think of an evaluating DFSP as one who is not necessarily part of a current switch implementation, but a party who is mojaloop-curious, and a potential candidate to evangelize mojaloop to - without the tangible goal of a switch implementation in sight._ + +**7.2.1 Use cases:** +- 1\. Validate assumptions about Mojaloop (how it works, what it does, what it _doesn't_ do) +- 2\. View and play with a reference implementation +- 3\. Learn about mojaloop-enabled hubs and associated use cases (technology perspective) +- 4\. Assess how Mojaloop will affect their business in the future + +**7.2.2 Examples from our user personas:** +- 1\. Carbon - Enable cash-outs and OTC remittances over their agent network +- 2\. Ssnapp - Enable multi payer/payee payments and rewards points over mojaloop +- 3\. Oneload - Simplify onboarding for other DFSPs to utilize OneLoad's agent network +- 4\. Juvo - Plug in to a Mojaloop switch for a credit scoring and lending marketplace + +**7.2.3 Outputs: (How can the Mojaloop OSS Community better serve these players?)** +- 1\. help to onboard to the mojaloop ecosystem +- 2\. help to understand the technology, where it works well, and the potential pitfalls/drawbacks +- 3\. minimize investment in getting things working so they can focus on building out use case prototypes +- 4\. take them from little to no understanding of Mojaloop -> demonstrating real prototypes + +**7.2.4 Inputs: (what are the things that we need to do to meet these goals)** +- 1\. Improved mojaloop documentation specific for this role. + - 1.1 Think about and design the documentation and onboarding flow specifically for *Evaluating DFSPs* + - 1.2 Documentation should be approachable by product manager etc. with little technical knowledge +- 2\. Technical deep dive on the technology behind mojaloop, why, how it works (perhaps we can repurpose the js demonstrator in an interactive walkthrough an end to end transaction) +- 3\. Improved guides for up and running on 2-3 major kubernetes providers, self service and install scripts +- 4\. Helm charts for 1-2 simulators/labs that can be spun up alongside a switch, with opinionated pre-configured settings + + +### 7.3 Mojaloop Powered Fintech + +>_A Mojaloop Powered fintech is a fintech operating or wishing to operate on top of a mojaloop switch. There will definitely be crossover between Fintechs and DFSPs in this classification, but we will focus here on fintechs who are at the third level on the above "Mojaloop Spokes"_ + +**7.3.1 Use cases:** +- 1\. Validate assumptions about Mojaloop (how it works, what it does, what it _doesn't_ do) +- 2\. Learn how mojaloop is aligned with wholesale APIs, and what it would take to get a DFSP using these APIs over a Mojaloop switch +- 3\. Learn about mojaloop-enabled hubs and associated use cases (technology perspective) +- 4\. Assess how Mojaloop will affect their business in the future + +**7.3.2 Examples from our user personas:** +- 1\. EastPay - compare and shop around for banks/payment providers based on Mojaloop's open fee structure +- 2\. Jumo - Open up transparent and fairer lending markets on top of a Mojaloop enabled switch? + +**7.3.3 Outputs: (How can the Mojaloop OSS Community better serve these players?)** +- 1\. Understand how Mojaloop and Wholesale APIs fit together (or don't) +- 2\. Enable fintechs to interact with Mojaloop over 1 or 2 wholesale banking APIs (e.g. GSMA MM api) +- 3\. take them from little to no understanding of Mojaloop -> demonstrating real prototypes + +**7.3.4 Inputs: (what are the things that we need to do to meet these goals)** +- 1\. Improved mojaloop documentation specific for this role. +- 2\. Documentation or working document on how Mojaloop will work with wholesale apis +- 3\. Self-deployed lab environment with DFSP that expose some wholesale apis with basic functionality for fintechs to test against + + +## 8. OSS Lab/Workbench efforts alongside others + +There are others in the community working on some of these needs we outlined above. How can we align ourselves together to: (1) Not duplicate efforts (nor step on each other's toes) and (2) Provide the most impact for end users and the Mojaloop community as a whole + +In general, we reached a consensus around the following: +- any OSS Lab effort should be focused with a specific end user in mind +- Our focus should be further out on the mojaloop spokes (DFSPs, Fintechs, 3rd Party app providers) + + +### 8.1 MIFOS +- 1\. Already extensive work done here with Fineract system, which provides out-of-the-box solution for Mojaloop enabled DFSPs +- 2\. working on open api implementations +- 3\. Working on lowering the barriers to entry for DFSPs and Fintechs +- 4\. Mifos Innovation Lab: "The Locomotion on top of Mojaloop's Rails" + - 4.1 Demonstrate end to end Mojaloop systems with DFSP integration + - 4.2 Build and contribute OS tools +- 5\. Working on real world deployments already +- 6\. See a need for a "Single Point of Entry to the Mojaloop Ecosystem" +- 7\. Have an existing Lab deployment with Mojaloop that is currently being upgraded to work with the latest Helm chart deployments + + +### 8.2 GSMA +- 1\. Have mobile money api, would like to see end to end solution with fintechs/DFSPs talking over a mojaloop switch +- 2\. The GSMA Lab has a very wide scope, Mojaloop is just one piece of this +- 3\. One main goal is the mobile money API- pushing for default standard for 3rd party integration into mobile money +- 4\. where does Mojaloop sit? + - 4.1 Is one of the branches that the GSMA Lab will be working on + - 4.2 Where can GSMA add the most value to Mojaloop? + - 4.2.1 Serve a need from the market to get the most impact + - 4.2.2 See a end-to-end prototype of the MM API talking over a Mojaloop switch + + +### 8.3 ModusBox +- 1\. More on the systems integrator perspective. Building a bunch of tools already to ease the development and onboarding process for switches and DFSPs +- 2\. Have open sourced the Mojaloop JS SDK +- 3\. Interested in showing 'how the engine works' to build confidence in business parters/customers +- 4\. Also interested (especially in WOCCU case) as a Mojaloop lab as a place for Fintechs to learn and test concepts on top of Mojaloop Switches + - 4.1 Once this is connected, the interesting use cases will start to develop beyond tranfers from A to B + - 4.2 MFIs (especially small-medium) don't have much capacity for experimentation or developing new business cases, but these cases can be driven from fintechs first +- 5\. How can we assist orgs. who have little-to-no technical capability to become confident with Mojaloop? + - 5.1 A technical lab environment won't do much in this case + - 5.2 Can we demonstrate Mojaloop over a spreadsheet? Everyone can understand spreadsheets. + +## 9. Questions + +- 1\. So much of this comes back to The Gates Foundation's proposed sales cycle for growing mojaloop adoption + - 1.1 Looking at the technical briefs from the hackathon alone, there are some __big__ players (Famoco, Ethiopay, GrameenPhone) that could really take mojaloop and run with it + - 1.2 How can the initial hurdle be overcome to drive adoption and help these orgs adopt mojaloop and contribute back to the ecosystem? + - 1.3 What does the entrypoint to the industry look like for Hub operators? + +- 2\. For evaluating DFSPs, what is their resource/risk allocation like? + - 2.1 If they think Mojaloop is a viable option for a future product, what type of time and resource investment will they put into it? + - 2.2 What are their alternatives? (This will be a case-by-case thing) + +- 3\. Is a certain amount of technical gatekeeping a good or bad thing? (This is a more philisophical question) + - 3.1 If we don't make it too easy to get up and running, we make sure that only interested and determined parties are using mojaloop, which self-selects for a better community (kinda) + - 3.2 But this locks out a lot of people who aren't up to scratch with kubernetes, docker etc. but may still have a good deal of experience with financial services etc. + +- 4\. Chicken and egg problem(?) between DFSPs and Hub operators. Does it go DFSPs -> Hub Operators or the other way around? + + +## 10. Recommendations + +- 1\. Find a target user that we can build a lab for/with + - 1.1 perhaps one of the more serious hackathon teams? +- 2\. Address and improve documentation gaps: driving from a role-specific (i.e. DFSP, fintech, hub operator) perspective +- 3\. Mojaloop over Spreadsheet demo +- 4\. Build a self-service lab prototype + - 4.1 Opinionated set of helm charts that can be deployed alongside general switch + - 4.2 Gather feedback from the community, and see where and how people are using it \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/archive/notes/README.md b/website/versioned_docs/v1.0.1/community/archive/notes/README.md new file mode 100644 index 000000000..8f7b7868c --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/notes/README.md @@ -0,0 +1,5 @@ +# OSS Meeting Group Notes (Archive) + +- [Change Control Board](./ccb-notes.md) +- [Design Authority](./da-notes.md) +- [Scrum-of-scrum calls](./scrum-of-scrum-notes.md) diff --git a/website/versioned_docs/v1.0.1/community/archive/notes/ccb-notes.md b/website/versioned_docs/v1.0.1/community/archive/notes/ccb-notes.md new file mode 100644 index 000000000..b8c49a9df --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/notes/ccb-notes.md @@ -0,0 +1,6 @@ +## CCB meetings: Overview +The Change Control Board meets every two weeks. + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have Change Requests or Solution Proposals to discuss. + +More details can be found here: https://github.com/mojaloop/mojaloop-specification/tree/master/ccb-meetings . \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/archive/notes/da-notes.md b/website/versioned_docs/v1.0.1/community/archive/notes/da-notes.md new file mode 100644 index 000000000..2e04a1be9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/notes/da-notes.md @@ -0,0 +1,125 @@ +## DA meetings: Overview +The Design Authority meets every week for a weekly update and has ad-hoc or detailed sessions for Specific topics + +The meetings are open for the public to participate, though discussions are usually limited to the Board members. However, attendees will be promoted to panelists in meetings if they have designs to be reviewed or proposals for changes. + +More details can be found [here](https://github.com/mojaloop/design-authority/issues/42#workspaces/da-issue-log-5cdd507422733779191866e9/board?notFullScreen=false&repos=186592307) + +# DA Meeting - 30 September 2020 +Discussion around the topics mentioned started - the newly implemented "patch" in version 1.1 of the API spec was discussed and the majority of the meeting was spent on how to promote wider adoption of this new pattern. + +Concerns about the implementation and use of the "patch" command was raised, stating that further discussion is required to determine if we are not trying to patch a design flaw with another potential implementation flaw. + +See: https://github.com/mojaloop/design-authority/issues/68 + + +# DA Meeting - 2 September 2020 +First we discussed the topic about the "models" folder from being excluded from the unit test coverage checks. The decision taken was that if the folder contains business logic (which generally should not be the case), it must be refactored and moved out. Once at that "business logic isolated" state, coverage testing for that folder can be ignored. See: https://github.com/mojaloop/design-authority/issues/64 + +We concluded discussions on the separate scheme-adapter for a PISP - see issue on board: https://github.com/mojaloop/design-authority/issues/51 +Please have a look at the draft document at this location: https://github.com/mojaloop/pisp/blob/scratch/api-collision/docs/api-collision.md +The above link has a detailed discussion regarding the latest thinking and some examples of mitigations. +The decision has been taken to block this topic until further development on the PoC has been done, in order for the DA to assess if the designs are still aligned with the recommended approach. + +# DA Meeting - 26 August 2020 +We discussed https://github.com/mojaloop/design-authority/issues/51 further on our DA Meeting on 26/08/2020. + +Some of the key points were noted: + +In order to take advantage of Typescript, and to help speed up development, the PISP workstream has gone ahead and separated out the thirdparty-scheme-adapter already. + +One of the challenges identified with the "multi-scheme-adapter" approach was for cases where there are shared resources between the APIs, such as GET /parties/{type}/{id}. + +Our decision to break the Thirdparty API into it's own API (and not extend the FSPIOP-API) was predicated on the idea that "not all participants will want thirdparty functions", and therefore shouldn't have to worry about them. As a part of the decision to keep a separate Thirdparty API, we decided that some resources would be duplicated between the two. + +This could lead to problems down the line, where callbacks to some resources might not be able to reach their desired destination: for example if a DFSP needs to listen for PUT /parties/{type}/{id} callbacks for both the FSPIOP API and the Thirdparty API, it may not be possible for DFSPs to route such callbacks to the right place. + +Lewis Daly will spend more time working on some diagrams and design documents, and come back to the DA shortly + +# DA Meeting (Ad-Hoc) - 24 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/65 +The Ad-Hoc meeting was conducted with a wider issue being addressed relating to recommendations required to be taken to the CCB for consideration to change/enhance the API spec. + +Many valid points were raised and discussed and Michael and Adrian suggested some collaboration on this platform to consolidate the ideas put forward in order to formulate a recommendation to the CCB. + +# DA Meeting - 19 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/61 +The group agreed that there needs to be a balance between the need to eliminate reconciliation and liquidity management of (Payer) FSPs by not holding/reserving funds for longer than necessary. In addition, It was proposed to use 'grace time period' before timing out transfers to compensate for differences in clocks. It was also suggested that for risky transactions, the final notification in the form of a PATCH call that was introduced with FSPIOP API v1.1 can be used to mitigate risk to the Payee FSPs. + +One point made was that after the timeout period (plus the grace period to account for clock difference), a transfer status cannot be changed - it is either finalized or it isn't, but it cannot be changed. For example, if a timeout period (expressed as a time in future and not duration) is 10 seconds, then a Payer FSP (or Switch), may add a grace period of 1second and after waiting for 11seconds can query the downstream entity to find the transfer's status; At this point, if a transfer is finalized (Committed or Aborted), then the Payer FSP can take action accordingly; however if it is in an intermediate state, then the transfer has to be timed-out since the time-out period is done. + +The group agreed on the need to revisit the topic of implementing 'telescopic timeouts', which is not currently supported in favor of end-to-end encryption of (most) messages. + +# DA Meeting - 12 August 2020 +The topic for discussion was: https://github.com/mojaloop/design-authority/issues/63 +The DA discussed the topic of where and how to create and work on issue tickets. With over 50 repositories, it makes sense to create a ticket in the repo where it originated and keep working on it there until it is resolved. The Product Owner and Scrum Master would have context and should replicate a ticket in the Design Autority Repo with a link to the originating ticket. Please have a look at the DA Board for the decisions made here: https://github.com/mojaloop/design-authority#workspaces/da-issue-log-5cdd507422733779191866e9/board?repos=186592307 + +# DA Meeting - 5 August 2020 +The topic for discussion was: https://github.com/mojaloop/project/issues/852 +The "HSM Integration Approach" was touched on a few times, and the workgroup taking care of the design and implementation, tabled this for discussion at this week's DA meeting to answer a few questions arising from the last PI-Planning session where progress on this was again presented. + +As we have not completed the discussion, an ad-hoc DA meeting has been arranged for this Friday with a sub-section of the DA Members. The reason for that was because there were a few specific questions we did not have time to go into detail for, which will be clarified with the individuals who raised those questions. Please drop me a note if you would like to participate in that meeting. + +# DA Meeting - 29 July 2020 +Issue discussed: https://github.com/mojaloop/design-authority/issues/60 +Claudio noted three observations regarding usage of best practices in the Mojaloop Core codebase. One of the issues has an active issue and will be used for tracking it; the other two will be followed up as separate stories/bugs as well (standards). Claudio will provide examples and in some cases sample snippets that can be used. + +Istvan and Michael discussed the usage of a unique ID for lookup requests and proposed to have a follow-up meeting the upcoming week for those interested. The current trace headers (optional) usage for traceability (APM) was brought up as a solution, which after the DA review can be proposed to the CCB (if accepted by the DA). + +# DA Meeting - 22 July 2020 +Canceled as a result of the PI-11 Mojaloop Convening taking place + +# DA Meeting - 15 July 2020 +Sam walked through some of the high-level changes being introduced with Helm v10.4.0 release and various sections from the release notes: https://github.com/mojaloop/helm/releases/tag/v10.4.0 +Please have a look on the DA Topic board: https://github.com/mojaloop/design-authority/issues/56 + +Neal and Michael discussed the issue of shared DB, code between central-settlement and central-ledger; they’re going to continue with the current work on Continuous Gross Settlement but after the convening will get the inputs from the Perf/Arch PoC (Event sourcing / CQRS) and then align. https://github.com/mojaloop/design-authority/issues/58 + +# DA Meeting - 8 July 2020 +The TIPS team did a presentation of the design and implementation of a **Rules Engine** satisfying their requirements of interpretation in the **Settlements Portion**, to extend fees levied as part of a transfer. The implementation allows for rules to be interpreted at any stage during a transaction. A formal presentation will be made at the convening during the week of the 20th July 2020 after which more informed decisions as to the adaption of this implementation into the Core OSS codebase can be considered as a generic approach to implementation of a rules engine. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/53 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting - 1 July 2020 +As part of the "Versioning" workstream, a "zero down-time deployment proposal" PoC is being conducted and feedback from that project has been presented in the form of a problem statement, solution and a demo. The team currently working on that is Lewis Daly, Mat de Haast and Sam Kummary. The feedback was well received and as this work is ongoing, the DA will follow up with any action items to come out of the upcoming presentation for this workstream at the PI 11 Meeting. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/54 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 29 June 2020 +KNEX Discussion - continued. The KNEX discussion extended into talking about the possible use of third-party tools to assist in the generation of queries to help migration efforts. This has no direct bearing on the use of KNEX itself and after exploring a bit deeper, it was decided that there was no compelling reason to continue further investigation into the use of KNEX itself, but to keep an open mind and look out for alternative solutions out there as and when they are introduced. Those libraries will be measured against the current implementation to ensure we deploy the right tools for the right purpose. This issue is now closed. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + +# DA Meeting (Ad-Hoc) - 25 June 2020 +KNEX Discussion - initiated +Conversations have been started, highlighting the problem statement of difficulty in generating or creating migration scripts when database changes occur, as well as the scenario of having to perform these upgrades on a database which is online at the time. +With this context in place, continued design sessions have been scheduled to determine if KNEX would be capable of handling the above scenario and if there are alternate libraries or tools out there to replace or supplement the current implementation, which may help alleviate this difficult task. +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/27 for a detailed problem statement, progression on meetings in the notes and remarks and also, if completed, the subsequent decision. + + +# DA Meeting - 24 June 2020 +Discussion today started with: Deprecation of Helm2 support - Issue #52, where it was agreed that migration to Helm3 should continue. Documentation to assist in the use of tools available to help in the migration should be provided. Find the link to this document at https://github.com/mojaloop/design-authority/issues/52 + +The topic of having a design approach of implementing a generic rules-based system was discussed with some specific reference first, to a requirement of having the capability to interrogate completed or in-flight transactions (either in the transfer stage or even as early in the quoting stage) in order to apply "interchange fees" for that transaction, depending on the transaction type, as interpreted by certain rules. +Various design decisions are going to be discussed around this topic as the requirement is the facility to attach rules at various points of the transaction path. +The current implementation of a Rules Engine in the TIPS project was discussed and a request to demonstrate the capabilities of that solution in order for the DA to see if it was generic anough to incorporate into the core Switch will be made in a follow-up discussion. +Please track the progression of the design decisions surrounding this issue on the board at https://github.com/mojaloop/design-authority/issues/53 + + +# DA Meeting - 17 June 2020 +Topic under discussion was: Understand and Define Mojaloop Roles for PISP, x-network, etc. use cases +The DA is happy for workstreams to go ahead and split out new APIs and Role definitions (e.g. Thirdparty API, CNP API etc.) +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/44 for a detailed problem statement and subsequent decision. + +# DA Meeting - 10 June 2020 +This week, the DA discussed: Discuss the PISP Simulator: https://github.com/mojaloop/design-authority/issues/46 +The decision was made that for the time being, the PISP workstream will work on it's own branch in the sdk-scheme-adapter, and such a division/abstraction of the sdk-scheme-adapter will be revisited at a later date (see #51) + +# DA Meeting - 3 June 2020 +We continued the discussion started last week regarding the separate API for PISP and decided to go with option 4: maximum API Separation, with common swagger/open api files for definition and data model reuse: +Please see the link on the Design Authority Board here: https://github.com/mojaloop/design-authority/issues/47 for a detailed problem statement and subsequent decision. + +# DA Meeting - 27 May 2020 +Consensus relating to the issue raised and discussed some time ago, as queried by Adrian, was reached amongst the attendees. The outcome is that the Switch development will not be restrictive and prescriptive but as far as recommendation for new contributions and modules are concerned, it will be preferred if those could be done in TypeScript. + +A new discussion topic was tabled: https://github.com/mojaloop/design-authority/issues/47 seeking to answer the question of whether to have a separate API for PISP, or simply extend the existing Open API. A position statement was prepared and added as a comment. All attendees were brought up to speed with the decision to be made and Issue-#47 will be the topic for the next DA meeting. + +Another, PISP related topic was tabled and will be scheduled for another DA meeting: https://github.com/mojaloop/design-authority/issues/48 - Answer the question of how to manage notifications so that a PISP can be registered as an interested party for notification of the success of a transfer + diff --git a/website/versioned_docs/v1.0.1/community/archive/notes/scrum-of-scrum-notes.md b/website/versioned_docs/v1.0.1/community/archive/notes/scrum-of-scrum-notes.md new file mode 100644 index 000000000..648d833d3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/archive/notes/scrum-of-scrum-notes.md @@ -0,0 +1,154 @@ +# Meeting Notes from Weekly Scrum-of-scrum meetings + +## OSS Scrum or scrum calls Thu **May 7th** 2020 + +1. Coil - Don: + a Performance: 'Big Gap' problem; changes to cs-stream; changed results; putting together a doc with changes for review; Joran's work on concurrent message processing on Kafka topics -> try to test it; seeing 40-50% throughput; + b LPS adapter: Working with Renjith (Applied Payments); putting together a lab / envt for partner teams to use it; Exploring collaboration with GSMA lab +2. Crosslake - Lewis: + a. Performance: Had report out with Confluent with Nakul, engagement wrapping up; Disseminating docs Nakul produced + b. PISP: Design discussions going on along with Implementation + c. Versioning: Figuring scope for ZDD deployments + d. Official launch related issues: DNS issues - worked on and were resolved +3. ModusBox - Sam: + a. Performance: Moving / standardizing Perf changes from PI-9 into master (not all PoCs); Working on goals, strategy for PI10 + b. Core-team: Bulk transfers - getting started by providing support in sdk-scheme-adapter + c. Maintenance (Bug Fixes): + i) Accents in names - Ongoing + ii) Mojaloop simulator on AWS deployments - almost done, working on QA scripts (on 'dev2' - second environment) + d. Testing toolkit: Currently available for testing - all resources in ML FSPIOP API Supported. Reports can be generated. Working on providing Command line options and more portability + e. CCB: Publishing v1.1 Spec this week - API Definition and corresponding Swagger (Open API) +4. Virtual / Mojaloop Foundation - Megan: + a. Launch of Mojaloop Foundation + b. Paula H - Executive Director of the Mojaloop Foundation. +5. Mojaloop Foundation - Simeon: + a. Provide feedback on the Community Survey + b. Hackathon possible in early June time-frame in collaboration with Google + c. Mojaloop Newsletter with interesting items such as ML FSPIOP v1.1 Spec, Helm v10.1.0 release, etc. to be launched next week. + +## OSS Scrum or scrum calls Thu **April 16th** 2020 + +1. Coil: + a. Don C: Perf - preliminary results - got some numbers - got individual handler numbers, to compare with individual handlers - focusing on DB - a thrid of time for one leg spent on perf + b. Don C: HSM: Renjit's team demo'ed the demo for next week - event prep +2. Crosslake: + a. Lewis D: PISP - Sprint planning - iterating designs + b. Lewis D: Hackathons - Discussed a few concepts with Innocent K (HiPiPo) + c. Lewis D: Has access to GSMA lab - will play around + d. Lewis D: Versioning: working on deck for PI10 + e. Kim W: Performance stream overall update - workshop with Confluent + f. Kim W: Performance stream update - Pedro putting together a proposal, presentation +3. Mifos: + a. Ed C: Demo Prep for PI10 meetings +4. Virtual: + a. Megan : Getting ready for the PI10 event and Logistics +5. DA: + a. Nico: Discussing PISP issue which Michael will be the owner of +6. Core team: + a. Sam K: Performance: Preparing Metrics; Doing performance runs to baseline master branches after moving some enhancements to master + b. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing - QA done for current iteration + g. Sam K: Testing toolkit: Improving unit test coverage. Assertions added for various endpoints + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, Reviews in progress +7. Mojaloop Community: + a. Community update by Simeon + +## OSS Scrum or scrum calls Thu **April 9th** 2020 + +1. Coil: + a. Don C: perf testing - Under utilization of resources - more tweaking to be done + b. Don C: HSM integration - demo prep + c. Don C: Legacy adapter - docs update - looking for feedback +2. Crosslake: + a. Kim W: FRMS meeting earlier today - proposals made + b. Kim W: PI10 meetings update, registrations - questions + c. Lewis D: PISP: more planning - working on stories, items, but discussing designs on Oauth, Fido + d. Lewis D: Performance: discussion with Pedro about PoC for arch changes, for Event Sourcing, CQRS, etc + e. Lewis D: Code standards - updated + f. Lewis D: Code quality & Security stream: HSM usage, demo, Security in the OSS community + g. Lewis D: Container scans working - will work with Victor, early benchmarks + h. Lewis D: Finally - versioning update +3. Mifos: + a. Ed C: Work on Payment Hub, integrating with Kafka, ML transactions going through, usiing Elastic Search, for backoffice ops moniring + b. Ed C: Demo Prep for PI10 meetings +4. Core team: + a. Sam K: Performance: Drafting reports, Moving metrics, other enhancements to master branches + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Provide tests and validate Merchant "Request to Pay" use case, standardization on-going + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS done, mTLS being added + h. Sam K: Testing toolkit: Usage guide in progress along with adding Golden path related tests + i. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - First draft done, waiting for review + +## OSS Scrum or scrum calls Thu **April 2nd** 2020 + +1. Mifos: + a. Ed C: Team continuing work on Payment Hub EE, Focus on Operational UI , capabilities for DFSP backends, Error event handling framework +2. Coil: + a. Don C: Performance - setup done and got started - on GCP - getting high latency times - need to troubleshoot and will probably get support from other contributors + b. Don C: ATM - OTP - Encryption +3. Crosslake: + a. Kim W: Agenda for PI10 drafted - email should good out soon + b. Kim W: Schedule for PI10: Tue - Fri; 11am - 4pm GMT - Remote / Virtual event + c. Lewis D: Perf meeting later today - architecture deep dive + d. Lewis D: Versioning - In progress + e. Lewis D: Code quality & Security - Overall Security architecture, HSM covered by Coil + f. Lewis D: Mojaloop in a Vagrant box - in progress +4. Core team: + a. Miguel dB: Performance: Wrapping up Perf work - nearing 900 TPS end-to-end; Currently attempting to identify / understand a single unit that needs this perf + b. Sam K: Performance: Wrapping-up final set of tests; Phase4 roadmap and kickoff planning + c. Sam K: Community Support: Fixing bugs (few major discussion items fixed), providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Fixing issues in /authorizations + e. Sam K: Accents in names issue - implementation ongoing + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum of scrum call Thu **March 26th** 2020 + +1. DA: Nico - Versioning topic discussed by Lewis, Matt, Sam +2. Crosslake: + a. Kim W: Finalizing Agenda - Monday to Friday + b. Kim W: Reach out if you want to present / speak + c. Kim W: Preparing pre-reads + d. Kim W: Fraud & AML workshop: Justus to post summary and notes to GitHub after the workshops + e. Lewis D: Performance workshop / deep-dive possibly Monday + f. Lewis D: PISP Design discussions ongoing + g: Lewis D: Code quality and security stream: i. Docker container security recommendations. ii. GDPR Scope for Mojaloop +3. Mifos: + a. Ed C / Istvan M: Continue creating Lab + b. Ed C / Istvan M: Fineract , new instance of Payment Hub - good progress + c. Ed C / Istvan M: Working on operational monitoring of backend part (back-office debugging, monitoring, etc) +4. Simeon O - Community Manager in attendance +5. Core team: + a. Sam K: Performance: Finalized phase-3 work. Get to immediate goals for logical conclusion - still ongoing - Phase4 roadmap and kickoff + b. Sam K: Community Support: Fixing bugs, providing clarifications regarding implementation decisions, etc. + d. Sam K: Merchant Payment Support - Standardization on-going - Metrics being added, event framework added + e. Sam K: Accents in names issue - Discussing issue, designing solution + f. Sam K: Settlements V2 implementation being done by OSS-TIPS team ongoing + g. Sam K: Testing toolkit: Assertions being added for API resources, JWS in progress. Usage guide in progress + h. Sam K: CCB: V1.1 of the ML FSPIOP API Definition - drafting in progress + +## OSS Scrum or scrum call Thu **March 19th** 2020 + +1. Coil: + a. Don C: Looking at performance, network hops (avoid dup checks etc) + b. Adrian hB: Renjith & Matt working on translation ISO20022, (to JWEs, etc) - demo by the time we meet on how to use HSM +2. Crosslake: + a. Kim W: Finishing action items from the Mid-PI Workshop, follow-up items + b. Kim W: April Community event is happening but will be a Virtual event. Kim has a planning event and will confirm details: Suggestions welcome + c. Lewis D: Performance - to include Don in other discussions + d. Lewis D: Code quality - GDPR requirements proposal + e: Lewis D: Versioning - iinitial draft made as PR - will be presented to DA next week +3. Mifos: + a. Ed C, Istvan M: Payment Hub, envt in Azure, + b. Ed C, Istvan M: Transactions now going through + c. Ed C, Istvan M: Next phase: to implement back office screens to see screens for business users + d. Ed C, Istvan M: Workshop with Google on PISP +4. Core team: + a. Sam K: Perf - Combining prepare+position handler and fulfil+position handlers, characterization work ongoing + b. Sam K: Perf - Working on gaining an understanding of how 1 unit of Infrastructure looks like for a Mojaloop deployment + c. Sam K: Transaction requests service standardization: Added event framework, Adding metrics now + d. Sam K: Community Support: Fixing issues, upgrade issues, issue for allowing accents in names, etc,. diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/admin_configure.png b/website/versioned_docs/v1.0.1/community/assets/cla/admin_configure.png new file mode 100644 index 000000000..1d8281bb4 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/admin_configure.png differ diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/admin_sign_in.png b/website/versioned_docs/v1.0.1/community/assets/cla/admin_sign_in.png new file mode 100644 index 000000000..a960e2dcd Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/admin_sign_in.png differ diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/cla_1.png b/website/versioned_docs/v1.0.1/community/assets/cla/cla_1.png new file mode 100644 index 000000000..46718fc66 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/cla_1.png differ diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_1.png b/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_1.png new file mode 100644 index 000000000..18ae1809c Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_1.png differ diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_2.png b/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_2.png new file mode 100644 index 000000000..2e60fb762 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/cla_2_2.png differ diff --git a/website/versioned_docs/v1.0.1/community/assets/cla/cla_3.png b/website/versioned_docs/v1.0.1/community/assets/cla/cla_3.png new file mode 100644 index 000000000..5e2ddc46d Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/assets/cla/cla_3.png differ diff --git a/website/versioned_docs/v1.0.1/community/contributing/code-of-conduct.md b/website/versioned_docs/v1.0.1/community/contributing/code-of-conduct.md new file mode 100644 index 000000000..641649471 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/contributing/code-of-conduct.md @@ -0,0 +1,94 @@ +# Mojaloop Code of Conduct + + +## Vision and Mission + +Mojaloop is a portmanteau derived from the Swahili word "Moja" meaning "one" and the English word loop. Mojaloop's vision is to loop digital financial providers and customers together in one inclusive ecosystem. + +The Mojaloop open source project mission is to increase financial inclusion by empowering organizations creating trusted and interoperable payments systems to enable digital financial services for all. We believe an economy that includes everyone, benefits everyone and we are building software that will accelerate full financial inclusion. Succeeding in our mission will require diverse opinions and contributions from people reflecting differing experiences and who come from culturally diverse backgrounds. + +## Community Foundation and Values + +Our goal is a strong and diverse community that welcomes new ideas in a complex field and fosters collaboration between groups and individuals with very different needs, interests, and skills. + +We build a strong and diverse community by actively seeking participation from those who add value to it. + +We treat each other openly and respectfully, we evaluate contributions with fairness and equity, and we seek to create a project that includes everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, and orientation. + +*This code of conduct exists to ensure that diverse groups collaborate to mutual advantage and enjoyment.* + +The Code of Conduct governs how we behave in public or in private, virtually or in person. We expect it to be honoured by everyone who represents the project officially or informally, claims affiliation with the project, or participates directly. + +### We strive to: + +- **Be Considerate**\ + Our work will be used by other people, and we in turn will depend on the work of others. Any decision we take will affect everyone involved in our ecosystem, and we should consider all relevant aspects when making decisions. + +- **Be Respectful**\ + We work together to resolve conflict, assume good intentions, and do our best to act in an empathic fashion. We believe a community where people are respected and feel comfortable is a productive one. + +- **Be Accountable**\ + We are accountable for our words and actions. We all can make mistakes; when we do, we take responsibility for them. If someone has been harmed or offended, we listen carefully and respectfully and work to right the wrong. + +- **Be Collaborative**\ + What we produce is a complex whole made of many parts. Collaboration between teams that each have their own goal and vision is essential; for the whole to be more than the sum of its parts, each part must make an effort to understand the whole.\ + Collaboration reduces redundancy and improves the quality of our work. Internally and externally, we celebrate good collaboration. Wherever possible, we work closely with upstream projects and others in the open-source software community to coordinate our efforts. We prefer to work transparently and involve interested parties as early as possible. + +- **Value Decisiveness, Clarity, and Consensus**\ + Disagreements, social and technical, are normal, but we do not allow them to persist and fester leaving others uncertain of the agreed direction.\ + We expect community members to resolve disagreements constructively. When they face obstacles in doing so, we escalate the matter to structures with designated leaders to arbitrate and provide clarity and direction. + +- **Ask for help when unsure**\ + Nobody is expected to be perfect in this community. Asking questions early avoids many problems later, so questions are encouraged, though they may be directed to the appropriate forum. Those who are asked should be responsive and helpful. + +- **Step Down Considerately**\ + When somebody leaves or disengages from the project, we ask that they do so in a way that minimises disruption to the project. They should tell people they are leaving and take the proper steps to ensure that others can pick up where they left off. + +- **Open Meritocracy**\ +We invite anybody, from any company or organization, to participate in any aspect of the project. Our community is open, and any responsibility can be carried by any contributor who demonstrates the required capacity and competence. + +- **Value Diversity and Inclusion**\ +This is a community that wants to make a real difference to people's lives across the globe; and, in particular, in developing societies and economies. We value our members, first of all, for themselves; and, second, for the help they can give each of us as we work together to transform the world. Each of us will strive never to allow any other considerations to weigh with us, either consciously or unconsciously. In particular, considerations of gender identity or expression, sexual orientation, religion, ethnicity, age, neurodiversity, disability status, language, and citizenship have no place in our collaboration and we will work to eradicate them where we find them: first of all, in ourselves; but after that, and with respect and affection, in those we work with. + +- **Be Transparent**\ +We believe community members will have personal and professional interests in the development of the Mojaloop Open Source Software. These interests will, directly and indirectly, influence perceptions about the best direction of the community. Community members should make every reasonable effort to be transparent about their interests within the limits of confidentiality.  Community members who hold permanent or temporary governance roles should not use those roles in the advancement of personal or professional interests but should base their influence on the best interests of the success of the community. + +This Code of Conduct is not exhaustive or complete. It is not a rulebook; it serves to distill our common understanding of a collaborative, shared environment, and goals. We expect it to be followed in spirit as much as in the letter. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language + +- Being respectful of differing viewpoints and experiences + +- Gracefully accepting constructive criticism + +- Focusing on what is best for the community + +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances + +- Trolling, insulting/derogatory comments, and personal or political attacks + +- Public or private harassment + +- Publishing others' private information, such as a physical or electronic address, without explicit permission + +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Reporting and Resolution + +If you see someone violating the code of conduct, you are encouraged to address the behavior directly with those involved. Many issues can be resolved quickly and easily, and this gives people more control over the outcome of their dispute. If you are unable to resolve the matter for any reason, or if the behavior is threatening or harassing, report it. We are dedicated to providing an environment where participants feel welcome and safe. + +Reports should be directed to the Community Leadership Committee via an email sent to . This email goes to the Mojaloop Foundation Community Manager whose duty it is to receive and address reported violations of the code of conduct. They will then work with the Community Leadership Committee to address and resolve the report. + +We will investigate every complaint, but you may not receive a direct response. Whether we respond to you directly or not, you will always be able to enquire after the status of a complaint by contacting a member of the Community Leadership Committee. We will use our discretion in determining when and how to follow up on reported incidents, which may range from not taking action to permanent expulsion from the community and foundation-sponsored spaces. We will notify the accused of the report and provide them an opportunity to discuss it before any action is taken. The identity of the reporter will be omitted from the details of the report supplied to the accused. In potentially harmful situations, such as ongoing harassment or threats to anyone's safety, we may take action without notice. + +### Attribution + +This Code of Conduct is adapted from the Ubuntu Code of Conduct v2.0, available at diff --git a/website/versioned_docs/v1.0.1/community/contributing/contributors-guide.md b/website/versioned_docs/v1.0.1/community/contributing/contributors-guide.md new file mode 100644 index 000000000..c931cb732 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/contributing/contributors-guide.md @@ -0,0 +1,60 @@ +# Contributors' Guide + +We are glad that you are considering becoming a part of the Mojaloop community. + +Based on the current phase of the Mojaloop project, we are looking for one of the following types of contributors: + +## Types of contributors +- #### Individual Contributors + +> These individuals are those that want to start contributing to the Mojaloop community. This could be a software developer or quality assurance person that wants to write new code or fix a bug. This could also be a business, compliance or risk specialist that wants to help provide rules, write documentation or participate in requirements gathering. + +- #### Hub Operators + +> Typically these or organizations or individuals or government agencies that are interested in setting up their own Mojaloop Switch to become part of the ecosystem. + +- #### Implementation Teams + +> Implementation teams can assist banks, government offices, mobile operators or credit unions in deploying Mojaloop. + + +## How do I contribute? + +* Review the [Mojaloop Deployment](https://docs.mojaloop.io/documentation/deployment-guide/) Guide and the [Onboarding Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md). +* Browse through the [Repository Overview](https://docs.mojaloop.io/documentation/repositories/) to understand how the Mojaloop code is managed across multiple Github Repositories. +* Get familiar with our [Standards](../standards/guide.md) for contributing to this project. +* Go through the [New Contributor Checklist](./new-contributor-checklist.md), and browse through the project board and work on your [good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) +* Review the [Roadmap](../mojaloop-roadmap.md) and contribute to future opportunities. +* Familiarize yourself with our Community [Code of Conduct](./code-of-conduct.md). + +## What work is needed? + +Work is tracked as issues in the [mojaloop/project](https://github.com/mojaloop/project) repository GitHub. You'll see issues there that are open and marked as bugs, stories, or epics. An epic is larger work that contains multiple stories. Start with any stories that are marked with "[good first issue](https://github.com/mojaloop/project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)". In addition, anything that is in the backlog and not assigned to someone are things we could use help with. Stories that have owners are in someone's backlog already, though you can always ask about them in the issue or on Slack. + +There's a [roadmap](../mojaloop-roadmap.md) that shows larger work that people could do or are working on. It has some main initiatives and epics and the order, but lacks dates as this work is community driven. Work is broken down from there into issues in GitHub. + +In general, we are looking for example implementations and bug fixes, and project enhancements. + +## Where do I get help? + +Join the [Mojaloop Slack Discussions](https://mojaloop-slack.herokuapp.com/) to connect with other developers. + +Also checkout the [FAQ](https://github.com/mojaloop/documentation/blob/master/contributors-guide/frequently-asked-questions.md) + +## What is the current release? + +See the [Mojaloop Slack Announcements](https://mojaloop.slack.com/messages/CG3MAJZ5J) to find out information on the latest release. + +## What's here and what's not? + +This is free code provided under an [Apache 2.0 license](https://github.com/mojaloop/mojaloop/blob/master/LICENSE.md). + +The code is released with an Apache 2.0 license but the Specification documents under the 'mojaloop-specification' documents are published with CC BY-ND 4.0 License + +We don't provide production servers to run it on. That's up to you. You are free \(and encouraged!\) to clone these repositories, participate in the community of developers, and contribute back to the code. + +We are not trying to replace any mobile wallet or financial providers. We provide code to link together new and existing financial providers using a common scheme. There are central services for identifying a customer's provider, quoting, fulfillment, deferred net settlement, and shared fraud management. Each provider can take advantage of these services to send and receive money with others on the system and there's no cost to them to onboard new providers. We provide code for a simple example mobile money provider to show how integration can be done, but our example DFSP is not meant to be a production mobile money provider. + +## Where do I send bugs, questions, and feedback? + +For bugs, see [Reporting bugs](https://github.com/mojaloop/mojaloop/blob/master/contribute/Reporting-Bugs.md). \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/contributing/new-contributor-checklist.md b/website/versioned_docs/v1.0.1/community/contributing/new-contributor-checklist.md new file mode 100644 index 000000000..ab7450d7b --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/contributing/new-contributor-checklist.md @@ -0,0 +1,63 @@ +# New Contributor Checklist + +This guide summarizes the steps needed to get up and running as a contributor to Mojaloop. They needn't be completed all in one sitting, but by the end of the checklist, you should have learned a good deal about Mojaloop, and be prepared to contribute to the community. + + +## 1. Tools & Documentation + +- Make sure you have a GitHub account already, or sign up for an account [here](https://github.com/join) + +- Join the slack community at the [self-invite link](https://mojaloop-slack.herokuapp.com/), and join the following channels: + - `#announcements` - Announcements for new Releases and QA Status + - `#design-authority` - Questions + Discussion around Mojaloop Design + - `#general` - General discussion about Mojaloop + - `#help-mojaloop` - Ask for help with installing or running Mojaloop + - `#ml-oss-bug-triage` - Discussion and triage for new bugs and issues + +- Say hi! Feel free to give a short introduction of yourself to the community on the `#general` channel. + +- Review the [Git workflow guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) and ensure you are familiar with git. + - Further reading: [Introduction to Github workflow](https://www.atlassian.com/git/tutorials/comparing-workflows) + +- Familiarize yourself with our standard coding style: https://standardjs.com/ + +- Browse through the [Mojaloop Documentation](https://mojaloop.io/documentation/) and get a basic understanding of how the technology works. + +- Go through the [Developer Tools Guide](https://github.com/mojaloop/mojaloop/blob/master/onboarding.md) to get the necessary developer tools up and running on your local environment. + +- (Optional) Get the Central-Ledger up and running on local machines: + - https://github.com/mojaloop/central-ledger/blob/master/Onboarding.md + - https://github.com/mojaloop/ml-api-adapter/blob/master/Onboarding.md + +- (Optional:) Run an entire switch yourself with Kubernetes https://mojaloop.io/documentation/deployment-guide/ _(note: if running locally, your Kubernetes cluster will need 8GB or more of RAM)_ + +## 2. Finding an Issue + +- Review the [good-first-issue](https://github.com/mojaloop/project/labels/good%20first%20issue) list on [`mojaloop/project`](https://github.com/mojaloop/project), to find a good issue to start working on. Alternatively, reach out to the community on Slack at `#general` to ask for help to find an issue. + +- Leave a comment on the issue asking for it to be assigned to you -- this helps make sure we don't duplicate work. As always, reach out to us on Slack if you have any questions or concerns. + +- Fork the relevant repos for the issue, clone and create a new branch for the issue + - Refer to our [Git User Guide](https://mojaloop.io/documentation/contributors-guide/standards/creating-new-features.html) if you get lost + + +## 3. Opening your First PR + +> Complete this part of the guide once you have been added to the Mojaloop GitHub organization. If you don't have access, reach out to us on the `#general` or `#help-mojaloop` + +- Sign up for [Zenhub](https://www.zenhub.com/), and connect it to the Mojaloop Organisation, Search for the _'project'_ workspace +- Install the [Zenhub Browser extension](https://www.zenhub.com/extension) for Chrome or Firefox, and browse the (Mojaloop Project Kanban board](https://github.com/mojaloop/project#zenhub) + +- When your branch is ready for review, open a new pull request from your repository back into the mojaloop project. + >_Note: if the CI/CD pipelines don't run, this may be because your Github account isn't added to the Mojaloop repo_ +- Ensure the following: + - A good description of the feature/bugfix you implemented + - The PR is _assigned_ to yourself + - You have assigned two or more _reviewers_. GitHub often has suggested reviewers, but if you don't know who to assign, feel free to ask whoever created the issue. + +- (Optional) Post a link to your PR on the `#ml-oss-devs` channel in Slack so everyone can share in the fun + + +## 4. Signing the CLA + +After you open your first PR, our CI/CD pipelines will ask you to sign the CLA. For more information on what the CLA is and how to sign it, see [Signing the CLA](./signing-the-cla.md) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/contributing/signing-the-cla.md b/website/versioned_docs/v1.0.1/community/contributing/signing-the-cla.md new file mode 100644 index 000000000..a07b97826 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/contributing/signing-the-cla.md @@ -0,0 +1,97 @@ +# Signing the CLA + +Mojaloop has a [Contributor License Agreement (CLA)](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) which clarifies the intellectual property rights for contributions from individuals or entities. + +To ensure every developer has signed the CLA, we use [CLA Assistant](https://cla-assistant.io/), a well maintained, open source tool which checks to make sure that a contributor has signed the CLA before allowing a pull request to be merged. + +## How to sign the CLA + +1. Open a pull request to any Mojaloop repository +2. When the pull request performs the standard checks, you will see the `license/cla` check has run, and requests users to sign the CLA: + + + +3. Click 'Details', and you will be directed to the CLA Assistant tool, where you can read the CLA, fill out some personal details, and sign it. + + +
    + + + +4. Once you have clicked "I agree", navigate back to the Pull request, and see that the CLA Assistant check has passed. + + + + + +### Signing For A Company + +Section 3 of the [Mojaloop CLA](https://github.com/mojaloop/mojaloop/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.md) covers contributions both from individuals and contributions made by individuals on behalf of their employer. If you are contributing to the Mojaloop Community on behalf of your employer, please enter your employer's name in the "Company or Organization" field. If not, feel free to write "OSS Contributor" and leave the "role" field blank. + + +## Administering the CLA tool + +The CLA Tool is easy to install, any GitHub admin can link it with the Mojaloop organization. + +1. Create a new GitHub Gist and enter in the text of the CLA in a new file. +> Since Github doesn't allow Gists to be owned my organizations, [our gist](https://gist.github.com/mojaloopci/9b7133e1ac153a097ae4ff893add8974) is owned by the 'mojaloopci' user. + +2. Go to [CLA Assistant](https://cla-assistant.io/) and click "Sign in with GitHub" + + + +3. You can add a CLA to either a Repo or Organization. Select "Mojaloop", and then select the gist you just created + + + +4. Hit "Link" and that's it! + + +### Requesting Additional Information: + +> Reference: [request-more-information-from-the-cla-signer](https://github.com/cla-assistant/cla-assistant#request-more-information-from-the-cla-signer) + +You can also add a `metadata` file to the CLA gist, to build a custom form for the CLA tool: + +```json +{ + "name": { + "title": "Full Name", + "type": "string", + "githubKey": "name" + }, + "email": { + "title": "E-Mail", + "type": "string", + "githubKey": "email", + "required": true + }, + "country": { + "title": "Country you are based in", + "type": "string", + "required": true + }, + "company": { + "title": "Company or Organization", + "description": "If you're not affiliated with any, please write 'OSS Contributor'", + "type": "string", + "required": true + }, + "role": { + "title": "Your Role", + "description": "What is your role in your company/organization? Skip this if you're not affiliated with any", + "type": "string", + "required": false + }, + "agreement": { + "title": "I have read and agree to the CLA", + "type": "boolean", + "required": true + } +} +``` + +Produces the following form: + + + diff --git a/website/versioned_docs/v1.0.1/community/documentation/api-documentation.md b/website/versioned_docs/v1.0.1/community/documentation/api-documentation.md new file mode 100644 index 000000000..c1c8f8174 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/documentation/api-documentation.md @@ -0,0 +1,29 @@ +# API Documentation + +All APIs should be documented in RAML or Swagger, see Architecture-Documentation-Guidelines\]\(Architecture-Documentation-Guidelines.md\) + + + +**Section Headings** + +* Do not number headings - for example, "Prepare and Fulfill", not "C - Prepare and Fulfill" +* Make sure section headings \(\# \) match the heading to which they correspond in the comprehensive PDF \(built from the [dactyl config file](https://github.com/Mojaloop/Docs/blob/master/ExportDocs/dactyl-config.yml)\) +* Do not include the word "documentation" in headings + +#### Retrievability + +* For sections that contain many subsections of endpoints or methods, provide a table of contents at the beginning of the section +* Don't say the word project; use component, microservice, interfaces, etc + +#### Language + +Instead of the word "project," use a specific noun such as component, microservice, or interface. + +#### Procedures + +* Introduce procedures with H3 \(\#\#\#\) or H4 \(\#\#\#\#\) headers \(not H2 \(\#\#\)\). +* Do not use numbers in procedure section headings. +* Use ordered-list tagging for procedure steps. For example: +* Step 1 +* Step 2 +* Step 2 diff --git a/website/versioned_docs/v1.0.1/community/documentation/standards.md b/website/versioned_docs/v1.0.1/community/documentation/standards.md new file mode 100644 index 000000000..fdc339691 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/documentation/standards.md @@ -0,0 +1,29 @@ +# Documentation + +### Overview + +Mojaloop has set forward several standards to ensure that documentation throughout the project is consistent and kept up to date. + +* All documentation that is relevant for contributors is kept on the "documentation" repository. +* The "documentation" repository is sync'ed with GitBook and all content is consumed in an easily readable format on: [https://www.gitbook.com/mojaloop](https://www.gitbook.com/mojaloop) +* All documentation should include: + * Overview: business overview to provide the value or reason for the documentation page + * Details: appropriate summary information to support the documentation + +### + +[Documentation standards](https://github.com/mojaloop/mojaloop/blob/master/contribute/Documentation-and-Template-Standards.md) + +### Documentation Style Guide + +All new documentation should confirm to the documentation and styles as discussed [here](style-guide.md). + +### Code Style Guide + +#### NodeJS + +We follow the [Standard style guidelines](https://github.com/feross/standard). Add `npm install standard` to you package.json. + +#### Java + +For Java we follow [Checkstyle](http://checkstyle.sourceforge.net/).Code Quality Metrics diff --git a/website/versioned_docs/v1.0.1/community/documentation/style-guide.md b/website/versioned_docs/v1.0.1/community/documentation/style-guide.md new file mode 100644 index 000000000..2d927651f --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/documentation/style-guide.md @@ -0,0 +1,229 @@ +# Documentation Style Guide + +In most cases, Mojaloop follows the latest edition of the Associated Press Stylebook. The following are foundation-specific guidelines which have been updated and slightly modified. + +#### Acronyms + +Spell out all acronyms on first reference. Include the acronym in parentheses immediately after the full spelling only if you refer to it again in the document. Example: _Kofi Annan, chairman of the board of the Alliance for a Green Revolution in Africa \(AGRA\), traveled to Nairobi this month. It was his first visit to the AGRA office._ + +#### Ampersand + +Only use an ampersand \(&\) when it's part of a formal name like the Bill & Melinda Gates Foundation. In all other cases, spell out and. + +#### Bill & Melinda Gates Foundation + +Our formal legal name is the Bill & Melinda Gates Foundation. Use it on first reference. Always use the ampersand \(&\) and always capitalize Foundation when Bill & Melinda Gates comes before it. + +Never abbreviate the foundation's name as _BMGF_. + +Never translate the foundation name into other languages, as it is a proper noun. The one exception to this is when translating the foundation's name into Chinese, in which case translation is acceptable. + +Do not capitalize foundation when the word stands alone. Example: _The foundation's new headquarters will be built near Seattle Center._ + +Use Gates Foundation only if you are sure the context makes the foundation's identity clear. There is a Gates Family Foundation in Colorado, so we need to be careful. Example: _The Bill & Melinda Gates Foundation and the Ford Foundation co-sponsored the event. A Gates Foundation staff member gave closing remarks._ + +The entity that manages the endowment is formally and legally known as the Bill & Melinda Gates Foundation Trust. You will not need to refer to this entity often, but when you do, write it out on first reference and refer to it as the asset trust thereafter. + +#### Bold and colons + +Frequently I see structures \(like in this very comment!\) where you have introductory terms or phrases that are bolded and set apart from the contents with a colon. Should the colon also be bolded, or not? \(I frequently see it done both ways.\) + +#### Buffett + +Note the spelling: two fs and two ts \(_i.e., Warren Buffett_\). + +#### Bulleted lists + +Introduce bulleted lists with a colon when the listed items complete the lead-in sentence or phrase. Exception: never use colons in headings or subheadings to introduce bulleted lists. + +Capitalize the first words of and use periods with listed items only if they are full sentences. Examples: + +* _This is a complete sentence._ +* _not a complete sentence_ + +Never link items in a bulleted list with coordinating conjunctions and punctuation \(semicolons or commas\) as you would in a sentence-style list. In other words, never do: + +* _this,_ +* _that, or_ +* _the other thing._ + +#### Captions + +Caption photos whenever possible. It helps people understand our work. + +Write captions as single gerund \(_ing verb_\) phrases, followed by the city, state or country, and year the photo was taken in parentheses. Example: _A doctor preparing a vaccine for delivery_ \(Brazzaville, Congo, 2007\).\_ + +When writing a caption, be sure to introduce the people featured and explain what's happening in the image as it relates to our areas of focus. Be as brief as possible so you don't distract from the image or layout. Avoid verbs that state the obvious about what the photo's subject is doing _\(e.g., smiling, standing, and so on\)._ + +If one of the co-chairs appears in a photo with other people, be sure to identify the co-chair in the caption. Don't assume everyone knows what our co-chairs look like. + +#### Citations + +Most fields have their own citation conventions. Adopt those used by the field in question. When citation conventions are unavailable or uncertain, follow The Chicago Manual of Style. + +When a document uses both footnotes and endnotes, for the footnotes, use the following symbols: + +* 1st note = \* \(asterisk\) +* 2nd note = † \(dagger\) +* 3rd note = ‡ \(double dagger\) +* 4th note = § \(section sign\) +* 5th note = \*\* \(2 asterisks\) +* 6th note = †† \(2 daggers\) +* 7th note = ‡‡ \(2 double daggers\) +* 8th note = §§ \(2 section signs\) + +Separate multiple superscript references \(footnotes, endnotes\) with commas, not semicolons. + +#### Clinical trials + +Use Roman numerals when referring to clinical trial phases and always capitalize Phase. Example: The company will begin Phase III trials on the new drug this spring. + +#### Contact information + +Use periods to separate parts of phone numbers, and begin each number with a plus sign. + +Because we work with people throughout the world, omit the international access code, which differs from country to country \(it's 011 in the United States\). Examples: _+1.206.709.3100 \(United States\)_ _+91.11.4100.3100 \(India\)_ + +#### Copyright and trademark notice + +All publications, media, and materials produced by or for the foundation should contain the notice shown below. The Legal team must approve all exceptions. + + _© \(year\) Bill & Melinda Gates Foundation. All Rights Reserved._ Bill & Melinda Gates Foundation is a registered trademark in the United States and other countries. + +When possible, begin the trademark portion of the notice on a separate line. + +#### Dashes + +Use dashes—those the width of a capital M—to indicate asides or abrupt changes in thought. Use en dashes—those the width of a capital N—with numerical ranges. + +Do not include a space before or after a dash. + +Examples: _We work to make safe, affordable financial services—particularly savings accounts—more widely available to people in developing countries._ + +_In the 2004 presidential election, 76 percent of U.S. college graduates ages 25-44 voted._ + +#### Dollars \($\) + +In Global Health and Global Development materials, because more than a dozen countries use dollars, specify U.S. dollars in parentheses on first mention in a document. Example: _$100,000 \(U.S.\)_. Omit the parenthetical U.S. in subsequent references to dollar amounts in the same document. + +#### Foundation program names + +We have three programs: Global Development Program, Global Health Program, and United States Program. + +_Program_ is capitalized when used with the full name \(Global Development Program\), but not when used alone \(The program makes grants in several areas.\). + +Use periods when abbreviating the name of the United States Program: U.S. Program. + +GH, GD, and USP are fine for internal use, but inappropriate for external publications. + +#### Gates family + +William Gates III is formally referred to as Bill Gates. In internal documents, use Bill—not a nickname or abbreviation. + +Use Melinda Gates when formally referring to Melinda. + +Use William H. Gates Sr. when formally referring to Bill Gates Sr. There is no comma between Gates and Sr. Bill Sr. is acceptable in internal documents. + +Plural: Gateses. Do not use an apostrophe to form the plural of the family's name. Example: The Gateses attended the opening of the new University of Washington law building. + +Possessive: The apostrophe follows Gates when you refer to something owned by either Bill or Melinda. Example: Melinda Gates' speech was well received. The apostrophe follows Gateses when you refer to something Bill and Melinda own jointly. Example: _The Gateses' decision to provide free Internet access in U.S. public libraries has increased library usage and circulation overall._ + +You may also phrase it this way: Bill and Melinda Gates' decision to provide free Internet access … + +See the Titles of people entry for the formal titles of Bill, Melinda, Bill Sr., and other leaders of the foundation. + +#### Hyphens + +There are few hard-and-fast rules when it comes to hyphens. Generally we use them to enhance the reader's understanding. + +Examples: _When writing for the Bill & Melinda Gates Foundation, use real-world poverty examples to illustrate your point._ _When writing for the Bill & Melinda Gates Foundation, use real world-poverty examples to illustrate your point._ + +In the first example, the hyphen in real-world connects real and world to form a single adjective describing poverty. In the second example, the hyphen in world-poverty connects world and poverty to form a single adjective describing examples. + +The meaning changes depending on the placement of the hyphen. In instances where a series of adjectives creates ambiguity about what they refer to, use a hyphen to clarify the intended meaning. + +When capitalizing hyphenated words, only capitalize the first part. Example: _Co-chairs Bill and Melinda Gates._ + +For other uses of hyphens—compound modifiers, prefixes and suffixes, fractions—refer to the Associated Press Stylebook. + +#### Numerals + +When referring to dollar figures, spell out million and billion. Use figures and decimals \(not fractions\). Do not go beyond two decimal places. Example: _The foundation granted .45 million to United Way._ + +When using numbers that have nothing to do with dollar figures or percentages, write them out if they are under 10, and use numerals if they are 10 or over. Example: Four program officers went on 13 site visits. + +In cases of grammatical parallelism, parallel construction always trumps this rule. For instance: Mr. Johnson has two children, 5-year-old Kyle and 13-year-old Frances. + +Never begin a sentence with a numeral. Either spell the number out or revise the sentence so it doesn't begin with a number. + +#### Percentages + +When using percentages, write out percent \(don't use %\). Use numerals instead of writing numbers out, even if they're less than 10. + +Example: _This program accounts for 6 percent of our grantmaking._ + +#### Photographer credits + +If the foundation owns the image you are using, you don't need to credit the photographer. All images in our media asset management system are foundation-owned. If the foundation has purchased a license to use the image, you may need to credit the photographer. If you have questions about photo credit requirements, contact the Foundation Communications Service Desk. + +#### Plain language + +We could call out a few specific constructions that are needlessly wordy. One that we frequently catch at Ripple is "in order to" instead of just "to." + +#### Quotation marks + +Use double quotation marks for dialogue and the citation of printed sources. Limit use of scare quotes—quotation marks meant to call attention to a quoted word or phrase and distance the author from its meaning, typically because the language is specialized, idiomatic, ironic, or misused. Example: _The foundation has increasingly used “program-related investments” in recent years._ + +#### Quoted strings and punctuation + +When describing exact strings in technical documentation, should punctuation \(not part of the literal strings\) be included in the quotation marks? For example, valid states include "pending," "in progress," and "completed." + +#### Scientific names + +Capitalize and italicize scientific names in accordance with conventions in the scientific community. Use the full version of a scientific name on first mention and the abbreviated form thereafter. For example, _use Salmonella typhi first and S. typhi for each additional reference._ + +#### Serial commas + +With lists of three or more items in a sentence, add a final comma before the coordinating conjunction and or or. Example: _The foundation's three program areas are Global Development, Global Health, and the United States._ + +#### Spacing after punctuation + +Use only one space after punctuation, including periods, colons, and semicolons. + +#### Spelling and capitalization conventions + +_bed net:_ two words, no hyphen. + +_email:_ one word, no hyphen, lowercase. + +_foundation:_ lowercase, except as part of the full foundation name. + +_grantmaking:_ one word, no hyphen. + +_nongovernmental:_ one word, no hyphen. + +_nonprofit:_ one word, no hyphen. + +_postsecondary:_ one word, no hyphen. + +_Washington state:_ lowercase state \(unless you're referring to Washington State University, the Washington State Legislature, or something similar\). + +_website:_ one word, lowercase + +#### Titles of people + +Formal titles should not be capitalized unless the title precedes a person's name or appears in a headline. Example: _Co-chair Melinda Gates will speak at the Washington Economic Club this year._ + +Lowercase and spell out titles when they are not used with an individual's name. Example: _The foundation co-chair issued a statement._ + +Lowercase and spell out titles in constructions that use commas to set them off from a name. Example: _Bill Gates, co-chair of the foundation, commented on the grant._ + +#### United States + +Spell out United States when using it as a noun. Abbreviate it as U.S. \(including periods\) when using it as an adjective. In certain cases, as when referring to a person from the United States, it's acceptable to use American. + +Examples: _The U.S. State Department is in the United States._ _The foundation's U.S. Program…_ + +#### URL + +Reference web addresses without the http:// as follows: _www.gatesfoundation.org_ diff --git a/website/versioned_docs/v1.0.1/community/faqs.md b/website/versioned_docs/v1.0.1/community/faqs.md new file mode 100644 index 000000000..71ac45b77 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/faqs.md @@ -0,0 +1,9 @@ +# Using Vue in Markdown + +## Browser API Access Restrictions + +Because VuePress applications are server-rendered in Node.js when generating static builds, any Vue usage must conform to the [universal code requirements](https://ssr.vuejs.org/en/universal.html). In short, make sure to only access Browser / DOM APIs in `beforeMount` or `mounted` hooks. + +If you are using or demoing components that are not SSR friendly (for example containing custom directives), you can wrap them inside the built-in `` component: + +## diff --git a/website/versioned_docs/v1.0.1/community/mojaloop-publications.md b/website/versioned_docs/v1.0.1/community/mojaloop-publications.md new file mode 100644 index 000000000..f1dbb7fb1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/mojaloop-publications.md @@ -0,0 +1,18 @@ +# Publications + +Publications are stored in the [Documentation Artifacts Github repository](https://github.com/mojaloop/documentation-artifacts). + +See below listing of current published publications. + +## OSS Community Convenings Sessions (Presentations and Notes) + +- [January 2020 (Phase 4 Kickoff) OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202020%20OSS%20Community%20Session) +- [September 2019 PI-8 (Phase 3 Wrap-up) OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/September%202019%20PI-8_OSS_community%20session) +- [June 2019 PI-7 OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/June%202019%20PI-7_OSS_community%20session) +- [April 2019 PI-6_OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/April%202019%20PI-6_OSS_community%20session) +- [January 2010 PI-5 OSS Community Session](https://github.com/mojaloop/documentation-artifacts/tree/master/presentations/January%202019) + +## Mojaloop Standard Publications + +- [Moajoop Decimal Type; Based on XML Schema Decimal Type](./discussions/decimal.md) +- [Mojaloop API Specification](https://github.com/mojaloop/mojaloop-specification/blob/master/API%20Definition%20v1.0.pdf) diff --git a/website/versioned_docs/v1.0.1/community/mojaloop-roadmap.md b/website/versioned_docs/v1.0.1/community/mojaloop-roadmap.md new file mode 100644 index 000000000..2df113fa3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/mojaloop-roadmap.md @@ -0,0 +1,171 @@ +# The Mojaloop Roadmap + + +## What makes the Mojaloop approach different? + +We've documented in our white paper [here](https://mojaloop.io/mojaloop-executive-briefing/) how we think Mojaloop supports markets towards financial inclusion through effective and efficient interoperability, by providing an alternate option for schemes choosing clearing and settlement switching technology. + +Here are 4 key reasons as to why we believe the open source approach with a vibrant community model is different: + +1. **Clearing and Settlement Hub: Business Critical Functionality** delivered with excellence, for day to day operations done well, allowing ecosystems to be able to embrace the potential of straight through processing and full automation. + +3. **Simplify Integration Complexity:** + - taking away as much complexity as possible through standardised and documented-in-the-open APIs & patterns & tools to support swift network participation & automated settlement rather than a reconciliation driven process. + - A future facing security design that allows cyber-secure safe use of the open internet (not VPNs) to create the network where ecosystems wish to embrace this cost reduction. + +4. Adopters can **take advantage of a tectonic shift in technology in financial services globally,** the post-covid demand, and the implication on future financial services: + - emergence of open banking & embedded finance as well as "merchant request to pay" models over push payments technology + - global use of opensource technologies in infrastructure projects + - COVID revolution around the need for digital transformation & bulk payments for a resilient response to such events. + + **4. Community Stronger Together** + - A solution developed & documented in the open in order to create an ability for participants to benefit from each other’s learnings: "stronger together” + - We have a community sustainability vision that enables impactful interoperability between last mile services through a community formed of a mix of mojaloop technology adopters on-the-ground putting the core technology to work, push payments & financial inclusion experts, and technology infrastructure gurus. + - An open source delivery model becomes sustainable with public-private partnership, adjacent commercial service offerings easily added as extensions (marketplace thinking), healthy co-opetition, and market-making around an open source core technology solution. + + +## Our 2021 community product strategy to help achieve the vision: + +The journey to the big vision starts with getting running hubs. So our 2021 product strategy is in service of productising what is already created to make it easier to start & to ensure existing adopters are engaged in providing feedback: + +- Remove Friction in the adoption funnel +- Cost Reduction (for new adopters & production grade deploys) +- Deliver Validated Feature asks that support Adopter Traction in Market +- Trustworthy/Quality/Credible = Secure, Performant at Scale, Cost Effective, Modular & Extensible, Resilient, Testable and Easy to Deploy & Operate + + +## Our 2021 product roadmap for workstream activity: + +**Looking closely at what areas of work might support In January 2021 we laid out this framework at our community event as important activity to shape community decisions that would support our 2021 goal of Mojaloop ground traction & community growth:** + +- Provide Better Business Process Support within the product +- Ensure the Core Hub is Secure, Performant at Scale, Modular & Extensible, Resilient, Testable and Easy to Deploy & Operate +- Make it Cost Effective for a new adopter to get Started +- Consolidate & Productise what we have for Advocacy efforts (demos, sandbox, better get-started material to ensure the product adaptation in-the-field is minimised & effective) +- Keep Innovating with Valuable Extensions to the Core Hub such as 3PPI & merchant extensions to help impact & decision making + +## **Our key initiatives in 2021 that have delivered on the above:** + +- **Better Business Process Support**: + - A business process team have created a foundational framework for a roadmap of business process improvement work. + - Key features improved around the core APIs: + - Role-Based Access Control using https://www.ory.sh/ for identity access management (authentication, authorization, access control, and delegation of users accessing the APIs) + - WSO2 as an out-of-the-box API Gateway: providing Provide role, policy-based access, security, abstraction, throttling & control, identity management + - Event Logging Framework: Better support for operational reporting and auditing of processing data + - Error Handling Framework: Consistent reporting and support of operational auditing + - Forensic Logging: to support auditing and reporting + - The team have worked to ensure that it is a community-adopted framework, so that future business process improvements can be run in parallel over this baseline, with a "home" for hub operator "need to know" reference manual documentation as a get started accelerator: + - RBAC: https://docs.mojaloop.io/mojaloop-business-docs/HubOperations/RBAC/Role-based-access-control.html + - Settlement: https://docs.mojaloop.io/mojaloop-business-docs/HubOperations/Settlement/settlement-management-introduction.html + - Participant Onboarding: https://docs.mojaloop.io/mojaloop-business-docs/HubOperations/Onboarding/business-onboarding.html + +*All contribution to improve process documentation is welcome, as in 2022 the roadmap will work to improve participant lifecycle management, settlement and merchant onboarding through a business process lens.* + +- **Make it Cost Effective for a new adopter to get Started** + - **A "get started" reference Hub UI** + - "Finance Portal 2.0" was recently contributed as this hub UI starting point by Modusbox, for those not wanting to integrate their own UI on day 1, and is in production for some adopters. + - We are an API-first product to allow the core to fit into multiple scenarios; however an optional get started hub UI has proved invaluable in demonstrating key processes to decision makers. + - The starting point for the UI is documented here: https://docs.mojaloop.io/mojaloop-business-docs/HubOperations/Portalv2/busops-portal-introduction.html + - **There is much that could be done in open source to further develop the UI. Any contributors welcome.** + + - **Payment Manager: A Tool to simplify DFSP integration work** : We are in the process of accepting a new contribution from Modusbox that make the integration process to a Mojaloop Hub in production for a DFSP much more seamless and efficient: https://rtplex.io/payment-manager-oss/ + +- **Core Hub is Modular & Extensible:** + - An architect-centred team have published the Mojaloop Reference architecture: https://mojaloop.github.io/reference-architecture-doc/ with a vision to ensuring that community growth is from a consistent base understanding of the solution. + - Not all elements of this reference are yet implemented, and **this will form the core of the technical roadmap future delivery work in 2022.** + +- **Consolidate & Productise what we have for Advocacy:** + - We have launched a sandbox to showcase our APIs and interaction with a simulated "model rural village" here: https://sandbox.mojaloop.io/ + - We ran some experiments around interoperability to last mile with CBDC technology alongside the MAS CBDC Global Hackathon participants: https://hackolosseum.apixplatform.com/hackathon/globalcbdcchallenge + - We were winners of an ISO20022 hackathon run by BIS showcasing ISO20022 and cross-border interoperability to last mile non-bank solutions: https://mojaloop.io/mojaloop-bis-iso20022-hackathon-submission/ + +**Keep Innovating with Valuable Extensions** +- Our 3PPI API (contributed by Google) is developed sufficiently for hackathon and market activity, and can be explored in detail in our sandbox. More information about its importance in bringing fintechs into the ecosystem more effectively can be seen here: https://mojaloop.io/webinar-what-pisp-means-for-inclusive-real-time-payments-systems/ +- We are exploring what valuable optional extensions to Mojaloop might support an effective accelerator for schemes around merchant ecosystems. The roadmap requires market validation, funding & community engagement to bring it to life. Here is our starting point hypothesis: [here](https://docs.google.com/presentation/d/1SoBgF5XGlsn2ZpO01DWoYUrirFQ_t0kYSLRHb2BOo8g/edit?usp=sharing) +- We are exploring with a "sister" open source FRMS project ensuring the right data is accessible from the Mojaloop solution for FRMS solutions: http://lextego.com/ + + +## 2022 Roadmap + +Here are some "big bets" we're currently thinking about in the community in 2022: + +- **One-Click Cloud Deploy:** A team from Microsoft are working to make it possible for a one-click-deploy for any potential adopter to get started on Microsoft Azure with a "vanilla" unconfigured hub sandbox in their own environment, based on the latest available release. +- **Google Pay Ready:** Our final push on the 3PPI engineering work contributed by Google will ensure that any fintechs using the Imali adapter (and Google Pay) have a swift way to get connected and transacting as a 3rd party. This will allow any Mojaloop-powered ecosystem to be able to launch an experience similar to that seen in India's UPI ecosystem. +- **ISO20022 Support:** ISO20022 is rapidly becoming the protocol of choice by banks, but it is not well known standard amongst Non-Banks - an incredibly important sector in emerging markets last mile services. Mojaloop want to ensure best practice use of ISO20022 for any adopters and will publish an accelerator for "greenfield" markets, as well as working software and adapters that make using it a simple scaled ask. +- **Cross Network Improvements:** Based on field learnings, we want to update the design to make Forex participants in a market "first class citizens" in the protocol, with robust timing management across the end to end protocol. This can lead to dynamic pricing and least cost realtime quotes becoming a reality whilst still supporting existing liqudity management models. +- **Settlement Batch Improvements:** In order to better support cross network models, settlement processing also needs some work. +- **vNext Build** - converting the existing codebase to the modular structure designed in the reference architecture. + +Each big bet has its own roadmap of what it is working on now, next and later. +This google doc holds a working space for the missions and current goals of the teams below: [Workstream Goals](https://docs.google.com/presentation/d/1CSNYZFD94qy4mh6baRPYLKYjo8N09baGQGxdZ424cWY/edit?usp=sharing) + +## How teams are structured around product improvement + +This framework is used to describe the various activites ongoing in the community. They are at different development stages from ideation to design to code development to maintenance mode. Some projects are on ice due to resourcing needs... all contributions welcome! + +**Core Clearing System Capabilities** + +1.1 Reference Architecture Completion & progression to BAU @ DA + +1.2 Improvement on v1 Hub: Supporting Services (“Business Operations Framework”) + - 1.2.1 Baseline RBAC Framework & out-of-the-box user profiles & user management + - 1.2.2 Improvement on Liquidity Monitoring & Settlement + - 1.2.3 Improvement on Participant Lifecycle Management: (Onboarding / Activating / Suspending / Terminating ) + - 1.2.4 Improvement on Reporting API + - 1.2.5 Improvement to the Reference UI + - 1.2.6 Scheme Rules Enforcement: Provide a framework to enforce, implement Scheme decisions + - 1.2.7 Automated Fees Calculation Improvements + - 1.2.8 Improvement to out-of-the-box Operational Moniitoring and Event Dashboards + +1.3 Improvement on v1 Hub - RTP Transfers Processing +- 1.3.1 Reliable Notifications to all Participants +- 1.3.2 Improved Cross-Network Timeouts +- 1.3.2 v1 Performance Improvement + +1.4 Best Practice National RTP ISO20022 Messaging +- at the hub +- at payment manager tool for DFSPs + +1.6 Deployments, Patches & Upgrades made Simple + +1.7 Deployments on Azure made Simple (Microsoft led) + +1.8 Provide Event Data to FRMS Solutions + +1.9 Deliver the Alpha release of vNext + + +**Core Clearing System Use Case Propositions, API Change & extensions into market:** + +2.1 Overlay Services (3PPI Enablement & 3rd party participant lifecycle management / adapters) + +2.2 Merchant Scheme Extension (inc ALS enhancement & QR Support) + - 2.2.1 A reference persistent Merchant Oracle & Merchant Blocklisting capability + +2.3 Bulk Payments Enhancement + + +**Adjacent tools & Marketplace:** + +3.1 Mojaloop Hosted OSS DFSP Support Tools: TTK + +3.2 Mojaloop Hosted OSS DFSP Support Tools: Payment Manager + +3.3 Mojaloop Hosted OSS DFSP Support Tools: SDKs + +3.4 Mojaloop Hosted OSS Hub Support Tools: Connection Manager + +3.5 Improvement on Reference UI (“Finance Portal 2.0”) + + + +**SUPPORTING Workstreams** + +4.1 Improve our “front of house”: API Documentation, Developer Portal, & Sandbox + +4.2 Ensure QA/UAT/Release Quality / Test Case Peer Review for Mission Critical Functionality + +4.3 Improve Hub Detailed Documentation for new adopters and contributors to hub software to get started more simply + +4.4 Add more Training Program content + diff --git a/website/versioned_docs/v1.0.1/community/standards/creating-new-features.md b/website/versioned_docs/v1.0.1/community/standards/creating-new-features.md new file mode 100644 index 000000000..a5a3ea3af --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/standards/creating-new-features.md @@ -0,0 +1,63 @@ +# Creating new Features + +### Fork + +Fork the Mojaloop repository into your own personal space. Ensure that you keep the `master` branch in sync. + +Refer to the following documentation for more information: [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/) + +1. Clone repo using Git Fork button \(refer to the above documentation for more information\) +2. Clone your forked repo: `git clone https://github.com//.git` +3. Synchronise your forked repo with Mojaloop + + Add a new upstream repo for Mojaloop `$ git remote add mojaloop https://github.com/mojaloop/.git` + + You should now see that you have two remotes: + + ```bash + git remote -v + origin https://github.com//.git (fetch) + origin https://github.com//.git (push) + mojaloop https://github.com/mojaloop/.git (fetch) + mojaloop https://github.com/mojaloop/.git (push) + ``` + +4. To sync to your current branch: `git pull mojaloop ` This will merge any changes from Mojaloop's repo into your forked repo. +5. Push the changes back to your remote fork: `git push origin ` + +### Creating a Branch + +Create a new branch from the `master` branch with the following format: `/` where `issue#` can be attained from the Github issue, and the `issueDescription` is the issue description formatted in CamelCase. + +1. Create and checkout the branch: `git checkout -b /` +2. Push the branch to your remote: `git push origin /` + +Where `` can be one of the following: + +| branchType | Description | +| :--- | :--- | +| feature | Any new or maintenance features that are in active development. | +| hotfix | A hotfix branch is for any urgent fixes. | +| release | A release branch containing a snapshot of a release. | +| backup | A temporary backup branch. Used normally during repo maintenance. | + +### Open a Pull Request (PR) + +Once your feature is ready for review, create a Pull Request from you feature branch back into the `master` branch on the Mojaloop Repository. If you're new to GitHub or Pull Requests, take a look at [this guide](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) for more information. + +#### Pull Request Titles + +Mojaloop uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to help our automated tooling manage releases and deployments. Your Pull Request title _must_conform to the conventional commits specification to pass the CI/CD checks in CircleCI. + +By adopting Conventional Commits + Semantic Versioning we can automatically release a new version for a given component and increment the `MAJOR`, `MINOR` and `BUGFIX` versions based soley on the PR titles, and auto generate rich changelogs. (See [this example](https://github.com/mojaloop/thirdparty-scheme-adapter/releases/tag/v11.20.0) of an auto generated changelog) + +> **Note**: +> When merging (and squashing) a PR, GitHub uses the _title_ of the PR for the git commit message. This means that to specify a breaking change, you must use the `!` format: +> "If included in the type/scope prefix, breaking changes MUST be indicated by a ! immediately before the :. If ! is used, BREAKING CHANGE: MAY be omitted from the footer section, and the commit description SHALL be used to describe the breaking change." + +**Examples of good PR titles** +- feat(api): add ability to handle `PUT /thirdpartyRequests/trasactions/{ID}` endpoint +- fix: update outdated node modules +- feat(models)!: change database schema +- chore: tidy up readme + diff --git a/website/versioned_docs/v1.0.1/community/standards/guide.md b/website/versioned_docs/v1.0.1/community/standards/guide.md new file mode 100644 index 000000000..ae839fe2d --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/standards/guide.md @@ -0,0 +1,355 @@ +# Standards + +> *Note:* These standards are by no means set in stone, and as a community, we always want to be iterating and improving Mojaloop. If you want to propose a change to these standards, or suggest further improvements, please reach out to the Design Authority Channel on the Mojaloop Slack (#design-authority) + +## Style Guide + +The Mojaloop Community provides a set of guidelines for the style of code we write. These standards help ensure that the Mojaloop codebase remains high quality, maintainable and consistent. + +These style guides are chosen because they can be easily enforced and checked using popular tools with minimal customisation. While we recognise that developers will have personal preferences that may conflict with these guidelines we favour consistency over [bike-shedding](https://en.wikipedia.org/wiki/Law_of_triviality) these rules. + +The goal of these guides is to ensure an easy developer workflow and reduce code commits that contain changes for the sake of style over content. By reducing the noise in diffs we make the job of reviewers easier. + +## Code Style + +### Javascript + +Mojaloop uses the Javascript code style dictated by [StandardJS](https://standardjs.com/). For a full set of rules, refer to the [Standard Rules](https://standardjs.com/rules.html), but as a brief set of highlights: + +- Use *2 spaces* for indentation + +```js +function helloWorld (name) { + console.log('hi', name) +} +``` + +- Use *single quotes* for strings except to avoid escaping. + +```js +console.log('hello there') // ✓ ok +console.log("hello there") // ✗ avoid +console.log(`hello there`) // ✗ avoid +``` + +- No semicolons. (see: 1, 2, 3) + +```js +window.alert('hi') // ✓ ok +window.alert('hi'); // ✗ avoid +``` + +### Typescript + +>*Note: Standard and Typescript* +> +>As we start to introduce more Typescript into the codebase, Standard becomes less useful, and can even be detrimental +>to our development workflow if we try to run standard across the Javascript compiled from Typescript. +>We need to evaluate other options for Standard in Typescript, such as a combination of Prettier + ESLint. + +Refer to the [template-typescript-public](https://github.com/mojaloop/template-typescript-public) for the standard typescript configuration. + + +### YAML + +While YAML deserializers can vary from one to another, we follow the following rules when writing YAML: +> Credit: these examples were taken from the [flathub style guide](https://github.com/flathub/flathub/wiki/YAML-Style-Guide) + +- 2 space indents +- Always indent child elements + +```yaml +# GOOD: +modules: + - name: foo + sources: + - type: bar + +# BAD: +modules: +- name: foo + sources: + - type: bar +``` + +- Do not align values + +```yaml +# BAD: +id: org.example.Foo +modules: + - name: foo + sources: + - type: git +``` +### sh + bash + +- The Shebang should respect the user's local environment: + +```bash +#!/usr/bin/env bash +``` + +This ensures that the script will match the `bash` that is defined in the user's environment, instead of hardcoding to a specific bash at `/usr/bin/bash`. + +- When referring to other files, don't use relative paths: + +This is because your script will likely break if somebody runs it from a different directory from where the script is located + +```bash +# BAD: +cat ../Dockerfile | wc -l + +# GOOD: +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cat ${DIR}/../Dockerfile | wc -l +``` + +For other recommended bash conventions, refer to this blog post: [Best Practices for Writing Shell Scripts](https://kvz.io/bash-best-practices.html) + +## Documentation + +- Documentation should be written in Mark Down format. +- All discussion documents should be placed in /community/archive/discussion-docs. +- The use of Google Docs and other tools should not be used. + +## Directory Structure + +Along with guidelines for coding styles, the Mojaloop Community recommends the following directory structure. This ensures that developers can easily switch from one project to another, and also ensures that our tools and configs (such as `.circleci/config.yml` and `Dockerfile`s) can be ported easily from one project to another with minor changes. + +The directory structure guide requires: + +```bash +├── package.json # at the root of the project +├── src # directory containing project source files +├── dist # directory containing compiled javascript files (see tsconfig below) +├── test # directory for tests, containing at least: +│  ├── unit # unit tests, matching the directory structure in `./src` +│  └── integration # integration tests, matching the directory structure in `./src` +└── config + └── default.json # RC config file +``` + +## Config Files + +The following Config files help to enforce the code styles outlined above: + + +### EditorConfig +> EditorConfig is supported out of the box in many IDEs and Text editors. For more information, refer to the [EditorConfig guide](https://editorconfig.org/). + +`.editorconfig` +```ini +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[{*.js,*.ts,package.json,*.yml,*.cjson}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false +``` + +### NYC (code coverage tool) + +`.nycrc.yml` +```yml +temp-directory: "./.nyc_output" +check-coverage: true +per-file: true +lines: 90 +statements: 90 +functions: 90 +branches: 90 +all: true +include: [ + "src/**/*.js" +] +reporter: [ + "lcov", + "text-summary" +] +exclude: [ + "**/node_modules/**", + '**/migrations/**' +] +``` + +### Typescript + +`.tsconfig.json` +```json +{ + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "lib", + "coverage" + ], + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": [ + "esnext" + ], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "outDir": "./dist", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "baseUrl": "./", + "paths": { + "*": [ + "src/*", + "node_modules/*" + ] + }, + "esModuleInterop": true + } +} +``` + +`.eslintrc.js` +```js +module.exports = { + parser: '@typescript-eslint/parser', // Specifies the ESLint parser + extends: [ + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier + 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. + // Enforces ES6+ import/export syntax + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', + ], + parserOptions: { + ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off' + }, + overrides: [ + { + // Disable some rules that we abuse in unit tests. + files: ['test/**/*.ts'], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + }, + }, + ], +}; +``` + +For a more detailed list of the recommended typescript configuration, including `package.json`, `jest.config.js` and more, refer to the [Typescript Template Project](https://github.com/mojaloop/template-typescript-public). + +## Design + Implementation Guidelines + +These guidelines are meant as recommendations for writing code in the Mojaloop community (or code that will be adopted into the community). If you are writing code that you wish to donate code to the community, we ask that you follow these guidelines as much as possible to aid with the consistency and maintainability of the codebase. Donations that adhere to these guidelines will be adopted more easily and swiftly. + +For more information, refer to the FAQ [below](#faqs). + +## Tools + Frameworks + +In the Mojaloop OSS Community, we are prefer the following tools and frameworks: + +- **Web Server:** [`HapiJS`](https://github.com/hapijs/hapi) +- **Web UI Framework:** [`ReactJS`](https://reactjs.org/) +- **Runtime Configuration:** [`rc`](https://www.npmjs.com/package/rc) (both from env variables and config files) +- **Package Management:** `npm` +- **Logging:** [`@mojaloop/central-services-logger`](https://github.com/mojaloop/central-services-logger#readme) library, built on top of Winston +- **Containers and Orchestration:** [`docker`](https://www.docker.com/) and [`kubernetes`](https://kubernetes.io/) +- **Unit Testing:** For existing tests, [`Tape`](https://github.com/substack/tape), but we are currently moving over to [`Jest`](https://jestjs.io/) for new codebases. +- **Test Coverage:** [`nyc`](https://github.com/istanbuljs/nyc) +- **CI:** [`CircleCI`](https://circleci.com/) + +By using these tools and frameworks, we maintain a high level of consistency and maintainability across the codebase, which keeps our developers productive and happy. While we don't mandate that donated codebases use these same tools and frameworks, we would like to stress that adoptions that use different tools could create an undue maintenance burden on the Community. + +## Adopting Open Source Contributions into Mojaloop + +This section provides guidelines regarding the adoption of a contribution to the Mojaloop Open Source repositories. Adoption is the process where we as the community work with a contributor to bring a contribution into alignment with our standards and guidelines to be a part of the Mojaloop OSS Codebase. + +>*Note:* Code Contributions are evaluated on a **case-by-case** basis. Contributions that don't align to these guidelines will need to go through the incubation phase as described below. Other misalignments to these standards (for example, framework choices) may be added to a roadmap for further improvement and OSS Standardization in the future. + +### Step 0: Prerequisites + +Before a contribution is to be considered for adoption, it: + +1. Should be in-line with the [Level One Project Principles](https://leveloneproject.org/). +1. Should adhere to the above Style and Design + Implementation Guides. +1. Should contain documentation to get started: the more, the better. +1. Contain tests with a high level of coverage. At a minimum, a contribution should contain unit tests, but a test suite with unit, integration and functional tests is preferred. Refer to the [contributors guide](./tools-and-technologies/automated-testing) for more information. + +### Step 1: Incubation + +1. Create a private repo within the Mojaloop GitHub organization for the adopted code. +1. Have a sub-team of the DA take a look to make sure its portable \(to OSS\) - aligns with L1P principles, etc, and ensure design is in line with standards. +1. Check Licensing of the contribution and any new dependencies it requires, and add the standard Mojaloop License with attribution to donor/contributors. +1. Assess the current state of the codebase, including documentation, tests, code quality, and address any shortfalls. +1. Assess Performance impact. +1. Create action items \(stories\) to update naming, remove/sanitize any items that are not generic +1. Inspect and discuss any framework and tooling choices. + - If a decision is made to make any changes, add them to the roadmap. + +### Step 2: Public Adoption + +1. Make the project public on Mojaloop GitHub. +1. Announce on the slack [`#announcements`](https://mojaloop.slack.com/archives/CG3MAJZ5J) channel. +1. Enable CI/CD Pipelines and publish any relevant artifacts, such as Docker Images or npm modules. +1. Review and recommend a module or course for the Mojaloop Training Program if needed and relevant for this contribution. + +## Versioning + +Review the information on [versioning](./versioning.md) for Mojaloop. + +## Creating new Features + +Process for creating new [features and branches](./creating-new-features.md) in Mojaloop. + +## Pull Request Process + +It's a good idea to ask about major changes on [Slack](https://mojaloop.slack.com). Submit pull requests which include both the change and the reason for the change. Feel free to use GitHub's "Draft Pull Request" feature to open up your changes for comments and review from the community. + +Pull requests will be denied if they violate the [Level One Principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf). + +## Code of conduct + +We use the [Mojaloop Foundation Code of Conduct](https://github.com/mojaloop/mojaloop/blob/master/CODE_OF_CONDUCT.md) + +## Licensing + +See [License](https://github.com/mojaloop/mojaloop/blob/master/contribute/License.md) policy. + +## FAQs + +__1. What if I want to contribute code, but it doesn't align with the code style and framework/tool recommendations in this guide?__ + +Contributions are accepted on a _case by case_ basis. If your contribution is not yet ready to be fully adopted, we can go through the incubation phase described above, where the code is refactored with our help and brought into alignment with the code and documentation requirements. + + +__2. These standards are outdated, and a newer, cooler tool (or framework, method or language) has come along that will solve problem _x_ for us. How can I update the standards?__ + +Writing high quality, functional code is a moving target, and we always want to be on the lookout for new tools that will improve the Mojaloop OSS codebase. So please talk to us in the design authority slack channel (`#design-authority`) if you have a recommendation. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/standards/triaging-bugs.md b/website/versioned_docs/v1.0.1/community/standards/triaging-bugs.md new file mode 100644 index 000000000..92d140af8 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/standards/triaging-bugs.md @@ -0,0 +1,33 @@ +# Triaging Mojaloop OSS bugs + +### Raising a bug / issue + +If there is a bug or issue in general an issue is logged as a bug or feature request on the [project](https://github.com/mojaloop/project/issues/new/choose) repository and in some cases linked to an issue logged on the repository for that specific component. + +There is a bug [template](https://github.com/mojaloop/project/issues/new?assignees=&labels=bug&template=bug_report.md&title=) that can be used and encourages use of details such as versions, expected results and other details, which help with triage and reproducing the issue. + +### Once a bug is logged + +1. Typically, the bug is initially triaged in the [#ml-oss-bug-triage](https://mojaloop.slack.com/messages/CMCVBHPUH) public channel on Mojaloop Slack +2. For Security and other sensitive issues, the bug is triaged on a private channel with current contributors, before information is made public at an appropriate time. +3. During bug triage, priority and severity are assigned to the bug after majority consensus usually +4. Based on the priority and severity the bug is taken up by the Core team or other contributors based on a collaborative effort. +5. Once it is taken up, conversation and updates happen on the slack channl, but mostly on the issue itself. + +### Triage + +1. The discussion regarding the issue is open to a public for normal bugs / issues +2. However, to start with, the voting rights are given to current contributors and stakeholders. +3. Based on the discussions, a final call on the priority and severity of the issue is made by the Program Manager. +4. If you think you need a vote, please reach out to Kim or Sam. +5. Here are the voting members [14] for triaging bugs to start with. + 1. Kim Walters + 1. Lewis Daly + 1. Miguel deBarros + 1. Sam Kummary + 1. Sri Miryala + 1. Warren Carew + 1. Vijay Guthi + 1. Valentin Genev + 1. Shashi Hirugade +6. The list and the process will be updated as it evolves, this is a proposal to start with do a Pilot on. diff --git a/website/versioned_docs/v1.0.1/community/standards/versioning.md b/website/versioned_docs/v1.0.1/community/standards/versioning.md new file mode 100644 index 000000000..d8d759985 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/standards/versioning.md @@ -0,0 +1,126 @@ +# Versioning + +## Versioning of releases made for core Switch services + +This document provides guidelines regarding the versioning strategy used for the releases of Mojaloop Open Source repositories corresponding to the Switch services. + +### Versioning Strategy + + +#### Standard for PI-11 and beyond +1. Starting PI-11 (27th July, 2020) the Versioning guidance is to move to a versioning system that is closely aligned with Semantic versioning by removing the PI/Sprint dependency. So starting 11.x.x, the proposal is to move to pure [SemVer](https://semver.org/). +2. At a high-level, we will still follow the vX.Y.Z format, but X represents ‘Major’ version, Y represents ‘Minor’ version and Z represents ‘patch’ version. Minor fixes, patches affect increments to ‘Z’, whereas non-breaking functionality changes affect changes to ‘Y; breaking changes affect the ‘X’ version. +3. Along with these, suffixes such as “-snapshot”, “-patch”, “-hotfix” are used as relevant and on need basis (supported by CI config). +4. So starting with 11.0.0 (primarily for Helm, but for individual services as well) for PI-11, the proposal is to move to pure [SemVer](https://semver.org/). +5. This implies that for any new release of a package/service below X=11 (for existing repositories and not new ones) will first be baselined to v11.0.0 and from then on follow standard SemVer guidelines as discussed above. For new projects or repositories, versioning can start from v1.0.0 (after they reach release status) + + +#### Versioning Strategy used until PI-10 +1. The Mojaloop (up to PI-10) versioning system is inspired by the [Semantic Versioning](https://semver.org/) numbering system for releases. +2. However, this is customized to depict the timelines of the Mojaloop project, based on the Program Increment \(PI\) and Sprint numbers +3. For example, the release number v5.1.0 implies that this release was the first one made during a Sprint 5.1, where Sprint5.1 is the first Sprint in PI-5. So for a version vX.Y.Z, X.Y is the Sprint number where X is the PI number and Z represents the number of release for this specific repository. Example v4.4.4 implies that the current release is the fourth of four releases made in Sprint 4.4 \(of PI-4\) + + + +### Current Version + +The currrent version information for Mojaloop can be found [here](../../deployment-guide/releases.md). + +### Sprint schedule for PI-13 + +Below is the Sprint schedule for Program Increment 13 which ends with the PI-14 Community event in April 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-5 Kick-off On-site**|1/25/2021|1/29/2021|5 days| Virtual Zoom Webinars| +|**Sprint 13.1**|02/01/2021|02/14/2021|2 weeks | | +|**Sprint 13.2**|02/15/2021|02/28/2021|2 weeks | | +|**Sprint 13.3**|03/01/2021|03/14/2021|2 weeks | | +|**Sprint 13.4**|03/15/2021|03/28/2021|2 weeks | | +|**Sprint 13.5**|03/29/2021|04/11/2021|2 weeks | | +|**Sprint 13.6**|04/12/2021|04/25/2021|2 weeks | | +|**Phase-5 PI-14**|04/26/2021|04/30/2021|5 days| Virtual meetings | + +### Sprint schedule for PI-12 + +Below is the Sprint schedule for Program Increment 12 which ends with the PI-13 Community event in January 2021. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars| +|**Phase-4 PI-12 Virtual**|10/19/2020|10/23/2020|5 days| Virtual Zoom Webinars| +|**Sprint 12.1**|10/26/2020|11/15/2020|3 weeks | | +|**Sprint 12.2**|11/16/2020|11/29/2020|2 weeks | | +|**Sprint 12.3**|11/30/2020|12/13/2020|2 weeks | | +|**Sprint 12.4**|12/14/2020|12/27/2020|2 weeks | | +|**Sprint 12.5**|12/28/2020|01/10/2021|2 weeks | | +|**Sprint 12.6**|01/11/2020|01/24/2020|2 weeks | | +|**Phase-5 Kick-off / PI-13**|01/25/2021|01/29/2021|5 days| TBD | + +### Previous Sprint Schedules: + +### Sprint schedule for PI-11 + +Below is the Sprint schedule for Program Increment 11 which ends with the PI 12 Event. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI-10 Virtual**|4/21/2020|4/24/2020|4 days| Virtual Zoom Webinars | +|**Phase-4 PI-11 Virtual**|7/21/2020|7/24/2020|4 days| Virtual Zoom Webinars | +|**Sprint 11.1**|7/27/2020|8/9/2020|2 weeks| | +|**Sprint 11.2**|8/10/2020|8/23/2020|2 weeks| | +|**Sprint 11.3**|8/24/2020|9/6/2020|2 weeks| | +|**Sprint 11.4**|9/7/2020|9/20/2020|2 weeks| | +|**Sprint 11.5**|9/21/2020|10/4/2020|2 weeks| | +|**Sprint 11.6**|10/5/2020|10/18/2020|2 weeks | | +|**Phase-4 PI-12**|10/20/2020|10/23/2020|4 days| TBD | + +#### Sprint schedule for PI-10 + +Below is the Sprint schedule for Program Increment 10 which ends with the PI 11 Event. Please use this as guidance during the versioning and release processes. + +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Phase-3 PI6 On-site**|4/16/2019|4/18/2019|3 days| Johannesburg| +|**Phase-3 PI7 On-site**|6/25/2019|6/27/2019|3 days| Arusha| +|**Phase-3 PI8 On-site**|9/10/2019|9/12/2019|3 days| Abidjan| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| +|**Phase-4 PI 10 Virtual**|4/21/2020|4/24/2020|5 days| Virtual Zoom Webinars | +|**Sprint 10.1**|4/27/2020|5/10/2020|2 weeks| | +|**Sprint 10.2**|5/11/2020|5/24/2020|2 weeks| | +|**Sprint 10.3**|5/25/2020|6/7/2020|2 weeks| | +|**Sprint 10.4**|6/8/2020|6/21/2020|2 weeks| | +|**Sprint 10.5**|6/22/2020|7/5/2020|2 weeks| | +|**Sprint 10.6**|7/6/2020|7/19/2020|2 weeks | | +|**Phase-4 PI 11 On-Site**|7/21/2020|7/23/2020|3 days| Kenya (Tentative) | + +#### PI-9 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 9.1**|2/3/2020|2/16/2020|2 weeks| | +|**Sprint 9.2**|2/17/2020|3/1/2020|2 weeks| | +|**Sprint 9.3**|3/2/2020|3/15/2020|2 weeks| | +|**Sprint 9.4**|3/16/2020|3/29/2020|2 weeks| | +|**Sprint 9.5**|3/30/2020|4/12/2020|2 weeks| | +|**Sprint 9.6**|3/13/2020|4/19/2020|1 week | | +|**Phase-4 PI 10 Virtual**|4/21/2020|4/23/2020|5 days| Virtual Zoom Webinars | + +#### PI-8 +|Phase/Milestone|Start|End|Weeks|Notes| +|---|---|---|---|---| +|**Sprint 8.1**|9/16/2019|9/29/2019|2 weeks| | +|**Sprint 8.2**|9/30/2019|10/13/2019|2 weeks| | +|**Sprint 8.3**|10/14/2019|10/27/2019|2 weeks| | +|**Sprint 8.4**|10/28/2019|11/10/2019|2 weeks| | +|**Sprint 8.5**|11/11/2019|11/24/2019|2 weeks| | +|**Sprint 8.6**|11/25/2019|12/8/2019|2 weeks| | +|**Sprint 8.7**|12/9/2019|1/5/2020|4 weeks| Christmas Break| +|**Sprint 8.8**|1/6/2020|1/26/2020|3 weeks| 1 week prep| +|**Phase-4 Kick-off On-site**|1/28/2020|1/30/2020|3 days| Johannesburg| + +### Notes + +1. A new release for **helm** repo is made based on the feature and configuration changes made to core services and requirements from thhe Community. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_master.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_master.png new file mode 100644 index 000000000..331087be4 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_master.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_pr.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_pr.png new file mode 100644 index 000000000..1a64f791f Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_pr.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_tag.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_tag.png new file mode 100644 index 000000000..13af7e59c Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_lib_tag.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_master.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_master.png new file mode 100644 index 000000000..6ab54d9d9 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_master.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_pr.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_pr.png new file mode 100644 index 000000000..389f5ccba Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_pr.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_tag.png b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_tag.png new file mode 100644 index 000000000..934aee684 Binary files /dev/null and b/website/versioned_docs/v1.0.1/community/tools/assets/images/ci_cd_svc_tag.png differ diff --git a/website/versioned_docs/v1.0.1/community/tools/automated-testing.md b/website/versioned_docs/v1.0.1/community/tools/automated-testing.md new file mode 100644 index 000000000..fad1f9eaf --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/tools/automated-testing.md @@ -0,0 +1,144 @@ +# QA and Regression Testing in Mojaloop +An overview of the testing framework set up in Mojaloop + +Contents: +1. [Regression requirements](#regression-topics) +2. [Developer Testing](#developer-testing) +3. [Postman and Newman Testing](#postman-and-newman-testing) +4. [Executing regression test](#executing-regression-test) +5. [Process flow of a typical Scheduled Test](#process-flow-of-a-typical-scheduled-test) +6. [Newman Commands](#newman-commands) + +## Regression Topics + In order for a deployed system to be robust, one of the last checkpoints is to determine if the environment it is deployed in, is in a healthy state and all exposed functionality works exactly the way as intended. + + Prior to that though, there are quite a number of disciplines one must put in place to ensure maximum control. + + To illustrate how the Mojaloop project reaches this goal, we are going to show you the various checkpoints put in place. + +### Developer Testing + Looking at each component and module, inside the code base, you will find a folder named "*test*" which contain three types of tests. + + Firstly, the *coverage test* which alerts one if there are unreachable or redundant code + + Unit Tests, which determines if the intended functionality works as expected + + Integration Tests, which does not test end-to-end functionality, but the immediate neighbouring interaction + + Automated code-standard checks implemented by means of packages that form part of the code base + + These tests are executed by running the command line instructions, by the developer, during the coding process. Also, the tests are automatically executed every time a *check-in* is done and a Github Pull-Request issued for the code to be integrated into the project. + + The procedure described above, falls outside the realm of Quality Assurance (QA) and Regression testing, which this document addresses. + + Once a developer has written new functionality or extended existing functionality, by having to go through the above rigorous tests, one can assume the functionality in question is executing as intended. How does one then ensure that this new portion of code does not negatively affect the project or product as a whole? + + When the code has passed all of the above and is deployed as part of the CI/CD processes implemented by our workflow, the new component(s) are accepted onto the various hosts, cloud-based or on-premise implementations. These hosts ranges from development platforms through to production environments. + +### Postman and Newman Testing + Parallel to the deployment process is the upkeep and maintenance of the [Postman](https://github.com/mojaloop/postman.git "Postman") Collection testing Framework. When a new release is done, as part of the workflow, Release Notes are published listing all of the new and/or enhanced functionality implemented as part of the release. These notes are used by the QA team to extend and enhance the existing Postman Collections where tests are written behind the request/response scripts to test both positive as well as negative scenarios agains the intended behaviour. These tests are then run in the following manner: + + Manually to determine if the tests cover all aspects and angles of the functionality, positive to assert intended behaviour and negative tests to determine if the correct alternate flows work as intended when something unexpected goes wrong + + Scheduled - as part of the Regression regime, to do exactly the same as the manual intent, but fully automated (with the *Newman Package*) with reports and logs produced to highlight any unintended behaviour and to also warn where known behaviour changed from a previous run. + +In order to facilitate the automated and scheduled testing of a Postman Collection, there are various methods one can follow and the one implemented for Mojaloop use is explained further down in this document. + +There is a complete repository containing all of the scripts, setup procedures and anything required in order to set up an automated [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"). This framework allows one to target any Postman Collection, specifying your intended Environment to execute against, as well as a comma-separated list of intended email recipients to receive the generated report. This framework is in daily use by Mojaloop and exists on an EC2 instance on AWS, hosting the required components like Node, Docker, Email Server and Newman, as well as various Bash Scripts and Templates for use by the framework to automatically run the intended collections every day. Using this guide will allow anyone to set up their own Framework. + +#### Postman Collections + +There are a number of Postman collections in use throughout the different processes: + +For Mojaloop Simulator: + ++ [MojaloopHub_Setup](https://github.com/mojaloop/postman/blob/master/MojaloopHub_Setup.postman_collection.json) : This collection needs to be executed once after a new deployment, normally by the Release Manager. It sets up an empty Mojaloop hub, including things such as the Hub's currency, the settlement accounts. ++ [MojaloopSims_Onboarding](https://github.com/mojaloop/postman/blob/master/MojaloopSims_Onboarding.postman_collection.json) : MojaloopSims_Onboarding sets up the DFSP simulators, and configures things such as the endpoint urls so that the Mojaloop hub knows where to send request callbacks. ++ [Golden_Path_Mojaloop](https://github.com/mojaloop/postman/blob/master/Golden_Path_Mojaloop.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + + Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. ++ [Bulk_API_Transfers_MojaSims](https://github.com/mojaloop/postman/blob/master/Bulk_API_Transfers_MojaSims.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Mojaloop Simulator. + +For Legacy Simulator (encouraged to use Mojaloop Simulator, as this will not be supported starting PI-12 (Oct 2020) ): + ++ [ML_OSS_Setup_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Setup_LegacySim.postman_collection.json) : This collection needs to be executed once after a new deployment (if it uses Legacy Simulator), normally by the Release Manager. It sets up the Mojaloop hub, including things such as the Hub's currency, the settlement accounts along with the Legacy Simulator(s) as FSP(s). ++ [ML_OSS_Golden_Path_LegacySim](https://github.com/mojaloop/postman/blob/master/ML_OSS_Golden_Path_LegacySim.postman_collection.json) : The Golden_Path_Mojaloop collection is an end-to-end regression test pack which does a complete test of all the deployed functionality. This test can be run manually but is actually designed to be run from the start, in an automated fashion, right through to the end, as response values are being passed from one request to the next. (The core team uses this set to validate various releases and deployments) + + Notes: In some cases, there is need for a delay of `250ms` - `500ms` if executed through Postman UI Test Runner. This will ensure that tests have enough time to validate requests against the simulator. However, this is not always required. ++ [Bulk API Transfers.postman_collection](https://github.com/mojaloop/postman/blob/master/Bulk%20API%20Transfers.postman_collection.json) : This collection can be used test the bulk transfers functionality that targets Legacy Simulator. + +#### Environment Configuration + +You will need to customize the following environment config file to match your deployment environment: ++ [Local Environment Config](https://github.com/mojaloop/postman/blob/master/environments/Mojaloop-Local.postman_environment.json) + +_Tips:_ +- _The host configurations will be the most likely changes required to match your environment. e.g. `HOST_CENTRAL_LEDGER: http://central-ledger.local`_ +- _Refer to the ingress hosts that have been configured in your `values.yaml` as part of your Helm deployment._ + +### Executing regression test +For the Mojaloop QA and Regression Testing Framework specifically, Postman regression test can be executed by going into the EC2 instance via SSH, for which you need the PEM file, and then by running a script(s). + +Following the requirements and instructions as set out in the detail in [QA and Regression Testing Framework](https://github.com/mojaloop/ml-qa-regression-testing.git "QA and Regression Testing Framework"), everyone will be able to create their own Framework and gain access to their instance to execute tests against any Postman Collection targeting any Environment they have control over. + +##### Steps to execute the script via Postman UI ++ Import the desired collection into your Postman UI. You can either download the collection from the repo or alternatively use the `RAW` link and import it directly via the **import link** option. ++ Import the environment config into your Postman UI via the Environmental Config setup. Note that you will need to download the environmental config to your machine and customize it to your environment. ++ Ensure that you have pre-loaded all prerequisite test data before executing transactions (party, quotes, transfers) as per the example collection [OSS-New-Deployment-FSP-Setup](https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json): + + Hub Accounts + + FSP onboarding + + Add any test data to Simulator (if applicable) + + Oracle onboarding ++ The `p2p_money_transfer` test cases from the [Golden_Path](https://github.com/mojaloop/postman/blob/master/Golden_Path.postman_collection.json) collection are a good place to start. + +##### Steps to execute the bash script to run the Newman / Postman test via CLI ++ To run a test via this method, you will have to be in posession of the PEM-file of the server on which the Mojaloop QA and Regression Framework was deployed on an EC2 instance on Amazon Cloud. + ++ SSH into the specific EC2 instance and when running the script, it will in turn run the commands via an instantiated Docker container. + ++ You will notice that by using this approach where both the URLs for the Postman-Collection and Environment File are required as input parameters (together with a comma-delimited email recipient list for the report) you have total freedom of executing any Postman Collection you choose. + ++ Also, by having an Environment File, the specific Mojaloop services targeted can be on any server. This means you can execute any Postman test against any Mojaloop installation on any server of your choice. + ++ The EC2 instance we execute these tests from are merely containing all the tools and processes in order to execute your required test and does not host any Mojaloop Services as such. + +``` +./testMojaloop.sh +``` + +## Process flow of a typical Scheduled Test + +{% uml src="contributors-guide/tools-and-technologies/assets/diagrams/automated-testing/QARegressionTestingMojaloop-Complete.plantuml" %} +{% enduml %} + +## Newman Commands +The following section is a reference, obtained from the Newman Package site itself, highlighting the different commands that may be used in order to have access to the Postman environment by specifying some commands via the CLI. +``` +Example: ++ newman run -e -n 1 -- + +Usage: run [options] + + URL or path to a Postman Collection. + + Options: + + -e, --environment Specify a URL or Path to a Postman Environment. + -g, --globals Specify a URL or Path to a file containing Postman Globals. + --folder Specify folder to run from a collection. Can be specified multiple times to run multiple folders (default: ) + -r, --reporters [reporters] Specify the reporters to use for this run. (default: cli) + -n, --iteration-count Define the number of iterations to run. + -d, --iteration-data Specify a data file to use for iterations (either json or csv). + --export-environment Exports the environment to a file after completing the run. + --export-globals Specify an output file to dump Globals before exiting. + --export-collection Specify an output file to save the executed collection + --postman-api-key API Key used to load the resources from the Postman API. + --delay-request [n] Specify the extent of delay between requests (milliseconds) (default: 0) + --bail [modifiers] Specify whether or not to gracefully stop a collection run on encountering an errorand whether to end the run with an error based on the optional modifier. + -x , --suppress-exit-code Specify whether or not to override the default exit code for the current run. + --silent Prevents newman from showing output to CLI. + --disable-unicode Forces unicode compliant symbols to be replaced by their plain text equivalents + --global-var Allows the specification of global variables via the command line, in a key=value format (default: ) + --color Enable/Disable colored output. (auto|on|off) (default: auto) + --timeout [n] Specify a timeout for collection run (in milliseconds) (default: 0) + --timeout-request [n] Specify a timeout for requests (in milliseconds). (default: 0) + --timeout-script [n] Specify a timeout for script (in milliseconds). (default: 0) + --ignore-redirects If present, Newman will not follow HTTP Redirects. + -k, --insecure Disables SSL validations. + --ssl-client-cert Specify the path to the Client SSL certificate. Supports .cert and .pfx files. + --ssl-client-key Specify the path to the Client SSL key (not needed for .pfx files) + --ssl-client-passphrase Specify the Client SSL passphrase (optional, needed for passphrase protected keys). + -h, --help output usage information +``` \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/tools/ci_cd_pipelines.md b/website/versioned_docs/v1.0.1/community/tools/ci_cd_pipelines.md new file mode 100644 index 000000000..d0b25a50c --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/tools/ci_cd_pipelines.md @@ -0,0 +1,127 @@ +# CI/CD Pipelines + +The Mojaloop Community uses [CircleCI](https://circleci.com/) to automatically build, test and deploy our +software. This document describes how we use CI/CD in Mojaloop, the different checks we perform on the +software, and how we distribute the software. + +Broadly speaking, there are 2 types of workflow we use, depending on the type of project: +- Library: build node project -> test -> publish to [npm](https://www.npmjs.com/search?q=%40mojaloop) +- Service: build docker image -> test -> publish to [Docker Hub](https://hub.docker.com/u/mojaloop) + +Additionally, we also maintain a set of [Mojaloop Helm Charts](http://docs.mojaloop.io/helm/), which are +built from the [mojaloop/helm](https://github.com/mojaloop/helm) + +## Libraries + +> For a good example of this CI/CD pattern see [central-services-shared](https://github.com/mojaloop/central-services-shared/blob/master/.circleci/config.yml) + +### Pull Request (PR) Flow: + +The PR flow runs on pull requests, and during the [PR review process](https://github.com/mojaloop/documentation/blob/master/contributors-guide/standards/creating-new-features.md#creating-new-features), these checks must be satisfied +for the code to be merged in. + +![](./assets/images/ci_cd_lib_pr.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | Checks that the PR title conforms to the conventional commits specification | Defined in a CircleCI orb here: [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Runs the unit-tests and checks that code coverage is above the specified limit. | Typically this is 90% | +| test-unit | Runs the unit-tests. Fails if any unit test fails. | | +| vulnerability-check | Runs the `npm audit` tool to search for any vulnerabilities in dependencies | `npm audit` is full of false positives, or security issues that don't apply to our codebase. We use `npm-audit-resolver` to give us flexibility over vulnerabilities that may be ignored, e.g `devDependencies` | +| audit-licenses | Runs the mojaloop `license-scanner-tool` and fails if any license found doesn't match an allowlist specified in the `license-scanner-tool` | [license-scanner-tool repo](https://github.com/mojaloop/license-scanner-tool) | + + +### Master and Release Flow: + +This CI/CD pipeline runs on the master/main branch: + +![](./assets/images/ci_cd_lib_master.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| release | Runs a release which creates a git tag and pushes the git tag | | +| github-release | Adds the release metadata (e.g. changelog) to github, sends a slack alert to #announcements | | + + +### Tag Flow: + +Once a git tag is pushed to the repository, it triggers a workflow that ends +in publishing to `npm`. Importantly, the checks are all run again, to ensure +nothing has changed (e.g. dependencies) inbetween the main/master and the actual +artefact that is published to `npm`. + +![](./assets/images/ci_cd_lib_tag.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| publish | Publishes the latest version of the library based on the git tag | | + + +## Services + +> For a good example of this CI/CD pattern see [central-ledger](https://github.com/mojaloop/central-ledger/blob/master/.circleci/config.yml) + +### Pull Request (PR) Flow: + +The PR flow runs on pull requests, and during the PR review process, these checks must be satisfied +for the code to be merged in. + +![](./assets/images/ci_cd_svc_pr.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | Checks that the PR title conforms to the conventional commits specification | Defined in a CircleCI orb here: [mojaloop/ci-config](https://github.com/mojaloop/ci-config) | +| test-coverage | Runs the unit-tests and checks that code coverage is above the specified limit. | Typically this is 90% | +| test-unit | Runs the unit-tests. Fails if any unit test fails. | | +| test-integration | Runs the integration-tests. Typically by building a docker image locally | | +| vulnerability-check | Runs the `npm audit` tool to search for any vulnerabilities in dependencies | `npm audit` is full of false positives, or security issues that don't apply to our codebase. We use `npm-audit-resolver` to give us flexibility over vulnerabilities that may be ignored, e.g `devDependencies` | +| audit-licenses | Runs the mojaloop `license-scanner-tool` and fails if any license found doesn't match an allowlist specified in the `license-scanner-tool` | [license-scanner-tool repo](https://github.com/mojaloop/license-scanner-tool) | + + +### Master and Release Flow: + +This CI/CD pipeline runs on the master/main branch: + +![](./assets/images/ci_cd_svc_master.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| test-integration | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| release | Runs a release which creates a git tag and pushes the git tag | | +| github-release | Adds the release metadata (e.g. changelog) to github, sends a slack alert to #announcements | | + + +### Tag Flow: + +Once a git tag is pushed to the repository, it triggers a workflow that ends +in publishing a docker image to Docker Hub. Importantly, the checks are all run again, +and further scans are made on the docker image before the image is pushed. + +![](./assets/images/ci_cd_svc_tag.png) + +| Step | Description | More Info | +| --- | ----------- | --------- | +| pr-title-check | See above | | +| test-coverage | See above | | +| test-unit | See above | | +| vulnerability-check | See above | | +| audit-licenses | See above | | +| build | Builds the docker image | | +| image-scan | Runs `anchore/analyze_local_image` to scan the image | See [anchore-engine](https://circleci.com/developer/orbs/orb/anchore/anchore-engine) CircleCI Orb for more information. | +| license-scan | Runs the mojaloop `license-scanner-tool` on the licenses contained in the docker image | | +| publish | Publishes the latest version of the library based on the git tag | | diff --git a/website/versioned_docs/v1.0.1/community/tools/code-quality-metrics.md b/website/versioned_docs/v1.0.1/community/tools/code-quality-metrics.md new file mode 100644 index 000000000..f155be68f --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/tools/code-quality-metrics.md @@ -0,0 +1,30 @@ +# Code Quality Metrics + +## Functional quality metrics + +### Unit test metrics + +High coverage and low dependencies show that the code is testable and therefore well isolated and easy to maintain. Low complexity also makes code readable and maintainable and helps enforce single responsibility. Real unit tests run very fast as they don't call external components. + +| Code Quality Metrics | New and Project Code | +| :--- | :--- | +| Unit test coverage | >= 80% block coverage | +| Unit test speed | <= 10 seconds | +| Dependencies/method | <= 10 | +| Complexity/method | <= 7 | + +### Component + +Functional testing typically covers pair combinations of the system states. + +### Integration + +Functional tests have one test per message and error. Messages and errors that are handled the same way use the same test. + +### Contract + +Limited to what the consuming teams need that isn't covered by existing unit, component, and integration tests. Often added to over time. + +### End to End + +End to end tests cover acceptance tests from scenarios. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/tools/pragmatic-rest.md b/website/versioned_docs/v1.0.1/community/tools/pragmatic-rest.md new file mode 100644 index 000000000..bb7db5ef3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/tools/pragmatic-rest.md @@ -0,0 +1,129 @@ +# Pragmatic REST + +## Pragmatic REST For the Mojaloop Project + +With the emergence of API strategy as a scaling tool for Internet service businesses, the focus on interconnect technology has shifted. Building on the principles that enabled the Web to form and scale, REST \(Representational State Transfer\) has become a design preference for Internet service APIs. But while the REST principles, proposed in Roy Fielding's dissertation that defined them, have academic value as a basis for research, a pure REST design is not at present practical for most applications. We are advocating a kind of Pragmatic REST-a design pattern that adopts the beneficial components of RESTful design without requiring strict adherence to academic purity. + +### The Richardson Maturity Model + +Martin Fowler has referenced a structured model of RESTful adoption developed by Leonard Richardson and [explained](http://www.crummy.com/writing/speaking/2008-QCon/act3.html) at a QCon talk. Fowler refers to this as the Richardson Maturity Model of RESTful design. + + + +Martin Fowler, referencing [Rest in Practice](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829),2 summarizes the genesis of RESTful design: + +> use Restful web services to handle many of the integration problems that enterprises face. At its heart . . . is the notion that the web is an existence proof of a massively scalable distributed system that works really well, and we can take ideas from that to build integrated systems more easily. + +A pragmatic approach to RESTful design uses the best parts of Fielding's conceptual framework to allow developers and integrators to understand what they can do with the API as rapidly as possible and without writing extraneous code. + +At its most fundamental, a RESTful design is resource-centric and uses HTTP verbs. At its most advanced, a design that follows pure academic REST utilizes the HATEOAS principle by implementing Hypermedia Controls. We are advocating a Level 2 RESTful design for Mojaloop. + +### Why not Hypermedia Controls? + +Although HATEOAS is a fascinating principle-it advocates that a server should respond to each client action with a list of all possible actions that can lead the client to its next application state. And further, clients _must not_ rely on out of band information \(like a written API spec\) for what actions can be performed on which resources or on the format of URIs. + +It is this final proscription that fails the test of Pragmatic REST: While HATEOAS is an interesting theoretical approach to limit coupling, it does not easily apply to Mojaloop \(or any other contract API design\). When we take into account our audience for the interconnect APIs, we find a group of commercial entities that will be operating under a set of highly specific scheme rules. Interactions between the participants, and between participant and central service hub, will be highly specified to assign acceptable commercial risk that can be priced at very low cost to end-users. This requires _ex-ante_ predictability of the API which is anathema to the HATEOAS principle defined by Fielding. + +### Pragmatic RESTful Principles + +#### URIs Define Resources + +A well-designed URI pattern makes an API easy to consume, discover, and extend, just as a carefully designed API does in a traditional programming language. Pure REST disdains this principle in favor of HATEOAS. But pragmatic REST follows a normal pattern for URI definitions to improve human understanding, even if HATEOAS principles are employed for discovery. + +URI paths that refer to a collection of objects should consist of a plural noun, e.g. /customers, to refer to a set of customers. When a collection can have only one instance, the singular noun should be used to avoid confusion. E.g. GET /transfers/:id/fulfillment is correct, since there is only one fulfillment object per identified transfer. + +URI paths that refer to a single object should consist of a plural noun \(representing the collection\), followed by a predefined unique identifier. E.g., /customers/123456 to refer to the specific customer with number 123456. The identifier must be unique within the containing collection and persist for the life of the object within that collection. IDs must not be ordinal values-ordinal retrieval of objects from a collection is possible using query parameters on the collection URI. + +URI paths may have a prefix to identify the environment, version, or other context of the resource. Nothing should follow the identifying path but collections and object references. + +URI path and query segment identifiers should be chosen from the Roman character set, \[0-9A-Za-z\]. Use _camelCase_ to define the elements of the URI path. Do not use snake\_case. + +For the avoidance of doubt, "\_" \(underscore\) and "-" \(hyphen\) should not be used in URI path or query segment identifiers. + +This probably seems a bit parochial. The purpose is to find a well-defined URI format that is consistent with wide-spread practice, easy to define, predictable, and that maps to native environments and conventions. It isn't going to satisfy everyone. Here is reasoning behind this constraint: + +CapitalCase and camelCase are the defacto standard for NodeJS and JavaScript and are a common constraint in URI definition: URI path segments are often mapped to JS internal resources and so conforming to JS naming conventions makes sense. + +Field names in JSON and SQL should also follow this convention since they are often automatically mapped into variable name space and can be referenced in URIs as path or query segment identifiers. + +We should also avoid the use of "$" unless it is required by a library \(e.g. JQuery\). IBM JCL has passed away; let it rest in peace. There are better scope control tools to separate name spaces than introducing non-roman symbols. + +We should avoid "-" \(hyphen\) in path segment and query parameter names as it does not map into variable names, SQL, or JSON field name identifiers. + +Underscore characters must be escaped in markdown source by prefixing each with a "\" character. + +Snake\_case has been reported to be slightly easier to read than camelCase in variable names, but it actually does not improve readability of URIs, as it visually interferes with path and query segment delimiters making it difficult to visually parse them. And when URIs are underlined in presentation, the underscores become illegible. + +#### URI Parameters + +Use a standard and predictable set of optional parameters in a consistent way. + +A set of standard query parameters should be used for collections to enable caller control over how much of the collection they see. E.g. "count" to determine how many objects to return, "start" to determine where to start counting in the result set, and "q" as a generic free-form search query. We will define the standard set of parameters as we go and will apply them consistently. + +#### Verbs + +Singular objects should support GET for read, PUT for complete replacement \(or creation when the primary key is specified by the client and is persistent, e.g. a payment card PAN\), and DELETE for delete. + +Collections should support GET to read back the whole or part of a collection, and POST to add a new object to the collection. + +Singular objects may support POST as a way to change their state in specified ways. Posting a JSON document to a singular object URI may allow selected field values to be updated or trigger a state change or action without replacing the whole object. + +GET must be implemented in a _nullipotent_ manner-that is, GET never causes side effects and never modifies client-visible system state \(other than logging events or updating instrumentation, e.g.\). + +PUT and DELETE must be implemented in an _idempotent_ manner-that is, changes are applied consistently to the system data in a way that is dependent only on the state of the resource and inputs but on nothing else. The action has no additional effect if it is executed more than once with the same input parameters and does not depend on the order of other operations on a containing collection or other resources held in the collection. For example, removing a resource from a collection can be considered an idempotent operation on the collection. Using PUT to fully replace \(or create\) a uniquely identified resource when the URI is fully known to the client is also idempotent. This implies that the system may reorder operations to improve efficiency, and the client does not need to know whether a resource exists before attempting to replace it. + +POST and PATCH3 are not idempotent operations. POST is used to create new resources where the resource identifier is assigned by the server or where a single identified internal resource is implied by the target URI \(e.g. POST /transfers, but PUT /transfers/:id/fulfillment\). + +#### Data Format + +We favor [JSON](http://json.org/)4 related data formats over XML. In some cases, data formats will be binary or XML, as defined by pre-existing standards, and these will be precisely specified. Binary formats should have a formal syntax to avoid ambiguous representational translations \(e.g. character set translations, big- or little-endian representations of numeric values, etc\). + +Date and time values used in APIs should comply to the ISO 8601 standard, and further profiled by the w3c Note on Date and Time Formats.5 This w3c note should lead to the reduction in complexity and error scope of communicating components that must exchange tangible dates and times. There will be cases where we use non-ISO format date or time as required by an external standard, e.g. ISO 7813 expiry dates. + +Existing standard XML formats should have an XSD schema for the acceptable subset profile used within the project. For particularly complex data formats, we may use a common format profile translator to map between our project subset of the standard format and the wire format used by a standardized protocol \(e.g.\). This will limit coupling to complex formats in a more maintainable way. + +When specifying the PATCH action for a resource, we will use a consistent patch document format \(e.g. [JSON Patch](http://jsonpatch.com/)6\). + +#### Return Codes + +Use HTTP return codes in a consistent way and according to their standard definitions. The standard codes are defined in RFC 2616.7 + +#### Machine Readable Error Format + +The API should provide a machine readable error result in a well-defined JSON format. {TBD whether to use a response envelope and how to format errors, faults, and success envelopes. RESTful design relies on headers to carry protocol-defined errors, debug info can also be carried in headers. We should be clear on why we are using an envelope and how this supports normal production communication between client and server. + +#### Versioning + +API URIs should include a version identifier in the format v_M_ as a leading path element \(where _"M"_ is the Major component of the multi-part version number\). The API and its version identifier element must conform to the [semantic versioning](http://semver.org/)8 2.0 specification for API versioning. + +A client must specify the Major version number in each request. It is not possible for a client to express a requirement for a specific minor version. + +The full API version number is specified in the response header \(TBD\) for all successful and error responses. + +While an API version contract will be influenced by Major, minor, _and_ patch levels, only the Major version number is a production API binding element-that is, a production client cannot request a particular minor version or patch level and a production server will not accept a URI request that specifies these extra elements. + +However, in pre-production environments, it is anticipated that some combination of minor, patch, pre-release, and metadata suffixes would be supported in client requests \(as defined in _semver_ \[3\]\) and _may_ be expressed in _pre-production_ URIs to assist with development and integration scenarios. + +### We May Need to Give REST a Rest + +As we design the interconnection APIs between components and between participating systems, we may find API requirements that don't precisely match the Pragmatic REST pattern defined here. We will evaluate these case-by-case and make the best choice to support the project goals. + +### Non-Functional Requirements + +As we develop the APIs, we will make consistent choices about non-functional requirements to reinforce the project goals. + +1: [http://martinfowler.com/articles/richardsonMaturityModel.html](Richardson%20Maturity%20Model), retrieved August 18, 2016. + +2: [https://www.amazon.com/gp/product/0596805829](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829), retrieved August 18, 2016. + +3: RFC 5789, _PATCH Method for HTTP_, [https://tools.ietf.org/html/rfc5789](https://tools.ietf.org/html/rfc5789), retrieved August 18, 2016. + +4: _Introducing JSON_, [http://json.org/](http://json.org/), retrieved August 18, 2016. + +5: [http://www.w3.org/TR/1998/NOTE-datetime-19980827](http://www.w3.org/TR/1998/NOTE-datetime-19980827), retrieved August 22, 2016. + +6: _JSON Patch_, [http://jsonpatch.com/](http://jsonpatch.com/), retrieved August 18, 2016. + +7: [https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) + +8: _Semantic Versioning 2.0.0_, [http://semver.org/](http://semver.org/), retrieved August 18, 2016. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/community/tools/tools-and-technologies.md b/website/versioned_docs/v1.0.1/community/tools/tools-and-technologies.md new file mode 100644 index 000000000..f92bfc47d --- /dev/null +++ b/website/versioned_docs/v1.0.1/community/tools/tools-and-technologies.md @@ -0,0 +1,50 @@ +# Tools and Technologies + +Here we document the reasoning behind certain tools, technology and process choices for Mojaloop. We also have included the recommendation links/versions for each of these tools. + +**TOOL CHOICES** + +* **API Development** + * **RAML** and **Swagger 2.0** is leveraged for API development. + * **WSO2** offers an enterprise platform for integrating APIs, applications, and web services—locally and across the Internet. It also provides Mojaloop with a Security Layer, and Development Portal. +* **Circle-CI** - This tool is used for continuous build and continuous deployment. We needed an online continuous build and testing system that can work with many small projects and a distributed team. Jenkins was considered, but it requires hosting a server and a lot of configuration. CircleCI allowed for a no host solution that could be started with no cost and very limited configuration. We thought we might start with CircleCI and move off later if we outgrew it, but that hasn’t been needed. +* **Dactyl** – We need to be able to print the online documentation. While it’s possible to print markdown files directly one at a time, we’d like to put the files into set of final PDF documents, where one page might end up in more than one final manual. [Dactyl](https://github.com/ripple/dactyl) is a maintained open source conversion tool that converts between markdown and PDF. We originally tried Pandoc, but it had bugs with converting tables. Dactyl fixes that and is much more flexible. +* **DBeaver** - [DBeaver](https://dbeaver.io/) is a free multi-platform database tool for developers, SQL programmers, database administrators and analysts. Supports all popular databases: MySQL, PostgreSQL, MariaDB, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Derby, etc. +* **Docker** - The Docker container engine creates and runs the Docker container from the Docker image file. +* **Docker hub** is used to link, build, test and push the Mojaloop code repositories. We needed to support both local and cloud execution. We have many small microservices that have very simple specific configurations and requirements. The easiest way to guarantee that the service works the same way in every environment from local development, to cloud, to hosted production is to put each microservice in a Docker container along with all the prerequisites it needs to run. The container becomes a secure, closed, pre-configured, runnable unit. +* **Draw.io** – We need to create pictures for our documents and architecture diagrams using an \(ideally free\) open source friendly tool, that is platform agnostic, supports vector and raster formats, allows WYSIWYG drawing, works with markdown, and is easy to use. We looked at many tools including: Visio, Mermaid, PlantUML, Sketchboard.io, LucidChart, Cacoo, Archi, and Google Drawings. Draw.io scored at the top for our needs. It’s free, maintained, easy to use, produces our formats, integrates with DropBox and GitHub, and platform agnostic. In order to save our diagrams, we have to save two copies – one in SVG \(scalable vector\) format and the other in PNG \(raster\). We use the PNG format within the docs since it can be viewed directly in GitHub. The SVG is used as the master copy as it is editable. +* **ESLint** - Within JavaScript code, we use [ESLint](https://eslint.org/) as a code style guide and style enforcement tool. +* **GitHub** – [GitHub](https://github.com/Mojaloop) is a widely-used source code repository service, based on git, the standard source code version control system for open source projects. So the decision to use GitHub was straightforward. We create a story every time for integration work. Create bugs for any issues. Ensure all stories are tracked throughout the pipeline to ensure reliable metrics. +* **Helm** - The Helm package manager for Kubernetes provides templatized deployments and configurations and allow for overall complexity management. +* **Kafka** - This technology is leveraged to support Mojaloop’s demand for a high velocity and high volume data messaging but keep our hardware requirements minimum. +* **JavaScript** - The Mojaloop application is primarily written in JavaScript. +* **Kubectl** - This is a command line interface for running commands against Kubernetes clusters. +* **Kubernetes** - This enterprise tool provides an extraction layer, infrastructure management and a container-orchestration system. +* **Markdown** – Documentation is a deliverable for this project, just like the code, and so we want to treat it like the code in terms of versioning, review, check in, and tracking changes. We also want the documentation to be easily viewable online without constantly opening a viewer. GitHub has a built-in format called Markdown which solves this well. The same files work for the Wiki and the documents. They can be reviewed with the check in using the same tools and viewed directly in GitHub. We considered Google Docs, Word and PDF, but these binary formats aren’t easily diff-able. A disadvantage is that markdown only allows simple formatting – no complex tables or font changes - but this should be fine when our main purpose is clarity. +* **MySQLWorkbench** – [MySQL Workbench](https://www.mysql.com/products/workbench/) is a unified visual tool for database architects, developers, and DBAs. MySQL Workbench provides data modeling, SQL development, and comprehensive administration tools for server configuration, user administration, backup, and much more. MySQL Workbench is available on Windows, Linux and Mac OS X. +* **NodeJS** - This development tool is a JavaScript runtime built on Chrome's V8 JavaScript engine that runs Mojaloop. NodeJS is designed to create simple microservices and it has a huge set of open source libraries available. Node performance is fine and while Node components don’t scale vertically a great deal, but we plan to scale horizontally, which it does fine. The original Interledger code was written in NodeJS as was the level one prototype. Most teams used Node already, so this made sense as a language. Within NodeJS code, we use [Standard](https://www.npmjs.com/package/standard) as a code style guide and to enforce code style. +* **NPM** - NPM is the package manager for Mojaloop since JavaScript is the default programming language. +* **Percona** for **MySQL** - These tools are leveraged as a relational database management system to ensure high performance and enterprise-grade functionality for the Mojaloop system. We needed a SQL backend that is open source friendly and can scale in a production environment. Thus, we chose MySQL, an open-source relational database management system. +* **Postman** is a Google Chrome application for interacting with HTTP APIs. It presents you with a friendly GUI for constructing requests and reading responses. +* **Rancher 2.0** - The Infrastructure management, provisioning and monitoring is provided by Rancher 2.0 which is an enterprise Kubernetes platform that manage Kubernetes deployments, clusters, on cloud & on-prem. Rancher makes it easy for DevOps teams to test, deploy and manage the Mojaloop system no matter where it is running. +* **Slack** – Slack is used for internal team communication. This was largely picked because several team already used it and liked it as a lightweight approach compared to email. +* **SonarQube** – We need an online dashboard of code quality \(size, complexity, issues, and coverage\) that can aggregate the code from all the repos. We looked at several online services \(CodeCov, Coveralls, and Code Climate\), but most couldn’t do complexity or even number of lines of code. Code Climate has limited complexity \(through ESLint\), but costs 6.67/seat/month. SonarQube is free, though it required us to setup and maintain our own server. It gave the P1 features we wanted. +* **SourceTree** – [Sourcetree](https://www.sourcetreeapp.com/) simplifies how you interact with your Git repositories so you can focus on coding. Visualize and manage your repositories through Sourcetree's simple Git GUI. +* **Stories On Board** - We use Stories on Board to help capture our high level Epics at a portfolio level before they are commmitted and moved to Github. Our Story Board for Mojaloop is located [here](https://mojaloop.storiesonboard.com/m/ml-phase3-planning) +* **Visual Studio Code** - [Visual Studio Code](https://code.visualstudio.com/) is a code editor redefined and optimized for building and debugging modern web and cloud applications. Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows. +* **ZenHub** – We needed a project management solution that was very light weight and cloud based to support distributed teams. It had to support epics, stories, and bugs and a basic project board. VS and Jira online offerings were both considered. For a small distributed development team an online service was better. For an open source project, we didn’t want ongoing maintenance costs of a server. Direct and strong GitHub integration was important. It was very useful to track work for each microservice with that microservice. Jira and VS both have more overhead than necessary for a project this size and don’t integrate as cleanly with GitHub as we’d want. ZenHub allowed us to start work immediately. A disadvantage is the lack of support for cumulative flow diagrams and support for tracking \# of stories instead of points, so we do these manually with a spreadsheet updated daily and the results published to the "Project Management" Slack channel. + +**TECHNOLOGY CHOICES** + +* **Agile development** - This methodology is used to track and run the project. The requirements need to be refined as the project is developed, therefore we picked agile development over waterfall or lean. +* **APIs** - In order to avoid confusion from too many changing microservices, we use strongly defined APIs that conform to our [Pragmatic REST](pragmatic-rest.md) design pattern. APIs will be defined using OpenAPI or RAML. Teams document their APIs with Swagger v2.0 or RAML v0.8 so they can automatically test, document, and share their work. Swagger is slightly preferred as there are free tools. Mule will make use of RAML 0.8. Swagger can be automatically converted to RAML v0.8, or manually to RAML v1.0 if additional readability is desired. +* **Automated Testing** - For the most part, most testing will be automated to allow for easy regression. See the [automated testing strategy](automated-testing.md) and [code quality metrics](code-quality-metrics.md) for standards. +* **Hosting** - Mojaloop has been designed to be infrastructure agnostic and as such is supported by AWS, Azure and On-Premise installations. +* **Interledger** – Mojaloop needed a lightweight, open, and secure transport protocol for funds. [Interledger.org](http://Interledger.org) provides all that. It also provides the ability to connect to other systems. We also considered block chain systems, but block chain systems send very large messages which will be harder to guarantee delivery of in third world infrastructure. Also, while blockchain systems provide good anonymity, that is not a project goal. To enable fraud detection, regulatory authorities need to be able to request records of transfers by account and person. +* **Open source** - The entire project has been released as open source in accordance with the [Level One Project principles](https://leveloneproject.org/wp-content/uploads/2016/03/L1P_Level-One-Principles-and-Perspective.pdf). All tools and processes must be open source friendly and support projects that use an Apache 2.0 license with no restrictive licenses requirements on developers. +* **Operating System** – Microsoft Windows is widely used in many target countries, but we need an operating system that is free of license fees and is open source compatible. We are using Linux. We don’t have a dependency on the particular flavor, but are using the basic Amazon Linux. In the Docker containers, [Alpine Linux](https://alpinelinux.org/) is used. +* **Microservices** - Because the architecture needs to easily deploy, scale, and have components be easily replaced or upgraded, it will be built as a set of microservices. +* **Scaled Agile Framework** - There were four initial development teams that are geographically separate. To keep the initial phase of the project on track, the [scaled agile framework \(SAFe\)](https://www.scaledagileframework.com/) was picked. This means work is divided into program increments \(PI\) that are typically four 2 week sprints long. As with the sprints, the PI has demo-able objective goals defined in each PI meeting. +* **Services** - Microservices are grouped and deployed in a few services such as the DFSP, Central Directory, etc. Each of these will have simple defined interfaces, configuration scripts, tests, and documentation. +* **Threat Modeling, Resilience Modeling, and Health Modeling** - Since the Mojaloop code needs to exchange money in an environment with very flaky infrastructure it must have good security, resilience, and easily report it's health state and automatically attempt to return to it. +* **USSD** - Smart phones are only 25% of the target market and not currently supported by most money transfer service, so we need a protocol that will work on simple feature phones. Like M-Pesa, we are using USSD between the phone and the digital financial service provider \(DFSP\). diff --git a/website/versioned_docs/v1.0.1/getting-started/README.md b/website/versioned_docs/v1.0.1/getting-started/README.md new file mode 100644 index 000000000..edf01f06d --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/README.md @@ -0,0 +1,10 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + +1. [View the quickstarts](/getting-started/quickstart/) +1. [Watch a demo](/getting-started/demo/) +1. [Read the documentation](/technical/) +1. [Test out Mojaloop APIs](/technical/) +1. [Take a training program](https://mojaloop.io/mojaloop-training-program/) +1. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/getting-started/demo-one.md b/website/versioned_docs/v1.0.1/getting-started/demo-one.md new file mode 100644 index 000000000..e8071921d --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/demo-one.md @@ -0,0 +1,3 @@ +# Demo One + +Details of Demo one goes here diff --git a/website/versioned_docs/v1.0.1/getting-started/demo.md b/website/versioned_docs/v1.0.1/getting-started/demo.md new file mode 100644 index 000000000..245a52d18 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/demo.md @@ -0,0 +1,6 @@ +# Demos + +## Demos List + +TODO: A list of demos + diff --git a/website/versioned_docs/v1.0.1/getting-started/faqs.md b/website/versioned_docs/v1.0.1/getting-started/faqs.md new file mode 100644 index 000000000..7193a2036 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/faqs.md @@ -0,0 +1,6 @@ +# Frequently Asked Questions + +This document contains some of the most frequently asked questions from the community. + +- [General FAQs](/getting-started/general-faqs) +- [Technical FAQs](/getting-started/technical-faqs) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/getting-started/general-faqs.md b/website/versioned_docs/v1.0.1/getting-started/general-faqs.md new file mode 100644 index 000000000..5afab4b63 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/general-faqs.md @@ -0,0 +1,59 @@ +# General FAQs + +This document contains some of the most frequently asked questions from the community. + +## 1. What is Mojaloop? + +Mojaloop is open-source software for building interoperable digital payments platforms on a national scale. It makes it easy for different kinds of providers to link up their services and deploy low-cost financial services in new markets. + + +## 2. How does it work? + +Most digital financial providers run on their own networks, which prevents customers who use different services from transacting with each other. Mojaloop functions like a universal switchboard, routing payments securely between all customers, regardless of which network they're on. It consists of three primary layers, each with a specific function: an interoperability layer, which connects bank accounts, mobile money wallets, and merchants in an open loop; a directory service layer, which navigates the different methods that providers use to identify accounts on each side of a transaction; a transactions settlement layer, which makes payments instant and irrevocable; and components which protect against fraud. + +## 3. Who is it for? + +There are many components to the code, and everyone either directly or indirectly working with digital financial transactions-fintech developers, bankers, entrepreneurs, startups-is invited to explore and use whatever parts are useful or appealing. The software as a whole is meant to be implemented on a national scale, and so it will be most applicable to mobile money providers, payments associations, central banks, and country regulators. + +Developers at fintech and financial services companies can use the code in three ways: adapt the code to the financial services standards for a country, use the code to update their own products and services or create new ones, and improve the code by proposing updates and new versions of it for other users. + +For example: + +- A central bank may commission the use of the software by their commercial partners to speed up the deployment of a national payment gateway. +- A major payment processor can use the software to modernize their current offering, to achieve lower transaction costs without major R&D investments. +- A fintech startup can use the code to understand practically how to comply with interoperable payment APIs. +- A bank can use the code to modify their internal systems so that they easily interoperate with other payment providers. + +## 4. Why does it exist? + +Providers trying to reach developing markets with innovative, low-cost digital financial services have to build everything on their own. This raises costs and segregates services from each other. Mojaloop can be used as a foundation to help build interoperable platforms, lowering costs for providers and allowing them to integrate their services with others in the market. + +## 5. Who's behind it? + +Mojaloop was built in collaboration with a group of leading tech and fintech companies: [Ripple](https://github.com/ripple), [Dwolla](https://github.com/dwolla), [Software Group](http://www.softwaregroup-bg.com/), [ModusBox](http://www.modusbox.com/) and [Crosslake Technologies](http://www.crosslaketech.com/). Mojaloop was created by the Gates Foundation's Mojaloop, which is aimed at leveling the economic playing field by crowding in expertise and resources to build inclusive payment models to benefit the world's poor. It is free to the public as open-source software under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). + +## 6. What platforms does Mojaloop run on? + +The Mojaloop platform was developed for modern cloud-computing environments. Open-source methods and widely used platforms, like Node.js, serve as the foundation layer for Mojaloop. The microservices are packaged in Docker and can be deployed to local hardware or to cloud computing environments like Amazon Web Services or Azure. + +## 7. Is it really open-source? + +Yes, it is really open-source. All core modules, documentation and white papers are available under a [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). Mojaloop relies on commonly used open-source software, including node.js, MuleCE, Java and PostgreSQL. Mojaloop also uses the [Interledger Protocol](https://github.com/interledger) to choreograph secure money transfers. The licenses for all of these platforms and their imported dependencies allow for many viable uses of the software. + +## 8. How can I contribute to Mojaloop? + +You can contribute by helping us create new functionality on our roadmap or by helping us improve the platform. For our roadmap, go to the [Mojaloop Roadmap](../mojaloop-roadmap.md). We recommend starting with the onboarding guide and sample problem. This has been designed by the team to introduce the core ideas of the platform and software, the build methods, and our process for check-ins. + +## 9. Using Mojaloop to do payment using crypto-currency? + +Not with the current Specification and with this platform. Currently this is limited to currencies listed in the ISO 4217. Since the specification and platform is all about digital transfers, it should be possible to investigate a use-case for this possible requirement. Alternatively, I guess an FSP can provide that conversion (like many do already from crypto to one of the listed currencies). + +## 10. How is the Mojaloop source accessible? + +Here are some resources to start with: +1. Docs: https://github.com/mojaloop/documentation. +2. Look at the repos that have “CORE COMPONENT (Mojaloop)” in the description and these are core components. “CORE RELATED (Mojaloop)” repos are the ones that are needed to support the current Mojaloop Switch implementation/deployment. +3. As a generic point of note, for latest code, please use the ‘develop’ branch for the time-being. +4. Current architecture: https://github.com/mojaloop/docs/tree/master/Diagrams/ArchitectureDiagrams. Please note that these are currently being migrated to https://github.com/mojaloop/documents. +5. You may use this for current deployment architecture and deployment information: https://github.com/mojaloop/documentation/tree/master/deployment-guide. + diff --git a/website/versioned_docs/v1.0.1/getting-started/quickstart-one.md b/website/versioned_docs/v1.0.1/getting-started/quickstart-one.md new file mode 100644 index 000000000..4148ea4d6 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/quickstart-one.md @@ -0,0 +1,3 @@ +# Quickstart One + +Quickstart goes here \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/getting-started/quickstart-two.md b/website/versioned_docs/v1.0.1/getting-started/quickstart-two.md new file mode 100644 index 000000000..ada2469e4 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/quickstart-two.md @@ -0,0 +1,3 @@ +# Quickstart Two + +Quickstart two goes here \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/getting-started/quickstart.md b/website/versioned_docs/v1.0.1/getting-started/quickstart.md new file mode 100644 index 000000000..0ed1d5a64 --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/quickstart.md @@ -0,0 +1,3 @@ +# Quickstarts + +View a list of quickstarts here \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/getting-started/technical-faqs.md b/website/versioned_docs/v1.0.1/getting-started/technical-faqs.md new file mode 100644 index 000000000..3529d878b --- /dev/null +++ b/website/versioned_docs/v1.0.1/getting-started/technical-faqs.md @@ -0,0 +1,158 @@ +# Technical FAQs + +This document contains some of the frequently asked technical questions from the community. + +## 1. What is supported? + +Currently the Central ledger components are supported by the team. The DFSP components are outdated and thus the end-to-end environment and full setup is challenging to install. + +## 2. Can we connect directly to Pathfinder in a development environment? + +For the local and test environment, we recommend interfacing with the 'mock-pathfinder' service instead. Pathfinder is a 'paid by usage' service. + +Access the https://github.com/mojaloop/mock-pathfinder repository to download and install mock-pathfinder. Run command npm install in mock-pathfinder directory to install dependencies after this update Database_URI in mock-pathfinder/src/lib/config.js. + +## 3. Should i register DFSP via url http://central-directory/commands/register or i need to update configuration in default.json? + +You should register using the API provided, using postman or curl. Client is using LevelOne code. Needs to implement the current Mojaloop release with the current Postman scripts. + +## 4. Status of the pod pi3-kafka-0 is still on CrashLoopBackOff? + +- More background related to the question: + + When I tired to get logs of the container centralledger-handler-admin-transfer, I get the following error: + Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing + And the status of the pod pi3-kafka-0 is still on CrashLoopBackOff. + I am using a vps on ubuntu 16.04 with RAM 12GB, 2vCores, 2.4GHz, Rom 50GB at OVH for the deployment. + +Increased RAM to 24 GB and CPU to 4 resolved the issues. Appears to be a timeout on Zookeeper due depletion of available resources, resulting in the services shutting down. + +## 5. Why am I getting an error when we try to create new DFSP using Admin? + +Please insure you are using the most current Postman scripts available on https://github.com/mojaloop/mock-pathfinder repository. + + +## 6. Can I spread Mojaloop components over different physical machines and VM's? + +You should be able to setup on different VM's or physical machines. The distribution pretty much depend on your requirements and would be implementation specific. We utilise Kubernetes to assist with the Container Orchestration. This enables us to schedule the deployments through the Kubernetes runtime to specific machines if required, and request specific resources if required. The helm charts in the helm repository could be used as guideline to how best allocate and group the components in your deployment. Naturally you would need to update the configurations to complement your custom implementation. + +## 7. Can we expect all the endpoints defined in the API document are implemented in Mojaloop? + +The Mojaloop Specification API for transfers and the Mojaloop Open Source Switch implementation are independent streams, though obviously the implementation is based on the Specification. Based on the use-cases prioritized for a time-frame and based on the end-points needed to support those use-cases, implementation will be done. If a few end-points are not prioritized then implementation for them may not be available. However, I think the goal is to eventually support all the end-points specified though it may take time. Thanks for the collection. We do have some of these on the ‘postman’ repo in the mojaloop GitHub org. + +## 8. Does Mojaloop store the payment initiator FSP’s quote/status info? + +At the moment, the Mojaloop Open source Switch implementation does *not* store Quotes related information. The onus is on the Payer, Payee involved in the process to store the relevant information. + +## 9. Does Mojaloop handle workflow validation? + +Not at the moment, but this may happen in the future. Regarding correlating requests that are related to a specific transfer, you may look at the ‘transaction’ end-point/resource in the Specification for more information on this. In addition to this, I can convey that some background work is ongoing regarding the specification to make this correlation more straight-forward and simpler i.e., to correlate quote and transfer requests that come under a single transaction. + + +## 10. How to register a new party in Mojaloop? + +There is no POST on /parties resource, as specified in section 6.1.1 of the API Defintion. Please refer to section: 6.2.2.3 `POST /participants//` in the API Defintion. + +” _The HTTP request `POST /participants//` (or `POST /participants///`) is used to create information on the server regarding the provided identity, defined by ``, ``, and optionally `` (for example, POST_ + _/participants/MSISDN/123456789 or POST /participants/BUSINESS/shoecompany/employee1). See Section 5.1.6.11 for more information regarding addressing of a Party._ ”. + +## 11. Does the participant represent an account of a customer in a bank? + +For more on this, please refer to this doc (Section 3..2): https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +” _In the API, a Participant is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource Participants is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system._ ” + +In essence, a participant is any FSP participating in the Scheme (usually not a customer). For account lookup, a directory service such as *Pathfinder* can be used, which provides user lookup and the mapping. If such a directory service is not provided, an alternative is provided in the Specification, where the Switch hosts an Account Lookup Service (ALS) but to which the participants need to register parties. I addressed this earlier. But one thing to note here is that the Switch does not store the details, just the mapping between an ID and an FSP and then the calls to resolve the party are sent to that FSP. + +https://github.com/mojaloop/mojaloop-specification CORE RELATED (Mojaloop): + +This repo contains the specification document set of the Open API for FSP Interoperability - mojaloop/mojaloop-specification. + +## 12. How to register _trusted_ payee to a payer, to skip OTP? + +To skip the OTP, the initial request on the /transactionRequests from the Payee can be programmatically (or manually for that matter) made to be approved without the use of the /authorizations endpoint (that is need for OTP approval). Indeed the FSP needs to handle this, the Switch does not. This is discussed briefly in section 6.4 of the Specification. + +## 13. Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file? + +From the official kubernetes github repository in the README.md, the latest link to use is "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Be sure to always verify 3rd party links before implementing. Open source applications are always evolving. + +## 14. When installing nginx-ingress for load balancing & external access - Error: no available release name found? + +Please have a look at the following addressing a similar issue. To summarise - it is most likely an RBAC issue. Have a look at the documentation to set up Tiller with RBAC. https://docs.helm.sh/using_helm/#role-based-access-control goes into detail about this. The issue logged: helm/helm#3839. + +## 15. Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command. + +Found a solution here https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Ubuntu 14 here, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. First, I want to build latest stable (seems it's 0.9.2) librdkafka into /opt/librdkafka. curl https://codeload.github.com/ede... + +Here are the steps to rebuild librdkafka: + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout ` + +cd librdkafka && ./configure && make && make install && ldconfig + +After that I'm able to import stuff without specifying LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +The Apache Kafka C/C++ library. Contribute to edenhill/librdkafka development by creating an account on GitHub. + +## 16. Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only? + +We can use mojaloop for interoperability to support mobile wallet and other such money transfers. This is not a software for a DFSP (there are open source projects that cater for these such as Finserv etc). Mojaloop is for a Hub/Switch primarily and an API that needs to be implemented by a DFSP. But this is not for managing mobile wallets as such. + +## 17. Describe companies that helps to deploy & support for mojaloop? + +Mojaloop is an open source software and specification. + +## 18. Can you say something about mojaloop & security? + +The Specification is pretty standard and has good security standards. But these need to be implemented by the adopters and deployers. Along with this, the security measures need to be coupled with other Operational and Deployment based security measures. Moreover, the coming few months will focus on security perspective for the Open Source community. + +## 19. What are the benefit(s) from using mojaloop as interoperabilty platform? + +Benefits: Right now for example, an Airtel mobile money user can transfer to another Airtel mobile money user only. With this, he/she can transfer to any Financial service provider such as another mobile money provider or any other bank account or Merchant that is connected to the Hub, irrespective of their implementation. They just need to be connected to the same Switch. Also, this is designed for feature phones so everyone can use it. + +## 20. What are the main challenges that companies face using mojaloop? + +At this point, the main challenges are around expectations. Expectations of the adopters of mojaloop and what really mojaloop is. A lot of adopters have different understanding of what mojaloop is and about its capabilities. If they have a good understanding, a lot of current challenges are mitigated.. +Yes, forensic logging is a security measure as well for auditing purposes which will ensure there is audit-able log of actions and that everything that is a possible action of note is logged and rolled up, securely after encryption at a couple of levels. + +## 21. Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform? + +This also ensures all the services always run the code they’re meant to run and anything wrong/bad is stopped from even starting up. Also, for reporting and auditors, reports can have a forensic-log to follow. + +## 22. How do the financial service providers connect with mojaloop? + +There is an architecture diagram that presents a good view of the integration between the different entities. https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +## 23. Is there any open source ISO8583-OpenAPI converter/connector available? + +I don't believe a generic ISO8583 `<-> Mojaloop integration is available currently. We're working on some "traditional payment channel" to Mojaloop integrations (POS and ATM) which we hope to demo at the next convening. These would form the basis for an ISO8583 integration we might build and add to the OSS stack but bare in mind that these integrations will be very use case specific. + +## 24. How do I know the end points to setup postman for testing the deployment? + +On the Kubernetes dashboard, select the correct NAMESPACE. Go to Ingeresses. Depending on how you deployed the helm charts, look for 'moja-centralledger-service'. Click on edit, and find the tag ``. This would contain the endpoint for this service. + +## 25. Why are there no reversals allowed on a Mojaloop? + +*Irrevocability* is a core Level One Principle (edited) and not allowing reversals is essential for that. Here is the section from the API Definition addressing this: + +_*6.7.1.2 Transaction Irrevocability*_ +_The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions._ +_As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using POST /transfers including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer’s expiry time is exceeded before the Payee FSP responds (see Sections 6.7.1.3 and 6.7.1.5 for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties._ + +However, *Refunds* is a use case supported by the API. + +## 26. ffg. error with microk8s installation "MountVolume.SetUp failed"? + +Would appear if it is a space issue, but more the 100GiB of EBS storage was allocated. +The issue resolved itself after 45 minutes. Initial implementation of the mojaloop project can take a while to stabilize. + +## 27. Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"? + +You need to create the corresponding Hub accounts (HUB_MULTILATERAL_SETTLEMENT and HUB_RECONCILIATION) for the specified currency before setting up the participants. +In this Postman collection you can find the requests to perform the operation in the "Hub Account" folder: https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Find also the related environments in the Postman repo: https://github.com/mojaloop/postman diff --git a/website/versioned_docs/v1.0.1/index.md b/website/versioned_docs/v1.0.1/index.md new file mode 100644 index 000000000..ee7c7c068 --- /dev/null +++ b/website/versioned_docs/v1.0.1/index.md @@ -0,0 +1,15 @@ +--- +home: true +heroImage: /mojaloop_logo_med.png +tagline: This is the official documentation of the Mojaloop project. +actionText: Getting Started → +actionLink: /getting-started/ +features: +- title: Commmunity + details: Feature 1 Description +- title: Technical + details: Feature 2 Description +- title: API Specification + details: Feature 3 Description +footer: Made by Mojaloop with ❤️ +--- \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/quickstarts/README.md b/website/versioned_docs/v1.0.1/quickstarts/README.md new file mode 100644 index 000000000..ee06bcdbe --- /dev/null +++ b/website/versioned_docs/v1.0.1/quickstarts/README.md @@ -0,0 +1,10 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + +1. [View the quickstarts](/1-overview/) +1. [Watch a demo](/99-demos/) +1. [Read the documentation](/1-overview/) +1. [Test out Mojaloop APIs](/1-overview/#apis) +1. [Take a training program](/3-guides/1_dfsp_setup/) +1. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/quickstarts/one.md b/website/versioned_docs/v1.0.1/quickstarts/one.md new file mode 100644 index 000000000..ee06bcdbe --- /dev/null +++ b/website/versioned_docs/v1.0.1/quickstarts/one.md @@ -0,0 +1,10 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + +1. [View the quickstarts](/1-overview/) +1. [Watch a demo](/99-demos/) +1. [Read the documentation](/1-overview/) +1. [Test out Mojaloop APIs](/1-overview/#apis) +1. [Take a training program](/3-guides/1_dfsp_setup/) +1. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/quickstarts/two.md b/website/versioned_docs/v1.0.1/quickstarts/two.md new file mode 100644 index 000000000..ee06bcdbe --- /dev/null +++ b/website/versioned_docs/v1.0.1/quickstarts/two.md @@ -0,0 +1,10 @@ +# Your First Action + +To help get you started with Mojaloop, select which of the options below best suits your needs: + +1. [View the quickstarts](/1-overview/) +1. [Watch a demo](/99-demos/) +1. [Read the documentation](/1-overview/) +1. [Test out Mojaloop APIs](/1-overview/#apis) +1. [Take a training program](/3-guides/1_dfsp_setup/) +1. [Contribute to Mojaloop](https://docs.mojaloop.io/documentation/) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/sidebar.config.json b/website/versioned_docs/v1.0.1/sidebar.config.json new file mode 100644 index 000000000..0dea9bf80 --- /dev/null +++ b/website/versioned_docs/v1.0.1/sidebar.config.json @@ -0,0 +1,610 @@ +{ + "sidebar": { + "/v1.0.1/getting-started/": [ + { + "title": "Getting Started", + "collapsable": false, + "children": [ + "" + ] + }, + { + "title": "Quickstarts", + "collapsable": false, + "children": [ + [ + "quickstart", + "Quickstarts" + ], + [ + "quickstart-one", + "Quickstart One" + ], + [ + "quickstart-two", + "Quickstart Two" + ] + ] + }, + { + "title": "Demos", + "collapsable": false, + "children": [ + "demo", + "demo-one" + ] + }, + { + "title": "FAQs", + "collapsable": false, + "children": [ + [ + "faqs", + "Frequently Asked Questions" + ], + [ + "general-faqs", + "General FAQs" + ], + [ + "technical-faqs", + "Technical FAQs" + ] + ], + "sidebarDepth": 2 + } + ], + "/v1.0.1/community/": [ + { + "title": "Community", + "collapsable": false, + "children": [ + [ + "contributing/contributors-guide", + "Contributors' Guide" + ], + [ + "contributing/new-contributor-checklist", + "New Contributor Checklist" + ], + [ + "contributing/code-of-conduct", + "Code of Conduct" + ], + [ + "contributing/signing-the-cla", + "Signing the CLA" + ] + ], + "sidebarDepth": 2 + }, + { + "title": "Community Standards", + "collapsable": false, + "children": [ + [ + "standards/guide", + "Our Standards" + ], + [ + "standards/versioning", + "Versioning" + ], + [ + "standards/creating-new-features", + "Creating New Features" + ], + [ + "standards/triaging-bugs", + "Triaging Bugs" + ] + ], + "sidebarDepth": 2 + }, + { + "title": "Tools and Technologies", + "collapsable": false, + "children": [ + [ + "tools/tools-and-technologies", + "Tools" + ], + [ + "tools/pragmatic-rest", + "Pragmatic Rest" + ], + [ + "tools/code-quality-metrics", + "Code Quality Metrics" + ], + [ + "tools/automated-testing", + "Automated Testing" + ] + ], + "sidebarDepth": 2 + }, + { + "title": "Documentation", + "collapsable": false, + "children": [ + [ + "documentation/standards", + "Standards" + ], + [ + "documentation/api-documentation", + "API Documentation" + ], + [ + "documentation/style-guide", + "Style Guide" + ] + ] + }, + { + "title": "Community Resources", + "collapsable": false, + "children": [ + { + "title": "Resources", + "collapsable": false, + "children": [ + [ + "mojaloop-roadmap", + "Product Roadmap" + ], + [ + "mojaloop-publications", + "Mojaloop Publications" + ] + ] + }, + { + "title": "Notes Archive", + "collapsable": true, + "path": "archive/notes/", + "children": [ + [ + "archive/notes/ccb-notes", + "CCB Notes" + ], + [ + "archive/notes/da-notes", + "Meeting Notes" + ], + [ + "archive/notes/scrum-of-scrum-notes", + "Scrum Notes" + ] + ] + }, + { + "title": "Discussion Docs Archive", + "collapsable": true, + "path": "archive/discussion-docs/", + "children": [ + { + "title": "PI 10", + "collapsable": true, + "children": [ + [ + "archive/discussion-docs/performance-project", + "Performance Project" + ], + [ + "archive/discussion-docs/code-improvement", + "Code Improvement Project" + ], + [ + "archive/discussion-docs/cross-border", + "Cross Border Project" + ], + [ + "archive/discussion-docs/psip-project", + "PSIP Project" + ] + ] + }, + { + "title": "PI 9", + "collapsable": true, + "children": [ + [ + "archive/discussion-docs/versioning-draft-proposal", + "Versioning Draft Proposal" + ] + ] + }, + { + "title": "PI 8", + "collapsable": true, + "children": [ + [ + "archive/discussion-docs/cross-border-day-1", + "CB Day 1 Meeting Notes" + ], + [ + "archive/discussion-docs/cross-border-day-2", + "CB Day 2 Meeting Notes" + ], + [ + "archive/discussion-docs/iso-integration", + "ISO Integration Overview" + ], + [ + "archive/discussion-docs/mojaloop-decimal", + "Mojaloop Decimal Type" + ] + ] + }, + { + "title": "PI 7", + "collapsable": true, + "children": [ + [ + "archive/discussion-docs/workbench", + "Workbench Workstream" + ] + ] + } + ] + } + ], + "sidebarDepth": 4 + } + ], + "/v1.0.1/api/": [ + { + "title": "Mojaloop APIs", + "collapsable": false, + "children": [ + "" + ] + }, + { + "title": "FSPIOP API", + "collapsable": false, + "children": [ + { + "title": "Overview", + "path": "fspiop/" + }, + { + "title": "API Definitions", + "collapsable": false, + "path": "fspiop/definitions", + "children": [ + { + "title": "v1.1 (Current)", + "path": "fspiop/v1.1/api-definition" + }, + { + "title": "Older versions", + "path": "fspiop/v1.0/", + "children": [ + [ + "fspiop/v1.0/api-definition", + "v1.0" + ] + ] + } + ] + }, + { + "title": "Logical Data Model", + "path": "fspiop/logical-data-model", + "collapsable": true + }, + { + "title": "Generic Transaction Patterns", + "path": "fspiop/generic-transaction-patterns", + "collapsable": true + }, + { + "title": "Use Cases", + "path": "fspiop/use-cases" + }, + { + "title": "JSON Binding Rules", + "path": "fspiop/json-binding-rules" + }, + { + "title": "Scheme Rules", + "path": "fspiop/scheme-rules" + }, + { + "title": "PKI Best Practices", + "path": "fspiop/pki-best-practices" + }, + { + "title": "Signature (v1.1)", + "path": "fspiop/v1.1/signature" + }, + { + "title": "Encryption (v1.1)", + "path": "fspiop/v1.1/encryption" + }, + { + "title": "Glossary", + "path": "fspiop/glossary" + } + ], + "sidebarDepth": 4 + }, + { + "title": "Administration API", + "collapsable": false, + "children": [ + { + "title": "Overview", + "path": "administration/" + }, + { + "title": "Central Ledger API", + "path": "administration/central-ledger-api" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Settlement API", + "collapsable": false, + "children": [ + [ + "settlement/", + "Overview" + ] + ], + "sidebarDepth": 2 + }, + { + "title": "Thirdparty API", + "collapsable": false, + "path": "thirdparty/", + "children": [ + { + "title": "API Definitions", + "path": "fspiop/logical-data-model", + "collapsable": true + }, + { + "title": "Transaction Patterns", + "path": "thirdparty/transaction-patterns", + "collapsable": true, + "children": [ + { + "title": "Transaction Patterns Linking", + "path": "thirdparty/transaction-patterns-linking" + }, + { + "title": "Transaction Patterns Transfer", + "path": "thirdparty/transaction-patterns-transfer" + } + ] + }, + { + "title": "Data Models", + "path": "thirdparty/data-models", + "collapsable": true + } + ], + "sidebarDepth": 2 + }, + { + "title": "Glossary", + "collapsable": false, + "children": [ + [ + "fspiop/glossary", + "Overview" + ] + ] + } + ], + "/v1.0.1/technical/": [ + { + "title": "Mojaloop Hub", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "overview/" + }, + { + "title": "Current Architecture - PI 14", + "path": "overview/components-PI14" + }, + { + "title": "Current Architecture - PI 12", + "path": "overview/components-PI12" + }, + { + "title": "Current Architecture - PI 11", + "path": "overview/components-PI11" + }, + { + "title": "Current Architecture - PI 8", + "path": "overview/components-PI8" + }, + { + "title": "Current Architecture - PI 7", + "path": "overview/components-PI7" + }, + { + "title": "Current Architecture - PI 6", + "path": "overview/components-PI6" + }, + { + "title": "Current Architecture - PI 5", + "path": "overview/components-PI5" + }, + { + "title": "Current Architecture - PI 3", + "path": "overview/components-PI3" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Account Lookup Service", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "account-lookup-service/" + }, + { + "title": "GET Participants", + "path": "account-lookup-service/als-get-participants" + }, + { + "title": "POST Participants", + "path": "account-lookup-service/als-post-participants" + }, + { + "title": "POST Participants (Batch)", + "path": "account-lookup-service/als-post-participants-batch" + }, + { + "title": "DEL Participants", + "path": "account-lookup-service/als-del-participants" + }, + { + "title": "GET Parties", + "path": "account-lookup-service/als-get-parties" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Quoting Service", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "quoting-service/" + }, + { + "title": "GET Quote", + "path": "quoting-service/qs-get-quotes" + }, + { + "title": "POST Quote", + "path": "quoting-service/qs-post-quotes" + }, + { + "title": "GET Bulk Quote", + "path": "quoting-service/qs-get-bulk-quotes" + }, + { + "title": "POST Bulk Quote", + "path": "quoting-service/qs-post-bulk-quotes" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Transaction Requests Service", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "transaction-requests-service/" + }, + { + "title": "GET Transaction Requests", + "path": "transaction-requests-service/transaction-requests-get" + }, + { + "title": "POST Transaction Requests", + "path": "transaction-requests-service/transaction-requests-post" + }, + { + "title": "Authorizations", + "path": "transaction-requests-service/authorizations" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Central Event Processor Service", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "central-event-processor/" + }, + { + "title": "Event Handler (Placeholder)", + "path": "central-event-processor/event-handler-placeholder" + }, + { + "title": "Notiification Handler for Rejections", + "path": "central-event-processor/notification-handler-for-rejections" + }, + { + "title": "Signature Validation", + "path": "central-event-processor/signature-validation" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Event Framework", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "event-framework/" + }, + { + "title": "Event Stream Processor", + "path": "event-stream-processor/" + } + ], + "sidebarDepth": 2 + }, + { + "title": "Fraud Services", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "fraud-services/" + }, + { + "title": "Usage", + "path": "fraud-services/related-documents/documentation" + } + ], + "sidebarDepth": 2 + }, + { + "title": "SDK Scheme Adapter", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "sdk-scheme-adapter/" + }, + { + "title": "Usage", + "path": "sdk-scheme-adapter/usage/" + } + ], + "sidebarDepth": 2 + }, + { + "title": "ML Testing Toolkit", + "collapsable": true, + "children": [ + { + "title": "Overview", + "path": "ml-testing-toolkit/" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/README.md b/website/versioned_docs/v1.0.1/technical/README.md new file mode 100644 index 000000000..35d07fe6c --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/README.md @@ -0,0 +1,16 @@ +# Mojaloop Technical Overview + +## Mojaloop Services + +The basic idea behind Mojaloop is that we need to connect multiple Digital Financial Services Providers (DFSPs) together into a competitive and interoperable network in order to maximize opportunities for poor people to get access to financial services with low or no fees. We don't want a single monopoly power in control of all payments in a country, or a system that shuts out new players. It also doesn't help if there are too many isolated subnetworks. The following diagrams shows the Mojaloop interconnects between DFSPs and the Mojaloop Hub (schema implementation example) for a Peer-to-Peer (P2P) Transfer: + +Mojaloop addresses these issues in several key ways: +* A set of central services provides a hub through which money can flow from one DFSP to another. This is similar to how money moves through a central bank or clearing house in developed countries. Besides a central ledger, central services can provide identity lookup, fraud management, and enforce scheme rules. +* A standard set of interfaces a DFSP can implement to connect to the system, and example code that shows how to use the system. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* Complete working open-source implementations of both sides of the interfaces - an example DFSP that can send and receive payments and the client that an existing DFSP could host to connect to the network. + +![Mojaloop End-to-end Architecture Flow PI5](./assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg) + +The Mojaloop Hub is the primary container and reference we use to describe the Mojaloop ecosystem which is split in to the following domains: +* Mojaloop Open Source Services - Core Mojaloop Open Source Software (OSS) that has been supported by the Bill & Melinda Gates Foundation in partnership with the Open Source Community. +* Mojaloop Hub - Overall Mojaloop reference (and customizable) implementation for Hub Operators is based on the above OSS solution. \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/README.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/README.md new file mode 100644 index 000000000..4475e8255 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/README.md @@ -0,0 +1,128 @@ +--- +version: 1.1 +--- + + +# Account Lookup Service + +The **Account Lookup Service** (**ALS**) _(refer to section `6.2.1.2`)_ as per the [Mojaloop {{ $page.frontmatter.version }} Specification](/api) implements the following use-cases: + +* Participant Look-up +* Party Look-up +* Manage Participants Registry information + * Adding Participant Registry information + * Deleting Participant Registry information + +Use-cases that have been implemented over and above for Hub Operational use: +* Admin Operations + * Manage Oracle End-point Routing information + * Manage Switch End-point Routing information + +## 1. Design Considerations + +### 1.1. Account Lookup Service (ALS) +The ALS design provides a generic Central-Service component as part of the core Mojaloop. The purpose of this component is to provide routing and alignment to the Mojaloop API Specification. This component will support multiple Look-up registries (Oracles). This ALS will provide an Admin API to configure routing/config for each of the Oracles similiar to the Central-Service API for the End-point configuration for DFSP routing by the Notification-Handler (ML-API-Adapter Component). The ALS will in all intense purpose be a switch with a persistence store for the storage/management of the routing rules/config. + +#### 1.1.1. Assumptions + +* The ALS design will only cater for a single switch for the time being. +* Support for multiple switches will utilise the same DNS resolution mechanism that is being developed for the Cross Border/Network design. + +#### 1.1.2. Routing + +The routing configuration will be based on the following: +* PartyIdType - See section `7.5.6` of the Mojaloop Specification +* Currency - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, however `isDefault` indicator must be set to `true` if the `Currency` is not provided. +* isDefault - Indicator that a specific Oracle is the default provider for a specific PartyIdType. Note that there can be many default Oracles, but there can only be a single Oracle default for a specific PartyIdType. The default Oracle for a specific PartyIdType will only be selected if the originating request does not include a Currency filter. + + +### 1.2. ALS Oracle +The ALS Oracle be implemented as either a **Service** or **Adapter** (semantic dependant on use - Mediation = Adapter, Service = Implementation) will provide a look-up registry component with similar functionality of the `/participants` Mojaloop API resources. It has however loosely based on the ML API specification as it's interface implements a sync pattern which reduces the correlation/persistence requirements of the Async Callback pattern implemented directly by the ML API Spec. This will provide all ALS Oracle Services/Adapters with a standard interface which will be mediated by the ALS based on its routing configuration. +This component (or back-end systems) will also be responsible for the persistence & defaulting of the Participant details. + +## 2. Participant Lookup Design + +### 2.1. Architecture overview +![Architecture Flow Account-Lookup for Participants](./assets/diagrams/architecture/arch-flow-account-lookup-participants.svg) + +_Note: The Participant Lookup use-case similarly applies to for a Payee Initiated use-case such as transactionRequests. The difference being that the Payee is the initiation in the above diagram._ + +### 2.2. Sequence diagrams + +#### 2.2.1. GET Participants + +- [Sequence Diagram for GET Participants](als-get-participants.md) + +#### 2.2.2. POST Participants + +- [Sequence Diagram for POST Participants](als-post-participants.md) + +#### 2.2.3. POST Participants (Batch) + +- [Sequence Diagram for POST Participants (Batch)](als-post-participants-batch.md) + +#### 2.2.4. DEL Participants + +- [Sequence Diagram for DEL Participants](als-del-participants.md) + +## 3. Party Lookup Design + +### 3.1. Architecture overview +![Architecture Flow Account-Lookup for Parties](./assets/diagrams/architecture/arch-flow-account-lookup-parties.svg) + +### 3.2. Sequence diagram + +#### 3.2.1. GET Parties + +- [Sequence Diagram for GET Parties](als-get-parties.md) + +## 4. ALS Admin Design + +### 4.1. Architecture overview +![Architecture Flow Account-Lookup for Admin Get Oracles](./assets/diagrams/architecture/arch-flow-account-lookup-admin.svg) + +### 4.2. Sequence diagram + +#### 4.2.1 GET Oracles + +- [Sequence Diagram for GET Oracles](als-admin-get-oracles.md) + +#### 4.2.2 POST Oracle + +- [Sequence Diagram for POST Oracle](als-admin-post-oracles.md) + +#### 4.2.3 PUT Oracle + +- [Sequence Diagram for PUT Oracle](als-admin-put-oracles.md) + +#### 4.2.4 DELETE Oracle + +- [Sequence Diagram for DELETE Oracle](als-admin-del-oracles.md) + +#### 4.2.5 DELETE Endpoint Cache + +- [Sequence Diagram for DELETE Endpoint Cache](als-del-endpoint.md) + +## 5. Database Design + +### 5.1. ALS Database Schema + +#### Notes +- `partyIdType` - Values are currently seeded as per section _`7.5.6`_ [Mojaloop {{ $page.frontmatter.version }} Specification](./api). +- `currency` - See section `7.5.5` of the Mojaloop Specification. Currency code defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as three-letter alphabetic string. This will be optional, and must provide a "default" config if no Currency is either provided or provide a default if the Currency is provided, but only the "default" End-point config exists. +- `endPointType` - Type identifier for the end-point (e.g. `URL`) which provides flexibility for future transport support. +- `migration*` - Meta-data tables used by Knex Framework engine. +- A `centralSwitchEndpoint` must be associated to the `OracleEndpoint` by the Admin API upon insertion of a new `OracleEndpoint` record. If the `centralSwitchEndpoint` is not provided as part of the API Request, then it must be defaulted. + +![Acount Lookup Service ERD](./assets/entities/AccountLookupService-schema.png) + +* [Acount Lookup Service DBeaver ERD](./assets/entities/AccountLookupDB-schema-DBeaver.erd) +* [Acount Lookup Service MySQL Workbench Export](./assets/entities/AccountLookup-ddl-MySQLWorkbench.sql) + +## 6. ALS Oracle Design + +Detail design for the Oracle is out of scope for this document. The Oracle design and implementation is specific to each Oracle's requirements. + +### 6.1. API Specification + +Refer to **ALS Oracle API** in the [API Specifications](../../api/README.md#als-oracle-api) section. diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-del-oracles.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-del-oracles.md new file mode 100644 index 000000000..bb5426368 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-del-oracles.md @@ -0,0 +1,7 @@ +# DELETE Oracles + +Design for the Deletion of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-delete-oracle-7.3.4.svg](assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-get-oracles.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-get-oracles.md new file mode 100644 index 000000000..45be49841 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-get-oracles.md @@ -0,0 +1,7 @@ +# GET Oracles + +Design for getting a list of all Oracle Endpoints by the Hub Operator with the option of querying but currency and/or type. + +## Sequence Diagram + +![seq-acct-lookup-admin-get-oracle-7.3.1.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-post-oracles.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-post-oracles.md new file mode 100644 index 000000000..9f2b210e0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-post-oracles.md @@ -0,0 +1,7 @@ +# POST Oracles + +Design for the creation of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-post-oracle-7.3.2.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-put-oracles.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-put-oracles.md new file mode 100644 index 000000000..46446c731 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-admin-put-oracles.md @@ -0,0 +1,7 @@ +# PUT Oracles + +Design for the Update of an Oracle Endpoint by a Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-admin-put-oracle-7.3.3.svg](./assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-endpoint.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-endpoint.md new file mode 100644 index 000000000..e8123a537 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-endpoint.md @@ -0,0 +1,7 @@ +# DELETE Endpoint Cache + +Design for the disabling of an Oracle by the Hub Operator. + +## Sequence Diagram + +![seq-acct-lookup-del-endpoint-cache-7.3.0.svg](./assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-participants.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-participants.md new file mode 100644 index 000000000..7e2621e74 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-del-participants.md @@ -0,0 +1,11 @@ +# DEL Participants + +Design for the deletion of a Participant by a DFSP. + +## Notes + +- Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. ~ This has been addressed in the design by insuring that the Party currently belongs to the FSPs requesting the deletion of the record. Any other validations are out of scope for the Switch and should be addressed at the schema level. + +## Sequence Diagram + +![seq-acct-lookup-del-participants-7.1.2.svg](./assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-participants.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-participants.md new file mode 100644 index 000000000..8844c37c2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-participants.md @@ -0,0 +1,7 @@ +# GET Participants + +Design for the retrieval of a Participant by a DFSP. + +## Sequence Diagram + +![seq-acct-lookup-get-participants-7.1.0.svg](./assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-parties.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-parties.md new file mode 100644 index 000000000..02bc1c311 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-get-parties.md @@ -0,0 +1,7 @@ +# GET Parties + +Design for the retrieval of a Party by a DFSP. + +## Sequence Diagram + +![seq-acct-lookup-get-parties-7.2.0.svg](./assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants-batch.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants-batch.md new file mode 100644 index 000000000..9610b7a1d --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants-batch.md @@ -0,0 +1,13 @@ +# Sequence Diagram for POST Participants (Batch) + +Design for the creation of a Participant by a DFSP via a batch request. + +## Notes +- Operation only supports requests which contain: + - All Participant's FSPs match the FSPIOP-Source7 + - All Participant's will be of the same Currency, per the `POST /participants` call in the [Mojaloop FSPIOP API](/api/fspiop/v1.1/api-definition.html#post-participants) +- Duplicate POST Requests with matching TYPE and optional CURRENCY will be considered an __update__ operation. The existing record must be completely **replaced** in its entirety. + +## Sequence Diagram + +![seq-acct-lookup-post-participants-batch-7.1.1.svg](./assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants.md b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants.md new file mode 100644 index 000000000..bc7c3bd29 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/als-post-participants.md @@ -0,0 +1,7 @@ +# POST Participant + +Design for the creation of a Participant by a DFSP via a request. + +## Sequence Diagram + +![seq-acct-lookup-post-participants-7.1.3.svg](./assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg) diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/.gitkeep b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg new file mode 100644 index 000000000..d46ffa284 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-admin.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service Admin
    (ALS)
    Account Lookup Service Adm...
    HUB
    Backend



    HUB...
    Account Lookup Admin
    Account Lookup Admin
    HUB Operator
    HUB Operator
    A1. Request Oracle Endpoints 
    GET /oracles
    A1. Requ...
    A1.3. Return List of Oracles
    A1.3. Re...
    ALS
    DB
    ALS...
    Key
    Key
    A1.2. Lookup All Oracle Registry Service End-points 
    API
    Internal Use-Only
    API...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg new file mode 100644 index 000000000..2bb5d7029 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-participants.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Participants Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A5. Retrieve Participant End-points GET /participants/<participantId>/endpoints
    A1. Request Participant Lookup
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A3. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A4. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    A3. Alt
    A3. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A7. User Lookup
    PUT /participants/<idType>/<id>
    A7. User Lookup <br>PUT /participants/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A6. Retrieve Participant End-point Data
    A6. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    A2. Lookup Oracle Adapter/Service End-points based on <idType>
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg new file mode 100644 index 000000000..0dd8b76e6 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/architecture/arch-flow-account-lookup-parties.svg @@ -0,0 +1,3 @@ + + +
    Account Lookup Service
    (ALS)

    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)

    [Not supported by viewer]
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    Parties Account Lookup
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Party Store
    [Not supported by viewer]
    Party
    Store
    [Not supported by viewer]
    A10. Get 
    receiver 
    details
    [Not supported by viewer]
    Persistance store
    [Not supported by viewer]
    Central Ledger
    Service
    [Not supported by viewer]
    A7. Retrieve PayeeFSP Participant End-pointsGET /participants/<participantId>/endpoints
    A1. Request Party Lookup
    GET /parties/<idType>/<id>
    [Not supported by viewer]
    A4. Request Participant Lookup via Oracle
    GET /participants/<idType>/<id>
    [Not supported by viewer]
    A9. User Lookup
    GET /parties/<idType>/<id>
    A9. User Lookup <br>GET /parties/<idType>/<id>
    Oracle Merchant
    Registry Service
    <idType = 'BUSINESS'>
    [Not supported by viewer]
    A5. Alt
    [Not supported by viewer]

    <font color="#000000"><br></font>
    Persistance store
    [Not supported by viewer]
    Oracle Bank Account
    Registry Service
    <idType = 'ACCOUNT_ID'>
    [Not supported by viewer]
    A5. Alt
    A5. Alt

    <font color="#000000"><br></font>
    Oracle Pathfinder
    Registry Service
    Adapter
    <idType = 'MSISDN'>
    [Not supported by viewer]
    A5. Retrieve Participant Data
    [Not supported by viewer]

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    A4. Alt
    A4. Alt

    <font color="#000000"><br></font>
    Mojaloop Central Services
    [Not supported by viewer]
    A11. User Lookup
    PUT /parties/<idType>/<id>
    A11. User Lookup <br>PUT /parties/<idType>/<id>
    A14. User Lookup
    PUT /parties/<idType>/<id>
    A14. User Lookup <br>PUT /parties/<idType>/<id>
    Central Ledger DB
    Central Ledger DB
    A8. Retrieve Participant End-point Data
    A8. Retrieve Participant End-point Data

    <font color="#000000"><br></font>
    ALS
    DB
    [Not supported by viewer]
    Hub Operator Schema Hosted
    [Not supported by viewer]
    Externally Hosted
    [Not supported by viewer]
    PathFinder GSMA
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    A3. Lookup Oracle Registry ServiceEnd-points based on <idType>A12. Retrieve PayerFSP Participant End-pointsGET /participants/<participantId>/endpointsA6. Retrieve PayeeFSP Data for ValidationGET /participants/<participantId>(retrieve FSP Data)
    A13. Retrieve Participant End-point Data
    <font style="font-size: 13px">A13. Retrieve Participant End-point Data</font>
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml new file mode 100644 index 000000000..3a6a6eecb --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.puml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.4 Delete Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "DELETE Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Delete Oracle Endpoint -\nDELETE /oracles/{ID} + activate ALSADM + + ALSADM -> ORC_HANDLER: Delete Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Update existing Oracle Endpoint By ID + hnote over DB #lightyellow + Update isActive = false + end note + alt Delete existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Success + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + alt Delete existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Throws Error (Not Found) + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg new file mode 100644 index 000000000..6cbc84f40 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-delete-oracle-7.3.4.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + 7.3.4 Delete Oracle Endpoint + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + DELETE Oracle Handler + + + + + DELETE Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Delete Oracle Endpoint - + + + DELETE /oracles/{ID} + + + + + 2 + + + Delete Oracle Endpoint + + + + + 3 + + + Update existing Oracle Endpoint By ID + + + + Update isActive = false + + + + + alt + + + [Delete existing Oracle Endpoint (success)] + + + + + 4 + + + Return Success + + + + + 5 + + + Return success response + + + + + 6 + + + Return + + + HTTP Status: + + + 204 + + + + + alt + + + [Delete existing Oracle Endpoint (failure)] + + + + + 7 + + + Throws Error (Not Found) + + + + + 8 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 9 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml new file mode 100644 index 000000000..b800d83f9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.puml @@ -0,0 +1,116 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.1 Get All Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "Get Oracles Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoints + OPERATOR -> ALSADM: Request to GET all Oracle Endpoints -\nGET /oracles?currency=USD&type=MSISDN + activate ALSADM + + ALSADM -> ORC_HANDLER: Get Oracle Endpoints + activate ORC_HANDLER + ORC_HANDLER -> DB: Get oracle endpoints + activate DB + + alt Get Oracle Endpoints (success) + DB --> ORC_HANDLER: Return Oracle Endpoints + deactivate DB + + deactivate DB + ORC_HANDLER -> ALSADM: Return Oracle Endpoints + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + [ + { + "oracleId": , + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + ] + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 200 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Get Oracle Endpoints (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg new file mode 100644 index 000000000..7447557a3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-get-oracle-7.3.1.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + 7.3.1 Get All Oracle Endpoints + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + Get Oracles Handler + + + + + Get Oracles Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoints + + + + + 1 + + + Request to GET all Oracle Endpoints - + + + GET /oracles?currency=USD&type=MSISDN + + + + + 2 + + + Get Oracle Endpoints + + + + + 3 + + + Get oracle endpoints + + + + + alt + + + [Get Oracle Endpoints (success)] + + + + + 4 + + + Return Oracle Endpoints + + + + + 5 + + + Return Oracle Endpoints + + + + + Message: + + + { + + + [ + + + { + + + "oracleId": <string>, + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + ] + + + } + + + + + 6 + + + Return + + + HTTP Status: + + + 200 + + + + + alt + + + [Get Oracle Endpoints (failure)] + + + + + 7 + + + Throw Error + + + + + 8 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 9 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml new file mode 100644 index 000000000..083b0fac2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.puml @@ -0,0 +1,112 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.2 Create Oracle Endpoints + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "POST Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Create Oracle Endpoint -\nPOST /oracles + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Create Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> ORC_HANDLER: Build Oracle Endpoint Data Object + ORC_HANDLER -> DB: Insert Oracle Endpoint Data Object + activate DB + + alt Create Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 201 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Create Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg new file mode 100644 index 000000000..0638bdb48 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-post-oracle-7.3.2.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + 7.3.2 Create Oracle Endpoints + + + + Account Lookup Service + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + POST Oracle Handler + + + + + POST Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Create Oracle Endpoint - + + + POST /oracles + + + + + Message: + + + { + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + + + 2 + + + Create Oracle Endpoint + + + + + 3 + + + Build Oracle Endpoint Data Object + + + + + 4 + + + Insert Oracle Endpoint Data Object + + + + + alt + + + [Create Oracle Entry (success)] + + + + + 5 + + + Return success response + + + + + 6 + + + Return success response + + + + + 7 + + + Return + + + HTTP Status: + + + 201 + + + + + alt + + + [Create Oracle Entry (failure)] + + + + + 8 + + + Throw Error + + + + + 9 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 10 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml new file mode 100644 index 000000000..142eae685 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.puml @@ -0,0 +1,131 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.3 Update Oracle Endpoint + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS Admin Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service Admin API" as ALSADM +control "PUT Oracle Handler" as ORC_HANDLER +database "ALS Store" as DB + +box "Account Lookup Service" #LightYellow +participant ALSADM +participant ORC_HANDLER +participant DB +end box + +' start flow + +activate OPERATOR +group Get Oracle Endpoint + OPERATOR -> ALSADM: Request to Update Oracle Endpoint -\nPUT /oracles/{ID} + note left of ALSADM #yellow + Message: + { + "oracleIdType": , + "endpoint": { + "value": , + "endpointType": + }, + "currency": , + "isDefault": + } + end note + activate ALSADM + + ALSADM -> ORC_HANDLER: Update Oracle Endpoint + + activate ORC_HANDLER + ORC_HANDLER -> DB: Find existing Oracle Endpoint + alt Find existing Oracle Endpoint (success) + activate DB + DB -> ORC_HANDLER: Return Oracle Endpoint Result + deactivate DB + ORC_HANDLER -> ORC_HANDLER: Update Returned Oracle Data Object + ORC_HANDLER -> DB: Update Oracle Data Object + activate DB + alt Update Oracle Entry (success) + DB --> ORC_HANDLER: Return success response + deactivate DB + + ORC_HANDLER -> ALSADM: Return success response + deactivate ORC_HANDLER + ALSADM --> OPERATOR: Return HTTP Status: 204 + + deactivate ALSADM + deactivate OPERATOR + end + + alt Update Oracle Entry (failure) + DB --> ORC_HANDLER: Throw Error + deactivate DB + ORC_HANDLER -> ALSADM: Throw Error + deactivate ORC_HANDLER + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSADM --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSADM + deactivate OPERATOR + + + end + end + alt Find existing Oracle Endpoint (failure) + DB -> ORC_HANDLER: Returns Empty Object + ORC_HANDLER -> ALSADM: Throw Error + note left of ALSADM #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + ALSADM --> OPERATOR: Return HTTP Status: 502 + end +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg new file mode 100644 index 000000000..98da55c5c --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-admin-put-oracle-7.3.3.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + 7.3.3 Update Oracle Endpoint + + + + Account Lookup Service + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service Admin API + + + + + Account Lookup Service Admin API + + + + + PUT Oracle Handler + + + + + PUT Oracle Handler + + + + + ALS Store + + + + + ALS Store + + + + + + + + Get Oracle Endpoint + + + + + 1 + + + Request to Update Oracle Endpoint - + + + PUT /oracles/{ID} + + + + + Message: + + + { + + + "oracleIdType": <PartyIdType>, + + + "endpoint": { + + + "value": <string>, + + + "endpointType": <EndpointType> + + + }, + + + "currency": <Currency>, + + + "isDefault": <boolean> + + + } + + + + + 2 + + + Update Oracle Endpoint + + + + + 3 + + + Find existing Oracle Endpoint + + + + + alt + + + [Find existing Oracle Endpoint (success)] + + + + + 4 + + + Return Oracle Endpoint Result + + + + + 5 + + + Update Returned Oracle Data Object + + + + + 6 + + + Update Oracle Data Object + + + + + alt + + + [Update Oracle Entry (success)] + + + + + 7 + + + Return success response + + + + + 8 + + + Return success response + + + + + 9 + + + Return + + + HTTP Status: + + + 204 + + + + + alt + + + [Update Oracle Entry (failure)] + + + + + 10 + + + Throw Error + + + + + 11 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 12 + + + Return + + + HTTP Status: + + + 502 + + + + + alt + + + [Find existing Oracle Endpoint (failure)] + + + + + 13 + + + Returns Empty Object + + + + + 14 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 15 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml new file mode 100644 index 000000000..3095e7bad --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.puml @@ -0,0 +1,104 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.3.0 Delete Endpoint Cache + +autonumber + + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' control - ALS API Handler +' database - Database Persistent Store + +' declare actors +entity "HUB OPERATOR" as OPERATOR +boundary "Account Lookup Service API" as ALSAPI +control "Delete Endpoint Cache Handler" as DEL_HANDLER +database "Cache" as Cache + +box "Account Lookup Service" #LightYellow +participant ALSAPI +participant DEL_HANDLER +participant Cache +end box + +' start flow + +activate OPERATOR +group Delete Endpoint Cache + OPERATOR -> ALSAPI: Request to DELETE Endpoint Cache - DELETE /endpointcache + activate ALSAPI + activate ALSAPI + + ALSAPI -> DEL_HANDLER: Delete Cache + activate DEL_HANDLER + DEL_HANDLER -> Cache: Stop Cache + activate Cache + + + alt Stop Cache Status (success) + Cache --> DEL_HANDLER: Return status + deactivate Cache + + DEL_HANDLER -> Cache: Initialize Cache + activate Cache + Cache -> DEL_HANDLER: Return Status + deactivate Cache + DEL_HANDLER -> ALSAPI: Return Status + deactivate DEL_HANDLER + ALSAPI --> OPERATOR: Return HTTP Status: 202 + + deactivate ALSAPI + deactivate OPERATOR + end + + alt Validate Status (service failure) + Cache --> DEL_HANDLER: Throw Error + deactivate Cache + DEL_HANDLER -> ALSAPI: Throw Error + deactivate DEL_HANDLER + note left of ALSAPI #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + + ALSAPI --> OPERATOR: Return HTTP Status: 502 + + deactivate ALSAPI + deactivate OPERATOR + + + end +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg new file mode 100644 index 000000000..ab60d1d1b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-endpoint-cache-7.3.0.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + 7.3.0 Delete Endpoint Cache + + + + Account Lookup Service + + + + + + + + HUB OPERATOR + + + + + HUB OPERATOR + + + + + Account Lookup Service API + + + + + Account Lookup Service API + + + + + Delete Endpoint Cache Handler + + + + + Delete Endpoint Cache Handler + + + + + Cache + + + + + Cache + + + + + + + + + Delete Endpoint Cache + + + + + 1 + + + Request to DELETE Endpoint Cache - DELETE /endpointcache + + + + + 2 + + + Delete Cache + + + + + 3 + + + Stop Cache + + + + + alt + + + [Stop Cache Status (success)] + + + + + 4 + + + Return status + + + + + 5 + + + Initialize Cache + + + + + 6 + + + Return Status + + + + + 7 + + + Return Status + + + + + 8 + + + Return + + + HTTP Status: + + + 202 + + + + + alt + + + [Validate Status (service failure)] + + + + + 9 + + + Throw Error + + + + + 10 + + + Throw Error + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <Error Code>, + + + "errorDescription": <Msg>, + + + } + + + } + + + + + 11 + + + Return + + + HTTP Status: + + + 502 + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml new file mode 100644 index 000000000..978a1e303 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.2. Delete Participant Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +actor "Payee FSP" as PAYEE_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +entity "ALS Participant Endpoint\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +box "Financial Service Provider" #LightGrey +participant PAYEE_FSP +end box + +' START OF FLOW + +group Get Party Details + PAYER_FSP ->> ALS_API: Request to delete Participant details\nDEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to delete Participant details + + alt oracleEndpoint match found & parties information retrieved + activate ALS_PARTICIPANT_HANDLER + '********************* Retrieve Oracle Routing Information - START ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + '********************* Retrieve Oracle Routing Information - END ************************ + ||| + '********************* Retrieve Switch Routing Information - START ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref + '********************* Retrieve Switch Routing Information - END ************************ + + ||| + + '********************* Validate FSPIOP-Source Participant - START ************************ + group Validate FSPIOP-Source Participant + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request FSPIOP-Source participant information\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return FSPIOP-Source participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return FSPIOP-Source participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate FSPIOP-Source participant\nError code: 320x + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + end group + '********************* Validate Participant - END ************************ + + ||| + + '********************* Request Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Get Participant Information for PayerFSP\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Request Participant Information from Oracle Sequence]] + ||| + end ref + + '********************* Request Oracle Participant Information - END ************************ + + ||| + + '********************* Validate Participant Ownership - START ************************ + ' Reference section 6.2.2.4 - Note: The ALS should verify that it is the Party’s current FSP that is deleting the FSP information. Is this adequate? + group Validate Participant Ownership + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId matches Participant Information retrieved from Oracle.\nError code: 3100 + end group + '********************* Validate Participant - END ************************ + + ||| + + '********************* Delete Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Delete Oracle Participant Information - END ************************ + ||| + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return delete request result + ALS_API ->> PAYER_FSP: Callback indiciating success:\nPUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + else Validation failure or Oracle was unable process delete request + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + + else Empty list of switchEndpoint results returned + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg new file mode 100644 index 000000000..4612fee5f --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-del-participants-7.1.2.svg @@ -0,0 +1,632 @@ + + + + + + + + + + + 7.1.2. Delete Participant Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + Financial Service Provider + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant Endpoint + + + Oracle DAO + + + + + ALS Participant Endpoint + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS Parties + + + FSP DAO + + + + + ALS Parties + + + FSP DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + Payee FSP + + + + + Payee FSP + + + + + + + + Get Party Details + + + + 1 + + + Request to delete Participant details + + + DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to delete Participant details + + + + + alt + + + [oracleEndpoint match found & parties information retrieved] + + + + + 3 + + + Get Oracle Routing Config + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + + + 4 + + + Request FSPIOP-Source participant information + + + Error code: + + + 200x + + + + + 5 + + + GET - /participants/{FSPIOP-Source} + + + Error code: + + + 200x, 310x, 320x + + + + + 6 + + + Return FSPIOP-Source participant information + + + + + 7 + + + Return FSPIOP-Source participant information + + + + + 8 + + + Validate FSPIOP-Source participant + + + Error code: + + + 320x + + + + + 9 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + 10 + + + Get Participant Information for PayerFSP + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Request Participant Information from Oracle Sequence + + + + + + + Validate Participant Ownership + + + + + 11 + + + Validate that PARTICIPANT.fspId matches Participant Information retrieved from Oracle. + + + Error code: + + + 3100 + + + + + 12 + + + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Request to delete Participant's FSP details DEL - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 14 + + + Return result + + + + + 15 + + + Return result + + + + + 16 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x + + + + + 17 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Error code: + + + 200x, 310x, 320x + + + + + 18 + + + List of PayerFSP Participant Callback Endpoints + + + + + 19 + + + List of PayerFSP Participant Callback Endpoints + + + + + 20 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 21 + + + Return delete request result + + + + 22 + + + Callback indiciating success: + + + PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + + [Validation failure or Oracle was unable process delete request] + + + + + 23 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 24 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 25 + + + List of PayerFSP Participant Callback Endpoints + + + + + 26 + + + List of PayerFSP Participant Callback Endpoints + + + + + 27 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 28 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 29 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of switchEndpoint results returned] + + + + + 30 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml new file mode 100644 index 000000000..09be5f1df --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.plantuml @@ -0,0 +1,180 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.0. Get Participant Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS Endpoint Type\nConfig DAO" as ALS_TYPE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Participant Endpoint\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_TYPE_ENDPOINT_CONFIG_DAO +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Get Participant's FSP Details + + + PAYER_FSP ->> ALS_API: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to get participant's FSP details + + alt oracleEndpoint match found + group #lightskyblue IMPLEMENTATION: Get Oracle Routing Config Sequence [CACHED] + activate ALS_PARTICIPANT_HANDLER + ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Fetch Oracle Routing information based on\n{TYPE} and {CURRENCY} if provided\nError code: 200x + activate ALS_TYPE_ENDPOINT_CONFIG_DAO + ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Retrieve oracleEndpoint\nError code: 200x + activate ALS_DB + hnote over ALS_DB #lightyellow + oracleEndpoint + endpointType + partyIdType + currency (optional) + end note + ALS_DB --> ALS_TYPE_ENDPOINT_CONFIG_DAO: Return oracleEndpoint result set + deactivate ALS_DB + ALS_TYPE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of **oracleEndpoint** for the Participant + deactivate ALS_TYPE_ENDPOINT_CONFIG_DAO + opt #lightskyblue oracleEndpoint IS NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Error code: 3200 + end + end group + + group #lightskyblue IMPLEMENTATION: Request Participant Information from Oracle Sequence + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Request to get participant's FSP details \nGET - /participants/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate ORACLE_API + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return list of Participant information + deactivate ORACLE_API + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return list of Participant information + deactivate ALS_PARTICIPANT_ORACLE_DAO + end group + +' group #lightskyblue IMPLEMENTATION: Get Switch Routing Config Sequence [CACHED] +' note right of ALS_PARTICIPANT_HANDLER #lightgray +' **REFERENCE**: Get Oracle Routing Config Sequence: oracleEndpoint +' end note +' alt #lightskyblue oracleEndpoint IS NOT NULL +' ALS_PARTICIPANT_HANDLER -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Fetch Switch Routing information\nError code: 200x +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_DB: Retrieve switchEndpoint\nError code: 200x +' activate ALS_DB +' hnote over ALS_DB #lightyellow +' switchEndpoint +' endpointType +' end note +' ALS_DB -> ALS_TYPE_ENDPOINT_CONFIG_DAO: Return switchEndpoint result set +' deactivate ALS_DB +' ALS_TYPE_ENDPOINT_CONFIG_DAO -> ALS_PARTICIPANT_HANDLER: Return **switchEndpoint** +' else +' ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Error code: 2000 +' end alt +' end group + + '********************* Get PayerFSP Participant End-point Information - START ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + else oracleEndpoint IS NULL OR error occurred + + '********************* Get PayerFSP Participant End-point Information - START ************************ + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints. \nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else switchEndpoint IS NULL + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + deactivate ALS_API + + deactivate ALS_PARTICIPANT_HANDLER + +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg new file mode 100644 index 000000000..74687dae8 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-participants-7.1.0.svg @@ -0,0 +1,558 @@ + + + + + + + + + + + 7.1.0. Get Participant Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Endpoint Type + + + Config DAO + + + + + ALS Endpoint Type + + + Config DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Get Participant's FSP Details + + + + 1 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to get participant's FSP details + + + + + alt + + + [oracleEndpoint match found] + + + + + IMPLEMENTATION: Get Oracle Routing Config Sequence + + + [CACHED] + + + + + 3 + + + Fetch Oracle Routing information based on + + + {TYPE} and {CURRENCY} if provided + + + Error code: + + + 200x + + + + + 4 + + + Retrieve oracleEndpoint + + + Error code: + + + 200x + + + + oracleEndpoint + + + endpointType + + + partyIdType + + + currency (optional) + + + + + 5 + + + Return oracleEndpoint result set + + + + + 6 + + + List of + + + oracleEndpoint + + + for the Participant + + + + + opt + + + [oracleEndpoint IS NULL] + + + + + 7 + + + Error code: + + + 3200 + + + + + IMPLEMENTATION: Request Participant Information from Oracle Sequence + + + + + 8 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 310x, 320x + + + + + 9 + + + Request to get participant's FSP details + + + GET - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 10 + + + Return list of Participant information + + + + + 11 + + + Return list of Participant information + + + + + 12 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 14 + + + List of PayerFSP Participant Callback Endpoints + + + + + 15 + + + List of PayerFSP Participant Callback Endpoints + + + + + 16 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 17 + + + Return list of Participant information + + + + 18 + + + Callback: PUT - /participants/{TYPE}/{ID}?currency={CURRENCY} + + + + [oracleEndpoint IS NULL OR error occurred] + + + + + 19 + + + Retrieve the Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 20 + + + Retrieve the Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints. + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 21 + + + List of Participant Callback Endpoints + + + + + 22 + + + List of Participant Callback Endpoints + + + + + 23 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 24 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 25 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [switchEndpoint IS NULL] + + + + + 26 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml new file mode 100644 index 000000000..776445cc5 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.plantuml @@ -0,0 +1,215 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.2.0. Get Party Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +actor "Payee FSP" as PAYEE_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +'entity "ALS Participant Oracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +entity "ALS Parties\nFSP DAO" as ALS_PARTIES_FSP_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +participant ALS_PARTIES_FSP_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +box "Financial Service Provider" #LightGrey +participant PAYEE_FSP +end box + +' START OF FLOW + +group Get Party Details + PAYER_FSP ->> ALS_API: Request to get parties's FSP details\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 300x, 310x, 320x + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Request to get parties's FSP details + + alt oracleEndpoint match found & parties information retrieved + activate ALS_PARTICIPANT_HANDLER + '********************* Retrieve Oracle Routing Information - START ************************ + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + '********************* Retrieve Oracle Routing Information - END ************************ + ||| + '********************* Retrieve Switch Routing Information - START ************************ +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 200x, 310x, 320x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref + '********************* Retrieve Switch Routing Information - END ************************ + ||| + group Validate FSPIOP-Source Participant + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request FSPIOP-Source participant information\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{FSPIOP-Source}\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return FSPIOP-Source participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return FSPIOP-Source participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate FSPIOP-Source participant\nError code: 320x + end group + ||| + + '********************* Request Oracle Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ORACLE_API: Get Participant Information for PayeeFSP\nError code: 200x, 310x, 320x + ref over ALS_PARTICIPANT_HANDLER, ORACLE_API + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Request Participant Information from Oracle Sequence]] + ||| + end ref + + '********************* Request Oracle Participant Information - END ************************ + ||| + '********************* Request Parties Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTIES_FSP_DAO: Request Parties information from FSP.\nError code: 200x + + activate ALS_PARTIES_FSP_DAO + ALS_PARTIES_FSP_DAO ->> PAYEE_FSP: Parties Callback to Destination:\nGET - /parties/{TYPE}/{ID}?currency={CURRENCY}\nResponse code: 202\nError code: 200x, 310x, 320x + deactivate ALS_PARTIES_FSP_DAO + activate PAYEE_FSP + + PAYEE_FSP ->> ALS_API: Callback with Participant Information:\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY}\nError code: 200x, 300x, 310x, 320x + deactivate PAYEE_FSP + + ALS_API -> ALS_API: Validate request against\nMojaloop Interface Specification\nError code: 300x, 310x + ALS_API -> ALS_PARTICIPANT_HANDLER: Process Participant Callback Information for PUT + + '********************* Request Parties Information - END ************************ + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return Participant Information to PayerFSP + ALS_API ->> PAYER_FSP: Callback with Parties Information:\nPUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + else Empty list of End-Points returned for either (PayeeFSP or Oracle) config information or Error occurred for PayerFSP + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else Empty list of End-Points returned for PayerFSP config information or Error occurred for PayeeFSP + + '********************* Get PayeeFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayeeFSP Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayeeFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200\nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayeeFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayeeFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayeeFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYEE_FSP: Callback: PUT - /participants/{TYPE}/{ID}/error + else Empty list of switchEndpoint results returned + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Handle error\nError code: 200x + hnote right ALS_PARTICIPANT_HANDLER #red + Error Handling Framework + end note + end alt + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg new file mode 100644 index 000000000..7b3342d7b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-get-parties-7.2.0.svg @@ -0,0 +1,699 @@ + + + + + + + + + + + 7.2.0. Get Party Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + Financial Service Provider + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS Parties + + + FSP DAO + + + + + ALS Parties + + + FSP DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + Payee FSP + + + + + Payee FSP + + + + + + + + Get Party Details + + + + 1 + + + Request to get parties's FSP details + + + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Request to get parties's FSP details + + + + + alt + + + [oracleEndpoint match found & parties information retrieved] + + + + + 3 + + + Get Oracle Routing Config + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate FSPIOP-Source Participant + + + + + 4 + + + Request FSPIOP-Source participant information + + + Error code: + + + 200x + + + + + 5 + + + GET - /participants/{FSPIOP-Source} + + + Error code: + + + 200x, 310x, 320x + + + + + 6 + + + Return FSPIOP-Source participant information + + + + + 7 + + + Return FSPIOP-Source participant information + + + + + 8 + + + Validate FSPIOP-Source participant + + + Error code: + + + 320x + + + + + 9 + + + Get Participant Information for PayeeFSP + + + Error code: + + + 200x, 310x, 320x + + + + + ref + + + GET Participants - + + + + Request Participant Information from Oracle Sequence + + + + + + + 10 + + + Request Parties information from FSP. + + + Error code: + + + 200x + + + + 11 + + + Parties Callback to Destination: + + + GET - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Response code: + + + 202 + + + Error code: + + + 200x, 310x, 320x + + + + 12 + + + Callback with Participant Information: + + + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + 13 + + + Validate request against + + + Mojaloop Interface Specification + + + Error code: + + + 300x, 310x + + + + + 14 + + + Process Participant Callback Information for PUT + + + + + 15 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x + + + + + 16 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Error code: + + + 200x, 310x, 320x + + + + + 17 + + + List of PayerFSP Participant Callback Endpoints + + + + + 18 + + + List of PayerFSP Participant Callback Endpoints + + + + + 19 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT + + + + + 20 + + + Return Participant Information to PayerFSP + + + + 21 + + + Callback with Parties Information: + + + PUT - /parties/{TYPE}/{ID}?currency={CURRENCY} + + + + [Empty list of End-Points returned for either (PayeeFSP or Oracle) config information or Error occurred for PayerFSP] + + + + + 22 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 23 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 24 + + + List of PayerFSP Participant Callback Endpoints + + + + + 25 + + + List of PayerFSP Participant Callback Endpoints + + + + + 26 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + + + 27 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 28 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of End-Points returned for PayerFSP config information or Error occurred for PayeeFSP] + + + + + 29 + + + Retrieve the PayeeFSP Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 30 + + + Retrieve the PayeeFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 31 + + + List of PayeeFSP Participant Callback Endpoints + + + + + 32 + + + List of PayeeFSP Participant Callback Endpoints + + + + + 33 + + + Match PayeeFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR + + + + + 34 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 35 + + + Callback: PUT - /participants/{TYPE}/{ID}/error + + + + [Empty list of switchEndpoint results returned] + + + + + 36 + + + Handle error + + + Error code: + + + 200x + + + + Error Handling Framework + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml new file mode 100644 index 000000000..7769e3a8d --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.plantuml @@ -0,0 +1,213 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.3 Post Participant Details by Type and ID + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Post Participant's FSP Details + note right of PAYER_FSP #yellow + Headers - postParticipantsByTypeIDHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - postParticipantsByTypeIDMessage: + { + "fspId": "string" + } + end note + PAYER_FSP ->> ALS_API: Request to add participant's FSP details\nPOST - /participants/{Type}/{ID}\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Process create participant's FSP details + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + + '********************* Sort into Participant buckets based on {TYPE} - END ************************ + + alt Validation passed + + + '********************* Fetch Oracle Routing Information - START ************************ + + '********************* Retrieve Oracle Routing Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config based on Type (and optional Currency)\nError code: 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + + '********************* Retrieve Oracle Routing Information - END ************************ + + ||| + +' '********************* Fetch Oracle Routing Information - END ************************ +' +' '********************* Retrieve Switch Routing Information - START ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref +' +' '********************* Retrieve Switch Routing Information - END ************************ +' ||| + + '********************* Validate Participant - START ************************ + group Validate Participant's FSP + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request participant (PARTICIPANT.fspId) information for {Type}\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate participant\nError code: 320x + end group + '********************* Validate Participant - END ************************ + + '********************* Create Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Create participant's FSP details\nPOST - /participants\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Create participant's FSP details\nPOST - /participants\nResponse code: 204 \nError code: 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result of Participant Create request + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result of Participant Create request + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Create Participant Information - END ************************ + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information from ParticipantResult + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID} + + else Validation failure + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{Type}/{ID}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg new file mode 100644 index 000000000..07a5a256d --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-7.1.3.svg @@ -0,0 +1,598 @@ + + + + + + + + + + + 7.1.3 Post Participant Details by Type and ID + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Post Participant's FSP Details + + + + + Headers - postParticipantsByTypeIDHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - postParticipantsByTypeIDMessage: + + + { + + + "fspId": "string" + + + } + + + + 1 + + + Request to add participant's FSP details + + + POST - /participants/{Type}/{ID} + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Process create participant's FSP details + + + + + 3 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + alt + + + [Validation passed] + + + + + 4 + + + Get Oracle Routing Config based on Type (and optional Currency) + + + Error code: + + + 300x, 310x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + + + 5 + + + Request participant (PARTICIPANT.fspId) information for {Type} + + + Error code: + + + 200x + + + + + 6 + + + GET - /participants/{PARTICIPANT.fspId} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 7 + + + Return participant information + + + + + 8 + + + Return participant information + + + + + 9 + + + Validate participant + + + Error code: + + + 320x + + + + + 10 + + + Create participant's FSP details + + + POST - /participants + + + Error code: + + + 200x, 310x, 320x + + + + + 11 + + + Create participant's FSP details + + + POST - /participants + + + Response code: + + + 204 + + + Error code: + + + 200x, 310x, 320x + + + + + 12 + + + Return result of Participant Create request + + + + + 13 + + + Return result of Participant Create request + + + + + 14 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 15 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 16 + + + List of PayerFSP Participant Callback Endpoints + + + + + 17 + + + List of PayerFSP Participant Callback Endpoints + + + + + 18 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT + + + + + 19 + + + Return list of Participant information from ParticipantResult + + + + 20 + + + Callback: PUT - /participants/{Type}/{ID} + + + + [Validation failure] + + + + + 21 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 22 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 23 + + + List of PayerFSP Participant Callback Endpoints + + + + + 24 + + + List of PayerFSP Participant Callback Endpoints + + + + + 25 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR + + + + + 26 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 27 + + + Callback: PUT - /participants/{Type}/{ID}/error + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml new file mode 100644 index 000000000..c92838dc9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.plantuml @@ -0,0 +1,238 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Rajiv Mothilal + -------------- + ******'/ + + +@startuml +' declare title +title 7.1.1. Post Participant (Batch) Details + +autonumber +' Actor Keys: +' boundary - APIs/Interfaces, etc +' entity - Database Access Objects +' database - Database Persistence Store + +' declare actors +actor "Payer FSP" as PAYER_FSP +boundary "Account Lookup\nService (ALS)" as ALS_API +control "ALS Participant\nHandler" as ALS_PARTICIPANT_HANDLER +entity "ALS CentralService\nEndpoint DAO" as ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +entity "ALS CentralService\nParticipant DAO" as ALS_CENTRALSERVICE_PARTICIPANT_DAO +entity "ALS Participant\nOracle DAO" as ALS_PARTICIPANT_ORACLE_DAO +database "ALS Database" as ALS_DB +boundary "Oracle Service API" as ORACLE_API +boundary "Central Service API" as CENTRALSERVICE_API + +box "Financial Service Provider" #LightGrey +participant PAYER_FSP +end box + +box "Account Lookup Service" #LightYellow +participant ALS_API +participant ALS_PARTICIPANT_HANDLER +participant ALS_PARTICIPANT_ORACLE_DAO +participant ALS_DB +participant ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO +participant ALS_CENTRALSERVICE_PARTICIPANT_DAO +end box + +box "Central Services" #LightGreen +participant CENTRALSERVICE_API +end box + +box "ALS Oracle Service/Adapter" #LightBlue +participant ORACLE_API +end box + +' START OF FLOW + +group Post Participant's FSP Details + note right of PAYER_FSP #yellow + Headers - postParticipantsHeaders: { + Content-Length: , + Content-Type: , + Date: , + X-Forwarded-For: , + FSPIOP-Source: , + FSPIOP-Destination: , + FSPIOP-Encryption: , + FSPIOP-Signature: , + FSPIOP-URI: , + FSPIOP-HTTP-Method: + } + + Payload - postParticipantsMessage: + { + "requestId": "string", + "partyList": [ + { + "partyIdType": "string", + "partyIdentifier": "string", + "partySubIdOrType": "string", + "fspId": "string" + } + ], + "currency": "string" + } + end note + PAYER_FSP ->> ALS_API: Request to add participant's FSP details\nPOST - /participants\nResponse code: 202 \nError code: 200x, 300x, 310x, 320x + + activate ALS_API + note left ALS_API #lightgray + Validate request against + Mojaloop Interface Specification. + Error code: 300x, 310x + end note + + ALS_API -> ALS_PARTICIPANT_HANDLER: Process create participant's FSP details + deactivate ALS_API + activate ALS_PARTICIPANT_HANDLER + + '********************* Sort into Participant buckets based on {TYPE} - START ************************ + loop for Participant in ParticipantList + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate that PARTICIPANT.fspId == FSPIOP-Source\nError code: 3100 + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Group Participant lists into a Map (ParticipantMap) based on {TYPE} + + end loop + + '********************* Sort into Participant buckets based on {TYPE} - END ************************ + + alt Validation passed and the ParticipantMap was created successfully + + loop for keys in ParticipantMap -> TypeKey + + '********************* Fetch Oracle Routing Information - START ************************ + + '********************* Retrieve Oracle Routing Information - START ************************ + + ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Oracle Routing Config based on TypeKey (and optional Currency)\nError code: 300x, 310x + ref over ALS_PARTICIPANT_HANDLER, ALS_DB + GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Oracle Routing Config Sequence]] + ||| + end ref + + '********************* Retrieve Oracle Routing Information - END ************************ + + ||| + +' '********************* Fetch Oracle Routing Information - END ************************ +' +' '********************* Retrieve Switch Routing Information - START ************************ +' +' ALS_PARTICIPANT_HANDLER <-> ALS_DB: Get Switch Routing Config\nError code: 300x, 310x +' ref over ALS_PARTICIPANT_HANDLER, ALS_DB +' ||| +' GET Participants - [[https://docs.mojaloop.live/mojaloop-technical-overview/account-lookup-service/als-get-participants.html Get Switch Routing Config Sequence]] +' ||| +' end ref +' +' '********************* Retrieve Switch Routing Information - END ************************ +' ||| + + '********************* Validate Participant - START ************************ + group Validate Participant's FSP + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Request participant (PARTICIPANT.fspId) information for {TypeKey}\nError code: 200x + activate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_CENTRALSERVICE_PARTICIPANT_DAO -> CENTRALSERVICE_API: GET - /participants/{PARTICIPANT.fspId}\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_PARTICIPANT_DAO: Return participant information + deactivate CENTRALSERVICE_API + + ALS_CENTRALSERVICE_PARTICIPANT_DAO --> ALS_PARTICIPANT_HANDLER: Return participant information + + deactivate ALS_CENTRALSERVICE_PARTICIPANT_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Validate participant\nError code: 320x + end group + '********************* Validate Participant - END ************************ + + '********************* Create Participant Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_ORACLE_DAO: Create participant's FSP details\nPOST - /participants\nError code: 200x, 310x, 320x + activate ALS_PARTICIPANT_ORACLE_DAO + ALS_PARTICIPANT_ORACLE_DAO -> ORACLE_API: Create participant's FSP details\nPOST - /participants\nResponse code: 204 \nError code: 200x, 310x, 320x + activate ORACLE_API + + ORACLE_API --> ALS_PARTICIPANT_ORACLE_DAO: Return result of Participant Create request + deactivate ORACLE_API + + ALS_PARTICIPANT_ORACLE_DAO --> ALS_PARTICIPANT_HANDLER: Return result of Participant Create request + deactivate ALS_PARTICIPANT_ORACLE_DAO + + '********************* Create Participant Information - END ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Store results in ParticipantResultMap[TypeKey] + + end loop + + loop for keys in ParticipantResultMap -> TypeKey + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Combine ParticipantResultMap[TypeKey] results into ParticipantResult + end loop + + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match PayerFSP Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Return list of Participant information from ParticipantResult + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{requestId} + + else Validation failure and/or the ParticipantMap was not created successfully + '********************* Get PayerFSP Participant End-point Information - START ************************ + + ALS_PARTICIPANT_HANDLER -> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint\nError code: 200x, 310x, 320x + activate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO -> CENTRALSERVICE_API: Retrieve the PayerFSP Participant Callback Endpoint\nGET - /participants/{FSPIOP-Source}/endpoints\nResponse code: 200 \nError code: 200x, 310x, 320x + activate CENTRALSERVICE_API + CENTRALSERVICE_API --> ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO: List of PayerFSP Participant Callback Endpoints + deactivate CENTRALSERVICE_API + ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO --> ALS_PARTICIPANT_HANDLER: List of PayerFSP Participant Callback Endpoints + deactivate ALS_CENTRALSERVICE_ENDPOINT_CONFIG_DAO + + ALS_PARTICIPANT_HANDLER -> ALS_PARTICIPANT_HANDLER: Match Participant Callback Endpoints for\nFSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + '********************* Get PayerFSP Participant End-point Information - END ************************ + + ALS_PARTICIPANT_HANDLER --> ALS_API: Handle error\nError code: 200x, 310x, 320x + ALS_API ->> PAYER_FSP: Callback: PUT - /participants/{requestId}/error + end alt + + + deactivate ALS_PARTICIPANT_HANDLER +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg new file mode 100644 index 000000000..e3883aba0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/diagrams/sequence/seq-acct-lookup-post-participants-batch-7.1.1.svg @@ -0,0 +1,674 @@ + + + + + + + + + + + 7.1.1. Post Participant (Batch) Details + + + + Financial Service Provider + + + + Account Lookup Service + + + + Central Services + + + + ALS Oracle Service/Adapter + + + + + + + + + + Payer FSP + + + + + Payer FSP + + + + + Account Lookup + + + Service (ALS) + + + + + Account Lookup + + + Service (ALS) + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Handler + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Participant + + + Oracle DAO + + + + + ALS Database + + + + + ALS Database + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Endpoint DAO + + + + + ALS CentralService + + + Participant DAO + + + + + ALS CentralService + + + Participant DAO + + + + + Central Service API + + + + + Central Service API + + + + + Oracle Service API + + + + + Oracle Service API + + + + + + + + Post Participant's FSP Details + + + + + Headers - postParticipantsHeaders: { + + + Content-Length: <Content-Length>, + + + Content-Type: <Content-Type>, + + + Date: <Date>, + + + X-Forwarded-For: <X-Forwarded-For>, + + + FSPIOP-Source: <FSPIOP-Source>, + + + FSPIOP-Destination: <FSPIOP-Destination>, + + + FSPIOP-Encryption: <FSPIOP-Encryption>, + + + FSPIOP-Signature: <FSPIOP-Signature>, + + + FSPIOP-URI: <FSPIOP-URI>, + + + FSPIOP-HTTP-Method: <FSPIOP-HTTP-Method> + + + } + + + Payload - postParticipantsMessage: + + + { + + + "requestId": "string", + + + "partyList": [ + + + { + + + "partyIdType": "string", + + + "partyIdentifier": "string", + + + "partySubIdOrType": "string", + + + "fspId": "string" + + + } + + + ], + + + "currency": "string" + + + } + + + + 1 + + + Request to add participant's FSP details + + + POST - /participants + + + Response code: + + + 202 + + + Error code: + + + 200x, 300x, 310x, 320x + + + + + Validate request against + + + Mojaloop Interface Specification. + + + Error code: + + + 300x, 310x + + + + + 2 + + + Process create participant's FSP details + + + + + loop + + + [for Participant in ParticipantList] + + + + + 3 + + + Validate that PARTICIPANT.fspId == FSPIOP-Source + + + Error code: + + + 3100 + + + + + 4 + + + Group Participant lists into a Map (ParticipantMap) based on {TYPE} + + + + + alt + + + [Validation passed and the ParticipantMap was created successfully] + + + + + loop + + + [for keys in ParticipantMap -> TypeKey] + + + + + 5 + + + Get Oracle Routing Config based on TypeKey (and optional Currency) + + + Error code: + + + 300x, 310x + + + + + ref + + + GET Participants - + + + + Get Oracle Routing Config Sequence + + + + + + + Validate Participant's FSP + + + + + 6 + + + Request participant (PARTICIPANT.fspId) information for {TypeKey} + + + Error code: + + + 200x + + + + + 7 + + + GET - /participants/{PARTICIPANT.fspId} + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 8 + + + Return participant information + + + + + 9 + + + Return participant information + + + + + 10 + + + Validate participant + + + Error code: + + + 320x + + + + + 11 + + + Create participant's FSP details + + + POST - /participants + + + Error code: + + + 200x, 310x, 320x + + + + + 12 + + + Create participant's FSP details + + + POST - /participants + + + Response code: + + + 204 + + + Error code: + + + 200x, 310x, 320x + + + + + 13 + + + Return result of Participant Create request + + + + + 14 + + + Return result of Participant Create request + + + + + 15 + + + Store results in ParticipantResultMap[TypeKey] + + + + + loop + + + [for keys in ParticipantResultMap -> TypeKey] + + + + + 16 + + + Combine ParticipantResultMap[TypeKey] results into ParticipantResult + + + + + 17 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 18 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 19 + + + List of PayerFSP Participant Callback Endpoints + + + + + 20 + + + List of PayerFSP Participant Callback Endpoints + + + + + 21 + + + Match PayerFSP Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT + + + + + 22 + + + Return list of Participant information from ParticipantResult + + + + 23 + + + Callback: PUT - /participants/{requestId} + + + + [Validation failure and/or the ParticipantMap was not created successfully] + + + + + 24 + + + Retrieve the PayerFSP (FSPIOP-Source) Participant Callback Endpoint + + + Error code: + + + 200x, 310x, 320x + + + + + 25 + + + Retrieve the PayerFSP Participant Callback Endpoint + + + GET - /participants/{FSPIOP-Source}/endpoints + + + Response code: + + + 200 + + + Error code: + + + 200x, 310x, 320x + + + + + 26 + + + List of PayerFSP Participant Callback Endpoints + + + + + 27 + + + List of PayerFSP Participant Callback Endpoints + + + + + 28 + + + Match Participant Callback Endpoints for + + + FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR + + + + + 29 + + + Handle error + + + Error code: + + + 200x, 310x, 320x + + + + 30 + + + Callback: PUT - /participants/{requestId}/error + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql new file mode 100644 index 000000000..e538b6351 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookup-ddl-MySQLWorkbench.sql @@ -0,0 +1,195 @@ +-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64) +-- +-- Host: 127.0.0.1 Database: account_lookup +-- ------------------------------------------------------ +-- Server version 8.0.12 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `currency` +-- + +DROP TABLE IF EXISTS `currency`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `currency` ( + `currencyId` varchar(3) NOT NULL, + `name` varchar(128) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`currencyId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `currency` +-- + +LOCK TABLES `currency` WRITE; +/*!40000 ALTER TABLE `currency` DISABLE KEYS */; +INSERT INTO `currency` VALUES ('AED','UAE dirham',1,'2019-03-28 09:07:47'),('AFA','Afghanistan afghani (obsolete)',1,'2019-03-28 09:07:47'),('AFN','Afghanistan afghani',1,'2019-03-28 09:07:47'),('ALL','Albanian lek',1,'2019-03-28 09:07:47'),('AMD','Armenian dram',1,'2019-03-28 09:07:47'),('ANG','Netherlands Antillian guilder',1,'2019-03-28 09:07:47'),('AOA','Angolan kwanza',1,'2019-03-28 09:07:47'),('AOR','Angolan kwanza reajustado',1,'2019-03-28 09:07:47'),('ARS','Argentine peso',1,'2019-03-28 09:07:47'),('AUD','Australian dollar',1,'2019-03-28 09:07:47'),('AWG','Aruban guilder',1,'2019-03-28 09:07:47'),('AZN','Azerbaijanian new manat',1,'2019-03-28 09:07:47'),('BAM','Bosnia-Herzegovina convertible mark',1,'2019-03-28 09:07:47'),('BBD','Barbados dollar',1,'2019-03-28 09:07:47'),('BDT','Bangladeshi taka',1,'2019-03-28 09:07:47'),('BGN','Bulgarian lev',1,'2019-03-28 09:07:47'),('BHD','Bahraini dinar',1,'2019-03-28 09:07:47'),('BIF','Burundi franc',1,'2019-03-28 09:07:47'),('BMD','Bermudian dollar',1,'2019-03-28 09:07:47'),('BND','Brunei dollar',1,'2019-03-28 09:07:47'),('BOB','Bolivian boliviano',1,'2019-03-28 09:07:47'),('BRL','Brazilian real',1,'2019-03-28 09:07:47'),('BSD','Bahamian dollar',1,'2019-03-28 09:07:47'),('BTN','Bhutan ngultrum',1,'2019-03-28 09:07:47'),('BWP','Botswana pula',1,'2019-03-28 09:07:47'),('BYN','Belarusian ruble',1,'2019-03-28 09:07:47'),('BZD','Belize dollar',1,'2019-03-28 09:07:47'),('CAD','Canadian dollar',1,'2019-03-28 09:07:47'),('CDF','Congolese franc',1,'2019-03-28 09:07:47'),('CHF','Swiss franc',1,'2019-03-28 09:07:47'),('CLP','Chilean peso',1,'2019-03-28 09:07:47'),('CNY','Chinese yuan renminbi',1,'2019-03-28 09:07:47'),('COP','Colombian peso',1,'2019-03-28 09:07:47'),('CRC','Costa Rican colon',1,'2019-03-28 09:07:47'),('CUC','Cuban convertible peso',1,'2019-03-28 09:07:47'),('CUP','Cuban peso',1,'2019-03-28 09:07:47'),('CVE','Cape Verde escudo',1,'2019-03-28 09:07:47'),('CZK','Czech koruna',1,'2019-03-28 09:07:47'),('DJF','Djibouti franc',1,'2019-03-28 09:07:47'),('DKK','Danish krone',1,'2019-03-28 09:07:47'),('DOP','Dominican peso',1,'2019-03-28 09:07:47'),('DZD','Algerian dinar',1,'2019-03-28 09:07:47'),('EEK','Estonian kroon',1,'2019-03-28 09:07:47'),('EGP','Egyptian pound',1,'2019-03-28 09:07:47'),('ERN','Eritrean nakfa',1,'2019-03-28 09:07:47'),('ETB','Ethiopian birr',1,'2019-03-28 09:07:47'),('EUR','EU euro',1,'2019-03-28 09:07:47'),('FJD','Fiji dollar',1,'2019-03-28 09:07:47'),('FKP','Falkland Islands pound',1,'2019-03-28 09:07:47'),('GBP','British pound',1,'2019-03-28 09:07:47'),('GEL','Georgian lari',1,'2019-03-28 09:07:47'),('GGP','Guernsey pound',1,'2019-03-28 09:07:47'),('GHS','Ghanaian new cedi',1,'2019-03-28 09:07:47'),('GIP','Gibraltar pound',1,'2019-03-28 09:07:47'),('GMD','Gambian dalasi',1,'2019-03-28 09:07:47'),('GNF','Guinean franc',1,'2019-03-28 09:07:47'),('GTQ','Guatemalan quetzal',1,'2019-03-28 09:07:47'),('GYD','Guyana dollar',1,'2019-03-28 09:07:47'),('HKD','Hong Kong SAR dollar',1,'2019-03-28 09:07:47'),('HNL','Honduran lempira',1,'2019-03-28 09:07:47'),('HRK','Croatian kuna',1,'2019-03-28 09:07:47'),('HTG','Haitian gourde',1,'2019-03-28 09:07:47'),('HUF','Hungarian forint',1,'2019-03-28 09:07:47'),('IDR','Indonesian rupiah',1,'2019-03-28 09:07:47'),('ILS','Israeli new shekel',1,'2019-03-28 09:07:47'),('IMP','Isle of Man pound',1,'2019-03-28 09:07:47'),('INR','Indian rupee',1,'2019-03-28 09:07:47'),('IQD','Iraqi dinar',1,'2019-03-28 09:07:47'),('IRR','Iranian rial',1,'2019-03-28 09:07:47'),('ISK','Icelandic krona',1,'2019-03-28 09:07:47'),('JEP','Jersey pound',1,'2019-03-28 09:07:47'),('JMD','Jamaican dollar',1,'2019-03-28 09:07:47'),('JOD','Jordanian dinar',1,'2019-03-28 09:07:47'),('JPY','Japanese yen',1,'2019-03-28 09:07:47'),('KES','Kenyan shilling',1,'2019-03-28 09:07:47'),('KGS','Kyrgyz som',1,'2019-03-28 09:07:47'),('KHR','Cambodian riel',1,'2019-03-28 09:07:47'),('KMF','Comoros franc',1,'2019-03-28 09:07:47'),('KPW','North Korean won',1,'2019-03-28 09:07:47'),('KRW','South Korean won',1,'2019-03-28 09:07:47'),('KWD','Kuwaiti dinar',1,'2019-03-28 09:07:47'),('KYD','Cayman Islands dollar',1,'2019-03-28 09:07:47'),('KZT','Kazakh tenge',1,'2019-03-28 09:07:47'),('LAK','Lao kip',1,'2019-03-28 09:07:47'),('LBP','Lebanese pound',1,'2019-03-28 09:07:47'),('LKR','Sri Lanka rupee',1,'2019-03-28 09:07:47'),('LRD','Liberian dollar',1,'2019-03-28 09:07:47'),('LSL','Lesotho loti',1,'2019-03-28 09:07:47'),('LTL','Lithuanian litas',1,'2019-03-28 09:07:47'),('LVL','Latvian lats',1,'2019-03-28 09:07:47'),('LYD','Libyan dinar',1,'2019-03-28 09:07:47'),('MAD','Moroccan dirham',1,'2019-03-28 09:07:47'),('MDL','Moldovan leu',1,'2019-03-28 09:07:47'),('MGA','Malagasy ariary',1,'2019-03-28 09:07:47'),('MKD','Macedonian denar',1,'2019-03-28 09:07:47'),('MMK','Myanmar kyat',1,'2019-03-28 09:07:47'),('MNT','Mongolian tugrik',1,'2019-03-28 09:07:47'),('MOP','Macao SAR pataca',1,'2019-03-28 09:07:47'),('MRO','Mauritanian ouguiya',1,'2019-03-28 09:07:47'),('MUR','Mauritius rupee',1,'2019-03-28 09:07:47'),('MVR','Maldivian rufiyaa',1,'2019-03-28 09:07:47'),('MWK','Malawi kwacha',1,'2019-03-28 09:07:47'),('MXN','Mexican peso',1,'2019-03-28 09:07:47'),('MYR','Malaysian ringgit',1,'2019-03-28 09:07:47'),('MZN','Mozambique new metical',1,'2019-03-28 09:07:47'),('NAD','Namibian dollar',1,'2019-03-28 09:07:47'),('NGN','Nigerian naira',1,'2019-03-28 09:07:47'),('NIO','Nicaraguan cordoba oro',1,'2019-03-28 09:07:47'),('NOK','Norwegian krone',1,'2019-03-28 09:07:47'),('NPR','Nepalese rupee',1,'2019-03-28 09:07:47'),('NZD','New Zealand dollar',1,'2019-03-28 09:07:47'),('OMR','Omani rial',1,'2019-03-28 09:07:47'),('PAB','Panamanian balboa',1,'2019-03-28 09:07:47'),('PEN','Peruvian nuevo sol',1,'2019-03-28 09:07:47'),('PGK','Papua New Guinea kina',1,'2019-03-28 09:07:47'),('PHP','Philippine peso',1,'2019-03-28 09:07:47'),('PKR','Pakistani rupee',1,'2019-03-28 09:07:47'),('PLN','Polish zloty',1,'2019-03-28 09:07:47'),('PYG','Paraguayan guarani',1,'2019-03-28 09:07:47'),('QAR','Qatari rial',1,'2019-03-28 09:07:47'),('RON','Romanian new leu',1,'2019-03-28 09:07:47'),('RSD','Serbian dinar',1,'2019-03-28 09:07:47'),('RUB','Russian ruble',1,'2019-03-28 09:07:47'),('RWF','Rwandan franc',1,'2019-03-28 09:07:47'),('SAR','Saudi riyal',1,'2019-03-28 09:07:47'),('SBD','Solomon Islands dollar',1,'2019-03-28 09:07:47'),('SCR','Seychelles rupee',1,'2019-03-28 09:07:47'),('SDG','Sudanese pound',1,'2019-03-28 09:07:47'),('SEK','Swedish krona',1,'2019-03-28 09:07:47'),('SGD','Singapore dollar',1,'2019-03-28 09:07:47'),('SHP','Saint Helena pound',1,'2019-03-28 09:07:47'),('SLL','Sierra Leone leone',1,'2019-03-28 09:07:47'),('SOS','Somali shilling',1,'2019-03-28 09:07:47'),('SPL','Seborgan luigino',1,'2019-03-28 09:07:47'),('SRD','Suriname dollar',1,'2019-03-28 09:07:47'),('STD','Sao Tome and Principe dobra',1,'2019-03-28 09:07:47'),('SVC','El Salvador colon',1,'2019-03-28 09:07:47'),('SYP','Syrian pound',1,'2019-03-28 09:07:47'),('SZL','Swaziland lilangeni',1,'2019-03-28 09:07:47'),('THB','Thai baht',1,'2019-03-28 09:07:47'),('TJS','Tajik somoni',1,'2019-03-28 09:07:47'),('TMT','Turkmen new manat',1,'2019-03-28 09:07:47'),('TND','Tunisian dinar',1,'2019-03-28 09:07:47'),('TOP','Tongan pa\'anga',1,'2019-03-28 09:07:47'),('TRY','Turkish lira',1,'2019-03-28 09:07:47'),('TTD','Trinidad and Tobago dollar',1,'2019-03-28 09:07:47'),('TVD','Tuvaluan dollar',1,'2019-03-28 09:07:47'),('TWD','Taiwan New dollar',1,'2019-03-28 09:07:47'),('TZS','Tanzanian shilling',1,'2019-03-28 09:07:47'),('UAH','Ukrainian hryvnia',1,'2019-03-28 09:07:47'),('UGX','Uganda new shilling',1,'2019-03-28 09:07:47'),('USD','US dollar',1,'2019-03-28 09:07:47'),('UYU','Uruguayan peso uruguayo',1,'2019-03-28 09:07:47'),('UZS','Uzbekistani sum',1,'2019-03-28 09:07:47'),('VEF','Venezuelan bolivar fuerte',1,'2019-03-28 09:07:47'),('VND','Vietnamese dong',1,'2019-03-28 09:07:47'),('VUV','Vanuatu vatu',1,'2019-03-28 09:07:47'),('WST','Samoan tala',1,'2019-03-28 09:07:47'),('XAF','CFA franc BEAC',1,'2019-03-28 09:07:47'),('XAG','Silver (ounce)',1,'2019-03-28 09:07:47'),('XAU','Gold (ounce)',1,'2019-03-28 09:07:47'),('XCD','East Caribbean dollar',1,'2019-03-28 09:07:47'),('XDR','IMF special drawing right',1,'2019-03-28 09:07:47'),('XFO','Gold franc',1,'2019-03-28 09:07:47'),('XFU','UIC franc',1,'2019-03-28 09:07:47'),('XOF','CFA franc BCEAO',1,'2019-03-28 09:07:47'),('XPD','Palladium (ounce)',1,'2019-03-28 09:07:47'),('XPF','CFP franc',1,'2019-03-28 09:07:47'),('XPT','Platinum (ounce)',1,'2019-03-28 09:07:47'),('YER','Yemeni rial',1,'2019-03-28 09:07:47'),('ZAR','South African rand',1,'2019-03-28 09:07:47'),('ZMK','Zambian kwacha (obsolete)',1,'2019-03-28 09:07:47'),('ZMW','Zambian kwacha',1,'2019-03-28 09:07:47'),('ZWD','Zimbabwe dollar (initial)',1,'2019-03-28 09:07:47'),('ZWL','Zimbabwe dollar (3rd denomination)',1,'2019-03-28 09:07:47'),('ZWN','Zimbabwe dollar (1st denomination)',1,'2019-03-28 09:07:47'),('ZWR','Zimbabwe dollar (2nd denomination)',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `currency` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `endpointType` +-- + +DROP TABLE IF EXISTS `endpointType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `endpointType` ( + `endpointTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type` varchar(50) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`endpointTypeId`), + UNIQUE KEY `endpointtype_type_unique` (`type`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `endpointType` +-- + +LOCK TABLES `endpointType` WRITE; +/*!40000 ALTER TABLE `endpointType` DISABLE KEYS */; +INSERT INTO `endpointType` VALUES (1,'URL','REST URLs',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `endpointType` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration` +-- + +DROP TABLE IF EXISTS `migration`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `batch` int(11) DEFAULT NULL, + `migration_time` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration` +-- + +LOCK TABLES `migration` WRITE; +/*!40000 ALTER TABLE `migration` DISABLE KEYS */; +INSERT INTO `migration` VALUES (1,'01_currency.js',1,'2019-03-28 11:07:46'),(2,'02_endpointType.js',1,'2019-03-28 11:07:46'),(3,'03_endpointType-indexes.js',1,'2019-03-28 11:07:46'),(4,'04_partyIdType.js',1,'2019-03-28 11:07:46'),(5,'05_partyIdType-indexes.js',1,'2019-03-28 11:07:46'),(6,'08_oracleEndpoint.js',1,'2019-03-28 11:07:47'),(7,'09_oracleEndpoint-indexes.js',1,'2019-03-28 11:07:47'); +/*!40000 ALTER TABLE `migration` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `migration_lock` +-- + +DROP TABLE IF EXISTS `migration_lock`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `migration_lock` ( + `index` int(10) unsigned NOT NULL AUTO_INCREMENT, + `is_locked` int(11) DEFAULT NULL, + PRIMARY KEY (`index`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `migration_lock` +-- + +LOCK TABLES `migration_lock` WRITE; +/*!40000 ALTER TABLE `migration_lock` DISABLE KEYS */; +INSERT INTO `migration_lock` VALUES (1,0); +/*!40000 ALTER TABLE `migration_lock` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `oracleEndpoint` +-- + +DROP TABLE IF EXISTS `oracleEndpoint`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `oracleEndpoint` ( + `oracleEndpointId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `partyIdTypeId` int(10) unsigned NOT NULL, + `endpointTypeId` int(10) unsigned NOT NULL, + `currencyId` varchar(255) DEFAULT NULL, + `value` varchar(512) NOT NULL, + `isDefault` tinyint(1) NOT NULL DEFAULT '0', + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` varchar(128) NOT NULL, + PRIMARY KEY (`oracleEndpointId`), + KEY `oracleendpoint_currencyid_foreign` (`currencyId`), + KEY `oracleendpoint_partyidtypeid_index` (`partyIdTypeId`), + KEY `oracleendpoint_endpointtypeid_index` (`endpointTypeId`), + CONSTRAINT `oracleendpoint_currencyid_foreign` FOREIGN KEY (`currencyId`) REFERENCES `currency` (`currencyid`), + CONSTRAINT `oracleendpoint_endpointtypeid_foreign` FOREIGN KEY (`endpointTypeId`) REFERENCES `endpointType` (`endpointtypeid`), + CONSTRAINT `oracleendpoint_partyidtypeid_foreign` FOREIGN KEY (`partyIdTypeId`) REFERENCES `partyIdType` (`partyidtypeid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `oracleEndpoint` +-- + +LOCK TABLES `oracleEndpoint` WRITE; +/*!40000 ALTER TABLE `oracleEndpoint` DISABLE KEYS */; +/*!40000 ALTER TABLE `oracleEndpoint` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `partyIdType` +-- + +DROP TABLE IF EXISTS `partyIdType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `partyIdType` ( + `partyIdTypeId` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` varchar(512) NOT NULL, + `isActive` tinyint(1) NOT NULL DEFAULT '1', + `createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`partyIdTypeId`), + UNIQUE KEY `partyidtype_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `partyIdType` +-- + +LOCK TABLES `partyIdType` WRITE; +/*!40000 ALTER TABLE `partyIdType` DISABLE KEYS */; +INSERT INTO `partyIdType` VALUES (1,'MSISDN','A MSISDN (Mobile Station International Subscriber Directory Number, that is, the phone number) is used as reference to a participant. The MSISDN identifier should be in international format according to the ITU-T E.164 standard. Optionally, the MSISDN may be prefixed by a single plus sign, indicating the international prefix.',1,'2019-03-28 09:07:47'),(2,'EMAIL','An email is used as reference to a participant. The format of the email should be according to the informational RFC 3696.',1,'2019-03-28 09:07:47'),(3,'PERSONAL_ID','A personal identifier is used as reference to a participant. Examples of personal identification are passport number, birth certificate number, and national registration number. The identifier number is added in the PartyIdentifier element. The personal identifier type is added in the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(4,'BUSINESS','A specific Business (for example, an organization or a company) is used as reference to a participant. The BUSINESS identifier can be in any format. To make a transaction connected to a specific username or bill number in a Business, the PartySubIdOrType element should be used.',1,'2019-03-28 09:07:47'),(5,'DEVICE','A specific device (for example, a POS or ATM) ID connected to a specific business or organization is used as reference to a Party. For referencing a specific device under a specific business or organization, use the PartySubIdOrType element.',1,'2019-03-28 09:07:47'),(6,'ACCOUNT_ID','A bank account number or FSP account ID should be used as reference to a participant. The ACCOUNT_ID identifier can be in any format, as formats can greatly differ depending on country and FSP.',1,'2019-03-28 09:07:47'),(7,'IBAN','A bank account number or FSP account ID is used as reference to a participant. The IBAN identifier can consist of up to 34 alphanumeric characters and should be entered without whitespace.',1,'2019-03-28 09:07:47'),(8,'ALIAS','An alias is used as reference to a participant. The alias should be created in the FSP as an alternative reference to an account owner. Another example of an alias is a username in the FSP system. The ALIAS identifier can be in any format. It is also possible to use the PartySubIdOrType element for identifying an account under an Alias defined by the PartyIdentifier.',1,'2019-03-28 09:07:47'); +/*!40000 ALTER TABLE `partyIdType` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-03-28 11:09:54 diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd new file mode 100644 index 000000000..ea177ae89 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupDB-schema-DBeaver.erd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png new file mode 100644 index 000000000..bdca208cd Binary files /dev/null and b/website/versioned_docs/v1.0.1/technical/account-lookup-service/assets/entities/AccountLookupService-schema.png differ diff --git a/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg new file mode 100644 index 000000000..d87484a3c --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI5.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Ledger
    Central-Ledger
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg new file mode 100644 index 000000000..f75130984 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-PI6.svg @@ -0,0 +1,3 @@ + + +
    Mojaloop Adapter
    Mojaloop Adapter
    Central-Services
    (Ledger - API, Handlers)
    Central-Services<br>(Ledger - API, Handlers)<br>
    Mojaloop
    Adapter
    [Not supported by viewer]
    C 1. Transfer
    C 1. Transfer
    request_to_prepare
    request_to_prepare
    C 1.2
    [Not supported by viewer]
    C 1.3
    [Not supported by viewer]
    prepared.notification
    prepared.notification
    C 1.4
    C 1.4
    fulfiled.notification
    fulfiled.notification
    request_to_fulfil
    request_to_fulfil
    Fulfil Transfer
    Fulfil Transfer
    C 1.8
    C 1.8
    C 1.9
    [Not supported by viewer]
    C 1.10
    [Not supported by viewer]
    C 1.11
    C 1.11
    C 1.12 Fulfil Notify
    C 1.12 Fulfil Notify
    C 1.1
    C 1.1
    C 1.5
    C 1.5
    DB
    DB
    Mojaloop
    Open Source Services
    [Not supported by viewer]
    positions
    positions
    Account Lookup Service
    (Parties / Participant)
    [Not supported by viewer]
    FSP
    Backend

    (Does not natively speak Mojaloop API)



    [Not supported by viewer]
    Scheme-Adapter

    (Converts from Mojaloop API to backend FSP API)
    [Not supported by viewer]
    A 2. MSISDN
    based lookup
    A 2. MSISDN <br>based lookup
    DB
    DB
     Database
     Database
    FSP
    Backend
      

    (Natively speaks Mojaloop API)



    [Not supported by viewer]
    A
    A
    A 1. User Lookup
    A 1. User Lookup
    A 3. Receiver Details
    A 3. Receiver Details
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based
    lookup
    A 2. mID based <br>lookup
    B 1. Quote
    B 1. Quote
    Mojaloop Hub
    <font>Mojaloop Hub<br></font>
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    kafka
    C 1.6
    Prepare
    Transfer
    [Not supported by viewer]
    C 1.7
    C 1.7
    C 1.11
    C 1.11
    C 1.12
    C 1.12
    Fulfil Notify
    Fulfil Notify
    C 1.13
    Fulfil Notify
    [Not supported by viewer]
    B 2. Fee /
    Commission
    [Not supported by viewer]
    A 4. Get 
    receiver 
    details
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    D 6.
    D 6.
    Central-Settlement
    Central-Settlement
    D 5. Update Positions
    [Not supported by viewer]
    settlement.notifications
    settlement.notifications
    kafka
    kafka
    Scheme Settlement Processor
    <span>Scheme Settlement Processor</span><br>
    Hub Operator
    Hub Operator
    D 1. Create
    Settlement
    [Not supported by viewer]
    D
    D
    D 2. Query
    Settlement
    Report
    (Pull)
    [Not supported by viewer]
    D 4. Send
    Acks
    (Push)
    [Not supported by viewer]
    Settlement
    Bank
    Settlement<br>Bank<br>
    D 3. Process Settlements
    [Not supported by viewer]
    Bank
    [Not supported by viewer]
    D 7. Position Notifications Change result
    D 7. Position Notifications Change result
    D 7. Settlement Notification
    D 7. Settlement Notification
    kafka
    kafka
    GSMA
    [Not supported by viewer]
    (Schema customised by Hub Operator)
    [Not supported by viewer]
    Pathfinder
    [Not supported by viewer]
    ALS Oracle MSISDN Adapter
    [Not supported by viewer]
    ALS Oracle Merchant Service
    [Not supported by viewer]
    API
    Internal Use-Only
    API <br>Internal Use-Only
    Mojaloop API
    Specification v1.0
    Mojaloop API<br>Specification v1.0<br>
    Key
    [Not supported by viewer]
    Quoting-Service
    Quoting-Service
    ALS Oracle Simulator
    [Not supported by viewer]
    A 2. *ID based
    lookup
    A 2. *ID based <br>lookup
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg new file mode 100644 index 000000000..a2fbbe512 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/Arch-Mojaloop-end-to-end-simple.svg @@ -0,0 +1,3 @@ + + +
    C 4. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Account Lookup Services
    [Not supported by viewer]
    Pathfinder
    Pathfinder
    FSP
    Backend


    (Does not natively speak Mojaloop API)








    [Not supported by viewer]
    S
    c
    h
    e
    m
    e

    A
    d
    a
    p
    t
    e
    r

    [Not supported by viewer]
    A 2. MSISDN based lookup
    A 2. MSISDN based lookup
    FSP
    Backend
      

    (Natively speaks Mojaloop API)









    [Not supported by viewer]
    A
    A
    A 1. User
    Lookup
    A 1. User <br>Lookup
    B
    B
    Merchant 
    Registry
    [Not supported by viewer]
    A 2. mID based lookup
    A 2. mID based lookup
    Mojaloop Hub
    [Not supported by viewer]
    Payer FSP
    [Not supported by viewer]
    Payee FSP
    [Not supported by viewer]
    Ledger
    Ledger<br>
    Ledger
    Ledger<br>
    C
    C
    C 1. Transfer
        Prepare
    [Not supported by viewer]
    A 3. Receiver
    Details
    A 3. Receiver<br>Details<br>
     Fee /
    Comm
    [Not supported by viewer]
    Get Receiver
    Details
    [Not supported by viewer]
     C 2. Transfer
    Prepare
    [Not supported by viewer]
    C 5. Transfer
    Fulfil Notify
    [Not supported by viewer]
    Transfer
    Prepare
    [Not supported by viewer]
    C 3. Transfer
    Fulfil
    C 3. Transfer<br>Fulfil<br>
    Transfer
    Fulfil
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote
    Central Services
    [Not supported by viewer]
    B 1. Quote
    B 1. Quote<br>
    Settlement Provider
    Settlement Provider
    Hub Operator
    Hub Operator
    D 1. Create Settlement
    D 1. Create Settlement
    D
    D
    D 2. Query Settlement Report
    (Pull)
    D 2. Query Settlement Report<br>(Pull)<br>
    D 3. Send Acknowledgements
    (Push)
    D 3. Send Acknowledgements<br>(Push)<br>
    Quoting Service
    <font style="font-size: 18px">Quoting Service</font>
    Central Services
    • Transfers
    • Settlements
    • Auditing
    • Notifications
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/central_ledger_block_diagram.png b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/central_ledger_block_diagram.png new file mode 100644 index 000000000..48199cf3e Binary files /dev/null and b/website/versioned_docs/v1.0.1/technical/assets/diagrams/architecture/central_ledger_block_diagram.png differ diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/README.md b/website/versioned_docs/v1.0.1/technical/central-event-processor/README.md new file mode 100644 index 000000000..45b2203f8 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/README.md @@ -0,0 +1,13 @@ +# Central Event Processor Service + +The Central Event Processor (CEP) service provides the capability to monitor for a pre-defined/configured set of business rules or patterns. + +In the current iteration, the rules are set to monitor for three criteria: + + 1. Breaching of a threshold on the Limit of Net Debit Cap (which may be set as part of on-boarding), + 2. Adjustment of the limit - Net Debit Cap, + 3. Adjust of position based on a Settlement. + +The CEP can then be integrated with a notifier service, to send out notifications or alerts. In this instance, it integrates with the email-notifier to send out alerts based on the aforementioned criteria. + +![Central Event Processor Architecture](./assets/diagrams/architecture/CEPArchTechOverview.svg) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg new file mode 100644 index 000000000..40e9f3ae0 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/architecture/CEPArchTechOverview.svg @@ -0,0 +1,2 @@ + +


    Notifiers
    /email, sms, etc./
    [Not supported by viewer]
    ML-Adapter
    [Not supported by viewer]
    prepare 
    [Not supported by viewer]
    fulfil 
    [Not supported by viewer]
    notification 
    <b>notification </b>

    DB
    [Not supported by viewer]
    Central-Services
    Central-Services

    MangoDB
    [Not supported by viewer]
    Central Event
    Processor (CEP)

    [Not supported by viewer]
    RxJS
    RxJS
    json-rule-engine
    json-rule-engine

    Heading

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    [Not supported by viewer]
    REST admin API
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml new file mode 100644 index 000000000..d01340e1f --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.plantuml @@ -0,0 +1,94 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + -------------- + ******'/ + +@startuml +' declate title +title 9.1.0. Event Handler Placeholder + +autonumber + +' Actor Keys: +' boundary - APIs/Interfaces, etc +' collections - Kafka Topics +' control - Kafka Consumers +' entity - Database Access Objects +' database - Database Persistance Store + +' declare actors +control "Event Handler Placeholder" as EVENT_HANDLER + +box "Event Handler Placeholder" #LightGray + participant EVENT_HANDLER +end box + +collections "Event-Topic" as TOPIC_EVENTS + +' start flow +activate EVENT_HANDLER + +group Event Handler Placeholder + EVENT_HANDLER -> TOPIC_EVENTS: Consume Event message \n Error code: 2001 + note right of EVENT_HANDLER #yellow + Message: + { + from: , + to: , + type: application/json, + content: { + headers: , + payload: + }, + metadata: { + event: { + id: , + type: INFO, + action: AUDIT, + createdAt: , + state: { + status: "success", + code: 0 + } + } + } + } + end note + note right of EVENT_HANDLER #LightGray + The type would be an ENUM with values: + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + Possible values for "action" would be + [AUDIT, EXCEPTION] + The event messages can be handled based on the values of these two variables + (when the placeholder is extended). + end note + EVENT_HANDLER -> EVENT_HANDLER: Auto-commit \n Error code: 2001 + note right of EVENT_HANDLER #lightBlue + Currently events to only be published as part of the placeholder. + This can be evolved to add relevant functionality. + end note + activate TOPIC_EVENTS + deactivate TOPIC_EVENTS +end +deactivate EVENT_HANDLER + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg new file mode 100644 index 000000000..3f48ce80a --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-event-9.1.0.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + 9.1.0. Event Handler Placeholder + + + + Event Handler Placeholder + + + + + + Event Handler Placeholder + + + + + Event Handler Placeholder + + + + + + + Event-Topic + + + + + Event-Topic + + + + + + Event Handler Placeholder + + + + + 1 + + + Consume Event message + + + Error code: + + + 2001 + + + + + Message: + + + { + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + headers: <transferHeaders>, + + + payload: <transferMessage> + + + }, + + + metadata: { + + + event: { + + + id: <uuid>, + + + type: INFO, + + + action: AUDIT, + + + createdAt: <timestamp>, + + + state: { + + + status: "success", + + + code: 0 + + + } + + + } + + + } + + + } + + + + + The type would be an ENUM with values: + + + [INFO, DEBUG, ERROR, WARN, FATAL, TRACE] + + + Possible values for "action" would be + + + [AUDIT, EXCEPTION] + + + The event messages can be handled based on the values of these two variables + + + (when the placeholder is extended). + + + + + 2 + + + Auto-commit + + + Error code: + + + 2001 + + + + + Currently events to only be published as part of the placeholder. + + + This can be evolved to add relevant functionality. + + diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml new file mode 100644 index 000000000..38e5e7dd3 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.plantuml @@ -0,0 +1,111 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Georgi Georgiev + * Henk Kodde + -------------- + ******'/ + +@startuml +' declate title +title 5.1.1. Notification Handler for Rejections + +autonumber + +' Actor Keys: + +' declare actors + +actor "DFSP1\nPayer" as DFSP1 +control "ML API Notification Event Handler" as NOTIFY_HANDLER +boundary "Central Service API" as CSAPI +collections "Event-Topic" as TOPIC_EVENT +collections "Notification-Topic" as TOPIC_NOTIFICATIONS + +box "Financial Service Providers" #lightGray + participant DFSP1 +end box + +box "ML API Adapter Service" #LightBlue + participant NOTIFY_HANDLER +end box + +box "Central Service" #LightYellow + participant CSAPI + participant TOPIC_EVENT + participant TOPIC_NOTIFICATIONS +end box + +' start flow + +group DFSP Notified of Rejection + activate NOTIFY_HANDLER + NOTIFY_HANDLER -> TOPIC_NOTIFICATIONS: Consume Notification event message \n Error code: 2001 + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + group Persist Event Information + NOTIFY_HANDLER -> TOPIC_EVENT: Publish event information \n Error code: 3201 + activate TOPIC_EVENT + ref over TOPIC_EVENT : Event Handler + deactivate TOPIC_EVENT + end + + alt consume a single messages + group Validate Event + NOTIFY_HANDLER <-> NOTIFY_HANDLER: Validate event - Rule: type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + end + NOTIFY_HANDLER -> CSAPI: Request Participant Callback details \n Error code: 3201 + ref over NOTIFY_HANDLER, CSAPI: Get Participant Callback Details + NOTIFY_HANDLER <-- CSAPI: Return Participant Callback details + note left of NOTIFY_HANDLER #yellow + Message: + { + id: , + from: , + to: , + type: application/json, + content: { + payload: + }, + } + end note + NOTIFY_HANDLER --> DFSP1: Send Callback Notification \n Error code: 1000, 1001, 3002 + else Validate rule type != 'notification' / Error + note right of NOTIFY_HANDLER #yellow + Message: + { + "errorInformation": { + "errorCode": , + "errorDescription": , + } + } + end note + NOTIFY_HANDLER -> TOPIC_EVENT: Invalid messages retrieved from the Notification Topic \n Error code: 3201 + activate TOPIC_EVENT + deactivate TOPIC_EVENT + ref over TOPIC_EVENT: Event Handler + note right of NOTIFY_HANDLER #lightblue + Log ERROR Messages + Update Event log upon ERROR notification + end note +' deactivate TOPIC_NOTIFICATIONS + end +end +@enduml \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg new file mode 100644 index 000000000..6eb610b07 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-notification-reject-5.1.1.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + 5.1.1. Notification Handler for Rejections + + + + Financial Service Providers + + + + ML API Adapter Service + + + + Central Service + + + + + + + + + DFSP1 + + + Payer + + + + + DFSP1 + + + Payer + + + + + ML API Notification Event Handler + + + + + ML API Notification Event Handler + + + + + Central Service API + + + + + Central Service API + + + + + + + Event-Topic + + + + + Event-Topic + + + + + Notification-Topic + + + + + Notification-Topic + + + + + + DFSP Notified of Rejection + + + + + 1 + + + Consume Notification event message + + + Error code: + + + 2001 + + + + + Persist Event Information + + + + + 2 + + + Publish event information + + + Error code: + + + 3201 + + + + + ref + + + Event Handler + + + + + alt + + + [consume a single messages] + + + + + Validate Event + + + + + 3 + + + Validate event - Rule: type == 'notification' && [action IN ['reject', 'timeout-received', 'timeout-reserved']] + + + + + 4 + + + Request Participant Callback details + + + Error code: + + + 3201 + + + + + ref + + + Get Participant Callback Details + + + + + 5 + + + Return Participant Callback details + + + + + Message: + + + { + + + id: <ID>, + + + from: <transferHeaders.FSPIOP-Source>, + + + to: <transferHeaders.FSPIOP-Destination>, + + + type: application/json, + + + content: { + + + payload: <transferMessage> + + + }, + + + } + + + + + 6 + + + Send Callback Notification + + + Error code: + + + 1000, 1001, 3002 + + + + [Validate rule type != 'notification' / Error] + + + + + Message: + + + { + + + "errorInformation": { + + + "errorCode": <errorCode>, + + + "errorDescription": <ErrorMessage>, + + + } + + + } + + + + + 7 + + + Invalid messages retrieved from the Notification Topic + + + Error code: + + + 3201 + + + + + ref + + + Event Handler + + + + + Log ERROR Messages + + + Update Event log upon ERROR notification + + diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml new file mode 100644 index 000000000..03a932865 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.plantuml @@ -0,0 +1,35 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Samuel Kummary + * Rajiv Mothilal + -------------- + ******'/ + +@startuml +' declare title +title Signature Validation + +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: another authentication Response +@enduml \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg new file mode 100644 index 000000000..4e80c45ca --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/assets/diagrams/sequence/seq-signature-validation.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + Signature Validation + + + + + Alice + + + + Alice + + + + Bob + + + + Bob + + + + + Authentication Request + + + + + Authentication Response + + + + + Another authentication Request + + + + + another authentication Response + + diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/event-handler-placeholder.md b/website/versioned_docs/v1.0.1/technical/central-event-processor/event-handler-placeholder.md new file mode 100644 index 000000000..38904e3d2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/event-handler-placeholder.md @@ -0,0 +1,7 @@ +# Event Handler Placeholder + +Sequence design diagram for the Event Handler process. + +## Sequence Diagram + +![seq-event-9.1.0.svg](./assets/diagrams/sequence/seq-event-9.1.0.svg) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/notification-handler-for-rejections.md b/website/versioned_docs/v1.0.1/technical/central-event-processor/notification-handler-for-rejections.md new file mode 100644 index 000000000..258ef5fb7 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/notification-handler-for-rejections.md @@ -0,0 +1,12 @@ +# Notification Handler for Rejections + +Sequence design diagram for the Notification Handler for Rejections process. + +## References within Sequence Diagram + +* [Event Handler Consume (9.1.0)](9.1.0-event-handler-placeholder.md) +* [Get Participant Callback Details (3.1.0)](../central-ledger/admin-operations/3.1.0-post-participant-callback-details.md) + +## Sequence Diagram + +![seq-notification-reject-5.1.1.svg](./assets/diagrams/sequence/seq-notification-reject-5.1.1.svg) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/central-event-processor/signature-validation.md b/website/versioned_docs/v1.0.1/technical/central-event-processor/signature-validation.md new file mode 100644 index 000000000..e4aabbbe7 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/central-event-processor/signature-validation.md @@ -0,0 +1,7 @@ +# Signature Validation + +Sequence design diagram for the Signature Validation process. + +## Sequence Diagram + +![seq-signature-validation.svg](./assets/diagrams/sequence/seq-signature-validation.svg) \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-framework/README.md b/website/versioned_docs/v1.0.1/technical/event-framework/README.md new file mode 100644 index 000000000..d1a0f5ece --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-framework/README.md @@ -0,0 +1,233 @@ +# Event Framework + +The purpose of the Event Framework is to provide a standard unified architecture to capture all Mojaloop events. + +_Disclaimer: This is experimental and is being implemented as a PoC. As such the design may change based on the evolution of the PoC's implementation, and any lessons learned._ + + +## 1. Requirements + +- Events will be produced by utilising a standard common library that will publish events to a sidecar component utilising a light-weight highly performant protocol (e.g. gRPC). +- Sidecar module will publish events to a singular Kafka topic that will allow for multiple handlers to consume and process the events as required. +- Kafka partitions will be determined by the event-type (e.g. log, audit, trace, errors etc). +- Each Mojaloop component will have its own tightly coupled Sidecar. +- Event messages will be produced to Kafka using the Trace-Id as the message key. This will ensure that all the messages part of the same trace (transaction) are stored in the same partition in order. + + +## 2. Architecture + +### 2.1 Overview + +![Event Framework Architecture](./assets/diagrams/architecture/architecture-event-framework.svg) + +### 2.2 Micro Service Pods + +![Pod Architecture](./assets/diagrams/architecture/architecture-event-sidecar.svg) + +### 2.3 Event Flow + +![Tracing Architecture](./assets/diagrams/architecture/architecture-event-trace.svg) + + +## 3. Event Envelope Model + +## 3.1 JSON Example + +```JSON +{ + "from": "noresponsepayeefsp", + "to": "payerfsp", + "id": "aa398930-f210-4dcd-8af0-7c769cea1660", + "content": { + "headers": { + "content-type": "application/vnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "noresponsepayeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": "data:application/vnd.interoperability.transfers+json;version=1.0;base64,ewogICJmdWxmaWxtZW50IjogIlVObEo5OGhaVFlfZHN3MGNBcXc0aV9VTjN2NHV0dDdDWkZCNHlmTGJWRkEiLAogICJjb21wbGV0ZWRUaW1lc3RhbXAiOiAiMjAxOS0wNS0yOVQyMzoxODozMi44NTZaIiwKICAidHJhbnNmZXJTdGF0ZSI6ICJDT01NSVRURUQiCn0" + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7-3978-408e-ae2e-a13012c47739", + "parentSpanId": "4e3ce424-d611-417b-a7b3-44ba9bbc5840", + "spanId": "efeb5c22-689b-4d04-ac5a-2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } +} +``` + +## 3.2 Schema Definition + +### 3.2.1 Object Definition: EventMessage + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | The id references the related message. | | +| from | string | N | If the value is not present in the destination, it means that the notification was generated by the connected node (server). | | +| to | string | Y | Mandatory for the sender and optional in the destination. The sender can ommit the value of the domain. | | +| pp | string | N | Optional for the sender, when is considered the identity of the session. Is mandatory in the destination if the identity of the originator is different of the identity of the from property. | | +| metadata | object `` | N | The sender should avoid to use this property to transport any kind of content-related information, but merely data relevant to the context of the communication. Consider to define a new content type if there's a need to include more content information into the message. | | +| type | string | Y | `MIME` declaration of the content type of the message. | | +| content | object \ | Y | The representation of the content. | | + +##### 3.2.1.1 Object Definition: MessageMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| event | object `` | Y | Event information. | | +| trace | object `` | Y | Trace information. | | + +##### 3.2.1.2 Object Definition: EventMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| id | string | Y | Generated UUIDv4 representing the event. | 3920382d-f78c-4023-adf9-0d7a4a2a3a2f | +| type | enum `` | Y | Type of event. | [`log`, `audit`, `error` `trace`] | +| action | enum `` | Y | Type of action. | [ `start`, `end` ] | +| createdAt | timestamp | Y | ISO Timestamp. | 2019-05-29T23:18:32.935Z | +| responseTo | string | N | UUIDv4 id link to the previous parent event. | 2019-05-29T23:18:32.935Z | +| state | object `` | Y | Object describing the state. | | + +##### 3.2.1.3 Object Definition: EventStateMetadata + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| status | enum `` | Y | The id references the related message. | success | +| code | number | N | The error code as per Mojaloop specification. | 2000 | +| description | string | N | Description for the status. Normally used to include an description for an error. | Generic server error to be used in order not to disclose information that may be considered private. | + +##### 3.2.1.4 Object Definition: EventTraceMetaData + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| service | string | Y | Name of service producing trace | central-ledger-prepare-handler | +| traceId | 32HEXDIGLC | Y | The end-to-end transaction identifier. | 664314d5b207d3ba722c6c0fdcd44c61 | +| spanId | 16HEXDIGLC | Y | Id for a processing leg identifier for a component or function. | 81fa25e8d66d2e88 | +| parentSpanId | 16HEXDIGLC | N | The id references the related message. | e457b5a2e4d86bd1 | +| sampled | number | N | Indicator if event message should be included in the trace `1`. If excluded it will be left the consumer to decide on sampling. | 1 | +| flags | number | N | Indicator if event message should be included in the trace flow. ( Debug `1` - this will override the sampled value ) | 0 | +| startTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the start timestamp of a span.| 2015-08-29T11:22:09.815479Z | +| finishTimestamp | datetime | N | ISO 8601 with the following format `yyyy-MM-dd'T'HH:mm:ss.SSSSSSz`. If not included the current timestamp will be taken. Represents the finish timestamp of a span | 2015-08-29T11:22:09.815479Z | +| tags | object `` | Y | The id references the related message. | success | + +_Note: HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lower case hex character. Ref: [WC3 standard for trace-context](https://www.w3.org/TR/trace-context/#field-value)._ + +##### 3.2.1.5 Object Definition: EventTraceMetaDataTags + +| Name | Type | Mandatory (Y/N) | Description | Example | +| --- | --- | --- | --- | --- | +| transactionId | string | N | Transaction Id representing either a transfer, quote, etc | 659ee338-c8f8-4c06-8aff-944e6c5cd694 | +| transactionType | string | N | The transaction type represented by the transactionId. E.g. (transfer, quote, etc) | transfer | +| parentEventType | string | N | The event-type of the parent Span. | bulk-prepare | +| parentEventAction | string | N | The event-action of the parent Span. | prepare | +| tracestate | string | N | This tag is set if EventSDK environmental variable `EVENT_SDK_TRACESTATE_HEADER_ENABLED` is `true` or if parent span context has the `tracestate` header or tag included. The tag holds updated `tracestate` header value as per the W3C trace headers specification. [More here](#411-wc3-http-headers)| `congo=t61rcWkgMzE,rojo=00f067aa0ba902b7` | +| `` | string | N | Arbitary Key-value pair for additional meta-data to be added to the trace information. | n/a | + +##### 3.2.1.6 Enum: EventStatusType + +| Enum | Description | +| --- | --- | +| success | Event was processed successfully | +| fail | Event was processed with a failure or error | + +##### 3.2.1.7 Enum: EventType + +| Enum | Description | +| --- | --- | +| log | Event representing a general log entry. | +| audit | Event to be signed and persisted into the audit store. | +| trace | Event containing trace context information to be persisted into the tracing store. | + +##### 3.2.1.8 Enum: LogEventAction + +| Enum | Description | +| --- | --- | +| info | Event representing an `info` level log entry. | +| debug | Event representing a `debug` level log entry. | +| error | Event representing an `error` level log entry. | +| verbose | Event representing a `verbose` level log entry. | +| warning | Event representing a `warning` level log entry. | +| performance | Event representing a `performance` level log entry. | + +##### 3.2.1.9 Enum: AuditEventAction + +| Enum | Description | +| --- | --- | +| default | Standard audit action. | +| start | Audit action to represent the start of a process. | +| finish | Audit action to represent the end of a process. | +| ingress | Audit action to capture ingress activity. | +| egress | Audit action to capture egress activity. | + +##### 3.2.1.10 Enum: TraceEventAction + +| Enum | Description | +| --- | --- | +| span | Event action representing a span of a trace. | + + +## 4. Tracing Design + +### 4.1 HTTP Transports + +Below find the current proposed standard HTTP Transport headers for tracing. + +Mojaloop has yet to standardise on either standard, or if it will possible support both. + +#### 4.1.1 W3C Http Headers + +Refer to the following publication for more information: https://w3c.github.io/trace-context/ + +| Header | Description | Example | +| --- | --- | --- | +| traceparent | Dash delimited string of tracing information: \-\-\-\ | 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00 | +| tracestate | Comma delimited vendor specific format captured as follows: \=\| congo=t61rcWkgMzE,rojo=00f067aa0ba902b7 | + +Note: Before this specification was written, some tracers propagated X-B3-Sampled as true or false as opposed to 1 or 0. While you shouldn't encode X-B3-Sampled as true or false, a lenient implementation may accept them. + +Note: (Event-SDK)[https://github.com/mojaloop/event-sdk] since version v9.4.1 has methods to add key value tags in the tracestate, and since version v9.5.2 the tracestate is base64 encoded. To be able to use the tracestate consistently, use matching versions across all services in a system. + +#### 4.1.2 B3 HTTP Headers + +Refer to the following publication for more information: https://github.com/apache/incubator-zipkin-b3-propagation + +| Header | Description | Example | +| --- | --- | --- | +| X-B3-TraceId | Encoded as 32 or 16 lower-hex characters. | a 128-bit TraceId header might look like: X-B3-TraceId: 463ac35c9f6413ad48485a3953bb6124. Unless propagating only the Sampling State, the X-B3-TraceId header is required. | +| X-B3-SpanId | Encoded as 16 lower-hex characters. | a SpanId header might look like: X-B3-SpanId: a2fb4a1d1a96d312. Unless propagating only the Sampling State, the X-B3-SpanId header is required. | +| X-B3-ParentSpanId | header may be present on a child span and must be absent on the root span. It is encoded as 16 lower-hex characters. | A ParentSpanId header might look like: X-B3-ParentSpanId: 0020000000000001 | +| X-B3-Sampled | An accept sampling decision is encoded as `1` and a deny as `0`. Absent means defer the decision to the receiver of this header. | A Sampled header might look like: X-B3-Sampled: 1. | +| X-B3-Flags | Debug is encoded as `1`. Debug implies an accept decision, so don't also send the X-B3-Sampled header. | | + +### 4.2 Kafka Transports + +Refer to `Event Envelope Model` section. This defines the message that will be sent through the Kafka transport. + +Alternatively the tracing context could be stored in Kafka headers which are only supports v0.11 or later. Note that this would break support for older versions of Kafka. + +### 4.3 Known limitations + +- Transfer tracing would be limited to each of the transfer legs (i.e. Prepare and Fulfil) as a result of the Mojaloop API specification not catering for tracing information. The trace information will be send as part of the callbacks by the Switch, but the FSPs will not be required to respond appropriately with a reciprocal trace headers. diff --git a/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg new file mode 100644 index 000000000..47c2c4acb --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-framework.svg @@ -0,0 +1,3 @@ + + +
    Central-Ledger
    (API)
    Central-Ledger<br>(API)<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    Handler #
    Central-Ledger<br>Handler #<br>
    Central-Ledger
    (Handler #)
    Central-Ledger<br>(Handler #)<br>

    <div style="text-align: left ; font-size: 8px"><br></div>
    ML-API-Adapter
    (API)
    ML-API-Adapter<br>(API)<br>
    Central-Settlements
    (API)
    Central-Settlements<br>(API)<br>
    ML-API-Adapter
    (Handler)
    ML-API-Adapter<br>(Handler)<br>
    Quoting-Service
    (API)
    Quoting-Service<br>(API)<br>
    Account-Lookup-Service
    (API)
    Account-Lookup-Service<br>(API)<br>

    <div style="text-align: left"><br></div>
    Message Types:
    - Tracing
    - Audit
    - Logs
    [Not supported by viewer]
    <div style="text-align: center"></div>
    Kafka
    (Event Stream)
    topic-events
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar

    <div style="text-align: left ; font-size: 8px"><br></div>
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    EFK
    (Elasticsearch, Fluentd, 
    Kibana & APM)
    [Not supported by viewer]
    Forensic-Logging
    (Future - re-factored from Side-Car into Service for Batch Audits)
    [Not supported by viewer]
    Central-KMS
    Central-KMS
    Audits
    Audits
    Keys
    Keys
    Partitioned by Trace-Id
    [Not supported by viewer]
    Event-stream-processor
    (Mediation,  Translation)
    [Not supported by viewer]
    Open-Tracing
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]

    <div style="text-align: left ; font-size: 8px"><br></div>
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    log, trace, audit
    [Not supported by viewer]
    Key provisioning
    [Not supported by viewer]
    Key provisioning
    [Not supported by viewer]
    Message Types:
    - Tracing
    - Audit
    - Logs
    [Not supported by viewer]
    Message Types:
    - Audits
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg new file mode 100644 index 000000000..b274a9d3a --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-sidecar.svg @@ -0,0 +1,3 @@ + + +

    <div style="text-align: left"><br></div>
    POD #2
    POD #2
    Service #2
    Service #2<br>
    POD #1
    POD #1
    <div style="text-align: center"></div>
    Kafka
    (Event Stream)
    topic-events
    [Not supported by viewer]
    Kubernetes Cluster
    [Not supported by viewer]
    Event Framework
    SideCar
    Event Framework<br>SideCar<br>
    gRPC Server
    gRPC Server
    gRPC Client
    gRPC Client
    Kafka
    Client
    [Not supported by viewer]
    Partitioned by Trace-Id
    [Not supported by viewer]
    Service #1
    Service #1<br>
    Event Framework
    SideCar
    Event Framework<br>SideCar<br>
    gRPC Server
    gRPC Server
    gRPC Client
    gRPC Client
    Kafka
    Client
    [Not supported by viewer]
    @mojaloop/
    event-sdk
    @mojaloop/<br>event-sdk
    Event Framework Sidecar included as part of each component Helm Chart
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg new file mode 100644 index 000000000..5fd81ccfb --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-framework/assets/diagrams/architecture/architecture-event-trace.svg @@ -0,0 +1,3 @@ + + +
    Sidecar
    Sidecar
    Sidecar
    Sidecar
    Service
    Consumer 
    Service...
    Parent Span
    Parent Span
    Trace
    Trace
    Start
    Start
    End
    End
    Child Span
    Child Span
    Start
    Start
    End
    End
    Child Span
    Child Span
    Start
    Start
    End
    End
    Trace Context
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tracestate
    Trace Context...
    Service
    Producer 
    Service...
    Tags: [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination: payeeFsp, tracestate: mojaloop=f32c19568004ce8b ]
    Tags: [ transactionId: transferId, transactionType: transfer, source: payerFsp, destination: payeeFsp, tracestate: mojaloop=f32c19568004ce...
    Child Span
    Child Span
    Start
    Start
    End
    End
    Message Transport
    - HTTP
    - Kafka

    Message Transport...
    Error
    Error
    Kafka
    (Event Topic)
    Kafka...
    Event Sidecar
    Event Sidecar
    Event Sidecar
    Event Sidecar
    Record Trace
    Record...
    Service A
    Service A
    Service B
    Service B
    Trace Message
    - traceId
    - spanId
    - parentId
    - sampled
    - flags
    - tags
    - tracestate
    - content / error
    Trace Message...
    Record Trace
    Record...
    Record Trace
    Record...
    Record Trace
    Record...
    Record Error
    Record...
    Audit
    Audit
    Record
    Audit
    Record...
    Log
    Log
    Record Log
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    Record
    Audit
    Record...
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-stream-processor/README.md b/website/versioned_docs/v1.0.1/technical/event-stream-processor/README.md new file mode 100644 index 000000000..645e221fc --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-stream-processor/README.md @@ -0,0 +1,18 @@ +# Event Stream Processor Service + +Event Stream Processor consumes event messages from the `topic-events` topic as a result of messages published by the [event-sidecar](https://github.com/mojaloop/event-sidecar) service. Refer to [Event Framework](../event-framework/README.md) for more information on the overall architecture. + +The Service delivers logs, including audits, and traces to EFK stack with enabled APM plugin. Based on the event message type, the messages are delivered to different indexes in the Elasticsearch. + +## 1. Prerequisites + +The service logs all the events to Elasticsearch instance with enabled APM plugin. Sample docker-compose of the Elastic stack is available [here](https://github.com/mojaloop/event-stream-processor/blob/master/test/util/scripts/docker-efk/docker-compose.yml). The logs and audits are created under custom index template, while the trace data is stored to the default `apm-*` index. +Please, ensure that you have created the `mojatemplate` as it is described into the [event-stream-processor](https://github.com/mojaloop/event-stream-processor#111-create-template) service documentation. + +## 2. Architecture overview + +### 2.1. Flow overview +![Event Stream Processor flow overview](./assets/diagrams/architecture/event-stream-processor-overview.svg) + +### 2.2 Trace processing flow sequence diagram +![process-flow.svg](./assets/diagrams/sequence/process-flow.svg) diff --git a/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg new file mode 100644 index 000000000..9deb189e9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/architecture/event-stream-processor-overview.svg @@ -0,0 +1,3 @@ + + +
    topic-event
    topic-event
    Event Stream Processor
    Send to Elasticsearch mojaloop custom schema via Elasticsearch API
    [Not supported by viewer]
    Yes
    Yes
    Is it trace?
    Is it trace?
    No
    No
    Should create master span?
    Should create master span?
    exit
    exit
    No
    No
    APM Agent
    APM Agent
    Create cache for the trace
    Create cache for the trace
    Yes
    Yes
    No
    No
    Is last span?
    Is last span?
    Recreate trace
    Recreate trace
    exit
    exit
    EFK Stack (Elasticsearch, Kibana, APM)
    EFK Stack (Elasticsearch, Kibana, APM)
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml new file mode 100644 index 000000000..9817a79d8 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.plantuml @@ -0,0 +1,280 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Valentin Genev + -------------- + ******'/ + +@startuml +' declate title +title Event Streaming Processor flow + +autonumber + +' Actor Keys: + +' declare actors + +collections "Notification topic" as TOPIC_NOTIFICATIONS +control "Topic Observable" as TOPIC_OBSERVABLE +control "Tracing Observable" as TRACING_OBSERVABLE +control "Caching Observable" as CACHING_OBSERVABLE +control "Check For Last Span Observable" as LASTSPAN_OBSERVABLE +control "Create Trace Observable" as CREATETRACE_OBSERVABLE +control "Cache Handler" as CACHE_HANDLER +control "Send Trace Handler" as TRACE_HANDLER +control "Send Span Handler" as SPAN_SENDER +database "Cache Storage" as CACHE +boundary "APM" as APM +boundary "Elasticsearch API" as ELASTIC + +box "Central Services" #lightGray + participant TOPIC_NOTIFICATIONS +end box + +box "Event Stream Processor" #LightBlue + participant TOPIC_OBSERVABLE + participant TRACING_OBSERVABLE + participant CACHING_OBSERVABLE + participant LASTSPAN_OBSERVABLE + participant CREATETRACE_OBSERVABLE + participant TRACE_HANDLER + participant SPAN_SENDER + participant CACHE_HANDLER +end box + +box "Cache" #LightSteelBlue + participant CACHE +end box + +box "Elasticsearch" #LightYellow + participant APM + participant ELASTIC +end box + +' start flow + +group New Event Message Received + TOPIC_NOTIFICATIONS -> TOPIC_OBSERVABLE: Consume Event Message + activate TOPIC_OBSERVABLE + activate TOPIC_NOTIFICATIONS + deactivate TOPIC_NOTIFICATIONS + note over TOPIC_OBSERVABLE #yellow + Message: + { + "from": "payeefsp", + "to": "payerfsp", + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "content": { + "headers": { + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + "date": "2019-05-28T16:34:41.000Z", + "fspiop-source": "payeefsp", + "fspiop-destination": "payerfsp" + }, + "payload": + }, + "type": "application/json", + "metadata": { + "event": { + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + "type": "trace", + "action": "span", + "createdAt": "2019-05-29T23:18:32.935Z", + "state": { + "status": "success", + "code": 0, + "description": "action successful" + }, + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + }, + "trace": { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": "44ba9bbc5840", + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + } + } + end note + TOPIC_OBSERVABLE -> ELASTIC: Send message for log purposes to custom index + TOPIC_OBSERVABLE -> TOPIC_OBSERVABLE: Verify its tracing event Message + TOPIC_OBSERVABLE -> TRACING_OBSERVABLE: Send Message to Tracing Observable + deactivate TOPIC_OBSERVABLE + activate TRACING_OBSERVABLE + group Cache Span + TRACING_OBSERVABLE -> CACHING_OBSERVABLE: Send Span Context, \nmetadata.State and Content\nfrom Message + note right of TRACING_OBSERVABLE #yellow + { + spanContext: { + service: "central-ledger-prepare-handler", + traceId: "bbd7b2c7bbd7b2c7", + parentSpanId: "44ba9bbc5840", + spanId: "2aa9cd0a7e87", + startTimestamp: "2015-08-29T11:22:09.815479Z", + finishTimestamp: "2015-08-29T11:22:09.815479Z", + tags: { + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + transctionType: "transfer", + parentEventType: "bulk-prepare", + parentEventAction: "prepare" + }, + state: metadata.state, + content + } + end note + deactivate TRACING_OBSERVABLE + activate CACHING_OBSERVABLE + CACHING_OBSERVABLE <- CACHE: Get cachedTrace by traceId + alt the span should not be cached + CACHING_OBSERVABLE -> SPAN_SENDER: currentSpan + SPAN_SENDER -> APM: store to APM + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Complete + else + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + alt !cachedTrace + CACHING_OBSERVABLE -> CACHING_OBSERVABLE: Create new cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: {}, + masterSpan: null, + lastSpan: null + } + end note + end + alt !parentSpan + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Generate MasterSpanId + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Make received span child of masterSpan \nmerge({ parentSpanId: MasterSpanId }, { ...spanContext }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, \n{ ...spanContext }, \n{ spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + CACHING_OBSERVABLE <-> CACHING_OBSERVABLE: Add masterSpan to cachedTrace + end + CACHING_OBSERVABLE <-> CACHE_HANDLER: Add span to cachedTrace + note right of CACHING_OBSERVABLE #yellow + { + spans: { + 2aa9cd0a7e87: { + state, + content + spanContext: { + "service": "central-ledger-prepare-handler", + "traceId": "bbd7b2c7bbd7b2c7", + "parentSpanId": MasterSpanId, + "spanId": "2aa9cd0a7e87", + "startTimestamp": "2015-08-29T11:22:09.815479Z", + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + "tags": { + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + "transctionType": "transfer", + "parentEventType": "bulk-prepare", + "parentEventAction": "prepare" + } + } + }, + MasterSpanId: { + state, + content, + MasterSpanContext + } + }, + masterSpan: MasterSpanContext, + lastSpan: null + } + end note + CACHING_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + end + CACHING_OBSERVABLE -> LASTSPAN_OBSERVABLE: Send traceId to check if last span has been received\nand cached + deactivate CACHING_OBSERVABLE + activate LASTSPAN_OBSERVABLE + end + group Check for last span + LASTSPAN_OBSERVABLE <- CACHE: Get cachedTrace by traceId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Sort spans by startTimestamp + loop for currentSpan of SortedSpans + alt parentSpan + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: isError = (errorCode in parentSpan \nOR parentSpan status === failed \nOR status === failed) + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: apply masterSpan and error tags from parent to current span in cachedTrace + alt !isLastSpan + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + else + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: Validate transactionType, TransactionAction, service and isError \nto match Config.START_CRITERIA && !parentSpandId + LASTSPAN_OBSERVABLE -> LASTSPAN_OBSERVABLE: cachedTrace.lastSpan = currentSpan.spanContext + LASTSPAN_OBSERVABLE -> CACHE_HANDLER: Update cachedTrace to Cache + alt cachedTrace not staled or expired + CACHE_HANDLER -> CACHE_HANDLER: unsubscribe from Scheduler + CACHE_HANDLER -> CACHE: record cachedTrace + CACHE_HANDLER <-> CACHE_HANDLER: Reschedule scheduler for handling stale traces + end + LASTSPAN_OBSERVABLE -> CREATETRACE_OBSERVABLE: Send traceId + deactivate LASTSPAN_OBSERVABLE + activate CREATETRACE_OBSERVABLE + end + end + end + end + group Recreate Trace from Cached Trace + CREATETRACE_OBSERVABLE <- CACHE: get cachedTrace by TraceId + alt cachedTrace.lastSpan AND cachedTrace.masterSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: currentSpan = lastSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: resultTrace = [lastSpan] + loop for i = 0; i < cachedTrace.spans.length; i++ + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: get parentSpan of currentSpan + alt parentSpan + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: insert parent span in resultTrace in front + else + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: break loop + end + end + alt cachedTrace.masterSpan === currentSpan.spanId + CREATETRACE_OBSERVABLE -> CREATETRACE_OBSERVABLE: masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + CREATETRACE_OBSERVABLE -> TRACE_HANDLER: send resultTrace + deactivate CREATETRACE_OBSERVABLE + activate TRACE_HANDLER + end + end + end + group send Trace + loop trace elements + TRACE_HANDLER -> SPAN_SENDER: send each span + SPAN_SENDER -> APM: send span to APM + end + TRACE_HANDLER -> TRACE_HANDLER: unsubscribe scheduler for traceId + TRACE_HANDLER -> CACHE: drop cachedTrace + + end + end +@enduml \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg new file mode 100644 index 000000000..0919b3c48 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/event-stream-processor/assets/diagrams/sequence/process-flow.svg @@ -0,0 +1,1028 @@ + + + + + + + + + + + Event Streaming Processor flow + + + + Central Services + + + + Event Stream Processor + + + + Cache + + + + Elasticsearch + + + + + + + + + + + + + + + + + + + + + + + + Notification topic + + + + + Notification topic + + + Topic Observable + + + + + Topic Observable + + + + + Tracing Observable + + + + + Tracing Observable + + + + + Caching Observable + + + + + Caching Observable + + + + + Check For Last Span Observable + + + + + Check For Last Span Observable + + + + + Create Trace Observable + + + + + Create Trace Observable + + + + + Send Trace Handler + + + + + Send Trace Handler + + + + + Send Span Handler + + + + + Send Span Handler + + + + + Cache Handler + + + + + Cache Handler + + + + + Cache Storage + + + + + Cache Storage + + + + + APM + + + + + APM + + + + + Elasticsearch API + + + + + Elasticsearch API + + + + + + + + New Event Message Received + + + + + 1 + + + Consume Event Message + + + + + Message: + + + { + + + "from": "payeefsp", + + + "to": "payerfsp", + + + "id": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "content": { + + + "headers": { + + + "content-type": "applicationvnd.interoperability.transfers+json;version=1.0", + + + "date": "2019-05-28T16:34:41.000Z", + + + "fspiop-source": "payeefsp", + + + "fspiop-destination": "payerfsp" + + + }, + + + "payload": <payload> + + + }, + + + "type": "application/json", + + + "metadata": { + + + "event": { + + + "id": "3920382d-f78c-4023-adf9-0d7a4a2a3a2f", + + + "type": "trace", + + + "action": "span", + + + "createdAt": "2019-05-29T23:18:32.935Z", + + + "state": { + + + "status": "success", + + + "code": 0, + + + "description": "action successful" + + + }, + + + "responseTo": "1a396c07-47ab-4d68-a7a0-7a1ea36f0012" + + + }, + + + "trace": { + + + "service": "central-ledger-prepare-handler", + + + "traceId": "bbd7b2c7bbd7b2c7", + + + "parentSpanId": "44ba9bbc5840", + + + "spanId": "2aa9cd0a7e87", + + + "startTimestamp": "2015-08-29T11:22:09.815479Z", + + + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + + + "tags": { + + + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "transctionType": "transfer", + + + "parentEventType": "bulk-prepare", + + + "parentEventAction": "prepare" + + + } + + + } + + + } + + + } + + + + + 2 + + + Send message for log purposes to custom index + + + + + 3 + + + Verify its tracing event Message + + + + + 4 + + + Send Message to Tracing Observable + + + + + Cache Span + + + + + 5 + + + Send Span Context, + + + metadata.State and Content + + + from Message + + + + + { + + + spanContext: { + + + service: "central-ledger-prepare-handler", + + + traceId: "bbd7b2c7bbd7b2c7", + + + parentSpanId: "44ba9bbc5840", + + + spanId: "2aa9cd0a7e87", + + + startTimestamp: "2015-08-29T11:22:09.815479Z", + + + finishTimestamp: "2015-08-29T11:22:09.815479Z", + + + tags: { + + + transctionId: "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + transctionType: "transfer", + + + parentEventType: "bulk-prepare", + + + parentEventAction: "prepare" + + + }, + + + state: metadata.state, + + + content + + + } + + + + + 6 + + + Get cachedTrace by traceId + + + + + alt + + + [the span should not be cached] + + + + + 7 + + + currentSpan + + + + + 8 + + + store to APM + + + + + 9 + + + Complete + + + + + + 10 + + + Validate transactionType, TransactionAction and service to match Config.START_CRITERIA && !parentSpandId + + + + + alt + + + [!cachedTrace] + + + + + 11 + + + Create new cachedTrace + + + + + { + + + spans: {}, + + + masterSpan: null, + + + lastSpan: null + + + } + + + + + alt + + + [!parentSpan] + + + + + 12 + + + Generate MasterSpanId + + + + + 13 + + + Make received span child of masterSpan + + + merge({ parentSpanId: MasterSpanId }, { ...spanContext }) + + + + + 14 + + + Create MasterSpanContext merge({ tags: { ...tags, masterSpan: MasterSpanId } }, + + + { ...spanContext }, + + + { spanId: MasterSpanId, service: `master-${tags.transactionType}` }) + + + + + 15 + + + Add masterSpan to cachedTrace + + + + + 16 + + + Add span to cachedTrace + + + + + { + + + spans: { + + + 2aa9cd0a7e87: { + + + state, + + + content + + + spanContext: { + + + "service": "central-ledger-prepare-handler", + + + "traceId": "bbd7b2c7bbd7b2c7", + + + "parentSpanId": + + + MasterSpanId + + + , + + + "spanId": "2aa9cd0a7e87", + + + "startTimestamp": "2015-08-29T11:22:09.815479Z", + + + "finishTimestamp": "2015-08-29T11:22:09.815479Z", + + + "tags": { + + + "transctionId": "659ee338-c8f8-4c06-8aff-944e6c5cd694", + + + "transctionType": "transfer", + + + "parentEventType": "bulk-prepare", + + + "parentEventAction": "prepare" + + + } + + + } + + + }, + + + MasterSpanId: + + + { + + + state, + + + content, + + + MasterSpanContext + + + } + + + }, + + + masterSpan: + + + MasterSpanContext + + + , + + + lastSpan: null + + + } + + + + + 17 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 18 + + + unsubscribe from Scheduler + + + + + 19 + + + record cachedTrace + + + + + 20 + + + Reschedule scheduler for handling stale traces + + + + + 21 + + + Send traceId to check if last span has been received + + + and cached + + + + + Check for last span + + + + + 22 + + + Get cachedTrace by traceId + + + + + 23 + + + Sort spans by startTimestamp + + + + + loop + + + [for currentSpan of SortedSpans] + + + + + alt + + + [parentSpan] + + + + + 24 + + + isError = (errorCode in parentSpan + + + OR parentSpan status === failed + + + OR status === failed) + + + + + 25 + + + apply masterSpan and error tags from parent to current span in cachedTrace + + + + + alt + + + [!isLastSpan] + + + + + 26 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 27 + + + unsubscribe from Scheduler + + + + + 28 + + + record cachedTrace + + + + + 29 + + + Reschedule scheduler for handling stale traces + + + + + + 30 + + + Validate transactionType, TransactionAction, service and isError + + + to match Config.START_CRITERIA && !parentSpandId + + + + + 31 + + + cachedTrace.lastSpan = currentSpan.spanContext + + + + + 32 + + + Update cachedTrace to Cache + + + + + alt + + + [cachedTrace not staled or expired] + + + + + 33 + + + unsubscribe from Scheduler + + + + + 34 + + + record cachedTrace + + + + + 35 + + + Reschedule scheduler for handling stale traces + + + + + 36 + + + Send traceId + + + + + Recreate Trace from Cached Trace + + + + + 37 + + + get cachedTrace by TraceId + + + + + alt + + + [cachedTrace.lastSpan AND cachedTrace.masterSpan] + + + + + 38 + + + currentSpan = lastSpan + + + + + 39 + + + resultTrace = [lastSpan] + + + + + loop + + + [for i = 0; i < cachedTrace.spans.length; i++] + + + + + 40 + + + get parentSpan of currentSpan + + + + + alt + + + [parentSpan] + + + + + 41 + + + insert parent span in resultTrace in front + + + + + + 42 + + + break loop + + + + + alt + + + [cachedTrace.masterSpan === currentSpan.spanId] + + + + + 43 + + + masterSpan.finishTimestamp = resultTrace[resultTrace.length - 1].finishTimestamp + + + + + 44 + + + send resultTrace + + + + + send Trace + + + + + loop + + + [trace elements] + + + + + 45 + + + send each span + + + + + 46 + + + send span to APM + + + + + 47 + + + unsubscribe scheduler for traceId + + + + + 48 + + + drop cachedTrace + + diff --git a/website/versioned_docs/v1.0.1/technical/faqs.md b/website/versioned_docs/v1.0.1/technical/faqs.md new file mode 100644 index 000000000..afb76ba68 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/faqs.md @@ -0,0 +1,158 @@ +# Frequently Asked Questions + +This document contains some of the frequently asked technical questions from the community. + +## 1. What is supported? + +Currently the Central ledger components are supported by the team. The DFSP components are outdated and thus the end-to-end environment and full setup is challenging to install. + +### 2. Can we connect directly to Pathfinder in a development environment? + +For the local and test environment, we recommend interfacing with the 'mock-pathfinder' service instead. Pathfinder is a 'paid by usage' service. + +Access the https://github.com/mojaloop/mock-pathfinder repository to download and install mock-pathfinder. Run command npm install in mock-pathfinder directory to install dependencies after this update Database_URI in mock-pathfinder/src/lib/config.js. + +### 3. Should i register DFSP via url http://central-directory/commands/register or i need to update configuration in default.json? + +You should register using the API provided, using postman or curl. Client is using LevelOne code. Needs to implement the current Mojaloop release with the current Postman scripts. + +### 4. Status of the pod pi3-kafka-0 is still on CrashLoopBackOff? + +- More background related to the question: + + When I tired to get logs of the container centralledger-handler-admin-transfer, I get the following error: + Error from server (BadRequest): container "centralledger-handler-admin-transfer" in pod "pi3-centralledger-handler-admin-transfer-6787b6dc8d-x68q9" is waiting to start: PodInitializing + And the status of the pod pi3-kafka-0 is still on CrashLoopBackOff. + I am using a vps on ubuntu 16.04 with RAM 12GB, 2vCores, 2.4GHz, Rom 50GB at OVH for the deployment. + +Increased RAM to 24 GB and CPU to 4 resolved the issues. Appears to be a timeout on Zookeeper due depletion of available resources, resulting in the services shutting down. + +### 5. Why am I getting an error when we try to create new DFSP using Admin? + +Please insure you are using the most current Postman scripts available on https://github.com/mojaloop/mock-pathfinder repository. + + +### 6. Can I spread Mojaloop components over different physical machines and VM's? + +You should be able to setup on different VM's or physical machines. The distribution pretty much depend on your requirements and would be implementation specific. We utilise Kubernetes to assist with the Container Orchestration. This enables us to schedule the deployments through the Kubernetes runtime to specific machines if required, and request specific resources if required. The helm charts in the helm repository could be used as guideline to how best allocate and group the components in your deployment. Naturally you would need to update the configurations to complement your custom implementation. + +### 7. Can we expect all the endpoints defined in the API document are implemented in Mojaloop? + +The Mojaloop Specification API for transfers and the Mojaloop Open Source Switch implementation are independent streams, though obviously the implementation is based on the Specification. Based on the use-cases prioritized for a time-frame and based on the end-points needed to support those use-cases, implementation will be done. If a few end-points are not prioritized then implementation for them may not be available. However, I think the goal is to eventually support all the end-points specified though it may take time. Thanks for the collection. We do have some of these on the ‘postman’ repo in the mojaloop GitHub org. + +### 8. Does Mojaloop store the payment initiator FSP’s quote/status info? + +At the moment, the Mojaloop Open source Switch implementation does *not* store Quotes related information. The onus is on the Payer, Payee involved in the process to store the relevant information. + +### 9. Does Mojaloop handle workflow validation? + +Not at the moment, but this may happen in the future. Regarding correlating requests that are related to a specific transfer, you may look at the ‘transaction’ end-point/resource in the Specification for more information on this. In addition to this, I can convey that some background work is ongoing regarding the specification to make this correlation more straight-forward and simpler i.e., to correlate quote and transfer requests that come under a single transaction. + + +### 10. How to register a new party in Mojaloop? + +There is no POST on /parties resource, as specified in section 6.1.1 of the API Defintion. Please refer to section: 6.2.2.3 `POST /participants//` in the API Defintion. + +” _The HTTP request `POST /participants//` (or `POST /participants///`) is used to create information on the server regarding the provided identity, defined by ``, ``, and optionally `` (for example, POST_ + _/participants/MSISDN/123456789 or POST /participants/BUSINESS/shoecompany/employee1). See Section 5.1.6.11 for more information regarding addressing of a Party._ ”. + +### 11. Does the participant represent an account of a customer in a bank? + +For more on this, please refer to this doc (Section 3..2): https://github.com/mojaloop/mojaloop-specification/blob/develop/Generic%20Transaction%20Patterns.pdf. + +” _In the API, a Participant is the same as an FSP that is participating in an Interoperability Scheme. The primary purpose of the logical API resource Participants is for FSPs to find out in which other FSP a counterparty in an interoperable financial transaction is located. There are also services defined for the FSPs to provision information to a common system._ ” + +In essence, a participant is any FSP participating in the Scheme (usually not a customer). For account lookup, a directory service such as *Pathfinder* can be used, which provides user lookup and the mapping. If such a directory service is not provided, an alternative is provided in the Specification, where the Switch hosts an Account Lookup Service (ALS) but to which the participants need to register parties. I addressed this earlier. But one thing to note here is that the Switch does not store the details, just the mapping between an ID and an FSP and then the calls to resolve the party are sent to that FSP. + +https://github.com/mojaloop/mojaloop-specification CORE RELATED (Mojaloop): + +This repo contains the specification document set of the Open API for FSP Interoperability - mojaloop/mojaloop-specification. + +### 12. How to register _trusted_ payee to a payer, to skip OTP? + +To skip the OTP, the initial request on the /transactionRequests from the Payee can be programmatically (or manually for that matter) made to be approved without the use of the /authorizations endpoint (that is need for OTP approval). Indeed the FSP needs to handle this, the Switch does not. This is discussed briefly in section 6.4 of the Specification. + +### 13. Receiving a 404 error when attempting to access or load kubernetes-dashboard.yaml file? + +From the official kubernetes github repository in the README.md, the latest link to use is "https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml". Be sure to always verify 3rd party links before implementing. Open source applications are always evolving. + +### 14. When installing nginx-ingress for load balancing & external access - Error: no available release name found? + +Please have a look at the following addressing a similar issue. To summarise - it is most likely an RBAC issue. Have a look at the documentation to set up Tiller with RBAC. https://docs.helm.sh/using_helm/#role-based-access-control goes into detail about this. The issue logged: helm/helm#3839. + +### 15. Received "ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory" when running `npm start' command. + +Found a solution here https://github.com/confluentinc/confluent-kafka-python/issues/65#issuecomment-269964346 +GitHub +ImportError: librdkafka.so.1: cannot open shared object file: No such file or directory · Issue #65 · confluentinc/confluent-kafka-python +Ubuntu 14 here, pip==7.1.2, setuptools==18.3.2, virtualenv==13.1.2. First, I want to build latest stable (seems it's 0.9.2) librdkafka into /opt/librdkafka. curl https://codeload.github.com/ede... + +Here are the steps to rebuild librdkafka: + +git clone https://github.com/edenhill/librdkafka && cd librdkafka && git checkout ` + +cd librdkafka && ./configure && make && make install && ldconfig + +After that I'm able to import stuff without specifying LD_LIBRARY_PATH. +GitHub +edenhill/librdkafka +The Apache Kafka C/C++ library. Contribute to edenhill/librdkafka development by creating an account on GitHub. + +### 16. Can we use mojaloop as open-source mobile wallet software or mojaloop does interoperability only? + +We can use mojaloop for interoperability to support mobile wallet and other such money transfers. This is not a software for a DFSP (there are open source projects that cater for these such as Finserv etc). Mojaloop is for a Hub/Switch primarily and an API that needs to be implemented by a DFSP. But this is not for managing mobile wallets as such. + +### 17. Describe companies that helps to deploy & support for mojaloop? + +Mojaloop is an open source software and specification. + +### 18. Can you say something about mojaloop & security? + +The Specification is pretty standard and has good security standards. But these need to be implemented by the adopters and deployers. Along with this, the security measures need to be coupled with other Operational and Deployment based security measures. Moreover, the coming few months will focus on security perspective for the Open Source community. + +### 19. What are the benefit(s) from using mojaloop as interoperabilty platform? + +Benefits: Right now for example, an Airtel mobile money user can transfer to another Airtel mobile money user only. With this, he/she can transfer to any Financial service provider such as another mobile money provider or any other bank account or Merchant that is connected to the Hub, irrespective of their implementation. They just need to be connected to the same Switch. Also, this is designed for feature phones so everyone can use it. + +### 20. What are the main challenges that companies face using mojaloop? + +At this point, the main challenges are around expectations. Expectations of the adopters of mojaloop and what really mojaloop is. A lot of adopters have different understanding of what mojaloop is and about its capabilities. If they have a good understanding, a lot of current challenges are mitigated.. +Yes, forensic logging is a security measure as well for auditing purposes which will ensure there is audit-able log of actions and that everything that is a possible action of note is logged and rolled up, securely after encryption at a couple of levels. + +### 21. Is forensic logging/audit in mojaloop , is it related with securing the inter-operability platform? + +This also ensures all the services always run the code they’re meant to run and anything wrong/bad is stopped from even starting up. Also, for reporting and auditors, reports can have a forensic-log to follow. + +### 22. How do the financial service providers connect with mojaloop? + +There is an architecture diagram that presents a good view of the integration between the different entities. https://github.com/mojaloop/docs/blob/master/Diagrams/ArchitectureDiagrams/Arch-Flows.svg. + +### 23. Is there any open source ISO8583-OpenAPI converter/connector available? + +I don't believe a generic ISO8583 `<-> Mojaloop integration is available currently. We're working on some "traditional payment channel" to Mojaloop integrations (POS and ATM) which we hope to demo at the next convening. These would form the basis for an ISO8583 integration we might build and add to the OSS stack but bare in mind that these integrations will be very use case specific. + +### 24. How do I know the end points to setup postman for testing the deployment? + +On the Kubernetes dashboard, select the correct NAMESPACE. Go to Ingeresses. Depending on how you deployed the helm charts, look for 'moja-centralledger-service'. Click on edit, and find the tag ``. This would contain the endpoint for this service. + +### 25. Why are there no reversals allowed on a Mojaloop? + +*Irrevocability* is a core Level One Principle (edited) and not allowing reversals is essential for that. Here is the section from the API Definition addressing this: + +_*6.7.1.2 Transaction Irrevocability*_ +_The API is designed to support irrevocable financial transactions only; this means that a financial transaction cannot be changed, cancelled, or reversed after it has been created. This is to simplify and reduce costs for FSPs using the API. A large percentage of the operating costs of a typical financial system is due to reversals of transactions._ +_As soon as a Payer FSP sends a financial transaction to a Payee FSP (that is, using POST /transfers including the end-to-end financial transaction), the transaction is irrevocable from the perspective of the Payer FSP. The transaction could still be rejected in the Payee FSP, but the Payer FSP can no longer reject or change the transaction. An exception to this would be if the transfer’s expiry time is exceeded before the Payee FSP responds (see Sections 6.7.1.3 and 6.7.1.5 for more information). As soon as the financial transaction has been accepted by the Payee FSP, the transaction is irrevocable for all parties._ + +However, *Refunds* is a use case supported by the API. + +### 26. ffg. error with microk8s installation "MountVolume.SetUp failed"? + +Would appear if it is a space issue, but more the 100GiB of EBS storage was allocated. +The issue resolved itself after 45 minutes. Initial implementation of the mojaloop project can take a while to stabilize. + +### 27. Why am I getting this error when trying to create a participant: "Hub reconciliation account for the specified currency does not exist"? + +You need to create the corresponding Hub accounts (HUB_MULTILATERAL_SETTLEMENT and HUB_RECONCILIATION) for the specified currency before setting up the participants. +In this Postman collection you can find the requests to perform the operation in the "Hub Account" folder: https://github.com/mojaloop/postman/blob/master/OSS-New-Deployment-FSP-Setup.postman_collection.json + +Find also the related environments in the Postman repo: https://github.com/mojaloop/postman diff --git a/website/versioned_docs/v1.0.1/technical/fraud-services/README.md b/website/versioned_docs/v1.0.1/technical/fraud-services/README.md new file mode 100644 index 000000000..d44482e5b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/fraud-services/README.md @@ -0,0 +1,5 @@ +# Fraud Services + +Provides an overview of the monitoring and preventative measures in consideration to prevent and discourage fraudulent activities within a Mojaloop scheme. + +Relevant artefacts available for public consumption are shared within [related-documents](./related-documents/documentation.md) section. diff --git a/website/versioned_docs/v1.0.1/technical/fraud-services/related-documents/documentation.md b/website/versioned_docs/v1.0.1/technical/fraud-services/related-documents/documentation.md new file mode 100644 index 000000000..920da7b7f --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/fraud-services/related-documents/documentation.md @@ -0,0 +1,7 @@ +# Fraud Services + +Artefacts available for public reference related to the preventative measures in preventing and discouraging fraudulent activities within the ecosystem. + +## List of current artefacts + +#### [Mojaloop Ecosystem Fraud Overview Document](https://github.com/mojaloop/documentation-artifacts/blob/master/presentations/April%202019%20PI-6_OSS_community%20session/Mojaloop-Fraud-20190410.pdf) diff --git a/website/versioned_docs/v1.0.1/technical/ml-testing-toolkit/README.md b/website/versioned_docs/v1.0.1/technical/ml-testing-toolkit/README.md new file mode 100644 index 000000000..0260e22a2 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/ml-testing-toolkit/README.md @@ -0,0 +1,16 @@ +Mojaloop Testing Toolkit +============================= + +The **Mojaloop Testing Toolkit** was designed to help Mojaloop Schemes scale effectively by easing the DFSP Onboarding process. Schemes can provide a set of rules and tests on the toolkit and DFSPs can use it for self testing (or self-certification in some cases). This ensures that DFSPs are well and truly ready with their implementations to be integrated with the Scheme and allows for a quick and smooth onboarding process for the Mojaloop Hubs, thereby increasing their scalability. + +This was initially aimed at FSPs/Participants that would like to participate in a Mojaloop scheme. However, in its current form, this tool set can potentially be used by both DFSPs and _Mojaloop Hubs_ to verify integration between the 2 entities. Intentionally built as a standard integration testing tool between a _Digital Financial Service Provider (DFSP)_ and the _Mojaloop Switch_ (Hub), to facilitate testing. + +For additional background on the Self Testing Toolkit, please see [Mojaloop Testing Toolkit](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md). It would be to the particpant's benefit to familiarise themselves with the understanding of the [Architecture Diagram](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/Mojaloop-Testing-Toolkit.md#7-architecture) that explains the various components and related flows. + +## Usage Guides + +For Web interface follow this [Usage Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide.md) + +For Command line tool follow this [CLI User Guide](https://github.com/mojaloop/ml-testing-toolkit/blob/master/documents/User-Guide-CLI.md) + +**If you have your own DFSP implementation you can point the peer endpoint to Mojaloop Testing Toolkit on port 5000 and try to send requests from your implementation instead of using mojaloop-simulator.** diff --git a/website/versioned_docs/v1.0.1/technical/overview/README.md b/website/versioned_docs/v1.0.1/technical/overview/README.md new file mode 100644 index 000000000..373cbfa93 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/README.md @@ -0,0 +1,24 @@ +# Mojaloop Hub + +There are several components that make up the Mojaloop ecosystem. The Mojaloop Hub is the primary container and reference we use to describe the core Mojaloop components. + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture: + +![Current Mojaloop Architecture Overview](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ + +These consist of: + +* The **Mojaloop API Adapters** (**ML-API-Adapter**) provide the standard set of interfaces a DFSP can implement to connect to the system for Transfers. A DFSP that wants to connect up can adapt our example code or implement the standard interfaces into their own software. The goal is for it to be as straightforward as possible for a DFSP to connect to the interoperable network. +* The **Central Services** (**CS**) provide the set of components required to move money from one DFSP to another through the Mojaloop API Adapters. This is similar to how money moves through a central bank or clearing house in developed countries. The Central Services contains the core Central Ledger logic to move money but also will be extended to provide fraud management and enforce scheme rules. +* The **Account Lookup Service** (**ALS**) provides a mechanism to resolve FSP routing information through the Participant API or orchestrate a Party request based on an internal Participant look-up. The internal Participant look-up is handled by a number of standard Oracle adapter or services. Example Oracle adapter/service would be to look-up Participant information from Pathfinder or a Merchant Registry. These Oracle adapters or services can easily be added depending on the schema requirements. +* The **Quoting Service** (**QA**) provides Quoting is the process that determines any fees and any commission required to perform a financial transaction between two FSPs. It is always initiated by the Payer FSP to the Payee FSP, which means that the quote flows in the same way as a financial transaction. +* The **Simulator** (**SIM**) mocks several DFSP functions as follows: + * Oracle end-points for Oracle Participant CRUD operations using in-memory cache; + * Participant end-points for Oracles with support for parameterized partyIdTypes; + * Parties end-points for Payer and Payee FSPs with associated callback responses; + * Transfer end-points for Payer and Payee FSPs with associated callback responses; and + * Query APIs to verify transactions (requests, responses, callbacks, etc) to support QA testing and verification. + +On either side of the Mojaloop Hub there is sample open source code to show how a DFSP can send and receive payments and the client that an existing DFSP could host to connect to the network. diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg new file mode 100644 index 000000000..df9396cae --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg new file mode 100644 index 000000000..763c5697e --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Settlement Windows)
    Central-Settlements...
    Central-Settlements
    (Handler - Transfer Settlements)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg new file mode 100644 index 000000000..06680fbae --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Metrics - Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway (IaC)
    (API - Parties, Participants, Quotes, Transfers, Bulk Transfers; OAuth; MTLS)
    API Gateway (IaC)...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Central-Settlements
    (API - Settlements)
    Central-Settlements...
    Event-Stream-Processor
    (Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Testing Toolkit
    (
    UI, CLI & Backend)
    Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Automated Lab/Env Setup & Configuration)
    IaC (Infra as Code) Tools...
    Third Party API Adapter
    (PoC - API - Transfers)
    Third Party API Adapter...
    Third Party API Adapter
    (PoC - Handler - Notifications)
    Third Party API Adapter...
    Central-Settlements
    (Handler - Deferred)
    Central-Settlements...
    Central-Settlements
    (Handler - Gross)
    Central-Settlements...
    Central-Settlements
    (Handler - Rules)
    Central-Settlements...
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg new file mode 100644 index 000000000..4a658b897 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    Central-Directory
    (Participant Lookup)
    [Not supported by viewer]
    Central-End-User-Registry
    (Custom Participant Store)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Central-Hub
    (Retired - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg new file mode 100644 index 000000000..ac0b21621 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg @@ -0,0 +1,3 @@ + + +
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Zipkin
    (Future - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Simulator
    (API - QA FSP Simulator)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Auditing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Msisdn-Service
    (Pathfinder Lookup Adapter)
    [Not supported by viewer]
    Mock-Pathfinder
    (Mocked Pathfinder)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational Web Interface)
    [Not supported by viewer]
    Interop-Switch
    (To be Retired - Transfers, Quotes, Parties, Participants)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg new file mode 100644 index 000000000..9697dfc5b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core
    <b>Core</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Persistence
    <b>Persistence</b>
    Scaffolding
    [Not supported by viewer]
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Event-Logging-Sidecar
    (POC - Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP, POCLogs, Error, Audits, Tracing)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Moja-Hub
    (Future - Operational UI)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging-Sidecar
    (Deprecated - Auditing)
    [Not supported by viewer]
    Simulator
    (API - FSP Simulator /
    API - Oracle Simulator)

    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg new file mode 100644 index 000000000..2fedecbc1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    <b>Operational Monitoring</b>
    Quality Assurance
    <b>Quality Assurance</b>
    Core Components
    <b>Core Components</b>
    API - Security / Policy / Ingress / Egress
    <b>API - Security / Policy / Ingress / Egress</b>
    Continuous Integration & Delivery
    <b>Continuous Integration & Delivery</b>
    Container Management & Orchestration
    <b>Container Management & Orchestration</b>
    Supporting Components
    <b style="line-height: 0%">Supporting Components</b>
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    [Not supported by viewer]
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    [Not supported by viewer]
    Docker
    (Container Engine)
    [Not supported by viewer]
    Infrastructure
    (AWS, Azure, On-Prem)
    [Not supported by viewer]
    EFK - ElasticSearch / Fluentd / Kabana
    (Log Search / Collection / Monitoring / PoC - Tracing)
    [Not supported by viewer]
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    [Not supported by viewer]
    Open Tracing
    (POC - Distributed Tracing)
    [Not supported by viewer]
    Rancher
    (Infrastructure Management)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Transfers)
    [Not supported by viewer]
    Central-Services
    (API - Operational Admin)
    [Not supported by viewer]
    Central-Services
    (Handler - Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Position)
    [Not supported by viewer]
    Central-Services
    (Handler - Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Get Transfers)
    [Not supported by viewer]
    Central-Services
    (Handler - Timeout)
    [Not supported by viewer]
    Central-KMS
    (Key Management Store)
    [Not supported by viewer]
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    [Not supported by viewer]
    ALS-Oracle-Pathfinder-Service
    (Future - MSISDN Lookup)
    [Not supported by viewer]
    Central-Event-Processor
    (CEP)
    [Not supported by viewer]
    Email-Notifier
    (Handler - Email)
    [Not supported by viewer]
    Central-Services
    (Handler - Admin)
    [Not supported by viewer]
    Circle-CI
    (Test, Build, Deploy)
    [Not supported by viewer]
    Docker Hub
    (Container Repository)
    [Not supported by viewer]
    NPM Org
    (NPM Repository)
    [Not supported by viewer]
    GitBooks
    (Documetation)
    [Not supported by viewer]
    API Gateway
    (POC - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    <b>API Gateway<br></b>(<b><font color="#ff1b0a">POC</font></b> - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)<br>
    Central-Services
    (Handler - Bulk Prepare)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Fulfil)
    [Not supported by viewer]
    Central-Services
    (Handler - Bulk Process)
    [Not supported by viewer]
    Mojaloop API Adapter
    (API - Bulk Transfers)
    [Not supported by viewer]
    Forensic-Logging
    (Future - Auditing)
    [Not supported by viewer]
    Central-Settlements
    (API - Settlement)
    [Not supported by viewer]
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    [Not supported by viewer]
    Simulator
    (API - FSP & Oracle Simulator)
    [Not supported by viewer]
    On-boarding
    (Postman - Scripts)
    [Not supported by viewer]
    Functional Tests
    (Postman - Scripts)
    [Not supported by viewer]
    Mojaloop-Simulator
    (SDK)
    [Not supported by viewer]
    License & Audit
    (Dependencies)
    [Not supported by viewer]
    Persistence
    <b>Persistence</b>
    PostgreSQL
    (Deprecated - Data)
    [Not supported by viewer]
    MongoDB
    (CEP - Data)
    [Not supported by viewer]
    MySQL
    (Percona - Data)
    [Not supported by viewer]
    Kafka
    (Message - Streaming)
    [Not supported by viewer]
    Transaction Request Service
    (API - Transaction)
    <b>Transaction Request Service</b><br>(API - Transaction)
    Software Dev Kits
    <b>Software Dev Kits</b>
    Oracle SDK
    (Participant Store)
    [Not supported by viewer]
    Mojaloop SDK 
    (FSP Payer/Payee)
    [Not supported by viewer]
    Event SDK
    (Audit, Log, Trace - Client/Server)
    [Not supported by viewer]
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    <b>Event-Sidecar</b><br>(Logs, Error, Audits, Tracing)
    Mojaloop API Adapter
    (Handler - Notifications)
    [Not supported by viewer]
    Quoting-Service
    (API - Quotes)
    [Not supported by viewer]
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg new file mode 100644 index 000000000..3e5b75f13 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg @@ -0,0 +1,3 @@ + + +
    Operational Monitoring
    Operational Monitoring
    Quality Assurance
    Quality Assurance
    Core Components
    Core Components
    API - Security / Policy / Ingress / Egress
    API - Security / Policy / Ingress / Egress
    Continuous Integration & Delivery
    Continuous Integration & Delivery
    Container Management & Orchestration
    Container Management & Orchestration
    Supporting Components
    Supporting Components
    Helm
    (Package Manager for K8s, Templatized Deployments and Configuration)
    Helm...
    Kubernetes
    (Abstraction layer for Infrastructure, Infrastructure as a Policy, Container Orchestration)
    Kubernetes...
    Docker
    (Container Engine)
    Docker...
    Infrastructure
    (AWS, Azure, On-Prem)
    Infrastructure...
    EFK - ElasticSearch / Fluentd / Kibana
    (Log Search / Collection / Monitoring / Tracing)
    EFK - ElasticSearch / Fluentd / Kibana...
    Promfana - Prometheus / Grafana
    (Log Search / Collection / Monitoring)
    Promfana - Prometheus / Grafana...
    Open Tracing
    (Distributed Tracing)
    Open Tracing...
    Rancher
    (Infrastructure Management)
    Rancher...
    Mojaloop API Adapter
    (API - Transfers)
    Mojaloop API Adapter...
    Central-Services
    (API - Operational Admin)
    Central-Services...
    Central-Services
    (Handler - Prepare)
    Central-Services...
    Central-Services
    (Handler - Position)
    Central-Services...
    Central-Services
    (Handler - Fulfil)
    Central-Services...
    Central-Services
    (Handler - Get Transfers)
    Central-Services...
    Central-Services
    (Handler - Timeout)
    Central-Services...
    Central-KMS
    (Future - Key Management Store)
    Central-KMS...
    ALS - Account-Lookup-Service
    (API - Parties, Participant)
    ALS - Account-Lookup-Service...
    ALS-Oracle-Pathfinder
    (MSISDN Lookup)
    ALS-Oracle-Pathfinder...
    Central-Event-Processor
    (CEP)
    Central-Event-Processor...
    Email-Notifier
    (Handler - Email)
    Email-Notifier...
    Central-Services
    (Handler - Admin)
    Central-Services...
    Circle-CI
    (Test, Build, Deploy)
    Circle-CI...
    Docker Hub
    (Container Repository)
    Docker Hub...
    NPM Org
    (NPM Repository)
    NPM Org...
    GitBooks
    (Documetation)
    GitBooks...
    API Gateway
    (Future - API - Parties, Participants, Quotes, Transfers, Bulk Transfers)
    API Gateway...
    Central-Services
    (Handler - Bulk Prepare)
    Central-Services...
    Central-Services
    (Handler - Bulk Fulfil)
    Central-Services...
    Central-Services
    (Handler - Bulk Process)
    Central-Services...
    Mojaloop API Adapter
    (API - Bulk Transfers)
    Mojaloop API Adapter...
    Forensic-Logging
    (Future - Auditing)
    Forensic-Logging...
    Central-Settlements
    (API - Settlement)
    Central-Settlements...
    Event-Stream-Processor
    Logs, Error, Audits, Tracing)
    Event-Stream-Processor...
    Simulators
    (API, SDK, FSP & Oracle)
    Simulators...
    On-boarding
    (Postman - Scripts)
    On-boarding...
    Functional Tests
    (Postman - Scripts)
    Functional Tests...
    Self Testing Toolkit
    (
    POC UI)
    Self Testing Toolkit...
    License, Security & Audit
    (Dependencies)
    License, Security & Audit...
    Persistence
    Persistence
    Redis
    (SDK - Cache)
    Redis...
    MongoDB
    (CEP - Data)
    MongoDB...
    MySQL
    (Percona - Data)
    MySQL...
    Kafka
    (Message - Streaming)
    Kafka...
    Transaction Request Service
    (API - Transaction)
    Transaction Request Service...
    Software Dev Kits
    Software Dev Kits
    Oracle SDK
    (Participant Store)
    Oracle SDK...
    Mojaloop SDK 
    (FSP Payer/Payee)
    Mojaloop SDK...
    Event SDK
    (Audit, Log, Trace - Client/Server)
    Event SDK...
    Event-Sidecar
    (Logs, Error, Audits, Tracing)
    Event-Sidecar...
    Mojaloop API Adapter
    (Handler - Notifications)
    Mojaloop API Adapter...
    Quoting-Service
    (API - Quotes)
    Quoting-Service...
    Finance-Portal-UI
    (API - Bulk Transfers)
    Finance-Portal-UI...
    Settlement-Management
    (Closing, Recon report, Cronjob)
    Settlement-Management...
    Schema-Adapter
    (SDK - Parties, Participants, Quotes, Transfers)
    Schema-Adapter...
    IaC (Infra as Code) Tools
    (Future - Automated
    Prov / Depl / Upgrades)
    IaC (Infra as Code) Tools...
    \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI11.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI11.md new file mode 100644 index 000000000..35b839657 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI11.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI11 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI11: + +![Mojaloop Architecture Overview PI11](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI11.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI12.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI12.md new file mode 100644 index 000000000..d90d82eb9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI12.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI12 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI12: + +![Mojaloop Architecture Overview PI12](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI12.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI14.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI14.md new file mode 100644 index 000000000..d4c4e3887 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI14.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Current Components - PI14 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI14: + +![Mojaloop Architecture Overview PI14](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI14.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI3.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI3.md new file mode 100644 index 000000000..a3cb1b686 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI3.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI3 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI3: + +![Mojaloop Architecture Overview PI5](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI3.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI5.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI5.md new file mode 100644 index 000000000..f54ac4856 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI5.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI5 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI5: + +![Mojaloop Architecture Overview PI5](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI5.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI6.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI6.md new file mode 100644 index 000000000..a935f7cc5 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI6.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI6 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI6: + +![Mojaloop Architecture Overview PI6](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI6.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI7.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI7.md new file mode 100644 index 000000000..f2f59dd8a --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI7.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI7 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI7: + +![Mojaloop Architecture Overview PI7](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI7.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/overview/components-PI8.md b/website/versioned_docs/v1.0.1/technical/overview/components-PI8.md new file mode 100644 index 000000000..3d18e7fac --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/overview/components-PI8.md @@ -0,0 +1,7 @@ +# Mojaloop Hub Legacy Components - PI8 + +The following component diagram shows the break-down of the Mojaloop services and its micro-service architecture for pre PI8: + +![Mojaloop Architecture Overview PI8](./assets/diagrams/architecture/Arch-Mojaloop-overview-PI8.svg) + +_Note: Colour-grading indicates the relationship between data-store, and message-streaming / adapter-interconnects. E.g. `Central-Services` utilise `MySQL` as a Data-store, and leverage on `Kafka` for Messaging_ diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/README.md b/website/versioned_docs/v1.0.1/technical/quoting-service/README.md new file mode 100644 index 000000000..95743aaae --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/README.md @@ -0,0 +1,12 @@ +--- +version: 1.1 +--- + +# Quoting Service Overview +The **Quoting Service** (**QS**) _(refer to section `5.1`) as per the [Mojaloop {{ $page.frontmatter.version }} Specification](/api) implements the quoting phase of the various use-cases. + +_Note: In addition to individual quotes, the quoting service supports bulk quotes as well._ + +## Sequence Diagram + +![seq-quotes-1.0.0.svg](./assets/diagrams/sequence/seq-quotes-1.0.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml new file mode 100644 index 000000000..0405a9868 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.plantuml @@ -0,0 +1,92 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Retrieve Bulk Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP + +autonumber +note right of PayerFSP: Payer FSP sends request to get bulk quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /bulkQuotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve bulk quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode) + Switch -\ PayeeFSP: GET /bulkQuotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves bulk quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** + end note + Switch --/ PayeeFSP: 200 Ok + alt Response is ok + Switch -> Switch: Retrieve bulk quotes endpoint for the Payer FSP + alt Bulk Quotes callback endpoint found + note left of Switch: Switch forwards bulk quote response to Payer FSP + Switch -\ PayerFSP: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Bulk Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else bulkQuote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP Bulk quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg new file mode 100644 index 000000000..9cab870cb --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg @@ -0,0 +1,369 @@ + + + + + + + + + + + Retrieve Bulk Quote Information + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting Service] + + + + Switch + + + [Quoting Service] + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP sends request to get bulk quote details + + + to Payee FSP via the Switch + + + + + 1 + + + GET /bulkQuotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Retrieve bulk quotes endpoint for Payee FSP + + + + + alt + + + [Payee FSP quotes endpoint is found] + + + + + Switch forwards request to Payee FSP (pass-through mode) + + + + + 5 + + + GET /bulkQuotes/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Payee FSP retireves bulk quote + + + + + alt + + + [Payee FSP successfully retieves quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 9 + + + 200 Ok + + + + + alt + + + [Response is ok] + + + + + 10 + + + Retrieve bulk quotes endpoint for the Payer FSP + + + + + alt + + + [Bulk Quotes callback endpoint found] + + + + + Switch forwards bulk quote response to Payer FSP + + + + + 11 + + + PUT /bulkQuotes/{ID} + + + + + 12 + + + 200 Ok + + + + [Bulk Quotes callback endpoint not found] + + + + + Switch returns error to Payee FSP + + + + + 13 + + + PUT /bulkQuotes/{ID}/error + + + + + 14 + + + 200 Ok + + + + [Response is invalid] + + + + + Switch returns error to Payee FSP + + + + + 15 + + + PUT /bulkQuotes/{ID}/error + + + + + 16 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [bulkQuote not found] + + + + + Payee FSP returns error to Switch + + + Error code: 3205 + + + + + 17 + + + PUT /bulkQuotes/{ID}/error + + + + + 18 + + + 200 OK + + + + + Switch returns error to Payer FSP + + + Error code: 3205 + + + + + 19 + + + PUT /bulkQuotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [Payee FSP Bulk quotes endpoint is not found] + + + + + Switch returns error to Payer FSP + + + Error code: 3201 + + + + + 21 + + + PUT /bulkQuotes/{ID}error + + + + + 22 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml new file mode 100644 index 000000000..dfcb1918b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.plantuml @@ -0,0 +1,86 @@ +@startuml +Title Retrieve Quote Information +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber +note right of PayerFSP: Payer FSP sends request to get quote details \nto Payee FSP via the Switch +PayerFSP -\ Switch: GET /quotes/{ID} +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +Switch -> Switch: Retrieve quotes endpoint for Payee FSP +alt Payee FSP quotes endpoint is found + note right of Switch: Switch forwards request to Payee FSP (pass-through mode)\n + Switch -\ PayeeFSP: GET /quotes/{ID} + PayeeFSP --/ Switch: 202 Accepted + PayeeFSP -> PayeeFSP: Payee FSP retireves quote + alt Payee FSP successfully retieves quote + note left of PayeeFSP: Payee FSP responds to quote request + PayeeFSP -\ Switch: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 Ok + Switch -> Switch: Validate response (schema, headers (**Error code: 3100**)) + alt Response is ok + alt SimpleRoutingMode is FALSE + Switch -> Switch: Validate response (duplicate response check, handle resend scenario (**Error code: 3106**)) + alt Validation passed + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteResponseDuplicateCheck + quoteResponseIlpPacket + quoteExtensions + geoCode + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + end + alt SimpleRoutingMode is TRUE + Switch -> Switch: Retrieve quotes endpoint for the Payer FSP + else SimpleRoutingMode is FALSE + Switch -> Switch: Retrieve quote party endpoint (PAYER) + end + alt Quotes callback endpoint found + note left of Switch: Switch forwards quote response to Payer FSP\n + Switch -\ PayerFSP: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 Ok + else Quotes callback endpoint not found + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + end + else Response is invalid + note right of Switch: Switch returns error to Payee FSP + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + PayeeFSP --/ Switch : 200 Ok + note over Switch, PayeeFSP #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + end + + else Quote not found + note left of PayeeFSP: Payee FSP returns error to Switch\n **Error code: 3205** + PayeeFSP -\ Switch: PUT quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode is FALSE + Switch -> Switch: Persist error data + end + note left of Switch: Switch returns error to Payer FSP\n **Error code: 3205** + Switch -\ PayerFSP: PUT quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint is not found + note left of Switch + Switch returns error to Payer FSP + **Error code: 3201** + end note + PayerFSP /- Switch: PUT quotes/{ID}error + PayerFSP --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg new file mode 100644 index 000000000..679d20f98 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-get-quotes-1.1.0.svg @@ -0,0 +1,496 @@ + + + + + + + + + + + Retrieve Quote Information + + + + + + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting + + + Service] + + + + Switch + + + [Quoting + + + Service] + + + Central Store + + + + + Central Store + + + + + + Payee FSP + + + + Payee FSP + + + + + + Payer FSP sends request to get quote details + + + to Payee FSP via the Switch + + + + + 1 + + + GET /quotes/{ID} + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Retrieve quotes endpoint for Payee FSP + + + + + alt + + + [Payee FSP quotes endpoint is found] + + + + + Switch forwards request to Payee FSP (pass-through mode) + + + <Payer based Rules> + + + + + 5 + + + GET /quotes/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Payee FSP retireves quote + + + + + alt + + + [Payee FSP successfully retieves quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate response (schema, headers ( + + + Error code: 3100 + + + )) + + + + + alt + + + [Response is ok] + + + + + alt + + + [SimpleRoutingMode is FALSE] + + + + + 11 + + + Validate response (duplicate response check, handle resend scenario ( + + + Error code: 3106 + + + )) + + + + + alt + + + [Validation passed] + + + + + 12 + + + Persist quote response + + + + quoteResponse + + + quoteResponseDuplicateCheck + + + quoteResponseIlpPacket + + + quoteExtensions + + + geoCode + + + + + 13 + + + Quote response saved + + + + + alt + + + [SimpleRoutingMode is TRUE] + + + + + 14 + + + Retrieve quotes endpoint for the Payer FSP + + + + [SimpleRoutingMode is FALSE] + + + + + 15 + + + Retrieve quote party endpoint (PAYER) + + + + + alt + + + [Quotes callback endpoint found] + + + + + Switch forwards quote response to Payer FSP + + + <Payee whole request Rule> + + + + + 16 + + + PUT /quotes/{ID} + + + + + 17 + + + 200 Ok + + + + [Quotes callback endpoint not found] + + + + + Switch returns error to Payee FSP + + + + + 18 + + + PUT /quotes/{ID}/error + + + + + 19 + + + 200 Ok + + + + [Response is invalid] + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /quotes/{ID}/error + + + + + 21 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [Quote not found] + + + + + Payee FSP returns error to Switch + + + Error code: 3205 + + + + + 22 + + + PUT quotes/{ID}/error + + + + + 23 + + + 200 OK + + + + + alt + + + [SimpleRoutingMode is FALSE] + + + + + 24 + + + Persist error data + + + + + Switch returns error to Payer FSP + + + Error code: 3205 + + + + + 25 + + + PUT quotes/{ID}/error + + + + + 26 + + + 200 OK + + + + [Payee FSP quotes endpoint is not found] + + + + + Switch returns error to Payer FSP + + + Error code: 3201 + + + + + 27 + + + PUT quotes/{ID}error + + + + + 28 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml new file mode 100644 index 000000000..ca4c1d30f --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.plantuml @@ -0,0 +1,99 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- +******'/ + +@startuml +Title Request Bulk Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting Service]" as Switch +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends bulk quote request\nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /bulkQuotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Bulk Quote request validation (rules engine etc.) +||| +Switch -> Switch: Duplicate check +||| +alt Request is a duplicate but not a resend +||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK +||| +else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario +end +||| +Switch -> Switch: Use fspiop-destination header to retrieve\n bulk quotes endpoint for Payee DFSP +alt Payee bulk quotes endpoint found + note right of Switch: Switch forwards bulk quote request to Payee FSP + Switch -\ PayeeFSP: POST /bulkQuotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP calculates individual quotes\nand responds with a bulk quote result + alt Payee bulkQuotes processing successful + note over PayeeFSP, Switch: Payee FSP sends bulk quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate bulk quote response + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects bulk quote or encounters an error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /bulkQuotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /bulkQuotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg new file mode 100644 index 000000000..4b3363dd6 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg @@ -0,0 +1,387 @@ + + + + + + + + + + + Request Bulk Quote Creation + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting Service] + + + + Switch + + + [Quoting Service] + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP sends bulk quote request + + + to Payee FSP via the Switch + + + + + 1 + + + POST /bulkQuotes + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Bulk Quote request validation (rules engine etc.) + + + + + 5 + + + Duplicate check + + + + + alt + + + [Request is a duplicate but not a resend] + + + + + Switch returns error back to Payer FSP + + + Error code: 3106 + + + + + 6 + + + PUT /bulkQuotes/{ID}/error + + + + + 7 + + + 200 OK + + + + [Request is a duplicate and a resend] + + + + + 8 + + + Switch handles resend scenario + + + + + 9 + + + Use fspiop-destination header to retrieve + + + bulk quotes endpoint for Payee DFSP + + + + + alt + + + [Payee bulk quotes endpoint found] + + + + + Switch forwards bulk quote request to Payee FSP + + + + + 10 + + + POST /bulkQuotes + + + + + 11 + + + 202 OK + + + + + 12 + + + Payee FSP calculates individual quotes + + + and responds with a bulk quote result + + + + + alt + + + [Payee bulkQuotes processing successful] + + + + + Payee FSP sends bulk quote response back to Payer FSP via the Switch + + + + + 13 + + + PUT /bulkQuotes/{ID} + + + + + 14 + + + 200 OK + + + + + 15 + + + Validate bulk quote response + + + + + 16 + + + Duplicate check + + + + + alt + + + [Response is duplicate but not a resend] + + + + + 17 + + + PUT /bulkQuotes/{ID}/error + + + + + 18 + + + 200 OK + + + + + alt + + + [Response is a duplicate and a resend] + + + + + 19 + + + Switch handles resend scenario + + + + + Switch forwards quote response to Payer FSP + + + + + 20 + + + PUT /bulkQuotes/{ID} + + + + + 21 + + + 200 OK + + + + [Payee rejects bulk quote or encounters an error] + + + + + Payee FSP sends error callback to Payer FSP via the Switch + + + + + 22 + + + PUT /bulkQuotes/{ID}/error + + + + + 23 + + + 200 OK + + + + + Switch forwards error callback to Payer FSP + + + + + 24 + + + PUT /bulkQuotes/{ID}/error + + + + + 25 + + + 200 OK + + + + [Payee FSP quotes endpoint not found] + + + + + Switch sends an error callback to Payer FSP + + + Error code: 3201 + + + + + 26 + + + PUT /bulkQuotes/{ID}/error + + + + + 27 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml new file mode 100644 index 000000000..86fb8f8b6 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.plantuml @@ -0,0 +1,117 @@ +@startuml +Title Request Quote Creation +participant "Payer FSP" as PayerFSP +participant "Switch\n[Quoting\nService]" as Switch +database "Central Store" as DB +participant "Payee FSP" as PayeeFSP +autonumber + +note over PayerFSP, Switch: Payer FSP sends request for quote \nto Payee FSP via the Switch +PayerFSP -\ Switch: POST /quotes +note right of Switch #aaa + Validate request against + Mojaloop interface specification + **Error code: 300x, 310x** + **HTTP error response code: 4xx** +end note +Switch -> Switch: Schema validation +PayerFSP \-- Switch: 202 Accepted +||| +Switch -> Switch: Quote request validation (rules engine etc.) +||| +alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + ||| + alt Request is a duplicate but not a resend + ||| + note left of Switch + Switch returns error back to Payer FSP + **Error code: 3106** + end note + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + ||| + else Request is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + ||| + Switch -\ DB: Persist quote request + activate DB + hnote over DB + quoteDuplicateCheck + transactionReference + quote + quoteParty + quoteExtension + geoCode + end hnote + Switch \-- DB: Quote request saved + deactivate DB +end +||| +alt SimpleRoutingMode === TRUE + Switch -> Switch: Use fspiop-destination header to retrieve quotes endpoint for Payee FSP +else SimpleRoutingMode === FALSE + Switch -> Switch: Retireve Payee FSP endpoint using quote party information +end +||| +alt Payee quotes endpoint found + note right of Switch: Switch forwards quote request to Payee FSP + Switch -\ PayeeFSP: POST /quotes + Switch \-- PayeeFSP: 202 OK + + PayeeFSP -> PayeeFSP: Payee FSP presists and calculates quote + alt Payee quotes processing successful + note left of PayeeFSP: Payee FSP sends quote response back to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID} + Switch --/ PayeeFSP: 200 OK + + Switch -> Switch: Validate quote response + alt SimpleRoutingMode === FALSE + Switch -> Switch: Duplicate check + alt Response is duplicate but not a resend + Switch -\ PayeeFSP: PUT /quotes/{ID}/error + Switch \-- PayeeFSP: 200 OK + end + alt Response is a duplicate and a resend + Switch -> Switch: Switch handles resend scenario + end + Switch -\ DB: Persist quote response + activate DB + hnote over DB + quoteResponse + quoteDuplicateCheck + quoteResponseIlpPacket + geoCode + quoteExtension + end hnote + Switch \-- DB: Quote response saved + deactivate DB + end + note left of Switch: Switch forwards quote response to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID} + PayerFSP --/ Switch: 200 OK + else Payee rejects quotes or encounters and error + note left of PayeeFSP: Payee FSP sends error callback to Payer FSP via the Switch + Switch /- PayeeFSP: PUT /quotes/{ID}/error + Switch --/ PayeeFSP: 200 OK + alt SimpleRoutingMode === FALSE + Switch -\ DB: Store quote error + activate DB + hnote over DB + quoteError + end hnote + Switch \-- DB: Quote error saved + deactivate DB + end + note left of Switch: Switch forwards error callback to Payer FSP + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --/ Switch: 200 OK + end +else Payee FSP quotes endpoint not found + note left of Switch: Switch sends an error callback to Payer FSP \n **Error code: 3201** + PayerFSP /- Switch: PUT /quotes/{ID}/error + PayerFSP --\ Switch: 200 OK +end + +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg new file mode 100644 index 000000000..6250d6e02 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-post-quotes-1.2.0.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + Request Quote Creation + + + + + + + + + + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + [Quoting + + + Service] + + + + Switch + + + [Quoting + + + Service] + + + Central Store + + + + + Central Store + + + + + + Payee FSP + + + + Payee FSP + + + + + + Payer FSP sends request for quote + + + to Payee FSP via the Switch + + + + + 1 + + + POST /quotes + + + + + Validate request against + + + Mojaloop interface specification + + + Error code: 300x, 310x + + + HTTP error response code: 4xx + + + + + 2 + + + Schema validation + + + + + 3 + + + 202 Accepted + + + + + 4 + + + Quote request validation (rules engine etc.) + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 5 + + + Duplicate check + + + + + alt + + + [Request is a duplicate but not a resend] + + + + + Switch returns error back to Payer FSP + + + Error code: 3106 + + + + + 6 + + + PUT /quotes/{ID}/error + + + + + 7 + + + 200 OK + + + + [Request is a duplicate and a resend] + + + + + 8 + + + Switch handles resend scenario + + + + + 9 + + + Persist quote request + + + + quoteDuplicateCheck + + + transactionReference + + + quote + + + quoteParty + + + quoteExtension + + + geoCode + + + + + 10 + + + Quote request saved + + + + + alt + + + [SimpleRoutingMode === TRUE] + + + + + 11 + + + Use fspiop-destination header to retrieve quotes endpoint for Payee FSP + + + + [SimpleRoutingMode === FALSE] + + + + + 12 + + + Retireve Payee FSP endpoint using quote party information + + + + + alt + + + [Payee quotes endpoint found] + + + + + Switch forwards quote request to Payee FSP + + + + + 13 + + + POST /quotes + + + + + 14 + + + 202 OK + + + + + 15 + + + Payee FSP presists and calculates quote + + + + + alt + + + [Payee quotes processing successful] + + + + + Payee FSP sends quote response back to Payer FSP via the Switch + + + + + 16 + + + PUT /quotes/{ID} + + + + + 17 + + + 200 OK + + + + + 18 + + + Validate quote response + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 19 + + + Duplicate check + + + + + alt + + + [Response is duplicate but not a resend] + + + + + 20 + + + PUT /quotes/{ID}/error + + + + + 21 + + + 200 OK + + + + + alt + + + [Response is a duplicate and a resend] + + + + + 22 + + + Switch handles resend scenario + + + + + 23 + + + Persist quote response + + + + quoteResponse + + + quoteDuplicateCheck + + + quoteResponseIlpPacket + + + geoCode + + + quoteExtension + + + + + 24 + + + Quote response saved + + + + + Switch forwards quote response to Payer FSP + + + + + 25 + + + PUT /quotes/{ID} + + + + + 26 + + + 200 OK + + + + [Payee rejects quotes or encounters and error] + + + + + Payee FSP sends error callback to Payer FSP via the Switch + + + + + 27 + + + PUT /quotes/{ID}/error + + + + + 28 + + + 200 OK + + + + + alt + + + [SimpleRoutingMode === FALSE] + + + + + 29 + + + Store quote error + + + + quoteError + + + + + 30 + + + Quote error saved + + + + + Switch forwards error callback to Payer FSP + + + + + 31 + + + PUT /quotes/{ID}/error + + + + + 32 + + + 200 OK + + + + [Payee FSP quotes endpoint not found] + + + + + Switch sends an error callback to Payer FSP + + + Error code: 3201 + + + + + 33 + + + PUT /quotes/{ID}/error + + + + + 34 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml new file mode 100644 index 000000000..4f3405364 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.plantuml @@ -0,0 +1,68 @@ +@startuml +Title Quoting Service Sequences +participant "Payer DFSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee DFSP" + +autonumber +note over "Payer DFSP", Switch: Payer DFSP requests quote from Payee DFSP +"Payer DFSP" -\ Switch: POST /quotes +Switch --/ "Payer DFSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee DFSP": Switch forwards quote request to Payee DFSP\n + Switch -\ "Payee DFSP": POST /quotes + "Payee DFSP" --/ Switch: 202 Accepted + "Payee DFSP" -> "Payee DFSP": Calculate Fees/Charges + + alt Payee DFSP successfully calculates quote + + note over "Payee DFSP", Switch: Payee DFSP responds to quote request + "Payee DFSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee DFSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + + Switch -> Switch: Persist Response Data + + note over Switch, "Payer DFSP": Switch forwards quote response to Payer DFSP\n + + Switch -\ "Payer DFSP": PUT /quotes/{ID} + "Payer DFSP" --/ Switch: 200 Ok + + note over "Payer DFSP" #3498db: Payer DFSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee DFSP": Switch returns error to Payee DFSP + + Switch -\ "Payee DFSP": PUT /quotes/{ID}/error + "Payee DFSP" --/ Switch : 200 Ok + + note over Switch, "Payee DFSP" #ec7063: Note that under this\nscenario the Payer DFSP\nmay not receive a response + + end + else Payee DFSP calculation fails or rejects the request + + note over "Payee DFSP", Switch: Payee DFSP returns error to Switch + + "Payee DFSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee DFSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer DFSP", Switch: Switch returns error to Payer DFSP + Switch -\ "Payer DFSP": PUT quotes/{ID}/error + "Payer DFSP" --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg new file mode 100644 index 000000000..b79aecb9d --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-1.0.0.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + Quoting Service Sequences + + + + + + + + + Payer DFSP + + + + Payer DFSP + + + + Switch + + + Quoting + + + Service + + + + Switch + + + Quoting + + + Service + + + + Payee DFSP + + + + Payee DFSP + + + + + Payer DFSP requests quote from Payee DFSP + + + + + 1 + + + POST /quotes + + + + + 2 + + + 202 Accepted + + + + + 3 + + + Validate Quote Request + + + + + alt + + + [quote is valid] + + + + + 4 + + + Persist Quote Data + + + + + Switch forwards quote request to Payee DFSP + + + <Payer based Rules> + + + + + 5 + + + POST /quotes + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Calculate Fees/Charges + + + + + alt + + + [Payee DFSP successfully calculates quote] + + + + + Payee DFSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate Quote Response + + + + + alt + + + [response is ok] + + + + + 11 + + + Persist Response Data + + + + + Switch forwards quote response to Payer DFSP + + + <Payee whole request Rule> + + + + + 12 + + + PUT /quotes/{ID} + + + + + 13 + + + 200 Ok + + + + + Payer DFSP continues + + + with transfer if quote + + + is acceptable... + + + + [response invalid] + + + + + Switch returns error to Payee DFSP + + + + + 14 + + + PUT /quotes/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer DFSP + + + may not receive a response + + + + [Payee DFSP calculation fails or rejects the request] + + + + + Payee DFSP returns error to Switch + + + + + 16 + + + PUT quotes/{ID}/error + + + + + 17 + + + 200 OK + + + + + 18 + + + Persist error data + + + + + Switch returns error to Payer DFSP + + + + + 19 + + + PUT quotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [quote invalid] + + + + + Switch returns error to Payer DFSP + + + + + 21 + + + PUT quotes/{ID}/error + + + + + 22 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml new file mode 100644 index 000000000..3275abff7 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.plantuml @@ -0,0 +1,67 @@ +@startuml +Title Quoting Service Sequences +participant "Payer FSP" +participant "Switch\nQuoting\nService" as Switch +participant "Payee FSP" + +autonumber +note over "Payer FSP", Switch: Payer FSP requests quote from Payee FSP +"Payer FSP" -\ Switch: POST /quotes +Switch --/ "Payer FSP": 202 Accepted +Switch -> Switch: Validate Quote Request + +alt quote is valid + + Switch -> Switch: Persist Quote Data + note over Switch, "Payee FSP": Switch forwards quote request to Payee FSP\n + Switch -\ "Payee FSP": POST /quotes + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Calculate Fees/Charges + + alt Payee FSP successfully calculates quote + + note over "Payee FSP", Switch: Payee FSP responds to quote request + "Payee FSP" -\ Switch: PUT /quotes/{ID} + Switch --/ "Payee FSP": 200 Ok + + Switch -> Switch: Validate Quote Response + + alt response is ok + Switch -> Switch: Persist Response Data + + note over Switch, "Payer FSP": Switch forwards quote response to Payer FSP\n + + Switch -\ "Payer FSP": PUT /quotes/{ID} + "Payer FSP" --/ Switch: 200 Ok + + note over "Payer FSP" #3498db: Payer FSP continues\nwith transfer if quote\nis acceptable... + else response invalid + + note over Switch, "Payee FSP": Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /quotes/{ID}/error + "Payee FSP" --/ Switch : 200 Ok + + note over Switch, "Payee FSP" #ec7063: Note that under this\nscenario the Payer FSP\nmay not receive a response + + end + else Payee FSP calculation fails or rejects the request + + note over "Payee FSP", Switch: Payee FSP returns error to Switch + + "Payee FSP" -\ Switch: PUT quotes/{ID}/error + Switch --/ "Payee FSP": 200 OK + Switch -> Switch: Persist error data + + note over "Payer FSP", Switch: Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK + + end +else quote invalid + note over "Payer FSP", Switch: Switch returns error to Payer FSP + Switch -\ "Payer FSP": PUT quotes/{ID}/error + "Payer FSP" --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg new file mode 100644 index 000000000..69b7fb6d4 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/assets/diagrams/sequence/seq-quotes-overview-1.0.0.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + Quoting Service Sequences + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + Quoting + + + Service + + + + Switch + + + Quoting + + + Service + + + + Payee FSP + + + + Payee FSP + + + + + Payer FSP requests quote from Payee FSP + + + + + 1 + + + POST /quotes + + + + + 2 + + + 202 Accepted + + + + + 3 + + + Validate Quote Request + + + + + alt + + + [quote is valid] + + + + + 4 + + + Persist Quote Data + + + + + Switch forwards quote request to Payee FSP + + + <Payer based Rules> + + + + + 5 + + + POST /quotes + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Calculate Fees/Charges + + + + + alt + + + [Payee FSP successfully calculates quote] + + + + + Payee FSP responds to quote request + + + + + 8 + + + PUT /quotes/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate Quote Response + + + + + alt + + + [response is ok] + + + + + 11 + + + Persist Response Data + + + + + Switch forwards quote response to Payer FSP + + + <Payee whole request Rule> + + + + + 12 + + + PUT /quotes/{ID} + + + + + 13 + + + 200 Ok + + + + + Payer FSP continues + + + with transfer if quote + + + is acceptable... + + + + [response invalid] + + + + + Switch returns error to Payee FSP + + + + + 14 + + + PUT /quotes/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payer FSP + + + may not receive a response + + + + [Payee FSP calculation fails or rejects the request] + + + + + Payee FSP returns error to Switch + + + + + 16 + + + PUT quotes/{ID}/error + + + + + 17 + + + 200 OK + + + + + 18 + + + Persist error data + + + + + Switch returns error to Payer FSP + + + + + 19 + + + PUT quotes/{ID}/error + + + + + 20 + + + 200 OK + + + + [quote invalid] + + + + + Switch returns error to Payer FSP + + + + + 21 + + + PUT quotes/{ID}/error + + + + + 22 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-bulk-quotes.md b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-bulk-quotes.md new file mode 100644 index 000000000..b78339ff6 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-bulk-quotes.md @@ -0,0 +1,7 @@ +# GET Quote By ID + +Design for the retrieval of a Bulk Quote by an FSP. + +## Sequence Diagram + +![seq-get-bulk-quotes-2.1.0.svg](./assets/diagrams/sequence/seq-get-bulk-quotes-2.1.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-quotes.md b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-quotes.md new file mode 100644 index 000000000..765b5b4bf --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-get-quotes.md @@ -0,0 +1,7 @@ +# GET Quote By ID + +Design for the retrieval of a Quote by an FSP. + +## Sequence Diagram + +![seq-get-quotes-1.1.0.svg](./assets/diagrams/sequence/seq-get-quotes-1.1.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-bulk-quotes.md b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-bulk-quotes.md new file mode 100644 index 000000000..28e692e68 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-bulk-quotes.md @@ -0,0 +1,7 @@ +# POST Quote + +Design for a Bulk Quote request by an FSP. + +## Sequence Diagram + +![seq-post-bulk-quotes-2.2.0.svg](./assets/diagrams/sequence/seq-post-bulk-quotes-2.2.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-quotes.md b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-quotes.md new file mode 100644 index 000000000..b8f99fedf --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/quoting-service/qs-post-quotes.md @@ -0,0 +1,7 @@ +# POST Quote + +Design for a Quote request by an FSP. + +## Sequence Diagram + +![seq-post-quotes-1.2.0.svg](./assets/diagrams/sequence/seq-post-quotes-1.2.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/README.md b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/README.md new file mode 100644 index 000000000..99127ef7c --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/README.md @@ -0,0 +1,9 @@ +# SDK Scheme Adapter +A scheme adapter is a service that interfaces between a Mojaloop API compliant switch and a DFSP backend platform that does not natively implement the Mojaloop API. + +The API between the scheme adapter and the DFSP backend is synchronous HTTP while the interface between the scheme adapter and the switch is native Mojaloop API. + +* [Usage](./usage/README.md) + * [Scheme Adapter to Scheme Adapter](./usage/scheme-adapter-to-scheme-adapter/README.md) + * [Scheme Adapter to Local K8S cluster](./usage/scheme-adapter-and-local-k8s/README.md) + * [Scheme Adapter to WSO2 API Gateway](./usage/scheme-adapter-and-wso2-api-gateway/README.md) diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/README.md b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/README.md new file mode 100644 index 000000000..4984fc721 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/README.md @@ -0,0 +1,44 @@ +# Overview +A scheme adapter is a service that interfaces between a Mojaloop API compliant switch and a DFSP backend platform that does not natively implement the Mojaloop API. + +The API between the scheme adapter and the DFSP backend is synchronous HTTP while the interface between the scheme adapter and the switch is native Mojaloop API. + +This document provides different ways of setups that a DFSP can test using the scheme adapter. + +# Scenarios +There are number of scenarios those we tested and documented as follows. + +* [[Scheme Adapter + Mock DFSP Backend] -> [Scheme Adapter + Mojaloop Simulator]](./scheme-adapter-to-scheme-adapter/README.md) +* [[Scheme Adapter + Mock DFSP Backend] -> [Local K8S cluster]](./scheme-adapter-and-local-k8s/README.md) +* [[Scheme Adapter + Mojaloop Simulator] -> [Public hosted WSO2 enabled Mojaloop Switch]](./scheme-adapter-and-wso2-api-gateway/README.md) + +## [Scheme Adapter + Mock DFSP Backend] -> [Scheme Adapter + Mojaloop Simulator] + +The scheme adpater can be used in combination with some already implemented mock backends "Mock DFSP Backend" and "Mojaloop Simulator". The below are the links for the repositories. + +https://github.com/mojaloop/sdk-mock-dfsp-backend.git + +https://github.com/mojaloop/mojaloop-simulator.git + +The idea is to combine scheme adapter with mock DFSP backend on oneside and with mojaloop simulator on another side. Consider one side is payer dfsp and another side is payee dfsp. By following this example, you can send and recieve funds from one dfsp to another. + +Please [click here](./scheme-adapter-to-scheme-adapter/README.md) for the documentation. + +![SchemeAdapterToSchemeAdapter](./scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png) + +## [Scheme Adapter + Mock DFSP Backend] -> [Local K8S cluster] + +Then if we want to include a switch inbetween the DFSPs, we can simulate that environment using a local K8S cluster. Please follow the onboarding documentation of local K8S cluster here (https://mojaloop.io/documentation/deployment-guide/). + +Please [click here](./scheme-adapter-and-local-k8s/README.md) for the documentation. + +![SchemeAdapterAndK8S](./scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png) + +## [Scheme Adapter + Mojaloop Simulator] -> [Public hosted WSO2 enabled Mojaloop Switch] + +If you have access to the WSO2 Mojaloop API, you can test that by the following documentation. In the above two scenarios, we didn't use token authentication and SSL encryption capabilities of scheme adapter. We are going to use those capabilites in this section. + +Please [click here](./scheme-adapter-and-wso2-api-gateway/README.md) for the documentation. + + +![SchemeAdapterAndWSO2APIGateway](./scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png) diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md new file mode 100644 index 000000000..5accc7ec1 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/README.md @@ -0,0 +1,206 @@ +# SDK Scheme Adapter and Local K8S cluster testing + +A detailed documentation for dfsps who want to test the mojaloop cluster deployment with scheme adapter and a mock backend service. + +![Overview](scheme-adapter-and-local-k8s-overview.png) + +## Prerequisite + +* A working mojaloop k8s cluster (Local / Cloud deployment) +* DFSP mock backend service +* sdk-scheme-adapter > 8.6.0 + +## Configuration & Starting services + +### Mojaloop Local K8S cluster deployment +Please follow the below link to deploy your own cluster on local system. +https://mojaloop.io/documentation/deployment-guide/ + +A Linux based operating system is recommended and at least 16GB RAM and 4 core processor is required. + +After installation please complete the `OSS-New-Deployment-FSP-Setup.postman_collection` collection available at https://github.com/mojaloop/postman + +Then make sure the oracles & endpoints are configured correctly and that the "Golden Path Collection" can be run successfully. + +### DFSP Mock Backend service & SDK Scheme adapter +The SDK scheme adapter version should be greater than 8.6.0 +The next step starts the scheme adapter from docker-compose file automatically. + +Please download the following repository +https://github.com/mojaloop/sdk-mock-dfsp-backend + +Edit the docker-compose.yml file and verify the following lines. + +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 +``` + +Edit the backend.env file and change the OUTBOUND_ENDPOINT value +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Edit scheme-adapter.env and change the following lines +Please replace the endpoint values with the appropriate hostnames provided in /etc/hosts file. + +``` +DFSP_ID=safsp +CACHE_HOST=redis2 +ALS_ENDPOINT=account-lookup-service.local +QUOTES_ENDPOINT=quoting-service.local +TRANSFERS_ENDPOINT=ml-api-adapter.local +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true +``` + +### Name resolution configuration - Mac ONLY + +Point the following hostnames to your local machine IP by adding the below line in /etc/hosts file +``` +192.168.5.101 ml-api-adapter.local account-lookup-service.local central-ledger.local central-settlement.local account-lookup-service-admin.local quoting-service.local moja-simulator.local central-ledger central-settlement ml-api-adapter account-lookup-service account-lookup-service-admin quoting-service simulator host.docker.internal moja-account-lookup-mysql +``` + +Make sure to change 192.168.5.101 to your real external IP. + +### Name resolution configuration - Linux ONLY + +Add extra_hosts configuration to scheme-adapter2 config in the docker-compose.yml file, so that the scheme-adapter2 container can resolve dns of account-lookup-service.local, quoting-service.local and ml-api-adapter.local. For example the config could be: + +``` + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + ports: + - "4000:4000" + depends_on: + - redis2 + extra_hosts: + - "account-lookup-service.local:172.17.0.1" + - "quoting-service.local:172.17.0.1" + - "ml-api-adapter.local:172.17.0.1" +``` + +The 172.17.0.1 is a default docker0 network interface on linux, however please make sure it's valid in your configuration and change it if needed. + +### Start + +Start the backend and scheme adapter using the following command. +``` +cd src +docker-compose up -d +``` + +## Testing + +### Configure new FSP +Download the following files: +* [Mojaloop-Local.postman_environment_modified.json](assets/postman_files/Mojaloop-Local.postman_environment_modified.json) - modified environment variables that point to your local setup +* [OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json](assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json) - steps that will setup new FSP + +The SCHEME_ADAPTER_ENDPOINT in the environment file should point to your local scheme-adapter deployment. For mac this is configured already to be http://host.docker.internal:4000. If you're running on Linux, please edit the environment file, so that SCHEME_ADAPTER_ENDPOINT points to your docker0 interface (usually 172.17.0.1 - see remarks in previous step). + +In postman, select the environment file and run the custom collection in the postman to provision a new FSP called "safsp". The endpoints for safsp will be set to the URL of the scheme adapter which is configured in environment file. + +### Add the target MSISDN to payee simulator which is running inside the K8S. Run the following commands +``` +curl -X POST \ + http://moja-simulator.local/payeefsp/parties/MSISDN/27713803912 \ + -H 'Accept: */*' \ + -H 'Accept-Encoding: gzip, deflate' \ + -H 'Cache-Control: no-cache' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 406' \ + -H 'Content-Type: application/json' \ + -H 'Host: moja-simulator.local' \ + -H 'User-Agent: PostmanRuntime/7.20.1' \ + -H 'cache-control: no-cache' \ + -d '{ + "party": { + "partyIdInfo": { + "partyIdType": "MSISDN", + "partyIdentifier": "27713803912", + "fspId": "payeefsp" + }, + "name": "Siabelo Maroka", + "personalInfo": { + "complexName": { + "firstName": "Siabelo", + "lastName": "Maroka" + }, + "dateOfBirth": "1974-01-01" + } + } +}' + +curl -X POST \ + http://account-lookup-service.local/participants/MSISDN/27713803912 \ + -H 'Accept: application/vnd.interoperability.participants+json;version=1' \ + -H 'Connection: keep-alive' \ + -H 'Content-Length: 50' \ + -H 'Content-Type: application/vnd.interoperability.participants+json;version=1.0' \ + -H 'Date: Fri, 21 Dec 2018 12:17:01 GMT' \ + -H 'FSPIOP-Source: payeefsp' \ + -H 'Host: account-lookup-service.local' \ + -H 'User-Agent: PostmanRuntime/7.11.0' \ + -H 'accept-encoding: gzip, deflate' \ + -H 'cache-control: no-cache,no-cache' \ + -d '{ + "fspId": "payeefsp", + "currency": "USD" +}' +``` + +### Try to send money +Try to send funds from "safsp" (Mock DFSP) to a MSISDN which is in "payeedfsp" (Simulator in K8S) through scheme adapter. +Run the following curl command to issue command to Mock DFSP service. +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "27713803912" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" +}' +``` + +You should get a response with COMPLETED currentState. diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json new file mode 100644 index 000000000..eddcac266 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/Mojaloop-Local.postman_environment_modified.json @@ -0,0 +1,1012 @@ +{ + "id": "a9937c8b-0281-4128-8b53-1f1f913ff2aa", + "name": "Mojaloop-Local", + "values": [ + { + "key": "payeefsp", + "value": "payeefsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfsp", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiration", + "value": "2019-05-27T15:44:53.292Z", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transactionRequestId", + "value": "25a00155-c777-4629-a6b7-61cf0d16f499", + "enabled": true + }, + { + "key": "transferDate", + "value": "Fri, 21 Dec 2018 12:17:01 GMT", + "enabled": true + }, + { + "key": "currentTimestamp", + "value": "2018-12-06T17:09:56.386Z", + "enabled": true + }, + { + "key": "quoteDate", + "value": "Fri, 21 Dec 2018 12:19:49 GMT", + "enabled": true + }, + { + "key": "quoteExpiration", + "value": "2018-11-08T21:31:00.534+01:00", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_MOJALOOP", + "value": "localhost:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_MOJALOOP", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_LEDGER", + "value": "http://central-ledger.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_LEDGER_ADMIN", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ML_API", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_ML_API", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_CENTRAL_SETTLEMENT", + "value": "http://central-settlement.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_CENTRAL_SETTLEMENT", + "value": "/v1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_PREPARE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSFER_UUID_ON_QUOTE\n", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TIMESTAMP", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_PREPARE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_QUOTE_DATE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "CONFIG_GENERATE_NEW_TRANSACTION_UUID_ON_QUOTE", + "value": "true", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "transferExpiredExpiration", + "value": "2018-08-31T15:26:01.870Z", + "enabled": true + }, + { + "key": "condition", + "value": "HOr22-H3AfTDHrSkPjJtVPRdKouuMkDXTR4ejlQa8Ks", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "fulfilment", + "value": "uU0nuZNNPgilLlLX2n2r-sSE7-N6U4DukIj3rOLvzek", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR", + "value": "http://moja-simulator.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "SCHEME_ADAPTER_ENDPOINT", + "value": "http://host.docker.internal:4000", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "quoteId", + "value": "ddaa67b3-5bf8-45c1-bfcf-1e8781177c37", + "enabled": true + }, + { + "key": "ilpPacket", + "value": "AQAAAAAAAADIEHByaXZhdGUucGF5ZWVmc3CCAiB7InRyYW5zYWN0aW9uSWQiOiIyZGY3NzRlMi1mMWRiLTRmZjctYTQ5NS0yZGRkMzdhZjdjMmMiLCJxdW90ZUlkIjoiMDNhNjA1NTAtNmYyZi00NTU2LThlMDQtMDcwM2UzOWI4N2ZmIiwicGF5ZWUiOnsicGFydHlJZEluZm8iOnsicGFydHlJZFR5cGUiOiJNU0lTRE4iLCJwYXJ0eUlkZW50aWZpZXIiOiIyNzcxMzgwMzkxMyIsImZzcElkIjoicGF5ZWVmc3AifSwicGVyc29uYWxJbmZvIjp7ImNvbXBsZXhOYW1lIjp7fX19LCJwYXllciI6eyJwYXJ0eUlkSW5mbyI6eyJwYXJ0eUlkVHlwZSI6Ik1TSVNETiIsInBhcnR5SWRlbnRpZmllciI6IjI3NzEzODAzOTExIiwiZnNwSWQiOiJwYXllcmZzcCJ9LCJwZXJzb25hbEluZm8iOnsiY29tcGxleE5hbWUiOnt9fX0sImFtb3VudCI6eyJjdXJyZW5jeSI6IlVTRCIsImFtb3VudCI6IjIwMCJ9LCJ0cmFuc2FjdGlvblR5cGUiOnsic2NlbmFyaW8iOiJERVBPU0lUIiwic3ViU2NlbmFyaW8iOiJERVBPU0lUIiwiaW5pdGlhdG9yIjoiUEFZRVIiLCJpbml0aWF0b3JUeXBlIjoiQ09OU1VNRVIiLCJyZWZ1bmRJbmZvIjp7fX19", + "enabled": true + }, + { + "key": "payerFspId", + "value": "3", + "enabled": true + }, + { + "key": "payerFspAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspId", + "value": "4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeeFspAccountId", + "value": "5", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "openWindowID", + "value": 1, + "enabled": true + }, + { + "key": "newOpenWindowID", + "value": 2, + "enabled": true + }, + { + "key": "closedWindowID", + "value": 1, + "enabled": true + }, + { + "key": "settlementId", + "value": 1, + "enabled": true + }, + { + "key": "expectedFullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "expectedFirstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "expectedLastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "expectedDOB", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "pathfinderMSISDN", + "value": "27713803912", + "enabled": true + }, + { + "key": "fullName", + "value": "Siabelo Maroka", + "enabled": true + }, + { + "key": "firstName", + "value": "Siabelo", + "enabled": true + }, + { + "key": "lastName", + "value": "Maroka", + "enabled": true + }, + { + "key": "dob", + "value": "3/3/1973", + "enabled": true + }, + { + "key": "HOST_ML_API_ADAPTER", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "dateHeader", + "value": "Thu, 24 Jan 2019 10:22:12 GMT", + "enabled": true + }, + { + "key": "participant", + "value": "testfsp4", + "enabled": true + }, + { + "key": "payerfspBeforePosition", + "value": -1782, + "enabled": true + }, + { + "key": "HOST_SWITCH_TRANSFERS", + "value": "http://ml-api-adapter.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "BASE_PATH_SWITCH_TRANSFERS", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_SIMULATOR_K8S_CLUSTER", + "value": "http://moja-simulator", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payerfspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payeefspPositionBeforeTransfer", + "value": 0, + "enabled": true + }, + { + "key": "blockTransferAmount", + "value": 7494, + "enabled": true + }, + { + "key": "payeeNDC", + "value": 1000, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "transferAmount", + "value": "99", + "enabled": true + }, + { + "key": "payeefspPositionAfterTransfer", + "value": 0, + "enabled": true + }, + { + "key": "payerfspPositionAfterTransferBeforeExpiry", + "value": 1596, + "enabled": true + }, + { + "key": "fspName", + "value": "payerfsp", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "settlementAccountId", + "value": "3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "reportEndDate", + "value": "2018-10-31", + "enabled": true + }, + { + "key": "reportFSPID", + "value": "payerfsp", + "enabled": true + }, + { + "key": "reportStartDate", + "value": "2018-10-01", + "enabled": true + }, + { + "key": "transactionId", + "value": "97f3f215-37a0-4755-a17c-c39313aa2f98", + "enabled": true + }, + { + "key": "payerfspSettlementAccountId", + "value": 8, + "enabled": true + }, + { + "key": "payeefspSettlementAccountId", + "value": 4, + "enabled": true + }, + { + "key": "fundsInPrepareTransferId", + "value": "b79a979e-9605-4db4-a052-85bc948be414", + "enabled": true + }, + { + "key": "HUBOPERATOR_BEARER_TOKEN", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hub_operator", + "value": "NOT_APPLICABLE", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefspNetSettlementAmount", + "value": -198, + "enabled": true + }, + { + "key": "payerfspNetSettlementAmount", + "value": 198, + "enabled": true + }, + { + "key": "fundsInPrepareAmount", + "value": 500, + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalance", + "value": -4800, + "enabled": true + }, + { + "key": "hubReconAccountBalance", + "value": 4800, + "enabled": true + }, + { + "key": "payerfspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "payeefspAccountBalanceBeforeSettlement", + "value": 0, + "enabled": true + }, + { + "key": "fundsOutPrepareTransferId", + "value": "f60c555f-72a7-44c7-a3a8-1f4a4df4b100", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsIn", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareAmount", + "value": "", + "enabled": true + }, + { + "key": "payerfspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspNDCBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionAccountId", + "value": 3, + "enabled": true + }, + { + "key": "payerfspPositionAccountId", + "value": 7, + "enabled": true + }, + { + "key": "testfsp1", + "value": "testfsp1", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2", + "value": "testfsp2", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountId", + "value": 25, + "enabled": true + }, + { + "key": "testfsp1SettlementAccountId", + "value": 26, + "enabled": true + }, + { + "key": "testfsp2PositionAccountId", + "value": 29, + "enabled": true + }, + { + "key": "testfsp2SettlementAccountId", + "value": 30, + "enabled": true + }, + { + "key": "testfsp1Id", + "value": "13", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp2Id", + "value": "14", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutCommitTransferId", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutCommit", + "value": "", + "enabled": true + }, + { + "key": "transfer_ID", + "value": "e7b43799-e69e-4578-bd26-2a4b9a22e92e", + "enabled": true + }, + { + "key": "get_transfer_ID", + "value": "7e19ae5f-7db6-4612-ab99-7538a56b4c25", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "env_prefix", + "value": "test", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsInReserve", + "value": "", + "enabled": true + }, + { + "key": "validCondition", + "value": "GRzLaTP7DJ9t4P-a_BA0WA9wzzlsugf00-Tn6kESAfM", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "validFulfillment", + "value": "UNlJ98hZTY_dsw0cAqw4i_UN3v4utt7CZFB4yfLbVFA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "currency", + "value": "USD", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalance", + "value": "", + "enabled": true + }, + { + "key": "testfspId3", + "value": "15", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfspId4", + "value": "16", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "invalidFulfillment", + "value": "_3cco-YN5OGpRKVWV3n6x6uNpBTH9tYUdOYmHA", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "completedTimestamp", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payeefspPositionBeforePrepare", + "value": "", + "enabled": true + }, + { + "key": "payerfspPositionAfterPrepare", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveAmount", + "value": "", + "enabled": true + }, + { + "key": "fundsOutPrepareReserveTransferId", + "value": "", + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceBeforeTransfer", + "value": "", + "enabled": true + }, + { + "key": "fspiop-signature", + "value": "{\"signature\":\"iU4GBXSfY8twZMj1zXX1CTe3LDO8Zvgui53icrriBxCUF_wltQmnjgWLWI4ZUEueVeOeTbDPBZazpBWYvBYpl5WJSUoXi14nVlangcsmu2vYkQUPmHtjOW-yb2ng6_aPfwd7oHLWrWzcsjTF-S4dW7GZRPHEbY_qCOhEwmmMOnE1FWF1OLvP0dM0r4y7FlnrZNhmuVIFhk_pMbEC44rtQmMFv4pm4EVGqmIm3eyXz0GkX8q_O1kGBoyIeV_P6RRcZ0nL6YUVMhPFSLJo6CIhL2zPm54Qdl2nVzDFWn_shVyV0Cl5vpcMJxJ--O_Zcbmpv6lxqDdygTC782Ob3CNMvg\\\",\\\"protectedHeader\\\":\\\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1VUkkiOiIvdHJhbnNmZXJzIiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUE9TVCIsIkZTUElPUC1Tb3VyY2UiOiJPTUwiLCJGU1BJT1AtRGVzdGluYXRpb24iOiJNVE5Nb2JpbGVNb25leSIsIkRhdGUiOiIifQ\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountId", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4SettlementAccountBalanceBeforeFundsIn", + "value": "", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp3", + "value": "testfsp3", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp4", + "value": "testfsp4", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "testfsp1PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp1SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp2SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp3SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4PositionAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "testfsp4SettleAccountBalanceAfterTransfer", + "value": "", + "enabled": true + }, + { + "key": "hubReconAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payerfspSettlementAccountBalanceBeforeFundsOutAbort", + "value": "", + "enabled": true + }, + { + "key": "payeefsp_fspiop_signature", + "value": "{\"signature\":\"abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess\",\"protectedHeader\":\"eyJhbGciOiJSUzI1NiIsIkZTUElPUC1Tb3VyY2UiOiJwYXllZWZzcCIsIkZTUElPUC1EZXN0aW5hdGlvbiI6InBheWVyZnNwIiwiRlNQSU9QLVVSSSI6Ii90cmFuc2ZlcnMvZDY3MGI1OTAtZjc5ZC00YWU5LThjNmUtMTVjZjZjNWMzODk5IiwiRlNQSU9QLUhUVFAtTWV0aG9kIjoiUFVUIiwiRGF0ZSI6IiJ9\"}", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_SERVICE", + "value": "http://account-lookup-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_ACCOUNT_LOOKUP_ADMIN", + "value": "http://account-lookup-service-admin.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "HOST_QUOTING_SERVICE", + "value": "http://quoting-service.local", + "description": { + "content": "", + "type": "text/plain" + }, + "enabled": true + }, + { + "key": "payeefsp_signature", + "value": "abcJjvNrkyK2KBieDUbGfhaBUn75aDUATNF4joqA8OLs4QgSD7i6EO8BIdy6Crph3LnXnTM20Ai1Z6nt0zliS_qPPLU9_vi6qLb15FOkl64DQs9hnfoGeo2tcjZJ88gm19uLY_s27AJqC1GH1B8E2emLrwQMDMikwQcYvXoyLrL7LL3CjaLMKdzR7KTcQi1tCK4sNg0noIQLpV3eA61kess", + "type": "text", + "description": "", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2019-05-30T00:29:41.827Z", + "_postman_exported_using": "Postman/6.7.4" +} diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json new file mode 100644 index 000000000..70e2b3599 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/assets/postman_files/OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup.postman_collection.json @@ -0,0 +1,1072 @@ +{ + "info": { + "_postman_id": "52f405c0-bec3-4915-8c43-c250208623aa", + "name": "OSS-Custom-FSP-Onboaring-SchemeAdapter-Setup", + "description": "Author: Sridevi Miriyala\nPurpose: Used to add new FSP and relevant Callback Information", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "FSP Onboarding", + "item": [ + { + "name": "safsp (p2p transfers)", + "item": [ + { + "name": "Add payerfsp - TRANSFERS", + "event": [ + { + "listen": "test", + "script": { + "id": "76c222f4-969b-4081-b4d7-133ebe48f50f", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\": \"safsp\",\"currency\": \"{{currency}}\"}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants" + ] + } + }, + "response": [] + }, + { + "name": "Add initial position and limits - payerfsp", + "event": [ + { + "listen": "test", + "script": { + "id": "d767079d-a9dd-401a-8d6a-5f94654c4259", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"currency\": \"{{currency}}\",\n\t\"limit\": {\n\t \"type\": \"NET_DEBIT_CAP\",\n\t \"value\": 1000000\n\t},\n\t\"initialPosition\": 0\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/initialPositionAndLimits", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "initialPositionAndLimits" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTICIPANT PUT Batch Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTICIPANT_BATCH_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/participants/{{requestId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES GET", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_GET\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - PARTIES PUT Error", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/parties/{{partyIdType}}/{{partyIdentifier}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - QUOTES PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_QUOTES\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER POST", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_POST\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER PUT", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_PUT\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "Add payerfsp callback - TRANSFER ERROR", + "event": [ + { + "listen": "test", + "script": { + "id": "bb928ca3-8904-4cff-94fa-9629ccf2418d", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"FSPIOP_CALLBACK_URL_TRANSFER_ERROR\",\n \"value\": \"{{SCHEME_ADAPTER_ENDPOINT}}/transfers/{{transferId}}/error\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + } + }, + "response": [] + }, + { + "name": "9. Set Endpoint-NET_DEBIT_CAP_ADJUSTMENT_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "83984619-0430-4a4c-87ec-671bf97894de", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_ADJUSTMENT_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Set Endpoint-SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "16f8d261-3f2d-470b-986b-c8e23602605b", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "DFSP Endpoint-NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "67082524-b658-4f1c-90c4-af6fc24adb3e", + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL\",\n \"value\": \"sridevi.miriyala@modusbox.com\"\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/endpoints", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "endpoints" + ] + }, + "description": "Generated from a curl request: \ncurl -i -X POST {{HOST_CENTRAL_LEDGER}}/participants/testfsp2/initialPositionAndLimits -H 'Cache-Control: no-cache' -H 'Content-Type: application/json' -d '{\n \\\"currency\\\": \\\"USD\\\",\n \\\"limit\\\": {\n \\\"type\\\": \\\"NET_DEBIT_CAP\\\",\n \\\"value\\\": 1000\n },\n \\\"initialPosition\\\": 0\n }'" + }, + "response": [ + { + "name": "2. Create Initial Position and Limits", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Cache-Control", + "value": "no-cache" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"currency\": \"USD\",\n \"limit\": {\n \"type\": \"NET_DEBIT_CAP\",\n \"value\": 1000\n },\n \"initialPosition\": 0\n }" + }, + "url": { + "raw": "http://{{HOST_CENTRAL_LEDGER}}/participants/testfsp/initialPositionAndLimits", + "protocol": "http", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "testfsp", + "initialPositionAndLimits" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "Text", + "header": [], + "cookie": [], + "body": "" + } + ] + }, + { + "name": "Record Funds In - payerfsp ", + "event": [ + { + "listen": "test", + "script": { + "id": "802139ed-ec95-40f8-99a7-d88f0e77e49d", + "exec": [ + "pm.test(\"Status code is 202\", function () {", + " pm.response.to.have.status(202);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "461d34bc-33f6-4031-bbc4-b26489ff1953", + "exec": [ + "var uuid = require('uuid');", + "var generatedUUID = uuid.v4();", + "pm.environment.set('fundsInPrepareTransferId', generatedUUID);", + "pm.environment.set('fundsInPrepareAmount', 5000);", + "", + "", + "const payerfspGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/'+pm.environment.get(\"payerfsp\")+'/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"HUB_OPERATOR_BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"hub_operator\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(payerfspGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'SETTLEMENT') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"payerfspSettlementAccountId\",jsonData[i].id)", + " pm.environment.set(\"payerfspSettlementAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "", + "const hubGetStatusRequest = {", + " url: pm.environment.get(\"HOST_CENTRAL_LEDGER\")+pm.environment.get(\"BASE_CENTRAL_LEDGER_ADMIN\")+'/participants/hub/accounts',", + " method: 'GET',", + " header: {", + " \"Authorization\":\"Bearer \"+pm.environment.get(\"BEARER_TOKEN\"),", + " \"FSPIOP-Source\": pm.environment.get(\"payerfsp\"),", + " \"Content-Type\": \"application/json\"", + " }", + "};", + "pm.sendRequest(hubGetStatusRequest, function (err, response) {", + " console.log(response.json())", + " var jsonData = response.json()", + " for(var i in jsonData) {", + " if((jsonData[i].ledgerAccountType === 'HUB_RECONCILIATION') && (jsonData[i].currency === pm.environment.get(\"currency\"))) {", + " pm.environment.set(\"hubReconAccountBalanceBeforeFundsIn\",jsonData[i].value)", + " }", + " }", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{BEARER_TOKEN}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "FSPIOP-Source", + "value": "{{payerfsp}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"transferId\": \"{{fundsInPrepareTransferId}}\",\n \"externalReference\": \"string\",\n \"action\": \"recordFundsIn\",\n \"reason\": \"string\",\n \"amount\": {\n \"amount\":\"{{fundsInPrepareAmount}}\" ,\n \"currency\": \"{{currency}}\"\n },\n \"extensionList\": {\n \"extension\": [\n {\n \"key\": \"string\",\n \"value\": \"string\"\n }\n ]\n }\n}" + }, + "url": { + "raw": "{{HOST_CENTRAL_LEDGER}}/participants/safsp/accounts/{{payerfspSettlementAccountId}}", + "host": [ + "{{HOST_CENTRAL_LEDGER}}" + ], + "path": [ + "participants", + "safsp", + "accounts", + "{{payerfspSettlementAccountId}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "e5ffaeb6-241f-4b10-af63-b52b064ff44f", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "efb91eb5-c6c5-460c-89b0-a424f39dcf9a", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "a29d64a2-7a89-4cc9-ac33-2a630283471d", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "7bcf1b8c-ce85-4b11-ac83-899cc81ce501", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "402cb439-04ee-4add-9a65-f4b3f9dafa58", + "type": "text/javascript", + "exec": [ + "", + "// Ensure that the following variables are not set in the environment", + "// This is a fix for the following issue: https://github.com/mojaloop/project/issues/903", + "// This will ensure that templates are not replaced in the endpoint configs:", + "pm.environment.unset('partyIdType')", + "pm.environment.unset('partyIdentifier')", + "pm.environment.unset('requestId')", + "pm.environment.unset('transferId')", + "", + "pm.globals.unset('partyIdType')", + "pm.globals.unset('partyIdentifier')", + "pm.globals.unset('requestId')", + "pm.globals.unset('transferId')" + ] + } + }, + { + "listen": "test", + "script": { + "id": "e73fb24a-c94a-4551-ac31-fb7ceb250579", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png new file mode 100644 index 000000000..4d6282c3c Binary files /dev/null and b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-local-k8s/scheme-adapter-and-local-k8s-overview.png differ diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md new file mode 100644 index 000000000..f780e85bc --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/README.md @@ -0,0 +1,221 @@ +# SDK Scheme Adapter and WSO2 API Gateway + +This documentaion is for testing scheme adapter against a public hosted WSO2 API gateway with SSL encryption and bearer token authentication. + + +![Overview](scheme-adapter-and-wso2-api-gateway-overview.png) + +## Prerequisite + +* Accesss to WSO2 API production api with a generated token. +* sdk-scheme-adapter +* mojaloop-simulator + +## Generate access token and URL from WSO2 API + +* Login to your WSO2 store and go to applications in the menu. Create a new application and access keys if you don't have those already. +* Then go to APIs menu, you should find the following applications. Subscribe to these two APIs by selecting your application and tier from the each API main page. + * Central Ledger Admin API - We will use this endpoint for creating a new fsp and configure endpoints for that fsp. (Please contact your infra team for the proper https endpoints, they need to provision them on the hub) + * FSPIOP API - This is the main API for account lookup, quotes & transfers +* You can try some api requests in "API Console" tab by selecting the generated access token. +* Please make a note of the API URLs for both APIs and access token. + + +## Infrastructure Stuff +The following are the things your infrastructure team should take care off. +Please contact your infra team for further details. +* For getting back the responses, we need a machine with static public IP. And a domain name should be pointed to that IP. +* Generate client and server SSL certificates using MCM portal and keychain tool. This step is to establish secure communication using mutual SSL. +* Provision the endpoints pointing to your https address in WSO2 / HA Proxy. +* Establish JWS authentication +* **AWS Deployment** + * Launch an EC2 instance in AWS console + * Create an EC2 instance in AWS console and select **t2.micro** instance type. + * Select **Ubuntu 18.04** as your operating system. + * After your instance is ready, you can connect to it using ssh and the downloaded key file from AWS EC2 dashboard. + * Install docker and docker-compose in that EC2 instance + + * Open 4000 TCP port in security groups and assign elastic IP + * Add the inbound rule in security group of this EC2 instance that will expose the TCP 4000 port to public + * Use Elastic IP service to assign a static IP for this instance + + * Setup domain name for this instance + * You can use route53 in aws or any other DNS service to point a DNS name to this IP address + * This step is required because the Let's Encrypt certificate authority will not issue certificates for a bare IP address. + + +## Setting up Scheme Adapter with Mojaloop Simulator + +Please download the Mojaloop Simulator repo +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Replace the certificates and keys in src/secrets folder with the generated certificates in the previous step. + +* Edit the file src/docker-compose.yml and change the required parameters. Please refer the following file. + + ``` + version: '3' + services: + redis: + image: "redis:5.0.4-alpine" + container_name: redis + backend: + image: "mojaloop/mojaloop-simulator-backend" + env_file: ./sim-backend.env + container_name: ml_simulator + ports: + - "3000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + volumes: + - ./secrets:/src/secrets + ports: + - "3500:3000" + - "4000:4000" + depends_on: + - redis + ``` + +* Edit the file src/sim-backend.env file and change the container name of the scheme adapter in that. Please refer the following lines. + + ``` + OUTBOUND_ENDPOINT=http://src_scheme-adapter_1:4001 + DFSP_ID=extpayerfsp + ``` + +* Edit the file src/scheme-adapter.env and change the following settings + ``` + MUTUAL_TLS_ENABLED=true + CACHE_HOST=redis + DFSP_ID=extpayerfsp + BACKEND_ENDPOINT=ml_simulator:3000 + PEER_ENDPOINT= + AUTO_ACCEPT_QUOTES=true + ``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +We can now access the mojaloop simulator's test api on 3003. + +## Provision a new DFSP "extpayerfsp" with proper endpoints + +We should create a new fsp named "extpayerfp" or with any other name. + +The FSP onboarding section in "OSS-New-Deployment-FSP-Setup" postman collection can be used for this. You can get the postman repo from https://github.com/mojaloop/postman. +* Duplicate the "Mojaloop-Local" environment and change the following valuesin that + * payerfsp - extpayerfsp + * HOST_ML_API_ADAPTER, HOST_ML_API, HOST_SWITCH_TRANSFERS, HOST_ACCOUNT_LOOKUP_SERVICE, HOST_QUOTING_SERVICE - Your WSO2 FSPIOP API endpoint + * HOST_CENTRAL_LEDGER - Your WSO2 Central Services Admin API endpoint + * HOST_CENTRAL_SETTLEMENT - Your WSO2 Central Settlement API endpoint (optional for our testing) + * HOST_SIMULATOR & HOST_SIMULATOR_K8S_CLUSTER - https://:4000 +* Change the URLs in payerfsp onboarding in "FSP Onboarding" section of "OSS-New-Deployment-FSP-Setup" from "payerfsp" to "extpayerfsp" +* Change the authentication as "Bearer Token" and provide the access token we created in WSO2 store for the entire "Payer FSP Onboarding" folder. +* Change the endpoint URLs to the https endpoints provided by your infra team. +* Then run the "Payer FSP Onboarding" folder in that collection with the newly created environment. + +You should get 100% pass then we can confirm that the fsp is created and endpoints are set for the fsp. + +## Provision payeefsp and register a participant against MSISDN simulator + +Generally the simulator running in the switch contains payeefsp and you should register a new participant (phone number) of your choice. + +You can refer the postman request "p2p_happy_path SEND QUOTE / Register Participant {{pathfinderMSISDN}} against MSISDN Simulator for PayeeFSP" in "Golden_Path" collection to achieve this. + +The postman request will send a POST request to /participants/MSISDN/ with the following body and required http headers. +``` +{ + "fspId": "payeefsp", + "currency": "USD" +} +``` + +## Send money + +### In one step +If you want to send the money in one step, the configuration options "AUTO_ACCEPT_QUOTES" & "AUTO_ACCEPT_PARTY" in "scheme_adapter.env" should be enabled. + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "919848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + } +]' + +``` + +### In two steps + +The following command is used to send the money in two steps (i.e Requesting the quote first, accept after review the charges and party details) + +``` +curl -X POST \ + "http://localhost:3003/scenarios" \ + -H 'Content-Type: application/json' \ + -d '[ + { + "name": "scenario1", + "operation": "postTransfers", + "body": { + "from": { + "displayName": "From some person name", + "idType": "MSISDN", + "idValue": "44123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9848123456" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "testpayment", + "homeTransactionId": "123ABC" + } + }, + { + "name": "scenario2", + "operation": "putTransfers", + "params": { + "transferId": "{{scenario1.result.transferId}}" + }, + "body": { + "acceptQuote": true + } + } +]' + +``` \ No newline at end of file diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png new file mode 100644 index 000000000..206d31d45 Binary files /dev/null and b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-and-wso2-api-gateway/scheme-adapter-and-wso2-api-gateway-overview.png differ diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md new file mode 100644 index 000000000..b34595858 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/README.md @@ -0,0 +1,180 @@ +# Scheme Adapter to Scheme Adapter testing + +A detailed documentation for dfsps who want to test the transfer of funds from a scheme adapter to another scheme adapter directly using mock backend and mojaloop simulator services. + +![Overview](scheme-adapter-to-scheme-adapter-overview.png) + +## Prerequisite + +* Mojaloop Simulator +* DFSP mock backend service +* Scheme adapter is already included in both the above docker-compose scripts + +## Configuration & Starting services + +The idea is to run two docker-compose scripts in parallel from the above two services. To avoid conflicts we need to edit the docker-compose.yml files and specify the container names. + +### Mojaloop Simulator service + +Please download the Mojaloop Simulator repo +``` +git clone https://github.com/mojaloop/mojaloop-simulator.git +``` +* Edit the file src/docker-compose.yml and add the container names for all the containers. Please refer the following lines + +``` +version: '3' +services: + redis1: + image: "redis:5.0.4-alpine" + container_name: redis1 + sim: + image: "mojaloop-simulator-backend" + build: ../ + env_file: ./sim-backend.env + container_name: ml_sim1 + ports: + - "13000:3000" + - "3001:3001" + - "3003:3003" + depends_on: + - scheme-adapter + scheme-adapter: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim1 + ports: + - "13500:3000" + - "14000:4000" + depends_on: + - redis1 +``` + +* Edit the file src/sim-backend.env file and change the container name of the scheme adapter in that. Please refer the following lines. + +``` +OUTBOUND_ENDPOINT=http://sa_sim1:4001 +``` + +* Edit the file src/scheme-adapter.env file and change the container names of the another scheme adapter and mojaloop simulator. Please refer the following lines + +``` +DFSP_ID=payeefsp +CACHE_HOST=redis1 +PEER_ENDPOINT=sa_sim2:4000 +BACKEND_ENDPOINT=ml_sim1:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +We can now access the mojaloop simulator's test api on 3003. + +A new party should be added to the simulator using the following command. Feel free to change the details you want. +``` +curl -X POST "http://localhost:3003/repository/parties" -H "accept: */*" -H "Content-Type: application/json" -d "{\"displayName\":\"Test Payee1\",\"firstName\":\"Test\",\"middleName\":\"\",\"lastName\":\"Payee1\",\"dateOfBirth\":\"1970-01-01\",\"idType\":\"MSISDN\",\"idValue\":\"9876543210\"}" +``` + +Then try to run the following command to check the new party added. +``` +curl -X GET "http://localhost:3003/repository/parties" -H "accept: */*" +``` + +Let's move on to setup another instance of scheme adapter with DFSP mock backend. + +### DFSP Mock Backend service + +The DFSP mock backend is a minimal implementation of an example DFSP. Only basic functions are supported at the moment. + +Please download the following repository +``` +git clone https://github.com/mojaloop/sdk-mock-dfsp-backend.git +``` + +Edit the files src/docker-compose.yml, src/backend.env and src/scheme-adapter.env and add the container names for all the containers. Please refer the following files. +docker-compose.yml +``` +version: '3' +services: + redis2: + image: "redis:5.0.4-alpine" + container_name: redis2 + backend: + image: "mojaloop/sdk-mock-dfsp-backend" + env_file: ./backend.env + container_name: dfsp_mock_backend2 + ports: + - "23000:3000" + depends_on: + - scheme-adapter2 + + scheme-adapter2: + image: "mojaloop/sdk-scheme-adapter:latest" + env_file: ./scheme-adapter.env + container_name: sa_sim2 + depends_on: + - redis2 +``` +scheme-adapter.env +``` +DFSP_ID=payerfsp +CACHE_HOST=redis2 +PEER_ENDPOINT=sa_sim1:4000 +BACKEND_ENDPOINT=dfsp_mock_backend2:3000 +AUTO_ACCEPT_PARTY=true +AUTO_ACCEPT_QUOTES=true +VALIDATE_INBOUND_JWS=false +VALIDATE_INBOUND_PUT_PARTIES_JWS=false +JWS_SIGN=true +JWS_SIGN_PUT_PARTIES=true + +``` + +backend.env +``` +OUTBOUND_ENDPOINT=http://sa_sim2:4001 +``` + +Then try running the following command to run the services +``` +cd src/ +docker-compose up -d +``` + +## Try to send money +Try to send funds from "payerfsp" (Mock DFSP) to a MSISDN which is in "payeefsp" (Mojaloop Simulator) through scheme adapter. +Run the following curl command to issue command to Mock DFSP service. +``` +curl -X POST \ + http://localhost:23000/send \ + -H 'Content-Type: application/json' \ + -d '{ + "from": { + "displayName": "John Doe", + "idType": "MSISDN", + "idValue": "123456789" + }, + "to": { + "idType": "MSISDN", + "idValue": "9876543210" + }, + "amountType": "SEND", + "currency": "USD", + "amount": "100", + "transactionType": "TRANSFER", + "note": "test payment", + "homeTransactionId": "123ABC" +}' +``` + +You should get a response with COMPLETED currentState. diff --git a/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png new file mode 100644 index 000000000..35702294c Binary files /dev/null and b/website/versioned_docs/v1.0.1/technical/sdk-scheme-adapter/usage/scheme-adapter-to-scheme-adapter/scheme-adapter-to-scheme-adapter-overview.png differ diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/README.md b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/README.md new file mode 100644 index 000000000..b339478a9 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/README.md @@ -0,0 +1,8 @@ +# Transaction Requests Service + +## Sequence Diagram + +![trx-service-overview-spec.svg](./assets/diagrams/sequence/trx-service-overview-spec.svg) + +* The transaction-requests-service is a mojaloop core service that enables Payee initiated use cases such as "Merchant Request to Pay". +* This is a pass through service which also includes Authorizations. diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml new file mode 100644 index 000000000..0d4005e68 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.plantuml @@ -0,0 +1,64 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Authorizations +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" --\ "Payee FSP": Lookup, Transaction request,\nprocessing not shown here +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payer FSP" --> "Payer FSP": Do quote, generate OTP\nnotify user (not shown here) +"Payer FSP" -\ Switch: GET /authorizations/{TransactionRequestID} +Switch --/ "Payer FSP": 202 Accepted + +alt authorization request is valid + + Switch -> Switch: Validate GET /authorizations/{TransactionRequestID} (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + note over Switch, "Payee FSP": Switch forwards GET /authorizations request to Payee FSP + Switch -\ "Payee FSP": GET /authorizations/{TransactionRequestID} + "Payee FSP" --/ Switch: 202 Accepted + "Payee FSP" -> "Payee FSP": Process authorization request\n(Payer approves/rejects transaction\nusing OTP) + + note over Switch, "Payee FSP": Payee FSP responds with PUT /authorizations//{TransactionRequestID} + "Payee FSP" -\ Switch: PUT /authorizations//{TransactionRequestID} + Switch --/ "Payee FSP": 200 Ok + + note over "Payer FSP", Switch: Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + Switch -\ "Payer FSP": PUT /authorizations//{TransactionRequestID} + "Payer FSP" --/ Switch: 200 Ok + + +else authorization request is invalid + note over "Payer FSP", Switch: Switch returns error callback to Payer FSP + Switch -\ "Payer FSP": PUT /authorizations/{TransactionRequestID}/error + "Payer FSP" --/ Switch: 200 OK + "Payer FSP" --> "Payer FSP": Validate OTP sent by Payee FSP +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg new file mode 100644 index 000000000..20f251063 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + Transaction Requests Service - Authorizations + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + 1 + + + Lookup, Transaction request, + + + processing not shown here + + + + + Payee FSP generates a transaction-request to the Payer FSP + + + + + 2 + + + Do quote, generate OTP + + + notify user (not shown here) + + + + + 3 + + + GET /authorizations/{TransactionRequestID} + + + + + 4 + + + 202 Accepted + + + + + alt + + + [authorization request is valid] + + + + + 5 + + + Validate GET /authorizations/{TransactionRequestID} (internal validation) + + + + + 6 + + + Retrieve corresponding end-points for Payee FSP + + + + + Switch forwards GET /authorizations request to Payee FSP + + + + + 7 + + + GET /authorizations/{TransactionRequestID} + + + + + 8 + + + 202 Accepted + + + + + 9 + + + Process authorization request + + + (Payer approves/rejects transaction + + + using OTP) + + + + + Payee FSP responds with PUT /authorizations//{TransactionRequestID} + + + + + 10 + + + PUT /authorizations//{TransactionRequestID} + + + + + 11 + + + 200 Ok + + + + + Switch forwards PUT /authorizations//{TransactionRequestID} to Payer FSP + + + + + 12 + + + Retrieve corresponding end-points for Payer FSP + + + + + 13 + + + PUT /authorizations//{TransactionRequestID} + + + + + 14 + + + 200 Ok + + + + [authorization request is invalid] + + + + + Switch returns error callback to Payer FSP + + + + + 15 + + + PUT /authorizations/{TransactionRequestID}/error + + + + + 16 + + + 200 OK + + + + + 17 + + + Validate OTP sent by Payee FSP + + diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml new file mode 100644 index 000000000..655cf6e07 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.plantuml @@ -0,0 +1,93 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Create +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +"Payee FSP" -\ "Payee FSP": Lookup process\n(not shown here) +note over "Payee FSP", Switch: Payee FSP generates a transaction-request to the Payer FSP +"Payee FSP" -\ Switch: POST /transactionRequests +Switch -> Switch: Validate POST /transactionRequests schema +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request is valid + + Switch -> Switch: Validate POST /transactionRequests (internal validation) + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards POST /transactionRequests request to Payer FSP + Switch -\ "Payer FSP": POST /transactionRequests + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Process transaction-request + + alt Payer FSP successfully processes transaction-request + + note over "Payer FSP", Switch: Payer FSP responds to POST /transactionRequests + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + note over "Payee FSP" #3498db: Wait for a quote, transfer by Payer FSP\nor a rejected transaction-request + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP calculation fails or rejects the request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg new file mode 100644 index 000000000..b5a1c7313 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + Transaction Requests Service - Create + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + 1 + + + Lookup process + + + (not shown here) + + + + + Payee FSP generates a transaction-request to the Payer FSP + + + + + 2 + + + POST /transactionRequests + + + + + 3 + + + Validate POST /transactionRequests schema + + + + + 4 + + + 202 Accepted + + + + + alt + + + [transaction-request is valid] + + + + + 5 + + + Validate POST /transactionRequests (internal validation) + + + + + 6 + + + Retrieve corresponding end-points for Payer FSP + + + + + Switch forwards POST /transactionRequests request to Payer FSP + + + + + 7 + + + POST /transactionRequests + + + + + 8 + + + 202 Accepted + + + + + 9 + + + Process transaction-request + + + + + alt + + + [Payer FSP successfully processes transaction-request] + + + + + Payer FSP responds to POST /transactionRequests + + + + + 10 + + + PUT /transactionRequests/{ID} + + + + + 11 + + + 200 Ok + + + + + 12 + + + Validate PUT /transactionRequests/{ID} + + + + + alt + + + [response is ok] + + + + + Switch forwards transaction-request response to Payee FSP + + + + + 13 + + + Retrieve corresponding end-points for Payee FSP + + + + + 14 + + + PUT /transactionRequests/{ID} + + + + + 15 + + + 200 Ok + + + + + Wait for a quote, transfer by Payer FSP + + + or a rejected transaction-request + + + + [response invalid] + + + + + Switch returns error to Payer FSP + + + + + 16 + + + PUT /transactionRequests/{ID}/error + + + + + 17 + + + 200 Ok + + + + + Note that under this + + + scenario the Payee FSP + + + may not receive a response + + + + [Payer FSP calculation fails or rejects the request] + + + + + Payer FSP returns error to Switch + + + + + 18 + + + PUT /transactionRequests/{ID}/error + + + + + 19 + + + 200 OK + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /transactionRequests/{ID}/error + + + + + 21 + + + 200 OK + + + + [transaction-request is invalid] + + + + + Switch returns error to Payee FSP + + + + + 22 + + + PUT /transactionRequests/{ID}/error + + + + + 23 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml new file mode 100644 index 000000000..17262a24a --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.plantuml @@ -0,0 +1,90 @@ +/'***** + License + -------------- + Copyright © 2017 Bill & Melinda Gates Foundation + The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + Contributors + -------------- + This is the official list of the Mojaloop project contributors for this file. + Names of the original copyright holders (individuals or organizations) + should be listed with a '*' in the first column. People who have + contributed from an organization can be listed under the organization + that actually holds the copyright for their contributions (see the + Gates Foundation organization for an example). Those individuals should have + their names indented and be marked with a '-'. Email address can be added + optionally within square brackets . + * Gates Foundation + - Name Surname + + * Sam Kummary + -------------- + ******'/ + + +@startuml +Title Transaction Requests Service - Query +participant "Payer FSP" +participant "Switch\ntransaction-requests-service" as Switch +participant "Payee FSP" + +autonumber +note over "Payee FSP", Switch: Payee FSP requests the status of a transaction-request at the Payer FSP.\nID here is the ID of prevoiusly created transaction-request +"Payee FSP" -\ Switch: GET /transactionRequests/{ID} +Switch -> Switch: Validate GET /transactionRequests/{ID} +Switch --/ "Payee FSP": 202 Accepted + +alt transaction-request query is valid + + Switch -> Switch: Retrieve corresponding end-points for Payer FSP + note over Switch, "Payer FSP": Switch forwards GET /transactionRequests/{ID} request to Payer FSP + Switch -\ "Payer FSP": GET /transactionRequests/{ID} + "Payer FSP" --/ Switch: 202 Accepted + "Payer FSP" -> "Payer FSP": Retrieve transaction-request + + alt Payer FSP successfully retrieves transaction-request + + note over "Payer FSP", Switch: Payer FSP responds with the\nPUT /transactionRequests/{ID} callback + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID} + Switch --/ "Payer FSP": 200 Ok + + Switch -> Switch: Validate PUT /transactionRequests/{ID} + + alt response is ok + + note over Switch, "Payee FSP": Switch forwards transaction-request response to Payee FSP + Switch -> Switch: Retrieve corresponding end-points for Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID} + "Payee FSP" --/ Switch: 200 Ok + + else response invalid + + note over Switch, "Payer FSP": Switch returns error to Payer FSP + + Switch -\ "Payer FSP": PUT /transactionRequests/{ID}/error + "Payer FSP" --/ Switch : 200 Ok + + note over Switch, "Payer FSP" #ec7063: Note that under this\nscenario the Payee FSP\nmay not receive a response + + end + else Payer FSP is unable to retrieve the transaction-request + + note over "Payer FSP", Switch: Payer FSP returns error to Switch + + "Payer FSP" -\ Switch: PUT /transactionRequests/{ID}/error + Switch --/ "Payer FSP": 200 OK + + note over "Payee FSP", Switch: Switch returns error to Payee FSP + + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK + + end +else transaction-request is invalid + note over "Payee FSP", Switch: Switch returns error to Payee FSP + Switch -\ "Payee FSP": PUT /transactionRequests/{ID}/error + "Payee FSP" --/ Switch: 200 OK +end +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg new file mode 100644 index 000000000..bbc20538b --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + Transaction Requests Service - Query + + + + + + + + + Payer FSP + + + + Payer FSP + + + + Switch + + + transaction-requests-service + + + + Switch + + + transaction-requests-service + + + + Payee FSP + + + + Payee FSP + + + + + Payee FSP requests the status of a transaction-request at the Payer FSP. + + + ID here is the ID of prevoiusly created transaction-request + + + + + 1 + + + GET /transactionRequests/{ID} + + + + + 2 + + + Validate GET /transactionRequests/{ID} + + + + + 3 + + + 202 Accepted + + + + + alt + + + [transaction-request query is valid] + + + + + 4 + + + Retrieve corresponding end-points for Payer FSP + + + + + Switch forwards GET /transactionRequests/{ID} request to Payer FSP + + + + + 5 + + + GET /transactionRequests/{ID} + + + + + 6 + + + 202 Accepted + + + + + 7 + + + Retrieve transaction-request + + + + + alt + + + [Payer FSP successfully retrieves transaction-request] + + + + + Payer FSP responds with the + + + PUT /transactionRequests/{ID} callback + + + + + 8 + + + PUT /transactionRequests/{ID} + + + + + 9 + + + 200 Ok + + + + + 10 + + + Validate PUT /transactionRequests/{ID} + + + + + alt + + + [response is ok] + + + + + Switch forwards transaction-request response to Payee FSP + + + + + 11 + + + Retrieve corresponding end-points for Payee FSP + + + + + 12 + + + PUT /transactionRequests/{ID} + + + + + 13 + + + 200 Ok + + + + [response invalid] + + + + + Switch returns error to Payer FSP + + + + + 14 + + + PUT /transactionRequests/{ID}/error + + + + + 15 + + + 200 Ok + + + + + Note that under this + + + scenario the Payee FSP + + + may not receive a response + + + + [Payer FSP is unable to retrieve the transaction-request] + + + + + Payer FSP returns error to Switch + + + + + 16 + + + PUT /transactionRequests/{ID}/error + + + + + 17 + + + 200 OK + + + + + Switch returns error to Payee FSP + + + + + 18 + + + PUT /transactionRequests/{ID}/error + + + + + 19 + + + 200 OK + + + + [transaction-request is invalid] + + + + + Switch returns error to Payee FSP + + + + + 20 + + + PUT /transactionRequests/{ID}/error + + + + + 21 + + + 200 OK + + diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml new file mode 100644 index 000000000..d88913d33 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.plantuml @@ -0,0 +1,138 @@ +/'***** +License +-------------- +Copyright © 2017 Bill & Melinda Gates Foundation +The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Contributors +-------------- +This is the official list of the Mojaloop project contributors for this file. +Names of the original copyright holders (individuals or organizations) +should be listed with a '*' in the first column. People who have +contributed from an organization can be listed under the organization +that actually holds the copyright for their contributions (see the +Gates Foundation organization for an example). Those individuals should have +their names indented and be marked with a '-'. Email address can be added +optionally within square brackets . +* Gates Foundation +- Name Surname + +* Henk Kodde +-------------- +******'/ + +@startuml transactionRequests + +' define actor image +sprite $actor [25x48/16] { + 0000000000010000000000000 + 0000000006CAC910000000000 + 0000000095101292000000000 + 0000000651000119000000000 + 0000000B10000018400000000 + 0000001A10000016600000000 + 0000000B10000017510000000 + 000000083100001A210000000 + 0000000191000176110000000 + 000000003A866A61100000000 + 0000000000466211100000000 + 0003333333334443333310000 + 0088888888888888888892000 + 0821111111111111111118200 + 8311111111111111111111A00 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111111111111111111111A20 + A111551111111111138111A20 + A111661111111111139111A20 + A211661111111111139111A20 + A211661111111111139111A20 + A211661111161111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A2116611111A2111139111A20 + A7669611111A211113A666B20 + 36669611111A211113A666610 + 00016611111A2111139111110 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006611111A2111139100000 + 00006966666B7666679100000 + 0000266666666666664100000 + 0000000111111111111100000 + 0000000000000000000000000 +} + +' declaring skinparam +skinparam sequenceMessageAlign center +skinparam shadowing false +skinparam defaultFontName Verdana +skinparam monochrome true +skinparam SequenceLifeLineBackgroundColor WhiteSmoke +skinparam SequenceLifeLineBorderColor Black +skinparam ActorFontStyle Bold +skinparam ActorFontSize 20 +skinparam ParticipantFontStyle Bold +skinparam ParticipantFontSize 20 +skinparam ParticipantBackgroundColor WhiteSmoke +skinparam ArrowColor Black + +skinparam actor { + Bordercolor none + Backgroundcolor none + shadowing false +} + +skinparam participant { + shadowing true +} + +hide footbox + +' declare title +' title How to use the /transactionRequests service + +' Actor Keys: +' participant - FSP(Payer/Payee) and Switch +' actor - Payee + +' declare actors +participant "Payer\nFSP" as payerfsp +participant "Optional\nSwitch" as Switch +participant "Payee\nFSP" as payeefsp +actor "<$actor>\nPayee" as Payee + +' start flow +payeefsp <- Payee: I would like to receive\nfunds from +123456789 +activate payeefsp +payeefsp <- payeefsp: Lookup +123456789\n(process not shown here) +Switch <<- payeefsp: **POST /transactionRequest/**\n(Payee information,\ntransaction details) +activate Switch +Switch -->> payeefsp: **HTTP 202** (Accepted) +payerfsp <<- Switch: **POST /transactionRequests/**\n(Payee information,\ntransaction details) +activate payerfsp +payerfsp -->> Switch: **HTTP 202** (Accepted) +payeefsp -> payeefsp: Perform optional validation +payerfsp ->> Switch: **PUT /transactionRequests/**\n(Received status) +payerfsp <<-- Switch: **HTTP 200** (OK) +deactivate payerfsp +Switch ->> payeefsp: **PUT /transactionRequests/**\n(Received status) +Switch <<-- payeefsp: **HTTP 200** (OK) +deactivate Switch +payeefsp -> payeefsp: Wait for either quote and\ntransfer, or rejected\ntransaction request by Payer +payeefsp <[hidden]- payeefsp +deactivate payeefsp +@enduml diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg new file mode 100644 index 000000000..e54569705 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/assets/diagrams/sequence/trx-service-overview-spec.svg @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + Payer + + + FSP + + + + Optional + + + Switch + + + + Payee + + + FSP + + + + Payee + + + + + + + I would like to receive + + + funds from +123456789 + + + + Lookup +123456789 + + + (process not shown here) + + + + POST /transactionRequest/ + + + (Payee information, + + + transaction details) + + + + + HTTP 202 + + + (Accepted) + + + + POST /transactionRequests/ + + + (Payee information, + + + transaction details) + + + + + HTTP 202 + + + (Accepted) + + + + Perform optional validation + + + + PUT /transactionRequests/ + + + <ID> + + + (Received status) + + + + + HTTP 200 + + + (OK) + + + + PUT /transactionRequests/ + + + <ID> + + + (Received status) + + + + + HTTP 200 + + + (OK) + + + + Wait for either quote and + + + transfer, or rejected + + + transaction request by Payer + + diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/authorizations.md b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/authorizations.md new file mode 100644 index 000000000..614b5d0a5 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/authorizations.md @@ -0,0 +1,7 @@ +# Transaction Requests + +GET /authorizations/{TransactionRequestID} and PUT /authorizations/{TransactionRequestID} to support authorizations in "Merchant Request to Pay" and other Payee initiated use cases + +## Sequence Diagram + +![seq-trx-req-authorizations-3.0.0.svg](./assets/diagrams/sequence/seq-trx-req-authorizations-3.0.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-get.md b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-get.md new file mode 100644 index 000000000..b99202192 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-get.md @@ -0,0 +1,7 @@ +# Transaction Requests - Query + +GET /transactionRequests and PUT /transacionRequests to suppport "Merchant Request to Pay" + +## Sequence Diagram + +![seq-trx-req-service-get-2.0.0.svg](./assets/diagrams/sequence/seq-trx-req-service-get-2.0.0.svg) diff --git a/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-post.md b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-post.md new file mode 100644 index 000000000..58ea60460 --- /dev/null +++ b/website/versioned_docs/v1.0.1/technical/transaction-requests-service/transaction-requests-post.md @@ -0,0 +1,7 @@ +# Transaction Requests + +POST /transactionRequests and PUT /transacionRequests to suppport "Merchant Request to Pay" + +## Sequence Diagram + +![seq-trx-req-service-1.0.0.svg](./assets/diagrams/sequence/seq-trx-req-service-1.0.0.svg)